POP3协议 中文翻译

翻译:N2Hsu

校对:Nii Ma

3-基本流程:

首先,服务器启动POP3服务监听TCP 100端口;

当客户机要使用这个服务器上的POP3服务时,与POP3服务器建立一个TCP连接;

连接建立后,POP3服务器发送一条问候语;

客户机和POP3服务器就可以进行命令和响应的交互,直到连接关闭或终止。

POP3协议中的命令是一个不区分大小的关键字,后面可能会有一个或多个参数。所有的命令都以一对换行符结尾。关键字和参数都是可打印的ASCII字符。关键字和参数之间、参数与参数之间都用一个空格相隔。关键字为三个或四个字符。每一个参数的长度最长为40个字符。

POP3协议的响应包含一个状态指示码、一个关键字,后面可能会有一些额外的信息。所有的响应都以一对换行符结尾。每个响应的长度最长为512个字符(包含最后的换行符)。当前有两种状态指示码:正确响应("+OK")、错误响应("-ERR")。服务器必须发送大写的"+OK"和"-ERR"。

某些命令的响应可能会有多行。这种情况遵循如下约定:首先发送第一行和一个换行符,此后要发送的其他行都以一对换行符结尾。当所有的响应行发送完成以后,一个八进制的终止符(ASCII046,字符“.”)加一对换行符的结尾行会被发送出去。如果多行响应中的任意一行开始于终止符,此行就是预填充入终止符的响应行。所以说,多行响应是以五个八进制字符(一对换行符+终止符+一对换行符)结束的。当客户端解释多行响应时需要判断此行是否以终止符开头,如果是并且紧随其后的不是换行符那么此行的第一个字符(终止符)会被剥离;如果是并且后面是换行符,表示POP服务响应完成,包含终止符+换行符的这一行则不会包含在多行响应行中。

POP3的会话期间会经历几个状态。

一旦TCP连接建立,POP3服务器发送了握手信息,会话进入AUTHORIZATION状态。在这个状态中,客户端对POP3服务器发起身份验证。

一旦客户端验证通过后,服务器获取与客户端邮件相关的资源,这时会话进入TRANSACTION状态。在这个状态中,客户端可以对POP3服务器进行相关的操作。

当客户端键入QUIT命令后,会话进入UPDATE状态。在这个状态中,POP3服务器会释放在TRANSACTION状态期间的相关资源,回复goodbye,TCP连接随之关闭。

服务器必须对不可识别的、未实现的、语法错误的命令给出错误的状态指示。服务器必须对处于不合法状态的会话给出错误的状态指示。因为客户端没有统一的方法来区分服务器是否实现某个可选命令或者服务器是否能够执行某个命令。

POP3服务器可能会包含一个非活动自动退出的计时器。计时器的周期最少为10分钟。在计时器一个周期内服务器接收到来自客户端的任意命令时,自动退出计时器应该重新计时。当计时器超时后,会话不会进入UPDATE状态,服务器不会删除消息、不会给予客户端任何响应的关闭TCP连接。

4-AUTHORIZATION 状态

一旦对客户端的TCP连接被打开,POP3服务器就会发送一条问候语,这是一条正确的响应。例子如下:

+OK POP3 server ready

此时会话处于AUTHORIZATION状态。客户端和服务器进行身份验证。在本文档中描述了两种认证机制,USERPASS命令和APOP命令。其他的认证机制在[RFC1734]中会有描述。虽然没有一种认证机制是POP3服务器必须支持的,但是它需要最少支持一种认证机制。

一旦服务器通过了客户端发起的某种认证,客户端就有权访问相应的邮箱,此时服务器会给邮箱加上独占访问锁,防止会话在进入UPDATE状态之前邮件被修改或者移除。如果独占锁成功获取,POP3服务器就会给予客户端正确响应的状态指示码,会话进入TRANSACTION状态,此时没有邮件被标记或者删除。如果邮箱由于某些原因无法打开(比如无法获得独占锁、客户端被拒绝访问相应邮箱、邮箱无法被解析),POP3发送错误响应的状态指示码(如果获取到了独占锁但服务器返回了错误响应的状态指示码,服务器必须释放这个锁,拒绝这个命令请求)。返回错误响应的状态指示码后,服务器可能会关闭连接。如果服务器没有关闭TCP连接,客户端可以重新发起认证命令或者发起QUIT命令断开连接。

