新书推介:《语义网技术体系》
作者:瞿裕忠,胡伟,程龚
   XML论坛     W3CHINA.ORG讨论区     计算机科学论坛     SOAChina论坛     Blog     开放翻译计划     新浪微博  
 
  • 首页
  • 登录
  • 注册
  • 软件下载
  • 资料下载
  • 核心成员
  • 帮助
  •   Add to Google

    >> 本版讨论高级C/C++编程、代码重构(Refactoring)、极限编程(XP)、泛型编程等话题
    [返回] 中文XML论坛 - 专业的XML技术讨论区计算机技术与应用『 C/C++编程思想 』 → 用BCB开发有身份认证功能的Email程序 查看新帖用户列表

      发表一个新主题  发表一个新投票  回复主题  (订阅本版) 您是本帖的第 4895 个阅读者浏览上一篇主题  刷新本主题   树形显示贴子 浏览下一篇主题
     * 贴子主题: 用BCB开发有身份认证功能的Email程序 举报  打印  推荐  IE收藏夹 
       本主题类别:     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客楼主
    发贴心情 用BCB开发有身份认证功能的Email程序

    引言

      为了更有效地抑制垃圾邮件的泛滥,目前多数网站的邮件收发系统都使用了ESMTP服务的身份认证功能。即用户发送邮件时,需要对用户的身份进行验证,如果帐号或密码错误,邮件服务器会拒绝发送邮件。Borland C++ Builder 6中有丰富的控件供开发者使用,其中当然也包括邮件发送控件NMSMTP,这个控件使用方便,但是惟一的缺点是不支持邮件发送时的身份认证功能。笔者通过对邮件发送协议的分析,在使用控件的基础上设计了具有身份认证功能的邮件发送程序。

      ESMTP协议分析

      为了实现身份认证功能,目前ESMTP协议中增加了一部分内容,这就是身份认证。下面我们看看这段认证过程,以笔者在网易的邮箱为例(其中C表示客户端,S表示邮件服务器):

      (1)C: AUTH LOGIN

      (2)S: 334 dXNlcm5hbWU6

      (3)C: d3lxX2puX3NkX2Nu

      (4)S: 334 UGFzc3dvcmQ6

      (5)C: 密码略去

      (6)S: 235 Authentication successful

      详细说明:

      (1)客户端向服务器发送认证指令。

      (2)服务器返回Base64编码串,334意味成功。编码字符串解码后为"username:",说明要求客户端发送用户名。

      (3)客户端发送Base64编码的用户名串,此处为"wyq_jn_sd_cn"。

      (4)服务器返回Base64编码串,334意味成功。编码字符串解码后为"password:",说明要求客户端发送用户口令。

      (5)客户端发送Base64编码的口令串,此处略去。

      (6)服务器返回普通字符串,235意味成功,表示认证成功可以发送邮件了。

      MIME Base64编码解释

      一般的计算机编码的一个字节是8bit,0——FF就是256种不同的8bit组合。我们现在要介绍的这种Base64编码则是每个字节6bit,共有26=64种组合。其中每种组合对应一个字符,这些字符是“ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz01234567 89+/。”这就意味着每3个普通编码可以转换成4个Base64编码,那么如果需要转换的普通编码不是3的整数倍怎么办?Base64规定,位数不足的字节后面补0,然后差几个字符补几个‘=’号。

      设计思路

      我们可以使用NMSMTP控件与邮件服务器连接。通过调用Connect方法,然后监听OnConnect事件;在OnConnect事件里我们可以增加身份认证功能。这里是主要利用了NMSMTP从Powersock中继承的一些基本网络通讯函数,包括Read,DataAvailable,SendBuffer等来实现身份认证过程。如果身份认证成功,就可以继续进行邮件发送;否则,提示错误信息,断开网络连接。

      程序实现

      使用BCB设计如图1所示的窗体。


    图1 程序主界面

      1、在登录按钮的OnClick事件中调用连接函数

    void __fastcall TForm1::Logon1Click(TObject *Sender)

    {

       AddLog("正在登录"+Edit1->Text+"......");

       NMSMTP1->Host = Edit1->Text;      //主机地址

       NMSMTP1->Port = 25;      //主机端口,缺省为25

       NMSMTP1->UserID = Edit4->Text;     //用户名

       NMSMTP1->Connect();      //连接主机

    }

       2、处理OnConnect事件

    void __fastcall TForm1::NMSMTP1Connect(TObject *Sender)

    {

     AddLog("连接服务器成功。");

     AnsiString Data="",rData="";

     bool b_ok;

     if(CheckBox1->Checked){

      Data="AUTH LOGIN\r\n";     //登录请求命令        

      NMSMTP1->SendBuffer(Data.c_str(),Data.Length()); //命令发出

      rData = WaitForReply(5);     //等待接收返回数据,5秒内必须返回

      b_ok = false;

      if(rData.Length()>=3){

       //334意味着服务器要求输入用户名

       if(rData.TrimLeft().SubString(0,3)=="334"){

        AddLog("正在验证身份......");

        b_ok =true;

       }

     }

     if(!b_ok){

      AddLog("登录失败,正在退出......");

      NMSMTP1->Disconnect();

      return;

     }

     rData="";

     Data=encode(Edit4->Text)+"\r\n";   //用户名转换为Base64编码。

     NMSMTP1->SendBuffer(Data.c_str(),Data.Length()); //发送用户名

     rData = WaitForReply(5);

     b_ok=false;

     if(rData.Length()>=3){

      // 334意味着服务器要求输入口令

      if(rData.TrimLeft().SubString(0,3)=="334"){

       AddLog("正在验证口令......");

       b_ok =true;

      }

     }


       收藏   分享  
    顶(0)
      




    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2008/10/24 8:48:00
     
     卷积内核 帅哥哟,离线,有人找我吗?
      
      
      威望:8
      头衔:总统
      等级:博士二年级(版主)
      文章:3942
      积分:27590
      门派:XML.ORG.CN
      注册:2004/7/21

    姓名:(无权查看)
    城市:(无权查看)
    院校:(无权查看)
    给卷积内核发送一个短消息 把卷积内核加入好友 查看卷积内核的个人资料 搜索卷积内核在『 C/C++编程思想 』的所有贴子 访问卷积内核的主页 引用回复这个贴子 回复这个贴子 查看卷积内核的博客2
    发贴心情 
    if(!b_ok){

      AddLog("登录失败,正在退出......");

      NMSMTP1->Disconnect();

      return;

     }

     rData="";

     Data=encode(Edit5->Text)+"\r\n";//口令转换成Base64编码。

     NMSMTP1->SendBuffer(Data.c_str(),Data.Length()); //发送口令

     rData=WaitForReply(5);

     b_ok = false;

     if(rData.Length()>=3){

      if(rData.TrimLeft().SubString(0,3)=="235"){

       AddLog("登录成功......");

       b_ok =true;

      }

     }

     if(!b_ok){

      AddLog("登录失败,正在退出......");

      NMSMTP1->Disconnect();

      return;

     }

    }

    SendMail->Enabled=true;      //允许发送邮件

    disconnect->Enabled=true;   //允许断开连接

    Logon1->Enabled=false;      //不允许再次登录

    }

      3、MIME Base64编码转换

    AnsiString TForm1::encode(AnsiString s)

    {

     int m_len; //字符串长度

     int i; //循环变量

     int m_tmp; //临时变量

     AnsiString m_64code; //储存Base64编码的字符串

     char* m_s; //临时存储参数字符串
     
     //Base64字符表

     char m_64[]= "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

     m_len = s.Length();     //取得字符串长度

     m_s = s.c_str();      

     m_64code="";         //返回串置空

     //处理3的倍数以内的字符

     for(i=0;i<m_len-m_len%3;i+=3){

      m_tmp=m_s[i]/4;

      m_64code+=m_64[m_tmp];

      m_tmp=m_s[i]%4*16 + m_s[i+1]/16;

      m_64code+=m_64[m_tmp];

      m_tmp=m_s[i+1]%16*4 + m_s[i+2]/64;

      m_64code+=m_64[m_tmp];

      m_tmp=m_s[i+2]%64;

      m_64code+=m_64[m_tmp];

     }

     //如果字符串的长度被3除余2 ,不足的位数补0,尾部补“=”

     if(m_len%3==2){
     
      m_tmp=m_s[m_len-2]/4;

      m_64code+=m_64[m_tmp];

      m_tmp=m_s[m_len-2]%4*16+m_s[m_len-1]/16;

      m_64code+=m_64[m_tmp];

      m_tmp=m_s[m_len-1]%16*4;

      m_64code+=m_64[m_tmp];

      m_64code+='=';

     }

     //如果字符串的长度被3除余1 ,不足的位数补0,尾部补两个“=”

     if(m_len%3==1){

      m_tmp=m_s[m_len-1]/4;

      m_64code+=m_64[m_tmp];

      m_tmp=m_s[m_len-1]%4*16;

      m_64code+=m_64[m_tmp];

      m_64code+="==";

     }

     return m_64code;

    }


      结束语

      本程序在Windows 2000环境下使用Borland C++ Builder 6.0编写及调试的,分别使用网易和新浪邮箱做实验,都可以顺利完成身份认证以及邮件发送功能。

    ----------------------------------------------
    事业是国家的,荣誉是单位的,成绩是领导的,工资是老婆的,财产是孩子的,错误是自己的。

    点击查看用户来源及管理<br>发贴IP:*.*.*.* 2008/10/24 8:49:00
     
     GoogleAdSense
      
      
      等级:大一新生
      文章:1
      积分:50
      门派:无门无派
      院校:未填写
      注册:2007-01-01
    给Google AdSense发送一个短消息 把Google AdSense加入好友 查看Google AdSense的个人资料 搜索Google AdSense在『 C/C++编程思想 』的所有贴子 访问Google AdSense的主页 引用回复这个贴子 回复这个贴子 查看Google AdSense的博客广告
    2024/4/30 2:57:35

    本主题贴数2,分页: [1]

    管理选项修改tag | 锁定 | 解锁 | 提升 | 删除 | 移动 | 固顶 | 总固顶 | 奖励 | 惩罚 | 发布公告
    W3C Contributing Supporter! W 3 C h i n a ( since 2003 ) 旗 下 站 点
    苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
    8,042.969ms