ENGINE-332: rewrite complete, but needs checking and testing.

doc_update_sequoia
Krista Bennett 5 years ago
parent d4f08f4461
commit 1f9c04611d

@ -21,6 +21,13 @@
#define KEY_EXPIRE_DELTA (60 * 60 * 24 * 365)
#ifndef _MIN
#define _MIN(A, B) ((B) > (A) ? (A) : (B))
#endif
#ifndef _MAX
#define _MAX(A, B) ((B) > (A) ? (B) : (A))
#endif
static bool key_matches_address(PEP_SESSION session, const char* address,
const char* fpr) {
@ -1149,39 +1156,101 @@ DYNAMIC_API PEP_STATUS trust_personal_key(
EMPTYSTR(ident->fpr))
return PEP_ILLEGAL_VALUE;
bool ident_has_trusted_default = false;
char* ident_default_fpr = NULL;
// Before we do anything, be sure the input fpr is even eligible to be trusted
PEP_comm_type input_default_ct = PEP_ct_unknown;
status = get_key_rating(session, ident->fpr, &input_default_ct);
if (input_default_ct < PEP_ct_strong_but_unconfirmed)
return PEP_KEY_UNSUITABLE;
// Save the input fpr
char* cached_fpr = strdup(ident->fpr);
ident->fpr = NULL;
bool me = is_me(session, ident);
if (me)
status = myself(session, ident);
else {
char* saved_fpr = ident->fpr;
ident->fpr = NULL;
return myself(session, ident); // FIXME: Not the right thing if we
// don't always replace user default!!!
// First, set up a temp trusted identity for the input fpr without a comm type;
pEp_identity* tmp_id = new_identity(ident->address, cached_fpr, ident->user_id, NULL);
status = validate_fpr(session, tmp_id);
if (status == PEP_STATUS_OK) {
// Validate fpr gets trust DB or, when that fails, key comm type. we checked
// above that the key was ok. (not revoked or expired), but we want the max.
tmp_id->comm_type = _MAX(tmp_id->comm_type, input_default_ct) | PEP_ct_confirmed;
// Get the default identity without setting the fpr
status = update_identity(session, ident);
if (EMPTYSTR(ident->fpr) || strcmp(ident->fpr, saved_fpr) != 0) {
ident->fpr = saved_fpr;
ident->comm_type = PEP_ct_unknown;
status = set_identity(session, ident);
if (status == PEP_STATUS_OK)
status = update_identity(session, ident);
}
// either saved_fpr got copied in update_identity and we're done
// with it, or it's not referenced anymore because we didn't call
// it.
free(saved_fpr);
}
if (status != PEP_STATUS_OK)
return status;
ident_default_fpr = strdup(ident->fpr);
if (ident->comm_type > PEP_ct_strong_but_unconfirmed) {
ident->comm_type |= PEP_ct_confirmed;
status = set_identity(session, ident);
}
else {
// MISSING: S/MIME has to be handled depending on trusted CAs
status = PEP_CANNOT_SET_TRUST;
}
if (status == PEP_STATUS_OK) {
bool trusted_default = false;
// If there's no default, or the default is different from the input...
if (EMPTYSTR(ident_default_fpr) || strcmp(cached_fpr, ident_default_fpr) != 0) {
// If the default fpr (if there is one) is trusted and key is strong enough,
// don't replace, we just set the trusted bit on this key for this user_id...
// (If there's no default fpr, this won't be true anyway.)
if (ident->comm_type >= PEP_ct_strong_but_unconfirmed &&
(ident->comm_type & PEP_ct_confirmed)) {
trusted_default = true;
status = set_trust(session, tmp_id->user_id, cached_fpr, tmp_id->comm_type);
input_default_ct = tmp_id->comm_type;
}
else {
free(ident->fpr);
ident->fpr = strdup(cached_fpr);
ident->comm_type = tmp_id->comm_type;
status = set_identity(session, ident); // replace identity default
}
}
else { // we're setting this on the default fpr
ident->comm_type = tmp_id->comm_type;
status = set_identity(session, ident);
trusted_default = true;
}
if (status == PEP_STATUS_OK) {
// Ok, there wasn't a trusted default, so we replaced. Thus, we also
// make sure there's a trusted default on the user_id. If there
// is not, we make this the default.
char* user_default = NULL;
status = get_main_user_fpr(session, ident->user_id, &user_default);
if (status == PEP_STATUS_OK && user_default) {
pEp_identity* tmp_user_ident = new_identity(ident->address,
user_default,
ident->user_id,
NULL);
if (!tmp_user_ident)
status = PEP_OUT_OF_MEMORY;
else {
status = validate_fpr(session, tmp_user_ident);
if (status != PEP_STATUS_OK ||
tmp_user_ident->comm_type < PEP_ct_strong_but_unconfirmed ||
!(tmp_user_ident->comm_type & PEP_ct_confirmed))
{
char* trusted_fpr = (trusted_default ? ident_default_fpr : cached_fpr);
status = replace_main_user_fpr(session, ident->user_id, trusted_fpr);
}
}
}
}
}
free(ident_default_fpr);
free(cached_fpr); // we took ownership upon successful update_identity call above
free_identity(tmp_id);
}
return status;
}

