mirror of
https://github.com/chatmail/core.git
synced 2026-04-02 05:22:14 +03:00
Compare commits
4 Commits
acffad37ef
...
refactor/m
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a6c7b42e99 | ||
|
|
b462cd566d | ||
|
|
97e09ebf4a | ||
|
|
f27ddb1bb4 |
@@ -7,6 +7,7 @@ use crate::config::*;
|
||||
use crate::constants::*;
|
||||
use crate::contact::*;
|
||||
use crate::context::Context;
|
||||
use crate::dc_mimeparser::SystemMessage;
|
||||
use crate::dc_tools::*;
|
||||
use crate::error::Error;
|
||||
use crate::events::Event;
|
||||
@@ -1669,7 +1670,8 @@ pub fn set_chat_profile_image(
|
||||
if chat.update_param(context).is_ok() {
|
||||
if chat.is_promoted() {
|
||||
let mut msg = dc_msg_new_untyped();
|
||||
msg.param.set_int(Param::Cmd, DC_CMD_GROUPIMAGE_CHANGED);
|
||||
msg.param
|
||||
.set_int(Param::Cmd, SystemMessage::GroupImageChanged as i32);
|
||||
msg.type_0 = Viewtype::Text;
|
||||
msg.text = Some(context.stock_system_msg(
|
||||
if new_image_rel == "" {
|
||||
|
||||
@@ -314,12 +314,3 @@ pub enum KeyType {
|
||||
Public = 0,
|
||||
Private = 1,
|
||||
}
|
||||
|
||||
pub const DC_CMD_GROUPNAME_CHANGED: libc::c_int = 2;
|
||||
pub const DC_CMD_GROUPIMAGE_CHANGED: libc::c_int = 3;
|
||||
pub const DC_CMD_MEMBER_ADDED_TO_GROUP: libc::c_int = 4;
|
||||
pub const DC_CMD_MEMBER_REMOVED_FROM_GROUP: libc::c_int = 5;
|
||||
pub const DC_CMD_AUTOCRYPT_SETUP_MESSAGE: libc::c_int = 6;
|
||||
pub const DC_CMD_SECUREJOIN_MESSAGE: libc::c_int = 7;
|
||||
pub const DC_CMD_LOCATION_STREAMING_ENABLED: libc::c_int = 8;
|
||||
pub const DC_CMD_LOCATION_ONLY: libc::c_int = 9;
|
||||
|
||||
@@ -490,10 +490,9 @@ pub unsafe fn dc_normalize_setup_code(
|
||||
pub unsafe fn dc_job_do_DC_JOB_IMEX_IMAP(context: &Context, job: &Job) {
|
||||
let mut ok_to_continue = true;
|
||||
let mut success: libc::c_int = 0;
|
||||
let what: libc::c_int;
|
||||
|
||||
if dc_alloc_ongoing(context) {
|
||||
what = job.param.get_int(Param::Cmd).unwrap_or_default();
|
||||
let what = job.param.get_int(Param::Cmd).unwrap_or_default();
|
||||
let param1_s = job.param.get(Param::Arg).unwrap_or_default();
|
||||
let param1 = CString::yolo(param1_s);
|
||||
let _param2 = CString::yolo(job.param.get(Param::Arg2).unwrap_or_default());
|
||||
|
||||
@@ -16,6 +16,7 @@ use crate::chat::{self, Chat};
|
||||
use crate::constants::*;
|
||||
use crate::contact::*;
|
||||
use crate::context::{get_version_str, Context};
|
||||
use crate::dc_mimeparser::SystemMessage;
|
||||
use crate::dc_strencode::*;
|
||||
use crate::dc_tools::*;
|
||||
use crate::e2ee::*;
|
||||
@@ -170,10 +171,10 @@ pub unsafe fn dc_mimefactory_load_msg(
|
||||
)
|
||||
.unwrap();
|
||||
|
||||
let command = factory.msg.param.get_int(Param::Cmd).unwrap_or_default();
|
||||
let command = factory.msg.param.get_cmd();
|
||||
let msg = &factory.msg;
|
||||
|
||||
if command == 5 {
|
||||
if command == SystemMessage::MemberRemovedFromGroup {
|
||||
let email_to_remove = msg.param.get(Param::Arg).unwrap_or_default();
|
||||
let email_to_remove_c = email_to_remove.strdup();
|
||||
|
||||
@@ -197,8 +198,8 @@ pub unsafe fn dc_mimefactory_load_msg(
|
||||
}
|
||||
}
|
||||
}
|
||||
if command != 6
|
||||
&& command != 7
|
||||
if command != SystemMessage::AutocryptSetupMessage
|
||||
&& command != SystemMessage::SecurejoinMessage
|
||||
&& 0 != context
|
||||
.sql
|
||||
.get_config_int(context, "mdns_enabled")
|
||||
@@ -529,7 +530,7 @@ pub unsafe fn dc_mimefactory_render(context: &Context, factory: &mut dc_mimefact
|
||||
}
|
||||
|
||||
/* build header etc. */
|
||||
let command = factory.msg.param.get_int(Param::Cmd).unwrap_or_default();
|
||||
let command = factory.msg.param.get_cmd();
|
||||
if chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup {
|
||||
mailimf_fields_add(
|
||||
imf_fields,
|
||||
@@ -546,7 +547,8 @@ pub unsafe fn dc_mimefactory_render(context: &Context, factory: &mut dc_mimefact
|
||||
dc_encode_header_words(name.as_ptr()),
|
||||
),
|
||||
);
|
||||
if command == DC_CMD_MEMBER_REMOVED_FROM_GROUP {
|
||||
|
||||
if command == SystemMessage::MemberRemovedFromGroup {
|
||||
let email_to_remove = factory
|
||||
.msg
|
||||
.param
|
||||
@@ -565,7 +567,7 @@ pub unsafe fn dc_mimefactory_render(context: &Context, factory: &mut dc_mimefact
|
||||
),
|
||||
);
|
||||
}
|
||||
} else if command == DC_CMD_MEMBER_ADDED_TO_GROUP {
|
||||
} else if command == SystemMessage::MemberAddedToGroup {
|
||||
let msg = &factory.msg;
|
||||
do_gossip = 1;
|
||||
let email_to_add = msg.param.get(Param::Arg).unwrap_or_default().strdup();
|
||||
@@ -596,7 +598,7 @@ pub unsafe fn dc_mimefactory_render(context: &Context, factory: &mut dc_mimefact
|
||||
),
|
||||
);
|
||||
}
|
||||
} else if command == DC_CMD_GROUPNAME_CHANGED {
|
||||
} else if command == SystemMessage::GroupNameChanged {
|
||||
let msg = &factory.msg;
|
||||
|
||||
let value_to_add = msg.param.get(Param::Arg).unwrap_or_default().strdup();
|
||||
@@ -609,7 +611,7 @@ pub unsafe fn dc_mimefactory_render(context: &Context, factory: &mut dc_mimefact
|
||||
value_to_add,
|
||||
),
|
||||
);
|
||||
} else if command == DC_CMD_GROUPIMAGE_CHANGED {
|
||||
} else if command == SystemMessage::GroupImageChanged {
|
||||
let msg = &factory.msg;
|
||||
grpimage = msg.param.get(Param::Arg);
|
||||
if grpimage.is_none() {
|
||||
@@ -623,7 +625,8 @@ pub unsafe fn dc_mimefactory_render(context: &Context, factory: &mut dc_mimefact
|
||||
}
|
||||
}
|
||||
}
|
||||
if command == DC_CMD_LOCATION_STREAMING_ENABLED {
|
||||
|
||||
if command == SystemMessage::LocationStreamingEnabled {
|
||||
mailimf_fields_add(
|
||||
imf_fields,
|
||||
mailimf_field_new_custom(
|
||||
@@ -634,7 +637,7 @@ pub unsafe fn dc_mimefactory_render(context: &Context, factory: &mut dc_mimefact
|
||||
),
|
||||
);
|
||||
}
|
||||
if command == DC_CMD_AUTOCRYPT_SETUP_MESSAGE {
|
||||
if command == SystemMessage::AutocryptSetupMessage {
|
||||
mailimf_fields_add(
|
||||
imf_fields,
|
||||
mailimf_field_new_custom(
|
||||
@@ -647,7 +650,7 @@ pub unsafe fn dc_mimefactory_render(context: &Context, factory: &mut dc_mimefact
|
||||
.stock_str(StockMessage::AcSetupMsgBody)
|
||||
.strdup();
|
||||
}
|
||||
if command == DC_CMD_SECUREJOIN_MESSAGE {
|
||||
if command == SystemMessage::SecurejoinMessage {
|
||||
let msg = &factory.msg;
|
||||
let step = msg.param.get(Param::Arg).unwrap_or_default().strdup();
|
||||
if strlen(step) > 0 {
|
||||
@@ -721,6 +724,7 @@ pub unsafe fn dc_mimefactory_render(context: &Context, factory: &mut dc_mimefact
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(grpimage) = grpimage {
|
||||
info!(factory.context, "setting group image '{}'", grpimage);
|
||||
let mut meta = dc_msg_new_untyped();
|
||||
@@ -1079,7 +1083,7 @@ unsafe fn get_subject(
|
||||
} else {
|
||||
b"\x00" as *const u8 as *const libc::c_char
|
||||
};
|
||||
if msg.param.get_int(Param::Cmd).unwrap_or_default() == DC_CMD_AUTOCRYPT_SETUP_MESSAGE {
|
||||
if msg.param.get_cmd() == SystemMessage::AutocryptSetupMessage {
|
||||
ret = context.stock_str(StockMessage::AcSetupMsgSubject).strdup()
|
||||
} else if chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup {
|
||||
ret = format!(
|
||||
|
||||
2292
src/dc_mimeparser.rs
2292
src/dc_mimeparser.rs
File diff suppressed because it is too large
Load Diff
@@ -63,7 +63,8 @@ pub unsafe fn dc_receive_imf(
|
||||
// somewhen, I did not found out anything that speaks against this approach yet)
|
||||
|
||||
let body = std::slice::from_raw_parts(imf_raw_not_terminated as *const u8, imf_raw_bytes);
|
||||
let mut mime_parser = dc_mimeparser_parse(context, body);
|
||||
let mut mime_parser = MimeParser::new(context);
|
||||
mime_parser.parse(body);
|
||||
|
||||
if mime_parser.header.is_empty() {
|
||||
// Error - even adding an empty record won't help as we do not know the message ID
|
||||
@@ -124,7 +125,7 @@ pub unsafe fn dc_receive_imf(
|
||||
}
|
||||
};
|
||||
|
||||
if let Some(field) = lookup_field(&mime_parser, "Date", MAILIMF_FIELD_ORIG_DATE) {
|
||||
if let Some(field) = mime_parser.lookup_field_typ("Date", MAILIMF_FIELD_ORIG_DATE) {
|
||||
let orig_date = (*field).fld_data.fld_orig_date;
|
||||
if !orig_date.is_null() {
|
||||
// is not yet checked against bad times! we do this later if we have the database information.
|
||||
@@ -135,7 +136,7 @@ pub unsafe fn dc_receive_imf(
|
||||
// get From: and check if it is known (for known From:'s we add the other To:/Cc: in the 3rd pass)
|
||||
// or if From: is equal to SELF (in this case, it is any outgoing messages,
|
||||
// we do not check Return-Path any more as this is unreliable, see issue #150
|
||||
if let Some(field) = lookup_field(&mime_parser, "From", MAILIMF_FIELD_FROM) {
|
||||
if let Some(field) = mime_parser.lookup_field_typ("From", MAILIMF_FIELD_FROM) {
|
||||
let fld_from = (*field).fld_data.fld_from;
|
||||
if !fld_from.is_null() {
|
||||
let mut check_self = 0;
|
||||
@@ -149,7 +150,7 @@ pub unsafe fn dc_receive_imf(
|
||||
);
|
||||
if 0 != check_self {
|
||||
incoming = 0;
|
||||
if 0 != dc_mimeparser_sender_equals_recipient(&mime_parser) {
|
||||
if mime_parser.sender_equals_recipient() {
|
||||
from_id = DC_CONTACT_ID_SELF;
|
||||
}
|
||||
} else if from_list.len() >= 1 {
|
||||
@@ -163,7 +164,7 @@ pub unsafe fn dc_receive_imf(
|
||||
}
|
||||
|
||||
// Make sure, to_ids starts with the first To:-address (Cc: is added in the loop below pass)
|
||||
if let Some(field) = lookup_field(&mime_parser, "To", MAILIMF_FIELD_TO) {
|
||||
if let Some(field) = mime_parser.lookup_field_typ("To", MAILIMF_FIELD_TO) {
|
||||
let fld_to = (*field).fld_data.fld_to;
|
||||
if !fld_to.is_null() {
|
||||
dc_add_or_lookup_contacts_by_address_list(
|
||||
@@ -183,7 +184,7 @@ pub unsafe fn dc_receive_imf(
|
||||
}
|
||||
|
||||
// Add parts
|
||||
if dc_mimeparser_get_last_nonmeta(&mut mime_parser).is_some() {
|
||||
if mime_parser.get_last_nonmeta().is_some() {
|
||||
if let Err(err) = add_parts(
|
||||
context,
|
||||
&mut mime_parser,
|
||||
@@ -278,7 +279,7 @@ pub unsafe fn dc_receive_imf(
|
||||
|
||||
unsafe fn add_parts(
|
||||
context: &Context,
|
||||
mut mime_parser: &mut dc_mimeparser_t,
|
||||
mut mime_parser: &mut MimeParser,
|
||||
imf_raw_not_terminated: *const libc::c_char,
|
||||
imf_raw_bytes: libc::size_t,
|
||||
incoming: i32,
|
||||
@@ -320,7 +321,7 @@ unsafe fn add_parts(
|
||||
// collect the rest information, CC: is added to the to-list, BCC: is ignored
|
||||
// (we should not add BCC to groups as this would split groups. We could add them as "known contacts",
|
||||
// however, the benefit is very small and this may leak data that is expected to be hidden)
|
||||
if let Some(field) = lookup_field(mime_parser, "Cc", MAILIMF_FIELD_CC) {
|
||||
if let Some(field) = mime_parser.lookup_field_typ("Cc", MAILIMF_FIELD_CC) {
|
||||
let fld_cc = (*field).fld_data.fld_cc;
|
||||
if !fld_cc.is_null() {
|
||||
dc_add_or_lookup_contacts_by_address_list(
|
||||
@@ -343,7 +344,7 @@ unsafe fn add_parts(
|
||||
// change. (missing Message-IDs may come if the mail was set from this account with another
|
||||
// client that relies in the SMTP server to generate one.
|
||||
// true eg. for the Webmailer used in all-inkl-KAS)
|
||||
if let Some(field) = lookup_field(mime_parser, "Message-ID", MAILIMF_FIELD_MESSAGE_ID) {
|
||||
if let Some(field) = mime_parser.lookup_field_typ("Message-ID", MAILIMF_FIELD_MESSAGE_ID) {
|
||||
let fld_message_id = (*field).fld_data.fld_message_id;
|
||||
if !fld_message_id.is_null() {
|
||||
rfc724_mid = dc_strdup((*fld_message_id).mid_value)
|
||||
@@ -388,7 +389,7 @@ unsafe fn add_parts(
|
||||
// incoming non-chat messages may be discarded;
|
||||
// maybe this can be optimized later, by checking the state before the message body is downloaded
|
||||
let mut allow_creation = 1;
|
||||
if mime_parser.is_system_message != DC_CMD_AUTOCRYPT_SETUP_MESSAGE && msgrmsg == 0 {
|
||||
if mime_parser.is_system_message != SystemMessage::AutocryptSetupMessage && msgrmsg == 0 {
|
||||
let show_emails = context
|
||||
.sql
|
||||
.get_config_int(context, "show_emails")
|
||||
@@ -414,7 +415,7 @@ unsafe fn add_parts(
|
||||
*to_id = 1;
|
||||
// handshake messages must be processed _before_ chats are created
|
||||
// (eg. contacs may be marked as verified)
|
||||
if !dc_mimeparser_lookup_field(mime_parser, "Secure-Join").is_null() {
|
||||
if mime_parser.lookup_field("Secure-Join").is_some() {
|
||||
// avoid discarding by show_emails setting
|
||||
msgrmsg = 1;
|
||||
*chat_id = 0;
|
||||
@@ -463,7 +464,7 @@ unsafe fn add_parts(
|
||||
|
||||
if *chat_id == 0 {
|
||||
// check if the message belongs to a mailing list
|
||||
if dc_mimeparser_is_mailinglist_message(mime_parser) {
|
||||
if mime_parser.is_mailinglist_message() {
|
||||
*chat_id = 3;
|
||||
info!(context, "Message belongs to a mailing list and is ignored.",);
|
||||
}
|
||||
@@ -605,7 +606,7 @@ unsafe fn add_parts(
|
||||
.sql
|
||||
.get_config_int(context, "save_mime_headers")
|
||||
.unwrap_or_default();
|
||||
if let Some(field) = lookup_field(mime_parser, "In-Reply-To", MAILIMF_FIELD_IN_REPLY_TO) {
|
||||
if let Some(field) = mime_parser.lookup_field_typ("In-Reply-To", MAILIMF_FIELD_IN_REPLY_TO) {
|
||||
let fld_in_reply_to = (*field).fld_data.fld_in_reply_to;
|
||||
if !fld_in_reply_to.is_null() {
|
||||
mime_in_reply_to = dc_str_from_clist(
|
||||
@@ -615,7 +616,7 @@ unsafe fn add_parts(
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(field) = lookup_field(mime_parser, "References", MAILIMF_FIELD_REFERENCES) {
|
||||
if let Some(field) = mime_parser.lookup_field_typ("References", MAILIMF_FIELD_REFERENCES) {
|
||||
let fld_references = (*field).fld_data.fld_references;
|
||||
if !fld_references.is_null() {
|
||||
mime_references = dc_str_from_clist(
|
||||
@@ -656,7 +657,7 @@ unsafe fn add_parts(
|
||||
}
|
||||
}
|
||||
}
|
||||
if part.type_0 == Viewtype::Text {
|
||||
if part.typ == Viewtype::Text {
|
||||
let msg_raw =
|
||||
CString::yolo(part.msg_raw.as_ref().cloned().unwrap_or_default());
|
||||
let subject_c = CString::yolo(
|
||||
@@ -672,9 +673,9 @@ unsafe fn add_parts(
|
||||
msg_raw.as_ptr(),
|
||||
)
|
||||
}
|
||||
if 0 != mime_parser.is_system_message {
|
||||
if mime_parser.is_system_message != SystemMessage::Unknown {
|
||||
part.param
|
||||
.set_int(Param::Cmd, mime_parser.is_system_message);
|
||||
.set_int(Param::Cmd, mime_parser.is_system_message as i32);
|
||||
}
|
||||
|
||||
stmt.execute(params![
|
||||
@@ -687,7 +688,7 @@ unsafe fn add_parts(
|
||||
sort_timestamp,
|
||||
*sent_timestamp,
|
||||
rcvd_timestamp,
|
||||
part.type_0,
|
||||
part.typ,
|
||||
state,
|
||||
msgrmsg,
|
||||
part.msg.as_ref().map_or("", String::as_str),
|
||||
@@ -761,24 +762,10 @@ unsafe fn add_parts(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Lookup a mime field given its name and type.
|
||||
unsafe fn lookup_field(
|
||||
parser: &dc_mimeparser_t,
|
||||
name: &str,
|
||||
typ: u32,
|
||||
) -> Option<*const mailimf_field> {
|
||||
let field = dc_mimeparser_lookup_field(parser, name);
|
||||
if !field.is_null() && (*field).fld_type == typ as libc::c_int {
|
||||
Some(field)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
// Handle reports (mainly MDNs)
|
||||
unsafe fn handle_reports(
|
||||
context: &Context,
|
||||
mime_parser: &dc_mimeparser_t,
|
||||
mime_parser: &MimeParser,
|
||||
from_id: u32,
|
||||
sent_timestamp: i64,
|
||||
rr_event_to_send: &mut Vec<(u32, u32)>,
|
||||
@@ -941,7 +928,7 @@ unsafe fn handle_reports(
|
||||
|
||||
fn save_locations(
|
||||
context: &Context,
|
||||
mime_parser: &dc_mimeparser_t,
|
||||
mime_parser: &MimeParser,
|
||||
chat_id: u32,
|
||||
from_id: u32,
|
||||
insert_msg_id: u32,
|
||||
@@ -1039,7 +1026,7 @@ unsafe fn calc_timestamps(
|
||||
#[allow(non_snake_case)]
|
||||
unsafe fn create_or_lookup_group(
|
||||
context: &Context,
|
||||
mime_parser: &mut dc_mimeparser_t,
|
||||
mime_parser: &mut MimeParser,
|
||||
allow_creation: libc::c_int,
|
||||
create_blocked: Blocked,
|
||||
from_id: u32,
|
||||
@@ -1051,28 +1038,20 @@ unsafe fn create_or_lookup_group(
|
||||
let mut chat_id = 0;
|
||||
let mut chat_id_blocked = Blocked::Not;
|
||||
let mut grpid = "".to_string();
|
||||
let mut grpname = std::ptr::null_mut();
|
||||
let mut grpname = None;
|
||||
let to_ids_cnt = to_ids.len();
|
||||
let mut recreate_member_list = 0;
|
||||
let mut send_EVENT_CHAT_MODIFIED = 0;
|
||||
// pointer somewhere into mime_parser, must not be freed
|
||||
let mut X_MrRemoveFromGrp = std::ptr::null_mut();
|
||||
// pointer somewhere into mime_parser, must not be freed
|
||||
let mut X_MrAddToGrp = std::ptr::null_mut();
|
||||
let mut X_MrRemoveFromGrp = None;
|
||||
let mut X_MrAddToGrp = None;
|
||||
let mut X_MrGrpNameChanged = 0;
|
||||
let mut X_MrGrpImageChanged = "".to_string();
|
||||
let mut better_msg: String = From::from("");
|
||||
let mut failure_reason = std::ptr::null_mut();
|
||||
|
||||
let cleanup = |grpname: *mut libc::c_char,
|
||||
failure_reason: *mut libc::c_char,
|
||||
ret_chat_id: *mut u32,
|
||||
let cleanup = |ret_chat_id: *mut u32,
|
||||
ret_chat_id_blocked: &mut Blocked,
|
||||
chat_id: u32,
|
||||
chat_id_blocked: Blocked| {
|
||||
free(grpname.cast());
|
||||
free(failure_reason.cast());
|
||||
|
||||
if !ret_chat_id.is_null() {
|
||||
*ret_chat_id = chat_id;
|
||||
}
|
||||
@@ -1083,18 +1062,18 @@ unsafe fn create_or_lookup_group(
|
||||
};
|
||||
};
|
||||
|
||||
if mime_parser.is_system_message == DC_CMD_LOCATION_STREAMING_ENABLED {
|
||||
if mime_parser.is_system_message == SystemMessage::LocationStreamingEnabled {
|
||||
better_msg =
|
||||
context.stock_system_msg(StockMessage::MsgLocationEnabled, "", "", from_id as u32)
|
||||
}
|
||||
set_better_msg(mime_parser, &better_msg);
|
||||
|
||||
let optional_field = dc_mimeparser_lookup_optional_field(mime_parser, "Chat-Group-ID");
|
||||
if !optional_field.is_null() {
|
||||
grpid = to_string((*optional_field).fld_value)
|
||||
if let Some(optional_field) = mime_parser.lookup_optional_field("Chat-Group-ID") {
|
||||
grpid = optional_field;
|
||||
}
|
||||
|
||||
if grpid.is_empty() {
|
||||
if let Some(field) = lookup_field(mime_parser, "Message-ID", MAILIMF_FIELD_MESSAGE_ID) {
|
||||
if let Some(field) = mime_parser.lookup_field_typ("Message-ID", MAILIMF_FIELD_MESSAGE_ID) {
|
||||
let fld_message_id = (*field).fld_data.fld_message_id;
|
||||
if !fld_message_id.is_null() {
|
||||
if let Some(extracted_grpid) =
|
||||
@@ -1107,7 +1086,8 @@ unsafe fn create_or_lookup_group(
|
||||
}
|
||||
}
|
||||
if grpid.is_empty() {
|
||||
if let Some(field) = lookup_field(mime_parser, "In-Reply-To", MAILIMF_FIELD_IN_REPLY_TO)
|
||||
if let Some(field) =
|
||||
mime_parser.lookup_field_typ("In-Reply-To", MAILIMF_FIELD_IN_REPLY_TO)
|
||||
{
|
||||
let fld_in_reply_to = (*field).fld_data.fld_in_reply_to;
|
||||
if !fld_in_reply_to.is_null() {
|
||||
@@ -1118,7 +1098,7 @@ unsafe fn create_or_lookup_group(
|
||||
}
|
||||
if grpid.is_empty() {
|
||||
if let Some(field) =
|
||||
lookup_field(mime_parser, "References", MAILIMF_FIELD_REFERENCES)
|
||||
mime_parser.lookup_field_typ("References", MAILIMF_FIELD_REFERENCES)
|
||||
{
|
||||
let fld_references = (*field).fld_data.fld_references;
|
||||
if !fld_references.is_null() {
|
||||
@@ -1139,30 +1119,20 @@ unsafe fn create_or_lookup_group(
|
||||
&mut chat_id,
|
||||
&mut chat_id_blocked,
|
||||
);
|
||||
cleanup(
|
||||
grpname,
|
||||
failure_reason,
|
||||
ret_chat_id,
|
||||
ret_chat_id_blocked,
|
||||
chat_id,
|
||||
chat_id_blocked,
|
||||
);
|
||||
cleanup(ret_chat_id, ret_chat_id_blocked, chat_id, chat_id_blocked);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let optional_field = dc_mimeparser_lookup_optional_field(mime_parser, "Chat-Group-Name");
|
||||
if !optional_field.is_null() {
|
||||
grpname = dc_decode_header_words((*optional_field).fld_value)
|
||||
if let Some(optional_field) = mime_parser.lookup_optional_field("Chat-Group-Name") {
|
||||
grpname = Some(dc_decode_header_words_safe(&optional_field));
|
||||
}
|
||||
let optional_field =
|
||||
dc_mimeparser_lookup_optional_field(mime_parser, "Chat-Group-Member-Removed");
|
||||
if !optional_field.is_null() {
|
||||
X_MrRemoveFromGrp = (*optional_field).fld_value;
|
||||
mime_parser.is_system_message = DC_CMD_MEMBER_REMOVED_FROM_GROUP;
|
||||
let left_group = (Contact::lookup_id_by_addr(context, as_str(X_MrRemoveFromGrp))
|
||||
if let Some(optional_field) = mime_parser.lookup_optional_field("Chat-Group-Member-Removed") {
|
||||
X_MrRemoveFromGrp = Some(optional_field);
|
||||
mime_parser.is_system_message = SystemMessage::MemberRemovedFromGroup;
|
||||
let left_group = (Contact::lookup_id_by_addr(context, X_MrRemoveFromGrp.as_ref().unwrap())
|
||||
== from_id as u32) as libc::c_int;
|
||||
better_msg = context.stock_system_msg(
|
||||
if 0 != left_group {
|
||||
@@ -1170,47 +1140,45 @@ unsafe fn create_or_lookup_group(
|
||||
} else {
|
||||
StockMessage::MsgDelMember
|
||||
},
|
||||
as_str(X_MrRemoveFromGrp),
|
||||
X_MrRemoveFromGrp.as_ref().unwrap(),
|
||||
"",
|
||||
from_id as u32,
|
||||
)
|
||||
} else {
|
||||
let optional_field =
|
||||
dc_mimeparser_lookup_optional_field(mime_parser, "Chat-Group-Member-Added");
|
||||
if !optional_field.is_null() {
|
||||
X_MrAddToGrp = (*optional_field).fld_value;
|
||||
mime_parser.is_system_message = DC_CMD_MEMBER_ADDED_TO_GROUP;
|
||||
let optional_field =
|
||||
dc_mimeparser_lookup_optional_field(mime_parser, "Chat-Group-Image");
|
||||
if !optional_field.is_null() {
|
||||
// fld_value is a pointer somewhere into mime_parser, must not be freed
|
||||
X_MrGrpImageChanged = as_str((*optional_field).fld_value).to_string();
|
||||
if let Some(optional_field) = mime_parser.lookup_optional_field("Chat-Group-Member-Added") {
|
||||
X_MrAddToGrp = Some(optional_field);
|
||||
mime_parser.is_system_message = SystemMessage::MemberAddedToGroup;
|
||||
if let Some(optional_field) = mime_parser.lookup_optional_field("Chat-Group-Image") {
|
||||
X_MrGrpImageChanged = optional_field;
|
||||
}
|
||||
better_msg = context.stock_system_msg(
|
||||
StockMessage::MsgAddMember,
|
||||
as_str(X_MrAddToGrp),
|
||||
X_MrAddToGrp.as_ref().unwrap(),
|
||||
"",
|
||||
from_id as u32,
|
||||
)
|
||||
} else {
|
||||
let optional_field =
|
||||
dc_mimeparser_lookup_optional_field(mime_parser, "Chat-Group-Name-Changed");
|
||||
if !optional_field.is_null() {
|
||||
if let Some(optional_field) =
|
||||
mime_parser.lookup_optional_field("Chat-Group-Name-Changed")
|
||||
{
|
||||
X_MrGrpNameChanged = 1;
|
||||
mime_parser.is_system_message = DC_CMD_GROUPNAME_CHANGED;
|
||||
mime_parser.is_system_message = SystemMessage::GroupNameChanged;
|
||||
better_msg = context.stock_system_msg(
|
||||
StockMessage::MsgGrpName,
|
||||
as_str((*optional_field).fld_value),
|
||||
as_str(grpname),
|
||||
&optional_field,
|
||||
if let Some(ref name) = grpname {
|
||||
name
|
||||
} else {
|
||||
""
|
||||
},
|
||||
from_id as u32,
|
||||
)
|
||||
} else {
|
||||
let optional_field =
|
||||
dc_mimeparser_lookup_optional_field(mime_parser, "Chat-Group-Image");
|
||||
if !optional_field.is_null() {
|
||||
if let Some(optional_field) = mime_parser.lookup_optional_field("Chat-Group-Image")
|
||||
{
|
||||
// fld_value is a pointer somewhere into mime_parser, must not be freed
|
||||
X_MrGrpImageChanged = as_str((*optional_field).fld_value).to_string();
|
||||
mime_parser.is_system_message = DC_CMD_GROUPIMAGE_CHANGED;
|
||||
X_MrGrpImageChanged = optional_field;
|
||||
mime_parser.is_system_message = SystemMessage::GroupImageChanged;
|
||||
better_msg = context.stock_system_msg(
|
||||
if X_MrGrpImageChanged == "0" {
|
||||
StockMessage::MsgGrpImgDeleted
|
||||
@@ -1230,6 +1198,8 @@ unsafe fn create_or_lookup_group(
|
||||
// check, if we have a chat with this group ID
|
||||
let (mut chat_id, chat_id_verified, _blocked) = chat::get_chat_id_by_grpid(context, &grpid);
|
||||
if chat_id != 0 {
|
||||
let mut failure_reason = std::ptr::null_mut();
|
||||
|
||||
if chat_id_verified
|
||||
&& 0 == check_verified_properties(
|
||||
context,
|
||||
@@ -1239,8 +1209,10 @@ unsafe fn create_or_lookup_group(
|
||||
&mut failure_reason,
|
||||
)
|
||||
{
|
||||
dc_mimeparser_repl_msg_by_error(mime_parser, failure_reason);
|
||||
mime_parser.repl_msg_by_error(to_string(failure_reason));
|
||||
}
|
||||
|
||||
free(failure_reason.cast());
|
||||
}
|
||||
|
||||
// check if the sender is a member of the existing group -
|
||||
@@ -1257,18 +1229,20 @@ unsafe fn create_or_lookup_group(
|
||||
.get_config(context, "configured_addr")
|
||||
.unwrap_or_default();
|
||||
if chat_id == 0
|
||||
&& !dc_mimeparser_is_mailinglist_message(mime_parser)
|
||||
&& !mime_parser.is_mailinglist_message()
|
||||
&& !grpid.is_empty()
|
||||
&& !grpname.is_null()
|
||||
&& grpname.is_some()
|
||||
// otherwise, a pending "quit" message may pop up
|
||||
&& X_MrRemoveFromGrp.is_null()
|
||||
&& X_MrRemoveFromGrp.is_none()
|
||||
// re-create explicitly left groups only if ourself is re-added
|
||||
&& (!group_explicitly_left
|
||||
|| !X_MrAddToGrp.is_null() && addr_cmp(&self_addr, as_str(X_MrAddToGrp)))
|
||||
|| X_MrAddToGrp.is_some() && addr_cmp(&self_addr, X_MrAddToGrp.as_ref().unwrap()))
|
||||
{
|
||||
let mut create_verified = VerifiedStatus::Unverified;
|
||||
if !dc_mimeparser_lookup_field(mime_parser, "Chat-Verified").is_null() {
|
||||
if mime_parser.lookup_field("Chat-Verified").is_some() {
|
||||
create_verified = VerifiedStatus::Verified;
|
||||
let mut failure_reason = std::ptr::null_mut();
|
||||
|
||||
if 0 == check_verified_properties(
|
||||
context,
|
||||
mime_parser,
|
||||
@@ -1276,21 +1250,21 @@ unsafe fn create_or_lookup_group(
|
||||
to_ids,
|
||||
&mut failure_reason,
|
||||
) {
|
||||
dc_mimeparser_repl_msg_by_error(mime_parser, failure_reason);
|
||||
mime_parser.repl_msg_by_error(to_string(failure_reason));
|
||||
}
|
||||
free(failure_reason.cast());
|
||||
}
|
||||
if 0 == allow_creation {
|
||||
cleanup(
|
||||
grpname,
|
||||
failure_reason,
|
||||
ret_chat_id,
|
||||
ret_chat_id_blocked,
|
||||
chat_id,
|
||||
chat_id_blocked,
|
||||
);
|
||||
cleanup(ret_chat_id, ret_chat_id_blocked, chat_id, chat_id_blocked);
|
||||
return;
|
||||
}
|
||||
chat_id = create_group_record(context, &grpid, grpname, create_blocked, create_verified);
|
||||
chat_id = create_group_record(
|
||||
context,
|
||||
&grpid,
|
||||
grpname.as_ref().unwrap(),
|
||||
create_blocked,
|
||||
create_verified,
|
||||
);
|
||||
chat_id_blocked = create_blocked;
|
||||
recreate_member_list = 1;
|
||||
}
|
||||
@@ -1312,31 +1286,28 @@ unsafe fn create_or_lookup_group(
|
||||
&mut chat_id_blocked,
|
||||
);
|
||||
}
|
||||
cleanup(
|
||||
grpname,
|
||||
failure_reason,
|
||||
ret_chat_id,
|
||||
ret_chat_id_blocked,
|
||||
chat_id,
|
||||
chat_id_blocked,
|
||||
);
|
||||
cleanup(ret_chat_id, ret_chat_id_blocked, chat_id, chat_id_blocked);
|
||||
return;
|
||||
}
|
||||
|
||||
// execute group commands
|
||||
if !X_MrAddToGrp.is_null() || !X_MrRemoveFromGrp.is_null() {
|
||||
if X_MrAddToGrp.is_some() || X_MrRemoveFromGrp.is_some() {
|
||||
recreate_member_list = 1;
|
||||
} else if 0 != X_MrGrpNameChanged && !grpname.is_null() && strlen(grpname) < 200 {
|
||||
info!(context, "updating grpname for chat {}", chat_id);
|
||||
if sql::execute(
|
||||
context,
|
||||
&context.sql,
|
||||
"UPDATE chats SET name=? WHERE id=?;",
|
||||
params![as_str(grpname), chat_id as i32],
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
context.call_cb(Event::ChatModified(chat_id));
|
||||
} else if 0 != X_MrGrpNameChanged {
|
||||
if let Some(ref grpname) = grpname {
|
||||
if grpname.len() < 200 {
|
||||
info!(context, "updating grpname for chat {}", chat_id);
|
||||
if sql::execute(
|
||||
context,
|
||||
&context.sql,
|
||||
"UPDATE chats SET name=? WHERE id=?;",
|
||||
params![grpname, chat_id as i32],
|
||||
)
|
||||
.is_ok()
|
||||
{
|
||||
context.call_cb(Event::ChatModified(chat_id));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if !X_MrGrpImageChanged.is_empty() {
|
||||
@@ -1350,7 +1321,7 @@ unsafe fn create_or_lookup_group(
|
||||
changed = true;
|
||||
} else {
|
||||
for part in &mut mime_parser.parts {
|
||||
if part.type_0 == Viewtype::Image {
|
||||
if part.typ == Viewtype::Image {
|
||||
grpimage = part
|
||||
.param
|
||||
.get(Param::File)
|
||||
@@ -1382,11 +1353,7 @@ unsafe fn create_or_lookup_group(
|
||||
// than the one that is responsible for the current member list, see
|
||||
// https://github.com/deltachat/deltachat-core/issues/127
|
||||
|
||||
let skip = if !X_MrRemoveFromGrp.is_null() {
|
||||
X_MrRemoveFromGrp
|
||||
} else {
|
||||
ptr::null_mut()
|
||||
};
|
||||
let skip = X_MrRemoveFromGrp.as_ref();
|
||||
sql::execute(
|
||||
context,
|
||||
&context.sql,
|
||||
@@ -1394,21 +1361,20 @@ unsafe fn create_or_lookup_group(
|
||||
params![chat_id as i32],
|
||||
)
|
||||
.ok();
|
||||
if skip.is_null() || !addr_cmp(&self_addr, as_str(skip)) {
|
||||
if skip.is_none() || !addr_cmp(&self_addr, skip.unwrap()) {
|
||||
chat::add_to_chat_contacts_table(context, chat_id, DC_CONTACT_ID_SELF);
|
||||
}
|
||||
if from_id > DC_CHAT_ID_LAST_SPECIAL {
|
||||
if !Contact::addr_equals_contact(context, &self_addr, from_id as u32)
|
||||
&& (skip.is_null()
|
||||
|| !Contact::addr_equals_contact(context, to_string(skip), from_id as u32))
|
||||
&& (skip.is_none()
|
||||
|| !Contact::addr_equals_contact(context, skip.unwrap(), from_id as u32))
|
||||
{
|
||||
chat::add_to_chat_contacts_table(context, chat_id, from_id as u32);
|
||||
}
|
||||
}
|
||||
for &to_id in to_ids.iter() {
|
||||
if !Contact::addr_equals_contact(context, &self_addr, to_id)
|
||||
&& (skip.is_null()
|
||||
|| !Contact::addr_equals_contact(context, to_string(skip), to_id))
|
||||
&& (skip.is_none() || !Contact::addr_equals_contact(context, skip.unwrap(), to_id))
|
||||
{
|
||||
chat::add_to_chat_contacts_table(context, chat_id, to_id);
|
||||
}
|
||||
@@ -1442,20 +1408,13 @@ unsafe fn create_or_lookup_group(
|
||||
}
|
||||
}
|
||||
|
||||
cleanup(
|
||||
grpname,
|
||||
failure_reason,
|
||||
ret_chat_id,
|
||||
ret_chat_id_blocked,
|
||||
chat_id,
|
||||
chat_id_blocked,
|
||||
);
|
||||
cleanup(ret_chat_id, ret_chat_id_blocked, chat_id, chat_id_blocked);
|
||||
}
|
||||
|
||||
/// Handle groups for received messages
|
||||
unsafe fn create_or_lookup_adhoc_group(
|
||||
context: &Context,
|
||||
mime_parser: &dc_mimeparser_t,
|
||||
mime_parser: &MimeParser,
|
||||
allow_creation: libc::c_int,
|
||||
create_blocked: Blocked,
|
||||
from_id: u32,
|
||||
@@ -1467,15 +1426,11 @@ unsafe fn create_or_lookup_adhoc_group(
|
||||
// group matching the to-list or if we can create one
|
||||
let mut chat_id = 0;
|
||||
let mut chat_id_blocked = Blocked::Not;
|
||||
let mut grpname = ptr::null_mut();
|
||||
|
||||
let cleanup = |grpname: *mut libc::c_char,
|
||||
ret_chat_id: *mut u32,
|
||||
let cleanup = |ret_chat_id: *mut u32,
|
||||
ret_chat_id_blocked: &mut Blocked,
|
||||
chat_id: u32,
|
||||
chat_id_blocked: Blocked| {
|
||||
free(grpname as *mut libc::c_void);
|
||||
|
||||
if !ret_chat_id.is_null() {
|
||||
*ret_chat_id = chat_id;
|
||||
}
|
||||
@@ -1483,15 +1438,9 @@ unsafe fn create_or_lookup_adhoc_group(
|
||||
};
|
||||
|
||||
// build member list from the given ids
|
||||
if to_ids.is_empty() || dc_mimeparser_is_mailinglist_message(mime_parser) {
|
||||
if to_ids.is_empty() || mime_parser.is_mailinglist_message() {
|
||||
// too few contacts or a mailinglist
|
||||
cleanup(
|
||||
grpname,
|
||||
ret_chat_id,
|
||||
ret_chat_id_blocked,
|
||||
chat_id,
|
||||
chat_id_blocked,
|
||||
);
|
||||
cleanup(ret_chat_id, ret_chat_id_blocked, chat_id, chat_id_blocked);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1504,13 +1453,7 @@ unsafe fn create_or_lookup_adhoc_group(
|
||||
}
|
||||
if member_ids.len() < 3 {
|
||||
// too few contacts given
|
||||
cleanup(
|
||||
grpname,
|
||||
ret_chat_id,
|
||||
ret_chat_id_blocked,
|
||||
chat_id,
|
||||
chat_id_blocked,
|
||||
);
|
||||
cleanup(ret_chat_id, ret_chat_id_blocked, chat_id, chat_id_blocked);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1533,25 +1476,13 @@ unsafe fn create_or_lookup_adhoc_group(
|
||||
chat_id = id as u32;
|
||||
chat_id_blocked = id_blocked;
|
||||
/* success, chat found */
|
||||
cleanup(
|
||||
grpname,
|
||||
ret_chat_id,
|
||||
ret_chat_id_blocked,
|
||||
chat_id,
|
||||
chat_id_blocked,
|
||||
);
|
||||
cleanup(ret_chat_id, ret_chat_id_blocked, chat_id, chat_id_blocked);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if 0 == allow_creation {
|
||||
cleanup(
|
||||
grpname,
|
||||
ret_chat_id,
|
||||
ret_chat_id_blocked,
|
||||
chat_id,
|
||||
chat_id_blocked,
|
||||
);
|
||||
cleanup(ret_chat_id, ret_chat_id_blocked, chat_id, chat_id_blocked);
|
||||
return;
|
||||
}
|
||||
// we do not check if the message is a reply to another group, this may result in
|
||||
@@ -1561,24 +1492,16 @@ unsafe fn create_or_lookup_adhoc_group(
|
||||
// - there is no need to check if this group exists; otherwise we would have caught it above
|
||||
let grpid = create_adhoc_grp_id(context, &member_ids);
|
||||
if grpid.is_empty() {
|
||||
cleanup(
|
||||
grpname,
|
||||
ret_chat_id,
|
||||
ret_chat_id_blocked,
|
||||
chat_id,
|
||||
chat_id_blocked,
|
||||
);
|
||||
cleanup(ret_chat_id, ret_chat_id_blocked, chat_id, chat_id_blocked);
|
||||
return;
|
||||
}
|
||||
|
||||
// use subject as initial chat name
|
||||
if let Some(subject) = mime_parser.subject.as_ref().filter(|s| !s.is_empty()) {
|
||||
grpname = subject.strdup();
|
||||
let grpname = if let Some(subject) = mime_parser.subject.as_ref().filter(|s| !s.is_empty()) {
|
||||
subject.to_string()
|
||||
} else {
|
||||
grpname = context
|
||||
.stock_string_repl_int(StockMessage::Member, member_ids.len() as libc::c_int)
|
||||
.strdup();
|
||||
}
|
||||
context.stock_string_repl_int(StockMessage::Member, member_ids.len() as libc::c_int)
|
||||
};
|
||||
|
||||
// create group record
|
||||
chat_id = create_group_record(
|
||||
@@ -1595,19 +1518,13 @@ unsafe fn create_or_lookup_adhoc_group(
|
||||
|
||||
context.call_cb(Event::ChatModified(chat_id));
|
||||
|
||||
cleanup(
|
||||
grpname,
|
||||
ret_chat_id,
|
||||
ret_chat_id_blocked,
|
||||
chat_id,
|
||||
chat_id_blocked,
|
||||
);
|
||||
cleanup(ret_chat_id, ret_chat_id_blocked, chat_id, chat_id_blocked);
|
||||
}
|
||||
|
||||
fn create_group_record(
|
||||
context: &Context,
|
||||
grpid: impl AsRef<str>,
|
||||
grpname: *const libc::c_char,
|
||||
grpname: impl AsRef<str>,
|
||||
create_blocked: Blocked,
|
||||
create_verified: VerifiedStatus,
|
||||
) -> u32 {
|
||||
@@ -1621,7 +1538,7 @@ fn create_group_record(
|
||||
} else {
|
||||
Chattype::Group
|
||||
},
|
||||
as_str(grpname),
|
||||
grpname.as_ref(),
|
||||
grpid.as_ref(),
|
||||
create_blocked,
|
||||
],
|
||||
@@ -1744,7 +1661,7 @@ fn search_chat_ids_by_contact_ids(context: &Context, unsorted_contact_ids: &Vec<
|
||||
|
||||
unsafe fn check_verified_properties(
|
||||
context: &Context,
|
||||
mimeparser: &dc_mimeparser_t,
|
||||
mimeparser: &MimeParser,
|
||||
from_id: u32,
|
||||
to_ids: &Vec<u32>,
|
||||
failure_reason: *mut *mut libc::c_char,
|
||||
@@ -1844,46 +1761,54 @@ unsafe fn check_verified_properties(
|
||||
1
|
||||
}
|
||||
|
||||
unsafe fn set_better_msg<T: AsRef<str>>(mime_parser: &mut dc_mimeparser_t, better_msg: T) {
|
||||
fn set_better_msg(mime_parser: &mut MimeParser, better_msg: impl AsRef<str>) {
|
||||
let msg = better_msg.as_ref();
|
||||
if msg.len() > 0 && !mime_parser.parts.is_empty() {
|
||||
let part = &mut mime_parser.parts[0];
|
||||
if (*part).type_0 == Viewtype::Text {
|
||||
if part.typ == Viewtype::Text {
|
||||
part.msg = Some(msg.to_string());
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
unsafe fn dc_is_reply_to_known_message(
|
||||
context: &Context,
|
||||
mime_parser: &dc_mimeparser_t,
|
||||
) -> libc::c_int {
|
||||
unsafe fn dc_is_reply_to_known_message(context: &Context, mime_parser: &MimeParser) -> libc::c_int {
|
||||
/* check if the message is a reply to a known message; the replies are identified by the Message-ID from
|
||||
`In-Reply-To`/`References:` (to support non-Delta-Clients) or from `Chat-Predecessor:` (Delta clients, see comment in dc_chat.c) */
|
||||
let optional_field = dc_mimeparser_lookup_optional_field(mime_parser, "Chat-Predecessor");
|
||||
if !optional_field.is_null() {
|
||||
if 0 != is_known_rfc724_mid(context, (*optional_field).fld_value) {
|
||||
if let Some(optional_field) = mime_parser.lookup_optional_field("Chat-Predecessor") {
|
||||
let optional_field_c = CString::new(optional_field).unwrap();
|
||||
if 0 != is_known_rfc724_mid(context, optional_field_c.as_ptr()) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
let field = dc_mimeparser_lookup_field(mime_parser, "In-Reply-To");
|
||||
if !field.is_null() && (*field).fld_type == MAILIMF_FIELD_IN_REPLY_TO as libc::c_int {
|
||||
let fld_in_reply_to: *mut mailimf_in_reply_to = (*field).fld_data.fld_in_reply_to;
|
||||
if !fld_in_reply_to.is_null() {
|
||||
if is_known_rfc724_mid_in_list(context, (*(*field).fld_data.fld_in_reply_to).mid_list) {
|
||||
return 1;
|
||||
|
||||
if let Some(field) = mime_parser.lookup_field("In-Reply-To") {
|
||||
if (*field).fld_type == MAILIMF_FIELD_IN_REPLY_TO as libc::c_int {
|
||||
let fld_in_reply_to = (*field).fld_data.fld_in_reply_to;
|
||||
if !fld_in_reply_to.is_null() {
|
||||
if is_known_rfc724_mid_in_list(
|
||||
context,
|
||||
(*(*field).fld_data.fld_in_reply_to).mid_list,
|
||||
) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let field = dc_mimeparser_lookup_field(mime_parser, "References");
|
||||
if !field.is_null() && (*field).fld_type == MAILIMF_FIELD_REFERENCES as libc::c_int {
|
||||
let fld_references: *mut mailimf_references = (*field).fld_data.fld_references;
|
||||
if !fld_references.is_null() {
|
||||
if is_known_rfc724_mid_in_list(context, (*(*field).fld_data.fld_references).mid_list) {
|
||||
return 1;
|
||||
|
||||
if let Some(field) = mime_parser.lookup_field("References") {
|
||||
if (*field).fld_type == MAILIMF_FIELD_REFERENCES as libc::c_int {
|
||||
let fld_references = (*field).fld_data.fld_references;
|
||||
if !fld_references.is_null() {
|
||||
if is_known_rfc724_mid_in_list(
|
||||
context,
|
||||
(*(*field).fld_data.fld_references).mid_list,
|
||||
) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
@@ -1920,37 +1845,42 @@ fn is_known_rfc724_mid(context: &Context, rfc724_mid: *const libc::c_char) -> li
|
||||
|
||||
unsafe fn dc_is_reply_to_messenger_message(
|
||||
context: &Context,
|
||||
mime_parser: &dc_mimeparser_t,
|
||||
mime_parser: &MimeParser,
|
||||
) -> libc::c_int {
|
||||
/* function checks, if the message defined by mime_parser references a message send by us from Delta Chat.
|
||||
This is similar to is_reply_to_known_message() but
|
||||
- checks also if any of the referenced IDs are send by a messenger
|
||||
- it is okay, if the referenced messages are moved to trash here
|
||||
- no check for the Chat-* headers (function is only called if it is no messenger message itself) */
|
||||
let field = dc_mimeparser_lookup_field(mime_parser, "In-Reply-To");
|
||||
if !field.is_null() && (*field).fld_type == MAILIMF_FIELD_IN_REPLY_TO as libc::c_int {
|
||||
let fld_in_reply_to: *mut mailimf_in_reply_to = (*field).fld_data.fld_in_reply_to;
|
||||
if !fld_in_reply_to.is_null() {
|
||||
if 0 != is_msgrmsg_rfc724_mid_in_list(
|
||||
context,
|
||||
(*(*field).fld_data.fld_in_reply_to).mid_list,
|
||||
) {
|
||||
return 1;
|
||||
|
||||
if let Some(field) = mime_parser.lookup_field("In-Reply-To") {
|
||||
if (*field).fld_type == MAILIMF_FIELD_IN_REPLY_TO as libc::c_int {
|
||||
let fld_in_reply_to = (*field).fld_data.fld_in_reply_to;
|
||||
if !fld_in_reply_to.is_null() {
|
||||
if 0 != is_msgrmsg_rfc724_mid_in_list(
|
||||
context,
|
||||
(*(*field).fld_data.fld_in_reply_to).mid_list,
|
||||
) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
let field = dc_mimeparser_lookup_field(mime_parser, "References");
|
||||
if !field.is_null() && (*field).fld_type == MAILIMF_FIELD_REFERENCES as libc::c_int {
|
||||
let fld_references: *mut mailimf_references = (*field).fld_data.fld_references;
|
||||
if !fld_references.is_null() {
|
||||
if 0 != is_msgrmsg_rfc724_mid_in_list(
|
||||
context,
|
||||
(*(*field).fld_data.fld_references).mid_list,
|
||||
) {
|
||||
return 1;
|
||||
|
||||
if let Some(field) = mime_parser.lookup_field("References") {
|
||||
if (*field).fld_type == MAILIMF_FIELD_REFERENCES as libc::c_int {
|
||||
let fld_references: *mut mailimf_references = (*field).fld_data.fld_references;
|
||||
if !fld_references.is_null() {
|
||||
if 0 != is_msgrmsg_rfc724_mid_in_list(
|
||||
context,
|
||||
(*(*field).fld_data.fld_references).mid_list,
|
||||
) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
0
|
||||
}
|
||||
|
||||
|
||||
49
src/e2ee.rs
49
src/e2ee.rs
@@ -386,16 +386,17 @@ impl E2eeHelper {
|
||||
/*just a pointer into mailmime structure, must not be freed*/
|
||||
let imffields: *mut mailimf_fields = mailmime_find_mailimf_fields(in_out_message);
|
||||
let mut message_time = 0;
|
||||
let mut from: *mut libc::c_char = ptr::null_mut();
|
||||
let mut from = None;
|
||||
let mut private_keyring = Keyring::default();
|
||||
let mut public_keyring_for_validate = Keyring::default();
|
||||
let mut gossip_headers: *mut mailimf_fields = ptr::null_mut();
|
||||
if !(in_out_message.is_null() || imffields.is_null()) {
|
||||
let mut field: *mut mailimf_field =
|
||||
mailimf_find_field(imffields, MAILIMF_FIELD_FROM as libc::c_int);
|
||||
let mut field = mailimf_find_field(imffields, MAILIMF_FIELD_FROM as libc::c_int);
|
||||
|
||||
if !field.is_null() && !(*field).fld_data.fld_from.is_null() {
|
||||
from = mailimf_find_first_addr((*(*field).fld_data.fld_from).frm_mb_list)
|
||||
}
|
||||
|
||||
field = mailimf_find_field(imffields, MAILIMF_FIELD_ORIG_DATE as libc::c_int);
|
||||
if !field.is_null() && !(*field).fld_data.fld_orig_date.is_null() {
|
||||
let orig_date: *mut mailimf_orig_date = (*field).fld_data.fld_orig_date;
|
||||
@@ -407,25 +408,28 @@ impl E2eeHelper {
|
||||
}
|
||||
}
|
||||
let mut peerstate = None;
|
||||
let autocryptheader =
|
||||
as_opt_str(from).and_then(|from| Aheader::from_imffields(from, imffields));
|
||||
if message_time > 0 && !from.is_null() {
|
||||
peerstate = Peerstate::from_addr(context, &context.sql, as_str(from));
|
||||
let autocryptheader = from
|
||||
.as_ref()
|
||||
.and_then(|from| Aheader::from_imffields(from, imffields));
|
||||
if message_time > 0 {
|
||||
if let Some(ref from) = from {
|
||||
peerstate = Peerstate::from_addr(context, &context.sql, from);
|
||||
|
||||
if let Some(ref mut peerstate) = peerstate {
|
||||
if let Some(ref header) = autocryptheader {
|
||||
peerstate.apply_header(&header, message_time);
|
||||
peerstate.save_to_db(&context.sql, false);
|
||||
} else if message_time > peerstate.last_seen_autocrypt
|
||||
&& !contains_report(in_out_message)
|
||||
{
|
||||
peerstate.degrade_encryption(message_time);
|
||||
peerstate.save_to_db(&context.sql, false);
|
||||
if let Some(ref mut peerstate) = peerstate {
|
||||
if let Some(ref header) = autocryptheader {
|
||||
peerstate.apply_header(&header, message_time);
|
||||
peerstate.save_to_db(&context.sql, false);
|
||||
} else if message_time > peerstate.last_seen_autocrypt
|
||||
&& !contains_report(in_out_message)
|
||||
{
|
||||
peerstate.degrade_encryption(message_time);
|
||||
peerstate.save_to_db(&context.sql, false);
|
||||
}
|
||||
} else if let Some(ref header) = autocryptheader {
|
||||
let p = Peerstate::from_header(context, header, message_time);
|
||||
assert!(p.save_to_db(&context.sql, true));
|
||||
peerstate = Some(p);
|
||||
}
|
||||
} else if let Some(ref header) = autocryptheader {
|
||||
let p = Peerstate::from_header(context, header, message_time);
|
||||
assert!(p.save_to_db(&context.sql, true));
|
||||
peerstate = Some(p);
|
||||
}
|
||||
}
|
||||
/* load private key for decryption */
|
||||
@@ -437,7 +441,8 @@ impl E2eeHelper {
|
||||
&context.sql,
|
||||
) {
|
||||
if peerstate.as_ref().map(|p| p.last_seen).unwrap_or_else(|| 0) == 0 {
|
||||
peerstate = Peerstate::from_addr(&context, &context.sql, as_str(from));
|
||||
peerstate =
|
||||
Peerstate::from_addr(&context, &context.sql, &from.unwrap_or_default());
|
||||
}
|
||||
if let Some(ref peerstate) = peerstate {
|
||||
if peerstate.degrade_event.is_some() {
|
||||
@@ -486,8 +491,6 @@ impl E2eeHelper {
|
||||
if !gossip_headers.is_null() {
|
||||
mailimf_fields_free(gossip_headers);
|
||||
}
|
||||
|
||||
free(from as *mut libc::c_void);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@ use crate::chat::{self, Chat};
|
||||
use crate::constants::*;
|
||||
use crate::contact::*;
|
||||
use crate::context::*;
|
||||
use crate::dc_mimeparser::SystemMessage;
|
||||
use crate::dc_tools::*;
|
||||
use crate::error::Error;
|
||||
use crate::events::Event;
|
||||
@@ -767,7 +768,7 @@ pub fn dc_msg_get_summarytext_by_raw(
|
||||
Viewtype::Video => context.stock_str(StockMessage::Video).into_owned(),
|
||||
Viewtype::Voice => context.stock_str(StockMessage::VoiceMessage).into_owned(),
|
||||
Viewtype::Audio | Viewtype::File => {
|
||||
if param.get_int(Param::Cmd) == Some(6) {
|
||||
if param.get_cmd() == SystemMessage::AutocryptSetupMessage {
|
||||
append_text = false;
|
||||
context
|
||||
.stock_str(StockMessage::AcSetupMsgSubject)
|
||||
@@ -793,7 +794,7 @@ pub fn dc_msg_get_summarytext_by_raw(
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
if param.get_int(Param::Cmd) != Some(9) {
|
||||
if param.get_cmd() != SystemMessage::LocationOnly {
|
||||
"".to_string()
|
||||
} else {
|
||||
append_text = false;
|
||||
@@ -839,10 +840,10 @@ pub fn dc_msg_is_forwarded(msg: &Message) -> bool {
|
||||
}
|
||||
|
||||
pub fn dc_msg_is_info(msg: &Message) -> bool {
|
||||
let cmd = msg.param.get_int(Param::Cmd).unwrap_or_default();
|
||||
let cmd = msg.param.get_cmd();
|
||||
msg.from_id == 2i32 as libc::c_uint
|
||||
|| msg.to_id == 2i32 as libc::c_uint
|
||||
|| 0 != cmd && cmd != 6i32
|
||||
|| cmd != SystemMessage::Unknown && cmd != SystemMessage::AutocryptSetupMessage
|
||||
}
|
||||
|
||||
pub fn dc_msg_is_increation(msg: &Message) -> bool {
|
||||
@@ -854,7 +855,7 @@ pub fn dc_msg_is_setupmessage(msg: &Message) -> bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
msg.param.get_int(Param::Cmd) == Some(6)
|
||||
msg.param.get_cmd() == SystemMessage::AutocryptSetupMessage
|
||||
}
|
||||
|
||||
pub unsafe fn dc_msg_get_setupcodebegin(context: &Context, msg: &Message) -> *mut libc::c_char {
|
||||
|
||||
@@ -4,6 +4,7 @@ use std::str;
|
||||
|
||||
use num_traits::FromPrimitive;
|
||||
|
||||
use crate::dc_mimeparser::SystemMessage;
|
||||
use crate::error;
|
||||
|
||||
/// Available param keys.
|
||||
@@ -178,6 +179,13 @@ impl Params {
|
||||
self.get(key).and_then(|s| s.parse().ok())
|
||||
}
|
||||
|
||||
/// Get the parameter behind `Param::Cmd` interpreted as `SystemMessage`.
|
||||
pub fn get_cmd(&self) -> SystemMessage {
|
||||
self.get_int(Param::Cmd)
|
||||
.and_then(SystemMessage::from_i32)
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
/// Get the given parameter and parse as `f64`.
|
||||
pub fn get_float(&self, key: Param) -> Option<f64> {
|
||||
self.get(key).and_then(|s| s.parse().ok())
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
use mmime::mailimf_types::*;
|
||||
use percent_encoding::{utf8_percent_encode, AsciiSet, NON_ALPHANUMERIC};
|
||||
use std::ptr;
|
||||
|
||||
use crate::aheader::EncryptPreference;
|
||||
use crate::chat::{self, Chat};
|
||||
@@ -10,7 +8,6 @@ use crate::constants::*;
|
||||
use crate::contact::*;
|
||||
use crate::context::Context;
|
||||
use crate::dc_mimeparser::*;
|
||||
use crate::dc_tools::*;
|
||||
use crate::e2ee::*;
|
||||
use crate::error::Error;
|
||||
use crate::events::Event;
|
||||
@@ -335,7 +332,7 @@ fn fingerprint_equals_sender(
|
||||
/* library private: secure-join */
|
||||
pub fn handle_securejoin_handshake(
|
||||
context: &Context,
|
||||
mimeparser: &dc_mimeparser_t,
|
||||
mimeparser: &MimeParser,
|
||||
contact_id: u32,
|
||||
) -> libc::c_int {
|
||||
let own_fingerprint: String;
|
||||
@@ -343,7 +340,7 @@ pub fn handle_securejoin_handshake(
|
||||
if contact_id <= DC_CONTACT_ID_LAST_SPECIAL {
|
||||
return 0;
|
||||
}
|
||||
let step = match lookup_field(mimeparser, "Secure-Join") {
|
||||
let step = match mimeparser.lookup_optional_field("Secure-Join") {
|
||||
Some(s) => s,
|
||||
None => {
|
||||
return 0;
|
||||
@@ -372,7 +369,7 @@ pub fn handle_securejoin_handshake(
|
||||
// it just ensures, we have Bobs key now. If we do _not_ have the key because eg. MitM has removed it,
|
||||
// send_message() will fail with the error "End-to-end-encryption unavailable unexpectedly.", so, there is no additional check needed here.
|
||||
// verify that the `Secure-Join-Invitenumber:`-header matches invitenumber written to the QR code
|
||||
let invitenumber = match lookup_field(mimeparser, "Secure-Join-Invitenumber") {
|
||||
let invitenumber = match mimeparser.lookup_optional_field("Secure-Join-Invitenumber") {
|
||||
Some(n) => n,
|
||||
None => {
|
||||
warn!(context, "Secure-join denied (invitenumber missing).",);
|
||||
@@ -459,7 +456,7 @@ pub fn handle_securejoin_handshake(
|
||||
==== Step 6 in "Out-of-band verified groups" protocol ====
|
||||
============================================================ */
|
||||
// verify that Secure-Join-Fingerprint:-header matches the fingerprint of Bob
|
||||
let fingerprint = match lookup_field(mimeparser, "Secure-Join-Fingerprint") {
|
||||
let fingerprint = match mimeparser.lookup_optional_field("Secure-Join-Fingerprint") {
|
||||
Some(fp) => fp,
|
||||
None => {
|
||||
could_not_establish_secure_connection(
|
||||
@@ -488,7 +485,7 @@ pub fn handle_securejoin_handshake(
|
||||
}
|
||||
info!(context, "Fingerprint verified.",);
|
||||
// verify that the `Secure-Join-Auth:`-header matches the secret written to the QR code
|
||||
let auth_0 = match lookup_field(mimeparser, "Secure-Join-Auth") {
|
||||
let auth_0 = match mimeparser.lookup_optional_field("Secure-Join-Auth") {
|
||||
Some(auth) => auth,
|
||||
None => {
|
||||
could_not_establish_secure_connection(
|
||||
@@ -517,7 +514,9 @@ pub fn handle_securejoin_handshake(
|
||||
emit_event!(context, Event::ContactsChanged(Some(contact_id)));
|
||||
inviter_progress!(context, contact_id, 600);
|
||||
if join_vg {
|
||||
let field_grpid = lookup_field(mimeparser, "Secure-Join-Group").unwrap_or_default();
|
||||
let field_grpid = mimeparser
|
||||
.lookup_optional_field("Secure-Join-Group")
|
||||
.unwrap_or_default();
|
||||
let (group_chat_id, _, _) = chat::get_chat_id_by_grpid(context, &field_grpid);
|
||||
if group_chat_id == 0 {
|
||||
error!(context, "Chat {} not found.", &field_grpid);
|
||||
@@ -586,8 +585,9 @@ pub fn handle_securejoin_handshake(
|
||||
}
|
||||
Contact::scaleup_origin_by_id(context, contact_id, Origin::SecurejoinJoined);
|
||||
emit_event!(context, Event::ContactsChanged(None));
|
||||
let cg_member_added =
|
||||
lookup_field(mimeparser, "Chat-Group-Member-Added").unwrap_or_default();
|
||||
let cg_member_added = mimeparser
|
||||
.lookup_optional_field("Chat-Group-Member-Added")
|
||||
.unwrap_or_default();
|
||||
if join_vg && !addr_equals_self(context, cg_member_added) {
|
||||
info!(context, "Message belongs to a different handshake (scaled up contact anyway to allow creation of group).");
|
||||
return ret;
|
||||
@@ -651,24 +651,6 @@ fn secure_connection_established(context: &Context, contact_chat_id: u32) {
|
||||
emit_event!(context, Event::ChatModified(contact_chat_id));
|
||||
}
|
||||
|
||||
fn lookup_field(mimeparser: &dc_mimeparser_t, key: &str) -> Option<String> {
|
||||
let field: *mut mailimf_field = dc_mimeparser_lookup_field(mimeparser, key);
|
||||
unsafe {
|
||||
let mut value: *const libc::c_char = ptr::null();
|
||||
if field.is_null()
|
||||
|| (*field).fld_type != MAILIMF_FIELD_OPTIONAL_FIELD as libc::c_int
|
||||
|| (*field).fld_data.fld_optional_field.is_null()
|
||||
|| {
|
||||
value = (*(*field).fld_data.fld_optional_field).fld_value;
|
||||
value.is_null()
|
||||
}
|
||||
{
|
||||
return None;
|
||||
}
|
||||
Some(as_str(value).to_string())
|
||||
}
|
||||
}
|
||||
|
||||
fn could_not_establish_secure_connection(context: &Context, contact_chat_id: u32, details: &str) {
|
||||
let contact_id = chat_id_2_contact_id(context, contact_chat_id);
|
||||
let contact = Contact::get_by_id(context, contact_id);
|
||||
@@ -706,10 +688,7 @@ fn mark_peer_as_verified(context: &Context, fingerprint: impl AsRef<str>) -> Res
|
||||
* Tools: Misc.
|
||||
******************************************************************************/
|
||||
|
||||
fn encrypted_and_signed(
|
||||
mimeparser: &dc_mimeparser_t,
|
||||
expected_fingerprint: impl AsRef<str>,
|
||||
) -> bool {
|
||||
fn encrypted_and_signed(mimeparser: &MimeParser, expected_fingerprint: impl AsRef<str>) -> bool {
|
||||
if !mimeparser.e2ee_helper.encrypted {
|
||||
warn!(mimeparser.context, "Message not encrypted.",);
|
||||
false
|
||||
|
||||
Reference in New Issue
Block a user