signstar_config/error.rs
1//! Common, top-level error type for all components of signstar-config.
2
3use std::{
4 path::PathBuf,
5 process::{ExitCode, ExitStatus},
6 string::FromUtf8Error,
7};
8
9/// An error that may occur when using Signstar config.
10#[derive(Debug, thiserror::Error)]
11pub enum Error {
12 /// An error specific to administrative secret handling.
13 #[error("Error with administrative secret handling:\n{0}")]
14 AdminSecretHandling(#[from] crate::admin_credentials::Error),
15
16 /// An error specific to Signstar config handling.
17 /// Applying permissions to a file or directory failed.
18 #[error("Unable to apply permissions from mode {mode} to {path}:\n{source}")]
19 ApplyPermissions {
20 /// The path to a file for which permissions can not be applied.
21 path: PathBuf,
22 /// The file mode that should be applied for `path`.
23 mode: u32,
24 /// The source error.
25 source: std::io::Error,
26 },
27
28 /// The ownership of a path can not be changed.
29 #[error("Changing ownership of {path} to user {user} failed:\n{source}")]
30 Chown {
31 /// The path to a file for which ownership can not be changed.
32 path: PathBuf,
33 /// The system user that should be the new owner of `path`.
34 user: String,
35 /// The source error.
36 source: std::io::Error,
37 },
38
39 /// Unable to attach to stdin of a command.
40 #[error("Unable to attach to stdin of command \"{command}\"")]
41 CommandAttachToStdin {
42 /// The command for which attaching to stdin failed.
43 command: String,
44 },
45
46 /// A command exited unsuccessfully.
47 #[error("The command \"{command}\" could not be started in the background:\n{source}")]
48 CommandBackground {
49 /// The command that could not be started in the background.
50 command: String,
51 /// The source error.
52 source: std::io::Error,
53 },
54
55 /// A command could not be executed.
56 #[error("The command \"{command}\" could not be executed:\n{source}")]
57 CommandExec {
58 /// The command that could not be executed.
59 command: String,
60 /// The source error.
61 source: std::io::Error,
62 },
63
64 /// A command exited unsuccessfully.
65 #[error(
66 "The command \"{command}\" exited with non-zero status code \"{exit_status}\":\nstderr:\n{stderr}"
67 )]
68 CommandNonZero {
69 /// The command that exited with a non-zero exit code.
70 command: String,
71 /// The exit status of `command`.
72 exit_status: ExitStatus,
73 /// The stderr of `command`.
74 stderr: String,
75 },
76
77 /// Unable to write to stdin of a command.
78 #[error("Unable to write to stdin of command \"{command}\"")]
79 CommandWriteToStdin {
80 /// The command for which writing to stdin failed.
81 command: String,
82 /// The source error.
83 source: std::io::Error,
84 },
85
86 /// Configuration errors.
87 #[error("Signstar config error:\n{0}")]
88 Config(#[from] crate::config::Error),
89
90 /// A NetHSM error.
91 #[error("NetHSM error:\n{0}")]
92 NetHsm(#[from] nethsm::Error),
93
94 /// A NetHSM backend error
95 ///
96 /// This variant is used when actions for a NetHSM backend fail.
97 #[error("NetHSM backend error:\n{0}")]
98 NetHsmBackend(#[from] crate::NetHsmBackendError),
99
100 /// An error specific to non-administrative secret handling.
101 #[error("Error with non-administrative secret handling:\n{0}")]
102 NonAdminSecretHandling(#[from] crate::non_admin_credentials::Error),
103
104 /// Low-level administrative credentials handling in signstar-common failed.
105 #[error("Handling of administrative credentials failed:\n{0}")]
106 SignstarCommonAdminCreds(#[from] signstar_common::admin_credentials::Error),
107
108 /// Joining a thread returned an error.
109 #[error("Thread error while {context}")]
110 Thread {
111 /// The context in which the failed thread ran.
112 ///
113 /// Should complete the sentence "Thread error while ".
114 context: String,
115 },
116
117 /// A UTF-8 error occurred when trying to convert a byte vector to a string.
118 #[error("Converting contents of {path} to string failed while {context}:\n{source}")]
119 Utf8String {
120 /// The path to a file for which conversion to UTF-8 string failed.
121 path: PathBuf,
122 /// The context in which the error occurred.
123 ///
124 /// Should complete the sentence "Converting contents of `path` to string failed while "
125 context: String,
126 /// The source error.
127 source: FromUtf8Error,
128 },
129
130 /// A utility function returned an error.
131 #[error("Utility function error: {0}")]
132 Utils(#[from] crate::utils::Error),
133}
134
135/// Mapping for relevant [`Error`] variants to an [`ExitCode`].
136#[derive(Clone, Copy, Debug, Eq, num_enum::IntoPrimitive, Ord, PartialEq, PartialOrd)]
137#[repr(u8)]
138pub enum ErrorExitCode {
139 /// Mapping for [`crate::admin_credentials::Error::AdministratorMissing`] wrapped in
140 /// [`Error::AdminSecretHandling`].
141 AdminCredentialsAdministratorMissing = 100,
142
143 /// Mapping for [`crate::admin_credentials::Error::AdministratorNoDefault`] wrapped in
144 /// [`Error::AdminSecretHandling`].
145 AdminCredentialsAdministratorNoDefault = 101,
146
147 /// Mapping for [`crate::admin_credentials::Error::ConfigFromToml`] wrapped in
148 /// [`Error::AdminSecretHandling`].
149 AdminCredentialsConfigFromToml = 102,
150
151 /// Mapping for [`crate::admin_credentials::Error::ConfigLoad`] wrapped in
152 /// [`Error::AdminSecretHandling`].
153 AdminCredentialsConfigLoad = 103,
154
155 /// Mapping for [`crate::admin_credentials::Error::ConfigStore`] wrapped in
156 /// [`Error::AdminSecretHandling`].
157 AdminCredentialsConfigStore = 104,
158
159 /// Mapping for [`crate::admin_credentials::Error::ConfigToToml`] wrapped in
160 /// [`Error::AdminSecretHandling`].
161 AdminCredentialsConfigToToml = 105,
162
163 /// Mapping for [`crate::admin_credentials::Error::CredsFileCreate`] wrapped in
164 /// [`Error::AdminSecretHandling`].
165 AdminCredentialsCredsFileCreate = 106,
166
167 /// Mapping for [`crate::admin_credentials::Error::CredsFileMissing`] wrapped in
168 /// [`Error::AdminSecretHandling`].
169 AdminCredentialsCredsFileMissing = 107,
170
171 /// Mapping for [`crate::admin_credentials::Error::CredsFileNotAFile`] wrapped in
172 /// [`Error::AdminSecretHandling`].
173 AdminCredentialsCredsFileNotAFile = 108,
174
175 /// Mapping for [`crate::admin_credentials::Error::CredsFileWrite`] wrapped in
176 /// [`Error::AdminSecretHandling`].
177 AdminCredentialsCredsFileWrite = 109,
178
179 /// Mapping for [`crate::admin_credentials::Error::PassphraseTooShort`] wrapped in
180 /// [`Error::AdminSecretHandling`].
181 AdminCredentialsPassphraseTooShort = 110,
182
183 /// Mapping for [`Error::ApplyPermissions`].
184 ApplyPermissions = 10,
185
186 /// Mapping for [`Error::Chown`].
187 Chown = 11,
188
189 /// Mapping for [`Error::CommandAttachToStdin`].
190 CommandAttachToStdin = 12,
191
192 /// Mapping for [`Error::CommandBackground`].
193 CommandBackground = 13,
194
195 /// Mapping for [`Error::CommandExec`].
196 CommandExec = 14,
197
198 /// Mapping for [`Error::CommandNonZero`].
199 CommandNonZero = 15,
200
201 /// Mapping for [`Error::CommandWriteToStdin`].
202 CommandWriteToStdin = 16,
203
204 /// Mapping for [`crate::config::Error::ConfigMissing`] wrapped in [`Error::Config`].
205 ConfigConfigMissing = 120,
206
207 /// Mapping for [`crate::config::Error::NetHsmConfig`] wrapped in [`Error::Config`].
208 ConfigNetHsmConfig = 121,
209
210 /// Mapping for [`crate::Error::NetHsm`].
211 NetHsm = 17,
212
213 /// Mapping for [`crate::Error::NetHsmBackend`].
214 NetHsmBackend = 18,
215
216 /// Mapping for [`crate::non_admin_credentials::Error::CredentialsLoading`] wrapped in
217 /// [`Error::NonAdminSecretHandling`].
218 NonAdminCredentialsCredentialsLoading = 140,
219
220 /// Mapping for [`crate::non_admin_credentials::Error::CredentialsMissing`] wrapped in
221 /// [`Error::NonAdminSecretHandling`].
222 NonAdminCredentialsCredentialsMissing = 141,
223
224 /// Mapping for [`crate::non_admin_credentials::Error::NoSystemUser`] wrapped in
225 /// [`Error::NonAdminSecretHandling`].
226 NonAdminCredentialsNoSystemUser = 142,
227
228 /// Mapping for [`crate::non_admin_credentials::Error::NotSigningUser`] wrapped in
229 /// [`Error::NonAdminSecretHandling`].
230 NonAdminCredentialsNotSigningUser = 143,
231
232 /// Mapping for [`crate::non_admin_credentials::Error::SecretsDirCreate`] wrapped in
233 /// [`Error::NonAdminSecretHandling`].
234 NonAdminCredentialsSecretsDirCreate = 144,
235
236 /// Mapping for [`crate::non_admin_credentials::Error::SecretsFileCreate`] wrapped in
237 /// [`Error::NonAdminSecretHandling`].
238 NonAdminCredentialsSecretsFileCreate = 145,
239
240 /// Mapping for [`crate::non_admin_credentials::Error::SecretsFileMetadata`] wrapped in
241 /// [`Error::NonAdminSecretHandling`].
242 NonAdminCredentialsSecretsFileMetadata = 146,
243
244 /// Mapping for [`crate::non_admin_credentials::Error::SecretsFileMissing`] wrapped in
245 /// [`Error::NonAdminSecretHandling`].
246 NonAdminCredentialsSecretsFileMissing = 147,
247
248 /// Mapping for [`crate::non_admin_credentials::Error::SecretsFileNotAFile`] wrapped in
249 /// [`Error::NonAdminSecretHandling`].
250 NonAdminCredentialsSecretsFileNotAFile = 148,
251
252 /// Mapping for [`crate::non_admin_credentials::Error::SecretsFilePermissions`] wrapped in
253 /// [`Error::NonAdminSecretHandling`].
254 NonAdminCredentialsSecretsFilePermissions = 149,
255
256 /// Mapping for [`crate::non_admin_credentials::Error::SecretsFileRead`] wrapped in
257 /// [`Error::NonAdminSecretHandling`].
258 NonAdminCredentialsSecretsFileRead = 150,
259
260 /// Mapping for [`crate::non_admin_credentials::Error::SecretsFileWrite`] wrapped in
261 /// [`Error::NonAdminSecretHandling`].
262 NonAdminCredentialsSecretsFileWrite = 151,
263
264 /// Mapping for [`signstar_common::admin_credentials::Error::ApplyPermissions`] wrapped in
265 /// [`Error::SignstarCommonAdminCreds`].
266 SignstarCommonAdminCredsApplyPermissions = 170,
267
268 /// Mapping for [`signstar_common::admin_credentials::Error::CreateDirectory`] wrapped in
269 /// [`Error::SignstarCommonAdminCreds`].
270 SignstarCommonAdminCredsCreateDirectory = 171,
271
272 /// Mapping for [`signstar_common::admin_credentials::Error::DirChangeOwner`] wrapped in
273 /// [`Error::SignstarCommonAdminCreds`].
274 SignstarCommonAdminCredsDirChangeOwner = 172,
275
276 /// Mapping for [`Error::Thread`].
277 Thread = 19,
278
279 /// Mapping for [`Error::Utf8String`].
280 Utf8String = 20,
281
282 /// Mapping for [`crate::utils::Error::ExecutableNotFound`] wrapped in [`Error::Utils`].
283 UtilsExecutableNotFound = 190,
284
285 /// Mapping for [`crate::utils::Error::MappingSystemUserGet`] wrapped in [`Error::Utils`].
286 UtilsMappingSystemUserGet = 191,
287
288 /// Mapping for [`crate::utils::Error::SystemUserData`] wrapped in [`Error::Utils`].
289 UtilsSystemUserData = 192,
290
291 /// Mapping for [`crate::utils::Error::SystemUserLookup`] wrapped in [`Error::Utils`].
292 UtilsSystemUserLookup = 193,
293
294 /// Mapping for [`crate::utils::Error::SystemUserMismatch`] wrapped in [`Error::Utils`].
295 UtilsSystemUserMismatch = 194,
296
297 /// Mapping for [`crate::utils::Error::SystemUserNotRoot`] wrapped in [`Error::Utils`].
298 UtilsSystemUserNotRoot = 195,
299
300 /// Mapping for [`crate::utils::Error::SystemUserRoot`] wrapped in [`Error::Utils`].
301 UtilsSystemUserRoot = 196,
302}
303
304impl From<Error> for ErrorExitCode {
305 fn from(value: Error) -> Self {
306 match value {
307 // admin credentials related errors and their exit codes
308 Error::AdminSecretHandling(error) => match error {
309 crate::admin_credentials::Error::AdministratorMissing => {
310 Self::AdminCredentialsAdministratorMissing
311 }
312 crate::admin_credentials::Error::AdministratorNoDefault => {
313 Self::AdminCredentialsAdministratorNoDefault
314 }
315 crate::admin_credentials::Error::ConfigFromToml { .. } => {
316 Self::AdminCredentialsConfigFromToml
317 }
318 crate::admin_credentials::Error::ConfigLoad { .. } => {
319 Self::AdminCredentialsConfigLoad
320 }
321 crate::admin_credentials::Error::ConfigStore { .. } => {
322 Self::AdminCredentialsConfigStore
323 }
324 crate::admin_credentials::Error::ConfigToToml(_) => {
325 Self::AdminCredentialsConfigToToml
326 }
327 crate::admin_credentials::Error::CredsFileCreate { .. } => {
328 Self::AdminCredentialsCredsFileCreate
329 }
330 crate::admin_credentials::Error::CredsFileMissing { .. } => {
331 Self::AdminCredentialsCredsFileMissing
332 }
333 crate::admin_credentials::Error::CredsFileNotAFile { .. } => {
334 Self::AdminCredentialsCredsFileNotAFile
335 }
336 crate::admin_credentials::Error::CredsFileWrite { .. } => {
337 Self::AdminCredentialsCredsFileWrite
338 }
339 crate::admin_credentials::Error::PassphraseTooShort { .. } => {
340 Self::AdminCredentialsPassphraseTooShort
341 }
342 },
343 // config related errors
344 Error::Config(error) => match error {
345 crate::config::Error::ConfigMissing => Self::ConfigConfigMissing,
346 crate::config::Error::NetHsmConfig(_) => Self::ConfigNetHsmConfig,
347 },
348 // NetHSM related errors
349 Error::NetHsm(_) => Self::NetHsm,
350 // NetHSM backend related errors
351 Error::NetHsmBackend(_) => Self::NetHsmBackend,
352 // non-admin credentials related errors and their exit codes
353 Error::NonAdminSecretHandling(error) => match error {
354 crate::non_admin_credentials::Error::CredentialsLoading { .. } => {
355 Self::NonAdminCredentialsCredentialsLoading
356 }
357 crate::non_admin_credentials::Error::CredentialsMissing { .. } => {
358 Self::NonAdminCredentialsCredentialsMissing
359 }
360 crate::non_admin_credentials::Error::NoSystemUser => {
361 Self::NonAdminCredentialsNoSystemUser
362 }
363 crate::non_admin_credentials::Error::NotSigningUser => {
364 Self::NonAdminCredentialsNotSigningUser
365 }
366 crate::non_admin_credentials::Error::SecretsDirCreate { .. } => {
367 Self::NonAdminCredentialsSecretsDirCreate
368 }
369 crate::non_admin_credentials::Error::SecretsFileCreate { .. } => {
370 Self::NonAdminCredentialsSecretsFileCreate
371 }
372 crate::non_admin_credentials::Error::SecretsFileMetadata { .. } => {
373 Self::NonAdminCredentialsSecretsFileMetadata
374 }
375 crate::non_admin_credentials::Error::SecretsFileMissing { .. } => {
376 Self::NonAdminCredentialsSecretsFileMissing
377 }
378 crate::non_admin_credentials::Error::SecretsFileNotAFile { .. } => {
379 Self::NonAdminCredentialsSecretsFileNotAFile
380 }
381 crate::non_admin_credentials::Error::SecretsFilePermissions { .. } => {
382 Self::NonAdminCredentialsSecretsFilePermissions
383 }
384 crate::non_admin_credentials::Error::SecretsFileRead { .. } => {
385 Self::NonAdminCredentialsSecretsFileRead
386 }
387 crate::non_admin_credentials::Error::SecretsFileWrite { .. } => {
388 Self::NonAdminCredentialsSecretsFileWrite
389 }
390 },
391 // signstar-common admin credentials related errors
392 Error::SignstarCommonAdminCreds(error) => match error {
393 signstar_common::admin_credentials::Error::ApplyPermissions { .. } => {
394 Self::SignstarCommonAdminCredsApplyPermissions
395 }
396 signstar_common::admin_credentials::Error::CreateDirectory { .. } => {
397 Self::SignstarCommonAdminCredsCreateDirectory
398 }
399 signstar_common::admin_credentials::Error::DirChangeOwner { .. } => {
400 Self::SignstarCommonAdminCredsDirChangeOwner
401 }
402 },
403 // utils related errors
404 Error::Utils(error) => match error {
405 crate::utils::Error::ExecutableNotFound { .. } => Self::UtilsExecutableNotFound,
406 crate::utils::Error::MappingSystemUserGet(_) => Self::UtilsMappingSystemUserGet,
407 crate::utils::Error::SystemUserData { .. } => Self::UtilsSystemUserData,
408 crate::utils::Error::SystemUserLookup { .. } => Self::UtilsSystemUserLookup,
409 crate::utils::Error::SystemUserMismatch { .. } => Self::UtilsSystemUserMismatch,
410 crate::utils::Error::SystemUserNotRoot { .. } => Self::UtilsSystemUserNotRoot,
411 crate::utils::Error::SystemUserRoot => Self::UtilsSystemUserRoot,
412 },
413 // top-level errors and their exit codes
414 Error::ApplyPermissions { .. } => Self::ApplyPermissions,
415 Error::CommandAttachToStdin { .. } => Self::CommandAttachToStdin,
416 Error::Chown { .. } => Self::Chown,
417 Error::CommandBackground { .. } => Self::CommandBackground,
418 Error::CommandExec { .. } => Self::CommandExec,
419 Error::CommandNonZero { .. } => Self::CommandNonZero,
420 Error::Thread { .. } => Self::Thread,
421 Error::Utf8String { .. } => Self::Utf8String,
422 Error::CommandWriteToStdin { .. } => Self::CommandWriteToStdin,
423 }
424 }
425}
426
427impl From<ErrorExitCode> for ExitCode {
428 fn from(value: ErrorExitCode) -> Self {
429 Self::from(std::convert::Into::<u8>::into(value))
430 }
431}
432
433impl From<ErrorExitCode> for i32 {
434 fn from(value: ErrorExitCode) -> Self {
435 Self::from(std::convert::Into::<u8>::into(value))
436 }
437}