src/pEpEngine.c
branchENGINE-633
changeset 4785 08d521da5611
parent 4079 da3b0627a59c
parent 4753 76930ab28dd8
child 4810 555f47152f28
     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 +}