diff --git a/Cargo.lock b/Cargo.lock index 97c0bd1..c7bc1a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -109,6 +109,17 @@ version = "1.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" +[[package]] +name = "bbqueue" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "68917624e17aad88607cb5a5936f6da9b607c48c711e4e9ed101e7189aed28c2" +dependencies = [ + "const-init", + "critical-section", + "maitake-sync", +] + [[package]] name = "bcrypt" version = "0.17.1" @@ -275,6 +286,12 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0b396d1f76d455557e1218ec8066ae14bba60b4b36ecd55577ba979f5db7ecaa" +[[package]] +name = "const-init" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4bd422bfb4f24a97243f60b6a4443e63d810c925d8da4bb2d8fde26a7c1d57ec" + [[package]] name = "cordyceps" version = "0.3.4" @@ -1692,6 +1709,22 @@ dependencies = [ "tracing-subscriber", ] +[[package]] +name = "maitake-sync" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3d77c365d697828821727b9bc09e6bc3c518b8c63804e79e1be5a5ae091a7c5f" +dependencies = [ + "cordyceps", + "critical-section", + "loom", + "mutex-traits", + "mycelium-bitfield", + "pin-project", + "portable-atomic", + "tracing", +] + [[package]] name = "managed" version = "0.8.0" @@ -1739,6 +1772,18 @@ dependencies = [ "zeroize", ] +[[package]] +name = "mutex-traits" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3929f2b5633d29cf7b6624992e5f3c1e9334f1193423e12d17be4faf678cde3f" + +[[package]] +name = "mycelium-bitfield" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24e0cc5e2c585acbd15c5ce911dff71e1f4d5313f43345873311c4f5efd741cc" + [[package]] name = "nb" version = "0.1.3" @@ -1871,6 +1916,26 @@ dependencies = [ "base64ct", ] +[[package]] +name = "pin-project" +version = "1.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2466b2336ed02bcdca6b294417127b90ec92038d1d5c4fbeac971a922e0e0924" +dependencies = [ + "pin-project-internal", +] + +[[package]] +name = "pin-project-internal" +version = "1.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c96395f0a926bc13b1c17622aaddda1ecb55d49c8f1bf9777e4d877800a43f8b" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "pin-project-lite" version = "0.2.17" @@ -2461,8 +2526,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "sunset" -version = "0.4.0" -source = "git+https://github.com/mkj/sunset?rev=fd3f8284ebca704f3c3789faf80487af18a50114#fd3f8284ebca704f3c3789faf80487af18a50114" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "65092d44c73e41086a523bea2087a9856fb41760b1b616b307f9895a8da0d35f" dependencies = [ "aes", "ascii", @@ -2491,8 +2557,9 @@ dependencies = [ [[package]] name = "sunset-async" -version = "0.4.0" -source = "git+https://github.com/mkj/sunset?rev=fd3f8284ebca704f3c3789faf80487af18a50114#fd3f8284ebca704f3c3789faf80487af18a50114" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b2e4501b7a6c98b2ecfbff0b0a4e856a313d05b7de3136543aee14361a69825c" dependencies = [ "embassy-futures", "embassy-sync 0.8.0", @@ -2504,9 +2571,11 @@ dependencies = [ [[package]] name = "sunset-sftp" -version = "0.1.2" -source = "git+https://github.com/mkj/sunset?rev=fd3f8284ebca704f3c3789faf80487af18a50114#fd3f8284ebca704f3c3789faf80487af18a50114" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aee9bdd4d1e5a597218f5ffa357124211dc637f159db08feab51caff9a1d83ae" dependencies = [ + "bbqueue", "embassy-futures", "embassy-sync 0.8.0", "embedded-io-async 0.7.0", @@ -2520,8 +2589,9 @@ dependencies = [ [[package]] name = "sunset-sshwire-derive" -version = "0.2.1" -source = "git+https://github.com/mkj/sunset?rev=fd3f8284ebca704f3c3789faf80487af18a50114#fd3f8284ebca704f3c3789faf80487af18a50114" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa1b56b572c079bec0ac9ca68613a245187b1cd1b28f77142cabe654e86e536b" dependencies = [ "virtue", ] diff --git a/Cargo.toml b/Cargo.toml index 2d6f77e..8eaafa1 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -43,15 +43,15 @@ heapless = "0.9" esp-hal = { version = "1.1", features = ["unstable", "log-04"] } # SSH protocol -sunset = { git = "https://github.com/mkj/sunset", rev = "fd3f8284ebca704f3c3789faf80487af18a50114", default-features = false, features = [ +sunset = { version = "0.5.0", default-features = false, features = [ "openssh-key", "embedded-io", ] } -sunset-async = { git = "https://github.com/mkj/sunset", rev = "fd3f8284ebca704f3c3789faf80487af18a50114", default-features = false, features = [ +sunset-async = { version = "0.5.0", default-features = false, features = [ "multi-thread", ] } -sunset-sshwire-derive = { git = "https://github.com/mkj/sunset", rev = "fd3f8284ebca704f3c3789faf80487af18a50114", default-features = false } -sunset-sftp = { git = "https://github.com/mkj/sunset", rev = "fd3f8284ebca704f3c3789faf80487af18a50114", default-features = false } +sunset-sshwire-derive = { version = "0.2.2", default-features = false } +sunset-sftp = { version = "0.1.3", default-features = false } # Crypto sha2 = { version = "0.10", default-features = false } diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..9069167 --- /dev/null +++ b/build.rs @@ -0,0 +1,28 @@ +// SPDX-FileCopyrightText: 2026 Roman Valls Guimera +// +// SPDX-License-Identifier: GPL-3.0-or-later + +//! Concatenates the upstream `sunset` SSH ident with the `ssh-stamp` +//! version, e.g. `SSH-2.0-Sunset-0.5.0-ssh-stamp-0.3.0`. + +fn main() { + println!("cargo:rerun-if-changed=Cargo.lock"); + let lock_path = std::path::Path::new(env!("CARGO_MANIFEST_DIR")).join("Cargo.lock"); + let lock = std::fs::read_to_string(&lock_path).unwrap(); + let sunset_ver = lock + .split("[[package]]") + .find(|s| s.contains("name = \"sunset\"")) + .and_then(|s| { + s.lines().find_map(|l| { + l.trim() + .strip_prefix("version = ") + .map(|v| v.trim_matches('"')) + }) + }) + .unwrap_or("unknown"); + let ident = format!( + "SSH-2.0-Sunset-{sunset_ver}-ssh-stamp-{}", + env!("CARGO_PKG_VERSION") + ); + println!("cargo::rustc-env=SSH_STAMP_IDENT={ident}"); +} diff --git a/ota/src/sftpserver.rs b/ota/src/sftpserver.rs index f93da62..f13023c 100644 --- a/ota/src/sftpserver.rs +++ b/ota/src/sftpserver.rs @@ -28,7 +28,6 @@ pub async fn run_ota_server( stdio: ChanInOut<'_>, ota_writer: W, ) -> Result<(), sunset::Error> { - let mut buffer_in = [0u8; 512]; let mut request_buffer = [0u8; MAX_REQUEST_LEN]; let mut file_server = SftpOtaServer::new(ota_writer); @@ -39,7 +38,7 @@ pub async fn run_ota_server( &mut file_server, &mut request_buffer, ) - .process_loop(chan_in, chan_out, &mut buffer_in) + .process_loop(chan_in, chan_out) .await { Ok(()) => { diff --git a/src/app.rs b/src/app.rs index 9ce4833..8c8db80 100644 --- a/src/app.rs +++ b/src/app.rs @@ -27,7 +27,7 @@ use crate::handle::{self, SessionType}; use crate::platform::PlatformServices; use crate::serial::BufferedSerial; use crate::serve; -use crate::settings::{UART_BUFFER_SIZE, WIFI_PASSWORD_CHARS}; +use crate::settings::{SSH_STAMP_IDENT, UART_BUFFER_SIZE, WIFI_PASSWORD_CHARS}; /// Ensures a `WiFi` password exists, persists a freshly-generated one if not, /// prints the SSH hostkey fingerprint, and returns a ready-to-use @@ -51,6 +51,8 @@ pub async fn prepare_ap_config( ) -> Result { let mut guard = config.lock().await; + info!("SSH server ident: {SSH_STAMP_IDENT}"); + if guard.wifi_ap_pw.is_empty() { let pw = generate_wifi_password()?; warn!("wifi_pw missing from config, generated new password"); diff --git a/src/settings.rs b/src/settings.rs index dd1acde..6fa0358 100644 --- a/src/settings.rs +++ b/src/settings.rs @@ -13,9 +13,10 @@ use core::net::Ipv4Addr; // SSH server settings //pub(crate) const MTU: usize = 1536; //pub(crate) const PORT: u16 = 22; -//pub(crate) const SSH_SERVER_ID: &str = "SSH-2.0-ssh-stamp-0.1"; +pub(crate) const SSH_STAMP_IDENT: &str = env!("SSH_STAMP_IDENT"); pub(crate) const KEY_SLOTS: usize = 1; // TODO: Document whether this a "reasonable default"? Justify why? -pub const DEFAULT_IP: Ipv4Addr = Ipv4Addr::new(192, 168, 4, 1); +pub const DEFAULT_IP: Ipv4Addr = Ipv4Addr::new(192, 168, 4, 1); // TODO: Expose this setting via +// SSH_STAMP env var? // WiFi SSID and password character set (alphanumeric) pub(crate) const WIFI_PASSWORD_CHARS: &[u8; 62] =