SMTP 是一种应用层协议。 要发送邮件的客户端打开到 SMTP 服务器的 TCP 连接,然后通过该连接发送邮件。 SMTP 服务器是一种永远在线的侦听模式。 一旦它侦听来自任何客户端的 TCP 连接,SMTP 进程就会通过端口 25 启动连接。成功建立 TCP 连接后,客户端进程会立即发送邮件。
理解SMTP协议
SMTP 协议背后的主要思想是在服务器之间建立通信指南。 服务器识别自己并宣布正在进行的通信类型。 服务器还处理错误,例如不正确的电子邮件地址。 例如,如果收件人地址不正确,则收件人服务器会以错误消息进行响应。
SMTP是发送电子邮件的协议。它使用的是TCP的25号端口。SMTP建立一个TCP连接以后,在这个连接上进行控制和应答以及数据的发送。客户端以文本的形式发出请求,服务端返回一个3位数字的应答。每个指令和应答的最后都必须追加换行指令。
SMTP通信模型
SMTP基于客户/服务端模式,需要TCP提供可靠的数据流。SMTP服务器默认监听TCP 25端口,规范SMTP协议的最新RFC文档RFC 5321,它淘汰了RFC 2821。
SMTP是一个相对简单的基于文本的协议。MIME规范使得二进制文件能够通过SMTP来传输。目前大多数SMTP软件实现都支持8位MIME扩展,从而使二进制文件的传输变得几乎和纯文本一样简单。
当SMTP客户端有邮件要传送时,与SMTP服务器建立一个双向的传输通道。SMTP客户端负责邮件信息传送到一个或多个SMTP服务器,如果失败则给出报告。
SMTP服务器可能最终目的地,也可能是中间的中继或者网关。SMTP命令由SMTP客户端产生,发送到SMTP服务器。SMTP响应由SMTP服务器发送给SMTP客户端,对命令做出回应。
也就是说,邮件传输者可以出现在起始SMTP发送方与最终的SMTP接收方之间建立的连接上,或者出现在通过中间系统的一系列跃点上。一旦传输通道建立和初始握手完成,SMTP客户端正常初始化邮件事务。这样的事务包括一系列命令,以定义邮件的发送方和目的地,以邮件内容本身的传递。
发送者发送 MAIL 命令来指定发送者的邮件,如果接受者接收这个邮件,就回复 OK ,接着发送者发送 RCPT命令来指定接收者的邮箱,如果被接收同样回复OK,如果不接受则拒绝(不会终止整个通话)。接收者邮箱确定后,发送者用DATA命令指示要发送数据,并用一个 . 结束发送。如果数据被接收,会收到OK ,然后用QUIT结束会话。
SMTP命令
EHLO命令:
参数为SMTP客户端全称域名 。SMTP客户端问候SMTP服务器,提供自己的名称或地址,以向服务器标识自己的身份。客户端应当通过EHLO命令来发起SMTP服务,如果服务器支持SMTP服务扩展,将给出成功、失败或者错误回应;
如果不支持SMTP扩展,服务器将产生一个错误响应。
MAIL命令:
- MAIL < SP > FROM:< reverse-path > < CRLF >
MAIL命令,包含发送者邮箱( 是空格,是回车换行)
反向路径是MAIL命令的参数。该路径便于服务返回错误信息,不仅包括邮箱,而且包括主机和源邮件的反向路由,其中的第1个主机就是发送此命令的主机。
参数为发件人邮件地址。用来发起邮件事务,让邮件数据传送到SMTP服务器,SMTP服务器依次将邮件数据投递到一个或者多个邮箱,或者传送到另一个系统。
RCPT命令:
- RCPT < SP > TO:< forward-path > < CRLF >
转发路径是RCPT命令的参数。该路径不仅包括邮件,而且包括主机和目的邮箱的路由表,在其中的第1个主机就是接收命令的主机。
参数为收件人邮件地址。用来标识邮件数据的收件人,可以指定多个收件人。
DATA命令:
- DATA < CRLF >
参数为邮件主机(正文)。将该命令之后的数据作为要发送的数据。数据加入到缓存区中,以单独一行是< CRLF >.< CRLF >的行结束数据。结束行对于接收方同时意味立即开始缓冲区的数据传送,传送结束后清空缓冲区。如果传送被接收,服务器回复OK。
RSET命令:
指定当前邮件事务终止。所存储的收件人、发件人和待发送的数据都必须清除,接收方必须回复OK。
VRFY命令:
参数为收件人名称。用于验证指定的用户或邮箱是否存在。
EXPN命令:
参数为邮递清单。验证给定的邮递清单是否存在,如果存在则返回其成员。
HELP命令:
- HELP [SP String] < CRLF >
参数命令名。提供给定命令的帮助信息。
QUIT命令:
- QUIT < CRLF >
指定接收方回复OK,关闭传输通道。
SMTP响应
SMTP命令的响应用于确保邮件传输过程中的请求与操作的同步,让SMTP客户端总是知道SMTP服务器的状态。每个命令必须正好产生一个响应。
与FTP响应类似,SMTP响应也由三个数字组成,后面跟着一些文本。数字用来自动判断当前的状态,文本内容提供给用户。
/* The following were copied from RFC 2821 */
static const value_string response_codes_vs[] = {
{ 211, "System status, or system help reply" },
{ 214, "Help message" },
{ 220, "<domain> Service ready" },
{ 221, "<domain> Service closing transmission channel" },
{ 235, "Authentication successful" },
{ 250, "Requested mail action okay, completed" },
{ 251, "User not local; will forward to <forward-path>" },
{ 252, "Cannot VRFY user, but will accept message and attempt delivery" },
{ 334, "AUTH input" },
{ 354, "Start mail input; end with <CRLF>.<CRLF>" },
{ 421, "<domain> Service not available, closing transmission channel" },
{ 432, "A password transition is needed" },
{ 450, "Requested mail action not taken: mailbox unavailable" },
{ 451, "Requested action aborted: local error in processing" },
{ 452, "Requested action not taken: insufficient system storage" },
{ 454, "Temporary authentication failed" },
{ 500, "Syntax error, command unrecognized" },
{ 501, "Syntax error in parameters or arguments" },
{ 502, "Command not implemented" },
{ 503, "Bad sequence of commands" },
{ 504, "Command parameter not implemented" },
{ 530, "Authentication required" },
{ 534, "Authentication mechanism is too weak" },
{ 535, "Authentication credentials invalid" },
{ 538, "Encryption required for requested authentication mechanism" },
{ 550, "Requested action not taken: mailbox unavailable" },
{ 551, "User not local; please try <forward-path>" },
{ 552, "Requested mail action aborted: exceeded storage allocation" },
{ 553, "Requested action not taken: mailbox name not allowed" },
{ 554, "Transaction failed" },
{ 0, NULL }
};
SMTP通信过程
SMTP 消息传输可以描述为客户端和服务器之间的对话。必须在它们之间交换一些命令,以便将消息从发送者传递给接收者。电子邮件传输的典型过程如下所示。
完整的SMTP通信过程包括连接建立、邮件传送、连接释放3个阶段,每个阶段都涉及一组命令和响应。
SMTP解析解析代码实现
int main(int argc, char* argv[])
{
char errbuf[1024];
pcap_t *desc = 0;
char *filename = argv[1];
if (argc != 2)
{
printf("usage: ./dissect_smtp [pcap file]\n");
return -1;
}
printf("ProcessFile: process file: %s\n", filename);
if ((desc = pcap_open_offline(filename, errbuf)) == NULL)
{
printf("pcap_open_offline: %s error!\n", filename);
return -1;
}
pcap_loop(desc, pkt_number, (pcap_handler)ace_pcap_hand, NULL);
pcap_close(desc);
return 0;
}
编译运行:
使用SMTP的好处
以下是 SMTP 协议的一些优点。
- 1、SMTP 通过电子邮件在特定网络中的多台计算机之间提供最简单的通信形式。
- 2、SMTP 由一个简单的平台组成,可以轻松快速地发送电子邮件。
- 3、SMTP 为外发电子邮件提供可靠性,因此如果邮件未成功发送,则 SMTP服务器会尝试重新发送相同的邮件,直到邮件成功发送为止。
- 4、SMTP 有助于拥有一个承诺的服务器来管理组织中的外发电子邮件。
- 5、连接到 SMTP 非常简单。 此外,它提供了一个简单的安装。
- 6、SMTP 连接没有限制,可用于连接到任何系统。我们所要做的就是合并 SMTP 信息。
- 7、它不包括我们最终的任何发展。
总结
电子邮件正在成为当今互联网上最有价值的服务之一。 大多数 Internet 系统使用 SMTP 作为一种将邮件从一个用户传输到另一个用户的方法。 SMTP 是一种推送协议,用于发送邮件,而 POP(邮局协议)或 IMAP(互联网消息访问协议)用于在接收方检索这些电子邮件。
欢迎关注微信公众号【程序猿编码】,需要SMTP 完整源码的添加本人微信号(c17865354792)
参考:RFC 5321