diff --git a/Cargo.toml b/Cargo.toml index 0cbfcc3ac06ab2728267cc4ce8ca7c86f2fa0112..6c57ed48e9100a138d7013a9aed9832483d30991 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -15,6 +15,7 @@ crate-type = [ "cdylib" ] [dependencies] pamsm = { version = "^0.4.2", features = ["libpam"] } oauth2 = "^4.0.0" +reqwest = "^0.11.3" config = "^0.11.0" log = "^0.4.11" syslog = "^5.0.0" diff --git a/src/pam.rs b/src/pam.rs index cb51a9430ff07cf42f155c96dfba8f35003358d4..f85ab5064013af99ddd2c20fd1f8599ca513607c 100644 --- a/src/pam.rs +++ b/src/pam.rs @@ -25,6 +25,7 @@ use oauth2::{ AuthUrl, ClientId, ClientSecret, + RequestTokenError, ResourceOwnerPassword, ResourceOwnerUsername, Scope, @@ -34,6 +35,7 @@ use oauth2::basic::{ BasicClient, BasicTokenResponse }; +use oauth2::reqwest; use oauth2::reqwest::http_client; use pamsm::{PamServiceModule, Pam, PamFlag, PamError, PamLibExt}; @@ -71,17 +73,51 @@ fn do_legacy_auth(username: String, password: String, config: Config) -> Result< let scope = get_or_pam_error(&config, "pam.scope")?; let client = BasicClient::new(client_id, Some(client_secret), auth_url, Some(token_url)); - match client + let result = client .exchange_password( &ResourceOwnerUsername::new(username), &ResourceOwnerPassword::new(password) ) .add_scope(Scope::new(scope.to_string())) - .request(http_client) { + .request(http_client); + match result { Ok(t) => Ok(t), - Err(e) => { - error!("Error requesting grant: {}", e); - return Err(PamError::AUTHINFO_UNAVAIL); + Err(e) => match e { + RequestTokenError::Request(re) => match re { + reqwest::Error::Reqwest(ree) => { + if ree.is_status() { + error!("Authentication failed for invalid grant: {}", ree); + return Err(PamError::AUTH_ERR); + } else { + error!("Request error requesting token: {}", ree); + return Err(PamError::AUTHINFO_UNAVAIL); + } + }, + reqwest::Error::Http(he) => { + error!("HTTP error requesting token: {}", he); + return Err(PamError::AUTHINFO_UNAVAIL); + }, + reqwest::Error::Io(ioe) => { + error!("IO error requesting token: {}", ioe); + return Err(PamError::SYSTEM_ERR); + }, + _ => { + error!("Unknown error: {}", re); + return Err(PamError::SERVICE_ERR); + }, + }, + RequestTokenError::ServerResponse(t) => { + error!("Authorization server returned error: {}", t); + return Err(PamError::AUTH_ERR); + }, + RequestTokenError::Parse(pe, _) => { + error!("Error parsing response: {}", pe); + return Err(PamError::SERVICE_ERR); + }, + _ => { + error!("Unknown error: {}", e); + return Err(PamError::SERVICE_ERR); + }, }, } }