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,