mirror of
https://github.com/chatmail/core.git
synced 2026-05-02 21:06:31 +03:00
rustify new_data_part() and related sanitizations
This commit is contained in:
@@ -2,7 +2,6 @@ use std::path::Path;
|
|||||||
use std::ptr;
|
use std::ptr;
|
||||||
|
|
||||||
use chrono::TimeZone;
|
use chrono::TimeZone;
|
||||||
use libc::free;
|
|
||||||
use mmime::clist::*;
|
use mmime::clist::*;
|
||||||
use mmime::mailimf_types::*;
|
use mmime::mailimf_types::*;
|
||||||
use mmime::mailimf_types_helper::*;
|
use mmime::mailimf_types_helper::*;
|
||||||
@@ -535,7 +534,7 @@ pub unsafe fn dc_mimefactory_render(
|
|||||||
meta.type_0 = Viewtype::Image;
|
meta.type_0 = Viewtype::Image;
|
||||||
meta.param.set(Param::File, grpimage);
|
meta.param.set(Param::File, grpimage);
|
||||||
|
|
||||||
let res = build_body_file(context, &meta, "group-image");
|
let res = build_body_file(context, &meta, "group-image")?;
|
||||||
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() {
|
||||||
@@ -610,12 +609,10 @@ pub unsafe fn dc_mimefactory_render(
|
|||||||
24 * 1024 * 1024 / 4 * 3 / 1000 / 1000,
|
24 * 1024 * 1024 / 4 * 3 / 1000 / 1000,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
let (file_part, _) = build_body_file(context, &factory.msg, "");
|
let (file_part, _) = build_body_file(context, &factory.msg, "")?;
|
||||||
if !file_part.is_null() {
|
|
||||||
mailmime_smart_add_part(message, file_part);
|
mailmime_smart_add_part(message, file_part);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if !meta_part.is_null() {
|
if !meta_part.is_null() {
|
||||||
mailmime_smart_add_part(message, meta_part);
|
mailmime_smart_add_part(message, meta_part);
|
||||||
}
|
}
|
||||||
@@ -699,8 +696,7 @@ pub unsafe fn dc_mimefactory_render(
|
|||||||
factory.msg.rfc724_mid
|
factory.msg.rfc724_mid
|
||||||
);
|
);
|
||||||
|
|
||||||
let content_type_0 =
|
let content_type_0 = wrapmime::new_content_type("message/disposition-notification")?;
|
||||||
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);
|
||||||
@@ -816,10 +812,14 @@ fn get_subject(
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
fn build_body_file(context: &Context, msg: &Message, base_name: &str) -> (*mut mailmime, String) {
|
fn build_body_file(
|
||||||
|
context: &Context,
|
||||||
|
msg: &Message,
|
||||||
|
base_name: &str,
|
||||||
|
) -> Result<(*mut mailmime, String), Error> {
|
||||||
let path_filename = match msg.param.get(Param::File) {
|
let path_filename = match msg.param.get(Param::File) {
|
||||||
None => {
|
None => {
|
||||||
return (ptr::null_mut(), "".to_string());
|
bail!("msg has no filename");
|
||||||
}
|
}
|
||||||
Some(path) => path,
|
Some(path) => path,
|
||||||
};
|
};
|
||||||
@@ -913,23 +913,16 @@ fn build_body_file(context: &Context, msg: &Message, base_name: &str) -> (*mut m
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let content = wrapmime::new_mailmime_content_type(&mimetype);
|
let content = wrapmime::new_content_type(&mimetype)?;
|
||||||
let filename_encoded = dc_encode_header_words(&filename_to_send).strdup();
|
let filename_encoded = dc_encode_header_words(&filename_to_send);
|
||||||
clist_insert_after(
|
wrapmime::append_ct_param(content, "name", &filename_encoded)?;
|
||||||
(*content).ct_parameters,
|
|
||||||
(*(*content).ct_parameters).last,
|
|
||||||
mailmime_param_new_with_data(
|
|
||||||
b"name\x00" as *const u8 as *const libc::c_char as *mut libc::c_char,
|
|
||||||
filename_encoded,
|
|
||||||
) as *mut libc::c_void,
|
|
||||||
);
|
|
||||||
free(filename_encoded as *mut libc::c_void);
|
|
||||||
let mime_sub = mailmime_new_empty(content, mime_fields);
|
let mime_sub = mailmime_new_empty(content, mime_fields);
|
||||||
let abs_path = dc_get_abs_path(context, path_filename)
|
let abs_path = dc_get_abs_path(context, path_filename)
|
||||||
.to_c_string()
|
.to_c_string()
|
||||||
.unwrap();
|
.unwrap();
|
||||||
mailmime_set_body_file(mime_sub, dc_strdup(abs_path.as_ptr()));
|
mailmime_set_body_file(mime_sub, dc_strdup(abs_path.as_ptr()));
|
||||||
(mime_sub, filename_to_send)
|
Ok((mime_sub, filename_to_send))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
105
src/e2ee.rs
105
src/e2ee.rs
@@ -252,16 +252,16 @@ impl EncryptHelper {
|
|||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
0 as libc::size_t,
|
0 as libc::size_t,
|
||||||
"multipart/encrypted",
|
"multipart/encrypted",
|
||||||
-1,
|
MAILMIME_MECHANISM_BASE64,
|
||||||
);
|
)?;
|
||||||
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")?;
|
||||||
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()),
|
||||||
"application/pgp-encrypted",
|
"application/pgp-encrypted",
|
||||||
MAILMIME_MECHANISM_7BIT as i32,
|
MAILMIME_MECHANISM_7BIT,
|
||||||
);
|
)?;
|
||||||
mailmime_smart_add_part(encrypted_part, version_mime);
|
mailmime_smart_add_part(encrypted_part, version_mime);
|
||||||
|
|
||||||
// we assume that ctext_v is not dropped until the end
|
// we assume that ctext_v is not dropped until the end
|
||||||
@@ -270,8 +270,8 @@ impl EncryptHelper {
|
|||||||
ctext_v.as_ptr() as *mut libc::c_void,
|
ctext_v.as_ptr() as *mut libc::c_void,
|
||||||
ctext_v.len(),
|
ctext_v.len(),
|
||||||
"application/octet-stream",
|
"application/octet-stream",
|
||||||
MAILMIME_MECHANISM_7BIT as i32,
|
MAILMIME_MECHANISM_7BIT,
|
||||||
);
|
)?;
|
||||||
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;
|
||||||
@@ -421,96 +421,39 @@ impl E2eeHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn new_data_part(
|
fn new_data_part(
|
||||||
data: *mut libc::c_void,
|
data: *mut libc::c_void,
|
||||||
data_bytes: libc::size_t,
|
data_bytes: libc::size_t,
|
||||||
default_content_type: &str,
|
content_type: &str,
|
||||||
default_encoding: libc::c_int,
|
default_encoding: u32,
|
||||||
) -> *mut mailmime {
|
) -> Result<*mut mailmime> {
|
||||||
let mut ok_to_continue = true;
|
let content = new_content_type(&content_type)?;
|
||||||
|
unsafe {
|
||||||
let mut encoding: *mut mailmime_mechanism = ptr::null_mut();
|
let mut encoding: *mut mailmime_mechanism = ptr::null_mut();
|
||||||
let content: *mut mailmime_content;
|
if wrapmime::content_type_needs_encoding(content) {
|
||||||
let mime: *mut mailmime;
|
encoding = mailmime_mechanism_new(default_encoding as i32, ptr::null_mut());
|
||||||
let mime_fields: *mut mailmime_fields;
|
ensure!(!encoding.is_null(), "failed to create encoding");
|
||||||
let encoding_type: libc::c_int;
|
|
||||||
let mut do_encoding: libc::c_int;
|
|
||||||
|
|
||||||
let content_type = if default_content_type.is_empty() {
|
|
||||||
"application/octet-stream"
|
|
||||||
} else {
|
|
||||||
default_content_type
|
|
||||||
};
|
|
||||||
content = new_mailmime_content_type(&content_type);
|
|
||||||
if content.is_null() {
|
|
||||||
ok_to_continue = false;
|
|
||||||
} else {
|
|
||||||
do_encoding = 1i32;
|
|
||||||
if (*(*content).ct_type).tp_type == MAILMIME_TYPE_COMPOSITE_TYPE as libc::c_int {
|
|
||||||
let composite: *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
|
|
||||||
}
|
}
|
||||||
}
|
let mime_fields = mailmime_fields_new_with_data(
|
||||||
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, ptr::null_mut());
|
|
||||||
if encoding.is_null() {
|
|
||||||
ok_to_continue = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ok_to_continue {
|
|
||||||
mime_fields = mailmime_fields_new_with_data(
|
|
||||||
encoding,
|
encoding,
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
);
|
);
|
||||||
if mime_fields.is_null() {
|
ensure!(!mime_fields.is_null(), "internal mime error");
|
||||||
ok_to_continue = false;
|
|
||||||
} else {
|
let mime = mailmime_new_empty(content, mime_fields);
|
||||||
mime = mailmime_new_empty(content, mime_fields);
|
ensure!(!mime.is_null(), "internal mime error");
|
||||||
if mime.is_null() {
|
|
||||||
mailmime_fields_free(mime_fields);
|
if (*mime).mm_type == MAILMIME_SINGLE as libc::c_int {
|
||||||
mailmime_content_free(content);
|
if !data.is_null() && data_bytes > 0 {
|
||||||
} else {
|
|
||||||
if !data.is_null()
|
|
||||||
&& data_bytes > 0
|
|
||||||
&& (*mime).mm_type == MAILMIME_SINGLE as libc::c_int
|
|
||||||
{
|
|
||||||
mailmime_set_body_text(mime, data as *mut libc::c_char, data_bytes);
|
mailmime_set_body_text(mime, data as *mut libc::c_char, data_bytes);
|
||||||
}
|
}
|
||||||
return mime;
|
|
||||||
}
|
}
|
||||||
|
return Ok(mime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if ok_to_continue == false {
|
|
||||||
if !encoding.is_null() {
|
|
||||||
mailmime_mechanism_free(encoding);
|
|
||||||
}
|
|
||||||
if !content.is_null() {
|
|
||||||
mailmime_content_free(content);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ptr::null_mut()
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Load public key from database or generate a new one.
|
/// Load public key from database or generate a new one.
|
||||||
///
|
///
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ use crate::error::Error;
|
|||||||
use mmime::clist::*;
|
use mmime::clist::*;
|
||||||
use mmime::mailimf_types::*;
|
use mmime::mailimf_types::*;
|
||||||
use mmime::mailimf_types_helper::*;
|
use mmime::mailimf_types_helper::*;
|
||||||
|
use mmime::mailmime::*;
|
||||||
use mmime::mailmime_disposition::*;
|
use mmime::mailmime_disposition::*;
|
||||||
use mmime::mailmime_types::*;
|
use mmime::mailmime_types::*;
|
||||||
use mmime::mailmime_types_helper::*;
|
use mmime::mailmime_types_helper::*;
|
||||||
@@ -60,7 +61,7 @@ pub fn build_body_text(text: &str) -> Result<*mut mailmime, Error> {
|
|||||||
let mime_fields: *mut mailmime_fields;
|
let mime_fields: *mut mailmime_fields;
|
||||||
let message_part: *mut mailmime;
|
let message_part: *mut mailmime;
|
||||||
|
|
||||||
let content = new_mailmime_content_type("text/plain");
|
let content = new_content_type("text/plain")?;
|
||||||
append_ct_param(content, "charset", "utf-8")?;
|
append_ct_param(content, "charset", "utf-8")?;
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
@@ -92,18 +93,15 @@ pub fn append_ct_param(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_mailmime_content_type(content_type: &str) -> *mut mailmime_content {
|
pub fn new_content_type(content_type: &str) -> Result<*mut mailmime_content, Error> {
|
||||||
let ct = CString::new(content_type).unwrap();
|
let ct = CString::new(content_type).unwrap();
|
||||||
let content: *mut mailmime_content;
|
let content: *mut mailmime_content;
|
||||||
// mailmime_content_new_with_str only parses but does not retain/own ct
|
// mailmime_content_new_with_str only parses but does not retain/own ct
|
||||||
//
|
|
||||||
unsafe {
|
unsafe {
|
||||||
content = mailmime_content_new_with_str(ct.as_ptr());
|
content = mailmime_content_new_with_str(ct.as_ptr());
|
||||||
}
|
}
|
||||||
if content.is_null() {
|
ensure!(!content.is_null(), "mailimf failed to allocate");
|
||||||
panic!("mailimf failed to allocate");
|
Ok(content)
|
||||||
}
|
|
||||||
content
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn set_body_text(part: *mut mailmime, text: &str) -> Result<(), Error> {
|
pub fn set_body_text(part: *mut mailmime, text: &str) -> Result<(), Error> {
|
||||||
@@ -116,3 +114,39 @@ pub fn set_body_text(part: *mut mailmime, text: &str) -> Result<(), Error> {
|
|||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn content_type_needs_encoding(content: *const mailmime_content) -> bool {
|
||||||
|
unsafe {
|
||||||
|
if (*(*content).ct_type).tp_type == MAILMIME_TYPE_COMPOSITE_TYPE as libc::c_int {
|
||||||
|
let composite = (*(*content).ct_type).tp_data.tp_composite_type;
|
||||||
|
match (*composite).ct_type as u32 {
|
||||||
|
MAILMIME_COMPOSITE_TYPE_MESSAGE => as_str((*content).ct_subtype) != "rfc822",
|
||||||
|
MAILMIME_COMPOSITE_TYPE_MULTIPART => false,
|
||||||
|
_ => false,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_needs_encoding() {
|
||||||
|
assert!(content_type_needs_encoding(
|
||||||
|
new_content_type("text/plain").unwrap()
|
||||||
|
));
|
||||||
|
assert!(content_type_needs_encoding(
|
||||||
|
new_content_type("application/octect-stream").unwrap()
|
||||||
|
));
|
||||||
|
assert!(!content_type_needs_encoding(
|
||||||
|
new_content_type("multipart/encrypted").unwrap()
|
||||||
|
));
|
||||||
|
assert!(content_type_needs_encoding(
|
||||||
|
new_content_type("application/pgp-encrypted").unwrap()
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user