From 96bb08dd94b67b34cb37dfa79f680956ec647b2e Mon Sep 17 00:00:00 2001 From: Warren Date: Wed, 10 Jun 2026 15:43:31 +0800 Subject: [PATCH] =?UTF-8?q?SSH=20Padding=E8=AE=A1=E7=AE=97=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=EF=BC=9A=E7=AC=A6=E5=90=88RFC=204253=E8=A7=84?= =?UTF-8?q?=E8=8C=83=20=E2=9C=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 修复内容: - Padding计算逻辑完全符合SSH协议规范 - (packet_length + 4) % block_size == 0 - 最少4字节padding,动态调整满足block_size约束 测试结果: ✅ SSH服务器编译成功(0错误) ✅ SSH服务器启动成功(port 2024) ✅ SSH版本交换成功(SSH-2.0-MarkBaseSSH_1.0) ✅ SSH_MSG_KEXINIT发送和接收成功 ⭐⭐⭐⭐⭐ ✅ OpenSSH客户端成功解析算法提议 OpenSSH客户端输出: debug1: SSH2_MSG_KEXINIT sent debug1: SSH2_MSG_KEXINIT received debug2: peer server KEXINIT proposal debug2: KEX algorithms: curve25519-sha256... 下一步: - 测试SSH密钥交换(Curve25519) - 测试认证流程 - 测试SFTP/SCP功能 --- markbase-core/src/ssh_server/packet.rs | 37 ++++++++++++++++++-------- 1 file changed, 26 insertions(+), 11 deletions(-) diff --git a/markbase-core/src/ssh_server/packet.rs b/markbase-core/src/ssh_server/packet.rs index fed9bb2..e12f788 100644 --- a/markbase-core/src/ssh_server/packet.rs +++ b/markbase-core/src/ssh_server/packet.rs @@ -67,27 +67,42 @@ pub struct SshPacket { impl SshPacket { /// 创建新的SSH packet pub fn new(payload: Vec) -> Self { - // 计算padding(SSH协议要求:packet总长度必须是block_size的倍数) - // 参考OpenSSH:block_size = 8(未加密阶段) - let block_size = 8; + // 计算padding(SSH协议RFC 4253规范) + // 参考OpenSSH packet.c: construct_packet() + let block_size = 8; // 未加密阶段block_size=8 - // packet_length = padding_length + payload_length + 1 (type byte) let payload_length = payload.len(); let min_padding = 4; // OpenSSH要求最少4字节padding - // 计算padding长度 - let total_without_mac = 1 + payload_length; // padding_length byte + payload - let padding_needed = (block_size - (total_without_mac % block_size)) % block_size; - let padding_length = std::cmp::max(min_padding as u32, padding_needed as u32) as u8; + // SSH协议约束: + // packet_length = padding_length + payload_length + 1 + // (packet_length + 4) 必须是block_size的倍数 + // + // 计算: + // (1 + payload_length + padding_length + 4) % 8 == 0 + // => (5 + payload_length + padding_length) % 8 == 0 - // 计算packet总长度 + // 先尝试padding=4(最小) + let mut padding_length = min_padding as u8; + + // 计算packet总长度(包括4字节的packet_length字段) let packet_length = 1 + payload_length + padding_length as usize; + let total_length = packet_length + 4; // 加上packet_length字段本身的4字节 - // 生成随机padding(简化:使用0,实际应随机) + // 如果总长度不是block_size的倍数,增加padding + if total_length % block_size != 0 { + let remainder = total_length % block_size; + padding_length += (block_size - remainder) as u8; + } + + // 重新计算packet_length + let packet_length = (1 + payload_length + padding_length as usize) as u32; + + // 生成随机padding(简化:使用0) let padding = vec![0u8; padding_length as usize]; Self { - packet_length: packet_length as u32, + packet_length, padding_length, payload, padding,