mirror of
https://github.com/chatmail/core.git
synced 2026-05-08 09:26:29 +03:00
Merge branch 'master' into fix_securejoin_closure
This commit is contained in:
@@ -1,5 +1,4 @@
|
|||||||
version: 2.1
|
version: 2.1
|
||||||
|
|
||||||
executors:
|
executors:
|
||||||
default:
|
default:
|
||||||
docker:
|
docker:
|
||||||
@@ -153,11 +152,12 @@ jobs:
|
|||||||
- wheelhouse
|
- wheelhouse
|
||||||
|
|
||||||
upload_docs_wheels:
|
upload_docs_wheels:
|
||||||
machine: True
|
machine: true
|
||||||
steps:
|
steps:
|
||||||
- checkout
|
- checkout
|
||||||
- attach_workspace:
|
- attach_workspace:
|
||||||
at: workspace
|
at: workspace
|
||||||
|
- run: pyenv global 3.5.2
|
||||||
- run: ls -laR workspace
|
- run: ls -laR workspace
|
||||||
- run: ci_scripts/ci_upload.sh workspace/py-docs workspace/wheelhouse
|
- run: ci_scripts/ci_upload.sh workspace/py-docs workspace/wheelhouse
|
||||||
|
|
||||||
|
|||||||
8
Cargo.lock
generated
8
Cargo.lock
generated
@@ -479,7 +479,7 @@ dependencies = [
|
|||||||
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lazy_static 1.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"lettre 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"lettre 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
"libc 0.2.62 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"mmime 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
|
"mmime 0.1.2-alpha.0 (git+https://github.com/dignifiedquire/mmime?rev=bccd2c2)",
|
||||||
"native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
"native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-derive 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
"num-traits 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -1192,8 +1192,8 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "mmime"
|
name = "mmime"
|
||||||
version = "0.1.1"
|
version = "0.1.2-alpha.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "git+https://github.com/dignifiedquire/mmime?rev=bccd2c2#bccd2c2c89e9241e05f321c963f638affdccad96"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"charset 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
"charset 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
"chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
"chrono 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||||
@@ -2884,7 +2884,7 @@ dependencies = [
|
|||||||
"checksum miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7108aff85b876d06f22503dcce091e29f76733b2bfdd91eebce81f5e68203a10"
|
"checksum miniz_oxide 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7108aff85b876d06f22503dcce091e29f76733b2bfdd91eebce81f5e68203a10"
|
||||||
"checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23"
|
"checksum mio 0.6.19 (registry+https://github.com/rust-lang/crates.io-index)" = "83f51996a3ed004ef184e16818edc51fadffe8e7ca68be67f9dee67d84d0ff23"
|
||||||
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
|
"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
|
||||||
"checksum mmime 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a1246fa340840c36f1fca1507db82463fbc4c2f7763fe84bfde666c7381e0593"
|
"checksum mmime 0.1.2-alpha.0 (git+https://github.com/dignifiedquire/mmime?rev=bccd2c2)" = "<none>"
|
||||||
"checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e"
|
"checksum native-tls 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4b2df1a4c22fd44a62147fd8f13dd0f95c9d8ca7b2610299b2a2f9cf8964274e"
|
||||||
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
|
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
|
||||||
"checksum nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4dbdc256eaac2e3bd236d93ad999d3479ef775c863dbda3068c4006a92eec51b"
|
"checksum nix 0.13.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4dbdc256eaac2e3bd236d93ad999d3479ef775c863dbda3068c4006a92eec51b"
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ num-traits = "0.2.6"
|
|||||||
native-tls = "0.2.3"
|
native-tls = "0.2.3"
|
||||||
lettre = "0.9.0"
|
lettre = "0.9.0"
|
||||||
imap = "1.0.1"
|
imap = "1.0.1"
|
||||||
mmime = "0.1.0"
|
mmime = { git = "https://github.com/dignifiedquire/mmime", rev = "bccd2c2" }
|
||||||
base64 = "0.10"
|
base64 = "0.10"
|
||||||
charset = "0.1"
|
charset = "0.1"
|
||||||
percent-encoding = "2.0"
|
percent-encoding = "2.0"
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ echo -----------------------
|
|||||||
# Bundle external shared libraries into the wheels
|
# Bundle external shared libraries into the wheels
|
||||||
pushd $WHEELHOUSEDIR
|
pushd $WHEELHOUSEDIR
|
||||||
|
|
||||||
pip install devpi-client
|
pip3 install devpi-client
|
||||||
devpi use https://m.devpi.net
|
devpi use https://m.devpi.net
|
||||||
devpi login dc --password $DEVPI_LOGIN
|
devpi login dc --password $DEVPI_LOGIN
|
||||||
|
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ if [ -n "$TESTS" ]; then
|
|||||||
# see https://github.com/deltachat/deltachat-core-rust/issues/331
|
# see https://github.com/deltachat/deltachat-core-rust/issues/331
|
||||||
# unset DCC_PY_LIVECONFIG
|
# unset DCC_PY_LIVECONFIG
|
||||||
|
|
||||||
tox --workdir "$TOXWORKDIR" -e lint,py27,py35,py36,py37,auditwheels
|
tox --workdir "$TOXWORKDIR" -e lint,py35,py36,py37,auditwheels
|
||||||
popd
|
popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
[tox]
|
[tox]
|
||||||
# make sure to update environment list in travis.yml and appveyor.yml
|
# make sure to update environment list in travis.yml and appveyor.yml
|
||||||
envlist =
|
envlist =
|
||||||
py27
|
|
||||||
py35
|
py35
|
||||||
lint
|
lint
|
||||||
auditwheels
|
auditwheels
|
||||||
|
|||||||
@@ -33,6 +33,7 @@ pub enum Config {
|
|||||||
E2eeEnabled,
|
E2eeEnabled,
|
||||||
#[strum(props(default = "1"))]
|
#[strum(props(default = "1"))]
|
||||||
MdnsEnabled,
|
MdnsEnabled,
|
||||||
|
#[strum(props(default = "1"))]
|
||||||
InboxWatch,
|
InboxWatch,
|
||||||
#[strum(props(default = "1"))]
|
#[strum(props(default = "1"))]
|
||||||
SentboxWatch,
|
SentboxWatch,
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ use percent_encoding::{utf8_percent_encode, NON_ALPHANUMERIC};
|
|||||||
|
|
||||||
use crate::constants::Event;
|
use crate::constants::Event;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::dc_e2ee::*;
|
|
||||||
use crate::dc_loginparam::*;
|
use crate::dc_loginparam::*;
|
||||||
use crate::dc_tools::*;
|
use crate::dc_tools::*;
|
||||||
|
use crate::e2ee;
|
||||||
use crate::imap::*;
|
use crate::imap::*;
|
||||||
use crate::job::*;
|
use crate::job::*;
|
||||||
use crate::oauth2::*;
|
use crate::oauth2::*;
|
||||||
@@ -589,7 +589,7 @@ pub unsafe fn dc_job_do_DC_JOB_CONFIGURE_IMAP(context: &Context, _job: &Job) {
|
|||||||
.ok();
|
.ok();
|
||||||
if !s.shall_stop_ongoing {
|
if !s.shall_stop_ongoing {
|
||||||
progress!(context, 920);
|
progress!(context, 920);
|
||||||
dc_ensure_secret_key_exists(context);
|
e2ee::ensure_secret_key_exists(context);
|
||||||
success = true;
|
success = true;
|
||||||
info!(
|
info!(
|
||||||
context,
|
context,
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ use crate::aheader::EncryptPreference;
|
|||||||
use crate::config::Config;
|
use crate::config::Config;
|
||||||
use crate::constants::*;
|
use crate::constants::*;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::dc_e2ee::*;
|
|
||||||
use crate::dc_loginparam::*;
|
use crate::dc_loginparam::*;
|
||||||
use crate::dc_tools::*;
|
use crate::dc_tools::*;
|
||||||
|
use crate::e2ee;
|
||||||
use crate::error::Result;
|
use crate::error::Result;
|
||||||
use crate::key::*;
|
use crate::key::*;
|
||||||
use crate::message::MessageState;
|
use crate::message::MessageState;
|
||||||
@@ -603,7 +603,7 @@ impl<'a> Contact<'a> {
|
|||||||
});
|
});
|
||||||
ret += &p;
|
ret += &p;
|
||||||
if self_key.is_none() {
|
if self_key.is_none() {
|
||||||
dc_ensure_secret_key_exists(context)?;
|
e2ee::ensure_secret_key_exists(context)?;
|
||||||
self_key = Key::from_self_public(context, &loginparam.addr, &context.sql);
|
self_key = Key::from_self_public(context, &loginparam.addr, &context.sql);
|
||||||
}
|
}
|
||||||
let p = context.stock_str(StockMessage::FingerPrints);
|
let p = context.stock_str(StockMessage::FingerPrints);
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ use crate::chat::*;
|
|||||||
use crate::constants::*;
|
use crate::constants::*;
|
||||||
use crate::contact::*;
|
use crate::contact::*;
|
||||||
use crate::dc_loginparam::*;
|
use crate::dc_loginparam::*;
|
||||||
use crate::dc_move::*;
|
|
||||||
use crate::dc_receive_imf::*;
|
use crate::dc_receive_imf::*;
|
||||||
use crate::dc_tools::*;
|
use crate::dc_tools::*;
|
||||||
use crate::imap::*;
|
use crate::imap::*;
|
||||||
@@ -228,7 +227,7 @@ unsafe fn cb_precheck_imf(
|
|||||||
if as_str(old_server_folder) != server_folder || old_server_uid != server_uid {
|
if as_str(old_server_folder) != server_folder || old_server_uid != server_uid {
|
||||||
dc_update_server_uid(context, rfc724_mid, server_folder, server_uid);
|
dc_update_server_uid(context, rfc724_mid, server_folder, server_uid);
|
||||||
}
|
}
|
||||||
dc_do_heuristics_moves(context, server_folder, msg_id);
|
do_heuristics_moves(context, server_folder, msg_id);
|
||||||
if 0 != mark_seen {
|
if 0 != mark_seen {
|
||||||
job_add(
|
job_add(
|
||||||
context,
|
context,
|
||||||
@@ -575,6 +574,45 @@ pub fn dc_is_mvbox(context: &Context, folder_name: impl AsRef<str>) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn do_heuristics_moves(context: &Context, folder: &str, msg_id: u32) {
|
||||||
|
if context
|
||||||
|
.sql
|
||||||
|
.get_config_int(context, "mvbox_move")
|
||||||
|
.unwrap_or_else(|| 1)
|
||||||
|
== 0
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if !dc_is_inbox(context, folder) && !dc_is_sentbox(context, folder) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok(msg) = dc_msg_new_load(context, msg_id) {
|
||||||
|
if dc_msg_is_setupmessage(&msg) {
|
||||||
|
// do not move setup messages;
|
||||||
|
// there may be a non-delta device that wants to handle it
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if dc_is_mvbox(context, folder) {
|
||||||
|
dc_update_msg_move_state(context, msg.rfc724_mid, MoveState::Stay);
|
||||||
|
}
|
||||||
|
|
||||||
|
// 1 = dc message, 2 = reply to dc message
|
||||||
|
if 0 != msg.is_dc_message {
|
||||||
|
job_add(
|
||||||
|
context,
|
||||||
|
Action::MoveMsg,
|
||||||
|
msg.id as libc::c_int,
|
||||||
|
Params::new(),
|
||||||
|
0,
|
||||||
|
);
|
||||||
|
dc_update_msg_move_state(context, msg.rfc724_mid, MoveState::Moving);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ use crate::config::Config;
|
|||||||
use crate::configure::*;
|
use crate::configure::*;
|
||||||
use crate::constants::*;
|
use crate::constants::*;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::dc_e2ee::*;
|
|
||||||
use crate::dc_tools::*;
|
use crate::dc_tools::*;
|
||||||
|
use crate::e2ee;
|
||||||
use crate::error::*;
|
use crate::error::*;
|
||||||
use crate::job::*;
|
use crate::job::*;
|
||||||
use crate::key::*;
|
use crate::key::*;
|
||||||
@@ -196,7 +196,7 @@ pub fn dc_render_setup_file(context: &Context, passphrase: &str) -> Result<Strin
|
|||||||
passphrase.len() >= 2,
|
passphrase.len() >= 2,
|
||||||
"Passphrase must be at least 2 chars long."
|
"Passphrase must be at least 2 chars long."
|
||||||
);
|
);
|
||||||
let self_addr = dc_ensure_secret_key_exists(context)?;
|
let self_addr = e2ee::ensure_secret_key_exists(context)?;
|
||||||
let private_key = Key::from_self_private(context, self_addr, &context.sql)
|
let private_key = Key::from_self_private(context, self_addr, &context.sql)
|
||||||
.ok_or(format_err!("Failed to get private key."))?;
|
.ok_or(format_err!("Failed to get private key."))?;
|
||||||
let ac_headers = match context
|
let ac_headers = match context
|
||||||
@@ -522,7 +522,7 @@ pub unsafe fn dc_job_do_DC_JOB_IMEX_IMAP(context: &Context, job: &Job) {
|
|||||||
} else {
|
} else {
|
||||||
if what == 1 || what == 11 {
|
if what == 1 || what == 11 {
|
||||||
/* before we export anything, make sure the private key exists */
|
/* before we export anything, make sure the private key exists */
|
||||||
if dc_ensure_secret_key_exists(context).is_err() {
|
if e2ee::ensure_secret_key_exists(context).is_err() {
|
||||||
error!(
|
error!(
|
||||||
context,
|
context,
|
||||||
0,
|
0,
|
||||||
@@ -712,7 +712,7 @@ The macro avoids weird values of 0% or 100% while still working. */
|
|||||||
// TODO should return bool /rtn
|
// TODO should return bool /rtn
|
||||||
#[allow(non_snake_case)]
|
#[allow(non_snake_case)]
|
||||||
unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_int {
|
unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_int {
|
||||||
let mut current_block: u64;
|
let mut ok_to_continue: bool;
|
||||||
let mut success: libc::c_int = 0;
|
let mut success: libc::c_int = 0;
|
||||||
|
|
||||||
let mut delete_dest_file: libc::c_int = 0;
|
let mut delete_dest_file: libc::c_int = 0;
|
||||||
@@ -768,16 +768,14 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_
|
|||||||
.is_err()
|
.is_err()
|
||||||
{
|
{
|
||||||
/* error already logged */
|
/* error already logged */
|
||||||
current_block = 11487273724841241105;
|
ok_to_continue = false;
|
||||||
} else {
|
} else {
|
||||||
current_block = 14648156034262866959;
|
ok_to_continue = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
current_block = 14648156034262866959;
|
ok_to_continue = true;
|
||||||
}
|
}
|
||||||
match current_block {
|
if ok_to_continue {
|
||||||
11487273724841241105 => {}
|
|
||||||
_ => {
|
|
||||||
let mut total_files_cnt = 0;
|
let mut total_files_cnt = 0;
|
||||||
let dir = std::path::Path::new(as_str(context.get_blobdir()));
|
let dir = std::path::Path::new(as_str(context.get_blobdir()));
|
||||||
if let Ok(dir_handle) = std::fs::read_dir(dir) {
|
if let Ok(dir_handle) = std::fs::read_dir(dir) {
|
||||||
@@ -793,7 +791,7 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_
|
|||||||
let mut processed_files_cnt = 0;
|
let mut processed_files_cnt = 0;
|
||||||
for entry in dir_handle {
|
for entry in dir_handle {
|
||||||
if entry.is_err() {
|
if entry.is_err() {
|
||||||
current_block = 2631791190359682872;
|
ok_to_continue = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
let entry = entry.unwrap();
|
let entry = entry.unwrap();
|
||||||
@@ -805,7 +803,7 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_
|
|||||||
.shall_stop_ongoing
|
.shall_stop_ongoing
|
||||||
{
|
{
|
||||||
delete_dest_file = 1;
|
delete_dest_file = 1;
|
||||||
current_block = 11487273724841241105;
|
ok_to_continue = false;
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
processed_files_cnt += 1;
|
processed_files_cnt += 1;
|
||||||
@@ -850,7 +848,7 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_
|
|||||||
&curr_pathNfilename,
|
&curr_pathNfilename,
|
||||||
);
|
);
|
||||||
/* this is not recoverable! writing to the sqlite database should work! */
|
/* this is not recoverable! writing to the sqlite database should work! */
|
||||||
current_block = 11487273724841241105;
|
ok_to_continue = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -872,11 +870,9 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
info!(context, 0, "Backup: No files to copy.",);
|
info!(context, 0, "Backup: No files to copy.",);
|
||||||
current_block = 2631791190359682872;
|
ok_to_continue = true;
|
||||||
}
|
}
|
||||||
match current_block {
|
if ok_to_continue {
|
||||||
11487273724841241105 => {}
|
|
||||||
_ => {
|
|
||||||
if sql
|
if sql
|
||||||
.set_config_int(context, "backup_time", now as i32)
|
.set_config_int(context, "backup_time", now as i32)
|
||||||
.is_ok()
|
.is_ok()
|
||||||
@@ -889,7 +885,6 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_
|
|||||||
success = 1;
|
success = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
error!(
|
error!(
|
||||||
context,
|
context,
|
||||||
@@ -901,7 +896,6 @@ unsafe fn export_backup(context: &Context, dir: *const libc::c_char) -> libc::c_
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
if closed {
|
if closed {
|
||||||
context
|
context
|
||||||
.sql
|
.sql
|
||||||
|
|||||||
@@ -15,9 +15,9 @@ use crate::chat::{self, Chat};
|
|||||||
use crate::constants::*;
|
use crate::constants::*;
|
||||||
use crate::contact::*;
|
use crate::contact::*;
|
||||||
use crate::context::{dc_get_version_str, Context};
|
use crate::context::{dc_get_version_str, Context};
|
||||||
use crate::dc_e2ee::*;
|
|
||||||
use crate::dc_strencode::*;
|
use crate::dc_strencode::*;
|
||||||
use crate::dc_tools::*;
|
use crate::dc_tools::*;
|
||||||
|
use crate::e2ee::*;
|
||||||
use crate::error::Error;
|
use crate::error::Error;
|
||||||
use crate::location;
|
use crate::location;
|
||||||
use crate::message::*;
|
use crate::message::*;
|
||||||
@@ -353,13 +353,7 @@ pub unsafe fn dc_mimefactory_render(factory: &mut dc_mimefactory_t) -> libc::c_i
|
|||||||
let mut force_plaintext: libc::c_int = 0;
|
let mut force_plaintext: libc::c_int = 0;
|
||||||
let mut do_gossip: libc::c_int = 0;
|
let mut do_gossip: libc::c_int = 0;
|
||||||
let mut grpimage = None;
|
let mut grpimage = None;
|
||||||
let mut e2ee_helper = dc_e2ee_helper_t {
|
let mut e2ee_helper = E2eeHelper::default();
|
||||||
encryption_successfull: 0,
|
|
||||||
cdata_to_free: ptr::null_mut(),
|
|
||||||
encrypted: 0,
|
|
||||||
signatures: Default::default(),
|
|
||||||
gossipped_addr: Default::default(),
|
|
||||||
};
|
|
||||||
|
|
||||||
if factory.loaded as libc::c_uint == DC_MF_NOTHING_LOADED as libc::c_int as libc::c_uint
|
if factory.loaded as libc::c_uint == DC_MF_NOTHING_LOADED as libc::c_int as libc::c_uint
|
||||||
|| !factory.out.is_null()
|
|| !factory.out.is_null()
|
||||||
@@ -1033,7 +1027,7 @@ pub unsafe fn dc_mimefactory_render(factory: &mut dc_mimefactory_t) -> libc::c_i
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
if force_plaintext != 2 {
|
if force_plaintext != 2 {
|
||||||
dc_e2ee_encrypt(
|
e2ee_helper.encrypt(
|
||||||
factory.context,
|
factory.context,
|
||||||
factory.recipients_addr,
|
factory.recipients_addr,
|
||||||
force_plaintext,
|
force_plaintext,
|
||||||
@@ -1041,10 +1035,9 @@ pub unsafe fn dc_mimefactory_render(factory: &mut dc_mimefactory_t) -> libc::c_i
|
|||||||
min_verified,
|
min_verified,
|
||||||
do_gossip,
|
do_gossip,
|
||||||
message,
|
message,
|
||||||
&mut e2ee_helper,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if 0 != e2ee_helper.encryption_successfull {
|
if e2ee_helper.encryption_successfull {
|
||||||
factory.out_encrypted = 1;
|
factory.out_encrypted = 1;
|
||||||
if 0 != do_gossip {
|
if 0 != do_gossip {
|
||||||
factory.out_gossiped = 1
|
factory.out_gossiped = 1
|
||||||
@@ -1052,14 +1045,14 @@ pub unsafe fn dc_mimefactory_render(factory: &mut dc_mimefactory_t) -> libc::c_i
|
|||||||
}
|
}
|
||||||
factory.out = mmap_string_new(b"\x00" as *const u8 as *const libc::c_char);
|
factory.out = mmap_string_new(b"\x00" as *const u8 as *const libc::c_char);
|
||||||
mailmime_write_mem(factory.out, &mut col, message);
|
mailmime_write_mem(factory.out, &mut col, message);
|
||||||
success = 1
|
success = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !message.is_null() {
|
if !message.is_null() {
|
||||||
mailmime_free(message);
|
mailmime_free(message);
|
||||||
}
|
}
|
||||||
dc_e2ee_thanks(&mut e2ee_helper);
|
e2ee_helper.thanks();
|
||||||
free(message_text as *mut libc::c_void);
|
free(message_text as *mut libc::c_void);
|
||||||
free(message_text2 as *mut libc::c_void);
|
free(message_text2 as *mut libc::c_void);
|
||||||
free(subject_str as *mut libc::c_void);
|
free(subject_str as *mut libc::c_void);
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ use mmime::other::*;
|
|||||||
use crate::constants::Viewtype;
|
use crate::constants::Viewtype;
|
||||||
use crate::contact::*;
|
use crate::contact::*;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::dc_e2ee::*;
|
|
||||||
use crate::dc_simplify::*;
|
use crate::dc_simplify::*;
|
||||||
use crate::dc_strencode::*;
|
use crate::dc_strencode::*;
|
||||||
use crate::dc_tools::*;
|
use crate::dc_tools::*;
|
||||||
|
use crate::e2ee::*;
|
||||||
use crate::location;
|
use crate::location;
|
||||||
use crate::param::*;
|
use crate::param::*;
|
||||||
use crate::stock::StockMessage;
|
use crate::stock::StockMessage;
|
||||||
@@ -43,7 +43,6 @@ pub struct dc_mimepart_t {
|
|||||||
/* *
|
/* *
|
||||||
* @class dc_mimeparser_t
|
* @class dc_mimeparser_t
|
||||||
*/
|
*/
|
||||||
#[derive(Clone)]
|
|
||||||
#[allow(non_camel_case_types)]
|
#[allow(non_camel_case_types)]
|
||||||
pub struct dc_mimeparser_t<'a> {
|
pub struct dc_mimeparser_t<'a> {
|
||||||
pub parts: Vec<dc_mimepart_t>,
|
pub parts: Vec<dc_mimepart_t>,
|
||||||
@@ -54,7 +53,7 @@ pub struct dc_mimeparser_t<'a> {
|
|||||||
pub subject: *mut libc::c_char,
|
pub subject: *mut libc::c_char,
|
||||||
pub is_send_by_messenger: bool,
|
pub is_send_by_messenger: bool,
|
||||||
pub decrypting_failed: libc::c_int,
|
pub decrypting_failed: libc::c_int,
|
||||||
pub e2ee_helper: dc_e2ee_helper_t,
|
pub e2ee_helper: E2eeHelper,
|
||||||
pub is_forwarded: libc::c_int,
|
pub is_forwarded: libc::c_int,
|
||||||
pub context: &'a Context,
|
pub context: &'a Context,
|
||||||
pub reports: Vec<*mut mailmime>,
|
pub reports: Vec<*mut mailmime>,
|
||||||
@@ -109,7 +108,7 @@ unsafe fn dc_mimeparser_empty(mimeparser: &mut dc_mimeparser_t) {
|
|||||||
mimeparser.is_forwarded = 0i32;
|
mimeparser.is_forwarded = 0i32;
|
||||||
mimeparser.reports.clear();
|
mimeparser.reports.clear();
|
||||||
mimeparser.decrypting_failed = 0i32;
|
mimeparser.decrypting_failed = 0i32;
|
||||||
dc_e2ee_thanks(&mut mimeparser.e2ee_helper);
|
mimeparser.e2ee_helper.thanks();
|
||||||
|
|
||||||
mimeparser.location_kml = None;
|
mimeparser.location_kml = None;
|
||||||
mimeparser.message_kml = None;
|
mimeparser.message_kml = None;
|
||||||
@@ -135,14 +134,12 @@ pub unsafe fn dc_mimeparser_parse<'a>(context: &'a Context, body: &[u8]) -> dc_m
|
|||||||
&mut mimeparser.mimeroot,
|
&mut mimeparser.mimeroot,
|
||||||
);
|
);
|
||||||
if r == MAILIMF_NO_ERROR as libc::c_int && !mimeparser.mimeroot.is_null() {
|
if r == MAILIMF_NO_ERROR as libc::c_int && !mimeparser.mimeroot.is_null() {
|
||||||
dc_e2ee_decrypt(
|
mimeparser
|
||||||
mimeparser.context,
|
.e2ee_helper
|
||||||
mimeparser.mimeroot,
|
.decrypt(mimeparser.context, mimeparser.mimeroot);
|
||||||
&mut mimeparser.e2ee_helper,
|
|
||||||
);
|
|
||||||
let mimeparser_ref = &mut mimeparser;
|
let mimeparser_ref = &mut mimeparser;
|
||||||
dc_mimeparser_parse_mime_recursive(mimeparser_ref, mimeparser_ref.mimeroot);
|
dc_mimeparser_parse_mime_recursive(mimeparser_ref, mimeparser_ref.mimeroot);
|
||||||
let field: *mut mailimf_field = dc_mimeparser_lookup_field(&mut mimeparser, "Subject");
|
let field: *mut mailimf_field = dc_mimeparser_lookup_field(&mimeparser, "Subject");
|
||||||
if !field.is_null() && (*field).fld_type == MAILIMF_FIELD_SUBJECT as libc::c_int {
|
if !field.is_null() && (*field).fld_type == MAILIMF_FIELD_SUBJECT as libc::c_int {
|
||||||
mimeparser.subject = dc_decode_header_words((*(*field).fld_data.fld_subject).sbj_value)
|
mimeparser.subject = dc_decode_header_words((*(*field).fld_data.fld_subject).sbj_value)
|
||||||
}
|
}
|
||||||
@@ -1361,9 +1358,9 @@ unsafe fn do_add_single_file_part(
|
|||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn do_add_single_part(parser: &mut dc_mimeparser_t, mut part: dc_mimepart_t) {
|
unsafe fn do_add_single_part(parser: &mut dc_mimeparser_t, mut part: dc_mimepart_t) {
|
||||||
if 0 != (*parser).e2ee_helper.encrypted && (*parser).e2ee_helper.signatures.len() > 0 {
|
if (*parser).e2ee_helper.encrypted && (*parser).e2ee_helper.signatures.len() > 0 {
|
||||||
part.param.set_int(Param::GuranteeE2ee, 1);
|
part.param.set_int(Param::GuranteeE2ee, 1);
|
||||||
} else if 0 != (*parser).e2ee_helper.encrypted {
|
} else if (*parser).e2ee_helper.encrypted {
|
||||||
part.param.set_int(Param::ErroneousE2ee, 0x2);
|
part.param.set_int(Param::ErroneousE2ee, 0x2);
|
||||||
}
|
}
|
||||||
parser.parts.push(part);
|
parser.parts.push(part);
|
||||||
@@ -1818,19 +1815,22 @@ mod tests {
|
|||||||
let mut mimeparser = dc_mimeparser_parse(&context.ctx, &raw[..]);
|
let mut mimeparser = dc_mimeparser_parse(&context.ctx, &raw[..]);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
as_str(mimeparser.subject as *const libc::c_char),
|
&to_string(mimeparser.subject as *const libc::c_char),
|
||||||
"inner-subject",
|
"inner-subject",
|
||||||
);
|
);
|
||||||
|
|
||||||
let mut of: *mut mailimf_optional_field =
|
let mut of: *mut mailimf_optional_field =
|
||||||
dc_mimeparser_lookup_optional_field(&mimeparser, "X-Special-A");
|
dc_mimeparser_lookup_optional_field(&mimeparser, "X-Special-A");
|
||||||
assert_eq!(as_str((*of).fld_value as *const libc::c_char), "special-a",);
|
assert_eq!(
|
||||||
|
&to_string((*of).fld_value as *const libc::c_char),
|
||||||
|
"special-a",
|
||||||
|
);
|
||||||
|
|
||||||
of = dc_mimeparser_lookup_optional_field(&mimeparser, "Foo");
|
of = dc_mimeparser_lookup_optional_field(&mimeparser, "Foo");
|
||||||
assert_eq!(as_str((*of).fld_value as *const libc::c_char), "Bar",);
|
assert_eq!(&to_string((*of).fld_value as *const libc::c_char), "Bar",);
|
||||||
|
|
||||||
of = dc_mimeparser_lookup_optional_field(&mimeparser, "Chat-Version");
|
of = dc_mimeparser_lookup_optional_field(&mimeparser, "Chat-Version");
|
||||||
assert_eq!(as_str((*of).fld_value as *const libc::c_char), "1.0",);
|
assert_eq!(&to_string((*of).fld_value as *const libc::c_char), "1.0",);
|
||||||
assert_eq!(mimeparser.parts.len(), 1);
|
assert_eq!(mimeparser.parts.len(), 1);
|
||||||
|
|
||||||
dc_mimeparser_unref(&mut mimeparser);
|
dc_mimeparser_unref(&mut mimeparser);
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
use crate::constants::*;
|
|
||||||
use crate::context::*;
|
|
||||||
use crate::job::*;
|
|
||||||
use crate::message::*;
|
|
||||||
use crate::param::Params;
|
|
||||||
|
|
||||||
pub unsafe fn dc_do_heuristics_moves(context: &Context, folder: &str, msg_id: u32) {
|
|
||||||
if context
|
|
||||||
.sql
|
|
||||||
.get_config_int(context, "mvbox_move")
|
|
||||||
.unwrap_or_else(|| 1)
|
|
||||||
== 0
|
|
||||||
{
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if !dc_is_inbox(context, folder) && !dc_is_sentbox(context, folder) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Ok(msg) = dc_msg_new_load(context, msg_id) {
|
|
||||||
if dc_msg_is_setupmessage(&msg) {
|
|
||||||
// do not move setup messages;
|
|
||||||
// there may be a non-delta device that wants to handle it
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if dc_is_mvbox(context, folder) {
|
|
||||||
dc_update_msg_move_state(context, msg.rfc724_mid, MoveState::Stay);
|
|
||||||
}
|
|
||||||
|
|
||||||
// 1 = dc message, 2 = reply to dc message
|
|
||||||
if 0 != msg.is_dc_message {
|
|
||||||
job_add(
|
|
||||||
context,
|
|
||||||
Action::MoveMsg,
|
|
||||||
msg.id as libc::c_int,
|
|
||||||
Params::new(),
|
|
||||||
0,
|
|
||||||
);
|
|
||||||
dc_update_msg_move_state(context, msg.rfc724_mid, MoveState::Moving);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -13,9 +13,8 @@ use sha2::{Digest, Sha256};
|
|||||||
use crate::chat::{self, Chat};
|
use crate::chat::{self, Chat};
|
||||||
use crate::constants::*;
|
use crate::constants::*;
|
||||||
use crate::contact::*;
|
use crate::contact::*;
|
||||||
use crate::context::Context;
|
use crate::context::{do_heuristics_moves, Context};
|
||||||
use crate::dc_mimeparser::*;
|
use crate::dc_mimeparser::*;
|
||||||
use crate::dc_move::*;
|
|
||||||
use crate::dc_securejoin::*;
|
use crate::dc_securejoin::*;
|
||||||
use crate::dc_strencode::*;
|
use crate::dc_strencode::*;
|
||||||
use crate::dc_tools::*;
|
use crate::dc_tools::*;
|
||||||
@@ -735,7 +734,7 @@ unsafe fn add_parts(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
dc_do_heuristics_moves(context, server_folder.as_ref(), *insert_msg_id);
|
do_heuristics_moves(context, server_folder.as_ref(), *insert_msg_id);
|
||||||
cleanup(mime_in_reply_to, mime_references, txt_raw);
|
cleanup(mime_in_reply_to, mime_references, txt_raw);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -1762,7 +1761,7 @@ unsafe fn check_verified_properties(
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if 0 == mimeparser.e2ee_helper.encrypted {
|
if mimeparser.e2ee_helper.encrypted {
|
||||||
verify_fail("This message is not encrypted".into());
|
verify_fail("This message is not encrypted".into());
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1875,10 +1874,7 @@ unsafe fn dc_is_reply_to_known_message(
|
|||||||
if !field.is_null() && (*field).fld_type == MAILIMF_FIELD_IN_REPLY_TO as libc::c_int {
|
if !field.is_null() && (*field).fld_type == MAILIMF_FIELD_IN_REPLY_TO as libc::c_int {
|
||||||
let fld_in_reply_to: *mut mailimf_in_reply_to = (*field).fld_data.fld_in_reply_to;
|
let fld_in_reply_to: *mut mailimf_in_reply_to = (*field).fld_data.fld_in_reply_to;
|
||||||
if !fld_in_reply_to.is_null() {
|
if !fld_in_reply_to.is_null() {
|
||||||
if 0 != is_known_rfc724_mid_in_list(
|
if is_known_rfc724_mid_in_list(context, (*(*field).fld_data.fld_in_reply_to).mid_list) {
|
||||||
context,
|
|
||||||
(*(*field).fld_data.fld_in_reply_to).mid_list,
|
|
||||||
) {
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1887,10 +1883,7 @@ unsafe fn dc_is_reply_to_known_message(
|
|||||||
if !field.is_null() && (*field).fld_type == MAILIMF_FIELD_REFERENCES as libc::c_int {
|
if !field.is_null() && (*field).fld_type == MAILIMF_FIELD_REFERENCES as libc::c_int {
|
||||||
let fld_references: *mut mailimf_references = (*field).fld_data.fld_references;
|
let fld_references: *mut mailimf_references = (*field).fld_data.fld_references;
|
||||||
if !fld_references.is_null() {
|
if !fld_references.is_null() {
|
||||||
if 0 != is_known_rfc724_mid_in_list(
|
if is_known_rfc724_mid_in_list(context, (*(*field).fld_data.fld_references).mid_list) {
|
||||||
context,
|
|
||||||
(*(*field).fld_data.fld_references).mid_list,
|
|
||||||
) {
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1898,29 +1891,18 @@ unsafe fn dc_is_reply_to_known_message(
|
|||||||
0
|
0
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn is_known_rfc724_mid_in_list(context: &Context, mid_list: *const clist) -> libc::c_int {
|
unsafe fn is_known_rfc724_mid_in_list(context: &Context, mid_list: *const clist) -> bool {
|
||||||
if !mid_list.is_null() {
|
if mid_list.is_null() {
|
||||||
let mut cur: *mut clistiter;
|
return false;
|
||||||
cur = (*mid_list).first;
|
|
||||||
while !cur.is_null() {
|
|
||||||
if 0 != is_known_rfc724_mid(
|
|
||||||
context,
|
|
||||||
(if !cur.is_null() {
|
|
||||||
(*cur).data
|
|
||||||
} else {
|
|
||||||
ptr::null_mut()
|
|
||||||
}) as *const libc::c_char,
|
|
||||||
) {
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
cur = if !cur.is_null() {
|
|
||||||
(*cur).next
|
for data in &*mid_list {
|
||||||
} else {
|
if 0 != is_known_rfc724_mid(context, data.cast()) {
|
||||||
ptr::null_mut()
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
0
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check if a message is a reply to a known message (messenger or non-messenger).
|
/// Check if a message is a reply to a known message (messenger or non-messenger).
|
||||||
|
|||||||
@@ -8,10 +8,10 @@ use crate::configure::*;
|
|||||||
use crate::constants::*;
|
use crate::constants::*;
|
||||||
use crate::contact::*;
|
use crate::contact::*;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::dc_e2ee::*;
|
|
||||||
use crate::dc_mimeparser::*;
|
use crate::dc_mimeparser::*;
|
||||||
use crate::dc_token::*;
|
use crate::dc_token::*;
|
||||||
use crate::dc_tools::*;
|
use crate::dc_tools::*;
|
||||||
|
use crate::e2ee::*;
|
||||||
use crate::key::*;
|
use crate::key::*;
|
||||||
use crate::lot::LotState;
|
use crate::lot::LotState;
|
||||||
use crate::message::*;
|
use crate::message::*;
|
||||||
@@ -43,21 +43,25 @@ pub unsafe fn dc_get_securejoin_qr(
|
|||||||
};
|
};
|
||||||
|
|
||||||
let mut fingerprint = ptr::null_mut();
|
let mut fingerprint = ptr::null_mut();
|
||||||
let mut invitenumber: *mut libc::c_char;
|
|
||||||
let mut auth: *mut libc::c_char;
|
|
||||||
let mut qr: Option<String> = None;
|
let mut qr: Option<String> = None;
|
||||||
|
|
||||||
dc_ensure_secret_key_exists(context).ok();
|
ensure_secret_key_exists(context).ok();
|
||||||
invitenumber = dc_token_lookup(context, DC_TOKEN_INVITENUMBER, group_chat_id);
|
let invitenumber = dc_token_lookup(context, DC_TOKEN_INVITENUMBER, group_chat_id)
|
||||||
if invitenumber.is_null() {
|
.unwrap_or_else(|| {
|
||||||
invitenumber = dc_create_id().strdup();
|
let invitenumber_s = dc_create_id();
|
||||||
dc_token_save(context, DC_TOKEN_INVITENUMBER, group_chat_id, invitenumber);
|
dc_token_save(
|
||||||
}
|
context,
|
||||||
auth = dc_token_lookup(context, DC_TOKEN_AUTH, group_chat_id);
|
DC_TOKEN_INVITENUMBER,
|
||||||
if auth.is_null() {
|
group_chat_id,
|
||||||
auth = dc_create_id().strdup();
|
&invitenumber_s,
|
||||||
dc_token_save(context, DC_TOKEN_AUTH, group_chat_id, auth);
|
);
|
||||||
}
|
invitenumber_s
|
||||||
|
});
|
||||||
|
let auth = dc_token_lookup(context, DC_TOKEN_AUTH, group_chat_id).unwrap_or_else(|| {
|
||||||
|
let auth_s = dc_create_id();
|
||||||
|
dc_token_save(context, DC_TOKEN_AUTH, group_chat_id, &auth_s);
|
||||||
|
auth_s
|
||||||
|
});
|
||||||
let self_addr = context.sql.get_config(context, "configured_addr");
|
let self_addr = context.sql.get_config(context, "configured_addr");
|
||||||
|
|
||||||
if self_addr.is_none() {
|
if self_addr.is_none() {
|
||||||
@@ -92,8 +96,8 @@ pub unsafe fn dc_get_securejoin_qr(
|
|||||||
self_addr_urlencoded,
|
self_addr_urlencoded,
|
||||||
&group_name_urlencoded,
|
&group_name_urlencoded,
|
||||||
&chat.grpid,
|
&chat.grpid,
|
||||||
as_str(invitenumber),
|
&invitenumber,
|
||||||
as_str(auth),
|
&auth,
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
error!(
|
error!(
|
||||||
@@ -108,8 +112,8 @@ pub unsafe fn dc_get_securejoin_qr(
|
|||||||
as_str(fingerprint),
|
as_str(fingerprint),
|
||||||
self_addr_urlencoded,
|
self_addr_urlencoded,
|
||||||
self_name_urlencoded,
|
self_name_urlencoded,
|
||||||
as_str(invitenumber),
|
&invitenumber,
|
||||||
as_str(auth),
|
&auth,
|
||||||
))
|
))
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -139,7 +143,7 @@ pub unsafe fn dc_join_securejoin(context: &Context, qr: *const libc::c_char) ->
|
|||||||
let mut join_vg: libc::c_int = 0i32;
|
let mut join_vg: libc::c_int = 0i32;
|
||||||
|
|
||||||
info!(context, 0, "Requesting secure-join ...",);
|
info!(context, 0, "Requesting secure-join ...",);
|
||||||
dc_ensure_secret_key_exists(context).ok();
|
ensure_secret_key_exists(context).ok();
|
||||||
ongoing_allocated = dc_alloc_ongoing(context);
|
ongoing_allocated = dc_alloc_ongoing(context);
|
||||||
|
|
||||||
if !(ongoing_allocated == 0i32) {
|
if !(ongoing_allocated == 0i32) {
|
||||||
@@ -368,7 +372,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
|||||||
mimeparser: &dc_mimeparser_t,
|
mimeparser: &dc_mimeparser_t,
|
||||||
contact_id: uint32_t,
|
contact_id: uint32_t,
|
||||||
) -> libc::c_int {
|
) -> libc::c_int {
|
||||||
let mut current_block: u64;
|
let mut ok_to_continue: bool;
|
||||||
let step: *const libc::c_char;
|
let step: *const libc::c_char;
|
||||||
let join_vg: libc::c_int;
|
let join_vg: libc::c_int;
|
||||||
let mut own_fingerprint: *mut libc::c_char = ptr::null_mut();
|
let mut own_fingerprint: *mut libc::c_char = ptr::null_mut();
|
||||||
@@ -412,10 +416,10 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
|||||||
invitenumber = lookup_field(mimeparser, "Secure-Join-Invitenumber");
|
invitenumber = lookup_field(mimeparser, "Secure-Join-Invitenumber");
|
||||||
if invitenumber.is_null() {
|
if invitenumber.is_null() {
|
||||||
warn!(context, 0, "Secure-join denied (invitenumber missing).",);
|
warn!(context, 0, "Secure-join denied (invitenumber missing).",);
|
||||||
current_block = 4378276786830486580;
|
ok_to_continue = false;
|
||||||
} else if !dc_token_exists(context, DC_TOKEN_INVITENUMBER, invitenumber) {
|
} else if !dc_token_exists(context, DC_TOKEN_INVITENUMBER, as_str(invitenumber)) {
|
||||||
warn!(context, 0, "Secure-join denied (bad invitenumber).",);
|
warn!(context, 0, "Secure-join denied (bad invitenumber).",);
|
||||||
current_block = 4378276786830486580;
|
ok_to_continue = false;
|
||||||
} else {
|
} else {
|
||||||
info!(context, 0, "Secure-join requested.",);
|
info!(context, 0, "Secure-join requested.",);
|
||||||
|
|
||||||
@@ -436,7 +440,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
|||||||
ptr::null(),
|
ptr::null(),
|
||||||
"",
|
"",
|
||||||
);
|
);
|
||||||
current_block = 10256747982273457880;
|
ok_to_continue = true;
|
||||||
}
|
}
|
||||||
} else if strcmp(
|
} else if strcmp(
|
||||||
step,
|
step,
|
||||||
@@ -458,7 +462,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
|||||||
if cond {
|
if cond {
|
||||||
warn!(context, 0, "auth-required message out of sync.",);
|
warn!(context, 0, "auth-required message out of sync.",);
|
||||||
// no error, just aborted somehow or a mail from another handshake
|
// no error, just aborted somehow or a mail from another handshake
|
||||||
current_block = 4378276786830486580;
|
ok_to_continue = false;
|
||||||
} else {
|
} else {
|
||||||
let scanned_fingerprint_of_alice = context
|
let scanned_fingerprint_of_alice = context
|
||||||
.bob
|
.bob
|
||||||
@@ -501,14 +505,14 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
|||||||
could_not_establish_secure_connection(
|
could_not_establish_secure_connection(
|
||||||
context,
|
context,
|
||||||
contact_chat_id,
|
contact_chat_id,
|
||||||
if 0 != mimeparser.e2ee_helper.encrypted {
|
if mimeparser.e2ee_helper.encrypted {
|
||||||
b"No valid signature.\x00" as *const u8 as *const libc::c_char
|
b"No valid signature.\x00" as *const u8 as *const libc::c_char
|
||||||
} else {
|
} else {
|
||||||
b"Not encrypted.\x00" as *const u8 as *const libc::c_char
|
b"Not encrypted.\x00" as *const u8 as *const libc::c_char
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
end_bobs_joining(context, 0i32);
|
end_bobs_joining(context, 0i32);
|
||||||
current_block = 4378276786830486580;
|
ok_to_continue = false;
|
||||||
} else if 0
|
} else if 0
|
||||||
== fingerprint_equals_sender(
|
== fingerprint_equals_sender(
|
||||||
context,
|
context,
|
||||||
@@ -523,7 +527,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
|||||||
as *const libc::c_char,
|
as *const libc::c_char,
|
||||||
);
|
);
|
||||||
end_bobs_joining(context, 0i32);
|
end_bobs_joining(context, 0i32);
|
||||||
current_block = 4378276786830486580;
|
ok_to_continue = false;
|
||||||
} else {
|
} else {
|
||||||
info!(context, 0, "Fingerprint verified.",);
|
info!(context, 0, "Fingerprint verified.",);
|
||||||
own_fingerprint = get_self_fingerprint(context);
|
own_fingerprint = get_self_fingerprint(context);
|
||||||
@@ -546,7 +550,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
|||||||
own_fingerprint,
|
own_fingerprint,
|
||||||
grpid,
|
grpid,
|
||||||
);
|
);
|
||||||
current_block = 10256747982273457880;
|
ok_to_continue = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if strcmp(
|
} else if strcmp(
|
||||||
@@ -571,14 +575,14 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
|||||||
contact_chat_id,
|
contact_chat_id,
|
||||||
b"Fingerprint not provided.\x00" as *const u8 as *const libc::c_char,
|
b"Fingerprint not provided.\x00" as *const u8 as *const libc::c_char,
|
||||||
);
|
);
|
||||||
current_block = 4378276786830486580;
|
ok_to_continue = false;
|
||||||
} else if !encrypted_and_signed(mimeparser, as_str(fingerprint)) {
|
} else if !encrypted_and_signed(mimeparser, as_str(fingerprint)) {
|
||||||
could_not_establish_secure_connection(
|
could_not_establish_secure_connection(
|
||||||
context,
|
context,
|
||||||
contact_chat_id,
|
contact_chat_id,
|
||||||
b"Auth not encrypted.\x00" as *const u8 as *const libc::c_char,
|
b"Auth not encrypted.\x00" as *const u8 as *const libc::c_char,
|
||||||
);
|
);
|
||||||
current_block = 4378276786830486580;
|
ok_to_continue = false;
|
||||||
} else if 0
|
} else if 0
|
||||||
== fingerprint_equals_sender(context, as_str(fingerprint), contact_chat_id)
|
== fingerprint_equals_sender(context, as_str(fingerprint), contact_chat_id)
|
||||||
{
|
{
|
||||||
@@ -588,7 +592,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
|||||||
b"Fingerprint mismatch on inviter-side.\x00" as *const u8
|
b"Fingerprint mismatch on inviter-side.\x00" as *const u8
|
||||||
as *const libc::c_char,
|
as *const libc::c_char,
|
||||||
);
|
);
|
||||||
current_block = 4378276786830486580;
|
ok_to_continue = false;
|
||||||
} else {
|
} else {
|
||||||
info!(context, 0, "Fingerprint verified.",);
|
info!(context, 0, "Fingerprint verified.",);
|
||||||
// verify that the `Secure-Join-Auth:`-header matches the secret written to the QR code
|
// verify that the `Secure-Join-Auth:`-header matches the secret written to the QR code
|
||||||
@@ -600,14 +604,14 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
|||||||
contact_chat_id,
|
contact_chat_id,
|
||||||
b"Auth not provided.\x00" as *const u8 as *const libc::c_char,
|
b"Auth not provided.\x00" as *const u8 as *const libc::c_char,
|
||||||
);
|
);
|
||||||
current_block = 4378276786830486580;
|
ok_to_continue = false;
|
||||||
} else if !dc_token_exists(context, DC_TOKEN_AUTH, auth_0) {
|
} else if !dc_token_exists(context, DC_TOKEN_AUTH, as_str(auth_0)) {
|
||||||
could_not_establish_secure_connection(
|
could_not_establish_secure_connection(
|
||||||
context,
|
context,
|
||||||
contact_chat_id,
|
contact_chat_id,
|
||||||
b"Auth invalid.\x00" as *const u8 as *const libc::c_char,
|
b"Auth invalid.\x00" as *const u8 as *const libc::c_char,
|
||||||
);
|
);
|
||||||
current_block = 4378276786830486580;
|
ok_to_continue = false;
|
||||||
} else if 0 == mark_peer_as_verified(context, as_str(fingerprint)) {
|
} else if 0 == mark_peer_as_verified(context, as_str(fingerprint)) {
|
||||||
could_not_establish_secure_connection(
|
could_not_establish_secure_connection(
|
||||||
context,
|
context,
|
||||||
@@ -615,7 +619,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
|||||||
b"Fingerprint mismatch on inviter-side.\x00" as *const u8
|
b"Fingerprint mismatch on inviter-side.\x00" as *const u8
|
||||||
as *const libc::c_char,
|
as *const libc::c_char,
|
||||||
);
|
);
|
||||||
current_block = 4378276786830486580;
|
ok_to_continue = false;
|
||||||
} else {
|
} else {
|
||||||
Contact::scaleup_origin_by_id(
|
Contact::scaleup_origin_by_id(
|
||||||
context,
|
context,
|
||||||
@@ -640,7 +644,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
|||||||
chat::get_chat_id_by_grpid(context, &grpid, None, ptr::null_mut());
|
chat::get_chat_id_by_grpid(context, &grpid, None, ptr::null_mut());
|
||||||
if group_chat_id == 0i32 as libc::c_uint {
|
if group_chat_id == 0i32 as libc::c_uint {
|
||||||
error!(context, 0, "Chat {} not found.", &grpid);
|
error!(context, 0, "Chat {} not found.", &grpid);
|
||||||
current_block = 4378276786830486580;
|
ok_to_continue = false;
|
||||||
} else {
|
} else {
|
||||||
chat::add_contact_to_chat_ex(
|
chat::add_contact_to_chat_ex(
|
||||||
context,
|
context,
|
||||||
@@ -648,7 +652,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
|||||||
contact_id,
|
contact_id,
|
||||||
0x1i32,
|
0x1i32,
|
||||||
);
|
);
|
||||||
current_block = 10256747982273457880;
|
ok_to_continue = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
send_handshake_msg(
|
send_handshake_msg(
|
||||||
@@ -664,7 +668,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
|||||||
contact_id as uintptr_t,
|
contact_id as uintptr_t,
|
||||||
1000i32 as uintptr_t,
|
1000i32 as uintptr_t,
|
||||||
);
|
);
|
||||||
current_block = 10256747982273457880;
|
ok_to_continue = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -682,7 +686,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
|||||||
}
|
}
|
||||||
if context.bob.read().unwrap().expects != 6 {
|
if context.bob.read().unwrap().expects != 6 {
|
||||||
info!(context, 0, "Message belongs to a different handshake.",);
|
info!(context, 0, "Message belongs to a different handshake.",);
|
||||||
current_block = 4378276786830486580;
|
ok_to_continue = false;
|
||||||
} else {
|
} else {
|
||||||
let cond = {
|
let cond = {
|
||||||
let bob = context.bob.read().unwrap();
|
let bob = context.bob.read().unwrap();
|
||||||
@@ -695,7 +699,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
|||||||
context,
|
context,
|
||||||
0, "Message out of sync or belongs to a different handshake.",
|
0, "Message out of sync or belongs to a different handshake.",
|
||||||
);
|
);
|
||||||
current_block = 4378276786830486580;
|
ok_to_continue = false;
|
||||||
} else {
|
} else {
|
||||||
let scanned_fingerprint_of_alice = context
|
let scanned_fingerprint_of_alice = context
|
||||||
.bob
|
.bob
|
||||||
@@ -745,27 +749,22 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
|||||||
as *const libc::c_char,
|
as *const libc::c_char,
|
||||||
);
|
);
|
||||||
end_bobs_joining(context, 0i32);
|
end_bobs_joining(context, 0i32);
|
||||||
current_block = 4378276786830486580;
|
ok_to_continue = false;
|
||||||
} else {
|
} else {
|
||||||
current_block = 5195798230510548452;
|
ok_to_continue = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
current_block = 5195798230510548452;
|
ok_to_continue = true;
|
||||||
}
|
}
|
||||||
match current_block {
|
if ok_to_continue {
|
||||||
4378276786830486580 => {}
|
if 0 == mark_peer_as_verified(context, &scanned_fingerprint_of_alice) {
|
||||||
_ => {
|
|
||||||
if 0 == mark_peer_as_verified(
|
|
||||||
context,
|
|
||||||
&scanned_fingerprint_of_alice,
|
|
||||||
) {
|
|
||||||
could_not_establish_secure_connection(
|
could_not_establish_secure_connection(
|
||||||
context,
|
context,
|
||||||
contact_chat_id,
|
contact_chat_id,
|
||||||
b"Fingerprint mismatch on joiner-side.\x00" as *const u8
|
b"Fingerprint mismatch on joiner-side.\x00" as *const u8
|
||||||
as *const libc::c_char,
|
as *const libc::c_char,
|
||||||
);
|
);
|
||||||
current_block = 4378276786830486580;
|
ok_to_continue = false;
|
||||||
} else {
|
} else {
|
||||||
Contact::scaleup_origin_by_id(
|
Contact::scaleup_origin_by_id(
|
||||||
context,
|
context,
|
||||||
@@ -780,26 +779,21 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
|||||||
if 0 != join_vg {
|
if 0 != join_vg {
|
||||||
if !addr_equals_self(
|
if !addr_equals_self(
|
||||||
context,
|
context,
|
||||||
as_str(lookup_field(
|
as_str(lookup_field(mimeparser, "Chat-Group-Member-Added")),
|
||||||
mimeparser,
|
|
||||||
"Chat-Group-Member-Added",
|
|
||||||
)),
|
|
||||||
) {
|
) {
|
||||||
info!(
|
info!(
|
||||||
context,
|
context,
|
||||||
0,
|
0,
|
||||||
"Message belongs to a different handshake (scaled up contact anyway to allow creation of group)."
|
"Message belongs to a different handshake (scaled up contact anyway to allow creation of group)."
|
||||||
);
|
);
|
||||||
current_block = 4378276786830486580;
|
ok_to_continue = false;
|
||||||
} else {
|
} else {
|
||||||
current_block = 9180031981464905198;
|
ok_to_continue = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
current_block = 9180031981464905198;
|
ok_to_continue = true;
|
||||||
}
|
}
|
||||||
match current_block {
|
if ok_to_continue {
|
||||||
4378276786830486580 => {}
|
|
||||||
_ => {
|
|
||||||
secure_connection_established(context, contact_chat_id);
|
secure_connection_established(context, contact_chat_id);
|
||||||
context.bob.write().unwrap().expects = 0;
|
context.bob.write().unwrap().expects = 0;
|
||||||
if 0 != join_vg {
|
if 0 != join_vg {
|
||||||
@@ -814,9 +808,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
end_bobs_joining(context, 1i32);
|
end_bobs_joining(context, 1i32);
|
||||||
current_block = 10256747982273457880;
|
ok_to_continue = true;
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -834,7 +826,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
|||||||
if let Ok(contact) = Contact::get_by_id(context, contact_id) {
|
if let Ok(contact) = Contact::get_by_id(context, contact_id) {
|
||||||
if contact.is_verified() == VerifiedStatus::Unverified {
|
if contact.is_verified() == VerifiedStatus::Unverified {
|
||||||
warn!(context, 0, "vg-member-added-received invalid.",);
|
warn!(context, 0, "vg-member-added-received invalid.",);
|
||||||
current_block = 4378276786830486580;
|
ok_to_continue = false;
|
||||||
} else {
|
} else {
|
||||||
context.call_cb(
|
context.call_cb(
|
||||||
Event::SECUREJOIN_INVITER_PROGRESS,
|
Event::SECUREJOIN_INVITER_PROGRESS,
|
||||||
@@ -846,25 +838,22 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
|||||||
contact_id as uintptr_t,
|
contact_id as uintptr_t,
|
||||||
1000i32 as uintptr_t,
|
1000i32 as uintptr_t,
|
||||||
);
|
);
|
||||||
current_block = 10256747982273457880;
|
ok_to_continue = true;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
warn!(context, 0, "vg-member-added-received invalid.",);
|
warn!(context, 0, "vg-member-added-received invalid.",);
|
||||||
current_block = 4378276786830486580;
|
ok_to_continue = false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
current_block = 10256747982273457880;
|
ok_to_continue = true;
|
||||||
}
|
}
|
||||||
match current_block {
|
if ok_to_continue {
|
||||||
4378276786830486580 => {}
|
|
||||||
_ => {
|
|
||||||
if 0 != ret & 0x2i32 {
|
if 0 != ret & 0x2i32 {
|
||||||
ret |= 0x4i32
|
ret |= 0x4i32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
free(own_fingerprint as *mut libc::c_void);
|
free(own_fingerprint as *mut libc::c_void);
|
||||||
|
|
||||||
@@ -955,7 +944,7 @@ unsafe fn encrypted_and_signed(
|
|||||||
mimeparser: &dc_mimeparser_t,
|
mimeparser: &dc_mimeparser_t,
|
||||||
expected_fingerprint: impl AsRef<str>,
|
expected_fingerprint: impl AsRef<str>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if 0 == mimeparser.e2ee_helper.encrypted {
|
if !mimeparser.e2ee_helper.encrypted {
|
||||||
warn!(mimeparser.context, 0, "Message not encrypted.",);
|
warn!(mimeparser.context, 0, "Message not encrypted.",);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,17 +14,14 @@ pub fn dc_token_save(
|
|||||||
context: &Context,
|
context: &Context,
|
||||||
namespc: dc_tokennamespc_t,
|
namespc: dc_tokennamespc_t,
|
||||||
foreign_id: u32,
|
foreign_id: u32,
|
||||||
token: *const libc::c_char,
|
token: &str,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if token.is_null() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// foreign_id may be 0
|
// foreign_id may be 0
|
||||||
sql::execute(
|
sql::execute(
|
||||||
context,
|
context,
|
||||||
&context.sql,
|
&context.sql,
|
||||||
"INSERT INTO tokens (namespc, foreign_id, token, timestamp) VALUES (?, ?, ?, ?);",
|
"INSERT INTO tokens (namespc, foreign_id, token, timestamp) VALUES (?, ?, ?, ?);",
|
||||||
params![namespc as i32, foreign_id as i32, as_str(token), time()],
|
params![namespc as i32, foreign_id as i32, token, time()],
|
||||||
)
|
)
|
||||||
.is_ok()
|
.is_ok()
|
||||||
}
|
}
|
||||||
@@ -33,33 +30,21 @@ pub fn dc_token_lookup(
|
|||||||
context: &Context,
|
context: &Context,
|
||||||
namespc: dc_tokennamespc_t,
|
namespc: dc_tokennamespc_t,
|
||||||
foreign_id: u32,
|
foreign_id: u32,
|
||||||
) -> *mut libc::c_char {
|
) -> Option<String> {
|
||||||
context
|
context.sql.query_row_col::<_, String>(
|
||||||
.sql
|
|
||||||
.query_row_col::<_, String>(
|
|
||||||
context,
|
context,
|
||||||
"SELECT token FROM tokens WHERE namespc=? AND foreign_id=?;",
|
"SELECT token FROM tokens WHERE namespc=? AND foreign_id=?;",
|
||||||
params![namespc as i32, foreign_id as i32],
|
params![namespc as i32, foreign_id as i32],
|
||||||
0,
|
0,
|
||||||
)
|
)
|
||||||
.map(|s| unsafe { s.strdup() })
|
|
||||||
.unwrap_or_else(|| std::ptr::null_mut())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn dc_token_exists(
|
pub fn dc_token_exists(context: &Context, namespc: dc_tokennamespc_t, token: &str) -> bool {
|
||||||
context: &Context,
|
|
||||||
namespc: dc_tokennamespc_t,
|
|
||||||
token: *const libc::c_char,
|
|
||||||
) -> bool {
|
|
||||||
if token.is_null() {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
context
|
context
|
||||||
.sql
|
.sql
|
||||||
.exists(
|
.exists(
|
||||||
"SELECT id FROM tokens WHERE namespc=? AND token=?;",
|
"SELECT id FROM tokens WHERE namespc=? AND token=?;",
|
||||||
params![namespc as i32, as_str(token)],
|
params![namespc as i32, token],
|
||||||
)
|
)
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
//! End-to-end encryption support.
|
//! End-to-end encryption support.
|
||||||
|
|
||||||
|
use std::any::Any;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::ptr;
|
use std::ptr;
|
||||||
@@ -32,36 +33,26 @@ use crate::pgp::*;
|
|||||||
use crate::types::*;
|
use crate::types::*;
|
||||||
use crate::x::*;
|
use crate::x::*;
|
||||||
|
|
||||||
// backups
|
#[derive(Default)]
|
||||||
// attachments of 25 mb brutto should work on the majority of providers
|
pub struct E2eeHelper {
|
||||||
// (brutto examples: web.de=50, 1&1=40, t-online.de=32, gmail=25, posteo=50, yahoo=25, all-inkl=100).
|
pub encryption_successfull: bool,
|
||||||
// as an upper limit, we double the size; the core won't send messages larger than this
|
cdata_to_free: Option<Box<dyn Any>>,
|
||||||
// to get the netto sizes, we subtract 1 mb header-overhead and the base64-overhead.
|
pub encrypted: bool,
|
||||||
// some defaults
|
|
||||||
#[derive(Clone)]
|
|
||||||
#[allow(non_camel_case_types)]
|
|
||||||
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: HashSet<String>,
|
pub signatures: HashSet<String>,
|
||||||
pub gossipped_addr: HashSet<String>,
|
pub gossipped_addr: HashSet<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for dc_e2ee_helper_t {
|
impl E2eeHelper {
|
||||||
fn default() -> Self {
|
/// Frees data referenced by "mailmime" but not freed by mailmime_free(). After calling this function,
|
||||||
dc_e2ee_helper_t {
|
/// in_out_message cannot be used any longer!
|
||||||
encryption_successfull: 0,
|
pub unsafe fn thanks(&mut self) {
|
||||||
cdata_to_free: std::ptr::null_mut(),
|
if let Some(data) = self.cdata_to_free.take() {
|
||||||
encrypted: 0,
|
free(Box::into_raw(data) as *mut _)
|
||||||
signatures: Default::default(),
|
|
||||||
gossipped_addr: Default::default(),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#[allow(non_snake_case)]
|
pub unsafe fn encrypt(
|
||||||
pub unsafe fn dc_e2ee_encrypt(
|
&mut self,
|
||||||
context: &Context,
|
context: &Context,
|
||||||
recipients_addr: *const clist,
|
recipients_addr: *const clist,
|
||||||
force_unencrypted: libc::c_int,
|
force_unencrypted: libc::c_int,
|
||||||
@@ -69,8 +60,7 @@ pub unsafe fn dc_e2ee_encrypt(
|
|||||||
min_verified: libc::c_int,
|
min_verified: libc::c_int,
|
||||||
do_gossip: libc::c_int,
|
do_gossip: libc::c_int,
|
||||||
mut in_out_message: *mut mailmime,
|
mut in_out_message: *mut mailmime,
|
||||||
helper: &mut dc_e2ee_helper_t,
|
) {
|
||||||
) {
|
|
||||||
let mut ok_to_continue = true;
|
let mut ok_to_continue = true;
|
||||||
let mut col: libc::c_int = 0i32;
|
let mut col: libc::c_int = 0i32;
|
||||||
let mut do_encrypt: libc::c_int = 0i32;
|
let mut do_encrypt: libc::c_int = 0i32;
|
||||||
@@ -79,7 +69,6 @@ pub unsafe fn dc_e2ee_encrypt(
|
|||||||
let mut keyring = Keyring::default();
|
let mut keyring = Keyring::default();
|
||||||
let plain: *mut MMAPString = mmap_string_new(b"\x00" as *const u8 as *const libc::c_char);
|
let plain: *mut MMAPString = mmap_string_new(b"\x00" as *const u8 as *const libc::c_char);
|
||||||
let mut peerstates: Vec<Peerstate> = Vec::new();
|
let mut peerstates: Vec<Peerstate> = Vec::new();
|
||||||
*helper = Default::default();
|
|
||||||
|
|
||||||
if !(recipients_addr.is_null()
|
if !(recipients_addr.is_null()
|
||||||
|| in_out_message.is_null()
|
|| in_out_message.is_null()
|
||||||
@@ -172,7 +161,8 @@ pub unsafe fn dc_e2ee_encrypt(
|
|||||||
let mut part_to_encrypt: *mut mailmime =
|
let mut part_to_encrypt: *mut mailmime =
|
||||||
(*in_out_message).mm_data.mm_message.mm_msg_mime;
|
(*in_out_message).mm_data.mm_message.mm_msg_mime;
|
||||||
(*part_to_encrypt).mm_parent = ptr::null_mut();
|
(*part_to_encrypt).mm_parent = ptr::null_mut();
|
||||||
let imffields_encrypted: *mut mailimf_fields = mailimf_fields_new_empty();
|
let 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 */
|
/* mailmime_new_message_data() calls mailmime_fields_new_with_version() which would add the unwanted MIME-Version:-header */
|
||||||
let message_to_encrypt: *mut mailmime = mailmime_new(
|
let message_to_encrypt: *mut mailmime = mailmime_new(
|
||||||
MAILMIME_MESSAGE as libc::c_int,
|
MAILMIME_MESSAGE as libc::c_int,
|
||||||
@@ -188,10 +178,10 @@ pub unsafe fn dc_e2ee_encrypt(
|
|||||||
part_to_encrypt,
|
part_to_encrypt,
|
||||||
);
|
);
|
||||||
if 0 != do_gossip {
|
if 0 != do_gossip {
|
||||||
let iCnt: libc::c_int = peerstates.len() as libc::c_int;
|
let i_cnt = peerstates.len() as libc::c_int;
|
||||||
if iCnt > 1i32 {
|
if i_cnt > 1 {
|
||||||
let mut i: libc::c_int = 0i32;
|
let mut i = 0;
|
||||||
while i < iCnt {
|
while i < i_cnt {
|
||||||
let p = peerstates[i as usize]
|
let p = peerstates[i as usize]
|
||||||
.render_gossip_header(min_verified as usize);
|
.render_gossip_header(min_verified as usize);
|
||||||
|
|
||||||
@@ -209,7 +199,8 @@ pub unsafe fn dc_e2ee_encrypt(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
/* memoryhole headers */
|
/* memoryhole headers */
|
||||||
let mut cur: *mut clistiter = (*(*imffields_unprotected).fld_list).first;
|
let mut cur: *mut clistiter =
|
||||||
|
(*(*imffields_unprotected).fld_list).first;
|
||||||
while !cur.is_null() {
|
while !cur.is_null() {
|
||||||
let mut move_to_encrypted: libc::c_int = 0i32;
|
let mut move_to_encrypted: libc::c_int = 0i32;
|
||||||
let field: *mut mailimf_field = (if !cur.is_null() {
|
let field: *mut mailimf_field = (if !cur.is_null() {
|
||||||
@@ -226,15 +217,18 @@ pub unsafe fn dc_e2ee_encrypt(
|
|||||||
{
|
{
|
||||||
let opt_field: *mut mailimf_optional_field =
|
let opt_field: *mut mailimf_optional_field =
|
||||||
(*field).fld_data.fld_optional_field;
|
(*field).fld_data.fld_optional_field;
|
||||||
if !opt_field.is_null() && !(*opt_field).fld_name.is_null() {
|
if !opt_field.is_null() && !(*opt_field).fld_name.is_null()
|
||||||
|
{
|
||||||
if strncmp(
|
if strncmp(
|
||||||
(*opt_field).fld_name,
|
(*opt_field).fld_name,
|
||||||
b"Secure-Join\x00" as *const u8 as *const libc::c_char,
|
b"Secure-Join\x00" as *const u8
|
||||||
|
as *const libc::c_char,
|
||||||
11,
|
11,
|
||||||
) == 0
|
) == 0
|
||||||
|| strncmp(
|
|| strncmp(
|
||||||
(*opt_field).fld_name,
|
(*opt_field).fld_name,
|
||||||
b"Chat-\x00" as *const u8 as *const libc::c_char,
|
b"Chat-\x00" as *const u8
|
||||||
|
as *const libc::c_char,
|
||||||
5,
|
5,
|
||||||
) == 0
|
) == 0
|
||||||
&& strcmp(
|
&& strcmp(
|
||||||
@@ -296,7 +290,8 @@ pub unsafe fn dc_e2ee_encrypt(
|
|||||||
mailmime_param_new_with_data(
|
mailmime_param_new_with_data(
|
||||||
b"protected-headers\x00" as *const u8 as *const libc::c_char
|
b"protected-headers\x00" as *const u8 as *const libc::c_char
|
||||||
as *mut libc::c_char,
|
as *mut libc::c_char,
|
||||||
b"v1\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,
|
) as *mut libc::c_void,
|
||||||
);
|
);
|
||||||
mailmime_write_mem(plain, &mut col, message_to_encrypt);
|
mailmime_write_mem(plain, &mut col, message_to_encrypt);
|
||||||
@@ -311,13 +306,14 @@ pub unsafe fn dc_e2ee_encrypt(
|
|||||||
) {
|
) {
|
||||||
let ctext_bytes = ctext_v.len();
|
let ctext_bytes = ctext_v.len();
|
||||||
let ctext = ctext_v.strdup();
|
let ctext = ctext_v.strdup();
|
||||||
helper.cdata_to_free = ctext as *mut _;
|
self.cdata_to_free = Some(Box::new(ctext));
|
||||||
|
|
||||||
/* create MIME-structure that will contain the encrypted text */
|
/* create MIME-structure that will contain the encrypted text */
|
||||||
let mut encrypted_part: *mut mailmime = new_data_part(
|
let mut encrypted_part: *mut mailmime = new_data_part(
|
||||||
ptr::null_mut(),
|
ptr::null_mut(),
|
||||||
0i32 as size_t,
|
0i32 as size_t,
|
||||||
b"multipart/encrypted\x00" as *const u8 as *const libc::c_char
|
b"multipart/encrypted\x00" as *const u8
|
||||||
|
as *const libc::c_char
|
||||||
as *mut libc::c_char,
|
as *mut libc::c_char,
|
||||||
-1i32,
|
-1i32,
|
||||||
);
|
);
|
||||||
@@ -332,7 +328,8 @@ pub unsafe fn dc_e2ee_encrypt(
|
|||||||
b"application/pgp-encrypted\x00" as *const u8
|
b"application/pgp-encrypted\x00" as *const u8
|
||||||
as *const libc::c_char
|
as *const libc::c_char
|
||||||
as *mut libc::c_char,
|
as *mut libc::c_char,
|
||||||
) as *mut libc::c_void,
|
)
|
||||||
|
as *mut libc::c_void,
|
||||||
);
|
);
|
||||||
static mut VERSION_CONTENT: [libc::c_char; 13] =
|
static mut VERSION_CONTENT: [libc::c_char; 13] =
|
||||||
[86, 101, 114, 115, 105, 111, 110, 58, 32, 49, 13, 10, 0];
|
[86, 101, 114, 115, 105, 111, 110, 58, 32, 49, 13, 10, 0];
|
||||||
@@ -354,10 +351,11 @@ pub unsafe fn dc_e2ee_encrypt(
|
|||||||
MAILMIME_MECHANISM_7BIT as libc::c_int,
|
MAILMIME_MECHANISM_7BIT as libc::c_int,
|
||||||
);
|
);
|
||||||
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);
|
mailmime_free(message_to_encrypt);
|
||||||
helper.encryption_successfull = 1i32;
|
self.encryption_successfull = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -379,11 +377,119 @@ pub unsafe fn dc_e2ee_encrypt(
|
|||||||
if !plain.is_null() {
|
if !plain.is_null() {
|
||||||
mmap_string_free(plain);
|
mmap_string_free(plain);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub unsafe fn decrypt(&mut self, context: &Context, in_out_message: *mut mailmime) {
|
||||||
|
let mut iterations: libc::c_int;
|
||||||
|
/* 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 imffields: *mut mailimf_fields = mailmime_find_mailimf_fields(in_out_message);
|
||||||
|
let mut message_time = 0;
|
||||||
|
let mut from: *mut libc::c_char = ptr::null_mut();
|
||||||
|
let mut private_keyring = Keyring::default();
|
||||||
|
let mut public_keyring_for_validate = Keyring::default();
|
||||||
|
let mut gossip_headers: *mut mailimf_fields = ptr::null_mut();
|
||||||
|
if !(in_out_message.is_null() || 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 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 != 0 && message_time > time() {
|
||||||
|
message_time = time()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let mut peerstate = None;
|
||||||
|
let autocryptheader = Aheader::from_imffields(from, imffields);
|
||||||
|
if message_time > 0 && !from.is_null() {
|
||||||
|
peerstate = Peerstate::from_addr(context, &context.sql, as_str(from));
|
||||||
|
|
||||||
|
if let Some(ref mut peerstate) = peerstate {
|
||||||
|
if let Some(ref header) = autocryptheader {
|
||||||
|
peerstate.apply_header(&header, message_time);
|
||||||
|
peerstate.save_to_db(&context.sql, false);
|
||||||
|
} else if message_time > peerstate.last_seen_autocrypt
|
||||||
|
&& !contains_report(in_out_message)
|
||||||
|
{
|
||||||
|
peerstate.degrade_encryption(message_time);
|
||||||
|
peerstate.save_to_db(&context.sql, false);
|
||||||
|
}
|
||||||
|
} else if let Some(ref header) = autocryptheader {
|
||||||
|
let p = Peerstate::from_header(context, header, message_time);
|
||||||
|
assert!(p.save_to_db(&context.sql, true));
|
||||||
|
peerstate = Some(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* load private key for decryption */
|
||||||
|
let self_addr = context.sql.get_config(context, "configured_addr");
|
||||||
|
if let Some(self_addr) = self_addr {
|
||||||
|
if private_keyring.load_self_private_for_decrypting(
|
||||||
|
context,
|
||||||
|
self_addr,
|
||||||
|
&context.sql,
|
||||||
|
) {
|
||||||
|
if peerstate.as_ref().map(|p| p.last_seen).unwrap_or_else(|| 0) == 0 {
|
||||||
|
peerstate = Peerstate::from_addr(&context, &context.sql, as_str(from));
|
||||||
|
}
|
||||||
|
if let Some(ref peerstate) = peerstate {
|
||||||
|
if peerstate.degrade_event.is_some() {
|
||||||
|
dc_handle_degrade_event(context, &peerstate);
|
||||||
|
}
|
||||||
|
if let Some(ref key) = peerstate.gossip_key {
|
||||||
|
public_keyring_for_validate.add_ref(key);
|
||||||
|
}
|
||||||
|
if let Some(ref key) = peerstate.public_key {
|
||||||
|
public_keyring_for_validate.add_ref(key);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
iterations = 0i32;
|
||||||
|
while iterations < 10i32 {
|
||||||
|
let mut has_unencrypted_parts: libc::c_int = 0i32;
|
||||||
|
if decrypt_recursive(
|
||||||
|
context,
|
||||||
|
in_out_message,
|
||||||
|
&private_keyring,
|
||||||
|
&public_keyring_for_validate,
|
||||||
|
&mut self.signatures,
|
||||||
|
&mut gossip_headers,
|
||||||
|
&mut has_unencrypted_parts,
|
||||||
|
)
|
||||||
|
.is_err()
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if iterations == 0i32 && 0 == has_unencrypted_parts {
|
||||||
|
self.encrypted = true;
|
||||||
|
}
|
||||||
|
iterations += 1;
|
||||||
|
}
|
||||||
|
if !gossip_headers.is_null() {
|
||||||
|
self.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);
|
||||||
|
}
|
||||||
|
|
||||||
|
free(from as *mut libc::c_void);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
|
||||||
* Tools
|
|
||||||
******************************************************************************/
|
|
||||||
unsafe fn new_data_part(
|
unsafe fn new_data_part(
|
||||||
data: *mut libc::c_void,
|
data: *mut libc::c_void,
|
||||||
data_bytes: size_t,
|
data_bytes: size_t,
|
||||||
@@ -528,111 +634,6 @@ fn load_or_generate_self_public_key(context: &Context, self_addr: impl AsRef<str
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* returns 1 if sth. was decrypted, 0 in other cases */
|
|
||||||
pub unsafe fn dc_e2ee_decrypt(
|
|
||||||
context: &Context,
|
|
||||||
in_out_message: *mut mailmime,
|
|
||||||
helper: &mut dc_e2ee_helper_t,
|
|
||||||
) {
|
|
||||||
let mut iterations: libc::c_int;
|
|
||||||
/* 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 imffields: *mut mailimf_fields = mailmime_find_mailimf_fields(in_out_message);
|
|
||||||
let mut message_time = 0;
|
|
||||||
let mut from: *mut libc::c_char = ptr::null_mut();
|
|
||||||
let mut private_keyring = Keyring::default();
|
|
||||||
let mut public_keyring_for_validate = Keyring::default();
|
|
||||||
let mut gossip_headers: *mut mailimf_fields = ptr::null_mut();
|
|
||||||
if !(in_out_message.is_null() || 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 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 != 0 && message_time > time() {
|
|
||||||
message_time = time()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let mut peerstate = None;
|
|
||||||
let autocryptheader = Aheader::from_imffields(from, imffields);
|
|
||||||
if message_time > 0 && !from.is_null() {
|
|
||||||
peerstate = Peerstate::from_addr(context, &context.sql, as_str(from));
|
|
||||||
|
|
||||||
if let Some(ref mut peerstate) = peerstate {
|
|
||||||
if let Some(ref header) = autocryptheader {
|
|
||||||
peerstate.apply_header(&header, message_time);
|
|
||||||
peerstate.save_to_db(&context.sql, false);
|
|
||||||
} else if message_time > peerstate.last_seen_autocrypt
|
|
||||||
&& 0 == contains_report(in_out_message)
|
|
||||||
{
|
|
||||||
peerstate.degrade_encryption(message_time);
|
|
||||||
peerstate.save_to_db(&context.sql, false);
|
|
||||||
}
|
|
||||||
} else if let Some(ref header) = autocryptheader {
|
|
||||||
let p = Peerstate::from_header(context, header, message_time);
|
|
||||||
assert!(p.save_to_db(&context.sql, true));
|
|
||||||
peerstate = Some(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* load private key for decryption */
|
|
||||||
let self_addr = context.sql.get_config(context, "configured_addr");
|
|
||||||
if let Some(self_addr) = self_addr {
|
|
||||||
if private_keyring.load_self_private_for_decrypting(context, self_addr, &context.sql) {
|
|
||||||
if peerstate.as_ref().map(|p| p.last_seen).unwrap_or_else(|| 0) == 0 {
|
|
||||||
peerstate = Peerstate::from_addr(&context, &context.sql, as_str(from));
|
|
||||||
}
|
|
||||||
if let Some(ref peerstate) = peerstate {
|
|
||||||
if peerstate.degrade_event.is_some() {
|
|
||||||
dc_handle_degrade_event(context, &peerstate);
|
|
||||||
}
|
|
||||||
if let Some(ref key) = peerstate.gossip_key {
|
|
||||||
public_keyring_for_validate.add_ref(key);
|
|
||||||
}
|
|
||||||
if let Some(ref key) = peerstate.public_key {
|
|
||||||
public_keyring_for_validate.add_ref(key);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
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,
|
|
||||||
&mut 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);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(from as *mut libc::c_void);
|
|
||||||
}
|
|
||||||
|
|
||||||
unsafe fn update_gossip_peerstates(
|
unsafe fn update_gossip_peerstates(
|
||||||
context: &Context,
|
context: &Context,
|
||||||
message_time: i64,
|
message_time: i64,
|
||||||
@@ -706,7 +707,6 @@ unsafe fn update_gossip_peerstates(
|
|||||||
gossipped_addr
|
gossipped_addr
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO should return bool /rtn
|
|
||||||
unsafe fn decrypt_recursive(
|
unsafe fn decrypt_recursive(
|
||||||
context: &Context,
|
context: &Context,
|
||||||
mime: *mut mailmime,
|
mime: *mut mailmime,
|
||||||
@@ -715,12 +715,11 @@ unsafe fn decrypt_recursive(
|
|||||||
ret_valid_signatures: &mut HashSet<String>,
|
ret_valid_signatures: &mut HashSet<String>,
|
||||||
ret_gossip_headers: *mut *mut mailimf_fields,
|
ret_gossip_headers: *mut *mut mailimf_fields,
|
||||||
ret_has_unencrypted_parts: *mut libc::c_int,
|
ret_has_unencrypted_parts: *mut libc::c_int,
|
||||||
) -> libc::c_int {
|
) -> Result<()> {
|
||||||
|
ensure!(!mime.is_null(), "Invalid mime reference");
|
||||||
let ct: *mut mailmime_content;
|
let ct: *mut mailmime_content;
|
||||||
let mut cur: *mut clistiter;
|
let mut cur: *mut clistiter;
|
||||||
if mime.is_null() {
|
|
||||||
return 0i32;
|
|
||||||
}
|
|
||||||
if (*mime).mm_type == MAILMIME_MULTIPLE as libc::c_int {
|
if (*mime).mm_type == MAILMIME_MULTIPLE as libc::c_int {
|
||||||
ct = (*mime).mm_content_type;
|
ct = (*mime).mm_content_type;
|
||||||
if !ct.is_null()
|
if !ct.is_null()
|
||||||
@@ -733,7 +732,7 @@ unsafe fn decrypt_recursive(
|
|||||||
cur = (*(*mime).mm_data.mm_multipart.mm_mp_list).first;
|
cur = (*(*mime).mm_data.mm_multipart.mm_mp_list).first;
|
||||||
while !cur.is_null() {
|
while !cur.is_null() {
|
||||||
let mut decrypted_mime: *mut mailmime = ptr::null_mut();
|
let mut decrypted_mime: *mut mailmime = ptr::null_mut();
|
||||||
if 0 != decrypt_part(
|
if decrypt_part(
|
||||||
context,
|
context,
|
||||||
(if !cur.is_null() {
|
(if !cur.is_null() {
|
||||||
(*cur).data
|
(*cur).data
|
||||||
@@ -761,7 +760,7 @@ unsafe fn decrypt_recursive(
|
|||||||
}
|
}
|
||||||
mailmime_substitute(mime, decrypted_mime);
|
mailmime_substitute(mime, decrypted_mime);
|
||||||
mailmime_free(mime);
|
mailmime_free(mime);
|
||||||
return 1i32;
|
return Ok(());
|
||||||
}
|
}
|
||||||
cur = if !cur.is_null() {
|
cur = if !cur.is_null() {
|
||||||
(*cur).next
|
(*cur).next
|
||||||
@@ -773,7 +772,7 @@ unsafe fn decrypt_recursive(
|
|||||||
} else {
|
} else {
|
||||||
cur = (*(*mime).mm_data.mm_multipart.mm_mp_list).first;
|
cur = (*(*mime).mm_data.mm_multipart.mm_mp_list).first;
|
||||||
while !cur.is_null() {
|
while !cur.is_null() {
|
||||||
if 0 != decrypt_recursive(
|
if decrypt_recursive(
|
||||||
context,
|
context,
|
||||||
(if !cur.is_null() {
|
(if !cur.is_null() {
|
||||||
(*cur).data
|
(*cur).data
|
||||||
@@ -785,8 +784,10 @@ unsafe fn decrypt_recursive(
|
|||||||
ret_valid_signatures,
|
ret_valid_signatures,
|
||||||
ret_gossip_headers,
|
ret_gossip_headers,
|
||||||
ret_has_unencrypted_parts,
|
ret_has_unencrypted_parts,
|
||||||
) {
|
)
|
||||||
return 1i32;
|
.is_ok()
|
||||||
|
{
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
cur = if !cur.is_null() {
|
cur = if !cur.is_null() {
|
||||||
(*cur).next
|
(*cur).next
|
||||||
@@ -796,7 +797,7 @@ unsafe fn decrypt_recursive(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (*mime).mm_type == MAILMIME_MESSAGE as libc::c_int {
|
} else if (*mime).mm_type == MAILMIME_MESSAGE as libc::c_int {
|
||||||
if 0 != decrypt_recursive(
|
if decrypt_recursive(
|
||||||
context,
|
context,
|
||||||
(*mime).mm_data.mm_message.mm_msg_mime,
|
(*mime).mm_data.mm_message.mm_msg_mime,
|
||||||
private_keyring,
|
private_keyring,
|
||||||
@@ -804,14 +805,16 @@ unsafe fn decrypt_recursive(
|
|||||||
ret_valid_signatures,
|
ret_valid_signatures,
|
||||||
ret_gossip_headers,
|
ret_gossip_headers,
|
||||||
ret_has_unencrypted_parts,
|
ret_has_unencrypted_parts,
|
||||||
) {
|
)
|
||||||
return 1i32;
|
.is_ok()
|
||||||
|
{
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*ret_has_unencrypted_parts = 1i32
|
*ret_has_unencrypted_parts = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
0
|
Err(format_err!("Failed to decrypt"))
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn decrypt_part(
|
unsafe fn decrypt_part(
|
||||||
@@ -821,7 +824,7 @@ unsafe fn decrypt_part(
|
|||||||
public_keyring_for_validate: &Keyring,
|
public_keyring_for_validate: &Keyring,
|
||||||
ret_valid_signatures: &mut HashSet<String>,
|
ret_valid_signatures: &mut HashSet<String>,
|
||||||
ret_decrypted_mime: *mut *mut mailmime,
|
ret_decrypted_mime: *mut *mut mailmime,
|
||||||
) -> libc::c_int {
|
) -> bool {
|
||||||
let mut ok_to_continue = true;
|
let mut ok_to_continue = true;
|
||||||
let mime_data: *mut mailmime_data;
|
let mime_data: *mut mailmime_data;
|
||||||
let mut mime_transfer_encoding: libc::c_int = MAILMIME_MECHANISM_BINARY as libc::c_int;
|
let mut mime_transfer_encoding: libc::c_int = MAILMIME_MECHANISM_BINARY as libc::c_int;
|
||||||
@@ -830,7 +833,8 @@ unsafe fn decrypt_part(
|
|||||||
/* must not be free()'d */
|
/* must not be free()'d */
|
||||||
let mut decoded_data: *const libc::c_char = ptr::null_mut();
|
let mut decoded_data: *const libc::c_char = ptr::null_mut();
|
||||||
let mut decoded_data_bytes: size_t = 0i32 as size_t;
|
let mut decoded_data_bytes: size_t = 0i32 as size_t;
|
||||||
let mut sth_decrypted: libc::c_int = 0i32;
|
let mut sth_decrypted = false;
|
||||||
|
|
||||||
*ret_decrypted_mime = ptr::null_mut();
|
*ret_decrypted_mime = ptr::null_mut();
|
||||||
mime_data = (*mime).mm_data.mm_single;
|
mime_data = (*mime).mm_data.mm_single;
|
||||||
/* MAILMIME_DATA_FILE indicates, the data is in a file; AFAIK this is not used on parsing */
|
/* MAILMIME_DATA_FILE indicates, the data is in a file; AFAIK this is not used on parsing */
|
||||||
@@ -894,7 +898,7 @@ unsafe fn decrypt_part(
|
|||||||
}
|
}
|
||||||
if ok_to_continue {
|
if ok_to_continue {
|
||||||
/* encrypted, decoded data in decoded_data now ... */
|
/* encrypted, decoded data in decoded_data now ... */
|
||||||
if !(0 == has_decrypted_pgp_armor(decoded_data, decoded_data_bytes as libc::c_int)) {
|
if has_decrypted_pgp_armor(decoded_data, decoded_data_bytes as libc::c_int) {
|
||||||
let add_signatures = if ret_valid_signatures.is_empty() {
|
let add_signatures = if ret_valid_signatures.is_empty() {
|
||||||
Some(ret_valid_signatures)
|
Some(ret_valid_signatures)
|
||||||
} else {
|
} else {
|
||||||
@@ -927,7 +931,7 @@ unsafe fn decrypt_part(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*ret_decrypted_mime = decrypted_mime;
|
*ret_decrypted_mime = decrypted_mime;
|
||||||
sth_decrypted = 1i32
|
sth_decrypted = true;
|
||||||
}
|
}
|
||||||
std::mem::forget(plain);
|
std::mem::forget(plain);
|
||||||
}
|
}
|
||||||
@@ -943,14 +947,7 @@ unsafe fn decrypt_part(
|
|||||||
sth_decrypted
|
sth_decrypted
|
||||||
}
|
}
|
||||||
|
|
||||||
/*******************************************************************************
|
unsafe fn has_decrypted_pgp_armor(str__: *const libc::c_char, mut str_bytes: libc::c_int) -> bool {
|
||||||
* Decrypt
|
|
||||||
******************************************************************************/
|
|
||||||
// TODO should return bool /rtn
|
|
||||||
unsafe fn has_decrypted_pgp_armor(
|
|
||||||
str__: *const libc::c_char,
|
|
||||||
mut str_bytes: libc::c_int,
|
|
||||||
) -> libc::c_int {
|
|
||||||
let str_end: *const libc::c_uchar = (str__ as *const libc::c_uchar).offset(str_bytes as isize);
|
let 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;
|
let mut p: *const libc::c_uchar = str__ as *const libc::c_uchar;
|
||||||
while p < str_end {
|
while p < str_end {
|
||||||
@@ -960,35 +957,23 @@ unsafe fn has_decrypted_pgp_armor(
|
|||||||
p = p.offset(1isize);
|
p = p.offset(1isize);
|
||||||
str_bytes -= 1
|
str_bytes -= 1
|
||||||
}
|
}
|
||||||
if str_bytes > 27i32
|
str_bytes > 27i32
|
||||||
&& strncmp(
|
&& strncmp(
|
||||||
p as *const libc::c_char,
|
p as *const libc::c_char,
|
||||||
b"-----BEGIN PGP MESSAGE-----\x00" as *const u8 as *const libc::c_char,
|
b"-----BEGIN PGP MESSAGE-----\x00" as *const u8 as *const libc::c_char,
|
||||||
27,
|
27,
|
||||||
) == 0
|
) == 0
|
||||||
{
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/// Check if a MIME structure contains a multipart/report part.
|
||||||
* Check if a MIME structure contains a multipart/report part.
|
///
|
||||||
*
|
/// As reports are often unencrypted, we do not reset the Autocrypt header in
|
||||||
* As reports are often unencrypted, we do not reset the Autocrypt header in
|
/// this case.
|
||||||
* this case.
|
///
|
||||||
*
|
/// However, Delta Chat itself has no problem with encrypted multipart/report
|
||||||
* However, Delta Chat itself has no problem with encrypted multipart/report
|
/// parts and MUAs should be encouraged to encrpyt multipart/reports as well so
|
||||||
* parts and MUAs should be encouraged to encrpyt multipart/reports as well so
|
/// that we could use the normal Autocrypt processing.
|
||||||
* that we could use the normal Autocrypt processing.
|
unsafe fn contains_report(mime: *mut mailmime) -> bool {
|
||||||
*
|
|
||||||
* @private
|
|
||||||
* @param mime The mime structure to check
|
|
||||||
* @return 1=multipart/report found in MIME, 0=no multipart/report found
|
|
||||||
*/
|
|
||||||
// TODO should return bool /rtn
|
|
||||||
unsafe fn contains_report(mime: *mut mailmime) -> libc::c_int {
|
|
||||||
if (*mime).mm_type == MAILMIME_MULTIPLE as libc::c_int {
|
if (*mime).mm_type == MAILMIME_MULTIPLE as libc::c_int {
|
||||||
if (*(*(*mime).mm_content_type).ct_type).tp_type
|
if (*(*(*mime).mm_content_type).ct_type).tp_type
|
||||||
== MAILMIME_TYPE_COMPOSITE_TYPE as libc::c_int
|
== MAILMIME_TYPE_COMPOSITE_TYPE as libc::c_int
|
||||||
@@ -1002,19 +987,19 @@ unsafe fn contains_report(mime: *mut mailmime) -> libc::c_int {
|
|||||||
b"report\x00" as *const u8 as *const libc::c_char,
|
b"report\x00" as *const u8 as *const libc::c_char,
|
||||||
) == 0i32
|
) == 0i32
|
||||||
{
|
{
|
||||||
return 1i32;
|
return true;
|
||||||
}
|
}
|
||||||
let mut cur: *mut clistiter;
|
let mut cur: *mut clistiter;
|
||||||
cur = (*(*mime).mm_data.mm_multipart.mm_mp_list).first;
|
cur = (*(*mime).mm_data.mm_multipart.mm_mp_list).first;
|
||||||
while !cur.is_null() {
|
while !cur.is_null() {
|
||||||
if 0 != contains_report(
|
if contains_report(
|
||||||
(if !cur.is_null() {
|
(if !cur.is_null() {
|
||||||
(*cur).data
|
(*cur).data
|
||||||
} else {
|
} else {
|
||||||
ptr::null_mut()
|
ptr::null_mut()
|
||||||
}) as *mut mailmime,
|
}) as *mut mailmime,
|
||||||
) {
|
) {
|
||||||
return 1i32;
|
return true;
|
||||||
}
|
}
|
||||||
cur = if !cur.is_null() {
|
cur = if !cur.is_null() {
|
||||||
(*cur).next
|
(*cur).next
|
||||||
@@ -1023,18 +1008,12 @@ unsafe fn contains_report(mime: *mut mailmime) -> libc::c_int {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if (*mime).mm_type == MAILMIME_MESSAGE as libc::c_int {
|
} else if (*mime).mm_type == MAILMIME_MESSAGE as libc::c_int {
|
||||||
if 0 != contains_report((*mime).mm_data.mm_message.mm_msg_mime) {
|
if contains_report((*mime).mm_data.mm_message.mm_msg_mime) {
|
||||||
return 1i32;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
0
|
false
|
||||||
}
|
|
||||||
|
|
||||||
/* 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 dc_e2ee_thanks(helper: &mut dc_e2ee_helper_t) {
|
|
||||||
free(helper.cdata_to_free);
|
|
||||||
helper.cdata_to_free = ptr::null_mut();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Ensures a private key exists for the configured user.
|
/// Ensures a private key exists for the configured user.
|
||||||
@@ -1046,7 +1025,7 @@ pub unsafe fn dc_e2ee_thanks(helper: &mut dc_e2ee_helper_t) {
|
|||||||
///
|
///
|
||||||
/// If this succeeds you are also guaranteed that the
|
/// If this succeeds you are also guaranteed that the
|
||||||
/// [Config::ConfiguredAddr] is configured, this address is returned.
|
/// [Config::ConfiguredAddr] is configured, this address is returned.
|
||||||
pub fn dc_ensure_secret_key_exists(context: &Context) -> Result<String> {
|
pub fn ensure_secret_key_exists(context: &Context) -> Result<String> {
|
||||||
let self_addr = context
|
let self_addr = context
|
||||||
.get_config(Config::ConfiguredAddr)
|
.get_config(Config::ConfiguredAddr)
|
||||||
.ok_or(format_err!(concat!(
|
.ok_or(format_err!(concat!(
|
||||||
@@ -1070,13 +1049,13 @@ mod tests {
|
|||||||
fn test_prexisting() {
|
fn test_prexisting() {
|
||||||
let t = dummy_context();
|
let t = dummy_context();
|
||||||
let test_addr = configure_alice_keypair(&t.ctx);
|
let test_addr = configure_alice_keypair(&t.ctx);
|
||||||
assert_eq!(dc_ensure_secret_key_exists(&t.ctx).unwrap(), test_addr);
|
assert_eq!(ensure_secret_key_exists(&t.ctx).unwrap(), test_addr);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_not_configured() {
|
fn test_not_configured() {
|
||||||
let t = dummy_context();
|
let t = dummy_context();
|
||||||
assert!(dc_ensure_secret_key_exists(&t.ctx).is_err());
|
assert!(ensure_secret_key_exists(&t.ctx).is_err());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -30,6 +30,7 @@ pub mod configure;
|
|||||||
pub mod constants;
|
pub mod constants;
|
||||||
pub mod contact;
|
pub mod contact;
|
||||||
pub mod context;
|
pub mod context;
|
||||||
|
mod e2ee;
|
||||||
mod imap;
|
mod imap;
|
||||||
pub mod job;
|
pub mod job;
|
||||||
mod job_thread;
|
mod job_thread;
|
||||||
@@ -51,12 +52,10 @@ pub mod x;
|
|||||||
|
|
||||||
pub mod dc_array;
|
pub mod dc_array;
|
||||||
mod dc_dehtml;
|
mod dc_dehtml;
|
||||||
mod dc_e2ee;
|
|
||||||
pub mod dc_imex;
|
pub mod dc_imex;
|
||||||
mod dc_loginparam;
|
mod dc_loginparam;
|
||||||
mod dc_mimefactory;
|
mod dc_mimefactory;
|
||||||
pub mod dc_mimeparser;
|
pub mod dc_mimeparser;
|
||||||
mod dc_move;
|
|
||||||
pub mod dc_receive_imf;
|
pub mod dc_receive_imf;
|
||||||
pub mod dc_securejoin;
|
pub mod dc_securejoin;
|
||||||
mod dc_simplify;
|
mod dc_simplify;
|
||||||
|
|||||||
Reference in New Issue
Block a user