摘要
- RFC 1204 建议:只要
USER参数的语法正确,即便服务器不认识这个用户名,也返回250。它要阻止客户端枚举账号,而不是确认账号存在。 - 后续的
PASS 250才表示密码与刚才的用户名已经核对成功。DATA 354只是准备接收正文;正文结束后的250只证明消息进入本地投递队列。 NOOP 250又只说明当前会话里的发布服务器没有发现内部错误。同一个数字若失去命令、状态和发言组件,就无法说明到底观察到了什么。
一条肯定答复,专门用来保留未知
RFC 1204 最值得记住的不是端口,而是一项信息不对称设计。客户端先用 USER 提交用户名。协议把 250 列为接受用户名的答复,却紧接着要求:只要字符串语法成立,即使服务器没有识别到这个名字,也应返回同样的代码。
文档解释了目的。服务器不能让客户端借答复差异测试某个用户是否存在,也不应泄露过多账号库信息。因此,外部看到 250 时,内部至少可以有两个事实:查到了账号,或没有查到账号。两种状态故意共用同一个外观。
这不是粗糙协议遗漏了错误码,而是协议把“不披露”做成了控制。服务器接受的是这一步输入的形式,并允许状态机继续;它没有对名字所指向的账号作公开确认。把这条记录改写成“账号有效”,会正好逆转设计意图。
RFC Editor 记录保存了它在 1991 年 2 月发布、类别为 Experimental 的事实。今天的 IETF Datatracker 记录还注明:这是一份在正式来源记录制度之前发布的 Legacy 文档,不受 IETF 背书,在当前标准流程中没有正式地位。它能证明当年的机制主张,不能证明广泛部署或今天仍受推荐。
个人电脑把两项工作交给了不同系统
RFC 的出发点带有鲜明的年代特征:当时的个人电脑操作系统被描述为没有用户认证机制,而邮件系统又希望降低冒用发件人的风险。方案是在邮件服务主机上设置 message posting server,由它验证 PC 用户,再代表用户把邮件交给 Sendmail、MMDF 等投递系统。
这不是一个无所不知的服务器。PC 客户端负责提交输入;发布服务器负责本地账号判断和消息队列;投递系统负责之后的递送尝试。Netix MPP 通过 TCP 工作,分配到 218 端口,并借用了 SMTP 与 FTP 的命令—答复结构。
RFC 821让 DATA、点号终止和数字答复成为熟悉的邮件语法。RFC 1204 借用了它们,但又为 USER、PASS 和本地发布过程定义了自己的状态。相同数字不能脱离触发它的命令搬运到另一个语境。
第二个 250 才涉及密码关系
USER 250 之后,客户端可以发送 PASS。如果服务器确认密码与前一个用户名正确关联,它再次返回 250;若密码不匹配,则返回 530。语法错误、顺序错误和内部故障另有代码。
两次相邻的肯定答复说的是两种事情。第一次把“账号是否被认识”藏起来,只公开“语法足以继续”。第二次才记录服务器对用户名—密码关系的核验。把它们混在一起,会在入口泄露账号;把第二次也当成纯语法,又会丢失真正发生的凭据判断。
即便 PASS 250 成立,它也仍是一项本地声明。RFC 没有让它证明键盘前人的法律身份,没有证明消息内容由此人亲自撰写,也没有授予他向任何目的地发送任何内容的普遍权限。账号库和发布服务器只对自己的凭据关系负责。
多年后的 RFC 4954用 SASL 协商机制定义 SMTP AUTH,并要求服务器能够在没有 TLS 或其他防窃听保护时禁止明文密码机制。这个后来的安全面不能倒灌进 RFC 1204。它只说明:认证方法、信道保护和消息处理本来就是不同层次。
354 只是把解析器切到正文状态
密码核验成功后,客户端才能进入 DATA。服务器回复 354,表示已经准备接收邮件正文。此时发生的是状态切换:后续字节按正文规则解释。它还没有见到完整终止符,更谈不上确认完整对象进入队列。
客户端发送正文和来自 SMTP 的点号终止序列。只有在收到完整结尾之后,新的 250 才表示消息文本已成功排入投递队列。如果内部错误使入队失败,则用 451 明确表示没有排队。
队列是一项真实的本地保管承诺,比“准备读取”更进一步。但 RFC 随即限定它:发布服务器应尽快尝试把已接受消息交给投递系统;之后的投递失败由投递系统处理,发布服务器不应介入。
因此,入队 250 不能替远端中继、邮箱存储、客户端显示或人的阅读发言。一个组件可以准确报告自己已经接住对象,同时完全不知道下一组件会作何决定。
第四种 250 甚至不对应一封消息
NOOP 不执行消息动作,它只测试发布服务器状态。NOOP 250 的含义是:服务器在当前会话中没有遇到内部错误。它没有检查下游投递系统,更没有查看收件箱。
同一份协议里,四条 250 可能分别表示:
- 用户名格式可继续,但账号识别结果被隐藏;
- 密码已与前一个用户名核对;
- 完整正文由发布服务器接收入本地队列;
- 当前会话的发布服务器没有已知内部错误。
如果监控系统只保留 code=250, success=true,上述差异会全部消失。可用证据必须连同协议、连接、命令、命令前状态、命令后状态、答复组件和被判断对象一起保存。数字只是索引,不能独立承担事实。
后来的投稿架构把角色写得更清楚
RFC 6409后来把邮件投稿正式放在 587 端口,并区分 Message Submission Agent 与 Message Transfer Agent。前者从用户代理接收消息,可以自行投递,也可以交给 MTA 中继;投稿和转运可以实施不同政策与安全机制。
这段后史只能用来说明角色分工长期有价值,不能凭相似性宣称 RFC 1204 导致了后来的标准,更不能证明 MPP 仍在运行。恰当的结论更窄:只要投稿和投递不是同一个决定,本地成功就不应冒充全链路结果。
RFC 1204 留下了一堂很现代的课。模糊有时不是数据质量问题,而是隐私控制;肯定代码有时只允许进入下一状态,而不确认输入对象;本地队列的确接住了消息,却没有获得替下游宣布成功的权力。
来源
会员简报
档案背景详情
使用相应会员等级登录,即可解锁完整简报与来源注释。
仅限 Strategic Circle
Strategic Circle
所有读者均可浏览。加入并登录后可解锁档案简报。
加入 Strategic Circle仅限 Leadership Alliance
Leadership Alliance
符合条件的 IP 资产所有者和管理层可登录查看 Leadership Alliance 简报。
加入 Leadership Alliance
