SSH Padding计算修复:符合RFC 4253规范 ✅
修复内容: - 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功能
This commit is contained in:
@@ -67,27 +67,42 @@ pub struct SshPacket {
|
|||||||
impl SshPacket {
|
impl SshPacket {
|
||||||
/// 创建新的SSH packet
|
/// 创建新的SSH packet
|
||||||
pub fn new(payload: Vec<u8>) -> Self {
|
pub fn new(payload: Vec<u8>) -> Self {
|
||||||
// 计算padding(SSH协议要求:packet总长度必须是block_size的倍数)
|
// 计算padding(SSH协议RFC 4253规范)
|
||||||
// 参考OpenSSH:block_size = 8(未加密阶段)
|
// 参考OpenSSH packet.c: construct_packet()
|
||||||
let block_size = 8;
|
let block_size = 8; // 未加密阶段block_size=8
|
||||||
|
|
||||||
// packet_length = padding_length + payload_length + 1 (type byte)
|
|
||||||
let payload_length = payload.len();
|
let payload_length = payload.len();
|
||||||
let min_padding = 4; // OpenSSH要求最少4字节padding
|
let min_padding = 4; // OpenSSH要求最少4字节padding
|
||||||
|
|
||||||
// 计算padding长度
|
// SSH协议约束:
|
||||||
let total_without_mac = 1 + payload_length; // padding_length byte + payload
|
// packet_length = padding_length + payload_length + 1
|
||||||
let padding_needed = (block_size - (total_without_mac % block_size)) % block_size;
|
// (packet_length + 4) 必须是block_size的倍数
|
||||||
let padding_length = std::cmp::max(min_padding as u32, padding_needed as u32) as u8;
|
//
|
||||||
|
// 计算:
|
||||||
|
// (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 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];
|
let padding = vec![0u8; padding_length as usize];
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
packet_length: packet_length as u32,
|
packet_length,
|
||||||
padding_length,
|
padding_length,
|
||||||
payload,
|
payload,
|
||||||
padding,
|
padding,
|
||||||
|
|||||||
Reference in New Issue
Block a user