c - C : STARTTLS via OpenSSL 上的 SMTP

标签 c linux smtp openssl ssl

我正在使用 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:

为什么?我做错了什么?

最佳答案

我昨天遇到了同样的问题。这是我解决它的方法:
- 首先创建一个普通的 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 证书对您自己(或服务器)进行身份验证。但对我来说,它解决了获取“未知协议(protocol)”的问题。

希望这有助于...
菲尔

关于c - C : STARTTLS via OpenSSL 上的 SMTP,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2563073/

上一篇:c - 跳进argv?

下一篇:c - Linux蓝牙编程

相关文章:

c - 当第三方 C 函数返回一个指针时,你应该自己释放它吗?

c - Linux 多线程程序中的串口读取

email - Sendgrid替代方案?

c - 创建共享对象时不能使用针对 .data 的重定位 R_X86_64_32S(64 位 NASM + gcc)

ruby-on-rails - Rails ActionMailer 将电子邮件复制到已发送文件夹 SMTP ruby

smtp - 如何找出 SMTP 服务器主机?

C可变包装器

c++ - 存在溢出时的整数运算

PHP 对 readdir 的权限被拒绝,即使它是相同的用户和组

linux - 如何使用 "top"仅提取 CPU 使用率和进程名称(命令)列?