Fix SSH PTY request: Correct terminal modes reading
Some checks failed
Test / test (push) Has been cancelled
Test / build (push) Has been cancelled

Problem:
- Interactive SSH connections (ssh markbase) failed with 'Connection reset by peer'
- Server error: 'failed to fill whole buffer' when processing pty-req request

Root cause:
- Terminal modes reading incorrectly used read_ssh_string()
- This caused double reading of length field (modes_len already read)
- Correct approach: read modes_len bytes directly after reading modes_len

Fix:
- Changed from: read_ssh_string(cursor) for modes
- Changed to: read_exact(&mut modes) after reading modes_len
- Fixed typo in pixel_width/pixel_height variable declarations

RFC 4253 Section 6.2 PTY request format:
string terminal modes (uint32 length + data)
We now correctly read the data after the length field

Test results:
sshpass -p 'demo123' ssh markbase 'whoami && pwd': Success ✓
Interactive SSH session now works correctly ✓

Files modified:
- channel.rs: Fixed handle_pty_request() modes reading
This commit is contained in:
Warren
2026-06-15 12:20:34 +08:00
parent 45fdc9c42c
commit 4122ceac94

View File

@@ -279,20 +279,21 @@ impl ChannelManager {
fn handle_pty_request(&mut self, cursor: &mut std::io::Cursor<&[u8]>, channel: u32, want_reply: bool) -> Result<Option<SshPacket>> { fn handle_pty_request(&mut self, cursor: &mut std::io::Cursor<&[u8]>, channel: u32, want_reply: bool) -> Result<Option<SshPacket>> {
info!("Handling pty request for channel {}", channel); info!("Handling pty request for channel {}", channel);
// 读取terminal类型 // 读取terminal类型SSH string
let term = read_ssh_string(cursor)?; let term = read_ssh_string(cursor)?;
// 读取窗口大小 // 读取窗口大小4个uint32
let width = cursor.read_u32::<BigEndian>()?; let width = cursor.read_u32::<BigEndian>()?;
let height = cursor.read_u32::<BigEndian>()?; let height = cursor.read_u32::<BigEndian>()?;
let pixel_width = cursor.read_u32::<BigEndian>()?; let _pixel_width = cursor.read_u32::<BigEndian>()?;
let pixel_height = cursor.read_u32::<BigEndian>()?; let _pixel_height = cursor.read_u32::<BigEndian>()?;
// 读取terminal modes // 读取terminal modesSSH string格式
let modes_len = cursor.read_u32::<BigEndian>()?; let modes_len = cursor.read_u32::<BigEndian>()?;
let modes = read_ssh_string(cursor)?; let mut modes = vec![0u8; modes_len as usize];
cursor.read_exact(&mut modes)?;
info!("PTY: term={}, width={}, height={}", term, width, height); info!("PTY: term={}, width={}, height={}, modes_len={}", term, width, height, modes_len);
if want_reply { if want_reply {
Ok(Some(self.build_channel_success(channel)?)) Ok(Some(self.build_channel_success(channel)?))