摘要

  • RFC 1505 用可选的 Encoding 邮件头排列正文各部分的行数、类型与解码顺序。正确解析只能说明“发送方如何描述这些字节”,不能直接证明内容可信、安全或可执行。
  • 它能携带文件所有者、组、ACL、口令、应用程序等属性,也能标记包含命令的 SHAR;规范明确反对自动执行,并把是否设置口令和权限的责任交给控制解码器的本地应用域。
  • 普通署名区、PGP/PEM 保护、行数、CRC、IANA 注册词与实际效果分别是不同证据。把其中任意一项显示成统一的“已验证”,都会丢掉权力从描述跨到行动的那一步。

同一个词先分成了两种事实

RFC 1505 的 Signature 并不天然表示密码学结果。它定义的可以是邮件或 Usenet 帖子末尾的普通署名区:几行姓名、一句格言,通常由发送软件自动附加。字段中的写法可能只是 Text Signature,意思是“这一段文本属于署名”。

密码学处理另有名字。PEM、PEM-Clear 与 PGP 各自指向加密、完整性校验、公钥材料或分离式签名等内部结构。即便解码器看见 PGP,也还需要确定实际覆盖的字节、算法结果、密钥来源,以及本地是否信任该密钥与所声称的姓名。

于是,三个看起来很近的状态必须拆开:发送方称某段是署名;密码学程序验证某组字节;接收方相信某个主体有权发送或授权内容。RFC 1505 没有给它们一个共同的绿色指示灯。

文档甚至提醒,PGP 后面嵌套的 Text 或 EDI-X12 仍可能暴露内容类别,成为流量分析线索。加密成功也不等于所有信息都已隐藏。一个字段可以同时提供格式线索、保护方式和展示建议,却仍没有完成身份与权限判断。

行数让旧式正文拥有了边界

RFC 822 把邮件分成头部与正文,两者以空行相隔。RFC 1505 不愿在正文里反复插入会干扰旧软件的结构标记,于是把正文各部分的说明放进一个 Encoding 字段。

每个子项对应正文中按出现顺序排列的一部分。它可以先写十进制行数,再写一个或多个关键字。分隔空行只含 CRLF,不计入前后任一部分。最后或唯一一部分可以省略行数。数字一定以数字开头,关键字一定以字母开头,接收程序因而能够区分两者。

嵌套关键字有顺序。编码器按实际变换的相反顺序写入名称;解码器从左到右还原。例如 uuencode LZW tar 不是三个随便排列的能力标签,而是一条具体处理路径。

括号注释则被明确降级。程序可以把注释交给客户端,但不能用它决定内容如何解释。这个小规则已经在区分展示语言与执行语言:人能看到的说明不必获得控制解析器的权力。

这是实验分支,不是 MIME 的草稿

Albert Costanzo、David Robinson 与 Robert Ullmann 在 1993 年 8 月发布 RFC 1505。它属于 Experimental,不是 Internet Standard,并取代了 1990 年的 RFC 1154。

第一页的 IESG 注释很关键:同一领域已有 standards-track 技术,即 RFC 1341 的 MIME。RFC 1505 因此不是一条必然通向今天 MIME 的早期直线,而是 MIME 已在标准轨道上时仍被记录的一种实验方案。

后来的 RFC 2045 修订了 MIME 自身经 RFC 1521、1522 与 1590 延伸的谱系。它采用 MIME-Version、Content-Type、Content-Transfer-Encoding 与正文内的分界线来表达结构。可以比较两套设计如何面对旧邮件系统,却不能据此宣称 MIME 正式废止了 RFC 1505,或 RFC 1505 的每个选择都进入了 MIME。

这段并行历史的价值不在胜负,而在取舍。RFC 1505 想让旧阅读器仍看到普通正文,同时让新程序从隐藏在邮件头中的说明恢复多段、多层内容。描述越紧凑,接收端越需要知道每个词究竟只承诺了什么。

解出 SHAR 后,行动才刚开始

RFC 1505 支持 SHAR,也就是 shell archive,却明确不推荐使用。它警告:归档中可能带有收件人并不希望执行的命令,解码器不应自动运行还原出的 shell 语句;今后凡包含接收端命令的类型,也适用同一警告。

