]> git.proxmox.com Git - proxmox-backup.git/blob - src/api2/config/tape_encryption_keys.rs
add "password hint" to KeyConfig
[proxmox-backup.git] / src / api2 / config / tape_encryption_keys.rs
1 use anyhow::{bail, Error};
2 use serde_json::Value;
3
4 use proxmox::{
5 api::{
6 api,
7 ApiMethod,
8 Router,
9 RpcEnvironment,
10 },
11 tools::fs::open_file_locked,
12 };
13
14 use crate::{
15 config::{
16 tape_encryption_keys::{
17 TAPE_KEYS_LOCKFILE,
18 generate_tape_encryption_key,
19 load_keys,
20 load_key_configs,
21 save_keys,
22 save_key_configs,
23 insert_key,
24 },
25 },
26 api2::types::{
27 TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA,
28 PROXMOX_CONFIG_DIGEST_SCHEMA,
29 PASSWORD_HINT_SCHEMA,
30 TapeKeyMetadata,
31 },
32 backup::{
33 Fingerprint,
34 },
35 tools::format::as_fingerprint,
36 };
37
38 #[api(
39 input: {
40 properties: {},
41 },
42 returns: {
43 description: "The list of tape encryption keys (with config digest).",
44 type: Array,
45 items: { type: TapeKeyMetadata },
46 },
47 )]
48 /// List existing keys
49 pub fn list_keys(
50 _param: Value,
51 _info: &ApiMethod,
52 mut rpcenv: &mut dyn RpcEnvironment,
53 ) -> Result<Vec<TapeKeyMetadata>, Error> {
54
55 let (key_map, digest) = load_key_configs()?;
56
57 let mut list = Vec::new();
58
59 for (fingerprint, item) in key_map {
60 list.push(TapeKeyMetadata {
61 hint: item.hint.unwrap_or(String::new()),
62 fingerprint: as_fingerprint(fingerprint.bytes()),
63 });
64 }
65
66 rpcenv["digest"] = proxmox::tools::digest_to_hex(&digest).into();
67
68 Ok(list)
69 }
70 #[api(
71 protected: true,
72 input: {
73 properties: {
74 password: {
75 description: "A secret password.",
76 min_length: 5,
77 },
78 hint: {
79 schema: PASSWORD_HINT_SCHEMA,
80 },
81 },
82 },
83 returns: {
84 schema: TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA,
85 },
86 )]
87 /// Create a new encryption key
88 pub fn create_key(
89 password: String,
90 hint: String,
91 _rpcenv: &mut dyn RpcEnvironment
92 ) -> Result<Fingerprint, Error> {
93
94 let (key, mut key_config) = generate_tape_encryption_key(password.as_bytes())?;
95 key_config.hint = Some(hint);
96
97 let fingerprint = key_config.fingerprint.clone().unwrap();
98
99 insert_key(key, key_config)?;
100
101 Ok(fingerprint)
102 }
103
104
105 #[api(
106 protected: true,
107 input: {
108 properties: {
109 fingerprint: {
110 schema: TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA,
111 },
112 digest: {
113 optional: true,
114 schema: PROXMOX_CONFIG_DIGEST_SCHEMA,
115 },
116 },
117 },
118 )]
119 /// Remove a encryption key from the database
120 ///
121 /// Please note that you can no longer access tapes using this key.
122 pub fn delete_key(
123 fingerprint: Fingerprint,
124 digest: Option<String>,
125 _rpcenv: &mut dyn RpcEnvironment,
126 ) -> Result<(), Error> {
127
128 let _lock = open_file_locked(
129 TAPE_KEYS_LOCKFILE,
130 std::time::Duration::new(10, 0),
131 true,
132 )?;
133
134 let (mut config_map, expected_digest) = load_key_configs()?;
135 let (mut key_map, _) = load_keys()?;
136
137 if let Some(ref digest) = digest {
138 let digest = proxmox::tools::hex_to_digest(digest)?;
139 crate::tools::detect_modified_configuration_file(&digest, &expected_digest)?;
140 }
141
142 match config_map.get(&fingerprint) {
143 Some(_) => { config_map.remove(&fingerprint); },
144 None => bail!("tape encryption key '{}' does not exist.", fingerprint),
145 }
146 save_key_configs(config_map)?;
147
148 key_map.remove(&fingerprint);
149 save_keys(key_map)?;
150
151 Ok(())
152 }
153
154 const ITEM_ROUTER: Router = Router::new()
155 //.get(&API_METHOD_READ_KEY_METADATA)
156 //.put(&API_METHOD_UPDATE_KEY_METADATA)
157 .delete(&API_METHOD_DELETE_KEY);
158
159 pub const ROUTER: Router = Router::new()
160 .get(&API_METHOD_LIST_KEYS)
161 .post(&API_METHOD_CREATE_KEY)
162 .match_all("fingerprint", &ITEM_ROUTER);