Browse Source

Merge cd45c52d0c into 904b80115d

pull/7752/merge
Timshel 1 week ago
committed by GitHub
parent
commit
f3f004912b
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 2
      Cargo.toml
  2. 2
      playwright/compose/warden/build.sh
  3. 4
      playwright/docker-compose.yml
  4. 2
      playwright/test.env
  5. 12
      src/api/core/accounts.rs
  6. 20
      src/config.rs
  7. 3
      src/db/models/user.rs

2
Cargo.toml

@ -48,6 +48,8 @@ s3 = [
"dep:reqsign-aws-v4",
"dep:reqsign-core",
]
# Enable to allow to set lower KDF iterations settings
unsafe_test_mode = []
# OIDC specific features
oidc-accept-rfc3339-timestamps = ["openidconnect/accept-rfc3339-timestamps"]

2
playwright/compose/warden/build.sh

@ -24,7 +24,7 @@ if [[ ! -z "$REPO_URL" ]] && [[ ! -z "$COMMIT_HASH" ]] ; then
fi
# Lower the KDF iterations default for faster tests.
sed -i 's/(6e5,2e6,6e5)/(1e5,2e6,1e5)/' /web-vault/app/main.*.js
sed -i 's/(6e5,2e6,6e5)/(6e3,2e6,6e3)/' /web-vault/app/main.*.js
# Generate a self signed cert
mkdir -p /data/ssl; cd /data/ssl

4
playwright/docker-compose.yml

@ -6,6 +6,8 @@ services:
build:
context: ..
dockerfile: Dockerfile
args:
DB: sqlite,mysql,postgresql,unsafe_test_mode
entrypoint: /bin/bash
restart: "no"
@ -23,12 +25,14 @@ services:
env_file: ${DC_ENV_FILE:-.env}
environment:
- ADMIN_TOKEN
- CLIENT_KDF_ITER
- DATABASE_URL
- CLIENT_SUPPRESS_ONBOARDING
- EMAIL_2FA_AUTO_FALLBACK
- I_REALLY_WANT_VOLATILE_STORAGE
- LOG_LEVEL
- LOGIN_RATELIMIT_MAX_BURST
- PASSWORD_ITERATIONS
- SMTP_HOST
- SMTP_FROM
- SMTP_DEBUG

2
playwright/test.env

@ -58,6 +58,8 @@ LOG_LEVEL=info,oidcwarden::sso=debug
LOGIN_RATELIMIT_MAX_BURST=100
ADMIN_TOKEN=admin
CLIENT_SUPPRESS_ONBOARDING=true
PASSWORD_ITERATIONS=6000
CLIENT_KDF_ITER=6000
SMTP_SECURITY=off
SMTP_PORT=${MAILDEV_SMTP_PORT}

12
src/api/core/accounts.rs

@ -688,8 +688,8 @@ async fn post_password(data: Json<ChangePassData>, headers: Headers, conn: DbCon
}
fn set_kdf_data(user: &mut User, data: &KDFData) -> EmptyResult {
if data.kdf == UserKdfType::Pbkdf2 as i32 && data.kdf_iterations < 100_000 {
err!("PBKDF2 KDF iterations must be at least 100000.")
if data.kdf == UserKdfType::Pbkdf2 as i32 && data.kdf_iterations < CONFIG.client_kdf_iter() {
err!(format!("PBKDF2 KDF iterations must be at least {}.", CONFIG.client_kdf_iter()))
}
if data.kdf == UserKdfType::Argon2id as i32 {
@ -1427,15 +1427,15 @@ fn unknown_email_kdf(email: &str) -> (i32, i32, Option<i32>, Option<i32>) {
const PBKDF2: i32 = UserKdfType::Pbkdf2 as i32;
const ARGON2ID: i32 = UserKdfType::Argon2id as i32;
// Same list as upstream, the default is in it twice to give it more weight
const KDF_SETTINGS: [(i32, i32, Option<i32>, Option<i32>); 6] = [
(User::CLIENT_KDF_TYPE_DEFAULT, User::CLIENT_KDF_ITER_DEFAULT, None, None),
(User::CLIENT_KDF_TYPE_DEFAULT, User::CLIENT_KDF_ITER_DEFAULT, None, None),
let kdf_settings: [(i32, i32, Option<i32>, Option<i32>); 6] = [
(User::CLIENT_KDF_TYPE_DEFAULT, CONFIG.client_kdf_iter(), None, None),
(User::CLIENT_KDF_TYPE_DEFAULT, CONFIG.client_kdf_iter(), None, None),
(PBKDF2, 100_000, None, None),
(PBKDF2, 5_000, None, None),
(ARGON2ID, 3, Some(64), Some(4)),
(ARGON2ID, 6, Some(32), Some(4)),
];
KDF_SETTINGS[crate::auth::prelogin_kdf_index(email, KDF_SETTINGS.len())]
kdf_settings[crate::auth::prelogin_kdf_index(email, kdf_settings.len())]
}
pub async fn prelogin(data: Json<PreloginData>, ip: ClientIp, conn: DbConn) -> JsonResult {

20
src/config.rs

@ -680,7 +680,9 @@ make_config! {
client {
/// Control whether clients onboarding interstitials are suppressed |> post-login welcome dialogs, extension install prompts, setup extension redirects, and premium upsell modals
client_suppress_onboarding: bool, true, def, false;
client_suppress_onboarding: bool, true, def, false;
/// In most cases this value is set by the client |> Will block clients from setting too low of a value in `accounts::post_kdf`
client_kdf_iter: i32, false, def, 600_000;
},
/// Advanced settings
@ -960,6 +962,17 @@ make_config! {
},
}
fn check_iterations(iterations: i32, key: &str) -> Result<(), Error> {
if iterations < 100_000 {
#[cfg(feature = "unsafe_test_mode")]
println!("[WARNING] {key} should be at least 100000 or higher. The default is 600000!");
#[cfg(not(feature = "unsafe_test_mode"))]
err!(format!("{key} should be at least 100000 or higher. The default is 600000!"));
}
Ok(())
}
fn validate_config(cfg: &ConfigItems, on_update: bool) -> Result<(), Error> {
// Validate connection URL is valid and DB feature is enabled
#[cfg(sqlite)]
@ -994,9 +1007,8 @@ fn validate_config(cfg: &ConfigItems, on_update: bool) -> Result<(), Error> {
}
}
if cfg.password_iterations < 100_000 {
err!("PASSWORD_ITERATIONS should be at least 100000 or higher. The default is 600000!");
}
check_iterations(cfg.password_iterations, "PASSWORD_ITERATIONS")?;
check_iterations(cfg.client_kdf_iter, "CLIENT_KDF_ITER")?;
let limit = 256;
if cfg.database_max_conns < 1 || cfg.database_max_conns > limit {

3
src/db/models/user.rs

@ -110,7 +110,6 @@ pub struct UserStampException {
/// Local methods
impl User {
pub const CLIENT_KDF_TYPE_DEFAULT: i32 = UserKdfType::Pbkdf2 as i32;
pub const CLIENT_KDF_ITER_DEFAULT: i32 = 600_000;
pub fn new(email: &str, name: Option<String>) -> Self {
let now = Utc::now().naive_utc();
@ -148,7 +147,7 @@ impl User {
excluded_globals: "[]".to_owned(),
client_kdf_type: Self::CLIENT_KDF_TYPE_DEFAULT,
client_kdf_iter: Self::CLIENT_KDF_ITER_DEFAULT,
client_kdf_iter: CONFIG.client_kdf_iter(),
client_kdf_memory: None,
client_kdf_parallelism: None,

Loading…
Cancel
Save