Skip to content

Commit

Permalink
Automate regeneration of PAM bindings (#882)
Browse files Browse the repository at this point in the history
  • Loading branch information
squell authored Oct 15, 2024
2 parents 55ec501 + 315e2b7 commit 14554f6
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 204 deletions.
30 changes: 30 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -284,6 +284,36 @@ jobs:
- name: Run tests
run: cargo miri test --workspace --all-features miri

check-bindings:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v4

- name: Install dependencies
run: |
sudo apt update
sudo apt install libpam0g-dev
- name: Rust Cache
uses: Swatinem/rust-cache@v2
with:
shared-key: "msrv"

- name: Install rust-bindgen
uses: taiki-e/install-action@v2
with:
tool: [email protected]

- name: Install cargo-minify
run: cargo install --locked --git https://github.com/tweedegolf/cargo-minify cargo-minify

- name: Regenerate bindings
run: make -B pam-sys

- name: Check for differences
run: git diff --exit-code

format:
runs-on: ubuntu-latest
env:
Expand Down
5 changes: 4 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
PAM_SRC_DIR = src/pam

BINDGEN_CMD = bindgen --allowlist-function '^pam_.*$$' --allowlist-var '^PAM_.*$$' --opaque-type pam_handle_t --ctypes-prefix libc
BINDGEN_CMD = bindgen --allowlist-function '^pam_.*$$' --allowlist-var '^PAM_.*$$' --opaque-type pam_handle_t --blocklist-function pam_vsyslog --blocklist-function pam_vprompt --blocklist-type '.*va_list.*' --ctypes-prefix libc --no-layout-tests --sort-semantically

.PHONY: all clean pam-sys pam-sys-diff

Expand All @@ -13,6 +13,9 @@ pam-sys: $(PAM_SRC_DIR)/sys.rs

$(PAM_SRC_DIR)/sys.rs: $(PAM_SRC_DIR)/wrapper.h
$(BINDGEN_CMD) $< --output $@
cargo minify --apply --allow-dirty
sed -i.bak 's/rust-bindgen \w*\.\w*\.\w*/\0, minified by cargo-minify/' $@
rm $@.bak

clean:
rm $(PAM_SRC_DIR)/sys.rs
2 changes: 1 addition & 1 deletion src/pam/converse.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ impl PamMessageStyle {
pub fn from_int(val: libc::c_int) -> Option<PamMessageStyle> {
use PamMessageStyle::*;

match val {
match val as _ {
PAM_PROMPT_ECHO_OFF => Some(PromptEchoOff),
PAM_PROMPT_ECHO_ON => Some(PromptEchoOn),
PAM_ERROR_MSG => Some(ErrorMessage),
Expand Down
2 changes: 1 addition & 1 deletion src/pam/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ impl PamErrorType {
pub(super) fn from_int(errno: libc::c_int) -> PamErrorType {
use PamErrorType::*;

match errno {
match errno as _ {
PAM_SUCCESS => Success,
PAM_OPEN_ERR => OpenError,
PAM_SYMBOL_ERR => SymbolError,
Expand Down
33 changes: 25 additions & 8 deletions src/pam/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ impl<C: Converser> PamContext<C> {
/// Get the PAM flag value for the silent flag
fn silent_flag(&self) -> i32 {
if self.silent {
PAM_SILENT
PAM_SILENT as _
} else {
0
}
Expand All @@ -153,7 +153,7 @@ impl<C: Converser> PamContext<C> {
if self.allow_null_auth_token {
0
} else {
PAM_DISALLOW_NULL_AUTHTOK
PAM_DISALLOW_NULL_AUTHTOK as _
}
}

Expand Down Expand Up @@ -202,15 +202,19 @@ impl<C: Converser> PamContext<C> {
// SAFETY: `self.pamh` contains a correct handle (obtained from `pam_start`); furthermore,
// `c_user.as_ptr()` will point to a correct null-terminated string.
pam_err(unsafe {
pam_set_item(self.pamh, PAM_USER, c_user.as_ptr() as *const libc::c_void)
pam_set_item(
self.pamh,
PAM_USER as _,
c_user.as_ptr() as *const libc::c_void,
)
})
}

/// Get the user that is currently active in the PAM handle
pub fn get_user(&mut self) -> PamResult<String> {
let mut data = std::ptr::null();
// SAFETY: `self.pamh` contains a correct handle (obtained from `pam_start`)
pam_err(unsafe { pam_get_item(self.pamh, PAM_USER, &mut data) })?;
pam_err(unsafe { pam_get_item(self.pamh, PAM_USER as _, &mut data) })?;

// safety check to make sure that we were not passed a null pointer by PAM,
// or that in fact PAM did not write to `data` at all.
Expand All @@ -230,15 +234,27 @@ impl<C: Converser> PamContext<C> {
let data = CString::new(tty_path.as_ref().as_bytes())?;
// SAFETY: `self.pamh` contains a correct handle (obtained from `pam_start`); furthermore,
// `data.as_ptr()` will point to a correct null-terminated string.
pam_err(unsafe { pam_set_item(self.pamh, PAM_TTY, data.as_ptr() as *const libc::c_void) })
pam_err(unsafe {
pam_set_item(
self.pamh,
PAM_TTY as _,
data.as_ptr() as *const libc::c_void,
)
})
}

// Set the user that requested the actions in this PAM instance.
pub fn set_requesting_user(&mut self, user: &str) -> PamResult<()> {
let data = CString::new(user.as_bytes())?;
// SAFETY: `self.pamh` contains a correct handle (obtained from `pam_start`); furthermore,
// `data.as_ptr()` will point to a correct null-terminated string.
pam_err(unsafe { pam_set_item(self.pamh, PAM_RUSER, data.as_ptr() as *const libc::c_void) })
pam_err(unsafe {
pam_set_item(
self.pamh,
PAM_RUSER as _,
data.as_ptr() as *const libc::c_void,
)
})
}

/// Re-initialize the credentials stored in PAM
Expand All @@ -264,7 +280,7 @@ impl<C: Converser> PamContext<C> {
let mut flags = 0;
flags |= self.silent_flag();
if expired_only {
flags |= PAM_CHANGE_EXPIRED_AUTHTOK;
flags |= PAM_CHANGE_EXPIRED_AUTHTOK as libc::c_int;
}
// SAFETY: `self.pamh` contains a correct handle (obtained from `pam_start`).
pam_err(unsafe { pam_chauthtok(self.pamh, flags) })
Expand Down Expand Up @@ -382,7 +398,8 @@ impl<C: Converser> Drop for PamContext<C> {
unsafe {
pam_end(
self.pamh,
self.last_pam_status.unwrap_or(PAM_SUCCESS as libc::c_int) | PAM_DATA_SILENT,
self.last_pam_status.unwrap_or(PAM_SUCCESS as libc::c_int)
| PAM_DATA_SILENT as libc::c_int,
)
};
}
Expand Down
Loading

0 comments on commit 14554f6

Please sign in to comment.