电子邮件的组成:信封、首部和正文

电子邮件由三部分组成,下图是 Client 发送的整个数据:
 
邮箱基础协议:SMTP/POP3/IMAP-LMLPHP

  1. 信封(envelope)
     
    信封是 MTA 用来交付的,在上例中由两个 SMTP 命令指明;
     
    MAIL From: [email protected]
    RCPT To: [email protected]

  2. 首部(header)
     
    首部由用户代理使用,上例中可以看到 9 个首部字段:Recived、Message-Id、From、Date、Reply-To、X-Phone、X-Mailer、To 和 Subject
    (以 X- 开头的是用户定义的字段,其他是由 RFC 822 定义的,详见 4.1 节)

  3. 正文(body)
     
    正文是发送用户发给接收用户报文的内容,RFC 822 指定正文为 NVT ASCII 文字行,用 DATA 命令发送的各行都必须小于 1000 字节

 
用户接收我们指定为正文的部分,加上一些首部字段,并把结果传到 MTA;MTA 加上一些首部字段,加上信封,并把结果发送到另一个 MTA

 
(更多实现细节,详见 RFC 2821

 
 

 
TCP/IP 交换电子邮件示意图:
邮箱基础协议:SMTP/POP3/IMAP-LMLPHP

 

邮件基础协议

邮件基础的网络协议有以下三个,一般我们使用 SMTP 协议来发送邮件,POP3 和 IMAP 协议来接收邮件(从服务端接收邮件至客户端)

  • 下表中 IMAP 协议支持发送邮件并不是邮件投递,而是通过 append 指令将邮件从客户端上传到服务端
SMTP25(465)TrueFalse
POP3110(995)FalseTrue
IMAP143(993)TrueTrue

 


SMTP

两个 MTA 之间通过 NVT ASCII 进行通信,客户向服务器发出命令,服务器用数字应答码和可选的人可读字符串进行响应
 
下图是 SMTP 的一个交互会话过程:
 
邮箱基础协议:SMTP/POP3/IMAP-LMLPHP

  1. 键入 mail -v 启动用户代理; 键入 subject(主题)和正文
  2. 主动打开 port:25 ;等待从 Server 返回的问候报文(应答码220)
  3. HELO:标识自己(参数必须是合格的主机名)
  4. MAIL:标识报文发起人
  5. RCPT:标识接收方(可发多次,标识多个接收方)
  6. DATA:邮件报文内容
  7. QUIT:结束邮件交换

下图是发送方 SMTP(Client)和接收方 SMTP(Server)之间的一个 SMTP 连接:
 
邮箱基础协议:SMTP/POP3/IMAP-LMLPHP

SMTP 指令

最小SMTP支持 8 个命令,除了上述 5 个命令还有:

  • RSET:异常中止当前的邮件事务并使两端复位。丢掉所有有关发送方、接收方或邮件的存储信息
  • VRFY:使客户询问发送方以验证接收方地址,而无需向发送方发送邮件(通常用与管理员查找邮件交付差错中使用)
  • NOOP:强迫服务器响应一个OK应答码(200)

(另外还有一些附加可选命令)

 
SMTP 用半双工的形式使用 TCP,客户发送一个命令后停止等待应答;实际上 Client 可以一次发多个命令,称为流水线技术(pipelining)

如果使用了这种技术,Client 则不能丢弃报文直到所有的应答都已检查过,确认报文被服务器接收了

使用 Telnet 模拟 SMTP 发送邮件

邮箱基础协议:SMTP/POP3/IMAP-LMLPHP


POP3

POP3 协议相对 SMTP/IMAP 要简单一些,协议的指令也不多
邮箱基础协议:SMTP/POP3/IMAP-LMLPHP

POP3 的生命周期

邮箱基础协议:SMTP/POP3/IMAP-LMLPHP

POP3 命令以 CRLF 对结束,特定命令多行响应,以 CRLF.CRLF 结束

在服务器打开邮件后,它为每个消息指定一个消息号,并以八进制表示每个消息的长度。第一个消息被指定为 1,第二个消息被指定为 2,以此类推,第 N 个消息被指定为 N
在POP3命令和响应中,所以的消息号和长度以十进制表示

AUTHORIZATION

邮箱基础协议:SMTP/POP3/IMAP-LMLPHP

  • USER :客户确认身份(参数:username)
  • PASS :身份确认完成
  • QUIT :终止 POP3 会话
  • APOP :用于替代 USER 和 PASS 命令,它以 MD5 数字摘要的形式向POP3邮件服务器提交帐户密码(参数:用户名/密钥)(该命令实现可选)

安全性:每个 POP3 会话都以 USER/PASS 互换开始,导致了用户名和口令在网络上的显式传送,当服务连接频率变大、时间间隔小,就会加大了泄密的可能
(使用APOP:随着密钥长度的增加,解读的难度也会上升)

TRANSACTION

操作状态下的命令:

  • STAT :查询邮箱中的统计信息(邮件数量和所有邮件大小)
  • LIST :列出邮箱中的所有邮件信息(消息号/大小)(参数:MSG 列出对应消息号的邮件信息)
  • RETR :获取某封邮件的内容(参数:MSG)
  • DELE :将某封邮件标记为删除(参数:MSG)(被标记的邮件直到当前会话进入 UPDATE 状态才被删除)
  • NOOP :检测连接状况
  • RSET :取消删除标记

UPDATE

当客户在 AUTHORIZATION 状态下发送 QUIT 命令后,会话进入 UPDATE 状态
如果会话因为 QUIT 命令以外的原因中断,会话并不进入 UPDATE 状态,也不从服务器中删除任何信件

 
(更多实现细节,详见 RFC 1939


IMAP

IMAP 协议通过 port:143 来提供电子邮件的收发服务,和 POP3 被用来提供电子邮件客户端服务(从服务器检索电子邮件)
相对于 POP3,IMAP 支持多个电子邮件客户端同时管理邮箱,并可以通过邮件的标签/状态,监测到其他用户对于邮件的操作
 
IMAP 还支持在线/离线两种操作模式,客户端可以获得邮件副本存储在本地

标志消息属性

与邮件关联的有一个或多个 token list,将 flag 添加至列表可以设置邮件的属性,每个 flag 可以设置为永久的或临时的(当前会话)

\Seen邮件已阅读
\Answered邮件已回复
\Flagged邮件被标记为紧急/特别关注
\Delete邮件被标记删除(to EXPUNGE)
\Draft邮件被标记为草稿
\Recent邮件最近到达该邮箱(本次会话是首次收到当前邮件通知)

具体的实现与服务器相关

状态和流程图

Client 和 Server 建立好连接后,IMAP 连接处于四种状态之一
最初的状态在服务器的 greeting 报文中标识,客户端在不当状态中尝试的命令服务器都将以 BAD/NO 响应(取决于实现)
邮箱基础协议:SMTP/POP3/IMAP-LMLPHP

  • Not Authenticated State :未经认证的状态,连接启动时进入该状态,除非已进行预验证
  • Authenticated State:认证状态,可选择邮箱进行访问
  • Selected State:选定状态,已选择一个邮箱访问
  • Logout State:退出状态,连接正在终止(LOGOUT 命令)

服务器必须发送 BYE 响应来关闭连接,同样的,客户端应该发送 LOGOUT 命令来关闭连接

如果服务器检测到客户端单方面关闭了连接,则可以省略 BYE 响应

IMAP 命令

下面罗列一些常见的 IMAP 命令

客户端命令 —— 任何状态

  • CAPABILITY:查询服务器实现的功能
  • NOOP:检测连接
  • LOGOUT:终止当前连接

客户端命令 —— 未经认证的状态

  • STARTTLS:与服务器使用 TLS 进行交互
  • AUTHENTICATE:与服务器的认证机制
  • LOGIN:鉴权登陆,输入用户名与密码

客户端命令 —— 认证状态

  • SELECT:选择邮箱
  • EXAMINE:以只读方式选择邮箱
  • CREATE:创建一个邮箱
  • DELETE:删除一个邮箱
  • RENAME:重命名邮箱
  • SUBSCRIBE:订阅指定邮箱
  • UNSUBSCRIBE:取消订阅邮箱
  • LSUB:返回订阅邮箱列表
  • APPEND:追加一个State,例如可以保存一封新的邮件

客户端命令 —— 选定状态

  • CHECK:检查当前服务器状态(例如:磁盘,内存等)
  • CLOSE:永久删除所有消息
  • EXPUNGE:永久删除所有消息,与 CLOSE 不同的是,将返回每个消息标识
  • SEARCH:类似 find 命令,功能很强大可以按照不同条件搜索邮件
  • FETCH:检索与消息相关数据,例如:获取正文
  • STORE:改变与消息相关数据,例如:设置邮箱已读、删除状态等
  • COPY:拷贝指定的消息
  • UID:返回 UID 列表用于 FETCH
05-17 22:43