diff --git a/Changelog.md b/Changelog.md index b04f1b1f..cb0a67ca 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,19 @@ Please see [here](https://github.com/NLnetLabs/krill/projects?query=is%3Aopen+sort%3Aname-asc) for planned releases. +## Unreleased Changes + +Features / improvements: +* Added option to CLI to generate a Krill config file. +* Added simple Prometheus endpoint (/metrics) +* Added check for reporting status between CAs and their parents and repository +* Disable the embedded repository by default (see docs for info) +* Added guards against using 'localhost' in non-test environments + +Breaking changes: +* The error responses have been overhauled. + + ## 0.4.2 'Finer Things' This release fixes a bug, and introduces minor usability improvements: diff --git a/src/bin/krillc.rs b/src/bin/krillc.rs index fffbb62c..0bf8c2b5 100644 --- a/src/bin/krillc.rs +++ b/src/bin/krillc.rs @@ -21,7 +21,7 @@ fn main() { if format == ReportFormat::Json { eprintln!("{}", e); } else { - eprintln!("Error {}: {}", res.code(), res.msg()); + eprintln!("Error: {}", res.msg()); } } _ => { diff --git a/src/commons/api/mod.rs b/src/commons/api/mod.rs index f930b9ba..e1ae9694 100644 --- a/src/commons/api/mod.rs +++ b/src/commons/api/mod.rs @@ -25,6 +25,7 @@ use serde::{Deserialize, Deserializer, Serialize, Serializer}; use rpki::cert::Cert; use rpki::crl::Crl; +use rpki::crypto::KeyIdentifier; use rpki::manifest::Manifest; use rpki::roa::Roa; @@ -228,15 +229,15 @@ pub struct Link { /// https://rpki.readthedocs.io/en/latest/krill/pub/api.html#error-responses #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] pub struct ErrorResponse { - code: usize, + label: String, msg: String, args: HashMap, } impl ErrorResponse { - pub fn new(code: usize, msg: impl fmt::Display) -> Self { + pub fn new(label: &str, msg: impl fmt::Display) -> Self { ErrorResponse { - code, + label: label.to_string(), msg: msg.to_string(), args: HashMap::new(), } @@ -287,8 +288,16 @@ impl ErrorResponse { res } - pub fn code(&self) -> usize { - self.code + pub fn with_key_identifier(self, ki: &KeyIdentifier) -> Self { + self.with_arg("key_id", ki) + } + + pub fn with_resource_class(self, class_name: &ResourceClassName) -> Self { + self.with_arg("class_name", class_name) + } + + pub fn label(&self) -> &str { + &self.label } pub fn msg(&self) -> &str { &self.msg diff --git a/src/commons/error.rs b/src/commons/error.rs index d3eaa7b0..90673171 100644 --- a/src/commons/error.rs +++ b/src/commons/error.rs @@ -19,180 +19,141 @@ use crate::commons::remote::rfc8181::ReportErrorCode; use crate::commons::util::httpclient; use crate::commons::util::softsigner::SignerError; use crate::daemon::ca::RouteAuthorization; +use commons::api::ResourceClassName; +use rpki::x509::ValidationError; #[derive(Debug, Display)] pub enum Error { //----------------------------------------------------------------- - // System Issues (1000-1099) + // System Issues //----------------------------------------------------------------- - - // 1000, internal server error - #[display(fmt = "{}", _0)] + #[display(fmt = "I/O error: {}", _0)] IoError(io::Error), - // 1001, internal server error - #[display(fmt = "{}", _0)] + #[display(fmt = "Persistence error: {}", _0)] AggregateStoreError(AggregateStoreError), - // 1002, internal server error #[display(fmt = "Signing issue: {}", _0)] SignerError(String), - // not on api (fails at start up) - #[display(fmt = "{}", _0)] + #[display(fmt = "Cannot set up HTTPS: {}", _0)] HttpsSetup(String), - // not on api - #[display(fmt = "{}", _0)] + #[display(fmt = "HTTP client error: {}", _0)] HttpClientError(httpclient::Error), //----------------------------------------------------------------- - // General API Client Issues (2000-2099) + // General API Client Issues //----------------------------------------------------------------- - - // 2000 #[display(fmt = "Invalid JSON: {}", _0)] JsonError(serde_json::Error), - // 2001, BAD REQUEST - #[display(fmt = "Unknown API method.")] + #[display(fmt = "Unknown API method")] ApiUnknownMethod, - // 2002, NOT FOUND (generic API not found) - #[display(fmt = "Unknown resource.")] + #[display(fmt = "Unknown resource")] ApiUnknownResource, //----------------------------------------------------------------- - // Repository Issues (2100-2199) + // Repository Issues //----------------------------------------------------------------- - - // 2100 - #[display(fmt = "No repository configured.")] + #[display(fmt = "No repository configured for CA")] RepoNotSet, //----------------------------------------------------------------- - // Publisher Issues (2200-2299) + // Publisher Issues //----------------------------------------------------------------- - - // 2200 #[display(fmt = "Unknown publisher '{}'", _0)] PublisherUnknown(PublisherHandle), - // 2201 #[display(fmt = "Publishing uri '{}' outside repository uri '{}'", _0, _1)] PublisherUriOutsideBase(String, String), - // 2202 #[display(fmt = "Publisher uri '{}' must have a trailing slash", _0)] PublisherBaseUriNoSlash(String), - // 2203 #[display(fmt = "Duplicate publisher '{}'", _0)] PublisherDuplicate(PublisherHandle), - // 2204 #[display(fmt = "No embedded repository configured")] PublisherNoEmbeddedRepo, //----------------------------------------------------------------- - // RF8181 (publishing, not on json API so no error responses) + // RFC 8181 (publishing) //----------------------------------------------------------------- + #[display(fmt = "Issue with RFC8181 request: {}", _0)] + Rfc8181Validation(ValidationError), - // not on api - #[display(fmt = "Could not decode or validate RFC8181 request: {}", _0)] - Rfc8181Validation(String), + #[display(fmt = "Issue with decoding RFC8181 request: {}", _0)] + Rfc8181Decode(String), - // not on api #[display(fmt = "{}", _0)] Rfc8181MessageError(rfc8181::MessageError), - // not on api #[display(fmt = "{}", _0)] Rfc8181Delta(PublicationDeltaError), //----------------------------------------------------------------- - // CA Issues (2300-2399) + // CA Issues //----------------------------------------------------------------- - - // 2300 #[display(fmt = "CA '{}' was already initialised", _0)] CaDuplicate(Handle), - - // 2301 #[display(fmt = "CA '{}' is unknown", _0)] CaUnknown(Handle), - // CA Repo Issues (2310-2319) - - // 2310 - #[display(fmt = "CA '{}' already uses this repository.", _0)] + // CA Repo Issues + #[display(fmt = "CA '{}' already uses this repository", _0)] CaRepoInUse(Handle), - - // 2311 #[display(fmt = "CA '{}' got error from repository: {}", _0, _1)] - CaRepoNotResponsive(Handle, String), - - // 2312 + CaRepoIssue(Handle, String), #[display(fmt = "CA '{}' got invalid repository response xml: {}", _0, _1)] CaRepoResponseInvalidXml(Handle, String), - - // 2312 - #[display(fmt = "CA '{}' got parent instead of repository response.", _0)] + #[display(fmt = "CA '{}' got parent instead of repository response", _0)] CaRepoResponseWrongXml(Handle), - // CA Parent Issues (2320-2329) - - // 2320 + // CA Parent Issues #[display(fmt = "CA '{}' already has a parent named '{}'", _0, _1)] CaParentDuplicate(Handle, ParentHandle), - - // 2321 #[display(fmt = "CA '{}' does not have parent named '{}'", _0, _1)] CaParentUnknown(Handle, ParentHandle), - - // 2322 #[display(fmt = "CA '{}' got error from parent '{}': {}", _0, _1, _2)] - CaParentNotResponsive(Handle, ParentHandle, String), - - // 2323 + CaParentIssue(Handle, ParentHandle, String), #[display(fmt = "CA '{}' got invalid parent response xml: {}", _0, _1)] CaParentResponseInvalidXml(Handle, String), - - // 2334 - #[display(fmt = "CA '{}' got repository response when adding parent.", _0)] + #[display(fmt = "CA '{}' got repository response when adding parent", _0)] CaParentResponseWrongXml(Handle), + #[display( + fmt = "Please configure the repository for CA '{}' before adding parents", + _0 + )] + CaParentWithoutRepo(Handle), //----------------------------------------------------------------- - // RFC6492 (requesting resources, not on JSON api) + // RFC6492 (requesting resources) //----------------------------------------------------------------- - // not on api - #[display(fmt = "{}", _0)] + #[display(fmt = "RFC 6492 Issue: {}", _0)] Rfc6492(rfc6492::Error), - - // not on api - #[display(fmt = "Invalid CSR received: {}.", _0)] + #[display(fmt = "Invalid CSR received: {}", _0)] Rfc6492InvalidCsrSent(String), - - // not on api - #[display(fmt = "Invalidly signed RFC 6492 CMS.")] + #[display(fmt = "Invalidly signed RFC 6492 CMS")] Rfc6492SignatureInvalid, // CA Child Issues (2330-2339) // 2330 - #[display(fmt = "CA '{}' already has child named {}.", _0, _1)] + #[display(fmt = "CA '{}' already has child named '{}'", _0, _1)] CaChildDuplicate(Handle, ChildHandle), // 2331 - #[display(fmt = "CA '{}' does not have child named {}.", _0, _1)] + #[display(fmt = "CA '{}' does not have child named '{}'", _0, _1)] CaChildUnknown(Handle, ChildHandle), // 2332 - #[display(fmt = "Child '{}' for CA '{}' MUST have resources specified.", _1, _0)] + #[display(fmt = "Child '{}' for CA '{}' MUST have resources specified", _1, _0)] CaChildMustHaveResources(Handle, ChildHandle), // 2333 - #[display(fmt = "CA '{}' does not know id certificate for child '{}'.", _0, _1)] + #[display(fmt = "CA '{}' does not know id certificate for child '{}'", _0, _1)] CaChildUnauthorised(Handle, ChildHandle), // RouteAuthorizations (2340-2349) @@ -218,7 +179,7 @@ pub enum Error { //----------------------------------------------------------------- // not on api - #[display(fmt = "Attempt at re-using keys.")] + #[display(fmt = "Attempt at re-using keys")] KeyUseAttemptReuse, // not on api @@ -238,7 +199,7 @@ pub enum Error { KeyUseNoIssuedCert, // not on api - #[display(fmt = "No key found matching key identifier: {}", _0)] + #[display(fmt = "No key found matching key identifier: '{}'", _0)] KeyUseNoMatch(KeyIdentifier), //----------------------------------------------------------------- @@ -246,15 +207,15 @@ pub enum Error { //----------------------------------------------------------------- // not on api - #[display(fmt = "Unknown resource class: {}", _0)] - ResourceClassUnknown(String), + #[display(fmt = "Unknown resource class: '{}'", _0)] + ResourceClassUnknown(ResourceClassName), // not on api #[display(fmt = "{}", _0)] ResourceSetError(ResourceSetError), // not on api - #[display(fmt = "Requester is not entitled to all requested resources.")] + #[display(fmt = "Requester is not entitled to all requested resources")] MissingResources, //----------------------------------------------------------------- @@ -262,11 +223,11 @@ pub enum Error { //----------------------------------------------------------------- // 2600 - #[display(fmt = "Functionality not supported for TA.")] + #[display(fmt = "Functionality not supported for Trust Anchor")] TaNotAllowed, // 2601 - #[display(fmt = "Name reserved for embedded TA.")] + #[display(fmt = "Name reserved for embedded Trust Anchor")] TaNameReserved, // not on api @@ -326,10 +287,6 @@ impl Error { Error::Rfc6492InvalidCsrSent(msg.to_string()) } - pub fn unknown_resource_class(class: impl Display) -> Self { - Error::ResourceClassUnknown(class.to_string()) - } - pub fn publishing_outside_jail(uri: &uri::Rsync, jail: &uri::Rsync) -> Self { Error::PublisherUriOutsideBase(uri.to_string(), jail.to_string()) } @@ -337,10 +294,6 @@ impl Error { pub fn custom(msg: impl fmt::Display) -> Self { Error::Custom(msg.to_string()) } - - pub fn rfc8181_validation(e: impl fmt::Display) -> Self { - Error::Rfc8181Validation(e.to_string()) - } } impl std::error::Error for Error {} @@ -362,206 +315,218 @@ impl Error { } pub fn to_error_response(&self) -> ErrorResponse { - fn not_in_api() -> ErrorResponse { - unimplemented!("Cannot be caused by API") - } - match self { //----------------------------------------------------------------- - // System Issues (1000-1099) + // System Issues (label: sys-*) //----------------------------------------------------------------- - // 1000, internal server error - Error::IoError(e) => ErrorResponse::new(1000, self.to_string()).with_cause(e), + // internal server error + Error::IoError(e) => ErrorResponse::new("sys-io", &self).with_cause(e), - // 1001, internal server error - Error::AggregateStoreError(e) => { - ErrorResponse::new(1001, self.to_string()).with_cause(e) - } + // internal server error + Error::AggregateStoreError(e) => ErrorResponse::new("sys-store", &self).with_cause(e), - // 1002, internal server error - Error::SignerError(e) => ErrorResponse::new(1002, self.to_string()).with_cause(e), + // internal server error + Error::SignerError(e) => ErrorResponse::new("sys-signer", &self).with_cause(e), - // not on api (fails at start up) - Error::HttpsSetup(_) => not_in_api(), + // internal server error + Error::HttpsSetup(e) => ErrorResponse::new("sys-https", &self).with_cause(e), - // not on api - Error::HttpClientError(_) => not_in_api(), + // internal server error + Error::HttpClientError(e) => ErrorResponse::new("sys-http-client", &self).with_cause(e), //----------------------------------------------------------------- - // General API Client Issues (2000-2099) + // General API Client Issues (label: api-*) //----------------------------------------------------------------- - // 2000 - Error::JsonError(e) => ErrorResponse::new(2000, self.to_string()).with_cause(e), + // BAD REQUEST + Error::JsonError(e) => ErrorResponse::new("api-json", &self).with_cause(e), - // 2001, BAD REQUEST - Error::ApiUnknownMethod => ErrorResponse::new(2001, &self), + // BAD REQUEST + Error::ApiUnknownMethod => ErrorResponse::new("api-unknown-method", &self), - // 2002, NOT FOUND (generic API not found) - Error::ApiUnknownResource => ErrorResponse::new(2002, &self), + // NOT FOUND (generic API not found) + Error::ApiUnknownResource => ErrorResponse::new("api-unknown-resource", &self), //----------------------------------------------------------------- - // Repository Issues (2100-2199) + // Repository Issues (label: repo-*) //----------------------------------------------------------------- // 2100 - Error::RepoNotSet => ErrorResponse::new(2100, &self), + Error::RepoNotSet => ErrorResponse::new("repo-not-set", &self), //----------------------------------------------------------------- - // Publisher Issues (2200-2299) + // Publisher Issues (label: pub-*) //----------------------------------------------------------------- Error::PublisherUnknown(p) => { - ErrorResponse::new(2200, self.to_string()).with_publisher(p) + ErrorResponse::new("pub-unknown", &self).with_publisher(p) } Error::PublisherDuplicate(p) => { - ErrorResponse::new(2201, self.to_string()).with_publisher(p) + ErrorResponse::new("pub-duplicate", &self).with_publisher(p) } - Error::PublisherUriOutsideBase(uri, base) => ErrorResponse::new(2202, self.to_string()) - .with_uri(uri) - .with_base_uri(base), + Error::PublisherUriOutsideBase(uri, base) => { + ErrorResponse::new("pub-outside-jail", &self) + .with_uri(uri) + .with_base_uri(base) + } Error::PublisherBaseUriNoSlash(uri) => { - ErrorResponse::new(2203, self.to_string()).with_uri(uri) + ErrorResponse::new("pub-uri-no-slash", &self).with_uri(uri) } - Error::PublisherNoEmbeddedRepo => ErrorResponse::new(2204, &self), + Error::PublisherNoEmbeddedRepo => ErrorResponse::new("pub-no-embedded-repo", &self), //----------------------------------------------------------------- - // RF8181 (publishing, not on json API so no error responses) + // RFC 8181 //----------------------------------------------------------------- - Error::Rfc8181Validation(_) => not_in_api(), - Error::Rfc8181MessageError(_) => not_in_api(), - Error::Rfc8181Delta(_) => not_in_api(), + Error::Rfc8181Validation(e) => { + ErrorResponse::new("rfc8181-validation", &self).with_cause(e) + } + Error::Rfc8181Decode(e) => ErrorResponse::new("rfc8181-decode", &self).with_cause(e), + Error::Rfc8181MessageError(e) => { + ErrorResponse::new("rfc8181-protocol-message", &self).with_cause(e) + } + Error::Rfc8181Delta(e) => ErrorResponse::new("rfc8181-delta", &self).with_cause(e), //----------------------------------------------------------------- - // CA Issues (2300-2399) + // CA Issues (label: ca-*) //----------------------------------------------------------------- - Error::CaDuplicate(ca) => ErrorResponse::new(2300, self.to_string()).with_ca(ca), + Error::CaDuplicate(ca) => ErrorResponse::new("ca-duplicate", &self).with_ca(ca), - Error::CaUnknown(ca) => ErrorResponse::new(2301, self.to_string()).with_ca(ca), + Error::CaUnknown(ca) => ErrorResponse::new("ca-unknown", &self).with_ca(ca), - Error::CaRepoInUse(ca) => ErrorResponse::new(2302, self.to_string()).with_ca(ca), + Error::CaRepoInUse(ca) => ErrorResponse::new("ca-repo-same", &self).with_ca(ca), - Error::CaRepoNotResponsive(ca, err) => ErrorResponse::new(2310, self.to_string()) + Error::CaRepoIssue(ca, err) => ErrorResponse::new("ca-repo-issue", &self) .with_ca(ca) .with_cause(err), - Error::CaRepoResponseInvalidXml(ca, err) => ErrorResponse::new(2311, self.to_string()) - .with_ca(ca) - .with_cause(err), - - Error::CaRepoResponseWrongXml(ca) => { - ErrorResponse::new(2312, self.to_string()).with_ca(ca) - } - - Error::CaParentDuplicate(ca, parent) => ErrorResponse::new(2320, self.to_string()) - .with_ca(ca) - .with_parent(parent), - - Error::CaParentUnknown(ca, parent) => ErrorResponse::new(2321, self.to_string()) - .with_ca(ca) - .with_parent(parent), - - Error::CaParentNotResponsive(ca, parent, err) => { - ErrorResponse::new(2322, self.to_string()) + Error::CaRepoResponseInvalidXml(ca, err) => { + ErrorResponse::new("ca-repo-response-invalid-xml", &self) .with_ca(ca) - .with_parent(parent) .with_cause(err) } + Error::CaRepoResponseWrongXml(ca) => { + ErrorResponse::new("ca-repo-response-wrong-xml", &self).with_ca(ca) + } + + Error::CaParentDuplicate(ca, parent) => { + ErrorResponse::new("ca-parent-duplicate", &self) + .with_ca(ca) + .with_parent(parent) + } + + Error::CaParentUnknown(ca, parent) => ErrorResponse::new("ca-parent-unknown", &self) + .with_ca(ca) + .with_parent(parent), + + Error::CaParentIssue(ca, parent, err) => ErrorResponse::new("ca-parent-issue", &self) + .with_ca(ca) + .with_parent(parent) + .with_cause(err), + Error::CaParentResponseInvalidXml(ca, err) => { - ErrorResponse::new(2323, self.to_string()) + ErrorResponse::new("ca-parent-response-invalid-xml", &self) .with_ca(ca) .with_cause(err) } Error::CaParentResponseWrongXml(ca) => { - ErrorResponse::new(2324, self.to_string()).with_ca(ca) + ErrorResponse::new("ca-parent-response-wrong-xml", &self).with_ca(ca) + } + + Error::CaParentWithoutRepo(ca) => { + ErrorResponse::new("ca-parent-no-repo", &self).with_ca(ca) } //----------------------------------------------------------------- // RFC6492 (requesting resources, not on JSON api) //----------------------------------------------------------------- - Error::Rfc6492(_) => not_in_api(), - Error::Rfc6492InvalidCsrSent(_) => not_in_api(), - Error::Rfc6492SignatureInvalid => not_in_api(), + Error::Rfc6492(e) => ErrorResponse::new("rfc6492-protocol", &self).with_cause(e), + Error::Rfc6492InvalidCsrSent(e) => { + ErrorResponse::new("rfc6492-invalid-csr", &self).with_cause(e) + } + Error::Rfc6492SignatureInvalid => { + ErrorResponse::new("rfc6492-invalid-signature", &self) + } - // CA Child Issues (2330-2339) - Error::CaChildDuplicate(ca, child) => ErrorResponse::new(2330, self.to_string()) + // CA Child Issues + Error::CaChildDuplicate(ca, child) => ErrorResponse::new("ca-child-duplicate", &self) .with_ca(ca) .with_child(child), - - Error::CaChildUnknown(ca, child) => ErrorResponse::new(2331, self.to_string()) + Error::CaChildUnknown(ca, child) => ErrorResponse::new("ca-child-unknown", &self) .with_ca(ca) .with_child(child), - Error::CaChildMustHaveResources(ca, child) => { - ErrorResponse::new(2332, self.to_string()) + ErrorResponse::new("ca-child-resources-required", &self) + .with_ca(ca) + .with_child(child) + } + Error::CaChildUnauthorised(ca, child) => { + ErrorResponse::new("ca-child-unauthorised", &self) .with_ca(ca) .with_child(child) } - Error::CaChildUnauthorised(ca, child) => ErrorResponse::new(2333, self.to_string()) - .with_ca(ca) - .with_child(child), - - // RouteAuthorizations (2340-2349) - Error::CaAuthorisationUnknown(ca, auth) => ErrorResponse::new(2340, self.to_string()) + // RouteAuthorizations + Error::CaAuthorisationUnknown(ca, auth) => ErrorResponse::new("ca-auth-unknown", &self) .with_ca(ca) .with_auth(auth), - Error::CaAuthorisationDuplicate(ca, auth) => ErrorResponse::new(2341, self.to_string()) - .with_ca(ca) - .with_auth(auth), + Error::CaAuthorisationDuplicate(ca, auth) => { + ErrorResponse::new("ca-auth-duplicate", &self) + .with_ca(ca) + .with_auth(auth) + } Error::CaAuthorisationInvalidMaxlength(ca, auth) => { - ErrorResponse::new(2342, self.to_string()) + ErrorResponse::new("ca-auth-invalid-max-length", &self) .with_ca(ca) .with_auth(auth) } Error::CaAuthorisationNotEntitled(ca, auth) => { - ErrorResponse::new(2343, self.to_string()) + ErrorResponse::new("ca-auth-not-entitled", &self) .with_ca(ca) .with_auth(auth) } //----------------------------------------------------------------- - // Key Usage Issues (2400-2499) + // Key Usage Issues (key-*) //----------------------------------------------------------------- - - // not on api - Error::KeyUseAttemptReuse => not_in_api(), - Error::KeyUseNoNewKey => not_in_api(), - Error::KeyUseNoCurrentKey => not_in_api(), - Error::KeyUseNoOldKey => not_in_api(), - Error::KeyUseNoIssuedCert => not_in_api(), - Error::KeyUseNoMatch(_) => not_in_api(), + Error::KeyUseAttemptReuse => ErrorResponse::new("key-re-use", &self), + Error::KeyUseNoNewKey => ErrorResponse::new("key-no-new", &self), + Error::KeyUseNoCurrentKey => ErrorResponse::new("key-no-current", &self), + Error::KeyUseNoOldKey => ErrorResponse::new("key-no-old", &self), + Error::KeyUseNoIssuedCert => ErrorResponse::new("key-no-cert", &self), + Error::KeyUseNoMatch(ki) => { + ErrorResponse::new("key-no-match", &self).with_key_identifier(ki) + } //----------------------------------------------------------------- - // Resource Issues (2500-2599) + // Resource Issues (label: rc-*) //----------------------------------------------------------------- - Error::ResourceClassUnknown(_) => not_in_api(), - Error::ResourceSetError(_) => not_in_api(), - Error::MissingResources => not_in_api(), + Error::ResourceClassUnknown(name) => { + ErrorResponse::new("rc-unknown", &self).with_resource_class(name) + } + Error::ResourceSetError(e) => ErrorResponse::new("rc-resources", &self).with_cause(e), + Error::MissingResources => ErrorResponse::new("rc-missing-resources", &self), //----------------------------------------------------------------- - // Embedded (test) TA issues (2600-2699) + // Embedded (test) TA issues (label: ta-*) //----------------------------------------------------------------- - Error::TaNotAllowed => ErrorResponse::new(2600, &self), - Error::TaNameReserved => ErrorResponse::new(2601, &self), - Error::TaAlreadyInitialised => not_in_api(), + Error::TaNotAllowed => ErrorResponse::new("ta-not-allowed", &self), + Error::TaNameReserved => ErrorResponse::new("ta-name-reserved", &self), + Error::TaAlreadyInitialised => ErrorResponse::new("ta-initialised", &self), //----------------------------------------------------------------- // If we really don't know any more.. //----------------------------------------------------------------- - Error::Custom(_msg) => ErrorResponse::new(65535, &self), + Error::Custom(_msg) => ErrorResponse::new("general-error", &self), } - - // self.code().clone().into() } pub fn to_rfc8181_error_code(&self) -> ReportErrorCode { @@ -583,3 +548,313 @@ impl Error { } } } + +//------------ Tests --------------------------------------------------------- + +#[cfg(test)] +mod tests { + + use std::str::FromStr; + + use crate::commons::api::RoaDefinition; + use crate::commons::remote::id::tests::test_id_certificate; + + use super::*; + + #[test] + fn error_response_json_regressiongit() { + let ca = Handle::from_str_unsafe("ca"); + let parent = ParentHandle::from_str_unsafe("parent"); + let child = ChildHandle::from_str_unsafe("child"); + let publisher = PublisherHandle::from_str_unsafe("publisher"); + + let auth = + RouteAuthorization::new(RoaDefinition::from_str("192.168.0.0/16-24 => 64496").unwrap()); + + fn verify(expected_json: &str, e: Error) { + let actual = e.to_error_response(); + let expected: ErrorResponse = serde_json::from_str(expected_json).unwrap(); + assert_eq!(expected, actual); + + // check that serde works too + let serialized = serde_json::to_string(&actual).unwrap(); + let des = serde_json::from_str(&serialized).unwrap(); + assert_eq!(actual, des); + } + + //----------------------------------------------------------------- + // System Issues + //----------------------------------------------------------------- + + let io_err = io::Error::new(io::ErrorKind::Other, "can't read file"); + verify( + include_str!("../../test-resources/errors/sys-io.json"), + Error::IoError(io_err), + ); + + verify( + include_str!("../../test-resources/errors/sys-store.json"), + Error::AggregateStoreError(AggregateStoreError::InitError), + ); + verify( + include_str!("../../test-resources/errors/sys-signer.json"), + Error::SignerError("signer issue".to_string()), + ); + verify( + include_str!("../../test-resources/errors/sys-https.json"), + Error::HttpsSetup("can't find pem file".to_string()), + ); + verify( + include_str!("../../test-resources/errors/sys-http-client.json"), + Error::HttpClientError(httpclient::Error::Forbidden), + ); + + //----------------------------------------------------------------- + // General API Client Issues + //----------------------------------------------------------------- + let invalid_rsync_json = "\"https://host/module/folder\""; + let json_err = serde_json::from_str::(invalid_rsync_json) + .err() + .unwrap(); + verify( + include_str!("../../test-resources/errors/api-json.json"), + Error::JsonError(json_err), + ); + verify( + include_str!("../../test-resources/errors/api-unknown-method.json"), + Error::ApiUnknownMethod, + ); + verify( + include_str!("../../test-resources/errors/api-unknown-resource.json"), + Error::ApiUnknownResource, + ); + + //----------------------------------------------------------------- + // Repository Issues + //----------------------------------------------------------------- + verify( + include_str!("../../test-resources/errors/repo-not-set.json"), + Error::RepoNotSet, + ); + + //----------------------------------------------------------------- + // Publisher Issues + //----------------------------------------------------------------- + verify( + include_str!("../../test-resources/errors/pub-unknown.json"), + Error::PublisherUnknown(publisher.clone()), + ); + verify( + include_str!("../../test-resources/errors/pub-duplicate.json"), + Error::PublisherDuplicate(publisher.clone()), + ); + verify( + include_str!("../../test-resources/errors/pub-outside-jail.json"), + Error::PublisherUriOutsideBase( + "rsync://somehost/module/folder".to_string(), + "rsync://otherhost/module/folder".to_string(), + ), + ); + verify( + include_str!("../../test-resources/errors/pub-uri-no-slash.json"), + Error::PublisherBaseUriNoSlash("rsync://host/module/folder".to_string()), + ); + verify( + include_str!("../../test-resources/errors/pub-no-embedded-repo.json"), + Error::PublisherNoEmbeddedRepo, + ); + + //----------------------------------------------------------------- + // RFC 8181 + //----------------------------------------------------------------- + verify( + include_str!("../../test-resources/errors/rfc8181-validation.json"), + Error::Rfc8181Validation(ValidationError), + ); + verify( + include_str!("../../test-resources/errors/rfc8181-decode.json"), + Error::Rfc8181Decode("could not parse CMS".to_string()), + ); + verify( + include_str!("../../test-resources/errors/rfc8181-protocol-message.json"), + Error::Rfc8181MessageError(rfc8181::MessageError::InvalidVersion), + ); + verify( + include_str!("../../test-resources/errors/rfc8181-delta.json"), + Error::Rfc8181Delta(PublicationDeltaError::ObjectAlreadyPresent( + uri::Rsync::from_str("rsync://host/module/file.cer").unwrap(), + )), + ); + + //----------------------------------------------------------------- + // CA Issues (label: ca-*) + //----------------------------------------------------------------- + verify( + include_str!("../../test-resources/errors/ca-duplicate.json"), + Error::CaDuplicate(ca.clone()), + ); + verify( + include_str!("../../test-resources/errors/ca-unknown.json"), + Error::CaUnknown(ca.clone()), + ); + + verify( + include_str!("../../test-resources/errors/ca-repo-same.json"), + Error::CaRepoInUse(ca.clone()), + ); + verify( + include_str!("../../test-resources/errors/ca-repo-issue.json"), + Error::CaRepoIssue(ca.clone(), "cannot connect".to_string()), + ); + verify( + include_str!("../../test-resources/errors/ca-repo-response-invalid-xml.json"), + Error::CaRepoResponseInvalidXml(ca.clone(), "expected some tag".to_string()), + ); + verify( + include_str!("../../test-resources/errors/ca-repo-response-wrong-xml.json"), + Error::CaRepoResponseWrongXml(ca.clone()), + ); + + verify( + include_str!("../../test-resources/errors/ca-parent-duplicate.json"), + Error::CaParentDuplicate(ca.clone(), parent.clone()), + ); + verify( + include_str!("../../test-resources/errors/ca-parent-unknown.json"), + Error::CaParentUnknown(ca.clone(), parent.clone()), + ); + verify( + include_str!("../../test-resources/errors/ca-parent-issue.json"), + Error::CaParentIssue(ca.clone(), parent.clone(), "connection refused".to_string()), + ); + verify( + include_str!("../../test-resources/errors/ca-parent-response-invalid-xml.json"), + Error::CaParentResponseInvalidXml(ca.clone(), "expected something".to_string()), + ); + verify( + include_str!("../../test-resources/errors/ca-parent-response-wrong-xml.json"), + Error::CaParentResponseWrongXml(ca.clone()), + ); + verify( + include_str!("../../test-resources/errors/ca-parent-no-repo.json"), + Error::CaParentWithoutRepo(ca.clone()), + ); + + verify( + include_str!("../../test-resources/errors/rfc6492-protocol.json"), + Error::Rfc6492(rfc6492::Error::InvalidVersion), + ); + verify( + include_str!("../../test-resources/errors/rfc6492-invalid-csr.json"), + Error::Rfc6492InvalidCsrSent("invalid signature".to_string()), + ); + verify( + include_str!("../../test-resources/errors/rfc6492-invalid-signature.json"), + Error::Rfc6492SignatureInvalid, + ); + + verify( + include_str!("../../test-resources/errors/ca-child-duplicate.json"), + Error::CaChildDuplicate(ca.clone(), child.clone()), + ); + verify( + include_str!("../../test-resources/errors/ca-child-unknown.json"), + Error::CaChildUnknown(ca.clone(), child.clone()), + ); + verify( + include_str!("../../test-resources/errors/ca-child-resources-required.json"), + Error::CaChildMustHaveResources(ca.clone(), child.clone()), + ); + verify( + include_str!("../../test-resources/errors/ca-child-unauthorised.json"), + Error::CaChildUnauthorised(ca.clone(), child.clone()), + ); + + verify( + include_str!("../../test-resources/errors/ca-auth-unknown.json"), + Error::CaAuthorisationUnknown(ca.clone(), auth), + ); + verify( + include_str!("../../test-resources/errors/ca-auth-duplicate.json"), + Error::CaAuthorisationDuplicate(ca.clone(), auth), + ); + verify( + include_str!("../../test-resources/errors/ca-auth-invalid-max-length.json"), + Error::CaAuthorisationInvalidMaxlength(ca.clone(), auth), + ); + verify( + include_str!("../../test-resources/errors/ca-auth-not-entitled.json"), + Error::CaAuthorisationNotEntitled(ca.clone(), auth), + ); + + verify( + include_str!("../../test-resources/errors/key-re-use.json"), + Error::KeyUseAttemptReuse, + ); + verify( + include_str!("../../test-resources/errors/key-no-new.json"), + Error::KeyUseNoNewKey, + ); + verify( + include_str!("../../test-resources/errors/key-no-current.json"), + Error::KeyUseNoCurrentKey, + ); + verify( + include_str!("../../test-resources/errors/key-no-old.json"), + Error::KeyUseNoOldKey, + ); + verify( + include_str!("../../test-resources/errors/key-no-cert.json"), + Error::KeyUseNoIssuedCert, + ); + let ki = test_id_certificate() + .subject_public_key_info() + .key_identifier(); + verify( + include_str!("../../test-resources/errors/key-no-match.json"), + Error::KeyUseNoMatch(ki), + ); + + verify( + include_str!("../../test-resources/errors/rc-unknown.json"), + Error::ResourceClassUnknown(ResourceClassName::from("RC0")), + ); + verify( + include_str!("../../test-resources/errors/rc-resources.json"), + Error::ResourceSetError(ResourceSetError::Mix), + ); + verify( + include_str!("../../test-resources/errors/rc-missing-resources.json"), + Error::MissingResources, + ); + + verify( + include_str!("../../test-resources/errors/ta-not-allowed.json"), + Error::TaNotAllowed, + ); + verify( + include_str!("../../test-resources/errors/ta-name-reserved.json"), + Error::TaNameReserved, + ); + verify( + include_str!("../../test-resources/errors/ta-initialised.json"), + Error::TaAlreadyInitialised, + ); + + verify( + include_str!("../../test-resources/errors/general-error.json"), + Error::custom("some unlikely corner case"), + ); + + // let mut res = String::new(); + // for e in errs { + // let error_response = e.to_error_response(); + // + // let path = format!("test-resources/errors/{}.json", error_response.label()); + // let path = PathBuf::from(&path); + // + // file::save_json(&error_response, &path).unwrap(); + // } + } + +} diff --git a/src/commons/eventsourcing/agg_store.rs b/src/commons/eventsourcing/agg_store.rs index ad201a03..7e6a3c29 100644 --- a/src/commons/eventsourcing/agg_store.rs +++ b/src/commons/eventsourcing/agg_store.rs @@ -53,16 +53,16 @@ pub enum AggregateStoreError { #[display(fmt = "{}", _0)] KeyStoreError(KeyStoreError), - #[display(fmt = "Unknown aggregate: {}", _0)] + #[display(fmt = "unknown entity: {}", _0)] UnknownAggregate(Handle), - #[display(fmt = "Aggregate init event exists, but cannot be applied")] + #[display(fmt = "init event exists, but cannot be applied")] InitError, - #[display(fmt = "Event not applicable to aggregate, id or version is off")] + #[display(fmt = "event not applicable to entity, id or version is off")] WrongEventForAggregate, - #[display(fmt = "Trying to update outdated aggregate '{}'", _0)] + #[display(fmt = "concurrent modifcation attempt for entity: '{}'", _0)] ConcurrentModification(Handle), } diff --git a/src/daemon/ca/certauth.rs b/src/daemon/ca/certauth.rs index 88475ff4..63c2ae04 100644 --- a/src/daemon/ca/certauth.rs +++ b/src/daemon/ca/certauth.rs @@ -741,7 +741,7 @@ impl CertAuth { let my_rc = self .resources .get(&rcn) - .ok_or_else(|| Error::unknown_resource_class(&rcn))?; + .ok_or_else(|| Error::ResourceClassUnknown(rcn))?; let child = self.get_child(&child)?; child.resources().apply_limit(&limit)?; @@ -753,7 +753,7 @@ impl CertAuth { /// for updating child certificates. fn republish_certs( &self, - class_name: &ResourceClassName, + rcn: &ResourceClassName, issued_certs: &[&IssuedCert], removed_certs: &[&Cert], signer: &S, @@ -761,8 +761,8 @@ impl CertAuth { let repo = self.get_repository_contact()?; self.resources - .get(&class_name) - .ok_or_else(|| Error::unknown_resource_class(&class_name))? + .get(&rcn) + .ok_or_else(|| Error::ResourceClassUnknown(rcn.clone()))? .republish_certs(issued_certs, removed_certs, repo.repo_info(), signer) } @@ -959,7 +959,7 @@ impl CertAuth { /// by this name (handle) is already known. fn add_parent(&self, parent: Handle, info: ParentCaContact) -> KrillResult> { if self.repository.is_none() { - Err(Error::RepoNotSet) + Err(Error::CaParentWithoutRepo(self.handle.clone())) } else if self.has_parent(&parent) { Err(Error::CaParentDuplicate(self.handle.clone(), parent)) } else if self.is_ta() { @@ -1241,7 +1241,7 @@ impl CertAuth { let rc = self .resources .get(&rcn) - .ok_or_else(|| Error::unknown_resource_class(&rcn))?; + .ok_or_else(|| Error::ResourceClassUnknown(rcn))?; let repo = self.get_repository_contact()?; @@ -1337,7 +1337,7 @@ impl CertAuth { let my_rc = self .resources .get(&rcn) - .ok_or_else(|| Error::unknown_resource_class(&rcn))?; + .ok_or_else(|| Error::ResourceClassUnknown(rcn.clone()))?; let repo = self.get_repository_contact()?; diff --git a/src/daemon/krillserver.rs b/src/daemon/krillserver.rs index 9316576f..c82b5973 100644 --- a/src/daemon/krillserver.rs +++ b/src/daemon/krillserver.rs @@ -520,7 +520,7 @@ impl KrillServer { RepositoryUpdate::Rfc8181(response) => { // first check that the new repo can be contacted if let CurrentRepoState::Error(error) = self.repo_state(&handle, Some(&response)) { - return Err(Error::CaRepoNotResponsive(handle, error.msg().to_string())); + return Err(Error::CaRepoIssue(handle, error.msg().to_string())); } RepositoryContact::Rfc8181(response) diff --git a/src/pubd/pubserver.rs b/src/pubd/pubserver.rs index e9f3050a..6b62beb5 100644 --- a/src/pubd/pubserver.rs +++ b/src/pubd/pubserver.rs @@ -129,12 +129,12 @@ impl PubServer { let repository = self.repository()?; let publisher = repository.get_publisher(&publisher_handle)?; - let msg = - SignedMessage::decode(msg_bytes.clone(), false).map_err(Error::rfc8181_validation)?; + let msg = SignedMessage::decode(msg_bytes.clone(), false) + .map_err(|e| Error::Rfc8181Decode(e.to_string()))?; let cms_logger = CmsLogger::for_rfc8181_rcvd(&self.cms_logger_work_dir, &publisher_handle); msg.validate(publisher.id_cert()) - .map_err(Error::rfc8181_validation)?; + .map_err(Error::Rfc8181Validation)?; let content = rfc8181::Message::from_signed_message(&msg)?; let query = content.into_query()?; diff --git a/test-resources/errors/api-json.json b/test-resources/errors/api-json.json new file mode 100644 index 00000000..2704e3c9 --- /dev/null +++ b/test-resources/errors/api-json.json @@ -0,0 +1 @@ +{"label":"api-json","msg":"Invalid JSON: bad URI scheme at line 1 column 28","args":{"cause":"bad URI scheme at line 1 column 28"}} \ No newline at end of file diff --git a/test-resources/errors/api-unknown-method.json b/test-resources/errors/api-unknown-method.json new file mode 100644 index 00000000..ba345197 --- /dev/null +++ b/test-resources/errors/api-unknown-method.json @@ -0,0 +1 @@ +{"label":"api-unknown-method","msg":"Unknown API method","args":{}} \ No newline at end of file diff --git a/test-resources/errors/api-unknown-resource.json b/test-resources/errors/api-unknown-resource.json new file mode 100644 index 00000000..b3ed821a --- /dev/null +++ b/test-resources/errors/api-unknown-resource.json @@ -0,0 +1 @@ +{"label":"api-unknown-resource","msg":"Unknown resource","args":{}} \ No newline at end of file diff --git a/test-resources/errors/ca-auth-duplicate.json b/test-resources/errors/ca-auth-duplicate.json new file mode 100644 index 00000000..1690755b --- /dev/null +++ b/test-resources/errors/ca-auth-duplicate.json @@ -0,0 +1 @@ +{"label":"ca-auth-duplicate","msg":"Duplicate authorization '192.168.0.0/16-24 => 64496' for CA 'ca'","args":{"asn":"64496","ca":"ca","prefix":"192.168.0.0/16","max_length":"24"}} \ No newline at end of file diff --git a/test-resources/errors/ca-auth-invalid-max-length.json b/test-resources/errors/ca-auth-invalid-max-length.json new file mode 100644 index 00000000..659bba1d --- /dev/null +++ b/test-resources/errors/ca-auth-invalid-max-length.json @@ -0,0 +1 @@ +{"label":"ca-auth-invalid-max-length","msg":"Invalid max length in authorization: '192.168.0.0/16-24 => 64496' for CA 'ca","args":{"ca":"ca","prefix":"192.168.0.0/16","max_length":"24","asn":"64496"}} \ No newline at end of file diff --git a/test-resources/errors/ca-auth-not-entitled.json b/test-resources/errors/ca-auth-not-entitled.json new file mode 100644 index 00000000..653e3aa0 --- /dev/null +++ b/test-resources/errors/ca-auth-not-entitled.json @@ -0,0 +1 @@ +{"label":"ca-auth-not-entitled","msg":"Authorisation '192.168.0.0/16-24 => 64496' resource not held by CA 'ca'.","args":{"asn":"64496","ca":"ca","prefix":"192.168.0.0/16","max_length":"24"}} \ No newline at end of file diff --git a/test-resources/errors/ca-auth-unknown.json b/test-resources/errors/ca-auth-unknown.json new file mode 100644 index 00000000..fa88bf8d --- /dev/null +++ b/test-resources/errors/ca-auth-unknown.json @@ -0,0 +1 @@ +{"label":"ca-auth-unknown","msg":"Cannot remove unknown authorization 'ca' from CA '192.168.0.0/16-24 => 64496'","args":{"ca":"ca","max_length":"24","asn":"64496","prefix":"192.168.0.0/16"}} \ No newline at end of file diff --git a/test-resources/errors/ca-child-duplicate.json b/test-resources/errors/ca-child-duplicate.json new file mode 100644 index 00000000..fea37ebc --- /dev/null +++ b/test-resources/errors/ca-child-duplicate.json @@ -0,0 +1 @@ +{"label":"ca-child-duplicate","msg":"CA 'ca' already has child named 'child'","args":{"child":"child","ca":"ca"}} \ No newline at end of file diff --git a/test-resources/errors/ca-child-resources-required.json b/test-resources/errors/ca-child-resources-required.json new file mode 100644 index 00000000..a71eefcc --- /dev/null +++ b/test-resources/errors/ca-child-resources-required.json @@ -0,0 +1 @@ +{"label":"ca-child-resources-required","msg":"Child 'child' for CA 'ca' MUST have resources specified","args":{"child":"child","ca":"ca"}} \ No newline at end of file diff --git a/test-resources/errors/ca-child-unauthorised.json b/test-resources/errors/ca-child-unauthorised.json new file mode 100644 index 00000000..ad64d6eb --- /dev/null +++ b/test-resources/errors/ca-child-unauthorised.json @@ -0,0 +1 @@ +{"label":"ca-child-unauthorised","msg":"CA 'ca' does not know id certificate for child 'child'","args":{"ca":"ca","child":"child"}} \ No newline at end of file diff --git a/test-resources/errors/ca-child-unknown.json b/test-resources/errors/ca-child-unknown.json new file mode 100644 index 00000000..95b3ca96 --- /dev/null +++ b/test-resources/errors/ca-child-unknown.json @@ -0,0 +1 @@ +{"label":"ca-child-unknown","msg":"CA 'ca' does not have child named 'child'","args":{"child":"child","ca":"ca"}} \ No newline at end of file diff --git a/test-resources/errors/ca-duplicate.json b/test-resources/errors/ca-duplicate.json new file mode 100644 index 00000000..f6ed156d --- /dev/null +++ b/test-resources/errors/ca-duplicate.json @@ -0,0 +1 @@ +{"label":"ca-duplicate","msg":"CA 'ca' was already initialised","args":{"ca":"ca"}} \ No newline at end of file diff --git a/test-resources/errors/ca-parent-duplicate.json b/test-resources/errors/ca-parent-duplicate.json new file mode 100644 index 00000000..df3a8a62 --- /dev/null +++ b/test-resources/errors/ca-parent-duplicate.json @@ -0,0 +1 @@ +{"label":"ca-parent-duplicate","msg":"CA 'ca' already has a parent named 'parent'","args":{"ca":"ca","parent":"parent"}} \ No newline at end of file diff --git a/test-resources/errors/ca-parent-issue.json b/test-resources/errors/ca-parent-issue.json new file mode 100644 index 00000000..cd64c690 --- /dev/null +++ b/test-resources/errors/ca-parent-issue.json @@ -0,0 +1 @@ +{"label":"ca-parent-issue","msg":"CA 'ca' got error from parent 'parent': connection refused","args":{"parent":"parent","ca":"ca","cause":"connection refused"}} \ No newline at end of file diff --git a/test-resources/errors/ca-parent-no-repo.json b/test-resources/errors/ca-parent-no-repo.json new file mode 100644 index 00000000..8cdb8b2f --- /dev/null +++ b/test-resources/errors/ca-parent-no-repo.json @@ -0,0 +1 @@ +{"label":"ca-parent-no-repo","msg":"Please configure the repository for CA 'ca' before adding parents","args":{"ca":"ca"}} \ No newline at end of file diff --git a/test-resources/errors/ca-parent-response-invalid-xml.json b/test-resources/errors/ca-parent-response-invalid-xml.json new file mode 100644 index 00000000..bc60cbc0 --- /dev/null +++ b/test-resources/errors/ca-parent-response-invalid-xml.json @@ -0,0 +1 @@ +{"label":"ca-parent-response-invalid-xml","msg":"CA 'ca' got invalid parent response xml: expected something","args":{"cause":"expected something","ca":"ca"}} \ No newline at end of file diff --git a/test-resources/errors/ca-parent-response-wrong-xml.json b/test-resources/errors/ca-parent-response-wrong-xml.json new file mode 100644 index 00000000..ea7f016d --- /dev/null +++ b/test-resources/errors/ca-parent-response-wrong-xml.json @@ -0,0 +1 @@ +{"label":"ca-parent-response-wrong-xml","msg":"CA 'ca' got repository response when adding parent","args":{"ca":"ca"}} \ No newline at end of file diff --git a/test-resources/errors/ca-parent-unknown.json b/test-resources/errors/ca-parent-unknown.json new file mode 100644 index 00000000..e0b475bd --- /dev/null +++ b/test-resources/errors/ca-parent-unknown.json @@ -0,0 +1 @@ +{"label":"ca-parent-unknown","msg":"CA 'ca' does not have parent named 'parent'","args":{"ca":"ca","parent":"parent"}} \ No newline at end of file diff --git a/test-resources/errors/ca-repo-issue.json b/test-resources/errors/ca-repo-issue.json new file mode 100644 index 00000000..fddeff07 --- /dev/null +++ b/test-resources/errors/ca-repo-issue.json @@ -0,0 +1 @@ +{"label":"ca-repo-issue","msg":"CA 'ca' got error from repository: cannot connect","args":{"cause":"cannot connect","ca":"ca"}} \ No newline at end of file diff --git a/test-resources/errors/ca-repo-response-invalid-xml.json b/test-resources/errors/ca-repo-response-invalid-xml.json new file mode 100644 index 00000000..25a83937 --- /dev/null +++ b/test-resources/errors/ca-repo-response-invalid-xml.json @@ -0,0 +1 @@ +{"label":"ca-repo-response-invalid-xml","msg":"CA 'ca' got invalid repository response xml: expected some tag","args":{"ca":"ca","cause":"expected some tag"}} \ No newline at end of file diff --git a/test-resources/errors/ca-repo-response-wrong-xml.json b/test-resources/errors/ca-repo-response-wrong-xml.json new file mode 100644 index 00000000..d704ebc9 --- /dev/null +++ b/test-resources/errors/ca-repo-response-wrong-xml.json @@ -0,0 +1 @@ +{"label":"ca-repo-response-wrong-xml","msg":"CA 'ca' got parent instead of repository response","args":{"ca":"ca"}} \ No newline at end of file diff --git a/test-resources/errors/ca-repo-same.json b/test-resources/errors/ca-repo-same.json new file mode 100644 index 00000000..70dab94f --- /dev/null +++ b/test-resources/errors/ca-repo-same.json @@ -0,0 +1 @@ +{"label":"ca-repo-same","msg":"CA 'ca' already uses this repository","args":{"ca":"ca"}} \ No newline at end of file diff --git a/test-resources/errors/ca-unknown.json b/test-resources/errors/ca-unknown.json new file mode 100644 index 00000000..a8e4908d --- /dev/null +++ b/test-resources/errors/ca-unknown.json @@ -0,0 +1 @@ +{"label":"ca-unknown","msg":"CA 'ca' is unknown","args":{"ca":"ca"}} \ No newline at end of file diff --git a/test-resources/errors/general-error.json b/test-resources/errors/general-error.json new file mode 100644 index 00000000..569d90ca --- /dev/null +++ b/test-resources/errors/general-error.json @@ -0,0 +1 @@ +{"label":"general-error","msg":"some unlikely corner case","args":{}} \ No newline at end of file diff --git a/test-resources/errors/key-no-cert.json b/test-resources/errors/key-no-cert.json new file mode 100644 index 00000000..770edcc7 --- /dev/null +++ b/test-resources/errors/key-no-cert.json @@ -0,0 +1 @@ +{"label":"key-no-cert","msg":"No issued cert matching pub key","args":{}} \ No newline at end of file diff --git a/test-resources/errors/key-no-current.json b/test-resources/errors/key-no-current.json new file mode 100644 index 00000000..8bb5ac1a --- /dev/null +++ b/test-resources/errors/key-no-current.json @@ -0,0 +1 @@ +{"label":"key-no-current","msg":"No current key in resource class","args":{}} \ No newline at end of file diff --git a/test-resources/errors/key-no-match.json b/test-resources/errors/key-no-match.json new file mode 100644 index 00000000..650f6697 --- /dev/null +++ b/test-resources/errors/key-no-match.json @@ -0,0 +1 @@ +{"label":"key-no-match","msg":"No key found matching key identifier: 'E445382DC63E360A9FB575FC12470E66785BB27E'","args":{"key_id":"E445382DC63E360A9FB575FC12470E66785BB27E"}} \ No newline at end of file diff --git a/test-resources/errors/key-no-new.json b/test-resources/errors/key-no-new.json new file mode 100644 index 00000000..f33637db --- /dev/null +++ b/test-resources/errors/key-no-new.json @@ -0,0 +1 @@ +{"label":"key-no-new","msg":"No new key in resource class","args":{}} \ No newline at end of file diff --git a/test-resources/errors/key-no-old.json b/test-resources/errors/key-no-old.json new file mode 100644 index 00000000..cd77c8f2 --- /dev/null +++ b/test-resources/errors/key-no-old.json @@ -0,0 +1 @@ +{"label":"key-no-old","msg":"No old key in resource class","args":{}} \ No newline at end of file diff --git a/test-resources/errors/key-re-use.json b/test-resources/errors/key-re-use.json new file mode 100644 index 00000000..841a2b64 --- /dev/null +++ b/test-resources/errors/key-re-use.json @@ -0,0 +1 @@ +{"label":"key-re-use","msg":"Attempt at re-using keys","args":{}} \ No newline at end of file diff --git a/test-resources/errors/pub-duplicate.json b/test-resources/errors/pub-duplicate.json new file mode 100644 index 00000000..f4e4f707 --- /dev/null +++ b/test-resources/errors/pub-duplicate.json @@ -0,0 +1 @@ +{"label":"pub-duplicate","msg":"Duplicate publisher 'publisher'","args":{"publisher":"publisher"}} \ No newline at end of file diff --git a/test-resources/errors/pub-no-embedded-repo.json b/test-resources/errors/pub-no-embedded-repo.json new file mode 100644 index 00000000..9b716519 --- /dev/null +++ b/test-resources/errors/pub-no-embedded-repo.json @@ -0,0 +1 @@ +{"label":"pub-no-embedded-repo","msg":"No embedded repository configured","args":{}} \ No newline at end of file diff --git a/test-resources/errors/pub-outside-jail.json b/test-resources/errors/pub-outside-jail.json new file mode 100644 index 00000000..2d8c31c0 --- /dev/null +++ b/test-resources/errors/pub-outside-jail.json @@ -0,0 +1 @@ +{"label":"pub-outside-jail","msg":"Publishing uri 'rsync://somehost/module/folder' outside repository uri 'rsync://otherhost/module/folder'","args":{"uri":"rsync://somehost/module/folder","base_uri":"rsync://otherhost/module/folder"}} \ No newline at end of file diff --git a/test-resources/errors/pub-unknown.json b/test-resources/errors/pub-unknown.json new file mode 100644 index 00000000..7b764cdb --- /dev/null +++ b/test-resources/errors/pub-unknown.json @@ -0,0 +1 @@ +{"label":"pub-unknown","msg":"Unknown publisher 'publisher'","args":{"publisher":"publisher"}} \ No newline at end of file diff --git a/test-resources/errors/pub-uri-no-slash.json b/test-resources/errors/pub-uri-no-slash.json new file mode 100644 index 00000000..a86c810b --- /dev/null +++ b/test-resources/errors/pub-uri-no-slash.json @@ -0,0 +1 @@ +{"label":"pub-uri-no-slash","msg":"Publisher uri 'rsync://host/module/folder' must have a trailing slash","args":{"uri":"rsync://host/module/folder"}} \ No newline at end of file diff --git a/test-resources/errors/rc-missing-resources.json b/test-resources/errors/rc-missing-resources.json new file mode 100644 index 00000000..88b31254 --- /dev/null +++ b/test-resources/errors/rc-missing-resources.json @@ -0,0 +1 @@ +{"label":"rc-missing-resources","msg":"Requester is not entitled to all requested resources","args":{}} \ No newline at end of file diff --git a/test-resources/errors/rc-resources.json b/test-resources/errors/rc-resources.json new file mode 100644 index 00000000..a3889cf3 --- /dev/null +++ b/test-resources/errors/rc-resources.json @@ -0,0 +1 @@ +{"label":"rc-resources","msg":"Mixed Address Families in configured resource set","args":{"cause":"Mixed Address Families in configured resource set"}} \ No newline at end of file diff --git a/test-resources/errors/rc-unknown.json b/test-resources/errors/rc-unknown.json new file mode 100644 index 00000000..cecd7ea6 --- /dev/null +++ b/test-resources/errors/rc-unknown.json @@ -0,0 +1 @@ +{"label":"rc-unknown","msg":"Unknown resource class: 'RC0'","args":{"class_name":"RC0"}} \ No newline at end of file diff --git a/test-resources/errors/repo-not-set.json b/test-resources/errors/repo-not-set.json new file mode 100644 index 00000000..9fa899b7 --- /dev/null +++ b/test-resources/errors/repo-not-set.json @@ -0,0 +1 @@ +{"label":"repo-not-set","msg":"No repository configured for CA","args":{}} \ No newline at end of file diff --git a/test-resources/errors/rfc6492-invalid-csr.json b/test-resources/errors/rfc6492-invalid-csr.json new file mode 100644 index 00000000..3239abf9 --- /dev/null +++ b/test-resources/errors/rfc6492-invalid-csr.json @@ -0,0 +1 @@ +{"label":"rfc6492-invalid-csr","msg":"Invalid CSR received: invalid signature","args":{"cause":"invalid signature"}} \ No newline at end of file diff --git a/test-resources/errors/rfc6492-invalid-signature.json b/test-resources/errors/rfc6492-invalid-signature.json new file mode 100644 index 00000000..f534afe5 --- /dev/null +++ b/test-resources/errors/rfc6492-invalid-signature.json @@ -0,0 +1 @@ +{"label":"rfc6492-invalid-signature","msg":"Invalidly signed RFC 6492 CMS","args":{}} \ No newline at end of file diff --git a/test-resources/errors/rfc6492-protocol.json b/test-resources/errors/rfc6492-protocol.json new file mode 100644 index 00000000..9ddb3fb0 --- /dev/null +++ b/test-resources/errors/rfc6492-protocol.json @@ -0,0 +1 @@ +{"label":"rfc6492-protocol","msg":"RFC 6492 Issue: Invalid protocol version, MUST be 1","args":{"cause":"Invalid protocol version, MUST be 1"}} \ No newline at end of file diff --git a/test-resources/errors/rfc8181-decode.json b/test-resources/errors/rfc8181-decode.json new file mode 100644 index 00000000..c571f3e0 --- /dev/null +++ b/test-resources/errors/rfc8181-decode.json @@ -0,0 +1 @@ +{"label":"rfc8181-decode","msg":"Issue with decoding RFC8181 request: could not parse CMS","args":{"cause":"could not parse CMS"}} \ No newline at end of file diff --git a/test-resources/errors/rfc8181-delta.json b/test-resources/errors/rfc8181-delta.json new file mode 100644 index 00000000..c2aa5740 --- /dev/null +++ b/test-resources/errors/rfc8181-delta.json @@ -0,0 +1 @@ +{"label":"rfc8181-delta","msg":"File already exists for uri (use update!): rsync://host/module/file.cer","args":{"cause":"File already exists for uri (use update!): rsync://host/module/file.cer"}} \ No newline at end of file diff --git a/test-resources/errors/rfc8181-protocol-message.json b/test-resources/errors/rfc8181-protocol-message.json new file mode 100644 index 00000000..5ead5c89 --- /dev/null +++ b/test-resources/errors/rfc8181-protocol-message.json @@ -0,0 +1 @@ +{"label":"rfc8181-protocol-message","msg":"Invalid version","args":{"cause":"Invalid version"}} \ No newline at end of file diff --git a/test-resources/errors/rfc8181-validation.json b/test-resources/errors/rfc8181-validation.json new file mode 100644 index 00000000..a542733d --- /dev/null +++ b/test-resources/errors/rfc8181-validation.json @@ -0,0 +1 @@ +{"label":"rfc8181-validation","msg":"Issue with RFC8181 request: validation error","args":{"cause":"validation error"}} \ No newline at end of file diff --git a/test-resources/errors/sys-http-client.json b/test-resources/errors/sys-http-client.json new file mode 100644 index 00000000..71afe38c --- /dev/null +++ b/test-resources/errors/sys-http-client.json @@ -0,0 +1 @@ +{"label":"sys-http-client","msg":"HTTP client error: Access Forbidden","args":{"cause":"Access Forbidden"}} \ No newline at end of file diff --git a/test-resources/errors/sys-https.json b/test-resources/errors/sys-https.json new file mode 100644 index 00000000..09e58f88 --- /dev/null +++ b/test-resources/errors/sys-https.json @@ -0,0 +1 @@ +{"label":"sys-https","msg":"Cannot set up HTTPS: can't find pem file","args":{"cause":"can't find pem file"}} \ No newline at end of file diff --git a/test-resources/errors/sys-io.json b/test-resources/errors/sys-io.json new file mode 100644 index 00000000..69b133e5 --- /dev/null +++ b/test-resources/errors/sys-io.json @@ -0,0 +1 @@ +{"label":"sys-io","msg":"I/O error: can't read file","args":{"cause":"can't read file"}} \ No newline at end of file diff --git a/test-resources/errors/sys-signer.json b/test-resources/errors/sys-signer.json new file mode 100644 index 00000000..6b125b8a --- /dev/null +++ b/test-resources/errors/sys-signer.json @@ -0,0 +1 @@ +{"label":"sys-signer","msg":"Signing issue: signer issue","args":{"cause":"signer issue"}} \ No newline at end of file diff --git a/test-resources/errors/sys-store.json b/test-resources/errors/sys-store.json new file mode 100644 index 00000000..c1c9e6e2 --- /dev/null +++ b/test-resources/errors/sys-store.json @@ -0,0 +1 @@ +{"label":"sys-store","msg":"Persistence error: init event exists, but cannot be applied","args":{"cause":"init event exists, but cannot be applied"}} \ No newline at end of file diff --git a/test-resources/errors/ta-initialised.json b/test-resources/errors/ta-initialised.json new file mode 100644 index 00000000..1b6950ce --- /dev/null +++ b/test-resources/errors/ta-initialised.json @@ -0,0 +1 @@ +{"label":"ta-initialised","msg":"TrustAnchor was already initialised","args":{}} \ No newline at end of file diff --git a/test-resources/errors/ta-name-reserved.json b/test-resources/errors/ta-name-reserved.json new file mode 100644 index 00000000..7221d7fa --- /dev/null +++ b/test-resources/errors/ta-name-reserved.json @@ -0,0 +1 @@ +{"label":"ta-name-reserved","msg":"Name reserved for embedded Trust Anchor","args":{}} \ No newline at end of file diff --git a/test-resources/errors/ta-not-allowed.json b/test-resources/errors/ta-not-allowed.json new file mode 100644 index 00000000..160599ac --- /dev/null +++ b/test-resources/errors/ta-not-allowed.json @@ -0,0 +1 @@ +{"label":"ta-not-allowed","msg":"Functionality not supported for Trust Anchor","args":{}} \ No newline at end of file