diff --git a/src/mrmailbox-private.h b/src/mrmailbox-private.h index 413617a6..20d9a697 100644 --- a/src/mrmailbox-private.h +++ b/src/mrmailbox-private.h @@ -32,6 +32,7 @@ typedef struct mrsmtp_t mrsmtp_t; typedef struct mrsqlite3_t mrsqlite3_t; typedef struct mrjob_t mrjob_t; typedef struct mrmimeparser_t mrmimeparser_t; +typedef struct mrhash_t mrhash_t; /** Structure behind mrmailbox_t */ @@ -142,7 +143,7 @@ typedef struct mrmailbox_e2ee_helper_t { } mrmailbox_e2ee_helper_t; void mrmailbox_e2ee_encrypt (mrmailbox_t*, const clist* recipients_addr, int force_unencrypted, int e2ee_guaranteed, int min_verified, struct mailmime* in_out_message, mrmailbox_e2ee_helper_t*); -int mrmailbox_e2ee_decrypt (mrmailbox_t*, struct mailmime* in_out_message, int* ret_validation_errors, int* ret_degrade_event); /* returns 1 if sth. was decrypted, 0 in other cases */ +int mrmailbox_e2ee_decrypt (mrmailbox_t*, struct mailmime* in_out_message, int* ret_validation_errors, int* ret_degrade_event, mrhash_t** ret_gossiped_addr); /* returns 1 if sth. was decrypted, 0 in other cases */ void mrmailbox_e2ee_thanks (mrmailbox_e2ee_helper_t*); /* frees data referenced by "mailmime" but not freed by mailmime_free(). After calling mre2ee_unhelp(), in_out_message cannot be used any longer! */ int mrmailbox_ensure_secret_key_exists (mrmailbox_t*); /* makes sure, the private key exists, needed only for exporting keys and the case no message was sent before */ char* mrmailbox_create_setup_code (mrmailbox_t*); diff --git a/src/mrmailbox_e2ee.c b/src/mrmailbox_e2ee.c index 154ea862..8c0d7c97 100644 --- a/src/mrmailbox_e2ee.c +++ b/src/mrmailbox_e2ee.c @@ -714,10 +714,11 @@ static int decrypt_recursive(mrmailbox_t* mailbox, } -static void update_gossip_peerstates(mrmailbox_t* mailbox, time_t message_time, struct mailimf_fields* imffields, const struct mailimf_fields* gossip_headers) +static mrhash_t* update_gossip_peerstates(mrmailbox_t* mailbox, time_t message_time, struct mailimf_fields* imffields, const struct mailimf_fields* gossip_headers) { clistiter* cur1; mrhash_t* recipients = NULL; + mrhash_t* gossipped_addr = NULL; for( cur1 = clist_begin(gossip_headers->fld_list); cur1!=NULL ; cur1=clist_next(cur1) ) { @@ -749,6 +750,14 @@ static void update_gossip_peerstates(mrmailbox_t* mailbox, time_t message_time, mrapeerstate_save_to_db__(peerstate, mailbox->m_sql, 0/*do not create*/); } mrapeerstate_unref(peerstate); + + // collect all gossipped addresses; we need them later to mark them as being + // verified when used in a verified group by a verified sender + if( gossipped_addr == NULL ) { + gossipped_addr = malloc(sizeof(mrhash_t)); + mrhash_init(gossipped_addr, MRHASH_STRING, 1/*copy key*/); + } + mrhash_insert(gossipped_addr, gossip_header->m_addr, strlen(gossip_header->m_addr), (void*)1); } else { @@ -764,10 +773,15 @@ static void update_gossip_peerstates(mrmailbox_t* mailbox, time_t message_time, mrhash_clear(recipients); free(recipients); } + + return gossipped_addr; } -int mrmailbox_e2ee_decrypt(mrmailbox_t* mailbox, struct mailmime* in_out_message, int* ret_validation_errors, int* ret_degrade_event) +int mrmailbox_e2ee_decrypt(mrmailbox_t* mailbox, struct mailmime* in_out_message, + int* ret_validation_errors, + int* ret_degrade_event, + mrhash_t** ret_gossipped_addr) { /* 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 */ @@ -781,11 +795,12 @@ int mrmailbox_e2ee_decrypt(mrmailbox_t* mailbox, struct mailmime* in_out_message int sth_decrypted = 0; struct mailimf_fields* gossip_headers = NULL; - if( ret_degrade_event ) { - *ret_degrade_event = 0; - } + if( ret_validation_errors ) { *ret_validation_errors = 0; } + if( ret_degrade_event ) { *ret_degrade_event = 0; } + if( ret_gossipped_addr ) { *ret_gossipped_addr = NULL; } - if( mailbox==NULL || mailbox->m_magic != MR_MAILBOX_MAGIC || in_out_message==NULL || ret_validation_errors==NULL + if( mailbox==NULL || mailbox->m_magic != MR_MAILBOX_MAGIC || in_out_message==NULL + || ret_validation_errors==NULL || ret_gossipped_addr || imffields==NULL || peerstate==NULL || private_keyring==NULL ) { goto cleanup; } @@ -876,7 +891,6 @@ int mrmailbox_e2ee_decrypt(mrmailbox_t* mailbox, struct mailmime* in_out_message : peerstate->m_public_key; /* finally, decrypt. If sth. was decrypted, decrypt_recursive() returns "true" and we start over to decrypt maybe just added parts. */ - *ret_validation_errors = 0; int avoid_deadlock = 10; while( avoid_deadlock > 0 ) { if( !decrypt_recursive(mailbox, in_out_message, private_keyring, @@ -888,9 +902,9 @@ int mrmailbox_e2ee_decrypt(mrmailbox_t* mailbox, struct mailmime* in_out_message avoid_deadlock--; } - /* check for Autocrypt-Gossip (NB: maybe we should use this header also for mrmimeparser_t::m_header_protected) */ + /* check for Autocrypt-Gossip */ if( gossip_headers ) { - update_gossip_peerstates(mailbox, message_time, imffields, gossip_headers); + *ret_gossipped_addr = update_gossip_peerstates(mailbox, message_time, imffields, gossip_headers); } //mailmime_print(in_out_message); diff --git a/src/mrmimeparser.c b/src/mrmimeparser.c index 147bc352..fa8d3f12 100644 --- a/src/mrmimeparser.c +++ b/src/mrmimeparser.c @@ -936,6 +936,13 @@ void mrmimeparser_empty(mrmimeparser_t* ths) ths->m_decrypted_and_validated = 0; ths->m_decrypted_with_validation_errors = 0; ths->m_decrypting_failed = 0; + + if( ths->m_gossipped_addr ) + { + mrhash_clear(ths->m_gossipped_addr); + free(ths->m_gossipped_addr); + ths->m_gossipped_addr = NULL; + } } @@ -1466,7 +1473,7 @@ void mrmimeparser_parse(mrmimeparser_t* ths, const char* body_not_terminated, si /* decrypt, if possible; handle Autocrypt:-header (decryption may modifiy the given object) */ int validation_errors = 0; - if( mrmailbox_e2ee_decrypt(ths->m_mailbox, ths->m_mimeroot, &validation_errors, &ths->m_degrade_event) ) { + if( mrmailbox_e2ee_decrypt(ths->m_mailbox, ths->m_mimeroot, &validation_errors, &ths->m_degrade_event, &ths->m_gossipped_addr) ) { if( validation_errors == 0 ) { ths->m_decrypted_and_validated = 1; } diff --git a/src/mrmimeparser.h b/src/mrmimeparser.h index 7b428c68..ea003b75 100644 --- a/src/mrmimeparser.h +++ b/src/mrmimeparser.h @@ -64,9 +64,13 @@ typedef struct mrmimeparser_t char* m_subject; int m_is_send_by_messenger; + int m_decrypted_and_validated; int m_decrypted_with_validation_errors; int m_decrypting_failed; /* set, if there are multipart/encrypted parts left after decryption */ + mrhash_t* m_gossipped_addr; + int m_degrade_event; + const char* m_blobdir; int m_is_forwarded; @@ -77,8 +81,6 @@ typedef struct mrmimeparser_t int m_is_system_message; - int m_degrade_event; - } mrmimeparser_t;