Handshake failed due to an unexpected packet format logging into Pop3

Tim picture Tim · Mar 8, 2016 · Viewed 18.8k times · Source

I am trying to update code that monitors an Exchange Server mailbox so it can log in using SSL. However, when it tries to log in, I get the error: The handshake failed due to an unexpected packet format.

My code for connecting is below (with logging and comments removed):

ServicePointManager.ServerCertificateValidationCallback += (o, c, ch, er) => true;

try
{
    tcpClient = new TcpClient(Host, Port);
}
catch (SocketException e) { ... }

try
{
    var stream = client.GetStream();
    ssl = new SslStream(stream);
    ssl.AuthenticateAsClient(Host, null, SslProtocols.Tls, true);
    streamReader = new StreamReader(ssl);

    response = streamReader.ReadLine();
    if (response.StartsWith("+OK"))
    {
        response = SendReceive("USER ", UserName.Trim() + "@" + Domain.Trim());
        if (response.StartsWith("+OK"))
        {
            response = SendReceive("PASS ", Password);
        }
    }

    if (response.StartsWith("+OK"))
        result = true;
}
catch (Exception e) { ... }

From logging, I've pinpointed the exception to the somewhere in the first 4 lines after the second Try (which is actually in the GetStreamReader method, but I combined it for brevity and readability).

The exception that I receive is below:

    --- Exception ---
Error:  3/8/2016 10:32:35 AM    The handshake failed due to an unexpected packet format.
Info:   3/8/2016 10:32:35 AM    There was an error connecting to the account.
The server returned 
The handshake failed due to an unexpected packet format.
Info:   3/8/2016 10:32:35 AM    Source: System
Info:   3/8/2016 10:32:35 AM    Method: Void StartReadFrame(Byte[], Int32, System.Net.AsyncProtocolRequest)
Info:   3/8/2016 10:32:35 AM    
   at System.Net.Security.SslState.StartReadFrame(Byte[] buffer, Int32 readBytes, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartReceiveBlob(Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.CheckCompletionBeforeNextReceive(ProtocolToken message, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.StartSendBlob(Byte[] incoming, Int32 count, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ForceAuthentication(Boolean receiveFirst, Byte[] buffer, AsyncProtocolRequest asyncRequest)
   at System.Net.Security.SslState.ProcessAuthentication(LazyAsyncResult lazyResult)
   at System.Net.Security.SslStream.AuthenticateAsClient(String targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)
   at POP3_Communication.Pop3.GetStreamReader(TcpClient client)
   at POP3_Communication.Pop3.Connect()

Answer

jstedfast picture jstedfast · Mar 8, 2016

I can narrow it down further based on your exception stacktrace :)

at System.Net.Security.SslStream.AuthenticateAsClient(String targetHost, X509CertificateCollection clientCertificates, SslProtocols enabledSslProtocols, Boolean checkCertificateRevocation)

The problem is that you are connecting to a port that does not have SSL enabled (i.e. you are probably connecting to port 110 instead of 995).

Have you considered using a library such as MailKit instead of rolling your own solution?