diff --git a/Cargo.lock b/Cargo.lock index 6b098a71e..7422c1348 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -84,7 +84,7 @@ version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -549,7 +549,7 @@ version = "0.1.12" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -631,7 +631,6 @@ dependencies = [ "lettre_email 0.9.2 (git+https://github.com/deltachat/lettre?branch=feat/mail)", "libc 0.2.66 (registry+https://github.com/rust-lang/crates.io-index)", "mailparse 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", - "mime 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)", "num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "percent-encoding 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -785,7 +784,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" [[package]] name = "email" version = "0.0.21" -source = "git+https://github.com/deltachat/rust-email#5fb7dac53e7e0014a8c5715017be3360aa83646c" +source = "git+https://github.com/deltachat/rust-email#265a54a8c31355c506610c032c81112dc0953afb" dependencies = [ "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)", @@ -911,7 +910,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1052,7 +1051,7 @@ dependencies = [ "proc-macro-hack 0.5.11 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1398,7 +1397,7 @@ dependencies = [ [[package]] name = "lettre" version = "0.9.2" -source = "git+https://github.com/deltachat/lettre?branch=feat/mail#0f393a3d1d3860183c5df97b4429d0919199344a" +source = "git+https://github.com/deltachat/lettre?branch=feat/mail#db7fe5fc06d4abb4c1cd70534310d1e0b1e79d57" dependencies = [ "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "bufstream 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1417,7 +1416,7 @@ dependencies = [ [[package]] name = "lettre_email" version = "0.9.2" -source = "git+https://github.com/deltachat/lettre?branch=feat/mail#0f393a3d1d3860183c5df97b4429d0919199344a" +source = "git+https://github.com/deltachat/lettre?branch=feat/mail#db7fe5fc06d4abb4c1cd70534310d1e0b1e79d57" dependencies = [ "base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)", "email 0.0.21 (git+https://github.com/deltachat/rust-email)", @@ -1862,7 +1861,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -1913,7 +1912,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2248,7 +2247,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2491,7 +2490,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2655,7 +2654,7 @@ dependencies = [ "heck 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", ] [[package]] @@ -2695,7 +2694,7 @@ dependencies = [ [[package]] name = "syn" -version = "1.0.9" +version = "1.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2718,7 +2717,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3139,7 +3138,7 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-shared 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3159,7 +3158,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-backend 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-shared 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3179,7 +3178,7 @@ dependencies = [ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "wasm-bindgen-backend 0.2.55 (registry+https://github.com/rust-lang/crates.io-index)", "weedle 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3341,7 +3340,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)", - "syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -3637,7 +3636,7 @@ dependencies = [ "checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad" "checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" "checksum syn 0.15.44 (registry+https://github.com/rust-lang/crates.io-index)" = "9ca4b3b69a77cbe1ffc9e198781b7acb0c7365a883670e8f1c1bc66fba79a5c5" -"checksum syn 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)" = "f89693ae015201f8de93fd96bde2d065f8bfc3f97ce006d5bc9f900b97c0c7c0" +"checksum syn 1.0.11 (registry+https://github.com/rust-lang/crates.io-index)" = "dff0acdb207ae2fe6d5976617f887eb1e35a2ba52c13c7234c790960cdad9238" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" "checksum synstructure 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)" = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" "checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8" diff --git a/Cargo.toml b/Cargo.toml index 4b9febc27..9e12520ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -54,7 +54,6 @@ rustls = "0.16.0" webpki-roots = "0.18.0" webpki = "0.21.0" mailparse = "0.10.1" -mime = "0.3.14" [dev-dependencies] tempfile = "3.0" diff --git a/src/aheader.rs b/src/aheader.rs index 06ec17b88..22b03102f 100644 --- a/src/aheader.rs +++ b/src/aheader.rs @@ -78,7 +78,6 @@ impl Aheader { Ok(header) => { info!(context, "comparing {} - {}", header.addr, wanted_from); if addr_cmp(&header.addr, wanted_from) { - info!(context, "found header {:?}", header); return Some(header); } } diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index bf96b159f..1a6b47c74 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -372,7 +372,7 @@ fn add_parts( // handshake messages must be processed _before_ chats are created // (eg. contacs may be marked as verified) - if let Some(_) = mime_parser.lookup_field("Secure-Join") { + if mime_parser.lookup_field("Secure-Join").is_some() { // avoid discarding by show_emails setting msgrmsg = 1; *chat_id = 0; diff --git a/src/e2ee.rs b/src/e2ee.rs index 7442e7867..e207fa1c3 100644 --- a/src/e2ee.rs +++ b/src/e2ee.rs @@ -2,6 +2,7 @@ use std::collections::HashSet; +use mailparse::MailHeaderMap; use num_traits::FromPrimitive; use crate::aheader::*; @@ -121,11 +122,7 @@ pub fn try_decrypt( mail: &mailparse::ParsedMail<'_>, message_time: i64, ) -> Result<(Option>, HashSet)> { - use mailparse::MailHeaderMap; - info!(context, "trying to decrypt: {:?}", mail.get_body()); - for part in &mail.subparts { - info!(context, "trying to decrypt part: {:?}", part.get_body()); - } + info!(context, "trying to decrypt"); let from = mail .headers @@ -137,7 +134,6 @@ pub fn try_decrypt( let mut peerstate = None; let autocryptheader = Aheader::from_headers(context, &from, &mail.headers); - info!(context, "got autocryptheader {:?}", &autocryptheader); if message_time > 0 { peerstate = Peerstate::from_addr(context, &context.sql, &from); diff --git a/src/error.rs b/src/error.rs index 816ba186e..25351bf71 100644 --- a/src/error.rs +++ b/src/error.rs @@ -1,4 +1,5 @@ use failure::Fail; +use lettre_email::mime; #[derive(Debug, Fail)] pub enum Error { diff --git a/src/mimefactory.rs b/src/mimefactory.rs index 8c79c26fc..62b732866 100644 --- a/src/mimefactory.rs +++ b/src/mimefactory.rs @@ -1,5 +1,5 @@ use chrono::TimeZone; -use lettre_email::{Address, Header, MimeMultipartType, PartBuilder}; +use lettre_email::{mime, Address, Header, MimeMultipartType, PartBuilder}; use crate::chat::{self, Chat}; use crate::config::Config; @@ -497,15 +497,31 @@ impl<'a, 'b> MimeFactory<'a, 'b> { unprotected_headers.push(Header::new_with_value("From".into(), vec![from]).unwrap()); let outer_message = if is_encrypted { + // Store protected headers in the inner message. for header in protected_headers.into_iter() { message = message.header(header); } + // Set the appropriate Content-Type for the inner message. + let mut existing_ct = message + .get_header("Content-Type".to_string()) + .and_then(|h| h.get_value::().ok()) + .unwrap_or_else(|| "text/plain; charset=utf-8;".to_string()); - let mut outer_message = PartBuilder::new().header(( + if !existing_ct.ends_with(';') { + existing_ct += ";"; + } + message = message.replace_header(Header::new( "Content-Type".to_string(), - "multipart/encrypted; protocol=\"application/pgp-encrypted\"".to_string(), + format!("{} protected-headers=\"v1\";", existing_ct), )); + // Set the appropriate Content-Type for the outer message + let mut outer_message = PartBuilder::new().header(( + "Content-Type".to_string(), + "multipart/encrypted; protocol=\"application/pgp-encrypted\";".to_string(), + )); + + // Store the unprotected headers on the outer message. for header in unprotected_headers.into_iter() { outer_message = outer_message.header(header); } @@ -531,7 +547,7 @@ impl<'a, 'b> MimeFactory<'a, 'b> { .unwrap(), ) .header(("Content-Description", "OpenPGP encrypted message")) - .header(("Content-Disposition", "inline; filename=\"encrypted.asc\"")) + .header(("Content-Disposition", "inline; filename=\"encrypted.asc\";")) .body(encrypted) .build(), ) diff --git a/src/mimeparser.rs b/src/mimeparser.rs index f0a90cfbe..96d788977 100644 --- a/src/mimeparser.rs +++ b/src/mimeparser.rs @@ -130,7 +130,10 @@ impl<'a> MimeParser<'a> { if let Some(raw) = raw { mail_raw = raw; + info!(context, "decrypted: {:?}", std::str::from_utf8(&mail_raw)); + let decrypted_mail = mailparse::parse_mail(&mail_raw)?; + // Decrypted the mail decrypted_mail } else { @@ -151,12 +154,13 @@ impl<'a> MimeParser<'a> { } }; + parser.parse_mime_recursive(&mail)?; + // Handle gossip headers let gossip_headers = mail.headers.get_all_values("Autocrypt-Gossip")?; parser.gossipped_addr = update_gossip_peerstates(context, message_time, &mail, gossip_headers)?; - parser.parse_mime_recursive(&mail)?; parser.parse_headers()?; Ok(parser) @@ -372,7 +376,10 @@ impl<'a> MimeParser<'a> { fn parse_mime_recursive(&mut self, mail: &mailparse::ParsedMail<'_>) -> Result { info!(self.context, "parse mime_recursive {:?}", mail.ctype); + if mail.ctype.params.get("protected-headers").is_some() { + info!(self.context, "found protected headers"); + if mail.ctype.mimetype == "text/rfc822-headers" { info!( self.context, @@ -381,9 +388,11 @@ impl<'a> MimeParser<'a> { return Ok(false); } - if !self.parsed_protected_headers { + if self.parsed_protected_headers { + warn!(self.context, "Ignoring nested protected headers"); + } else { self.hash_header(&mail.headers); - self.parsed_protected_headers; + self.parsed_protected_headers = true; } } @@ -884,7 +893,8 @@ fn update_gossip_peerstates( info!( context, - "Updating gossip peerstates: {:#?}", &gossip_headers + "Updating gossip peerstates: {}", + gossip_headers.len() ); for value in &gossip_headers { let gossip_header = value.parse::(); @@ -895,6 +905,7 @@ fn update_gossip_peerstates( recipients = Some(get_recipients(mail.headers.iter().filter_map(|v| { let key = v.get_key(); let value = v.get_value(); + info!(context, "header: {:?} - {:?}", key, value); if key.is_err() || value.is_err() { return None; } @@ -1143,6 +1154,19 @@ mod tests { assert_eq!(mimeparser.get_rfc724_mid(), None); } + #[test] + fn test_mailparse_content_type() { + let ctype = + mailparse::parse_content_type("text/plain; charset=utf-8; protected-headers=v1;"); + + assert_eq!(ctype.mimetype, "text/plain"); + assert_eq!(ctype.charset, "utf-8"); + assert_eq!( + ctype.params.get("protected-headers"), + Some(&"v1".to_string()) + ); + } + #[test] fn test_mimeparser_with_context() { let context = dummy_context();