提供安全外壳报文与会话协议构件。
源码浏览已生成;不能解析的文件以纯文本展示,不表示通过类型检查。
# 安全外壳协议 基础 SSH/SSHD 入口、文件传输和服务端后续工作见 [后续工作.汉语.md](后续工作.汉语.md)。 包身份为 `豫言/安全外壳协议`,版本 `0.1.0`。本包依赖标准库与安全外壳密码包,测试另用单元测试;SSH 二进制编码(原在拓展库)已并入本包。 `报文。豫` 实现初始无加密、无 MAC 的 SSH 二进制报文和 RFC 5647 的 AES-256-GCM 报文。初始报文连同四字节长度按 8 字节对齐;GCM 报文以四字节长度作附加认证数据,明文为填充长度、载荷、随机填充,末尾接完整 16 字节标签。GCM 编码和解码均返回下一 IV;前四字节保持不变,后八字节按大端整数递增,溢出时拒绝继续。单包长度限制为 1 MiB,以免超过底层密码原语的界限。 `分帧。豫` 从 TCP 字节缓冲区提取首个完整明文或 GCM 报文,区分数据未到齐、报头非法和已提取三种结果,并保留多帧合并时的剩余字节。分帧只确定边界;GCM 标签仍须由报文解码接口认证。 `版本。豫` 增量解析服务器识别行,接受 SSH 2.0 和兼容标识 1.99,保留识别行后同批收到的字节,并限制前置提示内容为 8192 字节。`协商。豫` 编解初始 KEXINIT,验证十个名称列并提供完整算法名查找;原始协商载荷应留作后续交换哈希的输入。 `密钥交换。豫` 编码并解析 Curve25519 初报与服务端回报、计算 SHA-256 交换哈希,供服务端生成 Ed25519 主机密钥 blob 和交换签名。客户端验签接口要求预先可信的完整主机密钥 blob,先比对主机密钥再验签。共享秘密以原始大端无符号字节编码为 SSH 正数 mpint;零编码为空,必要时在最高位前补零。 `公钥文本。豫` 严格解析单行 OpenSSH `ssh-ed25519` 公钥:要求 68 字符无填充 Base64,解码后校验 51 字节 SSH key blob,并可分别返回完整 blob 或 32 字节公钥。允许单行注释与末尾 LF/CRLF,拒绝前置选项、第二行、控制字符和畸形编码。它不解析 `authorized_keys` 选项。 `私钥文本。豫` 读取未加密、单把 Ed25519 的 OpenSSH `openssh-key-v1` 私钥文本,返回 32 字节种子。它校验 PEM 外壳、规范 Base64、算法与字段边界、双 checkint、公钥与种子的匹配,以及八字节对齐填充;加密或其他算法的私钥返回无结果。客户端与服务端探针优先读取标准私钥文件,缺少该文件时兼容原始种子文件。 `已知主机。豫` 读取 `known_hosts` 中的 Ed25519 条目,按调用方给出的主机名精确匹配,支持逗号分隔的精确别名、`[主机]:端口` 写法和 OpenSSH `|1|盐|摘要` 哈希主机名;只有条目里的公钥与握手所呈密钥完全相同时才信任。匹配密钥的 `@revoked` 条目优先否决,即使文件里另有可信条目;`@revoked *` 可全域撤销该密钥。注释、空行和其他算法可并存。一般通配模式、否定模式和证书颁发机构条目尚不支持;使用这些形式的条目不会授予信任。 `授权公钥。豫` 从多行 `authorized_keys` 文本中查找精确匹配的 Ed25519 公钥,允许空行、注释与其他算法行。权限结果 0 表示未授权,1 表示允许 PTY,2 表示禁止 PTY;当前只接受无选项、`no-pty`、`restrict` 和 `restrict,no-pty` 条目,其他选项不授权。同一密钥多行取较严格限制,扫描不完整则拒绝授权。服务端执行禁止 PTY 的约束。`用户认证。豫` 可从指定用户和服务的公钥请求提取候选钥;提取不等于授权或验签,调用方仍须检查授权文件并调用完整请求验证接口。 两种主机与用户密钥文本解析均限制文件为 256 KiB、每行 4096 字节,最多扫描 4096 行;超过扫描限制而仍未完成核对时拒绝授权。 `派钥。豫` 按 RFC 4253 派生 A 至 F 六个方向的 SHA-256 密钥材料,支持长于 32 字节的续展,并提供 AES-256-GCM 双向密钥与 12 字节 IV、NEWKEYS 载荷。`服务。豫` 编解服务请求与接受载荷。 `会话。豫` 可编解 RFC 4254 的 `signal` 通道请求,严格要求 `want_reply=false`、单个非空信号名及完整尾界。解析不会直接向进程发信号;会话层只执行 RFC 所列的标准信号名,未知扩展名忽略。 `会话。豫` 还可编解 `exit-signal`:包括信号名、core dumped、错误文本和语言标签,拒绝非法布尔位、截断及尾随数据。豫言客户端可区分它与正常退出的 `exit-status`。 `传输控制。豫` 按 RFC 4253 编解 DISCONNECT、IGNORE、UNIMPLEMENTED 和 DEBUG,严格核对消息号、长度、完整尾界及 DEBUG 布尔位,拒绝零值断开原因码。调试文本以原始字节返回;显示前调用方须验证 UTF-8 并过滤终端控制字符。发送 DISCONNECT 后不得再收发 SSH 报文。 `全局请求。豫` 编解 RFC 4254 的 GLOBAL_REQUEST 与请求应答,验证非空 US-ASCII 请求名和严格布尔位,保留请求专属数据;未知请求若要求应答,应回 REQUEST_FAILURE。全局请求与通道报文可交错到达,调用方须分别维持双向 IV 和会话状态。 `用户认证。豫` 编码 `none` 探询和 Ed25519 公钥认证请求,解析认证失败与成功,并供服务端验证指定用户、服务、会话号和获授权公钥上的签名。公钥签名覆盖 SSH string 会话标识符和完整请求前缀。 `通道。豫` 编解 session 通道开启、确认、窗口调整、普通数据、扩展数据和 EOF/CLOSE,并检查共用流量窗口及最大数据包。`通道寿命。豫` 记录双向 EOF/CLOSE,拒绝重复结束消息、EOF 后的同向数据和关闭后的发送;本端先发 CLOSE 时仍允许接收对端在途数据。`会话。豫` 编解 PTY、终端窗口变化、shell、exec、env、请求应答和 exit-status;env 仅解析原始名称和值,是否允许应用环境由服务端另行决定。PTY 已知模式按 RFC 4254 以零操作码结束,遇未知扩展操作码停止解析。原生主从 PTY、窗口尺寸和非阻塞读写由独立的 `安全外壳终端` 包提供。 客户端互通验证已覆盖与 OpenSSH 服务端的版本、KEXINIT、Curve25519、可信主机签名、NEWKEYS、加密服务请求以及 Ed25519 公钥用户认证。一次性豫言服务端探针也已与 OpenSSH 客户端完成主机密钥校验、Curve25519 换钥、公钥认证及 session 通道开启;未授权公钥收到 USERAUTH_FAILURE,客户端随后能用获准密钥登录。连续 12 次认证失败时,OpenSSH 客户端收到加密的 DISCONNECT 原因码 14。无 PTY 时认证用户的 `exec` 命令由真实标准流子进程执行,返回实际 exit-status;有 PTY 时,受限的 `/usr/bin/tty` 真子进程输出经 CHANNEL_DATA 回传,受限的 `/bin/cat` 也能接收 CHANNEL_DATA、回补窗口并回传测试文本,客户端均以 0 退出。会话消息、原生 PTY、当前用户权限下的控制终端子进程,以及 channel 与 PTY 的双向字节桥接已通过本地验证;桥接层见独立的 `安全外壳会话` 包。服务端多连接长期运行与完整授权策略尚待接入;客户端互通探针和服务端均已按报文数自动发起通道运行期重协商,并分别与 OpenSSH 对端通过。调用者须为两个传输方向分别保存密钥和 IV。
# 安全外壳协议 基础 SSH/SSHD 入口、传文与服务者后续事,见 [后续工作.文言.md](后续工作.文言.md)。 包名「豫言/安全外壳协议」,版「0.1.0」。依标准库与安全外壳密码包,其试另用单元测试;SSH 字节编解码(旧在拓展库)今并入此包。 「报文。豫」兼作初握无密无签之 SSH 报文,及 RFC 5647 之 AES-256-GCM 报文。初握报文并四字节长须八字节齐;GCM 以四字节长为附加文验之,明文次为填长一字节、载物、随机填充,末附十六字节全签。GCM 编解皆还后续 IV;前四字节不变,后八字节作大端数递增,满则拒续。单报限一兆字节,毋逾底层密码术之界。 「分帧。豫」自 TCP 字节缓冲取首个完整明文或 GCM 报文,分未足、头非法、已得三途;多报同至,余字保留。分帧惟定边界,GCM 签仍须报文解码术验之。 「版本。豫」渐析彼之识别行,受 SSH 2.0 及兼容号 1.99,保同行后之余字,前置提示限八千一百九十二字节。「协商。豫」编解初始 KEXINIT,核十名称列,按全名寻算法;原协商载荷当留供后续交换哈希。 「密钥交换。豫」编析曲线初报与服务者回报,求 SHA-256 交换哈希,供服务者造 Ed25519 主钥载物及交换之签。客户验签须受预先可信之主钥全载物,先比主钥而后验签。共密以原大端无符号字节书为 SSH 正 mpint;零为空,首位高则冠零。 「公钥文本。豫」严析单行 OpenSSH `ssh-ed25519` 公钥:Base64 无填号,恰六十八字;解后核五十一字 SSH 钥载物,可返全载物或三十二字节公钥。容单行注及末尾 LF/CRLF,拒前置选项、第二行、控制字与坏编码。不析 `authorized_keys` 选项。 「私钥文本。豫」读 OpenSSH `openssh-key-v1` 未加密单把 Ed25519 私钥文,返三十二字私种。严核 PEM 甲胄、规范 Base64、算法与字段界、双 checkint、公钥与私种相应、八字节齐之尾填;加密或他算法钥皆返无。客户及服务者探针先读常式私钥文;若无,仍循原种文件。 「已知主机。豫」读 `known_hosts` 中 Ed25519 条目,逐字比调用者所给主机名,容逗号别名、`[主机]:端口` 及 OpenSSH `|1|盐|摘要` 隐名;所载钥与握手所呈者全同,乃信。若同钥有 `@revoked`,虽别行许之,亦拒;`@revoked *` 可遍撤此钥。注行、空行及他算法可并存。常通配、否名、证书权威条目今未备;此等行不授信。 「授权公钥。豫」于多行 `authorized_keys` 文逐一寻 Ed25519 钥,空行、注行与他算法行不妨。权限零为不授,一为许 PTY,二为禁 PTY;今惟纳无选项、`no-pty`、`restrict`、`restrict,no-pty`,余选项不授。同钥多行取严者,未扫尽则拒。服务者行禁 PTY 之限。「用户认证。豫」可自指定用户及服务之公钥报取候选钥;取钥非授权亦非验签,调用者须继查授权簿并验全报。 二种主机与用户钥文,皆限全篇二百五十六 KiB、逐行四千九十六字节,至多检四千九十六行;未核毕而逾限则不授权。 「派钥。豫」依 RFC 4253 派 A 至 F 六向之 SHA-256 钥材,过三十二字节则续展;并得 AES-256-GCM 二向钥及十二字节 IV、NEWKEYS 载物。「服务。豫」编解服务请求及接受载物。 「会话。豫」可编解 RFC 4254 之 `signal` 通道请,严核 `want_reply=false`、非空独名及尾界。析报不径发进程信号;会话层惟施 RFC 所列常名,未知扩展名暂略。 「会话。豫」亦编解 `exit-signal`:含信号名、转储爻、错误文及语言,拒坏布尔、断报与余字。豫言客户可别之于常退之 `exit-status`。 「传输控制。豫」依 RFC 4253 编解 DISCONNECT、IGNORE、UNIMPLEMENTED、DEBUG,严核报号、长度、尾界及 DEBUG 布尔,拒断开原因码零。调试文惟返原字,若欲示人,调用者须先验 UTF-8 且滤终端控制字。发 DISCONNECT 后不得复收发 SSH 报。 「全局请求。豫」编解 RFC 4254 之 GLOBAL_REQUEST 与应答,核非空 US-ASCII 名及严布尔,保专用余文;未知请求若待答,当回 REQUEST_FAILURE。全局请求与通道报可交错而至,调用者须别存二向 IV 及会话态。 「用户认证。豫」编 `none` 探问及 Ed25519 公钥认证请求,析败与成之报;又供服务者验定用户、服务、会话号及获准公钥之签。公钥签盖 SSH string 会话号与完整请求前文。 「通道。豫」编解 session 通道开请、确认、增窗、常数据、扩展数据及 EOF/CLOSE,核共用收窗与最大包。「通道寿命。豫」记二向 EOF/CLOSE,拒重终、彼终后之彼文及闭后己发;己先闭,彼在途之文犹可收。「会话。豫」编解 PTY、终端窗变、shell、exec、env 及请求应答;env 惟析名与值,允否施于进程由服务者别决。PTY 已知模式依 RFC 4254 以零码终,遇未知扩展码则止析。原生主从 PTY、尺寸与非阻塞读写由「安全外壳终端」包供之。 客户端已与 OpenSSH 服务者互通版本、KEXINIT、Curve25519、可信主钥签、NEWKEYS、加密服务请求,及 Ed25519 公钥用户认证。一次性豫言服务者探针亦与 OpenSSH 客互通主钥验真、曲线换钥、公钥认证及 session 开通;非获准钥获 USERAUTH_FAILURE,继用获准钥乃登成。连败十二次,OpenSSH 客得加密 DISCONNECT,原因码十四。无 PTY 时获准用户之 `exec` 命令由真标准流子进程行之,返实退码;有 PTY 时,`/usr/bin/tty` 真子进程之出由 CHANNEL_DATA 回,`/bin/cat` 亦能收 CHANNEL_DATA、回增窗与回测试文,客户皆以零退出。会话报、原生 PTY、当前用户权下控制终端子进程,及 channel 与 PTY 二向字节桥接皆已本地验;桥接见独立「安全外壳会话」包。服务者多连久行与完备授权策尚待接入;客户互通探针及服务者皆已依报数自发通道行中再议,并各与 OpenSSH 对端通。来往二向之钥与 IV 当分别存之。