写smtp程序时如何实现安全认证

wanghainiu 2001-12-04 05:33:30
...全文
1157 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
wanghainiu 2001-12-11
  • 打赏
  • 举报
回复
给分了!! 谢谢!!!
hujun614 2001-12-07
  • 打赏
  • 举报
回复
hao hao hao
leoleevi 2001-12-07
  • 打赏
  • 举报
回复
下面这篇文章是我前段时间做验证的时候参考的一篇文章,写的比较详细了,用起来也没有问题。
当然前提是你需要有那个N多人用的CSMTP.CPP和CSMTP.H
把下文的身份验证部分加到CSMTP.CPP中再稍微调试一下就OK了。自己琢磨一下,更有成就感。


本站原创:KKnD

相关资料:Simple Mail Transfer Protocol (SMTP) RFC2821(英文)

  有一段时间很多地方都在讨论如何写一个发送邮件的程序的问题,其实一个邮件发送程序
没有想象的那么难做,现在先简单讲一下怎样连接邮件服务器以及怎样做验证的过程。

  首先创建一个socket,接下来连接你想要连接的发件服务器,连接上之后发送helo命令,
该命令的语法是helo <你的域名|你的IP>,之后分析接收到的返回串,返回字符串的前三位
是状态码,helo命令如果返回250就可以继续,否则就是有错误。接下来发送auth login命
令,如果返回码不是334,那么就是不需要验证,否则,注意!要将你的用户名和密码用
BASE64编码算法编码后分别发送过去,而不是直接发送。如果服务器返回状态码235就是验证
通过,不然就是用户名/密码有错误。下面是我连接smtp.263.net的过程(s:服务器 c:客户
端):

s:220 smtp.263.net ESMTP
c:HELO mylocalhost
s:250 smtp.263.net
c:auth login
s:334 VXNlcm5hbWU6
c://我的用户名(已编码)
s:334 UGFzc3dvcmQ6
c://我的密码(已编码)
s:235 Authentication successful

源代码:
[连接]
BOOL CSmtp::Connect()
{
CString sHello;
TCHAR local_host[80]; // Warning: arbitrary size
if(m_bConnected) return TRUE;

try {
// This will be deleted in Disconnect();
response_buf = new TCHAR[RESPONSE_BUFFER_SIZE];
if(response_buf == NULL) {
m_sError = _T("Not enough memory");
return FALSE;
}
} catch(CException* e) {
response_buf = NULL;
m_sError = _T("Not enough memory");
delete e;
return FALSE;
}

if(!m_wsSMTPServer.Create()) {
m_sError = _T("Unable to create the socket");
delete response_buf;
response_buf = NULL;
return FALSE;
}
if( !m_wsSMTPServer.Connect(m_sSMTPServerHostName, m_nPort)) {
m_sError = _T("Unable to connect to server");
m_wsSMTPServer.Close();
delete response_buf;
response_buf = NULL;
return FALSE;
}
if(!get_response(CONNECT_SUCCESS)) {
m_sError = _T( "Server didn’t respond" );
m_wsSMTPServer.Close();
delete response_buf;
response_buf = NULL;
return FALSE;
}
gethostname(local_host, 80);
sHello.Format(_T( "HELO %s\r\n" ), local_host);
m_wsSMTPServer.Send((LPCTSTR)sHello, sHello.GetLength());
if(!get_response(GENERIC_SUCCESS)) {
m_wsSMTPServer.Close();
delete response_buf;
response_buf = NULL;
return FALSE;
}
m_bConnected = TRUE;
return TRUE;
}

[验证]
BOOL CSmtp::Auth()
{
CString sAuth;
if(!m_bConnected) return FALSE;

sAuth.Format(_T( "auth login\r\n" )); //construct auth quest
m_wsSMTPServer.Send((LPCTSTR)sAuth, sAuth.GetLength());
if(!get_response(AUTHQUE_SUCCESS)) {
m_sError="SMTP server with no auth";
m_bAuthed=TRUE;
return TRUE;
}

sAuth.Empty();

sAuth.Format(_T( "%s\r\n" ), m_sSMTPUser); //is an string encoded with CBASE64
m_wsSMTPServer.Send((LPCTSTR)sAuth, sAuth.GetLength());
if(!get_response(AUTHQUE_SUCCESS)) {
m_sError="Unknown Error";
m_wsSMTPServer.Close();
delete response_buf;
response_buf = NULL;
return FALSE;
}

sAuth.Empty();

sAuth.Format(_T( "%s\r\n" ), m_sSMTPPass); //is an string encoded with CBASE64
m_wsSMTPServer.Send((LPCTSTR)sAuth, sAuth.GetLength());
if(!get_response(AUTH_SUCCESS)) {
m_wsSMTPServer.Close();
delete response_buf;
response_buf = NULL;
return FALSE;
}
m_bAuthed = TRUE;
return TRUE;
}


当上面的过程完成后,就完成了连接和验证的工作,可以开始准备发送邮件了。首先要使用的
是MAIL FROM:命令,格式"MAIL FROM: <发件人地址>",正常的返回码是250;这里要说的是有时上述命令会返回一个错误:553 Authentication is required to send mail as
xxx@xxx.xxx。出现这样的错误的原因是MAIL FROM发送过去的发件人地址里面包含的用户名
和你登陆发件服务器时使用的用户名不同,只需将二者统一就行了。接下来是RCPT TO:命令,
告诉服务器你想发给谁,格式和返回码同MAIL FROM。然后是DATA命令,没有参数,返回码
354;该命令送到之后就可以发送信件的内容了,内容结束的标志是<CRLF>.<CRLF>,用字符
串表示就是"\r\n.\r\n"。最后退出服务器的命令是QUIT,无参数,返回码221。

c:MAIL FROM: coolkknd@263.net
s:250 smtp.263.net
c:RCPT TO: acesee.263.net
s:250 smtp.263.net
c:DATA
s:354 Start mail input; end with .
c://信件正文
 。。。。。。
c:<CRLF>.<CRLF>//正文结束
s:250 smtp.263.net
c:QUIT
s:221 Bye

  源代码我就不在这里写了,太多了,请点击此处或到VC版下载仓库下载吧。

fhu113 2001-12-06
  • 打赏
  • 举报
回复
关注
wanghainiu 2001-12-06
  • 打赏
  • 举报
回复
please 高手指点
wanghainiu 2001-12-06
  • 打赏
  • 举报
回复
please 高手指点
shalala 2001-12-04
  • 打赏
  • 举报
回复
我也在写POP和SMTP。。
关注
wanghainiu 2001-12-04
  • 打赏
  • 举报
回复
用代码实现,说出原理也行
xinghf 2001-12-04
  • 打赏
  • 举报
回复
没有现成的工具

16,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

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