1 use anyhow
::{bail, Error}
;
4 use proxmox_router
::{ApiMethod, Router, RpcEnvironment, Permission}
;
5 use proxmox_schema
::api
;
8 Fingerprint
, KeyInfo
, Kdf
,
9 TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA
,
10 PROXMOX_CONFIG_DIGEST_SCHEMA
, PASSWORD_HINT_SCHEMA
,
11 PRIV_TAPE_AUDIT
, PRIV_TAPE_MODIFY
,
14 use pbs_config
::key_config
::KeyConfig
;
15 use pbs_config
::open_backup_lockfile
;
16 use pbs_config
::tape_encryption_keys
::{
30 description
: "The list of tape encryption keys (with config digest).",
32 items
: { type: KeyInfo }
,
35 permission
: &Permission
::Privilege(&["tape", "pool"], PRIV_TAPE_AUDIT
, false),
38 /// List existing keys
42 mut rpcenv
: &mut dyn RpcEnvironment
,
43 ) -> Result
<Vec
<KeyInfo
>, Error
> {
45 let (key_map
, digest
) = load_key_configs()?
;
47 let mut list
= Vec
::new();
49 for (_fingerprint
, item
) in key_map
.iter() {
50 list
.push(item
.into());
53 rpcenv
["digest"] = proxmox
::tools
::digest_to_hex(&digest
).into();
67 schema
: TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA
,
70 description
: "The current password.",
74 description
: "The new password.",
78 schema
: PASSWORD_HINT_SCHEMA
,
82 schema
: PROXMOX_CONFIG_DIGEST_SCHEMA
,
87 permission
: &Permission
::Privilege(&["tape", "pool"], PRIV_TAPE_MODIFY
, false),
90 /// Change the encryption key's password (and password hint).
91 pub fn change_passphrase(
96 fingerprint
: Fingerprint
,
97 digest
: Option
<String
>,
98 _rpcenv
: &mut dyn RpcEnvironment
99 ) -> Result
<(), Error
> {
101 let kdf
= kdf
.unwrap_or_default();
103 if let Kdf
::None
= kdf
{
104 bail
!("Please specify a key derivation function (none is not allowed here).");
107 let _lock
= open_backup_lockfile(TAPE_KEYS_LOCKFILE
, None
, true)?
;
109 let (mut config_map
, expected_digest
) = load_key_configs()?
;
111 if let Some(ref digest
) = digest
{
112 let digest
= proxmox
::tools
::hex_to_digest(digest
)?
;
113 crate::tools
::detect_modified_configuration_file(&digest
, &expected_digest
)?
;
116 let key_config
= match config_map
.get(&fingerprint
) {
117 Some(key_config
) => key_config
,
118 None
=> bail
!("tape encryption key '{}' does not exist.", fingerprint
),
121 let (key
, created
, fingerprint
) = key_config
.decrypt(&|| Ok(password
.as_bytes().to_vec()))?
;
122 let mut new_key_config
= KeyConfig
::with_key(&key
, new_password
.as_bytes(), kdf
)?
;
123 new_key_config
.created
= created
; // keep original value
124 new_key_config
.hint
= Some(hint
);
126 config_map
.insert(fingerprint
, new_key_config
);
128 save_key_configs(config_map
)?
;
142 description
: "A secret password.",
146 schema
: PASSWORD_HINT_SCHEMA
,
151 schema
: TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA
,
154 permission
: &Permission
::Privilege(&["tape", "pool"], PRIV_TAPE_MODIFY
, false),
157 /// Create a new encryption key
162 _rpcenv
: &mut dyn RpcEnvironment
163 ) -> Result
<Fingerprint
, Error
> {
165 let kdf
= kdf
.unwrap_or_default();
167 if let Kdf
::None
= kdf
{
168 bail
!("Please specify a key derivation function (none is not allowed here).");
171 let (key
, mut key_config
) = KeyConfig
::new(password
.as_bytes(), kdf
)?
;
172 key_config
.hint
= Some(hint
);
174 let fingerprint
= key_config
.fingerprint
.clone().unwrap();
176 insert_key(key
, key_config
, false)?
;
186 schema
: TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA
,
194 permission
: &Permission
::Privilege(&["tape", "pool"], PRIV_TAPE_AUDIT
, false),
197 /// Get key config (public key part)
199 fingerprint
: Fingerprint
,
200 _rpcenv
: &mut dyn RpcEnvironment
,
201 ) -> Result
<KeyInfo
, Error
> {
203 let (config_map
, _digest
) = load_key_configs()?
;
205 let key_config
= match config_map
.get(&fingerprint
) {
206 Some(key_config
) => key_config
,
207 None
=> bail
!("tape encryption key '{}' does not exist.", fingerprint
),
210 if key_config
.kdf
.is_none() {
211 bail
!("found unencrypted key - internal error");
214 Ok(key_config
.into())
222 schema
: TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA
,
226 schema
: PROXMOX_CONFIG_DIGEST_SCHEMA
,
231 permission
: &Permission
::Privilege(&["tape", "pool"], PRIV_TAPE_MODIFY
, false),
234 /// Remove a encryption key from the database
236 /// Please note that you can no longer access tapes using this key.
238 fingerprint
: Fingerprint
,
239 digest
: Option
<String
>,
240 _rpcenv
: &mut dyn RpcEnvironment
,
241 ) -> Result
<(), Error
> {
242 let _lock
= open_backup_lockfile(TAPE_KEYS_LOCKFILE
, None
, true)?
;
244 let (mut config_map
, expected_digest
) = load_key_configs()?
;
245 let (mut key_map
, _
) = load_keys()?
;
247 if let Some(ref digest
) = digest
{
248 let digest
= proxmox
::tools
::hex_to_digest(digest
)?
;
249 crate::tools
::detect_modified_configuration_file(&digest
, &expected_digest
)?
;
252 match config_map
.get(&fingerprint
) {
253 Some(_
) => { config_map.remove(&fingerprint); }
,
254 None
=> bail
!("tape encryption key '{}' does not exist.", fingerprint
),
256 save_key_configs(config_map
)?
;
258 key_map
.remove(&fingerprint
);
264 const ITEM_ROUTER
: Router
= Router
::new()
265 .get(&API_METHOD_READ_KEY
)
266 .put(&API_METHOD_CHANGE_PASSPHRASE
)
267 .delete(&API_METHOD_DELETE_KEY
);
269 pub const ROUTER
: Router
= Router
::new()
270 .get(&API_METHOD_LIST_KEYS
)
271 .post(&API_METHOD_CREATE_KEY
)
272 .match_all("fingerprint", &ITEM_ROUTER
);