C++使用Socket 邮箱登录服务器验证

转载:http://blog.csdn.net/zengraoli/article/details/36866241

转载:http://blog.csdn.net/alger_magic/article/details/25164187

一、如果想单纯验证一个邮箱帐号是否存在,我们可以拿邮箱帐号和密码请求服务器验证。

.h文件

#ifndef _AUTHENTICATIONEMAIL_H_
#define _AUTHENTICATIONEMAIL_H_

#include <atlenc.h>
#include <winsock2.h>

#pragma comment(lib, "wsock32.lib")

struct sMailInfo                    //邮件信息
{
    char *mailbox_user_name;        //用户登录邮箱的名称
    char *mailbox_user_pwd;            //用户登录邮箱的密码
    char *mailbox_sender_show_name;    //用户发送时显示的名称
    char *mailbox_sender;            //发送者的邮箱地址
    char *mailbox_receiver;            //接收者的邮箱地址
    char mail_server_ip_addr[32];    //服务器的IP
    char *mail_server_name;            //服务器的名称(IP与名称二选一,优先取名称)
    sMailInfo() { memset(this, 0, sizeof(sMailInfo)); }
};

class CAuthentic
{
public:
    CAuthentic();

    ~CAuthentic();

    void Char2Base64(char *buff_64, char *src_buff, int length);//把char类型转换成Base64类型

    bool CReateSocket(SOCKET &sock);            //建立socket连接

    bool Login(SOCKET &sock);                    //登录邮箱,主要进行发邮件前的准备工作

    void Init(sMailInfo &smail_info);

protected:
    char  send_buff_[4096];                        //发送缓冲区
    char  receive_buff_[1024];
    sMailInfo mail_info_;
};

.cpp文件

#include "AuthenticationEmail.h"
#pragma warning(disable:4996)

CAuthentic::CAuthentic()
{
    memset(send_buff_, 0, sizeof(send_buff_));
    memset(receive_buff_, 0, sizeof(receive_buff_));
}

CAuthentic::~CAuthentic()
{

}

