1 use anyhow
::{bail, Error}
;
27 TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA
,
33 config
::tape_encryption_keys
::{
35 complete_key_fingerprint
,
39 pub fn encryption_key_commands() -> CommandLineInterface
{
41 let cmd_def
= CliCommandMap
::new()
42 .insert("list", CliCommand
::new(&API_METHOD_LIST_KEYS
))
45 CliCommand
::new(&API_METHOD_CREATE_KEY
)
49 CliCommand
::new(&API_METHOD_CHANGE_PASSPHRASE
)
50 .arg_param(&["fingerprint"])
51 .completion_cb("fingerprint", complete_key_fingerprint
)
55 CliCommand
::new(&API_METHOD_SHOW_KEY
)
56 .arg_param(&["fingerprint"])
57 .completion_cb("fingerprint", complete_key_fingerprint
)
61 CliCommand
::new(&API_METHOD_PAPER_KEY
)
62 .arg_param(&["fingerprint"])
63 .completion_cb("fingerprint", complete_key_fingerprint
)
67 CliCommand
::new(&API_METHOD_RESTORE_KEY
)
71 CliCommand
::new(&api2
::config
::tape_encryption_keys
::API_METHOD_DELETE_KEY
)
72 .arg_param(&["fingerprint"])
73 .completion_cb("fingerprint", complete_key_fingerprint
)
84 schema
: TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA
,
87 description
: "Include the specified subject as title text.",
97 /// Generate a printable, human readable text file containing the encryption key.
99 /// This also includes a scanable QR code for fast key restore.
101 fingerprint
: Fingerprint
,
102 subject
: Option
<String
>,
103 output_format
: Option
<PaperkeyFormat
>,
104 ) -> Result
<(), Error
> {
106 let (config_map
, _digest
) = load_key_configs()?
;
108 let key_config
= match config_map
.get(&fingerprint
) {
109 Some(key_config
) => key_config
,
110 None
=> bail
!("tape encryption key '{}' does not exist.", fingerprint
),
113 let data
: String
= serde_json
::to_string_pretty(&key_config
)?
;
115 generate_paper_key(std
::io
::stdout(), &data
, subject
, output_format
)
122 schema
: TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA
,
125 schema
: OUTPUT_FORMAT
,
131 /// Print the encryption key's metadata.
134 rpcenv
: &mut dyn RpcEnvironment
,
135 ) -> Result
<(), Error
> {
137 let output_format
= get_output_format(¶m
);
139 let info
= &api2
::config
::tape_encryption_keys
::API_METHOD_READ_KEY
;
140 let mut data
= match info
.handler
{
141 ApiHandler
::Sync(handler
) => (handler
)(param
, info
, rpcenv
)?
,
145 let options
= proxmox
::api
::cli
::default_table_format_options()
146 .column(ColumnConfig
::new("kdf"))
147 .column(ColumnConfig
::new("created").renderer(tools
::format
::render_epoch
))
148 .column(ColumnConfig
::new("modified").renderer(tools
::format
::render_epoch
))
149 .column(ColumnConfig
::new("fingerprint"))
150 .column(ColumnConfig
::new("hint"));
152 format_and_print_result_full(&mut data
, &info
.returns
, &output_format
, &options
);
165 schema
: TAPE_ENCRYPTION_KEY_FINGERPRINT_SCHEMA
,
168 schema
: PASSWORD_HINT_SCHEMA
,
174 /// Change the encryption key's password.
175 fn change_passphrase(
177 rpcenv
: &mut dyn RpcEnvironment
,
178 ) -> Result
<(), Error
> {
180 if !tty
::stdin_isatty() {
181 bail
!("unable to change passphrase - no tty");
184 let password
= tty
::read_password("Current Tape Encryption Key Password: ")?
;
186 let new_password
= tty
::read_and_verify_password("New Tape Encryption Key Password: ")?
;
188 param
["password"] = String
::from_utf8(password
)?
.into();
189 param
["new-password"] = String
::from_utf8(new_password
)?
.into();
191 let info
= &api2
::config
::tape_encryption_keys
::API_METHOD_CHANGE_PASSPHRASE
;
193 ApiHandler
::Sync(handler
) => (handler
)(param
, info
, rpcenv
)?
,
204 schema
: DRIVE_NAME_SCHEMA
,
210 /// Restore encryption key from tape (read password from stdin)
211 async
fn restore_key(
213 rpcenv
: &mut dyn RpcEnvironment
,
214 ) -> Result
<(), Error
> {
216 let (config
, _digest
) = config
::drive
::config()?
;
217 param
["drive"] = crate::extract_drive_name(&mut param
, &config
)?
.into();
219 if !tty
::stdin_isatty() {
220 bail
!("no password input mechanism available");
223 let password
= tty
::read_password("Tepe Encryption Key Password: ")?
;
224 param
["password"] = String
::from_utf8(password
)?
.into();
226 let info
= &api2
::tape
::drive
::API_METHOD_RESTORE_KEY
;
228 ApiHandler
::Async(handler
) => (handler
)(param
, info
, rpcenv
).await?
,
243 description
: "Password restore hint.",
251 /// Create key (read password from stdin)
254 rpcenv
: &mut dyn RpcEnvironment
,
255 ) -> Result
<(), Error
> {
257 if !tty
::stdin_isatty() {
258 bail
!("no password input mechanism available");
261 let password
= tty
::read_and_verify_password("Tape Encryption Key Password: ")?
;
263 param
["password"] = String
::from_utf8(password
)?
.into();
265 let info
= &api2
::config
::tape_encryption_keys
::API_METHOD_CREATE_KEY
;
266 let fingerprint
= match info
.handler
{
267 ApiHandler
::Sync(handler
) => (handler
)(param
, info
, rpcenv
)?
,
271 println
!("{}", fingerprint
);
281 schema
: OUTPUT_FORMAT
,
290 rpcenv
: &mut dyn RpcEnvironment
,
291 ) -> Result
<(), Error
> {
293 let output_format
= get_output_format(¶m
);
294 let info
= &api2
::config
::tape_encryption_keys
::API_METHOD_LIST_KEYS
;
295 let mut data
= match info
.handler
{
296 ApiHandler
::Sync(handler
) => (handler
)(param
, info
, rpcenv
)?
,
300 let options
= default_table_format_options()
301 .column(ColumnConfig
::new("fingerprint"))
302 .column(ColumnConfig
::new("hint"))
305 format_and_print_result_full(&mut data
, &info
.returns
, &output_format
, &options
);