Compare commits

..

5 Commits

Author SHA1 Message Date
iequidoo
287d730556 chore: Apply rustmft after the previous commit 2026-04-26 12:04:18 -03:00
iequidoo
82bb77b056 feat: Drop support for replacing partial download stubs 2026-04-26 12:04:18 -03:00
Hocuri
aa1f129a48 refactor: Use self_fingerprint() where it makes sense (#8174) 2026-04-26 09:36:08 +02:00
Hocuri
0ad58f7a59 test: Remove unused test data related to Authentication-Result parsing (#8175)
Follow-up to https://github.com/chatmail/core/pull/8172
2026-04-26 09:35:45 +02:00
iequidoo
6d61f7e071 fix: Don't receive message if a deletion request was received before (#8143)
There's no check for `from_id` so another group member can delete the
message, but this can only happen in case of message reordering and the
problem already exists for usual messages, so we may ignore it and
overall a group represents a scope of trust.

Co-authored-by: Hocuri <hocuri@gmx.de>
2026-04-25 21:19:03 -03:00
330 changed files with 139 additions and 2778 deletions

View File

@@ -2541,7 +2541,7 @@ pub unsafe extern "C" fn dc_send_locations_to_chat(
}
let ctx = &*context;
block_on(location::send_to_chat(
block_on(location::send_locations_to_chat(
ctx,
ChatId::new(chat_id),
seconds as i64,
@@ -2561,14 +2561,14 @@ pub unsafe extern "C" fn dc_is_sending_locations_to_chat(
return 0;
}
let ctx = &*context;
if chat_id == 0 {
block_on(location::is_sending(ctx))
.unwrap_or_log_default(ctx, "Failed is_sending_locations()") as libc::c_int
let chat_id = if chat_id == 0 {
None
} else {
block_on(location::is_sending_to_chat(ctx, ChatId::new(chat_id)))
.unwrap_or_log_default(ctx, "Failed is_sending_locations_to_chat()")
as libc::c_int
}
Some(ChatId::new(chat_id))
};
block_on(location::is_sending_locations_to_chat(ctx, chat_id))
.unwrap_or_log_default(ctx, "Failed dc_is_sending_locations_to_chat()") as libc::c_int
}
#[no_mangle]

View File

@@ -2120,21 +2120,6 @@ impl CommandApi {
// locations
// ---------------------------------------------
/// Sets current location.
///
/// Returns true if location streaming is currently
/// enabled and locations should be updated.
///
/// Location is represented as latitude and longitude in degrees
/// and horizontal accuracy in meters.
async fn set_location(&self, latitude: f64, longitude: f64, accuracy: f64) -> Result<bool> {
self.accounts
.read()
.await
.set_location(latitude, longitude, accuracy)
.await
}
async fn get_locations(
&self,
account_id: u32,
@@ -2157,39 +2142,6 @@ impl CommandApi {
Ok(locations.into_iter().map(|l| l.into()).collect())
}
/// Enables location streaming in chat identified by `chat_id` for `seconds` seconds.
///
/// Pass 0 as the number of seconds to disable location streaming in the chat.
async fn send_locations_to_chat(
&self,
account_id: u32,
chat_id: u32,
seconds: i64,
) -> Result<()> {
let ctx = self.get_context(account_id).await?;
let chat_id = ChatId::new(chat_id);
location::send_to_chat(&ctx, chat_id, seconds).await?;
Ok(())
}
/// Returns whether any chat is sending locations.
async fn is_sending_locations(&self, account_id: u32) -> Result<bool> {
let ctx = self.get_context(account_id).await?;
location::is_sending(&ctx).await
}
/// Returns whether `chat_id` is sending locations.
async fn is_sending_locations_to_chat(&self, account_id: u32, chat_id: u32) -> Result<bool> {
let ctx = self.get_context(account_id).await?;
let chat_id = ChatId::new(chat_id);
location::is_sending_to_chat(&ctx, chat_id).await
}
/// Stops sending locations to all chats.
async fn stop_sending_locations(&self) -> Result<()> {
self.accounts.read().await.stop_sending_locations().await
}
// ---------------------------------------------
// webxdc
// ---------------------------------------------

View File

@@ -573,7 +573,7 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu
);
}
}
if location::is_sending(&context).await? {
if location::is_sending_locations_to_chat(&context, None).await? {
println!("Location streaming enabled.");
}
println!("{cnt} chats");
@@ -780,7 +780,11 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu
println!(
"Location streaming: {}",
location::is_sending_to_chat(&context, sel_chat.as_ref().unwrap().get_id()).await?,
location::is_sending_locations_to_chat(
&context,
Some(sel_chat.as_ref().unwrap().get_id())
)
.await?,
);
}
"getlocations" => {
@@ -820,7 +824,12 @@ pub async fn cmdline(context: Context, line: &str, chat_id: &mut ChatId) -> Resu
ensure!(!arg1.is_empty(), "No timeout given.");
let seconds = arg1.parse()?;
location::send_to_chat(&context, sel_chat.as_ref().unwrap().get_id(), seconds).await?;
location::send_locations_to_chat(
&context,
sel_chat.as_ref().unwrap().get_id(),
seconds,
)
.await?;
println!(
"Locations will be sent to Chat#{} for {} seconds. Use 'setlocation <lat> <lng>' to play around.",
sel_chat.as_ref().unwrap().get_id(),

View File

@@ -495,7 +495,3 @@ class Account:
"""Return ICE servers for WebRTC configuration."""
ice_servers_json = self._rpc.ice_servers(self.id)
return json.loads(ice_servers_json)
def is_sending_locations(self) -> bool:
"""Return True if sending locations to any chat."""
return self._rpc.is_sending_locations(self.id)

View File

@@ -277,16 +277,6 @@ class Chat:
"""Remove profile image of this chat."""
self._rpc.set_chat_profile_image(self.account.id, self.id, None)
def send_locations(self, seconds) -> None:
"""Enable location streaming in the chat for the given number of seconds.
Pass 0 to disable location streaming."""
self._rpc.send_locations_to_chat(self.account.id, self.id, seconds)
def is_sending_locations(self) -> bool:
"""Return True if sending locations to this chat."""
return self._rpc.is_sending_locations_to_chat(self.account.id, self.id)
def get_locations(
self,
contact: Optional[Contact] = None,

View File

@@ -59,11 +59,3 @@ class DeltaChat:
def set_translations(self, translations: dict[str, str]) -> None:
"""Set stock translation strings."""
self.rpc.set_stock_strings(translations)
def set_location(self, latitude, longitude, accuracy) -> bool:
"""Set location, return True if location streaming should continue."""
return self.rpc.set_location(latitude, longitude, accuracy)
def stop_sending_locations(self) -> None:
"""Stop sending locations to all chats."""
return self.rpc.stop_sending_locations()

View File

@@ -1,32 +0,0 @@
def test_set_location(dc, acfactory) -> None:
# Try setting location without any accounts.
assert not dc.set_location(1.0, 2.0, 0.1)
# Create one account that does not stream,
# set location.
acfactory.new_configured_account()
assert not dc.set_location(3.0, 4.0, 0.1)
def test_send_locations_to_chat(dc, acfactory):
alice, bob = acfactory.get_online_accounts(2)
assert not alice.is_sending_locations()
alice_chat_bob = alice.create_chat(bob)
assert not alice_chat_bob.is_sending_locations()
# Test starting and stopping location streaming in a chat.
alice_chat_bob.send_locations(3600)
assert alice.is_sending_locations()
assert alice_chat_bob.is_sending_locations()
alice_chat_bob.send_locations(0)
assert not alice.is_sending_locations()
assert not alice_chat_bob.is_sending_locations()
# Test stop_sending_locations() for all accounts and chats.
alice_chat_bob.send_locations(3600)
assert alice.is_sending_locations()
assert alice_chat_bob.is_sending_locations()
dc.stop_sending_locations()
assert not alice.is_sending_locations()
assert not alice_chat_bob.is_sending_locations()

View File

@@ -8,7 +8,6 @@ use std::sync::Arc;
use anyhow::{Context as _, Result, bail, ensure};
use async_channel::{self, Receiver, Sender};
use futures::FutureExt as _;
use futures::future;
use futures_lite::FutureExt as _;
use serde::{Deserialize, Serialize};
use tokio::fs;
@@ -23,7 +22,6 @@ use tokio::time::{Duration, sleep};
use crate::context::{Context, ContextBuilder};
use crate::events::{Event, EventEmitter, EventType, Events};
use crate::location;
use crate::log::warn;
use crate::push::PushSubscriber;
use crate::stock_str::StockStrings;
@@ -538,38 +536,6 @@ impl Accounts {
self.push_subscriber.set_device_token(token).await;
Ok(())
}
/// Sets location for all accounts.
///
/// Returns true if location should still be streamed.
pub async fn set_location(&self, latitude: f64, longitude: f64, accuracy: f64) -> Result<bool> {
let continue_streaming = future::try_join_all(self.accounts.iter().map(
|(account_id, account)| async move {
location::set(account, latitude, longitude, accuracy)
.await
.with_context(|| format!("Failed to set location for account {account_id}"))
},
))
.await?
.into_iter()
.any(|continue_streaming| continue_streaming);
Ok(continue_streaming)
}
/// Stops sending locations to all chats.
pub async fn stop_sending_locations(&self) -> Result<()> {
future::try_join_all(
self.accounts
.iter()
.map(|(account_id, account)| async move {
location::stop_sending(account).await.with_context(|| {
format!("Failed to stop sending locations for account {account_id}")
})
}),
)
.await?;
Ok(())
}
}
/// Configuration file name.

View File

@@ -5816,7 +5816,7 @@ async fn test_send_delete_request() -> Result<()> {
let sent2 = alice.pop_sent_msg().await;
assert_eq!(alice_chat.id.get_msg_cnt(alice).await?, E2EE_INFO_MSGS + 1);
// Bob receives both messages and has nothing the end
// Bob receives both messages and has nothing at the end
let bob_msg = bob.recv_msg(&sent1).await;
assert_eq!(bob_msg.text, "wtf");
assert_eq!(bob_msg.chat_id.get_msg_cnt(bob).await?, E2EE_INFO_MSGS + 2);
@@ -5824,6 +5824,11 @@ async fn test_send_delete_request() -> Result<()> {
bob.recv_msg_opt(&sent2).await;
assert_eq!(bob_msg.chat_id.get_msg_cnt(bob).await?, E2EE_INFO_MSGS + 1);
// ... even if he receives messages in reverse order.
let bob2 = &tcm.bob().await;
bob2.recv_msg_opt(&sent2).await;
assert!(bob2.recv_msg_opt(&sent1).await.is_none());
// Alice has another device, and there is also nothing at the end
let alice2 = &tcm.alice().await;
alice2.recv_msg(&sent0).await;

View File

@@ -264,11 +264,15 @@ impl Kml {
/// Enables location streaming in chat identified by `chat_id` for `seconds` seconds.
#[expect(clippy::arithmetic_side_effects)]
pub async fn send_to_chat(context: &Context, chat_id: ChatId, seconds: i64) -> Result<()> {
pub async fn send_locations_to_chat(
context: &Context,
chat_id: ChatId,
seconds: i64,
) -> Result<()> {
ensure!(seconds >= 0);
ensure!(!chat_id.is_special());
let now = time();
let is_sending_locations_before = is_sending_to_chat(context, chat_id).await?;
let is_sending_locations_before = is_sending_locations_to_chat(context, Some(chat_id)).await?;
context
.sql
.execute(
@@ -301,49 +305,35 @@ pub async fn send_to_chat(context: &Context, chat_id: ChatId, seconds: i64) -> R
Ok(())
}
/// Returns whether any chat is sending locations.
pub async fn is_sending(context: &Context) -> Result<bool> {
context
.sql
.exists(
"SELECT COUNT(id) FROM chats WHERE locations_send_until>?",
(time(),),
)
.await
}
/// Returns whether `chat_id` is sending locations.
pub async fn is_sending_to_chat(context: &Context, chat_id: ChatId) -> Result<bool> {
context
.sql
.exists(
"SELECT COUNT(id) FROM chats WHERE id=? AND locations_send_until>?",
(chat_id, time()),
)
.await
}
/// Returns a list of chats in which location streaming is enabled.
async fn get_chats_with_location_streaming(context: &Context) -> Result<Vec<ChatId>> {
context
.sql
.query_map_vec(
"SELECT id FROM chats WHERE locations_send_until>?",
(time(),),
|row| {
let chat_id: ChatId = row.get(0)?;
Ok(chat_id)
},
)
.await
}
/// Stop sending locations in all chats.
pub async fn stop_sending(context: &Context) -> Result<()> {
for chat_id in get_chats_with_location_streaming(context).await? {
send_to_chat(context, chat_id, 0).await?;
}
Ok(())
/// Returns whether `chat_id` or any chat is sending locations.
///
/// If `chat_id` is `Some` only that chat is checked, otherwise returns `true` if any chat
/// is sending locations.
pub async fn is_sending_locations_to_chat(
context: &Context,
chat_id: Option<ChatId>,
) -> Result<bool> {
let exists = match chat_id {
Some(chat_id) => {
context
.sql
.exists(
"SELECT COUNT(id) FROM chats WHERE id=? AND locations_send_until>?;",
(chat_id, time()),
)
.await?
}
None => {
context
.sql
.exists(
"SELECT COUNT(id) FROM chats WHERE locations_send_until>?;",
(time(),),
)
.await?
}
};
Ok(exists)
}
/// Sets current location of the user device.
@@ -498,7 +488,7 @@ pub(crate) async fn delete_expired(context: &Context, now: i64) -> Result<()> {
///
/// This function is used when a message is deleted
/// that has a corresponding `location_id`.
pub(crate) async fn delete_poi(context: &Context, location_id: u32) -> Result<()> {
pub(crate) async fn delete_poi_location(context: &Context, location_id: u32) -> Result<()> {
context
.sql
.execute(
@@ -510,7 +500,7 @@ pub(crate) async fn delete_poi(context: &Context, location_id: u32) -> Result<()
}
/// Deletes POI locations that don't have corresponding message anymore.
pub(crate) async fn delete_orphaned_poi(context: &Context) -> Result<()> {
pub(crate) async fn delete_orphaned_poi_locations(context: &Context) -> Result<()> {
context.sql.execute("
DELETE FROM locations
WHERE independent=1 AND id NOT IN
@@ -719,9 +709,9 @@ pub(crate) async fn save(
pub(crate) async fn location_loop(context: &Context, interrupt_receiver: Receiver<()>) {
loop {
let next_event = match maybe_send(context).await {
let next_event = match maybe_send_locations(context).await {
Err(err) => {
warn!(context, "location::maybe_send failed: {:#}", err);
warn!(context, "maybe_send_locations failed: {:#}", err);
Some(60) // Retry one minute later.
}
Ok(next_event) => next_event,
@@ -759,7 +749,7 @@ pub(crate) async fn location_loop(context: &Context, interrupt_receiver: Receive
/// Returns number of seconds until the next time location streaming for some chat ends
/// automatically.
#[expect(clippy::arithmetic_side_effects)]
async fn maybe_send(context: &Context) -> Result<Option<u64>> {
async fn maybe_send_locations(context: &Context) -> Result<Option<u64>> {
let mut next_event: Option<u64> = None;
let now = time();
@@ -1054,7 +1044,7 @@ Content-Disposition: attachment; filename="location.kml"
let bob = TestContext::new_bob().await;
let alice_chat = alice.create_chat(&bob).await;
send_to_chat(&alice, alice_chat.id, 1000).await?;
send_locations_to_chat(&alice, alice_chat.id, 1000).await?;
let sent = alice.pop_sent_msg().await;
let msg = bob.recv_msg(&sent).await;
assert_eq!(msg.text, "Location streaming enabled by alice@example.org.");
@@ -1106,7 +1096,7 @@ Content-Disposition: attachment; filename="location.kml"
// Alice enables location streaming.
// Bob receives a message saying that Alice enabled location streaming.
send_to_chat(alice, alice_chat.id, 60).await?;
send_locations_to_chat(alice, alice_chat.id, 60).await?;
bob.recv_msg(&alice.pop_sent_msg().await).await;
// Alice gets new location from GPS.
@@ -1116,7 +1106,7 @@ Content-Disposition: attachment; filename="location.kml"
// 10 seconds later location sending stream manages to send location.
SystemTime::shift(Duration::from_secs(10));
delete_expired(alice, time()).await?;
maybe_send(alice).await?;
maybe_send_locations(alice).await?;
bob.recv_msg_opt(&alice.pop_sent_msg().await).await;
assert_eq!(get_range(alice, None, None, 0, 0).await?.len(), 1);
assert_eq!(get_range(bob, None, None, 0, 0).await?.len(), 1);

View File

@@ -25,7 +25,7 @@ use crate::download::DownloadState;
use crate::ephemeral::{Timer as EphemeralTimer, start_ephemeral_timers_msgids};
use crate::events::EventType;
use crate::imap::markseen_on_imap_table;
use crate::location;
use crate::location::delete_poi_location;
use crate::log::warn;
use crate::mimeparser::{SystemMessage, parse_message_id};
use crate::param::{Param, Params};
@@ -529,7 +529,7 @@ impl Message {
FROM msgs m
LEFT JOIN chats c ON c.id=m.chat_id
LEFT JOIN msgs_mdns mdns ON mdns.msg_id=m.id
WHERE m.id=? AND chat_id!=3
WHERE m.id=? AND chat_id!=3 -- DC_CHAT_ID_TRASH
LIMIT 1",
(id,),
|row| {
@@ -739,7 +739,7 @@ impl Message {
/// at a position different from the self-location.
/// You should not call this function
/// if you want to bind the current self-location to a message;
/// this is done by [`location::set()`] and [`location::send_to_chat()`].
/// this is done by [`location::set()`] and [`send_locations_to_chat()`].
///
/// Typically results in the event [`LocationChanged`] with
/// `contact_id` set to [`ContactId::SELF`].
@@ -748,7 +748,7 @@ impl Message {
/// `longitude` is the East-west position of the location.
///
/// [`location::set()`]: crate::location::set
/// [`location::send_to_chat()`]: crate::location::send_to_chat
/// [`send_locations_to_chat()`]: crate::location::send_locations_to_chat
/// [`LocationChanged`]: crate::events::EventType::LocationChanged
pub fn set_location(&mut self, latitude: f64, longitude: f64) {
if latitude == 0.0 && longitude == 0.0 {
@@ -1649,7 +1649,7 @@ pub(crate) async fn get_mime_headers(context: &Context, msg_id: MsgId) -> Result
/// This may be called in batches; the final events are emitted in delete_msgs_locally_done() then.
pub(crate) async fn delete_msg_locally(context: &Context, msg: &Message) -> Result<()> {
if msg.location_id > 0 {
location::delete_poi(context, msg.location_id).await?;
delete_poi_location(context, msg.location_id).await?;
}
let on_server = true;
msg.id

View File

@@ -1829,7 +1829,7 @@ impl MimeFactory {
parts.push(msg_kml_part);
}
if location::is_sending_to_chat(context, msg.chat_id).await?
if location::is_sending_locations_to_chat(context, Some(msg.chat_id)).await?
&& let Some(part) = self.get_location_kml_part(context).await?
{
parts.push(part);

View File

@@ -524,52 +524,15 @@ pub(crate) async fn receive_imf_inner(
"Receiving message {rfc724_mid_orig:?}, seen={seen}...",
);
// check, if the mail is already in our database.
// make sure, this check is done eg. before securejoin-processing.
let (replace_msg_id, replace_chat_id);
// These checks must be done before processing of SecureJoin and other special messages.
if mime_parser.pre_message == mimeparser::PreMessageMode::Post {
// Post-Message just replaces the attachment and modifies Params, not the whole message.
// This is done in the `handle_post_message` method.
replace_msg_id = None;
replace_chat_id = None;
} else if let Some(old_msg_id) = message::rfc724_mid_exists(context, rfc724_mid).await? {
// This code handles the download of old partial download stub messages
// It will be removed after a transitioning period,
// after we have released a few versions with pre-messages
replace_msg_id = Some(old_msg_id);
replace_chat_id = if let Some(msg) = Message::load_from_db_optional(context, old_msg_id)
.await?
.filter(|msg| msg.download_state() != DownloadState::Done)
{
// The message was partially downloaded before.
match mime_parser.pre_message {
PreMessageMode::Post | PreMessageMode::None => {
info!(context, "Message already partly in DB, replacing.");
Some(msg.chat_id)
}
PreMessageMode::Pre { .. } => {
info!(context, "Cannot replace pre-message with a pre-message");
None
}
}
} else {
// The message was already fully downloaded
// or cannot be loaded because it is deleted.
None
};
} else {
replace_msg_id = if rfc724_mid_orig == rfc724_mid {
None
} else {
message::rfc724_mid_exists(context, rfc724_mid_orig).await?
};
replace_chat_id = None;
}
if replace_chat_id.is_some() {
// Need to update chat id in the db.
} else if let Some(msg_id) = replace_msg_id {
info!(context, "Message is already downloaded.");
} else if let Some(msg_id) = message::rfc724_mid_exists(context, rfc724_mid_orig).await? {
info!(
context,
"Message {rfc724_mid} is already in some chat or deleted."
);
if mime_parser.incoming {
return Ok(None);
}
@@ -588,7 +551,7 @@ pub(crate) async fn receive_imf_inner(
msg_id.set_delivered(context).await?;
}
return Ok(None);
};
}
let prevent_rename = should_prevent_rename(&mime_parser);
@@ -638,8 +601,7 @@ pub(crate) async fn receive_imf_inner(
mime_parser.get_header(HeaderDef::References),
mime_parser.get_header(HeaderDef::InReplyTo),
)
.await?
.filter(|p| Some(p.id) != replace_msg_id);
.await?;
let mut chat_assignment =
decide_chat_assignment(context, &mime_parser, &parent_message, rfc724_mid, from_id).await?;
@@ -755,7 +717,6 @@ pub(crate) async fn receive_imf_inner(
rfc724_mid_orig,
from_id,
seen,
replace_msg_id,
prevent_rename,
chat_id,
chat_id_blocked,
@@ -1050,11 +1011,6 @@ UPDATE msgs SET state=? WHERE
.await?;
} else if received_msg.hidden {
// No need to emit an event about the changed message
} else if let Some(replace_chat_id) = replace_chat_id {
match replace_chat_id == chat_id {
false => context.emit_msgs_changed_without_msg_id(replace_chat_id),
true => context.emit_msgs_changed(chat_id, replace_msg_id.unwrap_or_default()),
}
} else if !chat_id.is_trash() {
let fresh = received_msg.state == MessageState::InFresh
&& mime_parser.is_system_message != SystemMessage::CallAccepted
@@ -1781,7 +1737,6 @@ async fn add_parts(
rfc724_mid: &str,
from_id: ContactId,
seen: bool,
mut replace_msg_id: Option<MsgId>,
prevent_rename: bool,
mut chat_id: ChatId,
mut chat_id_blocked: Blocked,
@@ -2162,22 +2117,6 @@ async fn add_parts(
param.set_int(Param::Cmd, is_system_message as i32);
}
if let Some(replace_msg_id) = replace_msg_id {
let placeholder = Message::load_from_db(context, replace_msg_id)
.await
.context("Failed to load placeholder message")?;
for key in [
Param::WebxdcSummary,
Param::WebxdcSummaryTimestamp,
Param::WebxdcDocument,
Param::WebxdcDocumentTimestamp,
] {
if let Some(value) = placeholder.param.get(key) {
param.set(key, value);
}
}
}
let (msg, typ): (&str, Viewtype) = if let Some(better_msg) = &better_msg {
(better_msg, Viewtype::Text)
} else {
@@ -2220,10 +2159,9 @@ async fn add_parts(
.sql
.call_write(|conn| {
let mut stmt = conn.prepare_cached(
r#"
"
INSERT INTO msgs
(
id,
rfc724_mid, pre_rfc724_mid, chat_id,
from_id, to_id, timestamp, timestamp_sent,
timestamp_rcvd, type, state, msgrmsg,
@@ -2233,34 +2171,29 @@ INSERT INTO msgs
ephemeral_timestamp, download_state, hop_info
)
VALUES (
?,
?, ?, ?, ?, ?,
?, ?, ?, ?,
?, ?, ?, ?,
?, ?, ?, ?, ?, 1,
?, ?, ?, ?,
?, ?, ?, ?
)
ON CONFLICT (id) DO UPDATE
SET rfc724_mid=excluded.rfc724_mid, chat_id=excluded.chat_id,
from_id=excluded.from_id, to_id=excluded.to_id, timestamp_sent=excluded.timestamp_sent,
type=excluded.type, state=max(state,excluded.state), msgrmsg=excluded.msgrmsg,
txt=excluded.txt, txt_normalized=excluded.txt_normalized, subject=excluded.subject,
param=excluded.param,
hidden=excluded.hidden,bytes=excluded.bytes, mime_headers=excluded.mime_headers,
mime_compressed=excluded.mime_compressed, mime_in_reply_to=excluded.mime_in_reply_to,
mime_references=excluded.mime_references, mime_modified=excluded.mime_modified, error=excluded.error, ephemeral_timer=excluded.ephemeral_timer,
ephemeral_timestamp=excluded.ephemeral_timestamp, download_state=excluded.download_state, hop_info=excluded.hop_info
RETURNING id
"#)?;
let row_id: MsgId = stmt.query_row(params![
replace_msg_id,
if let PreMessageMode::Pre {post_msg_rfc724_mid, ..} = &mime_parser.pre_message {
)",
)?;
let params = params![
if let PreMessageMode::Pre {
post_msg_rfc724_mid,
..
} = &mime_parser.pre_message
{
post_msg_rfc724_mid
} else { rfc724_mid_orig },
if let PreMessageMode::Pre {..} = &mime_parser.pre_message {
} else {
rfc724_mid_orig
} else { "" },
},
if let PreMessageMode::Pre { .. } = &mime_parser.pre_message {
rfc724_mid_orig
} else {
""
},
if trash { DC_CHAT_ID_TRASH } else { chat_id },
if trash { ContactId::UNDEFINED } else { from_id },
if trash { ContactId::UNDEFINED } else { to_id },
@@ -2269,13 +2202,27 @@ RETURNING id
if trash { 0 } else { mime_parser.timestamp_rcvd },
if trash {
Viewtype::Unknown
} else if let PreMessageMode::Pre {..} = mime_parser.pre_message {
} else if let PreMessageMode::Pre { .. } = mime_parser.pre_message {
Viewtype::Text
} else { typ },
if trash { MessageState::Undefined } else { state },
if trash { MessengerMessage::No } else { is_dc_message },
} else {
typ
},
if trash {
MessageState::Undefined
} else {
state
},
if trash {
MessengerMessage::No
} else {
is_dc_message
},
if trash || hidden { "" } else { msg },
if trash || hidden { None } else { normalize_text(msg) },
if trash || hidden {
None
} else {
normalize_text(msg)
},
if trash || hidden { "" } else { &subject },
if trash {
"".to_string()
@@ -2292,33 +2239,28 @@ RETURNING id
if trash { "" } else { mime_in_reply_to },
if trash { "" } else { mime_references },
!trash && save_mime_modified,
if trash { "" } else { part.error.as_deref().unwrap_or_default() },
if trash {
""
} else {
part.error.as_deref().unwrap_or_default()
},
if trash { 0 } else { ephemeral_timer.to_u32() },
if trash { 0 } else { ephemeral_timestamp },
if trash {
DownloadState::Done
} else if mime_parser.decryption_error.is_some() {
DownloadState::Undecipherable
} else if let PreMessageMode::Pre {..} = mime_parser.pre_message {
} else if let PreMessageMode::Pre { .. } = mime_parser.pre_message {
DownloadState::Available
} else {
DownloadState::Done
},
if trash { "" } else { &mime_parser.hop_info },
],
|row| {
let msg_id: MsgId = row.get(0)?;
Ok(msg_id)
}
)?;
];
let row_id = MsgId::new(stmt.insert(params)?.try_into()?);
Ok(row_id)
})
.await?;
// We only replace placeholder with a first part,
// afterwards insert additional parts.
replace_msg_id = None;
ensure_and_debug_assert!(!row_id.is_special(), "Rowid {row_id} is special");
created_db_entries.push(row_id);
}
@@ -2343,14 +2285,6 @@ RETURNING id
.await?;
}
if let Some(replace_msg_id) = replace_msg_id {
// Trash the "replace" placeholder with a message that has no parts. If it has the original
// "Message-ID", mark the placeholder for server-side deletion so as if the user deletes the
// fully downloaded message later, the server-side deletion is issued.
let on_server = rfc724_mid == rfc724_mid_orig;
replace_msg_id.trash(context, on_server).await?;
}
let unarchive = match mime_parser.get_header(HeaderDef::ChatGroupMemberRemoved) {
Some(addr) => context.is_self_addr(addr).await?,
None => true,
@@ -2454,6 +2388,7 @@ async fn handle_edit_delete(
let rfc724_mid_vec: Vec<&str> = rfc724_mid_list.split_whitespace().collect();
for rfc724_mid in rfc724_mid_vec {
let rfc724_mid = rfc724_mid.trim_start_matches('<').trim_end_matches('>');
if let Some(msg_id) = message::rfc724_mid_exists(context, rfc724_mid).await? {
if let Some(msg) = Message::load_from_db_optional(context, msg_id).await? {
if msg.from_id == from_id {
@@ -2468,6 +2403,8 @@ async fn handle_edit_delete(
}
} else {
warn!(context, "Delete message: {rfc724_mid:?} not found.");
// Insert a tombstone so that the message will be ignored if it arrives later within a period specified in prune_tombstones().
insert_tombstone(context, rfc724_mid).await?;
}
}
message::delete_msgs_locally_done(context, &msg_ids, modified_chat_ids).await?;

View File

@@ -142,7 +142,7 @@ pub async fn get_securejoin_qr(context: &Context, chat: Option<ChatId>) -> Resul
let auth = create_id();
token::save(context, Namespace::Auth, grpid, &auth, time()).await?;
let fingerprint = get_self_fingerprint(context).await?.hex();
let fingerprint = self_fingerprint(context).await?;
let self_addr = context.get_primary_self_addr().await?;
let self_addr_urlencoded = utf8_percent_encode(&self_addr, DISALLOWED_CHARACTERS).to_string();

View File

@@ -15,7 +15,7 @@ use crate::context::Context;
use crate::debug_logging::set_debug_logging_xdc;
use crate::ephemeral::start_ephemeral_timers;
use crate::imex::BLOBS_BACKUP_NAME;
use crate::location;
use crate::location::delete_orphaned_poi_locations;
use crate::log::{LogExt, warn};
use crate::message::MsgId;
use crate::net::dns::prune_dns_cache;
@@ -902,7 +902,7 @@ pub async fn housekeeping(context: &Context) -> Result<()> {
// Delete POI locations
// which don't have corresponding message.
location::delete_orphaned_poi(context)
delete_orphaned_poi_locations(context)
.await
.context("Failed to delete orphaned POI locations")
.log_err(context)

View File

@@ -5,13 +5,9 @@ use crate::download::DownloadState;
use crate::receive_imf::receive_imf_from_inbox;
use crate::test_utils::TestContext;
// The code for downloading stub messages stays
// during the transition perios to pre-messages
// so people can still download their files shortly after they updated.
// After there are a few release with pre-message rolled out,
// we will remove the ability to download stub messages and replace the following test
// so it checks that it doesn't crash or that the messages are replaced by sth.
// like "download failed/expired, please ask sender to send it again"
// The code for replacing partial download stubs is already removed, so check that nothing happens
// if after that a full message is passed to receive_imf. Users should ask the sender to send the
// message again.
#[tokio::test(flavor = "multi_thread", worker_threads = 2)]
async fn test_download_stub_message() -> Result<()> {
let t = TestContext::new_alice().await;
@@ -53,9 +49,9 @@ async fn test_download_stub_message() -> Result<()> {
)
.await?;
let msg = t.get_last_msg().await;
assert_eq!(msg.download_state(), DownloadState::Done);
assert_eq!(msg.download_state(), DownloadState::Available);
assert_eq!(msg.get_subject(), "foo");
assert_eq!(msg.get_text(), "100k text...");
assert!(msg.get_text().contains("[97.66 KiB message]"));
Ok(())
}

View File

@@ -6,7 +6,7 @@ use crate::chat::{self, Chat, add_contact_to_chat, remove_contact_from_chat, sen
use crate::config::Config;
use crate::constants::Chattype;
use crate::contact::{Contact, ContactId};
use crate::key::{DcKey, load_self_public_key};
use crate::key::self_fingerprint;
use crate::message::{Message, Viewtype};
use crate::mimefactory::MimeFactory;
use crate::mimeparser::SystemMessage;
@@ -152,11 +152,7 @@ async fn test_missing_key_reexecute_securejoin() -> Result<()> {
bob.sql
.execute(
"DELETE FROM public_keys WHERE fingerprint=?",
(&load_self_public_key(alice)
.await
.unwrap()
.dc_fingerprint()
.hex(),),
(&self_fingerprint(alice).await.unwrap(),),
)
.await?;
let chat = Chat::load_from_db(bob, chat_id).await?;

View File

@@ -1,6 +0,0 @@
Authentication-Results: atlas106.aol.mail.ne1.yahoo.com;
dkim=pass header.i=@buzon.uy header.s=2019;
spf=pass smtp.mailfrom=buzon.uy;
dmarc=pass(p=REJECT) header.from=buzon.uy;
From: <alice@buzon.uy>
To: <alice@aol.com>

View File

@@ -1,6 +0,0 @@
Authentication-Results: atlas206.aol.mail.ne1.yahoo.com;
dkim=unknown;
spf=none smtp.mailfrom=delta.blinzeln.de;
dmarc=unknown header.from=delta.blinzeln.de;
From: <alice@delta.blinzeln.de>
To: <alice@aol.com>

View File

@@ -1,6 +0,0 @@
Authentication-Results: atlas210.aol.mail.bf1.yahoo.com;
dkim=pass header.i=@disroot.org header.s=mail;
spf=pass smtp.mailfrom=disroot.org;
dmarc=pass(p=QUARANTINE) header.from=disroot.org;
From: <alice@disroot.org>
To: <alice@aol.com>

View File

@@ -1,7 +0,0 @@
Authentication-Results: atlas105.aol.mail.ne1.yahoo.com;
dkim=pass header.i=@fastmail.com header.s=fm2;
dkim=pass header.i=@messagingengine.com header.s=fm2;
spf=pass smtp.mailfrom=fastmail.com;
dmarc=pass(p=NONE,sp=NONE) header.from=fastmail.com;
From: <alice@fastmail.com>
To: <alice@aol.com>

View File

@@ -1,6 +0,0 @@
Authentication-Results: atlas-baseline-production.v2-mail-prod1-gq1.omega.yahoo.com;
dkim=pass header.i=@gmail.com header.s=20210112;
spf=pass smtp.mailfrom=gmail.com;
dmarc=pass(p=NONE,sp=QUARANTINE) header.from=gmail.com;
From: <alice@gmail.com>
To: <alice@aol.com>

View File

@@ -1,8 +0,0 @@
Authentication-Results: atlas112.aol.mail.bf1.yahoo.com;
dkim=pass header.i=@hotmail.com header.s=selector1;
spf=pass smtp.mailfrom=hotmail.com;
dmarc=pass(p=NONE) header.from=hotmail.com;
ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none;
dkim=none; arc=none
From: <alice@hotmail.com>
To: <alice@aol.com>

View File

@@ -1,6 +0,0 @@
Authentication-Results: atlas101.aol.mail.bf1.yahoo.com;
dkim=pass header.i=@icloud.com header.s=1a1hai;
spf=pass smtp.mailfrom=icloud.com;
dmarc=pass(p=QUARANTINE,sp=QUARANTINE) header.from=icloud.com;
From: <alice@icloud.com>
To: <alice@aol.com>

View File

@@ -1,6 +0,0 @@
Authentication-Results: atlas-production.v2-mail-prod1-gq1.omega.yahoo.com;
dkim=pass header.i=@ik.me header.s=20200325;
spf=pass smtp.mailfrom=ik.me;
dmarc=pass(p=REJECT) header.from=ik.me;
From: <alice@ik.me>
To: <alice@aol.com>

View File

@@ -1,6 +0,0 @@
Authentication-Results: atlas104.aol.mail.bf1.yahoo.com;
dkim=pass header.i=@mail.ru header.s=mail4;
spf=pass smtp.mailfrom=mail.ru;
dmarc=pass(p=REJECT) header.from=mail.ru;
From: <alice@mail.ru>
To: <alice@aol.com>

View File

@@ -1,6 +0,0 @@
Authentication-Results: atlas211.aol.mail.bf1.yahoo.com;
dkim=pass header.i=@mailo.com header.s=mailo;
spf=pass smtp.mailfrom=mailo.com;
dmarc=pass(p=NONE) header.from=mailo.com;
From: <alice@mailo.com>
To: <alice@aol.com>

View File

@@ -1,8 +0,0 @@
Authentication-Results: atlas-production.v2-mail-prod1-gq1.omega.yahoo.com;
dkim=pass header.i=@outlook.com header.s=selector1;
spf=pass smtp.mailfrom=outlook.com;
dmarc=pass(p=NONE,sp=QUARANTINE) header.from=outlook.com;
ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none;
dkim=none; arc=none
From: <alice@outlook.com>
To: <alice@aol.com>

View File

@@ -1,6 +0,0 @@
Authentication-Results: atlas-production.v2-mail-prod1-gq1.omega.yahoo.com;
dkim=pass header.i=@posteo.de header.s=2017;
spf=pass smtp.mailfrom=posteo.de;
dmarc=pass(p=NONE) header.from=posteo.de;
From: <alice@posteo.de>
To: <alice@aol.com>

View File

@@ -1,6 +0,0 @@
Authentication-Results: atlas114.aol.mail.bf1.yahoo.com;
dkim=pass header.i=@yandex.ru header.s=mail;
spf=pass smtp.mailfrom=yandex.ru;
dmarc=pass(p=NONE) header.from=yandex.ru;
From: <alice@yandex.ru>
To: <alice@aol.com>

View File

@@ -1,6 +0,0 @@
Authentication-Results: atlas206.aol.mail.ne1.yahoo.com;
dkim=unknown;
spf=none smtp.mailfrom=delta.blinzeln.de;
dmarc=unknown header.from=delta.blinzeln.de;
From: forged-authres-added@example.com
Authentication-Results: aaa.com; dkim=pass header.i=@example.com

View File

@@ -1,5 +0,0 @@
Authentication-Results: mail.buzon.uy;
dkim=pass (2048-bit key; unprotected) header.d=aol.com header.i=@aol.com header.b="sjmqxpKe";
dkim-atps=neutral
From: <alice@aol.com>
To: <alice@buzon.uy>

View File

@@ -1,3 +0,0 @@
From: <alice@delta.blinzeln.de>
To: <alice@buzon.uy>
Authentication-Results: secure-mailgate.com; auth=pass smtp.auth=91.203.111.88@webbox222.server-home.org

View File

@@ -1,5 +0,0 @@
Authentication-Results: mail.buzon.uy;
dkim=pass (2048-bit key; secure) header.d=disroot.org header.i=@disroot.org header.b="L9SmOHOj";
dkim-atps=neutral
From: <alice@disroot.org>
To: <alice@buzon.uy>

View File

@@ -1,6 +0,0 @@
Authentication-Results: mail.buzon.uy;
dkim=pass (2048-bit key; unprotected) header.d=fastmail.com header.i=@fastmail.com header.b="kLB05is1";
dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="B8mfR89g";
dkim-atps=neutral
From: <alice@fastmail.com>
To: <alice@buzon.uy>

View File

@@ -1,5 +0,0 @@
Authentication-Results: mail.buzon.uy;
dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Ngf1X5eN";
dkim-atps=neutral
From: <alice@gmail.com>
To: <alice@buzon.uy>

View File

@@ -1,7 +0,0 @@
Authentication-Results: mail.buzon.uy;
dkim=pass (2048-bit key; unprotected) header.d=hotmail.com header.i=@hotmail.com header.b="dEHn9Szj";
dkim-atps=neutral
ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none;
dkim=none; arc=none
From: <alice@hotmail.com>
To: <alice@buzon.uy>

View File

@@ -1,5 +0,0 @@
Authentication-Results: mail.buzon.uy;
dkim=pass (2048-bit key; unprotected) header.d=icloud.com header.i=@icloud.com header.b="rAXD4xVN";
dkim-atps=neutral
From: <alice@icloud.com>
To: <alice@buzon.uy>

View File

@@ -1,5 +0,0 @@
Authentication-Results: mail.buzon.uy;
dkim=pass (1024-bit key; secure) header.d=ik.me header.i=@ik.me header.b="EWWQpVZX";
dkim-atps=neutral
From: <alice@ik.me>
To: <alice@buzon.uy>

View File

@@ -1,5 +0,0 @@
Authentication-Results: mail.buzon.uy;
dkim=pass (2048-bit key; secure) header.d=mail.de header.i=@mail.de header.b="18cRkjHf";
dkim-atps=neutral
From: <alice@mail.de>
To: <alice@buzon.uy>

View File

@@ -1,6 +0,0 @@
Authentication-Results: mail.buzon.uy;
dkim=pass (2048-bit key; unprotected) header.d=mail.ru header.i=@mail.ru header.b="uXBGAnnn";
dkim-atps=neutral
From: <alice@mail.ru>
To: <alice@buzon.uy>
Authentication-Results: smtpng1.m.smailru.net; auth=pass smtp.auth=alice@mail.ru smtp.mailfrom=alice@mail.ru

View File

@@ -1,5 +0,0 @@
Authentication-Results: mail.buzon.uy;
dkim=pass (1024-bit key; unprotected) header.d=mailo.com header.i=@mailo.com header.b="awx9eOw9";
dkim-atps=neutral
From: <alice@mailo.com>
To: <alice@buzon.uy>

View File

@@ -1,7 +0,0 @@
Authentication-Results: mail.buzon.uy;
dkim=pass (2048-bit key; unprotected) header.d=outlook.com header.i=@outlook.com header.b="Uq5LH/n/";
dkim-atps=neutral
ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none;
dkim=none; arc=none
From: <alice@outlook.com>
To: <alice@buzon.uy>

View File

@@ -1,5 +0,0 @@
Authentication-Results: mail.buzon.uy;
dkim=pass (2048-bit key; secure) header.d=posteo.de header.i=@posteo.de header.b="AyOucyBM";
dkim-atps=neutral
From: <alice@posteo.de>
To: <alice@buzon.uy>

View File

@@ -1,5 +0,0 @@
Authentication-Results: mail.buzon.uy;
dkim=pass (1024-bit key; secure) header.d=riseup.net header.i=@riseup.net header.b="eQhRD1BM";
dkim-atps=neutral
From: <alice@riseup.net>
To: <alice@buzon.uy>

View File

@@ -1,5 +0,0 @@
Authentication-Results: mail.buzon.uy;
dkim=pass (2048-bit key; unprotected) header.d=yahoo.com header.i=@yahoo.com header.b="a1T2PpDI";
dkim-atps=neutral
From: <alice@yahoo.com>
To: <alice@buzon.uy>

View File

@@ -1,6 +0,0 @@
Authentication-Results: mail.buzon.uy;
dkim=pass (1024-bit key; unprotected) header.d=yandex.ru header.i=@yandex.ru header.b="oGBtMMzR";
dkim-atps=neutral
Authentication-Results: iva4-143b1447cf50.qloud-c.yandex.net; dkim=pass header.i=@yandex.ru
From: <alice@yandex.ru>
To: <alice@buzon.uy>

View File

@@ -1,3 +0,0 @@
From: forged-authres-added@example.com
Authentication-Results: aaa.com; dkim=pass header.i=@example.com
Authentication-Results: aaa.com; dkim=pass header.i=@example.com

View File

@@ -1,2 +0,0 @@
From: <alice@aol.com>
To: <alice@delta.blinzeln.de>

View File

@@ -1,2 +0,0 @@
From: <alice@buzon.uy>
To: <alice@delta.blinzeln.de>

View File

@@ -1,2 +0,0 @@
From: <alice@disroot.org>
To: <alice@delta.blinzeln.de>

View File

@@ -1,2 +0,0 @@
From: <alice@fastmail.com>
To: <alice@delta.blinzeln.de>

View File

@@ -1,2 +0,0 @@
From: <alice@gmail.com>
To: <alice@delta.blinzeln.de>

View File

@@ -1,4 +0,0 @@
ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none;
dkim=none; arc=none
From: <alice@hotmail.com>
To: <alice@delta.blinzeln.de>

View File

@@ -1,2 +0,0 @@
From: <alice@icloud.com>
To: <alice@delta.blinzeln.de>

View File

@@ -1,2 +0,0 @@
From: <alice@ik.me>
To: <alice@delta.blinzeln.de>

View File

@@ -1,2 +0,0 @@
From: <alice@mail.de>
To: <alice@delta.blinzeln.de>

View File

@@ -1,3 +0,0 @@
From: <alice@mail.ru>
To: <alice@delta.blinzeln.de>
Authentication-Results: smtpng1.m.smailru.net; auth=pass smtp.auth=alice@mail.ru smtp.mailfrom=alice@mail.ru

View File

@@ -1,2 +0,0 @@
From: <alice@mailo.com>
To: <alice@delta.blinzeln.de>

View File

@@ -1,4 +0,0 @@
ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none;
dkim=none; arc=none
From: <alice@outlook.com>
To: <alice@delta.blinzeln.de>

View File

@@ -1,2 +0,0 @@
From: <alice@posteo.de>
To: <alice@delta.blinzeln.de>

View File

@@ -1,2 +0,0 @@
From: <alice@riseup.net>
To: <alice@delta.blinzeln.de>

View File

@@ -1,2 +0,0 @@
From: <alice@yahoo.com>
To: <alice@delta.blinzeln.de>

View File

@@ -1,3 +0,0 @@
Authentication-Results: iva4-143b1447cf50.qloud-c.yandex.net; dkim=pass header.i=@yandex.ru
From: <alice@yandex.ru>
To: <alice@delta.blinzeln.de>

View File

@@ -1,5 +0,0 @@
Authentication-Results: disroot.org;
dkim=pass (2048-bit key; unprotected) header.d=aol.com header.i=@aol.com header.b="DBDqUGR2";
dkim-atps=neutral
From: <alice@aol.com>
To: <alice@disroot.org>

View File

@@ -1,5 +0,0 @@
Authentication-Results: disroot.org;
dkim=pass (2048-bit key; unprotected) header.d=buzon.uy header.i=@buzon.uy header.b="VVA3HpHe";
dkim-atps=neutral
From: <alice@buzon.uy>
To: <alice@disroot.org>

View File

@@ -1,3 +0,0 @@
From: <alice@delta.blinzeln.de>
To: <alice@disroot.org>
Authentication-Results: secure-mailgate.com; auth=pass smtp.auth=91.203.111.88@webbox222.server-home.org

View File

@@ -1,6 +0,0 @@
Authentication-Results: disroot.org;
dkim=pass (2048-bit key; unprotected) header.d=fastmail.com header.i=@fastmail.com header.b="OFgq9UWZ";
dkim=pass (2048-bit key; unprotected) header.d=messagingengine.com header.i=@messagingengine.com header.b="B52d7C0G";
dkim-atps=neutral
From: <alice@fastmail.com>
To: <alice@disroot.org>

View File

@@ -1,5 +0,0 @@
Authentication-Results: disroot.org;
dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="lxlrOeGY";
dkim-atps=neutral
From: <alice@gmail.com>
To: <alice@disroot.org>

View File

@@ -1,7 +0,0 @@
Authentication-Results: disroot.org;
dkim=pass (2048-bit key; unprotected) header.d=hotmail.com header.i=@hotmail.com header.b="VdDCDs55";
dkim-atps=neutral
ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none;
dkim=none; arc=none
From: <alice@hotmail.com>
To: <alice@disroot.org>

View File

@@ -1,5 +0,0 @@
Authentication-Results: disroot.org;
dkim=pass (2048-bit key; unprotected) header.d=icloud.com header.i=@icloud.com header.b="kD59vbQH";
dkim-atps=neutral
From: <alice@icloud.com>
To: <alice@disroot.org>

View File

@@ -1,5 +0,0 @@
Authentication-Results: disroot.org;
dkim=pass (1024-bit key; unprotected) header.d=ik.me header.i=@ik.me header.b="YBLXQ2kp";
dkim-atps=neutral
From: <alice@ik.me>
To: <alice@disroot.org>

View File

@@ -1,5 +0,0 @@
Authentication-Results: disroot.org;
dkim=pass (2048-bit key; unprotected) header.d=mail.de header.i=@mail.de header.b="3ha9obSK";
dkim-atps=neutral
From: <alice@mail.de>
To: <alice@disroot.org>

View File

@@ -1,6 +0,0 @@
Authentication-Results: disroot.org;
dkim=pass (2048-bit key; unprotected) header.d=mail.ru header.i=@mail.ru header.b="IrDU+LTI";
dkim-atps=neutral
From: <alice@mail.ru>
To: <alice@disroot.org>
Authentication-Results: smtpng1.m.smailru.net; auth=pass smtp.auth=alice@mail.ru smtp.mailfrom=alice@mail.ru

View File

@@ -1,5 +0,0 @@
Authentication-Results: disroot.org;
dkim=fail reason="signature verification failed" (1024-bit key; unprotected) header.d=mailo.com header.i=@mailo.com header.b="WgsA5pwT";
dkim-atps=neutral
From: <alice@mailo.com>
To: <alice@disroot.org>

View File

@@ -1,7 +0,0 @@
Authentication-Results: disroot.org;
dkim=pass (2048-bit key; unprotected) header.d=outlook.com header.i=@outlook.com header.b="UtZoPK7Z";
dkim-atps=neutral
ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none;
dkim=none; arc=none
From: <alice@outlook.com>
To: <alice@disroot.org>

View File

@@ -1,5 +0,0 @@
Authentication-Results: disroot.org;
dkim=pass (2048-bit key; unprotected) header.d=posteo.de header.i=@posteo.de header.b="R67Ab9Vj";
dkim-atps=neutral
From: <alice@posteo.de>
To: <alice@disroot.org>

View File

@@ -1,5 +0,0 @@
Authentication-Results: disroot.org;
dkim=pass (1024-bit key; unprotected) header.d=riseup.net header.i=@riseup.net header.b="fFYxwl1W";
dkim-atps=neutral
From: <alice@riseup.net>
To: <alice@disroot.org>

View File

@@ -1,6 +0,0 @@
Authentication-Results: disroot.org;
dkim=pass (1024-bit key; unprotected) header.d=yandex.ru header.i=@yandex.ru header.b="CvyR5Vj/";
dkim-atps=neutral
Authentication-Results: iva4-143b1447cf50.qloud-c.yandex.net; dkim=pass header.i=@yandex.ru
From: <alice@yandex.ru>
To: <alice@disroot.org>

View File

@@ -1,3 +0,0 @@
From: forged-authres-added@example.com
Authentication-Results: aaa.com; dkim=pass header.i=@example.com
Authentication-Results: aaa.com; dkim=pass header.i=@example.com

View File

@@ -1,6 +0,0 @@
From: <alice@aol.com>
To: <alice@e.email>
Authentication-Results: mail3.ecloud.global;
dkim=pass header.d=aol.com header.s=a2048 header.b=HlBq3Lmt;
dmarc=pass (policy=reject) header.from=aol.com;
spf=pass (mail3.ecloud.global: domain of alice@aol.com designates 77.238.178.146 as permitted sender) smtp.mailfrom=alice@aol.com

View File

@@ -1,6 +0,0 @@
From: <alice@buzon.uy>
To: <alice@e.email>
Authentication-Results: mail3.ecloud.global;
dkim=pass header.d=buzon.uy header.s=2019 header.b=XfN4sE6M;
dmarc=pass (policy=reject) header.from=buzon.uy;
spf=pass (mail3.ecloud.global: domain of alice@buzon.uy designates 185.101.93.79 as permitted sender) smtp.mailfrom=alice@buzon.uy

View File

@@ -1,6 +0,0 @@
From: <alice@delta.blinzeln.de>
To: <alice@e.email>
Authentication-Results: mail2.ecloud.global;
dkim=none;
dmarc=none;
spf=none (mail2.ecloud.global: domain of alice@delta.blinzeln.de has no SPF policy when checking 192.162.87.117) smtp.mailfrom=alice@delta.blinzeln.de

View File

@@ -1,6 +0,0 @@
From: <alice@disroot.org>
To: <alice@e.email>
Authentication-Results: mail2.ecloud.global;
dkim=pass header.d=disroot.org header.s=mail header.b=Vf7JxMcu;
dmarc=pass (policy=quarantine) header.from=disroot.org;
spf=pass (mail2.ecloud.global: domain of alice@disroot.org designates 178.21.23.139 as permitted sender) smtp.mailfrom=alice@disroot.org

View File

@@ -1,7 +0,0 @@
From: <alice@fastmail.com>
To: <alice@e.email>
Authentication-Results: mail2.ecloud.global;
dkim=pass header.d=fastmail.com header.s=fm2 header.b=bQ080jJU;
dkim=pass header.d=messagingengine.com header.s=fm2 header.b=FVyMuSGb;
dmarc=pass (policy=none) header.from=fastmail.com;
spf=pass (mail2.ecloud.global: domain of alice@fastmail.com designates 66.111.4.28 as permitted sender) smtp.mailfrom=alice@fastmail.com

View File

@@ -1,6 +0,0 @@
From: <alice@gmail.com>
To: <alice@e.email>
Authentication-Results: mail2.ecloud.global;
dkim=pass header.d=gmail.com header.s=20210112 header.b=f2AxVaaA;
dmarc=pass (policy=none) header.from=gmail.com;
spf=pass (mail2.ecloud.global: domain of alice@gmail.com designates 2a00:1450:4864:20::443 as permitted sender) smtp.mailfrom=alice@gmail.com

View File

@@ -1,9 +0,0 @@
ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none;
dkim=none; arc=none
From: <alice@hotmail.com>
To: <alice@e.email>
Authentication-Results: mail3.ecloud.global;
dkim=pass header.d=hotmail.com header.s=selector1 header.b="ECc21y/J";
arc=pass ("microsoft.com:s=arcselector9901:i=1");
dmarc=pass (policy=none) header.from=hotmail.com;
spf=pass (mail3.ecloud.global: domain of alice@hotmail.com designates 40.92.68.54 as permitted sender) smtp.mailfrom=alice@hotmail.com

View File

@@ -1,6 +0,0 @@
From: <alice@icloud.com>
To: <alice@e.email>
Authentication-Results: mail3.ecloud.global;
dkim=pass header.d=icloud.com header.s=1a1hai header.b=enuQcpfH;
dmarc=pass (policy=quarantine) header.from=icloud.com;
spf=pass (mail3.ecloud.global: domain of alice@icloud.com designates 17.57.155.16 as permitted sender) smtp.mailfrom=alice@icloud.com

View File

@@ -1,6 +0,0 @@
From: <alice@ik.me>
To: <alice@e.email>
Authentication-Results: mail2.ecloud.global;
dkim=pass header.d=ik.me header.s=20200325 header.b=E5lGMzkQ;
dmarc=pass (policy=reject) header.from=ik.me;
spf=pass (mail2.ecloud.global: domain of alice@ik.me designates 83.166.143.168 as permitted sender) smtp.mailfrom=alice@ik.me

View File

@@ -1,6 +0,0 @@
From: <alice@mail.de>
To: <alice@e.email>
Authentication-Results: mail3.ecloud.global;
dkim=pass header.d=mail.de header.s=mailde202009 header.b=vVqLo0H5;
dmarc=pass (policy=none) header.from=mail.de;
spf=pass (mail3.ecloud.global: domain of alice@mail.de designates 2001:868:100:600::216 as permitted sender) smtp.mailfrom=alice@mail.de

View File

@@ -1,6 +0,0 @@
From: <alice@mail.ru>
To: <alice@e.email>
Authentication-Results: mail2.ecloud.global;
dkim=pass header.d=mail.ru header.s=mail4 header.b=heZ1ZiKV;
dmarc=pass (policy=reject) header.from=mail.ru;
spf=pass (mail2.ecloud.global: domain of alice@mail.ru designates 94.100.181.251 as permitted sender) smtp.mailfrom=alice@mail.ru

View File

@@ -1,6 +0,0 @@
From: <alice@mailo.com>
To: <alice@e.email>
Authentication-Results: mail2.ecloud.global;
dkim=pass header.d=mailo.com header.s=mailo header.b=HnhKNKUg;
dmarc=pass (policy=none) header.from=mailo.com;
spf=pass (mail2.ecloud.global: domain of alice@mailo.com designates 213.182.54.15 as permitted sender) smtp.mailfrom=alice@mailo.com

View File

@@ -1,9 +0,0 @@
ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=none; dmarc=none;
dkim=none; arc=none
From: <alice@outlook.com>
To: <alice@e.email>
Authentication-Results: mail3.ecloud.global;
dkim=pass header.d=outlook.com header.s=selector1 header.b=MqNsAJKf;
arc=pass ("microsoft.com:s=arcselector9901:i=1");
dmarc=pass (policy=none) header.from=outlook.com;
spf=pass (mail3.ecloud.global: domain of alice@outlook.com designates 40.92.66.84 as permitted sender) smtp.mailfrom=alice@outlook.com

View File

@@ -1,6 +0,0 @@
From: <alice@posteo.de>
To: <alice@e.email>
Authentication-Results: mail2.ecloud.global;
dkim=pass header.d=posteo.de header.s=2017 header.b=bMopHaXo;
dmarc=pass (policy=none) header.from=posteo.de;
spf=pass (mail2.ecloud.global: domain of alice@posteo.de designates 185.67.36.66 as permitted sender) smtp.mailfrom=alice@posteo.de

View File

@@ -1,6 +0,0 @@
From: <alice@riseup.net>
To: <alice@e.email>
Authentication-Results: mail2.ecloud.global;
dkim=pass header.d=riseup.net header.s=squak header.b="GUmo/IlI";
dmarc=pass (policy=none) header.from=riseup.net;
spf=pass (mail2.ecloud.global: domain of alice@riseup.net designates 198.252.153.129 as permitted sender) smtp.mailfrom=alice@riseup.net

View File

@@ -1,6 +0,0 @@
From: <alice@yahoo.com>
To: <alice@e.email>
Authentication-Results: mail2.ecloud.global;
dkim=pass header.d=yahoo.com header.s=s2048 header.b=mRSwanl2;
dmarc=pass (policy=reject) header.from=yahoo.com;
spf=pass (mail2.ecloud.global: domain of alice@yahoo.com designates 77.238.178.146 as permitted sender) smtp.mailfrom=alice@yahoo.com

View File

@@ -1,3 +0,0 @@
From: forged-authres-added@example.com
Authentication-Results: mail2.ecloud.global;
Authentication-Results: aaa.com; dkim=pass header.i=@example.com

View File

@@ -1,39 +0,0 @@
ARC-Authentication-Results: i=1; mx1.messagingengine.com;
x-csa=none;
x-me-sender=none;
x-ptr=pass smtp.helo=sonic314-20.consmr.mail.ir2.yahoo.com
policy.ptr=sonic314-20.consmr.mail.ir2.yahoo.com;
bimi=none (No BIMI records found);
arc=none (no signatures found);
dkim=pass (2048-bit rsa key sha256) header.d=aol.com header.i=@aol.com
header.b=Y+EgdIPN header.a=rsa-sha256 header.s=a2048 x-bits=2048;
dmarc=pass policy.published-domain-policy=reject
policy.applied-disposition=none policy.evaluated-disposition=none
(p=reject,d=none,d.eval=none) policy.policy-from=p
header.from=aol.com;
iprev=pass smtp.remote-ip=77.238.177.146
(sonic314-20.consmr.mail.ir2.yahoo.com);
spf=pass smtp.mailfrom=alice@aol.com
smtp.helo=sonic314-20.consmr.mail.ir2.yahoo.com
Authentication-Results: mx1.messagingengine.com;
x-csa=none;
x-me-sender=none;
x-ptr=pass smtp.helo=sonic314-20.consmr.mail.ir2.yahoo.com
policy.ptr=sonic314-20.consmr.mail.ir2.yahoo.com
Authentication-Results: mx1.messagingengine.com;
bimi=none (No BIMI records found)
Authentication-Results: mx1.messagingengine.com;
arc=none (no signatures found)
Authentication-Results: mx1.messagingengine.com;
dkim=pass (2048-bit rsa key sha256) header.d=aol.com header.i=@aol.com
header.b=Y+EgdIPN header.a=rsa-sha256 header.s=a2048 x-bits=2048;
dmarc=pass policy.published-domain-policy=reject
policy.applied-disposition=none policy.evaluated-disposition=none
(p=reject,d=none,d.eval=none) policy.policy-from=p
header.from=aol.com;
iprev=pass smtp.remote-ip=77.238.177.146
(sonic314-20.consmr.mail.ir2.yahoo.com);
spf=pass smtp.mailfrom=alice@aol.com
smtp.helo=sonic314-20.consmr.mail.ir2.yahoo.com
From: <alice@aol.com>
To: <alice@fastmail.com>

View File

@@ -1,33 +0,0 @@
ARC-Authentication-Results: i=1; mx4.messagingengine.com;
x-csa=none;
x-me-sender=none;
x-ptr=pass smtp.helo=mail.buzon.uy policy.ptr=mail.buzon.uy;
bimi=none (No BIMI records found);
arc=none (no signatures found);
dkim=pass (2048-bit rsa key sha256) header.d=buzon.uy header.i=@buzon.uy
header.b=ibjKHetx header.a=rsa-sha256 header.s=2019 x-bits=2048;
dmarc=pass policy.published-domain-policy=reject
policy.applied-disposition=none policy.evaluated-disposition=none
(p=reject,d=none,d.eval=none) policy.policy-from=p
header.from=buzon.uy;
iprev=pass smtp.remote-ip=185.101.93.79 (mail.buzon.uy);
spf=pass smtp.mailfrom=alice@buzon.uy smtp.helo=mail.buzon.uy
Authentication-Results: mx4.messagingengine.com;
x-csa=none;
x-me-sender=none;
x-ptr=pass smtp.helo=mail.buzon.uy policy.ptr=mail.buzon.uy
Authentication-Results: mx4.messagingengine.com;
bimi=none (No BIMI records found)
Authentication-Results: mx4.messagingengine.com;
arc=none (no signatures found)
Authentication-Results: mx4.messagingengine.com;
dkim=pass (2048-bit rsa key sha256) header.d=buzon.uy header.i=@buzon.uy
header.b=ibjKHetx header.a=rsa-sha256 header.s=2019 x-bits=2048;
dmarc=pass policy.published-domain-policy=reject
policy.applied-disposition=none policy.evaluated-disposition=none
(p=reject,d=none,d.eval=none) policy.policy-from=p
header.from=buzon.uy;
iprev=pass smtp.remote-ip=185.101.93.79 (mail.buzon.uy);
spf=pass smtp.mailfrom=alice@buzon.uy smtp.helo=mail.buzon.uy
From: <alice@buzon.uy>
To: <alice@fastmail.com>

View File

@@ -1,38 +0,0 @@
ARC-Authentication-Results: i=1; mx1.messagingengine.com;
x-csa=none;
x-me-sender=none;
x-ptr=pass smtp.helo=nx184.node01.secure-mailgate.com
policy.ptr=nx184.node01.secure-mailgate.com;
bimi=skipped (DMARC did not pass);
arc=none (no signatures found);
dkim=none (no signatures found);
dmarc=none policy.published-domain-policy=none
policy.applied-disposition=none policy.evaluated-disposition=none
(p=none,d=none,d.eval=none) policy.policy-from=p
header.from=delta.blinzeln.de;
iprev=pass smtp.remote-ip=89.22.108.184
(nx184.node01.secure-mailgate.com);
spf=none smtp.mailfrom=alice@delta.blinzeln.de
smtp.helo=nx184.node01.secure-mailgate.com
Authentication-Results: mx1.messagingengine.com;
x-csa=none;
x-me-sender=none;
x-ptr=pass smtp.helo=nx184.node01.secure-mailgate.com
policy.ptr=nx184.node01.secure-mailgate.com
Authentication-Results: mx1.messagingengine.com;
bimi=skipped (DMARC did not pass)
Authentication-Results: mx1.messagingengine.com;
arc=none (no signatures found)
Authentication-Results: mx1.messagingengine.com;
dkim=none (no signatures found);
dmarc=none policy.published-domain-policy=none
policy.applied-disposition=none policy.evaluated-disposition=none
(p=none,d=none,d.eval=none) policy.policy-from=p
header.from=delta.blinzeln.de;
iprev=pass smtp.remote-ip=89.22.108.184
(nx184.node01.secure-mailgate.com);
spf=none smtp.mailfrom=alice@delta.blinzeln.de
smtp.helo=nx184.node01.secure-mailgate.com
From: <alice@delta.blinzeln.de>
To: <alice@fastmail.com>
Authentication-Results: secure-mailgate.com; auth=pass smtp.auth=91.203.111.88@webbox222.server-home.org

Some files were not shown because too many files have changed in this diff Show More