diff --git a/src/key_reset.c b/src/key_reset.c index 0c4f77e8..6a16dac7 100644 --- a/src/key_reset.c +++ b/src/key_reset.c @@ -394,7 +394,7 @@ DYNAMIC_API PEP_STATUS key_reset( // // if (!EMPTYSTR(ident->fpr)) // fpr_copy = strdup(ident->fpr); - status = _myself(session, ident, false, true); + status = _myself(session, ident, false, true, true); if (status == PEP_STATUS_OK && ident->fpr) fpr_copy = strdup(ident->fpr); else { diff --git a/src/keymanagement.c b/src/keymanagement.c index 4a2eb8fe..8daefc22 100644 --- a/src/keymanagement.c +++ b/src/keymanagement.c @@ -994,7 +994,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; @@ -1016,18 +1020,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; + } } } @@ -1060,7 +1070,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); @@ -1113,7 +1123,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); @@ -1151,12 +1161,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); @@ -1166,7 +1178,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( @@ -1769,7 +1781,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 fcbb2c94..fc62e8b4 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() // @@ -375,7 +379,7 @@ PEP_STATUS get_all_keys_for_user(PEP_SESSION session, stringlist_t** keys); -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 9d7f5462..310c2b60 100644 --- a/src/message_api.c +++ b/src/message_api.c @@ -995,7 +995,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; } @@ -1312,7 +1312,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) @@ -2978,6 +2979,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, @@ -3308,6 +3310,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)); @@ -3371,7 +3374,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) @@ -3605,7 +3608,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; } @@ -4078,7 +4081,7 @@ DYNAMIC_API PEP_STATUS identity_rating( *rating = PEP_rating_undefined; if (ident->me) - status = _myself(session, ident, false, true); + status = _myself(session, ident, false, true, true); else status = update_identity(session, ident); @@ -4476,12 +4479,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; @@ -4799,7 +4803,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 7f91f867..ccf229e6 100644 --- a/src/pEpEngine.c +++ b/src/pEpEngine.c @@ -389,6 +389,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, identity.user_id, username," @@ -1446,6 +1457,11 @@ DYNAMIC_API PEP_STATUS init( (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), @@ -1680,6 +1696,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) @@ -2981,6 +2999,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 bind_own_ident_with_contact_ident(PEP_SESSION session, pEp_identity* own_ident, pEp_identity* contact_ident) { diff --git a/src/pEp_internal.h b/src/pEp_internal.h index 87f2ceb8..cddd6e95 100644 --- a/src/pEp_internal.h +++ b/src/pEp_internal.h @@ -209,6 +209,7 @@ struct _pEpSession { // 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;