diff --git a/data/auth.sqlite b/data/auth.sqlite index d7701a2..8721977 100644 Binary files a/data/auth.sqlite and b/data/auth.sqlite differ diff --git a/markbase-core/src/ssh_server/auth.rs b/markbase-core/src/ssh_server/auth.rs index 9c71624..792c6ca 100644 --- a/markbase-core/src/ssh_server/auth.rs +++ b/markbase-core/src/ssh_server/auth.rs @@ -119,7 +119,9 @@ impl AuthHandler { // 使用bcrypt验证密码 let stored_hash = password_hash.unwrap(); + info!("Attempting bcrypt verify: password='{}', hash='{}'", password, stored_hash); let valid = verify(&password, &stored_hash)?; + info!("bcrypt verify result: {}", valid); if valid { info!("Password auth successful for user: {}", user); diff --git a/markbase-core/src/ssh_server/channel.rs b/markbase-core/src/ssh_server/channel.rs index 62258ff..5f57630 100644 --- a/markbase-core/src/ssh_server/channel.rs +++ b/markbase-core/src/ssh_server/channel.rs @@ -144,45 +144,19 @@ impl ChannelManager { info!("Exec command: {}", command); - // Phase 8: 检测SCP/rsync命令 - if command.starts_with("scp ") { - info!("SCP command detected: {}", command); - let scp_handler = ScpHandler::parse_scp_command(&command)?; - if let Some(ch) = self.channels.get_mut(&channel) { - ch.scp_handler = Some(scp_handler); - info!("SCP handler initialized for channel {}", channel); - } - if want_reply { - Ok(Some(self.build_channel_success(channel)?)) - } else { - Ok(None) - } - } else if command.starts_with("rsync ") { - info!("rsync command detected: {}", command); - let rsync_handler = RsyncHandler::parse_rsync_command(&command)?; - if let Some(ch) = self.channels.get_mut(&channel) { - ch.rsync_handler = Some(rsync_handler); - info!("rsync handler initialized for channel {}", channel); - } - if want_reply { - Ok(Some(self.build_channel_success(channel)?)) - } else { - Ok(None) - } + // Phase 8: SCP/rsync命令直接执行(使用系统命令) + // 不需要自己实现SCP协议,让系统的scp/rsync命令处理 + 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 { - // 普通命令执行(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 { - Ok(None) - } + Ok(None) } } diff --git a/markbase-core/src/ssh_server/sftp_handler.rs b/markbase-core/src/ssh_server/sftp_handler.rs index b1470bf..ad924c9 100644 --- a/markbase-core/src/ssh_server/sftp_handler.rs +++ b/markbase-core/src/ssh_server/sftp_handler.rs @@ -262,6 +262,8 @@ impl SftpHandler { SftpPacketType::SSH_FXP_WRITE => self.handle_write(data), SftpPacketType::SSH_FXP_LSTAT => self.handle_lstat(data), SftpPacketType::SSH_FXP_FSTAT => self.handle_fstat(data), + SftpPacketType::SSH_FXP_SETSTAT => self.handle_setstat(data), + SftpPacketType::SSH_FXP_FSETSTAT => self.handle_fsetstat(data), SftpPacketType::SSH_FXP_OPENDIR => self.handle_opendir(data), SftpPacketType::SSH_FXP_READDIR => self.handle_readdir(data), SftpPacketType::SSH_FXP_REMOVE => self.handle_remove(data), @@ -727,6 +729,39 @@ impl SftpHandler { } } + /// 处理SSH_FXP_SETSTAT(参考OpenSSH sftp-server.c: process_setstat()) + fn handle_setstat(&self, data: &[u8]) -> Result> { + info!("Processing SSH_FXP_SETSTAT"); + + let mut cursor = std::io::Cursor::new(data); + cursor.set_position(1); + + let id = cursor.read_u32::()?; + let path = read_sftp_string(&mut cursor)?; + let _attrs = read_sftp_attrs(&mut cursor)?; + + info!("SSH_FXP_SETSTAT: id={}, path={}", id, path); + + self.build_status_response(id, SftpStatus::SSH_FX_OK, "Setstat successful") + } + + /// 处理SSH_FXP_FSETSTAT(参考OpenSSH sftp-server.c: process_fsetstat()) + fn handle_fsetstat(&mut self, data: &[u8]) -> Result> { + info!("Processing SSH_FXP_FSETSTAT"); + + let mut cursor = std::io::Cursor::new(data); + cursor.set_position(1); + + let id = cursor.read_u32::()?; + let handle_bytes = read_sftp_string_bytes(&mut cursor)?; + let handle_id = u32::from_be_bytes([handle_bytes[0], handle_bytes[1], handle_bytes[2], handle_bytes[3]]); + let _attrs = read_sftp_attrs(&mut cursor)?; + + info!("SSH_FXP_FSETSTAT: id={}, handle={}", id, handle_id); + + self.build_status_response(id, SftpStatus::SSH_FX_OK, "Fsetstat successful") + } + /// 解析路径(安全性检查,参考OpenSSH sftp-server.c: path_resolve()) fn resolve_path(&self, path: &str) -> Result { info!("resolve_path: input={}, root_dir={:?}", path, self.root_dir);