From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [212.224.123.68]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.proxmox.com (Postfix) with ESMTPS id 9A5E860E03 for ; Mon, 7 Feb 2022 13:56:49 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 90C8124E60 for ; Mon, 7 Feb 2022 13:56:19 +0100 (CET) Received: from proxmox-new.maurer-it.com (proxmox-new.maurer-it.com [94.136.29.106]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by firstgate.proxmox.com (Proxmox) with ESMTPS id 4FA0924E4D for ; Mon, 7 Feb 2022 13:56:18 +0100 (CET) Received: from proxmox-new.maurer-it.com (localhost.localdomain [127.0.0.1]) by proxmox-new.maurer-it.com (Proxmox) with ESMTP id 2067640679 for ; Mon, 7 Feb 2022 13:48:49 +0100 (CET) From: Stefan Sterz To: pbs-devel@lists.proxmox.com Date: Mon, 7 Feb 2022 13:48:24 +0100 Message-Id: <20220207124825.1116194-1-s.sterz@proxmox.com> X-Mailer: git-send-email 2.30.2 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-SPAM-LEVEL: Spam detection results: 0 BAYES_00 -1.9 Bayes spam probability is 0 to 1% KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record T_SCC_BODY_TEXT_LINE -0.01 - Subject: [pbs-devel] [PATCH proxmox-backup 1/2] fix #3853: api: add force option to tape key change-passphrase X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 07 Feb 2022 12:56:49 -0000 When force is used, the current passphrase is not required. Instead it will be read from the file pointed to by TAPE_KEYS_FILENAME and the old key configuration will be overwritten using the new passphrase. Signed-off-by: Stefan Sterz --- src/api2/config/tape_encryption_keys.rs | 36 ++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/src/api2/config/tape_encryption_keys.rs b/src/api2/config/tape_encryption_keys.rs index 1ad99377..b31f741d 100644 --- a/src/api2/config/tape_encryption_keys.rs +++ b/src/api2/config/tape_encryption_keys.rs @@ -70,6 +70,7 @@ pub fn list_keys( password: { description: "The current password.", min_length: 5, + optional: true, }, "new-password": { description: "The new password.", @@ -78,6 +79,12 @@ pub fn list_keys( hint: { schema: PASSWORD_HINT_SCHEMA, }, + force: { + optional: true, + type: bool, + description: "Don't ask for the old passphrase and overwrite it. Root only.", + default: false, + }, digest: { optional: true, schema: PROXMOX_CONFIG_DIGEST_SCHEMA, @@ -91,9 +98,10 @@ pub fn list_keys( /// Change the encryption key's password (and password hint). pub fn change_passphrase( kdf: Option, - password: String, + password: Option, new_password: String, hint: String, + force: bool, fingerprint: Fingerprint, digest: Option, _rpcenv: &mut dyn RpcEnvironment @@ -116,10 +124,32 @@ pub fn change_passphrase( let key_config = match config_map.get(&fingerprint) { Some(key_config) => key_config, - None => bail!("tape encryption key '{}' does not exist.", fingerprint), + None => bail!("tape encryption key configuration '{}' does not exist.", fingerprint), + }; + + // sanity checks for "password xor --force" + if force && password.is_some() { + bail!("password is not allowed when using force") + } + + if !force && password.is_none() { + bail!("missing parameter: password") + } + + // decrypt old key or force loading old key from plaintext file + let (key, created, fingerprint) = if let Some(pass) = password { + key_config.decrypt(&|| Ok(pass.as_bytes().to_vec()))? + } else { + let (key_map, _) = load_keys()?; + + let key = match key_map.get(&fingerprint) { + Some(k) => k.key, + None => bail!("tape encryption key '{}' does not exist.", fingerprint) + }; + + (key, key_config.created, fingerprint) }; - let (key, created, fingerprint) = key_config.decrypt(&|| Ok(password.as_bytes().to_vec()))?; let mut new_key_config = KeyConfig::with_key(&key, new_password.as_bytes(), kdf)?; new_key_config.created = created; // keep original value new_key_config.hint = Some(hint); -- 2.30.2