Browse Source

Can't seem to keep the branches separate - except for the "forwarded" changes, this should probably all be in 559, but was done in 551.

ENGINE-641
parent
commit
94f30b5f5f
7 changed files with 165 additions and 89 deletions
  1. +2
    -2
      src/etpan_mime.c
  2. +0
    -2
      src/keymanagement.c
  3. +100
    -53
      src/message_api.c
  4. +56
    -30
      src/pEpEngine.c
  5. +4
    -2
      src/pEpEngine.h
  6. +1
    -0
      src/pEp_internal.h
  7. +2
    -0
      test/src/util/test_util.cc

+ 2
- 2
src/etpan_mime.c View File

@ -390,7 +390,7 @@ struct mailmime * get_file_part(
stringpair_list_t* extra_params = NULL;
if (set_attachment_forward_comment)
extra_params = new_stringpair_list(new_stringpair("forward", "no"));
extra_params = new_stringpair_list(new_stringpair("forwarded", "no"));
mime = part_new_empty(content, mime_fields, extra_params, 1);
free_stringpair_list(extra_params);
@ -2628,7 +2628,7 @@ static PEP_STATUS interpret_MIME(
for (cur = clist_begin(content->ct_parameters); cur; cur =
clist_next(cur)) {
struct mailmime_parameter * param = clist_content(cur);
if (param && param->pa_name && strcasecmp(param->pa_name, "forward") == 0) {
if (param && param->pa_name && strcasecmp(param->pa_name, "forwarded") == 0) {
if (param->pa_value && strcasecmp(param->pa_value, "no") == 0) {
*raise_msg_attachment = true;
break;


+ 0
- 2
src/keymanagement.c View File

@ -1692,8 +1692,6 @@ PEP_STATUS _own_identities_retrieve(
}
ident->me = true;
ident->flags = flags;
ident->pEp_version = (float)
sqlite3_column_double(session->own_identities_retrieve, 6);
_bl = identity_list_add(_bl, ident);
if (_bl == NULL) {


+ 100
- 53
src/message_api.c View File

@ -2981,11 +2981,25 @@ static PEP_STATUS import_priv_keys_from_decrypted_msg(PEP_SESSION session,
return status;
}
// ident is in_only and should have been updated
static PEP_STATUS pEp_version_upgrade_or_ignore(
PEP_SESSION session,
pEp_identity* ident,
float version_number) {
PEP_STATUS status = PEP_STATUS_OK;
if (version_number > ident->_pEp_version)
status = set_pEp_version(session, ident, version_number);
return status;
}
// FIXME: myself ??????
static PEP_STATUS update_sender_to_pEp_trust(
PEP_SESSION session,
pEp_identity* sender,
stringlist_t* keylist)
stringlist_t* keylist,
float version_number)
{
assert(session);
assert(sender);
@ -2996,9 +3010,11 @@ static PEP_STATUS update_sender_to_pEp_trust(
free(sender->fpr);
sender->fpr = NULL;
PEP_STATUS status =
is_me(session, sender) ? myself(session, sender) : update_identity(session, sender);
PEP_STATUS status = PEP_STATUS_OK;
// Seems status doesn't matter
is_me(session, sender) ? myself(session, sender) : update_identity(session, sender);
if (EMPTYSTR(sender->fpr) || strcmp(sender->fpr, keylist->value) != 0) {
free(sender->fpr);
@ -3023,11 +3039,19 @@ static PEP_STATUS update_sender_to_pEp_trust(
// Could be done elegantly, but we do this explicitly here for readability.
// This file's code is difficult enough to parse. But change at will.
switch (sender->comm_type) {
switch (sender->comm_type) {
case PEP_ct_OpenPGP_unconfirmed:
case PEP_ct_OpenPGP:
sender->comm_type = PEP_ct_pEp_unconfirmed | (sender->comm_type & PEP_ct_confirmed);
status = set_trust(session, sender);
if (status != PEP_STATUS_OK)
break;
case PEP_ct_pEp:
case PEP_ct_pEp_unconfirmed:
// set version
if (version_number == 0)
version_number = 2;
status = pEp_version_upgrade_or_ignore(session, sender, version_number);
break;
default:
status = PEP_CANNOT_SET_TRUST;
@ -3314,6 +3338,7 @@ static PEP_STATUS _decrypt_message(
char* signer_fpr = NULL;
bool is_pEp_msg = is_a_pEpmessage(src);
bool myself_read_only = (src->dir == PEP_dir_incoming);
float pEp_version = 0;
// Grab input flags
bool reencrypt = (((*flags & PEP_decrypt_flag_untrusted_server) > 0) && *keylist && !EMPTYSTR((*keylist)->value));
@ -3330,34 +3355,39 @@ static PEP_STATUS _decrypt_message(
*keylist = NULL;
*rating = PEP_rating_undefined;
// *flags = 0;
/*** End init ***/
// Ok, before we do anything, if it's a pEp message, regardless of whether it's
// KB: FIXME - we should do this once we've seen an inner message in the case
// of pEp users. Since we've not used 1.0 in a billion years (but will receive
// 1.0 messages from pEp users who don't yet know WE are pEp users), we should
// sort this out sanely, not upfront.
//
// Was: Ok, before we do anything, if it's a pEp message, regardless of whether it's
// encrypted or not, we set the sender as a pEp user. This has NOTHING to do
// with the key.
if (src->from && !(is_me(session, src->from))) {
if (is_pEp_msg) {
pEp_identity* tmp_from = src->from;
// Ensure there's a user id
if (EMPTYSTR(tmp_from->user_id) && tmp_from->address) {
status = update_identity(session, tmp_from);
if (status == PEP_CANNOT_FIND_IDENTITY) {
tmp_from->user_id = calloc(1, strlen(tmp_from->address) + 6);
if (!tmp_from->user_id)
return PEP_OUT_OF_MEMORY;
snprintf(tmp_from->user_id, strlen(tmp_from->address) + 6,
"TOFU_%s", tmp_from->address);
status = PEP_STATUS_OK;
}
}
if (status == PEP_STATUS_OK) {
// Now set user as PEP (may also create an identity if none existed yet)
status = set_as_pEp_user(session, tmp_from);
}
}
}
// if (src->from && !(is_me(session, src->from))) {
// if (is_pEp_msg) {
// pEp_identity* tmp_from = src->from;
//
// // Ensure there's a user id
// if (EMPTYSTR(tmp_from->user_id) && tmp_from->address) {
// status = update_identity(session, tmp_from);
// if (status == PEP_CANNOT_FIND_IDENTITY) {
// tmp_from->user_id = calloc(1, strlen(tmp_from->address) + 6);
// if (!tmp_from->user_id)
// return PEP_OUT_OF_MEMORY;
// snprintf(tmp_from->user_id, strlen(tmp_from->address) + 6,
// "TOFU_%s", tmp_from->address);
// status = PEP_STATUS_OK;
// }
// }
// if (status == PEP_STATUS_OK) {
// // Now set user as PEP (may also create an identity if none existed yet)
// status = set_as_pEp_user(session, tmp_from);
// }
// }
// }
// We really need key used in signing to do anything further on the pEp comm_type.
// So we can't adjust the rating of the sender just yet.
@ -3373,16 +3403,16 @@ static PEP_STATUS _decrypt_message(
import_header_keys(session, src);
// FIXME: is this really necessary here?
if (src->from) {
if (!is_me(session, src->from))
status = update_identity(session, src->from);
else
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)
return status;
}
// if (src->from) {
// if (!is_me(session, src->from))
// status = update_identity(session, src->from);
// else
// 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)
// return status;
// }
/*** End Import any attached public keys and update identities accordingly ***/
@ -3582,6 +3612,8 @@ static PEP_STATUS _decrypt_message(
goto pEp_error;
if (inner_message) {
is_pEp_msg = is_a_pEpmessage(inner_message);
// Though this will strip any message info on the
// attachment, this is safe, as we do not
// produce more than one attachment-as-message,
@ -3592,16 +3624,17 @@ static PEP_STATUS _decrypt_message(
const stringpair_list_t* pEp_protocol_version = NULL;
pEp_protocol_version = stringpair_list_find(inner_message->opt_fields, "X-pEp-Version");
unsigned int pEp_v_major = 0;
unsigned int pEp_v_minor = 0;
if (pEp_protocol_version && !EMPTYSTR(pEp_protocol_version->value->value)) {
// Roker is of course right. Meh :)
if (sscanf(pEp_protocol_version->value->value, "%u.%u", &pEp_v_major, &pEp_v_minor) != 2) {
pEp_v_major = 0;
pEp_v_minor = 0;
if (sscanf(pEp_protocol_version->value->value, "%f", &pEp_version) != 1) {
pEp_version = 0;
}
}
// Sort out pEp user status and version number based on INNER message.
bool is_inner = false;
bool is_key_reset = false;
@ -3613,7 +3646,7 @@ static PEP_STATUS _decrypt_message(
if (status != PEP_STATUS_OK)
goto pEp_error;
if (((pEp_v_major == 2) && (pEp_v_minor > 0)) || (pEp_v_major > 2)) {
if (pEp_version < 2) {
stringpair_list_t* searched = stringpair_list_find(inner_message->opt_fields, "X-pEp-Sender-FPR");
inner_message->_sender_fpr = ((searched && searched->value && searched->value->value) ? strdup(searched->value->value) : NULL);
searched = stringpair_list_find(inner_message->opt_fields, X_PEP_MSG_WRAP_KEY);
@ -3673,13 +3706,6 @@ static PEP_STATUS _decrypt_message(
//src = msg = inner_message;
calculated_src = msg = inner_message;
// FIXME: should this be msg???
if (src->from) {
if (!is_me(session, src->from))
update_identity(session, (src->from));
else
_myself(session, src->from, false, false, myself_read_only);
}
}
else { // should never happen
status = PEP_UNKNOWN_ERROR;
@ -3700,14 +3726,35 @@ static PEP_STATUS _decrypt_message(
// else {} // shouldn't be anything to be done here
} // end if (has_inner || wrap_info)
else {
} // this we do if this isn't an inner message
pEp_identity* cs_from = calculated_src->from;
if (cs_from && !EMPTYSTR(cs_from->address)) {
if (!is_me(session, cs_from)) {
status = update_identity(session, cs_from);
if (status == PEP_CANNOT_FIND_IDENTITY) {
cs_from->user_id = calloc(1, strlen(cs_from->address) + 6);
if (!cs_from->user_id)
return PEP_OUT_OF_MEMORY;
snprintf(cs_from->user_id, strlen(cs_from->address) + 6,
"TOFU_%s", cs_from->address);
status = PEP_STATUS_OK;
}
}
else
status = _myself(session, cs_from, false, false, myself_read_only);
}
} // end if (decrypt_status == PEP_DECRYPTED || decrypt_status == PEP_DECRYPTED_AND_VERIFIED)
*rating = decrypt_rating(decrypt_status);
// Ok, so if it was signed and it's all verified, we can update
// eligible signer comm_types to PEP_ct_pEp_*
// This also sets and upgrades pEp version
if (decrypt_status == PEP_DECRYPTED_AND_VERIFIED && is_pEp_msg && calculated_src->from)
status = update_sender_to_pEp_trust(session, calculated_src->from, _keylist);
status = update_sender_to_pEp_trust(session, calculated_src->from, _keylist, pEp_version);
/* Ok, now we have a keylist used for decryption/verification.
now we need to update the message rating with the


+ 56
- 30
src/pEpEngine.c View File

@ -83,7 +83,7 @@ static const char *sql_trustword =
static const char *sql_get_identity =
"select fpr, username, comm_type, lang,"
" identity.flags | pgp_keypair.flags,"
" is_own, pEp_version"
" is_own"
" from identity"
" join person on id = identity.user_id"
" join pgp_keypair on fpr = identity.main_key_id"
@ -101,7 +101,7 @@ static const char *sql_get_identity =
static const char *sql_get_identities_by_main_key_id =
"select address, identity.user_id, username, comm_type, lang,"
" identity.flags | pgp_keypair.flags,"
" is_own, pEp_version"
" is_own"
" from identity"
" join person on id = identity.user_id"
" join pgp_keypair on fpr = identity.main_key_id"
@ -113,7 +113,7 @@ static const char *sql_get_identities_by_main_key_id =
static const char *sql_get_identity_without_trust_check =
"select identity.main_key_id, username, lang,"
" identity.flags, is_own, pEp_version"
" identity.flags, is_own"
" from identity"
" join person on id = identity.user_id"
" where (case when (address = ?1) then (1)"
@ -127,7 +127,7 @@ static const char *sql_get_identity_without_trust_check =
static const char *sql_get_identities_by_address =
"select user_id, identity.main_key_id, username, lang,"
" identity.flags, is_own, pEp_version"
" identity.flags, is_own"
" from identity"
" join person on id = identity.user_id"
" where (case when (address = ?1) then (1)"
@ -141,7 +141,7 @@ static const char *sql_get_identities_by_address =
static const char *sql_get_identities_by_userid =
"select address, fpr, username, comm_type, lang,"
" identity.flags | pgp_keypair.flags,"
" is_own, pEp_version"
" is_own"
" from identity"
" join person on id = identity.user_id"
" join pgp_keypair on fpr = identity.main_key_id"
@ -239,22 +239,20 @@ static const char* sql_exists_identity_entry =
static const char *sql_set_identity_entry =
"insert into identity ("
" address, main_key_id, "
" user_id, flags, is_own, pEp_version"
" user_id, flags, is_own"
" ) values ("
" ?1,"
" upper(replace(?2,' ','')),"
" ?3,"
" ?4,"
" ?5,"
" ?6"
" ?5"
" );";
static const char* sql_update_identity_entry =
"update identity "
" set main_key_id = upper(replace(?2,' ','')), "
" flags = ?4, "
" is_own = ?5, "
" pEp_version = ?6 "
" is_own = ?5 "
" where (case when (address = ?1) then (1)"
" when (lower(address) = lower(?1)) then (1)"
" when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1) "
@ -303,6 +301,16 @@ static const char *sql_unset_identity_flags =
" end) = 1"
" and user_id = ?3 ;";
static const char *sql_set_pEp_version =
"update identity "
" set pEp_version = ?1 "
" where (case when (address = ?2) then (1)"
" when (lower(address) = lower(?2)) then (1)"
" when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1) "
" else 0 "
" end) = 1 "
" and user_id = ?3 ;";
static const char *sql_set_trust =
"insert into trust (user_id, pgp_keypair_fpr, comm_type) "
"values (?1, upper(replace(?2,' ','')), ?3) ;";
@ -355,7 +363,7 @@ static const char *sql_languagelist =
static const char *sql_i18n_token =
"select phrase from i18n_token where lang = lower(?1) and id = ?2 ;";
// blacklist
static const char *sql_blacklist_add =
"insert or ignore into blacklist_keys (fpr) values (upper(replace(?1,' ',''))) ;"
@ -395,7 +403,7 @@ static const char *sql_is_own_address =
static const char *sql_own_identities_retrieve =
"select address, fpr, identity.user_id, username,"
" lang, identity.flags | pgp_keypair.flags, pEp_version"
" lang, identity.flags | pgp_keypair.flags"
" from identity"
" join person on id = identity.user_id"
" join pgp_keypair on fpr = identity.main_key_id"
@ -906,7 +914,7 @@ DYNAMIC_API PEP_STATUS init(
sqlite3_busy_timeout(_session->system_db, 1000);
// increment this when patching DDL
#define _DDL_USER_VERSION "12"
#define _DDL_USER_VERSION "11"
if (in_first) {
@ -967,7 +975,7 @@ DYNAMIC_API PEP_STATUS init(
" comment text,\n"
" flags integer default 0,\n"
" is_own integer default 0,\n"
" pEp_version real default 0.0,\n"
" pEp_version real default 0,\n"
" timestamp integer default (datetime('now')),\n"
" primary key (address, user_id)\n"
");\n"
@ -1073,9 +1081,9 @@ DYNAMIC_API PEP_STATUS init(
// Sometimes the user_version wasn't set correctly.
if (version == 1) {
bool version_changed = true;
if (table_contains_column(_session, "identity", "pEp_version") > 0) {
if (table_contains_column(_session, "identity", "pEp_version")) {
version = 12;
} // N.B. Version 11 was a DB internal fix; there's no identifying information, but this is only one extra exec.
}
else if (db_contains_table(_session, "social_graph") > 0) {
if (!table_contains_column(_session, "person", "device_group"))
version = 10;
@ -1433,12 +1441,13 @@ DYNAMIC_API PEP_STATUS init(
int_result = sqlite3_exec(
_session->db,
"alter table identity\n"
" add column pEp_version real default 0.0;\n",
" add column pEp_version real default 0\n",
NULL,
NULL,
NULL
);
assert(int_result == SQLITE_OK);
if (status != PEP_STATUS_OK)
return status;
}
}
else {
@ -1638,6 +1647,11 @@ DYNAMIC_API PEP_STATUS init(
NULL);
assert(int_result == SQLITE_OK);
int_result = sqlite3_prepare_v2(_session->db, sql_set_pEp_version,
(int)strlen(sql_set_pEp_version), &_session->set_pEp_version,
NULL);
assert(int_result == SQLITE_OK);
int_result = sqlite3_prepare_v2(_session->db, sql_set_trust,
(int)strlen(sql_set_trust), &_session->set_trust, NULL);
assert(int_result == SQLITE_OK);
@ -2468,8 +2482,6 @@ DYNAMIC_API PEP_STATUS get_identity(
sqlite3_column_int(session->get_identity, 4);
_identity->me = (unsigned int)
sqlite3_column_int(session->get_identity, 5);
_identity->pEp_version = (float)
sqlite3_column_double(session->get_identity, 6);
*identity = _identity;
break;
@ -2544,8 +2556,6 @@ PEP_STATUS get_identities_by_userid(
sqlite3_column_int(session->get_identities_by_userid, 5);
ident->me = (unsigned int)
sqlite3_column_int(session->get_identities_by_userid, 6);
ident->pEp_version = (float)
sqlite3_column_double(session->get_identities_by_userid, 7);
identity_list_add(*identities, ident);
ident = NULL;
@ -2612,8 +2622,6 @@ PEP_STATUS get_identities_by_main_key_id(
sqlite3_column_int(session->get_identities_by_main_key_id, 5);
ident->me = (unsigned int)
sqlite3_column_int(session->get_identities_by_main_key_id, 6);
ident->pEp_version = (float)
sqlite3_column_double(session->get_identities_by_main_key_id, 7);
identity_list_add(*identities, ident);
ident = NULL;
@ -2684,8 +2692,6 @@ PEP_STATUS get_identity_without_trust_check(
sqlite3_column_int(session->get_identity_without_trust_check, 3);
_identity->me = (unsigned int)
sqlite3_column_int(session->get_identity_without_trust_check, 4);
_identity->pEp_version = (float)
sqlite3_column_double(session->get_identity_without_trust_check, 5);
*identity = _identity;
break;
@ -2751,8 +2757,6 @@ PEP_STATUS get_identities_by_address(
sqlite3_column_int(session->get_identities_by_address, 4);
ident->me = (unsigned int)
sqlite3_column_int(session->get_identities_by_address, 5);
ident->pEp_version = (float)
sqlite3_column_double(session->get_identities_by_address, 6);
if (ident_list)
identity_list_add(ident_list, ident);
@ -2909,7 +2913,6 @@ static PEP_STATUS _set_or_update_identity_entry(PEP_SESSION session,
SQLITE_STATIC);
sqlite3_bind_int(set_or_update, 4, identity->flags);
sqlite3_bind_int(set_or_update, 5, identity->me);
sqlite3_bind_double(set_or_update, 6, identity->pEp_version);
int result = sqlite3_step(set_or_update);
sqlite3_reset(set_or_update);
if (result != SQLITE_DONE)
@ -3023,7 +3026,7 @@ PEP_STATUS set_identity_entry(PEP_SESSION session, pEp_identity* identity,
guard_transaction);
}
// This will NOT call set_as_pEp_user; you have to do that separately.
// This will NOT call set_as_pEp_user, nor set_pEp_version; you have to do that separately.
DYNAMIC_API PEP_STATUS set_identity(
PEP_SESSION session, const pEp_identity *identity
)
@ -3155,6 +3158,29 @@ DYNAMIC_API PEP_STATUS set_as_pEp_user(PEP_SESSION session, pEp_identity* user)
return status;
}
// This ONLY sets the version flag. Must be called outside of a transaction.
PEP_STATUS set_pEp_version(PEP_SESSION session, pEp_identity* ident, float new_pEp_version) {
assert(session);
assert(!EMPTYSTR(ident->user_id));
assert(!EMPTYSTR(ident->address));
sqlite3_reset(session->set_pEp_version);
sqlite3_bind_double(session->set_pEp_version, 1, new_pEp_version);
sqlite3_bind_text(session->set_pEp_version, 2, ident->address, -1,
SQLITE_STATIC);
sqlite3_bind_text(session->set_pEp_version, 3, ident->user_id, -1,
SQLITE_STATIC);
int result = sqlite3_step(session->set_pEp_version);
sqlite3_reset(session->set_pEp_version);
if (result != SQLITE_DONE)
return PEP_CANNOT_SET_PEP_VERSION;
return PEP_STATUS_OK;
}
PEP_STATUS exists_person(PEP_SESSION session, pEp_identity* identity,
bool* exists) {


+ 4
- 2
src/pEpEngine.h View File

@ -68,6 +68,7 @@ typedef enum {
PEP_CANNOT_SET_TRUST = 0x0384,
PEP_KEY_BLACKLISTED = 0x0385,
PEP_CANNOT_FIND_PERSON = 0x0386,
PEP_CANNOT_SET_PEP_VERSION = 0X0387,
PEP_CANNOT_FIND_ALIAS = 0x0391,
PEP_CANNOT_SET_ALIAS = 0x0392,
@ -630,9 +631,8 @@ typedef struct _pEp_identity {
PEP_comm_type comm_type; // type of communication with this ID
char lang[3]; // language of conversation
// ISO 639-1 ALPHA-2, last byte is 0
float pEp_version; // Used to determine highest seenencryption format.
// default is 2.0 for pEp users
bool me; // if this is the local user herself/himself
float _pEp_version; // highest version of pEp message received, if any
identity_flags_t flags; // identity_flag1 | identity_flag2 | ...
} pEp_identity;
@ -1386,6 +1386,8 @@ PEP_STATUS exists_person(PEP_SESSION session, pEp_identity* identity, bool* exis
PEP_STATUS set_pgp_keypair(PEP_SESSION session, const char* fpr);
PEP_STATUS set_pEp_version(PEP_SESSION session, pEp_identity* ident, float new_pEp_version);
// exposed for testing
PEP_STATUS set_person(PEP_SESSION session, pEp_identity* identity,
bool guard_transaction);


+ 1
- 0
src/pEp_internal.h View File

@ -195,6 +195,7 @@ struct _pEpSession {
sqlite3_stmt *exists_identity_entry;
sqlite3_stmt *set_identity_flags;
sqlite3_stmt *unset_identity_flags;
sqlite3_stmt *set_pEp_version;
sqlite3_stmt *set_trust;
sqlite3_stmt *update_trust;
sqlite3_stmt *exists_trust_entry;


+ 2
- 0
test/src/util/test_util.cc View File

@ -184,6 +184,8 @@ const char* tl_status_string(PEP_STATUS status) {
return "PEP_CANNOT_SET_PERSON";
case PEP_CANNOT_SET_PGP_KEYPAIR:
return "PEP_CANNOT_SET_PGP_KEYPAIR";
case PEP_CANNOT_SET_PEP_VERSION:
return "PEP_CANNOT_SET_PEP_VERSION";
case PEP_CANNOT_SET_IDENTITY:
return "PEP_CANNOT_SET_IDENTITY";
case PEP_CANNOT_SET_TRUST:


Loading…
Cancel
Save