1 use anyhow
::{bail, Error}
;
12 tools
::fs
::open_file_locked
,
21 tape_encryption_keys
::{
31 TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA
,
32 PROXMOX_CONFIG_DIGEST_SCHEMA
,
48 description
: "The list of tape encryption keys (with config digest).",
50 items
: { type: KeyInfo }
,
53 permission
: &Permission
::Privilege(&["tape", "pool"], PRIV_TAPE_AUDIT
, false),
56 /// List existing keys
60 mut rpcenv
: &mut dyn RpcEnvironment
,
61 ) -> Result
<Vec
<KeyInfo
>, Error
> {
63 let (key_map
, digest
) = load_key_configs()?
;
65 let mut list
= Vec
::new();
67 for (_fingerprint
, item
) in key_map
.iter() {
68 list
.push(item
.into());
71 rpcenv
["digest"] = proxmox
::tools
::digest_to_hex(&digest
).into();
85 schema
: TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA
,
88 description
: "The current password.",
92 description
: "The new password.",
96 schema
: PASSWORD_HINT_SCHEMA
,
100 schema
: PROXMOX_CONFIG_DIGEST_SCHEMA
,
105 permission
: &Permission
::Privilege(&["tape", "pool"], PRIV_TAPE_MODIFY
, false),
108 /// Change the encryption key's password (and password hint).
109 pub fn change_passphrase(
112 new_password
: String
,
114 fingerprint
: Fingerprint
,
115 digest
: Option
<String
>,
116 _rpcenv
: &mut dyn RpcEnvironment
117 ) -> Result
<(), Error
> {
119 let kdf
= kdf
.unwrap_or_default();
121 if let Kdf
::None
= kdf
{
122 bail
!("Please specify a key derivation function (none is not allowed here).");
125 let _lock
= open_file_locked(
127 std
::time
::Duration
::new(10, 0),
131 let (mut config_map
, expected_digest
) = load_key_configs()?
;
133 if let Some(ref digest
) = digest
{
134 let digest
= proxmox
::tools
::hex_to_digest(digest
)?
;
135 crate::tools
::detect_modified_configuration_file(&digest
, &expected_digest
)?
;
138 let key_config
= match config_map
.get(&fingerprint
) {
139 Some(key_config
) => key_config
,
140 None
=> bail
!("tape encryption key '{}' does not exist.", fingerprint
),
143 let (key
, created
, fingerprint
) = key_config
.decrypt(&|| Ok(password
.as_bytes().to_vec()))?
;
144 let mut new_key_config
= KeyConfig
::with_key(&key
, new_password
.as_bytes(), kdf
)?
;
145 new_key_config
.created
= created
; // keep original value
146 new_key_config
.hint
= Some(hint
);
148 config_map
.insert(fingerprint
, new_key_config
);
150 save_key_configs(config_map
)?
;
164 description
: "A secret password.",
168 schema
: PASSWORD_HINT_SCHEMA
,
173 schema
: TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA
,
176 permission
: &Permission
::Privilege(&["tape", "pool"], PRIV_TAPE_MODIFY
, false),
179 /// Create a new encryption key
184 _rpcenv
: &mut dyn RpcEnvironment
185 ) -> Result
<Fingerprint
, Error
> {
187 let kdf
= kdf
.unwrap_or_default();
189 if let Kdf
::None
= kdf
{
190 bail
!("Please specify a key derivation function (none is not allowed here).");
193 let (key
, mut key_config
) = KeyConfig
::new(password
.as_bytes(), kdf
)?
;
194 key_config
.hint
= Some(hint
);
196 let fingerprint
= key_config
.fingerprint
.clone().unwrap();
198 insert_key(key
, key_config
, false)?
;
208 schema
: TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA
,
216 permission
: &Permission
::Privilege(&["tape", "pool"], PRIV_TAPE_AUDIT
, false),
219 /// Get key config (public key part)
221 fingerprint
: Fingerprint
,
222 _rpcenv
: &mut dyn RpcEnvironment
,
223 ) -> Result
<KeyInfo
, Error
> {
225 let (config_map
, _digest
) = load_key_configs()?
;
227 let key_config
= match config_map
.get(&fingerprint
) {
228 Some(key_config
) => key_config
,
229 None
=> bail
!("tape encryption key '{}' does not exist.", fingerprint
),
232 if key_config
.kdf
.is_none() {
233 bail
!("found unencrypted key - internal error");
236 Ok(key_config
.into())
244 schema
: TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA
,
248 schema
: PROXMOX_CONFIG_DIGEST_SCHEMA
,
253 permission
: &Permission
::Privilege(&["tape", "pool"], PRIV_TAPE_MODIFY
, false),
256 /// Remove a encryption key from the database
258 /// Please note that you can no longer access tapes using this key.
260 fingerprint
: Fingerprint
,
261 digest
: Option
<String
>,
262 _rpcenv
: &mut dyn RpcEnvironment
,
263 ) -> Result
<(), Error
> {
265 let _lock
= open_file_locked(
267 std
::time
::Duration
::new(10, 0),
271 let (mut config_map
, expected_digest
) = load_key_configs()?
;
272 let (mut key_map
, _
) = load_keys()?
;
274 if let Some(ref digest
) = digest
{
275 let digest
= proxmox
::tools
::hex_to_digest(digest
)?
;
276 crate::tools
::detect_modified_configuration_file(&digest
, &expected_digest
)?
;
279 match config_map
.get(&fingerprint
) {
280 Some(_
) => { config_map.remove(&fingerprint); }
,
281 None
=> bail
!("tape encryption key '{}' does not exist.", fingerprint
),
283 save_key_configs(config_map
)?
;
285 key_map
.remove(&fingerprint
);
291 const ITEM_ROUTER
: Router
= Router
::new()
292 .get(&API_METHOD_READ_KEY
)
293 .put(&API_METHOD_CHANGE_PASSPHRASE
)
294 .delete(&API_METHOD_DELETE_KEY
);
296 pub const ROUTER
: Router
= Router
::new()
297 .get(&API_METHOD_LIST_KEYS
)
298 .post(&API_METHOD_CREATE_KEY
)
299 .match_all("fingerprint", &ITEM_ROUTER
);