SMTPS:OpenSSL - SSL例程:SSL23_GET_SERVER_HELLO:未知协议s23_clnt.c:787:

时间:2014-03-17 08:47:47

标签: c ssl smtp openssl smtps

我使用OpenSSL来加密一些硬件发送的电子邮件。但是,每当我尝试调用SSL_connect()时,我得到: SSL例程:SSL23_GET_SERVER_HELLO:未知协议

发送" EHLO"和" STARTTLS"我调用以下函数:

SSL_CTX *ctx = NULL;
SSL *ssl = NULL;

    void CreateTLSSession(int sockfd)
    {
        printf("///////////////creating TLS Session/////////////////////\n");
        SSL_library_init();
        SSL_load_error_strings();
        OpenSSL_add_all_algorithms();
        ctx = SSL_CTX_new(SSLv23_client_method());
        if (ctx == NULL)
        {
            printf("failed to initialize context\n");
            return;
        }
        SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
        ssl = SSL_new(ctx);
        if (!SSL_set_fd(ssl, sockfd))
        {
            printf("failed to bind to socket fd\n");
            return;
        }
        if (SSL_connect(ssl) < 1)
        {
            ERR_print_errors_fp(stdout);
            fflush(stdout);
            printf("SSL_connect failed\n");
            return;
        }
    }

我已尝试连接到:

  • smtp.live.com:587 - &gt; SSL例程:SSL23_GET_SERVER_HELLO:未知 protocol s23_clnt.c:787:
  • smtp.live.com:25 - &gt; SSL例程:SSL23_GET_SERVER_HELLO:未知协议s23_clnt.c:787:
  • smtp.gmail.com:587 - &gt; SSL例程:SSL23_GET_SERVER_HELLO:未知 protocol s23_clnt.c:787:
  • smtp.gmail.com:465 - &gt;根本没有来自服务器的响应!
  • smtp.gmail.com:25 - &gt; SSL例程:SSL23_GET_SERVER_HELLO:未知
    protocol s23_clnt.c:787:

我尝试过不同的端口,因为有关此SO的类似问题表明,此类错误通常与使用错误的SSL端口有关。

我在这里错过了什么吗?

更新:

所有其他方法(即TLSv1_1_method(),SSLv3_method()...)导致SSL3_GET_RECORD:版本号错误

更新:

我能够在wireshark上观察以下内容:

&#34; EHLO&#34;

&#34;在您的服务&#34;

&#34; STARTTLS&#34;

&#34;准备开始&#34;

- &gt;现在我调用上面的函数

无法读取的请求(已加密)

无法回复(加密)

- &GT; ERROR

3 个答案:

答案 0 :(得分:3)

端口587和25上的SMTP服务器通常是纯文本,只有在初始SMTP对话框和客户端的STARTTLS命令之后才会切换到TLS。在纯文本套接字上尝试SSL_connect将失败。

答案 1 :(得分:1)

解决此问题的另一种方法可能是在Scott Gifford的sslclient下运行您的C程序(请参阅http://www.superscript.com/ucspi-ssl/sslclient.html)。 sslclient将生成您的程序并打开到服务器的tcp连接,并将程序的标准输出管道传送到服务器,并将服务器的输出管道输出到您的程序的标准输入。他有一个用于TLS的修补版本,它将以纯文本方式启动连接,然后一旦双方同意STARTTLS,您的程序就可以通过向文件描述符写入命令来向sslcient发出信号以启用连接上的SSL加密目的。这样做的好处是你可以让sslclient完成所有繁重的工作,只要设置套接字和ssl等,你就可以专注于程序的核心功能。

答案 2 :(得分:0)

潜在的袜子是非阻塞的。通过使用select并等待TLS握手完成,问题得以解决。