POP3服务器打开邮箱后,会为每一封邮件指定一个编号,用八进制标记每封邮件的大小。邮箱中的第一封编号为“1”,第二封为“2”,以此类推,第N封邮件编号为N。在POP3的命令和响应中,所有的邮件编号和邮件大小都用BASE10编码(十进制)。

下面是一个AUTHORIZATION状态时QUIT命令的介绍:

QUIT

参数:无

限制:无

正确的响应:+OK

例子:C: QUITS: +OK dewey POP3 server signing off

5-TRANSACTION状态

一旦客户端通过了身份认证,POP3服务器对邮箱成功加锁并且已经打开,会话进入TRANSACTION状态。客户端就可以重复的执行以下的命令。最终客户端发起QUIT命令,会话进入UPDATE状态。

以下是在TRANSACTION状态时的POP3命令:

STAT

参数:无

限制:只能在TRANSACTION状态时使用

解释:

POP3服务器用一行信息来表明邮箱的信息,作为此命令的正确响应。这一行信息称为邮箱的“信息统计”。

为了简单解析起见,所有的POP3服务器都必须使用固定的格式来表示邮件概述信息。正确的响应由“+OK”、一个空格符、邮箱的邮件数量、一个空格符、八进制表示的邮箱大小组成。在这个版本的协议中,邮箱大小后面的信息不是必须的,因此对这个命令响应的最小实现应该是以一对换行符作为响应行的结束。对此命令响应的高级实现可能会包含额外的信息。

注意:

当前协议中强烈不建议对此命令响应实现其他的额外信息。

注意:被标记为删除的邮件不会被计入邮件总数中。

可能的响应:

+OK nn mm

例子:C: STATS: +OK 2 320

LIST [msg]

参数:

邮件编号(可选),如果这封邮件还存在,不能被标记为删除

限制:

只能在TRANSACTION状态时使用

解释:

如果给出参数,POP3服务器会返回这封邮件的一行信息作为正确响应。这一行信息被称为针对这封邮件的概述。

如果没有给出参数,POP3服务器会返回多行作为正确响应。首先返回“+OK”,然后是对每封邮件的一行信息。这一行信息也被称为这封邮件的概述。如果邮箱中没有邮件,POP3服务器会返回空的邮件概述作为正确的响应,并用一个八进制的终止符和一对还行符作为结尾。

为了简单解析起见,所有的POP3服务器都必须使用固定的格式来描述邮件概述。对于一封邮件的概述由邮件编号、紧随其后的一个空格符和八进制表示的邮件扩展之后的大小的数字组成。计算邮件的扩展后大小会在后面的邮件格式中提到。在这个版本的协议中,邮件大小后面的信息不是必须的,因此对这个命令响应的最小实现应该是以一对换行符作为响应行的结束。在其他的高级实现中,解析此邮件时可能会有其他的额外信息。

注意:当前协议中强烈不建议对此命令响应实现其他的额外信息。

注意:被标记为删除的邮件不会出现在此列表中。

可能的响应:

+OK scan listing follows-ERR no such message

_例子:C: _LIST_ +OK 2 messages (320 octets)_S:_ 1 120_S:_ 2 200_S:_ .__ ..._C:_ LIST 2_S:_ +OK 2 200__ ..._C:_ LIST 3_S:_ -ERR no such message, only 2 messages in maildrop_

RETR msg

参数:

邮件编号(必需),而且这封邮件不能标记为删除

限制:

只能在TRANSACTION状态时使用

解释:

如果POP3服务器给出正确响应的知识码,那么响应应该是多行。在“+OK”后,发送给定邮件编号的邮件内容,一定要小心处理多行响应中的终止填充符。

可能的响应:

+OK message follows-ERR no such message

例子:

C: RETR 1S: +OK 120 octetsS: <the POP3 server sends the entire message here>S: .

DELE msg

参数:

邮件编号(必需),而且这封邮件不能标记为删除。

限制:

只能在TRANSACTION状态时使用

解释:

POP3服务器会标记此邮件为删除。在以后的POP3命令中关于此邮件的操作都会产生一个错误。此时POP3服务器并不会真正的删除此封邮件,而是在会话进入UPDATE状态时才执行删除。

可能的响应:

+OK message deleted_ -ERR no such message_

例子:

C: DELE 1S: +OK message 1 deleted...C: DELE 2S: -ERR message 2 already deleted

NOOP

参数:无

限制:

只能在TRANSACTION状态时使用

解释:

