diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index 3620eac35..d401c7def 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -2324,4 +2324,52 @@ mod tests { "Carl" ); } + + #[async_std::test] + async fn test_parse_ndn() { + let t = dummy_context().await; + t.ctx + .set_config(Config::Addr, Some("alice@example.org")) + .await + .unwrap(); + t.ctx + .set_config(Config::ConfiguredAddr, Some("alice@example.org")) + .await + .unwrap(); + t.ctx + .set_config(Config::Configured, Some("1")) + .await + .unwrap(); + + dc_receive_imf( + &t.ctx, + b"From: alice@example.org\n\ + To: assidhfaaspocwaeofi@gmail.com\n\ + Subject: foo\n\ + Message-ID: \n\ + Chat-Version: 1.0\n\ + Chat-Disposition-Notification-To: alice@example.org\n\ + Date: Sun, 22 Mar 2020 22:37:57 +0000\n\ + \n\ + hello\n", + "INBOX", + 1, + false, + ) + .await + .unwrap(); + + let chats = Chatlist::try_load(&t.ctx, 0, None, None).await.unwrap(); + let msg_id = chats.get_msg_id(0).unwrap(); + + let raw = include_bytes!("../test-data/message/gmail_ndn.eml"); + dc_receive_imf(&t.ctx, raw, "INBOX", 1, false) + .await + .unwrap(); + + assert_eq!( + Message::load_from_db(&t.ctx, msg_id).await.unwrap().state, + MessageState::OutFailed + ); + } } diff --git a/src/message.rs b/src/message.rs index 1c77b4017..2c539695f 100644 --- a/src/message.rs +++ b/src/message.rs @@ -1384,6 +1384,28 @@ pub async fn mdn_from_ext( None } +pub async fn ndn_from_ext( + context: &Context, + from_id: u32, + rfc724_mid: &str, + error: impl AsRef, +) { + if from_id <= DC_MSG_ID_LAST_SPECIAL || rfc724_mid.is_empty() { + return; + } + + match rfc724_mid_exists(context, rfc724_mid).await { + Ok(Some((_, _, msg_id))) => { + set_msg_failed(context, msg_id, Some(error)).await; + } + Ok(None) => info!( + context, + "Failed to select NDN, could not find failed msg {}", rfc724_mid + ), + Err(e) => info!(context, "Failed to select NDN {:?}", e), + } +} + /// The number of messages assigned to real chat (!=deaddrop, !=trash) pub async fn get_real_msg_cnt(context: &Context) -> i32 { match context diff --git a/src/mimeparser.rs b/src/mimeparser.rs index 17883e137..b5e0bcaf5 100644 --- a/src/mimeparser.rs +++ b/src/mimeparser.rs @@ -54,6 +54,7 @@ pub struct MimeMessage { pub(crate) user_avatar: Option, pub(crate) group_avatar: Option, pub(crate) reports: Vec, + pub(crate) failed_msg: Option, } #[derive(Debug, PartialEq)] @@ -182,6 +183,7 @@ impl MimeMessage { message_kml: None, user_avatar: None, group_avatar: None, + failed_msg: None, }; parser.parse_mime_recursive(context, &mail).await?; parser.parse_headers(context)?; @@ -550,8 +552,8 @@ impl MimeMessage { (mime::MULTIPART, "report") => { /* RFC 6522: the first part is for humans, the second for machines */ if mail.subparts.len() >= 2 { - if let Some(report_type) = mail.ctype.params.get("report-type") { - if report_type == "disposition-notification" { + match mail.ctype.params.get("report-type").map(|s| s as &str) { + Some("disposition-notification") => { if let Some(report) = self.process_report(context, mail)? { self.reports.push(report); } @@ -565,13 +567,24 @@ impl MimeMessage { self.parts.push(part); any_part_added = true; - } else { - /* eg. `report-type=delivery-status`; - maybe we should show them as a little error icon */ + } + Some("delivery-status") => { + if let Some(report) = self.process_delivery_status(context, mail)? { + self.failed_msg = Some(report); + } + + let mut part = Part::default(); + part.typ = Viewtype::Unknown; + self.parts.push(part); + + any_part_added = true; + } + Some(_) => { if let Some(first) = mail.subparts.iter().next() { any_part_added = self.parse_mime_recursive(context, first).await?; } } + None => {} } } } @@ -842,10 +855,6 @@ impl MimeMessage { /// Handle reports (only MDNs for now) pub async fn handle_reports(&self, context: &Context, from_id: u32, sent_timestamp: i64) { - if self.reports.is_empty() { - return; - } - for report in &self.reports { for original_message_id in std::iter::once(&report.original_message_id).chain(&report.additional_message_ids) @@ -858,6 +867,41 @@ impl MimeMessage { } } } + + if let Some(original_message_id) = &self.failed_msg { + message::ndn_from_ext(context, from_id, original_message_id, "TODO error message").await + } + } + + fn process_delivery_status( + &self, + context: &Context, + report: &mailparse::ParsedMail<'_>, + ) -> Result> { + // parse as mailheaders + if let Some(original_msg) = report + .subparts + .iter() + .find(|p| p.ctype.mimetype == "message/rfc822") + { + let report_body = original_msg.get_body_raw()?; + let (report_fields, _) = mailparse::parse_headers(&report_body)?; + + if let Some(original_message_id) = report_fields + .get_header_value(HeaderDef::MessageId) + .and_then(|v| parse_message_id(&v).ok()) + { + return Ok(Some(original_message_id)); + } + + warn!( + context, + "ignoring unknown ndn-notification, Message-Id: {:?}", + report_fields.get_header_value(HeaderDef::MessageId) + ); + } + + Ok(None) } } diff --git a/test-data/message/gmail_ndn.eml b/test-data/message/gmail_ndn.eml new file mode 100644 index 000000000..f73ff115a --- /dev/null +++ b/test-data/message/gmail_ndn.eml @@ -0,0 +1,242 @@ +Delivered-To: alice@gmail.com +Received: by 2002:a1c:b4d7:0:0:0:0:0 with SMTP id d206csp3026053wmf; + Mon, 18 May 2020 09:23:25 -0700 (PDT) +X-Received: by 2002:a5d:4651:: with SMTP id j17mr19532177wrs.50.1589819005555; + Mon, 18 May 2020 09:23:25 -0700 (PDT) +ARC-Seal: i=1; a=rsa-sha256; t=1589819005; cv=none; + d=google.com; s=arc-20160816; + b=IZbNnzzuYzTFuqfuZwpd3ehqpYYGpn31c8DsfGbQ8rpbS0OTTROkVYvihQl8Ne/8X/ + brEWsrcmaCh9WpFMzpI+cp/TY39uusnI6qdp5rcgrFmFgoANtwf3TBBj1+f7wBPn46BP + dQOUsg/J8KVfvzVgvL1x4uyJ0m9QirDgJeJ/BvrswbTleRQK7oY3fIireUCDxj6r2lCB + 1Z0TKw1mgIb1LiFMZz8kvCNn3R4KSFnwS8rIju0hYwnsioNiExVQgumXL+RVkEZ9BMzf + UdoWIAw3VW+MOZFTpfLCEfgIPtLg/gtE0Q1P+a3KKpi8dkPiV2n6DGMecy9lTLtdhCXt + pnaA== +ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; + h=in-reply-to:references:subject:from:date:message-id:auto-submitted + :to:dkim-signature; + bh=5xjZvcHbEGbMY0K2QB+3U6tpm1L1LAVv5h1pd4YXDEE=; + b=nNP0DktrSjdBaFfhhoDi2O9KVKM0iXE5ZgubQ0q0ff68Z6Ke7c8dDBXEsZoToI0s4Y + w90KyJFpgMJLFmP3iVDRqCfohi2y1HGdWg5VXQPTvzM7+YozZRlbNNV9UsuyRY91CXrJ + a2XREBgB+LPMGQivwcHtUMZfyNv/4uiwWivk+92ySNDhxqOiDt4R5Jak/7RkZMFwQpsE + JGwk6asM6VqZlihkF24lKv3pPaob6feyX3wD5N0+Mqiy1kQTj2JkpQk6nkTmdf0gapZe + fOhU1NkbNfbuS3U7m2gEUiyktE+MhV/MgAzgBhm9bgNt2gQLVWju8rHkPndfv1PDmEkC + FsYQ== +ARC-Authentication-Results: i=1; mx.google.com; + dkim=pass header.i=@googlemail.com header.s=20161025 header.b=dPisws+O; + spf=pass (google.com: best guess record for domain of postmaster@mail-sor-f69.google.com designates 209.85.220.69 as permitted sender) smtp.helo=mail-sor-f69.google.com; + dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=googlemail.com +Return-Path: <> +Received: from mail-sor-f69.google.com (mail-sor-f69.google.com. [209.85.220.69]) + by mx.google.com with SMTPS id s18sor5584435wrb.25.2020.05.18.09.23.25 + for + (Google Transport Security); + Mon, 18 May 2020 09:23:25 -0700 (PDT) +Received-SPF: pass (google.com: best guess record for domain of postmaster@mail-sor-f69.google.com designates 209.85.220.69 as permitted sender) client-ip=209.85.220.69; +Authentication-Results: mx.google.com; + dkim=pass header.i=@googlemail.com header.s=20161025 header.b=dPisws+O; + spf=pass (google.com: best guess record for domain of postmaster@mail-sor-f69.google.com designates 209.85.220.69 as permitted sender) smtp.helo=mail-sor-f69.google.com; + dmarc=pass (p=QUARANTINE sp=QUARANTINE dis=NONE) header.from=googlemail.com +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=googlemail.com; s=20161025; + h=to:auto-submitted:message-id:date:from:subject:references + :in-reply-to; + bh=5xjZvcHbEGbMY0K2QB+3U6tpm1L1LAVv5h1pd4YXDEE=; + b=dPisws+OwGFyOy0a612XYZgvz5T71GcJRJtU068/Tce8vN/+ggIQtUsZnZtsphe71v + 2NvfP9ULxR4cXvomTvhrYAk19KdxN/S7SeyBbmXv3x/tg+DBVCmmPS/6RXrcl6Ms3Hkw + uPFQ9S3KcvHe/2bcb5LSTA/stIP4tuxxAXvsX2j+MjPYPWKAl50jkSbWK98U0Q0U+MTl + pKaaC9s9iEBafac8BFZCy4DfpumKlemNEyRa3cSV2hw+DYHKA5peModrK1A2tcsfstFF + rZi8yF/D90RIFbE04DI2QCxB3trsChNF1aYF06aSzI//wsfM1+lb+uGPi0YVkw3n4HrX + Xw4w== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20161025; + h=x-gm-message-state:to:auto-submitted:message-id:date:from:subject + :references:in-reply-to; + bh=5xjZvcHbEGbMY0K2QB+3U6tpm1L1LAVv5h1pd4YXDEE=; + b=A/NCOtgbpA7VzB1G7ZFo8TA2FfrjuqjGdwMrJr3yXe21FrBFwzssprJwOkynqoVLkK + iJU7uMF/KTcQPDEmOLFThzFfe5GCx7eJtZPhwY+FbBlC5sq4I55/xaQLd0gOZ1BYXwMn + 2bk169d2aoukbaLbGSQZF3d9atd+/e48YzkRxpmUoLcrWk2LcHAeQIG7SgT9pfX5DKPr + VpxM5/GMVEBbTRhBIWCeVSfpYCs80l0xEeTC3/B5lzpzMVDE8QCW6Dwh75b4Tb2K6yru + Zsy5ZpRmwv0wrkrb2vM+pl4IMkaF7s8XosIvlIT++fQV5xDFItT4atpykZvSDB92RKV0 + 8lEA== +X-Gm-Message-State: AOAM532RG/PT3ChZHBCDORGLtAjKvX8TGBuOy+AxrnEaJT6v1ieb+VV1 + +ejly+/6UthxHYlkOJYAszCSgL4dKVFotoVaN7LhEA== +X-Google-Smtp-Source: ABdhPJz6veVKWhomCL4gK+whrybuMzHCDCq8AowgQvi7sobpMoM/k9CDw79jo1j3OUcTz6MEeUYLxEXuNIuu4zyoS7kVtsUYryGFHAI= +X-Received: by 2002:a5d:5183:: with SMTP id k3mr20545185wrv.159.1589819005394; + Mon, 18 May 2020 09:23:25 -0700 (PDT) +Content-Type: multipart/report; boundary="00000000000012d63005a5ee9520"; report-type=delivery-status +To: alice@gmail.com +Received: by 2002:a5d:5183:: with SMTP id k3mr13704211wrv.159; Mon, 18 May + 2020 09:23:25 -0700 (PDT) +Return-Path: <> +Auto-Submitted: auto-replied +Message-ID: <5ec2b67d.1c69fb81.213af.67a5.GMR@mx.google.com> +Date: Mon, 18 May 2020 09:23:25 -0700 (PDT) +From: Mail Delivery Subsystem +Subject: Delivery Status Notification (Failure) +References: +In-Reply-To: +X-Failed-Recipients: assidhfaaspocwaeofi@gmail.com + +--00000000000012d63005a5ee9520 +Content-Type: multipart/related; boundary="00000000000012dc0005a5ee952f" + +--00000000000012dc0005a5ee952f +Content-Type: multipart/alternative; boundary="00000000000012dc0705a5ee9530" + +--00000000000012dc0705a5ee9530 +Content-Type: text/plain; charset="UTF-8" + + +** Die Adresse wurde nicht gefunden ** + +Ihre Nachricht wurde nicht an assidhfaaspocwaeofi@gmail.com zugestellt, weil die Adresse nicht gefunden wurde oder keine E-Mails empfangen kann. + +Hier erfahren Sie mehr: https://support.google.com/mail/?p=NoSuchUser + +Antwort: + +550 5.1.1 The email account that you tried to reach does not exist. Please try double-checking the recipient's email address for typos or unnecessary spaces. Learn more at https://support.google.com/mail/?p=NoSuchUser i18sor6261697wrs.38 - gsmtp + +--00000000000012dc0705a5ee9530 +Content-Type: text/html; charset="UTF-8" + + + + + + + + + + + + + + + + +--00000000000012dc0705a5ee9530-- +--00000000000012dc0005a5ee952f +Content-Type: image/png; name="icon.png" +Content-Disposition: attachment; filename="icon.png" +Content-Transfer-Encoding: base64 +Content-ID: + +iVBORw0KGgoAAAANSUhEUgAAAJAAAACQCAYAAADnRuK4AAAACXBIWXMAABYlAAAWJQFJUiTwAAAA +GXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAABTdJREFUeNrsnD9sFEcUh5+PRMqZ +yA0SPhAUQAQFUkyTgiBASARo6QApqVIkfdxGFJFSgGhJAUIiBaQB0ZIOKVCkwUgURjIg2fxL4kS+ +YDvkbC/388bi8N16Z4/d7J/5PsniuD3fyePP772ZeTsDQRAYQL/UGAJAIEAgQCBAIAAEAgQCBAIE +AkAgyJT3Mv+Eq7vYK8mTE+MDRCAghQECAeRQA5V2ZOpmg5vDx3NPzRbmGRMEcmTrEbNNB8zWfRD+ +f/Efs2e3zCZvMjaksBg27TfbcuSNPEKP9ZyuAQKtHX2O9ncNgWC57umMPKvRNb0GEKgnLoUyxTQC +rcns0/6uIRAs8/hGf9cQCJZpTpjdO2f25/03z+mxntM1eLtsZAgiUtX4JcaBCAQIBAgECARQ8CJa +G5jab4J4pm4WZmO3OALVh802fIwcLkyPkcKAGggAgQCBAIEAgQCBABAIEAjKA/1AnahhbO5FdOOY +VsrrDbPBYcYKgf5D2wLaV3p+22xh1u17tO3S+DTcvxvagUDeivPgx/a/95J/73w7Sj26Hn4pKo2M +ehuV/KyBJM6d0f7k6RKx/R63vvL2tmf/ItDdM2ZTP6f7nkp9Y2fDx1v9akmpIU+KSCLVUghUQfSL +zVKeTklbLxGoctw/nzC5rw8L5KRNbkpnKq6pgSqEClzNnFzY+XnYWrt6VpVk1vbwWvg+RKCKMOUw +Q1LEOXA+/MX3mpJvGDHb265xtnzmFoUK1HaKQGlMtePYM+q2KKjXuaS1NJYIEKgI8jhEgqHt4cqy +Ky53j3hyHz2bqSLp2o2LbJ7MxKovkGqXteoWpaOk96O9/yF/dF7NwlS36AuIQIBA5celQK4PIxBE +4LLzrtoLgaALdSy6CJRkWQCBPGLsTHznomZ9nszUECgJ2ml3WWHe+QVFNPSQx6UdZNtxr9pbEShN +eTTz8mQXHoHSlke7+Z+c9m6VGoHSkEfs/trLW3wQKApN1V3lGfnGu2Z6BFoLtYCs3GWBPAiUCLVh +/HoaeRCoT9R873KLM/IgUBfapnCpe5AHgXry4pf412ihEHkQqCdxd5VqrcezhUIESsJMTJ+Pdthp +Z0WgyNlXXPHc2Mc4IVAELl2Gnh8mhUDvCkfbIVAkcbf/aOoO3fMKhqAD3frTa4quwpn0hUDOkQhI +YYBAgECAQAAU0QlYObl+5Ug8NcprZkZxjUCxRPVA6zmtEXHCBykskrhjgHXN09PoEcgFl4M4H11j +nBAoApcj6ZoPGScEAgTKApcDoTw5sgWB+sGlz1n90IBAPdE6j1o21PfcC11jLagL1oFWRyGlKU3p +OxcSJQ7NZAjkhHp/uG2HFAYIBAgECASAQIBAgECAQAAIBOkxEARBtp9wdVfAMOfIifEBIhCQwgCB +ABAI0oV2jhxZ+nfBatuPZfgBCy0Eqqo8c01b+uu51XZvzOgDWoHNTGR+pCwpLEd5svuAZXlO2uEr +PyEQ8hRWHgRCHmqg0sjTnLalv6crJQ8C/U8stqNO0I4+VZOHFIY8COS1PGL2ybd5yUMKK7s8zYmL +dujyd3n+nESgcsvzZd4/KwIhDwIhT35QA6UyE1qyxZnfvJMHgdKS549JC1qvvJOHFIY8CFR5eV5O +XimqPAhUdHnmfx+zgxdOFXkoqIGKKs/cswnb/8Oeog8HEai48nxUhiFBIORBIOShBioskkbySCLk +IQIhDwIhj28p7FApR6b1qlEbHGpkO/rr6215vi/zH1r2x7tApSGFAQIBAgECAQIBIBAgECAQIBBA +LK8FGADCTxYrr+EVJgAAAABJRU5ErkJggg== +--00000000000012dc0005a5ee952f-- +--00000000000012d63005a5ee9520 +Content-Type: message/delivery-status + +Reporting-MTA: dns; googlemail.com +Arrival-Date: Mon, 18 May 2020 09:23:25 -0700 (PDT) +X-Original-Message-ID: + +Final-Recipient: rfc822; assidhfaaspocwaeofi@gmail.com +Action: failed +Status: 5.1.1 +Diagnostic-Code: smtp; 550-5.1.1 The email account that you tried to reach does not exist. Please try + 550-5.1.1 double-checking the recipient's email address for typos or + 550-5.1.1 unnecessary spaces. Learn more at + 550 5.1.1 https://support.google.com/mail/?p=NoSuchUser i18sor6261697wrs.38 - gsmtp +Last-Attempt-Date: Mon, 18 May 2020 09:23:25 -0700 (PDT) + +--00000000000012d63005a5ee9520 +Content-Type: message/rfc822 + +DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=gmail.com; s=20161025; + h=mime-version:from:date:message-id:subject:to; + bh=gtlm3j0shCgZYOVxUt74zkQ69Zq+GTQeHeXLfMlrhlk=; + b=a185ogBcMzF9whNVWvuyUoUunNZk3Vc1kEIFmPkX0IxLpAFcI+fOQajOSromGl7Oyi + yecLwQevpww2Xd0XjZ3UkZvrI9m9koRmh0QeoHvgTRORiVwj08+PVc3N4F9bCO4w9i0J + ir7SSsJqBCDovoIFSFDyNa64vs6Nxno0cH/DaPG7pVTdD+3jfB7nLXIsMQYeX+1eP6rB + UhKxH82r7Mh9CI2PWDQpVtGj63AMUEyHgE9Ou08PWbbKjrQOasoG3Tw8tB1GoN1XYssM + rxOTgWEoTiduZ35AUH6h+eChOn9OHuI3SPECcVob70Qndayia3dMKfHMO6sEx9J0Wpic + 29vg== +X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; + d=1e100.net; s=20161025; + h=x-gm-message-state:mime-version:from:date:message-id:subject:to; + bh=gtlm3j0shCgZYOVxUt74zkQ69Zq+GTQeHeXLfMlrhlk=; + b=miGIfL5BgnkD3wQvS34RtGwRRoh+8gJT5sFFfdX/hVyG/dvjXfdwP4yyNWr8ox8iY2 + BLlahS4y4VGcbG1e2aYjurnWNytGu6utQcZax/uUngJ0bTOwXW1VaIiEZtqd6gTV+8d/ + rrfQ459+4vXqIoQf0+Oi/U6dWwgJvPPjjRiToWdF3vIJE8R1iTRdZbW4lkgxSADbmskg + noT/gWGWblHtR6uuGuKGJ3bkhJKCBnjavKh0LlbWEeFBZfmVNPRvzEFWHjBDdu5wvSL5 + 0QJ+Qn0Orfn5CJuN3xPfzT1S2rI2iYZx37KX9zyMnZEx0ilkTYqCtBPWkrXRYDSXcxYS + Y1ag== +X-Gm-Message-State: AOAM531vhwpXiK8M12286dOJx0Q5fBl9ZaH6BJKts93GoxvPv0xdryP0 + jg9wYmoP5MUHudsxAMCYDFsCUMVx2PEywyIsaQqklw== +X-Google-Smtp-Source: ABdhPJxlVJtTODM3pZZSTbbpAAAQRU8XbmuosDF9fgQZmVwxGZSzRWl22o+moppVRU/r8xMAyf0r3+qXwEBe1vZfjZo= +X-Received: by 2002:a5d:5183:: with SMTP id k3mr20545162wrv.159.1589819005034; + Mon, 18 May 2020 09:23:25 -0700 (PDT) +MIME-Version: 1.0 +From: +Date: Mon, 18 May 2020 18:23:39 +0200 +Message-ID: +Subject: Kommt sowieso nicht an +To: assidhfaaspocwaeofi@gmail.com +Content-Type: multipart/alternative; boundary="0000000000000d652a05a5ee95df" + +--0000000000000d652a05a5ee95df +Content-Type: text/plain; charset="UTF-8" + +Wollte nur was testen + +--0000000000000d652a05a5ee95df +Content-Type: text/html; charset="UTF-8" + +
Wollte nur was testen
+ +--0000000000000d652a05a5ee95df-- + +--00000000000012d63005a5ee9520--