我使用OPENSSL来进行SSL验证。但对于需要STARTTLS验证的,似乎总不能成功。
谁能给个使用OPENSSL进行STARTTLS验证的例子啊。
举例:
服务器:smtp.gmail.com
端口:587
要求STARTTLS ,
我的做法是,普通socket connect,然后发送 EHLO,然后STARTTLS,
然后使用OPENSSL按照普通SSL方式连接,失败!
但对于pop.gmail.com 995是可以使用SSL连接的。似乎OPENSSL的SSL连接
应该是可行的,但STARTTLS就不可以,是我少做了什么还是什么原因?
请帮忙,谢谢!
12 个解决方案
#1
使用OPENSSL直接连接。
#2
google官网上写的是pop只需要ssl,默认情况下一般使用的是sslv23,这个是可以通过的
而smtp则要求使用tls,所以如果的ssl选项当中使用的还是sslv23就无法成功了,如果没有特别的话,应该是只需要修改ssl选项即可。
#3
如下代码供你参考,其中的有一些常量定义和类变量及编码函数,可以通过命名识别,凑合着看,应该由你需要的东东
int CSmtp::TestSSL()
{
//-- 初始化 --SSL--
int err=-1;
//char* str;
SSL_CTX* ctx;
SSL* ssl;
//X509* server_cert;
SSL_METHOD *meth;
SSLeay_add_ssl_algorithms();
meth = SSLv2_client_method();
SSL_load_error_strings();
ctx = SSL_CTX_new (meth);
if(ctx == NULL)
{
SetLastError(ME_SSL);
return -20;
}
char *p,*b;
//--
sockaddr_in sin;
int sock = socket (AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
{
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_CREATE);
return -1;
}
sin.sin_family = AF_INET;
sin.sin_port = htons( (unsigned short)m_iPort);
struct hostent * host_addr = gethostbyname(m_szHost);
if(host_addr==NULL)
{
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_HOST);
return -4;
}
sin.sin_addr.s_addr = *((int*)*host_addr->h_addr_list) ;
//******************************
int TimeOut=50000;
if(::setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
closesocket(sock);
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_OPT);
return -5;
}
if(::setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
closesocket(sock);
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_OPT);
return -5;
}
//设置非阻塞方式连接
unsigned long ul = 1;
int ret = ioctlsocket(sock, FIONBIO, (unsigned long*)&ul);
if(ret==SOCKET_ERROR)
{
closesocket(sock);
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_OPT);
return -5;
}
//连接
connect (sock,(const struct sockaddr *)&sin, sizeof(sockaddr_in) );//MAY ERROR
struct timeval timeout ;
fd_set r;
FD_ZERO(&r);
FD_SET(sock, &r);
timeout.tv_sec = SSL_CNT_TIMEOUT;
timeout.tv_usec =0;
ret = select(0, 0, &r, 0, &timeout);
if ( ret <= 0 )
{
::closesocket(sock);
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_OPT);
return -5;
}
unsigned long ul1= 0 ;
ret = ioctlsocket(sock, FIONBIO, (unsigned long*)&ul1);
if(ret==SOCKET_ERROR)
{
::closesocket (sock);
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_OPT);
return -5;
}
//----
unsigned int iLen=0;
char sz[512]={0};
char * pszPut;
int iBufLen=m_nDataLen*2+1024;
try
{
pszPut =new char[iBufLen];
}
catch(CException * e)
{
e->Delete();
::closesocket (sock);
SSL_CTX_free (ctx);
SetLastError(ME_MOMERY);
return -7;
}
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(recv(sock,p,1,0) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
if(iLen < 1)
{
SetLastError(ME_SOCK_CONNECT);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -6;
}
if(atoi(b) != 220)
{
SetLastError(ME_SOCK_CONNECT);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -100;
}
//-----
//握手信号;
strcpy(sz,"EHLO BigLee\r\n");
iLen=send(sock,sz,strlen(sz),0);
if(iLen == SOCKET_ERROR)
{
SetLastError(ME_HELLO);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -8;
}
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(recv(sock,p,1,0) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
if(iLen < 1)
{
SetLastError(ME_HELLO);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -8;
}
if(atoi(b) != 250)
{
SetLastError(ME_HELLO);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -100;
}
//***************
//握手信号;
strcpy(sz,"STARTTLS\r\n");
iLen=send(sock,sz,strlen(sz),0);
if(iLen == SOCKET_ERROR)
{
SetLastError(ME_HELLO);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -8;
}
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(recv(sock,p,1,0) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
if(iLen < 1)
{
SetLastError(ME_HELLO);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -8;
}
if(atoi(b) != 220)
{
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
SetLastError(ME_HELLO);
return -8;
}
//************************
ssl = SSL_new (ctx);
if(ssl == NULL)
{
SetLastError(ME_SSL);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -20;
}
SSL_set_fd (ssl, sock);
err = SSL_connect (ssl);
if(err == -1)
{
SetLastError(ME_SSL);
goto Error;
}
//--auth
strcpy(sz,"AUTH LOGIN\r\n");
err = SSL_write (ssl, sz,strlen(sz));
if(err == -1)
{
SetLastError(ME_AUTH);
goto Error;
}
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(SSL_read (ssl, p,1) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
if(iLen < 1)
{
SetLastError(ME_AUTH);
goto Error;
}
if(atoi(b) != 334)
{
SetLastError(ME_AUTH);
goto Error;
}
//account
strcpy(sz,m_szAc);
memset(pszPut,'\0',iBufLen);
CXMail::Base64Encode(sz,strlen(sz),pszPut,iBufLen,&iLen,0);
strcat(pszPut,"\r\n");
err = SSL_write (ssl, pszPut,strlen(pszPut));
if(err == -1)
{
SetLastError(ME_AUTH_AC);
goto Error;
}
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(SSL_read (ssl, p,1) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
if(iLen < 1)
{
SetLastError(ME_AUTH_AC);
goto Error;
}
if(atoi(b) != 334)
{
SetLastError(ME_AUTH_AC);
goto Error;
}
//password
strcpy(sz,m_szPwd);
memset(pszPut,'\0',256);
CXMail::Base64Encode(sz,strlen(sz),pszPut,256,&iLen,0);
strcat(pszPut,"\r\n");
err = SSL_write (ssl, pszPut,strlen(pszPut));
if(err == -1)
{
SetLastError(ME_AUTH_PWD);
goto Error;
}
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(SSL_read (ssl, p,1) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
if(iLen < 1)
{
SetLastError(ME_AUTH_PWD);
goto Error;
}
if(atoi(b) != 235)
{
SetLastError(ME_AUTH_PWD);
goto Error;
}
//-- END OF AUTH --
strcpy(sz,"QUIT\r\n");
SSL_write (ssl, sz,strlen(sz));
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(SSL_read (ssl, p,1) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
delete pszPut;
SSL_shutdown (ssl);
closesocket(sock);
SSL_free (ssl);
SSL_CTX_free (ctx);
SetLastError("邮箱测试连接成功。",0);
m_bTestOk = TRUE;
return 0;
Error:
delete pszPut;
SSL_shutdown (ssl);
closesocket(sock);
SSL_free (ssl);
SSL_CTX_free (ctx);
return -100;
}
int CSmtp::TestSSL()
{
//-- 初始化 --SSL--
int err=-1;
//char* str;
SSL_CTX* ctx;
SSL* ssl;
//X509* server_cert;
SSL_METHOD *meth;
SSLeay_add_ssl_algorithms();
meth = SSLv2_client_method();
SSL_load_error_strings();
ctx = SSL_CTX_new (meth);
if(ctx == NULL)
{
SetLastError(ME_SSL);
return -20;
}
char *p,*b;
//--
sockaddr_in sin;
int sock = socket (AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
{
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_CREATE);
return -1;
}
sin.sin_family = AF_INET;
sin.sin_port = htons( (unsigned short)m_iPort);
struct hostent * host_addr = gethostbyname(m_szHost);
if(host_addr==NULL)
{
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_HOST);
return -4;
}
sin.sin_addr.s_addr = *((int*)*host_addr->h_addr_list) ;
//******************************
int TimeOut=50000;
if(::setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
closesocket(sock);
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_OPT);
return -5;
}
if(::setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
closesocket(sock);
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_OPT);
return -5;
}
//设置非阻塞方式连接
unsigned long ul = 1;
int ret = ioctlsocket(sock, FIONBIO, (unsigned long*)&ul);
if(ret==SOCKET_ERROR)
{
closesocket(sock);
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_OPT);
return -5;
}
//连接
connect (sock,(const struct sockaddr *)&sin, sizeof(sockaddr_in) );//MAY ERROR
struct timeval timeout ;
fd_set r;
FD_ZERO(&r);
FD_SET(sock, &r);
timeout.tv_sec = SSL_CNT_TIMEOUT;
timeout.tv_usec =0;
ret = select(0, 0, &r, 0, &timeout);
if ( ret <= 0 )
{
::closesocket(sock);
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_OPT);
return -5;
}
unsigned long ul1= 0 ;
ret = ioctlsocket(sock, FIONBIO, (unsigned long*)&ul1);
if(ret==SOCKET_ERROR)
{
::closesocket (sock);
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_OPT);
return -5;
}
//----
unsigned int iLen=0;
char sz[512]={0};
char * pszPut;
int iBufLen=m_nDataLen*2+1024;
try
{
pszPut =new char[iBufLen];
}
catch(CException * e)
{
e->Delete();
::closesocket (sock);
SSL_CTX_free (ctx);
SetLastError(ME_MOMERY);
return -7;
}
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(recv(sock,p,1,0) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
if(iLen < 1)
{
SetLastError(ME_SOCK_CONNECT);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -6;
}
if(atoi(b) != 220)
{
SetLastError(ME_SOCK_CONNECT);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -100;
}
//-----
//握手信号;
strcpy(sz,"EHLO BigLee\r\n");
iLen=send(sock,sz,strlen(sz),0);
if(iLen == SOCKET_ERROR)
{
SetLastError(ME_HELLO);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -8;
}
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(recv(sock,p,1,0) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
if(iLen < 1)
{
SetLastError(ME_HELLO);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -8;
}
if(atoi(b) != 250)
{
SetLastError(ME_HELLO);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -100;
}
//***************
//握手信号;
strcpy(sz,"STARTTLS\r\n");
iLen=send(sock,sz,strlen(sz),0);
if(iLen == SOCKET_ERROR)
{
SetLastError(ME_HELLO);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -8;
}
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(recv(sock,p,1,0) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
if(iLen < 1)
{
SetLastError(ME_HELLO);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -8;
}
if(atoi(b) != 220)
{
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
SetLastError(ME_HELLO);
return -8;
}
//************************
ssl = SSL_new (ctx);
if(ssl == NULL)
{
SetLastError(ME_SSL);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -20;
}
SSL_set_fd (ssl, sock);
err = SSL_connect (ssl);
if(err == -1)
{
SetLastError(ME_SSL);
goto Error;
}
//--auth
strcpy(sz,"AUTH LOGIN\r\n");
err = SSL_write (ssl, sz,strlen(sz));
if(err == -1)
{
SetLastError(ME_AUTH);
goto Error;
}
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(SSL_read (ssl, p,1) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
if(iLen < 1)
{
SetLastError(ME_AUTH);
goto Error;
}
if(atoi(b) != 334)
{
SetLastError(ME_AUTH);
goto Error;
}
//account
strcpy(sz,m_szAc);
memset(pszPut,'\0',iBufLen);
CXMail::Base64Encode(sz,strlen(sz),pszPut,iBufLen,&iLen,0);
strcat(pszPut,"\r\n");
err = SSL_write (ssl, pszPut,strlen(pszPut));
if(err == -1)
{
SetLastError(ME_AUTH_AC);
goto Error;
}
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(SSL_read (ssl, p,1) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
if(iLen < 1)
{
SetLastError(ME_AUTH_AC);
goto Error;
}
if(atoi(b) != 334)
{
SetLastError(ME_AUTH_AC);
goto Error;
}
//password
strcpy(sz,m_szPwd);
memset(pszPut,'\0',256);
CXMail::Base64Encode(sz,strlen(sz),pszPut,256,&iLen,0);
strcat(pszPut,"\r\n");
err = SSL_write (ssl, pszPut,strlen(pszPut));
if(err == -1)
{
SetLastError(ME_AUTH_PWD);
goto Error;
}
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(SSL_read (ssl, p,1) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
if(iLen < 1)
{
SetLastError(ME_AUTH_PWD);
goto Error;
}
if(atoi(b) != 235)
{
SetLastError(ME_AUTH_PWD);
goto Error;
}
//-- END OF AUTH --
strcpy(sz,"QUIT\r\n");
SSL_write (ssl, sz,strlen(sz));
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(SSL_read (ssl, p,1) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
delete pszPut;
SSL_shutdown (ssl);
closesocket(sock);
SSL_free (ssl);
SSL_CTX_free (ctx);
SetLastError("邮箱测试连接成功。",0);
m_bTestOk = TRUE;
return 0;
Error:
delete pszPut;
SSL_shutdown (ssl);
closesocket(sock);
SSL_free (ssl);
SSL_CTX_free (ctx);
return -100;
}
#4
up一个
学习一下
学习一下
#5
MARK,学习!
#6
学习
#7
http://blog.vkill.net/read.php/138.htm
这个是ruby的,参考下
这个是ruby的,参考下
#8
你发送starttls后用新的socket重新连接了?
#9
刚好也在做这个东西,应该是你初始化或是链接的地方不对吧.
你可以加我msn:ckt1120@hotmail.com
你可以加我msn:ckt1120@hotmail.com
#10
mark
#11
#1
使用OPENSSL直接连接。
#2
google官网上写的是pop只需要ssl,默认情况下一般使用的是sslv23,这个是可以通过的
而smtp则要求使用tls,所以如果的ssl选项当中使用的还是sslv23就无法成功了,如果没有特别的话,应该是只需要修改ssl选项即可。
#3
如下代码供你参考,其中的有一些常量定义和类变量及编码函数,可以通过命名识别,凑合着看,应该由你需要的东东
int CSmtp::TestSSL()
{
//-- 初始化 --SSL--
int err=-1;
//char* str;
SSL_CTX* ctx;
SSL* ssl;
//X509* server_cert;
SSL_METHOD *meth;
SSLeay_add_ssl_algorithms();
meth = SSLv2_client_method();
SSL_load_error_strings();
ctx = SSL_CTX_new (meth);
if(ctx == NULL)
{
SetLastError(ME_SSL);
return -20;
}
char *p,*b;
//--
sockaddr_in sin;
int sock = socket (AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
{
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_CREATE);
return -1;
}
sin.sin_family = AF_INET;
sin.sin_port = htons( (unsigned short)m_iPort);
struct hostent * host_addr = gethostbyname(m_szHost);
if(host_addr==NULL)
{
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_HOST);
return -4;
}
sin.sin_addr.s_addr = *((int*)*host_addr->h_addr_list) ;
//******************************
int TimeOut=50000;
if(::setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
closesocket(sock);
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_OPT);
return -5;
}
if(::setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
closesocket(sock);
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_OPT);
return -5;
}
//设置非阻塞方式连接
unsigned long ul = 1;
int ret = ioctlsocket(sock, FIONBIO, (unsigned long*)&ul);
if(ret==SOCKET_ERROR)
{
closesocket(sock);
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_OPT);
return -5;
}
//连接
connect (sock,(const struct sockaddr *)&sin, sizeof(sockaddr_in) );//MAY ERROR
struct timeval timeout ;
fd_set r;
FD_ZERO(&r);
FD_SET(sock, &r);
timeout.tv_sec = SSL_CNT_TIMEOUT;
timeout.tv_usec =0;
ret = select(0, 0, &r, 0, &timeout);
if ( ret <= 0 )
{
::closesocket(sock);
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_OPT);
return -5;
}
unsigned long ul1= 0 ;
ret = ioctlsocket(sock, FIONBIO, (unsigned long*)&ul1);
if(ret==SOCKET_ERROR)
{
::closesocket (sock);
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_OPT);
return -5;
}
//----
unsigned int iLen=0;
char sz[512]={0};
char * pszPut;
int iBufLen=m_nDataLen*2+1024;
try
{
pszPut =new char[iBufLen];
}
catch(CException * e)
{
e->Delete();
::closesocket (sock);
SSL_CTX_free (ctx);
SetLastError(ME_MOMERY);
return -7;
}
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(recv(sock,p,1,0) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
if(iLen < 1)
{
SetLastError(ME_SOCK_CONNECT);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -6;
}
if(atoi(b) != 220)
{
SetLastError(ME_SOCK_CONNECT);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -100;
}
//-----
//握手信号;
strcpy(sz,"EHLO BigLee\r\n");
iLen=send(sock,sz,strlen(sz),0);
if(iLen == SOCKET_ERROR)
{
SetLastError(ME_HELLO);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -8;
}
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(recv(sock,p,1,0) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
if(iLen < 1)
{
SetLastError(ME_HELLO);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -8;
}
if(atoi(b) != 250)
{
SetLastError(ME_HELLO);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -100;
}
//***************
//握手信号;
strcpy(sz,"STARTTLS\r\n");
iLen=send(sock,sz,strlen(sz),0);
if(iLen == SOCKET_ERROR)
{
SetLastError(ME_HELLO);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -8;
}
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(recv(sock,p,1,0) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
if(iLen < 1)
{
SetLastError(ME_HELLO);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -8;
}
if(atoi(b) != 220)
{
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
SetLastError(ME_HELLO);
return -8;
}
//************************
ssl = SSL_new (ctx);
if(ssl == NULL)
{
SetLastError(ME_SSL);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -20;
}
SSL_set_fd (ssl, sock);
err = SSL_connect (ssl);
if(err == -1)
{
SetLastError(ME_SSL);
goto Error;
}
//--auth
strcpy(sz,"AUTH LOGIN\r\n");
err = SSL_write (ssl, sz,strlen(sz));
if(err == -1)
{
SetLastError(ME_AUTH);
goto Error;
}
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(SSL_read (ssl, p,1) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
if(iLen < 1)
{
SetLastError(ME_AUTH);
goto Error;
}
if(atoi(b) != 334)
{
SetLastError(ME_AUTH);
goto Error;
}
//account
strcpy(sz,m_szAc);
memset(pszPut,'\0',iBufLen);
CXMail::Base64Encode(sz,strlen(sz),pszPut,iBufLen,&iLen,0);
strcat(pszPut,"\r\n");
err = SSL_write (ssl, pszPut,strlen(pszPut));
if(err == -1)
{
SetLastError(ME_AUTH_AC);
goto Error;
}
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(SSL_read (ssl, p,1) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
if(iLen < 1)
{
SetLastError(ME_AUTH_AC);
goto Error;
}
if(atoi(b) != 334)
{
SetLastError(ME_AUTH_AC);
goto Error;
}
//password
strcpy(sz,m_szPwd);
memset(pszPut,'\0',256);
CXMail::Base64Encode(sz,strlen(sz),pszPut,256,&iLen,0);
strcat(pszPut,"\r\n");
err = SSL_write (ssl, pszPut,strlen(pszPut));
if(err == -1)
{
SetLastError(ME_AUTH_PWD);
goto Error;
}
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(SSL_read (ssl, p,1) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
if(iLen < 1)
{
SetLastError(ME_AUTH_PWD);
goto Error;
}
if(atoi(b) != 235)
{
SetLastError(ME_AUTH_PWD);
goto Error;
}
//-- END OF AUTH --
strcpy(sz,"QUIT\r\n");
SSL_write (ssl, sz,strlen(sz));
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(SSL_read (ssl, p,1) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
delete pszPut;
SSL_shutdown (ssl);
closesocket(sock);
SSL_free (ssl);
SSL_CTX_free (ctx);
SetLastError("邮箱测试连接成功。",0);
m_bTestOk = TRUE;
return 0;
Error:
delete pszPut;
SSL_shutdown (ssl);
closesocket(sock);
SSL_free (ssl);
SSL_CTX_free (ctx);
return -100;
}
int CSmtp::TestSSL()
{
//-- 初始化 --SSL--
int err=-1;
//char* str;
SSL_CTX* ctx;
SSL* ssl;
//X509* server_cert;
SSL_METHOD *meth;
SSLeay_add_ssl_algorithms();
meth = SSLv2_client_method();
SSL_load_error_strings();
ctx = SSL_CTX_new (meth);
if(ctx == NULL)
{
SetLastError(ME_SSL);
return -20;
}
char *p,*b;
//--
sockaddr_in sin;
int sock = socket (AF_INET, SOCK_STREAM, 0);
if (sock == INVALID_SOCKET)
{
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_CREATE);
return -1;
}
sin.sin_family = AF_INET;
sin.sin_port = htons( (unsigned short)m_iPort);
struct hostent * host_addr = gethostbyname(m_szHost);
if(host_addr==NULL)
{
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_HOST);
return -4;
}
sin.sin_addr.s_addr = *((int*)*host_addr->h_addr_list) ;
//******************************
int TimeOut=50000;
if(::setsockopt(sock,SOL_SOCKET,SO_SNDTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
closesocket(sock);
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_OPT);
return -5;
}
if(::setsockopt(sock,SOL_SOCKET,SO_RCVTIMEO,(char *)&TimeOut,sizeof(TimeOut))==SOCKET_ERROR)
{
closesocket(sock);
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_OPT);
return -5;
}
//设置非阻塞方式连接
unsigned long ul = 1;
int ret = ioctlsocket(sock, FIONBIO, (unsigned long*)&ul);
if(ret==SOCKET_ERROR)
{
closesocket(sock);
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_OPT);
return -5;
}
//连接
connect (sock,(const struct sockaddr *)&sin, sizeof(sockaddr_in) );//MAY ERROR
struct timeval timeout ;
fd_set r;
FD_ZERO(&r);
FD_SET(sock, &r);
timeout.tv_sec = SSL_CNT_TIMEOUT;
timeout.tv_usec =0;
ret = select(0, 0, &r, 0, &timeout);
if ( ret <= 0 )
{
::closesocket(sock);
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_OPT);
return -5;
}
unsigned long ul1= 0 ;
ret = ioctlsocket(sock, FIONBIO, (unsigned long*)&ul1);
if(ret==SOCKET_ERROR)
{
::closesocket (sock);
SSL_CTX_free (ctx);
SetLastError(ME_SOCK_OPT);
return -5;
}
//----
unsigned int iLen=0;
char sz[512]={0};
char * pszPut;
int iBufLen=m_nDataLen*2+1024;
try
{
pszPut =new char[iBufLen];
}
catch(CException * e)
{
e->Delete();
::closesocket (sock);
SSL_CTX_free (ctx);
SetLastError(ME_MOMERY);
return -7;
}
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(recv(sock,p,1,0) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
if(iLen < 1)
{
SetLastError(ME_SOCK_CONNECT);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -6;
}
if(atoi(b) != 220)
{
SetLastError(ME_SOCK_CONNECT);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -100;
}
//-----
//握手信号;
strcpy(sz,"EHLO BigLee\r\n");
iLen=send(sock,sz,strlen(sz),0);
if(iLen == SOCKET_ERROR)
{
SetLastError(ME_HELLO);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -8;
}
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(recv(sock,p,1,0) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
if(iLen < 1)
{
SetLastError(ME_HELLO);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -8;
}
if(atoi(b) != 250)
{
SetLastError(ME_HELLO);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -100;
}
//***************
//握手信号;
strcpy(sz,"STARTTLS\r\n");
iLen=send(sock,sz,strlen(sz),0);
if(iLen == SOCKET_ERROR)
{
SetLastError(ME_HELLO);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -8;
}
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(recv(sock,p,1,0) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
if(iLen < 1)
{
SetLastError(ME_HELLO);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -8;
}
if(atoi(b) != 220)
{
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
SetLastError(ME_HELLO);
return -8;
}
//************************
ssl = SSL_new (ctx);
if(ssl == NULL)
{
SetLastError(ME_SSL);
delete pszPut;
::closesocket (sock);
SSL_CTX_free (ctx);
return -20;
}
SSL_set_fd (ssl, sock);
err = SSL_connect (ssl);
if(err == -1)
{
SetLastError(ME_SSL);
goto Error;
}
//--auth
strcpy(sz,"AUTH LOGIN\r\n");
err = SSL_write (ssl, sz,strlen(sz));
if(err == -1)
{
SetLastError(ME_AUTH);
goto Error;
}
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(SSL_read (ssl, p,1) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
if(iLen < 1)
{
SetLastError(ME_AUTH);
goto Error;
}
if(atoi(b) != 334)
{
SetLastError(ME_AUTH);
goto Error;
}
//account
strcpy(sz,m_szAc);
memset(pszPut,'\0',iBufLen);
CXMail::Base64Encode(sz,strlen(sz),pszPut,iBufLen,&iLen,0);
strcat(pszPut,"\r\n");
err = SSL_write (ssl, pszPut,strlen(pszPut));
if(err == -1)
{
SetLastError(ME_AUTH_AC);
goto Error;
}
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(SSL_read (ssl, p,1) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
if(iLen < 1)
{
SetLastError(ME_AUTH_AC);
goto Error;
}
if(atoi(b) != 334)
{
SetLastError(ME_AUTH_AC);
goto Error;
}
//password
strcpy(sz,m_szPwd);
memset(pszPut,'\0',256);
CXMail::Base64Encode(sz,strlen(sz),pszPut,256,&iLen,0);
strcat(pszPut,"\r\n");
err = SSL_write (ssl, pszPut,strlen(pszPut));
if(err == -1)
{
SetLastError(ME_AUTH_PWD);
goto Error;
}
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(SSL_read (ssl, p,1) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
if(iLen < 1)
{
SetLastError(ME_AUTH_PWD);
goto Error;
}
if(atoi(b) != 235)
{
SetLastError(ME_AUTH_PWD);
goto Error;
}
//-- END OF AUTH --
strcpy(sz,"QUIT\r\n");
SSL_write (ssl, sz,strlen(sz));
p = m_sz;
iLen = 0;
memset(p,'\0',MAX_MAIL_GET_LEN);
b = p;
while(SSL_read (ssl, p,1) > 0)
{
if((iLen++) >= MAX_MAIL_GET_LEN) break;
if(*p == 10)
{
if(b[3] == ' ') break;
b = p+1;
}
p++;
}
delete pszPut;
SSL_shutdown (ssl);
closesocket(sock);
SSL_free (ssl);
SSL_CTX_free (ctx);
SetLastError("邮箱测试连接成功。",0);
m_bTestOk = TRUE;
return 0;
Error:
delete pszPut;
SSL_shutdown (ssl);
closesocket(sock);
SSL_free (ssl);
SSL_CTX_free (ctx);
return -100;
}
#4
up一个
学习一下
学习一下
#5
MARK,学习!
#6
学习
#7
http://blog.vkill.net/read.php/138.htm
这个是ruby的,参考下
这个是ruby的,参考下
#8
你发送starttls后用新的socket重新连接了?
#9
刚好也在做这个东西,应该是你初始化或是链接的地方不对吧.
你可以加我msn:ckt1120@hotmail.com
你可以加我msn:ckt1120@hotmail.com
#10
mark