Browse Source

ENGINE-559: first running version that passes the old tests - need to test the new functionality, but hey, it didn't explode. Theoretically, we now keep track of the latest pEp version received from pEp users.

ENGINE-641
parent
commit
23008a6113
7 changed files with 331 additions and 58 deletions
  1. +6
    -0
      src/keymanagement.c
  2. +58
    -31
      src/message_api.c
  3. +153
    -23
      src/pEpEngine.c
  4. +10
    -2
      src/pEpEngine.h
  5. +63
    -1
      src/pEp_internal.h
  6. +35
    -0
      src/stringpair.c
  7. +6
    -1
      src/stringpair.h

+ 6
- 0
src/keymanagement.c View File

@ -1198,6 +1198,12 @@ PEP_STATUS _myself(PEP_SESSION session,
identity->comm_type = PEP_ct_unknown;
}
int major_ver = 0;
int minor_ver = 0;
pEp_version_major_minor(PEP_VERSION, &major_ver, &minor_ver);
identity->major_ver = major_ver;
identity->minor_ver = minor_ver;
// 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
if (!read_only) {


+ 58
- 31
src/message_api.c View File

@ -838,7 +838,7 @@ enomem:
}
static message* wrap_message_as_attachment(message* envelope,
message* attachment, message_wrap_type wrap_type, bool keep_orig_subject) {
message* attachment, message_wrap_type wrap_type, bool keep_orig_subject, unsigned int max_major, unsigned int max_minor) {
if (!attachment)
return NULL;
@ -864,9 +864,17 @@ static message* wrap_message_as_attachment(message* envelope,
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);
if (max_major < 2 || (max_major == 2 && max_minor == 0)) {
attachment->longmsg = encapsulate_message_wrap_info(inner_type_string, attachment->longmsg);
_envelope->longmsg = encapsulate_message_wrap_info("OUTER", _envelope->longmsg);
}
else {
_envelope->longmsg = strdup(
"This message was encrypted with p≡p (https://pep.software). If you are seeing this message,\n"
"your client does not support raising message attachments. Please click on the message attachment to\n"
"to view it, or better yet, consider using p≡p!\n"
);
}
// 2.1, to replace the above
add_opt_field(attachment, X_PEP_MSG_WRAP_KEY, inner_type_string);
}
@ -1711,7 +1719,10 @@ DYNAMIC_API PEP_STATUS encrypt_message(
bool has_pEp_user = false;
PEP_comm_type max_comm_type = PEP_ct_pEp;
unsigned int max_version_major = 0;
unsigned int max_version_minor = 0;
pEp_version_major_minor(PEP_VERSION, &max_version_major, &max_version_minor);
identity_list * _il = NULL;
if (enc_format != PEP_enc_none && (_il = src->bcc) && _il->ident)
@ -1719,7 +1730,6 @@ DYNAMIC_API PEP_STATUS encrypt_message(
{
// - App splits mails with BCC in multiple mails.
// - Each email is encrypted separately
if(_il->next || (src->to && src->to->ident) || (src->cc && src->cc->ident))
{
// Only one Bcc with no other recipient allowed for now
@ -1733,6 +1743,12 @@ DYNAMIC_API PEP_STATUS encrypt_message(
_il->ident->comm_type = PEP_ct_key_not_found;
_status = PEP_STATUS_OK;
}
// 0 unless set, so safe.
set_min_version( _il->ident->major_ver, _il->ident->minor_ver,
max_version_major, max_version_minor,
&max_version_major, &max_version_minor);
bool is_blacklisted = false;
if (_il->ident->fpr && IS_PGP_CT(_il->ident->comm_type)) {
_status = blacklist_is_listed(session, _il->ident->fpr, &is_blacklisted);
@ -1758,6 +1774,7 @@ DYNAMIC_API PEP_STATUS encrypt_message(
}
else
_status = myself(session, _il->ident);
if (_status != PEP_STATUS_OK) {
status = PEP_UNENCRYPTED;
goto pEp_error;
@ -1785,6 +1802,11 @@ DYNAMIC_API PEP_STATUS encrypt_message(
_il->ident->comm_type = PEP_ct_key_not_found;
_status = PEP_STATUS_OK;
}
// 0 unless set, so safe.
set_min_version( _il->ident->major_ver, _il->ident->minor_ver,
max_version_major, max_version_minor,
&max_version_major, &max_version_minor);
bool is_blacklisted = false;
if (_il->ident->fpr && IS_PGP_CT(_il->ident->comm_type)) {
_status = blacklist_is_listed(session, _il->ident->fpr, &is_blacklisted);
@ -1906,7 +1928,7 @@ DYNAMIC_API PEP_STATUS encrypt_message(
message_wrap_type wrap_type = PEP_message_unwrapped;
if ((enc_format != PEP_enc_inline) && (!force_v_1) && ((max_comm_type | PEP_ct_confirmed) == PEP_ct_pEp)) {
wrap_type = ((flags & PEP_encrypt_flag_key_reset_only) ? PEP_message_key_reset : PEP_message_default);
_src = wrap_message_as_attachment(NULL, src, wrap_type, false);
_src = wrap_message_as_attachment(NULL, src, wrap_type, false, max_version_major, max_version_minor);
if (!_src)
goto pEp_error;
}
@ -2252,7 +2274,9 @@ 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, PEP_message_default, false);
unsigned int major_ver, minor_ver;
pEp_version_major_minor(PEP_VERSION, &major_ver, &minor_ver);
_src = wrap_message_as_attachment(NULL, src, PEP_message_default, false, major_ver, minor_ver);
if (!_src)
goto pEp_error;
@ -2985,11 +3009,13 @@ static PEP_STATUS import_priv_keys_from_decrypted_msg(PEP_SESSION session,
static PEP_STATUS pEp_version_upgrade_or_ignore(
PEP_SESSION session,
pEp_identity* ident,
float version_number) {
unsigned int major,
unsigned int minor) {
PEP_STATUS status = PEP_STATUS_OK;
if (version_number > ident->_pEp_version)
status = set_pEp_version(session, ident, version_number);
int ver_compare = compare_versions(major, minor, ident->major_ver, ident->minor_ver);
if (ver_compare > 0)
status = set_pEp_version(session, ident, major, minor);
return status;
}
@ -2999,7 +3025,8 @@ static PEP_STATUS update_sender_to_pEp_trust(
PEP_SESSION session,
pEp_identity* sender,
stringlist_t* keylist,
float version_number)
unsigned int major,
unsigned int minor)
{
assert(session);
assert(sender);
@ -3049,9 +3076,11 @@ static PEP_STATUS update_sender_to_pEp_trust(
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);
if (major == 0) {
major = 2;
minor = 0;
}
status = pEp_version_upgrade_or_ignore(session, sender, major, minor);
break;
default:
status = PEP_CANNOT_SET_TRUST;
@ -3338,8 +3367,9 @@ 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;
unsigned int major_ver;
unsigned int minor_ver;
// Grab input flags
bool reencrypt = (((*flags & PEP_decrypt_flag_untrusted_server) > 0) && *keylist && !EMPTYSTR((*keylist)->value));
@ -3625,16 +3655,11 @@ 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");
if (pEp_protocol_version && !EMPTYSTR(pEp_protocol_version->value->value)) {
// Roker is of course right. Meh :)
if (sscanf(pEp_protocol_version->value->value, "%f", &pEp_version) != 1) {
pEp_version = 0;
}
}
if (pEp_protocol_version && pEp_protocol_version->value)
pEp_version_major_minor(pEp_protocol_version->value->value, &major_ver, &minor_ver);
// Sort out pEp user status and version number based on INNER message.
bool is_inner = false;
bool is_key_reset = false;
@ -3646,20 +3671,22 @@ static PEP_STATUS _decrypt_message(
if (status != PEP_STATUS_OK)
goto pEp_error;
if (pEp_version < 2) {
if (major_ver > 2 || (major_ver == 2 && minor_ver > 0)) {
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);
if (searched && searched->value && searched->value->value) {
is_inner = (strcmp(searched->value->value, "INNER") == 0);
if (!is_inner)
is_key_reset = (strcmp(searched->value->value, "INNER") == 0);
is_key_reset = (strcmp(searched->value->value, "KEY_RESET") == 0);
if (is_inner || is_key_reset)
inner_message->opt_fields = stringpair_list_delete_by_key(inner_message->opt_fields, X_PEP_MSG_WRAP_KEY);
}
}
else {
is_inner = (strcmp(wrap_info, "INNER") == 0);
if (!is_inner)
is_key_reset = (strcmp(wrap_info, "KEY_RESET") == 0);
is_inner = (strcmp(wrap_info, "INNER") == 0);
if (!is_inner)
is_key_reset = (strcmp(wrap_info, "KEY_RESET") == 0);
}
@ -3754,7 +3781,7 @@ static PEP_STATUS _decrypt_message(
// 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, pEp_version);
status = update_sender_to_pEp_trust(session, calculated_src->from, _keylist, major_ver, minor_ver);
/* Ok, now we have a keylist used for decryption/verification.
now we need to update the message rating with the
@ -4125,7 +4152,7 @@ DYNAMIC_API PEP_STATUS outgoing_message_rating(
*rating = PEP_rating_undefined;
}
else
*rating = MAX(_rating(max_comm_type), PEP_rating_unencrypted);
*rating = _MAX(_rating(max_comm_type), PEP_rating_unencrypted);
return PEP_STATUS_OK;
}


+ 153
- 23
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"
" is_own, pEp_version_major, pEp_version_minor"
" 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"
" is_own, pEp_version_major, pEp_version_minor"
" 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"
" identity.flags, is_own, pEp_version_major, pEp_version_minor"
" 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"
" identity.flags, is_own, pEp_version_major, pEp_version_minor"
" 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"
" is_own, pEp_version_major, pEp_version_minor"
" from identity"
" join person on id = identity.user_id"
" join pgp_keypair on fpr = identity.main_key_id"
@ -239,20 +239,25 @@ 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"
" user_id, flags, is_own,"
" pEp_version_major, pEp_version_minor"
" ) values ("
" ?1,"
" upper(replace(?2,' ','')),"
" ?3,"
" ?4,"
" ?5"
" ?5,"
" ?6,"
" ?7"
" );";
static const char* sql_update_identity_entry =
"update identity "
" set main_key_id = upper(replace(?2,' ','')), "
" flags = ?4, "
" is_own = ?5 "
" is_own = ?5, "
" pEp_version_major = ?6, "
" pEp_version_major = ?7 "
" where (case when (address = ?1) then (1)"
" when (lower(address) = lower(?1)) then (1)"
" when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1) "
@ -303,13 +308,25 @@ static const char *sql_unset_identity_flags =
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) "
" set pEp_version_major = ?1, "
" pEp_version_minor = ?2 "
" where (case when (address = ?3) then (1)"
" when (lower(address) = lower(?3)) then (1)"
" when (replace(lower(address),'.','') = replace(lower(?3),'.','')) then (1) "
" else 0 "
" end) = 1 "
" and user_id = ?3 ;";
" and user_id = ?4 ;";
static const char *sql_upgrade_pEp_version_by_user_id =
"update identity "
" set pEp_version_major = ?1, "
" pEp_version_minor = ?2 "
" where user_id = ?3 "
" and (case when (pEp_version_major < ?1) then (1)"
" when (pEp_version_major > ?1) then (0)"
" when (pEp_version_minor < ?2) then (1)"
" else 0 "
" end) = 1 ;";
static const char *sql_set_trust =
"insert into trust (user_id, pgp_keypair_fpr, comm_type) "
@ -403,7 +420,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"
" lang, identity.flags | pgp_keypair.flags, pEp_version_major, pEp_version_minor"
" from identity"
" join person on id = identity.user_id"
" join pgp_keypair on fpr = identity.main_key_id"
@ -975,7 +992,8 @@ DYNAMIC_API PEP_STATUS init(
" comment text,\n"
" flags integer default 0,\n"
" is_own integer default 0,\n"
" pEp_version real default 0,\n"
" pEp_version_major integer default 0,\n"
" pEp_version_minor integer default 0,\n"
" timestamp integer default (datetime('now')),\n"
" primary key (address, user_id)\n"
");\n"
@ -1081,7 +1099,7 @@ 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")) {
if (table_contains_column(_session, "identity", "pEp_version_major")) {
version = 12;
}
else if (db_contains_table(_session, "social_graph") > 0) {
@ -1441,13 +1459,66 @@ DYNAMIC_API PEP_STATUS init(
int_result = sqlite3_exec(
_session->db,
"alter table identity\n"
" add column pEp_version real default 0\n",
" add column pEp_version_major integer default 0;\n"
"alter table identity\n"
" add column pEp_version_minor integer default 0;\n",
NULL,
NULL,
NULL
);
if (status != PEP_STATUS_OK)
return status;
int_result = sqlite3_exec(
_session->db,
"update identity\n"
" set pEp_version_major = 2\n"
" where exists (select * from person\n"
" where identity.user_id = person.id\n"
" and identity.is_own = 0\n"
" and person.is_pEp_user = 1);\n",
NULL,
NULL,
NULL
);
if (status != PEP_STATUS_OK)
return status;
return status;
// N.B. WE DEFINE PEP_VERSION - IF WE'RE AT 9-DIGIT MAJOR OR MINOR VERSIONS, ER, BAD.
char major_buf[10];
char minor_buf[10];
if (sscanf("%s.%s", major_buf, minor_buf) != 2)
return PEP_UNKNOWN_ERROR; // DO BETTER
size_t major_len = strlen(major_buf);
size_t minor_len = strlen(minor_buf);
const char* _ver_12_startstr =
"update identity\n"
" set pEp_version_major = ";
const char* _ver_12_midstr = ",\n"
" pEp_version_minor = ";
const char* _ver_12_endstr =
"\n"
" where identity.is_own = 1;\n";
size_t new_stringlen = strlen(_ver_12_startstr) + major_len +
strlen(_ver_12_midstr) + minor_len +
strlen(_ver_12_endstr);
char* _ver_12_stmt = calloc(new_stringlen + 1, 1);
snprintf(_ver_12_stmt, new_stringlen + 1, "%s%s%s%s%s",
_ver_12_startstr, major_buf, _ver_12_midstr, minor_buf, _ver_12_endstr);
int_result = sqlite3_exec(
_session->db,
_ver_12_stmt,
NULL,
NULL,
NULL
);
free(_ver_12_stmt);
if (status != PEP_STATUS_OK)
return status;
}
}
else {
@ -1651,6 +1722,11 @@ DYNAMIC_API PEP_STATUS init(
(int)strlen(sql_set_pEp_version), &_session->set_pEp_version,
NULL);
assert(int_result == SQLITE_OK);
int_result = sqlite3_prepare_v2(_session->db, sql_upgrade_pEp_version_by_user_id,
(int)strlen(sql_upgrade_pEp_version_by_user_id), &_session->upgrade_pEp_version_by_user_id,
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);
@ -1892,6 +1968,8 @@ DYNAMIC_API void release(PEP_SESSION session)
sqlite3_finalize(session->delete_person);
if (session->set_as_pEp_user)
sqlite3_finalize(session->set_as_pEp_user);
if (session->upgrade_pEp_version_by_user_id)
sqlite3_finalize(session->upgrade_pEp_version_by_user_id);
if (session->is_pEp_user)
sqlite3_finalize(session->is_pEp_user);
if (session->exists_person)
@ -1920,6 +1998,8 @@ DYNAMIC_API void release(PEP_SESSION session)
sqlite3_finalize(session->set_identity_flags);
if (session->unset_identity_flags)
sqlite3_finalize(session->unset_identity_flags);
if (session->set_pEp_version)
sqlite3_finalize(session->set_pEp_version);
if (session->exists_trust_entry)
sqlite3_finalize(session->exists_trust_entry);
if (session->set_trust)
@ -2482,6 +2562,10 @@ 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->major_ver =
sqlite3_column_int(session->get_identity, 6);
_identity->minor_ver =
sqlite3_column_int(session->get_identity, 7);
*identity = _identity;
break;
@ -2556,6 +2640,10 @@ 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->major_ver =
sqlite3_column_int(session->get_identities_by_userid, 6);
ident->minor_ver =
sqlite3_column_int(session->get_identities_by_userid, 7);
identity_list_add(*identities, ident);
ident = NULL;
@ -2622,6 +2710,10 @@ 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->major_ver =
sqlite3_column_int(session->get_identities_by_main_key_id, 7);
ident->minor_ver =
sqlite3_column_int(session->get_identities_by_main_key_id, 8);
identity_list_add(*identities, ident);
ident = NULL;
@ -2692,6 +2784,10 @@ 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->major_ver =
sqlite3_column_int(session->get_identity_without_trust_check, 6);
_identity->minor_ver =
sqlite3_column_int(session->get_identity_without_trust_check, 7);
*identity = _identity;
break;
@ -2757,6 +2853,10 @@ 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->major_ver =
sqlite3_column_int(session->get_identities_by_address, 6);
ident->minor_ver =
sqlite3_column_int(session->get_identities_by_address, 7);
if (ident_list)
identity_list_add(ident_list, ident);
@ -2913,6 +3013,9 @@ 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_int(set_or_update, 6, identity->major_ver);
sqlite3_bind_int(set_or_update, 7, identity->minor_ver);
int result = sqlite3_step(set_or_update);
sqlite3_reset(set_or_update);
if (result != SQLITE_DONE)
@ -3117,7 +3220,9 @@ PEP_STATUS update_pEp_user_trust_vals(PEP_SESSION session,
if (result != SQLITE_DONE)
return PEP_CANNOT_SET_TRUST;
return PEP_STATUS_OK;
PEP_STATUS status = upgrade_pEp_version_by_user_id(session, user, 2, 0);
return status;
}
@ -3159,16 +3264,17 @@ DYNAMIC_API PEP_STATUS set_as_pEp_user(PEP_SESSION session, pEp_identity* user)
}
// 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) {
PEP_STATUS set_pEp_version(PEP_SESSION session, pEp_identity* ident, unsigned int new_ver_major, unsigned int new_ver_minor) {
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,
sqlite3_bind_double(session->set_pEp_version, 1, new_ver_major);
sqlite3_bind_double(session->set_pEp_version, 2, new_ver_minor);
sqlite3_bind_text(session->set_pEp_version, 3, ident->address, -1,
SQLITE_STATIC);
sqlite3_bind_text(session->set_pEp_version, 3, ident->user_id, -1,
sqlite3_bind_text(session->set_pEp_version, 4, ident->user_id, -1,
SQLITE_STATIC);
int result = sqlite3_step(session->set_pEp_version);
@ -3180,6 +3286,30 @@ PEP_STATUS set_pEp_version(PEP_SESSION session, pEp_identity* ident, float new_p
return PEP_STATUS_OK;
}
// Generally ONLY called by set_as_pEp_user, and ONLY from < 2.0 to 2.0.
PEP_STATUS upgrade_pEp_version_by_user_id(PEP_SESSION session,
pEp_identity* ident,
unsigned int new_ver_major,
unsigned int new_ver_minor
)
{
assert(session);
assert(!EMPTYSTR(ident->user_id));
sqlite3_reset(session->upgrade_pEp_version_by_user_id);
sqlite3_bind_int(session->upgrade_pEp_version_by_user_id, 1, new_ver_major);
sqlite3_bind_int(session->upgrade_pEp_version_by_user_id, 2, new_ver_minor);
sqlite3_bind_text(session->upgrade_pEp_version_by_user_id, 3, ident->user_id, -1,
SQLITE_STATIC);
int result = sqlite3_step(session->upgrade_pEp_version_by_user_id);
sqlite3_reset(session->upgrade_pEp_version_by_user_id);
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) {


+ 10
- 2
src/pEpEngine.h View File

@ -632,7 +632,8 @@ typedef struct _pEp_identity {
char lang[3]; // language of conversation
// ISO 639-1 ALPHA-2, last byte is 0
bool me; // if this is the local user herself/himself
float _pEp_version; // highest version of pEp message received, if any
int major_ver; // highest version of pEp message received, if any
int minor_ver; // highest version of pEp message received, if any
identity_flags_t flags; // identity_flag1 | identity_flag2 | ...
} pEp_identity;
@ -1386,8 +1387,15 @@ 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);
PEP_STATUS set_pEp_version(PEP_SESSION session, pEp_identity* ident, unsigned int new_ver_major, unsigned int new_ver_minor);
// Generally ONLY called by set_as_pEp_user, and ONLY from < 2.0 to 2.0.
PEP_STATUS upgrade_pEp_version_by_user_id(PEP_SESSION session,
pEp_identity* ident,
unsigned int new_ver_major,
unsigned int new_ver_minor
);
// exposed for testing
PEP_STATUS set_person(PEP_SESSION session, pEp_identity* identity,
bool guard_transaction);


+ 63
- 1
src/pEp_internal.h View File

@ -181,6 +181,7 @@ struct _pEpSession {
sqlite3_stmt *exists_person;
sqlite3_stmt *set_as_pEp_user;
sqlite3_stmt *is_pEp_user;
sqlite3_stmt *upgrade_pEp_version_by_user_id;
sqlite3_stmt *add_into_social_graph;
sqlite3_stmt *get_own_address_binding_from_contact;
sqlite3_stmt *set_revoke_contact_as_notified;
@ -457,6 +458,68 @@ static inline bool is_me(PEP_SESSION session, pEp_identity* test_ident) {
return retval;
}
static inline float pEp_version_numeric(const char* version_str) {
float retval = 0;
if (!version_str || sscanf(version_str, "%f", &retval) != 1)
return 0;
return retval;
}
static inline void pEp_version_major_minor(const char* version_str, unsigned int* major, unsigned int* minor) {
if (!major || !minor)
return;
if (!version_str || sscanf(version_str, "%u.%u", major, minor) != 2) {
*major = 0;
*minor = 0;
}
return;
}
static inline int compare_versions(unsigned int first_maj, unsigned int first_min,
unsigned int second_maj, unsigned int second_min) {
if (first_maj > second_maj)
return 1;
if (first_maj < second_maj)
return -1;
if (first_min > second_min)
return 1;
if (first_min < second_min)
return -1;
return 0;
}
static inline void set_min_version(unsigned int first_maj, unsigned int first_minor,
unsigned int second_maj, unsigned int second_minor,
unsigned int* result_maj, unsigned int* result_minor) {
int result = compare_versions(first_maj, first_minor, second_maj, second_minor);
if (result < 0) {
*result_maj = first_maj;
*result_minor = first_minor;
}
else {
*result_maj = second_maj;
*result_minor = second_minor;
}
}
static inline void set_max_version(unsigned int first_maj, unsigned int first_minor,
unsigned int second_maj, unsigned int second_minor,
unsigned int* result_maj, unsigned int* result_minor) {
int result = compare_versions(first_maj, first_minor, second_maj, second_minor);
if (result > 0) {
*result_maj = first_maj;
*result_minor = first_minor;
}
else {
*result_maj = second_maj;
*result_minor = second_minor;
}
}
#ifndef EMPTYSTR
#define EMPTYSTR(STR) ((STR) == NULL || (STR)[0] == '\0')
#endif
@ -472,7 +535,6 @@ static inline bool is_me(PEP_SESSION session, pEp_identity* test_ident) {
#define _MAX(A, B) ((B) > (A) ? (B) : (A))
#endif
// These are globals used in generating message IDs and should only be
// computed once, as they're either really constants or OS-dependent


+ 35
- 0
src/stringpair.c View File

@ -194,6 +194,41 @@ DYNAMIC_API void free_stringpair_list(stringpair_list_t *stringpair_list)
}
}
// ONLY DELETES ONE.
DYNAMIC_API stringpair_list_t *stringpair_list_delete_by_key(
stringpair_list_t *sp_list,
const char *key
)
{
assert(sp_list);
assert(key);
if (sp_list->value == NULL) {
free_stringpair_list(sp_list);
return NULL;
}
if (key == NULL)
return sp_list;
stringpair_list_t *_sl;
stringpair_list_t *last = NULL;
for (_sl = sp_list; _sl && _sl->value && _sl->value->key; _sl = _sl->next) {
if (strcmp(_sl->value->key, key) == 0) {
if (last == NULL)
sp_list = sp_list->next;
else
last->next = _sl->next;
_sl->next = NULL;
free_stringpair_list(_sl);
break;
}
last = _sl;
}
return sp_list;
}
DYNAMIC_API stringpair_list_t *stringpair_list_find(
stringpair_list_t *stringpair_list,
const char *key


+ 6
- 1
src/stringpair.h View File

@ -159,8 +159,13 @@ DYNAMIC_API stringpair_list_t *stringpair_list_find(
const char *key
);
// ONLY DELETES ONE.
DYNAMIC_API stringpair_list_t *stringpair_list_delete_by_key(
stringpair_list_t *sp_list,
const char *key
);
#ifdef __cplusplus
}
#endif

Loading…
Cancel
Save