C 上的 SMTP:通过 OpenSSL 的 STARTTLS
我正在使用 openssl 构建与 gmail.com:25 的安全 smtp 连接。这样我就可以成功连接到服务器并发送命令 STARTTLS (我收到 220 2.0.0 Ready to start 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:
为什么?我做错了什么?
I am using openssl to build secure smtp connections to gmail.com:25. So I can successfully connect to the server and sends a command STARTTLS (I receive 220 2.0.0 Ready to start TLS). Then execute the following code without disconnecting:
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
}
But after calling SSL_connect I get an error:
24953:error:140770FC:SSL routines:SSL23_GET_SERVER_HELLO:unknown protocol:s23_clnt.c:601:
If I use SSLv3_client_method I get an error:
18143:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number:s3_pkt.c:284.
And If TLSv1_client_method:
21293:error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number:s3_pkt.c:284:
Why? What I do wrong?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(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 套接字的“SSL_write”和“SSL_read”来发送您的身份验证信息和电子邮件。
请注意,此方法仅加密您的数据,但不会使用 SSL 证书对您自己(或服务器)进行身份验证。但对我来说,它解决了获取“未知协议”的问题。
希望这有帮助...
菲尔
I ran in the same problem yesterday. Here is how I solved it:
- start by creating a normal TCP socket and connect it to smtp.gmail.com:587
- send a "ehlo [127.0.0.1]\r\n" command
- get the answers from the server (Notice: so far everything is in clear)
- send a "STARTTLS\r\n" command
- get the answer (i.e. "220 Ready for TLS")
- at this moment, create your ssl wrapper (method, ctx, etc...) and use "SSL_set_fd" and "SSL_connect" to activate it
- send a new "ehlo [127.0.0.1]\r\n" command but using the SSL socket
From now on, use "SSL_write" and "SSL_read" with the SSL socket to send your authentication information and email.
Please realize that this method only encrypts your data but doesn't authenticate yourself (or the server) with SSL certificates. But for me, it solved the problem of getting "unknown protocol".
Hope this helps...
Phil
尝试使用 SSLv3_client_method 或 TLSv1_client_method 而不是 SSLv23_client_method。我认为 Gmail 不支持 SSLv23。
Try using SSLv3_client_method or TLSv1_client_method instead of SSLv23_client_method. I don't think Gmail supports SSLv23.
您是否同时读取了分隔服务器
220
响应末尾的\r
(回车符)和\n
(换行符)字符?启动 TLS?Are you reading both the
\r
(carriage return) and\n
(newline) characters that delimit the end of the server's220
response, before starting TLS?