comparison pam-http/src/lib.rs @ 15:27730595f1ea

Adding pam-http module
author Anthony Nowell <anthony@algorithmia.com>
date Sun, 24 Sep 2017 00:22:29 -0600
parents
children d654aa0655e5
comparison
equal deleted inserted replaced
14:51b097c12d3c 15:27730595f1ea
1 extern crate pam;
2 extern crate reqwest;
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 reqwest::{Client, StatusCode};
12
13 macro_rules! pam_try {
14 ($e:expr) => (
15 match $e {
16 Ok(v) => v,
17 Err(e) => return e,
18 }
19 );
20 ($e:expr, $err:expr) => (
21 match $e {
22 Ok(v) => v,
23 Err(e) => {
24 println!("Error: {}", e);
25 return $err;
26 }
27 }
28 );
29 }
30
31 // This function performs the task of authenticating the user.
32 pub fn sm_authenticate(pamh: &PamHandleT, args: Vec<String>, silent: bool) -> PamResultCode {
33 println!("Let's auth over HTTP");
34
35 let args: HashMap<&str, &str> = args.iter().map(|s| {
36 let mut parts = s.splitn(2, "=");
37 (parts.next().unwrap(), parts.next().unwrap_or(""))
38 }).collect();
39
40 let user = pam_try!(get_user(&pamh, None));
41
42 let url: &str = match args.get("url") {
43 Some(url) => url,
44 None => return PamResultCode::PAM_AUTH_ERR,
45 };
46 let ca_file = args.get("ca_file");
47
48 let conv = match get_item::<PamConv>(&pamh) {
49 Ok(conv) => conv,
50 Err(err) => {
51 println!("Couldn't get pam_conv");
52 return err;
53 }
54 };
55 let password = pam_try!(conv.send(PAM_PROMPT_ECHO_OFF, "Word, yo: "));
56 println!("Got a password {:?}", password);
57 let status = pam_try!(get_url(url, &user, password.as_ref().map(|p|&**p)), PamResultCode::PAM_AUTH_ERR);
58
59 if !status.is_success() {
60 println!("HTTP Error: {}", status);
61 return PamResultCode::PAM_AUTH_ERR;
62 }
63
64 PamResultCode::PAM_SUCCESS
65 }
66
67 fn get_url(url: &str, user: &str, password: Option<&str>) -> reqwest::Result<StatusCode> {
68 let client = Client::builder()?.timeout(Duration::from_secs(5)).build()?;
69 client.get(url)?
70 .basic_auth(user, password)
71 .send()
72 .map(|r| r.status())
73 }
74
75 // This function performs the task of altering the credentials of the user with respect to the
76 // corresponding authorization scheme. Generally, an authentication module may have access to more
77 // information about a user than their authentication token. This function is used to make such
78 // information available to the application. It should only be called after the user has been
79 // authenticated but before a session has been established.
80 pub fn sm_setcred(_pamh: &PamHandleT, _args: Vec<String>, _silent: bool) -> PamResultCode {
81 println!("set credentials");
82 PamResultCode::PAM_SUCCESS
83 }
84
85 // This function performs the task of establishing whether the user is permitted to gain access at
86 // this time. It should be understood that the user has previously been validated by an
87 // authentication module. This function checks for other things. Such things might be: the time of
88 // day or the date, the terminal line, remote hostname, etc. This function may also determine
89 // things like the expiration on passwords, and respond that the user change it before continuing.
90 pub fn acct_mgmt(_pamh: &PamHandleT, _args: Vec<String>, _silent: bool) -> PamResultCode {
91 println!("account management");
92 PamResultCode::PAM_SUCCESS
93 }