1 use anyhow
::{bail, Error}
;
14 use pbs_api_types
::{Fingerprint, KeyInfo, Kdf}
;
15 use pbs_config
::key_config
::KeyConfig
;
16 use pbs_config
::open_backup_lockfile
;
24 tape_encryption_keys
::{
34 TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA
,
35 PROXMOX_CONFIG_DIGEST_SCHEMA
,
45 description
: "The list of tape encryption keys (with config digest).",
47 items
: { type: KeyInfo }
,
50 permission
: &Permission
::Privilege(&["tape", "pool"], PRIV_TAPE_AUDIT
, false),
53 /// List existing keys
57 mut rpcenv
: &mut dyn RpcEnvironment
,
58 ) -> Result
<Vec
<KeyInfo
>, Error
> {
60 let (key_map
, digest
) = load_key_configs()?
;
62 let mut list
= Vec
::new();
64 for (_fingerprint
, item
) in key_map
.iter() {
65 list
.push(item
.into());
68 rpcenv
["digest"] = proxmox
::tools
::digest_to_hex(&digest
).into();
82 schema
: TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA
,
85 description
: "The current password.",
89 description
: "The new password.",
93 schema
: PASSWORD_HINT_SCHEMA
,
97 schema
: PROXMOX_CONFIG_DIGEST_SCHEMA
,
102 permission
: &Permission
::Privilege(&["tape", "pool"], PRIV_TAPE_MODIFY
, false),
105 /// Change the encryption key's password (and password hint).
106 pub fn change_passphrase(
109 new_password
: String
,
111 fingerprint
: Fingerprint
,
112 digest
: Option
<String
>,
113 _rpcenv
: &mut dyn RpcEnvironment
114 ) -> Result
<(), Error
> {
116 let kdf
= kdf
.unwrap_or_default();
118 if let Kdf
::None
= kdf
{
119 bail
!("Please specify a key derivation function (none is not allowed here).");
122 let _lock
= open_backup_lockfile(TAPE_KEYS_LOCKFILE
, None
, true)?
;
124 let (mut config_map
, expected_digest
) = load_key_configs()?
;
126 if let Some(ref digest
) = digest
{
127 let digest
= proxmox
::tools
::hex_to_digest(digest
)?
;
128 crate::tools
::detect_modified_configuration_file(&digest
, &expected_digest
)?
;
131 let key_config
= match config_map
.get(&fingerprint
) {
132 Some(key_config
) => key_config
,
133 None
=> bail
!("tape encryption key '{}' does not exist.", fingerprint
),
136 let (key
, created
, fingerprint
) = key_config
.decrypt(&|| Ok(password
.as_bytes().to_vec()))?
;
137 let mut new_key_config
= KeyConfig
::with_key(&key
, new_password
.as_bytes(), kdf
)?
;
138 new_key_config
.created
= created
; // keep original value
139 new_key_config
.hint
= Some(hint
);
141 config_map
.insert(fingerprint
, new_key_config
);
143 save_key_configs(config_map
)?
;
157 description
: "A secret password.",
161 schema
: PASSWORD_HINT_SCHEMA
,
166 schema
: TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA
,
169 permission
: &Permission
::Privilege(&["tape", "pool"], PRIV_TAPE_MODIFY
, false),
172 /// Create a new encryption key
177 _rpcenv
: &mut dyn RpcEnvironment
178 ) -> Result
<Fingerprint
, Error
> {
180 let kdf
= kdf
.unwrap_or_default();
182 if let Kdf
::None
= kdf
{
183 bail
!("Please specify a key derivation function (none is not allowed here).");
186 let (key
, mut key_config
) = KeyConfig
::new(password
.as_bytes(), kdf
)?
;
187 key_config
.hint
= Some(hint
);
189 let fingerprint
= key_config
.fingerprint
.clone().unwrap();
191 insert_key(key
, key_config
, false)?
;
201 schema
: TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA
,
209 permission
: &Permission
::Privilege(&["tape", "pool"], PRIV_TAPE_AUDIT
, false),
212 /// Get key config (public key part)
214 fingerprint
: Fingerprint
,
215 _rpcenv
: &mut dyn RpcEnvironment
,
216 ) -> Result
<KeyInfo
, Error
> {
218 let (config_map
, _digest
) = load_key_configs()?
;
220 let key_config
= match config_map
.get(&fingerprint
) {
221 Some(key_config
) => key_config
,
222 None
=> bail
!("tape encryption key '{}' does not exist.", fingerprint
),
225 if key_config
.kdf
.is_none() {
226 bail
!("found unencrypted key - internal error");
229 Ok(key_config
.into())
237 schema
: TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA
,
241 schema
: PROXMOX_CONFIG_DIGEST_SCHEMA
,
246 permission
: &Permission
::Privilege(&["tape", "pool"], PRIV_TAPE_MODIFY
, false),
249 /// Remove a encryption key from the database
251 /// Please note that you can no longer access tapes using this key.
253 fingerprint
: Fingerprint
,
254 digest
: Option
<String
>,
255 _rpcenv
: &mut dyn RpcEnvironment
,
256 ) -> Result
<(), Error
> {
257 let _lock
= open_backup_lockfile(TAPE_KEYS_LOCKFILE
, None
, true)?
;
259 let (mut config_map
, expected_digest
) = load_key_configs()?
;
260 let (mut key_map
, _
) = load_keys()?
;
262 if let Some(ref digest
) = digest
{
263 let digest
= proxmox
::tools
::hex_to_digest(digest
)?
;
264 crate::tools
::detect_modified_configuration_file(&digest
, &expected_digest
)?
;
267 match config_map
.get(&fingerprint
) {
268 Some(_
) => { config_map.remove(&fingerprint); }
,
269 None
=> bail
!("tape encryption key '{}' does not exist.", fingerprint
),
271 save_key_configs(config_map
)?
;
273 key_map
.remove(&fingerprint
);
279 const ITEM_ROUTER
: Router
= Router
::new()
280 .get(&API_METHOD_READ_KEY
)
281 .put(&API_METHOD_CHANGE_PASSPHRASE
)
282 .delete(&API_METHOD_DELETE_KEY
);
284 pub const ROUTER
: Router
= Router
::new()
285 .get(&API_METHOD_LIST_KEYS
)
286 .post(&API_METHOD_CREATE_KEY
)
287 .match_all("fingerprint", &ITEM_ROUTER
);