Browse Source

Harden the Key Connector account endpoints

set-key-connector-key now refuses to touch an already initialized
account (same check as set-password) and convert-to-key-connector
refuses accounts that have no keys yet. Logins of key connector users
fail with a clear error when KEY_CONNECTOR_ENABLED was turned off
again, instead of returning a response without any usable decryption
option. KEY_CONNECTOR_URL is also validated as a URL on startup.
pull/7419/head
Luca Biemelt 1 week ago
parent
commit
f48a4b7eba
  1. 9
      src/api/core/key_connector.rs
  2. 5
      src/api/identity.rs
  3. 3
      src/config.rs

9
src/api/core/key_connector.rs

@ -44,6 +44,10 @@ async fn post_set_key_connector_key(data: Json<SetKeyConnectorKeyData>, headers:
let data = data.into_inner(); let data = data.into_inner();
let mut user = headers.user; let mut user = headers.user;
if user.private_key.is_some() {
err!("Account already initialized, cannot set Key Connector key");
}
user.client_kdf_type = data.kdf; user.client_kdf_type = data.kdf;
user.client_kdf_iter = data.kdf_iterations; user.client_kdf_iter = data.kdf_iterations;
user.client_kdf_memory = data.kdf_memory; user.client_kdf_memory = data.kdf_memory;
@ -69,6 +73,11 @@ async fn post_convert_to_key_connector(headers: Headers, conn: DbConn) -> EmptyR
} }
let mut user = headers.user; let mut user = headers.user;
if user.private_key.is_none() {
err!("Account is not initialized, cannot convert to Key Connector");
}
user.password_hash = Vec::new(); user.password_hash = Vec::new();
user.password_hint = None; user.password_hint = None;
user.uses_key_connector = true; user.uses_key_connector = true;

5
src/api/identity.rs

@ -515,7 +515,10 @@ async fn authenticated_response(
let master_password_policy = master_password_policy(user, conn).await; let master_password_policy = master_password_policy(user, conn).await;
// Key connector users have no master password, the master key is stored on the connector // Key connector users have no master password, the master key is stored on the connector
let uses_key_connector = CONFIG.key_connector_enabled() && user.uses_key_connector; let uses_key_connector = user.uses_key_connector;
if uses_key_connector && !CONFIG.key_connector_enabled() {
err!("This user's master key is stored on a key connector, but Key Connector support is disabled")
}
let has_master_password = !user.password_hash.is_empty() && !uses_key_connector; let has_master_password = !user.password_hash.is_empty() && !uses_key_connector;
let master_password_unlock = if has_master_password { let master_password_unlock = if has_master_password {
json!({ json!({

3
src/config.rs

@ -1104,6 +1104,9 @@ fn validate_config(cfg: &ConfigItems, on_update: bool) -> Result<(), Error> {
if cfg.key_connector_url.is_empty() { if cfg.key_connector_url.is_empty() {
err!("`KEY_CONNECTOR_URL` must be set when Key Connector is enabled") err!("`KEY_CONNECTOR_URL` must be set when Key Connector is enabled")
} }
if Url::parse(&cfg.key_connector_url).is_err() {
err!("Invalid URL format for `KEY_CONNECTOR_URL`.");
}
} }
if cfg._enable_yubico { if cfg._enable_yubico {

Loading…
Cancel
Save