extern crate rand; extern crate ring; extern crate scram_2; use ring::digest::SHA256_OUTPUT_LEN; use scram_2::*; use std::num::NonZeroU32; struct TestProvider { user_password: [u8; SHA256_OUTPUT_LEN], admin_password: [u8; SHA256_OUTPUT_LEN], } impl TestProvider { pub fn new() -> Self { let pwd_iterations = NonZeroU32::new(4096).unwrap(); let user_password = hash_password("password", pwd_iterations, b"salt"); let adm_iterations = NonZeroU32::new(8192).unwrap(); let admin_password = hash_password("admin_password", adm_iterations, b"messy"); TestProvider { user_password, admin_password, } } } impl server::AuthenticationProvider for TestProvider { fn get_password_for(&self, username: &str) -> Option { match username { "user" => Some(server::PasswordInfo::new( self.user_password.to_vec(), 4096, "salt".bytes().collect(), )), "admin" => Some(server::PasswordInfo::new( self.admin_password.to_vec(), 8192, "messy".bytes().collect(), )), _ => None, } } fn authorize(&self, authcid: &str, authzid: &str) -> bool { authcid == authzid || authcid == "admin" && authzid == "user" } } #[test] fn test_simple_success() { let scram_client = ScramClient::new("user", "password", None); let scram_server = ScramServer::new(TestProvider::new()); let (scram_client, client_first) = scram_client.client_first(); let scram_server = scram_server.handle_client_first(&client_first).unwrap(); let (scram_server, server_first) = scram_server.server_first(); let scram_client = scram_client.handle_server_first(&server_first).unwrap(); let (scram_client, client_final) = scram_client.client_final(); let scram_server = scram_server.handle_client_final(&client_final).unwrap(); let (status, server_final) = scram_server.server_final(); scram_client.handle_server_final(&server_final).unwrap(); assert_eq!(status, AuthenticationStatus::Authenticated); } #[test] fn test_bad_password() { let scram_client = ScramClient::new("user", "badpassword", None); let scram_server = ScramServer::new(TestProvider::new()); let (scram_client, client_first) = scram_client.client_first(); let scram_server = scram_server.handle_client_first(&client_first).unwrap(); let (scram_server, server_first) = scram_server.server_first(); let scram_client = scram_client.handle_server_first(&server_first).unwrap(); let (scram_client, client_final) = scram_client.client_final(); let scram_server = scram_server.handle_client_final(&client_final).unwrap(); let (status, server_final) = scram_server.server_final(); assert_eq!(status, AuthenticationStatus::NotAuthenticated); assert!(scram_client.handle_server_final(&server_final).is_err()); } #[test] fn test_authorize_different() { let scram_client = ScramClient::new("admin", "admin_password", Some("user")); let scram_server = ScramServer::new(TestProvider::new()); let (scram_client, client_first) = scram_client.client_first(); let scram_server = scram_server.handle_client_first(&client_first).unwrap(); let (scram_server, server_first) = scram_server.server_first(); let scram_client = scram_client.handle_server_first(&server_first).unwrap(); let (scram_client, client_final) = scram_client.client_final(); let scram_server = scram_server.handle_client_final(&client_final).unwrap(); let (status, server_final) = scram_server.server_final(); scram_client.handle_server_final(&server_final).unwrap(); assert_eq!(status, AuthenticationStatus::Authenticated); } #[test] fn test_authorize_fail() { let scram_client = ScramClient::new("user", "password", Some("admin")); let scram_server = ScramServer::new(TestProvider::new()); let (scram_client, client_first) = scram_client.client_first(); let scram_server = scram_server.handle_client_first(&client_first).unwrap(); let (scram_server, server_first) = scram_server.server_first(); let scram_client = scram_client.handle_server_first(&server_first).unwrap(); let (scram_client, client_final) = scram_client.client_final(); let scram_server = scram_server.handle_client_final(&client_final).unwrap(); let (status, server_final) = scram_server.server_final(); assert_eq!(status, AuthenticationStatus::NotAuthorized); assert!(scram_client.handle_server_final(&server_final).is_err()); } #[test] fn test_authorize_non_existent() { let scram_client = ScramClient::new("admin", "admin_password", Some("nonexistent")); let scram_server = ScramServer::new(TestProvider::new()); let (scram_client, client_first) = scram_client.client_first(); let scram_server = scram_server.handle_client_first(&client_first).unwrap(); let (scram_server, server_first) = scram_server.server_first(); let scram_client = scram_client.handle_server_first(&server_first).unwrap(); let (scram_client, client_final) = scram_client.client_final(); let scram_server = scram_server.handle_client_final(&client_final).unwrap(); let (status, server_final) = scram_server.server_final(); assert_eq!(status, AuthenticationStatus::NotAuthorized); assert!(scram_client.handle_server_final(&server_final).is_err()); } #[test] fn test_invalid_user() { let scram_client = ScramClient::new("nobody", "password", None); let scram_server = ScramServer::new(TestProvider::new()); let (_, client_first) = scram_client.client_first(); assert!(scram_server.handle_client_first(&client_first).is_err()) } #[test] fn test_empty_username() { let scram_client = ScramClient::new("", "password", None); let scram_server = ScramServer::new(TestProvider::new()); let (_, client_first) = scram_client.client_first(); assert!(scram_server.handle_client_first(&client_first).is_err()) } #[test] fn test_empty_password() { let scram_client = ScramClient::new("user", "", None); let scram_server = ScramServer::new(TestProvider::new()); let (scram_client, client_first) = scram_client.client_first(); let scram_server = scram_server.handle_client_first(&client_first).unwrap(); let (scram_server, server_first) = scram_server.server_first(); let scram_client = scram_client.handle_server_first(&server_first).unwrap(); let (scram_client, client_final) = scram_client.client_final(); let scram_server = scram_server.handle_client_final(&client_final).unwrap(); let (status, server_final) = scram_server.server_final(); assert_eq!(status, AuthenticationStatus::NotAuthenticated); assert!(scram_client.handle_server_final(&server_final).is_err()); }