address @dignifiedquire comments

This commit is contained in:
holger krekel
2019-09-23 15:23:20 +02:00
parent 095cb759ed
commit ba231d2c5f
4 changed files with 77 additions and 60 deletions

View File

@@ -27,7 +27,6 @@ use crate::message::{self, Message};
use crate::param::*; use crate::param::*;
use crate::stock::StockMessage; use crate::stock::StockMessage;
use crate::wrapmime; use crate::wrapmime;
use crate::wrapmime::*;
#[derive(Clone, Copy, Eq, PartialEq)] #[derive(Clone, Copy, Eq, PartialEq)]
pub enum Loaded { pub enum Loaded {
@@ -96,9 +95,11 @@ impl<'a> MimeFactory<'a> {
assert!(self.out.is_null()); // guard against double-calls assert!(self.out.is_null()); // guard against double-calls
self.out = mmap_string_new(b"\x00" as *const u8 as *const libc::c_char); self.out = mmap_string_new(b"\x00" as *const u8 as *const libc::c_char);
let mut col: libc::c_int = 0; let mut col: libc::c_int = 0;
if 0 != mailmime_write_mem(self.out, &mut col, message) { ensure_eq!(
bail!("could not write memory-mime-message") mailmime_write_mem(self.out, &mut col, message),
} 0,
"mem-error"
);
} }
self.out_encrypted = encrypted; self.out_encrypted = encrypted;
self.out_gossiped = encrypted && gossiped; self.out_gossiped = encrypted && gossiped;
@@ -261,7 +262,7 @@ pub fn dc_mimefactory_load_mdn<'a>(
pub unsafe fn dc_mimefactory_render( pub unsafe fn dc_mimefactory_render(
context: &Context, context: &Context,
mut factory: &mut MimeFactory, factory: &mut MimeFactory,
) -> Result<(), Error> { ) -> Result<(), Error> {
if factory.loaded == Loaded::Nothing || !factory.out.is_null() { if factory.loaded == Loaded::Nothing || !factory.out.is_null() {
bail!("Invalid use of mimefactory-object."); bail!("Invalid use of mimefactory-object.");
@@ -340,13 +341,13 @@ pub unsafe fn dc_mimefactory_render(
/* Add a X-Mailer header. /* Add a X-Mailer header.
This is only informational for debugging and may be removed in the release. This is only informational for debugging and may be removed in the release.
We do not rely on this header as it may be removed by MTAs. */ We do not rely on this header as it may be removed by MTAs. */
new_custom_field(imf_fields, "X-Mailer", &headerval); wrapmime::new_custom_field(imf_fields, "X-Mailer", &headerval);
new_custom_field(imf_fields, "Chat-Version", "1.0"); wrapmime::new_custom_field(imf_fields, "Chat-Version", "1.0");
if factory.req_mdn { if factory.req_mdn {
/* we use "Chat-Disposition-Notification-To" /* we use "Chat-Disposition-Notification-To"
because replies to "Disposition-Notification-To" are weird in many cases because replies to "Disposition-Notification-To" are weird in many cases
eg. are just freetext and/or do not follow any standard. */ eg. are just freetext and/or do not follow any standard. */
new_custom_field( wrapmime::new_custom_field(
imf_fields, imf_fields,
"Chat-Disposition-Notification-To", "Chat-Disposition-Notification-To",
&factory.from_addr, &factory.from_addr,
@@ -359,9 +360,8 @@ pub unsafe fn dc_mimefactory_render(
} }
}; };
let message = mailmime_new_message_data(0 as *mut mailmime); let message = mailmime_new_message_data(0 as *mut mailmime);
if message.is_null() { ensure!(!message.is_null(), "could not create mime message data");
bail!("could not create mime message data")
}
mailmime_set_imf_fields(message, imf_fields); mailmime_set_imf_fields(message, imf_fields);
// 1=add Autocrypt-header (needed eg. for handshaking), 2=no Autocrypte-header (used for MDN) // 1=add Autocrypt-header (needed eg. for handshaking), 2=no Autocrypte-header (used for MDN)
@@ -379,7 +379,7 @@ pub unsafe fn dc_mimefactory_render(
let mut placeholdertext = None; let mut placeholdertext = None;
if chat.typ == Chattype::VerifiedGroup { if chat.typ == Chattype::VerifiedGroup {
new_custom_field(imf_fields, "Chat-Verified", "1"); wrapmime::new_custom_field(imf_fields, "Chat-Verified", "1");
force_plaintext = 0; force_plaintext = 0;
e2ee_guaranteed = true; e2ee_guaranteed = true;
min_verified = 2 min_verified = 2
@@ -409,16 +409,16 @@ pub unsafe fn dc_mimefactory_render(
/* build header etc. */ /* build header etc. */
let command = factory.msg.param.get_cmd(); let command = factory.msg.param.get_cmd();
if chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup { if chat.typ == Chattype::Group || chat.typ == Chattype::VerifiedGroup {
new_custom_field(imf_fields, "Chat-Group-ID", &chat.grpid); wrapmime::new_custom_field(imf_fields, "Chat-Group-ID", &chat.grpid);
let encoded = dc_encode_header_words(&chat.name); let encoded = dc_encode_header_words(&chat.name);
new_custom_field(imf_fields, "Chat-Group-Name", &encoded); wrapmime::new_custom_field(imf_fields, "Chat-Group-Name", &encoded);
match command { match command {
SystemMessage::MemberRemovedFromGroup => { SystemMessage::MemberRemovedFromGroup => {
let email_to_remove = factory.msg.param.get(Param::Arg).unwrap_or_default(); let email_to_remove = factory.msg.param.get(Param::Arg).unwrap_or_default();
if !email_to_remove.is_empty() { if !email_to_remove.is_empty() {
new_custom_field( wrapmime::new_custom_field(
imf_fields, imf_fields,
"Chat-Group-Member-Removed", "Chat-Group-Member-Removed",
&email_to_remove, &email_to_remove,
@@ -430,7 +430,11 @@ pub unsafe fn dc_mimefactory_render(
do_gossip = true; do_gossip = true;
let email_to_add = msg.param.get(Param::Arg).unwrap_or_default(); let email_to_add = msg.param.get(Param::Arg).unwrap_or_default();
if !email_to_add.is_empty() { if !email_to_add.is_empty() {
new_custom_field(imf_fields, "Chat-Group-Member-Added", &email_to_add); wrapmime::new_custom_field(
imf_fields,
"Chat-Group-Member-Added",
&email_to_add,
);
grpimage = chat.param.get(Param::ProfileImage); grpimage = chat.param.get(Param::ProfileImage);
} }
if 0 != msg.param.get_int(Param::Arg2).unwrap_or_default() & 0x1 { if 0 != msg.param.get_int(Param::Arg2).unwrap_or_default() & 0x1 {
@@ -439,20 +443,28 @@ pub unsafe fn dc_mimefactory_render(
"sending secure-join message \'{}\' >>>>>>>>>>>>>>>>>>>>>>>>>", "sending secure-join message \'{}\' >>>>>>>>>>>>>>>>>>>>>>>>>",
"vg-member-added", "vg-member-added",
); );
new_custom_field(imf_fields, "Secure-Join", "vg-member-added"); wrapmime::new_custom_field(
imf_fields,
"Secure-Join",
"vg-member-added",
);
} }
} }
SystemMessage::GroupNameChanged => { SystemMessage::GroupNameChanged => {
let msg = &factory.msg; let msg = &factory.msg;
let value_to_add = msg.param.get(Param::Arg).unwrap_or_default(); let value_to_add = msg.param.get(Param::Arg).unwrap_or_default();
new_custom_field(imf_fields, "Chat-Group-Name-Changed", &value_to_add); wrapmime::new_custom_field(
imf_fields,
"Chat-Group-Name-Changed",
&value_to_add,
);
} }
SystemMessage::GroupImageChanged => { SystemMessage::GroupImageChanged => {
let msg = &factory.msg; let msg = &factory.msg;
grpimage = msg.param.get(Param::Arg); grpimage = msg.param.get(Param::Arg);
if grpimage.is_none() { if grpimage.is_none() {
new_custom_field(imf_fields, "Chat-Group-Image", "0"); wrapmime::new_custom_field(imf_fields, "Chat-Group-Image", "0");
} }
} }
_ => {} _ => {}
@@ -461,10 +473,14 @@ pub unsafe fn dc_mimefactory_render(
match command { match command {
SystemMessage::LocationStreamingEnabled => { SystemMessage::LocationStreamingEnabled => {
new_custom_field(imf_fields, "Chat-Content", "location-streaming-enabled"); wrapmime::new_custom_field(
imf_fields,
"Chat-Content",
"location-streaming-enabled",
);
} }
SystemMessage::AutocryptSetupMessage => { SystemMessage::AutocryptSetupMessage => {
new_custom_field(imf_fields, "Autocrypt-Setup-Message", "v1"); wrapmime::new_custom_field(imf_fields, "Autocrypt-Setup-Message", "v1");
placeholdertext = Some( placeholdertext = Some(
factory factory
.context .context
@@ -480,10 +496,10 @@ pub unsafe fn dc_mimefactory_render(
context, context,
"sending secure-join message \'{}\' >>>>>>>>>>>>>>>>>>>>>>>>>", step, "sending secure-join message \'{}\' >>>>>>>>>>>>>>>>>>>>>>>>>", step,
); );
new_custom_field(imf_fields, "Secure-Join", &step); wrapmime::new_custom_field(imf_fields, "Secure-Join", &step);
let param2 = msg.param.get(Param::Arg2).unwrap_or_default(); let param2 = msg.param.get(Param::Arg2).unwrap_or_default();
if !param2.is_empty() { if !param2.is_empty() {
new_custom_field( wrapmime::new_custom_field(
imf_fields, imf_fields,
if step == "vg-request-with-auth" || step == "vc-request-with-auth" if step == "vg-request-with-auth" || step == "vc-request-with-auth"
{ {
@@ -496,11 +512,15 @@ pub unsafe fn dc_mimefactory_render(
} }
let fingerprint = msg.param.get(Param::Arg3).unwrap_or_default(); let fingerprint = msg.param.get(Param::Arg3).unwrap_or_default();
if !fingerprint.is_empty() { if !fingerprint.is_empty() {
new_custom_field(imf_fields, "Secure-Join-Fingerprint", &fingerprint); wrapmime::new_custom_field(
imf_fields,
"Secure-Join-Fingerprint",
&fingerprint,
);
} }
match msg.param.get(Param::Arg4) { match msg.param.get(Param::Arg4) {
Some(id) => { Some(id) => {
new_custom_field(imf_fields, "Secure-Join-Group", &id); wrapmime::new_custom_field(imf_fields, "Secure-Join-Group", &id);
} }
None => {} None => {}
}; };
@@ -519,7 +539,7 @@ pub unsafe fn dc_mimefactory_render(
meta_part = res.0; meta_part = res.0;
let filename_as_sent = res.1; let filename_as_sent = res.1;
if !meta_part.is_null() { if !meta_part.is_null() {
new_custom_field(imf_fields, "Chat-Group-Image", &filename_as_sent) wrapmime::new_custom_field(imf_fields, "Chat-Group-Image", &filename_as_sent)
} }
} }
@@ -528,7 +548,7 @@ pub unsafe fn dc_mimefactory_render(
|| factory.msg.type_0 == Viewtype::Video || factory.msg.type_0 == Viewtype::Video
{ {
if factory.msg.type_0 == Viewtype::Voice { if factory.msg.type_0 == Viewtype::Voice {
new_custom_field(imf_fields, "Chat-Voice-Message", "1"); wrapmime::new_custom_field(imf_fields, "Chat-Voice-Message", "1");
} }
let duration_ms = factory let duration_ms = factory
.msg .msg
@@ -537,7 +557,7 @@ pub unsafe fn dc_mimefactory_render(
.unwrap_or_default(); .unwrap_or_default();
if duration_ms > 0 { if duration_ms > 0 {
let dur = duration_ms.to_string(); let dur = duration_ms.to_string();
new_custom_field(imf_fields, "Chat-Duration", &dur); wrapmime::new_custom_field(imf_fields, "Chat-Duration", &dur);
} }
} }
@@ -578,7 +598,7 @@ pub unsafe fn dc_mimefactory_render(
if !footer.is_empty() { "-- \r\n" } else { "" }, if !footer.is_empty() { "-- \r\n" } else { "" },
footer footer
); );
let text_part = build_body_text(&message_text)?; let text_part = wrapmime::build_body_text(&message_text)?;
mailmime_smart_add_part(message, text_part); mailmime_smart_add_part(message, text_part);
/* add attachment part */ /* add attachment part */
@@ -606,7 +626,7 @@ pub unsafe fn dc_mimefactory_render(
param.get_float(Param::SetLatitude).unwrap_or_default(), param.get_float(Param::SetLatitude).unwrap_or_default(),
param.get_float(Param::SetLongitude).unwrap_or_default(), param.get_float(Param::SetLongitude).unwrap_or_default(),
); );
add_filename_part( wrapmime::add_filename_part(
message, message,
"message.kml", "message.kml",
"application/vnd.google-earth.kml+xml", "application/vnd.google-earth.kml+xml",
@@ -618,7 +638,7 @@ pub unsafe fn dc_mimefactory_render(
if let Ok((kml_file, last_added_location_id)) = if let Ok((kml_file, last_added_location_id)) =
location::get_kml(context, factory.msg.chat_id) location::get_kml(context, factory.msg.chat_id)
{ {
add_filename_part( wrapmime::add_filename_part(
message, message,
"location.kml", "location.kml",
"application/vnd.google-earth.kml+xml", "application/vnd.google-earth.kml+xml",
@@ -666,7 +686,7 @@ pub unsafe fn dc_mimefactory_render(
.context .context
.stock_string_repl_str(StockMessage::ReadRcptMailBody, p1); .stock_string_repl_str(StockMessage::ReadRcptMailBody, p1);
let message_text = format!("{}\r\n", p2); let message_text = format!("{}\r\n", p2);
let human_mime_part = build_body_text(&message_text)?; let human_mime_part = wrapmime::build_body_text(&message_text)?;
mailmime_add_part(multipart, human_mime_part); mailmime_add_part(multipart, human_mime_part);
/* second body part: machine-readable, always REQUIRED by RFC 6522 */ /* second body part: machine-readable, always REQUIRED by RFC 6522 */
@@ -679,11 +699,12 @@ pub unsafe fn dc_mimefactory_render(
factory.msg.rfc724_mid factory.msg.rfc724_mid
); );
let content_type_0 = new_mailmime_content_type("message/disposition-notification"); let content_type_0 =
wrapmime::new_mailmime_content_type("message/disposition-notification");
let mime_fields_0: *mut mailmime_fields = let mime_fields_0: *mut mailmime_fields =
mailmime_fields_new_encoding(MAILMIME_MECHANISM_8BIT as libc::c_int); mailmime_fields_new_encoding(MAILMIME_MECHANISM_8BIT as libc::c_int);
let mach_mime_part: *mut mailmime = mailmime_new_empty(content_type_0, mime_fields_0); let mach_mime_part: *mut mailmime = mailmime_new_empty(content_type_0, mime_fields_0);
set_body_text(mach_mime_part, &message_text2)?; wrapmime::set_body_text(mach_mime_part, &message_text2)?;
mailmime_add_part(multipart, mach_mime_part); mailmime_add_part(multipart, mach_mime_part);
force_plaintext = DC_FP_NO_AUTOCRYPT_HEADER; force_plaintext = DC_FP_NO_AUTOCRYPT_HEADER;
info!(context, "sending MDM {:?}", message_text2); info!(context, "sending MDM {:?}", message_text2);
@@ -738,20 +759,21 @@ pub unsafe fn dc_mimefactory_render(
/*just a pointer into mailmime structure, must not be freed*/ /*just a pointer into mailmime structure, must not be freed*/
let imffields_unprotected = mailmime_find_mailimf_fields(message); let imffields_unprotected = mailmime_find_mailimf_fields(message);
if imffields_unprotected.is_null() { ensure!(
bail!("could not find mime fields"); !imffields_unprotected.is_null(),
} "could not find mime fields"
);
let mut encrypt_helper = EncryptHelper::new(&context)?; let mut encrypt_helper = EncryptHelper::new(&context)?;
if force_plaintext != DC_FP_NO_AUTOCRYPT_HEADER { if force_plaintext != DC_FP_NO_AUTOCRYPT_HEADER {
// unless determined otherwise we add Autocrypt header // unless determined otherwise we add Autocrypt header
let aheader = encrypt_helper.get_aheader().to_string(); let aheader = encrypt_helper.get_aheader().to_string();
new_custom_field(imffields_unprotected, "Autocrypt", &aheader); wrapmime::new_custom_field(imffields_unprotected, "Autocrypt", &aheader);
} }
let mut finalized = false; let mut finalized = false;
if force_plaintext == 0 { if force_plaintext == 0 {
finalized = encrypt_helper.try_encrypt( finalized = encrypt_helper.try_encrypt(
&mut factory, factory,
e2ee_guaranteed, e2ee_guaranteed,
min_verified, min_verified,
do_gossip, do_gossip,
@@ -891,7 +913,7 @@ fn build_body_file(context: &Context, msg: &Message, base_name: &str) -> (*mut m
} }
} }
} }
let content = new_mailmime_content_type(&mimetype); let content = wrapmime::new_mailmime_content_type(&mimetype);
let filename_encoded = dc_encode_header_words(&filename_to_send).strdup(); let filename_encoded = dc_encode_header_words(&filename_to_send).strdup();
clist_insert_after( clist_insert_after(
(*content).ct_parameters, (*content).ct_parameters,

View File

@@ -35,6 +35,10 @@ use crate::securejoin::handle_degrade_event;
use crate::wrapmime; use crate::wrapmime;
use crate::wrapmime::*; use crate::wrapmime::*;
// standard mime-version header aka b"Version: 1\r\n\x00"
static mut VERSION_CONTENT: [libc::c_char; 13] =
[86, 101, 114, 115, 105, 111, 110, 58, 32, 49, 13, 10, 0];
#[derive(Debug)] #[derive(Debug)]
pub struct EncryptHelper { pub struct EncryptHelper {
pub prefer_encrypt: EncryptPreference, pub prefer_encrypt: EncryptPreference,
@@ -57,16 +61,11 @@ impl EncryptHelper {
Some(addr) => addr, Some(addr) => addr,
}; };
let public_key = match load_or_generate_self_public_key(context, &addr) { let public_key = load_or_generate_self_public_key(context, &addr)?;
Ok(res) => res,
Err(err) => {
bail!("failed to load own public key: {}", err);
}
};
Ok(EncryptHelper { Ok(EncryptHelper {
prefer_encrypt: prefer_encrypt, prefer_encrypt,
addr: addr, addr,
public_key: public_key, public_key,
}) })
} }
@@ -100,10 +99,10 @@ impl EncryptHelper {
// determine if we can and should encrypt // determine if we can and should encrypt
for recipient_addr in factory.recipients_addr.iter() { for recipient_addr in factory.recipients_addr.iter() {
if *recipient_addr == self.addr { if recipient_addr == &self.addr {
continue; continue;
} }
let peerstate = match Peerstate::from_addr(context, &context.sql, &recipient_addr) { let peerstate = match Peerstate::from_addr(context, &context.sql, recipient_addr) {
Some(peerstate) => peerstate, Some(peerstate) => peerstate,
None => { None => {
let msg = format!("peerstate for {} missing, cannot encrypt", recipient_addr); let msg = format!("peerstate for {} missing, cannot encrypt", recipient_addr);
@@ -257,8 +256,6 @@ impl EncryptHelper {
); );
let content: *mut mailmime_content = (*encrypted_part).mm_content_type; let content: *mut mailmime_content = (*encrypted_part).mm_content_type;
wrapmime::append_ct_param(content, "protocol", "application/pgp-encrypted")?; wrapmime::append_ct_param(content, "protocol", "application/pgp-encrypted")?;
static mut VERSION_CONTENT: [libc::c_char; 13] =
[86, 101, 114, 115, 105, 111, 110, 58, 32, 49, 13, 10, 0];
let version_mime: *mut mailmime = new_data_part( let version_mime: *mut mailmime = new_data_part(
VERSION_CONTENT.as_mut_ptr() as *mut libc::c_void, VERSION_CONTENT.as_mut_ptr() as *mut libc::c_void,
strlen(VERSION_CONTENT.as_mut_ptr()), strlen(VERSION_CONTENT.as_mut_ptr()),

View File

@@ -68,7 +68,7 @@ mod login_param;
pub mod securejoin; pub mod securejoin;
mod token; mod token;
#[macro_use] #[macro_use]
pub(crate) mod wrapmime; mod wrapmime;
#[cfg(test)] #[cfg(test)]
mod test_utils; mod test_utils;

View File

@@ -78,18 +78,16 @@ pub fn append_ct_param(
value: &str, value: &str,
) -> Result<(), Error> { ) -> Result<(), Error> {
unsafe { unsafe {
let name_c = name.strdup(); let name_c = CString::new(name).unwrap();
let value_c = value.strdup(); let value_c = CString::new(value).unwrap();
clist_append!( clist_append!(
(*content).ct_parameters, (*content).ct_parameters,
mailmime_param_new_with_data( mailmime_param_new_with_data(
name_c as *const u8 as *const libc::c_char as *mut libc::c_char, name_c.as_ptr() as *const u8 as *const libc::c_char as *mut libc::c_char,
value_c as *const u8 as *const libc::c_char as *mut libc::c_char value_c.as_ptr() as *const u8 as *const libc::c_char as *mut libc::c_char
) )
); );
libc::free(name_c as *mut libc::c_void);
libc::free(value_c as *mut libc::c_void);
} }
Ok(()) Ok(())
} }