Update Phase 6: Fix SFTP subsystem initialization and data handling
Some checks failed
Test / test (push) Has been cancelled
Test / build (push) Has been cancelled

Phase 6 updates:
- Add SftpHandler integration in Channel structure
- Initialize SFTP handler on subsystem request
- Handle SFTP packets via CHANNEL_DATA
- Fix CHANNEL_DATA response handling in server loop

Phase 7 progress:
- SFTP subsystem initialization working
- SSH_FXP_INIT/VERSION handshake working
- SFTP packet format partially implemented
- Need further debugging for complete SFTP functionality

Current status:
- SSH command execution fully working (Phase 6 ✓)
- SFTP connection initialization working
- File transfer operations pending debug
This commit is contained in:
Warren
2026-06-15 10:50:08 +08:00
parent 723482f59a
commit 1be361d91a
2 changed files with 54 additions and 7 deletions

View File

@@ -8,6 +8,8 @@ use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
use log::{info, warn, debug};
use std::collections::HashMap;
use std::sync::{Arc, Mutex};
use crate::ssh_server::sftp_handler::SftpHandler; // Phase 7: SFTP handler
use std::path::PathBuf; // Phase 7: Path for SFTP root directory
/// SSH Channel管理器参考OpenSSH channel.c: struct channel
pub struct ChannelManager {
@@ -73,6 +75,7 @@ impl ChannelManager {
maximum_packet_size,
state: ChannelState::Open,
output_buffer: None, // Phase 6: 初始化为空
sftp_handler: None, // Phase 7: 初始化为空
};
self.channels.insert(server_channel, channel);
@@ -184,7 +187,17 @@ impl ChannelManager {
// 检查subsystem支持OpenSSH支持sftp
if subsystem == "sftp" {
info!("SFTP subsystem requested");
// Phase 7将实现SFTP
// Phase 7: 初始化SFTP handler
let root_dir = PathBuf::from("/Users/accusys/markbase"); // 默认root目录
let sftp_handler = SftpHandler::new(root_dir);
// 存储到channel
if let Some(ch) = self.channels.get_mut(&channel) {
ch.sftp_handler = Some(sftp_handler);
info!("SFTP handler initialized for channel {}", channel);
}
if want_reply {
Ok(Some(self.build_channel_success(channel)?))
} else {
@@ -258,10 +271,10 @@ impl ChannelManager {
}
/// 处理SSH_MSG_CHANNEL_DATA参考OpenSSH channel.c: channel_input_data())
pub fn handle_channel_data(&mut self, packet: &SshPacket) -> Result<()> {
pub fn handle_channel_data(&mut self, packet: &SshPacket) -> Result<Option<SshPacket>> {
info!("Processing SSH_MSG_CHANNEL_DATA");
let mut cursor = std::io::Cursor::new(packet.payload.as_slice()); // 使用as_slice()Rust标准
let mut cursor = std::io::Cursor::new(packet.payload.as_slice());
// Packet type
let packet_type = cursor.read_u8()?;
@@ -273,13 +286,41 @@ impl ChannelManager {
let recipient_channel = cursor.read_u32::<BigEndian>()?;
// 读取数据SSH string
let data = read_ssh_string(&mut cursor)?;
let data_length = cursor.read_u32::<BigEndian>()?;
let mut data = vec![0u8; data_length as usize];
cursor.read_exact(&mut data)?;
info!("Channel data: channel={}, length={}", recipient_channel, data.len());
info!("Channel data content (first 20 bytes): {:?}", &data[..std::cmp::min(20, data.len())]);
// 简化实现:接受数据(实际应处理)
// Phase 7: 检查是否是SFTP channel
if let Some(channel) = self.channels.get_mut(&recipient_channel) {
if let Some(sftp_handler) = &mut channel.sftp_handler {
info!("Processing SFTP request ({} bytes)", data.len());
// SFTP data是SSH string格式前4 bytes是length field
// 真正的SFTP packet从data[4]开始跳过length field
if data.len() < 4 {
warn!("SFTP data too short (less than 4 bytes)");
return Ok(None);
}
let sftp_packet_length = u32::from_be_bytes([data[0], data[1], data[2], data[3]]) as usize;
let sftp_packet = &data[4..4 + sftp_packet_length];
info!("SFTP packet: length={}, content={:?}", sftp_packet_length, &sftp_packet[..std::cmp::min(20, sftp_packet.len())]);
// 处理SFTP请求
let response = sftp_handler.handle_request(sftp_packet)?;
info!("SFTP response: {} bytes", response.len());
// 构建SSH_MSG_CHANNEL_DATA返回SFTP响应需要SSH string格式
return Ok(Some(self.build_channel_data(recipient_channel, &response)?));
}
}
Ok(())
// 如果不是SFTP返回NonePhase 6的普通channel data处理
Ok(None)
}
/// 处理SSH_MSG_CHANNEL_CLOSE参考OpenSSH channel.c: channel_input_close())
@@ -455,6 +496,7 @@ struct Channel {
maximum_packet_size: u32,
state: ChannelState,
output_buffer: Option<Vec<u8>>, // Phase 6: 命令输出缓冲
sftp_handler: Option<SftpHandler>, // Phase 7: SFTP处理器
}
/// SSH Channel状态参考OpenSSH channel.c