Add pam_honeypot

This commit is contained in:
Tim Schubert 2024-12-28 21:21:06 +01:00
parent e206547823
commit 0fc4c2ef0c
Signed by: dadada
SSH key fingerprint: SHA256:bFAjFH3hR8zRBaJjzQDjc3o4jqoq5EZ87l+KXEjxIz0
7 changed files with 186 additions and 30 deletions

25
Cargo.lock generated Normal file
View file

@ -0,0 +1,25 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "libc"
version = "0.2.169"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
[[package]]
name = "pam-bindings"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95c337e922acb6ab9c3ddd1016fed13957a5bf14f51b6caa293ddc8dd47660ca"
dependencies = [
"libc",
]
[[package]]
name = "pam-honeypot"
version = "0.1.0"
dependencies = [
"pam-bindings",
]

View file

@ -3,4 +3,9 @@ name = "pam-honeypot"
version = "0.1.0" version = "0.1.0"
edition = "2021" edition = "2021"
[lib]
name = "pam_honeypot"
crate-type = ["cdylib"]
[dependencies] [dependencies]
pam-bindings = { version = "0.1.1" }

1
conf/pam-honeypot Normal file
View file

@ -0,0 +1 @@
auth sufficient pam_honeypot.so user=Admin password=AdminPwdQ1

58
flake.lock generated Normal file
View file

@ -0,0 +1,58 @@
{
"nodes": {
"flake-utils": {
"inputs": {
"systems": "systems"
},
"locked": {
"lastModified": 1731533236,
"narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=",
"owner": "numtide",
"repo": "flake-utils",
"rev": "11707dc2f618dd54ca8739b309ec4fc024de578b",
"type": "github"
},
"original": {
"owner": "numtide",
"repo": "flake-utils",
"type": "github"
}
},
"nixpkgs": {
"locked": {
"lastModified": 1735191716,
"narHash": "sha256-rwHLmGc/2OfudyjGnH8h5vQK2e5uJ6gt2GwPhWL9pPk=",
"path": "/nix/store/g421ks4gdcizmgacddxm2b7c6xabfhiv-source",
"rev": "1dd8f51e62c0ff199e551744ab46fc4fbe6f827a",
"type": "path"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"root": {
"inputs": {
"flake-utils": "flake-utils",
"nixpkgs": "nixpkgs"
}
},
"systems": {
"locked": {
"lastModified": 1681028828,
"narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
"owner": "nix-systems",
"repo": "default",
"rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e",
"type": "github"
},
"original": {
"owner": "nix-systems",
"repo": "default",
"type": "github"
}
}
},
"root": "root",
"version": 7
}

View file

@ -2,32 +2,32 @@
description = "a653rs-router"; description = "a653rs-router";
inputs = { inputs = {
fenix = {
url = "github:nix-community/fenix";
inputs.nixpkgs.follows = "nixpkgs";
};
flake-utils.url = "github:numtide/flake-utils"; flake-utils.url = "github:numtide/flake-utils";
}; };
outputs = { fenix, flake-utils, nixpkgs, ... }: flake-utils.lib.eachSystem [ "x86_64-linux" ] (system: outputs =
{
flake-utils,
nixpkgs,
...
}:
flake-utils.lib.eachSystem [ "x86_64-linux" ] (
system:
let let
pkgs = import nixpkgs { inherit system; }; pkgs = import nixpkgs { inherit system; };
rustToolchain = with fenix.packages.${system}; combine [
latest.rustc
latest.cargo
latest.clippy
latest.rustfmt
latest.rust-src
latest.rust-analyzer
targets.aarch64-unknown-uefi.latest.rust-std
targets.i686-unknown-uefi.latest.rust-std
targets.x86_64-unknown-uefi.latest.rust-std
];
in in
{ {
devShells.default = pkgs.mkShell { devShells.default = pkgs.mkShell {
packages = [ nativeBuildInputs = [
rustToolchain pkgs.cargo
pkgs.clang
pkgs.clippy
pkgs.pam
pkgs.pkg-config
pkgs.rustc
pkgs.rustfmt
pkgs.rust-analyzer
pkgs.rustPlatform.bindgenHook
]; ];
}; };
} }

70
src/lib.rs Normal file
View file

@ -0,0 +1,70 @@
use std::{collections::HashMap, env::temp_dir, ffi::CStr, fs::File};
use pam::{
constants::{PamResultCode, PAM_PROMPT_ECHO_ON},
conv::Conv,
module::PamHooks,
pam_try,
};
struct PamHoneypot;
impl PamHooks for PamHoneypot {
fn sm_authenticate(
pamh: &mut pam::module::PamHandle,
args: Vec<&CStr>,
_flags: pam::constants::PamFlag,
) -> pam::constants::PamResultCode {
let args: Vec<_> = args.iter().map(|s| s.to_string_lossy()).collect();
let args: HashMap<&str, &str> = args
.iter()
.map(|s| {
let mut parts = s.splitn(2, '=');
(parts.next().unwrap(), parts.next().unwrap_or(""))
})
.collect();
let honey_user = match args.get("user") {
Some(user) => user,
_ => return PamResultCode::PAM_IGNORE,
};
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 {
return PamResultCode::PAM_IGNORE;
}
let conv = match pamh.get_item::<Conv>() {
Ok(Some(conv)) => conv,
Ok(_) => {
unreachable!("No conv available");
}
Err(err) => {
return err;
}
};
let password = pam_try!(conv.send(PAM_PROMPT_ECHO_ON, "Password"));
let password = match password {
Some(password) => Some(pam_try!(password.to_str(), PamResultCode::PAM_AUTH_ERR)),
_ => None,
};
if let Some(password) = password {
if *honey_password == password {
let mut tmp = temp_dir();
tmp.push("honeypot");
let _ = File::create(tmp);
return PamResultCode::PAM_AUTH_ERR;
}
}
PamResultCode::PAM_IGNORE
}
}
pam::pam_hooks!(PamHoneypot);

View file

@ -1,3 +0,0 @@
fn main() {
println!("Hello, world!");
}