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.
Diff
Cargo.lock | 6 ++----
Cargo.toml | 4 ++++
src/server.rs | 61 +++++++++++++++++++++++++++++++------------------------------
3 files changed, 31 insertions(+), 40 deletions(-)
@@ -1184,8 +1184,7 @@
[[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 @@
[[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",
@@ -23,3 +23,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" }
@@ -29,7 +29,7 @@
};
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 @@
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 @@
}
fn auth_keyboard_interactive(
self,
_user: &str,
mut self,
user: &str,
_submethods: &str,
_response: Option<Response>,
mut response: Option<Response>,
) -> 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 = 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");
let result = Auth::Reject;
Auth::Partial {
name: "".into(),
instructions: "".into(),
prompts: KEYBOARD_INTERACTIVE_PROMPT.into(),
}
};
self.finished_auth(result)
}
@@ -220,8 +213,6 @@
fn channel_close(self, channel: ChannelId, mut session: Session) -> Self::FutureUnit {
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())
@@ -240,8 +231,6 @@
fn channel_open_session(self, channel: ChannelId, mut session: Session) -> Self::FutureUnit {
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())