mirror of
https://github.com/chatmail/core.git
synced 2026-04-25 09:26:30 +03:00
- remove many *libc::char usages, and c-pointer from fingerprint
- rustify get_chat_id_by_grpid and streamline returned chat id handling (thereby apprently fixing the test, don't ask)
This commit is contained in:
@@ -1341,7 +1341,7 @@ pub unsafe extern "C" fn dc_join_securejoin(
|
||||
|
||||
let context = &*context;
|
||||
|
||||
dc_securejoin::dc_join_securejoin(context, qr)
|
||||
dc_securejoin::dc_join_securejoin(context, as_str(qr))
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
|
||||
@@ -538,7 +538,7 @@ unsafe fn handle_cmd(line: &str, ctx: Arc<RwLock<Context>>) -> Result<ExitResult
|
||||
"joinqr" => {
|
||||
start_threads(ctx.clone());
|
||||
if !arg0.is_empty() {
|
||||
dc_join_securejoin(&ctx.read().unwrap(), arg1_c);
|
||||
dc_join_securejoin(&ctx.read().unwrap(), arg1);
|
||||
}
|
||||
}
|
||||
"exit" | "quit" => return Ok(ExitResult::Exit),
|
||||
|
||||
@@ -316,7 +316,7 @@ class TestOfflineChat:
|
||||
def test_qr_setup_contact(self, acfactory, lp):
|
||||
ac1 = acfactory.get_configured_offline_account()
|
||||
ac2 = acfactory.get_configured_offline_account()
|
||||
qr = ac1.qr_setup_contact()
|
||||
qr = ac1.get_setup_contact_qr()
|
||||
assert qr.startswith("OPENPGP4FPR:")
|
||||
res = ac2.check_qr(qr)
|
||||
assert res.is_ask_verifycontact()
|
||||
|
||||
23
src/chat.rs
23
src/chat.rs
@@ -1918,16 +1918,7 @@ pub fn get_chat_cnt(context: &Context) -> usize {
|
||||
}
|
||||
}
|
||||
|
||||
pub unsafe fn get_chat_id_by_grpid(
|
||||
context: &Context,
|
||||
grpid: impl AsRef<str>,
|
||||
ret_blocked: Option<&mut Blocked>,
|
||||
ret_verified: *mut libc::c_int,
|
||||
) -> u32 {
|
||||
if !ret_verified.is_null() {
|
||||
*ret_verified = 0;
|
||||
}
|
||||
|
||||
pub fn get_chat_id_by_grpid(context: &Context, grpid: impl AsRef<str>) -> (u32, bool, Blocked) {
|
||||
context
|
||||
.sql
|
||||
.query_row(
|
||||
@@ -1936,18 +1927,12 @@ pub unsafe fn get_chat_id_by_grpid(
|
||||
|row| {
|
||||
let chat_id = row.get(0)?;
|
||||
|
||||
if let Some(b) = ret_blocked {
|
||||
*b = row.get::<_, Option<Blocked>>(1)?.unwrap_or_default();
|
||||
}
|
||||
|
||||
let b = row.get::<_, Option<Blocked>>(1)?.unwrap_or_default();
|
||||
let v = row.get::<_, Option<Chattype>>(2)?.unwrap_or_default();
|
||||
if !ret_verified.is_null() {
|
||||
*ret_verified = (v == Chattype::VerifiedGroup) as libc::c_int;
|
||||
}
|
||||
Ok(chat_id)
|
||||
Ok((chat_id, v == Chattype::VerifiedGroup, b))
|
||||
},
|
||||
)
|
||||
.unwrap_or_default()
|
||||
.unwrap_or((0, false, Blocked::Not))
|
||||
}
|
||||
|
||||
pub fn add_device_msg(context: &Context, chat_id: u32, text: impl AsRef<str>) {
|
||||
|
||||
@@ -1034,7 +1034,6 @@ unsafe fn create_or_lookup_group(
|
||||
let group_explicitly_left: bool;
|
||||
let mut chat_id = 0;
|
||||
let mut chat_id_blocked = Blocked::Not;
|
||||
let mut chat_id_verified = 0;
|
||||
let mut grpid = "".to_string();
|
||||
let mut grpname = std::ptr::null_mut();
|
||||
let to_ids_cnt = to_ids.len();
|
||||
@@ -1216,14 +1215,9 @@ unsafe fn create_or_lookup_group(
|
||||
set_better_msg(mime_parser, &better_msg);
|
||||
|
||||
// check, if we have a chat with this group ID
|
||||
chat_id = chat::get_chat_id_by_grpid(
|
||||
context,
|
||||
&grpid,
|
||||
Some(&mut chat_id_blocked),
|
||||
&mut chat_id_verified,
|
||||
);
|
||||
let (mut chat_id, chat_id_verified, _blocked) = chat::get_chat_id_by_grpid(context, &grpid);
|
||||
if chat_id != 0 {
|
||||
if 0 != chat_id_verified
|
||||
if chat_id_verified
|
||||
&& 0 == check_verified_properties(
|
||||
context,
|
||||
mime_parser,
|
||||
|
||||
@@ -21,7 +21,6 @@ use crate::peerstate::*;
|
||||
use crate::qr::check_qr;
|
||||
use crate::stock::StockMessage;
|
||||
use crate::types::*;
|
||||
use crate::x::*;
|
||||
|
||||
pub const NON_ALPHANUMERIC_WITHOUT_DOT: &AsciiSet = &NON_ALPHANUMERIC.remove(b'.');
|
||||
|
||||
@@ -31,13 +30,7 @@ pub unsafe fn dc_get_securejoin_qr(context: &Context, group_chat_id: uint32_t) -
|
||||
==== Step 1 in "Setup verified contact" protocol ====
|
||||
========================================================= */
|
||||
|
||||
let cleanup = |fingerprint, qr: Option<String>| {
|
||||
free(fingerprint as *mut libc::c_void);
|
||||
qr
|
||||
};
|
||||
|
||||
let mut fingerprint = ptr::null_mut();
|
||||
let mut qr: Option<String> = None;
|
||||
let fingerprint: String;
|
||||
|
||||
ensure_secret_key_exists(context).ok();
|
||||
let invitenumber = dc_token_lookup(context, DC_TOKEN_INVITENUMBER, group_chat_id)
|
||||
@@ -60,7 +53,7 @@ pub unsafe fn dc_get_securejoin_qr(context: &Context, group_chat_id: uint32_t) -
|
||||
|
||||
if self_addr.is_none() {
|
||||
error!(context, 0, "Not configured, cannot generate QR code.",);
|
||||
return cleanup(fingerprint, qr);
|
||||
return None;
|
||||
}
|
||||
|
||||
let self_addr = self_addr.unwrap();
|
||||
@@ -69,18 +62,19 @@ pub unsafe fn dc_get_securejoin_qr(context: &Context, group_chat_id: uint32_t) -
|
||||
.get_config(context, "displayname")
|
||||
.unwrap_or_default();
|
||||
|
||||
fingerprint = get_self_fingerprint(context);
|
||||
|
||||
if fingerprint.is_null() {
|
||||
return cleanup(fingerprint, qr);
|
||||
}
|
||||
fingerprint = match get_self_fingerprint(context) {
|
||||
Some(fp) => fp,
|
||||
None => {
|
||||
return None;
|
||||
}
|
||||
};
|
||||
|
||||
let self_addr_urlencoded =
|
||||
utf8_percent_encode(&self_addr, NON_ALPHANUMERIC_WITHOUT_DOT).to_string();
|
||||
let self_name_urlencoded =
|
||||
utf8_percent_encode(&self_name, NON_ALPHANUMERIC_WITHOUT_DOT).to_string();
|
||||
|
||||
qr = if 0 != group_chat_id {
|
||||
let qr = if 0 != group_chat_id {
|
||||
if let Ok(chat) = Chat::load_from_db(context, group_chat_id) {
|
||||
let group_name = chat.get_name();
|
||||
let group_name_urlencoded =
|
||||
@@ -88,7 +82,7 @@ pub unsafe fn dc_get_securejoin_qr(context: &Context, group_chat_id: uint32_t) -
|
||||
|
||||
Some(format!(
|
||||
"OPENPGP4FPR:{}#a={}&g={}&x={}&i={}&s={}",
|
||||
as_str(fingerprint),
|
||||
fingerprint,
|
||||
self_addr_urlencoded,
|
||||
&group_name_urlencoded,
|
||||
&chat.grpid,
|
||||
@@ -100,57 +94,51 @@ pub unsafe fn dc_get_securejoin_qr(context: &Context, group_chat_id: uint32_t) -
|
||||
context,
|
||||
0, "Cannot get QR-code for chat-id {}", group_chat_id,
|
||||
);
|
||||
return cleanup(fingerprint, qr);
|
||||
return None;
|
||||
}
|
||||
} else {
|
||||
Some(format!(
|
||||
"OPENPGP4FPR:{}#a={}&n={}&i={}&s={}",
|
||||
as_str(fingerprint),
|
||||
self_addr_urlencoded,
|
||||
self_name_urlencoded,
|
||||
&invitenumber,
|
||||
&auth,
|
||||
fingerprint, self_addr_urlencoded, self_name_urlencoded, &invitenumber, &auth,
|
||||
))
|
||||
};
|
||||
|
||||
info!(context, 0, "Generated QR code: {}", qr.as_ref().unwrap());
|
||||
|
||||
cleanup(fingerprint, qr)
|
||||
qr
|
||||
}
|
||||
|
||||
fn get_self_fingerprint(context: &Context) -> *mut libc::c_char {
|
||||
fn get_self_fingerprint(context: &Context) -> Option<String> {
|
||||
if let Some(self_addr) = context.sql.get_config(context, "configured_addr") {
|
||||
if let Some(key) = Key::from_self_public(context, self_addr, &context.sql) {
|
||||
return key.fingerprint_c();
|
||||
return Some(key.fingerprint());
|
||||
}
|
||||
}
|
||||
|
||||
std::ptr::null_mut()
|
||||
None
|
||||
}
|
||||
|
||||
pub unsafe fn dc_join_securejoin(context: &Context, qr: *const libc::c_char) -> uint32_t {
|
||||
pub unsafe fn dc_join_securejoin(context: &Context, qr: &str) -> uint32_t {
|
||||
/* ==========================================================
|
||||
==== Bob - the joiner's side =====
|
||||
==== Step 2 in "Setup verified contact" protocol =====
|
||||
========================================================== */
|
||||
let mut ret_chat_id: libc::c_int = 0i32;
|
||||
let ongoing_allocated: libc::c_int;
|
||||
let mut contact_chat_id: uint32_t = 0i32 as uint32_t;
|
||||
let mut join_vg: libc::c_int = 0i32;
|
||||
let mut contact_chat_id: uint32_t = 0;
|
||||
let mut join_vg: bool = false;
|
||||
|
||||
info!(context, 0, "Requesting secure-join ...",);
|
||||
ensure_secret_key_exists(context).ok();
|
||||
ongoing_allocated = dc_alloc_ongoing(context);
|
||||
|
||||
if !(ongoing_allocated == 0i32) {
|
||||
let qr_scan = check_qr(context, as_str(qr));
|
||||
if ongoing_allocated != 0 {
|
||||
let qr_scan = check_qr(context, &qr);
|
||||
if qr_scan.state != LotState::QrAskVerifyContact
|
||||
&& qr_scan.state != LotState::QrAskVerifyGroup
|
||||
{
|
||||
error!(context, 0, "Unknown QR code.",);
|
||||
} else {
|
||||
contact_chat_id = chat::create_by_contact_id(context, qr_scan.id).unwrap_or_default();
|
||||
if contact_chat_id == 0i32 as libc::c_uint {
|
||||
if contact_chat_id == 0 {
|
||||
error!(context, 0, "Unknown contact.",);
|
||||
} else if !(context
|
||||
.running_state
|
||||
@@ -159,7 +147,7 @@ pub unsafe fn dc_join_securejoin(context: &Context, qr: *const libc::c_char) ->
|
||||
.unwrap()
|
||||
.shall_stop_ongoing)
|
||||
{
|
||||
join_vg = (qr_scan.get_state() == LotState::QrAskVerifyGroup) as libc::c_int;
|
||||
join_vg = qr_scan.get_state() == LotState::QrAskVerifyGroup;
|
||||
{
|
||||
let mut bob = context.bob.write().unwrap();
|
||||
bob.status = 0;
|
||||
@@ -186,14 +174,14 @@ pub unsafe fn dc_join_securejoin(context: &Context, qr: *const libc::c_char) ->
|
||||
chat_id_2_contact_id(context, contact_chat_id) as uintptr_t,
|
||||
400i32 as uintptr_t,
|
||||
);
|
||||
let own_fingerprint: *mut libc::c_char = get_self_fingerprint(context);
|
||||
let own_fingerprint = get_self_fingerprint(context).unwrap();
|
||||
send_handshake_msg(
|
||||
context,
|
||||
contact_chat_id,
|
||||
if 0 != join_vg {
|
||||
b"vg-request-with-auth\x00" as *const u8 as *const libc::c_char
|
||||
if join_vg {
|
||||
"vg-request-with-auth"
|
||||
} else {
|
||||
b"vc-request-with-auth\x00" as *const u8 as *const libc::c_char
|
||||
"vc-request-with-auth"
|
||||
},
|
||||
context
|
||||
.bob
|
||||
@@ -206,8 +194,8 @@ pub unsafe fn dc_join_securejoin(context: &Context, qr: *const libc::c_char) ->
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.to_string(),
|
||||
own_fingerprint,
|
||||
if 0 != join_vg {
|
||||
Some(own_fingerprint),
|
||||
if join_vg {
|
||||
context
|
||||
.bob
|
||||
.read()
|
||||
@@ -223,17 +211,12 @@ pub unsafe fn dc_join_securejoin(context: &Context, qr: *const libc::c_char) ->
|
||||
"".to_string()
|
||||
},
|
||||
);
|
||||
free(own_fingerprint as *mut libc::c_void);
|
||||
} else {
|
||||
context.bob.write().unwrap().expects = 2;
|
||||
send_handshake_msg(
|
||||
context,
|
||||
contact_chat_id,
|
||||
if 0 != join_vg {
|
||||
b"vg-request\x00" as *const u8 as *const libc::c_char
|
||||
} else {
|
||||
b"vc-request\x00" as *const u8 as *const libc::c_char
|
||||
},
|
||||
if join_vg { "vg-request" } else { "vc-request" },
|
||||
context
|
||||
.bob
|
||||
.read()
|
||||
@@ -244,7 +227,7 @@ pub unsafe fn dc_join_securejoin(context: &Context, qr: *const libc::c_char) ->
|
||||
.invitenumber
|
||||
.as_ref()
|
||||
.unwrap(),
|
||||
ptr::null(),
|
||||
None,
|
||||
"",
|
||||
);
|
||||
}
|
||||
@@ -264,19 +247,19 @@ pub unsafe fn dc_join_securejoin(context: &Context, qr: *const libc::c_char) ->
|
||||
}
|
||||
let mut bob = context.bob.write().unwrap();
|
||||
bob.expects = 0;
|
||||
if bob.status == 1 {
|
||||
if 0 != join_vg {
|
||||
ret_chat_id = chat::get_chat_id_by_grpid(
|
||||
let ret_chat_id = if bob.status == 1 {
|
||||
if join_vg {
|
||||
chat::get_chat_id_by_grpid(
|
||||
context,
|
||||
bob.qr_scan.as_ref().unwrap().text2.as_ref().unwrap(),
|
||||
None,
|
||||
ptr::null_mut(),
|
||||
) as libc::c_int
|
||||
)
|
||||
.0
|
||||
} else {
|
||||
ret_chat_id = contact_chat_id as libc::c_int
|
||||
contact_chat_id
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
0
|
||||
};
|
||||
bob.qr_scan = None;
|
||||
|
||||
if 0 != ongoing_allocated {
|
||||
@@ -288,33 +271,31 @@ pub unsafe fn dc_join_securejoin(context: &Context, qr: *const libc::c_char) ->
|
||||
unsafe fn send_handshake_msg(
|
||||
context: &Context,
|
||||
contact_chat_id: uint32_t,
|
||||
step: *const libc::c_char,
|
||||
step: &str,
|
||||
param2: impl AsRef<str>,
|
||||
fingerprint: *const libc::c_char,
|
||||
fingerprint: Option<String>,
|
||||
grpid: impl AsRef<str>,
|
||||
) {
|
||||
let mut msg = dc_msg_new_untyped(context);
|
||||
msg.type_0 = Viewtype::Text;
|
||||
msg.text = Some(format!("Secure-Join: {}", to_string(step)));
|
||||
msg.text = Some(format!("Secure-Join: {}", step));
|
||||
msg.hidden = true;
|
||||
msg.param.set_int(Param::Cmd, 7);
|
||||
if step.is_null() {
|
||||
if step.is_empty() {
|
||||
msg.param.remove(Param::Arg);
|
||||
} else {
|
||||
msg.param.set(Param::Arg, as_str(step));
|
||||
msg.param.set(Param::Arg, step);
|
||||
}
|
||||
if !param2.as_ref().is_empty() {
|
||||
msg.param.set(Param::Arg2, param2);
|
||||
}
|
||||
if !fingerprint.is_null() {
|
||||
msg.param.set(Param::Arg3, as_str(fingerprint));
|
||||
if let Some(fp) = fingerprint {
|
||||
msg.param.set(Param::Arg3, fp);
|
||||
}
|
||||
if !grpid.as_ref().is_empty() {
|
||||
msg.param.set(Param::Arg4, grpid.as_ref());
|
||||
}
|
||||
if strcmp(step, b"vg-request\x00" as *const u8 as *const libc::c_char) == 0i32
|
||||
|| strcmp(step, b"vc-request\x00" as *const u8 as *const libc::c_char) == 0i32
|
||||
{
|
||||
if step == "vg-request" || step == "vc-request" {
|
||||
msg.param.set_int(
|
||||
Param::ForcePlaintext,
|
||||
ForcePlaintext::AddAutocryptHeader as i32,
|
||||
@@ -326,7 +307,7 @@ unsafe fn send_handshake_msg(
|
||||
chat::send_msg(context, contact_chat_id, &mut msg).unwrap();
|
||||
}
|
||||
|
||||
unsafe fn chat_id_2_contact_id(context: &Context, contact_chat_id: uint32_t) -> uint32_t {
|
||||
fn chat_id_2_contact_id(context: &Context, contact_chat_id: uint32_t) -> uint32_t {
|
||||
let contacts = chat::get_chat_contacts(context, contact_chat_id);
|
||||
if contacts.len() == 1 {
|
||||
contacts[0]
|
||||
@@ -365,25 +346,22 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
||||
contact_id: uint32_t,
|
||||
) -> libc::c_int {
|
||||
let mut ok_to_continue: bool;
|
||||
let step: *const libc::c_char;
|
||||
let join_vg: libc::c_int;
|
||||
let mut own_fingerprint: *mut libc::c_char = ptr::null_mut();
|
||||
let step: String;
|
||||
let join_vg: bool;
|
||||
let own_fingerprint: String;
|
||||
let contact_chat_id: u32;
|
||||
let contact_chat_id_blocked: Blocked;
|
||||
let mut grpid = "".to_string();
|
||||
let mut ret: libc::c_int = 0i32;
|
||||
|
||||
if !(contact_id <= 9i32 as libc::c_uint) {
|
||||
if !(contact_id <= DC_CONTACT_ID_LAST_SPECIAL) {
|
||||
step = lookup_field(mimeparser, "Secure-Join");
|
||||
if !step.is_null() {
|
||||
if !step.is_empty() {
|
||||
info!(
|
||||
context,
|
||||
0,
|
||||
">>>>>>>>>>>>>>>>>>>>>>>>> secure-join message \'{}\' received",
|
||||
as_str(step),
|
||||
0, ">>>>>>>>>>>>>>>>>>>>>>>>> secure-join message \'{}\' received", step,
|
||||
);
|
||||
join_vg = (strncmp(step, b"vg-\x00" as *const u8 as *const libc::c_char, 3) == 0)
|
||||
as libc::c_int;
|
||||
join_vg = step.starts_with("vg-");
|
||||
let (id, bl) = chat::create_or_lookup_by_contact_id(context, contact_id, Blocked::Not)
|
||||
.unwrap_or_default();
|
||||
contact_chat_id = id;
|
||||
@@ -393,9 +371,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
||||
chat::unblock(context, contact_chat_id);
|
||||
}
|
||||
ret = 0x2i32;
|
||||
if strcmp(step, b"vg-request\x00" as *const u8 as *const libc::c_char) == 0i32
|
||||
|| strcmp(step, b"vc-request\x00" as *const u8 as *const libc::c_char) == 0i32
|
||||
{
|
||||
if step == "vg-request" || step == "vc-request" {
|
||||
/* =========================================================
|
||||
==== Alice - the inviter side ====
|
||||
==== Step 3 in "Setup verified contact" protocol ====
|
||||
@@ -404,12 +380,11 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
||||
// it just ensures, we have Bobs key now. If we do _not_ have the key because eg. MitM has removed it,
|
||||
// send_message() will fail with the error "End-to-end-encryption unavailable unexpectedly.", so, there is no additional check needed here.
|
||||
// verify that the `Secure-Join-Invitenumber:`-header matches invitenumber written to the QR code
|
||||
let invitenumber: *const libc::c_char;
|
||||
invitenumber = lookup_field(mimeparser, "Secure-Join-Invitenumber");
|
||||
if invitenumber.is_null() {
|
||||
let invitenumber = lookup_field(mimeparser, "Secure-Join-Invitenumber");
|
||||
if invitenumber == "" {
|
||||
warn!(context, 0, "Secure-join denied (invitenumber missing).",);
|
||||
ok_to_continue = false;
|
||||
} else if !dc_token_exists(context, DC_TOKEN_INVITENUMBER, as_str(invitenumber)) {
|
||||
} else if !dc_token_exists(context, DC_TOKEN_INVITENUMBER, &invitenumber) {
|
||||
warn!(context, 0, "Secure-join denied (bad invitenumber).",);
|
||||
ok_to_continue = false;
|
||||
} else {
|
||||
@@ -423,32 +398,24 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
||||
send_handshake_msg(
|
||||
context,
|
||||
contact_chat_id,
|
||||
if 0 != join_vg {
|
||||
b"vg-auth-required\x00" as *const u8 as *const libc::c_char
|
||||
if join_vg {
|
||||
"vg-auth-required"
|
||||
} else {
|
||||
b"vc-auth-required\x00" as *const u8 as *const libc::c_char
|
||||
"vc-auth-required"
|
||||
},
|
||||
"",
|
||||
ptr::null(),
|
||||
None,
|
||||
"",
|
||||
);
|
||||
ok_to_continue = true;
|
||||
}
|
||||
} else if strcmp(
|
||||
step,
|
||||
b"vg-auth-required\x00" as *const u8 as *const libc::c_char,
|
||||
) == 0i32
|
||||
|| strcmp(
|
||||
step,
|
||||
b"vc-auth-required\x00" as *const u8 as *const libc::c_char,
|
||||
) == 0i32
|
||||
{
|
||||
} else if step == "vg-auth-required" || step == "vc-auth-required" {
|
||||
let cond = {
|
||||
let bob = context.bob.read().unwrap();
|
||||
let scan = bob.qr_scan.as_ref();
|
||||
scan.is_none()
|
||||
|| bob.expects != 2
|
||||
|| 0 != join_vg && scan.unwrap().state != LotState::QrAskVerifyGroup
|
||||
|| join_vg && scan.unwrap().state != LotState::QrAskVerifyGroup
|
||||
};
|
||||
|
||||
if cond {
|
||||
@@ -479,7 +446,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.to_string();
|
||||
if 0 != join_vg {
|
||||
if join_vg {
|
||||
grpid = context
|
||||
.bob
|
||||
.read()
|
||||
@@ -498,9 +465,9 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
||||
context,
|
||||
contact_chat_id,
|
||||
if mimeparser.e2ee_helper.encrypted {
|
||||
b"No valid signature.\x00" as *const u8 as *const libc::c_char
|
||||
"No valid signature."
|
||||
} else {
|
||||
b"Not encrypted.\x00" as *const u8 as *const libc::c_char
|
||||
"Not encrypted."
|
||||
},
|
||||
);
|
||||
end_bobs_joining(context, 0i32);
|
||||
@@ -513,14 +480,13 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
||||
could_not_establish_secure_connection(
|
||||
context,
|
||||
contact_chat_id,
|
||||
b"Fingerprint mismatch on joiner-side.\x00" as *const u8
|
||||
as *const libc::c_char,
|
||||
"Fingerprint mismatch on joiner-side.",
|
||||
);
|
||||
end_bobs_joining(context, 0i32);
|
||||
ok_to_continue = false;
|
||||
} else {
|
||||
info!(context, 0, "Fingerprint verified.",);
|
||||
own_fingerprint = get_self_fingerprint(context);
|
||||
own_fingerprint = get_self_fingerprint(context).unwrap();
|
||||
context.call_cb(
|
||||
Event::SECUREJOIN_JOINER_PROGRESS,
|
||||
contact_id as uintptr_t,
|
||||
@@ -531,27 +497,19 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
||||
send_handshake_msg(
|
||||
context,
|
||||
contact_chat_id,
|
||||
if 0 != join_vg {
|
||||
b"vg-request-with-auth\x00" as *const u8 as *const libc::c_char
|
||||
if join_vg {
|
||||
"vg-request-with-auth"
|
||||
} else {
|
||||
b"vc-request-with-auth\x00" as *const u8 as *const libc::c_char
|
||||
"vc-request-with-auth"
|
||||
},
|
||||
auth,
|
||||
own_fingerprint,
|
||||
Some(own_fingerprint),
|
||||
grpid,
|
||||
);
|
||||
ok_to_continue = true;
|
||||
}
|
||||
}
|
||||
} else if strcmp(
|
||||
step,
|
||||
b"vg-request-with-auth\x00" as *const u8 as *const libc::c_char,
|
||||
) == 0i32
|
||||
|| strcmp(
|
||||
step,
|
||||
b"vc-request-with-auth\x00" as *const u8 as *const libc::c_char,
|
||||
) == 0i32
|
||||
{
|
||||
} else if step == "vg-request-with-auth" || step == "vc-request-with-auth" {
|
||||
/* ============================================================
|
||||
==== Alice - the inviter side ====
|
||||
==== Steps 5+6 in "Setup verified contact" protocol ====
|
||||
@@ -559,54 +517,50 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
||||
============================================================ */
|
||||
// verify that Secure-Join-Fingerprint:-header matches the fingerprint of Bob
|
||||
let fingerprint = lookup_field(mimeparser, "Secure-Join-Fingerprint");
|
||||
if fingerprint.is_null() {
|
||||
if fingerprint.is_empty() {
|
||||
could_not_establish_secure_connection(
|
||||
context,
|
||||
contact_chat_id,
|
||||
b"Fingerprint not provided.\x00" as *const u8 as *const libc::c_char,
|
||||
"Fingerprint not provided.",
|
||||
);
|
||||
ok_to_continue = false;
|
||||
} else if !encrypted_and_signed(mimeparser, as_str(fingerprint)) {
|
||||
} else if !encrypted_and_signed(mimeparser, &fingerprint) {
|
||||
could_not_establish_secure_connection(
|
||||
context,
|
||||
contact_chat_id,
|
||||
b"Auth not encrypted.\x00" as *const u8 as *const libc::c_char,
|
||||
"Auth not encrypted.",
|
||||
);
|
||||
ok_to_continue = false;
|
||||
} else if !fingerprint_equals_sender(context, as_str(fingerprint), contact_chat_id)
|
||||
{
|
||||
} else if !fingerprint_equals_sender(context, &fingerprint, contact_chat_id) {
|
||||
could_not_establish_secure_connection(
|
||||
context,
|
||||
contact_chat_id,
|
||||
b"Fingerprint mismatch on inviter-side.\x00" as *const u8
|
||||
as *const libc::c_char,
|
||||
"Fingerprint mismatch on inviter-side.",
|
||||
);
|
||||
ok_to_continue = false;
|
||||
} else {
|
||||
info!(context, 0, "Fingerprint verified.",);
|
||||
// verify that the `Secure-Join-Auth:`-header matches the secret written to the QR code
|
||||
let auth_0: *const libc::c_char;
|
||||
auth_0 = lookup_field(mimeparser, "Secure-Join-Auth");
|
||||
if auth_0.is_null() {
|
||||
let auth_0 = lookup_field(mimeparser, "Secure-Join-Auth");
|
||||
if auth_0.is_empty() {
|
||||
could_not_establish_secure_connection(
|
||||
context,
|
||||
contact_chat_id,
|
||||
b"Auth not provided.\x00" as *const u8 as *const libc::c_char,
|
||||
"Auth not provided.",
|
||||
);
|
||||
ok_to_continue = false;
|
||||
} else if !dc_token_exists(context, DC_TOKEN_AUTH, as_str(auth_0)) {
|
||||
} else if !dc_token_exists(context, DC_TOKEN_AUTH, &auth_0) {
|
||||
could_not_establish_secure_connection(
|
||||
context,
|
||||
contact_chat_id,
|
||||
b"Auth invalid.\x00" as *const u8 as *const libc::c_char,
|
||||
"Auth invalid.",
|
||||
);
|
||||
ok_to_continue = false;
|
||||
} else if mark_peer_as_verified(context, as_str(fingerprint)).is_err() {
|
||||
} else if mark_peer_as_verified(context, fingerprint).is_err() {
|
||||
could_not_establish_secure_connection(
|
||||
context,
|
||||
contact_chat_id,
|
||||
b"Fingerprint mismatch on inviter-side.\x00" as *const u8
|
||||
as *const libc::c_char,
|
||||
"Fingerprint mismatch on inviter-side.",
|
||||
);
|
||||
ok_to_continue = false;
|
||||
} else {
|
||||
@@ -627,11 +581,10 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
||||
contact_id as uintptr_t,
|
||||
600i32 as uintptr_t,
|
||||
);
|
||||
if 0 != join_vg {
|
||||
grpid = to_string(lookup_field(mimeparser, "Secure-Join-Group"));
|
||||
let group_chat_id: uint32_t =
|
||||
chat::get_chat_id_by_grpid(context, &grpid, None, ptr::null_mut());
|
||||
if group_chat_id == 0i32 as libc::c_uint {
|
||||
if join_vg {
|
||||
grpid = lookup_field(mimeparser, "Secure-Join-Group");
|
||||
let (group_chat_id, _, _) = chat::get_chat_id_by_grpid(context, &grpid);
|
||||
if group_chat_id == 0 {
|
||||
error!(context, 0, "Chat {} not found.", &grpid);
|
||||
ok_to_continue = false;
|
||||
} else {
|
||||
@@ -647,9 +600,9 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
||||
send_handshake_msg(
|
||||
context,
|
||||
contact_chat_id,
|
||||
b"vc-contact-confirm\x00" as *const u8 as *const libc::c_char,
|
||||
"vc-contact-confirm",
|
||||
"",
|
||||
ptr::null(),
|
||||
None,
|
||||
"",
|
||||
);
|
||||
context.call_cb(
|
||||
@@ -661,16 +614,8 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if strcmp(
|
||||
step,
|
||||
b"vg-member-added\x00" as *const u8 as *const libc::c_char,
|
||||
) == 0i32
|
||||
|| strcmp(
|
||||
step,
|
||||
b"vc-contact-confirm\x00" as *const u8 as *const libc::c_char,
|
||||
) == 0i32
|
||||
{
|
||||
if 0 != join_vg {
|
||||
} else if step == "vg-member-added" || step == "vc-contact-confirm" {
|
||||
if join_vg {
|
||||
ret = 0x1i32
|
||||
}
|
||||
if context.bob.read().unwrap().expects != 6 {
|
||||
@@ -681,7 +626,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
||||
let bob = context.bob.read().unwrap();
|
||||
let scan = bob.qr_scan.as_ref();
|
||||
scan.is_none()
|
||||
|| 0 != join_vg && scan.unwrap().state != LotState::QrAskVerifyGroup
|
||||
|| join_vg && scan.unwrap().state != LotState::QrAskVerifyGroup
|
||||
};
|
||||
if cond {
|
||||
warn!(
|
||||
@@ -702,7 +647,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
||||
.unwrap()
|
||||
.to_string();
|
||||
|
||||
if 0 != join_vg {
|
||||
if join_vg {
|
||||
grpid = context
|
||||
.bob
|
||||
.read()
|
||||
@@ -716,26 +661,23 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
||||
.to_string();
|
||||
}
|
||||
|
||||
let mut vg_expect_encrypted: libc::c_int = 1i32;
|
||||
if 0 != join_vg {
|
||||
let mut is_verified_group: libc::c_int = 0i32;
|
||||
chat::get_chat_id_by_grpid(
|
||||
context,
|
||||
grpid,
|
||||
None,
|
||||
&mut is_verified_group,
|
||||
);
|
||||
if 0 == is_verified_group {
|
||||
vg_expect_encrypted = 0i32
|
||||
}
|
||||
}
|
||||
if 0 != vg_expect_encrypted {
|
||||
let vg_expect_encrypted = if join_vg {
|
||||
let (_, is_verified_group, _) =
|
||||
chat::get_chat_id_by_grpid(context, grpid);
|
||||
// when joining a non-verified group
|
||||
// the vg-member-added message may be unencrypted
|
||||
// when not all group members have keys or prefer encryption.
|
||||
// So only expect encryption if this is a verified group
|
||||
is_verified_group
|
||||
} else {
|
||||
true
|
||||
};
|
||||
if vg_expect_encrypted {
|
||||
if !encrypted_and_signed(mimeparser, &scanned_fingerprint_of_alice) {
|
||||
could_not_establish_secure_connection(
|
||||
context,
|
||||
contact_chat_id,
|
||||
b"Contact confirm message not encrypted.\x00" as *const u8
|
||||
as *const libc::c_char,
|
||||
"Contact confirm message not encrypted.",
|
||||
);
|
||||
end_bobs_joining(context, 0i32);
|
||||
ok_to_continue = false;
|
||||
@@ -752,8 +694,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
||||
could_not_establish_secure_connection(
|
||||
context,
|
||||
contact_chat_id,
|
||||
b"Fingerprint mismatch on joiner-side.\x00" as *const u8
|
||||
as *const libc::c_char,
|
||||
"Fingerprint mismatch on joiner-side.",
|
||||
);
|
||||
ok_to_continue = false;
|
||||
} else {
|
||||
@@ -767,10 +708,10 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
||||
0i32 as uintptr_t,
|
||||
0i32 as uintptr_t,
|
||||
);
|
||||
if 0 != join_vg {
|
||||
if join_vg {
|
||||
if !addr_equals_self(
|
||||
context,
|
||||
as_str(lookup_field(mimeparser, "Chat-Group-Member-Added")),
|
||||
lookup_field(mimeparser, "Chat-Group-Member-Added"),
|
||||
) {
|
||||
info!(
|
||||
context,
|
||||
@@ -787,14 +728,13 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
||||
if ok_to_continue {
|
||||
secure_connection_established(context, contact_chat_id);
|
||||
context.bob.write().unwrap().expects = 0;
|
||||
if 0 != join_vg {
|
||||
if join_vg {
|
||||
send_handshake_msg(
|
||||
context,
|
||||
contact_chat_id,
|
||||
b"vg-member-added-received\x00" as *const u8
|
||||
as *const libc::c_char,
|
||||
"vg-member-added-received",
|
||||
"",
|
||||
ptr::null(),
|
||||
None,
|
||||
"",
|
||||
);
|
||||
}
|
||||
@@ -805,11 +745,7 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if strcmp(
|
||||
step,
|
||||
b"vg-member-added-received\x00" as *const u8 as *const libc::c_char,
|
||||
) == 0i32
|
||||
{
|
||||
} else if step == "vg-member-added-received" {
|
||||
/* ============================================================
|
||||
==== Alice - the inviter side ====
|
||||
==== Step 8 in "Out-of-band verified groups" protocol ====
|
||||
@@ -846,8 +782,6 @@ pub unsafe fn dc_handle_securejoin_handshake(
|
||||
}
|
||||
}
|
||||
|
||||
free(own_fingerprint as *mut libc::c_void);
|
||||
|
||||
ret
|
||||
}
|
||||
|
||||
@@ -873,9 +807,9 @@ unsafe fn secure_connection_established(context: &Context, contact_chat_id: uint
|
||||
);
|
||||
}
|
||||
|
||||
unsafe fn lookup_field(mimeparser: &dc_mimeparser_t, key: &str) -> *const libc::c_char {
|
||||
let mut value: *const libc::c_char = ptr::null();
|
||||
unsafe fn lookup_field(mimeparser: &dc_mimeparser_t, key: &str) -> String {
|
||||
let field: *mut mailimf_field = dc_mimeparser_lookup_field(mimeparser, key);
|
||||
let mut value: *const libc::c_char = ptr::null();
|
||||
if field.is_null()
|
||||
|| (*field).fld_type != MAILIMF_FIELD_OPTIONAL_FIELD as libc::c_int
|
||||
|| (*field).fld_data.fld_optional_field.is_null()
|
||||
@@ -884,18 +818,17 @@ unsafe fn lookup_field(mimeparser: &dc_mimeparser_t, key: &str) -> *const libc::
|
||||
value.is_null()
|
||||
}
|
||||
{
|
||||
return ptr::null();
|
||||
return String::from("");
|
||||
}
|
||||
|
||||
value
|
||||
as_str(value).to_string()
|
||||
}
|
||||
|
||||
unsafe fn could_not_establish_secure_connection(
|
||||
fn could_not_establish_secure_connection(
|
||||
context: &Context,
|
||||
contact_chat_id: uint32_t,
|
||||
details: *const libc::c_char,
|
||||
details: &str,
|
||||
) {
|
||||
let contact_id: uint32_t = chat_id_2_contact_id(context, contact_chat_id);
|
||||
let contact_id = chat_id_2_contact_id(context, contact_chat_id);
|
||||
let contact = Contact::get_by_id(context, contact_id);
|
||||
let msg = context.stock_string_repl_str(
|
||||
StockMessage::ContactNotVerified,
|
||||
@@ -907,7 +840,7 @@ unsafe fn could_not_establish_secure_connection(
|
||||
);
|
||||
|
||||
chat::add_device_msg(context, contact_chat_id, &msg);
|
||||
error!(context, 0, "{} ({})", &msg, as_str(details));
|
||||
error!(context, 0, "{} ({})", &msg, details);
|
||||
}
|
||||
|
||||
fn mark_peer_as_verified(context: &Context, fingerprint: impl AsRef<str>) -> Result<(), Error> {
|
||||
|
||||
Reference in New Issue
Block a user