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