这意味着“成功”至少有五层。邮件头被正确解析;归档被正确还原;内容被识别为命令;本地规则或人员允许运行;运行后产生了可观察效果。前三层可以自动完成,第四层不能从前三层推导出来,第五层更不能靠格式标签代替。

如果系统在看见注册关键字后立即调用解释器,发送者就借一个描述词取得了接收机器上的行动权。若系统完全拒绝展示,合法内容又可能永远无法使用。安全边界不是“不解码”,而是让解码与执行之间保留可审计的本地决定。

文件带来了另一个世界的权限

RFC 1505 的 FS 编码比普通附件更有野心。它能表示目录、条目、文件、分段与数据,目标是在不同操作系统之间搬运结构化文件并尽可能保存共同属性。

属性包括显示名称、注释、类型、创建与修改及访问时间、所有者、组、ACL、口令、块大小、记录大小和创建应用。ACL 还能列出读、写、执行、删除、修改保护等权限。发送的不只是字节,还有一套关于这些字节应如何被管理的说法。

但源系统的数字所有者可能在目标系统指向完全不同的账户。源端的 $SYSTEM 未必对应目标端管理员。一个可以执行的权限字母也未必能无损映射到另一种保护模型。时间精度也会损失:目标文件系统若表示不了收到的精度,RFC 1505 要求解码器忽略超出的部分。

因此“恢复全部属性”并不总比“报告无法映射”更忠实。未经说明地把外来身份压进本地账户,可能保存了字段,却改写了权力。

明文口令把责任写得最清楚

FS 中甚至可以出现 password 属性,携带该项目的访问口令。RFC 1505 认为内容本身也紧随其后,因此明文出现口令不被单独视为安全问题。但它马上加上限制:若解码器真的把口令设置在新建项目上,安全或不安全由控制解码器的应用域负责;ACL 与其他保护同理。

发送方可以提供一个名为口令的字符串,却不能凭字段名决定它应成为本地秘密、覆盖已有保护、证明账户等价,或满足当前政策。接收端需要保留源值,把它转换为本地提案,显示语义损失,再记录谁批准了实际设置。

把外来保护静默复制过去看似省事,实质上可能是远端对本地授权的一次隐形改写。

CRC 验的是字节,不是权力

LZJU90 把压缩结果转成可打印字符,字符集特意选择为能够经受 ASCII 与 EBCDIC 之间的转换。编码结尾包含原始字节数与 CRC;解压所得的数量和 CRC 应与之相符。邮件头里的行数则核对编码文本占用了多少行。

两种检查都很有用,也都很窄。行数能帮助定位部分,字节数和 CRC 能暴露传输或解压错误。它们不认证发送人,不证明关键字如实,不授权执行 SHAR,也不认可 ACL。

调查时至少要保留:原始邮件哈希和头部;各部分行区间与关键字顺序;解析器及解码器版本;输出哈希;长度、CRC 或密码学结果;源端所有者与权限;本地映射和批准人;实际创建、执行与业务效果。

缺失一张凭据时,界面应显示缺口,而不是借最近的一次成功把整条链染绿。

注册协调词义,不替实现背书

RFC 1505 要求非私有的新关键字向 IANA 注册,把 X- 前缀永久留给实现自用。注册能减少命名冲突,让不同开发者更可能用同一个词描述同一种编码。

它没有证明某台机器支持该方法,没有审查每个解码器是否安全,也没有赋予内容自动运行的权利。注册表协调共同词汇;运行代码、本地政策和实际效果分别提供后续证据。

这正是 RFC 1505 留下的边界:共享语法可以使一个提案被认出来,不能使它在陌生机器上成为命令。

资料没有证明什么

这些 RFC 能证明格式、文档状态、警告与谱系,不能证明部署数量、某个邮件软件实现了 FS 或 SHAR、真实用户收到过恶意归档,或某条 ACL、口令真的由邮件安装。

RFC 1341 与 RFC 2045 记录 MIME 的标准轨道,不能证明 RFC 1505 被 MIME 正式废止。RFC 发布不是运行证据;CRC 匹配不是作者认证;IANA 注册不是安全认证;外来权限列表也不会凭传输自动创造本地主体。

邮件头能告诉机器包裹声称如何打开。打开之后能做什么,仍必须由承担后果的系统决定。

来源