From b19931457e148f7c11635bfa793b8a23a4488c28 Mon Sep 17 00:00:00 2001 From: Krista 'DarthMama' Bennett Date: Tue, 19 Mar 2019 18:19:59 +0100 Subject: [PATCH] ENGINE-527: part 1, myself now doesn't write when called from decrypt_message (directly or, hoepfully, indirectly) --- src/keymanagement.c | 56 +++++++++++++++++++++++++++------------------ src/keymanagement.h | 8 +++++-- src/message_api.c | 18 +++++++++------ src/pEpEngine.c | 55 ++++++++++++++++++++++++++++++++++++++++++++ src/pEp_internal.h | 1 + 5 files changed, 107 insertions(+), 31 deletions(-) diff --git a/src/keymanagement.c b/src/keymanagement.c index 31f0c5ed..6f689782 100644 --- a/src/keymanagement.c +++ b/src/keymanagement.c @@ -663,7 +663,7 @@ DYNAMIC_API PEP_STATUS update_identity( // here, none of them fit. // * call set_identity() to store // FIXME: Do we set if we had to copy in the address? - adjust_pep_trust_status(session, identity); + adjust_pep_trust_status(session, identity); status = set_identity(session, identity); // * Return: created identity } @@ -958,7 +958,11 @@ PEP_STATUS _has_usable_priv_key(PEP_SESSION session, char* fpr, return status; } -PEP_STATUS _myself(PEP_SESSION session, pEp_identity * identity, bool do_keygen, bool ignore_flags) +PEP_STATUS _myself(PEP_SESSION session, + pEp_identity * identity, + bool do_keygen, + bool ignore_flags, + bool read_only) { PEP_STATUS status; @@ -980,18 +984,24 @@ PEP_STATUS _myself(PEP_SESSION session, pEp_identity * identity, bool do_keygen, status = get_default_own_userid(session, &default_own_id); // Deal with non-default user_ids. + // FIXME: if non-default and read-only, reject totally? if (default_own_id && strcmp(default_own_id, identity->user_id) != 0) { - - status = set_userid_alias(session, default_own_id, identity->user_id); - // Do we want this to be fatal? For now, we'll do it... - if (status != PEP_STATUS_OK) - goto pep_free; - - free(identity->user_id); - identity->user_id = strdup(default_own_id); - if (identity->user_id == NULL) { - status = PEP_OUT_OF_MEMORY; - goto pep_free; + if (read_only) { + free(identity->user_id); + identity->user_id = strdup(default_own_id); + } + else { + status = set_userid_alias(session, default_own_id, identity->user_id); + // Do we want this to be fatal? For now, we'll do it... + if (status != PEP_STATUS_OK) + goto pep_free; + + free(identity->user_id); + identity->user_id = strdup(default_own_id); + if (identity->user_id == NULL) { + status = PEP_OUT_OF_MEMORY; + goto pep_free; + } } } @@ -1024,7 +1034,7 @@ PEP_STATUS _myself(PEP_SESSION session, pEp_identity * identity, bool do_keygen, // Set usernames - priority is input username > stored name > address // If there's an input username, we always patch the username with that // input. - if (EMPTYSTR(identity->username)) { + if (EMPTYSTR(identity->username) || read_only) { bool stored_uname = (stored_identity && !EMPTYSTR(stored_identity->username)); char* uname = (stored_uname ? stored_identity->username : identity->address); free(identity->username); @@ -1077,7 +1087,7 @@ PEP_STATUS _myself(PEP_SESSION session, pEp_identity * identity, bool do_keygen, // Nothing left to do but generate a key if (!valid_key_found) { - if (!do_keygen) + if (!do_keygen || read_only) status = PEP_GET_KEY_FAILED; else { // / DEBUG_LOG("Generating key pair", "debug", identity->address); @@ -1115,12 +1125,14 @@ PEP_STATUS _myself(PEP_SESSION session, pEp_identity * identity, bool do_keygen, // We want to set an identity in the DB even if a key isn't found, but we have to preserve the status if // it's NOT ok - PEP_STATUS set_id_status = set_identity(session, identity); - if (set_id_status == PEP_STATUS_OK) - set_id_status = set_as_pep_user(session, identity); - - status = (status == PEP_STATUS_OK ? set_id_status : status); + if (!read_only) { + PEP_STATUS set_id_status = set_identity(session, identity); + if (set_id_status == PEP_STATUS_OK) + set_id_status = set_as_pep_user(session, identity); + status = (status == PEP_STATUS_OK ? set_id_status : status); + } + pep_free: free(default_own_id); free(revoked_fpr); @@ -1156,7 +1168,7 @@ pep_free: DYNAMIC_API PEP_STATUS myself(PEP_SESSION session, pEp_identity * identity) { - return _myself(session, identity, true, false); + return _myself(session, identity, true, false, false); } DYNAMIC_API PEP_STATUS register_examine_function( @@ -1804,7 +1816,7 @@ DYNAMIC_API PEP_STATUS set_own_key( EMPTYSTR(me->user_id) || EMPTYSTR(me->username)) return PEP_ILLEGAL_VALUE; - status = _myself(session, me, false, true); + status = _myself(session, me, false, true, false); // we do not need a valid key but dislike other errors if (status != PEP_STATUS_OK && status != PEP_GET_KEY_FAILED && status != PEP_KEY_UNSUITABLE) return status; diff --git a/src/keymanagement.h b/src/keymanagement.h index 4f2728c0..06ca0c67 100644 --- a/src/keymanagement.h +++ b/src/keymanagement.h @@ -114,7 +114,11 @@ DYNAMIC_API PEP_STATUS update_identity( DYNAMIC_API PEP_STATUS myself(PEP_SESSION session, pEp_identity * identity); -PEP_STATUS _myself(PEP_SESSION session, pEp_identity * identity, bool do_keygen, bool ignore_flags); +PEP_STATUS _myself(PEP_SESSION session, + pEp_identity * identity, + bool do_keygen, + bool ignore_flags, + bool read_only); // retrieve_next_identity() - callback being called by do_keymanagement() // @@ -387,7 +391,7 @@ DYNAMIC_API PEP_STATUS set_own_key( const char *fpr ); -PEP_STATUS _myself(PEP_SESSION session, pEp_identity * identity, bool do_keygen, bool ignore_flags); +//PEP_STATUS _myself(PEP_SESSION session, pEp_identity * identity, bool do_keygen, bool ignore_flags); PEP_STATUS add_mistrusted_key(PEP_SESSION session, const char* fpr); PEP_STATUS delete_mistrusted_key(PEP_SESSION session, const char* fpr); diff --git a/src/message_api.c b/src/message_api.c index 6dc0e66b..77922e0a 100644 --- a/src/message_api.c +++ b/src/message_api.c @@ -987,7 +987,7 @@ static PEP_STATUS update_identity_recip_list(PEP_SESSION session, } } else - status = myself(session, curr_identity); + status = _myself(session, curr_identity, false, false, true); if (status == PEP_ILLEGAL_VALUE || status == PEP_OUT_OF_MEMORY) return status; } @@ -1322,7 +1322,8 @@ static PEP_comm_type _get_comm_type( if (!is_me(session, ident)) status = update_identity(session, ident); else - status = myself(session, ident); + // ??? + status = _myself(session, ident, false, false, true); if (status == PEP_STATUS_OK) { if (ident->comm_type == PEP_ct_compromised) @@ -2970,6 +2971,7 @@ static PEP_STATUS import_priv_keys_from_decrypted_msg(PEP_SESSION session, return status; } +// FIXME: myself ?????? static PEP_STATUS update_sender_to_pep_trust( PEP_SESSION session, pEp_identity* sender, @@ -3238,6 +3240,7 @@ DYNAMIC_API PEP_STATUS _decrypt_message( stringlist_t *_keylist = NULL; char* signer_fpr = NULL; bool is_pep_msg = is_a_pEpmessage(src); + bool myself_read_only = (src->dir == PEP_dir_incoming); // Grab input flags bool reencrypt = (((*flags & PEP_decrypt_flag_untrusted_server) > 0) && *keylist && !EMPTYSTR((*keylist)->value)); @@ -3301,7 +3304,7 @@ DYNAMIC_API PEP_STATUS _decrypt_message( if (!is_me(session, src->from)) status = update_identity(session, src->from); else - status = myself(session, src->from); + status = _myself(session, src->from, false, false, myself_read_only); // We absolutely should NOT be bailing here unless it's a serious error if (status == PEP_OUT_OF_MEMORY) @@ -3517,7 +3520,7 @@ DYNAMIC_API PEP_STATUS _decrypt_message( if (!is_me(session, src->from)) update_identity(session, (src->from)); else - myself(session, src->from); + _myself(session, src->from, false, false, myself_read_only); } break; } @@ -3882,7 +3885,7 @@ DYNAMIC_API PEP_STATUS identity_rating( return PEP_ILLEGAL_VALUE; if (ident->me) - status = _myself(session, ident, false, true); + status = _myself(session, ident, false, true, true); else status = update_identity(session, ident); @@ -4280,12 +4283,13 @@ DYNAMIC_API PEP_STATUS MIME_decrypt_message( if (status != PEP_STATUS_OK) goto pep_error; + tmp_msg->dir = PEP_dir_incoming; // MIME decode message delivers only addresses. We need more. if (tmp_msg->from) { if (!is_me(session, tmp_msg->from)) status = update_identity(session, (tmp_msg->from)); else - status = myself(session, tmp_msg->from); + status = _myself(session, tmp_msg->from, false, false, true); if (status == PEP_ILLEGAL_VALUE || status == PEP_OUT_OF_MEMORY) goto pep_error; @@ -4603,7 +4607,7 @@ got_keylist: if (!is_me(session, msg->from)) status = update_identity(session, msg->from); else - status = myself(session, msg->from); + status = _myself(session, msg->from, false, false, true); switch (status) { case PEP_KEY_NOT_FOUND: diff --git a/src/pEpEngine.c b/src/pEpEngine.c index 07c0f4b7..c2526f97 100644 --- a/src/pEpEngine.c +++ b/src/pEpEngine.c @@ -367,6 +367,17 @@ static const char *sql_own_key_is_listed = " where pgp_keypair_fpr = upper(replace(?1,' ',''))" " and identity.is_own = 1" ");"; + +static const char *sql_is_own_address = + "select count(*) from (" + " select address from identity" + " where (case when (address = ?1) then (1)" + " when (lower(address) = lower(?1)) then (1)" + " when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)" + " else 0" + " end) = 1 " + " and identity.is_own = 1" + ");"; static const char *sql_own_identities_retrieve = "select address, fpr, username, identity.user_id, " @@ -1268,6 +1279,11 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session) (int)strlen(sql_own_key_is_listed), &_session->own_key_is_listed, NULL); assert(int_result == SQLITE_OK); + + int_result = sqlite3_prepare_v2(_session->db, sql_is_own_address, + (int)strlen(sql_is_own_address), &_session->is_own_address, + NULL); + assert(int_result == SQLITE_OK); int_result = sqlite3_prepare_v2(_session->db, sql_own_identities_retrieve, (int)strlen(sql_own_identities_retrieve), @@ -1489,6 +1505,8 @@ DYNAMIC_API void release(PEP_SESSION session) sqlite3_finalize(session->blacklist_retrieve); if (session->own_key_is_listed) sqlite3_finalize(session->own_key_is_listed); + if (session->is_own_address) + sqlite3_finalize(session->is_own_address); if (session->own_identities_retrieve) sqlite3_finalize(session->own_identities_retrieve); if (session->own_keys_retrieve) @@ -2722,6 +2740,43 @@ DYNAMIC_API PEP_STATUS is_pep_user(PEP_SESSION session, pEp_identity *identity, return PEP_STATUS_OK; } +DYNAMIC_API PEP_STATUS is_own_address(PEP_SESSION session, pEp_identity *identity, bool* is_own_addr) +{ + assert(session); + assert(is_own_addr); + assert(identity); + assert(!EMPTYSTR(identity->user_id)); + + if (!session || !is_own_addr || !identity || EMPTYSTR(identity->address)) + return PEP_ILLEGAL_VALUE; + + *is_own_addr = false; + + const char* address = identity->address; + + if (!session || EMPTYSTR(address)) + return PEP_ILLEGAL_VALUE; + + sqlite3_reset(session->is_own_address); + sqlite3_bind_text(session->is_own_address, 1, address, -1, + SQLITE_STATIC); + int result = sqlite3_step(session->is_own_address); + switch (result) { + case SQLITE_ROW: { + // yeah yeah, I know, we could be lazy here, but it looks bad. + *is_own_addr = (sqlite3_column_int(session->is_own_address, 0) != 0); + break; + } + default: + sqlite3_reset(session->is_own_address); + return PEP_RECORD_NOT_FOUND; + } + + sqlite3_reset(session->is_own_address); + + return PEP_STATUS_OK; +} + PEP_STATUS remove_fpr_as_default(PEP_SESSION session, const char* fpr) diff --git a/src/pEp_internal.h b/src/pEp_internal.h index 23f880a9..149efe88 100644 --- a/src/pEp_internal.h +++ b/src/pEp_internal.h @@ -174,6 +174,7 @@ struct _pEpSession { // Own keys sqlite3_stmt *own_key_is_listed; + sqlite3_stmt *is_own_address; sqlite3_stmt *own_identities_retrieve; sqlite3_stmt *own_keys_retrieve; sqlite3_stmt *get_user_default_key;