first compile

This commit is contained in:
dignifiedquire
2019-11-27 23:48:26 +01:00
parent e22b4e8430
commit d2de2aef07
5 changed files with 1005 additions and 1042 deletions

18
Cargo.lock generated
View File

@@ -631,6 +631,7 @@ dependencies = [
"lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "lazy_static 1.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lettre 0.9.2 (git+https://github.com/deltachat/lettre?branch=feat/rustls)", "lettre 0.9.2 (git+https://github.com/deltachat/lettre?branch=feat/rustls)",
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
"mailparse 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
"mmime 0.1.2", "mmime 0.1.2",
"num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)", "num-traits 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1416,6 +1417,16 @@ dependencies = [
"libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)", "libc 0.2.65 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "mailparse"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"base64 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
"charset 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
"quoted_printable 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]] [[package]]
name = "matches" name = "matches"
version = "0.1.8" version = "0.1.8"
@@ -1906,6 +1917,11 @@ dependencies = [
"proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
] ]
[[package]]
name = "quoted_printable"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]] [[package]]
name = "r2d2" name = "r2d2"
version = "0.8.6" version = "0.8.6"
@@ -3388,6 +3404,7 @@ dependencies = [
"checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7" "checksum log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "14b6052be84e6b71ab17edffc2eeabf5c2c3ae1fdb464aae35ac50c67a44e1f7"
"checksum lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" "checksum lru-cache 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c"
"checksum mach 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "86dd2487cdfea56def77b88438a2c915fb45113c5319bfe7e14306ca4cd0b0e1" "checksum mach 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "86dd2487cdfea56def77b88438a2c915fb45113c5319bfe7e14306ca4cd0b0e1"
"checksum mailparse 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "51a60bad00d8aa905d31cf239f207ad4ef16c963ea53cf522d5fd7dc7f3ecfe2"
"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08" "checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
"checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00" "checksum maybe-uninit 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "60302e4db3a61da70c0cb7991976248362f30319e88850c487b9b95bbf059e00"
"checksum md-5 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a18af3dcaf2b0219366cdb4e2af65a6101457b415c3d1a5c71dd9c2b7c77b9c8" "checksum md-5 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a18af3dcaf2b0219366cdb4e2af65a6101457b415c3d1a5c71dd9c2b7c77b9c8"
@@ -3439,6 +3456,7 @@ dependencies = [
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
"checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1" "checksum quote 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "6ce23b6b870e8f94f81fb0a363d65d86675884b34a09043c81e5562f11c1f8e1"
"checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe" "checksum quote 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "053a8c8bcc71fcce321828dc897a98ab9760bef03a4fc36693c231e5b3216cfe"
"checksum quoted_printable 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "86cedf331228892e747bb85beb130b6bb23fc628c40dde9ea01eb6becea3c798"
"checksum r2d2 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e48fa64898ef0286b6ee4b4d8f61483f9182acf5e44e62a398b1c7f56f2f861d" "checksum r2d2 0.8.6 (registry+https://github.com/rust-lang/crates.io-index)" = "e48fa64898ef0286b6ee4b4d8f61483f9182acf5e44e62a398b1c7f56f2f861d"
"checksum r2d2_sqlite 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "806e268035ce9e5a604bf617ac8a073ef28b59ef2e48e8338db0baf530caef33" "checksum r2d2_sqlite 0.12.0 (registry+https://github.com/rust-lang/crates.io-index)" = "806e268035ce9e5a604bf617ac8a073ef28b59ef2e48e8338db0baf530caef33"
"checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" "checksum rand 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293"

View File

@@ -54,6 +54,7 @@ stop-token = { version = "0.1.1", features = ["unstable"] }
rustls = "0.16.0" rustls = "0.16.0"
webpki-roots = "0.18.0" webpki-roots = "0.18.0"
webpki = "0.21.0" webpki = "0.21.0"
mailparse = "0.9.2"
[dev-dependencies] [dev-dependencies]
tempfile = "3.0" tempfile = "3.0"

File diff suppressed because it is too large Load Diff

View File

@@ -122,61 +122,59 @@ pub unsafe fn dc_receive_imf(
} }
}; };
if let Some(field) = mime_parser.lookup_field_typ("Date", MAILIMF_FIELD_ORIG_DATE) { if let Some(field) = mime_parser.lookup_field("Date") {
let orig_date = (*field).fld_data.fld_orig_date; if let Ok(value) = field.get_value() {
if !orig_date.is_null() {
// is not yet checked against bad times! we do this later if we have the database information. // is not yet checked against bad times! we do this later if we have the database information.
sent_timestamp = dc_timestamp_from_date((*orig_date).dt_date_time) // sent_timestamp = dc_timestamp_from_date((*orig_date).dt_date_time)
// TODO
} }
} }
// get From: and check if it is known (for known From:'s we add the other To:/Cc: in the 3rd pass) // 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, // 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 // we do not check Return-Path any more as this is unreliable, see issue #150
if let Some(field) = mime_parser.lookup_field_typ("From", MAILIMF_FIELD_FROM) { if let Some(field) = mime_parser.lookup_field("From") {
let fld_from = (*field).fld_data.fld_from; if let Ok(fld_from) = field.get_value() {
if !fld_from.is_null() {
let mut check_self = 0; let mut check_self = 0;
let mut from_list = Vec::with_capacity(16); // let mut from_list = Vec::with_capacity(16);
dc_add_or_lookup_contacts_by_mailbox_list( // dc_add_or_lookup_contacts_by_mailbox_list(
context, // context,
(*fld_from).frm_mb_list, // (*fld_from).frm_mb_list,
Origin::IncomingUnknownFrom, // Origin::IncomingUnknownFrom,
&mut from_list, // &mut from_list,
&mut check_self, // &mut check_self,
); // );
if 0 != check_self { // if 0 != check_self {
incoming = 0; // incoming = 0;
if mime_parser.sender_equals_recipient() { // if mime_parser.sender_equals_recipient() {
from_id = DC_CONTACT_ID_SELF; // from_id = DC_CONTACT_ID_SELF;
} // }
} else if !from_list.is_empty() { // } else if !from_list.is_empty() {
// if there is no from given, from_id stays 0 which is just fine. These messages // // if there is no from given, from_id stays 0 which is just fine. These messages
// are very rare, however, we have to add them to the database (they go to the // // are very rare, however, we have to add them to the database (they go to the
// "deaddrop" chat) to avoid a re-download from the server. See also [**] // // "deaddrop" chat) to avoid a re-download from the server. See also [**]
from_id = from_list[0]; // from_id = from_list[0];
incoming_origin = Contact::get_origin_by_id(context, from_id, &mut from_id_blocked) // incoming_origin = Contact::get_origin_by_id(context, from_id, &mut from_id_blocked)
} // }
} }
} }
// Make sure, to_ids starts with the first To:-address (Cc: is added in the loop below pass) // Make sure, to_ids starts with the first To:-address (Cc: is added in the loop below pass)
if let Some(field) = mime_parser.lookup_field_typ("To", MAILIMF_FIELD_TO) { if let Some(field) = mime_parser.lookup_field("To") {
let fld_to = (*field).fld_data.fld_to; if let Ok(fld_to) = field.get_value() {
if !fld_to.is_null() { // dc_add_or_lookup_contacts_by_address_list(
dc_add_or_lookup_contacts_by_address_list( // context,
context, // (*fld_to).to_addr_list,
(*fld_to).to_addr_list, // if 0 == incoming {
if 0 == incoming { // Origin::OutgoingTo
Origin::OutgoingTo // } else if incoming_origin.is_verified() {
} else if incoming_origin.is_verified() { // Origin::IncomingTo
Origin::IncomingTo // } else {
} else { // Origin::IncomingUnknownTo
Origin::IncomingUnknownTo // },
}, // &mut to_ids,
&mut to_ids, // &mut to_self,
&mut to_self, // );
);
} }
} }
@@ -328,22 +326,21 @@ unsafe fn add_parts(
// collect the rest information, CC: is added to the to-list, BCC: is ignored // 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", // (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) // however, the benefit is very small and this may leak data that is expected to be hidden)
if let Some(field) = mime_parser.lookup_field_typ("Cc", MAILIMF_FIELD_CC) { if let Some(field) = mime_parser.lookup_field("Cc") {
let fld_cc = (*field).fld_data.fld_cc; if let Ok(fld_cc) = field.get_value() {
if !fld_cc.is_null() { // dc_add_or_lookup_contacts_by_address_list(
dc_add_or_lookup_contacts_by_address_list( // context,
context, // (*fld_cc).cc_addr_list,
(*fld_cc).cc_addr_list, // if 0 == incoming {
if 0 == incoming { // Origin::OutgoingCc
Origin::OutgoingCc // } else if incoming_origin.is_verified() {
} else if incoming_origin.is_verified() { // Origin::IncomingCc
Origin::IncomingCc // } else {
} else { // Origin::IncomingUnknownCc
Origin::IncomingUnknownCc // },
}, // to_ids,
to_ids, // std::ptr::null_mut(),
std::ptr::null_mut(), // );
);
} }
} }
@@ -608,17 +605,15 @@ unsafe fn add_parts(
// if the mime-headers should be saved, find out its size // if the mime-headers should be saved, find out its size
// (the mime-header ends with an empty line) // (the mime-header ends with an empty line)
let save_mime_headers = context.get_config_bool(Config::SaveMimeHeaders); let save_mime_headers = context.get_config_bool(Config::SaveMimeHeaders);
if let Some(field) = mime_parser.lookup_field_typ("In-Reply-To", MAILIMF_FIELD_IN_REPLY_TO) { if let Some(field) = mime_parser.lookup_field("In-Reply-To") {
let fld_in_reply_to = (*field).fld_data.fld_in_reply_to; if let Ok(raw) = field.get_value() {
if !fld_in_reply_to.is_null() { mime_in_reply_to = raw;
mime_in_reply_to = dc_str_from_clist((*(*field).fld_data.fld_in_reply_to).mid_list, " ")
} }
} }
if let Some(field) = mime_parser.lookup_field_typ("References", MAILIMF_FIELD_REFERENCES) { if let Some(field) = mime_parser.lookup_field("References") {
let fld_references = (*field).fld_data.fld_references; if let Ok(raw) = field.get_value() {
if !fld_references.is_null() { mime_references = raw;
mime_references = dc_str_from_clist((*(*field).fld_data.fld_references).mid_list, " ")
} }
} }
@@ -1002,43 +997,32 @@ unsafe fn create_or_lookup_group(
} }
set_better_msg(mime_parser, &better_msg); set_better_msg(mime_parser, &better_msg);
if let Some(optional_field) = mime_parser.lookup_optional_field("Chat-Group-ID") { if let Some(optional_field) = mime_parser.lookup_field("Chat-Group-ID") {
grpid = optional_field; grpid = optional_field.get_value().unwrap_or_default();
} }
if grpid.is_empty() { if grpid.is_empty() {
if let Some(field) = mime_parser.lookup_field_typ("Message-ID", MAILIMF_FIELD_MESSAGE_ID) { if let Some(field) = mime_parser.lookup_field("Message-ID") {
let fld_message_id = (*field).fld_data.fld_message_id; if let Ok(value) = field.get_value() {
if !fld_message_id.is_null() { // if let Some(extracted_grpid) =
if let Some(extracted_grpid) = // dc_extract_grpid_from_rfc724_mid(&to_string_lossy((*fld_message_id).mid_value))
dc_extract_grpid_from_rfc724_mid(&to_string_lossy((*fld_message_id).mid_value)) // {
{ // grpid = extracted_grpid.to_string();
grpid = extracted_grpid.to_string(); // } else {
} else { // grpid = "".to_string();
grpid = "".to_string(); // }
}
}
}
if grpid.is_empty() {
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() {
grpid = to_string_lossy(dc_extract_grpid_from_rfc724_mid_list(
(*fld_in_reply_to).mid_list,
));
} }
} }
if grpid.is_empty() { if grpid.is_empty() {
if let Some(field) = if let Some(field) = mime_parser.lookup_field("In-Reply-To") {
mime_parser.lookup_field_typ("References", MAILIMF_FIELD_REFERENCES) if let Ok(value) = field.get_value() {
{ grpid = value;
let fld_references = (*field).fld_data.fld_references; }
if !fld_references.is_null() { }
grpid = to_string_lossy(dc_extract_grpid_from_rfc724_mid_list( if grpid.is_empty() {
(*fld_references).mid_list, if let Some(field) = mime_parser.lookup_field("References") {
)); if let Ok(value) = field.get_value() {
grpid = value;
} }
} }
@@ -1060,11 +1044,11 @@ unsafe fn create_or_lookup_group(
} }
} }
if let Some(optional_field) = mime_parser.lookup_optional_field("Chat-Group-Name") { if let Some(optional_field) = mime_parser.lookup_field("Chat-Group-Name") {
grpname = Some(dc_decode_header_words(&optional_field)); grpname = Some(dc_decode_header_words(&optional_field.get_value().unwrap()));
} }
if let Some(optional_field) = mime_parser.lookup_optional_field("Chat-Group-Member-Removed") { if let Some(optional_field) = mime_parser.lookup_field("Chat-Group-Member-Removed") {
X_MrRemoveFromGrp = Some(optional_field); X_MrRemoveFromGrp = optional_field.get_value().ok();
mime_parser.is_system_message = SystemMessage::MemberRemovedFromGroup; mime_parser.is_system_message = SystemMessage::MemberRemovedFromGroup;
let left_group = (Contact::lookup_id_by_addr(context, X_MrRemoveFromGrp.as_ref().unwrap()) let left_group = (Contact::lookup_id_by_addr(context, X_MrRemoveFromGrp.as_ref().unwrap())
== from_id as u32) as libc::c_int; == from_id as u32) as libc::c_int;
@@ -1079,11 +1063,11 @@ unsafe fn create_or_lookup_group(
from_id as u32, from_id as u32,
) )
} else { } else {
if let Some(optional_field) = mime_parser.lookup_optional_field("Chat-Group-Member-Added") { if let Some(optional_field) = mime_parser.lookup_field("Chat-Group-Member-Added") {
X_MrAddToGrp = Some(optional_field); X_MrAddToGrp = optional_field.get_value().ok();
mime_parser.is_system_message = SystemMessage::MemberAddedToGroup; mime_parser.is_system_message = SystemMessage::MemberAddedToGroup;
if let Some(optional_field) = mime_parser.lookup_optional_field("Chat-Group-Image") { if let Some(optional_field) = mime_parser.lookup_field("Chat-Group-Image") {
X_MrGrpImageChanged = optional_field; X_MrGrpImageChanged = optional_field.get_value().unwrap();
} }
better_msg = context.stock_system_msg( better_msg = context.stock_system_msg(
StockMessage::MsgAddMember, StockMessage::MsgAddMember,
@@ -1092,26 +1076,25 @@ unsafe fn create_or_lookup_group(
from_id as u32, from_id as u32,
) )
} else { } else {
if let Some(optional_field) = let field = mime_parser.lookup_field("Chat-Group-Name-Changed");
mime_parser.lookup_optional_field("Chat-Group-Name-Changed") if field.is_some() {
{
X_MrGrpNameChanged = 1; X_MrGrpNameChanged = 1;
mime_parser.is_system_message = SystemMessage::GroupNameChanged;
better_msg = context.stock_system_msg( better_msg = context.stock_system_msg(
StockMessage::MsgGrpName, StockMessage::MsgGrpName,
&optional_field, &field.unwrap().get_value().unwrap(),
if let Some(ref name) = grpname { if let Some(ref name) = grpname {
name name
} else { } else {
"" ""
}, },
from_id as u32, from_id as u32,
) );
drop(field);
mime_parser.is_system_message = SystemMessage::GroupNameChanged;
} else { } else {
if let Some(optional_field) = mime_parser.lookup_optional_field("Chat-Group-Image") if let Some(optional_field) = mime_parser.lookup_field("Chat-Group-Image") {
{
// fld_value is a pointer somewhere into mime_parser, must not be freed // fld_value is a pointer somewhere into mime_parser, must not be freed
X_MrGrpImageChanged = optional_field; X_MrGrpImageChanged = optional_field.get_value().unwrap();
mime_parser.is_system_message = SystemMessage::GroupImageChanged; mime_parser.is_system_message = SystemMessage::GroupImageChanged;
better_msg = context.stock_system_msg( better_msg = context.stock_system_msg(
if X_MrGrpImageChanged == "0" { if X_MrGrpImageChanged == "0" {
@@ -1693,35 +1676,33 @@ fn set_better_msg(mime_parser: &mut MimeParser, better_msg: impl AsRef<str>) {
}; };
} }
unsafe fn dc_is_reply_to_known_message(context: &Context, mime_parser: &MimeParser) -> libc::c_int { 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 /* 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) */ `In-Reply-To`/`References:` (to support non-Delta-Clients) */
if let Some(field) = mime_parser.lookup_field("In-Reply-To") { if let Some(field) = mime_parser.lookup_field("In-Reply-To") {
if (*field).fld_type == MAILIMF_FIELD_IN_REPLY_TO as libc::c_int { if let Ok(value) = field.get_value() {
let fld_in_reply_to = (*field).fld_data.fld_in_reply_to; // if !fld_in_reply_to.is_null() {
if !fld_in_reply_to.is_null() { // if is_known_rfc724_mid_in_list(
if is_known_rfc724_mid_in_list( // context,
context, // (*(*field).fld_data.fld_in_reply_to).mid_list,
(*(*field).fld_data.fld_in_reply_to).mid_list, // ) {
) { // return 1;
return 1; // }
} // }
}
} }
} }
if let Some(field) = mime_parser.lookup_field("References") { if let Some(field) = mime_parser.lookup_field("References") {
if (*field).fld_type == MAILIMF_FIELD_REFERENCES as libc::c_int { if let Ok(value) = field.get_value() {
let fld_references = (*field).fld_data.fld_references; // if !fld_references.is_null()
if !fld_references.is_null() // && is_known_rfc724_mid_in_list(
&& is_known_rfc724_mid_in_list( // context,
context, // (*(*field).fld_data.fld_references).mid_list,
(*(*field).fld_data.fld_references).mid_list, // )
) // {
{ // return 1;
return 1; // }
}
} }
} }
@@ -1770,30 +1751,24 @@ unsafe fn dc_is_reply_to_messenger_message(
- no check for the Chat-* headers (function is only called if it is no messenger message itself) */ - no check for the Chat-* headers (function is only called if it is no messenger message itself) */
if let Some(field) = mime_parser.lookup_field("In-Reply-To") { if let Some(field) = mime_parser.lookup_field("In-Reply-To") {
if (*field).fld_type == MAILIMF_FIELD_IN_REPLY_TO as libc::c_int { if let Ok(value) = field.get_value() {
let fld_in_reply_to = (*field).fld_data.fld_in_reply_to; // if 0 != is_msgrmsg_rfc724_mid_in_list(
if !fld_in_reply_to.is_null() { // context,
if 0 != is_msgrmsg_rfc724_mid_in_list( // (*(*field).fld_data.fld_in_reply_to).mid_list,
context, // ) {
(*(*field).fld_data.fld_in_reply_to).mid_list, // return 1;
) { // }
return 1;
}
}
} }
} }
if let Some(field) = mime_parser.lookup_field("References") { if let Some(field) = mime_parser.lookup_field("References") {
if (*field).fld_type == MAILIMF_FIELD_REFERENCES as libc::c_int { if let Ok(value) = field.get_value() {
let fld_references: *mut mailimf_references = (*field).fld_data.fld_references; // if 0 != is_msgrmsg_rfc724_mid_in_list(
if !fld_references.is_null() { // context,
if 0 != is_msgrmsg_rfc724_mid_in_list( // (*(*field).fld_data.fld_references).mid_list,
context, // ) {
(*(*field).fld_data.fld_references).mid_list, // return 1;
) { // }
return 1;
}
}
} }
} }

View File

@@ -343,318 +343,319 @@ pub(crate) fn handle_securejoin_handshake(
mimeparser: &MimeParser, mimeparser: &MimeParser,
contact_id: u32, contact_id: u32,
) -> Result<HandshakeMessageStatus, Error> { ) -> Result<HandshakeMessageStatus, Error> {
let own_fingerprint: String; unimplemented!()
// let own_fingerprint: String;
ensure!( // ensure!(
contact_id > DC_CONTACT_ID_LAST_SPECIAL, // contact_id > DC_CONTACT_ID_LAST_SPECIAL,
"handle_securejoin_handshake(): called with special contact id" // "handle_securejoin_handshake(): called with special contact id"
); // );
let step = match mimeparser.lookup_optional_field("Secure-Join") { // let step = match mimeparser.lookup_optional_field("Secure-Join") {
Some(s) => s, // Some(s) => s,
None => { // None => {
bail!("This message is not a Secure-Join message"); // bail!("This message is not a Secure-Join message");
} // }
}; // };
info!( // info!(
context, // context,
">>>>>>>>>>>>>>>>>>>>>>>>> secure-join message \'{}\' received", step, // ">>>>>>>>>>>>>>>>>>>>>>>>> secure-join message \'{}\' received", step,
); // );
let (contact_chat_id, contact_chat_id_blocked) = // let (contact_chat_id, contact_chat_id_blocked) =
chat::create_or_lookup_by_contact_id(context, contact_id, Blocked::Not).unwrap_or_default(); // chat::create_or_lookup_by_contact_id(context, contact_id, Blocked::Not).unwrap_or_default();
if contact_chat_id_blocked != Blocked::Not { // if contact_chat_id_blocked != Blocked::Not {
chat::unblock(context, contact_chat_id); // chat::unblock(context, contact_chat_id);
} // }
let join_vg = step.starts_with("vg-"); // let join_vg = step.starts_with("vg-");
let mut ret = HandshakeMessageStatus::default(); // let mut ret = HandshakeMessageStatus::default();
match step.as_str() { // match step.as_str() {
"vg-request" | "vc-request" => { // "vg-request" | "vc-request" => {
/* ========================================================= // /* =========================================================
==== Alice - the inviter side ==== // ==== Alice - the inviter side ====
==== Step 3 in "Setup verified contact" protocol ==== // ==== Step 3 in "Setup verified contact" protocol ====
========================================================= */ // ========================================================= */
// this message may be unencrypted (Bob, the joinder and the sender, might not have Alice's key yet) // // this message may be unencrypted (Bob, the joinder and the sender, might not have Alice's key yet)
// it just ensures, we have Bobs key now. If we do _not_ have the key because eg. MitM has removed it, // // 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. // // 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 // // verify that the `Secure-Join-Invitenumber:`-header matches invitenumber written to the QR code
let invitenumber = match mimeparser.lookup_optional_field("Secure-Join-Invitenumber") { // let invitenumber = match mimeparser.lookup_optional_field("Secure-Join-Invitenumber") {
Some(n) => n, // Some(n) => n,
None => { // None => {
warn!(context, "Secure-join denied (invitenumber missing).",); // warn!(context, "Secure-join denied (invitenumber missing).",);
return Ok(ret); // return Ok(ret);
} // }
}; // };
if !token::exists(context, token::Namespace::InviteNumber, &invitenumber) { // if !token::exists(context, token::Namespace::InviteNumber, &invitenumber) {
warn!(context, "Secure-join denied (bad invitenumber).",); // warn!(context, "Secure-join denied (bad invitenumber).",);
return Ok(ret); // return Ok(ret);
} // }
info!(context, "Secure-join requested.",); // info!(context, "Secure-join requested.",);
inviter_progress!(context, contact_id, 300); // inviter_progress!(context, contact_id, 300);
send_handshake_msg( // send_handshake_msg(
context, // context,
contact_chat_id, // contact_chat_id,
&format!("{}-auth-required", &step[..2]), // &format!("{}-auth-required", &step[..2]),
"", // "",
None, // None,
"", // "",
); // );
} // }
"vg-auth-required" | "vc-auth-required" => { // "vg-auth-required" | "vc-auth-required" => {
let cond = { // let cond = {
let bob = context.bob.read().unwrap(); // let bob = context.bob.read().unwrap();
let scan = bob.qr_scan.as_ref(); // let scan = bob.qr_scan.as_ref();
scan.is_none() // scan.is_none()
|| bob.expects != DC_VC_AUTH_REQUIRED // || bob.expects != DC_VC_AUTH_REQUIRED
|| join_vg && scan.unwrap().state != LotState::QrAskVerifyGroup // || join_vg && scan.unwrap().state != LotState::QrAskVerifyGroup
}; // };
if cond { // if cond {
warn!(context, "auth-required message out of sync.",); // warn!(context, "auth-required message out of sync.",);
// no error, just aborted somehow or a mail from another handshake // // no error, just aborted somehow or a mail from another handshake
return Ok(ret); // return Ok(ret);
} // }
let scanned_fingerprint_of_alice = get_qr_attr!(context, fingerprint).to_string(); // let scanned_fingerprint_of_alice = get_qr_attr!(context, fingerprint).to_string();
let auth = get_qr_attr!(context, auth).to_string(); // let auth = get_qr_attr!(context, auth).to_string();
if !encrypted_and_signed(mimeparser, &scanned_fingerprint_of_alice) { // if !encrypted_and_signed(mimeparser, &scanned_fingerprint_of_alice) {
could_not_establish_secure_connection( // could_not_establish_secure_connection(
context, // context,
contact_chat_id, // contact_chat_id,
if mimeparser.encrypted { // if mimeparser.encrypted {
"No valid signature." // "No valid signature."
} else { // } else {
"Not encrypted." // "Not encrypted."
}, // },
); // );
ret.stop_ongoing_process = true; // ret.stop_ongoing_process = true;
ret.bob_securejoin_success = Some(false); // ret.bob_securejoin_success = Some(false);
return Ok(ret); // return Ok(ret);
} // }
if !fingerprint_equals_sender(context, &scanned_fingerprint_of_alice, contact_chat_id) { // if !fingerprint_equals_sender(context, &scanned_fingerprint_of_alice, contact_chat_id) {
could_not_establish_secure_connection( // could_not_establish_secure_connection(
context, // context,
contact_chat_id, // contact_chat_id,
"Fingerprint mismatch on joiner-side.", // "Fingerprint mismatch on joiner-side.",
); // );
ret.stop_ongoing_process = true; // ret.stop_ongoing_process = true;
ret.bob_securejoin_success = Some(false); // ret.bob_securejoin_success = Some(false);
return Ok(ret); // return Ok(ret);
} // }
info!(context, "Fingerprint verified.",); // info!(context, "Fingerprint verified.",);
own_fingerprint = get_self_fingerprint(context).unwrap(); // own_fingerprint = get_self_fingerprint(context).unwrap();
joiner_progress!(context, contact_id, 400); // joiner_progress!(context, contact_id, 400);
context.bob.write().unwrap().expects = DC_VC_CONTACT_CONFIRM; // context.bob.write().unwrap().expects = DC_VC_CONTACT_CONFIRM;
send_handshake_msg( // send_handshake_msg(
context, // context,
contact_chat_id, // contact_chat_id,
&format!("{}-request-with-auth", &step[..2]), // &format!("{}-request-with-auth", &step[..2]),
auth, // auth,
Some(own_fingerprint), // Some(own_fingerprint),
if join_vg { // if join_vg {
get_qr_attr!(context, text2).to_string() // get_qr_attr!(context, text2).to_string()
} else { // } else {
"".to_string() // "".to_string()
}, // },
); // );
} // }
"vg-request-with-auth" | "vc-request-with-auth" => { // "vg-request-with-auth" | "vc-request-with-auth" => {
/* ============================================================ // /* ============================================================
==== Alice - the inviter side ==== // ==== Alice - the inviter side ====
==== Steps 5+6 in "Setup verified contact" protocol ==== // ==== Steps 5+6 in "Setup verified contact" protocol ====
==== Step 6 in "Out-of-band verified groups" protocol ==== // ==== Step 6 in "Out-of-band verified groups" protocol ====
============================================================ */ // ============================================================ */
// verify that Secure-Join-Fingerprint:-header matches the fingerprint of Bob // // verify that Secure-Join-Fingerprint:-header matches the fingerprint of Bob
let fingerprint = match mimeparser.lookup_optional_field("Secure-Join-Fingerprint") { // let fingerprint = match mimeparser.lookup_optional_field("Secure-Join-Fingerprint") {
Some(fp) => fp, // Some(fp) => fp,
None => { // None => {
could_not_establish_secure_connection( // could_not_establish_secure_connection(
context, // context,
contact_chat_id, // contact_chat_id,
"Fingerprint not provided.", // "Fingerprint not provided.",
); // );
return Ok(ret); // return Ok(ret);
} // }
}; // };
if !encrypted_and_signed(mimeparser, &fingerprint) { // if !encrypted_and_signed(mimeparser, &fingerprint) {
could_not_establish_secure_connection( // could_not_establish_secure_connection(
context, // context,
contact_chat_id, // contact_chat_id,
"Auth not encrypted.", // "Auth not encrypted.",
); // );
return Ok(ret); // return Ok(ret);
} // }
if !fingerprint_equals_sender(context, &fingerprint, contact_chat_id) { // if !fingerprint_equals_sender(context, &fingerprint, contact_chat_id) {
could_not_establish_secure_connection( // could_not_establish_secure_connection(
context, // context,
contact_chat_id, // contact_chat_id,
"Fingerprint mismatch on inviter-side.", // "Fingerprint mismatch on inviter-side.",
); // );
return Ok(ret); // return Ok(ret);
} // }
info!(context, "Fingerprint verified.",); // info!(context, "Fingerprint verified.",);
// verify that the `Secure-Join-Auth:`-header matches the secret written to the QR code // // verify that the `Secure-Join-Auth:`-header matches the secret written to the QR code
let auth_0 = match mimeparser.lookup_optional_field("Secure-Join-Auth") { // let auth_0 = match mimeparser.lookup_optional_field("Secure-Join-Auth") {
Some(auth) => auth, // Some(auth) => auth,
None => { // None => {
could_not_establish_secure_connection( // could_not_establish_secure_connection(
context, // context,
contact_chat_id, // contact_chat_id,
"Auth not provided.", // "Auth not provided.",
); // );
return Ok(ret); // return Ok(ret);
} // }
}; // };
if !token::exists(context, token::Namespace::Auth, &auth_0) { // if !token::exists(context, token::Namespace::Auth, &auth_0) {
could_not_establish_secure_connection(context, contact_chat_id, "Auth invalid."); // could_not_establish_secure_connection(context, contact_chat_id, "Auth invalid.");
return Ok(ret); // return Ok(ret);
} // }
if mark_peer_as_verified(context, fingerprint).is_err() { // if mark_peer_as_verified(context, fingerprint).is_err() {
could_not_establish_secure_connection( // could_not_establish_secure_connection(
context, // context,
contact_chat_id, // contact_chat_id,
"Fingerprint mismatch on inviter-side.", // "Fingerprint mismatch on inviter-side.",
); // );
return Ok(ret); // return Ok(ret);
} // }
Contact::scaleup_origin_by_id(context, contact_id, Origin::SecurejoinInvited); // Contact::scaleup_origin_by_id(context, contact_id, Origin::SecurejoinInvited);
info!(context, "Auth verified.",); // info!(context, "Auth verified.",);
secure_connection_established(context, contact_chat_id); // secure_connection_established(context, contact_chat_id);
emit_event!(context, Event::ContactsChanged(Some(contact_id))); // emit_event!(context, Event::ContactsChanged(Some(contact_id)));
inviter_progress!(context, contact_id, 600); // inviter_progress!(context, contact_id, 600);
if join_vg { // if join_vg {
let field_grpid = mimeparser // let field_grpid = mimeparser
.lookup_optional_field("Secure-Join-Group") // .lookup_optional_field("Secure-Join-Group")
.unwrap_or_default(); // .unwrap_or_default();
let (group_chat_id, _, _) = chat::get_chat_id_by_grpid(context, &field_grpid); // let (group_chat_id, _, _) = chat::get_chat_id_by_grpid(context, &field_grpid);
if group_chat_id == 0 { // if group_chat_id == 0 {
error!(context, "Chat {} not found.", &field_grpid); // error!(context, "Chat {} not found.", &field_grpid);
return Ok(ret); // return Ok(ret);
} else { // } else {
if let Err(err) = // if let Err(err) =
chat::add_contact_to_chat_ex(context, group_chat_id, contact_id, true) // chat::add_contact_to_chat_ex(context, group_chat_id, contact_id, true)
{ // {
error!(context, "failed to add contact: {}", err); // error!(context, "failed to add contact: {}", err);
} // }
} // }
} else { // } else {
send_handshake_msg(context, contact_chat_id, "vc-contact-confirm", "", None, ""); // send_handshake_msg(context, contact_chat_id, "vc-contact-confirm", "", None, "");
inviter_progress!(context, contact_id, 1000); // inviter_progress!(context, contact_id, 1000);
} // }
} // }
"vg-member-added" | "vc-contact-confirm" => { // "vg-member-added" | "vc-contact-confirm" => {
if join_vg { // if join_vg {
ret.hide_this_msg = false; // ret.hide_this_msg = false;
} // }
if context.bob.read().unwrap().expects != DC_VC_CONTACT_CONFIRM { // if context.bob.read().unwrap().expects != DC_VC_CONTACT_CONFIRM {
info!(context, "Message belongs to a different handshake.",); // info!(context, "Message belongs to a different handshake.",);
return Ok(ret); // return Ok(ret);
} // }
let cond = { // let cond = {
let bob = context.bob.read().unwrap(); // let bob = context.bob.read().unwrap();
let scan = bob.qr_scan.as_ref(); // let scan = bob.qr_scan.as_ref();
scan.is_none() || join_vg && scan.unwrap().state != LotState::QrAskVerifyGroup // scan.is_none() || join_vg && scan.unwrap().state != LotState::QrAskVerifyGroup
}; // };
if cond { // if cond {
warn!( // warn!(
context, // context,
"Message out of sync or belongs to a different handshake.", // "Message out of sync or belongs to a different handshake.",
); // );
return Ok(ret); // return Ok(ret);
} // }
let scanned_fingerprint_of_alice = get_qr_attr!(context, fingerprint).to_string(); // let scanned_fingerprint_of_alice = get_qr_attr!(context, fingerprint).to_string();
let vg_expect_encrypted = if join_vg { // let vg_expect_encrypted = if join_vg {
let group_id = get_qr_attr!(context, text2).to_string(); // let group_id = get_qr_attr!(context, text2).to_string();
let (_, is_verified_group, _) = chat::get_chat_id_by_grpid(context, group_id); // let (_, is_verified_group, _) = chat::get_chat_id_by_grpid(context, group_id);
// when joining a non-verified group // // when joining a non-verified group
// the vg-member-added message may be unencrypted // // the vg-member-added message may be unencrypted
// when not all group members have keys or prefer encryption. // // when not all group members have keys or prefer encryption.
// So only expect encryption if this is a verified group // // So only expect encryption if this is a verified group
is_verified_group // is_verified_group
} else { // } else {
// setup contact is always encrypted // // setup contact is always encrypted
true // true
}; // };
if vg_expect_encrypted // if vg_expect_encrypted
&& !encrypted_and_signed(mimeparser, &scanned_fingerprint_of_alice) // && !encrypted_and_signed(mimeparser, &scanned_fingerprint_of_alice)
{ // {
could_not_establish_secure_connection( // could_not_establish_secure_connection(
context, // context,
contact_chat_id, // contact_chat_id,
"Contact confirm message not encrypted.", // "Contact confirm message not encrypted.",
); // );
ret.bob_securejoin_success = Some(false); // ret.bob_securejoin_success = Some(false);
return Ok(ret); // return Ok(ret);
} // }
if mark_peer_as_verified(context, &scanned_fingerprint_of_alice).is_err() { // if mark_peer_as_verified(context, &scanned_fingerprint_of_alice).is_err() {
could_not_establish_secure_connection( // could_not_establish_secure_connection(
context, // context,
contact_chat_id, // contact_chat_id,
"Fingerprint mismatch on joiner-side.", // "Fingerprint mismatch on joiner-side.",
); // );
return Ok(ret); // return Ok(ret);
} // }
Contact::scaleup_origin_by_id(context, contact_id, Origin::SecurejoinJoined); // Contact::scaleup_origin_by_id(context, contact_id, Origin::SecurejoinJoined);
emit_event!(context, Event::ContactsChanged(None)); // emit_event!(context, Event::ContactsChanged(None));
let cg_member_added = mimeparser // let cg_member_added = mimeparser
.lookup_optional_field("Chat-Group-Member-Added") // .lookup_optional_field("Chat-Group-Member-Added")
.unwrap_or_default(); // .unwrap_or_default();
if join_vg && !addr_equals_self(context, cg_member_added) { // 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)."); // info!(context, "Message belongs to a different handshake (scaled up contact anyway to allow creation of group).");
return Ok(ret); // return Ok(ret);
} // }
secure_connection_established(context, contact_chat_id); // secure_connection_established(context, contact_chat_id);
context.bob.write().unwrap().expects = 0; // context.bob.write().unwrap().expects = 0;
if join_vg { // if join_vg {
send_handshake_msg( // send_handshake_msg(
context, // context,
contact_chat_id, // contact_chat_id,
"vg-member-added-received", // "vg-member-added-received",
"", // "",
None, // None,
"", // "",
); // );
} // }
ret.stop_ongoing_process = true; // ret.stop_ongoing_process = true;
ret.bob_securejoin_success = Some(true); // ret.bob_securejoin_success = Some(true);
} // }
"vg-member-added-received" => { // "vg-member-added-received" => {
/* ============================================================ // /* ============================================================
==== Alice - the inviter side ==== // ==== Alice - the inviter side ====
==== Step 8 in "Out-of-band verified groups" protocol ==== // ==== Step 8 in "Out-of-band verified groups" protocol ====
============================================================ */ // ============================================================ */
if let Ok(contact) = Contact::get_by_id(context, contact_id) { // if let Ok(contact) = Contact::get_by_id(context, contact_id) {
if contact.is_verified(context) == VerifiedStatus::Unverified { // if contact.is_verified(context) == VerifiedStatus::Unverified {
warn!(context, "vg-member-added-received invalid.",); // warn!(context, "vg-member-added-received invalid.",);
return Ok(ret); // return Ok(ret);
} // }
inviter_progress!(context, contact_id, 800); // inviter_progress!(context, contact_id, 800);
inviter_progress!(context, contact_id, 1000); // inviter_progress!(context, contact_id, 1000);
let field_grpid = mimeparser // let field_grpid = mimeparser
.lookup_optional_field("Secure-Join-Group") // .lookup_optional_field("Secure-Join-Group")
.unwrap_or_default(); // .unwrap_or_default();
let (group_chat_id, _, _) = chat::get_chat_id_by_grpid(context, &field_grpid); // let (group_chat_id, _, _) = chat::get_chat_id_by_grpid(context, &field_grpid);
context.call_cb(Event::SecurejoinMemberAdded { // context.call_cb(Event::SecurejoinMemberAdded {
chat_id: group_chat_id, // chat_id: group_chat_id,
contact_id: contact_id, // contact_id: contact_id,
}); // });
} else { // } else {
warn!(context, "vg-member-added-received invalid.",); // warn!(context, "vg-member-added-received invalid.",);
return Ok(ret); // return Ok(ret);
} // }
} // }
_ => { // _ => {
warn!(context, "invalid step: {}", step); // warn!(context, "invalid step: {}", step);
} // }
} // }
if ret.hide_this_msg { // if ret.hide_this_msg {
ret.delete_this_msg = true; // ret.delete_this_msg = true;
} // }
Ok(ret) // Ok(ret)
} }
fn secure_connection_established(context: &Context, contact_chat_id: u32) { fn secure_connection_established(context: &Context, contact_chat_id: u32) {