Compare commits

...

9 Commits

Author SHA1 Message Date
holger krekel
829a7b5c72 address three comments from @dignifiedquire 2019-09-22 22:06:25 +02:00
holger krekel
1e80cfc72f rustify references, in_reply_to, mimefactory's recipients_{addr,names} 2019-09-22 13:02:27 +02:00
holger krekel
695ba44a6c rustify parts of MimeFactory struct 2019-09-22 03:37:38 +02:00
holger krekel
aa5cab9ae7 more rustifications 2019-09-22 02:59:02 +02:00
holger krekel
cea931dcc7 streamline mimetype guessing and build_body_file 2019-09-22 00:11:56 +02:00
holger krekel
cace6fee85 better looping on some clists 2019-09-21 20:45:53 +02:00
holger krekel
d3dfe02ef1 - add mailimf_field_add helper to reduce number of strdup()s
- make build_body_text avoid char*
2019-09-21 20:41:35 +02:00
holger krekel
a134ace787 dc_mimefactory+friends: simplify used strings, convert message_text and message_text2 to String, convert ints to bools 2019-09-21 20:41:31 +02:00
holger krekel
1812b55b20 e2ee_guaranteed -> bool, rustify set_error 2019-09-21 18:18:37 +02:00
10 changed files with 693 additions and 1255 deletions

View File

