summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorWez Furlong <wez@wezfurlong.org>2019-07-24 08:04:51 -0700
committerWez Furlong <wez@wezfurlong.org>2019-07-31 15:26:38 -0700
commitf29ca5b717858d365f0477d824d2069ce727a702 (patch)
tree2b9d1301603b0ae38d5bb7650e42454b50fd14b3 /tests
parent3aa8096bc4e1c6c762f8553c516b5ce099ba5f71 (diff)
downloadssh2-rs-f29ca5b717858d365f0477d824d2069ce727a702.zip
Support keyboard-interactive authentication
Refs: https://github.com/alexcrichton/ssh2-rs/issues/65
Diffstat (limited to 'tests')
-rw-r--r--tests/all/session.rs73
-rwxr-xr-xtests/run_integration_tests.sh1
2 files changed, 73 insertions, 1 deletions
diff --git a/tests/all/session.rs b/tests/all/session.rs
index 2c636a2..5e45d53 100644
--- a/tests/all/session.rs
+++ b/tests/all/session.rs
@@ -4,7 +4,7 @@ use std::io::prelude::*;
use std::path::Path;
use tempdir::TempDir;
-use ssh2::{HashType, MethodType, Session};
+use ssh2::{HashType, KeyboardInteractivePrompt, MethodType, Prompt, Session};
#[test]
fn smoke() {
@@ -48,6 +48,77 @@ fn smoke_handshake() {
}
#[test]
+fn keyboard_interactive() {
+ let user = env::var("USER").unwrap();
+ let socket = ::socket();
+ let mut sess = Session::new().unwrap();
+ sess.handshake(socket).unwrap();
+ sess.host_key().unwrap();
+ let methods = sess.auth_methods(&user).unwrap();
+ assert!(methods.contains("keyboard-interactive"), "{}", methods);
+ assert!(!sess.authenticated());
+
+ // We don't know the correct response for whatever challenges
+ // will be returned to us, but that's ok; the purpose of this
+ // test is to check that we have some basically sane interaction
+ // with the library.
+
+ struct Prompter {
+ some_data: usize,
+ }
+
+ impl KeyboardInteractivePrompt for Prompter {
+ fn prompt<'a>(
+ &mut self,
+ username: &str,
+ instructions: &str,
+ prompts: &[Prompt<'a>],
+ ) -> Vec<String> {
+ // Sanity check that the pointer manipulation resolves and
+ // we read back our member data ok
+ assert_eq!(self.some_data, 42);
+
+ eprintln!("username: {}", username);
+ eprintln!("instructions: {}", instructions);
+ eprintln!("prompts: {:?}", prompts);
+
+ // Unfortunately, we can't make any assertions about username
+ // or instructions, as they can be empty (on my linux system)
+ // or may have arbitrary contents
+ // assert_eq!(username, env::var("USER").unwrap());
+ // assert!(!instructions.is_empty());
+
+ // Hopefully this isn't too brittle an assertion
+ if prompts.len() == 1 {
+ assert_eq!(prompts.len(), 1);
+ // Might be "Password: " or "Password:" or other variations
+ assert!(prompts[0].text.contains("sword"));
+ assert_eq!(prompts[0].echo, false);
+ } else {
+ // maybe there's some PAM configuration that results
+ // in multiple prompts. We can't make any real assertions
+ // in this case, other than that there has to be at least
+ // one prompt.
+ assert!(!prompts.is_empty());
+ }
+
+ prompts.iter().map(|_| "bogus".to_string()).collect()
+ }
+ }
+
+ let mut p = Prompter { some_data: 42 };
+
+ match sess.userauth_keyboard_interactive(&user, &mut p) {
+ Ok(_) => eprintln!("auth succeeded somehow(!)"),
+ Err(err) => eprintln!("auth failed as expected: {}", err),
+ };
+
+ // The only way this assertion will be false is if the person
+ // running these tests has "bogus" as their password
+ assert!(!sess.authenticated());
+}
+
+#[test]
fn keepalive() {
let sess = ::authed_session();
sess.set_keepalive(false, 10);
diff --git a/tests/run_integration_tests.sh b/tests/run_integration_tests.sh
index 784a734..a1f8b0b 100755
--- a/tests/run_integration_tests.sh
+++ b/tests/run_integration_tests.sh
@@ -46,6 +46,7 @@ UsePAM yes
X11Forwarding yes
PrintMotd yes
PermitTunnel yes
+KbdInteractiveAuthentication yes
AllowTcpForwarding yes
MaxStartups 500
# Relax modes when the repo is under eg: /var/tmp