diff --git a/Cargo.lock b/Cargo.lock index aa04f749..e12ef60f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -108,6 +108,7 @@ dependencies = [ "num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)", "oath 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)", "openssl 0.10.25 (registry+https://github.com/rust-lang/crates.io-index)", + "openssl-sys 0.9.51 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", "quoted_printable 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)", "regex 1.3.1 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 3ae721d7..4c5410a5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ build = "build.rs" # Empty to keep compatibility, prefer to set USE_SYSLOG=true enable_syslog = [] mysql = ["diesel/mysql", "diesel_migrations/mysql"] -postgresql = ["diesel/postgres", "diesel_migrations/postgres", "openssl"] +postgresql = ["diesel/postgres", "diesel_migrations/postgres"] sqlite = ["diesel/sqlite", "diesel_migrations/sqlite", "libsqlite3-sys"] [target."cfg(not(windows))".dependencies] @@ -106,14 +106,13 @@ handlebars = "2.0.2" soup = "0.4.1" regex = "1.3.1" -# Required for SSL support for PostgreSQL -openssl = { version = "0.10.25", optional = true } - # URL encoding library percent-encoding = "2.1.0" # LDAP ldap3 = "0.6.1" +openssl = "0.10.25" +openssl-sys = "*" [patch.crates-io] # Add support for Timestamp type diff --git a/src/ldap.rs b/src/ldap.rs index 3762302d..1cd28a44 100644 --- a/src/ldap.rs +++ b/src/ldap.rs @@ -1,7 +1,9 @@ use crate::db; use crate::CONFIG; use ldap3::{DerefAliases, LdapConn, Scope, SearchEntry, SearchOptions}; +use ring::{digest, pbkdf2}; use std::collections::HashSet; +use std::convert::TryInto; use std::error::Error; use std::thread::sleep; use std::time::Duration; @@ -22,34 +24,40 @@ pub fn launch_ldap_connector() { /// Invite all LDAP users to Bitwarden fn sync_from_ldap(conn: &db::DbConn) -> Result<(), Box> { - match get_existing_users(&conn) { - Ok(existing_users) => { - let mut num_users = 0; - for ldap_user in search_entries()? { - // Safely get first email from list of emails in field - if let Some(user_email) = ldap_user.attrs.get("mail").and_then(|l| (l.first())) { - if existing_users.contains(user_email) { - println!("User with email already exists: {}", user_email); - } else { - println!("Try to add user: {}", user_email); - // Add user - db::models::User::new(user_email.to_string()).save(conn)?; - num_users = num_users + 1; - } - } else { - println!("Warning: Email field, mail, not found on user"); - } + let existing_users = get_existing_users(&conn).expect("Error: Failed to get existing users from Bitwarden"); + let mut num_users = 0; + for ldap_user in search_entries()? { + // Safely get first email from list of emails in field + if let Some(user_email) = ldap_user.attrs.get("mail").and_then(|l| (l.first())) { + if !existing_users.contains(user_email) { + println!("Try to add user: {}", user_email); + // Add user + let mut user = db::models::User::new(user_email.to_string()); + let mut password_bytes = vec![0u8; 16]; + password_bytes = crate::crypto::get_random(password_bytes); + let password = std::str::from_utf8(password_bytes.as_slice()).unwrap(); + user.set_password(password); + user.client_kdf_iter = 100000; + let key = &mut [0u8; digest::SHA256_OUTPUT_LEN]; + pbkdf2::derive( + &digest::SHA256, + std::num::NonZeroU32::new(user.client_kdf_iter.try_into().unwrap()).unwrap(), + user.email.as_bytes(), + password.as_bytes(), + key, + ); + user.akey = String::from_utf8(key.to_vec()).unwrap(); + user.save(conn)?; + num_users = num_users + 1; } - - // Maybe think about returning this value for some other use - println!("Added {} user(s).", num_users); - } - Err(e) => { - println!("Error: Failed to get existing users from Bitwarden"); - return Err(e); + } else { + println!("Warning: Email field, mail, not found on user"); } } + // Maybe think about returning this value for some other use + println!("Added {} user(s).", num_users); + Ok(()) }