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 } |