登录 用户中心() [退出] 后台管理 注册
   
您的位置: 首页 >> SoftHub关联区 >> 主题: smtp中使用SSL与starttls的问题[zt]     [回主站]     [分站链接]
smtp中使用SSL与starttls的问题[zt]
clq
浏览(275) - 2018-03-23 15:59:03 发表 编辑

关键字: openssl

smtp中使用SSL与starttls的问题

https://bbs.csdn.net/topics/300191928

开发smtp的时候,有些网站需要SSL验证,有些网站需要STARTTLS验证。
我使用OPENSSL来进行SSL验证。但对于需要STARTTLS验证的,似乎总不能成功。
谁能给个使用OPENSSL进行STARTTLS验证的例子啊。

举例:
服务器:smtp.gmail.com
端口:587
要求STARTTLS ,
我的做法是,普通socket connect,然后发送 EHLO,然后STARTTLS,
然后使用OPENSSL按照普通SSL方式连接,失败!

但对于pop.gmail.com 995是可以使用SSL连接的。似乎OPENSSL的SSL连接
应该是可行的,但STARTTLS就不可以,是我少做了什么还是什么原因?
请帮忙,谢谢!


    
引用楼主 snowboy1124 的帖子:

    开发smtp的时候,有些网站需要SSL验证,有些网站需要STARTTLS验证。
    我使用OPENSSL来进行SSL验证。但对于需要STARTTLS验证的,似乎总不能成功。
    谁能给个使用OPENSSL进行STARTTLS验证的例子啊。

    举例:
    服务器:smtp.gmail.com
    端口:587
    要求STARTTLS ,
    我的做法是,普通socket connect,然后发送 EHLO,然后STARTTLS,
    然后使用OPENSSL按照普通SSL方式连接,失败!

    但对于pop.gmail.com 995是可以使用SSL…

google官网上写的是pop只需要ssl,默认情况下一般使用的是sslv23,这个是可以通过的
而smtp则要求使用tls,所以如果的ssl选项当中使用的还是sslv23就无法成功了,如果没有特别的话,应该是只需要修改ssl选项即可。

    
如下代码供你参考,其中的有一些常量定义和类变量及编码函数,可以通过命名识别,凑合着看,应该由你需要的东东

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;

}


回复于: 2009-07-30 11:00:45 #11

    
找到一套提供SMTP STARTTLS以及SMTP PORT465 (SSL CONNECT)的MAIL SERVER軟件
可提供需要的人測試

EVO mail server

    openfalcon mail provider with starttls (fastmail)




总数:0 页次:1/0 首页 尾页  
总数:0 页次:1/0 首页 尾页  


所在合集/目录



发表评论:
文本/html模式切换 插入图片 文本/html模式切换


附件:



NEWBT官方QQ群1: 276678893
可求档连环画,漫画;询问文本处理大师等软件使用技巧;求档softhub软件下载及使用技巧.
但不可"开车",严禁国家敏感话题,不可求档涉及版权的文档软件.
验证问题说明申请入群原因即可.

Copyright © 2005-2020 clq, All Rights Reserved
版权所有
桂ICP备15002303号-1