Question


I have a strange problem: I wrote a server and client in c# based on .net2 which are chatting over the .net 2 SslStream. There is 1 Connection for sending commands between Cl and S and theres one connection for sending files between cl and s.
Locally all is working fine on my windows machine. But if I run the server on my Linux server(with mono), sharing files doesnt work in certain situations. I have different Categories for files, and in 2 of 3 its working, in the third, the server hangs on SSLStream.AuthenticateAsServer(....); and the client throws a Exception with the Message "A Call to SSPI Failed, see inner exception". The innerexception is a System.ComponentModel.Win32Exception with the Message "The message received was unexpected or badly formatted."

I think that my way to run it on linux could be wrong. Actually Im using VS2012 for local developing and when I want to put it on the server I upload the compiled exe by VS and Im using mono server.exe to start it. But I also tried to use monodevelop on Windows to compile it(compiled stuff from monodevelop does also work locally) and use it on the linux server, but this ended in the same result.

Any help will be greatly appreciated.



Heres my shortened Code:

Client:

//gets auth guid before, then it does
Thread Thre = new Thread(sendfile);
Thre.Start(authguid);


private void sendfile(string guid){
TcpClient cl = new TcpClient();
cl.Connect(hostname, 8789);
SslStream Stream = new SslStream(cl.GetStream(), true, new RemoteCertificateValidationCallback(ServerConnector.ValidateServerCertificate));
Stream.AuthenticateAsClient(hostname);//throws the exception
//sends auth guid and file

}

Server:

 public class FServer
    {

        protected static bool halt = false;
        protected List<FConnection> connections;
        private TcpListener tcpServer;
        private IPEndPoint ipEnde = new IPEndPoint(IPAddress.Any, 8789);
        private delegate void dlgAccept();
        private dlgAccept accepting;
        private IAsyncResult resAccept;

        public FServer()
        {
            tcpServer = new TcpListener(ipEnde);
            connections = new List<FConnection>();
            tcpServer.Start();
            accepting = new dlgAccept(accept);
            resAccept = accepting.BeginInvoke(null, null);


        }

        public void accept()
        {
            do
            {
                if (tcpServer.Pending())
                    connections.Add(new FConnection(tcpServer.AcceptTcpClient(), this));

                else
                    Thread.Sleep(750);
            } while (!halt && tcpServer != null);
        }

        public class FConnection 
        {
           public SslStream stream;
            //.....some other properties

           public static bool ValidateClientCertificate (object sender, X509Certificate certificate, X509Chain chain, SslPolicyErrors sslPolicyErrors)
            {
                return true;

            }

            public FConnection(TcpClient cl, FServer inst)
            {
                instance = inst;
                client = cl;

                    stream = new SslStream(client.GetStream(), false, new RemoteCertificateValidationCallback(ValidateClientCertificate), null);
                    stream.AuthenticateAsServer(instance.mainserver.serverCert, false, SslProtocols.Tls, false);//hangs sometimes on this
                    if (stream.IsAuthenticated && stream.IsEncrypted)
                    {
                    }
                    else
                    {
                        this.Dispose();
                    }

                    //auth and receiving file

            }

        }
    }
Was it helpful?

Solution

Ok I researched about the innerexception a bit deeper and found the solution here:

http://social.msdn.microsoft.com/forums/en-US/netfxnetcom/thread/18b4a0ce-b348-403d-8655-fe9d558f8d6b

The credit goes to paksys from MSDN

The problem is in the client and i changed

Stream.AuthenticateAsClient(hostname);

to

X509Certificates.X509Certificate2Collection xc = new X509Certificates.X509Certificate2Collection();
Stream.AuthenticateAsClient(hostname, xc, Security.Authentication.SslProtocols.Tls, false);

OTHER TIPS

I just had the same problem and the accepted answer was not working for me. The problem was that the server certificate was using SHA-2. Here is the code I use to fix it:

X509Certificates.X509Certificate2Collection xc = new X509Certificates.X509Certificate2Collection();
Stream.AuthenticateAsClient(hostname, xc, Security.Authentication.SslProtocols.Tls12, false);
  • Note that the only difference with the accepted answer is the sslProtocol

Hope it can help someone

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top