POP3服务器不会做任何操作,仅仅返回一个正确响应的指示码。

可能的响应:

+OK

例子:

C: NOOPS: +OK

RSET

参数:无

限制:

只能在TRANSACTION状态时使用

解释:

如果有邮件被标记为删除,这个标记会被清除(此后,在进入UPDATE状态时不会被真正删除),POP3服务器回复正确响应的指示码。

可能的响应:

+OK

例子:

C: RSETS: +OK maildrop has 2 messages (320 octets)

6-UPDATE状态

当客户端在TRANSACTION状态时请求QUIT命令,会话进入UPDATE状态。(注意,如果客户端在AUTHORIZATION状态请求QUIT命令,会话会终止而不是进入UPDATE状态)

如果一个会话不是由于客户端请求QUIT命令而是其他原因终止的,会话不会进入UPDATE状态,此时邮箱中的任意一封邮件都不会被删除。

QUIT

参数:无

限制:无

解释:

POP3服务器会从邮箱移除所有标记为删除的邮件,回复操作的结果。如果操作执行时遇到资源不足,重复删除等错误,可能会导致有些邮件或者所有被标记为删除的邮件没有被删除。当然,没有标记为删除的邮件肯定不会被删除。

无论删除邮件成功还是失败,服务器都会释放邮箱的独占访问锁,然后关闭TCP连接。

可能的响应:

+OK_ -ERR some deleted messages not removed_

例子:

C: QUITS: +OK dewey POP3 server signing off (maildrop empty)...C: QUIT

7-可选的POP3命令

上面所讲的命令是一个POP3服务器所必须支持的最小实现。

可选命令是为了让邮件操作的实现有更多的自由度。

注意:此协议强烈建议在开发构建服务器和客户端时实现这些命令。总之,这些命令是为了是得客户端更加的智能与完善,而不是针对服务器。

TOP msg n

参数:

邮件编号(必须),此邮件不能被标记为删除;非负的一个行号(必须)

限制:

只能在TRANSACTION状态时使用

解释:

如果服务器给出正确的响应,响应应该是多行的。首先是“+OK”,后面是邮件的头部信息,一个空行,n行的邮件正文,小心处理多行响应的终止填充符。

注意:如果给出的行数值大于邮件正文的行数,POP3服务器会返回邮件正文的所有内容。

可能的响应:

+OK top of message follows_ -ERR no such message_

例子:

C: TOP 1 10S: +OKS: <the POP3 server sends the headers of the message, a blank line, and the first          10 lines of the body of the message>S: ....C: TOP 100 3S: -ERR no such message

UIDL [msg]

参数:

邮件编号(可选),如果指定编号,这封邮件不能被标记为删除。

限制:

只能在TRANSACTION状态时使用

解释:

如果给出了参数,POP3服务器会返回一行邮件的概述信息。这一行被称为唯一ID标记的概述。

如果没有给出参数,POP3服务器会返回多行的邮件概述信息。首先是“+OK”,然后针对邮箱里面的每封邮件,都会返回一行此邮件的概述信息。每一行也被称为唯一ID标记的概述。

为了解析简单起见,所有的POP3服务器都必须使用固定的格式来描述邮件概述信息。它由邮件编号,后面一个空格符外加邮件唯一ID组成。邮件唯一ID后面没有额外信息。

邮件的唯一ID是服务器随机出来的一个字符串,它由0x21~0x7E之间的任意1到70个字符组成,能够标识某个邮箱内的唯一一封邮件。邮件的唯一ID与会话没有关系,即便是会话结束没有进入UPDATE它也不存在。只要这个ID标识的邮件在邮箱中存在,POP3服务器就不应该重复使用这个ID。

注意:被标记为删除的邮件不会出现。

虽然对服务器来说这是实现邮箱内唯一ID标识邮件的存储的最好方式,但本规范的初衷是通过唯一ID标识来计算邮件的HASH值,这样客户端就可以处理具有相同唯一ID标识的邮件的两个副本问题。---暂不明晰

可能的响应:

+OK unique-id listing follows_ -ERR no such message_

例子:

C: UIDLS: +OKS: 1 whqtswO00WBw418f9t5JxYwZS: 2 QhdPYR:00WBw1Ph7x7S: ....C: UIDL 2S: +OK 2 QhdPYR:00WBw1Ph7x7...C: UIDL 3S: -ERR no such message, only 2 messages in maildrop

USER name

参数:

