diff 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 diff
--- a/pam-sober/src/lib.rs	Mon Sep 25 23:42:35 2017 -0600
+++ b/pam-sober/src/lib.rs	Tue Sep 26 01:51:39 2017 -0600
@@ -1,13 +1,13 @@
-extern crate pam;
+#[macro_use] extern crate pam;
 extern crate rand;
 
-pub mod ffi;
-
 use pam::module::PamHandle;
-use pam::constants::{PamResultCode, PAM_PROMPT_ECHO_OFF};
+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) => (
@@ -27,62 +27,57 @@
     );
 }
 
-// This function performs the task of authenticating the user.
-pub fn sm_authenticate(pamh: &PamHandle, args: Vec<String>, silent: bool) -> PamResultCode {
-    println!("Let's auth over HTTP");
+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: 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));
+        // 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 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);
+        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);
 
-    // 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));
 
-    let password = pam_try!(conv.send(PAM_PROMPT_ECHO_OFF, &math));
+        if password.and_then(|p| u32::from_str(&p).ok()) == Some(a+b) {
+            return PamResultCode::PAM_SUCCESS;
+        }
 
-    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;
     }
 
-    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
+    }
 
-// This function performs the task of altering the credentials of the user with respect to the
-// corresponding authorization scheme. Generally, an authentication module may have access to more
-// information about a user than their authentication token. This function is used to make such
-// information available to the application. It should only be called after the user has been
-// authenticated but before a session has been established.
-pub fn sm_setcred(_pamh: &PamHandle, _args: Vec<String>, _silent: bool) -> PamResultCode {
-    println!("set credentials");
-    PamResultCode::PAM_SUCCESS
-}
-
-// This function performs the task of establishing whether the user is permitted to gain access at
-// this time. It should be understood that the user has previously been validated by an
-// authentication module. This function checks for other things. Such things might be: the time of
-// day or the date, the terminal line, remote hostname, etc. This function may also determine
-// things like the expiration on passwords, and respond that the user change it before continuing.
-pub fn acct_mgmt(_pamh: &PamHandle, _args: Vec<String>, _silent: bool) -> PamResultCode {
-    println!("account management");
-    PamResultCode::PAM_SUCCESS
-}
+    fn acct_mgmt(_pamh: &PamHandle, _args: Vec<&CStr>, _flags: PamFlag) -> PamResultCode {
+        println!("account management");
+        PamResultCode::PAM_SUCCESS
+    }
+}
\ No newline at end of file