From ac17e1725c20781ff913f786f21ad8d6bdde0e0d Mon Sep 17 00:00:00 2001 From: Warren Date: Sat, 20 Jun 2026 11:32:55 +0800 Subject: [PATCH] feat(ssh): Add SCP subsystem packet processing framework (Phase 8 partial) --- data/auth.sqlite | Bin 73728 -> 73728 bytes markbase-core/src/ssh_server/channel.rs | 60 ++++++++++++++++++++++++ 2 files changed, 60 insertions(+) diff --git a/data/auth.sqlite b/data/auth.sqlite index 09e7041c9839ca2fc0b12bdf8d20d4632baf3332..d92f7afbae2a3609cb5eb625c3b3212c89d92310 100644 GIT binary patch delta 707 zcmZwFze}4z7{Kvd?u~c;c=9T|(xw`dKsuL#CU1Veg}OLpu|qrACRrL%i;05@nikQa zgDr=Hbo4I>SLjkSPU0ZAI7nzI{y=Oiba>IB)YsR$_T>g|`rLPV?syt4tf>Q`uKIL?A^cqL8MfMqKRSbGX zztS)CBb}vBsY&mU3$o8+y#?ZrSS+?xlpuQ;bTt2m=L ptvIFFRGd_tP&^{d-<^NzLm~FaY07PL938EFwsqv_u%>K^?;0cv)TjUe delta 249 zcmZoTz|wGlWr8%L-$WT_M!$^-?J|rmlMhNMOy-ci&2C!pq=}>7ZSyNxRz?t~v98~B z@;ABP%s}?$FY?d%C6Dql%QEHW=ceYB6jibx<75_PN=ePlXFsy}i~a|GfupR>luu$Z`vstg z!ZO~?68GLPGMn;NPG)}q5@F}vT>18xAS3@|hyNQPZv6kBpRs@Y7k> = Vec::new(); + while let Some(newline_pos) = channel.scp_input_buffer.iter().position(|&b| b == b'\n') { + let line = channel.scp_input_buffer[..newline_pos].to_vec(); + channel.scp_input_buffer = channel.scp_input_buffer[newline_pos + 1..].to_vec(); + + info!("SCP command: {}", String::from_utf8_lossy(&line)); + + // Process SCP command + // TODO: Full implementation requires ScpHandler.handle_scp() with ReadWrite trait + // Current implementation: basic ACK (0 byte) + responses.push(vec![0]); // SCP ACK + } + + // Check for window adjust + if let Some(window_adjust_packet) = + channel_check_window(recipient_channel, &mut self.channels) + { + return Ok(Some(window_adjust_packet)); + } + + // Send SCP responses + if !responses.is_empty() { + // All responses except last go to pending_packets + for i in 0..responses.len().saturating_sub(1) { + let pending = self.build_channel_data(recipient_channel, &responses[i])?; + self.pending_packets.push_back(pending); + } + + // Last response is returned + if let Some(last_response) = responses.into_iter().last() { + return Ok(Some(self.build_channel_data(recipient_channel, &last_response)?)); + } + } + + return Ok(None); + } + // ⭐⭐⭐⭐⭐ Phase 16.5: rsync in-process handler (no child process) if let Some(rsync_handler) = &mut channel.rsync_handler { info!(