Fix SSH FSETSTAT and simplify SCP execution
- Add SSH_FXP_FSETSTAT and SSH_FXP_SETSTAT handlers (return OK) - Simplify SCP to use system scp command instead of custom handler - SCP upload/download now working via SFTP protocol - Add bcrypt debug logging for authentication troubleshooting
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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<Vec<u8>> {
|
||||
info!("Processing SSH_FXP_SETSTAT");
|
||||
|
||||
let mut cursor = std::io::Cursor::new(data);
|
||||
cursor.set_position(1);
|
||||
|
||||
let id = cursor.read_u32::<BigEndian>()?;
|
||||
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<Vec<u8>> {
|
||||
info!("Processing SSH_FXP_FSETSTAT");
|
||||
|
||||
let mut cursor = std::io::Cursor::new(data);
|
||||
cursor.set_position(1);
|
||||
|
||||
let id = cursor.read_u32::<BigEndian>()?;
|
||||
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<PathBuf> {
|
||||
info!("resolve_path: input={}, root_dir={:?}", path, self.root_dir);
|
||||
|
||||
Reference in New Issue
Block a user