@@ -118,17 +118,14 @@ fn dc_poke_eml_file(context: &Context, filename: impl AsRef<Path>) -> Result<(),
/// @param context The context as created by dc_context_new().
/// @param spec The file or directory to import. NULL for the last command.
/// @return 1=success, 0=error.
unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int {
fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int {
if !context.sql.is_open() {
error!(context, "Import: Database not opened.");
return 0;
}
let ok_to_continue;
let mut success: libc::c_int = 0;
let real_spec: String;
let mut suffix: *mut libc::c_char = ptr::null_mut();
let mut read_cnt: libc::c_int = 0;
let mut read_cnt = 0;
/* if `spec` is given, remember it for later usage; if it is not given, try to use the last one */
if !spec.is_null() {
@@ -137,71 +134,57 @@ unsafe fn poke_spec(context: &Context, spec: *const libc::c_char) -> libc::c_int
.sql
.set_config(context, "import_spec", Some(&real_spec))
.unwrap();
ok_to_continue = true;
} else {
let rs = context.sql.get_config(context, "import_spec");
if rs.is_none() {
error!(context, "Import: No file or folder given.");
ok_to_continue = false;
} else {
ok_to_continue = true;
return 0;
}
real_spec = rs.unwrap_or_default();
real_spec = rs.unwrap();
}
if ok_to_continue {
let ok_to_continue2;
suffix = dc_get_filesuffix_lc(&real_spec);
if !suffix.is_null()
&& libc::strcmp(suffix, b"eml\x00" as *const u8 as *const libc::c_char) == 0
{
if let Some(suffix) = dc_get_filesuffix_lc(&real_spec) {
if suffix == "eml" {
if dc_poke_eml_file(context, &real_spec).is_ok() {
read_cnt += 1
}
ok_to_continue2 = true;
}
} else {
/* import a directory */
let dir_name = std::path::Path::new(&real_spec);
let dir = std::fs::read_dir(dir_name);
if dir.is_err() {
error!(context, "Import: Cannot open directory \"{}\".", &real_spec,);
return 0;
} else {
/* import a directory */
let dir_name = std::path::Path::new(&real_spec);
let dir = std::fs::read_dir(dir_name);
if dir.is_err() {
error!(context, "Import: Cannot open directory \"{}\".", &real_spec,);
ok_to_continue2 = false;
} else {
let dir = dir.unwrap();
for entry in dir {
if entry.is_err() {
break;
}
let entry = entry.unwrap();
let name_f = entry.file_name();
let name = name_f.to_string_lossy();
if name.ends_with(".eml") {
let path_plus_name = format!("{}/{}", &real_spec, name);
info!(context, "Import: {}", path_plus_name);
if dc_poke_eml_file(context, path_plus_name).is_ok() {
read_cnt += 1
}
let dir = dir.unwrap();
for entry in dir {
if entry.is_err() {
break;
}
let entry = entry.unwrap();
let name_f = entry.file_name();
let name = name_f.to_string_lossy();
if name.ends_with(".eml") {
let path_plus_name = format!("{}/{}", &real_spec, name);
info!(context, "Import: {}", path_plus_name);
if dc_poke_eml_file(context, path_plus_name).is_ok() {
read_cnt += 1
}
}
ok_to_continue2 = true;
}
}
if ok_to_continue2 {
info!(
context,
"Import: {} items read from \"{}\".", read_cnt, &real_spec
);
if read_cnt > 0 {
context.call_cb(Event::MsgsChanged {
chat_id: 0,
msg_id: 0,
});
}
success = 1
}
}
free(suffix as *mut libc::c_void);
success
info!(
context,
"Import: {} items read from \"{}\".", read_cnt, &real_spec
);
if read_cnt > 0 {
context.call_cb(Event::MsgsChanged {
chat_id: 0,
msg_id: 0,
});
}
1
}
unsafe fn log_msg(context: &Context, prefix: impl AsRef<str>, msg: &Message) {

View File

@@ -784,7 +784,7 @@ pub fn send_msg(context: &Context, chat_id: u32, msg: &mut Message) -> Result<u3
}
ensure!(
unsafe { job_send_msg(context, msg.id) } != 0,
job_send_msg(context, msg.id) != 0,
"Failed to initiate send job"
);
@@ -1787,7 +1787,7 @@ pub fn forward_msgs(context: &Context, msg_ids: &[u32], chat_id: u32) {
new_msg_id = chat
.prepare_msg_raw(context, &mut msg, fresh10)
.unwrap_or_default();
unsafe { job_send_msg(context, new_msg_id) };
job_send_msg(context, new_msg_id);
}
created_db_entries.push(chat_id);
created_db_entries.push(new_msg_id);

View File

@@ -60,6 +60,10 @@ const DC_GCM_ADDDAYMARKER: usize = 0x01;
pub const DC_GCL_VERIFIED_ONLY: usize = 0x01;
pub const DC_GCL_ADD_SELF: usize = 0x02;
// values for DC_PARAM_FORCE_PLAINTEXT
pub(crate) const DC_FP_NO_AUTOCRYPT_HEADER: i32 = 2;
pub(crate) const DC_FP_ADD_AUTOCRYPT_HEADER: i32 = 1;
/// param1 is a directory where the keys are written to
const DC_IMEX_EXPORT_SELF_KEYS: usize = 1;
/// param1 is a directory where the keys are searched in and read from

View File

@@ -135,7 +135,8 @@ pub unsafe fn dc_initiate_key_transfer(context: &Context) -> *mut libc::c_char {
msg.param
.set(Param::MimeType, "application/autocrypt-setup");
msg.param.set_int(Param::Cmd, 6);
msg.param.set_int(Param::ForcePlaintext, 2);
msg.param
.set_int(Param::ForcePlaintext, DC_FP_NO_AUTOCRYPT_HEADER);
if !context
.running_state
@@ -843,7 +844,6 @@ unsafe fn import_self_keys(context: &Context, dir_name: *const libc::c_char) ->
Maybe we should make the "default" key handlong also a little bit smarter
(currently, the last imported key is the standard key unless it contains the string "legacy" in its name) */
let mut imported_cnt: libc::c_int = 0;
let mut suffix: *mut libc::c_char = ptr::null_mut();
let mut set_default: libc::c_int;
let mut buf: *mut libc::c_char = ptr::null_mut();
// a pointer inside buf, MUST NOT be free()'d
@@ -858,17 +858,20 @@ unsafe fn import_self_keys(context: &Context, dir_name: *const libc::c_char) ->
if entry.is_err() {
break;
}
let entry = entry.unwrap();
free(suffix as *mut libc::c_void);
let name_f = entry.file_name();
let name_c = name_f.to_c_string().unwrap();
suffix = dc_get_filesuffix_lc(name_f.to_string_lossy());
if suffix.is_null()
|| strcmp(suffix, b"asc\x00" as *const u8 as *const libc::c_char) != 0
{
continue;
let entry_fn = entry.unwrap().file_name();
let name_f = entry_fn.to_string_lossy();
match dc_get_filesuffix_lc(&name_f) {
Some(suffix) => {
if suffix != ".asc" {
continue;
}
}
None => {
continue;
}
}
let path_plus_name = dir.join(entry.file_name());
let path_plus_name = dir.join(&entry_fn);
info!(context, "Checking: {}", path_plus_name.display());
free(buf.cast());
@@ -906,12 +909,7 @@ unsafe fn import_self_keys(context: &Context, dir_name: *const libc::c_char) ->
}
}
set_default = 1;
if !strstr(
name_c.as_ptr(),
b"legacy\x00" as *const u8 as *const libc::c_char,
)
.is_null()
{
if name_f.contains("legacy") {
info!(
context,
"Treating \"{}\" as a legacy private key.",
@@ -940,7 +938,6 @@ unsafe fn import_self_keys(context: &Context, dir_name: *const libc::c_char) ->
}
}
free(suffix as *mut libc::c_void);
free(buf as *mut libc::c_void);
free(buf2 as *mut libc::c_void);

File diff suppressed because it is too large Load Diff

View File

@@ -25,7 +25,7 @@ use crate::dc_tools::*;
* @return Returns the encoded string which must be free()'d when no longed needed.
* On errors, NULL is returned.
*/
pub unsafe fn dc_encode_header_words(to_encode_r: impl AsRef<str>) -> *mut libc::c_char {
pub unsafe fn dc_encode_header_words(to_encode_r: impl AsRef<str>) -> String {
let to_encode =
CString::new(to_encode_r.as_ref().as_bytes()).expect("invalid cstring to_encode");
@@ -117,7 +117,9 @@ pub unsafe fn dc_encode_header_words(to_encode_r: impl AsRef<str>) -> *mut libc:
}
}
ret_str
let s = to_string(ret_str);
free(ret_str.cast());
s
}
unsafe fn quote_word(
@@ -337,7 +339,7 @@ unsafe fn print_hex(target: *mut libc::c_char, cur: *const libc::c_char) {
mod tests {
use super::*;
use libc::{strcmp, strncmp};
use libc::strcmp;
use std::ffi::CStr;
#[test]
@@ -360,19 +362,15 @@ mod tests {
assert_eq!(CStr::from_ptr(buf1).to_str().unwrap(), "just ascii test");
free(buf1 as *mut libc::c_void);
buf1 = dc_encode_header_words("abcdef");
assert_eq!(CStr::from_ptr(buf1).to_str().unwrap(), "abcdef");
free(buf1 as *mut libc::c_void);
assert_eq!(dc_encode_header_words("abcdef"), "abcdef");
buf1 = dc_encode_header_words(
let r = dc_encode_header_words(
std::string::String::from_utf8(b"test\xc3\xa4\xc3\xb6\xc3\xbc.txt".to_vec())
.unwrap(),
);
assert_eq!(
strncmp(buf1, b"=?utf-8\x00" as *const u8 as *const libc::c_char, 7),
0
);
assert!(r.starts_with("=?utf-8"));
buf1 = r.strdup();
let buf2: *mut libc::c_char = dc_decode_header_words(buf1);
assert_eq!(
strcmp(
@@ -381,7 +379,6 @@ mod tests {
),
0
);
free(buf1 as *mut libc::c_void);
free(buf2 as *mut libc::c_void);
buf1 = dc_decode_header_words(
@@ -395,7 +392,6 @@ mod tests {
),
0
);
free(buf1 as *mut libc::c_void);
}
}

View File

@@ -9,7 +9,7 @@ use std::time::SystemTime;
use std::{fmt, fs, ptr};
use chrono::{Local, TimeZone};
use libc::{free, memcpy, strcpy, strlen, strstr, uintptr_t};
use libc::{memcpy, strcpy, strlen, uintptr_t};
use mmime::clist::*;
use mmime::mailimf_types::*;
use rand::{thread_rng, Rng};
@@ -49,15 +49,6 @@ pub unsafe fn dc_strdup(s: *const libc::c_char) -> *mut libc::c_char {
ret
}
/// Duplicates a string, returns null if given string is null
pub(crate) unsafe fn dc_strdup_keep_null(s: *const libc::c_char) -> *mut libc::c_char {
if !s.is_null() {
dc_strdup(s)
} else {
ptr::null_mut()
}
}
pub(crate) fn dc_atoi_null_is_0(s: *const libc::c_char) -> libc::c_int {
if !s.is_null() {
as_str(s).parse().unwrap_or_default()
@@ -250,32 +241,14 @@ pub(crate) unsafe fn dc_str_from_clist(
res.strdup()
}
pub(crate) unsafe fn dc_str_to_clist(
str: *const libc::c_char,
delimiter: *const libc::c_char,
) -> *mut clist {
let list: *mut clist = clist_new();
assert!(!list.is_null());
if !str.is_null() && !delimiter.is_null() && strlen(delimiter) >= 1 {
let mut p1: *const libc::c_char = str;
loop {
let p2: *const libc::c_char = strstr(p1, delimiter);
if p2.is_null() {
clist_insert_after(list, (*list).last, strdup(p1) as *mut libc::c_void);
break;
} else {
clist_insert_after(
list,
(*list).last,
strndup(p1, p2.wrapping_offset_from(p1) as libc::c_ulong) as *mut libc::c_void,
);
p1 = p2.add(strlen(delimiter))
}
pub(crate) fn dc_str_to_clist(str: &str, delimiter: &str) -> *mut clist {
unsafe {
let list: *mut clist = clist_new();
for cur in str.split(&delimiter) {
clist_insert_after(list, (*list).last, cur.strdup().cast());
}
list
}
list
}
/* the colors must fulfill some criterions as:
@@ -302,32 +275,6 @@ pub(crate) fn dc_str_to_color(s: impl AsRef<str>) -> u32 {
COLORS[color_index]
}
/* clist tools */
/* calls free() for each item content */
pub(crate) unsafe fn clist_free_content(haystack: *const clist) {
let mut iter = (*haystack).first;
while !iter.is_null() {
free((*iter).data);
(*iter).data = ptr::null_mut();
iter = if !iter.is_null() {
(*iter).next
} else {
ptr::null_mut()
}
}
}
pub(crate) unsafe fn clist_search_string_nocase(
haystack: *const clist,
needle: *const libc::c_char,
) -> bool {
(&*haystack)
.into_iter()
.any(|data| strcasecmp(data.cast(), needle) == 0)
}
/* date/time tools */
/* the result is UTC or DC_INVALID_TIMESTAMP */
pub(crate) unsafe fn dc_timestamp_from_date(date_time: *mut mailimf_date_time) -> i64 {
@@ -505,25 +452,15 @@ pub(crate) fn dc_extract_grpid_from_rfc724_mid(mid: &str) -> Option<&str> {
None
}
pub(crate) unsafe fn dc_extract_grpid_from_rfc724_mid_list(
list: *const clist,
) -> *mut libc::c_char {
pub(crate) fn dc_extract_grpid_from_rfc724_mid_list(list: *const clist) -> *mut libc::c_char {
if !list.is_null() {
let mut cur: *mut clistiter = (*list).first;
while !cur.is_null() {
let mid = if !cur.is_null() {
as_str((*cur).data as *const libc::c_char)
} else {
""
};
unsafe {
for cur in (*list).into_iter() {
let mid = as_str(cur as *const libc::c_char);
if let Some(grpid) = dc_extract_grpid_from_rfc724_mid(mid) {
return grpid.strdup();
}
cur = if !cur.is_null() {
(*cur).next
} else {
ptr::null_mut()
if let Some(grpid) = dc_extract_grpid_from_rfc724_mid(mid) {
return grpid.strdup();
}
}
}
}
@@ -548,11 +485,11 @@ fn validate_filename(filename: &str) -> String {
// the returned suffix is lower-case
#[allow(non_snake_case)]
pub unsafe fn dc_get_filesuffix_lc(path_filename: impl AsRef<str>) -> *mut libc::c_char {
pub fn dc_get_filesuffix_lc(path_filename: impl AsRef<str>) -> Option<String> {
if let Some(p) = Path::new(path_filename.as_ref()).extension() {
p.to_string_lossy().to_lowercase().strdup()
Some(p.to_string_lossy().to_lowercase())
} else {
ptr::null_mut()
None
}
}
@@ -1091,21 +1028,6 @@ pub(crate) unsafe fn strdup(s: *const libc::c_char) -> *mut libc::c_char {
result as *mut _
}
pub(crate) fn strndup(s: *const libc::c_char, n: libc::c_ulong) -> *mut libc::c_char {
if s.is_null() {
return std::ptr::null_mut();
}
let end = std::cmp::min(n as usize, unsafe { strlen(s) });
unsafe {
let result = libc::malloc(end + 1);
memcpy(result, s as *const _, end);
std::ptr::write_bytes(result.offset(end as isize), b'\x00', 1);
result as *mut _
}
}
pub(crate) unsafe fn strcasecmp(s1: *const libc::c_char, s2: *const libc::c_char) -> libc::c_int {
let s1 = std::ffi::CStr::from_ptr(s1)
.to_string_lossy()
@@ -1124,7 +1046,7 @@ pub(crate) unsafe fn strcasecmp(s1: *const libc::c_char, s2: *const libc::c_char
mod tests {
use super::*;
use libc::strcmp;
use libc::{free, strcmp};
use std::convert::TryInto;
use std::ffi::CStr;
@@ -1156,24 +1078,6 @@ mod tests {
}
}
#[test]
fn test_dc_strdup_keep_null() {
unsafe {
let str_a = b"foobar\x00" as *const u8 as *const libc::c_char;
let str_a_copy = dc_strdup_keep_null(str_a);
assert_eq!(
CStr::from_ptr(str_a_copy),
CString::new("foobar").unwrap().as_c_str()
);
assert_ne!(str_a, str_a_copy);
let str_a = ptr::null();
let str_a_copy = dc_strdup_keep_null(str_a);
assert_eq!(str_a.is_null(), true);
assert_eq!(str_a_copy.is_null(), true);
}
}
#[test]
fn test_dc_ltrim() {
unsafe {
@@ -1282,49 +1186,50 @@ mod tests {
);
}
/* calls free() for each item content */
unsafe fn clist_free_content(haystack: *const clist) {
let mut iter = (*haystack).first;
while !iter.is_null() {
free((*iter).data);
(*iter).data = ptr::null_mut();
iter = if !iter.is_null() {
(*iter).next
} else {
ptr::null_mut()
}
}
}
fn strndup(s: *const libc::c_char, n: libc::c_ulong) -> *mut libc::c_char {
if s.is_null() {
return std::ptr::null_mut();
}
let end = std::cmp::min(n as usize, unsafe { strlen(s) });
unsafe {
let result = libc::malloc(end + 1);
memcpy(result, s as *const _, end);
std::ptr::write_bytes(result.offset(end as isize), b'\x00', 1);
result as *mut _
}
}
#[test]
fn test_dc_str_to_clist_1() {
unsafe {
let list = dc_str_to_clist(ptr::null(), b" \x00" as *const u8 as *const libc::c_char);
assert_eq!((*list).count, 0);
clist_free_content(list);
clist_free(list);
}
}
#[test]
fn test_dc_str_to_clist_2() {
unsafe {
let list: *mut clist = dc_str_to_clist(
b"\x00" as *const u8 as *const libc::c_char,
b" \x00" as *const u8 as *const libc::c_char,
);
let list = dc_str_to_clist("", " ");
assert_eq!((*list).count, 1);
clist_free_content(list);
clist_free(list);
}
}
#[test]
fn test_dc_str_to_clist_3() {
unsafe {
let list: *mut clist = dc_str_to_clist(
b" \x00" as *const u8 as *const libc::c_char,
b" \x00" as *const u8 as *const libc::c_char,
);
assert_eq!((*list).count, 2);
clist_free_content(list);
clist_free(list);
}
}
#[test]
fn test_dc_str_to_clist_4() {
unsafe {
let list: *mut clist = dc_str_to_clist(
b"foo bar test\x00" as *const u8 as *const libc::c_char,
b" \x00" as *const u8 as *const libc::c_char,
);
let list: *mut clist = dc_str_to_clist("foo bar test", " ");
assert_eq!((*list).count, 3);
let str: *mut libc::c_char =
dc_str_from_clist(list, b" \x00" as *const u8 as *const libc::c_char);

View File

@@ -53,11 +53,11 @@ impl E2eeHelper {
pub unsafe fn encrypt(
&mut self,
context: &Context,
recipients_addr: *const clist,
force_unencrypted: libc::c_int,
e2ee_guaranteed: libc::c_int,
recipients_addr: &Vec<String>,
force_unencrypted: bool,
e2ee_guaranteed: bool,
min_verified: libc::c_int,
do_gossip: libc::c_int,
do_gossip: bool,
mut in_out_message: *mut mailmime,
) {
let mut ok_to_continue = true;
@@ -69,10 +69,7 @@ impl E2eeHelper {
let plain: *mut MMAPString = mmap_string_new(b"\x00" as *const u8 as *const libc::c_char);
let mut peerstates: Vec<Peerstate> = Vec::new();
if !(recipients_addr.is_null()
|| in_out_message.is_null()
|| !(*in_out_message).mm_parent.is_null()
|| plain.is_null())
if !(in_out_message.is_null() || !(*in_out_message).mm_parent.is_null() || plain.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. */
let prefer_encrypt = if 0
@@ -95,19 +92,16 @@ impl E2eeHelper {
});
if let Ok(public_key) = pubkey_ret {
/*only for random-seed*/
if prefer_encrypt == EncryptPreference::Mutual || 0 != e2ee_guaranteed {
if prefer_encrypt == EncryptPreference::Mutual || e2ee_guaranteed {
do_encrypt = 1i32;
let mut iter1: *mut clistiter;
iter1 = (*recipients_addr).first;
while !iter1.is_null() {
let recipient_addr = to_string((*iter1).data as *const libc::c_char);
if recipient_addr != addr {
for recipient_addr in recipients_addr.iter() {
if *recipient_addr != addr {
let peerstate =
Peerstate::from_addr(context, &context.sql, &recipient_addr);
if peerstate.is_some()
&& (peerstate.as_ref().unwrap().prefer_encrypt
== EncryptPreference::Mutual
|| 0 != e2ee_guaranteed)
|| e2ee_guaranteed)
{
let peerstate = peerstate.unwrap();
info!(
@@ -130,11 +124,6 @@ impl E2eeHelper {
break;
}
}
iter1 = if !iter1.is_null() {
(*iter1).next
} else {
ptr::null_mut()
}
}
}
let sign_key = if 0 != do_encrypt {
@@ -148,7 +137,7 @@ impl E2eeHelper {
} else {
None
};
if 0 != force_unencrypted {
if force_unencrypted {
do_encrypt = 0i32
}
imffields_unprotected = mailmime_find_mailimf_fields(in_out_message);
@@ -175,7 +164,7 @@ impl E2eeHelper {
imffields_encrypted,
part_to_encrypt,
);
if 0 != do_gossip {
if do_gossip {
let i_cnt = peerstates.len() as libc::c_int;
if i_cnt > 1 {
let mut i = 0;
@@ -197,63 +186,39 @@ impl E2eeHelper {
}
}
/* memoryhole headers */
// XXX we can't use clist's into_iter()
// because the loop body also removes items
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() {
(*cur).data
} else {
ptr::null_mut()
})
as *mut mailimf_field;
let field: *mut mailimf_field = (*cur).data as *mut mailimf_field;
let mut move_to_encrypted = false;
if !field.is_null() {
if (*field).fld_type == MAILIMF_FIELD_SUBJECT as libc::c_int {
move_to_encrypted = 1i32
move_to_encrypted = true;
} else if (*field).fld_type
== MAILIMF_FIELD_OPTIONAL_FIELD as libc::c_int
{
let opt_field: *mut mailimf_optional_field =
(*field).fld_data.fld_optional_field;
let opt_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,
11,
) == 0
|| strncmp(
(*opt_field).fld_name,
b"Chat-\x00" as *const u8
as *const libc::c_char,
5,
) == 0
&& strcmp(
(*opt_field).fld_name,
b"Chat-Version\x00" as *const u8
as *const libc::c_char,
) != 0
let fld_name = to_string_lossy((*opt_field).fld_name);
if fld_name.starts_with("Secure-Join")
|| fld_name.starts_with("Chat-")
{
move_to_encrypted = 1
move_to_encrypted = true;
}
}
}
}
if 0 != move_to_encrypted {
if move_to_encrypted {
mailimf_fields_add(imffields_encrypted, field);
cur = clist_delete((*imffields_unprotected).fld_list, cur)
cur = clist_delete((*imffields_unprotected).fld_list, cur);
} else {
cur = if !cur.is_null() {
(*cur).next
} else {
ptr::null_mut()
}
cur = (*cur).next;
}
}
let subject: *mut mailimf_subject = mailimf_subject_new(dc_strdup(
b"...\x00" as *const u8 as *const libc::c_char,
));
let subject: *mut mailimf_subject = mailimf_subject_new("...".strdup());
mailimf_fields_add(
imffields_unprotected,
mailimf_field_new(
@@ -645,19 +610,13 @@ unsafe fn update_gossip_peerstates(
imffields: *mut mailimf_fields,
gossip_headers: *const mailimf_fields,
) -> HashSet<String> {
let mut cur1: *mut clistiter;
let mut recipients: Option<HashSet<String>> = None;
let mut gossipped_addr: HashSet<String> = Default::default();
cur1 = (*(*gossip_headers).fld_list).first;
while !cur1.is_null() {
let field: *mut mailimf_field = (if !cur1.is_null() {
(*cur1).data
} else {
ptr::null_mut()
}) as *mut mailimf_field;
for cur_data in (*(*gossip_headers).fld_list).into_iter() {
let field: *mut mailimf_field = cur_data as *mut _;
if (*field).fld_type == MAILIMF_FIELD_OPTIONAL_FIELD as libc::c_int {
let optional_field: *const mailimf_optional_field =
(*field).fld_data.fld_optional_field;
let optional_field = (*field).fld_data.fld_optional_field;
if !optional_field.is_null()
&& !(*optional_field).fld_name.is_null()
&& strcasecmp(
@@ -701,11 +660,6 @@ unsafe fn update_gossip_peerstates(
}
}
}
cur1 = if !cur1.is_null() {
(*cur1).next
} else {
ptr::null_mut()
}
}
gossipped_addr
@@ -722,7 +676,6 @@ unsafe fn decrypt_recursive(
) -> Result<()> {
ensure!(!mime.is_null(), "Invalid mime reference");
let ct: *mut mailmime_content;
let mut cur: *mut clistiter;
if (*mime).mm_type == MAILMIME_MULTIPLE as libc::c_int {
ct = (*mime).mm_content_type;
@@ -733,23 +686,18 @@ unsafe fn decrypt_recursive(
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() {
for cur_data in (*(*mime).mm_data.mm_multipart.mm_mp_list).into_iter() {
let mut decrypted_mime: *mut mailmime = ptr::null_mut();
if decrypt_part(
context,
(if !cur.is_null() {
(*cur).data
} else {
ptr::null_mut()
}) as *mut mailmime,
cur_data as *mut mailmime,
private_keyring,
public_keyring_for_validate,
ret_valid_signatures,
&mut decrypted_mime,
) {
if (*ret_gossip_headers).is_null() && ret_valid_signatures.len() > 0 {
let mut dummy: libc::size_t = 0i32 as libc::size_t;
let mut dummy: libc::size_t = 0;
let mut test: *mut mailimf_fields = ptr::null_mut();
if mailimf_envelope_and_optional_fields_parse(
(*decrypted_mime).mm_mime_start,
@@ -766,23 +714,13 @@ unsafe fn decrypt_recursive(
mailmime_free(mime);
return Ok(());
}
cur = if !cur.is_null() {
(*cur).next
} else {
ptr::null_mut()
}
}
*ret_has_unencrypted_parts = 1i32
} else {
cur = (*(*mime).mm_data.mm_multipart.mm_mp_list).first;
while !cur.is_null() {
for cur_data in (*(*mime).mm_data.mm_multipart.mm_mp_list).into_iter() {
if decrypt_recursive(
context,
(if !cur.is_null() {
(*cur).data
} else {
ptr::null_mut()
}) as *mut mailmime,
cur_data as *mut mailmime,
private_keyring,
public_keyring_for_validate,
ret_valid_signatures,
@@ -793,11 +731,6 @@ unsafe fn decrypt_recursive(
{
return Ok(());
}
cur = if !cur.is_null() {
(*cur).next
} else {
ptr::null_mut()
}
}
}
} else if (*mime).mm_type == MAILMIME_MESSAGE as libc::c_int {
@@ -847,25 +780,12 @@ unsafe fn decrypt_part(
|| (*mime_data).dt_data.dt_text.dt_length <= 0)
{
if !(*mime).mm_mime_fields.is_null() {
let mut cur: *mut clistiter;
cur = (*(*(*mime).mm_mime_fields).fld_list).first;
while !cur.is_null() {
let field: *mut mailmime_field = (if !cur.is_null() {
(*cur).data
} else {
ptr::null_mut()
}) 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 {
ptr::null_mut()
for cur_data in (*(*(*mime).mm_mime_fields).fld_list).into_iter() {
let field: *mut mailmime_field = cur_data as *mut _;
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
}
}
}
@@ -992,23 +912,10 @@ unsafe fn contains_report(mime: *mut mailmime) -> bool {
{
return true;
}
let mut cur: *mut clistiter;
cur = (*(*mime).mm_data.mm_multipart.mm_mp_list).first;
while !cur.is_null() {
if contains_report(
(if !cur.is_null() {
(*cur).data
} else {
ptr::null_mut()
}) as *mut mailmime,
) {
for cur_data in (*(*(*mime).mm_mime_fields).fld_list).into_iter() {
if contains_report(cur_data as *mut mailmime) {
return true;
}
cur = if !cur.is_null() {
(*cur).next
} else {
ptr::null_mut()
}
}
} else if (*mime).mm_type == MAILMIME_MESSAGE as libc::c_int {
if contains_report((*mime).mm_data.mm_message.mm_msg_mime) {

View File

@@ -1,8 +1,6 @@
use std::ptr;
use std::time::Duration;
use deltachat_derive::{FromSql, ToSql};
use mmime::clist::*;
use rand::{thread_rng, Rng};
use crate::chat;
@@ -642,12 +640,12 @@ pub fn job_action_exists(context: &Context, action: Action) -> bool {
/* special case for DC_JOB_SEND_MSG_TO_SMTP */
#[allow(non_snake_case)]
pub unsafe fn job_send_msg(context: &Context, msg_id: u32) -> libc::c_int {
pub fn job_send_msg(context: &Context, msg_id: u32) -> libc::c_int {
let mut success = 0;
/* load message data */
let mimefactory = dc_mimefactory_load_msg(context, msg_id);
if mimefactory.is_err() || mimefactory.as_ref().unwrap().from_addr.is_null() {
if mimefactory.is_err() {
warn!(
context,
"Cannot load data to send, maybe the message is deleted in between.",
@@ -680,8 +678,9 @@ pub unsafe fn job_send_msg(context: &Context, msg_id: u32) -> libc::c_int {
}
}
/* create message */
if !dc_mimefactory_render(context, &mut mimefactory) {
message::set_msg_failed(context, msg_id, as_opt_str(mimefactory.error));
if let Err(msg) = unsafe { dc_mimefactory_render(context, &mut mimefactory) } {
let e = msg.to_string();
message::set_msg_failed(context, msg_id, Some(e));
} else if 0
!= mimefactory
.msg
@@ -690,6 +689,7 @@ pub unsafe fn job_send_msg(context: &Context, msg_id: u32) -> libc::c_int {
.unwrap_or_default()
&& !mimefactory.out_encrypted
{
/* unrecoverable */
warn!(
context,
"e2e encryption unavailable {} - {:?}",
@@ -702,18 +702,11 @@ pub unsafe fn job_send_msg(context: &Context, msg_id: u32) -> libc::c_int {
Some("End-to-end-encryption unavailable unexpectedly."),
);
} else {
/* unrecoverable */
if !clist_search_string_nocase(mimefactory.recipients_addr, mimefactory.from_addr) {
clist_insert_after(
mimefactory.recipients_names,
(*mimefactory.recipients_names).last,
ptr::null_mut(),
);
clist_insert_after(
mimefactory.recipients_addr,
(*mimefactory.recipients_addr).last,
dc_strdup(mimefactory.from_addr) as *mut libc::c_void,
);
if !vec_contains_lowercase(&mimefactory.recipients_addr, &mimefactory.from_addr) {
mimefactory.recipients_names.push("".to_string());
mimefactory
.recipients_addr
.push(mimefactory.from_addr.to_string());
}
if mimefactory.out_gossiped {
chat::set_gossiped_timestamp(context, mimefactory.msg.chat_id, time());
@@ -997,8 +990,8 @@ fn connect_to_inbox(context: &Context, inbox: &Imap) -> libc::c_int {
}
fn send_mdn(context: &Context, msg_id: u32) {
if let Ok(mut mimefactory) = unsafe { dc_mimefactory_load_mdn(context, msg_id) } {
if unsafe { dc_mimefactory_render(context, &mut mimefactory) } {
if let Ok(mut mimefactory) = dc_mimefactory_load_mdn(context, msg_id) {
if unsafe { dc_mimefactory_render(context, &mut mimefactory) }.is_ok() {
add_smtp_job(context, Action::SendMdn, &mut mimefactory);
}
}
@@ -1007,7 +1000,6 @@ fn send_mdn(context: &Context, msg_id: u32) {
#[allow(non_snake_case)]
fn add_smtp_job(context: &Context, action: Action, mimefactory: &MimeFactory) -> libc::c_int {
let mut success: libc::c_int = 0i32;
let mut recipients: *mut libc::c_char = ptr::null_mut();
let mut param = Params::new();
let path_filename = dc_get_fine_path_filename(context, "$BLOBDIR", &mimefactory.rfc724_mid);
let bytes = unsafe {
@@ -1024,14 +1016,9 @@ fn add_smtp_job(context: &Context, action: Action, mimefactory: &MimeFactory) ->
path_filename.display(),
);
} else {
recipients = unsafe {
dc_str_from_clist(
mimefactory.recipients_addr,
b"\x1e\x00" as *const u8 as *const libc::c_char,
)
};
let recipients = mimefactory.recipients_addr.join("\x1e");
param.set(Param::File, path_filename.to_string_lossy());
param.set(Param::Recipients, as_str(recipients));
param.set(Param::Recipients, &recipients);
job_add(
context,
action,
@@ -1045,9 +1032,6 @@ fn add_smtp_job(context: &Context, action: Action, mimefactory: &MimeFactory) ->
);
success = 1;
}
unsafe {
libc::free(recipients.cast());
}
success
}

View File

@@ -680,6 +680,7 @@ pub fn guess_msgtype_from_suffix(path: &Path) -> Option<(Viewtype, &str)> {
"mp4" => (Viewtype::Video, "video/mp4"),
"jpg" => (Viewtype::Image, "image/jpeg"),
"jpeg" => (Viewtype::Image, "image/jpeg"),
"jpe" => (Viewtype::Image, "image/jpeg"),
"png" => (Viewtype::Image, "image/png"),
"webp" => (Viewtype::Image, "image/webp"),
"gif" => (Viewtype::Gif, "image/gif"),