mirror of
https://github.com/chatmail/core.git
synced 2026-04-06 15:42:10 +03:00
1255 lines
56 KiB
Rust
1255 lines
56 KiB
Rust
use c2rust_bitfields::BitfieldStruct;
|
|
use libc;
|
|
|
|
use crate::dc_aheader::*;
|
|
use crate::dc_apeerstate::*;
|
|
use crate::dc_array::*;
|
|
use crate::dc_context::dc_context_t;
|
|
use crate::dc_hash::*;
|
|
use crate::dc_key::*;
|
|
use crate::dc_keyring::*;
|
|
use crate::dc_log::*;
|
|
use crate::dc_lot::dc_lot_t;
|
|
use crate::dc_mimeparser::*;
|
|
use crate::dc_pgp::*;
|
|
use crate::dc_securejoin::*;
|
|
use crate::dc_sqlite3::*;
|
|
use crate::dc_tools::*;
|
|
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 substract 1 mb header-overhead and the base64-overhead.
|
|
// some defaults
|
|
#[derive(Copy, Clone)]
|
|
#[repr(C)]
|
|
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,
|
|
pub signatures: *mut dc_hash_t,
|
|
pub gossipped_addr: *mut dc_hash_t,
|
|
}
|
|
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn dc_e2ee_encrypt(
|
|
mut context: *mut dc_context_t,
|
|
mut recipients_addr: *const clist,
|
|
mut force_unencrypted: libc::c_int,
|
|
mut e2ee_guaranteed: libc::c_int,
|
|
mut min_verified: libc::c_int,
|
|
mut do_gossip: libc::c_int,
|
|
mut in_out_message: *mut mailmime,
|
|
mut helper: *mut dc_e2ee_helper_t,
|
|
) {
|
|
let mut p_0: *mut libc::c_char = 0 as *mut libc::c_char;
|
|
let mut current_block: u64;
|
|
let mut col: libc::c_int = 0i32;
|
|
let mut do_encrypt: libc::c_int = 0i32;
|
|
let mut autocryptheader: *mut dc_aheader_t = dc_aheader_new();
|
|
/*just a pointer into mailmime structure, must not be freed*/
|
|
let mut imffields_unprotected: *mut mailimf_fields = 0 as *mut mailimf_fields;
|
|
let mut keyring: *mut dc_keyring_t = dc_keyring_new();
|
|
let mut sign_key: *mut dc_key_t = dc_key_new();
|
|
let mut plain: *mut MMAPString = mmap_string_new(b"\x00" as *const u8 as *const libc::c_char);
|
|
let mut ctext: *mut libc::c_char = 0 as *mut libc::c_char;
|
|
let mut ctext_bytes: size_t = 0i32 as size_t;
|
|
let mut peerstates: *mut dc_array_t = dc_array_new(0 as *mut dc_context_t, 10i32 as size_t);
|
|
if !helper.is_null() {
|
|
memset(
|
|
helper as *mut libc::c_void,
|
|
0i32,
|
|
::std::mem::size_of::<dc_e2ee_helper_t>() as libc::c_ulong,
|
|
);
|
|
}
|
|
if !(context.is_null()
|
|
|| (*context).magic != 0x11a11807i32 as libc::c_uint
|
|
|| recipients_addr.is_null()
|
|
|| in_out_message.is_null()
|
|
|| !(*in_out_message).mm_parent.is_null()
|
|
|| autocryptheader.is_null()
|
|
|| keyring.is_null()
|
|
|| sign_key.is_null()
|
|
|| plain.is_null()
|
|
|| helper.is_null())
|
|
{
|
|
/* libEtPan's pgp_encrypt_mime() takes the parent as the new root. We just expect the root as being given to this function. */
|
|
(*autocryptheader).prefer_encrypt = 0i32;
|
|
if 0 != dc_sqlite3_get_config_int(
|
|
(*context).sql,
|
|
b"e2ee_enabled\x00" as *const u8 as *const libc::c_char,
|
|
1i32,
|
|
) {
|
|
(*autocryptheader).prefer_encrypt = 1i32
|
|
}
|
|
(*autocryptheader).addr = dc_sqlite3_get_config(
|
|
(*context).sql,
|
|
b"configured_addr\x00" as *const u8 as *const libc::c_char,
|
|
0 as *const libc::c_char,
|
|
);
|
|
if !(*autocryptheader).addr.is_null() {
|
|
if !(0
|
|
== load_or_generate_self_public_key(
|
|
context,
|
|
(*autocryptheader).public_key,
|
|
(*autocryptheader).addr,
|
|
in_out_message,
|
|
))
|
|
{
|
|
/*only for random-seed*/
|
|
if (*autocryptheader).prefer_encrypt == 1i32 || 0 != e2ee_guaranteed {
|
|
do_encrypt = 1i32;
|
|
let mut iter1: *mut clistiter = 0 as *mut clistiter;
|
|
iter1 = (*recipients_addr).first;
|
|
while !iter1.is_null() {
|
|
let mut recipient_addr: *const libc::c_char = (if !iter1.is_null() {
|
|
(*iter1).data
|
|
} else {
|
|
0 as *mut libc::c_void
|
|
})
|
|
as *const libc::c_char;
|
|
let mut peerstate: *mut dc_apeerstate_t = dc_apeerstate_new(context);
|
|
let mut key_to_use: *mut dc_key_t = 0 as *mut dc_key_t;
|
|
if !(strcasecmp(recipient_addr, (*autocryptheader).addr) == 0i32) {
|
|
if 0 != dc_apeerstate_load_by_addr(
|
|
peerstate,
|
|
(*context).sql,
|
|
recipient_addr,
|
|
) && {
|
|
key_to_use = dc_apeerstate_peek_key(peerstate, min_verified);
|
|
!key_to_use.is_null()
|
|
} && ((*peerstate).prefer_encrypt == 1i32 || 0 != e2ee_guaranteed)
|
|
{
|
|
dc_keyring_add(keyring, key_to_use);
|
|
dc_array_add_ptr(peerstates, peerstate as *mut libc::c_void);
|
|
} else {
|
|
dc_apeerstate_unref(peerstate);
|
|
do_encrypt = 0i32;
|
|
/* if we cannot encrypt to a single recipient, we cannot encrypt the message at all */
|
|
break;
|
|
}
|
|
}
|
|
iter1 = if !iter1.is_null() {
|
|
(*iter1).next
|
|
} else {
|
|
0 as *mut clistcell_s
|
|
}
|
|
}
|
|
}
|
|
if 0 != do_encrypt {
|
|
dc_keyring_add(keyring, (*autocryptheader).public_key);
|
|
if 0 == dc_key_load_self_private(
|
|
sign_key,
|
|
(*autocryptheader).addr,
|
|
(*context).sql,
|
|
) {
|
|
do_encrypt = 0i32
|
|
}
|
|
}
|
|
if 0 != force_unencrypted {
|
|
do_encrypt = 0i32
|
|
}
|
|
imffields_unprotected = mailmime_find_mailimf_fields(in_out_message);
|
|
if !imffields_unprotected.is_null() {
|
|
/* encrypt message, if possible */
|
|
if 0 != do_encrypt {
|
|
mailprivacy_prepare_mime(in_out_message);
|
|
let mut part_to_encrypt: *mut mailmime =
|
|
(*in_out_message).mm_data.mm_message.mm_msg_mime;
|
|
(*part_to_encrypt).mm_parent = 0 as *mut mailmime;
|
|
let mut 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 mut message_to_encrypt: *mut mailmime = mailmime_new(
|
|
MAILMIME_MESSAGE as libc::c_int,
|
|
0 as *const libc::c_char,
|
|
0i32 as size_t,
|
|
mailmime_fields_new_empty(),
|
|
mailmime_get_content_message(),
|
|
0 as *mut mailmime_data,
|
|
0 as *mut mailmime_data,
|
|
0 as *mut mailmime_data,
|
|
0 as *mut clist,
|
|
imffields_encrypted,
|
|
part_to_encrypt,
|
|
);
|
|
if 0 != do_gossip {
|
|
let mut iCnt: libc::c_int = dc_array_get_cnt(peerstates) as libc::c_int;
|
|
if iCnt > 1i32 {
|
|
let mut i: libc::c_int = 0i32;
|
|
while i < iCnt {
|
|
let mut p: *mut libc::c_char =
|
|
dc_apeerstate_render_gossip_header(
|
|
dc_array_get_ptr(peerstates, i as size_t)
|
|
as *mut dc_apeerstate_t,
|
|
min_verified,
|
|
);
|
|
if !p.is_null() {
|
|
mailimf_fields_add(
|
|
imffields_encrypted,
|
|
mailimf_field_new_custom(
|
|
strdup(
|
|
b"Autocrypt-Gossip\x00" as *const u8
|
|
as *const libc::c_char,
|
|
),
|
|
p,
|
|
),
|
|
);
|
|
}
|
|
i += 1
|
|
}
|
|
}
|
|
}
|
|
/* memoryhole headers */
|
|
let mut cur: *mut clistiter = (*(*imffields_unprotected).fld_list).first;
|
|
while !cur.is_null() {
|
|
let mut move_to_encrypted: libc::c_int = 0i32;
|
|
let mut field: *mut mailimf_field = (if !cur.is_null() {
|
|
(*cur).data
|
|
} else {
|
|
0 as *mut libc::c_void
|
|
})
|
|
as *mut mailimf_field;
|
|
if !field.is_null() {
|
|
if (*field).fld_type == MAILIMF_FIELD_SUBJECT as libc::c_int {
|
|
move_to_encrypted = 1i32
|
|
} else if (*field).fld_type
|
|
== MAILIMF_FIELD_OPTIONAL_FIELD as libc::c_int
|
|
{
|
|
let mut opt_field: *mut mailimf_optional_field =
|
|
(*field).fld_data.fld_optional_field;
|
|
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,
|
|
11i32 as libc::c_ulong,
|
|
) == 0i32
|
|
|| strncmp(
|
|
(*opt_field).fld_name,
|
|
b"Chat-\x00" as *const u8 as *const libc::c_char,
|
|
5i32 as libc::c_ulong,
|
|
) == 0i32
|
|
&& strcmp(
|
|
(*opt_field).fld_name,
|
|
b"Chat-Version\x00" as *const u8
|
|
as *const libc::c_char,
|
|
) != 0i32
|
|
{
|
|
move_to_encrypted = 1i32
|
|
}
|
|
}
|
|
}
|
|
}
|
|
if 0 != move_to_encrypted {
|
|
mailimf_fields_add(imffields_encrypted, field);
|
|
cur = clist_delete((*imffields_unprotected).fld_list, cur)
|
|
} else {
|
|
cur = if !cur.is_null() {
|
|
(*cur).next
|
|
} else {
|
|
0 as *mut clistcell_s
|
|
}
|
|
}
|
|
}
|
|
let mut subject: *mut mailimf_subject = mailimf_subject_new(dc_strdup(
|
|
b"...\x00" as *const u8 as *const libc::c_char,
|
|
));
|
|
mailimf_fields_add(
|
|
imffields_unprotected,
|
|
mailimf_field_new(
|
|
MAILIMF_FIELD_SUBJECT as libc::c_int,
|
|
0 as *mut mailimf_return,
|
|
0 as *mut mailimf_orig_date,
|
|
0 as *mut mailimf_from,
|
|
0 as *mut mailimf_sender,
|
|
0 as *mut mailimf_to,
|
|
0 as *mut mailimf_cc,
|
|
0 as *mut mailimf_bcc,
|
|
0 as *mut mailimf_message_id,
|
|
0 as *mut mailimf_orig_date,
|
|
0 as *mut mailimf_from,
|
|
0 as *mut mailimf_sender,
|
|
0 as *mut mailimf_reply_to,
|
|
0 as *mut mailimf_to,
|
|
0 as *mut mailimf_cc,
|
|
0 as *mut mailimf_bcc,
|
|
0 as *mut mailimf_message_id,
|
|
0 as *mut mailimf_in_reply_to,
|
|
0 as *mut mailimf_references,
|
|
subject,
|
|
0 as *mut mailimf_comments,
|
|
0 as *mut mailimf_keywords,
|
|
0 as *mut mailimf_optional_field,
|
|
),
|
|
);
|
|
clist_insert_after(
|
|
(*(*part_to_encrypt).mm_content_type).ct_parameters,
|
|
(*(*(*part_to_encrypt).mm_content_type).ct_parameters).last,
|
|
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,
|
|
) as *mut libc::c_void,
|
|
);
|
|
mailmime_write_mem(plain, &mut col, message_to_encrypt);
|
|
if (*plain).str_0.is_null() || (*plain).len <= 0i32 as libc::c_ulong {
|
|
current_block = 14181132614457621749;
|
|
} else if 0
|
|
== dc_pgp_pk_encrypt(
|
|
context,
|
|
(*plain).str_0 as *const libc::c_void,
|
|
(*plain).len,
|
|
keyring,
|
|
sign_key,
|
|
1i32,
|
|
&mut ctext as *mut *mut libc::c_char as *mut *mut libc::c_void,
|
|
&mut ctext_bytes,
|
|
)
|
|
{
|
|
/*use_armor*/
|
|
current_block = 14181132614457621749;
|
|
} else {
|
|
(*helper).cdata_to_free = ctext as *mut libc::c_void;
|
|
//char* t2=dc_null_terminate(ctext,ctext_bytes);printf("ENCRYPTED:\n%s\n",t2);free(t2); // DEBUG OUTPUT
|
|
/* create MIME-structure that will contain the encrypted text */
|
|
let mut encrypted_part: *mut mailmime = new_data_part(
|
|
0 as *mut libc::c_void,
|
|
0i32 as size_t,
|
|
b"multipart/encrypted\x00" as *const u8 as *const libc::c_char
|
|
as *mut libc::c_char,
|
|
-1i32,
|
|
);
|
|
let mut content: *mut mailmime_content =
|
|
(*encrypted_part).mm_content_type;
|
|
clist_insert_after(
|
|
(*content).ct_parameters,
|
|
(*(*content).ct_parameters).last,
|
|
mailmime_param_new_with_data(
|
|
b"protocol\x00" as *const u8 as *const libc::c_char
|
|
as *mut libc::c_char,
|
|
b"application/pgp-encrypted\x00" as *const u8
|
|
as *const libc::c_char
|
|
as *mut libc::c_char,
|
|
) 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];
|
|
let mut version_mime: *mut mailmime = new_data_part(
|
|
version_content.as_mut_ptr() as *mut libc::c_void,
|
|
strlen(version_content.as_mut_ptr()),
|
|
b"application/pgp-encrypted\x00" as *const u8 as *const libc::c_char
|
|
as *mut libc::c_char,
|
|
MAILMIME_MECHANISM_7BIT as libc::c_int,
|
|
);
|
|
mailmime_smart_add_part(encrypted_part, version_mime);
|
|
let mut ctext_part: *mut mailmime = new_data_part(
|
|
ctext as *mut libc::c_void,
|
|
ctext_bytes,
|
|
b"application/octet-stream\x00" as *const u8 as *const libc::c_char
|
|
as *mut libc::c_char,
|
|
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;
|
|
(*encrypted_part).mm_parent = in_out_message;
|
|
mailmime_free(message_to_encrypt);
|
|
(*helper).encryption_successfull = 1i32;
|
|
current_block = 13824533195664196414;
|
|
}
|
|
} else {
|
|
current_block = 13824533195664196414;
|
|
}
|
|
match current_block {
|
|
14181132614457621749 => {}
|
|
_ => {
|
|
p_0 = dc_aheader_render(autocryptheader);
|
|
if !p_0.is_null() {
|
|
mailimf_fields_add(
|
|
imffields_unprotected,
|
|
mailimf_field_new_custom(
|
|
strdup(
|
|
b"Autocrypt\x00" as *const u8 as *const libc::c_char,
|
|
),
|
|
p_0,
|
|
),
|
|
);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
dc_aheader_unref(autocryptheader);
|
|
dc_keyring_unref(keyring);
|
|
dc_key_unref(sign_key);
|
|
if !plain.is_null() {
|
|
mmap_string_free(plain);
|
|
}
|
|
let mut i_0: libc::c_int =
|
|
dc_array_get_cnt(peerstates).wrapping_sub(1i32 as libc::c_ulong) as libc::c_int;
|
|
while i_0 >= 0i32 {
|
|
dc_apeerstate_unref(dc_array_get_ptr(peerstates, i_0 as size_t) as *mut dc_apeerstate_t);
|
|
i_0 -= 1
|
|
}
|
|
dc_array_unref(peerstates);
|
|
}
|
|
/* ******************************************************************************
|
|
* Tools
|
|
******************************************************************************/
|
|
unsafe extern "C" fn new_data_part(
|
|
mut data: *mut libc::c_void,
|
|
mut data_bytes: size_t,
|
|
mut default_content_type: *mut libc::c_char,
|
|
mut default_encoding: libc::c_int,
|
|
) -> *mut mailmime {
|
|
let mut current_block: u64;
|
|
//char basename_buf[PATH_MAX];
|
|
let mut encoding: *mut mailmime_mechanism = 0 as *mut mailmime_mechanism;
|
|
let mut content: *mut mailmime_content = 0 as *mut mailmime_content;
|
|
let mut mime: *mut mailmime = 0 as *mut mailmime;
|
|
//int r;
|
|
//char * dup_filename;
|
|
let mut mime_fields: *mut mailmime_fields = 0 as *mut mailmime_fields;
|
|
let mut encoding_type: libc::c_int = 0;
|
|
let mut content_type_str: *mut libc::c_char = 0 as *mut libc::c_char;
|
|
let mut do_encoding: libc::c_int = 0;
|
|
encoding = 0 as *mut mailmime_mechanism;
|
|
if default_content_type.is_null() {
|
|
content_type_str =
|
|
b"application/octet-stream\x00" as *const u8 as *const libc::c_char as *mut libc::c_char
|
|
} else {
|
|
content_type_str = default_content_type
|
|
}
|
|
content = mailmime_content_new_with_str(content_type_str);
|
|
if content.is_null() {
|
|
current_block = 16266721588079097885;
|
|
} else {
|
|
do_encoding = 1i32;
|
|
if (*(*content).ct_type).tp_type == MAILMIME_TYPE_COMPOSITE_TYPE as libc::c_int {
|
|
let mut composite: *mut mailmime_composite_type = 0 as *mut mailmime_composite_type;
|
|
composite = (*(*content).ct_type).tp_data.tp_composite_type;
|
|
match (*composite).ct_type {
|
|
1 => {
|
|
if strcasecmp(
|
|
(*content).ct_subtype,
|
|
b"rfc822\x00" as *const u8 as *const libc::c_char,
|
|
) == 0i32
|
|
{
|
|
do_encoding = 0i32
|
|
}
|
|
}
|
|
2 => do_encoding = 0i32,
|
|
_ => {}
|
|
}
|
|
}
|
|
if 0 != do_encoding {
|
|
if default_encoding == -1i32 {
|
|
encoding_type = MAILMIME_MECHANISM_BASE64 as libc::c_int
|
|
} else {
|
|
encoding_type = default_encoding
|
|
}
|
|
encoding = mailmime_mechanism_new(encoding_type, 0 as *mut libc::c_char);
|
|
if encoding.is_null() {
|
|
current_block = 16266721588079097885;
|
|
} else {
|
|
current_block = 11057878835866523405;
|
|
}
|
|
} else {
|
|
current_block = 11057878835866523405;
|
|
}
|
|
match current_block {
|
|
16266721588079097885 => {}
|
|
_ => {
|
|
mime_fields = mailmime_fields_new_with_data(
|
|
encoding,
|
|
0 as *mut libc::c_char,
|
|
0 as *mut libc::c_char,
|
|
0 as *mut mailmime_disposition,
|
|
0 as *mut mailmime_language,
|
|
);
|
|
if mime_fields.is_null() {
|
|
current_block = 16266721588079097885;
|
|
} else {
|
|
mime = mailmime_new_empty(content, mime_fields);
|
|
if mime.is_null() {
|
|
mailmime_fields_free(mime_fields);
|
|
mailmime_content_free(content);
|
|
} else {
|
|
if !data.is_null()
|
|
&& data_bytes > 0i32 as libc::c_ulong
|
|
&& (*mime).mm_type == MAILMIME_SINGLE as libc::c_int
|
|
{
|
|
mailmime_set_body_text(mime, data as *mut libc::c_char, data_bytes);
|
|
}
|
|
return mime;
|
|
}
|
|
current_block = 13668317689588454213;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
match current_block {
|
|
16266721588079097885 => {
|
|
if !encoding.is_null() {
|
|
mailmime_mechanism_free(encoding);
|
|
}
|
|
if !content.is_null() {
|
|
mailmime_content_free(content);
|
|
}
|
|
}
|
|
_ => {}
|
|
}
|
|
return 0 as *mut mailmime;
|
|
}
|
|
/* ******************************************************************************
|
|
* Generate Keypairs
|
|
******************************************************************************/
|
|
unsafe extern "C" fn load_or_generate_self_public_key(
|
|
mut context: *mut dc_context_t,
|
|
mut public_key: *mut dc_key_t,
|
|
mut self_addr: *const libc::c_char,
|
|
mut random_data_mime: *mut mailmime,
|
|
) -> libc::c_int {
|
|
let mut current_block: u64;
|
|
/* avoid double creation (we unlock the database during creation) */
|
|
static mut s_in_key_creation: libc::c_int = 0i32;
|
|
let mut key_created: libc::c_int = 0i32;
|
|
let mut success: libc::c_int = 0i32;
|
|
let mut key_creation_here: libc::c_int = 0i32;
|
|
if !(context.is_null()
|
|
|| (*context).magic != 0x11a11807i32 as libc::c_uint
|
|
|| public_key.is_null())
|
|
{
|
|
if 0 == dc_key_load_self_public(public_key, self_addr, (*context).sql) {
|
|
/* create the keypair - this may take a moment, however, as this is in a thread, this is no big deal */
|
|
if 0 != s_in_key_creation {
|
|
current_block = 10496152961502316708;
|
|
} else {
|
|
key_creation_here = 1i32;
|
|
s_in_key_creation = 1i32;
|
|
/* seed the random generator */
|
|
let mut seed: [uintptr_t; 4] = [0; 4];
|
|
seed[0usize] = time(0 as *mut time_t) as uintptr_t;
|
|
seed[1usize] = seed.as_mut_ptr() as uintptr_t;
|
|
seed[2usize] = public_key as uintptr_t;
|
|
seed[3usize] = pthread_self() as uintptr_t;
|
|
dc_pgp_rand_seed(
|
|
context,
|
|
seed.as_mut_ptr() as *const libc::c_void,
|
|
::std::mem::size_of::<[uintptr_t; 4]>() as libc::c_ulong,
|
|
);
|
|
if !random_data_mime.is_null() {
|
|
let mut random_data_mmap: *mut MMAPString = 0 as *mut MMAPString;
|
|
let mut col: libc::c_int = 0i32;
|
|
random_data_mmap = mmap_string_new(b"\x00" as *const u8 as *const libc::c_char);
|
|
if random_data_mmap.is_null() {
|
|
current_block = 10496152961502316708;
|
|
} else {
|
|
mailmime_write_mem(random_data_mmap, &mut col, random_data_mime);
|
|
dc_pgp_rand_seed(
|
|
context,
|
|
(*random_data_mmap).str_0 as *const libc::c_void,
|
|
(*random_data_mmap).len,
|
|
);
|
|
mmap_string_free(random_data_mmap);
|
|
current_block = 26972500619410423;
|
|
}
|
|
} else {
|
|
current_block = 26972500619410423;
|
|
}
|
|
match current_block {
|
|
10496152961502316708 => {}
|
|
_ => {
|
|
let mut private_key: *mut dc_key_t = dc_key_new();
|
|
let mut start: libc::clock_t = clock();
|
|
dc_log_info(
|
|
context,
|
|
0i32,
|
|
b"Generating keypair with %i bits, e=%i ...\x00" as *const u8
|
|
as *const libc::c_char,
|
|
2048i32,
|
|
65537i32,
|
|
);
|
|
key_created =
|
|
dc_pgp_create_keypair(context, self_addr, public_key, private_key);
|
|
if 0 == key_created {
|
|
dc_log_warning(
|
|
context,
|
|
0i32,
|
|
b"Cannot create keypair.\x00" as *const u8 as *const libc::c_char,
|
|
);
|
|
current_block = 10496152961502316708;
|
|
} else if 0 == dc_pgp_is_valid_key(context, public_key)
|
|
|| 0 == dc_pgp_is_valid_key(context, private_key)
|
|
{
|
|
dc_log_warning(
|
|
context,
|
|
0i32,
|
|
b"Generated keys are not valid.\x00" as *const u8
|
|
as *const libc::c_char,
|
|
);
|
|
current_block = 10496152961502316708;
|
|
} else if 0
|
|
== dc_key_save_self_keypair(
|
|
public_key,
|
|
private_key,
|
|
self_addr,
|
|
1i32,
|
|
(*context).sql,
|
|
)
|
|
{
|
|
/*set default*/
|
|
dc_log_warning(
|
|
context,
|
|
0i32,
|
|
b"Cannot save keypair.\x00" as *const u8 as *const libc::c_char,
|
|
);
|
|
current_block = 10496152961502316708;
|
|
} else {
|
|
dc_log_info(
|
|
context,
|
|
0i32,
|
|
b"Keypair generated in %.3f s.\x00" as *const u8
|
|
as *const libc::c_char,
|
|
clock().wrapping_sub(start) as libc::c_double
|
|
/ 1000000i32 as libc::c_double,
|
|
);
|
|
dc_key_unref(private_key);
|
|
current_block = 1118134448028020070;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
current_block = 1118134448028020070;
|
|
}
|
|
match current_block {
|
|
10496152961502316708 => {}
|
|
_ => success = 1i32,
|
|
}
|
|
}
|
|
if 0 != key_creation_here {
|
|
s_in_key_creation = 0i32
|
|
}
|
|
return success;
|
|
}
|
|
/* returns 1 if sth. was decrypted, 0 in other cases */
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn dc_e2ee_decrypt(
|
|
mut context: *mut dc_context_t,
|
|
mut in_out_message: *mut mailmime,
|
|
mut helper: *mut dc_e2ee_helper_t,
|
|
) {
|
|
let mut iterations: libc::c_int = 0;
|
|
/* 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 mut imffields: *mut mailimf_fields = mailmime_find_mailimf_fields(in_out_message);
|
|
let mut autocryptheader: *mut dc_aheader_t = 0 as *mut dc_aheader_t;
|
|
let mut message_time: time_t = 0i32 as time_t;
|
|
let mut peerstate: *mut dc_apeerstate_t = dc_apeerstate_new(context);
|
|
let mut from: *mut libc::c_char = 0 as *mut libc::c_char;
|
|
let mut self_addr: *mut libc::c_char = 0 as *mut libc::c_char;
|
|
let mut private_keyring: *mut dc_keyring_t = dc_keyring_new();
|
|
let mut public_keyring_for_validate: *mut dc_keyring_t = dc_keyring_new();
|
|
let mut gossip_headers: *mut mailimf_fields = 0 as *mut mailimf_fields;
|
|
if !helper.is_null() {
|
|
memset(
|
|
helper as *mut libc::c_void,
|
|
0i32,
|
|
::std::mem::size_of::<dc_e2ee_helper_t>() as libc::c_ulong,
|
|
);
|
|
}
|
|
if !(context.is_null()
|
|
|| (*context).magic != 0x11a11807i32 as libc::c_uint
|
|
|| in_out_message.is_null()
|
|
|| helper.is_null()
|
|
|| imffields.is_null())
|
|
{
|
|
if !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 mut 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 != -1i32 as libc::c_long
|
|
&& message_time > time(0 as *mut time_t)
|
|
{
|
|
message_time = time(0 as *mut time_t)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
autocryptheader = dc_aheader_new_from_imffields(from, imffields);
|
|
if !autocryptheader.is_null() {
|
|
if 0 == dc_pgp_is_valid_key(context, (*autocryptheader).public_key) {
|
|
dc_aheader_unref(autocryptheader);
|
|
autocryptheader = 0 as *mut dc_aheader_t
|
|
}
|
|
}
|
|
if message_time > 0i32 as libc::c_long && !from.is_null() {
|
|
if 0 != dc_apeerstate_load_by_addr(peerstate, (*context).sql, from) {
|
|
if !autocryptheader.is_null() {
|
|
dc_apeerstate_apply_header(peerstate, autocryptheader, message_time);
|
|
dc_apeerstate_save_to_db(peerstate, (*context).sql, 0i32);
|
|
} else if message_time > (*peerstate).last_seen_autocrypt
|
|
&& 0 == contains_report(in_out_message)
|
|
{
|
|
dc_apeerstate_degrade_encryption(peerstate, message_time);
|
|
dc_apeerstate_save_to_db(peerstate, (*context).sql, 0i32);
|
|
}
|
|
} else if !autocryptheader.is_null() {
|
|
dc_apeerstate_init_from_header(peerstate, autocryptheader, message_time);
|
|
dc_apeerstate_save_to_db(peerstate, (*context).sql, 1i32);
|
|
}
|
|
}
|
|
/* load private key for decryption */
|
|
self_addr = dc_sqlite3_get_config(
|
|
(*context).sql,
|
|
b"configured_addr\x00" as *const u8 as *const libc::c_char,
|
|
0 as *const libc::c_char,
|
|
);
|
|
if !self_addr.is_null() {
|
|
if !(0
|
|
== dc_keyring_load_self_private_for_decrypting(
|
|
private_keyring,
|
|
self_addr,
|
|
(*context).sql,
|
|
))
|
|
{
|
|
if (*peerstate).last_seen == 0i32 as libc::c_long {
|
|
dc_apeerstate_load_by_addr(peerstate, (*context).sql, from);
|
|
}
|
|
if 0 != (*peerstate).degrade_event {
|
|
dc_handle_degrade_event(context, peerstate);
|
|
}
|
|
dc_keyring_add(public_keyring_for_validate, (*peerstate).gossip_key);
|
|
dc_keyring_add(public_keyring_for_validate, (*peerstate).public_key);
|
|
(*helper).signatures =
|
|
malloc(::std::mem::size_of::<dc_hash_t>() as libc::c_ulong) as *mut dc_hash_t;
|
|
dc_hash_init((*helper).signatures, 3i32, 1i32);
|
|
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,
|
|
(*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);
|
|
}
|
|
dc_aheader_unref(autocryptheader);
|
|
dc_apeerstate_unref(peerstate);
|
|
dc_keyring_unref(private_keyring);
|
|
dc_keyring_unref(public_keyring_for_validate);
|
|
free(from as *mut libc::c_void);
|
|
free(self_addr as *mut libc::c_void);
|
|
}
|
|
unsafe extern "C" fn update_gossip_peerstates(
|
|
mut context: *mut dc_context_t,
|
|
mut message_time: time_t,
|
|
mut imffields: *mut mailimf_fields,
|
|
mut gossip_headers: *const mailimf_fields,
|
|
) -> *mut dc_hash_t {
|
|
let mut cur1: *mut clistiter = 0 as *mut clistiter;
|
|
let mut recipients: *mut dc_hash_t = 0 as *mut dc_hash_t;
|
|
let mut gossipped_addr: *mut dc_hash_t = 0 as *mut dc_hash_t;
|
|
cur1 = (*(*gossip_headers).fld_list).first;
|
|
while !cur1.is_null() {
|
|
let mut field: *mut mailimf_field = (if !cur1.is_null() {
|
|
(*cur1).data
|
|
} else {
|
|
0 as *mut libc::c_void
|
|
}) as *mut mailimf_field;
|
|
if (*field).fld_type == MAILIMF_FIELD_OPTIONAL_FIELD as libc::c_int {
|
|
let mut optional_field: *const mailimf_optional_field =
|
|
(*field).fld_data.fld_optional_field;
|
|
if !optional_field.is_null()
|
|
&& !(*optional_field).fld_name.is_null()
|
|
&& strcasecmp(
|
|
(*optional_field).fld_name,
|
|
b"Autocrypt-Gossip\x00" as *const u8 as *const libc::c_char,
|
|
) == 0i32
|
|
{
|
|
let mut gossip_header: *mut dc_aheader_t = dc_aheader_new();
|
|
if 0 != dc_aheader_set_from_string(gossip_header, (*optional_field).fld_value)
|
|
&& 0 != dc_pgp_is_valid_key(context, (*gossip_header).public_key)
|
|
{
|
|
if recipients.is_null() {
|
|
recipients = mailimf_get_recipients(imffields)
|
|
}
|
|
if !dc_hash_find(
|
|
recipients,
|
|
(*gossip_header).addr as *const libc::c_void,
|
|
strlen((*gossip_header).addr) as libc::c_int,
|
|
)
|
|
.is_null()
|
|
{
|
|
let mut peerstate: *mut dc_apeerstate_t = dc_apeerstate_new(context);
|
|
if 0 == dc_apeerstate_load_by_addr(
|
|
peerstate,
|
|
(*context).sql,
|
|
(*gossip_header).addr,
|
|
) {
|
|
dc_apeerstate_init_from_gossip(peerstate, gossip_header, message_time);
|
|
dc_apeerstate_save_to_db(peerstate, (*context).sql, 1i32);
|
|
} else {
|
|
dc_apeerstate_apply_gossip(peerstate, gossip_header, message_time);
|
|
dc_apeerstate_save_to_db(peerstate, (*context).sql, 0i32);
|
|
}
|
|
if 0 != (*peerstate).degrade_event {
|
|
dc_handle_degrade_event(context, peerstate);
|
|
}
|
|
dc_apeerstate_unref(peerstate);
|
|
if gossipped_addr.is_null() {
|
|
gossipped_addr =
|
|
malloc(::std::mem::size_of::<dc_hash_t>() as libc::c_ulong)
|
|
as *mut dc_hash_t;
|
|
dc_hash_init(gossipped_addr, 3i32, 1i32);
|
|
}
|
|
dc_hash_insert(
|
|
gossipped_addr,
|
|
(*gossip_header).addr as *const libc::c_void,
|
|
strlen((*gossip_header).addr) as libc::c_int,
|
|
1i32 as *mut libc::c_void,
|
|
);
|
|
} else {
|
|
dc_log_info(
|
|
context,
|
|
0i32,
|
|
b"Ignoring gossipped \"%s\" as the address is not in To/Cc list.\x00"
|
|
as *const u8 as *const libc::c_char,
|
|
(*gossip_header).addr,
|
|
);
|
|
}
|
|
}
|
|
dc_aheader_unref(gossip_header);
|
|
}
|
|
}
|
|
cur1 = if !cur1.is_null() {
|
|
(*cur1).next
|
|
} else {
|
|
0 as *mut clistcell_s
|
|
}
|
|
}
|
|
if !recipients.is_null() {
|
|
dc_hash_clear(recipients);
|
|
free(recipients as *mut libc::c_void);
|
|
}
|
|
return gossipped_addr;
|
|
}
|
|
unsafe extern "C" fn decrypt_recursive(
|
|
mut context: *mut dc_context_t,
|
|
mut mime: *mut mailmime,
|
|
mut private_keyring: *const dc_keyring_t,
|
|
mut public_keyring_for_validate: *const dc_keyring_t,
|
|
mut ret_valid_signatures: *mut dc_hash_t,
|
|
mut ret_gossip_headers: *mut *mut mailimf_fields,
|
|
mut ret_has_unencrypted_parts: *mut libc::c_int,
|
|
) -> libc::c_int {
|
|
let mut ct: *mut mailmime_content = 0 as *mut mailmime_content;
|
|
let mut cur: *mut clistiter = 0 as *mut clistiter;
|
|
if context.is_null() || mime.is_null() {
|
|
return 0i32;
|
|
}
|
|
if (*mime).mm_type == MAILMIME_MULTIPLE as libc::c_int {
|
|
ct = (*mime).mm_content_type;
|
|
if !ct.is_null()
|
|
&& !(*ct).ct_subtype.is_null()
|
|
&& strcmp(
|
|
(*ct).ct_subtype,
|
|
b"encrypted\x00" as *const u8 as *const libc::c_char,
|
|
) == 0i32
|
|
{
|
|
cur = (*(*mime).mm_data.mm_multipart.mm_mp_list).first;
|
|
while !cur.is_null() {
|
|
let mut decrypted_mime: *mut mailmime = 0 as *mut mailmime;
|
|
if 0 != decrypt_part(
|
|
context,
|
|
(if !cur.is_null() {
|
|
(*cur).data
|
|
} else {
|
|
0 as *mut libc::c_void
|
|
}) as *mut mailmime,
|
|
private_keyring,
|
|
public_keyring_for_validate,
|
|
ret_valid_signatures,
|
|
&mut decrypted_mime,
|
|
) {
|
|
if (*ret_gossip_headers).is_null() && (*ret_valid_signatures).count > 0i32 {
|
|
let mut dummy: size_t = 0i32 as size_t;
|
|
let mut test: *mut mailimf_fields = 0 as *mut mailimf_fields;
|
|
if mailimf_envelope_and_optional_fields_parse(
|
|
(*decrypted_mime).mm_mime_start,
|
|
(*decrypted_mime).mm_length,
|
|
&mut dummy,
|
|
&mut test,
|
|
) == MAILIMF_NO_ERROR as libc::c_int
|
|
&& !test.is_null()
|
|
{
|
|
*ret_gossip_headers = test
|
|
}
|
|
}
|
|
mailmime_substitute(mime, decrypted_mime);
|
|
mailmime_free(mime);
|
|
return 1i32;
|
|
}
|
|
cur = if !cur.is_null() {
|
|
(*cur).next
|
|
} else {
|
|
0 as *mut clistcell_s
|
|
}
|
|
}
|
|
*ret_has_unencrypted_parts = 1i32
|
|
} else {
|
|
cur = (*(*mime).mm_data.mm_multipart.mm_mp_list).first;
|
|
while !cur.is_null() {
|
|
if 0 != decrypt_recursive(
|
|
context,
|
|
(if !cur.is_null() {
|
|
(*cur).data
|
|
} else {
|
|
0 as *mut libc::c_void
|
|
}) as *mut mailmime,
|
|
private_keyring,
|
|
public_keyring_for_validate,
|
|
ret_valid_signatures,
|
|
ret_gossip_headers,
|
|
ret_has_unencrypted_parts,
|
|
) {
|
|
return 1i32;
|
|
}
|
|
cur = if !cur.is_null() {
|
|
(*cur).next
|
|
} else {
|
|
0 as *mut clistcell_s
|
|
}
|
|
}
|
|
}
|
|
} else if (*mime).mm_type == MAILMIME_MESSAGE as libc::c_int {
|
|
if 0 != decrypt_recursive(
|
|
context,
|
|
(*mime).mm_data.mm_message.mm_msg_mime,
|
|
private_keyring,
|
|
public_keyring_for_validate,
|
|
ret_valid_signatures,
|
|
ret_gossip_headers,
|
|
ret_has_unencrypted_parts,
|
|
) {
|
|
return 1i32;
|
|
}
|
|
} else {
|
|
*ret_has_unencrypted_parts = 1i32
|
|
}
|
|
return 0i32;
|
|
}
|
|
unsafe extern "C" fn decrypt_part(
|
|
mut context: *mut dc_context_t,
|
|
mut mime: *mut mailmime,
|
|
mut private_keyring: *const dc_keyring_t,
|
|
mut public_keyring_for_validate: *const dc_keyring_t,
|
|
mut ret_valid_signatures: *mut dc_hash_t,
|
|
mut ret_decrypted_mime: *mut *mut mailmime,
|
|
) -> libc::c_int {
|
|
let mut add_signatures: *mut dc_hash_t = 0 as *mut dc_hash_t;
|
|
let mut current_block: u64;
|
|
let mut mime_data: *mut mailmime_data = 0 as *mut mailmime_data;
|
|
let mut mime_transfer_encoding: libc::c_int = MAILMIME_MECHANISM_BINARY as libc::c_int;
|
|
/* mmap_string_unref()'d if set */
|
|
let mut transfer_decoding_buffer: *mut libc::c_char = 0 as *mut libc::c_char;
|
|
/* must not be free()'d */
|
|
let mut decoded_data: *const libc::c_char = 0 as *const libc::c_char;
|
|
let mut decoded_data_bytes: size_t = 0i32 as size_t;
|
|
let mut plain_buf: *mut libc::c_void = 0 as *mut libc::c_void;
|
|
let mut plain_bytes: size_t = 0i32 as size_t;
|
|
let mut sth_decrypted: libc::c_int = 0i32;
|
|
*ret_decrypted_mime = 0 as *mut mailmime;
|
|
mime_data = (*mime).mm_data.mm_single;
|
|
/* MAILMIME_DATA_FILE indicates, the data is in a file; AFAIK this is not used on parsing */
|
|
if !((*mime_data).dt_type != MAILMIME_DATA_TEXT as libc::c_int
|
|
|| (*mime_data).dt_data.dt_text.dt_data.is_null()
|
|
|| (*mime_data).dt_data.dt_text.dt_length <= 0i32 as libc::c_ulong)
|
|
{
|
|
if !(*mime).mm_mime_fields.is_null() {
|
|
let mut cur: *mut clistiter = 0 as *mut clistiter;
|
|
cur = (*(*(*mime).mm_mime_fields).fld_list).first;
|
|
while !cur.is_null() {
|
|
let mut field: *mut mailmime_field = (if !cur.is_null() {
|
|
(*cur).data
|
|
} else {
|
|
0 as *mut libc::c_void
|
|
}) as *mut mailmime_field;
|
|
if !field.is_null() {
|
|
if (*field).fld_type == MAILMIME_FIELD_TRANSFER_ENCODING as libc::c_int
|
|
&& !(*field).fld_data.fld_encoding.is_null()
|
|
{
|
|
mime_transfer_encoding = (*(*field).fld_data.fld_encoding).enc_type
|
|
}
|
|
}
|
|
cur = if !cur.is_null() {
|
|
(*cur).next
|
|
} else {
|
|
0 as *mut clistcell_s
|
|
}
|
|
}
|
|
}
|
|
/* regard `Content-Transfer-Encoding:` */
|
|
if mime_transfer_encoding == MAILMIME_MECHANISM_7BIT as libc::c_int
|
|
|| mime_transfer_encoding == MAILMIME_MECHANISM_8BIT as libc::c_int
|
|
|| mime_transfer_encoding == MAILMIME_MECHANISM_BINARY as libc::c_int
|
|
{
|
|
decoded_data = (*mime_data).dt_data.dt_text.dt_data;
|
|
decoded_data_bytes = (*mime_data).dt_data.dt_text.dt_length;
|
|
if decoded_data.is_null() || decoded_data_bytes <= 0i32 as libc::c_ulong {
|
|
/* no error - but no data */
|
|
current_block = 2554982661806928548;
|
|
} else {
|
|
current_block = 4488286894823169796;
|
|
}
|
|
} else {
|
|
let mut r: libc::c_int = 0;
|
|
let mut current_index: size_t = 0i32 as size_t;
|
|
r = mailmime_part_parse(
|
|
(*mime_data).dt_data.dt_text.dt_data,
|
|
(*mime_data).dt_data.dt_text.dt_length,
|
|
&mut current_index,
|
|
mime_transfer_encoding,
|
|
&mut transfer_decoding_buffer,
|
|
&mut decoded_data_bytes,
|
|
);
|
|
if r != MAILIMF_NO_ERROR as libc::c_int
|
|
|| transfer_decoding_buffer.is_null()
|
|
|| decoded_data_bytes <= 0i32 as libc::c_ulong
|
|
{
|
|
current_block = 2554982661806928548;
|
|
} else {
|
|
decoded_data = transfer_decoding_buffer;
|
|
current_block = 4488286894823169796;
|
|
}
|
|
}
|
|
match current_block {
|
|
2554982661806928548 => {}
|
|
_ => {
|
|
/* encrypted, decoded data in decoded_data now ... */
|
|
if !(0 == has_decrypted_pgp_armor(decoded_data, decoded_data_bytes as libc::c_int))
|
|
{
|
|
add_signatures = if (*ret_valid_signatures).count <= 0i32 {
|
|
ret_valid_signatures
|
|
} else {
|
|
0 as *mut dc_hash_t
|
|
};
|
|
/*if we already have fingerprints, do not add more; this ensures, only the fingerprints from the outer-most part are collected */
|
|
if !(0
|
|
== dc_pgp_pk_decrypt(
|
|
context,
|
|
decoded_data as *const libc::c_void,
|
|
decoded_data_bytes,
|
|
private_keyring,
|
|
public_keyring_for_validate,
|
|
1i32,
|
|
&mut plain_buf,
|
|
&mut plain_bytes,
|
|
add_signatures,
|
|
)
|
|
|| plain_buf.is_null()
|
|
|| plain_bytes <= 0i32 as libc::c_ulong)
|
|
{
|
|
//{char* t1=dc_null_terminate(plain_buf,plain_bytes);printf("\n**********\n%s\n**********\n",t1);free(t1);}
|
|
let mut index: size_t = 0i32 as size_t;
|
|
let mut decrypted_mime: *mut mailmime = 0 as *mut mailmime;
|
|
if mailmime_parse(
|
|
plain_buf as *const libc::c_char,
|
|
plain_bytes,
|
|
&mut index,
|
|
&mut decrypted_mime,
|
|
) != MAIL_NO_ERROR as libc::c_int
|
|
|| decrypted_mime.is_null()
|
|
{
|
|
if !decrypted_mime.is_null() {
|
|
mailmime_free(decrypted_mime);
|
|
}
|
|
} else {
|
|
*ret_decrypted_mime = decrypted_mime;
|
|
sth_decrypted = 1i32
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
//mailmime_substitute(mime, new_mime);
|
|
//s. mailprivacy_gnupg.c::pgp_decrypt()
|
|
if !transfer_decoding_buffer.is_null() {
|
|
mmap_string_unref(transfer_decoding_buffer);
|
|
}
|
|
return sth_decrypted;
|
|
}
|
|
/* ******************************************************************************
|
|
* Decrypt
|
|
******************************************************************************/
|
|
unsafe extern "C" fn has_decrypted_pgp_armor(
|
|
mut str__: *const libc::c_char,
|
|
mut str_bytes: libc::c_int,
|
|
) -> libc::c_int {
|
|
let mut 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 {
|
|
if *p as libc::c_int > ' ' as i32 {
|
|
break;
|
|
}
|
|
p = p.offset(1isize);
|
|
str_bytes -= 1
|
|
}
|
|
if str_bytes > 27i32
|
|
&& strncmp(
|
|
p as *const libc::c_char,
|
|
b"-----BEGIN PGP MESSAGE-----\x00" as *const u8 as *const libc::c_char,
|
|
27i32 as libc::c_ulong,
|
|
) == 0i32
|
|
{
|
|
return 1i32;
|
|
}
|
|
return 0i32;
|
|
}
|
|
/* *
|
|
* 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 struture to check
|
|
* @return 1=multipart/report found in MIME, 0=no multipart/report found
|
|
*/
|
|
unsafe extern "C" fn contains_report(mut mime: *mut mailmime) -> libc::c_int {
|
|
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
|
|
&& (*(*(*(*mime).mm_content_type).ct_type)
|
|
.tp_data
|
|
.tp_composite_type)
|
|
.ct_type
|
|
== MAILMIME_COMPOSITE_TYPE_MULTIPART as libc::c_int
|
|
&& strcmp(
|
|
(*(*mime).mm_content_type).ct_subtype,
|
|
b"report\x00" as *const u8 as *const libc::c_char,
|
|
) == 0i32
|
|
{
|
|
return 1i32;
|
|
}
|
|
let mut cur: *mut clistiter = 0 as *mut clistiter;
|
|
cur = (*(*mime).mm_data.mm_multipart.mm_mp_list).first;
|
|
while !cur.is_null() {
|
|
if 0 != contains_report(
|
|
(if !cur.is_null() {
|
|
(*cur).data
|
|
} else {
|
|
0 as *mut libc::c_void
|
|
}) as *mut mailmime,
|
|
) {
|
|
return 1i32;
|
|
}
|
|
cur = if !cur.is_null() {
|
|
(*cur).next
|
|
} else {
|
|
0 as *mut clistcell_s
|
|
}
|
|
}
|
|
} 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;
|
|
}
|
|
}
|
|
return 0i32;
|
|
}
|
|
/* frees data referenced by "mailmime" but not freed by mailmime_free(). After calling this function, in_out_message cannot be used any longer! */
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn dc_e2ee_thanks(mut helper: *mut dc_e2ee_helper_t) {
|
|
if helper.is_null() {
|
|
return;
|
|
}
|
|
free((*helper).cdata_to_free);
|
|
(*helper).cdata_to_free = 0 as *mut libc::c_void;
|
|
if !(*helper).gossipped_addr.is_null() {
|
|
dc_hash_clear((*helper).gossipped_addr);
|
|
free((*helper).gossipped_addr as *mut libc::c_void);
|
|
(*helper).gossipped_addr = 0 as *mut dc_hash_t
|
|
}
|
|
if !(*helper).signatures.is_null() {
|
|
dc_hash_clear((*helper).signatures);
|
|
free((*helper).signatures as *mut libc::c_void);
|
|
(*helper).signatures = 0 as *mut dc_hash_t
|
|
};
|
|
}
|
|
/* makes sure, the private key exists, needed only for exporting keys and the case no message was sent before */
|
|
#[no_mangle]
|
|
pub unsafe extern "C" fn dc_ensure_secret_key_exists(
|
|
mut context: *mut dc_context_t,
|
|
) -> libc::c_int {
|
|
/* normally, the key is generated as soon as the first mail is send
|
|
(this is to gain some extra-random-seed by the message content and the timespan between program start and message sending) */
|
|
let mut success: libc::c_int = 0i32;
|
|
let mut public_key: *mut dc_key_t = dc_key_new();
|
|
let mut self_addr: *mut libc::c_char = 0 as *mut libc::c_char;
|
|
if !(context.is_null()
|
|
|| (*context).magic != 0x11a11807i32 as libc::c_uint
|
|
|| public_key.is_null())
|
|
{
|
|
self_addr = dc_sqlite3_get_config(
|
|
(*context).sql,
|
|
b"configured_addr\x00" as *const u8 as *const libc::c_char,
|
|
0 as *const libc::c_char,
|
|
);
|
|
if self_addr.is_null() {
|
|
dc_log_warning(
|
|
context,
|
|
0i32,
|
|
b"Cannot ensure secret key if context is not configured.\x00" as *const u8
|
|
as *const libc::c_char,
|
|
);
|
|
} else if !(0
|
|
== load_or_generate_self_public_key(context, public_key, self_addr, 0 as *mut mailmime))
|
|
{
|
|
/*no random text data for seeding available*/
|
|
success = 1i32
|
|
}
|
|
}
|
|
dc_key_unref(public_key);
|
|
free(self_addr as *mut libc::c_void);
|
|
return success;
|
|
}
|