kumo_dkim/
errors.rs

1use dns_resolver::DnsError;
2use thiserror::Error;
3
4/// DKIM error status
5#[derive(Debug, Copy, Clone, Eq, PartialEq)]
6pub enum Status {
7    Permfail,
8    Tempfail,
9}
10
11#[derive(Debug, PartialEq, Clone, Error)]
12/// DKIM errors
13pub enum DKIMError {
14    #[error("unsupported hash algorithm: {0}")]
15    UnsupportedHashAlgorithm(String),
16    #[error("unsupported canonicalization: {0}")]
17    UnsupportedCanonicalizationType(String),
18    #[error("signature syntax error: {0}")]
19    SignatureSyntaxError(String),
20    #[error("signature missing required tag ({0})")]
21    SignatureMissingRequiredTag(&'static str),
22    #[error("incompatible version")]
23    IncompatibleVersion,
24    #[error("domain mismatch")]
25    DomainMismatch,
26    #[error("From field not signed")]
27    FromFieldNotSigned,
28    #[error("signature expired")]
29    SignatureExpired,
30    #[error("unacceptable signature header")]
31    UnacceptableSignatureHeader,
32    #[error("unsupported query method")]
33    UnsupportedQueryMethod,
34    #[error("key unavailable: {0}")]
35    KeyUnavailable(String),
36    #[error("internal error: {0}")]
37    UnknownInternalError(String),
38    #[error("no key for signature")]
39    NoKeyForSignature,
40    #[error("key syntax error")]
41    KeySyntaxError,
42    #[error("key incompatible version")]
43    KeyIncompatibleVersion,
44    #[error("inappropriate key algorithm")]
45    InappropriateKeyAlgorithm,
46    #[error("signature did not verify")]
47    SignatureDidNotVerify,
48    #[error("body hash did not verify")]
49    BodyHashDidNotVerify,
50    #[error("malformed email body")]
51    MalformedBody,
52    #[error("failed sign: {0}")]
53    FailedToSign(String),
54    #[error("failed to build object: {0}")]
55    BuilderError(&'static str),
56    #[error("failed to serialize DKIM header: {0}")]
57    HeaderSerializeError(String),
58    #[error("failed to load private key: {0}")]
59    PrivateKeyLoadError(String),
60    #[error("failed to parse message: {0:#}")]
61    MailParsingError(#[from] mailparsing::MailParsingError),
62    #[error("Canonical CRLF line endings are required for correct signing and verification")]
63    CanonicalLineEndingsRequired,
64    #[error(transparent)]
65    Dns(#[from] DnsError),
66}
67
68impl DKIMError {
69    pub fn status(self) -> Status {
70        use DKIMError::*;
71        match self {
72            SignatureSyntaxError(_)
73            | SignatureMissingRequiredTag(_)
74            | IncompatibleVersion
75            | DomainMismatch
76            | FromFieldNotSigned
77            | SignatureExpired
78            | UnacceptableSignatureHeader
79            | UnsupportedQueryMethod
80            | NoKeyForSignature
81            | KeySyntaxError
82            | KeyIncompatibleVersion
83            | InappropriateKeyAlgorithm
84            | SignatureDidNotVerify
85            | BodyHashDidNotVerify
86            | MalformedBody
87            | CanonicalLineEndingsRequired
88            | MailParsingError(_)
89            | UnsupportedCanonicalizationType(_)
90            | UnsupportedHashAlgorithm(_) => Status::Permfail,
91            KeyUnavailable(_)
92            | UnknownInternalError(_)
93            | BuilderError(_)
94            | FailedToSign(_)
95            | PrivateKeyLoadError(_)
96            | HeaderSerializeError(_) => Status::Tempfail,
97            Dns(dns) => match dns {
98                DnsError::InvalidName(_) => Status::Permfail,
99                DnsError::ResolveFailed(_) => Status::Tempfail,
100            },
101        }
102    }
103}