feat: turns out there is an extended ldap3 operation called password modify
This commit is contained in:
parent
f8089113f5
commit
aa196ba33b
3 changed files with 30 additions and 131 deletions
86
Cargo.lock
generated
86
Cargo.lock
generated
|
@ -359,12 +359,6 @@ version = "0.13.1"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8"
|
||||
|
||||
[[package]]
|
||||
name = "base64"
|
||||
version = "0.21.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d"
|
||||
|
||||
[[package]]
|
||||
name = "bincode"
|
||||
version = "1.3.3"
|
||||
|
@ -844,12 +838,6 @@ dependencies = [
|
|||
"percent-encoding",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fuchsia-cprng"
|
||||
version = "0.1.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba"
|
||||
|
||||
[[package]]
|
||||
name = "futures"
|
||||
version = "0.3.28"
|
||||
|
@ -965,12 +953,6 @@ dependencies = [
|
|||
"slab",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "gcc"
|
||||
version = "0.3.55"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f5f3913fa0bfe7ee1fd8248b6b9f42a5af4b9d65ec2dd2c3c26132b950ecfc2"
|
||||
|
||||
[[package]]
|
||||
name = "generic-array"
|
||||
version = "0.14.7"
|
||||
|
@ -1671,29 +1653,6 @@ dependencies = [
|
|||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.3.23"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rand 0.4.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.4.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"
|
||||
dependencies = [
|
||||
"fuchsia-cprng",
|
||||
"libc",
|
||||
"rand_core 0.3.1",
|
||||
"rdrand",
|
||||
"winapi",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand"
|
||||
version = "0.7.3"
|
||||
|
@ -1738,21 +1697,6 @@ dependencies = [
|
|||
"rand_core 0.6.4",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b"
|
||||
dependencies = [
|
||||
"rand_core 0.4.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.4.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc"
|
||||
|
||||
[[package]]
|
||||
name = "rand_core"
|
||||
version = "0.5.1"
|
||||
|
@ -1780,15 +1724,6 @@ dependencies = [
|
|||
"rand_core 0.5.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rdrand"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2"
|
||||
dependencies = [
|
||||
"rand_core 0.3.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.16"
|
||||
|
@ -1813,25 +1748,6 @@ version = "0.2.0"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "56770675ebc04927ded3e60633437841581c285dc6236109ea25fbf3beb7b59e"
|
||||
|
||||
[[package]]
|
||||
name = "rust-crypto"
|
||||
version = "0.2.36"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f76d05d3993fd5f4af9434e8e436db163a12a9d40e1a58a726f27a01dfd12a2a"
|
||||
dependencies = [
|
||||
"gcc",
|
||||
"libc",
|
||||
"rand 0.3.23",
|
||||
"rustc-serialize",
|
||||
"time 0.1.45",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "rustc-serialize"
|
||||
version = "0.3.24"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
|
||||
|
||||
[[package]]
|
||||
name = "rustc_version"
|
||||
version = "0.2.3"
|
||||
|
@ -2049,10 +1965,8 @@ name = "skynet_ldap_server"
|
|||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"async-std",
|
||||
"base64 0.21.2",
|
||||
"dotenv",
|
||||
"ldap3",
|
||||
"rust-crypto",
|
||||
"serde",
|
||||
"sqlx",
|
||||
"surf",
|
||||
|
|
|
@ -8,9 +8,6 @@ edition = "2021"
|
|||
[dependencies]
|
||||
# for the ldap
|
||||
ldap3="0.11.1"
|
||||
# to be able to upgrade user passwords
|
||||
base64 = "0.21"
|
||||
rust-crypto = "^0.2"
|
||||
|
||||
# to move some config into env
|
||||
dotenv = "0.15.0"
|
||||
|
|
72
src/main.rs
72
src/main.rs
|
@ -1,8 +1,7 @@
|
|||
use ldap3::{LdapConn, Mod, Scope, SearchEntry};
|
||||
use std::collections::HashSet;
|
||||
|
||||
use base64::{engine::general_purpose, Engine as _};
|
||||
use crypto::{digest::Digest, sha2::Sha512};
|
||||
use ldap3::exop::{PasswordModify, PasswordModifyResp};
|
||||
use std::collections::HashSet;
|
||||
|
||||
// for teh webserver
|
||||
use dotenv::dotenv;
|
||||
|
@ -69,21 +68,6 @@ fn get_config() -> Config {
|
|||
config
|
||||
}
|
||||
|
||||
//https://stackoverflow.com/a/44532957
|
||||
pub fn hex_to_base64(hex: &str) -> String {
|
||||
// Make vector of bytes from octets
|
||||
let mut bytes = Vec::new();
|
||||
for i in 0..(hex.len() / 2) {
|
||||
let res = u8::from_str_radix(&hex[2 * i..2 * i + 2], 16);
|
||||
match res {
|
||||
Ok(v) => bytes.push(v),
|
||||
Err(e) => println!("Problem with hex: {}", e),
|
||||
};
|
||||
}
|
||||
|
||||
general_purpose::STANDARD.encode(&bytes) // now convert from Vec<u8> to b64-encoded String
|
||||
}
|
||||
|
||||
#[derive(Debug, Deserialize)]
|
||||
struct LdapUpdate {
|
||||
user: String,
|
||||
|
@ -114,46 +98,50 @@ async fn post_update_ldap(mut req: Request<State>) -> tide::Result {
|
|||
let (rs, _res) = ldap.search(&dn, Scope::Base, "(objectClass=*)", vec!["userPassword"])?.success()?;
|
||||
if !rs.is_empty() {
|
||||
let tmp = SearchEntry::construct(rs[0].clone());
|
||||
if !tmp.attrs["userPassword"].is_empty() && tmp.attrs["userPassword"][0].starts_with("{SHA512}") {
|
||||
if !tmp.attrs["userPassword"].is_empty() && tmp.attrs["userPassword"][0].starts_with("{SSHA512}") {
|
||||
pw_keep_same = true;
|
||||
}
|
||||
}
|
||||
|
||||
let mut mods = vec![];
|
||||
|
||||
// check if the password field itself is being updated
|
||||
let pass_new = if &field != "userPassword" {
|
||||
mods.push(Mod::Replace(field, HashSet::from([value])));
|
||||
// retain the older password
|
||||
pass
|
||||
let (pass_old, pass_new) = if &field != "userPassword" {
|
||||
// if password is not being updated then just update the required field
|
||||
let mods = vec![
|
||||
Mod::Replace(field, HashSet::from([value]))
|
||||
];
|
||||
ldap.modify(&dn, mods)?.success()?;
|
||||
|
||||
|
||||
// pass back the "old" and "new" passwords
|
||||
(pass.clone(), pass.clone())
|
||||
} else {
|
||||
// password is going to be updated, even if the old value is not starting with "{SSHA512}"
|
||||
|
||||
pw_keep_same = false;
|
||||
value
|
||||
(pass.clone(), value.clone())
|
||||
};
|
||||
|
||||
if !pw_keep_same {
|
||||
let mut hasher = Sha512::new();
|
||||
// really easy to update password once ye know how
|
||||
|
||||
let tmp = PasswordModify{
|
||||
// none as we are staying on the same connection
|
||||
user_id: None,
|
||||
|
||||
old_pass: Some(&pass_old),
|
||||
new_pass: Some(&pass_new),
|
||||
};
|
||||
|
||||
hasher.input_str(&pass_new);
|
||||
|
||||
// get it as hex string
|
||||
let hex = hasher.result_str();
|
||||
|
||||
// convert it to b64
|
||||
let pass_tmp = format!("{{SHA512}}{}", hex_to_base64(&hex));
|
||||
|
||||
mods.push(Mod::Replace(String::from("userPassword"), HashSet::from([pass_tmp])));
|
||||
ldap.extended(tmp)?.success()?;
|
||||
};
|
||||
|
||||
ldap.modify(&dn, mods)?.success()?;
|
||||
|
||||
ldap.unbind()?;
|
||||
|
||||
Ok(json!({"result": "success"}).into())
|
||||
}
|
||||
|
||||
|
||||
/** Create new account
|
||||
/* Create new account
|
||||
|
||||
|
||||
1. Check if ID is available
|
||||
|
@ -170,16 +158,16 @@ async fn post_update_ldap(mut req: Request<State>) -> tide::Result {
|
|||
|
||||
*/
|
||||
|
||||
/** Join existing account to wolves
|
||||
/* Join existing account to wolves
|
||||
related to above
|
||||
|
||||
*/
|
||||
|
||||
/** Password reset via email
|
||||
/* Password reset via email
|
||||
|
||||
*/
|
||||
|
||||
/** script to pull in all active members from wolves
|
||||
/* script to pull in all active members from wolves
|
||||
update the groups
|
||||
check if there are any pending signups
|
||||
|
||||
|
|
Loading…
Reference in a new issue