重换钥。豫 保存首次 session_id 和本轮待启用的双向 AES-256-GCM 密钥、IV。调用方用旧钥发送并认证 NEWKEYS 后,分别切换发送和接收方向;状态接口拒绝同方向重复切换。豫言客户端与服务端互通探针均可在认证后、开启通道前主动发起一轮重协商;客户端已与真实 OpenSSH 服务端互通,服务端已与真实 OpenSSH 客户端互通。服务端会话与客户端互通探针现均按本轮任一方向报文数自动换钥,默认阈值 4096 包。
服务端重换钥。豫 验证客户端与服务端 KEXINIT 的曲线、主机密钥、双向 GCM 和无压缩候选项,再用客户端 ECDH_INIT、服务器临时种子和主机私种生成 ECDH_REPLY 与待切换密钥状态。它沿用首次 session_id;发送回报、收发 NEWKEYS 和切换方向仍由调用方负责。
重换钥传输。豫 将剩余密文缓冲和双向密钥、IV 保存为一个传输状态。服务端收到客户端 KEXINIT 后,可用此状态完成加密的 ECDH_INIT、ECDH_REPLY 与双向 NEWKEYS;发送 NEWKEYS 后才切换发送钥,验收对端 NEWKEYS 后才切换接收钥。服务端主动发起时,旧钥验证后先到的通道报文按顺序暂存,最多 16 条、合计 1 MiB,换钥后再交给桥接层。自动触发以本轮双向 IV 为基准,默认任一方向累计 4096 包即重换钥;计数器接近末界时提前触发。
应按时重换钥吗 接受本轮起始和当前的单调纳秒读数,阈值为 1 至 86400 秒;达到阈值返回真,时钟倒退则报错。客户端互通探针与服务端标准流、PTY 会话桥接均以默认 3600 秒间隔调用它,并在换钥后重置起始时间。服务端桥接与客户端单步收报后的就绪等待会周期返回以复查时限,半包不会使客户端一直阻塞到整帧到齐。
客户端重换钥传输。豫 在已打开的会话中收到服务端 KEXINIT 后,重新验证 Ed25519 主机签名,沿用首次 session_id 派钥,并在双向 NEWKEYS 边界切换。豫言客户端已与豫言服务端在无 PTY 小窗口输出和 PTY 数据回传中验证此路径。客户端也可在通道已打开后先发 KEXINIT,并有界暂存等待服务端协商期间收到的已认证通道报文;打开通道后、请求命令前的先发路径已与真实 OpenSSH 服务端互通。
客户端会话收包。豫 单步读取并认证一帧密报。未收齐时返回状态 0,完整通道或换钥载荷返回 1,合法传输控制、未知全局请求或窗口调整处理后返回 2;剩余密文、双向下一 IV 始终随结果返回。调用方可在状态 0 等待就绪并复查计时器,无需阻塞至整帧到齐。客户端互通探针在小窗口输出和空闲计时换钥路径中已使用该接口。
无 PTY 标准流和 PTY 双向桥接在收到已认证的客户端 KEXINIT 后保存当前窗口、EOF、待写数据和剩余网络缓冲,完成重换钥后以新密钥继续;退出报告和通道关闭也使用新发送密钥。关闭等待期若再收到 KEXINIT,服务端仍会尝试完成重协商;本端已发送 CLOSE 后,对端明确 DISCONNECT 或关闭连接可结束等待。客户端发起的运行中重协商已与真实 OpenSSH 的无 PTY、PTY 会话互通;服务端按报文数自动触发已与真实 OpenSSH 在两种会话中互通。客户端互通探针的按报文数及按时间自动触发亦已与真实 OpenSSH 服务端互通;客户端单步收包可在完整空闲或半包时周期复查时限。
标准流桥接。豫 为无 PTY 会话封装 stdout 的 CHANNEL_DATA 和 stderr 的 CHANNEL_EXTENDED_DATA,按两路共用的远端窗口及最大包限制读取。单步 stdin 写入返回实际写入量和未写尾部,供调用方按实际写入量回补接收窗口。标准流 EOF 分别返回,只有两路均结束后才应发送通道 EOF;标准流会话。豫 负责单通道加密收发与三路标准流就绪事件循环,调用方负责子进程、exit-status 和 CLOSE 生命周期。
双向转发终端 返回发送 IV、剩余网络字节、接收 IV、是否已收到客户端 EOF,以及当前发送和接收密钥。PTY 子进程可先退出;调用方据 EOF 标志记录通道寿命,并用返回的密钥发送 exit-status、EOF 和 CLOSE。
标准流与 PTY 双向桥接会识别本通道的 signal 请求,按 RFC 4254 标准信号名调用原生接口;仅向本库登记的子进程或 PTY 进程组发送,不回请求应答。未知扩展名忽略。豫言客户端与服务端已分别验证无 PTY、PTY 的 TERM 和 INT 请求及对应 exit-signal;正常退出仍发送 exit-status。
桥接。豫 在已认证、已打开的 SSH session channel 与本机 PTY 主端之间搬运原始字节。等待连接与伪终端 以同一次原生多路等待观察 SSH 套接字和 PTY,网络端始终关注可读,PTY 可选择不关注、可读、可写或读写;返回两个独立事件位和状态。入站先解析 CHANNEL_DATA 并扣减本端接收窗口,再尝试非阻塞写入 PTY;实际未写入的尾部原样返回。冲刷伪终端待写至尽 会等待可写并重试,返回累计写入量及剩余尾部;超时仍保留尾部,调用方须在继续接收网络数据前处理它。出站读取量不超过对端窗口、对端最大通道包和 64 KiB,并返回新的对端窗口。入站待写缓冲上限为 1 MiB。
状态 0 表示入站处理成功;负的普通数值为原生 -errno,-100001 至 -100004 为消息、通道、缓冲或参数错误,-100005 表示待写重试次数耗尽。出站状态 0 表示窗口阻塞,1 表示产生 CHANNEL_DATA,2 表示 PTY EOF 并产生 CHANNEL_EOF,负值为错误。调用方负责按实际已写入 PTY 的字节发送 WINDOW_ADJUST,并确保 EOF 只发送一次。本库不启动程序,也不维护整个 SSH 连接状态。
加密收包。豫 从已有 TCP 缓冲区优先提取并认证一帧 AES-256-GCM 报文;若未收齐,单步接口最多非阻塞读取 64 KiB,保留半包、粘包剩余字节和当前 IV。状态 0 表示等待更多数据,1 表示已得到一帧,2 表示连接关闭,负值表示报头、认证或网络错误。会话循环可在状态 0 时转去处理 PTY 事件。客户端和服务端互通探针均已使用该接口收取加密报文。
会话桥接收到已认证的传输控制载荷时,严格检查 IGNORE、UNIMPLEMENTED 和 DEBUG 的字段并继续会话;合法的 DISCONNECT 结束会话,格式错误的控制报文被拒绝。此处理适用于 PTY 和无 PTY 的会话循环。
通道运行期间收到 GLOBAL_REQUEST 时,两种桥接均检查名称和 want_reply 字段,保留请求专属数据但不执行未知请求;要求应答时发送 REQUEST_FAILURE,并更新发送方向的 IV 后继续原通道。不要求应答的请求直接跳过,非法报文终止会话。
加密发包。豫 处理加密帧的部分写入与可写等待,完整发出后才返回下一发送 IV;发送失败后调用方应终止此连接。双向终端。豫 是服务端单通道 PTY 桥接:交替处理网络和终端就绪事件,按实际写入回补接收窗口,按对端窗口发送数据,解析数据、增窗、EOF 和终端尺寸变化,保留接收缓冲与双向 IV。调用前须已完成认证与通道开启,并提供本地通道号 0、最大接收包 32768 字节及规范行 PTY;客户端 EOF 通过 EOT 传给终端。桥接不启动或回收子进程,也不发送 exit-status/CLOSE;这些由调用方完成。当前仍是单通道、有界空闲的会话接口,不处理会话中的其他 SSH 消息。