Skip to content
This repository was archived by the owner on Nov 25, 2022. It is now read-only.

Commit 83bb25e

Browse files
authored
Merge pull request #559 from deltachat/noverisplit
avoid group-splits on verification problems
2 parents 2fd1d2b + 63e9827 commit 83bb25e

File tree

3 files changed

+57
-24
lines changed

3 files changed

+57
-24
lines changed

src/dc_mimeparser.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -943,6 +943,35 @@ void dc_mimeparser_empty(dc_mimeparser_t* mimeparser)
943943
}
944944

945945

946+
void dc_mimeparser_repl_msg_by_error(dc_mimeparser_t* mimeparser,
947+
const char* error_msg)
948+
{
949+
dc_mimepart_t* part = NULL;
950+
int i = 0;
951+
952+
if (mimeparser==NULL || mimeparser->parts==NULL
953+
|| carray_count(mimeparser->parts)<=0) {
954+
return;
955+
}
956+
957+
// part->raw_msg is unchanged
958+
// so that the original message can be retrieved using dc_get_msg_info()
959+
part = (dc_mimepart_t*)carray_get(mimeparser->parts, 0);
960+
part->type = DC_MSG_TEXT;
961+
free(part->msg);
962+
part->msg = dc_mprintf(DC_EDITORIAL_OPEN "%s" DC_EDITORIAL_CLOSE, error_msg);
963+
964+
for (i = 1; i < carray_count(mimeparser->parts); i++) {
965+
part = (dc_mimepart_t*)carray_get(mimeparser->parts, i);
966+
if (part) {
967+
dc_mimepart_unref(part);
968+
}
969+
}
970+
971+
carray_set_size(mimeparser->parts, 1);
972+
}
973+
974+
946975
static void do_add_single_part(dc_mimeparser_t* parser, dc_mimepart_t* part)
947976
{
948977
/* add a single part to the list of parts, the parser takes the ownership of the part, so you MUST NOT unref it after calling this function. */

src/dc_mimeparser.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ dc_mimepart_t* dc_mimeparser_get_last_nonmeta (dc_mimepars
8181
#define dc_mimeparser_has_nonmeta(a) (dc_mimeparser_get_last_nonmeta((a))!=NULL)
8282
int dc_mimeparser_is_mailinglist_message (dc_mimeparser_t*);
8383
int dc_mimeparser_sender_equals_recipient(dc_mimeparser_t*);
84-
84+
void dc_mimeparser_repl_msg_by_error (dc_mimeparser_t*, const char* error_msg);
8585

8686

8787
/* low-level-tools for working with mailmime structures directly */

src/dc_receive_imf.c

Lines changed: 27 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -490,7 +490,8 @@ static void create_or_lookup_adhoc_group(dc_context_t* context, dc_mimeparser_t*
490490

491491

492492
static int check_verified_properties(dc_context_t* context, dc_mimeparser_t* mimeparser,
493-
uint32_t from_id, const dc_array_t* to_ids)
493+
uint32_t from_id, const dc_array_t* to_ids,
494+
char** failure_reason)
494495
{
495496
int everythings_okay = 0;
496497
dc_contact_t* contact = dc_contact_new(context);
@@ -499,8 +500,18 @@ static int check_verified_properties(dc_context_t* context, dc_mimeparser_t* mim
499500
char* q3 = NULL;
500501
sqlite3_stmt* stmt = NULL;
501502

503+
#define VERIFY_FAIL(a) \
504+
*failure_reason = dc_mprintf("%s. See \"Info\" for details.", (a)); \
505+
dc_log_warning(context, 0, *failure_reason);
506+
502507
if (!dc_contact_load_from_db(contact, context->sql, from_id)) {
503-
dc_log_warning(context, 0, "Cannot verifiy group; cannot load contact.");
508+
VERIFY_FAIL("Internal Error; cannot load contact.")
509+
goto cleanup;
510+
}
511+
512+
// ensure, the message is encrypted
513+
if (!mimeparser->e2ee_helper->encrypted) {
514+
VERIFY_FAIL("This message is not encrypted.")
504515
goto cleanup;
505516
}
506517

@@ -511,23 +522,17 @@ static int check_verified_properties(dc_context_t* context, dc_mimeparser_t* mim
511522
if (from_id!=DC_CONTACT_ID_SELF)
512523
{
513524
if (!dc_apeerstate_load_by_addr(peerstate, context->sql, contact->addr)
514-
|| dc_contact_is_verified_ex(contact, peerstate) < DC_BIDIRECT_VERIFIED) {
515-
dc_log_warning(context, 0, "Cannot verifiy group; sender is not verified.");
525+
|| dc_contact_is_verified_ex(contact, peerstate) != DC_BIDIRECT_VERIFIED) {
526+
VERIFY_FAIL("The sender of this message is not verified.")
516527
goto cleanup;
517528
}
518529

519530
if (!dc_apeerstate_has_verified_key(peerstate, mimeparser->e2ee_helper->signatures)) {
520-
dc_log_warning(context, 0, "Cannot verifiy group; message is not signed properly.");
531+
VERIFY_FAIL("The message was sent with non-verified encryption.")
521532
goto cleanup;
522533
}
523534
}
524535

525-
// ensure, the message is encrypted
526-
if (!mimeparser->e2ee_helper->encrypted) {
527-
dc_log_warning(context, 0, "Cannot verifiy group; message is not encrypted properly.");
528-
goto cleanup;
529-
}
530-
531536
// check that all members are verified.
532537
// if a verification is missing, check if this was just gossiped - as we've verified the sender, we verify the member then.
533538
to_ids_str = dc_array_get_string(to_ids, ",");
@@ -554,7 +559,7 @@ static int check_verified_properties(dc_context_t* context, dc_mimeparser_t* mim
554559
|| (strcmp(peerstate->verified_key_fingerprint, peerstate->public_key_fingerprint)!=0
555560
&& strcmp(peerstate->verified_key_fingerprint, peerstate->gossip_key_fingerprint)!=0))
556561
{
557-
dc_log_info(context, 0, "Marking gossipped key %s as verified due to verified %s.", to_addr, contact->addr);
562+
dc_log_info(context, 0, "%s has verfied %s.", contact->addr, to_addr);
558563
dc_apeerstate_set_verified(peerstate, DC_PS_GOSSIP_KEY, peerstate->gossip_key_fingerprint, DC_BIDIRECT_VERIFIED);
559564
dc_apeerstate_save_to_db(peerstate, context->sql, 0);
560565
is_verified = 1;
@@ -563,7 +568,9 @@ static int check_verified_properties(dc_context_t* context, dc_mimeparser_t* mim
563568

564569
if (!is_verified)
565570
{
566-
dc_log_warning(context, 0, "Cannot verifiy group; recipient %s is not gossipped.", to_addr);
571+
char* err = dc_mprintf("%s is not a member of this verified group.", to_addr);
572+
VERIFY_FAIL(err)
573+
free(err);
567574
goto cleanup;
568575
}
569576
}
@@ -614,6 +621,7 @@ static void create_or_lookup_group(dc_context_t* context, dc_mimeparser_t* mime_
614621
int X_MrGrpNameChanged = 0;
615622
const char* X_MrGrpImageChanged = NULL;
616623
char* better_msg = NULL;
624+
char* failure_reason = NULL;
617625

618626
/* search the grpid in the header */
619627
{
@@ -713,14 +721,8 @@ static void create_or_lookup_group(dc_context_t* context, dc_mimeparser_t* mime_
713721
/* check, if we have a chat with this group ID */
714722
if ((chat_id=dc_get_chat_id_by_grpid(context, grpid, &chat_id_blocked, &chat_id_verified))!=0) {
715723
if (chat_id_verified
716-
&& !check_verified_properties(context, mime_parser, from_id, to_ids)) {
717-
chat_id = 0; // force the creation of an unverified ad-hoc group.
718-
chat_id_blocked = 0;
719-
chat_id_verified = 0;
720-
free(grpid);
721-
grpid = NULL;
722-
free(grpname);
723-
grpname = NULL;
724+
&& !check_verified_properties(context, mime_parser, from_id, to_ids, &failure_reason)) {
725+
dc_mimeparser_repl_msg_by_error(mime_parser, failure_reason);
724726
}
725727
}
726728

@@ -744,8 +746,9 @@ static void create_or_lookup_group(dc_context_t* context, dc_mimeparser_t* mime_
744746
{
745747
int create_verified = 0;
746748
if (dc_mimeparser_lookup_field(mime_parser, "Chat-Verified")) {
747-
if (check_verified_properties(context, mime_parser, from_id, to_ids)) {
748-
create_verified = 1;
749+
create_verified = 1;
750+
if (!check_verified_properties(context, mime_parser, from_id, to_ids, &failure_reason)) {
751+
dc_mimeparser_repl_msg_by_error(mime_parser, failure_reason);
749752
}
750753
}
751754

@@ -868,6 +871,7 @@ static void create_or_lookup_group(dc_context_t* context, dc_mimeparser_t* mime_
868871
free(grpname);
869872
free(self_addr);
870873
free(better_msg);
874+
free(failure_reason);
871875
if (ret_chat_id) { *ret_chat_id = chat_id; }
872876
if (ret_chat_id_blocked) { *ret_chat_id_blocked = chat_id? chat_id_blocked : 0; }
873877
}

0 commit comments

Comments
 (0)