@ -113,6 +113,15 @@ static const char* sql_replace_userid =
"update person set id = ?1 "
"where id = ?2;";
static const char *sql_replace_main_user_fpr =
"update person"
" set main_key_id = ?1 "
" where id = ?2 ;";
static const char *sql_get_main_user_fpr =
"select main_key_id from person"
" where id = ?1 ;";
static const char *sql_get_device_group =
"select device_group from person "
"where id = ?1;";
@ -823,6 +832,14 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
(int)strlen(sql_replace_userid), &_session->replace_userid, NULL);
assert(int_result == SQLITE_OK);
int_result = sqlite3_prepare_v2(_session->db, sql_replace_main_user_fpr,
(int)strlen(sql_replace_main_user_fpr), &_session->replace_main_user_fpr, NULL);
assert(int_result == SQLITE_OK);
int_result = sqlite3_prepare_v2(_session->db, sql_get_main_user_fpr,
(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_replace_identities_fpr,
(int)strlen(sql_replace_identities_fpr),
&_session->replace_identities_fpr, NULL);
@ -1117,6 +1134,10 @@ DYNAMIC_API void release(PEP_SESSION session)
sqlite3_finalize(session->i18n_token);
if (session->replace_userid)
sqlite3_finalize(session->replace_userid);
if (session->replace_main_user_fpr)
sqlite3_finalize(session->replace_main_user_fpr);
if (session->get_main_user_fpr)
sqlite3_finalize(session->get_main_user_fpr);
if (session->blacklist_add)
sqlite3_finalize(session->blacklist_add);
if (session->blacklist_delete)
@ -1791,7 +1812,7 @@ DYNAMIC_API PEP_STATUS set_identity(
bool has_fpr = (identity->fpr && identity->fpr[0] != '\0');
if (has_fpr) {
// blacklist check
// blacklist check - FIXME: ENGINE-294 will remove
status = blacklist_is_listed(session, identity->fpr, &listed);
assert(status == PEP_STATUS_OK);
if (status != PEP_STATUS_OK)
@ -2123,6 +2144,69 @@ PEP_STATUS replace_userid(PEP_SESSION session, const char* old_uid,
return PEP_STATUS_OK;
}
PEP_STATUS replace_main_user_fpr(PEP_SESSION session, const char* user_id,
const char* new_fpr) {
assert(session);
assert(user_id);
assert(new_fpr);
if (!session || !user_id || !new_fpr)
return PEP_ILLEGAL_VALUE;
int result;
sqlite3_reset(session->replace_main_user_fpr);
sqlite3_bind_text(session->replace_main_user_fpr, 1, new_fpr, -1,
SQLITE_STATIC);
sqlite3_bind_text(session->replace_main_user_fpr, 2, user_id, -1,
SQLITE_STATIC);
result = sqlite3_step(session->replace_main_user_fpr);
sqlite3_reset(session->replace_main_user_fpr);
if (result != SQLITE_DONE)
return PEP_CANNOT_SET_PERSON;
return PEP_STATUS_OK;
}
PEP_STATUS get_main_user_fpr(PEP_SESSION session,
const char* user_id,
char** main_fpr)
{
PEP_STATUS status = PEP_STATUS_OK;
int result;
assert(session);
assert(user_id);
assert(main_fpr);
if (!(session && user_id && user_id[0] && main_fpr))
return PEP_ILLEGAL_VALUE;
*main_fpr = NULL;
sqlite3_reset(session->get_main_user_fpr);
sqlite3_bind_text(session->get_main_user_fpr, 1, user_id, -1,
SQLITE_STATIC);
result = sqlite3_step(session->get_main_user_fpr);
switch (result) {
case SQLITE_ROW: {
const char* _fpr =
(const char *) sqlite3_column_text(session->get_main_user_fpr, 0);
if (_fpr)
*main_fpr = strdup(_fpr);
if (!(*main_fpr))
status = PEP_OUT_OF_MEMORY;
break;
}
default:
status = PEP_CANNOT_FIND_PERSON;
}
sqlite3_reset(session->get_main_user_fpr);
return status;
}
DYNAMIC_API PEP_STATUS mark_as_compromized(
PEP_SESSION session,
const char *fpr
@ -2153,6 +2237,36 @@ void pEp_free(void *p)
free(p);
}
PEP_STATUS set_trust(PEP_SESSION session,
const char* user_id,
const char* fpr,
PEP_comm_type comm_type)
{
assert(session);
assert(user_id);
assert(fpr);
if (!session || !user_id || user_id[0] == '\0' || !fpr || fpr[0] == '\0')
return PEP_ILLEGAL_VALUE;
int result;
sqlite3_reset(session->set_trust);
sqlite3_bind_text(session->set_trust, 1, user_id, -1,
SQLITE_STATIC);
sqlite3_bind_text(session->set_trust, 2, fpr, -1,
SQLITE_STATIC);
sqlite3_bind_int(session->set_trust, 3, comm_type);
result = sqlite3_step(session->set_trust);
assert(result == SQLITE_DONE);
sqlite3_reset(session->set_trust);
if (result != SQLITE_DONE)
return PEP_CANNOT_SET_TRUST;
return PEP_STATUS_OK;
}
DYNAMIC_API PEP_STATUS get_trust(PEP_SESSION session, pEp_identity *identity)
{
PEP_STATUS status = PEP_STATUS_OK;

@ -58,6 +58,7 @@ typedef enum {
PEP_CANNOT_SET_IDENTITY = 0x0383,
PEP_CANNOT_SET_TRUST = 0x0384,
PEP_KEY_BLACKLISTED = 0x0385,
PEP_CANNOT_FIND_PERSON = 0x0386,
PEP_CANNOT_FIND_ALIAS = 0x0391,
PEP_CANNOT_SET_ALIAS = 0x0392,
@ -668,6 +669,7 @@ DYNAMIC_API PEP_STATUS set_userid_alias (
const char* default_id,
const char* alias_id);
// set_device_group() - update own person's device group
//
// parameters:
@ -1217,6 +1219,13 @@ PEP_STATUS replace_userid(PEP_SESSION session, const char* old_uid,
PEP_STATUS remove_fpr_as_default(PEP_SESSION session,
const char* fpr);
PEP_STATUS get_main_user_fpr(PEP_SESSION session,
const char* user_id,
char** main_fpr);
PEP_STATUS replace_main_user_fpr(PEP_SESSION session, const char* user_id,
const char* new_fpr);
#ifdef __cplusplus
}

@ -126,6 +126,8 @@ struct _pEpSession {
sqlite3_stmt *get_identity_without_trust_check;
sqlite3_stmt *get_identities_by_address;
sqlite3_stmt *replace_identities_fpr;
sqlite3_stmt *replace_main_user_fpr;
sqlite3_stmt *get_main_user_fpr;
sqlite3_stmt *remove_fpr_as_default;
sqlite3_stmt *set_person;
sqlite3_stmt *set_device_group;

Loading…
Cancel
Save