1use std::path::PathBuf;
2
3use chrono::{DateTime, Utc};
4use clap::{Parser, Subcommand};
5use expression_format::ex_format;
6use nethsm::{
7 SystemState::{Locked, Operational, Unprovisioned},
8 UserRole::{Administrator, Backup},
9};
10
11use super::BIN_NAME;
12use crate::passphrase_file::PassphraseFile;
13
14#[derive(Debug, Subcommand)]
15#[command(about = "Do system actions for a device")]
16pub enum SystemCommand {
17 Backup(SystemBackupCommand),
18 FactoryReset(SystemFactoryResetCommand),
19 Info(SystemInfoCommand),
20 Reboot(SystemRebootCommand),
21 Restore(SystemRestoreCommand),
22 Shutdown(SystemShutdownCommand),
23 UploadUpdate(SystemUploadUpdateCommand),
24 CancelUpdate(SystemCancelUpdateCommand),
25 CommitUpdate(SystemCommitUpdateCommand),
26 ValidateBackup(SystemValidateBackupCommand),
27}
28
29#[derive(Debug, Parser)]
30#[command(
31 about = "Backup the key store of a device",
32 long_about = ex_format!("Backup the key store of a device
33
34Writes an encrypted backup to a file in the current working directory, named after the device label in the configuration file and the current time.
35Optionally, a specific output file can be provided.
36
37Note: Requires setting the backup passphrase using \"{BIN_NAME} config set backup-passphrase\" first!
38
39Requires authentication of a system-wide user in the \"{Backup}\" role.")
40)]
41pub struct SystemBackupCommand {
42 #[arg(
43 env = "NETHSM_FORCE",
44 help = "Write to output file even if it exists already",
45 long,
46 short
47 )]
48 pub force: bool,
49
50 #[arg(
51 env = "NETHSM_BACKUP_OUTPUT_FILE",
52 help = "The optional path to a specific output file",
53 long,
54 short
55 )]
56 pub output: Option<PathBuf>,
57}
58
59#[derive(Debug, Parser)]
60#[command(
61 about = "Reset the device to factory settings",
62 long_about = ex_format!("Reset the device to factory settings
63
64Triggers a factory reset for the device.
65
66**WARNING**: This action deletes all user and system data! Make sure to create a backup using \"{BIN_NAME} system backup\" first!
67
68Requires authentication of a system-wide user in the \"{Administrator}\" role.")
69)]
70pub struct SystemFactoryResetCommand {}
71
72#[derive(Debug, Parser)]
73#[command(
74 about = "Retrieve system information of a device",
75 long_about = ex_format!("Retrieve system information of a device
76
77Provides information on software version, software build, firmware version, hardware version, device ID and information related to TPM and PCR.
78
79Requires authentication of a system-wide user in the \"{Administrator}\" role.")
80)]
81pub struct SystemInfoCommand {}
82
83#[derive(Debug, Parser)]
84#[command(
85 about = "Reboot the device",
86 long_about = ex_format!("Reboot the device
87
88Requires authentication of a user in the \"{Administrator}\" role.")
89)]
90pub struct SystemRebootCommand {}
91
92#[derive(Debug, Parser)]
93#[command(
94 about = "Restore the device from a backup",
95 long_about = ex_format!("Restore the device from a backup
96
97The device may be in state \"{Operational}\" or \"{Unprovisioned}\".
98In both cases, the users and keys from the backup replace those on the device (if any).
99
100If the device is in state \"{Unprovisioned}\", any credentials provided for authentication are ignored, the system configuration
101(e.g. TLS certificate, unlock passphrase, etc.) from the backup is used as well, the device is rebooted and ends up in
102\"{Locked}\" state.
103
104If no new system time is provided, it is derived from the caller's system time.
105If no backup passphrase is provided specifically, it is prompted for interactively.
106
107Requires authentication of a system-wide user in the \"{Administrator}\" role only if the device is in \"{Operational}\" state.")
108)]
109pub struct SystemRestoreCommand {
110 #[arg(
111 env = "NETHSM_BACKUP_FILE",
112 help = "The path to a valid NetHSM backup file"
113 )]
114 pub input: PathBuf,
115
116 #[arg(
117 env = "NETHSM_BACKUP_PASSPHRASE_FILE",
118 help = "The path to a file containing the backup passphrase",
119 long,
120 short
121 )]
122 pub backup_passphrase_file: Option<PassphraseFile>,
123
124 #[arg(
125 env = "NETHSM_SYSTEM_TIME",
126 help = "The new system time for the device",
127 long_help = "The new system time for the device
128
129Must be provided as an ISO 8601 formatted UTC timestamp.",
130 long,
131 short
132 )]
133 pub system_time: Option<DateTime<Utc>>,
134}
135
136#[derive(Debug, Parser)]
137#[command(
138 about = "Shut down the device",
139 long_about = ex_format!("Shut down the device
140
141The device must be in state \"{Operational}\".
142
143Requires authentication of a system-wide user in the \"{Administrator}\" role.")
144)]
145pub struct SystemShutdownCommand {}
146
147#[derive(Debug, Parser)]
148#[command(
149 about = "Upload an update to the device",
150 long_about = ex_format!("Upload an update to the device
151
152Requires authentication of a user in the \"{Administrator}\" role.")
153)]
154pub struct SystemUploadUpdateCommand {
155 #[arg(env = "NETHSM_UPDATE_FILE", help = "The path to an update file")]
156 pub input: PathBuf,
157}
158
159#[derive(Debug, Parser)]
160#[command(
161 about = "Cancel an uploaded update on the device",
162 long_about = ex_format!("Cancel an uploaded update on the device
163
164The device must be in state \"{Operational}\" and an update file must have been uploaded first!
165
166Requires authentication of a system-wide user in the \"{Administrator}\" role.")
167)]
168pub struct SystemCancelUpdateCommand {}
169
170#[derive(Debug, Parser)]
171#[command(
172 about = "Commit an uploaded update on the device",
173 long_about = ex_format!("Commit an uploaded update on the device
174
175The device must be in state \"{Operational}\" and an update file must have been uploaded first!
176
177Requires authentication of a system-wide user in the \"{Administrator}\" role.")
178)]
179pub struct SystemCommitUpdateCommand {}
180
181#[derive(Debug, Parser)]
182#[command(
183 about = "Validate a backup file",
184 long_about = ex_format!("Validate a backup file
185
186Parse an encrypted backup file to ensure general properties.
187If a passphrase is provided, decrypting the backup file and validating its version number is attempted.
188This command exits with a non-zero exit code, if the file is corrupted, decryption or validation fails.
189
190Note: Backups are created using \"{BIN_NAME} system backup\"")
191)]
192pub struct SystemValidateBackupCommand {
193 #[arg(
194 env = "NETHSM_VALIDATE_BACKUP_PASSPHRASE_FILE",
195 help = "The path to a file containing the backup passphrase",
196 long,
197 short
198 )]
199 pub backup_passphrase_file: Option<PassphraseFile>,
200
201 #[arg(
202 env = "NETHSM_VALIDATE_BACKUP_FILE",
203 help = "The path to the backup file to validate"
204 )]
205 pub input: PathBuf,
206}