Skip to content

Commit 67f768f

Browse files
committed
refactor: use mail-builder instead of lettre_email
1 parent 82ea4e2 commit 67f768f

File tree

13 files changed

+544
-853
lines changed

13 files changed

+544
-853
lines changed

Cargo.lock

Lines changed: 68 additions & 264 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@ brotli = { version = "7", default-features=false, features = ["std"] }
5050
bytes = "1"
5151
chrono = { workspace = true, features = ["alloc", "clock", "std"] }
5252
data-encoding = "2.7.0"
53-
email = { git = "https://github.com/deltachat/rust-email", branch = "master" }
5453
encoded-words = "0.2"
5554
escaper = "0.1"
5655
fast-socks5 = "0.10"
@@ -67,8 +66,8 @@ image = { version = "0.25.5", default-features=false, features = ["gif", "jpeg",
6766
iroh-gossip = { version = "0.32", default-features = false, features = ["net"] }
6867
iroh = { version = "0.32", default-features = false }
6968
kamadak-exif = "0.6.1"
70-
lettre_email = { git = "https://github.com/deltachat/lettre", branch = "master" }
7169
libc = { workspace = true }
70+
mail-builder = { git = "https://github.com/stalwartlabs/mail-builder", branch = "main", default-features = false }
7271
mailparse = "0.16"
7372
mime = "0.3.17"
7473
num_cpus = "1.16"

deny.toml

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,12 @@
11
[advisories]
22
ignore = [
3-
"RUSTSEC-2020-0071",
4-
53
# Timing attack on RSA.
64
# Delta Chat does not use RSA for new keys
75
# and this requires precise measurement of the decryption time by the attacker.
86
# There is no fix at the time of writing this (2023-11-28).
97
# <https://rustsec.org/advisories/RUSTSEC-2023-0071>
108
"RUSTSEC-2023-0071",
119

12-
# Unmaintained encoding
13-
"RUSTSEC-2021-0153",
14-
1510
# Unmaintained instant
1611
"RUSTSEC-2024-0384",
1712

@@ -32,16 +27,12 @@ skip = [
3227
{ name = "core-foundation", version = "0.9.4" },
3328
{ name = "event-listener", version = "2.5.3" },
3429
{ name = "generator", version = "0.7.5" },
35-
{ name = "getrandom", version = "<0.2" },
3630
{ name = "http", version = "0.2.12" },
3731
{ name = "loom", version = "0.5.6" },
3832
{ name = "netlink-packet-route", version = "0.17.1" },
3933
{ name = "nix", version = "0.26.4" },
4034
{ name = "nix", version = "0.27.1" },
4135
{ name = "quick-error", version = "<2.0" },
42-
{ name = "rand_chacha", version = "<0.3" },
43-
{ name = "rand_core", version = "<0.6" },
44-
{ name = "rand", version = "<0.8" },
4536
{ name = "redox_syscall", version = "0.3.5" },
4637
{ name = "regex-automata", version = "0.1.10" },
4738
{ name = "regex-syntax", version = "0.6.29" },
@@ -51,11 +42,9 @@ skip = [
5142
{ name = "syn", version = "1.0.109" },
5243
{ name = "thiserror-impl", version = "1.0.69" },
5344
{ name = "thiserror", version = "1.0.69" },
54-
{ name = "time", version = "<0.3" },
5545
{ name = "tokio-tungstenite", version = "0.21.0" },
5646
{ name = "tungstenite", version = "0.21.0" },
5747
{ name = "unicode-width", version = "0.1.11" },
58-
{ name = "wasi", version = "<0.11" },
5948
{ name = "windows" },
6049
{ name = "windows_aarch64_gnullvm" },
6150
{ name = "windows_aarch64_msvc" },
@@ -102,5 +91,5 @@ license-files = [
10291
[sources.allow-org]
10392
# Organisations which we allow git sources from.
10493
github = [
105-
"deltachat",
94+
"stalwartlabs",
10695
]

src/chat.rs

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
use std::cmp;
44
use std::collections::{HashMap, HashSet};
55
use std::fmt;
6+
use std::io::Cursor;
67
use std::marker::Sync;
78
use std::path::{Path, PathBuf};
89
use std::str::FromStr;
@@ -11,6 +12,7 @@ use std::time::Duration;
1112
use anyhow::{anyhow, bail, ensure, Context as _, Result};
1213
use deltachat_contact_tools::{sanitize_bidi_characters, sanitize_single_line, ContactAddress};
1314
use deltachat_derive::{FromSql, ToSql};
15+
use mail_builder::mime::MimePart;
1416
use serde::{Deserialize, Serialize};
1517
use strum_macros::EnumIter;
1618
use tokio::task;
@@ -32,7 +34,6 @@ use crate::debug_logging::maybe_set_logging_xdc;
3234
use crate::download::DownloadState;
3335
use crate::ephemeral::{start_chat_ephemeral_timers, Timer as EphemeralTimer};
3436
use crate::events::EventType;
35-
use crate::html::new_html_mimepart;
3637
use crate::location;
3738
use crate::log::LogExt;
3839
use crate::message::{self, Message, MessageState, MsgId, Viewtype};
@@ -2157,14 +2158,18 @@ impl Chat {
21572158
} else {
21582159
None
21592160
};
2160-
let new_mime_headers = new_mime_headers.map(|s| new_html_mimepart(s).build().as_string());
2161+
let new_mime_headers: Option<String> = new_mime_headers.map(|s| {
2162+
let html_part = MimePart::new("text/html", s);
2163+
let mut buffer = Vec::new();
2164+
let cursor = Cursor::new(&mut buffer);
2165+
html_part.write_part(cursor).ok();
2166+
String::from_utf8_lossy(&buffer).to_string()
2167+
});
21612168
let new_mime_headers = new_mime_headers.or_else(|| match was_truncated {
21622169
// We need to add some headers so that they are stripped before formatting HTML by
21632170
// `MsgId::get_html()`, not a part of the actual text. Let's add "Content-Type", it's
21642171
// anyway a useful metadata about the stored text.
2165-
true => Some(
2166-
"Content-Type: text/plain; charset=utf-8\r\n\r\n".to_string() + &msg.text + "\r\n",
2167-
),
2172+
true => Some("Content-Type: text/plain; charset=utf-8\r\n\r\n".to_string() + &msg.text),
21682173
false => None,
21692174
});
21702175
let new_mime_headers = match new_mime_headers {

src/contact.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,16 @@ pub async fn make_vcard(context: &Context, contacts: &[ContactId]) -> Result<Str
247247
timestamp: Ok(now),
248248
});
249249
}
250-
Ok(contact_tools::make_vcard(&vcard_contacts))
250+
251+
// XXX: newline at the end of vCard is trimmed
252+
// for compatibility with core <=1.155.3
253+
// Newer core should be able to deal with
254+
// trailing CRLF as the fix
255+
// <https://github.com/deltachat/deltachat-core-rust/pull/6522>
256+
// is merged.
257+
Ok(contact_tools::make_vcard(&vcard_contacts)
258+
.trim_end()
259+
.to_string())
251260
}
252261

253262
/// Imports contacts from the given vCard.

src/e2ee.rs

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
//! End-to-end encryption support.
22
3+
use std::io::Cursor;
4+
35
use anyhow::{format_err, Context as _, Result};
6+
use mail_builder::mime::MimePart;
47
use num_traits::FromPrimitive;
58

69
use crate::aheader::{Aheader, EncryptPreference};
@@ -95,7 +98,7 @@ impl EncryptHelper {
9598
self,
9699
context: &Context,
97100
verified: bool,
98-
mail_to_encrypt: lettre_email::PartBuilder,
101+
mail_to_encrypt: MimePart<'static>,
99102
peerstates: Vec<(Option<Peerstate>, String)>,
100103
compress: bool,
101104
) -> Result<String> {
@@ -136,7 +139,9 @@ impl EncryptHelper {
136139

137140
let sign_key = load_self_secret_key(context).await?;
138141

139-
let raw_message = mail_to_encrypt.build().as_string().into_bytes();
142+
let mut raw_message = Vec::new();
143+
let cursor = Cursor::new(&mut raw_message);
144+
mail_to_encrypt.clone().write_part(cursor).ok();
140145

141146
let ctext = pgp::pk_encrypt(&raw_message, keyring, Some(sign_key), compress).await?;
142147

@@ -145,15 +150,13 @@ impl EncryptHelper {
145150

146151
/// Signs the passed-in `mail` using the private key from `context`.
147152
/// Returns the payload and the signature.
148-
pub async fn sign(
149-
self,
150-
context: &Context,
151-
mail: lettre_email::PartBuilder,
152-
) -> Result<(lettre_email::MimeMessage, String)> {
153+
pub async fn sign(self, context: &Context, mail: &MimePart<'static>) -> Result<String> {
153154
let sign_key = load_self_secret_key(context).await?;
154-
let mime_message = mail.build();
155-
let signature = pgp::pk_calc_signature(mime_message.as_string().as_bytes(), &sign_key)?;
156-
Ok((mime_message, signature))
155+
let mut buffer = Vec::new();
156+
let cursor = Cursor::new(&mut buffer);
157+
mail.clone().write_part(cursor).ok();
158+
let signature = pgp::pk_calc_signature(&buffer, &sign_key)?;
159+
Ok(signature)
157160
}
158161
}
159162

src/html.rs

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@ use std::mem;
1111

1212
use anyhow::{Context as _, Result};
1313
use base64::Engine as _;
14-
use lettre_email::mime::Mime;
15-
use lettre_email::PartBuilder;
1614
use mailparse::ParsedContentType;
15+
use mime::Mime;
1716

1817
use crate::context::Context;
1918
use crate::headerdef::{HeaderDef, HeaderDefMap};
@@ -277,16 +276,6 @@ impl MsgId {
277276
}
278277
}
279278

280-
/// Wraps HTML text into a new text/html mimepart structure.
281-
///
282-
/// Used on forwarding messages to avoid leaking the original mime structure
283-
/// and also to avoid sending too much, maybe large data.
284-
pub fn new_html_mimepart(html: String) -> PartBuilder {
285-
PartBuilder::new()
286-
.content_type(&"text/html; charset=utf-8".parse::<mime::Mime>().unwrap())
287-
.body(html)
288-
}
289-
290279
#[cfg(test)]
291280
mod tests {
292281
use super::*;

0 commit comments

Comments
 (0)