From 6e1b423f11e391570f077c62124365dcfa28598c Mon Sep 17 00:00:00 2001 From: Jordan Doyle Date: Sun, 25 Jun 2023 16:46:17 +0100 Subject: [PATCH] Fix keyboard-interactive authentication A bug in `thrussh` caused clients to hang after authenticating via challenge-response, we've had to fork thrussh to fix it. --- Cargo.lock | 6 ++---- Cargo.toml | 4 ++++ src/server.rs | 61 +++++++++++++++++++++++++------------------------------------ 3 files changed, 31 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 241f129..bc4764f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1184,8 +1184,7 @@ dependencies = [ [[package]] name = "thrussh" version = "0.34.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eb7f634184fe86d7a9fd587d9350137508cba7b77626a7785db2ca695ebc503" +source = "git+ssh://git@github.com/JordanForks/thrussh#5b7232db70817c3519d191d1c4440da933f28563" dependencies = [ "bitflags", "byteorder", @@ -1206,8 +1205,7 @@ dependencies = [ [[package]] name = "thrussh-keys" version = "0.22.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c43d59b13e4c08db0e379bced99bda596ac5ed33651d919bf3916d34ad4259bb" +source = "git+ssh://git@github.com/JordanForks/thrussh#5b7232db70817c3519d191d1c4440da933f28563" dependencies = [ "aes", "bcrypt-pbkdf", diff --git a/Cargo.toml b/Cargo.toml index bc04b9c..b666354 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -23,3 +23,7 @@ toml = "0.7" tracing = "0.1" tracing-subscriber = { version = "0.3", features = ["env-filter"] } uuid = { version = "1.3", features = ["v4", "serde"] } + +[patch."crates-io"] +thrussh = { git = "ssh://git@github.com/JordanForks/thrussh" } +thrussh-keys = { git = "ssh://git@github.com/JordanForks/thrussh" } diff --git a/src/server.rs b/src/server.rs index e311e02..f3437a6 100644 --- a/src/server.rs +++ b/src/server.rs @@ -29,7 +29,7 @@ use thrussh::{ }; use thrussh_keys::key::PublicKey; use tokio::sync::mpsc::UnboundedSender; -use tracing::{error, info, info_span, instrument::Instrumented, Instrument, Span}; +use tracing::{debug, error, info, info_span, instrument::Instrumented, Instrument, Span}; pub static KEYBOARD_INTERACTIVE_PROMPT: &[(Cow<'static, str>, bool)] = &[(Cow::Borrowed("Password: "), false)]; @@ -154,11 +154,7 @@ impl thrussh::server::Handler for Connection { let res = if self.try_login(user, password) { Auth::Accept } else { - Auth::Partial { - name: "".into(), - instructions: "".into(), - prompts: KEYBOARD_INTERACTIVE_PROMPT.into(), - } + Auth::Reject }; self.finished_auth(res) @@ -183,36 +179,33 @@ impl thrussh::server::Handler for Connection { } fn auth_keyboard_interactive( - self, - _user: &str, + mut self, + user: &str, _submethods: &str, - _response: Option, + mut response: Option, ) -> Self::FutureAuth { - let span = info_span!(parent: &self.span, "auth_publickey"); + let span = info_span!(parent: &self.span, "auth_keyboard_interactive"); let _entered = span.enter(); - let result = Auth::Reject; - - // TODO: why doesn't this work - // let result = if let Some(password) = response - // .as_mut() - // .and_then(Response::next) - // .map(String::from_utf8_lossy) - // { - // if self.try_login(user, password.as_ref()) { - // Auth::Accept - // } else { - // Auth::Reject - // } - // } else { - // debug!("Client is attempting keyboard-interactive, obliging"); - // - // Auth::Partial { - // name: "".into(), - // instructions: "".into(), - // prompts: KEYBOARD_INTERACTIVE_PROMPT.into(), - // } - // }; + let result = if let Some(password) = response + .as_mut() + .and_then(Response::next) + .map(String::from_utf8_lossy) + { + if self.try_login(user, password.as_ref()) { + Auth::Accept + } else { + Auth::Reject + } + } else { + debug!("Client is attempting keyboard-interactive, obliging"); + + Auth::Partial { + name: "".into(), + instructions: "".into(), + prompts: KEYBOARD_INTERACTIVE_PROMPT.into(), + } + }; self.finished_auth(result) } @@ -221,8 +214,6 @@ impl thrussh::server::Handler for Connection { let span = info_span!(parent: &self.span, "channel_close"); let _entered = span.enter(); - info!("In here"); - session.channel_success(channel); self.finished(session).boxed().wrap(Span::current()) } @@ -241,8 +232,6 @@ impl thrussh::server::Handler for Connection { let span = info_span!(parent: &self.span, "channel_open_session"); let _entered = span.enter(); - info!("In here"); - session.channel_success(channel); self.finished(session).boxed().wrap(Span::current()) } -- libgit2 1.7.2