use bssh::commands::interactive::connection::is_auth_error_for_password_fallback;
use bssh::ssh::tokio_client::Error as SshError;
#[test]
fn test_all_agent_errors_trigger_password_fallback() {
let agent_errors = vec![
(
SshError::AgentAuthenticationFailed,
"AgentAuthenticationFailed",
),
(SshError::AgentNoIdentities, "AgentNoIdentities"),
(SshError::AgentConnectionFailed, "AgentConnectionFailed"),
(
SshError::AgentRequestIdentitiesFailed,
"AgentRequestIdentitiesFailed",
),
];
for (error, name) in agent_errors {
assert!(
is_auth_error_for_password_fallback(&error),
"{} should trigger password fallback",
name
);
}
}
#[test]
fn test_key_auth_failure_triggers_password_fallback() {
let error = SshError::KeyAuthFailed;
assert!(
is_auth_error_for_password_fallback(&error),
"KeyAuthFailed should trigger password fallback"
);
}
#[test]
fn test_non_auth_errors_do_not_trigger_fallback() {
let non_auth_errors: Vec<(SshError, &str)> = vec![
(SshError::PasswordWrong, "PasswordWrong"),
(SshError::ServerCheckFailed, "ServerCheckFailed"),
(SshError::CommandDidntExit, "CommandDidntExit"),
(
SshError::KeyboardInteractiveAuthFailed,
"KeyboardInteractiveAuthFailed",
),
(
SshError::IoError(std::io::Error::new(
std::io::ErrorKind::ConnectionRefused,
"connection refused",
)),
"IoError",
),
];
for (error, name) in non_auth_errors {
assert!(
!is_auth_error_for_password_fallback(&error),
"{} should NOT trigger password fallback",
name
);
}
}
#[test]
fn test_password_wrong_prevents_infinite_loop() {
let error = SshError::PasswordWrong;
assert!(
!is_auth_error_for_password_fallback(&error),
"PasswordWrong must NOT trigger password fallback to prevent infinite retry loops"
);
}
#[test]
fn test_host_key_verification_not_bypassed() {
let error = SshError::ServerCheckFailed;
assert!(
!is_auth_error_for_password_fallback(&error),
"ServerCheckFailed must NOT trigger password fallback - host key verification is a security feature"
);
}