对于一个邮箱的唯一标识串,它仅仅是对某服务器唯一。

限制:

只能在AUTHORIZATION状态时使用,并且只能是在POP3的握手信息之后或者不成功的USER/PASS命令之后使用

解释:

为了组合起来使用USER/PASS命令,客户端必须发起USER命令。如果POP3服务器返回正确响应的指示码(“+OK”),客户端才能再发送PASS命令来完成身份认证或者发送QUIT命令终止会话。如果POP3服务器返回错误响应的指示码(“-ERR”),客户端可以重新发送身份认证命令或者发送QUIT命令终止会话。

即便这个邮箱不存在,服务器也可能返回正确响应的指示码。如果这个邮箱存在,但服务器返回错误响应的指示码,那就说明服务器不允许明文密码认证。

可能的响应:

+OK name is a valid mailbox_ -ERR never heard of mailbox name_

例子:

C: USER fratedS: -ERR sorry, no mailbox for frated here...C: USER mroseS: +OK mrose is a real hoopy frood

PASS string

参数:

服务器或者特殊标识的密码(必需)

限制:

只能在AUTHORIZATION状态时使用,并且必须在USER命令返回正确响应的指示码之后使用

解释:

当客户端发送PASS命令后,POP3服务器使用USER命令的参数和PASS命令的参数进行认证,以此来决定是否允许客户端访问这个邮箱。

由于PASS命令包含一个参数,所以服务器可能会把命令与参数之间的参数分隔符-空格也当作密码的一部分进行校验。

可能的响应:

+OK maildrop locked and ready_ -ERR invalid password__ -ERR unable to lock maildrop_

例子:

C: USER mroseS: +OK mrose is a real hoopy froodC: PASS secretS: -ERR maildrop already locked...C: USER mroseS: +OK mrose is a real hoopy froodC: PASS secretS: +OK mrose's maildrop has 2 messages (320 octets)

APOP name digest

参数:

一个邮箱的唯一标识串name(必需),一个MD5的加密串digest(必需)

限制:

只能在AUTHORIZATION状态时使用,并且只能是在POP3的握手信息之后或者不成功的USER/PASS命令之后使用

解释:

正常情况下,每一个POP3会话都是开始于USER/PASS命令,但是这导致了明文密码在网络中传输。这对于无规律间断性的POP3交互可能不是一个巨大的风险,但是很多客户端都会进行一项基本操作-定期检查新邮件。这样的会话周期可能是5分钟,密码被暴露的风险可能就随之增大。

APOP命令就是为了解决这个问题而产生的。既能保留原有的认证方式,还可以对密码进行加密使之不会在网络上明文传输。

POP3服务器在实现APOP命令时在握手信息中加入一个时间戳。这个时间戳的语法在[RFC822]关于“msg-id”中会有描述。每一个POP3服务器必须有唯一的握手信息。比如UNIX上是用POP3服务器上独立的实例进程来表示的。比如:

process-ID.clock@hostname

‘process-ID’是十进制的进程PID,clock是十进制的系统时间,hostname是POP3服务器运行时的域。

客户端记录这个时间戳,然后发送APOP命令。name这个参数与USER命令中name这个参数一致。digest这个参数是用一个共享密钥来对时间戳(包含尖括号)进行MD5运算得到的。共享密钥只有客户端和POP3服务器共享的一个字符串,所以要防止密钥被泄露,如果密钥泄露将导致任何人都能以这个用户进行邮箱操作。digest参数是一个十六进制的长度为16字节的小写ASCII值。

当POP3服务器收到APOP命令时,首先验证客户端提供的digest。如果digest正确,服务器返回正确响应的指示码,然后进入TRANSACTION状态,否则一个错误响应的指示码会被返回,会话状态维持在AUTHORIZATION。

注意:应该增加密钥的长度为了防止密钥被破解,所以考虑使用长度大于8的密钥串。可能的响应:

+OK maildrop locked and ready_ -ERR permission denied_

例子:

S:_ +OK POP3 server ready 1896.697170952@dbc.mtview.ca.us_C: APOP mrose c4c9334bac560ecc979e58001b3e22fbS: +OK maildrop has 1 message (369 octets)

在这个例子中,共享密钥串为“tan-staaf”。然后对下面的字符串进行MD5计算

1896.697170952@dbc.mtview.ca.ustanstaaf

得到的值就是

c4c9334bac560ecc979e58001b3e22fb

8-Scaling and Operational Considerations