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 /// An error specific to non-administrative secret handling.
91 #[error("Error with non-administrative secret handling:\n{0}")]
92 NonAdminSecretHandling(#[from] crate::non_admin_credentials::Error),
93
94 /// Low-level administrative credentials handling in signstar-common failed.
95 #[error("Handling of administrative credentials failed:\n{0}")]
96 SignstarCommonAdminCreds(#[from] signstar_common::admin_credentials::Error),
97
98 /// Joining a thread returned an error.
99 #[error("Thread error while {context}")]
100 Thread {
101 /// The context in which the failed thread ran.
102 ///
103 /// Should complete the sentence "Thread error while ".
104 context: String,
105 },
106
107 /// A UTF-8 error occurred when trying to convert a byte vector to a string.
108 #[error("Converting contents of {path} to string failed while {context}:\n{source}")]
109 Utf8String {
110 /// The path to a file for which conversion to UTF-8 string failed.
111 path: PathBuf,
112 /// The context in which the error occurred.
113 ///
114 /// Should complete the sentence "Converting contents of `path` to string failed while "
115 context: String,
116 /// The source error.
117 source: FromUtf8Error,
118 },
119
120 /// A utility function returned an error.
121 #[error("Utility function error: {0}")]
122 Utils(#[from] crate::utils::Error),
123}
124
125/// Mapping for relevant [`Error`] variants to an [`ExitCode`].
126#[derive(Clone, Copy, Debug, num_enum::IntoPrimitive, Eq, Ord, PartialEq, PartialOrd)]
127#[repr(u8)]
128pub enum ErrorExitCode {
129 /// Mapping for [`crate::admin_credentials::Error::AdministratorMissing`] wrapped in
130 /// [`Error::AdminSecretHandling`].
131 AdminCredentialsAdministratorMissing = 100,
132
133 /// Mapping for [`crate::admin_credentials::Error::AdministratorNoDefault`] wrapped in
134 /// [`Error::AdminSecretHandling`].
135 AdminCredentialsAdministratorNoDefault = 101,
136
137 /// Mapping for [`crate::admin_credentials::Error::ConfigFromToml`] wrapped in
138 /// [`Error::AdminSecretHandling`].
139 AdminCredentialsConfigFromToml = 102,
140
141 /// Mapping for [`crate::admin_credentials::Error::ConfigLoad`] wrapped in
142 /// [`Error::AdminSecretHandling`].
143 AdminCredentialsConfigLoad = 103,
144
145 /// Mapping for [`crate::admin_credentials::Error::ConfigStore`] wrapped in
146 /// [`Error::AdminSecretHandling`].
147 AdminCredentialsConfigStore = 104,
148
149 /// Mapping for [`crate::admin_credentials::Error::ConfigToToml`] wrapped in
150 /// [`Error::AdminSecretHandling`].
151 AdminCredentialsConfigToToml = 105,
152
153 /// Mapping for [`crate::admin_credentials::Error::CredsFileCreate`] wrapped in
154 /// [`Error::AdminSecretHandling`].
155 AdminCredentialsCredsFileCreate = 106,
156
157 /// Mapping for [`crate::admin_credentials::Error::CredsFileMissing`] wrapped in
158 /// [`Error::AdminSecretHandling`].
159 AdminCredentialsCredsFileMissing = 107,
160
161 /// Mapping for [`crate::admin_credentials::Error::CredsFileNotAFile`] wrapped in
162 /// [`Error::AdminSecretHandling`].
163 AdminCredentialsCredsFileNotAFile = 108,
164
165 /// Mapping for [`crate::admin_credentials::Error::CredsFileWrite`] wrapped in
166 /// [`Error::AdminSecretHandling`].
167 AdminCredentialsCredsFileWrite = 109,
168
169 /// Mapping for [`crate::admin_credentials::Error::PassphraseTooShort`] wrapped in
170 /// [`Error::AdminSecretHandling`].
171 AdminCredentialsPassphraseTooShort = 110,
172
173 /// Mapping for [`Error::ApplyPermissions`].
174 ApplyPermissions = 10,
175
176 /// Mapping for [`Error::Chown`].
177 Chown = 11,
178
179 /// Mapping for [`Error::CommandAttachToStdin`].
180 CommandAttachToStdin = 12,
181
182 /// Mapping for [`Error::CommandBackground`].
183 CommandBackground = 13,
184
185 /// Mapping for [`Error::CommandExec`].
186 CommandExec = 14,
187
188 /// Mapping for [`Error::CommandNonZero`].
189 CommandNonZero = 15,
190
191 /// Mapping for [`Error::CommandWriteToStdin`].
192 CommandWriteToStdin = 16,
193
194 /// Mapping for [`crate::config::Error::ConfigMissing`] wrapped in [`Error::Config`].
195 ConfigConfigMissing = 120,
196
197 /// Mapping for [`crate::config::Error::NetHsmConfig`] wrapped in [`Error::Config`].
198 ConfigNetHsmConfig = 121,
199
200 /// Mapping for [`crate::non_admin_credentials::Error::CredentialsLoading`] wrapped in
201 /// [`Error::NonAdminSecretHandling`].
202 NonAdminCredentialsCredentialsLoading = 140,
203
204 /// Mapping for [`crate::non_admin_credentials::Error::CredentialsMissing`] wrapped in
205 /// [`Error::NonAdminSecretHandling`].
206 NonAdminCredentialsCredentialsMissing = 141,
207
208 /// Mapping for [`crate::non_admin_credentials::Error::NoSystemUser`] wrapped in
209 /// [`Error::NonAdminSecretHandling`].
210 NonAdminCredentialsNoSystemUser = 142,
211
212 /// Mapping for [`crate::non_admin_credentials::Error::NotSigningUser`] wrapped in
213 /// [`Error::NonAdminSecretHandling`].
214 NonAdminCredentialsNotSigningUser = 143,
215
216 /// Mapping for [`crate::non_admin_credentials::Error::SecretsDirCreate`] wrapped in
217 /// [`Error::NonAdminSecretHandling`].
218 NonAdminCredentialsSecretsDirCreate = 144,
219
220 /// Mapping for [`crate::non_admin_credentials::Error::SecretsFileCreate`] wrapped in
221 /// [`Error::NonAdminSecretHandling`].
222 NonAdminCredentialsSecretsFileCreate = 145,
223
224 /// Mapping for [`crate::non_admin_credentials::Error::SecretsFileMetadata`] wrapped in
225 /// [`Error::NonAdminSecretHandling`].
226 NonAdminCredentialsSecretsFileMetadata = 146,
227
228 /// Mapping for [`crate::non_admin_credentials::Error::SecretsFileMissing`] wrapped in
229 /// [`Error::NonAdminSecretHandling`].
230 NonAdminCredentialsSecretsFileMissing = 147,
231
232 /// Mapping for [`crate::non_admin_credentials::Error::SecretsFileNotAFile`] wrapped in
233 /// [`Error::NonAdminSecretHandling`].
234 NonAdminCredentialsSecretsFileNotAFile = 148,
235
236 /// Mapping for [`crate::non_admin_credentials::Error::SecretsFilePermissions`] wrapped in
237 /// [`Error::NonAdminSecretHandling`].
238 NonAdminCredentialsSecretsFilePermissions = 149,
239
240 /// Mapping for [`crate::non_admin_credentials::Error::SecretsFileRead`] wrapped in
241 /// [`Error::NonAdminSecretHandling`].
242 NonAdminCredentialsSecretsFileRead = 150,
243
244 /// Mapping for [`crate::non_admin_credentials::Error::SecretsFileWrite`] wrapped in
245 /// [`Error::NonAdminSecretHandling`].
246 NonAdminCredentialsSecretsFileWrite = 151,
247
248 /// Mapping for [`signstar_common::admin_credentials::Error::ApplyPermissions`] wrapped in
249 /// [`Error::SignstarCommonAdminCreds`].
250 SignstarCommonAdminCredsApplyPermissions = 170,
251
252 /// Mapping for [`signstar_common::admin_credentials::Error::CreateDirectory`] wrapped in
253 /// [`Error::SignstarCommonAdminCreds`].
254 SignstarCommonAdminCredsCreateDirectory = 171,
255
256 /// Mapping for [`signstar_common::admin_credentials::Error::DirChangeOwner`] wrapped in
257 /// [`Error::SignstarCommonAdminCreds`].
258 SignstarCommonAdminCredsDirChangeOwner = 172,
259
260 /// Mapping for [`Error::Thread`].
261 Thread = 17,
262
263 /// Mapping for [`Error::Utf8String`].
264 Utf8String = 18,
265
266 /// Mapping for [`crate::utils::Error::ExecutableNotFound`] wrapped in [`Error::Utils`].
267 UtilsExecutableNotFound = 190,
268
269 /// Mapping for [`crate::utils::Error::MappingSystemUserGet`] wrapped in [`Error::Utils`].
270 UtilsMappingSystemUserGet = 191,
271
272 /// Mapping for [`crate::utils::Error::SystemUserData`] wrapped in [`Error::Utils`].
273 UtilsSystemUserData = 192,
274
275 /// Mapping for [`crate::utils::Error::SystemUserLookup`] wrapped in [`Error::Utils`].
276 UtilsSystemUserLookup = 193,
277
278 /// Mapping for [`crate::utils::Error::SystemUserMismatch`] wrapped in [`Error::Utils`].
279 UtilsSystemUserMismatch = 194,
280
281 /// Mapping for [`crate::utils::Error::SystemUserNotRoot`] wrapped in [`Error::Utils`].
282 UtilsSystemUserNotRoot = 195,
283
284 /// Mapping for [`crate::utils::Error::SystemUserRoot`] wrapped in [`Error::Utils`].
285 UtilsSystemUserRoot = 196,
286}
287
288impl From<Error> for ErrorExitCode {
289 fn from(value: Error) -> Self {
290 match value {
291 // admin credentials related errors and their exit codes
292 Error::AdminSecretHandling(error) => match error {
293 crate::admin_credentials::Error::AdministratorMissing => {
294 Self::AdminCredentialsAdministratorMissing
295 }
296 crate::admin_credentials::Error::AdministratorNoDefault => {
297 Self::AdminCredentialsAdministratorNoDefault
298 }
299 crate::admin_credentials::Error::ConfigFromToml { .. } => {
300 Self::AdminCredentialsConfigFromToml
301 }
302 crate::admin_credentials::Error::ConfigLoad { .. } => {
303 Self::AdminCredentialsConfigLoad
304 }
305 crate::admin_credentials::Error::ConfigStore { .. } => {
306 Self::AdminCredentialsConfigStore
307 }
308 crate::admin_credentials::Error::ConfigToToml(_) => {
309 Self::AdminCredentialsConfigToToml
310 }
311 crate::admin_credentials::Error::CredsFileCreate { .. } => {
312 Self::AdminCredentialsCredsFileCreate
313 }
314 crate::admin_credentials::Error::CredsFileMissing { .. } => {
315 Self::AdminCredentialsCredsFileMissing
316 }
317 crate::admin_credentials::Error::CredsFileNotAFile { .. } => {
318 Self::AdminCredentialsCredsFileNotAFile
319 }
320 crate::admin_credentials::Error::CredsFileWrite { .. } => {
321 Self::AdminCredentialsCredsFileWrite
322 }
323 crate::admin_credentials::Error::PassphraseTooShort { .. } => {
324 Self::AdminCredentialsPassphraseTooShort
325 }
326 },
327 // config related errors
328 Error::Config(error) => match error {
329 crate::config::Error::ConfigMissing => Self::ConfigConfigMissing,
330 crate::config::Error::NetHsmConfig(_) => Self::ConfigNetHsmConfig,
331 },
332 // non-admin credentials related errors and their exit codes
333 Error::NonAdminSecretHandling(error) => match error {
334 crate::non_admin_credentials::Error::CredentialsLoading { .. } => {
335 Self::NonAdminCredentialsCredentialsLoading
336 }
337 crate::non_admin_credentials::Error::CredentialsMissing { .. } => {
338 Self::NonAdminCredentialsCredentialsMissing
339 }
340 crate::non_admin_credentials::Error::NoSystemUser => {
341 Self::NonAdminCredentialsNoSystemUser
342 }
343 crate::non_admin_credentials::Error::NotSigningUser => {
344 Self::NonAdminCredentialsNotSigningUser
345 }
346 crate::non_admin_credentials::Error::SecretsDirCreate { .. } => {
347 Self::NonAdminCredentialsSecretsDirCreate
348 }
349 crate::non_admin_credentials::Error::SecretsFileCreate { .. } => {
350 Self::NonAdminCredentialsSecretsFileCreate
351 }
352 crate::non_admin_credentials::Error::SecretsFileMetadata { .. } => {
353 Self::NonAdminCredentialsSecretsFileMetadata
354 }
355 crate::non_admin_credentials::Error::SecretsFileMissing { .. } => {
356 Self::NonAdminCredentialsSecretsFileMissing
357 }
358 crate::non_admin_credentials::Error::SecretsFileNotAFile { .. } => {
359 Self::NonAdminCredentialsSecretsFileNotAFile
360 }
361 crate::non_admin_credentials::Error::SecretsFilePermissions { .. } => {
362 Self::NonAdminCredentialsSecretsFilePermissions
363 }
364 crate::non_admin_credentials::Error::SecretsFileRead { .. } => {
365 Self::NonAdminCredentialsSecretsFileRead
366 }
367 crate::non_admin_credentials::Error::SecretsFileWrite { .. } => {
368 Self::NonAdminCredentialsSecretsFileWrite
369 }
370 },
371 // signstar-common admin credentials related errors
372 Error::SignstarCommonAdminCreds(error) => match error {
373 signstar_common::admin_credentials::Error::ApplyPermissions { .. } => {
374 Self::SignstarCommonAdminCredsApplyPermissions
375 }
376 signstar_common::admin_credentials::Error::CreateDirectory { .. } => {
377 Self::SignstarCommonAdminCredsCreateDirectory
378 }
379 signstar_common::admin_credentials::Error::DirChangeOwner { .. } => {
380 Self::SignstarCommonAdminCredsDirChangeOwner
381 }
382 },
383 // utils related errors
384 Error::Utils(error) => match error {
385 crate::utils::Error::ExecutableNotFound { .. } => Self::UtilsExecutableNotFound,
386 crate::utils::Error::MappingSystemUserGet(_) => Self::UtilsMappingSystemUserGet,
387 crate::utils::Error::SystemUserData { .. } => Self::UtilsSystemUserData,
388 crate::utils::Error::SystemUserLookup { .. } => Self::UtilsSystemUserLookup,
389 crate::utils::Error::SystemUserMismatch { .. } => Self::UtilsSystemUserMismatch,
390 crate::utils::Error::SystemUserNotRoot { .. } => Self::UtilsSystemUserNotRoot,
391 crate::utils::Error::SystemUserRoot => Self::UtilsSystemUserRoot,
392 },
393 // top-level errors and their exit codes
394 Error::ApplyPermissions { .. } => Self::ApplyPermissions,
395 Error::CommandAttachToStdin { .. } => Self::CommandAttachToStdin,
396 Error::Chown { .. } => Self::Chown,
397 Error::CommandBackground { .. } => Self::CommandBackground,
398 Error::CommandExec { .. } => Self::CommandExec,
399 Error::CommandNonZero { .. } => Self::CommandNonZero,
400 Error::Thread { .. } => Self::Thread,
401 Error::Utf8String { .. } => Self::Utf8String,
402 Error::CommandWriteToStdin { .. } => Self::CommandWriteToStdin,
403 }
404 }
405}
406
407impl From<ErrorExitCode> for ExitCode {
408 fn from(value: ErrorExitCode) -> Self {
409 Self::from(std::convert::Into::<u8>::into(value))
410 }
411}
412
413impl From<ErrorExitCode> for i32 {
414 fn from(value: ErrorExitCode) -> Self {
415 Self::from(std::convert::Into::<u8>::into(value))
416 }
417}