无法在STARTTLS之后写入ssl(openssl)套接字 你好,我尝试在C++中编写一个SMTP客户端。 在执行“ehlo…”和STARTTLS命令后,连接似乎正常。当我尝试SSL_write()时,出现此错误:
在SSL\u写入之前,我尝试了SSL\u do\u handshake(),它成功了 这是我的SSL部分代码无法在STARTTLS之后写入ssl(openssl)套接字 你好,我尝试在C++中编写一个SMTP客户端。 在执行“ehlo…”和STARTTLS命令后,连接似乎正常。当我尝试SSL_write()时,出现此错误:,c++,ssl,openssl,smtp,starttls,C++,Ssl,Openssl,Smtp,Starttls,在SSL\u写入之前,我尝试了SSL\u do\u handshake(),它成功了 这是我的SSL部分代码 typedef struct { int socket; SSL *sslHandle; SSL_CTX *sslContext; } SSLConnection; SSLConnection* wrapSslSocket(SOCKET hSocket) { SSLConnection *c; c = (SSLConnection *)mallo
typedef struct {
int socket;
SSL *sslHandle;
SSL_CTX *sslContext;
} SSLConnection;
SSLConnection* wrapSslSocket(SOCKET hSocket)
{
SSLConnection *c;
c = (SSLConnection *)malloc (sizeof (SSLConnection));
c->sslHandle = NULL;
c->sslContext = NULL;
c->socket = hSocket;
if (c->socket)
{
// Register the error strings for libcrypto & libssl
SSL_load_error_strings ();
// Register the available ciphers and digests
SSL_library_init ();
c->sslContext = SSL_CTX_new (SSLv23_client_method ()); //I tried SSLv23, SSLv3, SSLv2, TLSv1.2 TLSv1.1, TLSv1.0
if (c->sslContext == NULL)
ERR_print_errors_fp (stderr);
// Create an SSL struct for the connection
c->sslHandle = SSL_new (c->sslContext);
if (c->sslHandle == NULL)
ERR_print_errors_fp (stderr);
// Connect the SSL struct to our connection
if (!SSL_set_fd (c->sslHandle, c->socket))
ERR_print_errors_fp (stderr);
if (!SSL_set_mode(c->sslHandle, SSL_MODE_AUTO_RETRY))
ERR_print_errors_fp (stderr);
// Initiate SSL handshake
if (SSL_connect (c->sslHandle) != 1)
ERR_print_errors_fp (stderr);
}
return c;
}
// Read all available text from the connection
int sslRead (SSLConnection *c)
{
const int readSize = 1024;
char buffer[1024];
int cb;
int cbBuffer = 0;
if (c)
{
while (1)
{
cb = SSL_read( c->sslHandle, buffer + cbBuffer, sizeof(buffer) - 1 - cbBuffer);
if( cb <= 0 )
{
ERR_print_errors_fp (stderr);
return -1;
}
cbBuffer += cb;
if( memcmp( buffer + cbBuffer - 2, "\r\n", 2 ) == 0 )
{
buffer[cbBuffer] = '\0';
break;
}
}
}
printf("ssl send : %s \n",buffer);
char status[3];
memcpy(status,buffer, 3*sizeof(char));
status[3] = '\0';
return atoi(status);
}
// Write text to the connection
int sslWrite (SSLConnection *c, char *text)
{
if (c)
{
int v = SSL_do_handshake(c->sslHandle);
ERR_print_errors_fp (stderr);
return SSL_write (c->sslHandle, text, strlen (text));
}
}
typedef结构{
int插座;
SSL*sslHandle;
SSL_CTX*sslContext;
}SSL连接;
SSL连接*wrapSslSocket(插座hSocket)
{
SSL连接*c;
c=(SSLConnection*)malloc(sizeof(SSLConnection));
c->sslHandle=NULL;
c->sslContext=NULL;
c->socket=hssocket;
if(c->socket)
{
//注册libcrypto和libssl的错误字符串
SSL_加载_错误_字符串();
//注册可用的密码和摘要
SSL_库_init();
c->sslContext=SSL\u CTX\u new(SSLv23\u client\u method());//我尝试了SSLv23、SSLv3、SSLv2、TLSv1.2、TLSv1.1、TLSv1.0
如果(c->sslContext==NULL)
错误打印错误fp(stderr);
//为连接创建SSL结构
c->sslHandle=SSL\u新建(c->sslContext);
如果(c->sslHandle==NULL)
错误打印错误fp(stderr);
//将SSL结构连接到我们的连接
如果(!SSL\u set\u fd(c->sslHandle,c->socket))
错误打印错误fp(stderr);
如果(!SSL\u设置\u模式(c->sslHandle,SSL\u模式\u自动\u重试))
错误打印错误fp(stderr);
//启动SSL握手
如果(SSL\U连接(c->sslHandle)!=1)
错误打印错误fp(stderr);
}
返回c;
}
//读取连接中的所有可用文本
内部sslRead(SSL连接*c)
{
常数int readSize=1024;
字符缓冲区[1024];
int-cb;
int cbBuffer=0;
如果(c)
{
而(1)
{
cb=SSL_read(c->sslHandle,buffer+cbBuffer,sizeof(buffer)-1-cbBuffer);
if(cb-sslHandle);
错误打印错误fp(stderr);
返回SSL_write(c->sslHandle,text,strlen(text));
}
}
我正在smtp.gmail.com端口587上测试
谢谢
< p>您可能想考虑使用Scott Gifford的<代码> SSLCubule<代码>(参见).sslclient将生成您的程序并打开到服务器的tcp连接,将您的程序的stdout传输到服务器,并将输出从服务器传输到您的程序的stdin。他有一个TLS的分叉版本,该版本将以纯文本启动连接,然后一旦双方同意STARTTLS,您的程序就可以向sslcient发送信号o为此目的,通过向文件描述符写入命令来启用连接上的SSL加密(请参阅)。通过这种方式,您可以使用sslclient完成所有繁重的工作,如设置套接字和SSL等,并且您可以专注于程序的核心功能typedef struct {
int socket;
SSL *sslHandle;
SSL_CTX *sslContext;
} SSLConnection;
SSLConnection* wrapSslSocket(SOCKET hSocket)
{
SSLConnection *c;
c = (SSLConnection *)malloc (sizeof (SSLConnection));
c->sslHandle = NULL;
c->sslContext = NULL;
c->socket = hSocket;
if (c->socket)
{
// Register the error strings for libcrypto & libssl
SSL_load_error_strings ();
// Register the available ciphers and digests
SSL_library_init ();
c->sslContext = SSL_CTX_new (SSLv23_client_method ()); //I tried SSLv23, SSLv3, SSLv2, TLSv1.2 TLSv1.1, TLSv1.0
if (c->sslContext == NULL)
ERR_print_errors_fp (stderr);
// Create an SSL struct for the connection
c->sslHandle = SSL_new (c->sslContext);
if (c->sslHandle == NULL)
ERR_print_errors_fp (stderr);
// Connect the SSL struct to our connection
if (!SSL_set_fd (c->sslHandle, c->socket))
ERR_print_errors_fp (stderr);
if (!SSL_set_mode(c->sslHandle, SSL_MODE_AUTO_RETRY))
ERR_print_errors_fp (stderr);
// Initiate SSL handshake
if (SSL_connect (c->sslHandle) != 1)
ERR_print_errors_fp (stderr);
}
return c;
}
// Read all available text from the connection
int sslRead (SSLConnection *c)
{
const int readSize = 1024;
char buffer[1024];
int cb;
int cbBuffer = 0;
if (c)
{
while (1)
{
cb = SSL_read( c->sslHandle, buffer + cbBuffer, sizeof(buffer) - 1 - cbBuffer);
if( cb <= 0 )
{
ERR_print_errors_fp (stderr);
return -1;
}
cbBuffer += cb;
if( memcmp( buffer + cbBuffer - 2, "\r\n", 2 ) == 0 )
{
buffer[cbBuffer] = '\0';
break;
}
}
}
printf("ssl send : %s \n",buffer);
char status[3];
memcpy(status,buffer, 3*sizeof(char));
status[3] = '\0';
return atoi(status);
}
// Write text to the connection
int sslWrite (SSLConnection *c, char *text)
{
if (c)
{
int v = SSL_do_handshake(c->sslHandle);
ERR_print_errors_fp (stderr);
return SSL_write (c->sslHandle, text, strlen (text));
}
}