1use std::{
4 path::PathBuf,
5 process::{ExitCode, ExitStatus},
6 string::FromUtf8Error,
7};
8
9#[derive(Debug, thiserror::Error)]
11pub enum Error {
12 #[error("Error with administrative secret handling:\n{0}")]
14 AdminSecretHandling(#[from] crate::admin_credentials::Error),
15
16 #[error("Unable to apply permissions from mode {mode} to {path}:\n{source}")]
19 ApplyPermissions {
20 path: PathBuf,
22 mode: u32,
24 source: std::io::Error,
26 },
27
28 #[error("Changing ownership of {path} to user {user} failed:\n{source}")]
30 Chown {
31 path: PathBuf,
33 user: String,
35 source: std::io::Error,
37 },
38
39 #[error("Unable to attach to stdin of command \"{command}\"")]
41 CommandAttachToStdin {
42 command: String,
44 },
45
46 #[error("The command \"{command}\" could not be started in the background:\n{source}")]
48 CommandBackground {
49 command: String,
51 source: std::io::Error,
53 },
54
55 #[error("The command \"{command}\" could not be executed:\n{source}")]
57 CommandExec {
58 command: String,
60 source: std::io::Error,
62 },
63
64 #[error(
66 "The command \"{command}\" exited with non-zero status code \"{exit_status}\":\nstderr:\n{stderr}"
67 )]
68 CommandNonZero {
69 command: String,
71 exit_status: ExitStatus,
73 stderr: String,
75 },
76
77 #[error("Unable to write to stdin of command \"{command}\"")]
79 CommandWriteToStdin {
80 command: String,
82 source: std::io::Error,
84 },
85
86 #[error("Signstar config error:\n{0}")]
88 Config(#[from] crate::ConfigError),
89
90 #[error("I/O error for file {path} while {context}: {source}")]
92 IoPath {
93 path: PathBuf,
95 context: &'static str,
99 source: std::io::Error,
101 },
102
103 #[cfg(feature = "nethsm")]
105 #[error("NetHSM error:\n{0}")]
106 NetHsm(#[from] nethsm::Error),
107
108 #[cfg(feature = "nethsm")]
112 #[error("NetHSM backend error:\n{0}")]
113 NetHsmBackend(#[from] crate::NetHsmBackendError),
114
115 #[error("Handling of administrative credentials failed:\n{0}")]
117 SignstarCommonAdminCreds(#[from] signstar_common::admin_credentials::Error),
118
119 #[error(transparent)]
121 SignstarCrypto(#[from] signstar_crypto::Error),
122
123 #[error("Thread error while {context}")]
125 Thread {
126 context: String,
130 },
131
132 #[error("TOML read error for file {path} while {context}: {source}")]
134 TomlRead {
135 path: PathBuf,
137 context: &'static str,
141 source: Box<toml::de::Error>,
143 },
144
145 #[error("TOML write error for file {path} while {context}: {source}")]
147 TomlWrite {
148 path: PathBuf,
150 context: &'static str,
154 source: toml::ser::Error,
156 },
157
158 #[error(transparent)]
160 Traits(#[from] crate::config::TraitsError),
161
162 #[error("Converting contents of {path} to string failed while {context}:\n{source}")]
164 Utf8String {
165 path: PathBuf,
167 context: String,
171 source: FromUtf8Error,
173 },
174
175 #[error("Utility function error: {0}")]
177 Utils(#[from] crate::utils::Error),
178
179 #[error("Validation error while {context}: {source}")]
181 Validation {
182 context: String,
186
187 source: garde::Report,
189 },
190
191 #[cfg(feature = "nethsm")]
193 #[error("NetHSM configuration object error: {0}")]
194 NetHsmConfig(#[from] crate::nethsm::NetHsmConfigError),
195
196 #[cfg(feature = "yubihsm2")]
198 #[error("YubiHSM2 configuration object error: {0}")]
199 YubiHsm2Config(#[from] crate::yubihsm2::YubiHSM2ConfigError),
200}
201
202#[derive(Clone, Copy, Debug, Eq, num_enum::IntoPrimitive, Ord, PartialEq, PartialOrd)]
204#[repr(u8)]
205pub enum ErrorExitCode {
206 AdminCredentialsAdministratorMissing = 100,
209
210 AdminCredentialsAdministratorNoDefault = 101,
213
214 AdminCredentialsCredsFileCreate = 102,
217
218 AdminCredentialsCredsFileMissing = 103,
221
222 AdminCredentialsCredsFileNotAFile = 104,
225
226 AdminCredentialsCredsFileWrite = 105,
229
230 AdminCredentialsPassphraseTooShort = 106,
233
234 ApplyPermissions = 10,
236
237 Chown = 11,
239
240 CommandAttachToStdin = 12,
242
243 CommandBackground = 13,
245
246 CommandExec = 14,
248
249 CommandNonZero = 15,
251
252 CommandWriteToStdin = 16,
254
255 ConfigConfigMissing = 120,
257
258 ConfigMissingFileExtension = 180,
260
261 ConfigUnsupportedFileExtension = 181,
263
264 #[cfg(feature = "nethsm")]
267 ConfigDuplicateNetHsmUserId = 121,
268
269 ConfigDuplicateSshPublicKey = 122,
272
273 #[cfg(feature = "nethsm")]
275 ConfigDuplicateKeyId = 123,
276
277 ConfigDuplicateSystemUserId = 124,
280
281 #[cfg(feature = "nethsm")]
283 ConfigDuplicateTag = 125,
284
285 ConfigInvalidSystemUserName = 126,
288
289 ConfigInvalidAuthorizedKeyEntry = 127,
292
293 #[cfg(feature = "nethsm")]
296 ConfigMetricsAlsoOperator = 128,
297
298 #[cfg(feature = "nethsm")]
301 ConfigMissingAdministrator = 129,
302
303 ConfigMissingShareDownloadSystemUser = 130,
306
307 ConfigMissingShareUploadSystemUser = 131,
310
311 ConfigNoAuthorizedKeys = 132,
313
314 ConfigNoMatchingMappingForSystemUser = 133,
317
318 ConfigNoSssButShareUsers = 134,
320
321 ConfigSshKey = 135,
323
324 #[cfg(feature = "nethsm")]
326 ConfigUser = 136,
327
328 ConfigYamlDeserialize = 137,
330
331 ConfigYamlSerialize = 138,
333
334 IoPath = 17,
336
337 #[cfg(feature = "nethsm")]
339 NetHsm = 18,
340
341 #[cfg(feature = "nethsm")]
343 NetHsmBackend = 19,
344
345 SignstarCommonAdminCredsApplyPermissions = 170,
348
349 SignstarCommonAdminCredsCreateDirectory = 171,
352
353 SignstarCommonAdminCredsDirChangeOwner = 172,
356
357 SignstarCrypto = 20,
359
360 Thread = 21,
362
363 TomlRead = 22,
365
366 TomlWrite = 23,
368
369 Traits = 40,
371
372 Utf8String = 24,
374
375 Validation = 25,
377
378 #[cfg(feature = "nethsm")]
380 NetHsmConfig = 26,
381
382 #[cfg(feature = "yubihsm2")]
384 YubiHsm2Config = 27,
385
386 UtilsExecutableNotFound = 190,
388
389 UtilsSystemUserData = 192,
391
392 UtilsSystemUserLookup = 193,
394
395 UtilsSystemUserMismatch = 194,
397
398 UtilsSystemUserNotRoot = 195,
400}
401
402impl From<Error> for ErrorExitCode {
403 fn from(value: Error) -> Self {
404 match value {
405 Error::AdminSecretHandling(error) => match error {
407 crate::admin_credentials::Error::AdministratorMissing => {
408 Self::AdminCredentialsAdministratorMissing
409 }
410 crate::admin_credentials::Error::AdministratorNoDefault => {
411 Self::AdminCredentialsAdministratorNoDefault
412 }
413 crate::admin_credentials::Error::CredsFileCreate { .. } => {
414 Self::AdminCredentialsCredsFileCreate
415 }
416 crate::admin_credentials::Error::CredsFileMissing { .. } => {
417 Self::AdminCredentialsCredsFileMissing
418 }
419 crate::admin_credentials::Error::CredsFileNotAFile { .. } => {
420 Self::AdminCredentialsCredsFileNotAFile
421 }
422 crate::admin_credentials::Error::CredsFileWrite { .. } => {
423 Self::AdminCredentialsCredsFileWrite
424 }
425 crate::admin_credentials::Error::PassphraseTooShort { .. } => {
426 Self::AdminCredentialsPassphraseTooShort
427 }
428 },
429 Error::Config(error) => match error {
431 crate::ConfigError::ConfigIsMissing => Self::ConfigConfigMissing,
432 crate::ConfigError::MissingFileExtension { .. } => Self::ConfigMissingFileExtension,
433 crate::ConfigError::UnsupportedFileExtension { .. } => {
434 Self::ConfigUnsupportedFileExtension
435 }
436 #[cfg(feature = "nethsm")]
437 crate::ConfigError::DuplicateNetHsmUserId { .. } => {
438 Self::ConfigDuplicateNetHsmUserId
439 }
440 crate::ConfigError::DuplicateSshPublicKey { .. } => {
441 Self::ConfigDuplicateSshPublicKey
442 }
443 #[cfg(feature = "nethsm")]
444 crate::ConfigError::DuplicateKeyId { .. } => Self::ConfigDuplicateKeyId,
445 crate::ConfigError::DuplicateSystemUserId { .. } => {
446 Self::ConfigDuplicateSystemUserId
447 }
448 #[cfg(feature = "nethsm")]
449 crate::ConfigError::DuplicateTag { .. } => Self::ConfigDuplicateTag,
450 crate::ConfigError::InvalidSystemUserName { .. } => {
451 Self::ConfigInvalidSystemUserName
452 }
453 crate::ConfigError::InvalidAuthorizedKeyEntry { .. } => {
454 Self::ConfigInvalidAuthorizedKeyEntry
455 }
456 #[cfg(feature = "nethsm")]
457 crate::ConfigError::MetricsAlsoOperator { .. } => Self::ConfigMetricsAlsoOperator,
458 #[cfg(feature = "nethsm")]
459 crate::ConfigError::MissingAdministrator { .. } => Self::ConfigMissingAdministrator,
460 crate::ConfigError::MissingShareDownloadSystemUser => {
461 Self::ConfigMissingShareDownloadSystemUser
462 }
463 crate::ConfigError::MissingShareUploadSystemUser => {
464 Self::ConfigMissingShareUploadSystemUser
465 }
466 crate::ConfigError::NoAuthorizedKeys => Self::ConfigNoAuthorizedKeys,
467 crate::ConfigError::NoMatchingMappingForSystemUser { .. } => {
468 Self::ConfigNoMatchingMappingForSystemUser
469 }
470 crate::ConfigError::NoSssButShareUsers { .. } => Self::ConfigNoSssButShareUsers,
471 crate::ConfigError::SshKey(_) => Self::ConfigSshKey,
472 #[cfg(feature = "nethsm")]
473 crate::ConfigError::User(_) => Self::ConfigUser,
474 crate::ConfigError::YamlDeserialize { .. } => Self::ConfigYamlDeserialize,
475 crate::ConfigError::YamlSerialize { .. } => Self::ConfigYamlSerialize,
476 },
477 #[cfg(feature = "nethsm")]
479 Error::NetHsm(_) => Self::NetHsm,
480 #[cfg(feature = "nethsm")]
482 Error::NetHsmBackend(_) => Self::NetHsmBackend,
483 Error::SignstarCommonAdminCreds(error) => match error {
485 signstar_common::admin_credentials::Error::ApplyPermissions { .. } => {
486 Self::SignstarCommonAdminCredsApplyPermissions
487 }
488 signstar_common::admin_credentials::Error::CreateDirectory { .. } => {
489 Self::SignstarCommonAdminCredsCreateDirectory
490 }
491 signstar_common::admin_credentials::Error::DirChangeOwner { .. } => {
492 Self::SignstarCommonAdminCredsDirChangeOwner
493 }
494 },
495 Error::Utils(error) => match error {
497 crate::utils::Error::ExecutableNotFound { .. } => Self::UtilsExecutableNotFound,
498 crate::utils::Error::SystemUserData { .. } => Self::UtilsSystemUserData,
499 crate::utils::Error::SystemUserLookup { .. } => Self::UtilsSystemUserLookup,
500 crate::utils::Error::SystemUserMismatch { .. } => Self::UtilsSystemUserMismatch,
501 crate::utils::Error::SystemUserNotRoot { .. } => Self::UtilsSystemUserNotRoot,
502 },
503 Error::ApplyPermissions { .. } => Self::ApplyPermissions,
505 Error::CommandAttachToStdin { .. } => Self::CommandAttachToStdin,
506 Error::Chown { .. } => Self::Chown,
507 Error::CommandBackground { .. } => Self::CommandBackground,
508 Error::CommandExec { .. } => Self::CommandExec,
509 Error::CommandNonZero { .. } => Self::CommandNonZero,
510 Error::CommandWriteToStdin { .. } => Self::CommandWriteToStdin,
511 Error::IoPath { .. } => Self::IoPath,
512 Error::SignstarCrypto { .. } => Self::SignstarCrypto,
513 Error::Thread { .. } => Self::Thread,
514 Error::TomlRead { .. } => Self::TomlRead,
515 Error::TomlWrite { .. } => Self::TomlWrite,
516 Error::Traits { .. } => Self::Traits,
517 Error::Utf8String { .. } => Self::Utf8String,
518 Error::Validation { .. } => Self::Validation,
519 #[cfg(feature = "nethsm")]
520 Error::NetHsmConfig { .. } => Self::NetHsmConfig,
521 #[cfg(feature = "yubihsm2")]
522 Error::YubiHsm2Config { .. } => Self::YubiHsm2Config,
523 }
524 }
525}
526
527impl From<ErrorExitCode> for ExitCode {
528 fn from(value: ErrorExitCode) -> Self {
529 Self::from(std::convert::Into::<u8>::into(value))
530 }
531}
532
533impl From<ErrorExitCode> for i32 {
534 fn from(value: ErrorExitCode) -> Self {
535 Self::from(std::convert::Into::<u8>::into(value))
536 }
537}