Fix error handling and add nixos test
This commit is contained in:
parent
c06b3a7142
commit
ef60878471
6 changed files with 335 additions and 20 deletions
40
src/lib.rs
40
src/lib.rs
|
@ -1,11 +1,14 @@
|
|||
use std::{collections::HashMap, env::temp_dir, ffi::CStr, fs::File};
|
||||
use std::{collections::HashMap, ffi::CStr};
|
||||
|
||||
use log::{debug, info, trace, warn};
|
||||
use pam::{
|
||||
constants::{PamResultCode, PAM_PROMPT_ECHO_ON},
|
||||
constants::{PamResultCode, PAM_PROMPT_ECHO_OFF},
|
||||
conv::Conv,
|
||||
items::User,
|
||||
module::PamHooks,
|
||||
pam_try,
|
||||
};
|
||||
use syslog::Facility;
|
||||
|
||||
struct PamHoneypot;
|
||||
|
||||
|
@ -15,12 +18,23 @@ impl PamHooks for PamHoneypot {
|
|||
args: Vec<&CStr>,
|
||||
_flags: pam::constants::PamFlag,
|
||||
) -> pam::constants::PamResultCode {
|
||||
let _ = syslog::init(
|
||||
Facility::LOG_USER,
|
||||
log::LevelFilter::Info,
|
||||
Some("pam_honeypot"),
|
||||
);
|
||||
|
||||
trace!("Running pam_honeypot");
|
||||
let args: Vec<_> = args.iter().map(|s| s.to_string_lossy()).collect();
|
||||
debug!("args = {args:?}");
|
||||
let args: HashMap<&str, &str> = args
|
||||
.iter()
|
||||
.map(|s| {
|
||||
let mut parts = s.splitn(2, '=');
|
||||
(parts.next().unwrap(), parts.next().unwrap_or(""))
|
||||
(
|
||||
parts.next().expect("Failed to parse arguments"),
|
||||
parts.next().unwrap_or(""),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
|
||||
|
@ -28,13 +42,16 @@ impl PamHooks for PamHoneypot {
|
|||
Some(user) => user,
|
||||
_ => return PamResultCode::PAM_IGNORE,
|
||||
};
|
||||
debug!("honeypot user = {honey_user}");
|
||||
let honey_password = match args.get("password") {
|
||||
Some(password) => password,
|
||||
_ => return PamResultCode::PAM_IGNORE,
|
||||
};
|
||||
|
||||
let user = pam_try!(pamh.get_user(None));
|
||||
if user != *honey_user {
|
||||
trace!("Getting user from PAM");
|
||||
let user: User = pam_try!(pamh.get_item()).unwrap_or(User(c""));
|
||||
info!("Checking if entered username is honeypot user");
|
||||
if user.to_string_lossy() != *honey_user {
|
||||
return PamResultCode::PAM_IGNORE;
|
||||
}
|
||||
|
||||
|
@ -47,20 +64,21 @@ impl PamHooks for PamHoneypot {
|
|||
return err;
|
||||
}
|
||||
};
|
||||
let password = pam_try!(conv.send(PAM_PROMPT_ECHO_ON, "Password"));
|
||||
trace!("Getting password from PAM");
|
||||
let password = pam_try!(conv.send(PAM_PROMPT_ECHO_OFF, "Password: "));
|
||||
let password = match password {
|
||||
Some(password) => Some(pam_try!(password.to_str(), PamResultCode::PAM_AUTH_ERR)),
|
||||
_ => None,
|
||||
};
|
||||
|
||||
if let Some(password) = password {
|
||||
trace!("Checking if password is honeypot password");
|
||||
if *honey_password == password {
|
||||
let mut tmp = temp_dir();
|
||||
tmp.push("honeypot");
|
||||
let _ = File::create(tmp);
|
||||
|
||||
return PamResultCode::PAM_AUTH_ERR;
|
||||
warn!("Someone tried to log in with the honeypot credentials");
|
||||
} else {
|
||||
info!("Entered username is not the honeypot user")
|
||||
}
|
||||
return PamResultCode::PAM_AUTH_ERR;
|
||||
}
|
||||
|
||||
PamResultCode::PAM_IGNORE
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue