Skip to content
Draft
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
38 commits
Select commit Hold shift + click to select a range
de638df
[skip ci] Adding proto, dependencies and required
jubeormk1 Mar 3, 2026
fd01170
[skip ci] Adding sunset-sftp crate with basic SFTP server implementation
jubeormk1 Mar 4, 2026
1f38033
[skip ci] Adding @mkj contributions troubleshooting channel reception…
jubeormk1 Mar 4, 2026
f06643c
[skip ci] WIP: Adding demo sftp std example and testing
jubeormk1 Mar 4, 2026
8b585a8
[skip ci] Improved demo sftp std testing scripts
jubeormk1 Mar 5, 2026
8ef777f
CI updated
jubeormk1 Mar 5, 2026
5259179
CI fix: cargo fmt
jubeormk1 Mar 5, 2026
19f63d4
Addressing easier some points in the review
jubeormk1 Mar 10, 2026
e8cab8c
Fixing missing points in previous commit
jubeormk1 Mar 24, 2026
6be8a2c
removing size from demo/sftp/std build outputs
jubeormk1 Mar 24, 2026
7aaa7de
Fixing unnecessary duplicated lifetimes and tidying up
jubeormk1 Mar 24, 2026
74ff19a
Reverting changes to sshwire-derive/src/lib.rs
jubeormk1 Mar 25, 2026
91c3763
Removing new(&str) from `OpaqueFileHandle`
jubeormk1 Mar 26, 2026
1feecff
RUSTSEC-2024-0436: Fixing Paste to version 1.0.25
jubeormk1 Apr 4, 2026
635b173
Fixing typo in previous commit
jubeormk1 Apr 4, 2026
45f54ff
Extra typo. Running CI now to make sure that all is good
jubeormk1 Apr 4, 2026
fbe6fc6
sftp: simplify some lifetimes
mkj Apr 12, 2026
d15ecc7
Fix formatting for "sftp: simplify lifetimes"
mkj Apr 12, 2026
a5e42fa
Fix read refcount for ChanIn and ChanInOut clone()
mkj Mar 17, 2026
5c81041
Rust 1.88 min version
mkj Apr 1, 2026
0ead867
Update some outdated dependencies
mkj Apr 1, 2026
8149c7c
Fix some clippy warnings
mkj Apr 12, 2026
9c7ce51
pretty-hex isn't needed, plain hex format instead
mkj Apr 15, 2026
6287abc
Fix url typo in readme
mkj Apr 15, 2026
10ee61d
Remove rust-toolchain files
mkj Apr 15, 2026
6dea4d6
Delete update-toolchain.sh
mkj Apr 15, 2026
477237f
[skip ci] Deleted empty default feature
jubeormk1 Apr 16, 2026
53ce64e
[skip ci] Correcting typo "peak"
jubeormk1 Apr 16, 2026
fa819f0
[skip ci] Naively adding bug to WireError
jubeormk1 Apr 16, 2026
1482278
[skip ci] Documenting generic parameters for sftp structures
jubeormk1 Apr 17, 2026
0fa5e16
Using AtomicUsize instead of Mutex in sftpoutputchannelhandler.rs
jubeormk1 Apr 17, 2026
3b37af3
SftpOutputConsumer.receive_task exits on 0 byte reads
jubeormk1 Apr 17, 2026
27c116f
sftp: Add a ParseContext to sftpsource
mkj Apr 12, 2026
7c6186e
Fixing fmt to pass CI
jubeormk1 Apr 17, 2026
aa0960c
Adding strict-path to demo/sftp/std
jubeormk1 Apr 20, 2026
906cd3d
Simplifying sftp std example. No seeds + 32 bytes handle_id
jubeormk1 Apr 22, 2026
611d792
Fixing unclear naming in OpaqueFileHandle implementation
jubeormk1 Apr 23, 2026
53cd6e8
Addressing potential integer overflow
jubeormk1 Apr 23, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 32 additions & 16 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

