From 735612ccfba150978d174fcc7d95b2ea3013ab9e Mon Sep 17 00:00:00 2001 From: KunoiSayami Date: Mon, 9 Feb 2026 20:59:33 +0800 Subject: refactor: Remove pam authentication method Signed-off-by: KunoiSayami --- Cargo.toml | 6 +-- README.md | 14 ------- src/authentication.rs | 11 +---- src/datastructures.rs | 112 -------------------------------------------------- src/test.rs | 17 -------- 5 files changed, 2 insertions(+), 158 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index f4be69e..288effc 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "cgit-simple-authentication" -version = "4.2.1" +version = "4.3.0" authors = ["KunoiSayami "] edition = "2024" @@ -18,7 +18,6 @@ log = { version = "0.4", features = [ "release_max_level_info", ] } log4rs = "1" -pam = { git = "https://github.com/1wilkens/pam.git", optional = true } rand = "0.10" redis = { version = "1", features = ["tokio-comp"] } regex = "1" @@ -43,6 +42,3 @@ cpufeatures = "0.3" [profile.release] lto = true panic = "abort" - -[features] -default = [] diff --git a/README.md b/README.md index 10d1844..f75eb17 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,6 @@ Simple authentication filter for [cgit](https://wiki.archlinux.org/title/Cgit) p - Password hashing with [Argon2](https://en.wikipedia.org/wiki/Argon2) - Per-repository access control lists (ACL) - Flexible protection modes: protect all repos, selected repos, or none -- Optional [PAM](https://wiki.archlinux.org/title/PAM) authentication support - Session storage via Redis for fast cookie validation - Built-in login page served by the filter - Database migration support (v2 to v3) @@ -62,7 +61,6 @@ All options are set in the `cgitrc` file: | `cgit-simple-auth-database` | `/etc/cgit/auth.db` | SQLite database file path | | `cgit-simple-auth-bypass-root` | `false` | Skip authentication on the repository list (root) page | | `cgit-simple-auth-protect` | `full` | Protection mode: `full`, `part`, or `none` | -| `cgit-simple-auth-use-pam` | `false` | PAM service name, or `false` to disable | ### Protection Modes @@ -107,18 +105,6 @@ cgit-simple-authentication repo list cgit-simple-authentication repo list my-repo ``` -### PAM Authentication - -To authenticate against system users via PAM instead of the built-in SQLite database, enable the `pam` feature at compile time and set the PAM service name: - -```shell -cargo build --release --features pam -``` - -```conf -cgit-simple-auth-use-pam=system-auth -``` - ### Logging Logs are written to `/var/cache/cgit/auth.log` by default. Override with the `LOG_FILE` environment variable. diff --git a/src/authentication.rs b/src/authentication.rs index 4d343c0..151d7e0 100644 --- a/src/authentication.rs +++ b/src/authentication.rs @@ -1,5 +1,4 @@ -#[cfg(feature = "pam")] -use crate::datastructures::AuthorizerType; + use crate::datastructures::{Config, Cookie, FormData, WrapConfigure}; use anyhow::Result; use clap::ArgMatches; @@ -215,19 +214,11 @@ pub(crate) async fn cmd_init(cfg: Config) -> Result<()> { Ok(()) } -#[cfg(not(feature = "pam"))] pub(crate) async fn verify_login(cfg: &WrapConfigure, data: &FormData) -> Result { cfg.hook().await?; data.authorize(cfg.get_authorizer()).await } -#[cfg(feature = "pam")] -pub(crate) async fn verify_login(cfg: &WrapConfigure, data: &FormData) -> Result { - if let AuthorizerType::Password = cfg.get_authorizer().method() { - cfg.hook().await?; - } - data.authorize(cfg.get_authorizer()).await -} #[derive(Serialize)] pub struct Meta<'a> { diff --git a/src/datastructures.rs b/src/datastructures.rs index 1494257..c312f8f 100644 --- a/src/datastructures.rs +++ b/src/datastructures.rs @@ -21,14 +21,10 @@ use argon2::{ password_hash::{PasswordHash, PasswordHasher, PasswordVerifier, SaltString, rand_core::OsRng}, }; use base64::Engine; -#[cfg(feature = "pam")] -pub use ds_pam::*; use log::error; use rand::RngExt; use serde::{Deserialize, Serialize}; use sqlx::ConnectOptions; -#[cfg(feature = "pam")] -use std::borrow::BorrowMut; use std::borrow::Cow; use std::fmt::{Debug, Formatter}; use std::fs::read_to_string; @@ -77,71 +73,12 @@ pub(crate) trait TestSuite { fn generate_test_config() -> Self; } -#[cfg(feature = "pam")] -pub mod ds_pam { - - #[derive(Debug, Clone)] - pub struct PAMConfig { - use_pam: bool, - provider: String, - } - - impl From<&str> for PAMConfig { - fn from(s: &str) -> Self { - let use_pam = !s.to_lowercase().eq("false"); - Self { - use_pam, - provider: s.to_string(), - } - } - } - - impl PAMConfig { - pub fn get_enabled(&self) -> bool { - self.use_pam - } - - pub fn get_provider(&self) -> &String { - &self.provider - } - } - - impl Default for PAMConfig { - fn default() -> Self { - Self { - use_pam: false, - provider: "system-auth".to_string(), - } - } - } - - #[derive(Debug, Clone)] - pub struct PAMAuthorizer { - provider: String, - } - - impl PAMAuthorizer { - pub fn provider(&self) -> &str { - &self.provider - } - } - - impl From<&PAMConfig> for PAMAuthorizer { - fn from(cfg: &PAMConfig) -> Self { - Self { - provider: cfg.get_provider().clone(), - } - } - } -} #[derive(Debug, Clone)] pub struct Config { pub cookie_ttl: u64, database: String, pub bypass_root: bool, - #[cfg(feature = "pam")] - pam_config: PAMConfig, pub(crate) test: bool, protect_config: ProtectSettings, } @@ -152,8 +89,6 @@ impl Default for Config { cookie_ttl: DEFAULT_COOKIE_TTL, database: DEFAULT_DATABASE_LOCATION.to_string(), bypass_root: false, - #[cfg(feature = "pam")] - pam_config: Default::default(), test: false, protect_config: Default::default(), } @@ -173,8 +108,6 @@ impl Config { let mut bypass_root: bool = false; let mut protect_enabled: bool = true; let mut protect_white_list_mode: bool = true; - #[cfg(feature = "pam")] - let mut use_pam: &str = "false"; //let mut skip_user_access_check: bool = false; for line in file.lines() { @@ -194,8 +127,6 @@ impl Config { "cookie-ttl" => cookie_ttl = value.parse().unwrap_or(DEFAULT_COOKIE_TTL), "database" => database = value, "bypass-root" => bypass_root = value.to_lowercase().eq("true"), - #[cfg(feature = "pam")] - "use-pam" => use_pam = value, "protect" => match value.to_lowercase().as_str() { "full" => { protect_enabled = true; @@ -219,8 +150,6 @@ impl Config { database: database.to_string(), bypass_root, - #[cfg(feature = "pam")] - pam_config: PAMConfig::from(use_pam), test: false, protect_config: ProtectSettings::from_path( protect_enabled, @@ -307,11 +236,6 @@ impl Config { self.protect_config.query_is_all_protected() } - #[cfg(feature = "pam")] - fn get_pam_config(&self) -> &PAMConfig { - &self.pam_config - } - pub fn get_test_status(&self) -> bool { self.test } @@ -323,8 +247,6 @@ impl TestSuite for Config { database: "test/tmp.db".to_string(), bypass_root: false, cookie_ttl: DEFAULT_COOKIE_TTL, - #[cfg(feature = "pam")] - pam_config: Default::default(), test: true, protect_config: ProtectSettings::generate_test_config(), } @@ -651,8 +573,6 @@ impl std::fmt::Display for Cookie { #[derive(Debug, Clone)] pub enum AuthorizerType { - #[cfg(feature = "pam")] - PAM, Password, } @@ -662,8 +582,6 @@ impl std::fmt::Display for AuthorizerType { f, "{}", match self { - #[cfg(feature = "pam")] - AuthorizerType::PAM => "PAM", AuthorizerType::Password => "PASSWORD", } ) @@ -698,7 +616,6 @@ pub struct WrapConfigure { } impl From for WrapConfigure { - #[cfg(not(feature = "pam"))] fn from(cfg: Config) -> Self { let authorizer = Box::new(SQLAuthorizer::from(&cfg)); Self { @@ -706,37 +623,8 @@ impl From for WrapConfigure { authorizer, } } - #[cfg(feature = "pam")] - fn from(cfg: Config) -> Self { - let authorizer: Box = if cfg.get_pam_config().get_enabled() { - Box::new(PAMAuthorizer::from(cfg.get_pam_config())) - } else { - Box::new(SQLAuthorizer::from(&cfg)) - }; - Self { - config: cfg, - authorizer, - } - } } -#[cfg(feature = "pam")] -#[async_trait::async_trait] -impl Authorizer for PAMAuthorizer { - fn method(&self) -> AuthorizerType { - AuthorizerType::PAM - } - - async fn verify(&self, user: &str, password: &str) -> Result { - let service = self.provider(); - - let mut auth = pam::Client::with_password(service).unwrap(); - auth.conversation_mut() - .borrow_mut() - .set_credentials(user, password); - Ok(auth.authenticate().is_ok() && auth.open_session().is_ok()) - } -} #[derive(Debug, Clone)] struct SQLAuthorizer { diff --git a/src/test.rs b/src/test.rs index e6e1bbc..a1d961b 100644 --- a/src/test.rs +++ b/src/test.rs @@ -29,8 +29,6 @@ mod core { password_hash::{PasswordHash, PasswordHasher, PasswordVerifier, SaltString}, }; use redis::AsyncCommands; - #[cfg(feature = "pam")] - use std::borrow::BorrowMut; use std::io::{Read, Write}; use std::path::Path; use std::path::PathBuf; @@ -366,19 +364,4 @@ mod core { .block_on(clear_redis_setting()) .unwrap(); } - - #[cfg(feature = "pam")] - #[ignore] - #[test] - fn test_pam() { - let service = option_env!("pam_service").unwrap_or("system-auth"); - let user = option_env!("pam_user").unwrap_or("user"); - let password = option_env!("pam_password").unwrap_or("password"); - - let mut auth = pam::Client::with_password(service).unwrap(); - auth.conversation_mut() - .borrow_mut() - .set_credentials(user, password); - assert!(auth.authenticate().is_ok() && auth.open_session().is_ok()) - } } -- cgit v1.3.1