From 48e744274b455ecbb86d335c34c9a6dcbc2a1695 Mon Sep 17 00:00:00 2001 From: Dominik George <dominik.george@teckids.org> Date: Fri, 7 May 2021 00:17:27 +0200 Subject: [PATCH] Move get_optional to config, make it type-agnostic, and allow scopes as array --- Cargo.toml | 1 + src/config.rs | 9 +++++++++ src/pam.rs | 46 +++++++++++++++++++--------------------------- 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 288fb6c..f407f3a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,6 +21,7 @@ lazy_static = "^1.3.0" oauth2 = "^4.0.0" reqwest = "^0.11.3" config = "^0.11.0" +serde = "^1.0.125" log = "^0.4.11" syslog = "^5.0.0" diff --git a/src/config.rs b/src/config.rs index 7d30459..4828be0 100644 --- a/src/config.rs +++ b/src/config.rs @@ -13,6 +13,8 @@ * limitations under the License. */ +use serde::de::Deserialize; + extern crate config; const DEFAULT_CONFIG_FILE: &str = "/etc/nss_pam_oidc"; @@ -54,3 +56,10 @@ pub fn argv_to_config(argv: &Vec<String>) -> config::Config { } return conf; } + +pub fn get_optional<'de, T: Deserialize<'de>>(conf: &config::Config, key: &str) -> Option<T> { + match conf.get(key) { + Ok(v) => Some(v), + Err(_) => None, + } +} diff --git a/src/pam.rs b/src/pam.rs index 2200ee3..2761e25 100644 --- a/src/pam.rs +++ b/src/pam.rs @@ -15,10 +15,13 @@ use crate::config::{ argv_to_config, - get_config + get_config, + get_optional }; use config::Config; +use serde::de::Deserialize; + use crate::logging::setup_log; use oauth2::{ @@ -40,32 +43,19 @@ use oauth2::reqwest::http_client; use pamsm::{PamServiceModule, Pam, PamFlag, PamError, PamLibExt}; -fn get_or_pam_error(config: &Config, key: &str) -> Result<String, PamError> { - match config.get_str(key) { - Ok(v) => { - debug!("Configuration key found: {} = {}", key, v); +fn get_or_pam_error<'de, T: Deserialize<'de>>(config: &Config, key: &str) -> Result<T, PamError> { + match get_optional(config, key) { + Some(v) => { + debug!("Configuration key found: {}", key); return Ok(v); }, - Err(_) => { + None => { error!("Configuration key not found: {}", key); return Err(PamError::SERVICE_ERR); }, } } -fn get_optional(config: &Config, key: &str) -> Option<String> { - match config.get_str(key) { - Ok(v) => { - debug!("Configuration key found: {} = {}", key, v); - return Some(v); - }, - Err(_) => { - debug!("Configuration key not found (optional): {}", key); - return None; - }, - } -} - fn do_legacy_auth(username: String, password: String, config: Config) -> Result<BasicTokenResponse, PamError> { let client_id = ClientId::new(get_or_pam_error(&config, "pam.client_id")?); let client_secret = match get_optional(&config, "pam.client_secret") { @@ -89,16 +79,18 @@ fn do_legacy_auth(username: String, password: String, config: Config) -> Result< }, None => None, }; - let scope = get_or_pam_error(&config, "pam.scope")?; + let scopes: Vec<&str> = get_or_pam_error(&config, "pam.scopes")?; + + let res_username = ResourceOwnerUsername::new(username); + let res_password = ResourceOwnerPassword::new(password); let client = BasicClient::new(client_id, client_secret, auth_url, token_url); - let result = client - .exchange_password( - &ResourceOwnerUsername::new(username), - &ResourceOwnerPassword::new(password) - ) - .add_scope(Scope::new(scope.to_string())) - .request(http_client); + let mut request = client.exchange_password(&res_username, &res_password); + for scope in scopes { + request = request.add_scope(Scope::new(scope.to_string())); + } + let result = request.request(http_client); + match result { Ok(t) => Ok(t), Err(e) => match e { -- GitLab