33 changes: 25 additions & 8 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ rust-version = "1.87"
[workspace]
members = [
"demo/picow",
"demo/std", "fuzz",
"demo/std",
"fuzz",
"stdasync",
"sftp",
# workspace.dependencies paths are automatic
]

Expand All @@ -39,7 +41,9 @@ ascii = { version = "1.0", default-features = false }
arbitrary = { workspace = true, optional = true }

getrandom = "0.2"
rand_core = { version = "0.6", default-features = false, features = ["getrandom"]}
rand_core = { version = "0.6", default-features = false, features = [
"getrandom",
] }

ctr = { version = "0.9", features = ["zeroize"] }
aes = { version = "0.8", features = ["zeroize"] }
Expand All @@ -53,14 +57,27 @@ zeroize = { version = "1", default-features = false, features = ["derive"] }
cipher = { version = "0.4", features = ["zeroize"] }
subtle = { version = "2.4", default-features = false }
# ed25519/x25519
ed25519-dalek = { version = "2.1", default-features = false, features = ["zeroize", "rand_core"] }
x25519-dalek = { version = "2.0", default-features = false, features = ["zeroize"] }
curve25519-dalek = { version = "4.1", default-features = false, features = ["zeroize"] }
ml-kem = { version = "0.2.1", default-features = false, features = ["zeroize"], optional = true }
ed25519-dalek = { version = "2.1", default-features = false, features = [
"zeroize",
"rand_core",
] }
x25519-dalek = { version = "2.0", default-features = false, features = [
"zeroize",
] }
curve25519-dalek = { version = "4.1", default-features = false, features = [
"zeroize",
] }
ml-kem = { version = "0.2.1", default-features = false, features = [
"zeroize",
], optional = true }
# p521 = { version = "0.13.2", default-features = false, features = ["ecdh", "ecdsa"] }
rsa = { version = "0.9", default-features = false, optional = true, features = ["sha2"] }
rsa = { version = "0.9", default-features = false, optional = true, features = [
"sha2",
] }
# TODO: getrandom feature is a workaround for missing ssh-key dependency with rsa. fixed in pending 0.6
ssh-key = { version = "0.6", default-features = false, optional = true, features = ["getrandom"] }
ssh-key = { version = "0.6", default-features = false, optional = true, features = [
"getrandom",
] }

embedded-io = { version = "0.6", optional = true }

Expand Down
26 changes: 26 additions & 0 deletions sftp/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
[package]
name = "sunset-sftp"
version = "0.1.2"
edition = "2024"

[features]
default = []
Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't need default feature if it's empty

# long paths support, which allows paths up to 4096 bytes, by default paths are limited to 256 bytes
long-paths-4096 = []
long-paths-1024 = []

# Standard library support - enables std helpers
std = []

[dependencies]
sunset = { path = "../" }
sunset-async = { path = "../async" }
sunset-sshwire-derive = { path = "../sshwire-derive" }


