mirror of
https://github.com/chatmail/core.git
synced 2026-05-08 09:26:29 +03:00
avoid cdata_to_free trick and some more cleanups
This commit is contained in:
@@ -85,6 +85,25 @@ impl<'a> MimeFactory<'a> {
|
|||||||
context,
|
context,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn finalize_mime_message(
|
||||||
|
&mut self,
|
||||||
|
message: *mut mailmime,
|
||||||
|
encrypted: bool,
|
||||||
|
gossiped: bool,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
unsafe {
|
||||||
|
assert!(self.out.is_null()); // guard against double-calls
|
||||||
|
self.out = mmap_string_new(b"\x00" as *const u8 as *const libc::c_char);
|
||||||
|
let mut col: libc::c_int = 0;
|
||||||
|
if 0 != mailmime_write_mem(self.out, &mut col, message) {
|
||||||
|
bail!("could not write memory-mime-message")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.out_encrypted = encrypted;
|
||||||
|
self.out_gossiped = encrypted && gossiped;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Drop for MimeFactory<'a> {
|
impl<'a> Drop for MimeFactory<'a> {
|
||||||
@@ -242,7 +261,7 @@ pub fn dc_mimefactory_load_mdn<'a>(
|
|||||||
|
|
||||||
pub unsafe fn dc_mimefactory_render(
|
pub unsafe fn dc_mimefactory_render(
|
||||||
context: &Context,
|
context: &Context,
|
||||||
factory: &mut MimeFactory,
|
mut 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.");
|
||||||
@@ -729,28 +748,20 @@ pub unsafe fn dc_mimefactory_render(
|
|||||||
let aheader = encrypt_helper.get_aheader().to_string();
|
let aheader = encrypt_helper.get_aheader().to_string();
|
||||||
new_custom_field(imffields_unprotected, "Autocrypt", &aheader);
|
new_custom_field(imffields_unprotected, "Autocrypt", &aheader);
|
||||||
}
|
}
|
||||||
|
let mut finalized = false;
|
||||||
if force_plaintext == 0 {
|
if force_plaintext == 0 {
|
||||||
let was_encrypted = encrypt_helper.try_encrypt(
|
finalized = encrypt_helper.try_encrypt(
|
||||||
factory.context,
|
&mut factory,
|
||||||
&factory.recipients_addr,
|
|
||||||
e2ee_guaranteed,
|
e2ee_guaranteed,
|
||||||
min_verified,
|
min_verified,
|
||||||
do_gossip,
|
do_gossip,
|
||||||
message,
|
message,
|
||||||
imffields_unprotected,
|
imffields_unprotected,
|
||||||
)?;
|
)?;
|
||||||
if was_encrypted {
|
|
||||||
info!(context, "message was encrypted");
|
|
||||||
factory.out_encrypted = true;
|
|
||||||
if do_gossip {
|
|
||||||
factory.out_gossiped = true;
|
|
||||||
}
|
}
|
||||||
|
if !finalized {
|
||||||
|
factory.finalize_mime_message(message, false, false)?;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
factory.out = mmap_string_new(b"\x00" as *const u8 as *const libc::c_char);
|
|
||||||
let mut col: libc::c_int = 0;
|
|
||||||
mailmime_write_mem(factory.out, &mut col, message);
|
|
||||||
encrypt_helper.thanks();
|
|
||||||
cleanup(message);
|
cleanup(message);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
36
src/e2ee.rs
36
src/e2ee.rs
@@ -23,6 +23,7 @@ use mmime::{mailmime_substitute, MAILIMF_NO_ERROR, MAIL_NO_ERROR};
|
|||||||
use crate::aheader::*;
|
use crate::aheader::*;
|
||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
|
use crate::dc_mimefactory::*;
|
||||||
use crate::dc_mimeparser::*;
|
use crate::dc_mimeparser::*;
|
||||||
use crate::dc_tools::*;
|
use crate::dc_tools::*;
|
||||||
use crate::error::*;
|
use crate::error::*;
|
||||||
@@ -36,21 +37,12 @@ use crate::wrapmime::*;
|
|||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct EncryptHelper {
|
pub struct EncryptHelper {
|
||||||
cdata_to_free: Option<Box<dyn Any>>,
|
|
||||||
pub prefer_encrypt: EncryptPreference,
|
pub prefer_encrypt: EncryptPreference,
|
||||||
pub addr: String,
|
pub addr: String,
|
||||||
pub public_key: Key,
|
pub public_key: Key,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EncryptHelper {
|
impl EncryptHelper {
|
||||||
/// 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 _)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn new(context: &Context) -> Result<EncryptHelper> {
|
pub fn new(context: &Context) -> Result<EncryptHelper> {
|
||||||
let e2ee = context.sql.get_config_int(&context, "e2ee_enabled");
|
let e2ee = context.sql.get_config_int(&context, "e2ee_enabled");
|
||||||
let prefer_encrypt = if 0 != e2ee.unwrap_or_default() {
|
let prefer_encrypt = if 0 != e2ee.unwrap_or_default() {
|
||||||
@@ -72,7 +64,6 @@ impl EncryptHelper {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
Ok(EncryptHelper {
|
Ok(EncryptHelper {
|
||||||
cdata_to_free: None,
|
|
||||||
prefer_encrypt: prefer_encrypt,
|
prefer_encrypt: prefer_encrypt,
|
||||||
addr: addr,
|
addr: addr,
|
||||||
public_key: public_key,
|
public_key: public_key,
|
||||||
@@ -87,8 +78,7 @@ impl EncryptHelper {
|
|||||||
|
|
||||||
pub fn try_encrypt(
|
pub fn try_encrypt(
|
||||||
&mut self,
|
&mut self,
|
||||||
context: &Context,
|
factory: &mut MimeFactory,
|
||||||
recipients_addr: &Vec<String>,
|
|
||||||
e2ee_guaranteed: bool,
|
e2ee_guaranteed: bool,
|
||||||
min_verified: libc::c_int,
|
min_verified: libc::c_int,
|
||||||
do_gossip: bool,
|
do_gossip: bool,
|
||||||
@@ -104,11 +94,12 @@ impl EncryptHelper {
|
|||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let context = &factory.context;
|
||||||
let mut keyring = Keyring::default();
|
let mut keyring = Keyring::default();
|
||||||
let mut gossip_headers: Vec<String> = Vec::with_capacity(recipients_addr.len());
|
let mut gossip_headers: Vec<String> = Vec::with_capacity(factory.recipients_addr.len());
|
||||||
|
|
||||||
// determine if we can and should encrypt
|
// determine if we can and should encrypt
|
||||||
for recipient_addr in recipients_addr.iter() {
|
for recipient_addr in factory.recipients_addr.iter() {
|
||||||
if *recipient_addr == self.addr {
|
if *recipient_addr == self.addr {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -175,7 +166,7 @@ impl EncryptHelper {
|
|||||||
part_to_encrypt,
|
part_to_encrypt,
|
||||||
);
|
);
|
||||||
|
|
||||||
for header in gossip_headers {
|
for header in &gossip_headers {
|
||||||
wrapmime::new_custom_field(imffields_encrypted, "Autocrypt-Gossip", &header)
|
wrapmime::new_custom_field(imffields_encrypted, "Autocrypt-Gossip", &header)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,9 +235,11 @@ impl EncryptHelper {
|
|||||||
mmap_string_new(b"\x00" as *const u8 as *const libc::c_char);
|
mmap_string_new(b"\x00" as *const u8 as *const libc::c_char);
|
||||||
let mut col: libc::c_int = 0i32;
|
let mut col: libc::c_int = 0i32;
|
||||||
mailmime_write_mem(plain, &mut col, message_to_encrypt);
|
mailmime_write_mem(plain, &mut col, message_to_encrypt);
|
||||||
|
mailmime_free(message_to_encrypt);
|
||||||
if (*plain).str_0.is_null() || (*plain).len <= 0 {
|
if (*plain).str_0.is_null() || (*plain).len <= 0 {
|
||||||
bail!("could not write/allocate");
|
bail!("could not write/allocate");
|
||||||
}
|
}
|
||||||
|
|
||||||
let ctext = dc_pgp_pk_encrypt(
|
let ctext = dc_pgp_pk_encrypt(
|
||||||
std::slice::from_raw_parts((*plain).str_0 as *const u8, (*plain).len),
|
std::slice::from_raw_parts((*plain).str_0 as *const u8, (*plain).len),
|
||||||
&keyring,
|
&keyring,
|
||||||
@@ -274,20 +267,19 @@ impl EncryptHelper {
|
|||||||
);
|
);
|
||||||
mailmime_smart_add_part(encrypted_part, version_mime);
|
mailmime_smart_add_part(encrypted_part, version_mime);
|
||||||
|
|
||||||
let ctext_bytes = ctext_v.len();
|
// we assume that ctext_v is not dropped until the end
|
||||||
let ctext = ctext_v.strdup();
|
// of this if-scope
|
||||||
self.cdata_to_free = Some(Box::new(ctext));
|
|
||||||
|
|
||||||
let ctext_part: *mut mailmime = new_data_part(
|
let ctext_part: *mut mailmime = new_data_part(
|
||||||
ctext as *mut libc::c_void,
|
ctext_v.as_ptr() as *mut libc::c_void,
|
||||||
ctext_bytes,
|
ctext_v.len(),
|
||||||
"application/octet-stream",
|
"application/octet-stream",
|
||||||
MAILMIME_MECHANISM_7BIT as i32,
|
MAILMIME_MECHANISM_7BIT as i32,
|
||||||
);
|
);
|
||||||
mailmime_smart_add_part(encrypted_part, ctext_part);
|
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;
|
(*encrypted_part).mm_parent = in_out_message;
|
||||||
mailmime_free(message_to_encrypt);
|
let gossiped = !&gossip_headers.is_empty();
|
||||||
|
factory.finalize_mime_message(in_out_message, true, gossiped)?;
|
||||||
Ok(true)
|
Ok(true)
|
||||||
} else {
|
} else {
|
||||||
bail!("encryption failed")
|
bail!("encryption failed")
|
||||||
|
|||||||
Reference in New Issue
Block a user