alexcrichton / ssh2-rs

Rust bindings for libssh2
https://docs.rs/ssh2
Apache License 2.0
482 stars 145 forks source link

Error on keyboard interactive auth #326

Open GeniusV opened 3 weeks ago

GeniusV commented 3 weeks ago

System: M1 Mac @ macOS 14.5

Hi, I recently try login my company sftp server with keyboard interactive auth, But I got:

thread 'sftp_test::sync_test::test_sync' panicked at library/core/src/panicking.rs:156:5:
unsafe precondition(s) violated: slice::from_raw_parts requires the pointer to be aligned and non-null, and the total size of the slice not to exceed `isize::MAX`
stack backtrace:
   0: _rust_begin_unwind
   1: core::panicking::panic_nounwind_fmt
   2: core::panicking::panic_nounwind
   3: core::slice::raw::from_raw_parts::precondition_check
             at /private/tmp/rust-20240518-7986-rmyaj5/rustc-1.78.0-src/library/core/src/intrinsics.rs:2799:21
   4: core::slice::raw::from_raw_parts
             at /private/tmp/rust-20240518-7986-rmyaj5/rustc-1.78.0-src/library/core/src/slice/raw.rs:98:9
   5: ssh2::session::Session::userauth_keyboard_interactive::prompt::{{closure}}
             at /Users/geniusv/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ssh2-0.9.4/src/session.rs:391:30
   6: core::ops::function::FnOnce::call_once
             at /private/tmp/rust-20240518-7986-rmyaj5/rustc-1.78.0-src/library/core/src/ops/function.rs:250:5
   7: <core::panic::unwind_safe::AssertUnwindSafe<F> as core::ops::function::FnOnce<()>>::call_once
             at /private/tmp/rust-20240518-7986-rmyaj5/rustc-1.78.0-src/library/core/src/panic/unwind_safe.rs:272:9
   8: std::panicking::try::do_call
             at /private/tmp/rust-20240518-7986-rmyaj5/rustc-1.78.0-src/library/std/src/panicking.rs:552:40
   9: ___rust_try
  10: std::panicking::try
             at /private/tmp/rust-20240518-7986-rmyaj5/rustc-1.78.0-src/library/std/src/panicking.rs:516:19
  11: std::panic::catch_unwind
             at /private/tmp/rust-20240518-7986-rmyaj5/rustc-1.78.0-src/library/std/src/panic.rs:146:14
  12: ssh2::session::Session::userauth_keyboard_interactive::prompt
             at /Users/geniusv/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ssh2-0.9.4/src/session.rs:387:21
  13: userauth_keyboard_interactive
             at /Users/geniusv/.cargo/registry/src/index.crates.io-6f17d22bba15001f/libssh2-sys-0.3.0/libssh2/src/userauth.c:2022:13
  14: libssh2_userauth_keyboard_interactive_ex
             at /Users/geniusv/.cargo/registry/src/index.crates.io-6f17d22bba15001f/libssh2-sys-0.3.0/libssh2/src/userauth.c:2162:5
  15: ssh2::session::Session::userauth_keyboard_interactive::{{closure}}
             at /Users/geniusv/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ssh2-0.9.4/src/session.rs:458:26
  16: ssh2::session::with_abstract
             at /Users/geniusv/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ssh2-0.9.4/src/session.rs:91:15
  17: ssh2::session::Session::userauth_keyboard_interactive
             at /Users/geniusv/.cargo/registry/src/index.crates.io-6f17d22bba15001f/ssh2-0.9.4/src/session.rs:457:13
  18: crate_test::sftp_test::sync_test::test_sync
             at ./src/sftp_test/sync_test.rs:80:11
  19: crate_test::sftp_test::sync_test::test_sync::{{closure}}
             at ./src/sftp_test/sync_test.rs:19:19
  20: core::ops::function::FnOnce::call_once
             at /private/tmp/rust-20240518-7986-rmyaj5/rustc-1.78.0-src/library/core/src/ops/function.rs:250:5
note: Some details are omitted, run with `RUST_BACKTRACE=full` for a verbose backtrace.
thread caused non-unwinding panic. aborting.
error: test failed, to rerun pass `--lib`

Caused by:
  process didn't exit successfully: `/Users/geniusv/Projects/rust/rust-test/target/debug/deps/crate_test-e8c1a50874cb9730 'sftp_test::sync_test::test_sync' --format=json --exact -Z unstable-options --show-output` (signal: 6, SIGABRT: process abort signal)
error: 1 target failed:
    `--lib`

My test code:

#[test]
fn test_sync() -> Result<(), Box<dyn std::error::Error>> {
    // Connect to the SFTP server
    let tcp = TcpStream::connect("ftp.comany.com:22")?;
    let mut session = Session::new().unwrap();
    session.set_tcp_stream(tcp);
    session.handshake()?;
    session.host_key().unwrap();
    let methods = session.auth_methods("dla_sftp").unwrap();
    assert!(
        methods.contains("keyboard-interactive"),
        "test server () must support `ChallengeResponseAuthentication yes`"
    );
    assert!(!session.authenticated());

    // Perform interactive authentication
    struct Prompter {
        some_data: usize,
    }

    impl KeyboardInteractivePrompt for Prompter {
        fn prompt<'a>(
            &mut self,
            username: &str,
            instructions: &str,
            prompts: &[Prompt<'a>],
        ) -> Vec<String> {
            assert_eq!(self.some_data, 42);

            eprintln!("username: {}", username);
            eprintln!("instructions: {}", instructions);
            eprintln!("prompts: {:?}", prompts);

            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 session.userauth_keyboard_interactive("dla_sftp", &mut p) {
        Ok(_) => eprintln!("auth succeeded somehow(!)"),
        Err(err) => eprintln!("auth failed as expected: {}", err),
    };

    Ok(())
}
Kek5chen commented 3 weeks ago

Same thing happening over here ✋ M3 Mac

craigdods commented 6 days ago

Same here on an M1 Mac.

The same crash does not occur on Linux with x86-64 (AMD 7950X) with the same code, so I suspect it's either MacOS related or just ARM in general