embedded-io-async = "0.6"
num_enum = { version = "0.7.4", default-features = false }
paste = "1.0"
log = "0.4"
embassy-sync = "0.7.2"
embassy-futures = "0.1.2"
128 changes: 128 additions & 0 deletions sftp/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
//! SFTP (SSH File Transfer Protocol) implementation for [`sunset`].
//!
//! (Partially) Implements SFTP v3 as defined in [draft-ietf-secsh-filexfer-02](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02).
//!
//! **Work in Progress**: Currently focuses on file upload operations.
//! Long packets for requests other than writing and additional SFTP operations
//! are not yet implemented. `no_std` compatibility is intended but not
//! yet complete. Please see the roadmap and use this crate carefully.
//!
//! This crate implements a handler that, given a [`sunset::ChanHandle`]
//! a `sunset_async::SSHServer` and some auxiliary buffers,
//! can dispatch SFTP packets to a struct implementing [`crate::sftpserver::SftpServer`] trait.
//!
//! See example usage in the `../demo/sftd/std` directory for the intended usage
//! of this library.
//!
//! # Roadmap
//!
//! The following list is an opinionated collection of the points that should be
//! completed to provide growing functionality.
//!
//! ## Basic features
//!
//! - [ ] [SFTP Protocol Initialization](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02#section-4) (Only SFTP V3 supported)
//! - [ ] [Canonicalizing the Server-Side Path Name](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02#section-6.11) support
//! - [ ] [Open, close](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02#section-6.3)
//! and [write](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02#section-6.4)
//! - [ ] Directory [Browsing](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02#section-6.7)
//! - [ ] File [read](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02#section-6.4),
//! - [ ] File [stats](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02#section-6.8)
//!
//! ## Minimal features for convenient usability
//!
//! - [ ] [Removing files](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02#section-6.5)
//! - [ ] [Renaming files](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02#section-6.5)
//! - [ ] [Creating directories](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02#section-6.6)
//! - [ ] [Removing directories](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02#section-6.6)
//!
//! ## Extended features
//!
//! - [ ] [Append, create and truncate files](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02#section-6.3)
//! files
//! - [ ] [Reading](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02#section-6.8)
//! files attributes
//! - [ ] [Setting](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02#section-6.9) files attributes
//! - [ ] [Dealing with Symbolic links](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02#section-6.10)
//! - [ ] [Vendor Specific](https://datatracker.ietf.org/doc/html/draft-ietf-secsh-filexfer-02#section-8)
//! request and responses

#![forbid(unsafe_code)]
#![warn(missing_docs)]
#![cfg_attr(not(feature = "std"), no_std)]

// mod opaquefilehandle;
mod proto;
// mod sftperror;
// mod sftphandler;
// mod sftpserver;
// mod sftpsink;
mod sftpsource;

// Main calling point for the library provided that the user implements
// a [`server::SftpServer`].
//
// Please see basic usage at `../demo/sftd/std`
// pub use sftphandler::SftpHandler;

/// Source of SFTP packets
///
/// Used to decode SFTP packets from a byte slice
pub use sftpsource::SftpSource;

// /// Structures and types used to add the details for the target system
// /// Related to the implementation of the [`server::SftpServer`], which
// /// is meant to be instantiated by the user and passed to [`SftpHandler`]
// /// and has the task of executing client requests in the underlying system
// pub mod server {

// pub use crate::sftpserver::DirReply;
// pub use crate::sftpserver::ReadReply;
// pub use crate::sftpserver::ReadStatus;
// pub use crate::sftpserver::SftpOpResult;
// pub use crate::sftpserver::SftpServer;
// /// Helpers to reduce error prone tasks and hide some details that
// /// add complexity when implementing an [`SftpServer`]
// pub mod helpers {
// pub use crate::sftpserver::helpers::*;

// #[cfg(feature = "std")]
// pub use crate::sftpserver::DirEntriesCollection;
// #[cfg(feature = "std")]
// pub use crate::sftpserver::get_file_attrs;
// }
// pub use crate::sftpsink::SftpSink;
// pub use sunset::sshwire::SSHEncode;

// pub use crate::proto::MAX_REQUEST_LEN;
// }

/// Handles and helpers used by the [`sftpserver::SftpServer`] trait implementer
// pub mod handles {
// pub use crate::opaquefilehandle::OpaqueFileHandle;
// pub use crate::opaquefilehandle::OpaqueFileHandleManager;
// pub use crate::opaquefilehandle::PathFinder;
// }

/// SFTP Protocol types and structures
pub mod protocol {
pub use crate::proto::Attrs;
pub use crate::proto::FileHandle;
pub use crate::proto::Filename;
pub use crate::proto::Name;
pub use crate::proto::NameEntry;
pub use crate::proto::PFlags;
pub use crate::proto::PathInfo;
pub use crate::proto::SftpPacket;
pub use crate::proto::StatusCode;
/// Constants that might be useful for SFTP developers
pub mod constants {
pub use crate::proto::MAX_NAME_ENTRY_SIZE;
}
}

// /// Errors and results used in this crate
// pub mod error {
// pub use crate::sftperror::SftpError;
// pub use crate::sftperror::SftpResult;
// }
Loading