diff --git a/Cargo.toml b/Cargo.toml index 5646ca2f..94e2838f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ members = [ "proxmox-shared-memory", "proxmox-section-config", "proxmox-sortable-macro", + "proxmox-sys", "proxmox-tfa", "proxmox-time", "proxmox-uuid", diff --git a/Makefile b/Makefile index f755ff8c..83b736e5 100644 --- a/Makefile +++ b/Makefile @@ -12,6 +12,7 @@ CRATES = \ proxmox-shared-memory \ proxmox-section-config \ proxmox-sortable-macro \ + proxmox-sys \ proxmox-tfa \ proxmox-time \ proxmox-uuid diff --git a/proxmox-sys/Cargo.toml b/proxmox-sys/Cargo.toml new file mode 100644 index 00000000..ba32e07d --- /dev/null +++ b/proxmox-sys/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "proxmox-sys" +version = "0.1.0" +authors = ["Proxmox Support Team "] +edition = "2018" +license = "AGPL-3" +description = "System tools (using nix)." + +exclude = [ "debian" ] + +[dependencies] +anyhow = "1.0" +base64 = "0.12" +libc = "0.2.107" +nix = "0.19.1" + +proxmox = { path = "../proxmox", version = "0.15", default-features = false } diff --git a/proxmox-sys/debian/changelog b/proxmox-sys/debian/changelog new file mode 100644 index 00000000..47bee90b --- /dev/null +++ b/proxmox-sys/debian/changelog @@ -0,0 +1,8 @@ +rust-proxmox-sys (0.1.0) unstable; urgency=medium + + * imported pbs-tools/src/crypt.rs + + * initial release + + -- Proxmox Support Team Fri, 19 Nov 2021 07:19:19 +0100 + diff --git a/proxmox-sys/debian/debcargo.toml b/proxmox-sys/debian/debcargo.toml new file mode 100644 index 00000000..1e7ee9f1 --- /dev/null +++ b/proxmox-sys/debian/debcargo.toml @@ -0,0 +1,10 @@ +overlay = "." +crate_src_path = ".." +maintainer = "Proxmox Support Team " + +[source] +vcs_git = "git://git.proxmox.com/git/proxmox.git" +vcs_browser = "https://git.proxmox.com/?p=proxmox.git" + +[packages.lib] +depends = [ "uuid-dev" ] diff --git a/proxmox-sys/src/crypt.rs b/proxmox-sys/src/crypt.rs new file mode 100644 index 00000000..c47bfe24 --- /dev/null +++ b/proxmox-sys/src/crypt.rs @@ -0,0 +1,68 @@ +use std::ffi::CStr; + +use anyhow::{bail, Error}; + +// from libcrypt1, 'lib/crypt.h.in' +const CRYPT_OUTPUT_SIZE: usize = 384; +const CRYPT_MAX_PASSPHRASE_SIZE: usize = 512; +const CRYPT_DATA_RESERVED_SIZE: usize = 767; +const CRYPT_DATA_INTERNAL_SIZE: usize = 30720; + +#[repr(C)] +struct crypt_data { + output: [libc::c_char; CRYPT_OUTPUT_SIZE], + setting: [libc::c_char; CRYPT_OUTPUT_SIZE], + input: [libc::c_char; CRYPT_MAX_PASSPHRASE_SIZE], + reserved: [libc::c_char; CRYPT_DATA_RESERVED_SIZE], + initialized: libc::c_char, + internal: [libc::c_char; CRYPT_DATA_INTERNAL_SIZE], +} + +pub fn crypt(password: &[u8], salt: &[u8]) -> Result { + #[link(name = "crypt")] + extern "C" { + #[link_name = "crypt_r"] + fn __crypt_r( + key: *const libc::c_char, + salt: *const libc::c_char, + data: *mut crypt_data, + ) -> *mut libc::c_char; + } + + let mut data: crypt_data = unsafe { std::mem::zeroed() }; + for (i, c) in salt.iter().take(data.setting.len() - 1).enumerate() { + data.setting[i] = *c as libc::c_char; + } + for (i, c) in password.iter().take(data.input.len() - 1).enumerate() { + data.input[i] = *c as libc::c_char; + } + + let res = unsafe { + let status = __crypt_r( + &data.input as *const _, + &data.setting as *const _, + &mut data as *mut _, + ); + if status.is_null() { + bail!("internal error: crypt_r returned null pointer"); + } + CStr::from_ptr(&data.output as *const _) + }; + Ok(String::from(res.to_str()?)) +} + +pub fn encrypt_pw(password: &str) -> Result { + + let salt = proxmox::sys::linux::random_data(8)?; + let salt = format!("$5${}$", base64::encode_config(&salt, base64::CRYPT)); + + crypt(password.as_bytes(), salt.as_bytes()) +} + +pub fn verify_crypt_pw(password: &str, enc_password: &str) -> Result<(), Error> { + let verify = crypt(password.as_bytes(), enc_password.as_bytes())?; + if verify != enc_password { + bail!("invalid credentials"); + } + Ok(()) +} diff --git a/proxmox-sys/src/lib.rs b/proxmox-sys/src/lib.rs new file mode 100644 index 00000000..09cf2bc4 --- /dev/null +++ b/proxmox-sys/src/lib.rs @@ -0,0 +1 @@ +pub mod crypt;