ENGINE-633: refactoring and correction

doxygen_doc
parent 4fe7a15cf3
commit 9f22625d72

@ -3828,6 +3828,38 @@ static PEP_STATUS set_default_key_fpr_if_valid(
return status;
}
static PEP_STATUS _check_and_set_default_key(
PEP_SESSION session,
pEp_identity* src_ident,
const char* sender_key
)
{
if (!session || !src_ident)
return PEP_ILLEGAL_VALUE;
if (src_ident->address || EMPTYSTR(sender_key))
return PEP_STATUS_OK; // DOH, we're not setting anything here
char* default_from_fpr = NULL;
PEP_STATUS status = update_identity(session, src_ident);
if (status == PEP_STATUS_OK && !is_me(session, src_ident)) {
// Right now, we just want to know if there's a DB default, NOT
// if it matches what update_identity gives us (there are good reasons it might not)
status = get_default_identity_fpr(session, src_ident->address, src_ident->user_id, &default_from_fpr);
if (status == PEP_KEY_NOT_FOUND || status == PEP_CANNOT_FIND_IDENTITY) {
if (!EMPTYSTR(sender_key))
status = set_default_key_fpr_if_valid(session, src_ident, sender_key);
}
}
if (status == PEP_OUT_OF_MEMORY)
return status;
free(default_from_fpr);
return PEP_STATUS_OK; // We don't care about other errors here.
}
static PEP_STATUS _decrypt_message(
PEP_SESSION session,
@ -4003,32 +4035,27 @@ static PEP_STATUS _decrypt_message(
pull_up_attached_main_msg(src);
// Set default key if there isn't one
if (src->from && !is_me(session, src->from)) {
status = update_identity(session, src->from);
const char* hk_fpr = (_imported_key_list ? _imported_key_list->value : NULL);
// Set a default key if there isn't one, if we have one
if (status == PEP_STATUS_OK && EMPTYSTR(src->from->fpr) && !EMPTYSTR(hk_fpr)) {
const char* check_key = NULL;
if (imported_sender_key_fpr) // pEp message version 2.2 or greater
check_key = imported_sender_key_fpr;
else if (header_key_imported) // autocrypt
check_key = _imported_key_list->value;
else {
// We do this only with pEp messages 2.1 or less, or OpenPGP messages
if (!is_pEp_msg || (major_ver == 2 && minor_ver < 2) || major_ver < 2) {
if (_imported_key_list && !(_imported_key_list->next))
check_key = _imported_key_list->value;
}
} // Otherwise, too bad.
if (EMPTYSTR(hk_fpr) && !EMPTYSTR(check_key)) {
status = set_default_key_fpr_if_valid(session, src->from, check_key);
if (status != PEP_OUT_OF_MEMORY)
status = PEP_STATUS_OK;
free(imported_sender_key_fpr);
// This is the case ONLY for unencrypted messages and differs from the 1.0 and 2.x cases,
// in case you are led to think this is pure code duplication.
if (src->from && src->from->address && !is_me(session, src->from)) {
const char* sender_key = NULL;
if (imported_sender_key_fpr) // pEp message version 2.2 or greater
sender_key = imported_sender_key_fpr;
else if (header_key_imported) // autocrypt
sender_key = _imported_key_list->value;
else {
// We do this only with pEp messages 2.1 or less, or OpenPGP messages
if (!is_pEp_msg || (major_ver == 2 && minor_ver < 2) || major_ver < 2) {
if (_imported_key_list && !(_imported_key_list->next))
sender_key = _imported_key_list->value;
}
}
} // Otherwise, too bad.
status = _check_and_set_default_key(session, src->from, sender_key);
if (status == PEP_OUT_OF_MEMORY)
goto enomem;
}
if (imported_key_fprs)
@ -4109,28 +4136,18 @@ static PEP_STATUS _decrypt_message(
if (status == PEP_STATUS_OK && !has_inner) {
// If we're claiming to have a pEp version 2.2 or greater, we only take it
// if it had the right name during the import and if it was the ONLY key on the message?
// (This was Volker's first assertion, but then it may have been walked back.
// FIXME: verify)
// pEp key or no, we only take this key if it's the only one.
if (*start && !((*start)->next)) {
const char* check_key = NULL;
status = update_identity(session, src->from);
// In case we're claiming 2.2 or greater, though, the following must hold
if ((major_ver == 2 && minor_ver > 1) || major_ver > 2) {
if (imported_sender_key_fpr)
check_key = imported_sender_key_fpr;
}
else
check_key = (*start)->value;
if (status == PEP_STATUS_OK && EMPTYSTR(src->from->fpr) && !EMPTYSTR(check_key)) {
status = set_default_key_fpr_if_valid(session, src->from, check_key);
if (status != PEP_OUT_OF_MEMORY)
status = PEP_STATUS_OK;
}
free(imported_sender_key_fpr);
imported_sender_key_fpr = NULL;
}
const char* sender_key = NULL;
if ((major_ver == 2 && minor_ver > 1) || major_ver > 2) {
if (imported_sender_key_fpr)
sender_key = imported_sender_key_fpr;
}
else if (*start && !((*start)->next))
sender_key = (*start)->value; // signer if sent from < 2.1
status = _check_and_set_default_key(session, src->from, sender_key);
if (status == PEP_OUT_OF_MEMORY)
goto enomem;
}
} // else, it needs to get set from INNER keys.
@ -4223,28 +4240,15 @@ static PEP_STATUS _decrypt_message(
if (status == PEP_STATUS_OK && src->from && !is_me(session, src->from)) {
// If we're claiming to have a pEp version 2.2 or greater, we only take it
// if it had the right name during the import and if it was the ONLY key on the message?
// (This was Volker's first assertion, but then it may have been walked back.
// FIXME: verify)
// pEp key or no, we only take this key if it's the only one.
if (*start && !((*start)->next)) {
const char* check_key = NULL;
status = update_identity(session, src->from);
// In case we're claiming 2.2 or greater, though, the following must hold
if ((major_ver == 2 && minor_ver > 1) || major_ver > 2) {
if (imported_sender_key_fpr)
check_key = imported_sender_key_fpr;
}
else
check_key = (*start)->value;
if (status == PEP_STATUS_OK && EMPTYSTR(src->from->fpr) && !EMPTYSTR(check_key)) {
status = set_default_key_fpr_if_valid(session, src->from, check_key);
if (status != PEP_OUT_OF_MEMORY)
status = PEP_STATUS_OK;
}
free(imported_sender_key_fpr);
imported_sender_key_fpr = NULL;
}
const char* sender_key = NULL;
if ((major_ver == 2 && minor_ver > 1) || major_ver > 2) {
if (imported_sender_key_fpr)
sender_key = imported_sender_key_fpr;
}
else if (*start && !((*start)->next))
sender_key = (*start)->value; // signer if sent from < 2.1
status = _check_and_set_default_key(session, src->from, sender_key);
}
break;
@ -4454,27 +4458,22 @@ static PEP_STATUS _decrypt_message(
if (status != PEP_STATUS_OK)
goto pEp_error;
if (!breaks_protocol) {
// Set default key if there isn't one
if (inner_message->from && !is_me(session, inner_message->from)) {
status = update_identity(session, inner_message->from);
if (status == PEP_STATUS_OK && EMPTYSTR(inner_message->from->fpr)) {
const char* check_key = NULL;
if ((msg_major_ver == 2 && msg_minor_ver > 0) || msg_major_ver > 2)
check_key = inner_message->_sender_fpr;
else if (msg_major_ver == 2 && msg_minor_ver == 0 && _keylist && _keylist->value)
check_key = _keylist->value;
// Set a default key if there isn't one, if we have one
if (!EMPTYSTR(check_key)) {
status = set_default_key_fpr_if_valid(session, src->from, check_key);
free(imported_sender_key_fpr);
}
}
if (status == PEP_OUT_OF_MEMORY)
goto enomem;
if (!breaks_protocol && inner_message->from && !is_me(session, inner_message->from)) {
const char* sender_key = NULL;
if ((msg_major_ver == 2 && msg_minor_ver > 0) || msg_major_ver > 2)
sender_key = inner_message->_sender_fpr;
else { // !breaks_protocol is true, so this is a 2.0 message
if ((major_ver == 2 && minor_ver > 1)|| major_ver > 2) {
sender_key = imported_sender_key_fpr; // can be empty
}
else if (_keylist) { // signer key, 2.0 sent from 2.0 client
sender_key = _keylist->value; // can be empty
}
}
}
status = _check_and_set_default_key(session, inner_message->from, sender_key);
if (status == PEP_OUT_OF_MEMORY)
goto enomem;
}
}
if (is_key_reset) {
if (decrypt_status == PEP_DECRYPTED || decrypt_status == PEP_DECRYPTED_AND_VERIFIED) {

@ -212,6 +212,15 @@ static const char *sql_get_main_user_fpr =
"select main_key_id from person"
" where id = ?1 ;";
static const char *sql_get_default_identity_fpr =
"select main_key_id 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 user_id = ?2 ;";
static const char *sql_replace_main_user_fpr_if_equal =
"update person "
" set main_key_id = ?1 "
@ -1810,6 +1819,10 @@ DYNAMIC_API PEP_STATUS init(
(int)strlen(sql_get_main_user_fpr), &_session->get_main_user_fpr, NULL);
assert(int_result == SQLITE_OK);
int_result = sqlite3_prepare_v2(_session->db, sql_get_default_identity_fpr,
(int)strlen(sql_get_default_identity_fpr), &_session->get_default_identity_fpr, NULL);
assert(int_result == SQLITE_OK);
int_result = sqlite3_prepare_v2(_session->db, sql_refresh_userid_default_key,
(int)strlen(sql_refresh_userid_default_key), &_session->refresh_userid_default_key, NULL);
assert(int_result == SQLITE_OK);
@ -2243,6 +2256,8 @@ DYNAMIC_API void release(PEP_SESSION session)
sqlite3_finalize(session->replace_main_user_fpr_if_equal);
if (session->get_main_user_fpr)
sqlite3_finalize(session->get_main_user_fpr);
if (session->get_default_identity_fpr)
sqlite3_finalize(session->get_default_identity_fpr);
if (session->refresh_userid_default_key)
sqlite3_finalize(session->refresh_userid_default_key);
if (session->blacklist_add)
@ -4414,6 +4429,48 @@ PEP_STATUS get_main_user_fpr(PEP_SESSION session,
return status;
}
PEP_STATUS get_default_identity_fpr(PEP_SESSION session,
const char* address,
const char* user_id,
char** main_fpr)
{
PEP_STATUS status = PEP_STATUS_OK;
int result;
if (!session || EMPTYSTR(address) || EMPTYSTR(user_id) || !main_fpr)
return PEP_ILLEGAL_VALUE;
*main_fpr = NULL;
sqlite3_reset(session->get_default_identity_fpr);
sqlite3_bind_text(session->get_default_identity_fpr, 1, address, -1,
SQLITE_STATIC);
sqlite3_bind_text(session->get_default_identity_fpr, 2, user_id, -1,
SQLITE_STATIC);
result = sqlite3_step(session->get_default_identity_fpr);
switch (result) {
case SQLITE_ROW: {
const char* _fpr =
(const char *) sqlite3_column_text(session->get_default_identity_fpr, 0);
if (_fpr) {
*main_fpr = strdup(_fpr);
if (!(*main_fpr))
status = PEP_OUT_OF_MEMORY;
}
else {
status = PEP_KEY_NOT_FOUND;
}
break;
}
default:
status = PEP_CANNOT_FIND_IDENTITY;
}
sqlite3_reset(session->get_default_identity_fpr);
return status;
}
// Deprecated
DYNAMIC_API PEP_STATUS mark_as_compromized(
PEP_SESSION session,

@ -1527,6 +1527,11 @@ PEP_STATUS get_main_user_fpr(PEP_SESSION session,
const char* user_id,
char** main_fpr);
PEP_STATUS get_default_identity_fpr(PEP_SESSION session,
const char* address,
const char* user_id,
char** main_fpr);
PEP_STATUS replace_main_user_fpr(PEP_SESSION session, const char* user_id,
const char* new_fpr);

@ -170,6 +170,7 @@ struct _pEpSession {
sqlite3_stmt *replace_main_user_fpr;
sqlite3_stmt *replace_main_user_fpr_if_equal;
sqlite3_stmt *get_main_user_fpr;
sqlite3_stmt *get_default_identity_fpr;
sqlite3_stmt *refresh_userid_default_key;
sqlite3_stmt *delete_key;
sqlite3_stmt *remove_fpr_as_identity_default;

@ -65,7 +65,7 @@ newfile.write("\n" + tb(4) + "// Get a new test Engine.\n")
newfile.write(tb(4) + "engine = new Engine(test_path);\n");
newfile.write(tb(4) + "ASSERT_NE(engine, nullptr);\n")
newfile.write("\n" + tb(4) + "// Ok, let's initialize test directories etc.\n")
newfile.write(tb(4) + "engine->prep(NULL, NULL, init_files);\n")
newfile.write(tb(4) + "engine->prep(NULL, NULL, NULL, init_files);\n")
newfile.write("\n" + tb(4) + "// Ok, try to start this bugger.\n")
newfile.write(tb(4) + "engine->start();\n")
newfile.write(tb(4) + "ASSERT_NE(engine->session, nullptr);\n")

Loading…
Cancel
Save