From 34ef60dfdd77987181a85998d310782daac7ac12 Mon Sep 17 00:00:00 2001 From: 34n0 <34n0@immerda.ch> Date: Thu, 11 Apr 2024 13:43:32 +0200 Subject: [PATCH] feat: configurable countdown #70 --- README.md | 13 ++++++++----- crates/common/src/config.rs | 9 +++++++++ examples/system-auth/authramp.conf | 5 ++++- src/lib.rs | 15 ++++++++++----- src/tally.rs | 4 +++- 5 files changed, 34 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 10f6a6a..533c44a 100644 --- a/README.md +++ b/README.md @@ -58,25 +58,28 @@ Create a configuration file under /etc/security/authramp.conf. This is an exampl [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 +# tally_dir = /var/run/authramp # # Number of allowed free authentication attempts before applying delays. # During these free tries, the module allows authentication without introducing delays. -free_tries = 6 +# free_tries = 6 # # Base delay applied to each authentication failure. # This is the initial delay applied after the free tries are exhausted. -base_delay_seconds = 30 +# base_delay_seconds = 30 # # Multiplier for the delay calculation based on the number of failures. # The delay for each subsequent failure is calculated as follows: # delay = ramp_multiplier * (fails - free_tries) * ln(fails - free_tries) + base_delay_seconds -ramp_multiplier = 50 +# ramp_multiplier = 50 # # Even lock out the root user. Enabling this can be dangerous and may result in a total system lockout. # For auditing purposes, the tally will still be created for the root user, even if this setting is disabled. # If you plan to enable this feature, make sure there isn't any tally stored under /root, or you risk immediate lockout. -even_deny_root = false +# even_deny_root = false +# +# Whether the PAM user messages in the login screen should update automatically or not. +# countdown = true ``` ### default delay The default configuration of this module is very restrictive. The standard delays are: diff --git a/crates/common/src/config.rs b/crates/common/src/config.rs index cff0a53..c268f64 100644 --- a/crates/common/src/config.rs +++ b/crates/common/src/config.rs @@ -47,6 +47,8 @@ pub struct Config { pub ramp_multiplier: i32, // Even lock out root user pub even_deny_root: bool, + // Count down lockout loop, + pub countdown: bool, } impl Default for Config { @@ -58,6 +60,7 @@ impl Default for Config { base_delay_seconds: 30, ramp_multiplier: 50, even_deny_root: false, + countdown: false, } } } @@ -113,6 +116,11 @@ impl Config { .get("even_deny_root") .and_then(toml::Value::as_bool) .unwrap_or_else(|| Config::default().even_deny_root), + + countdown: s + .get("countdown") + .and_then(toml::Value::as_bool) + .unwrap_or_else(|| Config::default().countdown), }) } } @@ -131,6 +139,7 @@ mod tests { assert_eq!(default_config.free_tries, 6); assert_eq!(default_config.base_delay_seconds, 30); assert_eq!(default_config.ramp_multiplier, 50); + assert_eq!(default_config.countdown, true); assert!(!default_config.even_deny_root); } diff --git a/examples/system-auth/authramp.conf b/examples/system-auth/authramp.conf index db8880d..a5a13db 100644 --- a/examples/system-auth/authramp.conf +++ b/examples/system-auth/authramp.conf @@ -22,4 +22,7 @@ # Even lock out the root user. Enabling this can be dangerous and may result in a total system lockout. # For auditing purposes, the tally will still be created for the root user, even if this setting is disabled. # If you plan to enable this feature, make sure there isn't any tally stored under /root, or you risk immediate lockout. -# even_deny_root = false \ No newline at end of file +# even_deny_root = false +# +# Whether the PAM user messages in the login screen should update automatically or not. +# countdown = true diff --git a/src/lib.rs b/src/lib.rs index 24a6870..5d5a85e 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -58,6 +58,7 @@ use pam::{PamFlag, PamResultCode, PAM_TEXT_INFO}; use pam::{PamHandle, PamHooks}; use std::cmp::min; use std::ffi::CStr; +use std::thread::sleep; use uzers::get_user_by_name; use tally::Tally; @@ -92,7 +93,7 @@ impl PamHooks for Pamauthramp { Actions::PREAUTH => Ok(bounce_auth(pamh, settings, tally)), // bounce if called with authfail Actions::AUTHFAIL => Err(bounce_auth(pamh, settings, tally)), - Actions::AUTHSUCC => Err(PamResultCode::PAM_AUTH_ERR), + Actions::AUTHSUCC => Ok(PamResultCode::PAM_SUCCESS), } }) .unwrap_or_else(|e| e) @@ -177,7 +178,7 @@ fn format_remaining_time(remaining_time: Duration) -> String { } else { unit }; - formatted_time.push_str(&format!("{value} {unit_str}")); + formatted_time.push_str(&format!("{value} {unit_str} ")); } } @@ -240,7 +241,7 @@ fn bounce_auth(pamh: &mut PamHandle, settings: &Settings, tally: &Tally) -> PamR } // disable loop for now (#48, #50) - if Utc::now() < unlock_instant { + while Utc::now() < unlock_instant { // Calculate remaining time until unlock let remaining_time = unlock_instant - Utc::now(); @@ -270,9 +271,13 @@ fn bounce_auth(pamh: &mut PamHandle, settings: &Settings, tally: &Tally) -> PamR } } + // Don't loop if configured + if !settings.config.countdown { + return PamResultCode::PAM_AUTH_ERR; + } + // Wait for one second - // sleep(std::time::Duration::from_secs(1)); - return PamResultCode::PAM_AUTH_ERR; + sleep(std::time::Duration::from_secs(1)); } } else { println!("Init Conversation failed"); diff --git a/src/tally.rs b/src/tally.rs index a68d5bd..da4a70f 100644 --- a/src/tally.rs +++ b/src/tally.rs @@ -204,7 +204,7 @@ impl Tally { /// Updates tally information based on a section from the tally file. /// - /// AUTHSUCC deteltes the tally + /// AUTHSUCC deletes the tally /// AUTHERR increases the tally /// PREAUTH is ignored; /// @@ -497,6 +497,7 @@ mod tests { ramp_multiplier: 50, base_delay_seconds: 30, even_deny_root: false, + countdown: true, }; // Create settings and call new_from_tally_file with AUTHFAIL action @@ -542,6 +543,7 @@ mod tests { ramp_multiplier: 50, base_delay_seconds: 30, even_deny_root: false, + countdown: true, }; // Create settings and call new_from_tally_file with AUTHSUCC action