comparison pam-sober/src/lib.rs @ 17:53efbcff805d

Add pam-sober
author Anthony Nowell <anthony@algorithmia.com>
date Sun, 24 Sep 2017 00:57:13 -0600
parents
children d654aa0655e5
comparison
equal deleted inserted replaced
16:f64ee7b6cdf1 17:53efbcff805d
1 extern crate pam;
2 extern crate rand;
3
4 pub mod ffi;
5
6 use pam::module::{PamHandleT, get_item, get_user};
7 use pam::constants::{PamResultCode, PAM_PROMPT_ECHO_OFF};
8 use pam::conv::PamConv;
9 use std::collections::HashMap;
10 use std::time::Duration;
11 use rand::Rng;
12 use std::str::FromStr;
13
14 macro_rules! pam_try {
15 ($e:expr) => (
16 match $e {
17 Ok(v) => v,
18 Err(e) => return e,
19 }
20 );
21 ($e:expr, $err:expr) => (
22 match $e {
23 Ok(v) => v,
24 Err(e) => {
25 println!("Error: {}", e);
26 return $err;
27 }
28 }
29 );
30 }
31
32 // This function performs the task of authenticating the user.
33 pub fn sm_authenticate(pamh: &PamHandleT, args: Vec<String>, silent: bool) -> PamResultCode {
34 println!("Let's auth over HTTP");
35
36 /* TODO: use args to change difficulty ;-)
37 let args: HashMap<&str, &str> = args.iter().map(|s| {
38 let mut parts = s.splitn(2, "=");
39 (parts.next().unwrap(), parts.next().unwrap_or(""))
40 }).collect();
41 */
42
43 // TODO: maybe we can change difficulty base on user?
44 // let user = pam_try!(get_user(&pamh, None));
45
46 let conv = match get_item::<PamConv>(&pamh) {
47 Ok(conv) => conv,
48 Err(err) => {
49 println!("Couldn't get pam_conv");
50 return err;
51 }
52 };
53
54 let mut rng = rand::thread_rng();
55 let a = rng.gen::<u32>() % 100;
56 let b = rng.gen::<u32>() % 100;
57 let math = format!("{} + {} = ", a, b);
58
59 // This println kinda helps debugging since the test script doesn't echo
60 println!("{}", math);
61
62 let password = pam_try!(conv.send(PAM_PROMPT_ECHO_OFF, &math));
63
64 if password.and_then(|p| u32::from_str(&p).ok()) == Some(a+b) {
65 return PamResultCode::PAM_SUCCESS;
66 }
67
68 println!("You failed the PAM sobriety test.");
69 return PamResultCode::PAM_AUTH_ERR;
70 }
71
72 // This function performs the task of altering the credentials of the user with respect to the
73 // corresponding authorization scheme. Generally, an authentication module may have access to more
74 // information about a user than their authentication token. This function is used to make such
75 // information available to the application. It should only be called after the user has been
76 // authenticated but before a session has been established.
77 pub fn sm_setcred(_pamh: &PamHandleT, _args: Vec<String>, _silent: bool) -> PamResultCode {
78 println!("set credentials");
79 PamResultCode::PAM_SUCCESS
80 }
81
82 // This function performs the task of establishing whether the user is permitted to gain access at
83 // this time. It should be understood that the user has previously been validated by an
84 // authentication module. This function checks for other things. Such things might be: the time of
85 // day or the date, the terminal line, remote hostname, etc. This function may also determine
86 // things like the expiration on passwords, and respond that the user change it before continuing.
87 pub fn acct_mgmt(_pamh: &PamHandleT, _args: Vec<String>, _silent: bool) -> PamResultCode {
88 println!("account management");
89 PamResultCode::PAM_SUCCESS
90 }