diff --git a/embassy/demos/common/src/config.rs b/embassy/demos/common/src/config.rs index 0406fa58dea56cc504a6da56167cdd26fc1d7927..bda9addc4112add946b1a0cea855d1e50f6acf04 100644 --- a/embassy/demos/common/src/config.rs +++ b/embassy/demos/common/src/config.rs @@ -12,13 +12,12 @@ use defmt::{debug, error, info, panic, trace, warn}; use hmac::{Hmac, Mac}; use sha2::Sha256; -use heapless::{String, Vec}; +use heapless::String; use sunset_sshwire_derive::*; -use sunset::sshwire; use sunset::sshwire::{ - BinString, SSHDecode, SSHEncode, SSHSink, SSHSource, WireError, WireResult, + SSHDecode, SSHEncode, SSHSink, SSHSource, WireError, WireResult, }; use sunset::packets::Ed25519PubKey; diff --git a/embassy/demos/common/src/server.rs b/embassy/demos/common/src/server.rs index 7f24db8e98270fa531111a3f1aafd602a49bfd7b..d6c9fe043627405a98f5e32d0c527b7cfc2e2514 100644 --- a/embassy/demos/common/src/server.rs +++ b/embassy/demos/common/src/server.rs @@ -9,15 +9,11 @@ use { #[cfg(feature = "defmt")] use defmt::{debug, info, warn, panic, error, trace}; -use core::fmt::Write as _; -use pretty_hex::PrettyHex; - use embassy_sync::mutex::Mutex; use embassy_sync::blocking_mutex::raw::NoopRawMutex; use embassy_net::tcp::TcpSocket; use embassy_net::Stack; use embassy_net_driver::Driver; -use embassy_futures::join::join; use embassy_futures::select::{select, Either}; use embassy_time::{Duration, Timer}; diff --git a/embassy/demos/picow/Cargo.toml b/embassy/demos/picow/Cargo.toml index b9777052dbdcd75ea0962000e1eec116af4e6921..4810e9bfea5fdd64b5522ac1dc4151faa03c7828 100644 --- a/embassy/demos/picow/Cargo.toml +++ b/embassy/demos/picow/Cargo.toml @@ -60,7 +60,7 @@ rand = { version = "0.8", default-features = false, features = ["getrandom"] } sha2 = { version = "0.10", default-features = false } # for defmt feature -smoltcp = { default-features = false } +smoltcp = { version = "0.9", default-features = false } [features] default = ["defmt", "sunset-demo-embassy-common/defmt", "embassy-usb/defmt"] @@ -71,7 +71,7 @@ defmt = ["dep:defmt", "sunset/defmt", "sunset-embassy/defmt", "smoltcp/defmt"] # probe-rs-cli download firmware/43439A0_clm.bin --format bin --chip RP2040 --base-address 0x10140000 romfw = [] -# Add a UART on tx pin1, rx pin2 +# Default console is serial serial1 = [] [patch.crates-io] diff --git a/embassy/demos/picow/src/flashconfig.rs b/embassy/demos/picow/src/flashconfig.rs index 7a82ef9a85d1241394c55d9f24e7e72775ba358c..c32bbcdfa330bf914146a4bd8d81a813a79b844c 100644 --- a/embassy/demos/picow/src/flashconfig.rs +++ b/embassy/demos/picow/src/flashconfig.rs @@ -12,7 +12,7 @@ pub use { #[cfg(feature = "defmt")] pub use defmt::{debug, info, warn, panic, error, trace}; -use embassy_rp::flash::{Flash, ERASE_SIZE, FLASH_BASE}; +use embassy_rp::flash::{Flash, ERASE_SIZE}; use embassy_rp::peripherals::FLASH; use sha2::Digest; @@ -21,7 +21,6 @@ use core::borrow::Borrow; use sunset_sshwire_derive::*; use sunset::sshwire; -use sunset::sshwire::{BinString, SSHEncode, SSHDecode, WireResult, SSHSource, SSHSink, WireError}; use sunset::sshwire::OwnOrBorrow; use crate::demo_common; @@ -53,7 +52,6 @@ fn config_hash(config: &SSHConfig) -> Result<[u8; 32]> { /// Loads a SSHConfig at startup. Good for persisting hostkeys. pub fn load_or_create(flash: &mut Flash<'_, FLASH, FLASH_SIZE>) -> Result<SSHConfig> { use snafu::Error; - let c = load(flash); match load(flash) { Ok(c) => { info!("Good existing config"); @@ -68,7 +66,7 @@ pub fn load_or_create(flash: &mut Flash<'_, FLASH, FLASH_SIZE>) -> Result<SSHCon pub fn create(flash: &mut Flash<'_, FLASH, FLASH_SIZE>) -> Result<SSHConfig> { let c = SSHConfig::new()?; - if let Err(e) = save(flash, &c) { + if let Err(_) = save(flash, &c) { warn!("Error writing config"); } Ok(c) diff --git a/embassy/demos/picow/src/main.rs b/embassy/demos/picow/src/main.rs index aa5bb9463a7688938829d3beb2ab8a091bc3234b..55515b5db3d78d119d1f0bc6a5b825ca3e04566f 100644 --- a/embassy/demos/picow/src/main.rs +++ b/embassy/demos/picow/src/main.rs @@ -14,15 +14,10 @@ pub use defmt::{debug, error, info, panic, trace, warn}; use {defmt_rtt as _, panic_probe as _}; -use core::fmt::Write as _; -use pretty_hex::PrettyHex; - use embassy_executor::Spawner; -use embassy_futures::join::join; use embassy_futures::select::select; use embassy_net::Stack; use embassy_rp::peripherals::FLASH; -use embassy_time::Duration; use embedded_io::asynch::Write as _; use embedded_io::{asynch, Io}; @@ -43,13 +38,12 @@ pub(crate) use sunset_demo_embassy_common as demo_common; mod flashconfig; mod picowmenu; -#[cfg(feature = "serial1")] mod serial; mod takepipe; mod usbserial; mod wifi; -use demo_common::{demo_menu, SSHConfig, Shell}; +use demo_common::{SSHConfig, Shell}; use takepipe::TakePipe; @@ -97,12 +91,10 @@ async fn main(spawner: Spawner) { singleton!(p.pipe()) }; - #[cfg(feature = "serial1")] let serial1_pipe = { let s = singleton!(takepipe::TakePipeStorage::new()); singleton!(s.pipe()) }; - #[cfg(feature = "serial1")] spawner .spawn(serial::task( p.UART0, @@ -120,10 +112,9 @@ async fn main(spawner: Spawner) { let state = GlobalState { usb_pipe, - #[cfg(feature = "serial1")] serial1_pipe, - wifi_control, + _wifi_control: wifi_control, config, flash, watchdog, @@ -150,10 +141,9 @@ async fn listener( pub(crate) struct GlobalState { // If taking multiple mutexes, lock in the order below avoid inversion. pub usb_pipe: &'static TakePipe<'static>, - #[cfg(feature = "serial1")] pub serial1_pipe: &'static TakePipe<'static>, - pub wifi_control: &'static SunsetMutex<cyw43::Control<'static>>, + pub _wifi_control: &'static SunsetMutex<cyw43::Control<'static>>, pub config: &'static SunsetMutex<SSHConfig>, pub flash: &'static SunsetMutex< embassy_rp::flash::Flash<'static, FLASH, { flashconfig::FLASH_SIZE }>, diff --git a/embassy/demos/picow/src/picowmenu.rs b/embassy/demos/picow/src/picowmenu.rs index b610422629e3d069a1bb20366f74f5e3e07b11c7..5ac58f09828577fe4c4beb31bb3c3f11776c5aca 100644 --- a/embassy/demos/picow/src/picowmenu.rs +++ b/embassy/demos/picow/src/picowmenu.rs @@ -1,3 +1,6 @@ +// callbacks have lots of unused arguments. Ignore them, this might get replaced. +#![allow(unused)] + #[allow(unused_imports)] #[cfg(not(feature = "defmt"))] pub use log::{debug, error, info, log, trace, warn}; @@ -12,7 +15,6 @@ use core::ops::DerefMut; use core::sync::atomic::Ordering::{Relaxed, SeqCst}; use embedded_io::{asynch, Io}; -use embedded_io::asynch::Write as _; use embassy_sync::waitqueue::MultiWakerRegistration; use embassy_time::Duration; @@ -69,7 +71,7 @@ impl MenuCtx { let mut c = match self.state.config.try_lock() { Ok(c) => c, Err(e) => { - writeln!(self, "Lock problem, try again."); + let _ = writeln!(self, "Lock problem, try again."); return false; } }; @@ -90,12 +92,12 @@ impl MenuCtx { if self.switch_usb1 { self.switch_usb1 = false; if self.local { - writeln!(self.out, "serial can't loop"); + let _ = writeln!(self.out, "serial can't loop"); } else { if self.state.usb_pipe.is_in_use() { - writeln!(self.out, "Opening usb1, stealing existing session"); + let _ = writeln!(self.out, "Opening usb1, stealing existing session"); } else { - writeln!(self.out, "Opening usb1"); + let _ = writeln!(self.out, "Opening usb1"); } crate::serial(chanr, chanw, self.state.usb_pipe).await?; // TODO we could return to the menu on serial error? @@ -103,16 +105,15 @@ impl MenuCtx { } } - #[cfg(feature = "serial1")] if self.switch_serial1 { self.switch_serial1 = false; if self.local { - writeln!(self.out, "serial can't loop"); + let _ = writeln!(self.out, "serial can't loop"); } else { if self.state.serial1_pipe.is_in_use() { - writeln!(self.out, "Opening serial1, stealing existing session"); + let _ = writeln!(self.out, "Opening serial1, stealing existing session"); } else { - writeln!(self.out, "Opening serial1"); + let _ = writeln!(self.out, "Opening serial1"); } crate::serial(chanr, chanw, self.state.serial1_pipe).await?; // TODO we could return to the menu on serial error? @@ -170,7 +171,7 @@ pub(crate) const SETUP_MENU: Menu<MenuCtx> = Menu { item_type: ItemType::Callback { function: do_logout, parameters: &[] }, }, &AUTH_ITEM, - &GPIO_ITEM, + // &GPIO_ITEM, &SERIAL_ITEM, &WIFI_ITEM, &Item { @@ -389,39 +390,39 @@ const WIFI_ITEM: Item<MenuCtx> = Item { help: None, }; -const GPIO_ITEM: Item<MenuCtx> = Item { - command: "gpio", - item_type: ItemType::Menu(&Menu { - label: "gpio", - items: &[ - &Item { - command: "show", - item_type: ItemType::Callback { - parameters: &[], - function: do_gpio_show, - }, - help: None, - }, - &Item { - command: "set", - item_type: ItemType::Callback { - parameters: &[ - Parameter::Mandatory { parameter_name: "pin", help: None }, - Parameter::Mandatory { - parameter_name: "state", - help: Some("0/1/Z"), - }, - ], - function: do_gpio_set, - }, - help: None, - }, - ], - entry: None, - exit: None, - }), - help: Some("GPIO, todo"), -}; +// const _GPIO_ITEM: Item<MenuCtx> = Item { +// command: "gpio", +// item_type: ItemType::Menu(&Menu { +// label: "gpio", +// items: &[ +// &Item { +// command: "show", +// item_type: ItemType::Callback { +// parameters: &[], +// function: do_gpio_show, +// }, +// help: None, +// }, +// &Item { +// command: "set", +// item_type: ItemType::Callback { +// parameters: &[ +// Parameter::Mandatory { parameter_name: "pin", help: None }, +// Parameter::Mandatory { +// parameter_name: "state", +// help: Some("0/1/Z"), +// }, +// ], +// function: do_gpio_set, +// }, +// help: None, +// }, +// ], +// entry: None, +// exit: None, +// }), +// help: Some("GPIO, todo"), +// }; const SERIAL_ITEM: Item<MenuCtx> = Item { command: "serial", @@ -433,7 +434,6 @@ const SERIAL_ITEM: Item<MenuCtx> = Item { item_type: ItemType::Callback { parameters: &[], function: do_usb1 }, help: Some("Connect to if00 serial port. Disconnect to exit."), }, - #[cfg(feature = "serial1")] &Item { command: "serial1", item_type: ItemType::Callback { @@ -450,7 +450,7 @@ const SERIAL_ITEM: Item<MenuCtx> = Item { }; fn enter_auth(context: &mut MenuCtx) { - writeln!(context, "In auth menu").unwrap(); + let _ = writeln!(context, "In auth menu").unwrap(); } fn endis(v: bool) -> &'static str { @@ -463,25 +463,25 @@ fn endis(v: bool) -> &'static str { fn prkey(context: &mut dyn Write, name: &str, k: &Option<Ed25519PubKey>) { if let Some(k) = k { - writeln!(context, "{} ed25519 todo", name); + let _ = writeln!(context, "{} ed25519 todo", name); } else { - writeln!(context, "{} disabled", name); + let _ = writeln!(context, "{} disabled", name); } } fn do_auth_show(_item: &Item<MenuCtx>, _args: &[&str], context: &mut MenuCtx) { context.with_config(|c, out| { - write!(out, "Console password "); + let _ = write!(out, "Console password "); if c.console_noauth { - writeln!(out, "not required"); + let _ = writeln!(out, "not required"); } else { - writeln!(out, "{}", endis(c.console_pw.is_some())); + let _ = writeln!(out, "{}", endis(c.console_pw.is_some())); } - writeln!(out, "Console password {}", endis(c.console_pw.is_some())); + let _ = writeln!(out, "Console password {}", endis(c.console_pw.is_some())); prkey(out, "Console key1", &c.console_keys[0]); prkey(out, "Console key2", &c.console_keys[1]); prkey(out, "Console key3", &c.console_keys[2]); - writeln!(out, "Admin password {}", endis(c.admin_pw.is_some())); + let _ = writeln!(out, "Admin password {}", endis(c.admin_pw.is_some())); prkey(out, "Admin key1", &c.admin_keys[0]); prkey(out, "Admin key2", &c.admin_keys[1]); prkey(out, "Admin key3", &c.admin_keys[2]); @@ -491,33 +491,33 @@ fn do_auth_show(_item: &Item<MenuCtx>, _args: &[&str], context: &mut MenuCtx) { fn do_key(_item: &Item<MenuCtx>, args: &[&str], context: &mut MenuCtx) { let slot: usize = match args[0].parse() { Err(e) => { - writeln!(context, "Bad slot"); + let _ = writeln!(context, "Bad slot"); return; } Ok(s) => s, }; if slot == 0 || slot > demo_common::config::KEY_SLOTS { - writeln!(context, "Bad slot"); + let _ = writeln!(context, "Bad slot"); return; } context.need_save = true; - writeln!(context, "todo openssh key parsing"); + let _ = writeln!(context, "todo openssh key parsing"); } fn do_clear_key(_item: &Item<MenuCtx>, args: &[&str], context: &mut MenuCtx) { - writeln!(context, "todo"); + let _ = writeln!(context, "todo"); context.need_save = true; } fn do_console_pw(_item: &Item<MenuCtx>, args: &[&str], context: &mut MenuCtx) { let pw = args[0]; if pw.as_bytes().len() > MAX_PW_LEN { - writeln!(context, "Too long"); + let _ = writeln!(context, "Too long"); return; } context.with_config(|c, out| { - match c.set_console_pw(Some(pw)) { + let _ = match c.set_console_pw(Some(pw)) { Ok(()) => writeln!(out, "Set console password"), Err(e) => writeln!(out, "Failed setting, {}", e), }; @@ -539,19 +539,19 @@ fn do_console_noauth(_item: &Item<MenuCtx>, args: &[&str], context: &mut MenuCtx } fn do_admin_key(_item: &Item<MenuCtx>, args: &[&str], context: &mut MenuCtx) { - writeln!(context, "todo"); + let _ = writeln!(context, "todo"); context.need_save = true; } fn do_admin_clear_key(_item: &Item<MenuCtx>, args: &[&str], context: &mut MenuCtx) { - writeln!(context, "todo"); + let _ = writeln!(context, "todo"); context.need_save = true; } fn do_console_clear_pw(_item: &Item<MenuCtx>, args: &[&str], context: &mut MenuCtx) { context.with_config(|c, out| { let _ = c.set_console_pw(None); - writeln!(out, "Disabled console password"); + let _ = writeln!(out, "Disabled console password"); }); context.need_save = true; } @@ -559,11 +559,11 @@ fn do_console_clear_pw(_item: &Item<MenuCtx>, args: &[&str], context: &mut MenuC fn do_admin_pw(_item: &Item<MenuCtx>, args: &[&str], context: &mut MenuCtx) { let pw = args[0]; if pw.as_bytes().len() > MAX_PW_LEN { - writeln!(context, "Too long"); + let _ = writeln!(context, "Too long"); return; } context.with_config(|c, out| { - match c.set_admin_pw(Some(pw)) { + let _ = match c.set_admin_pw(Some(pw)) { Ok(()) => writeln!(out, "Set admin password"), Err(e) => writeln!(out, "Failed setting, {}", e), }; @@ -574,28 +574,38 @@ fn do_admin_pw(_item: &Item<MenuCtx>, args: &[&str], context: &mut MenuCtx) { fn do_admin_clear_pw(_item: &Item<MenuCtx>, args: &[&str], context: &mut MenuCtx) { context.with_config(|c, out| { let _ = c.set_admin_pw(None); - writeln!(out, "Disabled admin password"); + let _ = writeln!(out, "Disabled admin password"); }); context.need_save = true; } -fn do_gpio_show(_item: &Item<MenuCtx>, _args: &[&str], context: &mut MenuCtx) { - writeln!(context, "gpio show here"); -} +// fn do_gpio_show(_item: &Item<MenuCtx>, _args: &[&str], context: &mut MenuCtx) { +// let _ = writeln!(context, "gpio show here"); +// } -fn do_gpio_set(_item: &Item<MenuCtx>, _args: &[&str], context: &mut MenuCtx) {} +// fn do_gpio_set(_item: &Item<MenuCtx>, _args: &[&str], _context: &mut MenuCtx) {} -fn do_erase_config(_item: &Item<MenuCtx>, args: &[&str], context: &mut MenuCtx) {} +fn do_erase_config(_item: &Item<MenuCtx>, _args: &[&str], context: &mut MenuCtx) { + context.with_config(|c, out| { + match SSHConfig::new() { + Ok(n) => *c = n, + Err(e) => { + let _ = writeln!(out, "failed: {e}"); + } + } + }); + context.need_save = true; +} -fn do_logout(_item: &Item<MenuCtx>, args: &[&str], context: &mut MenuCtx) { +fn do_logout(_item: &Item<MenuCtx>, _args: &[&str], context: &mut MenuCtx) { context.logout = true; } -fn do_reset(_item: &Item<MenuCtx>, args: &[&str], context: &mut MenuCtx) { +fn do_reset(_item: &Item<MenuCtx>, _args: &[&str], context: &mut MenuCtx) { context.reset = true; } -fn do_bootsel(_item: &Item<MenuCtx>, args: &[&str], context: &mut MenuCtx) { +fn do_bootsel(_item: &Item<MenuCtx>, _args: &[&str], context: &mut MenuCtx) { context.bootsel = true; } @@ -607,22 +617,22 @@ fn do_about(_item: &Item<MenuCtx>, _args: &[&str], context: &mut MenuCtx) { } fn do_usb1(_item: &Item<MenuCtx>, _args: &[&str], context: &mut MenuCtx) { - writeln!(context, "USB serial"); + let _ = writeln!(context, "USB serial"); context.switch_usb1 = true; } fn do_serial1(_item: &Item<MenuCtx>, _args: &[&str], context: &mut MenuCtx) { - writeln!(context, "serial1"); + let _ = writeln!(context, "serial1"); context.switch_serial1 = true; } fn wifi_entry(context: &mut MenuCtx) { context.with_config(|c, out| { - write!(out, "Wifi net {} ", c.wifi_net); + let _ = write!(out, "Wifi net {} ", c.wifi_net); if c.wifi_pw.is_some() { - writeln!(out, "wpa2"); + let _ = writeln!(out, "wpa2"); } else { - writeln!(out, "open"); + let _ = writeln!(out, "open"); } }); } @@ -632,11 +642,11 @@ fn do_wifi_wpa2(_item: &Item<MenuCtx>, args: &[&str], context: &mut MenuCtx) { let net = args[0]; let pw = args[1]; if c.wifi_net.capacity() < net.len() { - writeln!(out, "Too long net"); + let _ = writeln!(out, "Too long net"); return; } if pw.len() > 63 { - writeln!(out, "Too long pw"); + let _ = writeln!(out, "Too long pw"); return; } c.wifi_net = net.into(); @@ -650,7 +660,7 @@ fn do_wifi_open(_item: &Item<MenuCtx>, args: &[&str], context: &mut MenuCtx) { context.with_config(|c, out| { let net = args[0]; if c.wifi_net.capacity() < net.len() { - writeln!(out, "Too long net"); + let _ = writeln!(out, "Too long net"); return; } c.wifi_pw = None; diff --git a/embassy/demos/picow/src/serial.rs b/embassy/demos/picow/src/serial.rs index 25e38e0fc553631d169d422af775c276b20d50c4..4258cad75055a37e9aadb366544fb2a73eb23639 100644 --- a/embassy/demos/picow/src/serial.rs +++ b/embassy/demos/picow/src/serial.rs @@ -9,16 +9,11 @@ pub use log::{debug, error, info, log, trace, warn}; pub use defmt::{debug, error, info, panic, trace, warn}; use embassy_rp::peripherals::*; -use embassy_rp::interrupt::UART0_IRQ; -use embassy_rp::{bind_interrupts, Peripheral}; +use embassy_rp::bind_interrupts; use embassy_rp::uart::{ - self as rp_uart, BufferedInterruptHandler, BufferedUart, BufferedUartRx, CtsPin, - RtsPin, RxPin, TxPin, + self as rp_uart, BufferedInterruptHandler, BufferedUart, }; -use embassy_rp::interrupt::{Interrupt, InterruptExt}; - -use sunset::*; use sunset_embassy::*; use crate::*; diff --git a/embassy/demos/picow/src/takepipe.rs b/embassy/demos/picow/src/takepipe.rs index d14a94bc88f2e0c516080d227c402a7d7375941d..c5011ef6d33c1c2d720f96a489d81c61bd70ba1e 100644 --- a/embassy/demos/picow/src/takepipe.rs +++ b/embassy/demos/picow/src/takepipe.rs @@ -12,7 +12,7 @@ use core::ops::DerefMut; use embedded_io::{asynch, Io}; -use embassy_sync::{pipe, mutex::{MutexGuard, Mutex}, signal::Signal}; +use embassy_sync::{pipe, mutex::Mutex, signal::Signal}; use embassy_sync::pipe::Pipe; use embassy_futures::select::{select, Either}; @@ -38,7 +38,6 @@ pub(crate) struct TakePipeStorage { fanout: Pipe<SunsetRawMutex, READ_SIZE>, fanin: Pipe<SunsetRawMutex, WRITE_SIZE>, wake: Signal<SunsetRawMutex, ()>, - counter: u64, } impl TakePipeStorage { @@ -61,7 +60,6 @@ impl Default for TakePipeStorage { fanout: Pipe::new(), fanin: Pipe::new(), wake: Signal::new(), - counter: 0, } } } @@ -216,7 +214,7 @@ impl asynch::Write for TakeWrite<'_> { // write completed Either::First(l) => l, // lost the pipe - Either::Second(l) => { + Either::Second(_) => { self.shared = None; Err(sunset::Error::ChannelEOF) } diff --git a/embassy/demos/picow/src/usbserial.rs b/embassy/demos/picow/src/usbserial.rs index 04fc999f902a895a641f09451ebbfd91d9ec255d..f4fa29a6d0ed0861174d7bd4d87741c53d0e267a 100644 --- a/embassy/demos/picow/src/usbserial.rs +++ b/embassy/demos/picow/src/usbserial.rs @@ -7,7 +7,7 @@ pub use log::{debug, error, info, log, trace, warn}; pub use defmt::{debug, error, info, panic, trace, warn}; use embassy_futures::join::{join, join3}; -use embassy_rp::usb::{Instance, InterruptHandler}; +use embassy_rp::usb::{InterruptHandler}; use embassy_rp::bind_interrupts; use embassy_rp::peripherals::USB; use embassy_usb::class::cdc_acm::{self, CdcAcmClass, State}; @@ -16,9 +16,6 @@ use embassy_usb_driver::Driver; use embedded_io::{asynch, Io, asynch::BufRead}; -use heapless::Vec; - -use sunset::*; use sunset_embassy::*; use crate::*; diff --git a/embassy/demos/picow/src/wifi.rs b/embassy/demos/picow/src/wifi.rs index 98a8ad4736d47715e4c0951cd93183301a28a4f5..c933d69bbb2a52026d8f35922a279f0317b60e02 100644 --- a/embassy/demos/picow/src/wifi.rs +++ b/embassy/demos/picow/src/wifi.rs @@ -66,9 +66,8 @@ pub(crate) async fn wifi_stack(spawner: &Spawner, // TODO: this should move out of the critical path, run in the bg. // just return control before joining. - let mut status = Ok(()); - for i in 0..2 { - status = if let Some(ref pw) = wpa_password { + for _ in 0..2 { + let status = if let Some(ref pw) = wpa_password { info!("wifi net {} wpa2", wifi_net); control.join_wpa2(&wifi_net, &pw).await } else { diff --git a/embassy/src/embassy_sunset.rs b/embassy/src/embassy_sunset.rs index 62eea99c3f2508c208d0a079c52e974fab2e0fa4..0dc7a715b19574d255b909f9f402b12d05cb0546 100644 --- a/embassy/src/embassy_sunset.rs +++ b/embassy/src/embassy_sunset.rs @@ -18,7 +18,7 @@ use embassy_sync::mutex::Mutex; use embassy_sync::signal::Signal; use embassy_futures::select::select; use embassy_futures::join; -use embedded_io::{asynch, asynch::Write, Io}; +use embedded_io::{asynch, Io}; // thumbv6m has no atomic usize add/sub use atomic_polyfill::AtomicUsize; @@ -140,7 +140,7 @@ impl<'a, C: CliBehaviour, S: ServBehaviour> EmbassySunset<'a, C, S> { let mut buf = [0; 1024]; let l = self.output(&mut buf).await?; wsock.write_all(&buf[..l]).await - .map_err(|e| { + .map_err(|_| { info!("socket write error"); Error::ChannelEOF })?; @@ -155,7 +155,7 @@ impl<'a, C: CliBehaviour, S: ServBehaviour> EmbassySunset<'a, C, S> { // TODO: make sunset read directly from socket, no intermediate buffer. let mut buf = [0; 1024]; let l = rsock.read(&mut buf).await - .map_err(|e| { + .map_err(|_| { info!("socket read error"); Error::ChannelEOF })?; @@ -545,7 +545,7 @@ pub async fn io_copy_nowriteerror<const B: usize, R, W>(r: &mut R, w: &mut W) -> return sunset::error::ChannelEOF.fail(); } let b = &b[..n]; - if let Err(e) = w.write_all(b).await { + if let Err(_) = w.write_all(b).await { info!("write error"); } } @@ -577,7 +577,7 @@ pub async fn io_buf_copy_noreaderror<R, W>(r: &mut R, w: &mut W) -> Result<()> loop { let b = match r.fill_buf().await { Ok(b) => b, - Err(e) => { + Err(_) => { info!("read error"); embassy_futures::yield_now().await; continue; diff --git a/src/behaviour.rs b/src/behaviour.rs index c9a48fff11069e0df57256ce5d7652e35299f1c4..7d1c5dbe6ccd76610e46c28c72c4dce7ba311a23 100644 --- a/src/behaviour.rs +++ b/src/behaviour.rs @@ -301,7 +301,7 @@ impl CliBehaviour for UnusedCli { fn username(&mut self) -> BhResult<ResponseString> { unreachable!() } - fn valid_hostkey(&mut self, key: &PubKey) -> BhResult<bool> { + fn valid_hostkey(&mut self, _key: &PubKey) -> BhResult<bool> { unreachable!() } fn authenticated(&mut self) { @@ -317,7 +317,7 @@ impl ServBehaviour for UnusedServ { fn hostkeys(&mut self) -> BhResult<heapless::Vec<&SignKey, 2>> { unreachable!() } - fn open_session(&mut self, chan: ChanHandle) -> channel::ChanOpened { + fn open_session(&mut self, _chan: ChanHandle) -> channel::ChanOpened { unreachable!() } } diff --git a/src/channel.rs b/src/channel.rs index 352044d24476766e3f76f65670c0ef53c320fbdc..03a2ab107fc2ecd6c5976149efd5ddeb4da8e011 100644 --- a/src/channel.rs +++ b/src/channel.rs @@ -329,7 +329,7 @@ impl<C: CliBehaviour, S: ServBehaviour> Channels<C, S> { // let the CliBehaviour open a shell etc let mut opener = SessionOpener::new(&ch, s); let r = b.client()?.session_opened(ch.num(), &mut opener).await; - if let Err(e) = r { + if let Err(_) = r { trace!("Error from session_opened"); } } diff --git a/src/cliauth.rs b/src/cliauth.rs index 80af9e3045031db1d4dbbce8fe03f10885d5a486..537f5c9186b00996313bca1f0b30fc304bd24a34 100644 --- a/src/cliauth.rs +++ b/src/cliauth.rs @@ -144,7 +144,7 @@ impl CliAuth { b: &mut impl CliBehaviour, ) -> Option<Req> { loop { - let k = b.next_authkey().unwrap_or_else(|e| { + let k = b.next_authkey().unwrap_or_else(|_| { warn!("Error getting pubkey for auth"); None }); @@ -220,7 +220,7 @@ impl CliAuth { match auth60 { Userauth60::PkOk(pkok) => self.auth_pkok(pkok, sess_id, parse_ctx, s, b).await, - Userauth60::PwChangeReq(_req) => todo!("pwchange"), + Userauth60::PwChangeReq(_req) => self.change_password(), } } @@ -255,6 +255,11 @@ impl CliAuth { Err(Error::SSHProtoError) } + fn change_password(&self) -> Result<()> { + // Doesn't seem to be widely implemented, we'll just fail. + Err(Error::msg("Password has expired")) + } + pub async fn failure( &mut self, failure: &packets::UserauthFailure<'_>, diff --git a/src/client.rs b/src/client.rs index d9f02f8197b29072f4d519649bfe5b93fd729f37..05ada6fb3126f24fcdb924089a6d327964f022d6 100644 --- a/src/client.rs +++ b/src/client.rs @@ -27,14 +27,10 @@ impl Client { pub(crate) fn auth_success( &mut self, parse_ctx: &mut ParseContext, - s: &mut TrafSend, b: &mut impl CliBehaviour, ) -> Result<()> { parse_ctx.cli_auth_type = None; - // github.com doesn't like this, openssh doesn't send it - // s.send(packets::ServiceRequest { name: SSH_SERVICE_CONNECTION })?; - self.auth.success(b) } diff --git a/src/conn.rs b/src/conn.rs index d8f236c5c3029c9f768b8002b09fbac555f0c927..1df974325f6389798f0e4ea8801c4891132d2608 100644 --- a/src/conn.rs +++ b/src/conn.rs @@ -260,7 +260,7 @@ impl<C: CliBehaviour, S: ServBehaviour> Conn<C, S> { return Err(Error::SSHProtoError); } - self.kex.handle_kexdhreply(&p, s, b.client()?).await?; + self.kex.handle_kexdhreply(&p, s, b.client()?, self.sess_id.is_none()).await?; } Packet::NewKeys(_) => { self.kex.handle_newkeys(&mut self.sess_id, s)?; @@ -327,7 +327,7 @@ impl<C: CliBehaviour, S: ServBehaviour> Conn<C, S> { if let ClientServer::Client(cli) = &mut self.cliserv { if matches!(self.state, ConnState::PreAuth) { self.state = ConnState::Authed; - cli.auth_success(&mut self.parse_ctx, s, b.client()?)?; + cli.auth_success(&mut self.parse_ctx, b.client()?)?; } else { debug!("Received UserauthSuccess unrequested") } @@ -375,7 +375,7 @@ impl<C: CliBehaviour, S: ServBehaviour> Conn<C, S> { s.send(packets::RequestFailure {})?; } } - Packet::RequestSuccess(p) => { + Packet::RequestSuccess(_p) => { trace!("Got global request success") } Packet::RequestFailure(_) => { diff --git a/src/kex.rs b/src/kex.rs index 2becba96e3a5164af96d460c91b69ecc79fb34ab..b7e3cfbd3d6b13a22e318424b71f00e51825e7c1 100644 --- a/src/kex.rs +++ b/src/kex.rs @@ -338,6 +338,7 @@ impl Kex { &mut self, p: &packets::KexDHReply<'f>, s: &mut TrafSend<'_, '_>, b: &mut impl CliBehaviour, + first_kex: bool, ) -> Result<()> { if let Kex::KexDH { algos, ..} = self { if !algos.is_client { @@ -353,14 +354,31 @@ impl Kex { if let Kex::KexDH { mut algos, kex_hash } = self.take() { let output = SharedSecret::handle_kexdhreply(&mut algos, kex_hash, p, b).await?; - *self = Kex::NewKeys { output, algos }; s.send(packets::NewKeys {})?; + + if first_kex && algos.send_ext_info { + self.send_ext_info(s)?; + } + + *self = Kex::NewKeys { output, algos }; Ok(()) } else { error::PacketWrong.fail() } } + pub fn send_ext_info(&self, s: &mut TrafSend) -> Result<()> { + if cfg!(feature = "rsa") { + // OK unwrap: namelist has capacity + let algs = ([SSH_NAME_RSA_SHA256, SSH_NAME_ED25519].as_slice()).try_into().unwrap(); + let ext = packets::ExtInfo { + server_sig_algs: Some(NameList::Local(&algs)), + }; + s.send(ext)?; + } + Ok(()) + } + pub fn handle_newkeys(&mut self, sess_id: &mut Option<SessId>, s: &mut TrafSend<'_, '_>) -> Result<()> { if let Kex::NewKeys { output, algos } = self.take() { // We will have already sent our own NewKeys message if we reach thi @@ -377,6 +395,7 @@ impl Kex { } } + /// Perform SSH algorithm negotiation fn algo_negotiation( is_client: bool, p: &packets::KexInit, conf: &AlgoConfig, @@ -405,10 +424,11 @@ impl Kex { // we only send MSG_EXT_INFO to a client, don't look // for SSH_NAME_EXT_INFO_S - let send_ext_info = match is_client { - true => false, + let send_ext_info = if is_client { + false + } else { // OK unwrap: p.kex is a remote list - false => p.kex.has_algo(SSH_NAME_EXT_INFO_C).unwrap(), + p.kex.has_algo(SSH_NAME_EXT_INFO_C).unwrap() }; debug!("hostsig {:?} vs {:?}", p.hostsig, conf.hostsig); @@ -693,7 +713,7 @@ impl KexCurve25519 { let mut s = [0u8; 32]; random::fill_random(s.as_mut_slice())?; // TODO: check that pure random bytes are OK - let ours = x25519_dalek::EphemeralSecret::new(OsRng); + let ours = x25519_dalek::EphemeralSecret::random_from_rng(OsRng); let pubkey = x25519_dalek::PublicKey::from(&ours); let pubkey = pubkey.to_bytes(); Ok(KexCurve25519 { ours: Some(ours), pubkey }) diff --git a/src/packets.rs b/src/packets.rs index 7b1efd9fb84fc2b02e16347c09915ad72bd5be25..a7ed113a4d48525dc9e4107dbde8b5fb8741b43a 100644 --- a/src/packets.rs +++ b/src/packets.rs @@ -841,7 +841,7 @@ impl TryFrom<u8> for MessageNumber { fn try_from(v: u8) -> Result<Self> { match v { // eg - // 20 = Ok(MessageNumber::SSH_MSG_KEXINIT) + // 20 => Ok(MessageNumber::SSH_MSG_KEXINIT) $( $message_num => Ok(MessageNumber::$SSH_MESSAGE_NAME), )* diff --git a/src/sign.rs b/src/sign.rs index d2299aca4beee78c9a00712e8d7940b2db41261c..419812c3549a113baeeb8ef8672cd5e0bf612191 100644 --- a/src/sign.rs +++ b/src/sign.rs @@ -372,7 +372,7 @@ impl TryFrom<ssh_key::PrivateKey> for SignKey { fn try_from(k: ssh_key::PrivateKey) -> Result<Self> { match k.key_data() { ssh_key::private::KeypairData::Ed25519(k) => { - Ok(SignKey::Ed25519(k.private.to_bytes())) + Ok(SignKey::Ed25519(k.private.to_bytes().into())) } #[cfg(feature = "rsa")] diff --git a/src/sshnames.rs b/src/sshnames.rs index 57ec5bff669702a4db8f2b6e93cb12f4328db100..d631a912f93682cabb8b78d6e6f9eeda9abcab68 100644 --- a/src/sshnames.rs +++ b/src/sshnames.rs @@ -87,4 +87,5 @@ pub enum AgentMessageNum { } +/// [draft-miller-ssh-agent-04](https://datatracker.ietf.org/doc/html/draft-miller-ssh-agent-04) pub const SSH_AGENT_FLAG_RSA_SHA2_256: u32 = 0x02;