refactor(e2ee): restructure types a and method slightly

This commit is contained in:
dignifiedquire
2019-08-26 22:24:18 +02:00
committed by holger krekel
parent a5f862a564
commit 3944592c09
5 changed files with 481 additions and 510 deletions

View File

@@ -1,5 +1,6 @@
//! End-to-end encryption support.
use std::any::Any;
use std::collections::HashSet;
use std::ffi::CStr;
use std::ptr;
@@ -32,36 +33,26 @@ use crate::pgp::*;
use crate::types::*;
use crate::x::*;
// backups
// attachments of 25 mb brutto should work on the majority of providers
// (brutto examples: web.de=50, 1&1=40, t-online.de=32, gmail=25, posteo=50, yahoo=25, all-inkl=100).
// as an upper limit, we double the size; the core won't send messages larger than this
// to get the netto sizes, we subtract 1 mb header-overhead and the base64-overhead.
// some defaults
#[derive(Clone)]
#[allow(non_camel_case_types)]
pub struct dc_e2ee_helper_t {
pub encryption_successfull: libc::c_int,
pub cdata_to_free: *mut libc::c_void,
pub encrypted: libc::c_int,
#[derive(Default)]
pub struct E2eeHelper {
pub encryption_successfull: bool,
cdata_to_free: Option<Box<dyn Any>>,
pub encrypted: bool,
pub signatures: HashSet<String>,
pub gossipped_addr: HashSet<String>,
}
impl Default for dc_e2ee_helper_t {
fn default() -> Self {
dc_e2ee_helper_t {
encryption_successfull: 0,
cdata_to_free: std::ptr::null_mut(),
encrypted: 0,
signatures: Default::default(),
gossipped_addr: Default::default(),
impl E2eeHelper {
/// Frees data referenced by "mailmime" but not freed by mailmime_free(). After calling this function,
/// in_out_message cannot be used any longer!
pub unsafe fn thanks(&mut self) {
if let Some(data) = self.cdata_to_free.take() {
free(Box::into_raw(data) as *mut _)
}
}
}
#[allow(non_snake_case)]
pub unsafe fn dc_e2ee_encrypt(
pub unsafe fn encrypt(
&mut self,
context: &Context,
recipients_addr: *const clist,
force_unencrypted: libc::c_int,
@@ -69,8 +60,7 @@ pub unsafe fn dc_e2ee_encrypt(
min_verified: libc::c_int,
do_gossip: libc::c_int,
mut in_out_message: *mut mailmime,
helper: &mut dc_e2ee_helper_t,
) {
) {
let mut ok_to_continue = true;
let mut col: libc::c_int = 0i32;
let mut do_encrypt: libc::c_int = 0i32;
@@ -79,7 +69,6 @@ pub unsafe fn dc_e2ee_encrypt(
let mut keyring = Keyring::default();
let plain: *mut MMAPString = mmap_string_new(b"\x00" as *const u8 as *const libc::c_char);
let mut peerstates: Vec<Peerstate> = Vec::new();
*helper = Default::default();
if !(recipients_addr.is_null()
|| in_out_message.is_null()
@@ -172,7 +161,8 @@ pub unsafe fn dc_e2ee_encrypt(
let mut part_to_encrypt: *mut mailmime =
(*in_out_message).mm_data.mm_message.mm_msg_mime;
(*part_to_encrypt).mm_parent = ptr::null_mut();
let imffields_encrypted: *mut mailimf_fields = mailimf_fields_new_empty();
let imffields_encrypted: *mut mailimf_fields =
mailimf_fields_new_empty();
/* mailmime_new_message_data() calls mailmime_fields_new_with_version() which would add the unwanted MIME-Version:-header */
let message_to_encrypt: *mut mailmime = mailmime_new(
MAILMIME_MESSAGE as libc::c_int,
@@ -188,10 +178,10 @@ pub unsafe fn dc_e2ee_encrypt(
part_to_encrypt,
);
if 0 != do_gossip {
let iCnt: libc::c_int = peerstates.len() as libc::c_int;
if iCnt > 1i32 {
let mut i: libc::c_int = 0i32;
while i < iCnt {
let i_cnt = peerstates.len() as libc::c_int;
if i_cnt > 1 {
let mut i = 0;
while i < i_cnt {
let p = peerstates[i as usize]
.render_gossip_header(min_verified as usize);
@@ -209,7 +199,8 @@ pub unsafe fn dc_e2ee_encrypt(
}
}
/* memoryhole headers */
let mut cur: *mut clistiter = (*(*imffields_unprotected).fld_list).first;
let mut cur: *mut clistiter =
(*(*imffields_unprotected).fld_list).first;
while !cur.is_null() {
let mut move_to_encrypted: libc::c_int = 0i32;
let field: *mut mailimf_field = (if !cur.is_null() {
@@ -226,15 +217,18 @@ pub unsafe fn dc_e2ee_encrypt(
{
let opt_field: *mut mailimf_optional_field =
(*field).fld_data.fld_optional_field;
if !opt_field.is_null() && !(*opt_field).fld_name.is_null() {
if !opt_field.is_null() && !(*opt_field).fld_name.is_null()
{
if strncmp(
(*opt_field).fld_name,
b"Secure-Join\x00" as *const u8 as *const libc::c_char,
b"Secure-Join\x00" as *const u8
as *const libc::c_char,
11,
) == 0
|| strncmp(
(*opt_field).fld_name,
b"Chat-\x00" as *const u8 as *const libc::c_char,
b"Chat-\x00" as *const u8
as *const libc::c_char,
5,
) == 0
&& strcmp(
@@ -296,7 +290,8 @@ pub unsafe fn dc_e2ee_encrypt(
mailmime_param_new_with_data(
b"protected-headers\x00" as *const u8 as *const libc::c_char
as *mut libc::c_char,
b"v1\x00" as *const u8 as *const libc::c_char as *mut libc::c_char,
b"v1\x00" as *const u8 as *const libc::c_char
as *mut libc::c_char,
) as *mut libc::c_void,
);
mailmime_write_mem(plain, &mut col, message_to_encrypt);
@@ -311,13 +306,14 @@ pub unsafe fn dc_e2ee_encrypt(
) {
let ctext_bytes = ctext_v.len();
let ctext = ctext_v.strdup();
helper.cdata_to_free = ctext as *mut _;
self.cdata_to_free = Some(Box::new(ctext));
/* create MIME-structure that will contain the encrypted text */
let mut encrypted_part: *mut mailmime = new_data_part(
ptr::null_mut(),
0i32 as size_t,
b"multipart/encrypted\x00" as *const u8 as *const libc::c_char
b"multipart/encrypted\x00" as *const u8
as *const libc::c_char
as *mut libc::c_char,
-1i32,
);
@@ -332,7 +328,8 @@ pub unsafe fn dc_e2ee_encrypt(
b"application/pgp-encrypted\x00" as *const u8
as *const libc::c_char
as *mut libc::c_char,
) as *mut libc::c_void,
)
as *mut libc::c_void,
);
static mut VERSION_CONTENT: [libc::c_char; 13] =
[86, 101, 114, 115, 105, 111, 110, 58, 32, 49, 13, 10, 0];
@@ -354,10 +351,11 @@ pub unsafe fn dc_e2ee_encrypt(
MAILMIME_MECHANISM_7BIT as libc::c_int,
);
mailmime_smart_add_part(encrypted_part, ctext_part);
(*in_out_message).mm_data.mm_message.mm_msg_mime = encrypted_part;
(*in_out_message).mm_data.mm_message.mm_msg_mime =
encrypted_part;
(*encrypted_part).mm_parent = in_out_message;
mailmime_free(message_to_encrypt);
helper.encryption_successfull = 1i32;
self.encryption_successfull = true;
}
}
}
@@ -379,11 +377,119 @@ pub unsafe fn dc_e2ee_encrypt(
if !plain.is_null() {
mmap_string_free(plain);
}
}
pub unsafe fn decrypt(&mut self, context: &Context, in_out_message: *mut mailmime) {
let mut iterations: libc::c_int;
/* return values: 0=nothing to decrypt/cannot decrypt, 1=sth. decrypted
(to detect parts that could not be decrypted, simply look for left "multipart/encrypted" MIME types */
/*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 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);
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;
if !orig_date.is_null() {
message_time = dc_timestamp_from_date((*orig_date).dt_date_time);
if message_time != 0 && message_time > time() {
message_time = time()
}
}
}
let mut peerstate = None;
let autocryptheader = Aheader::from_imffields(from, imffields);
if message_time > 0 && !from.is_null() {
peerstate = Peerstate::from_addr(context, &context.sql, as_str(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);
}
} 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 */
let self_addr = context.sql.get_config(context, "configured_addr");
if let Some(self_addr) = self_addr {
if private_keyring.load_self_private_for_decrypting(
context,
self_addr,
&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));
}
if let Some(ref peerstate) = peerstate {
if peerstate.degrade_event.is_some() {
dc_handle_degrade_event(context, &peerstate);
}
if let Some(ref key) = peerstate.gossip_key {
public_keyring_for_validate.add_ref(key);
}
if let Some(ref key) = peerstate.public_key {
public_keyring_for_validate.add_ref(key);
}
}
iterations = 0i32;
while iterations < 10i32 {
let mut has_unencrypted_parts: libc::c_int = 0i32;
if decrypt_recursive(
context,
in_out_message,
&private_keyring,
&public_keyring_for_validate,
&mut self.signatures,
&mut gossip_headers,
&mut has_unencrypted_parts,
)
.is_err()
{
break;
}
if iterations == 0i32 && 0 == has_unencrypted_parts {
self.encrypted = true;
}
iterations += 1;
}
if !gossip_headers.is_null() {
self.gossipped_addr = update_gossip_peerstates(
context,
message_time,
imffields,
gossip_headers,
)
}
}
}
}
//mailmime_print(in_out_message);
if !gossip_headers.is_null() {
mailimf_fields_free(gossip_headers);
}
free(from as *mut libc::c_void);
}
}
/*******************************************************************************
* Tools
******************************************************************************/
unsafe fn new_data_part(
data: *mut libc::c_void,
data_bytes: size_t,
@@ -528,111 +634,6 @@ fn load_or_generate_self_public_key(context: &Context, self_addr: impl AsRef<str
}
}
/* returns 1 if sth. was decrypted, 0 in other cases */
pub unsafe fn dc_e2ee_decrypt(
context: &Context,
in_out_message: *mut mailmime,
helper: &mut dc_e2ee_helper_t,
) {
let mut iterations: libc::c_int;
/* return values: 0=nothing to decrypt/cannot decrypt, 1=sth. decrypted
(to detect parts that could not be decrypted, simply look for left "multipart/encrypted" MIME types */
/*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 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);
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;
if !orig_date.is_null() {
message_time = dc_timestamp_from_date((*orig_date).dt_date_time);
if message_time != 0 && message_time > time() {
message_time = time()
}
}
}
let mut peerstate = None;
let autocryptheader = Aheader::from_imffields(from, imffields);
if message_time > 0 && !from.is_null() {
peerstate = Peerstate::from_addr(context, &context.sql, as_str(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
&& 0 == 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);
}
}
/* load private key for decryption */
let self_addr = context.sql.get_config(context, "configured_addr");
if let Some(self_addr) = self_addr {
if private_keyring.load_self_private_for_decrypting(context, self_addr, &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));
}
if let Some(ref peerstate) = peerstate {
if peerstate.degrade_event.is_some() {
dc_handle_degrade_event(context, &peerstate);
}
if let Some(ref key) = peerstate.gossip_key {
public_keyring_for_validate.add_ref(key);
}
if let Some(ref key) = peerstate.public_key {
public_keyring_for_validate.add_ref(key);
}
}
iterations = 0i32;
while iterations < 10i32 {
let mut has_unencrypted_parts: libc::c_int = 0i32;
if 0 == decrypt_recursive(
context,
in_out_message,
&private_keyring,
&public_keyring_for_validate,
&mut helper.signatures,
&mut gossip_headers,
&mut has_unencrypted_parts,
) {
break;
}
if iterations == 0i32 && 0 == has_unencrypted_parts {
helper.encrypted = 1i32
}
iterations += 1
}
if !gossip_headers.is_null() {
helper.gossipped_addr =
update_gossip_peerstates(context, message_time, imffields, gossip_headers)
}
}
}
}
//mailmime_print(in_out_message);
if !gossip_headers.is_null() {
mailimf_fields_free(gossip_headers);
}
free(from as *mut libc::c_void);
}
unsafe fn update_gossip_peerstates(
context: &Context,
message_time: i64,
@@ -706,7 +707,6 @@ unsafe fn update_gossip_peerstates(
gossipped_addr
}
// TODO should return bool /rtn
unsafe fn decrypt_recursive(
context: &Context,
mime: *mut mailmime,
@@ -715,12 +715,11 @@ unsafe fn decrypt_recursive(
ret_valid_signatures: &mut HashSet<String>,
ret_gossip_headers: *mut *mut mailimf_fields,
ret_has_unencrypted_parts: *mut libc::c_int,
) -> libc::c_int {
) -> Result<()> {
ensure!(!mime.is_null(), "Invalid mime reference");
let ct: *mut mailmime_content;
let mut cur: *mut clistiter;
if mime.is_null() {
return 0i32;
}
if (*mime).mm_type == MAILMIME_MULTIPLE as libc::c_int {
ct = (*mime).mm_content_type;
if !ct.is_null()
@@ -733,7 +732,7 @@ unsafe fn decrypt_recursive(
cur = (*(*mime).mm_data.mm_multipart.mm_mp_list).first;
while !cur.is_null() {
let mut decrypted_mime: *mut mailmime = ptr::null_mut();
if 0 != decrypt_part(
if decrypt_part(
context,
(if !cur.is_null() {
(*cur).data
@@ -761,7 +760,7 @@ unsafe fn decrypt_recursive(
}
mailmime_substitute(mime, decrypted_mime);
mailmime_free(mime);
return 1i32;
return Ok(());
}
cur = if !cur.is_null() {
(*cur).next
@@ -773,7 +772,7 @@ unsafe fn decrypt_recursive(
} else {
cur = (*(*mime).mm_data.mm_multipart.mm_mp_list).first;
while !cur.is_null() {
if 0 != decrypt_recursive(
if decrypt_recursive(
context,
(if !cur.is_null() {
(*cur).data
@@ -785,8 +784,10 @@ unsafe fn decrypt_recursive(
ret_valid_signatures,
ret_gossip_headers,
ret_has_unencrypted_parts,
) {
return 1i32;
)
.is_ok()
{
return Ok(());
}
cur = if !cur.is_null() {
(*cur).next
@@ -796,7 +797,7 @@ unsafe fn decrypt_recursive(
}
}
} else if (*mime).mm_type == MAILMIME_MESSAGE as libc::c_int {
if 0 != decrypt_recursive(
if decrypt_recursive(
context,
(*mime).mm_data.mm_message.mm_msg_mime,
private_keyring,
@@ -804,14 +805,16 @@ unsafe fn decrypt_recursive(
ret_valid_signatures,
ret_gossip_headers,
ret_has_unencrypted_parts,
) {
return 1i32;
)
.is_ok()
{
return Ok(());
}
} else {
*ret_has_unencrypted_parts = 1i32
*ret_has_unencrypted_parts = 1;
}
0
Err(format_err!("Failed to decrypt"))
}
unsafe fn decrypt_part(
@@ -821,7 +824,7 @@ unsafe fn decrypt_part(
public_keyring_for_validate: &Keyring,
ret_valid_signatures: &mut HashSet<String>,
ret_decrypted_mime: *mut *mut mailmime,
) -> libc::c_int {
) -> bool {
let mut ok_to_continue = true;
let mime_data: *mut mailmime_data;
let mut mime_transfer_encoding: libc::c_int = MAILMIME_MECHANISM_BINARY as libc::c_int;
@@ -830,7 +833,8 @@ unsafe fn decrypt_part(
/* must not be free()'d */
let mut decoded_data: *const libc::c_char = ptr::null_mut();
let mut decoded_data_bytes: size_t = 0i32 as size_t;
let mut sth_decrypted: libc::c_int = 0i32;
let mut sth_decrypted = false;
*ret_decrypted_mime = ptr::null_mut();
mime_data = (*mime).mm_data.mm_single;
/* MAILMIME_DATA_FILE indicates, the data is in a file; AFAIK this is not used on parsing */
@@ -894,7 +898,7 @@ unsafe fn decrypt_part(
}
if ok_to_continue {
/* encrypted, decoded data in decoded_data now ... */
if !(0 == has_decrypted_pgp_armor(decoded_data, decoded_data_bytes as libc::c_int)) {
if has_decrypted_pgp_armor(decoded_data, decoded_data_bytes as libc::c_int) {
let add_signatures = if ret_valid_signatures.is_empty() {
Some(ret_valid_signatures)
} else {
@@ -927,7 +931,7 @@ unsafe fn decrypt_part(
}
} else {
*ret_decrypted_mime = decrypted_mime;
sth_decrypted = 1i32
sth_decrypted = true;
}
std::mem::forget(plain);
}
@@ -943,14 +947,7 @@ unsafe fn decrypt_part(
sth_decrypted
}
/*******************************************************************************
* Decrypt
******************************************************************************/
// TODO should return bool /rtn
unsafe fn has_decrypted_pgp_armor(
str__: *const libc::c_char,
mut str_bytes: libc::c_int,
) -> libc::c_int {
unsafe fn has_decrypted_pgp_armor(str__: *const libc::c_char, mut str_bytes: libc::c_int) -> bool {
let str_end: *const libc::c_uchar = (str__ as *const libc::c_uchar).offset(str_bytes as isize);
let mut p: *const libc::c_uchar = str__ as *const libc::c_uchar;
while p < str_end {
@@ -960,35 +957,23 @@ unsafe fn has_decrypted_pgp_armor(
p = p.offset(1isize);
str_bytes -= 1
}
if str_bytes > 27i32
str_bytes > 27i32
&& strncmp(
p as *const libc::c_char,
b"-----BEGIN PGP MESSAGE-----\x00" as *const u8 as *const libc::c_char,
27,
) == 0
{
return 1;
}
0
}
/**
* Check if a MIME structure contains a multipart/report part.
*
* As reports are often unencrypted, we do not reset the Autocrypt header in
* this case.
*
* However, Delta Chat itself has no problem with encrypted multipart/report
* parts and MUAs should be encouraged to encrpyt multipart/reports as well so
* that we could use the normal Autocrypt processing.
*
* @private
* @param mime The mime structure to check
* @return 1=multipart/report found in MIME, 0=no multipart/report found
*/
// TODO should return bool /rtn
unsafe fn contains_report(mime: *mut mailmime) -> libc::c_int {
/// Check if a MIME structure contains a multipart/report part.
///
/// As reports are often unencrypted, we do not reset the Autocrypt header in
/// this case.
///
/// However, Delta Chat itself has no problem with encrypted multipart/report
/// parts and MUAs should be encouraged to encrpyt multipart/reports as well so
/// that we could use the normal Autocrypt processing.
unsafe fn contains_report(mime: *mut mailmime) -> bool {
if (*mime).mm_type == MAILMIME_MULTIPLE as libc::c_int {
if (*(*(*mime).mm_content_type).ct_type).tp_type
== MAILMIME_TYPE_COMPOSITE_TYPE as libc::c_int
@@ -1002,19 +987,19 @@ unsafe fn contains_report(mime: *mut mailmime) -> libc::c_int {
b"report\x00" as *const u8 as *const libc::c_char,
) == 0i32
{
return 1i32;
return true;
}
let mut cur: *mut clistiter;
cur = (*(*mime).mm_data.mm_multipart.mm_mp_list).first;
while !cur.is_null() {
if 0 != contains_report(
if contains_report(
(if !cur.is_null() {
(*cur).data
} else {
ptr::null_mut()
}) as *mut mailmime,
) {
return 1i32;
return true;
}
cur = if !cur.is_null() {
(*cur).next
@@ -1023,18 +1008,12 @@ unsafe fn contains_report(mime: *mut mailmime) -> libc::c_int {
}
}
} else if (*mime).mm_type == MAILMIME_MESSAGE as libc::c_int {
if 0 != contains_report((*mime).mm_data.mm_message.mm_msg_mime) {
return 1i32;
if contains_report((*mime).mm_data.mm_message.mm_msg_mime) {
return true;
}
}
0
}
/* frees data referenced by "mailmime" but not freed by mailmime_free(). After calling this function, in_out_message cannot be used any longer! */
pub unsafe fn dc_e2ee_thanks(helper: &mut dc_e2ee_helper_t) {
free(helper.cdata_to_free);
helper.cdata_to_free = ptr::null_mut();
false
}
/// Ensures a private key exists for the configured user.

View File

@@ -353,13 +353,7 @@ pub unsafe fn dc_mimefactory_render(factory: &mut dc_mimefactory_t) -> libc::c_i
let mut force_plaintext: libc::c_int = 0;
let mut do_gossip: libc::c_int = 0;
let mut grpimage = None;
let mut e2ee_helper = dc_e2ee_helper_t {
encryption_successfull: 0,
cdata_to_free: ptr::null_mut(),
encrypted: 0,
signatures: Default::default(),
gossipped_addr: Default::default(),
};
let mut e2ee_helper = E2eeHelper::default();
if factory.loaded as libc::c_uint == DC_MF_NOTHING_LOADED as libc::c_int as libc::c_uint
|| !factory.out.is_null()
@@ -1033,7 +1027,7 @@ pub unsafe fn dc_mimefactory_render(factory: &mut dc_mimefactory_t) -> libc::c_i
),
);
if force_plaintext != 2 {
dc_e2ee_encrypt(
e2ee_helper.encrypt(
factory.context,
factory.recipients_addr,
force_plaintext,
@@ -1041,10 +1035,9 @@ pub unsafe fn dc_mimefactory_render(factory: &mut dc_mimefactory_t) -> libc::c_i
min_verified,
do_gossip,
message,
&mut e2ee_helper,
);
}
if 0 != e2ee_helper.encryption_successfull {
if e2ee_helper.encryption_successfull {
factory.out_encrypted = 1;
if 0 != do_gossip {
factory.out_gossiped = 1
@@ -1052,14 +1045,14 @@ pub unsafe fn dc_mimefactory_render(factory: &mut dc_mimefactory_t) -> libc::c_i
}
factory.out = mmap_string_new(b"\x00" as *const u8 as *const libc::c_char);
mailmime_write_mem(factory.out, &mut col, message);
success = 1
success = 1;
}
}
if !message.is_null() {
mailmime_free(message);
}
dc_e2ee_thanks(&mut e2ee_helper);
e2ee_helper.thanks();
free(message_text as *mut libc::c_void);
free(message_text2 as *mut libc::c_void);
free(subject_str as *mut libc::c_void);

View File

@@ -43,7 +43,6 @@ pub struct dc_mimepart_t {
/* *
* @class dc_mimeparser_t
*/
#[derive(Clone)]
#[allow(non_camel_case_types)]
pub struct dc_mimeparser_t<'a> {
pub parts: Vec<dc_mimepart_t>,
@@ -54,7 +53,7 @@ pub struct dc_mimeparser_t<'a> {
pub subject: *mut libc::c_char,
pub is_send_by_messenger: bool,
pub decrypting_failed: libc::c_int,
pub e2ee_helper: dc_e2ee_helper_t,
pub e2ee_helper: E2eeHelper,
pub is_forwarded: libc::c_int,
pub context: &'a Context,
pub reports: Vec<*mut mailmime>,
@@ -109,7 +108,7 @@ unsafe fn dc_mimeparser_empty(mimeparser: &mut dc_mimeparser_t) {
mimeparser.is_forwarded = 0i32;
mimeparser.reports.clear();
mimeparser.decrypting_failed = 0i32;
dc_e2ee_thanks(&mut mimeparser.e2ee_helper);
mimeparser.e2ee_helper.thanks();
mimeparser.location_kml = None;
mimeparser.message_kml = None;
@@ -135,14 +134,11 @@ pub unsafe fn dc_mimeparser_parse<'a>(context: &'a Context, body: &[u8]) -> dc_m
&mut mimeparser.mimeroot,
);
if r == MAILIMF_NO_ERROR as libc::c_int && !mimeparser.mimeroot.is_null() {
dc_e2ee_decrypt(
mimeparser.context,
mimeparser.mimeroot,
&mut mimeparser.e2ee_helper,
);
let mimeparser_ref = &mut mimeparser;
dc_mimeparser_parse_mime_recursive(mimeparser_ref, mimeparser_ref.mimeroot);
let field: *mut mailimf_field = dc_mimeparser_lookup_field(&mut mimeparser, "Subject");
mimeparser
.e2ee_helper
.decrypt(mimeparser.context, mimeparser.mimeroot);
dc_mimeparser_parse_mime_recursive(&mut mimeparser, mimeparser.mimeroot);
let field: *mut mailimf_field = dc_mimeparser_lookup_field(&mimeparser, "Subject");
if !field.is_null() && (*field).fld_type == MAILIMF_FIELD_SUBJECT as libc::c_int {
mimeparser.subject = dc_decode_header_words((*(*field).fld_data.fld_subject).sbj_value)
}
@@ -1361,9 +1357,9 @@ unsafe fn do_add_single_file_part(
}
unsafe fn do_add_single_part(parser: &mut dc_mimeparser_t, mut part: dc_mimepart_t) {
if 0 != (*parser).e2ee_helper.encrypted && (*parser).e2ee_helper.signatures.len() > 0 {
if (*parser).e2ee_helper.encrypted && (*parser).e2ee_helper.signatures.len() > 0 {
part.param.set_int(Param::GuranteeE2ee, 1);
} else if 0 != (*parser).e2ee_helper.encrypted {
} else if (*parser).e2ee_helper.encrypted {
part.param.set_int(Param::ErroneousE2ee, 0x2);
}
parser.parts.push(part);
@@ -1818,19 +1814,22 @@ mod tests {
let mut mimeparser = dc_mimeparser_parse(&context.ctx, &raw[..]);
assert_eq!(
as_str(mimeparser.subject as *const libc::c_char),
&to_string(mimeparser.subject as *const libc::c_char),
"inner-subject",
);
let mut of: *mut mailimf_optional_field =
dc_mimeparser_lookup_optional_field(&mimeparser, "X-Special-A");
assert_eq!(as_str((*of).fld_value as *const libc::c_char), "special-a",);
assert_eq!(
&to_string((*of).fld_value as *const libc::c_char),
"special-a",
);
of = dc_mimeparser_lookup_optional_field(&mimeparser, "Foo");
assert_eq!(as_str((*of).fld_value as *const libc::c_char), "Bar",);
assert_eq!(&to_string((*of).fld_value as *const libc::c_char), "Bar",);
of = dc_mimeparser_lookup_optional_field(&mimeparser, "Chat-Version");
assert_eq!(as_str((*of).fld_value as *const libc::c_char), "1.0",);
assert_eq!(&to_string((*of).fld_value as *const libc::c_char), "1.0",);
assert_eq!(mimeparser.parts.len(), 1);
dc_mimeparser_unref(&mut mimeparser);

View File

@@ -1761,7 +1761,7 @@ unsafe fn check_verified_properties(
}
};
if 0 == mimeparser.e2ee_helper.encrypted {
if mimeparser.e2ee_helper.encrypted {
verify_fail("This message is not encrypted".into());
return 0;
}

View File

@@ -504,7 +504,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
could_not_establish_secure_connection(
context,
contact_chat_id,
if 0 != mimeparser.e2ee_helper.encrypted {
if mimeparser.e2ee_helper.encrypted {
b"No valid signature.\x00" as *const u8 as *const libc::c_char
} else {
b"Not encrypted.\x00" as *const u8 as *const libc::c_char
@@ -943,7 +943,7 @@ unsafe fn encrypted_and_signed(
mimeparser: &dc_mimeparser_t,
expected_fingerprint: impl AsRef<str>,
) -> bool {
if 0 == mimeparser.e2ee_helper.encrypted {
if !mimeparser.e2ee_helper.encrypted {
warn!(mimeparser.context, 0, "Message not encrypted.",);
return false;
}