Commit
+29 -16 +/-2 browse
1 | diff --git a/resources/spf/basic.yml b/resources/spf/basic.yml |
2 | index a00787c..ff26b09 100644 |
3 | --- a/resources/spf/basic.yml |
4 | +++ b/resources/spf/basic.yml |
5 | @@ -1,17 +1,22 @@ |
6 | - # If the <domain> is malformed (e.g., label longer than 63 characters, |
7 | - # zero-length label not at the end, etc.) or is not a multi-label |
8 | - # domain name, or if the DNS lookup returns "Name Error" (RCODE 3, also |
9 | - # known as "NXDOMAIN" [RFC2308]), check_host() immediately returns the |
10 | - # result "none". |
11 | + # If the <domain> is malformed (e.g., label longer than 63 characters, total |
12 | + # length longer than 255 characters, zero-length label not at the end, etc.) or |
13 | + # is not a multi-label domain name, or if the DNS lookup returns "Name Error" |
14 | + # (RCODE 3, also known as "NXDOMAIN" [RFC2308]), check_host() immediately |
15 | + # returns the result "none". |
16 | |
17 | name: Malformed Domains |
18 | records: |
19 | - spf: extremely.ridiculously.long.domain.name.that.should.fail.immediately.com v=spf1 +all |
20 | + spf: this.domain.name.is.extremely.long.because.we.want.to.explicitly.show.that.the.maximum.length.of.a.domain.name.is.255.characters.so.this.one.will.definitely.fail.immediately.due.to.its.excessive.length.and.ridiculously.large.number.of.characters.which.makes.it.invalid.com v=spf1 +all |
21 | + spf: thislabelisjustoverthesixtythreecharacterlimitandshouldbeanerror.com v=spf1 +all |
22 | spf: nolabels v=spf1 +all |
23 | spf: none.test.org v=something-else not=spf for=sure |
24 | tests: |
25 | - - domain: extremely.ridiculously.long.domain.name.that.should.fail.immediately.com |
26 | - sender: sender@extremely.ridiculously.long.domain.name.that.should.fail.immediately.com |
27 | + - domain: this.domain.name.is.extremely.long.because.we.want.to.explicitly.show.that.the.maximum.length.of.a.domain.name.is.255.characters.so.this.one.will.definitely.fail.immediately.due.to.its.excessive.length.and.ridiculously.large.number.of.characters.which.makes.it.invalid.com |
28 | + sender: sender@this.domain.name.is.extremely.long.because.we.want.to.explicitly.show.that.the.maximum.length.of.a.domain.name.is.255.characters.so.this.one.will.definitely.fail.immediately.due.to.its.excessive.length.and.ridiculously.large.number.of.characters.which.makes.it.invalid.com |
29 | + ip: 172.168.0.1 |
30 | + expect: none |
31 | + - domain: thislabelisjustoverthesixtythreecharacterlimitandshouldbeanerror.com |
32 | + sender: sender@thislabelisjustoverthesixtythreecharacterlimitandshouldbeanerror.com |
33 | ip: 172.168.0.1 |
34 | expect: none |
35 | - domain: nolabels |
36 | diff --git a/src/spf/verify.rs b/src/spf/verify.rs |
37 | index 22842b8..8067315 100644 |
38 | --- a/src/spf/verify.rs |
39 | +++ b/src/spf/verify.rs |
40 | @@ -26,7 +26,7 @@ impl Resolver { |
41 | helo_domain: &str, |
42 | host_domain: &str, |
43 | ) -> SpfOutput { |
44 | - if helo_domain.has_labels() { |
45 | + if helo_domain.has_valid_labels() { |
46 | self.check_host( |
47 | ip, |
48 | helo_domain, |
49 | @@ -88,7 +88,7 @@ impl Resolver { |
50 | sender: &str, |
51 | ) -> SpfOutput { |
52 | let output = SpfOutput::new(domain.to_string()); |
53 | - if domain.is_empty() || domain.len() > 63 || !domain.has_labels() { |
54 | + if domain.is_empty() || domain.len() > 255 || !domain.has_valid_labels() { |
55 | return output.with_result(SpfResult::None); |
56 | } |
57 | let mut vars = Variables::new(); |
58 | @@ -495,24 +495,32 @@ impl LookupLimit { |
59 | } |
60 | } |
61 | |
62 | - pub trait HasLabels { |
63 | - fn has_labels(&self) -> bool; |
64 | + pub trait HasValidLabels { |
65 | + fn has_valid_labels(&self) -> bool; |
66 | } |
67 | |
68 | - impl HasLabels for &str { |
69 | - fn has_labels(&self) -> bool { |
70 | + impl HasValidLabels for &str { |
71 | + fn has_valid_labels(&self) -> bool { |
72 | let mut has_dots = false; |
73 | let mut has_chars = false; |
74 | + let mut label_len = 0; |
75 | for ch in self.chars() { |
76 | + label_len += 1; |
77 | + |
78 | if ch.is_alphanumeric() { |
79 | has_chars = true; |
80 | } else if ch == '.' { |
81 | has_dots = true; |
82 | + label_len = 0; |
83 | } |
84 | - if has_chars && has_dots { |
85 | - return true; |
86 | + |
87 | + if label_len > 63 { |
88 | + return false; |
89 | } |
90 | } |
91 | + if has_chars && has_dots { |
92 | + return true; |
93 | + } |
94 | false |
95 | } |
96 | } |