initial commit: WIP debugging PAM module
This commit is contained in:
16
rust-backend/Cargo.lock
generated
Normal file
16
rust-backend/Cargo.lock
generated
Normal file
@@ -0,0 +1,16 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "once_cell"
|
||||
version = "1.21.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
|
||||
|
||||
[[package]]
|
||||
name = "rust-backend"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
16
rust-backend/Cargo.toml
Normal file
16
rust-backend/Cargo.toml
Normal file
@@ -0,0 +1,16 @@
|
||||
[package]
|
||||
name = "rust-backend"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["staticlib"]
|
||||
|
||||
[dependencies]
|
||||
once_cell = "1.18"
|
||||
|
||||
[profile.release]
|
||||
panic = "unwind"
|
||||
|
||||
[profile.dev]
|
||||
panic = "unwind"
|
||||
14
rust-backend/src/auth.rs
Normal file
14
rust-backend/src/auth.rs
Normal file
@@ -0,0 +1,14 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2026 Suyono
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
pub fn authenticate(user: &str, password: &str) -> Result<(), ()> {
|
||||
// Stub: always fail if user == "fail", else succeed
|
||||
if user == "fail" {
|
||||
Err(())
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
10
rust-backend/src/error.rs
Normal file
10
rust-backend/src/error.rs
Normal file
@@ -0,0 +1,10 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2026 Suyono
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
pub const SUCCESS: i32 = 0;
|
||||
pub const ERR_INVALID_INPUT: i32 = -1;
|
||||
pub const ERR_AUTH_FAILED: i32 = -2;
|
||||
pub const ERR_PANIC: i32 = -99;
|
||||
62
rust-backend/src/lib.rs
Normal file
62
rust-backend/src/lib.rs
Normal file
@@ -0,0 +1,62 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2026 Suyono
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
use std::ffi::{CStr, CString};
|
||||
use std::os::raw::c_char;
|
||||
use std::panic::{catch_unwind, AssertUnwindSafe};
|
||||
|
||||
mod auth;
|
||||
mod logging;
|
||||
mod error;
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rust_init_logging(log_path: *const c_char) {
|
||||
let _ = catch_unwind(AssertUnwindSafe(|| {
|
||||
let path = unsafe {
|
||||
if log_path.is_null() {
|
||||
"/var/log/pam_rust_backend.log"
|
||||
} else {
|
||||
CStr::from_ptr(log_path).to_str().unwrap_or("/var/log/pam_rust_backend.log")
|
||||
}
|
||||
};
|
||||
logging::init_logger(path);
|
||||
}));
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rust_log_event(event: *const c_char) {
|
||||
let _ = catch_unwind(AssertUnwindSafe(|| {
|
||||
let msg = unsafe {
|
||||
if event.is_null() {
|
||||
return;
|
||||
}
|
||||
CStr::from_ptr(event).to_str().unwrap_or("")
|
||||
};
|
||||
logging::log_event(msg);
|
||||
}));
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn rust_auth_user(user: *const c_char, password: *const c_char) -> i32 {
|
||||
catch_unwind(AssertUnwindSafe(|| {
|
||||
let u = unsafe {
|
||||
if user.is_null() {
|
||||
return error::ERR_INVALID_INPUT;
|
||||
}
|
||||
CStr::from_ptr(user).to_str().unwrap_or("")
|
||||
};
|
||||
let p = unsafe {
|
||||
if password.is_null() {
|
||||
return error::ERR_INVALID_INPUT;
|
||||
}
|
||||
CStr::from_ptr(password).to_str().unwrap_or("")
|
||||
};
|
||||
match auth::authenticate(u, p) {
|
||||
Ok(_) => error::SUCCESS,
|
||||
Err(_) => error::ERR_AUTH_FAILED,
|
||||
}
|
||||
})).unwrap_or(error::ERR_PANIC)
|
||||
}
|
||||
32
rust-backend/src/logging.rs
Normal file
32
rust-backend/src/logging.rs
Normal file
@@ -0,0 +1,32 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
// Copyright 2026 Suyono
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
use std::fs::{OpenOptions, File};
|
||||
use std::io::Write;
|
||||
use std::sync::Mutex;
|
||||
use once_cell::sync::OnceCell;
|
||||
|
||||
static LOGGER: OnceCell<Mutex<File>> = OnceCell::new();
|
||||
|
||||
pub fn init_logger(path: &str) {
|
||||
if LOGGER.get().is_some() {
|
||||
// Already initialized, do nothing
|
||||
return;
|
||||
}
|
||||
let file = OpenOptions::new()
|
||||
.create(true)
|
||||
.append(true)
|
||||
.open(path)
|
||||
.expect("Failed to open log file");
|
||||
LOGGER.set(Mutex::new(file)).ok();
|
||||
}
|
||||
|
||||
pub fn log_event(event: &str) {
|
||||
if let Some(logger) = LOGGER.get() {
|
||||
let mut file = logger.lock().unwrap();
|
||||
writeln!(file, "{}", event).ok();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user