tags:

views:

401

answers:

1

Hi,

I made a simple ftp client in C# which does what I need (connect to a ftp, optionally using a proxy), but I want to be able to use AUTH SSL also.

So instead of NetworkStream I looked at SslStream and hoped it would be a fairly easy substitute.

However I seem to have a lot of problems when handshaking with my (glftpd, selfsigned openssl cert) ftp. Here's a code snippit:

    TcpClient client = new TcpClient("192.168.0.2", 1337);
    SslStream sslStream = new SslStream(
                client.GetStream(),
                false,
                new RemoteCertificateValidationCallback(ValidateServerCertificate),
                null
                );
        try
        {
            sslStream.AuthenticateAsClient("192.168.0.2"); // or "glftpd", neither worked.
        }
        catch (AuthenticationException e)
        {
            Console.WriteLine("Exception: {0}", e.Message);
            if (e.InnerException != null)
            {
                Console.WriteLine("Inner exception: {0}", e.InnerException.Message);
            }
            Console.WriteLine("Authentication failed - closing the connection.");
            client.Close();
            return;
        }

I break on AuthenticateAsClient with IOException: "The handshake failed due to an unexpected packet format.". I don't break in ValidateServerCertificate (never reached).

I find it hard to debug this error as I can set the TcpClient port to 1208219421 and still recieve the same error (so I don't even know if it fails to talk to a ssl port).

The code (among 3-4 different C# ssl guides I looked at) above is modified from link text

I've tried both sslStream.AuthenticateAsClient(..., ..., SslProtocols.Tls, false) and sslStream.AuthenticateAsClient(..., ..., SslProtocols.Ssl3, false) Ssl2 and Default, and I know for a fact that TLS works with my glftpd install.

If I had to guess I'd think it has something to do with machinename/certname, but I've tried the certname (which is "glftpd"), so right now I'm clueless as to why I get failed handshake.

Also it should be noted that the cert is self-signed.

Any help is greatly appreciated!

  • Chuck
+1  A: 

Did you check the port number? Is that the problem?

EDIT 1

http://en.wikipedia.org/wki/FTPS

Perhaps your server is not in "Implicit" mode? Should it be?

You probably want Explicit mode support in your product too/instead.

EDIT 2

(Apologies, I can't comment yet, not enough reps so I am making edits instead. :-) )

If support for both explicit and implicit in your live code are not required, I often like to run TCP servers on two ports simultaneously if possible, one for implicit SSL and one for explicit/non-SSL. Your server software may or may not support this.

EDIT 3

Depends whether you control the servers / how standards compliant you want to be!

Implicit mode will be regarded as slightly less standardsy but OTOH its less work.

EDIT 4

It may be better protection against denial-of-service issues to use Explicit rather than Implicit but I am not sure, I'd have to study the protocol. My experience is with XMPP.

EDIT 5

Plus the plain text startup of explicit mode may make some corporate legal departments a little bit more relaxed about legal issues of any unauthorised access than with something that starts off doing TLS gibberish on the wire straightaway.

martinr
Unfortunately I don't think so. The port should be correct. 1337 is what I can connect to with non-SSL and with AUTH SSL in various ftp clients, but thanks for your reply.
You're right, implicit is not supported. So that could be it. What I want is either AUTH SSL or just TLS will do fine (if that's less work?)
My objective is simply to connect (TCP) to an IP. Then be able to send "AUTH TSL" (or "AUTH SSL") and accept the certificate no matter what, and then have a secure connection to that IP.
Relying on DNS alone not good - the DNS may be subject to man-in-the-middle attacks. Do a risk assessment and probably try to avoid . Also if you start using certificates, validate the results of each TLS handshake. The negotiated protocol should be a recognised strong one (TLS libraries generally can negotiate connections from a suite of bundled protocols) and check the certificate fingerprint. Ideally disable weak protocols in your TLS software.
martinr
I appreciate your security concern, but I need to at least say yes/no to accepting the cert, and by saying yes, it would accept no matter what.
Would = should.
... Assuming the protocol negotiated uses a certificate that can be said yes/no to. We're pretty much on the same page I feel.
martinr
Yes. But of course if SslStream doesn't allow you to accept a certificate that's selfsigned, then I think my project is better left alone, hehe.
Ok, port is right, but certificate is just not cooporating. Grrrr. "The handshake failed due to an unexpected packet format." WHAT THE...Can anybody tell me if there're some debug tools I can use to identify the problem? I tried raw'ing to the server on port 1337 (which the ssl is set to) with no luck. Tried ssh'ing to it, no luck
Get some Unix tools for Windows and the OpenSSL toolkit? openssl has command line options to do a handshake over stdin/stdout I believe. Write a bash script to try the protocol or something. If you don't know what I mean try opening a new question.
martinr
I know what you mean, and thank you.