1use dns_resolver::DnsError;
2use thiserror::Error;
3
4#[derive(Debug, Copy, Clone, Eq, PartialEq)]
6pub enum Status {
7 Permfail,
8 Tempfail,
9}
10
11#[derive(Debug, PartialEq, Clone, Error)]
12pub 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}