void CAuthentic::Char2Base64(char *buff_64, char *src_buff, int length)
{
    //1   1   1   1   1   1   1   1
    // 分配给pBuff64  ↑ 分配给pBuff64+1
    // point所在的位置
    static char base_64_encode[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";//base64所映射的字符表
    int point;        // 每一个源字符拆分的位置,可取2,4,6;初始为2
    point = 2;
    int base_index; // base64字符的索引
    char n = 0;        // 上一个源字符的残留值
    for(int index = 0; index < length; index++)
    {
        if(point == 2)
        {
            base_index = ((*src_buff) >> point) & 0x3f; // 取得pSrcBuff的高point位
        }
        else if (point == 4)
        {
            base_index = ((*src_buff) >> point) & 0xf;    // 取得pSrcBuff的高point位
        }
        else if(point == 6)
        {
            base_index = ((*src_buff) >> point) & 0x3;    // 取得pSrcBuff的高point位
        }
        base_index += n;                                // 与pSrcBuff-1的低point结合组成Base64的索引
        *buff_64++ = base_64_encode[base_index];        // 由索引表得到pBuff64
        n = ((*src_buff) << (6 - point));                // 计算源字符中的残留值
        n = n & 0x3f;                                    //确保n的最高两位为0
        point += 2;                                        //源字符的拆分位置上升2
        if(point == 8)        //如果拆分位置为8说明pSrcBuff有6位残留,可以组成一个完整的Base64字符,所以直接再组合一次
        {
            base_index = (*src_buff) & 0x3f;            //提取低6位,这就是索引了
            *buff_64++ =base_64_encode[base_index];
            n = 0;            // 残留值为0
            point = 2;        // 拆分位置设为2
        }
        src_buff++;

    }
    if(n != 0)
    {
        *buff_64++ = base_64_encode[n];
    }
    if(length % 3  == 2)    // 如果源字符串长度不是3的倍数要用‘=‘补全
    {
        *buff_64 = ‘=‘;
    }
    else if(length % 3 == 1)
    {
        *buff_64++ = ‘=‘;
        *buff_64 = ‘=‘;
    }
}

bool CAuthentic::CReateSocket(SOCKET &sock)
{
    WORD wVersionRequested;
    WSADATA wsaData;
    int err;
    wVersionRequested = MAKEWORD( 2, 2 );
    err = WSAStartup(wVersionRequested, &wsaData);
    if (err != 0)
    {
        return false;
    }
    if (LOBYTE(wsaData.wVersion) != 2 ||
        HIBYTE(wsaData.wVersion) != 2 )
    {
        WSACleanup();
        return false;
    }
    sock = socket(AF_INET, SOCK_STREAM, IPPROTO_IP);
    if (sock == INVALID_SOCKET)
    {
        return false;
    }

    sockaddr_in server_addr;
    memset(&server_addr, 0, sizeof(sockaddr_in));
    server_addr.sin_family = AF_INET;
    server_addr.sin_port = htons(25);    // 发邮件一般都是25端口,SSL的是465端口
    if(mail_info_.mail_server_name == "")
    {
        server_addr.sin_addr.s_addr = inet_addr(mail_info_.mail_server_ip_addr);    // 直接使用IP地址
    }
    else
    {
        struct hostent *hp = gethostbyname(mail_info_.mail_server_name);    // 使用名称
        server_addr.sin_addr.s_addr = *(int*)(*hp->h_addr_list);
        char* ip = inet_ntoa(server_addr.sin_addr);
        strcpy(mail_info_.mail_server_ip_addr, ip);
    }

    int ret = connect(sock, (sockaddr*)&server_addr, sizeof(server_addr));    // 建立连接
    if (ret == SOCKET_ERROR)
    {
        return false;
    }

    return true;
}

bool CAuthentic::Login(SOCKET &sock)
{
    recv(sock, receive_buff_, 1024, 0);

    memset(send_buff_, 0, sizeof(send_buff_));
    sprintf_s(send_buff_, "HELO %s\r\n", mail_info_.mail_server_ip_addr);
    send(sock,send_buff_, strlen(send_buff_), 0);    // 开始会话
    memset(receive_buff_, 0, sizeof(receive_buff_));
    recv(sock,receive_buff_, 1024, 0);
    if(receive_buff_[0] != ‘2‘ || receive_buff_[1] != ‘5‘ || receive_buff_[2] != ‘0‘)
    {
        return false;
    }

    memset(send_buff_, 0, sizeof(send_buff_));
    sprintf_s(send_buff_, "AUTH LOGIN\r\n");
    send(sock,send_buff_, strlen(send_buff_),0);    // 请求登录
    recv(sock,receive_buff_, 1024, 0);
    if(receive_buff_[0] != ‘3‘ || receive_buff_[1] != ‘3‘ || receive_buff_[2] != ‘4‘)
    {
        return false;
    }

    memset(send_buff_, 0, sizeof(send_buff_));
    Char2Base64(send_buff_, mail_info_.mailbox_user_name, strlen(mail_info_.mailbox_user_name));
    send_buff_[strlen(send_buff_)] = ‘\r‘;
    send_buff_[strlen(send_buff_)] = ‘\n‘;
    send(sock,send_buff_, strlen(send_buff_), 0);    // 发送用户名
    recv(sock,receive_buff_, 1024, 0);
    if(receive_buff_[0] != ‘3‘ || receive_buff_[1] != ‘3‘ || receive_buff_[2] != ‘4‘)
    {
        return false;
    }

    memset(send_buff_, 0, sizeof(send_buff_));
    Char2Base64(send_buff_, mail_info_.mailbox_user_pwd, strlen(mail_info_.mailbox_user_pwd));
    send_buff_[strlen(send_buff_)] = ‘\r‘;
    send_buff_[strlen(send_buff_)] = ‘\n‘;
    send(sock, send_buff_, strlen(send_buff_), 0);    // 发送用户密码
    recv(sock, receive_buff_, 1024, 0);
    if(receive_buff_[0] != ‘2‘ || receive_buff_[1] != ‘3‘ || receive_buff_[2] != ‘5‘)
    {
        return false;
    }
    return true;    // 登录成功
}

void CAuthentic::Init(sMailInfo &smail_info)
{
    memcpy(&mail_info_, &smail_info, sizeof(smail_info));
}

二、测试使用

这里我用的163来测试,具体换成存在的邮箱测试

#include "AuthenticationEmail.h"

//验证邮箱
void Authenticate()
{
    CSendMail mail;
    sMailInfo info;

    info.mail_server_name = "smtp.163.com";//邮件服务器名称
    info.mailbox_receiver = "[email protected]";//收件人邮箱帐号
    info.mailbox_sender = "[email protected]";//发送者邮箱帐号
    info.mailbox_user_name = "sendername";//发送者名字
    info.mailbox_user_pwd = "xxxxxxxxx";//发送者邮箱密码

    mail.Init(info);

    SOCKET sock;
     // 建立连接
    if(mail.CReateSocket(sock))
    {
        if(mail.Logon(sock))        // 登录邮箱
        {
            ::MessageBox(NULL,_T("验证成功"),_T("tip"),MB_OK);
        }
    }
}

int _tmain(int argc, _TCHAR* argv[])
{
    Authenticate();

    return 0;
}
时间: 2024-10-09 07:48:18

C++使用Socket 邮箱登录服务器验证的相关文章

ssh远程登录原理以及putty免密码验证登录服务器

作为一名运维人员登录服务器这个动作,比我们吃饭喝水的频率要来得高.一般来说没人整天在机房管理着公司服务器的吧,机房这个地方为了咱们的健康生活能少呆还是尽量少呆吧,毕竟辐射这东西是积累伤. 我们通常是通过终端远程控制服务器进行着管理工作,早先的终端是通过telnet协议传输来完成远程登录的.可是telnet协议在网上是明文传输的,随便在数据包经过的地方装个抓包工具一抓就能够获取到你服务器的账号密码.现在搞网络安全测评的评估的一条重要标准就是看你网络设备跟服务器里面的telnet服务关掉没. 为了解

邮箱连接服务器超时,不能连接远程服务器,VNC无法远程

昨天遇到一问题,用户邮箱连接服务器超时,不能连接远程服务器,VNC远程也报错,加域时错误信息里有提示未安装TCPIP协议 大致的意思就是: can't create tcp/ip socket 10106 can not open socket winsock error 10106 ping服务器什么的都是通的 解决办法就是用360修复LSP就OK了 网络上也有其它办法: 1.netsh winsock reset 然后重启,xp貌似不用 2. Winsock 10106错误解决方法事由:wi

WebApi 登录身份验证

前言:Web 用户的身份验证,及页面操作权限验证是B/S系统的基础功能,一个功能复杂的业务应用系统,通过角色授权来控制用户访问,本文通过Form认证,Mvc的Controller基类及Action的权限验证来实现Web系统登录,Mvc前端权限校验以及WebApi服务端的访问校验功能. 1. Web Form认证介绍 Web应用的访问方式因为是基于浏览器的Http地址请求,所以需要验证用户身份的合法性.目前常见的方式是Form认证,其处理逻辑描述如下:1. 用户首先要在登录页面输入用户名和密码,然

mac ssh 免密码登录服务器

刚接触mac不久,在使用中自己遇到的一些小问题,现在一一记录下来,供其他人参考和自己学习. ssh命令:ssh (-P端口)用户名@远程服务器IP. 要实现ssh登录服务器,首先就要保证mac和服务器的ssh服务是开启的,它们的相关的命令如下: linux:service sshd start (start:开启 stop:关闭 restart:重启 status:查看服务状态:知道的忽略) Mac :1.编辑/etc/sshd_config文件,注释掉 #ForceCommand /usr/l

守护进程与远程登录服务器

1.在Red Hat7版本中,系统启动和服务器进程由systemd进行管理 systemctl命令用于管理各种类型的systemd对象,它们称为单元. systemctl -t help 显示可用单元类型列表. 一些常见的单元类型: (1).服务单元具有.service扩展名 (2).套接字单元具有.socket扩展名 (3).路径单元具有.path扩展名 2.常见命令 常见的systemctl控制命令: 命令 解释 systemctl stop UNIT 停止一项服务 systemctl st

CentOS 7.1下SSH远程登录服务器详解-转

转自:http://www.linuxidc.com/Linux/2016-03/129204.htm 一.明文传输与加密传输 明文传输:当我们的数据包在网络上传输的时候,以数据包的原始格式进行传输,别人很容易截获我们的数据包,得到我们的信息. 加密传输:当两个主机之间传输信息或者是A主机远程控制B主机的时候,在两个主机传输数据包之前,加密过之后才通过网络传输过去.因此,就算有人截获了传输的数据包,也不知道传输的内容. 二.SSH(Secure Shell)简介 SSH是建立在传输层和应用层上面

ecshop登录支持手机号码登录、邮箱登录

更改users.php 加在 之上 if ($user->login($username, $password,isset($_POST['remember'])))    {        update_user_info();        recalculate_price(); $ucdata = isset($user->ucdata)? $user->ucdata : '';        show_message($_LANG['login_success'] . $ucd

kotlin和vertx和mongo写的一个服务器验证登陆功能(很简陋)

包结构长这个样子: server包:(服务器相关配置) HttpServer:用ver.x创建了一个http服务器,把接收到的req请求传入RPCRequest中: RPCRequest:解析请求body内容,把信息保存为M(类名) A(方法名) P(参数),同时还拥有invoke()方法,根据m.a.p的数据用反射调用方法. RPCResponse:没写,用来保存响应信息的. controller包:(将所有需要被远程调用的方法保存到内容中,加快调用时遍历查询方法的响应速度) MethodMa

保存邮箱并发送验证邮件

后端接口设计: 请求方式:PUT /email/ 请求参数: JSON 或 表单 参数 类型 是否必须 说明 email str 是 Email邮箱 返回数据: JSON 返回值 类型 是否必须 说明 id int 是 用户id email str 是 Email邮箱 在users/serializers.py中新建序列化器,用户验证用户提交的邮箱信息. class EmailSerializer(serializers.ModelSerializer): """ 邮箱序列化