Commit
Author: Mauro D [mauro@stalw.art]
Hash: d3351d65ecf4af3441a9cf81ec8b203b28d81530
Timestamp: Thu, 26 Jan 2023 19:01:33 +0000 (1 year ago)

+66 -13 +/-7 browse
Ring as default backend.
1diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml
2index 04df1f9..c544e47 100644
3--- a/.github/workflows/rust.yml
4+++ b/.github/workflows/rust.yml
5 @@ -29,7 +29,7 @@ jobs:
6 args: --all-features
7 - name: Build
8 run: cargo build --verbose
9- - name: Run tests
10- run: cargo test --verbose
11+ - name: Run tests (rust-crypto)
12+ run: cargo test --verbose --no-default-features --features rust-crypto
13 - name: Run tests (ring)
14- run: cargo test --verbose --no-default-features --features ring,rustls-pemfile
15+ run: cargo test --verbose
16 diff --git a/CHANGELOG.md b/CHANGELOG.md
17index f72c9b4..966ff07 100644
18--- a/CHANGELOG.md
19+++ b/CHANGELOG.md
20 @@ -1,3 +1,12 @@
21+ mail-auth 0.3.0
22+ ================================
23+ - ``ring`` backend support.
24+ - API improvements: ``DkimSigner`` and ``ArcSealer`` builders.
25+ - Reverse IP authentication (iprev).
26+ - MTA-STS lookup.
27+ - SMTP TLS Report generation and parsing.
28+ - Bug fixes.
29+
30 mail-auth 0.2.0
31 ================================
32 - Fixed: Acronyms in type names do not match the recommended spelling from RFC 430 (#31)
33 diff --git a/Cargo.toml b/Cargo.toml
34index e02e2ae..ac9dcdd 100644
35--- a/Cargo.toml
36+++ b/Cargo.toml
37 @@ -1,7 +1,7 @@
38 [package]
39 name = "mail-auth"
40 description = "DKIM, ARC, SPF and DMARC library for Rust"
41- version = "0.2.0"
42+ version = "0.3.0"
43 edition = "2021"
44 authors = [ "Stalwart Labs <hello@stalw.art>"]
45 license = "Apache-2.0 OR MIT"
46 @@ -16,7 +16,7 @@ resolver = "2"
47 doctest = false
48
49 [features]
50- default = ["rust-crypto"]
51+ default = ["ring", "rustls-pemfile"]
52 rust-crypto = ["ed25519-dalek", "rsa", "sha1", "sha2"]
53 test = []
54
55 diff --git a/resources/arc/002.txt b/resources/arc/002.txt
56new file mode 100644
57index 0000000..b5e4445
58--- /dev/null
59+++ b/resources/arc/002.txt
60 @@ -0,0 +1,37 @@
61+ rsa._domainkey.manchego.org v=DKIM1; t=s; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDwIRP/UC3SBsEmGqZ9ZJW3/DkMoGeLnQg1fWn7/zYtIxN2SnFCjxOCKG9v3b4jYfcTNh5ijSsq631uBItLa7od+v/RtdC2UzJ1lWT947qR+Rcac2gbto/NMqJ0fzfVjH4OuKhitdY9tf6mcwGjaNBcWToIMmPSPDdQPNUYckcQ2QIDAQAB
62+ ed._domainkey.scamorza.org v=DKIM1; k=ed25519; p=11qYAYKxCrfVS/7TyWQHOg7hcvPapiMlrwIaaPcHURo=
63+
64+ ARC-Seal: i=2; a=rsa-sha256; s=rsa; d=manchego.org; cv=pass;
65+ b=wpAAy6QusmF4O8SeziNaKxXL6EleeBYxQ0HrXl2cDgzHLOvYG0N1Wpz0bpVbA8VgteD2X8XCW
66+ yrdlZ5dIPTcCvgfLGLXLRTIcYUdKyfFh5IVEciaUOUsxlSRPpekENZKzdHFkL4j1mAAvpDNJ7Ft
67+ OFIp0ku5dACn80g7D4cSEU0=;
68+ ARC-Message-Signature: i=2; a=rsa-sha256; s=rsa; d=manchego.org; c=relaxed/relaxed;
69+ h=Subject:To:From:DKIM-Signature; t=1674137914; bh=4ET7siw2kYV7jcN+fzsuYng/
70+ sr/BmIzzEjh43dVAv40=; b=V3tMBI1RsyJJY7HUABcebHf0mDJ9odbPm++ZMY5AsCaUYNoSsAm
71+ wCf5wYlJQ26KmsluOYXoPwML0a/xvnMXPv6Rs4Z9k4IwzpzhGLsijDXymGPsW3hgq/6ivVTPkwU
72+ +pGSCC70rHNrAFFk5P67Ly0tbGYjJ0wZVHBzqL8IJBXK4=;
73+ ARC-Authentication-Results: i=2; manchego.org;
74+ dkim=pass header.d=manchego.org header.s=rsa header.b=IN4oMvqq
75+ Authentication-Results: manchego.org;
76+ dkim=pass header.d=manchego.org header.s=rsa header.b=IN4oMvqq
77+ ARC-Seal: i=1; a=ed25519-sha256; s=ed; d=scamorza.org; cv=none;
78+ b=k/MAHECtaer9v4oczoe00a6XMjrxU4QUVVPlZI8XYegbiOgDSaeR6IrwBSKVcN0ELYU+HXlNW
79+ RuUGkRuZXQODA==;
80+ ARC-Message-Signature: i=1; a=ed25519-sha256; s=ed; d=scamorza.org; c=relaxed/relaxed;
81+ h=Subject:To:From:DKIM-Signature; t=1674137914; bh=4ET7siw2kYV7jcN+fzsuYng/
82+ sr/BmIzzEjh43dVAv40=; b=ZVPqB/5+mbOEKIgBsq+S71Sfj2JZUlGmYEA0Ygbj0S1VmTAnsVu
83+ FQSInMY4/qcIeqU23BtzMgCFVZfAg5i3zDw==;
84+ ARC-Authentication-Results: i=1; scamorza.org;
85+ dkim=pass header.d=manchego.org header.s=rsa header.b=IN4oMvqq
86+ Authentication-Results: scamorza.org;
87+ dkim=pass header.d=manchego.org header.s=rsa header.b=IN4oMvqq
88+ DKIM-Signature: v=1; a=rsa-sha256; s=rsa; d=manchego.org; c=relaxed/relaxed;
89+ h=Subject:To:From; t=1674137914; bh=4ET7siw2kYV7jcN+fzsuYng/sr/BmIzzEjh43dV
90+ Av40=; b=IN4oMvqqxWCEyC38F7fZecYJcnq+7zP3G/xjcI64M3/Dzys2lmQeLYAXipwwYvEa5a
91+ VwCcJ7XUX0kSxtr6igC8FIJEDI6UmdvJgMEj/hnEjXR8m4GPrphigjJy7hagaQymBT9WhlzsDPI
92+ QRlUVoW0y5v1aDp3KF9bLVCKTELJPM=;
93+ From: queso@manchego.org
94+ To: affumicata@scamorza.org
95+ Subject: Say cheese
96+
97+ We need to settle which one of us is tastier.
98 diff --git a/src/common/auth_results.rs b/src/common/auth_results.rs
99index 710abac..7f740c4 100644
100--- a/src/common/auth_results.rs
101+++ b/src/common/auth_results.rs
102 @@ -123,7 +123,7 @@ impl<'x> AuthenticationResults<'x> {
103
104 pub fn with_dmarc_result(mut self, dmarc: &DmarcOutput) -> Self {
105 self.auth_results.push_str(";\r\n\tdmarc=");
106- if dmarc.spf_result == DmarcResult::Pass && dmarc.dkim_result == DmarcResult::Pass {
107+ if dmarc.spf_result == DmarcResult::Pass || dmarc.dkim_result == DmarcResult::Pass {
108 DmarcResult::Pass.as_auth_result(&mut self.auth_results);
109 } else if dmarc.spf_result != DmarcResult::None {
110 dmarc.spf_result.as_auth_result(&mut self.auth_results);
111 diff --git a/src/dkim/canonicalize.rs b/src/dkim/canonicalize.rs
112index 4184675..92c2c37 100644
113--- a/src/dkim/canonicalize.rs
114+++ b/src/dkim/canonicalize.rs
115 @@ -174,7 +174,7 @@ impl Signature {
116 let body = message.body();
117 let body_len = body.len();
118 let canonical_headers = self.ch.canonical_headers(headers);
119- let canonical_body = self.ch.canonical_body(&body, u64::MAX);
120+ let canonical_body = self.ch.canonical_body(body, u64::MAX);
121
122 // Add any missing headers
123 signed_headers.reverse();
124 @@ -280,7 +280,7 @@ mod test {
125 let mut body = Vec::new();
126 CanonicalBody {
127 canonicalization,
128- body: &raw_body,
129+ body: raw_body,
130 }
131 .write(&mut body);
132 assert_eq!(expected_body, String::from_utf8(body).unwrap());
133 diff --git a/src/report/dmarc/mod.rs b/src/report/dmarc/mod.rs
134index 566fd80..6f3b35b 100644
135--- a/src/report/dmarc/mod.rs
136+++ b/src/report/dmarc/mod.rs
137 @@ -247,11 +247,18 @@ impl Record {
138 }
139
140 pub fn with_dmarc_output(mut self, dmarc_output: &DmarcOutput) -> Self {
141- self.row.policy_evaluated.disposition = match dmarc_output.policy {
142- crate::dmarc::Policy::None => ActionDisposition::None,
143- crate::dmarc::Policy::Quarantine => ActionDisposition::Quarantine,
144- crate::dmarc::Policy::Reject => ActionDisposition::Reject,
145- crate::dmarc::Policy::Unspecified => ActionDisposition::None,
146+ self.row.policy_evaluated.disposition = if dmarc_output.dkim_result
147+ == crate::DmarcResult::Pass
148+ || dmarc_output.spf_result == crate::DmarcResult::Pass
149+ {
150+ ActionDisposition::Pass
151+ } else {
152+ match dmarc_output.policy {
153+ crate::dmarc::Policy::None => ActionDisposition::None,
154+ crate::dmarc::Policy::Quarantine => ActionDisposition::Quarantine,
155+ crate::dmarc::Policy::Reject => ActionDisposition::Reject,
156+ crate::dmarc::Policy::Unspecified => ActionDisposition::None,
157+ }
158 };
159 self.row.policy_evaluated.dkim = (&dmarc_output.dkim_result).into();
160 self.row.policy_evaluated.spf = (&dmarc_output.spf_result).into();