Skip to content

Commit 11214c7

Browse files
authored
fix: Never allow a message timestamp to be a lot in the future (#5249)
We must finish what was started in #5088.
1 parent fba27ff commit 11214c7

File tree

1 file changed

+44
-12
lines changed

1 file changed

+44
-12
lines changed

src/mimeparser.rs

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -208,11 +208,12 @@ impl MimeMessage {
208208
) -> Result<Self> {
209209
let mail = mailparse::parse_mail(body)?;
210210

211-
let message_time = mail
211+
let timestamp_rcvd = smeared_time(context);
212+
let timestamp_sent = mail
212213
.headers
213214
.get_header_value(HeaderDef::Date)
214215
.and_then(|v| mailparse::dateparse(&v).ok())
215-
.unwrap_or_default();
216+
.map_or(timestamp_rcvd, |value| min(value, timestamp_rcvd + 60));
216217
let mut hop_info = parse_receive_headers(&mail.get_headers());
217218

218219
let mut headers = Default::default();
@@ -279,7 +280,7 @@ impl MimeMessage {
279280
let private_keyring = load_self_secret_keyring(context).await?;
280281

281282
let mut decryption_info =
282-
prepare_decryption(context, &mail, &from.addr, message_time).await?;
283+
prepare_decryption(context, &mail, &from.addr, timestamp_sent).await?;
283284

284285
// Memory location for a possible decrypted message.
285286
let mut mail_raw = Vec::new();
@@ -325,7 +326,7 @@ impl MimeMessage {
325326
let gossip_headers = mail.headers.get_all_values("Autocrypt-Gossip");
326327
gossiped_keys = update_gossip_peerstates(
327328
context,
328-
message_time,
329+
timestamp_sent,
329330
&from.addr,
330331
&recipients,
331332
gossip_headers,
@@ -376,12 +377,12 @@ impl MimeMessage {
376377

377378
// If it is not a read receipt, degrade encryption.
378379
if let (Some(peerstate), Ok(mail)) = (&mut decryption_info.peerstate, mail) {
379-
if message_time > peerstate.last_seen_autocrypt
380+
if timestamp_sent > peerstate.last_seen_autocrypt
380381
&& mail.ctype.mimetype != "multipart/report"
381382
// Disallowing keychanges is disabled for now:
382383
// && decryption_info.dkim_results.allow_keychange
383384
{
384-
peerstate.degrade_encryption(message_time);
385+
peerstate.degrade_encryption(timestamp_sent);
385386
}
386387
}
387388
}
@@ -395,12 +396,6 @@ impl MimeMessage {
395396
}
396397
}
397398

398-
let timestamp_rcvd = smeared_time(context);
399-
let timestamp_sent = headers
400-
.get(HeaderDef::Date.get_headername())
401-
.and_then(|value| mailparse::dateparse(value).ok())
402-
.map_or(timestamp_rcvd, |value| min(value, timestamp_rcvd + 60));
403-
404399
let mut parser = MimeMessage {
405400
parts: Vec::new(),
406401
headers,
@@ -2237,6 +2232,7 @@ mod tests {
22372232
message::{Message, MessageState, MessengerMessage},
22382233
receive_imf::receive_imf,
22392234
test_utils::TestContext,
2235+
tools::time,
22402236
};
22412237

22422238
impl AvatarAction {
@@ -3849,4 +3845,40 @@ Content-Disposition: reaction\n\
38493845

38503846
Ok(())
38513847
}
3848+
3849+
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
3850+
async fn test_time_in_future() -> Result<()> {
3851+
let alice = TestContext::new_alice().await;
3852+
3853+
let beginning_time = time();
3854+
3855+
// Receive a message with a date far in the future (year 3004)
3856+
// I'm just going to assume that no one uses this code after the year 3000
3857+
let mime_message = MimeMessage::from_bytes(
3858+
&alice,
3859+
b"To: alice@example.org\n\
3860+
From: bob@example.net\n\
3861+
Date: Today, 29 February 3004 00:00:10 -800\n\
3862+
Message-ID: 56789@example.net\n\
3863+
Subject: Meeting\n\
3864+
Mime-Version: 1.0 (1.0)\n\
3865+
Content-Type: text/plain; charset=utf-8\n\
3866+
\n\
3867+
Hi",
3868+
None,
3869+
)
3870+
.await?;
3871+
3872+
// We do allow the time to be in the future a bit (because of unsynchronized clocks),
3873+
// but only 60 seconds:
3874+
assert!(mime_message.decryption_info.message_time <= time() + 60);
3875+
assert!(mime_message.decryption_info.message_time >= beginning_time + 60);
3876+
assert_eq!(
3877+
mime_message.decryption_info.message_time,
3878+
mime_message.timestamp_sent
3879+
);
3880+
assert!(mime_message.timestamp_rcvd <= time());
3881+
3882+
Ok(())
3883+
}
38523884
}

0 commit comments

Comments
 (0)