Phase 17: SCP over SFTP subsystem + EOF/CLOSE fixes
Some checks failed
Test / test (push) Has been cancelled
Test / build (push) Has been cancelled

This commit is contained in:
Warren
2026-06-20 16:31:00 +08:00
parent 56217bc9a5
commit 5b439dfbef
3 changed files with 88 additions and 16 deletions

View File

@@ -655,6 +655,22 @@ fn handle_ssh_service_loop(
// Phase 17: EOF means client won't send more data → close child stdin
// (Essential for SCP upload where scp -t waits for EOF on stdin)
channel_manager.close_child_stdin();
// ⭐⭐⭐⭐⭐ Phase 17: Send SSH_MSG_CHANNEL_CLOSE in response to EOF
// ONLY for subsystem channels (no exec_process) — RFC 4254 §5.3
// For exec channels, wait for child exit → exit-status + EOF + CLOSE
let has_exec = packet.payload.len() >= 5 && {
let channel_id =
u32::from_be_bytes([packet.payload[1], packet.payload[2], packet.payload[3], packet.payload[4]]);
channel_manager.channel_has_exec_process(channel_id)
};
if !has_exec && packet.payload.len() >= 5 {
let channel_id =
u32::from_be_bytes([packet.payload[1], packet.payload[2], packet.payload[3], packet.payload[4]]);
let close_packet = channel_manager.build_channel_close(channel_id)?;
let encrypted_response =
EncryptedPacket::new(&close_packet.payload, encryption_ctx, true)?;
encrypted_response.write(stream)?;
}
}
Some(&pt) if pt == PacketType::SSH_MSG_DISCONNECT as u8 => {
info!("Received SSH_MSG_DISCONNECT");