Mercurial > crates > nonstick
comparison pam-sober/src/lib.rs @ 34:ec70822cbdef
Overhaul
| author | Andy Caldwell <andrew.caldwell@metaswitch.com> |
|---|---|
| date | Sun, 24 Apr 2022 03:42:11 +0100 |
| parents | d5c842a50827 |
| children |
comparison
equal
deleted
inserted
replaced
| 32:ea5f195f035f | 34:ec70822cbdef |
|---|---|
| 1 #[macro_use] extern crate pam; | 1 extern crate pam; |
| 2 extern crate rand; | 2 extern crate rand; |
| 3 | 3 |
| 4 use pam::constants::{PamFlag, PamResultCode, PAM_PROMPT_ECHO_ON}; | |
| 5 use pam::conv::Conv; | |
| 4 use pam::module::{PamHandle, PamHooks}; | 6 use pam::module::{PamHandle, PamHooks}; |
| 5 use pam::constants::{PamResultCode, PamFlag, PAM_PROMPT_ECHO_ON}; | |
| 6 use pam::conv::PamConv; | |
| 7 use rand::Rng; | 7 use rand::Rng; |
| 8 use std::ffi::CStr; | |
| 8 use std::str::FromStr; | 9 use std::str::FromStr; |
| 9 use std::ffi::CStr; | 10 use pam::pam_try; |
| 10 | |
| 11 macro_rules! pam_try { | |
| 12 ($e:expr) => ( | |
| 13 match $e { | |
| 14 Ok(v) => v, | |
| 15 Err(e) => return e, | |
| 16 } | |
| 17 ); | |
| 18 ($e:expr, $err:expr) => ( | |
| 19 match $e { | |
| 20 Ok(v) => v, | |
| 21 Err(e) => { | |
| 22 println!("Error: {}", e); | |
| 23 return $err; | |
| 24 } | |
| 25 } | |
| 26 ); | |
| 27 } | |
| 28 | 11 |
| 29 struct PamSober; | 12 struct PamSober; |
| 30 pam_hooks!(PamSober); | 13 pam::pam_hooks!(PamSober); |
| 31 | 14 |
| 32 impl PamHooks for PamSober { | 15 impl PamHooks for PamSober { |
| 33 // This function performs the task of authenticating the user. | 16 // This function performs the task of authenticating the user. |
| 34 fn sm_authenticate(pamh: &PamHandle, _args: Vec<&CStr>, _flags: PamFlag) -> PamResultCode { | 17 fn sm_authenticate(pamh: &mut PamHandle, _args: Vec<&CStr>, _flags: PamFlag) -> PamResultCode { |
| 35 println!("Let's make sure you're sober enough to perform basic addition"); | 18 println!("Let's make sure you're sober enough to perform basic addition"); |
| 36 | 19 |
| 37 /* TODO: use args to change difficulty ;-) | 20 /* TODO: use args to change difficulty ;-) |
| 38 let args: HashMap<&str, &str> = args.iter().map(|s| { | 21 let args: HashMap<&str, &str> = args.iter().map(|s| { |
| 39 let mut parts = s.splitn(2, "="); | 22 let mut parts = s.splitn(2, "="); |
| 42 */ | 25 */ |
| 43 | 26 |
| 44 // TODO: maybe we can change difficulty base on user? | 27 // TODO: maybe we can change difficulty base on user? |
| 45 // let user = pam_try!(pam.get_user(None)); | 28 // let user = pam_try!(pam.get_user(None)); |
| 46 | 29 |
| 47 let conv = match pamh.get_item::<PamConv>() { | 30 let conv = match pamh.get_item::<Conv>() { |
| 48 Ok(conv) => conv, | 31 Ok(Some(conv)) => conv, |
| 32 Ok(None) => todo!(), | |
| 49 Err(err) => { | 33 Err(err) => { |
| 50 println!("Couldn't get pam_conv"); | 34 println!("Couldn't get pam_conv"); |
| 51 return err; | 35 return err; |
| 52 } | 36 } |
| 53 }; | 37 }; |
| 56 let a = rng.gen::<u32>() % 100; | 40 let a = rng.gen::<u32>() % 100; |
| 57 let b = rng.gen::<u32>() % 100; | 41 let b = rng.gen::<u32>() % 100; |
| 58 let math = format!("{} + {} = ", a, b); | 42 let math = format!("{} + {} = ", a, b); |
| 59 | 43 |
| 60 // This println kinda helps debugging since the test script doesn't echo | 44 // This println kinda helps debugging since the test script doesn't echo |
| 61 println!("{}", math); | 45 eprintln!("[DEBUG]: {}{}", math, a + b); |
| 62 | 46 |
| 63 let password = pam_try!(conv.send(PAM_PROMPT_ECHO_ON, &math)); | 47 let password = pam_try!(conv.send(PAM_PROMPT_ECHO_ON, &math)); |
| 64 | 48 |
| 65 if password.and_then(|p| u32::from_str(&p).ok()) == Some(a+b) { | 49 if let Some(password) = password { |
| 66 return PamResultCode::PAM_SUCCESS; | 50 let password = pam_try!(password.to_str(), PamResultCode::PAM_AUTH_ERR); |
| 51 let answer = pam_try!(u32::from_str(password), PamResultCode::PAM_AUTH_ERR); | |
| 52 if answer == a + b { | |
| 53 PamResultCode::PAM_SUCCESS | |
| 54 } else { | |
| 55 println!("Wrong answer provided {} + {} != {}", a, b, answer); | |
| 56 PamResultCode::PAM_AUTH_ERR | |
| 57 } | |
| 58 } else { | |
| 59 println!("You failed the PAM sobriety test."); | |
| 60 PamResultCode::PAM_AUTH_ERR | |
| 67 } | 61 } |
| 68 | |
| 69 println!("You failed the PAM sobriety test."); | |
| 70 return PamResultCode::PAM_AUTH_ERR; | |
| 71 } | 62 } |
| 72 | 63 |
| 73 fn sm_setcred(_pamh: &PamHandle, _args: Vec<&CStr>, _flags: PamFlag) -> PamResultCode { | 64 fn sm_setcred(_pamh: &mut PamHandle, _args: Vec<&CStr>, _flags: PamFlag) -> PamResultCode { |
| 74 println!("set credentials"); | 65 println!("set credentials"); |
| 75 PamResultCode::PAM_SUCCESS | 66 PamResultCode::PAM_SUCCESS |
| 76 } | 67 } |
| 77 | 68 |
| 78 fn acct_mgmt(_pamh: &PamHandle, _args: Vec<&CStr>, _flags: PamFlag) -> PamResultCode { | 69 fn acct_mgmt(_pamh: &mut PamHandle, _args: Vec<&CStr>, _flags: PamFlag) -> PamResultCode { |
| 79 println!("account management"); | 70 println!("account management"); |
| 80 PamResultCode::PAM_SUCCESS | 71 PamResultCode::PAM_SUCCESS |
| 81 } | 72 } |
| 82 } | 73 } |
