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
}
}
}
Ok I researched about the innerexception a bit deeper and found the solution here:
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);