C上的SMTP:通过OpenSSL STARTTLS

时间:2010-04-01 19:24:36

标签: c linux smtp openssl ssl

我使用openssl建立与gmail.com:25的安全smtp连接。所以我可以成功连接到服务器并发送命令STARTTLS(我收到220 2.0.0准备启动TLS)。然后执行以下代码而不断开连接:

SSL_METHOD* method = NULL;

SSL_library_init();
SSL_load_error_strings();

method = SSLv23_client_method();

ctx = SSL_CTX_new(method);
if (ctx == NULL)
{
    ERR_print_errors_fp(stderr);
}
SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2);
ssl = SSL_new(ctx);
if (!SSL_set_fd(ssl, socket))
{
        ERR_print_errors_fp(stderr);
        return;
}
if (ssl)
{

    if (SSL_connect((SSL*)ssl) < 1)
    {
        ERR_print_errors_fp(stderr);
    }
    // then i think i need to send EHLO
}

但是在调用SSL_connect之后我收到一个错误:

24953:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:s23_clnt.c:601:

如果我使用SSLv3_client_method,则会收到错误消息:

18143:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number:s3_pkt.c:284.

如果是TLSv1_client_method:

21293:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number:s3_pkt.c:284:

为什么呢?我做错了什么?

3 个答案:

答案 0 :(得分:3)

昨天我遇到了同样的问题。以下是我解决的方法:
- 首先创建一个普通的TCP套接字并将其连接到smtp.gmail.com:587
- 发送“ehlo [127.0.0.1] \ r \ n”命令
- 从服务器获得答案(注意:到目前为止一切都清楚了)
- 发送“STARTTLS \ r \ n”命令
- 得到答案(即“220 Ready for TLS”)
- 此时,创建你的ssl包装器(方法,ctx等等)并使用“SSL_set_fd”和“SSL_connect”激活它 - 发送新的“ehlo [127.0.0.1] \ r \ n”命令,但使用SSL插座

从现在开始,使用“SSL_write”和“SSL_read”与SSL套接字发送您的身份验证信息和电子邮件。

请注意,此方法仅对您的数据进行加密,但不会使用SSL证书对您自己(或服务器)进行身份验证。但对我来说,它解决了获得“未知协议”的问题。

希望这有助于...
菲尔

答案 1 :(得分:0)

尝试使用SSLv3_client_method或TLSv1_client_method而不是SSLv23_client_method。我认为Gmail不支持SSLv23。

答案 2 :(得分:0)

在开始TLS之前,您是否正在读取分隔服务器\r响应结束的\n(回车)和220(换行符)字符?