smtp中使用SSL与starttls的问题

snowboy1124 2009-04-12 08:53:23
开发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就不可以,是我少做了什么还是什么原因?
请帮忙,谢谢!
...全文
7798 12 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
12 条回复
切换为时间正序
请发表友善的回复…
发表回复
liao19795 2011-07-03
  • 打赏
  • 举报
回复
找到一套提供SMTP STARTTLS以及SMTP PORT465 (SSL CONNECT)的MAIL SERVER軟件
可提供需要的人測試

EVO mail server
eagerle01 2009-07-30
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 blackcat242 的回复:]
up一个
学习一下
[/Quote]
mmx369 2009-07-30
  • 打赏
  • 举报
回复

mark
ckt 2009-07-29
  • 打赏
  • 举报
回复
刚好也在做这个东西,应该是你初始化或是链接的地方不对吧.
你可以加我msn:ckt1120@hotmail.com
ahao 2009-07-29
  • 打赏
  • 举报
回复
你发送starttls后用新的socket重新连接了?
vkill 2009-07-28
  • 打赏
  • 举报
回复
http://blog.vkill.net/read.php/138.htm
这个是ruby的,参考下
jian_tian_yang 2009-06-02
  • 打赏
  • 举报
回复
学习
wuhuwy 2009-06-01
  • 打赏
  • 举报
回复
MARK,学习!
blackcat242 2009-04-24
  • 打赏
  • 举报
回复
up一个
学习一下
僵哥 2009-04-13
  • 打赏
  • 举报
回复
[Quote=引用楼主 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…
[/Quote]
google官网上写的是pop只需要ssl,默认情况下一般使用的是sslv23,这个是可以通过的
而smtp则要求使用tls,所以如果的ssl选项当中使用的还是sslv23就无法成功了,如果没有特别的话,应该是只需要修改ssl选项即可。
ok1234567 2009-04-13
  • 打赏
  • 举报
回复
如下代码供你参考,其中的有一些常量定义和类变量及编码函数,可以通过命名识别,凑合着看,应该由你需要的东东

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;

}
zhoujianhei 2009-04-12
  • 打赏
  • 举报
回复
使用OPENSSL直接连接。

18,357

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 网络编程
c++c语言开发语言 技术论坛(原bbs)
社区管理员
  • 网络编程
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