diff --git a/deltachat-ffi/src/lib.rs b/deltachat-ffi/src/lib.rs index 5c2730aa7..ccf146fac 100644 --- a/deltachat-ffi/src/lib.rs +++ b/deltachat-ffi/src/lib.rs @@ -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] diff --git a/examples/repl/main.rs b/examples/repl/main.rs index c4fd6be5a..0964d4542 100644 --- a/examples/repl/main.rs +++ b/examples/repl/main.rs @@ -538,7 +538,7 @@ unsafe fn handle_cmd(line: &str, ctx: Arc>) -> Result { 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), diff --git a/python/tests/test_account.py b/python/tests/test_account.py index f827bda3e..b5990cd97 100644 --- a/python/tests/test_account.py +++ b/python/tests/test_account.py @@ -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() diff --git a/src/chat.rs b/src/chat.rs index 47c6e86c9..3a6a67dc0 100644 --- a/src/chat.rs +++ b/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, - 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) -> (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>(1)?.unwrap_or_default(); - } - + let b = row.get::<_, Option>(1)?.unwrap_or_default(); let v = row.get::<_, Option>(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) { diff --git a/src/dc_receive_imf.rs b/src/dc_receive_imf.rs index 6cd7b9f26..6d624f039 100644 --- a/src/dc_receive_imf.rs +++ b/src/dc_receive_imf.rs @@ -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, diff --git a/src/dc_securejoin.rs b/src/dc_securejoin.rs index 37d9fc26b..e20abb41f 100644 --- a/src/dc_securejoin.rs +++ b/src/dc_securejoin.rs @@ -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| { - free(fingerprint as *mut libc::c_void); - qr - }; - - let mut fingerprint = ptr::null_mut(); - let mut qr: Option = 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 { 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, - fingerprint: *const libc::c_char, + fingerprint: Option, grpid: impl AsRef, ) { 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) -> Result<(), Error> {