AuthenticateAsClient:System.IO.IOException:从传输流中收到意外的EOF或0字节

时间:2014-08-20 21:42:36

标签: c#-2.0 tcpclient ioexception sslstream

由于Heartbleed,我们的网关服务器已更新,此问题出现了。

由于POODLE,不再支持SSLv3。

  • 注意,问题仅出现在Win7 +盒子上; WinXP框没有问题(相同的代码,不同的操作系统=问题);授予WinXP不再是一个有效的操作系统,只是想记下功能。

客户端应用程序(.NET 2.0)位于Windows 7(或8)框中。服务器在网关服务器后面的DMZ内运行。请注意,我发现.NET 4.0+不再存在这个问题 - 但是由于遗留代码,我没有更新的余地。

Gateway Server是一个传递框,运行带有SSL的Apache HTTP Server。它的位置在DMZ之外,用于访问DMZ内部的服务器。在网关服务器上运行的软件版本是Apache / 2.2.25(Win32),mod_jk / 1.2.39,mod_ssl / 2.2.25,OpenSSL / 1.0.1g

以下是客户端应用程序中使用的代码(添加了大量的日志记录)...注意,'serverName'通常包含诸如“https://some.url.com”之类的值

private bool ConnectAndAuthenicate(string serverName, out TcpClient client, out SslStream sslStream)
{
    client = null;
    sslStream = null;
    try
    {
        client = new TcpClient(serverName, 443); // Create a TCP/IP client; ctor attempts connection
        Log("ConnectAndAuthenicate: Client CONNECTED"));

        sslStream = new SslStream(client.GetStream(), false, ValidateServerCertificate, null);
        Log("ConnectAndAuthenicate: SSL Stream CREATED"));
    }
    catch (Exception x)
    {
        Log("ConnectAndAuthenicate: EXCEPTION >> CONNECTING to server: {0}", x.ToString()));

        if (x is SocketException)
        {
            SocketException s = x as SocketException;
            Log("ConnectAndAuthenicate: EXCEPTION >> CONNECTING to server: Socket.ErrorCode: {0}", s.ErrorCode));
        }
        if (client != null) { client.Close(); client = null; }
        if (sslStream != null) { sslStream.Close(); sslStream = null; }
    }

    if (sslStream == null) return false;

    try
    {
        sslStream.ReadTimeout = 10000; // wait 10 seconds for a response ...
        Log("ConnectAndAuthenicate: AuthenticateAsClient CALLED ({0})", serverName));
        sslStream.AuthenticateAsClient(serverName);
        Log("ConnectAndAuthenicate: AuthenticateAsClient COMPLETED SUCCESSFULLY"));
        return true;
    }
    catch (Exception x)
    {
        Log("ConnectAndAuthenicate: EXCEPTION >> AuthenticateAsClient: {0}", x.ToString()));
        client.Close(); client = null;
        sslStream.Close(); sslStream = null;
    }
    return false;
}

注意 - 与ServicePointManager相关的answers posted对此应用程序的结果完全没有影响。

每次在Win 7+框上运行应用程序时调用AuthenicateAsClient()时,都会发生异常 - 如果在WinXP框上运行应用程序,代码可以正常运行而无例外。

非常欢迎任何解决方案的想法。

1 个答案:

答案 0 :(得分:6)

在设置ServicePointManager.SecurityProtocol静态ctor并使用SecurityProtocolType之后,我发现了另一个名为SslPolicy的枚举 - 进一步的研究发现AuthenicateAsClient has an overload以SslPolicy为参数。

在上面的代码中更改此行修复了此问题:

sslStream.AuthenticateAsClient(serverName, null, SslPolicy.Tls, false);