Replies: 1 comment
-
|
Ah, the git branch I found was outdated, I've updated that now. Application customisationFirst off, have a look at https://github.com/AspectUnk/russh-sftp and see how much design work can be reused from that. The filesystem side of the application will vary depending on the platform/device/use case. My thought there was that an application would provide an implementation of One idle thought - someone could implement a [1] https://github.com/mkj/sunset/blob/dev/sftp-start/sftp/src/sftpserver.rs |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
Here's a set of thoughts I had for a SFTP implementation. Feel free to ask for more detail about any of these points.
I'm writing this aimed at https://github.com/brainstorm/ssh-stamp/, but might be generally useful.
Some design ideas here may not be good! I haven't tried to implement them yet. There are more design points I've forgotten, I'll add more posts if I think of those.
Transport
SFTP is a separate packetised protocol inside a SSH channel stream [1]. There isn't necessarily a correlation between
SSH_MSG_CHANNEL_DATAdata packets and the innerSSH_FXP_*packets. The sftp implementation will need its own framing handling to read/write the packet length then handle the data - somewhat similar to https://github.com/mkj/sunset/blob/main/src/traffic.rs but without encryption.Since it's fairly independent of Sunset, my approach would be for the SFTP server to take a
impl embedded_io_async::{Read/Write}. That will be treated as a generic stream. For Sunset integration that would come from theChanInOutreturned byembassy_sunset::SSHServer::stdio().It might be possible to do something clever to borrow the file read/write data without serialising into a separate SFTP packet buffer. Make
ChanIOandRunner::channel_send()and everything in between optionally take aimpl SSHEncodemaybe? That would likely be a premature optimisation at this stage.Sunset hooks
SFTP would be treated as a generic "subsystem" https://www.rfc-editor.org/rfc/rfc4254.html#page-13.
The application's
ServEventhandler would recognise a subsytem name of "sftp" and pass that channel to its SFTP handling, similar to how aServEvent::SessionExechandles a command to run.Note that today (2025-05-31)
ServEvent::SessionExecis missing the command argument! Hopefully will get that fixed soon.Packets
I'd implement something similar to https://github.com/mkj/sunset/blob/main/src/packets.rs but for
SSH_FXP_*packet formats.main...dev/sftp-start was a start at that.
I didn't figure how I would handle variable-length lists of attributes in
SSH_FXP_NAME, I guess it need a fixed upper limit, store them in aheapless::Vec.For a simpler firmware update case maybe you can get away with avoiding the commands that would return a
SSH_FXP_NAMEresponse?File data for
SSH_FXP_DATAwould be borrowed in aBinStringobject, avoiding a memcpy/RAM usage there.sftpmessages!macro mirrors the existing packets.rs SSHmessagetypes!macro.Protocol version
https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02 is the closest draft to what OpenSSH implements, with some extensions. See https://cvsweb.openbsd.org/src/usr.bin/ssh/PROTOCOL?annotate=HEAD
@jubeormk1 and @brainstorm
Beta Was this translation helpful? Give feedback.
All reactions