🏡 index : ~doyle/pisshoff.git

author Jordan Doyle <jordan@doyle.la> 2023-06-25 15:46:17.0 +00:00:00
committer Jordan Doyle <jordan@doyle.la> 2023-06-25 15:46:17.0 +00:00:00
commit
6e1b423f11e391570f077c62124365dcfa28598c [patch]
tree
fa52799b2d32b65fa0101afea11cc514db5a3de4
parent
f2959023893ae422dd929a487ad664700bc9c833
download
6e1b423f11e391570f077c62124365dcfa28598c.tar.gz

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(-)

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<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 = 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())
    }