Mercurial > crates > nonstick
view pam-sober/src/lib.rs @ 20:734ca62159fb
Refactor exported endpoings into pam_hooks macro
author | Anthony Nowell <anthony@algorithmia.com> |
---|---|
date | Tue, 26 Sep 2017 01:51:39 -0600 |
parents | d654aa0655e5 |
children | 4263c1d83d5b |
line wrap: on
line source
#[macro_use] extern crate pam; extern crate rand; use pam::module::PamHandle; use pam::constants::{PamResultCode, PamFlag, PAM_PROMPT_ECHO_ON}; use pam::conv::PamConv; use pam::hooks::PamHooks; use rand::Rng; use std::str::FromStr; use std::ffi::CStr; macro_rules! pam_try { ($e:expr) => ( match $e { Ok(v) => v, Err(e) => return e, } ); ($e:expr, $err:expr) => ( match $e { Ok(v) => v, Err(e) => { println!("Error: {}", e); return $err; } } ); } struct PamSober; pam_hooks!(PamSober); impl PamHooks for PamSober { // This function performs the task of authenticating the user. fn sm_authenticate(pamh: &PamHandle, _args: Vec<&CStr>, _flags: PamFlag) -> PamResultCode { println!("Let's auth over HTTP"); /* TODO: use args to change difficulty ;-) let args: HashMap<&str, &str> = args.iter().map(|s| { let mut parts = s.splitn(2, "="); (parts.next().unwrap(), parts.next().unwrap_or("")) }).collect(); */ // TODO: maybe we can change difficulty base on user? // let user = pam_try!(pam.get_user(None)); let conv = match pamh.get_item::<PamConv>() { Ok(conv) => conv, Err(err) => { println!("Couldn't get pam_conv"); return err; } }; let mut rng = rand::thread_rng(); let a = rng.gen::<u32>() % 100; let b = rng.gen::<u32>() % 100; let math = format!("{} + {} = ", a, b); // This println kinda helps debugging since the test script doesn't echo println!("{}", math); let password = pam_try!(conv.send(PAM_PROMPT_ECHO_ON, &math)); if password.and_then(|p| u32::from_str(&p).ok()) == Some(a+b) { return PamResultCode::PAM_SUCCESS; } println!("You failed the PAM sobriety test."); return PamResultCode::PAM_AUTH_ERR; } fn sm_setcred(_pamh: &PamHandle, _args: Vec<&CStr>, _flags: PamFlag) -> PamResultCode { println!("set credentials"); PamResultCode::PAM_SUCCESS } fn acct_mgmt(_pamh: &PamHandle, _args: Vec<&CStr>, _flags: PamFlag) -> PamResultCode { println!("account management"); PamResultCode::PAM_SUCCESS } }