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 147A76314B for ; Mon, 14 Feb 2022 10:20:15 +0100 (CET) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 0B2F720834 for ; Mon, 14 Feb 2022 10:20:15 +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 5367920829 for ; Mon, 14 Feb 2022 10:20:14 +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 25D9D42C08; Mon, 14 Feb 2022 10:20:14 +0100 (CET) Message-ID: <24789990-1e3c-33ba-97d9-23b9f65e9e9f@proxmox.com> Date: Mon, 14 Feb 2022 10:20:12 +0100 MIME-Version: 1.0 User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:97.0) Gecko/20100101 Thunderbird/97.0 Content-Language: en-US To: Proxmox Backup Server development discussion , Stefan Sterz References: <20220210142325.2595867-1-s.sterz@proxmox.com> From: Dominik Csapak In-Reply-To: <20220210142325.2595867-1-s.sterz@proxmox.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 7bit X-SPAM-LEVEL: Spam detection results: 0 AWL 0.159 Adjusted score from AWL reputation of From: address 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 NICE_REPLY_A -0.001 Looks like a legit reply (A) 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: Re: [pbs-devel] [PATCH proxmox-backup v2 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, 14 Feb 2022 09:20:15 -0000 one nit inline (could be done as a followup) On 2/10/22 15:23, Stefan Sterz wrote: > 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. Requires super user privileges. > > Signed-off-by: Stefan Sterz > --- > v1->v2: check for root privileges moved into the api endpoint, better > descriptions and errors strings and incorporated some nitpicks. > > Thanks for the feedback to Thomas Lamprecht, Dominik Csapak, and > Wolfgang Bumiller. > > src/api2/config/tape_encryption_keys.rs | 41 +++++++++++++++++++++---- > 1 file changed, 35 insertions(+), 6 deletions(-) > > diff --git a/src/api2/config/tape_encryption_keys.rs b/src/api2/config/tape_encryption_keys.rs > index 1ad99377..25cc6cc0 100644 > --- a/src/api2/config/tape_encryption_keys.rs > +++ b/src/api2/config/tape_encryption_keys.rs > @@ -1,4 +1,4 @@ > -use anyhow::{bail, Error}; > +use anyhow::{format_err, bail, Error}; > use serde_json::Value; > use hex::FromHex; > > @@ -6,12 +6,14 @@ use proxmox_router::{ApiMethod, Router, RpcEnvironment, Permission}; > use proxmox_schema::api; > > use pbs_api_types::{ > - Fingerprint, KeyInfo, Kdf, > + Authid, Fingerprint, KeyInfo, Kdf, > TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA, > PROXMOX_CONFIG_DIGEST_SCHEMA, PASSWORD_HINT_SCHEMA, > PRIV_TAPE_AUDIT, PRIV_TAPE_MODIFY, > }; > > +use pbs_config::CachedUserInfo; > + > use pbs_config::key_config::KeyConfig; > use pbs_config::open_backup_lockfile; > use pbs_config::tape_encryption_keys::{ > @@ -70,6 +72,7 @@ pub fn list_keys( > password: { > description: "The current password.", > min_length: 5, > + optional: true, > }, > "new-password": { > description: "The new password.", > @@ -78,6 +81,12 @@ pub fn list_keys( > hint: { > schema: PASSWORD_HINT_SCHEMA, > }, > + force: { > + optional: true, > + type: bool, > + description: "Reset the passphrase for a tape key, using the root-only accessible copy.", > + default: false, > + }, > digest: { > optional: true, > schema: PROXMOX_CONFIG_DIGEST_SCHEMA, > @@ -91,12 +100,13 @@ 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 > + rpcenv: &mut dyn RpcEnvironment > ) -> Result<(), Error> { > > let kdf = kdf.unwrap_or_default(); > @@ -116,10 +126,29 @@ 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), > + }; > + > + let auth_id: Authid = rpcenv.get_auth_id().unwrap().parse()?; > + let user_info = CachedUserInfo::new()?; > + > + if force && !user_info.is_superuser(&auth_id) { > + bail!("resetting the key's passphrase requires root privileges") > + } > + > + let (key, created, fingerprint) = match (force, &password) { > + (true, Some(_)) => bail!("password is not allowed when using force"), > + (false, None) => bail!("missing parameter: password"), those two errors could make use of 'ParameterError' see proxmox-schema/src/schema.rs > + (false, Some(pass)) => key_config.decrypt(&|| Ok(pass.as_bytes().to_vec()))?, > + (true, None) => { > + let key = load_keys()?.0.get(&fingerprint).ok_or_else(|| { > + format_err!("failed to reset passphrase, could not find key '{}'", fingerprint) > + })?.key; > + > + (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);