1.1 --- a/src/pEpEngine.c Mon Sep 23 15:00:30 2019 +0200
1.2 +++ b/src/pEpEngine.c Mon Jun 29 14:48:46 2020 +0200
1.3 @@ -11,8 +11,7 @@
1.4 #include <time.h>
1.5 #include <stdlib.h>
1.6
1.7 -#define _PEP_SQLITE_DEBUG 0
1.8 -#if _PEP_SQLITE_DEBUG
1.9 +#ifdef _PEP_SQLITE_DEBUG
1.10 #include <sqlite3.h>
1.11 #endif
1.12
1.13 @@ -42,7 +41,7 @@
1.14 }
1.15 }
1.16
1.17 -#if _PEP_SQLITE_DEBUG
1.18 +#ifdef _PEP_SQLITE_DEBUG
1.19 int sql_trace_callback (unsigned trace_constant,
1.20 void* context_ptr,
1.21 void* P,
1.22 @@ -54,7 +53,7 @@
1.23 if (!EMPTYSTR(X_str) && X_str[0] == '-' && X_str[1] == '-')
1.24 fprintf(stderr, "%s\n", X_str);
1.25 else
1.26 - fprintf(stderr, "%s\n", sqlite3_expanded_sql((sqlite3_stmt*)P));
1.27 + fprintf(stderr, "%s\n", sqlite3_expanded_sql((sqlite3_stmt*)P));
1.28 break;
1.29 case SQLITE_TRACE_ROW:
1.30 fprintf(stderr, "SQL_DEBUG: ROW - ");
1.31 @@ -81,13 +80,13 @@
1.32
1.33 // FIXME?: problems if we don't have a key for the user - we get nothing
1.34 static const char *sql_get_identity =
1.35 - "select fpr, username, comm_type, lang,"
1.36 + "select identity.main_key_id, username, comm_type, lang,"
1.37 " identity.flags | pgp_keypair.flags,"
1.38 " is_own, pEp_version_major, pEp_version_minor"
1.39 " from identity"
1.40 " join person on id = identity.user_id"
1.41 - " join pgp_keypair on fpr = identity.main_key_id"
1.42 - " join trust on id = trust.user_id"
1.43 + " left join pgp_keypair on fpr = identity.main_key_id"
1.44 + " left join trust on id = trust.user_id"
1.45 " and pgp_keypair_fpr = identity.main_key_id"
1.46 " where (case when (address = ?1) then (1)"
1.47 " when (lower(address) = lower(?1)) then (1)"
1.48 @@ -104,8 +103,8 @@
1.49 " is_own, pEp_version_major, pEp_version_minor"
1.50 " from identity"
1.51 " join person on id = identity.user_id"
1.52 - " join pgp_keypair on fpr = identity.main_key_id"
1.53 - " join trust on id = trust.user_id"
1.54 + " left join pgp_keypair on fpr = identity.main_key_id"
1.55 + " left join trust on id = trust.user_id"
1.56 " and pgp_keypair_fpr = identity.main_key_id"
1.57 " where identity.main_key_id = ?1"
1.58 " order by is_own desc, "
1.59 @@ -139,13 +138,13 @@
1.60 " timestamp desc; ";
1.61
1.62 static const char *sql_get_identities_by_userid =
1.63 - "select address, fpr, username, comm_type, lang,"
1.64 + "select address, identity.main_key_id, username, comm_type, lang,"
1.65 " identity.flags | pgp_keypair.flags,"
1.66 " is_own, pEp_version_major, pEp_version_minor"
1.67 " from identity"
1.68 " join person on id = identity.user_id"
1.69 - " join pgp_keypair on fpr = identity.main_key_id"
1.70 - " join trust on id = trust.user_id"
1.71 + " left join pgp_keypair on fpr = identity.main_key_id"
1.72 + " left join trust on id = trust.user_id"
1.73 " and pgp_keypair_fpr = identity.main_key_id"
1.74 " where identity.user_id = ?1"
1.75 " order by is_own desc, "
1.76 @@ -156,10 +155,12 @@
1.77 " set main_key_id = ?1 "
1.78 " where main_key_id = ?2 ;";
1.79
1.80 -static const char *sql_remove_fpr_as_default =
1.81 - "update person set main_key_id = NULL where main_key_id = ?1 ;"
1.82 +static const char *sql_remove_fpr_as_identity_default =
1.83 "update identity set main_key_id = NULL where main_key_id = ?1 ;";
1.84
1.85 +static const char *sql_remove_fpr_as_user_default =
1.86 + "update person set main_key_id = NULL where main_key_id = ?1 ;";
1.87 +
1.88 // Set person, but if already exist, only update.
1.89 // if main_key_id already set, don't touch.
1.90 static const char *sql_set_person =
1.91 @@ -211,13 +212,18 @@
1.92 "select main_key_id from person"
1.93 " where id = ?1 ;";
1.94
1.95 +static const char *sql_replace_main_user_fpr_if_equal =
1.96 + "update person "
1.97 + " set main_key_id = ?1 "
1.98 + " where id = ?2 and main_key_id = ?3;";
1.99 +
1.100 static const char *sql_refresh_userid_default_key =
1.101 "update person "
1.102 " set main_key_id = "
1.103 " (select identity.main_key_id from identity "
1.104 " join trust on trust.user_id = identity.user_id "
1.105 " and trust.pgp_keypair_fpr = identity.main_key_id "
1.106 - " join person on identity.user_id = identity.user_id "
1.107 + " join person on person.id = identity.user_id "
1.108 " where identity.user_id = ?1 "
1.109 " order by trust.comm_type desc "
1.110 " limit 1) "
1.111 @@ -336,6 +342,10 @@
1.112 "update trust set comm_type = ?3 "
1.113 " where user_id = ?1 and pgp_keypair_fpr = upper(replace(?2,' ',''));";
1.114
1.115 +static const char *sql_clear_trust_info =
1.116 + "delete from trust "
1.117 + " where user_id = ?1 and pgp_keypair_fpr = upper(replace(?2,' ',''));";
1.118 +
1.119 static const char *sql_update_trust_to_pEp =
1.120 "update trust set comm_type = comm_type + 71 "
1.121 " where (user_id = ?1 "
1.122 @@ -419,18 +429,18 @@
1.123 ");";
1.124
1.125 static const char *sql_own_identities_retrieve =
1.126 - "select address, fpr, identity.user_id, username,"
1.127 + "select address, identity.main_key_id, identity.user_id, username,"
1.128 " lang, identity.flags | pgp_keypair.flags, pEp_version_major, pEp_version_minor"
1.129 " from identity"
1.130 " join person on id = identity.user_id"
1.131 - " join pgp_keypair on fpr = identity.main_key_id"
1.132 - " join trust on id = trust.user_id"
1.133 + " left join pgp_keypair on fpr = identity.main_key_id"
1.134 + " left join trust on id = trust.user_id"
1.135 " and pgp_keypair_fpr = identity.main_key_id"
1.136 " where identity.is_own = 1"
1.137 " and (identity.flags & ?1) = 0;";
1.138
1.139 static const char *sql_own_keys_retrieve =
1.140 - "select pgp_keypair_fpr from trust"
1.141 + "select distinct pgp_keypair_fpr from trust"
1.142 " join identity on trust.user_id = identity.user_id"
1.143 " where identity.is_own = 1";
1.144
1.145 @@ -446,7 +456,7 @@
1.146 "select id from person"
1.147 " join identity on id = identity.user_id"
1.148 " where identity.is_own = 1";
1.149 -
1.150 +
1.151 // Sequence
1.152 static const char *sql_sequence_value1 =
1.153 "insert or replace into sequences (name, value) "
1.154 @@ -500,19 +510,22 @@
1.155 "select own_address from social_graph where own_userid = ?1 and contact_userid = ?2 ;";
1.156
1.157 static const char *sql_set_revoke_contact_as_notified =
1.158 - "insert or replace into revocation_contact_list(fpr, contact_id) values (?1, ?2) ;";
1.159 + "insert or replace into revocation_contact_list(fpr, own_address, contact_id) values (?1, ?2, ?3) ;";
1.160
1.161 static const char *sql_get_contacted_ids_from_revoke_fpr =
1.162 "select * from revocation_contact_list where fpr = ?1 ;";
1.163
1.164 static const char *sql_was_id_for_revoke_contacted =
1.165 - "select count(*) from revocation_contact_list where fpr = ?1 and contact_id = ?2 ;";
1.166 + "select count(*) from revocation_contact_list where fpr = ?1 and own_address = ?2 and contact_id = ?3 ;";
1.167 +
1.168 +static const char *sql_has_id_contacted_address =
1.169 + "select count(*) from social_graph where own_address = ?1 and contact_userid = ?2 ;";
1.170
1.171 // We only need user_id and address, since in the main usage, we'll call update_identity
1.172 // on this anyway when sending out messages.
1.173 static const char *sql_get_last_contacted =
1.174 "select user_id, address from identity where datetime('now') < datetime(timestamp, '+14 days') ; ";
1.175 -
1.176 +
1.177 static int user_version(void *_version, int count, char **text, char **name)
1.178 {
1.179 assert(_version);
1.180 @@ -560,7 +573,7 @@
1.181
1.182 int retval = 0;
1.183
1.184 - int rc = Sqlite3_step(stmt);
1.185 + int rc = sqlite3_step(stmt);
1.186 if (rc == SQLITE_DONE || rc == SQLITE_OK || rc == SQLITE_ROW) {
1.187 retval = 1;
1.188 }
1.189 @@ -611,7 +624,7 @@
1.190
1.191 int retval = 0;
1.192
1.193 - int rc = Sqlite3_step(stmt);
1.194 + int rc = sqlite3_step(stmt);
1.195 if (rc == SQLITE_DONE || rc == SQLITE_OK || rc == SQLITE_ROW) {
1.196 retval = 1;
1.197 }
1.198 @@ -624,7 +637,7 @@
1.199 PEP_STATUS repair_altered_tables(PEP_SESSION session) {
1.200 PEP_STATUS status = PEP_STATUS_OK;
1.201
1.202 - const unsigned int _PEP_MAX_AFFECTED = 5;
1.203 + const int _PEP_MAX_AFFECTED = 5;
1.204 char** table_names = calloc(_PEP_MAX_AFFECTED, sizeof(char*));
1.205 if (!table_names)
1.206 return PEP_OUT_OF_MEMORY;
1.207 @@ -634,7 +647,7 @@
1.208 sqlite3_prepare_v2(session->db, sql_query, -1, &stmt, NULL);
1.209 int i = 0;
1.210 int int_result = 0;
1.211 - while ((int_result = Sqlite3_step(stmt)) == SQLITE_ROW && i < _PEP_MAX_AFFECTED) {
1.212 + while ((int_result = sqlite3_step(stmt)) == SQLITE_ROW && i < _PEP_MAX_AFFECTED) {
1.213 table_names[i++] = strdup((const char*)(sqlite3_column_text(stmt, 0)));
1.214 }
1.215
1.216 @@ -803,9 +816,123 @@
1.217 fprintf(stderr, "(%d) %s\n", iErrCode, zMsg);
1.218 }
1.219
1.220 -#ifdef USE_GPG
1.221 -PEP_STATUS pgp_import_ultimately_trusted_keypairs(PEP_SESSION session);
1.222 -#endif // USE_GPG
1.223 +static PEP_STATUS upgrade_revoc_contact_to_13(PEP_SESSION session) {
1.224 + // I HATE SQLITE.
1.225 + PEP_STATUS status = PEP_STATUS_OK;
1.226 + int int_result = 0;
1.227 +
1.228 + // Ok, first we ADD the column so we can USE it.
1.229 + // We will end up propagating the "error" this first time
1.230 + // (one-to-one revoke-replace relationships), but since key reset
1.231 + // hasn't been used in production, this is not a customer-facing
1.232 + // issue.
1.233 +
1.234 + // Note: the check upfront is to deal with partially-upgraded DB issues
1.235 + if (!table_contains_column(session, "revocation_contact_list", "own_address")) {
1.236 + int_result = sqlite3_exec(
1.237 + session->db,
1.238 + "alter table revocation_contact_list\n"
1.239 + " add column own_address text;\n",
1.240 + NULL,
1.241 + NULL,
1.242 + NULL
1.243 + );
1.244 + assert(int_result == SQLITE_OK);
1.245 + }
1.246 +
1.247 + // the best we can do here is search per address, since these
1.248 + // are no longer associated with an identity. For now, if we find
1.249 + // something we can't add an address to, we'll delete the record.
1.250 + // this should not, in the current environment, ever happen, but
1.251 + // since we need to make the address part of the primary key, it's
1.252 + // the right thing to do. sqlite does support null fields in a primary
1.253 + // key for a weird version compatibility reason, but that doesn't
1.254 + // mean we should use it, and we should be *safe*, not relying
1.255 + // on an implementation-specific quirk which might be sanely removed
1.256 + // in a future sqlite version.
1.257 +
1.258 + identity_list* id_list = NULL;
1.259 +
1.260 + sqlite3_stmt* tmp_own_id_retrieve = NULL;
1.261 + sqlite3_prepare_v2(session->db, sql_own_identities_retrieve, -1, &tmp_own_id_retrieve, NULL);
1.262 +
1.263 + // Kludgey - put the stmt in temporarily, and then remove again, so less code dup.
1.264 + // FIXME LATER: refactor if possible, but... chicken and egg, and thiis case rarely happens.
1.265 + session->own_identities_retrieve = tmp_own_id_retrieve;
1.266 + status = own_identities_retrieve(session, &id_list);
1.267 + sqlite3_finalize(tmp_own_id_retrieve);
1.268 + session->own_identities_retrieve = NULL;
1.269 +
1.270 + if (!status || !id_list)
1.271 + return PEP_STATUS_OK; // it's empty AFAIK (FIXME)
1.272 +
1.273 + identity_list* curr_own = id_list;
1.274 +
1.275 + sqlite3_stmt* update_revoked_w_addr_stmt = NULL;
1.276 + const char* sql_query = "update revocation_contact_list set own_address = ?1 where fpr = ?2;";
1.277 + sqlite3_prepare_v2(session->db, sql_query, -1, &update_revoked_w_addr_stmt, NULL);
1.278 +
1.279 + // Ok, go through and find any keys associated with this address
1.280 + for ( ; curr_own && curr_own->ident; curr_own = curr_own->next) {
1.281 + if (EMPTYSTR(curr_own->ident->address)) // shouldn't happen
1.282 + continue;
1.283 + stringlist_t* keylist = NULL;
1.284 + status = find_keys(session, curr_own->ident->address, &keylist);
1.285 + stringlist_t* curr_key = keylist;
1.286 + for ( ; curr_key && curr_key->value; curr_key = curr_key->next) {
1.287 + if (EMPTYSTR(curr_key->value))
1.288 + continue;
1.289 +
1.290 + // We just do this lazily - if this isn't a revoked key, it
1.291 + // won't do anything.
1.292 + sqlite3_bind_text(update_revoked_w_addr_stmt, 1, curr_own->ident->address, -1,
1.293 + SQLITE_STATIC);
1.294 + sqlite3_bind_text(update_revoked_w_addr_stmt, 2, curr_key->value, -1,
1.295 + SQLITE_STATIC);
1.296 +
1.297 + int_result = sqlite3_step(update_revoked_w_addr_stmt);
1.298 + assert(int_result == SQLITE_DONE);
1.299 + sqlite3_reset(update_revoked_w_addr_stmt);
1.300 + }
1.301 + }
1.302 + sqlite3_finalize(update_revoked_w_addr_stmt);
1.303 +
1.304 + int_result = sqlite3_exec(
1.305 + session->db,
1.306 + "delete from revocation_contact_list where own_address is NULL;\n"
1.307 + "PRAGMA foreign_keys=off;\n"
1.308 + "BEGIN TRANSACTION;\n"
1.309 + "create table if not exists _revocation_contact_list_new (\n"
1.310 + " fpr text not null references pgp_keypair (fpr)\n"
1.311 + " on delete cascade,\n"
1.312 + " own_address text,\n"
1.313 + " contact_id text not null references person (id)\n"
1.314 + " on delete cascade on update cascade,\n"
1.315 + " timestamp integer default (datetime('now')),\n"
1.316 + " PRIMARY KEY(fpr, own_address, contact_id)\n"
1.317 + ");\n"
1.318 + "INSERT INTO _revocation_contact_list_new (fpr, "
1.319 + " own_address, "
1.320 + " contact_id) "
1.321 + " SELECT revocation_contact_list.fpr, "
1.322 + " revocation_contact_list.own_address, "
1.323 + " revocation_contact_list.contact_id "
1.324 + " FROM revocation_contact_list "
1.325 + " WHERE 1;\n"
1.326 + "DROP TABLE revocation_contact_list;\n"
1.327 + "ALTER TABLE _revocation_contact_list_new RENAME TO revocation_contact_list;\n"
1.328 + "COMMIT;\n"
1.329 + "\n"
1.330 + "PRAGMA foreign_keys=on;\n"
1.331 + ,
1.332 + NULL,
1.333 + NULL,
1.334 + NULL
1.335 + );
1.336 + assert(int_result == SQLITE_OK);
1.337 +
1.338 + return status;
1.339 +}
1.340
1.341 DYNAMIC_API PEP_STATUS init(
1.342 PEP_SESSION *session,
1.343 @@ -871,7 +998,7 @@
1.344 goto pEp_error;
1.345 }
1.346
1.347 -#if _PEP_SQLITE_DEBUG
1.348 +#ifdef _PEP_SQLITE_DEBUG
1.349 sqlite3_config(SQLITE_CONFIG_LOG, errorLogCallback, NULL);
1.350 #endif
1.351
1.352 @@ -902,7 +1029,7 @@
1.353
1.354 sqlite3_busy_timeout(_session->db, BUSY_WAIT_TIME);
1.355
1.356 -#if _PEP_SQLITE_DEBUG
1.357 +#ifdef _PEP_SQLITE_DEBUG
1.358 sqlite3_trace_v2(_session->db,
1.359 SQLITE_TRACE_STMT | SQLITE_TRACE_ROW | SQLITE_TRACE_CLOSE,
1.360 sql_trace_callback,
1.361 @@ -931,7 +1058,7 @@
1.362 sqlite3_busy_timeout(_session->system_db, 1000);
1.363
1.364 // increment this when patching DDL
1.365 -#define _DDL_USER_VERSION "12"
1.366 +#define _DDL_USER_VERSION "13"
1.367
1.368 if (in_first) {
1.369
1.370 @@ -1049,10 +1176,11 @@
1.371 "create table if not exists revocation_contact_list (\n"
1.372 " fpr text not null references pgp_keypair (fpr)\n"
1.373 " on delete cascade,\n"
1.374 + " own_address text,\n"
1.375 " contact_id text not null references person (id)\n"
1.376 " on delete cascade on update cascade,\n"
1.377 " timestamp integer default (datetime('now')),\n"
1.378 - " PRIMARY KEY(fpr, contact_id)\n"
1.379 + " PRIMARY KEY(fpr, own_address, contact_id)\n"
1.380 ");\n"
1.381 ,
1.382 NULL,
1.383 @@ -1096,11 +1224,18 @@
1.384
1.385 assert(int_result == SQLITE_OK);
1.386
1.387 + if (version > atoi(_DDL_USER_VERSION)) {
1.388 + // This is *explicitly* not allowed.
1.389 + return PEP_INIT_DB_DOWNGRADE_VIOLATION;
1.390 + }
1.391
1.392 // Sometimes the user_version wasn't set correctly.
1.393 if (version == 1) {
1.394 bool version_changed = true;
1.395 - if (table_contains_column(_session, "identity", "pEp_version_major")) {
1.396 + if (table_contains_column(_session, "revocation_contact_list", "own_address")) {
1.397 + version = 13;
1.398 + }
1.399 + else if (table_contains_column(_session, "identity", "pEp_version_major")) {
1.400 version = 12;
1.401 }
1.402 else if (db_contains_table(_session, "social_graph") > 0) {
1.403 @@ -1552,6 +1687,12 @@
1.404 if (status != PEP_STATUS_OK)
1.405 return status;
1.406 }
1.407 + if (version < 13) {
1.408 + status = upgrade_revoc_contact_to_13(_session);
1.409 + assert(status == PEP_STATUS_OK);
1.410 + if (status != PEP_STATUS_OK)
1.411 + return status;
1.412 + }
1.413 }
1.414 else {
1.415 // Version from DB was 0, it means this is initial setup.
1.416 @@ -1641,6 +1782,10 @@
1.417 (int)strlen(sql_replace_main_user_fpr), &_session->replace_main_user_fpr, NULL);
1.418 assert(int_result == SQLITE_OK);
1.419
1.420 + int_result = sqlite3_prepare_v2(_session->db, sql_replace_main_user_fpr_if_equal,
1.421 + (int)strlen(sql_replace_main_user_fpr_if_equal), &_session->replace_main_user_fpr_if_equal, NULL);
1.422 + assert(int_result == SQLITE_OK);
1.423 +
1.424 int_result = sqlite3_prepare_v2(_session->db, sql_get_main_user_fpr,
1.425 (int)strlen(sql_get_main_user_fpr), &_session->get_main_user_fpr, NULL);
1.426 assert(int_result == SQLITE_OK);
1.427 @@ -1654,9 +1799,14 @@
1.428 &_session->replace_identities_fpr, NULL);
1.429 assert(int_result == SQLITE_OK);
1.430
1.431 - int_result = sqlite3_prepare_v2(_session->db, sql_remove_fpr_as_default,
1.432 - (int)strlen(sql_remove_fpr_as_default),
1.433 - &_session->remove_fpr_as_default, NULL);
1.434 + int_result = sqlite3_prepare_v2(_session->db, sql_remove_fpr_as_identity_default,
1.435 + (int)strlen(sql_remove_fpr_as_identity_default),
1.436 + &_session->remove_fpr_as_identity_default, NULL);
1.437 + assert(int_result == SQLITE_OK);
1.438 +
1.439 + int_result = sqlite3_prepare_v2(_session->db, sql_remove_fpr_as_user_default,
1.440 + (int)strlen(sql_remove_fpr_as_user_default),
1.441 + &_session->remove_fpr_as_user_default, NULL);
1.442 assert(int_result == SQLITE_OK);
1.443
1.444 int_result = sqlite3_prepare_v2(_session->db, sql_set_person,
1.445 @@ -1712,6 +1862,12 @@
1.446 assert(int_result == SQLITE_OK);
1.447
1.448 int_result = sqlite3_prepare_v2(_session->db,
1.449 + sql_has_id_contacted_address,
1.450 + (int)strlen(sql_has_id_contacted_address),
1.451 + &_session->has_id_contacted_address, NULL);
1.452 + assert(int_result == SQLITE_OK);
1.453 +
1.454 + int_result = sqlite3_prepare_v2(_session->db,
1.455 sql_get_last_contacted,
1.456 (int)strlen(sql_get_last_contacted),
1.457 &_session->get_last_contacted, NULL);
1.458 @@ -1760,6 +1916,10 @@
1.459 NULL);
1.460 assert(int_result == SQLITE_OK);
1.461
1.462 + int_result = sqlite3_prepare_v2(_session->db, sql_clear_trust_info,
1.463 + (int)strlen(sql_clear_trust_info), &_session->clear_trust_info, NULL);
1.464 + assert(int_result == SQLITE_OK);
1.465 +
1.466 int_result = sqlite3_prepare_v2(_session->db, sql_set_trust,
1.467 (int)strlen(sql_set_trust), &_session->set_trust, NULL);
1.468 assert(int_result == SQLITE_OK);
1.469 @@ -1908,25 +2068,11 @@
1.470 goto pEp_error;
1.471
1.472 // runtime config
1.473 -
1.474 - if (very_first)
1.475 - {
1.476 -#ifdef USE_GPG
1.477 - // On first run, all private keys already present in PGP keyring
1.478 - // are taken as own in order to seamlessly integrate with
1.479 - // pre-existing GPG setup.
1.480 -
1.481 - // Note: earlier fears about danger because of DB reinitialisation should
1.482 - // be a non-issue here, as we ONLY take the ultimately trusted keys now.
1.483 - // Thus, unless the user has assigned ultimate trust through PGP, there is
1.484 - // no chance of automatically imported pEp keys from a previous run making
1.485 - // their way into PEP trusted status without explicit action (Bare imported
1.486 - // private keys have an 'unknown' trust designation in PGP).
1.487 -
1.488 - // We don't really worry about the status here.
1.489 - status = pgp_import_ultimately_trusted_keypairs(_session);
1.490 -#endif // USE_GPG
1.491 - }
1.492 +
1.493 + // clean up invalid keys
1.494 + status = clean_own_key_defaults(_session);
1.495 + if (status != PEP_STATUS_OK)
1.496 + goto pEp_error;
1.497
1.498 *session = _session;
1.499
1.500 @@ -1992,8 +2138,10 @@
1.501 sqlite3_finalize(session->add_userid_alias);
1.502 if (session->replace_identities_fpr)
1.503 sqlite3_finalize(session->replace_identities_fpr);
1.504 - if (session->remove_fpr_as_default)
1.505 - sqlite3_finalize(session->remove_fpr_as_default);
1.506 + if (session->remove_fpr_as_identity_default)
1.507 + sqlite3_finalize(session->remove_fpr_as_identity_default);
1.508 + if (session->remove_fpr_as_user_default)
1.509 + sqlite3_finalize(session->remove_fpr_as_user_default);
1.510 if (session->set_person)
1.511 sqlite3_finalize(session->set_person);
1.512 if (session->delete_person)
1.513 @@ -2015,7 +2163,9 @@
1.514 if (session->get_contacted_ids_from_revoke_fpr)
1.515 sqlite3_finalize(session->get_contacted_ids_from_revoke_fpr);
1.516 if (session->was_id_for_revoke_contacted)
1.517 - sqlite3_finalize(session->was_id_for_revoke_contacted);
1.518 + sqlite3_finalize(session->was_id_for_revoke_contacted);
1.519 + if (session->has_id_contacted_address)
1.520 + sqlite3_finalize(session->has_id_contacted_address);
1.521 if (session->get_last_contacted)
1.522 sqlite3_finalize(session->get_last_contacted);
1.523 if (session->set_pgp_keypair)
1.524 @@ -2034,6 +2184,8 @@
1.525 sqlite3_finalize(session->set_pEp_version);
1.526 if (session->exists_trust_entry)
1.527 sqlite3_finalize(session->exists_trust_entry);
1.528 + if (session->clear_trust_info)
1.529 + sqlite3_finalize(session->clear_trust_info);
1.530 if (session->set_trust)
1.531 sqlite3_finalize(session->set_trust);
1.532 if (session->update_trust)
1.533 @@ -2062,6 +2214,8 @@
1.534 sqlite3_finalize(session->delete_key);
1.535 if (session->replace_main_user_fpr)
1.536 sqlite3_finalize(session->replace_main_user_fpr);
1.537 + if (session->replace_main_user_fpr_if_equal)
1.538 + sqlite3_finalize(session->replace_main_user_fpr_if_equal);
1.539 if (session->get_main_user_fpr)
1.540 sqlite3_finalize(session->get_main_user_fpr);
1.541 if (session->refresh_userid_default_key)
1.542 @@ -2102,13 +2256,15 @@
1.543 sqlite3_finalize(session->is_mistrusted_key);
1.544
1.545 if (session->db) {
1.546 - sqlite3_exec(
1.547 - session->db,
1.548 - "PRAGMA optimize;\n",
1.549 - NULL,
1.550 - NULL,
1.551 - NULL
1.552 - );
1.553 + if (out_last) {
1.554 + sqlite3_exec(
1.555 + session->db,
1.556 + "PRAGMA optimize;\n",
1.557 + NULL,
1.558 + NULL,
1.559 + NULL
1.560 + );
1.561 + }
1.562 sqlite3_close_v2(session->db);
1.563 }
1.564 if (session->system_db)
1.565 @@ -2139,6 +2295,41 @@
1.566 session->unencrypted_subject = enable;
1.567 }
1.568
1.569 +DYNAMIC_API PEP_STATUS config_passphrase(PEP_SESSION session, const char *passphrase) {
1.570 + if (!session)
1.571 + return PEP_ILLEGAL_VALUE;
1.572 +
1.573 + PEP_STATUS status = PEP_STATUS_OK;
1.574 + free(session->curr_passphrase);
1.575 + if (!passphrase)
1.576 + session->curr_passphrase = NULL;
1.577 + else {
1.578 + session->curr_passphrase = strdup(passphrase);
1.579 + if (!session->curr_passphrase)
1.580 + status = PEP_OUT_OF_MEMORY;
1.581 + }
1.582 + return status;
1.583 +}
1.584 +
1.585 +DYNAMIC_API PEP_STATUS config_passphrase_for_new_keys(PEP_SESSION session, bool enable, const char *passphrase) {
1.586 + if (enable && EMPTYSTR(passphrase))
1.587 + return PEP_PASSPHRASE_FOR_NEW_KEYS_REQUIRED;
1.588 +
1.589 + session->new_key_pass_enable = enable;
1.590 + PEP_STATUS status = PEP_STATUS_OK;
1.591 +
1.592 + free(session->generation_passphrase);
1.593 + if (!passphrase)
1.594 + session->generation_passphrase = NULL;
1.595 + else {
1.596 + session->generation_passphrase = strdup(passphrase);
1.597 + if (!session->generation_passphrase)
1.598 + status = PEP_OUT_OF_MEMORY;
1.599 + }
1.600 + return status;
1.601 +}
1.602 +
1.603 +
1.604 DYNAMIC_API void config_service_log(PEP_SESSION session, bool enable)
1.605 {
1.606 assert(session);
1.607 @@ -2159,10 +2350,21 @@
1.608 log_output_debug(title, entity, description, comment);
1.609 #endif
1.610
1.611 +#if defined(ANDROID) && !defined(NDEBUG)
1.612 + __android_log_print(ANDROID_LOG_DEBUG, "pEpEngine", " %s :: %s :: %s :: %s ",
1.613 + title, entity, description, comment);
1.614 +#endif
1.615 +
1.616 // N.B. If testing (so NDEBUG not defined) but this message is spam,
1.617 // put -D_PEP_SERVICE_LOG_OFF into CFLAGS/CXXFLAGS
1.618 #if !defined(NDEBUG) && !defined(_PEP_SERVICE_LOG_OFF)
1.619 +#ifndef NDEBUG
1.620 + printf("\x1b[%dm", session->debug_color);
1.621 +#endif
1.622 fprintf(stdout, "\n*** %s %s %s %s\n", title, entity, description, comment);
1.623 +#ifndef NDEBUG
1.624 + printf("\x1b[0m");
1.625 +#endif
1.626 session->service_log = true;
1.627
1.628 int result;
1.629 @@ -2185,7 +2387,7 @@
1.630 sqlite3_bind_text(session->log, 4, comment, -1, SQLITE_STATIC);
1.631 else
1.632 sqlite3_bind_null(session->log, 4);
1.633 - result = Sqlite3_step(session->log);
1.634 + result = sqlite3_step(session->log);
1.635 sqlite3_reset(session->log);
1.636
1.637 #endif
1.638 @@ -2240,7 +2442,7 @@
1.639 sqlite3_bind_text(session->trustword, 1, lang, -1, SQLITE_STATIC);
1.640 sqlite3_bind_int(session->trustword, 2, value);
1.641
1.642 - const int result = Sqlite3_step(session->trustword);
1.643 + const int result = sqlite3_step(session->trustword);
1.644 if (result == SQLITE_ROW) {
1.645 *word = strdup((const char *) sqlite3_column_text(session->trustword,
1.646 1));
1.647 @@ -2330,13 +2532,13 @@
1.648 break; // buffer full
1.649 }
1.650
1.651 + ++n_words;
1.652 + if (max_words && n_words >= max_words)
1.653 + break;
1.654 +
1.655 if (source < fingerprint + fsize
1.656 && dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1)
1.657 *dest++ = ' ';
1.658 -
1.659 - ++n_words;
1.660 - if (max_words && n_words >= max_words)
1.661 - break;
1.662 }
1.663
1.664 *words = buffer;
1.665 @@ -2437,7 +2639,7 @@
1.666
1.667 sqlite3_reset(session->get_default_own_userid);
1.668
1.669 - const int result = Sqlite3_step(session->get_default_own_userid);
1.670 + const int result = sqlite3_step(session->get_default_own_userid);
1.671 const char* id;
1.672
1.673 switch (result) {
1.674 @@ -2486,7 +2688,7 @@
1.675
1.676 const char* tempid;
1.677
1.678 - const int result = Sqlite3_step(session->get_userid_alias_default);
1.679 + const int result = sqlite3_step(session->get_userid_alias_default);
1.680 switch (result) {
1.681 case SQLITE_ROW:
1.682 tempid = (const char *) sqlite3_column_text(session->get_userid_alias_default, 0);
1.683 @@ -2531,7 +2733,7 @@
1.684 sqlite3_bind_text(session->add_userid_alias, 2, alias_id, -1,
1.685 SQLITE_STATIC);
1.686
1.687 - result = Sqlite3_step(session->add_userid_alias);
1.688 + result = sqlite3_step(session->add_userid_alias);
1.689
1.690 sqlite3_reset(session->add_userid_alias);
1.691 if (result != SQLITE_DONE) {
1.692 @@ -2568,7 +2770,7 @@
1.693 sqlite3_bind_text(session->get_identity, 1, address, -1, SQLITE_STATIC);
1.694 sqlite3_bind_text(session->get_identity, 2, user_id, -1, SQLITE_STATIC);
1.695
1.696 - const int result = Sqlite3_step(session->get_identity);
1.697 + const int result = sqlite3_step(session->get_identity);
1.698 switch (result) {
1.699 case SQLITE_ROW:
1.700 _identity = new_identity(
1.701 @@ -2635,8 +2837,8 @@
1.702 sqlite3_bind_text(session->get_identities_by_userid, 1, user_id, -1, SQLITE_STATIC);
1.703
1.704 int result = -1;
1.705 - while ((result = Sqlite3_step(session->get_identities_by_userid)) == SQLITE_ROW) {
1.706 - // "select address, fpr, username, comm_type, lang,"
1.707 + while ((result = sqlite3_step(session->get_identities_by_userid)) == SQLITE_ROW) {
1.708 + // "select address, identity.main_key_id, username, comm_type, lang,"
1.709 // " identity.flags | pgp_keypair.flags,"
1.710 // " is_own"
1.711 // " from identity"
1.712 @@ -2717,7 +2919,7 @@
1.713
1.714 int result = -1;
1.715
1.716 - while ((result = Sqlite3_step(session->get_identities_by_main_key_id)) == SQLITE_ROW) {
1.717 + while ((result = sqlite3_step(session->get_identities_by_main_key_id)) == SQLITE_ROW) {
1.718 ident = new_identity(
1.719 (const char *) sqlite3_column_text(session->get_identities_by_main_key_id, 0),
1.720 fpr,
1.721 @@ -2791,7 +2993,7 @@
1.722 sqlite3_bind_text(session->get_identity_without_trust_check, 1, address, -1, SQLITE_STATIC);
1.723 sqlite3_bind_text(session->get_identity_without_trust_check, 2, user_id, -1, SQLITE_STATIC);
1.724
1.725 - const int result = Sqlite3_step(session->get_identity_without_trust_check);
1.726 + const int result = sqlite3_step(session->get_identity_without_trust_check);
1.727 switch (result) {
1.728 case SQLITE_ROW:
1.729 _identity = new_identity(
1.730 @@ -2859,7 +3061,7 @@
1.731 sqlite3_bind_text(session->get_identities_by_address, 1, address, -1, SQLITE_STATIC);
1.732 int result;
1.733
1.734 - while ((result = Sqlite3_step(session->get_identities_by_address)) == SQLITE_ROW) {
1.735 + while ((result = sqlite3_step(session->get_identities_by_address)) == SQLITE_ROW) {
1.736 //"select user_id, main_key_id, username, comm_type, lang,"
1.737 //" identity.flags, is_own"
1.738 pEp_identity *ident = new_identity(
1.739 @@ -2930,7 +3132,7 @@
1.740 sqlite3_bind_text(session->exists_identity_entry, 2, identity->user_id, -1,
1.741 SQLITE_STATIC);
1.742
1.743 - int result = Sqlite3_step(session->exists_identity_entry);
1.744 + int result = sqlite3_step(session->exists_identity_entry);
1.745
1.746 switch (result) {
1.747 case SQLITE_ROW: {
1.748 @@ -2965,7 +3167,7 @@
1.749 sqlite3_bind_text(session->exists_trust_entry, 2, identity->fpr, -1,
1.750 SQLITE_STATIC);
1.751
1.752 - int result = Sqlite3_step(session->exists_trust_entry);
1.753 + int result = sqlite3_step(session->exists_trust_entry);
1.754 switch (result) {
1.755 case SQLITE_ROW: {
1.756 // yeah yeah, I know, we could be lazy here, but it looks bad.
1.757 @@ -2989,7 +3191,7 @@
1.758 sqlite3_reset(session->set_pgp_keypair);
1.759 sqlite3_bind_text(session->set_pgp_keypair, 1, fpr, -1,
1.760 SQLITE_STATIC);
1.761 - result = Sqlite3_step(session->set_pgp_keypair);
1.762 + result = sqlite3_step(session->set_pgp_keypair);
1.763 sqlite3_reset(session->set_pgp_keypair);
1.764 if (result != SQLITE_DONE) {
1.765 return PEP_CANNOT_SET_PGP_KEYPAIR;
1.766 @@ -2998,6 +3200,28 @@
1.767 return PEP_STATUS_OK;
1.768 }
1.769
1.770 +PEP_STATUS clear_trust_info(PEP_SESSION session,
1.771 + const char* user_id,
1.772 + const char* fpr) {
1.773 + if (!session || EMPTYSTR(fpr) || EMPTYSTR(user_id))
1.774 + return PEP_ILLEGAL_VALUE;
1.775 +
1.776 + int result;
1.777 +
1.778 + sqlite3_reset(session->clear_trust_info);
1.779 + sqlite3_bind_text(session->clear_trust_info, 1, user_id, -1,
1.780 + SQLITE_STATIC);
1.781 + sqlite3_bind_text(session->clear_trust_info, 2, fpr, -1,
1.782 + SQLITE_STATIC);
1.783 + result = sqlite3_step(session->clear_trust_info);
1.784 + sqlite3_reset(session->clear_trust_info);
1.785 + if (result != SQLITE_DONE) {
1.786 + return PEP_UNKNOWN_ERROR;
1.787 + }
1.788 +
1.789 + return PEP_STATUS_OK;
1.790 +}
1.791 +
1.792 static PEP_STATUS _set_or_update_trust(PEP_SESSION session,
1.793 pEp_identity* identity,
1.794 sqlite3_stmt* set_or_update) {
1.795 @@ -3022,7 +3246,7 @@
1.796 sqlite3_bind_text(set_or_update, 2, identity->fpr, -1,
1.797 SQLITE_STATIC);
1.798 sqlite3_bind_int(set_or_update, 3, identity->comm_type);
1.799 - result = Sqlite3_step(set_or_update);
1.800 + result = sqlite3_step(set_or_update);
1.801 assert(result == SQLITE_DONE);
1.802 sqlite3_reset(set_or_update);
1.803 if (result != SQLITE_DONE)
1.804 @@ -3053,7 +3277,7 @@
1.805 sqlite3_bind_int(set_or_update, 6, identity->major_ver);
1.806 sqlite3_bind_int(set_or_update, 7, identity->minor_ver);
1.807
1.808 - int result = Sqlite3_step(set_or_update);
1.809 + int result = sqlite3_step(set_or_update);
1.810 sqlite3_reset(set_or_update);
1.811 if (result != SQLITE_DONE)
1.812 return PEP_CANNOT_SET_IDENTITY;
1.813 @@ -3083,7 +3307,7 @@
1.814 sqlite3_bind_null(set_or_update, 3);
1.815 sqlite3_bind_text(set_or_update, 4, identity->fpr, -1,
1.816 SQLITE_STATIC);
1.817 - int result = Sqlite3_step(set_or_update);
1.818 + int result = sqlite3_step(set_or_update);
1.819 sqlite3_reset(set_or_update);
1.820
1.821 if (result != SQLITE_DONE)
1.822 @@ -3199,7 +3423,7 @@
1.823 sqlite3_reset(session->set_pgp_keypair);
1.824 sqlite3_bind_text(session->set_pgp_keypair, 1, identity->fpr, -1,
1.825 SQLITE_STATIC);
1.826 - result = Sqlite3_step(session->set_pgp_keypair);
1.827 + result = sqlite3_step(session->set_pgp_keypair);
1.828 sqlite3_reset(session->set_pgp_keypair);
1.829 if (result != SQLITE_DONE) {
1.830 sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
1.831 @@ -3258,7 +3482,7 @@
1.832 sqlite3_reset(session->update_trust_to_pEp);
1.833 sqlite3_bind_text(session->update_trust_to_pEp, 1, user->user_id, -1,
1.834 SQLITE_STATIC);
1.835 - int result = Sqlite3_step(session->update_trust_to_pEp);
1.836 + int result = sqlite3_step(session->update_trust_to_pEp);
1.837 sqlite3_reset(session->update_trust_to_pEp);
1.838 if (result != SQLITE_DONE)
1.839 return PEP_CANNOT_SET_TRUST;
1.840 @@ -3295,7 +3519,7 @@
1.841 sqlite3_reset(session->set_as_pEp_user);
1.842 sqlite3_bind_text(session->set_as_pEp_user, 1, user->user_id, -1,
1.843 SQLITE_STATIC);
1.844 - int result = Sqlite3_step(session->set_as_pEp_user);
1.845 + int result = sqlite3_step(session->set_as_pEp_user);
1.846 sqlite3_reset(session->set_as_pEp_user);
1.847
1.848 if (result != SQLITE_DONE)
1.849 @@ -3320,7 +3544,7 @@
1.850 sqlite3_bind_text(session->set_pEp_version, 4, ident->user_id, -1,
1.851 SQLITE_STATIC);
1.852
1.853 - int result = Sqlite3_step(session->set_pEp_version);
1.854 + int result = sqlite3_step(session->set_pEp_version);
1.855 sqlite3_reset(session->set_pEp_version);
1.856
1.857 if (result != SQLITE_DONE)
1.858 @@ -3345,7 +3569,7 @@
1.859 sqlite3_bind_text(session->upgrade_pEp_version_by_user_id, 3, ident->user_id, -1,
1.860 SQLITE_STATIC);
1.861
1.862 - int result = Sqlite3_step(session->upgrade_pEp_version_by_user_id);
1.863 + int result = sqlite3_step(session->upgrade_pEp_version_by_user_id);
1.864 sqlite3_reset(session->upgrade_pEp_version_by_user_id);
1.865
1.866 if (result != SQLITE_DONE)
1.867 @@ -3378,7 +3602,7 @@
1.868 sqlite3_reset(session->exists_person);
1.869 sqlite3_bind_text(session->exists_person, 1, user_id, -1,
1.870 SQLITE_STATIC);
1.871 - int result = Sqlite3_step(session->exists_person);
1.872 + int result = sqlite3_step(session->exists_person);
1.873 switch (result) {
1.874 case SQLITE_ROW: {
1.875 // yeah yeah, I know, we could be lazy here, but it looks bad.
1.876 @@ -3416,7 +3640,7 @@
1.877 sqlite3_bind_text(session->delete_person, 1, user_id, -1,
1.878 SQLITE_STATIC);
1.879
1.880 - int result = Sqlite3_step(session->delete_person);
1.881 + int result = sqlite3_step(session->delete_person);
1.882
1.883 if (result != SQLITE_DONE)
1.884 status = PEP_UNKNOWN_ERROR;
1.885 @@ -3451,7 +3675,7 @@
1.886 sqlite3_reset(session->is_pEp_user);
1.887 sqlite3_bind_text(session->is_pEp_user, 1, user_id, -1,
1.888 SQLITE_STATIC);
1.889 - int result = Sqlite3_step(session->is_pEp_user);
1.890 + int result = sqlite3_step(session->is_pEp_user);
1.891 switch (result) {
1.892 case SQLITE_ROW: {
1.893 // yeah yeah, I know, we could be lazy here, but it looks bad.
1.894 @@ -3487,7 +3711,7 @@
1.895 sqlite3_reset(session->is_own_address);
1.896 sqlite3_bind_text(session->is_own_address, 1, address, -1,
1.897 SQLITE_STATIC);
1.898 - int result = Sqlite3_step(session->is_own_address);
1.899 + int result = sqlite3_step(session->is_own_address);
1.900 switch (result) {
1.901 case SQLITE_ROW: {
1.902 // yeah yeah, I know, we could be lazy here, but it looks bad.
1.903 @@ -3519,7 +3743,7 @@
1.904 sqlite3_bind_text(session->add_into_social_graph, 3, contact_ident->user_id, -1,
1.905 SQLITE_STATIC);
1.906
1.907 - int result = Sqlite3_step(session->add_into_social_graph);
1.908 + int result = sqlite3_step(session->add_into_social_graph);
1.909 sqlite3_reset(session->add_into_social_graph);
1.910
1.911 if (result != SQLITE_DONE)
1.912 @@ -3528,6 +3752,46 @@
1.913 return PEP_STATUS_OK;
1.914 }
1.915
1.916 +// FIXME: should be more like is there a communications relationship,
1.917 +// since this could be either way
1.918 +PEP_STATUS has_partner_contacted_address(PEP_SESSION session, const char* partner_id,
1.919 + const char* own_address, bool* was_contacted) {
1.920 +
1.921 + assert(session);
1.922 + assert(!EMPTYSTR(partner_id));
1.923 + assert(!EMPTYSTR(own_address));
1.924 + assert(was_contacted);
1.925 +
1.926 + if (!session || !was_contacted || EMPTYSTR(partner_id) || EMPTYSTR(own_address))
1.927 + return PEP_ILLEGAL_VALUE;
1.928 +
1.929 + *was_contacted = false;
1.930 +
1.931 + PEP_STATUS status = PEP_STATUS_OK;
1.932 +
1.933 + sqlite3_reset(session->has_id_contacted_address);
1.934 + sqlite3_bind_text(session->has_id_contacted_address, 1, own_address, -1,
1.935 + SQLITE_STATIC);
1.936 + sqlite3_bind_text(session->has_id_contacted_address, 2, partner_id, -1,
1.937 + SQLITE_STATIC);
1.938 +
1.939 + int result = sqlite3_step(session->has_id_contacted_address);
1.940 + switch (result) {
1.941 + case SQLITE_ROW: {
1.942 + // yeah yeah, I know, we could be lazy here, but it looks bad.
1.943 + *was_contacted = (sqlite3_column_int(session->has_id_contacted_address, 0) != 0);
1.944 + status = PEP_STATUS_OK;
1.945 + break;
1.946 + }
1.947 + default:
1.948 + status = PEP_UNKNOWN_DB_ERROR;
1.949 + }
1.950 + sqlite3_reset(session->has_id_contacted_address);
1.951 +
1.952 + return status;
1.953 +}
1.954 +
1.955 +// FIXME: problematic - can be multiple and this now matters
1.956 PEP_STATUS get_own_ident_for_contact_id(PEP_SESSION session,
1.957 const pEp_identity* contact,
1.958 pEp_identity** own_ident) {
1.959 @@ -3548,7 +3812,7 @@
1.960 sqlite3_bind_text(session->get_own_address_binding_from_contact, 2, contact->user_id, -1,
1.961 SQLITE_STATIC);
1.962
1.963 - int result = Sqlite3_step(session->get_own_address_binding_from_contact);
1.964 + int result = sqlite3_step(session->get_own_address_binding_from_contact);
1.965
1.966 const char* own_address = NULL;
1.967
1.968 @@ -3580,16 +3844,26 @@
1.969 if (!session || !fpr)
1.970 return PEP_ILLEGAL_VALUE;
1.971
1.972 - sqlite3_reset(session->remove_fpr_as_default);
1.973 - sqlite3_bind_text(session->remove_fpr_as_default, 1, fpr, -1,
1.974 + sqlite3_reset(session->remove_fpr_as_identity_default);
1.975 + sqlite3_bind_text(session->remove_fpr_as_identity_default, 1, fpr, -1,
1.976 SQLITE_STATIC);
1.977
1.978 - int result = Sqlite3_step(session->remove_fpr_as_default);
1.979 - sqlite3_reset(session->remove_fpr_as_default);
1.980 + int result = sqlite3_step(session->remove_fpr_as_identity_default);
1.981 + sqlite3_reset(session->remove_fpr_as_identity_default);
1.982
1.983 if (result != SQLITE_DONE)
1.984 - return PEP_CANNOT_SET_IDENTITY; // misleading - could also be person
1.985 -
1.986 + return PEP_CANNOT_SET_IDENTITY;
1.987 +
1.988 + sqlite3_reset(session->remove_fpr_as_user_default);
1.989 + sqlite3_bind_text(session->remove_fpr_as_user_default, 1, fpr, -1,
1.990 + SQLITE_STATIC);
1.991 +
1.992 + result = sqlite3_step(session->remove_fpr_as_user_default);
1.993 + sqlite3_reset(session->remove_fpr_as_user_default);
1.994 +
1.995 + if (result != SQLITE_DONE)
1.996 + return PEP_CANNOT_SET_PERSON;
1.997 +
1.998 return PEP_STATUS_OK;
1.999 }
1.1000
1.1001 @@ -3610,7 +3884,7 @@
1.1002 sqlite3_bind_text(session->replace_identities_fpr, 2, old_fpr, -1,
1.1003 SQLITE_STATIC);
1.1004
1.1005 - int result = Sqlite3_step(session->replace_identities_fpr);
1.1006 + int result = sqlite3_step(session->replace_identities_fpr);
1.1007 sqlite3_reset(session->replace_identities_fpr);
1.1008
1.1009 if (result != SQLITE_DONE)
1.1010 @@ -3630,7 +3904,7 @@
1.1011 sqlite3_bind_int(session->update_trust_for_fpr, 1, comm_type);
1.1012 sqlite3_bind_text(session->update_trust_for_fpr, 2, fpr, -1,
1.1013 SQLITE_STATIC);
1.1014 - int result = Sqlite3_step(session->update_trust_for_fpr);
1.1015 + int result = sqlite3_step(session->update_trust_for_fpr);
1.1016 sqlite3_reset(session->update_trust_for_fpr);
1.1017 if (result != SQLITE_DONE) {
1.1018 return PEP_CANNOT_SET_TRUST;
1.1019 @@ -3662,7 +3936,7 @@
1.1020 sqlite3_bind_text(session->set_identity_flags, 3, identity->user_id, -1,
1.1021 SQLITE_STATIC);
1.1022
1.1023 - result = Sqlite3_step(session->set_identity_flags);
1.1024 + result = sqlite3_step(session->set_identity_flags);
1.1025
1.1026 sqlite3_reset(session->set_identity_flags);
1.1027 if (result != SQLITE_DONE)
1.1028 @@ -3694,7 +3968,7 @@
1.1029 SQLITE_STATIC);
1.1030 sqlite3_bind_text(session->unset_identity_flags, 3, identity->user_id, -1,
1.1031 SQLITE_STATIC);
1.1032 - result = Sqlite3_step(session->unset_identity_flags);
1.1033 + result = sqlite3_step(session->unset_identity_flags);
1.1034 sqlite3_reset(session->unset_identity_flags);
1.1035 if (result != SQLITE_DONE)
1.1036 return PEP_CANNOT_SET_IDENTITY;
1.1037 @@ -3718,7 +3992,7 @@
1.1038 sqlite3_reset(session->get_trust_by_userid);
1.1039 sqlite3_bind_text(session->get_trust_by_userid, 1, user_id, -1, SQLITE_STATIC);
1.1040
1.1041 - while ((result = Sqlite3_step(session->get_trust_by_userid)) == SQLITE_ROW) {
1.1042 + while ((result = sqlite3_step(session->get_trust_by_userid)) == SQLITE_ROW) {
1.1043 if (!t_list)
1.1044 t_list = new_labeled_int_list(sqlite3_column_int(session->get_trust_by_userid, 1),
1.1045 (const char *) sqlite3_column_text(session->get_trust_by_userid, 0));
1.1046 @@ -4049,7 +4323,7 @@
1.1047 SQLITE_STATIC);
1.1048 sqlite3_bind_text(session->replace_userid, 2, old_uid, -1,
1.1049 SQLITE_STATIC);
1.1050 - result = Sqlite3_step(session->replace_userid);
1.1051 + result = sqlite3_step(session->replace_userid);
1.1052 #ifndef NDEBUG
1.1053 if (result) {
1.1054 const char *errmsg = sqlite3_errmsg(session->db);
1.1055 @@ -4075,7 +4349,7 @@
1.1056 sqlite3_reset(session->delete_key);
1.1057 sqlite3_bind_text(session->delete_key, 1, fpr, -1,
1.1058 SQLITE_STATIC);
1.1059 - result = Sqlite3_step(session->delete_key);
1.1060 + result = sqlite3_step(session->delete_key);
1.1061 sqlite3_reset(session->delete_key);
1.1062 if (result != SQLITE_DONE)
1.1063 return PEP_CANNOT_SET_PGP_KEYPAIR;
1.1064 @@ -4096,7 +4370,7 @@
1.1065 sqlite3_reset(session->refresh_userid_default_key);
1.1066 sqlite3_bind_text(session->refresh_userid_default_key, 1, user_id, -1,
1.1067 SQLITE_STATIC);
1.1068 - result = Sqlite3_step(session->refresh_userid_default_key);
1.1069 + result = sqlite3_step(session->refresh_userid_default_key);
1.1070 sqlite3_reset(session->refresh_userid_default_key);
1.1071 if (result != SQLITE_DONE)
1.1072 return PEP_CANNOT_SET_PERSON;
1.1073 @@ -4120,7 +4394,7 @@
1.1074 SQLITE_STATIC);
1.1075 sqlite3_bind_text(session->replace_main_user_fpr, 2, user_id, -1,
1.1076 SQLITE_STATIC);
1.1077 - result = Sqlite3_step(session->replace_main_user_fpr);
1.1078 + result = sqlite3_step(session->replace_main_user_fpr);
1.1079 sqlite3_reset(session->replace_main_user_fpr);
1.1080 if (result != SQLITE_DONE)
1.1081 return PEP_CANNOT_SET_PERSON;
1.1082 @@ -4128,6 +4402,35 @@
1.1083 return PEP_STATUS_OK;
1.1084 }
1.1085
1.1086 +PEP_STATUS replace_main_user_fpr_if_equal(PEP_SESSION session, const char* user_id,
1.1087 + const char* new_fpr, const char* compare_fpr) {
1.1088 + assert(session);
1.1089 + assert(user_id);
1.1090 + assert(new_fpr);
1.1091 +
1.1092 + if (!session || !user_id || !compare_fpr)
1.1093 + return PEP_ILLEGAL_VALUE;
1.1094 +
1.1095 + // N.B. new_fpr can be NULL - if there's no key to replace it, this is fine.
1.1096 + // See sqlite3 documentation on sqlite3_bind_text() and sqlite3_bind_null()
1.1097 +
1.1098 + int result;
1.1099 +
1.1100 + sqlite3_reset(session->replace_main_user_fpr_if_equal);
1.1101 + sqlite3_bind_text(session->replace_main_user_fpr, 1, new_fpr, -1,
1.1102 + SQLITE_STATIC);
1.1103 + sqlite3_bind_text(session->replace_main_user_fpr_if_equal, 2, user_id, -1,
1.1104 + SQLITE_STATIC);
1.1105 + sqlite3_bind_text(session->replace_main_user_fpr_if_equal, 3, compare_fpr, -1,
1.1106 + SQLITE_STATIC);
1.1107 + result = sqlite3_step(session->replace_main_user_fpr_if_equal);
1.1108 + sqlite3_reset(session->replace_main_user_fpr_if_equal);
1.1109 + if (result != SQLITE_DONE)
1.1110 + return PEP_CANNOT_SET_PERSON;
1.1111 +
1.1112 + return PEP_STATUS_OK;
1.1113 +}
1.1114 +
1.1115 PEP_STATUS get_main_user_fpr(PEP_SESSION session,
1.1116 const char* user_id,
1.1117 char** main_fpr)
1.1118 @@ -4147,7 +4450,7 @@
1.1119 sqlite3_reset(session->get_main_user_fpr);
1.1120 sqlite3_bind_text(session->get_main_user_fpr, 1, user_id, -1,
1.1121 SQLITE_STATIC);
1.1122 - result = Sqlite3_step(session->get_main_user_fpr);
1.1123 + result = sqlite3_step(session->get_main_user_fpr);
1.1124 switch (result) {
1.1125 case SQLITE_ROW: {
1.1126 const char* _fpr =
1.1127 @@ -4195,7 +4498,7 @@
1.1128 sqlite3_reset(session->mark_compromised);
1.1129 sqlite3_bind_text(session->mark_compromised, 1, fpr, -1,
1.1130 SQLITE_STATIC);
1.1131 - result = Sqlite3_step(session->mark_compromised);
1.1132 + result = sqlite3_step(session->mark_compromised);
1.1133 sqlite3_reset(session->mark_compromised);
1.1134
1.1135 if (result != SQLITE_DONE)
1.1136 @@ -4204,11 +4507,15 @@
1.1137 return PEP_STATUS_OK;
1.1138 }
1.1139
1.1140 -void pEp_free(void *p)
1.1141 +DYNAMIC_API void pEp_free(void *p)
1.1142 {
1.1143 free(p);
1.1144 }
1.1145
1.1146 +DYNAMIC_API void *pEp_realloc(void *p, size_t size)
1.1147 +{
1.1148 + return realloc(p, size);
1.1149 +}
1.1150
1.1151 DYNAMIC_API PEP_STATUS get_trust(PEP_SESSION session, pEp_identity *identity)
1.1152 {
1.1153 @@ -4235,7 +4542,7 @@
1.1154 SQLITE_STATIC);
1.1155 sqlite3_bind_text(session->get_trust, 2, identity->fpr, -1, SQLITE_STATIC);
1.1156
1.1157 - result = Sqlite3_step(session->get_trust);
1.1158 + result = sqlite3_step(session->get_trust);
1.1159 switch (result) {
1.1160 case SQLITE_ROW: {
1.1161 int comm_type = (PEP_comm_type) sqlite3_column_int(session->get_trust,
1.1162 @@ -4274,7 +4581,7 @@
1.1163 sqlite3_reset(session->least_trust);
1.1164 sqlite3_bind_text(session->least_trust, 1, fpr, -1, SQLITE_STATIC);
1.1165
1.1166 - result = Sqlite3_step(session->least_trust);
1.1167 + result = sqlite3_step(session->least_trust);
1.1168 switch (result) {
1.1169 case SQLITE_ROW: {
1.1170 int _comm_type = sqlite3_column_int(session->least_trust, 0);
1.1171 @@ -4290,6 +4597,26 @@
1.1172 return status;
1.1173 }
1.1174
1.1175 +static void sanitize_pgp_filename(char *filename)
1.1176 +{
1.1177 + for (int i=0; filename[i]; ++i) {
1.1178 + switch(filename[i]) {
1.1179 + // path separators
1.1180 + case '/':
1.1181 + case ':':
1.1182 + case '\\':
1.1183 + // expansion operators
1.1184 + case '%':
1.1185 + case '$':
1.1186 + // code execution operators
1.1187 + case '`':
1.1188 + case '|':
1.1189 + filename[i] = '-';
1.1190 + break;
1.1191 + }
1.1192 + }
1.1193 +}
1.1194 +
1.1195 DYNAMIC_API PEP_STATUS decrypt_and_verify(
1.1196 PEP_SESSION session, const char *ctext, size_t csize,
1.1197 const char *dsigtext, size_t dsigsize,
1.1198 @@ -4314,6 +4641,9 @@
1.1199 if (status == PEP_DECRYPT_NO_KEY)
1.1200 signal_Sync_event(session, Sync_PR_keysync, CannotDecrypt, NULL);
1.1201
1.1202 + if (filename_ptr && *filename_ptr)
1.1203 + sanitize_pgp_filename(*filename_ptr);
1.1204 +
1.1205 return status;
1.1206 }
1.1207
1.1208 @@ -4473,36 +4803,49 @@
1.1209 PEP_SESSION session, pEp_identity *identity
1.1210 )
1.1211 {
1.1212 + return _generate_keypair(session, identity, false);
1.1213 +}
1.1214 +
1.1215 +PEP_STATUS _generate_keypair(PEP_SESSION session,
1.1216 + pEp_identity *identity,
1.1217 + bool suppress_event
1.1218 + )
1.1219 +{
1.1220 assert(session);
1.1221 assert(identity);
1.1222 assert(identity->address);
1.1223 assert(identity->fpr == NULL || identity->fpr[0] == 0);
1.1224 - assert(identity->username);
1.1225 +// assert(identity->username);
1.1226 + // N.B. We now allow empty usernames, so the underlying layer for
1.1227 + // non-sequoia crypto implementations will have to deal with this.
1.1228
1.1229 if (!(session && identity && identity->address &&
1.1230 - (identity->fpr == NULL || identity->fpr[0] == 0) &&
1.1231 - identity->username))
1.1232 + (identity->fpr == NULL || identity->fpr[0] == 0)))
1.1233 return PEP_ILLEGAL_VALUE;
1.1234
1.1235 char* saved_username = NULL;
1.1236 - char* at = NULL;
1.1237 - size_t uname_len = strlen(identity->username);
1.1238 -
1.1239 - if (uname_len > 0)
1.1240 - at = strstr(identity->username, "@");
1.1241 -
1.1242 - if (at) {
1.1243 - saved_username = identity->username;
1.1244 - identity->username = calloc(uname_len + 3, 1);
1.1245 - if (!identity->username) {
1.1246 - identity->username = saved_username;
1.1247 - return PEP_OUT_OF_MEMORY;
1.1248 +
1.1249 + // KB: In light of the above, remove? FIXME.
1.1250 + if (identity->username) {
1.1251 + char* at = NULL;
1.1252 + size_t uname_len = strlen(identity->username);
1.1253 +
1.1254 + if (uname_len > 0)
1.1255 + at = strstr(identity->username, "@");
1.1256 +
1.1257 + if (at) {
1.1258 + saved_username = identity->username;
1.1259 + identity->username = calloc(uname_len + 3, 1);
1.1260 + if (!identity->username) {
1.1261 + identity->username = saved_username;
1.1262 + return PEP_OUT_OF_MEMORY;
1.1263 + }
1.1264 + identity->username[0] = '"';
1.1265 + strlcpy((identity->username) + 1, saved_username, uname_len + 1);
1.1266 + identity->username[uname_len + 1] = '"';
1.1267 }
1.1268 - identity->username[0] = '"';
1.1269 - strlcpy((identity->username) + 1, saved_username, uname_len + 1);
1.1270 - identity->username[uname_len + 1] = '"';
1.1271 }
1.1272 -
1.1273 +
1.1274 PEP_STATUS status =
1.1275 session->cryptotech[PEP_crypt_OpenPGP].generate_keypair(session,
1.1276 identity);
1.1277 @@ -4517,12 +4860,14 @@
1.1278 if (identity->fpr)
1.1279 status = set_pgp_keypair(session, identity->fpr);
1.1280
1.1281 - signal_Sync_event(session, Sync_PR_keysync, KeyGen, NULL);
1.1282 + if ((!suppress_event) && (identity->flags & PEP_idf_devicegroup))
1.1283 + signal_Sync_event(session, Sync_PR_keysync, KeyGen, NULL);
1.1284
1.1285 // add to known keypair DB, as this might not end up being a default
1.1286 return status;
1.1287 }
1.1288
1.1289 +
1.1290 DYNAMIC_API PEP_STATUS get_key_rating(
1.1291 PEP_SESSION session,
1.1292 const char *fpr,
1.1293 @@ -4544,7 +4889,18 @@
1.1294 PEP_SESSION session,
1.1295 const char *key_data,
1.1296 size_t size,
1.1297 - identity_list **private_keys
1.1298 + identity_list **private_keys)
1.1299 +{
1.1300 + return _import_key_with_fpr_return(session, key_data, size, private_keys, NULL, NULL);
1.1301 +}
1.1302 +
1.1303 +PEP_STATUS _import_key_with_fpr_return(
1.1304 + PEP_SESSION session,
1.1305 + const char *key_data,
1.1306 + size_t size,
1.1307 + identity_list **private_keys,
1.1308 + stringlist_t** imported_keys,
1.1309 + uint64_t* changed_public_keys
1.1310 )
1.1311 {
1.1312 assert(session);
1.1313 @@ -4552,25 +4908,14 @@
1.1314
1.1315 if (!(session && key_data))
1.1316 return PEP_ILLEGAL_VALUE;
1.1317 -
1.1318 - return session->cryptotech[PEP_crypt_OpenPGP]._import_key_with_fpr_return(
1.1319 - session, key_data,
1.1320 - size, private_keys, NULL);
1.1321 +
1.1322 + if (imported_keys && !*imported_keys && changed_public_keys)
1.1323 + *changed_public_keys = 0;
1.1324 +
1.1325 + return session->cryptotech[PEP_crypt_OpenPGP].import_key(session, key_data,
1.1326 + size, private_keys, imported_keys, changed_public_keys);
1.1327 }
1.1328
1.1329 -PEP_STATUS _import_key_with_fpr_return(
1.1330 - PEP_SESSION session,
1.1331 - const char *key_data,
1.1332 - size_t size,
1.1333 - identity_list **private_keys,
1.1334 - stringlist_t** imported_keys
1.1335 - )
1.1336 -{
1.1337 - return session->cryptotech[PEP_crypt_OpenPGP]._import_key_with_fpr_return(
1.1338 - session, key_data,
1.1339 - size, private_keys, imported_keys);
1.1340 -}
1.1341 -
1.1342 DYNAMIC_API PEP_STATUS recv_key(PEP_SESSION session, const char *pattern)
1.1343 {
1.1344 assert(session);
1.1345 @@ -4744,7 +5089,7 @@
1.1346 int result;
1.1347
1.1348 do {
1.1349 - result = Sqlite3_step(session->crashdump);
1.1350 + result = sqlite3_step(session->crashdump);
1.1351 switch (result) {
1.1352 case SQLITE_ROW:
1.1353 timestamp = (const char *) sqlite3_column_text(session->crashdump,
1.1354 @@ -4836,7 +5181,7 @@
1.1355 int result;
1.1356
1.1357 do {
1.1358 - result = Sqlite3_step(session->languagelist);
1.1359 + result = sqlite3_step(session->languagelist);
1.1360 switch (result) {
1.1361 case SQLITE_ROW:
1.1362 lang = (const char *) sqlite3_column_text(session->languagelist,
1.1363 @@ -4904,7 +5249,7 @@
1.1364 const char *_phrase = NULL;
1.1365 int result;
1.1366
1.1367 - result = Sqlite3_step(session->i18n_token);
1.1368 + result = sqlite3_step(session->i18n_token);
1.1369 switch (result) {
1.1370 case SQLITE_ROW:
1.1371 _phrase = (const char *) sqlite3_column_text(session->i18n_token, 0);
1.1372 @@ -4946,7 +5291,7 @@
1.1373 sqlite3_reset(session->sequence_value2);
1.1374 sqlite3_bind_text(session->sequence_value2, 1, name, -1,
1.1375 SQLITE_STATIC);
1.1376 - int result = Sqlite3_step(session->sequence_value2);
1.1377 + int result = sqlite3_step(session->sequence_value2);
1.1378 switch (result) {
1.1379 case SQLITE_ROW: {
1.1380 int32_t _value = (int32_t)
1.1381 @@ -4974,7 +5319,7 @@
1.1382
1.1383 sqlite3_reset(session->sequence_value1);
1.1384 sqlite3_bind_text(session->sequence_value1, 1, name, -1, SQLITE_STATIC);
1.1385 - int result = Sqlite3_step(session->sequence_value1);
1.1386 + int result = sqlite3_step(session->sequence_value1);
1.1387 assert(result == SQLITE_DONE);
1.1388 sqlite3_reset(session->sequence_value1);
1.1389 if (result == SQLITE_DONE)
1.1390 @@ -5024,9 +5369,6 @@
1.1391
1.1392 PEP_STATUS is_own_key(PEP_SESSION session, const char* fpr, bool* own_key) {
1.1393
1.1394 - assert(session);
1.1395 - assert(!EMPTYSTR(fpr));
1.1396 -
1.1397 if (!session || EMPTYSTR(fpr))
1.1398 return PEP_ILLEGAL_VALUE;
1.1399
1.1400 @@ -5035,7 +5377,7 @@
1.1401
1.1402 sqlite3_bind_text(session->own_key_is_listed, 1, fpr, -1,
1.1403 SQLITE_STATIC);
1.1404 - int result = Sqlite3_step(session->own_key_is_listed);
1.1405 + int result = sqlite3_step(session->own_key_is_listed);
1.1406 switch (result) {
1.1407 case SQLITE_ROW: {
1.1408 *own_key = (sqlite3_column_int(session->own_key_is_listed, 0) != 0);
1.1409 @@ -5079,7 +5421,7 @@
1.1410
1.1411 int result;
1.1412
1.1413 - result = Sqlite3_step(session->set_revoked);
1.1414 + result = sqlite3_step(session->set_revoked);
1.1415 switch (result) {
1.1416 case SQLITE_DONE:
1.1417 status = PEP_STATUS_OK;
1.1418 @@ -5121,7 +5463,7 @@
1.1419
1.1420 int result;
1.1421
1.1422 - result = Sqlite3_step(session->get_revoked);
1.1423 + result = sqlite3_step(session->get_revoked);
1.1424 switch (result) {
1.1425 case SQLITE_ROW: {
1.1426 *revoked_fpr = strdup((const char *)
1.1427 @@ -5165,7 +5507,7 @@
1.1428
1.1429 int result;
1.1430
1.1431 - result = Sqlite3_step(session->get_replacement_fpr);
1.1432 + result = sqlite3_step(session->get_replacement_fpr);
1.1433 switch (result) {
1.1434 case SQLITE_ROW: {
1.1435 *revoked_fpr = strdup((const char *)
1.1436 @@ -5204,7 +5546,7 @@
1.1437 sqlite3_reset(session->get_last_contacted);
1.1438 int result;
1.1439
1.1440 - while ((result = Sqlite3_step(session->get_last_contacted)) == SQLITE_ROW) {
1.1441 + while ((result = sqlite3_step(session->get_last_contacted)) == SQLITE_ROW) {
1.1442 pEp_identity *ident = new_identity(
1.1443 (const char *) sqlite3_column_text(session->get_last_contacted, 1),
1.1444 NULL,
1.1445 @@ -5351,3 +5693,24 @@
1.1446 #endif
1.1447 log_service(session, "### service error log ###", entity, buffer, where);
1.1448 }
1.1449 +
1.1450 +DYNAMIC_API void set_debug_color(PEP_SESSION session, int ansi_color)
1.1451 +{
1.1452 +#ifndef NDEBUG
1.1453 + session->debug_color = ansi_color;
1.1454 +#endif
1.1455 +}
1.1456 +
1.1457 +PEP_STATUS set_all_userids_to_own(PEP_SESSION session, identity_list* id_list) {
1.1458 + static char* ownid = NULL;
1.1459 + PEP_STATUS status = PEP_STATUS_OK;
1.1460 + if (!ownid) {
1.1461 + status = get_default_own_userid(session, &ownid);
1.1462 + }
1.1463 + if (status == PEP_STATUS_OK) {
1.1464 + if (ownid) {
1.1465 + status = set_all_userids_in_list(id_list, ownid);
1.1466 + }
1.1467 + }
1.1468 + return status;
1.1469 +}