Browse Source

ENGINE-398: reset notification (outgoing)

generate_api
Krista Bennett 4 years ago
parent
commit
fe04c71b27
4 changed files with 334 additions and 20 deletions
  1. +158
    -7
      src/message_api.c
  2. +173
    -13
      src/pEpEngine.c
  3. +2
    -0
      src/pEpEngine.h
  4. +1
    -0
      src/pEp_internal.h

+ 158
- 7
src/message_api.c View File

@ -899,7 +899,7 @@ enomem:
}
static message* wrap_message_as_attachment(message* envelope,
message* attachment, bool keep_orig_subject) {
message* attachment, message_wrap_type wrap_type, bool keep_orig_subject) {
if (!attachment)
return NULL;
@ -910,14 +910,22 @@ static message* wrap_message_as_attachment(message* envelope,
replace_opt_field(attachment, "X-pEp-Version", PEP_VERSION, true);
if (!_envelope) {
if (!_envelope && (wrap_type != PEP_message_transport)) {
_envelope = extract_minimal_envelope(attachment, PEP_dir_outgoing);
status = generate_message_id(_envelope);
if (status != PEP_STATUS_OK)
goto enomem;
attachment->longmsg = encapsulate_message_wrap_info("INNER", attachment->longmsg);
const char* inner_type_string = "";
switch (wrap_type) {
case PEP_message_key_reset:
inner_type_string = "KEY_RESET";
break;
default:
inner_type_string = "INNER";
}
attachment->longmsg = encapsulate_message_wrap_info(inner_type_string, attachment->longmsg);
_envelope->longmsg = encapsulate_message_wrap_info("OUTER", _envelope->longmsg);
}
else {
@ -1500,6 +1508,129 @@ void attach_own_key(PEP_SESSION session, message *msg)
free(revoked_fpr);
}
PEP_STATUS send_key_reset_to_recents(PEP_SESSION session,
const char* revoke_fpr,
const char* new_fpr) {
assert(revoke_fpr);
assert(new_fpr);
assert(session);
assert(session->sync_session);
assert(session->sync_session->inject_sync_message);
assert(session->sync_session->management);
if (!session || !revoke_fpr || !new_fpr)
return PEP_ILLEGAL_VALUE;
if (!session->sync_session->inject_sync_msg || session->sync_session->sync_management)
return PEP_SYNC_NO_INJECT_CALLBACK;
identity_list* recent_contacts = NULL;
message* reset_msg = NULL;
PEP_STATUS status = get_last_contacted(session, &recent_contacts);
if (status != PEP_STATUS_OK)
goto pep_free;
identity_list* curr_id_ptr = recent_contacts;
while (curr_id_ptr) {
pEp_identity* curr_id = curr_id_ptr->ident;
if (!curr_id)
break;
const char* user_id = curr_id->user_id;
// Should be impossible, but?
if (user_id)
continue;
// Check if they've already been told - this shouldn't be the case, but...
bool contacted = false;
status = has_key_reset_been_sent(session, user_id, revoke_fpr, &contacted);
if (status != PEP_STATUS_OK)
goto pep_free;
if (contacted)
continue;
// if not, make em a message
reset_msg = NULL;
status = create_standalone_key_reset_message(&reset_msg,
curr_id,
revoke_fpr,
new_fpr);
if (status != PEP_STATUS_OK)
goto pep_free;
// insert into queue
int result = session->sync_session->inject_sync_msg(reset_msg, session->sync_session->sync_management);
if (result != 0) {
status = PEP_SYNC_INJECT_FAILED;
goto pep_free;
}
// Put into notified DB
status = set_reset_contact_notified(session, revoke_fpr, user_id);
if (status != PEP_STATUS_OK)
goto pep_free;
curr_id_ptr = curr_id_ptr->next;
}
pep_free:
free_identity_list(recent_contacts);
free_message(reset_msg);
return status;
}
PEP_STATUS create_standalone_key_reset_message(message** dst,
pEp_identity* recip,
const char* revoke_fpr,
const char* new_fpr) {
if (!dst || !recip->user_id || !recip->address)
return PEP_ILLEGAL_VALUE;
*dst = NULL;
// Get own identity user has corresponded with
pEp_identity* own_identity = NULL;
PEP_STATUS status = get_own_address_for_contact_id(PEP_SESSION session,
recip,
&own_identity);
if (status != PEP_STATUS_OK)
return status;
message* reset_message = new_message(PEP_dir_outgoing);
reset_message->from = own_identity;
reset_message->to = new_identity_list(identity_dup(recip)); // ?
status = _attach_key(session, revoke_fpr, reset_message);
if (status != PEP_STATUS_OK)
goto pep_free;
status = _attach_key(session, new_fpr, reset_message);
if (status != PEP_STATUS_OK)
goto pep_free;
message* output_msg = NULL;
status = encrypt_message(session, reset_message, NULL,
output_msg, PEP_enc_PGP_MIME,
PEP_encrypt_flag_key_reset_only);
if (status == PEP_STATUS_OK)
*dst = output_msg;
pep_free:
free_message(reset_message);
return status;
}
PEP_cryptotech determine_encryption_format(message *msg)
{
assert(msg);
@ -1625,7 +1756,6 @@ DYNAMIC_API PEP_STATUS encrypt_message(
identity_list * _il;
if (enc_format != PEP_enc_none && (_il = src->bcc) && _il->ident)
{
// BCC limited support:
@ -1809,7 +1939,8 @@ DYNAMIC_API PEP_STATUS encrypt_message(
else {
// FIXME - we need to deal with transport types (via flag)
if ((!force_v_1) && ((max_comm_type | PEP_ct_confirmed) == PEP_ct_pEp)) {
_src = wrap_message_as_attachment(NULL, src, false);
message_wrap_type = ((flags & PEP_encrypt_flag_key_reset_only) ? PEP_message_key_reset : PEP_message_default);
_src = wrap_message_as_attachment(NULL, src, message_wrap_type, false);
if (!_src)
goto pep_error;
}
@ -2106,8 +2237,8 @@ DYNAMIC_API PEP_STATUS encrypt_message_for_self(
determine_encryption_format(src);
if (src->enc_format != PEP_enc_none)
return PEP_ILLEGAL_VALUE;
if (target_id && (!target_id->user_id || target_id->user_id[0] == '\0')) {
char* own_id = NULL;
status = get_default_own_userid(session, &own_id);
if (own_id) {
@ -2150,7 +2281,7 @@ DYNAMIC_API PEP_STATUS encrypt_message_for_self(
// if (!(flags & PEP_encrypt_flag_force_no_attached_key))
// _attach_key(session, target_fpr, src);
_src = wrap_message_as_attachment(NULL, src, false);
_src = wrap_message_as_attachment(NULL, src, PEP_message_default, false);
if (!_src)
goto pep_error;
@ -3022,6 +3153,22 @@ static char* seek_good_trusted_private_fpr(PEP_SESSION session, char* own_id,
return NULL;
}
PEP_STATUS check_for_own_revoked_key(
PEP_SESSION session,
stringlist_t* keylist,
char** bad_fpr,
char** replacement_fpr
)
{
if (!session || !bad_fpr || !replacement_fpr)
return PEP_ILLEGAL_VALUE;
stringlist_t* _k = keylist;
while (_k) {
}
}
DYNAMIC_API PEP_STATUS _decrypt_message(
PEP_SESSION session,
message *src,
@ -3412,6 +3559,10 @@ DYNAMIC_API PEP_STATUS _decrypt_message(
}
} // End prepare output message for return
// 3. Check to see if the sender used a bad key
char* bad_fpr = NULL;
status = check_for_own_revoked_key(session, _keylist, &bad_fpr);
*dst = msg;
*keylist = _keylist;


+ 173
- 13
src/pEpEngine.c View File

@ -446,6 +446,11 @@ static const char *sql_get_contacted_ids_from_revoke_fpr =
static const char *sql_was_id_for_revoke_contacted =
"select count(*) from revocation_contact_list where fpr = ?1 and contact_id = ?2 ;";
// We only need user_id and address, since in the main usage, we'll call update_identity
// on this anyway when sending out messages.
static const char *sql_get_last_contacted =
"select userid, address from identity where datetime('now') < datetime(timestamp, '+14 days') ; ";
static int user_version(void *_version, int count, char **text, char **name)
{
@ -1220,6 +1225,27 @@ DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
&_session->get_contacted_ids_from_revoke_fpr, NULL);
assert(int_result == SQLITE_OK);
int_result = sqlite3_prepare_v2(_session->db,
sql_was_id_for_revoke_contacted,
(int)strlen(sql_was_id_for_revoke_contacted),
&_session->was_id_for_revoke_contacted, NULL);
assert(int_result == SQLITE_OK);
int_result = sqlite3_prepare_v2(_session->db,
sql_get_last_contacted,
(int)strlen(sql_get_last_contacted),
&_session->get_last_contacted, NULL);
assert(int_result == SQLITE_OK);
static const char *sql_was_id_for_revoke_contacted =
"select count(*) from revocation_contact_list where fpr = ?1 and contact_id = ?2 ;";
// We only need user_id and address, since in the main usage, we'll call update_identity
// on this anyway when sending out messages.
static const char *sql_get_last_contacted =
"select userid, address from identity where datetime('now') < datetime(timestamp, '+14 days') ; ";
int_result = sqlite3_prepare_v2(_session->db,
sql_get_own_address_binding_from_contact,
(int)strlen(sql_get_own_address_binding_from_contact),
@ -1505,7 +1531,9 @@ DYNAMIC_API void release(PEP_SESSION session)
if (session->get_contacted_ids_from_revoke_fpr)
sqlite3_finalize(session->get_contacted_ids_from_revoke_fpr);
if (session->was_id_for_revoke_contacted)
sqlite3_finalize(session->was_id_for_revoke_contacted);
sqlite3_finalize(session->was_id_for_revoke_contacted);
if (session->get_last_contacted)
sqlite3_finalize(session->get_last_contacted);
if (session->set_device_group)
sqlite3_finalize(session->set_device_group);
if (session->get_device_group)
@ -2155,6 +2183,7 @@ PEP_STATUS get_identity_without_trust_check(
return status;
}
PEP_STATUS get_identities_by_address(
PEP_SESSION session,
const char *address,
@ -2253,7 +2282,7 @@ PEP_STATUS exists_identity_entry(PEP_SESSION session, pEp_identity* identity,
break;
}
default:
status = PEP_UNKNOWN_ERROR;
status = PEP_UNKNOWN_DB_ERROR;
}
sqlite3_reset(session->exists_identity_entry);
@ -2287,7 +2316,7 @@ PEP_STATUS exists_trust_entry(PEP_SESSION session, pEp_identity* identity,
break;
}
default:
status = PEP_UNKNOWN_ERROR;
status = PEP_UNKNOWN_DB_ERROR;
}
sqlite3_reset(session->exists_trust_entry);
@ -2641,7 +2670,7 @@ PEP_STATUS exists_person(PEP_SESSION session, pEp_identity* identity,
}
default:
sqlite3_reset(session->exists_person);
return PEP_UNKNOWN_ERROR;
return PEP_UNKNOWN_DB_ERROR;
}
sqlite3_reset(session->exists_person);
}
@ -2670,10 +2699,7 @@ DYNAMIC_API PEP_STATUS is_pep_user(PEP_SESSION session, pEp_identity *identity,
*is_pep = false;
const char* user_id = identity->user_id;
if (!session || EMPTYSTR(user_id))
return PEP_ILLEGAL_VALUE;
char* alias_default = NULL;
PEP_STATUS status = get_userid_alias_default(session, user_id, &alias_default);
@ -3703,7 +3729,7 @@ DYNAMIC_API PEP_STATUS get_languagelist(
break;
default:
status = PEP_UNKNOWN_ERROR;
status = PEP_UNKNOWN_DB_ERROR;
result = SQLITE_DONE;
}
} while (result != SQLITE_DONE);
@ -3754,7 +3780,7 @@ DYNAMIC_API PEP_STATUS get_phrase(
break;
default:
status = PEP_UNKNOWN_ERROR;
status = PEP_UNKNOWN_DB_ERROR;
}
if (status == PEP_STATUS_OK) {
@ -3801,7 +3827,7 @@ static PEP_STATUS _get_sequence_value(PEP_SESSION session, const char *name,
status = PEP_RECORD_NOT_FOUND;
break;
default:
status = PEP_UNKNOWN_ERROR;
status = PEP_UNKNOWN_DB_ERROR;
}
sqlite3_reset(session->sequence_value2);
@ -3963,7 +3989,7 @@ DYNAMIC_API PEP_STATUS set_revoked(
break;
default:
status = PEP_UNKNOWN_ERROR;
status = PEP_UNKNOWN_DB_ERROR;
}
sqlite3_reset(session->set_revoked);
@ -4070,6 +4096,140 @@ DYNAMIC_API PEP_STATUS get_replacement_fpr(
return status;
}
PEP_STATUS get_last_contacted(
PEP_SESSION session,
identity_list** id_list
)
{
pEp_identity* ident;
assert(session);
assert(address);
assert(address[0]);
assert(id_list);
if (!(session && address && address[0] && id_list))
return PEP_ILLEGAL_VALUE;
*id_list = NULL;
identity_list* ident_list = NULL;
sqlite3_reset(session->get_last_contacted);
int result;
while ((result = sqlite3_step(session->get_last_contacted)) == SQLITE_ROW) {
ident = new_identity(
(const char *) sqlite3_column_text(session->get_last_contacted, 1),
NULL,
(const char *) sqlite3_column_text(session->get_last_contacted, 0),
);
assert(ident);
if (ident == NULL) {
sqlite3_reset(session->get_last_contacted);
return PEP_OUT_OF_MEMORY;
}
if (ident_list)
identity_list_add(ident_list, ident);
else
ident_list = new_identity_list(ident);
}
sqlite3_reset(session->get_last_contacted);
*id_list = ident_list;
if (!ident_list)
return PEP_CANNOT_FIND_IDENTITY;
return PEP_STATUS_OK;
}
PEP_STATUS has_key_reset_been_sent(
PEP_SESSION session,
const char* user_id,
const char* revoked_fpr,
bool* contacted)
{
assert(session);
assert(contacted);
assert(identity);
assert(!EMPTYSTR(user_id));
if (!session || !contacted || !identity || EMPTYSTR(user_id))
return PEP_ILLEGAL_VALUE;
*contacted = false;
char* alias_default = NULL;
PEP_STATUS status = get_userid_alias_default(session, user_id, &alias_default);
if (status == PEP_CANNOT_FIND_ALIAS || EMPTYSTR(alias_default)) {
free(alias_default);
alias_default = strdup(user_id);
}
sqlite3_reset(session->was_id_for_revoke_contacted);
sqlite3_bind_text(session->was_id_for_revoke_contacted, 1, revoked_fpr, -1,
SQLITE_STATIC);
sqlite3_bind_text(session->was_id_for_revoke_contacted, 2, user_id, -1,
SQLITE_STATIC);
int result = sqlite3_step(session->was_id_for_revoke_contacted);
switch (result) {
case SQLITE_ROW: {
*contacted = (sqlite3_column_int(session->was_id_for_revoke_contacted, 0) != 0);
break;
}
default:
sqlite3_reset(session->was_id_for_revoke_contacted);
free(alias_default);
return PEP_UNKNOWN_DB_ERROR;
}
sqlite3_reset(session->was_id_for_revoke_contacted);
return PEP_STATUS_OK;
}
//static const char *sql_set_revoke_contact_as_notified =
// "insert or replace into revocation_contact_list(fpr, contact_id) values (?1, ?2) ;";
PEP_STATUS set_reset_contact_notified(
PEP_SESSION session,
const char* revoke_fpr,
const char* contact_id
)
{
PEP_STATUS status = PEP_STATUS_OK;
assert(session && !EMPTY_STR(revoke_fpr) && !EMPTY_STR(contact_id));
if (!session || EMPTY_STR(revoke_fpr) || EMPTY_STR(contact_id))
return PEP_ILLEGAL_VALUE;
sqlite3_reset(session->set_revoke_contact_as_notified);
sqlite3_bind_text(session->set_revoke_contact_as_notified, 1, revoke_fpr, -1,
SQLITE_STATIC);
sqlite3_bind_text(session->set_revoke_contact_as_notified, 2, contact_id, -1,
SQLITE_STATIC);
int result;
result = sqlite3_step(session->set_revoke_contact_as_notified);
switch (result) {
case SQLITE_DONE:
status = PEP_STATUS_OK;
break;
default:
status = PEP_UNKNOWN_DB_ERROR;
}
sqlite3_reset(session->set_revoke_contact_as_notified);
return status;
}
PEP_STATUS key_created(
PEP_SESSION session,
@ -4118,7 +4278,7 @@ DYNAMIC_API PEP_STATUS reset_peptest_hack(PEP_SESSION session)
assert(int_result == SQLITE_OK);
if (int_result != SQLITE_OK)
return PEP_UNKNOWN_ERROR;
return PEP_UNKNOWN_DB_ERROR;
return PEP_STATUS_OK;
}


+ 2
- 0
src/pEpEngine.h View File

@ -44,6 +44,7 @@ typedef enum {
PEP_INIT_SQLITE3_WITHOUT_MUTEX = 0x0120,
PEP_INIT_CANNOT_OPEN_DB = 0x0121,
PEP_INIT_CANNOT_OPEN_SYSTEM_DB = 0x0122,
PEP_UNKNOWN_DB_ERROR = 0x01ff,
PEP_KEY_NOT_FOUND = 0x0201,
PEP_KEY_HAS_AMBIG_NAME = 0x0202,
@ -91,6 +92,7 @@ typedef enum {
PEP_SYNC_NO_NOTIFY_CALLBACK = 0x0901,
PEP_SYNC_ILLEGAL_MESSAGE = 0x0902,
PEP_SYNC_NO_INJECT_CALLBACK = 0x0903,
PEP_SYNC_INJECT_FAILED = 0x0904,
PEP_SEQUENCE_VIOLATED = 0x0970,
PEP_CANNOT_INCREASE_SEQUENCE = 0x0971,


+ 1
- 0
src/pEp_internal.h View File

@ -146,6 +146,7 @@ struct _pEpSession {
sqlite3_stmt *set_revoke_contact_as_notified;
sqlite3_stmt *get_contacted_ids_from_revoke_fpr;
sqlite3_stmt *was_id_for_revoke_contacted;
sqlite3_stmt *get_last_contacted;
sqlite3_stmt *set_device_group;
sqlite3_stmt *get_device_group;
sqlite3_stmt *set_pgp_keypair;


Loading…
Cancel
Save