diff --git a/markbase-core/src/ssh_server/channel.rs b/markbase-core/src/ssh_server/channel.rs index d5abb34..543f495 100644 --- a/markbase-core/src/ssh_server/channel.rs +++ b/markbase-core/src/ssh_server/channel.rs @@ -72,6 +72,7 @@ impl ChannelManager { window_size: initial_window_size, maximum_packet_size, state: ChannelState::Open, + output_buffer: None, // Phase 6: 初始化为空 }; self.channels.insert(server_channel, channel); @@ -136,7 +137,14 @@ impl ChannelManager { info!("Exec command: {}", command); - // 简化实现:返回成功(实际应执行命令) + // 执行命令(Phase 6实现基础命令执行) + let output = self.execute_command(&command)?; + + // 存储输出,等待后续发送CHANNEL_DATA + if let Some(ch) = self.channels.get_mut(&channel) { + ch.output_buffer = Some(output); + } + if want_reply { Ok(Some(self.build_channel_success(channel)?)) } else { @@ -144,6 +152,26 @@ impl ChannelManager { } } + /// 执行命令并捕获输出(Phase 6基础实现) + fn execute_command(&self, command: &str) -> Result> { + use std::process::{Command, Stdio}; + + info!("Executing command: {}", command); + + // 使用shell执行命令(参考OpenSSH session.c) + let output = Command::new("sh") + .arg("-c") + .arg(command) + .output()?; + + // 返回stdout + stderr + let mut result = output.stdout; + result.extend_from_slice(&output.stderr); + + info!("Command output: {} bytes", result.len()); + Ok(result) + } + /// 处理subsystem请求(参考OpenSSH channel.c: channel_request_subsystem()) fn handle_subsystem_request(&mut self, cursor: &mut std::io::Cursor<&[u8]>, channel: u32, want_reply: bool) -> Result> { info!("Handling subsystem request for channel {}", channel); @@ -362,7 +390,7 @@ impl ChannelManager { } /// 构建SSH_MSG_CHANNEL_CLOSE(参考OpenSSH channel.c) - fn build_channel_close(&self, channel: u32) -> Result { + pub fn build_channel_close(&self, channel: u32) -> Result { let mut payload = Vec::new(); payload.write_u8(PacketType::SSH_MSG_CHANNEL_CLOSE as u8)?; @@ -370,6 +398,52 @@ impl ChannelManager { Ok(SshPacket::new(payload)) } + + /// 构建SSH_MSG_CHANNEL_DATA(Phase 6新增) + pub fn build_channel_data(&self, channel: u32, data: &[u8]) -> Result { + let mut payload = Vec::new(); + + payload.write_u8(PacketType::SSH_MSG_CHANNEL_DATA as u8)?; + payload.write_u32::(channel)?; + payload.write_u32::(data.len() as u32)?; + payload.write_all(data)?; + + Ok(SshPacket::new(payload)) + } + + /// 构建SSH_MSG_CHANNEL_EOF(Phase 6新增) + pub fn build_channel_eof(&self, channel: u32) -> Result { + let mut payload = Vec::new(); + + payload.write_u8(PacketType::SSH_MSG_CHANNEL_EOF as u8)?; + payload.write_u32::(channel)?; + + Ok(SshPacket::new(payload)) + } + + /// 获取有输出待发送的channel ID(Phase 6新增) + pub fn get_channel_with_output(&self) -> Option { + for (&id, channel) in &self.channels { + if channel.output_buffer.is_some() { + return Some(id); + } + } + None + } + + /// 获取channel输出(Phase 6新增) + pub fn get_channel_output(&mut self, channel_id: u32) -> Option> { + if let Some(channel) = self.channels.get_mut(&channel_id) { + channel.output_buffer.take() + } else { + None + } + } + + /// 移除channel(Phase 6新增) + pub fn remove_channel(&mut self, channel_id: u32) { + self.channels.remove(&channel_id); + } } /// SSH Channel结构(参考OpenSSH channel.c: struct channel) @@ -380,6 +454,7 @@ struct Channel { window_size: u32, maximum_packet_size: u32, state: ChannelState, + output_buffer: Option>, // Phase 6: 命令输出缓冲 } /// SSH Channel状态(参考OpenSSH channel.c) diff --git a/markbase-core/src/ssh_server/server.rs b/markbase-core/src/ssh_server/server.rs index 8e03651..c374310 100644 --- a/markbase-core/src/ssh_server/server.rs +++ b/markbase-core/src/ssh_server/server.rs @@ -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 => {