From 17a16370502a751fdb702d65a09bde6d660a1d1b Mon Sep 17 00:00:00 2001 From: 34n0 <34n0@immerda.ch> Date: Sun, 21 Jan 2024 23:15:33 +0100 Subject: [PATCH] refactor: update deps, more concise config, better logging fix #43 #42 #20 --- Cargo.lock | 18 ++++++------- Cargo.toml | 20 +++++++-------- README.md | 2 +- crates/cli/Cargo.toml | 2 +- crates/cli/src/cmd/reset.rs | 2 +- crates/cli/src/main.rs | 2 +- crates/lib/Cargo.toml | 4 +-- crates/lib/src/lib.rs | 18 +++++++++---- crates/lib/src/tally.rs | 4 +-- crates/util/Cargo.toml | 4 +-- crates/util/src/config.rs | 32 ++++++++++++++++-------- crates/util/src/settings.rs | 9 +++---- crates/util/src/types.rs | 2 +- crates/xtask-test-integration/Cargo.toml | 2 +- examples/system-auth/authramp.conf | 2 +- tests/test-pam-auth.rs | 2 +- 16 files changed, 70 insertions(+), 55 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6d65e3c..ad5eefe 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -754,9 +754,9 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "proc-macro2" -version = "1.0.76" +version = "1.0.78" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95fc56cda0b5c3325f5fbbd7ff9fda9e02bb00bb3dac51252d2f1bfa1cb8cc8c" +checksum = "e2422ad645d89c99f8f3e6b88a9fdeca7fabeac836b1002371c4367c8f984aae" dependencies = [ "unicode-ident", ] @@ -838,13 +838,13 @@ dependencies = [ [[package]] name = "regex" -version = "1.10.2" +version = "1.10.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "380b951a9c5e80ddfd6136919eef32310721aa4aacd4889a8d39124b026ab343" +checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.3", + "regex-automata 0.4.4", "regex-syntax 0.8.2", ] @@ -859,9 +859,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f804c7828047e88b2d32e2d7fe5a105da8ee3264f01902f796c8e067dc2483f" +checksum = "3b7fa1134405e2ec9353fd416b17f8dacd46c473d7d3fd1cf202706a14eb792a" dependencies = [ "aho-corasick", "memchr", @@ -1013,9 +1013,9 @@ checksum = "a7cee0529a6d40f580e7a5e6c495c8fbfe21b7b52795ed4bb5e62cdf92bc6380" [[package]] name = "smallvec" -version = "1.13.0" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3b187f0231d56fe41bfb12034819dd2bf336422a5866de41bc3fec4b2e3883e8" +checksum = "e6ecd384b10a64542d77071bd64bd7b231f4ed5940fba55e98c3de13824cf3d7" [[package]] name = "strsim" diff --git a/Cargo.toml b/Cargo.toml index 32c50ec..44a5b0f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -12,21 +12,21 @@ homepage = "https://github.com/34N0/pam-authramp/" repository = "https://github.com/34N0/pam-authramp/" [workspace.dependencies] +anyhow = "1.0.75" chrono = "0.4.31" +clap = { version = "4.4.16", features = ["derive"] } +cli-xtask = { version = "0.8.0", features = ["main", "lib-crate"] } +colored = "2.1.0" +log = "0.4" pam-bindings = "0.1.1" +pam-client = "0.5.0" sysinfo = "0.30.0" syslog = "6.1.0" -uzers = "0.11.3" -log = "0.4" -toml = "0.8.8" -pam-client = "0.5.0" -tempfile = "3.8.1" tempdir = "0.3.7" -anyhow = "1.0.75" -cli-xtask = { version = "0.8.0", features = ["main", "lib-crate"] } +tempfile = "3.8.1" +toml = "0.8.8" +uzers = "0.11.3" xshell = "0.2.5" -clap = { version = "4.4.16", features = ["derive"] } -colored = "2.1.0" [workspace.lints.clippy] pedantic = { level = "deny" } @@ -42,8 +42,8 @@ license.workspace = true [dev-dependencies] pam-client.workspace = true -tempfile.workspace = true tempdir.workspace = true +tempfile.workspace = true [package.metadata.generate-rpm] assets = [ diff --git a/README.md b/README.md index e419fde..bca7766 100644 --- a/README.md +++ b/README.md @@ -54,7 +54,7 @@ Create a configuration file under /etc/security/authramp.conf. This is an exampl # AuthRamp Configuration File # This file configures the behavior of the AuthRamp PAM module. # -[Settings] +[Configuration] # Directory where tally information is stored. # Each user has a separate file in this directory to track authentication failures. tally_dir = /var/run/authramp diff --git a/crates/cli/Cargo.toml b/crates/cli/Cargo.toml index 81257f8..ee411d2 100644 --- a/crates/cli/Cargo.toml +++ b/crates/cli/Cargo.toml @@ -15,8 +15,8 @@ doc = false [dependencies] clap = { workspace = true, features = ["derive"] } -log.workspace = true colored.workspace = true +log.workspace = true util = { path = "../util" } [dev-dependencies] diff --git a/crates/cli/src/cmd/reset.rs b/crates/cli/src/cmd/reset.rs index 6a36fd4..38d97ad 100644 --- a/crates/cli/src/cmd/reset.rs +++ b/crates/cli/src/cmd/reset.rs @@ -3,7 +3,7 @@ //! The `reset` module provides functionality to reset the tally information for a user. //! It is used in the context of the `sm_authenticate` PAM hook when the `reset` command is specified. //! The tally information is stored in a file, and this module allows resetting the tally for a specific user. -//! +//! //! ## License //! //! pam-authramp diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index d88b007..1b3a35e 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -26,7 +26,7 @@ //! - [`ArCliResult`](struct.ArCliResult.html): Represents the result of a command execution in the `AuthRamp` CLI. //! - [`Cli`](struct.Cli.html): Represents the main CLI struct. //! - [`Command`](enum.Command.html): Represents the available subcommands. -//! +//! //! ## License //! //! pam-authramp diff --git a/crates/lib/Cargo.toml b/crates/lib/Cargo.toml index 4a46478..a496132 100644 --- a/crates/lib/Cargo.toml +++ b/crates/lib/Cargo.toml @@ -16,11 +16,11 @@ doc = false [dependencies] chrono.workspace = true +log.workspace = true pam-bindings.workspace = true -uzers.workspace = true toml.workspace = true -log.workspace = true util = { path = "../util" } +uzers.workspace = true [dev-dependencies] tempdir.workspace = true diff --git a/crates/lib/src/lib.rs b/crates/lib/src/lib.rs index db9b043..ba92c2e 100644 --- a/crates/lib/src/lib.rs +++ b/crates/lib/src/lib.rs @@ -12,12 +12,12 @@ //! //! ## Configuration //! -//! The behavior of the `AuthRamp` module is configurable through an INI file located at +//! The behavior of the `AuthRamp` module is configurable through an TOML file located at //! `/etc/security/authramp.conf` by default. The configuration file can be customized with settings //! such as the tally directory, free tries threshold, base delay, and multiplier. //! //! ```ini -//! [Settings] +//! [Configuration] //! tally_dir = /var/run/authramp //! free_tries = 6 //! base_delay_seconds = 30 @@ -57,10 +57,10 @@ use pam::pam_try; use std::cmp::min; use std::ffi::CStr; use std::thread::sleep; -use uzers::get_user_by_name; -use util::log_info; use util::settings::Settings; use util::types::Actions; +use util::{log_error, log_info}; +use uzers::get_user_by_name; use tally::Tally; @@ -252,7 +252,7 @@ fn bounce_auth(pamh: &mut PamHandle, settings: &Settings, tally: &Tally) -> PamR let capped_remaining_time = min(remaining_time, Duration::hours(24)); // Send a message to the conversation function - let _ = conv.send( + let conv_res = conv.send( PAM_ERROR_MSG, &format!( "Account locked! Unlocking in {}.", @@ -260,6 +260,14 @@ fn bounce_auth(pamh: &mut PamHandle, settings: &Settings, tally: &Tally) -> PamR ), ); + // Log Conversation Error but continue loop + match conv_res { + Ok(_) => (), + Err(pam_code) => { + log_error!("{:?}: Error starting PAM conversation.", pam_code); + } + } + // Wait for one second sleep(std::time::Duration::from_secs(1)); } diff --git a/crates/lib/src/tally.rs b/crates/lib/src/tally.rs index 43eabed..2abc656 100644 --- a/crates/lib/src/tally.rs +++ b/crates/lib/src/tally.rs @@ -43,10 +43,10 @@ use std::{ use chrono::{DateTime, Duration, Utc}; use pam::constants::PamResultCode; -use uzers::User; use util::settings::Settings; use util::types::Actions; use util::{log_error, log_info}; +use uzers::User; /// The `Tally` struct represents the account lockout information, including /// the number of authentication failures and the timestamp of the last failure. @@ -179,7 +179,7 @@ impl Tally { /// PREAUTH is ignored; /// /// # Arguments - /// - `fails_section`: A reference to the "Fails" section of the INI file. + /// - `fails_section`: A reference to the "Fails" section of the TOML file. /// - `tally`: A mutable reference to the `Tally` struct. /// - `settings`: A reference to the `Settings` struct. /// diff --git a/crates/util/Cargo.toml b/crates/util/Cargo.toml index 58bddbc..f061c9f 100644 --- a/crates/util/Cargo.toml +++ b/crates/util/Cargo.toml @@ -16,12 +16,12 @@ doc = false [dependencies] chrono.workspace = true +log.workspace = true pam-bindings.workspace = true sysinfo.workspace = true syslog.workspace = true -log.workspace = true -uzers.workspace = true toml.workspace = true +uzers.workspace = true [dev-dependencies] tempdir.workspace = true diff --git a/crates/util/src/config.rs b/crates/util/src/config.rs index d5d2caa..cc3ab7c 100644 --- a/crates/util/src/config.rs +++ b/crates/util/src/config.rs @@ -12,7 +12,7 @@ //! # Structs //! //! - [`Config`](struct.Config.html): Represents the configuration settings for `AuthRamp`. -//! +//! //! ## License //! //! pam-authramp @@ -31,10 +31,10 @@ //! You should have received a copy of the GNU General Public License //! along with this program. If not, see . - - use std::{fs, path::PathBuf}; +use crate::log_info; + const DEFAULT_CONFIG_FILE_PATH: &str = "/etc/security/authramp.conf"; #[derive(Debug)] @@ -65,11 +65,11 @@ impl Default for Config { } impl Config { - /// Loads configuration config from an INI file, returning a `Config` instance. + /// Loads configuration config from an TOML file, returning a `Config` instance. /// /// # Arguments /// - /// * `config_file`: An optional `PathBuf` specifying the path to the INI file. If + /// * `config_file`: An optional `PathBuf` specifying the path to the TOML file. If /// not provided, the default configuration file path is used. /// /// # Returns @@ -87,33 +87,43 @@ impl Config { content.and_then(|c| toml::de::from_str(&c).ok()); // Extract the "Config" section from the TOML table - let config = toml_table.and_then(|t| t.get("Settings").cloned()); + let config = toml_table.and_then(|t| t.get("Configuration").cloned()); // Map the config to the Config struct - config - .map(|s| Config { + config.map_or_else( + || { + log_info!( + "PAM_SYSTEM_ERR: Error parsing configuration file. Using default values." + ); + Config::default() + }, + |s| Config { tally_dir: s .get("tally_dir") .and_then(|val| val.as_str().map(PathBuf::from)) .unwrap_or_else(|| Config::default().tally_dir), + free_tries: s .get("free_tries") .and_then(toml::Value::as_integer) .map_or_else(|| Config::default().free_tries, |val| val as i32), + base_delay_seconds: s .get("base_delay_seconds") .and_then(toml::Value::as_integer) .map_or_else(|| Config::default().base_delay_seconds, |val| val as i32), + ramp_multiplier: s .get("ramp_multiplier") .and_then(toml::Value::as_float) .map_or_else(|| Config::default().ramp_multiplier, |val| val as i32), + even_deny_root: s .get("even_deny_root") .and_then(toml::Value::as_bool) .unwrap_or_else(|| Config::default().even_deny_root), - }) - .unwrap_or_default() + }, + ) } } @@ -141,7 +151,7 @@ mod tests { // Create a TOML file with settings let toml_content = r#" - [Settings] + [Configuration] tally_dir = "/tmp/tally_dir" free_tries = 10 base_delay_seconds = 15 diff --git a/crates/util/src/settings.rs b/crates/util/src/settings.rs index b436f14..ae1560d 100644 --- a/crates/util/src/settings.rs +++ b/crates/util/src/settings.rs @@ -1,14 +1,11 @@ //! # Settings Module //! //! The `settings` module is responsible for managing configuration settings related to the -//! authramp PAM module. It provides a structure `Settings` and functions to load configuration -//! from an INI file, build settings based on user input, and set default values. +//! authramp PAM module. //! //! ## Overview //! //! The `Settings` structure represents the configuration settings for the authramp PAM module. -//! It includes fields such as `action`, `user`, `tally_dir`, `free_tries`, `base_delay_seconds`, -//! and `ramp_multiplier`. //! //! ## License //! @@ -72,7 +69,7 @@ impl Settings<'_> { /// the PAM session. /// * `args`: A vector of `CStr` references representing the PAM module arguments. /// * `_flags`: PAM flags indicating the context of the PAM operation (unused). - /// * `config_file`: An optional `PathBuf` specifying the path to the INI file. If + /// * `config_file`: An optional `PathBuf` specifying the path to the TOML file. If /// not provided, the default configuration file path is used. /// /// # Returns @@ -89,7 +86,7 @@ impl Settings<'_> { _flags: PamFlag, pam_hook: &'a str, ) -> Result, PamResultCode> { - // Load INI file. + // Load TOML file. let mut settings = Settings::default(); // create possible action collection diff --git a/crates/util/src/types.rs b/crates/util/src/types.rs index 6a88d69..96e0076 100644 --- a/crates/util/src/types.rs +++ b/crates/util/src/types.rs @@ -10,7 +10,7 @@ //! # Enumerations //! //! - [`Actions`](enum.Actions.html): Represents different actions in the `AuthRamp` library. -//! +//! //! ## License //! //! pam-authramp diff --git a/crates/xtask-test-integration/Cargo.toml b/crates/xtask-test-integration/Cargo.toml index e57a6d2..565bd7b 100644 --- a/crates/xtask-test-integration/Cargo.toml +++ b/crates/xtask-test-integration/Cargo.toml @@ -5,9 +5,9 @@ version.workspace = true publish = false [dependencies] +anyhow.workspace = true cli-xtask.workspace = true xshell.workspace = true -anyhow.workspace = true [lints] workspace = true \ No newline at end of file diff --git a/examples/system-auth/authramp.conf b/examples/system-auth/authramp.conf index d4b6815..db8880d 100644 --- a/examples/system-auth/authramp.conf +++ b/examples/system-auth/authramp.conf @@ -1,7 +1,7 @@ # AuthRamp Configuration File # This file configures the behavior of the AuthRamp PAM module. # -[Settings] +[Configuration] # Directory where tally information is stored. # Each user has a separate file in this directory to track authentication failures. # tally_dir = /var/run/authramp diff --git a/tests/test-pam-auth.rs b/tests/test-pam-auth.rs index e2f964a..a3a2ed7 100644 --- a/tests/test-pam-auth.rs +++ b/tests/test-pam-auth.rs @@ -203,7 +203,7 @@ mod test_pam_auth { // Set the custom tally_dir path in authramp.conf let config_content = format!( - "[Settings]\n\ + "[Configuration]\n\ tally_dir = \"{}\"\n\ free_tries = 6\n\ base_delay_seconds = 30\n\