Implement SSH Phase 6: Channel protocol with command execution
Phase 6 completed: - SSH_MSG_CHANNEL_OPEN handling - SSH_MSG_CHANNEL_OPEN_CONFIRMATION/FAILURE responses - SSH_MSG_CHANNEL_REQUEST handling (exec, env, shell, subsystem) - SSH_MSG_CHANNEL_DATA transmission (command output) - SSH_MSG_CHANNEL_EOF/CLOSE handling - Command execution via shell (sh -c) - Encrypted packet handling in service loop Test results: - SSH connection successful with channel creation - Command execution working: 'echo', 'whoami', 'pwd', 'ls' - Output correctly transmitted via CHANNEL_DATA - EOF and CLOSE properly sent after execution - Multiple commands working correctly Files modified: - channel.rs: Channel management, command execution, output buffering - server.rs: Encrypted service loop, channel output handling Progress: SSH implementation 95% complete (Phase 1-6)
This commit is contained in:
@@ -95,7 +95,7 @@ fn handle_connection_complete(stream: TcpStream) -> Result<()> {
|
||||
let mut channel_manager = ChannelManager::new();
|
||||
|
||||
// Phase 6-7: SSH服务循环(处理channel请求)
|
||||
handle_ssh_service_loop(&mut stream, &mut channel_manager)?;
|
||||
handle_ssh_service_loop(&mut stream, &mut channel_manager, &mut encryption_ctx)?;
|
||||
|
||||
info!("SSH session completed successfully");
|
||||
Ok(())
|
||||
@@ -278,23 +278,54 @@ AuthResult::Failure(message) => {
|
||||
fn handle_ssh_service_loop(
|
||||
stream: &mut TcpStream,
|
||||
channel_manager: &mut ChannelManager,
|
||||
encryption_ctx: &mut EncryptionContext,
|
||||
) -> Result<()> {
|
||||
info!("Starting SSH service loop (channel management)");
|
||||
|
||||
loop {
|
||||
let packet = SshPacket::read(stream)?;
|
||||
// 使用EncryptedPacket读取加密packet(Phase 6)
|
||||
let encrypted_packet = EncryptedPacket::read(stream, encryption_ctx, true)?;
|
||||
let packet = SshPacket::new(encrypted_packet.payload().to_vec());
|
||||
|
||||
match packet.payload.first() {
|
||||
Some(&pt) if pt == PacketType::SSH_MSG_CHANNEL_OPEN as u8 => {
|
||||
info!("Received SSH_MSG_CHANNEL_OPEN");
|
||||
let response = channel_manager.handle_channel_open(&packet)?;
|
||||
response.write(stream)?;
|
||||
let encrypted_response = EncryptedPacket::new(&response.payload, encryption_ctx, true)?;
|
||||
encrypted_response.write(stream)?;
|
||||
info!("Sent SSH_MSG_CHANNEL_OPEN_CONFIRMATION");
|
||||
}
|
||||
Some(&pt) if pt == PacketType::SSH_MSG_CHANNEL_REQUEST as u8 => {
|
||||
info!("Received SSH_MSG_CHANNEL_REQUEST");
|
||||
if let Some(response) = channel_manager.handle_channel_request(&packet)? {
|
||||
response.write(stream)?;
|
||||
let encrypted_response = EncryptedPacket::new(&response.payload, encryption_ctx, true)?;
|
||||
encrypted_response.write(stream)?;
|
||||
|
||||
// Phase 6: 检查是否有命令输出需要发送
|
||||
if let Some(channel_id) = channel_manager.get_channel_with_output() {
|
||||
if let Some(output) = channel_manager.get_channel_output(channel_id) {
|
||||
// 发送命令输出(SSH_MSG_CHANNEL_DATA)
|
||||
let data_packet = channel_manager.build_channel_data(channel_id, &output)?;
|
||||
let encrypted_data = EncryptedPacket::new(&data_packet.payload, encryption_ctx, true)?;
|
||||
encrypted_data.write(stream)?;
|
||||
info!("Sent command output ({} bytes)", output.len());
|
||||
|
||||
// 发送SSH_MSG_CHANNEL_EOF
|
||||
let eof_packet = channel_manager.build_channel_eof(channel_id)?;
|
||||
let encrypted_eof = EncryptedPacket::new(&eof_packet.payload, encryption_ctx, true)?;
|
||||
encrypted_eof.write(stream)?;
|
||||
info!("Sent SSH_MSG_CHANNEL_EOF");
|
||||
|
||||
// 发送SSH_MSG_CHANNEL_CLOSE
|
||||
let close_packet = channel_manager.build_channel_close(channel_id)?;
|
||||
let encrypted_close = EncryptedPacket::new(&close_packet.payload, encryption_ctx, true)?;
|
||||
encrypted_close.write(stream)?;
|
||||
info!("Sent SSH_MSG_CHANNEL_CLOSE");
|
||||
|
||||
// 移除channel
|
||||
channel_manager.remove_channel(channel_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Some(&pt) if pt == PacketType::SSH_MSG_CHANNEL_DATA as u8 => {
|
||||
@@ -303,7 +334,10 @@ fn handle_ssh_service_loop(
|
||||
}
|
||||
Some(&pt) if pt == PacketType::SSH_MSG_CHANNEL_CLOSE as u8 => {
|
||||
info!("Received SSH_MSG_CHANNEL_CLOSE");
|
||||
channel_manager.handle_channel_close(&packet)?;
|
||||
if let Some(response) = channel_manager.handle_channel_close(&packet)? {
|
||||
let encrypted_response = EncryptedPacket::new(&response.payload, encryption_ctx, true)?;
|
||||
encrypted_response.write(stream)?;
|
||||
}
|
||||
break;
|
||||
}
|
||||
Some(&pt) if pt == PacketType::SSH_MSG_DISCONNECT as u8 => {
|
||||
|
||||
Reference in New Issue
Block a user