@@ -16,6 +16,10 @@ use super::headers::{AuthenticatedHeader, Header, HeaderParser};
1616
1717impl < ' x > AuthenticatedMessage < ' x > {
1818 pub fn parse ( raw_message : & ' x [ u8 ] ) -> Option < Self > {
19+ Self :: parse_with_opts ( raw_message, true )
20+ }
21+
22+ pub fn parse_with_opts ( raw_message : & ' x [ u8 ] , strict : bool ) -> Option < Self > {
1923 let mut message = AuthenticatedMessage {
2024 headers : Vec :: new ( ) ,
2125 from : Vec :: new ( ) ,
@@ -35,90 +39,103 @@ impl<'x> AuthenticatedMessage<'x> {
3539 let mut has_arc_errors = false ;
3640
3741 for ( header, value) in & mut headers {
38- let name = match header {
39- AuthenticatedHeader :: Ds ( name) => {
40- let signature = dkim:: Signature :: parse ( value) ;
41- if let Ok ( signature) = & signature {
42- let ha = HashAlgorithm :: from ( signature. a ) ;
43- if !message
44- . body_hashes
45- . iter ( )
46- . any ( |( c, h, l, _) | c == & signature. cb && h == & ha && l == & signature. l )
47- {
48- message
49- . body_hashes
50- . push ( ( signature. cb , ha, signature. l , Vec :: new ( ) ) ) ;
51- }
52- }
53- message
54- . dkim_headers
55- . push ( Header :: new ( name, value, signature) ) ;
56- name
57- }
58- AuthenticatedHeader :: Aar ( name) => {
59- let results = arc:: Results :: parse ( value) ;
60- if !has_arc_errors {
61- has_arc_errors = results. is_err ( ) ;
42+ let name =
43+ match header {
44+ AuthenticatedHeader :: Ds ( name) => {
45+ let signature = match dkim:: Signature :: parse ( value) {
46+ Ok ( signature) if signature. l == 0 || !strict => {
47+ let ha = HashAlgorithm :: from ( signature. a ) ;
48+ if !message. body_hashes . iter ( ) . any ( |( c, h, l, _) | {
49+ c == & signature. cb && h == & ha && l == & signature. l
50+ } ) {
51+ message. body_hashes . push ( (
52+ signature. cb ,
53+ ha,
54+ signature. l ,
55+ Vec :: new ( ) ,
56+ ) ) ;
57+ }
58+ Ok ( signature)
59+ }
60+ Ok ( _) => Err ( crate :: Error :: SignatureLength ) ,
61+ Err ( err) => Err ( err) ,
62+ } ;
63+
64+ message
65+ . dkim_headers
66+ . push ( Header :: new ( name, value, signature) ) ;
67+ name
6268 }
63- message. aar_headers . push ( Header :: new ( name, value, results) ) ;
64- name
65- }
66- AuthenticatedHeader :: Ams ( name) => {
67- let signature = arc:: Signature :: parse ( value) ;
68-
69- if let Ok ( signature) = & signature {
70- let ha = HashAlgorithm :: from ( signature. a ) ;
71- if !message
72- . body_hashes
73- . iter ( )
74- . any ( |( c, h, l, _) | c == & signature. cb && h == & ha && l == & signature. l )
75- {
76- message
77- . body_hashes
78- . push ( ( signature. cb , ha, signature. l , Vec :: new ( ) ) ) ;
69+ AuthenticatedHeader :: Aar ( name) => {
70+ let results = arc:: Results :: parse ( value) ;
71+ if !has_arc_errors {
72+ has_arc_errors = results. is_err ( ) ;
7973 }
80- } else {
81- has_arc_errors = true ;
74+ message . aar_headers . push ( Header :: new ( name , value , results ) ) ;
75+ name
8276 }
83-
84- message
85- . ams_headers
86- . push ( Header :: new ( name, value, signature) ) ;
87- name
88- }
89- AuthenticatedHeader :: As ( name) => {
90- let seal = arc:: Seal :: parse ( value) ;
91- if !has_arc_errors {
92- has_arc_errors = seal. is_err ( ) ;
77+ AuthenticatedHeader :: Ams ( name) => {
78+ let signature = match arc:: Signature :: parse ( value) {
79+ Ok ( signature) if signature. l == 0 || !strict => {
80+ let ha = HashAlgorithm :: from ( signature. a ) ;
81+ if !message. body_hashes . iter ( ) . any ( |( c, h, l, _) | {
82+ c == & signature. cb && h == & ha && l == & signature. l
83+ } ) {
84+ message. body_hashes . push ( (
85+ signature. cb ,
86+ ha,
87+ signature. l ,
88+ Vec :: new ( ) ,
89+ ) ) ;
90+ }
91+ Ok ( signature)
92+ }
93+ Ok ( _) => {
94+ has_arc_errors = true ;
95+ Err ( crate :: Error :: SignatureLength )
96+ }
97+ Err ( err) => {
98+ has_arc_errors = true ;
99+ Err ( err)
100+ }
101+ } ;
102+
103+ message
104+ . ams_headers
105+ . push ( Header :: new ( name, value, signature) ) ;
106+ name
93107 }
94- message. as_headers . push ( Header :: new ( name, value, seal) ) ;
95- name
96- }
97- AuthenticatedHeader :: From ( name) => {
98- match MessageStream :: new ( value) . parse_address ( ) {
99- HeaderValue :: Address ( Address :: List ( list) ) => {
100- message. from . extend (
101- list. into_iter ( )
102- . filter_map ( |a| a. address . map ( |a| a. to_lowercase ( ) ) ) ,
103- ) ;
108+ AuthenticatedHeader :: As ( name) => {
109+ let seal = arc:: Seal :: parse ( value) ;
110+ if !has_arc_errors {
111+ has_arc_errors = seal. is_err ( ) ;
104112 }
105- HeaderValue :: Address ( Address :: Group ( group_list) ) => {
106- message
113+ message. as_headers . push ( Header :: new ( name, value, seal) ) ;
114+ name
115+ }
116+ AuthenticatedHeader :: From ( name) => {
117+ match MessageStream :: new ( value) . parse_address ( ) {
118+ HeaderValue :: Address ( Address :: List ( list) ) => {
119+ message. from . extend (
120+ list. into_iter ( )
121+ . filter_map ( |a| a. address . map ( |a| a. to_lowercase ( ) ) ) ,
122+ ) ;
123+ }
124+ HeaderValue :: Address ( Address :: Group ( group_list) ) => message
107125 . from
108126 . extend ( group_list. into_iter ( ) . flat_map ( |group| {
109127 group
110128 . addresses
111129 . into_iter ( )
112130 . filter_map ( |a| a. address . map ( |a| a. to_lowercase ( ) ) )
113- } ) )
131+ } ) ) ,
132+ _ => ( ) ,
114133 }
115- _ => ( ) ,
116- }
117134
118- name
119- }
120- AuthenticatedHeader :: Other ( name) => name,
121- } ;
135+ name
136+ }
137+ AuthenticatedHeader :: Other ( name) => name,
138+ } ;
122139
123140 message. headers . push ( ( name, value) ) ;
124141 }
0 commit comments