src/pEpEngine.c
changeset 2461 85c8e5aad3bc
parent 2265 73c0738de68c
child 2462 48b526a0daac
     1.1 --- a/src/pEpEngine.c	Mon Jan 15 12:26:14 2018 +0100
     1.2 +++ b/src/pEpEngine.c	Mon Jan 29 12:15:51 2018 +0100
     1.3 @@ -47,10 +47,10 @@
     1.4      "select id, word from wordlist where lang = lower(?1) "
     1.5      "and id = ?2 ;";
     1.6  
     1.7 -
     1.8  static const char *sql_get_identity =  
     1.9      "select fpr, username, comm_type, lang,"
    1.10 -    "   identity.flags | pgp_keypair.flags"
    1.11 +    "   identity.flags | pgp_keypair.flags,"
    1.12 +    "   is_own"
    1.13      "   from identity"
    1.14      "   join person on id = identity.user_id"
    1.15      "   join pgp_keypair on fpr = identity.main_key_id"
    1.16 @@ -63,10 +63,37 @@
    1.17      "          end) = 1"
    1.18      "   and identity.user_id = ?2;";
    1.19  
    1.20 +static const char *sql_get_identity_without_trust_check =  
    1.21 +    "select identity.main_key_id, username, lang,"
    1.22 +    "   identity.flags, is_own"
    1.23 +    "   from identity"
    1.24 +    "   join person on id = identity.user_id"
    1.25 +    "   where (case when (address = ?1) then (1)"
    1.26 +    "               when (lower(address) = lower(?1)) then (1)"
    1.27 +    "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
    1.28 +    "               else 0"
    1.29 +    "          end) = 1"
    1.30 +    "   and identity.user_id = ?2;";
    1.31 +
    1.32 +static const char *sql_get_identities_by_address =  
    1.33 +    "select user_id, identity.main_key_id, username, lang,"
    1.34 +    "   identity.flags, is_own"
    1.35 +    "   from identity"
    1.36 +    "   join person on id = identity.user_id"
    1.37 +    "   where (case when (address = ?1) then (1)"
    1.38 +    "               when (lower(address) = lower(?1)) then (1)"
    1.39 +    "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
    1.40 +    "               else 0"
    1.41 +    "          end) = 1;";
    1.42 +
    1.43  static const char *sql_replace_identities_fpr =  
    1.44      "update identity"
    1.45      "   set main_key_id = ?1 "
    1.46      "   where main_key_id = ?2 ;";
    1.47 +    
    1.48 +static const char *sql_remove_fpr_as_default =
    1.49 +    "update person set main_key_id = NULL where main_key_id = ?1 ;"
    1.50 +    "update identity set main_key_id = NULL where main_key_id = ?1 ;";
    1.51  
    1.52  // Set person, but if already exist, only update.
    1.53  // if main_key_id already set, don't touch.
    1.54 @@ -79,11 +106,37 @@
    1.55  
    1.56  static const char *sql_set_device_group = 
    1.57      "update person set device_group = ?1 "
    1.58 -    "where id = '" PEP_OWN_USERID "';";
    1.59 +    "where id = ?2;";
    1.60 +
    1.61 +// This will cascade to identity and trust
    1.62 +static const char* sql_replace_userid =
    1.63 +    "update person set id = ?1 " 
    1.64 +    "where id = ?2;";
    1.65 +
    1.66 +static const char *sql_replace_main_user_fpr =  
    1.67 +    "update person "
    1.68 +    "   set main_key_id = ?1 "
    1.69 +    "   where id = ?2 ;";
    1.70 +
    1.71 +static const char *sql_get_main_user_fpr =  
    1.72 +    "select main_key_id from person"
    1.73 +    "   where id = ?1 ;";
    1.74 +
    1.75 +static const char *sql_refresh_userid_default_key =
    1.76 +    "update person "
    1.77 +    "   set main_key_id = "
    1.78 +    "       (select identity.main_key_id from identity "
    1.79 +    "           join trust on trust.user_id = identity.user_id "
    1.80 +    "               and trust.pgp_keypair_fpr = identity.main_key_id "
    1.81 +    "           join person on identity.user_id = identity.user_id "
    1.82 +    "       where identity.user_id = ?1 "
    1.83 +    "       order by trust.comm_type desc "
    1.84 +    "       limit 1) "
    1.85 +    "where id = ?1 ; ";
    1.86  
    1.87  static const char *sql_get_device_group = 
    1.88      "select device_group from person "
    1.89 -    "where id = '" PEP_OWN_USERID "';";
    1.90 +    "where id = ?1;";
    1.91  
    1.92  static const char *sql_set_pgp_keypair = 
    1.93      "insert or replace into pgp_keypair (fpr) "
    1.94 @@ -92,7 +145,7 @@
    1.95  static const char *sql_set_identity = 
    1.96      "insert or replace into identity ("
    1.97      " address, main_key_id, "
    1.98 -    " user_id, flags"
    1.99 +    " user_id, flags, is_own"
   1.100      ") values ("
   1.101      " ?1,"
   1.102      " upper(replace(?2,' ','')),"
   1.103 @@ -105,7 +158,8 @@
   1.104      // "    0)"
   1.105      // " ) | (?4 & 255)"
   1.106      /* set_identity ignores previous flags, and doesn't filter machine flags */
   1.107 -    " ?4"
   1.108 +    " ?4,"
   1.109 +    " ?5"
   1.110      ");";
   1.111          
   1.112  static const char *sql_set_identity_flags = 
   1.113 @@ -142,7 +196,7 @@
   1.114  static const char *sql_mark_as_compromized = 
   1.115      "update trust not indexed set comm_type = 15"
   1.116      " where pgp_keypair_fpr = upper(replace(?1,' ','')) ;";
   1.117 -
   1.118 +    
   1.119  static const char *sql_crashdump = 
   1.120      "select timestamp, title, entity, description, comment"
   1.121      " from log order by timestamp desc limit ?1 ;";
   1.122 @@ -154,7 +208,6 @@
   1.123  static const char *sql_i18n_token = 
   1.124      "select phrase from i18n_token where lang = lower(?1) and id = ?2 ;";
   1.125  
   1.126 -
   1.127  // blacklist
   1.128  static const char *sql_blacklist_add = 
   1.129      "insert or replace into blacklist_keys (fpr) values (upper(replace(?1,' ',''))) ;"
   1.130 @@ -172,40 +225,39 @@
   1.131                  
   1.132  
   1.133  // Own keys
   1.134 +// We only care if it's 0 or non-zero
   1.135  static const char *sql_own_key_is_listed = 
   1.136      "select count(*) from ("
   1.137 -    " select main_key_id from person "
   1.138 -    "   where main_key_id = upper(replace(?1,' ',''))"
   1.139 -    "    and id = '" PEP_OWN_USERID "' "
   1.140 -    " union "
   1.141 -    "  select main_key_id from identity "
   1.142 -    "   where main_key_id = upper(replace(?1,' ',''))"
   1.143 -    "    and user_id = '" PEP_OWN_USERID "' "
   1.144 -    " union "
   1.145 -    "  select fpr from own_keys "
   1.146 -    "   where fpr = upper(replace(?1,' ',''))"
   1.147 -    " );";
   1.148 +    "   select pgp_keypair_fpr from trust"
   1.149 +    "      join identity on trust.user_id = identity.user_id"
   1.150 +    "      where pgp_keypair_fpr = upper(replace(?1,' ',''))"
   1.151 +    "           and identity.is_own = 1"
   1.152 +    ");";
   1.153  
   1.154  static const char *sql_own_identities_retrieve =  
   1.155 -    "select address, fpr, username, "
   1.156 +    "select address, fpr, username, identity.user_id, "
   1.157      "   lang, identity.flags | pgp_keypair.flags"
   1.158      "   from identity"
   1.159      "   join person on id = identity.user_id"
   1.160      "   join pgp_keypair on fpr = identity.main_key_id"
   1.161      "   join trust on id = trust.user_id"
   1.162      "       and pgp_keypair_fpr = identity.main_key_id"
   1.163 -    "   where identity.user_id = '" PEP_OWN_USERID "'"
   1.164 +    "   where identity.is_own = 1"
   1.165      "       and (identity.flags & ?1) = 0;";
   1.166 -        
   1.167 -static const char *sql_own_keys_retrieve =  
   1.168 -    "select fpr from own_keys"
   1.169 -    "   natural join identity"
   1.170 -    "   where (identity.flags & ?1) = 0;";
   1.171 -
   1.172 -static const char *sql_set_own_key = 
   1.173 -    "insert or replace into own_keys (address, user_id, fpr)"
   1.174 -    " values (?1, '" PEP_OWN_USERID "', upper(replace(?2,' ','')));";
   1.175 -
   1.176 +
   1.177 +static const char *sql_own_keys_retrieve = 
   1.178 +    "select pgp_keypair_fpr from trust"
   1.179 +    "   join identity on trust.user_id = identity.user_id"
   1.180 +    "   where identity.is_own = 1";
   1.181 +
   1.182 +static const char* sql_get_user_default_key =
   1.183 +    "select main_key_id from person" 
   1.184 +    "   where id = ?1;";
   1.185 +
   1.186 +static const char* sql_get_default_own_userid =
   1.187 +    "select id from person"
   1.188 +    "   join identity on id = identity.user_id"
   1.189 +    "   where identity.is_own = 1";
   1.190  
   1.191  // Sequence
   1.192  static const char *sql_sequence_value1 = 
   1.193 @@ -238,6 +290,14 @@
   1.194      "select revoked_fpr, revocation_date from revoked_keys"
   1.195      "    where replacement_fpr = upper(replace(?1,' ','')) ;";
   1.196  
   1.197 +static const char *sql_get_userid_alias_default =
   1.198 +    "select default_id from alternate_user_id "
   1.199 +    "   where alternate_id = ?1 ; ";
   1.200 +
   1.201 +static const char *sql_add_userid_alias =
   1.202 +    "insert or replace into alternate_user_id (default_id, alternate_id) "
   1.203 +    "values (?1, ?2) ;";
   1.204 +    
   1.205  static int user_version(void *_version, int count, char **text, char **name)
   1.206  {
   1.207      assert(_version);
   1.208 @@ -251,6 +311,56 @@
   1.209      return 0;
   1.210  }
   1.211  
   1.212 +static int table_contains_column(PEP_SESSION session, const char* table_name,
   1.213 +                                                      const char* col_name) {
   1.214 +
   1.215 +
   1.216 +    if (!session || !table_name || !col_name)
   1.217 +        return -1;
   1.218 +        
   1.219 +    // Table names can't be SQL parameters, so we do it this way.
   1.220 +    
   1.221 +    // these two must be the same number.
   1.222 +    char sql_buf[500];
   1.223 +    const size_t max_q_len = 500;
   1.224 +    
   1.225 +    size_t t_size, c_size, q_size;
   1.226 +    
   1.227 +    const char* q1 = "SELECT "; // 7
   1.228 +    const char* q2 = " from "; // 6
   1.229 +    const char* q3 = ";";       // 1
   1.230 +    
   1.231 +    q_size = 14;
   1.232 +    t_size = strlen(table_name);
   1.233 +    c_size = strlen(col_name);
   1.234 +    
   1.235 +    size_t query_len = q_size + c_size + t_size + 1;
   1.236 +    
   1.237 +    if (query_len > max_q_len)
   1.238 +        return -1;
   1.239 +
   1.240 +    strlcpy(sql_buf, q1, max_q_len);
   1.241 +    strlcat(sql_buf, col_name, max_q_len);
   1.242 +    strlcat(sql_buf, q2, max_q_len);
   1.243 +    strlcat(sql_buf, table_name, max_q_len);
   1.244 +    strlcat(sql_buf, q3, max_q_len);
   1.245 +
   1.246 +    sqlite3_stmt *stmt; 
   1.247 +
   1.248 +    sqlite3_prepare_v2(session->db, sql_buf, -1, &stmt, NULL);
   1.249 +
   1.250 +    int retval = 0;
   1.251 +
   1.252 +    int rc = sqlite3_step(stmt);  
   1.253 +    if (rc == SQLITE_DONE || rc == SQLITE_OK || rc == SQLITE_ROW) {
   1.254 +        retval = 1;
   1.255 +    }
   1.256 +
   1.257 +    sqlite3_finalize(stmt);      
   1.258 +        
   1.259 +    return retval;
   1.260 +}
   1.261 +
   1.262  DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
   1.263  {
   1.264      PEP_STATUS status = PEP_STATUS_OK;
   1.265 @@ -358,7 +468,7 @@
   1.266      sqlite3_busy_timeout(_session->system_db, 1000);
   1.267  
   1.268  // increment this when patching DDL
   1.269 -#define _DDL_USER_VERSION "5"
   1.270 +#define _DDL_USER_VERSION "6"
   1.271  
   1.272      if (in_first) {
   1.273  
   1.274 @@ -411,18 +521,19 @@
   1.275                  "   address text,\n"
   1.276                  "   user_id text\n"
   1.277                  "       references person (id)\n"
   1.278 -                "       on delete cascade,\n"
   1.279 +                "       on delete cascade on update cascade,\n"
   1.280                  "   main_key_id text\n"
   1.281                  "       references pgp_keypair (fpr)\n"
   1.282                  "       on delete set null,\n"
   1.283                  "   comment text,\n"
   1.284 -                "   flags integer default 0,"
   1.285 +                "   flags integer default 0,\n"
   1.286 +                "   is_own integer default 0,\n"
   1.287                  "   primary key (address, user_id)\n"
   1.288                  ");\n"
   1.289                  "create table if not exists trust (\n"
   1.290                  "   user_id text not null\n"
   1.291                  "       references person (id)\n"
   1.292 -                "       on delete cascade,\n"
   1.293 +                "       on delete cascade on update cascade,\n"
   1.294                  "   pgp_keypair_fpr text not null\n"
   1.295                  "       references pgp_keypair (fpr)\n"
   1.296                  "       on delete cascade,\n"
   1.297 @@ -447,18 +558,12 @@
   1.298                  "       on delete cascade,\n"
   1.299                  "   revocation_date integer\n"
   1.300                  ");\n"
   1.301 -                "create table if not exists own_keys (\n"
   1.302 -                "   address text,\n"
   1.303 -                "   user_id text,\n"
   1.304 -                "   fpr text not null\n"
   1.305 -                "       references pgp_keypair (fpr)\n"
   1.306 -                "       on delete cascade,\n"
   1.307 -                "   foreign key (address, user_id)\n"
   1.308 -                "       references identity\n"
   1.309 -                "       on delete cascade,\n"
   1.310 -                "   check (user_id = '" PEP_OWN_USERID "')\n"
   1.311 -                "   primary key (address, fpr)\n"
   1.312 -                ");\n" 
   1.313 +                // user id aliases
   1.314 +                "create table if not exists alternate_user_id (\n"
   1.315 +                "    default_id text references person (id)\n"
   1.316 +                "       on delete cascade on update cascade,\n"
   1.317 +                "    alternate_id text primary key\n"
   1.318 +                ");\n"
   1.319                  ,
   1.320              NULL,
   1.321              NULL,
   1.322 @@ -490,6 +595,48 @@
   1.323              NULL,
   1.324              NULL);
   1.325          assert(int_result == SQLITE_OK);
   1.326 +        
   1.327 +        // Sometimes the user_version wasn't set correctly. Check to see if this
   1.328 +        // is really necessary...
   1.329 +        if (version == 1) {
   1.330 +            bool version_changed = true;
   1.331 +            
   1.332 +            if (table_contains_column(_session, "identity", "is_own") > 0) {
   1.333 +                version = 6;
   1.334 +            }
   1.335 +            else if (table_contains_column(_session, "sequences", "own") > 0) {
   1.336 +                version = 3;
   1.337 +            }
   1.338 +            else if (table_contains_column(_session, "pgp_keypair", "flags") > 0) {
   1.339 +                version = 2;
   1.340 +            }
   1.341 +            else {
   1.342 +                version_changed = false;
   1.343 +            }
   1.344 +            
   1.345 +            if (version_changed) {
   1.346 +                // set it in the DB, finally. Yeesh.
   1.347 +                char verbuf[21]; // enough digits for a max-sized 64 bit int, cmon. 
   1.348 +                sprintf(verbuf,"%d",version);
   1.349 +                
   1.350 +                size_t query_size = strlen(verbuf) + 25;
   1.351 +                char* query = calloc(query_size, 1);
   1.352 +                
   1.353 +                strlcpy(query, "pragma user_version = ", query_size);
   1.354 +                strlcat(query, verbuf, query_size);
   1.355 +                strlcat(query, ";", query_size);
   1.356 +                
   1.357 +                int_result = sqlite3_exec(
   1.358 +                    _session->db,
   1.359 +                    query,
   1.360 +                    user_version,
   1.361 +                    &version,
   1.362 +                    NULL
   1.363 +                );
   1.364 +                free(query);
   1.365 +            }
   1.366 +        }
   1.367 +
   1.368  
   1.369          if(version != 0) { 
   1.370              // Version has been already set
   1.371 @@ -510,7 +657,7 @@
   1.372              //     );
   1.373              //     assert(int_result == SQLITE_OK);
   1.374              // }
   1.375 -
   1.376 +            
   1.377              if (version < 2) {
   1.378                  int_result = sqlite3_exec(
   1.379                      _session->db,
   1.380 @@ -555,6 +702,81 @@
   1.381                  );
   1.382                  assert(int_result == SQLITE_OK);
   1.383              }
   1.384 +            
   1.385 +            if (version < 6) {
   1.386 +                int_result = sqlite3_exec(
   1.387 +                    _session->db,
   1.388 +                    "alter table identity\n"
   1.389 +                    "   add column is_own integer default 0;\n",
   1.390 +                    NULL,
   1.391 +                    NULL,
   1.392 +                    NULL
   1.393 +                );
   1.394 +                assert(int_result == SQLITE_OK);                
   1.395 +                int_result = sqlite3_exec(
   1.396 +                    _session->db,
   1.397 +                    "update identity\n"
   1.398 +                    "   set is_own = 1\n"
   1.399 +                    "   where (user_id = '" PEP_OWN_USERID "');\n",
   1.400 +                    NULL,
   1.401 +                    NULL,
   1.402 +                    NULL
   1.403 +                );
   1.404 +                assert(int_result == SQLITE_OK);    
   1.405 +
   1.406 +                // Turns out that just adding "on update cascade" in
   1.407 +                // sqlite is a PITA. We need to be able to cascade
   1.408 +                // person->id replacements (for temp ids like "TOFU_")
   1.409 +                // so here we go...
   1.410 +                int_result = sqlite3_exec(
   1.411 +                    _session->db,
   1.412 +                    "PRAGMA foreign_keys=off;\n"
   1.413 +                    "BEGIN TRANSACTION;\n"
   1.414 +                    "ALTER TABLE identity RENAME TO _identity_old;\n"
   1.415 +                    "create table identity (\n"
   1.416 +                    "   address text,\n"
   1.417 +                    "   user_id text\n"
   1.418 +                    "       references person (id)\n"
   1.419 +                    "       on delete cascade on update cascade,\n"
   1.420 +                    "   main_key_id text\n"
   1.421 +                    "       references pgp_keypair (fpr)\n"
   1.422 +                    "       on delete set null,\n"
   1.423 +                    "   comment text,\n"
   1.424 +                    "   flags integer default 0,\n"
   1.425 +                    "   is_own integer default 0,\n"
   1.426 +                    "   primary key (address, user_id)\n"
   1.427 +                    ");\n"
   1.428 +                    "INSERT INTO identity SELECT * FROM _identity_old;\n"
   1.429 +                    "DROP TABLE _identity_old;\n"
   1.430 +                    "ALTER TABLE trust RENAME TO _trust_old;\n"
   1.431 +                    "create table trust (\n"
   1.432 +                    "   user_id text not null\n"
   1.433 +                    "       references person (id)\n"
   1.434 +                    "       on delete cascade on update cascade,\n"
   1.435 +                    "   pgp_keypair_fpr text not null\n"
   1.436 +                    "       references pgp_keypair (fpr)\n"
   1.437 +                    "       on delete cascade,\n"
   1.438 +                    "   comm_type integer not null,\n"
   1.439 +                    "   comment text,\n"
   1.440 +                    "   primary key (user_id, pgp_keypair_fpr)\n"
   1.441 +                    ");\n"
   1.442 +                    "INSERT INTO trust SELECT * FROM _trust_old;\n"
   1.443 +                    "DROP TABLE _trust_old;\n"
   1.444 +                    "COMMIT;\n"
   1.445 +                    "\n"
   1.446 +                    "PRAGMA foreign_keys=on;\n"
   1.447 +                    "create table if not exists alternate_user_id (\n"
   1.448 +                    "    default_id text references person (id)\n"
   1.449 +                    "       on delete cascade on update cascade,\n"
   1.450 +                    "    alternate_id text primary key\n"
   1.451 +                    ");\n"
   1.452 +                    ,
   1.453 +                    NULL,
   1.454 +                    NULL,
   1.455 +                    NULL
   1.456 +                );
   1.457 +                assert(int_result == SQLITE_OK);    
   1.458 +            }
   1.459          }
   1.460          else { 
   1.461              // Version from DB was 0, it means this is initial setup.
   1.462 @@ -592,10 +814,57 @@
   1.463              (int)strlen(sql_get_identity), &_session->get_identity, NULL);
   1.464      assert(int_result == SQLITE_OK);
   1.465  
   1.466 +    int_result = sqlite3_prepare_v2(_session->db, sql_get_identity_without_trust_check,
   1.467 +            (int)strlen(sql_get_identity_without_trust_check), 
   1.468 +            &_session->get_identity_without_trust_check, NULL);
   1.469 +    assert(int_result == SQLITE_OK);
   1.470 +
   1.471 +    int_result = sqlite3_prepare_v2(_session->db, sql_get_identities_by_address,
   1.472 +            (int)strlen(sql_get_identities_by_address), 
   1.473 +            &_session->get_identities_by_address, NULL);
   1.474 +    assert(int_result == SQLITE_OK);
   1.475 +
   1.476 +    int_result = sqlite3_prepare_v2(_session->db, sql_get_user_default_key,
   1.477 +            (int)strlen(sql_get_user_default_key), &_session->get_user_default_key, NULL);
   1.478 +    assert(int_result == SQLITE_OK);
   1.479 +
   1.480 +    int_result = sqlite3_prepare_v2(_session->db, sql_get_default_own_userid,
   1.481 +            (int)strlen(sql_get_default_own_userid), &_session->get_default_own_userid, NULL);
   1.482 +    assert(int_result == SQLITE_OK);
   1.483 +    
   1.484 +    int_result = sqlite3_prepare_v2(_session->db, sql_get_userid_alias_default,
   1.485 +            (int)strlen(sql_get_userid_alias_default), &_session->get_userid_alias_default, NULL);
   1.486 +    assert(int_result == SQLITE_OK);
   1.487 +
   1.488 +    int_result = sqlite3_prepare_v2(_session->db, sql_add_userid_alias,
   1.489 +            (int)strlen(sql_add_userid_alias), &_session->add_userid_alias, NULL);
   1.490 +    assert(int_result == SQLITE_OK);
   1.491 +
   1.492 +    int_result = sqlite3_prepare_v2(_session->db, sql_replace_userid,
   1.493 +            (int)strlen(sql_replace_userid), &_session->replace_userid, NULL);
   1.494 +    assert(int_result == SQLITE_OK);
   1.495 +
   1.496 +    int_result = sqlite3_prepare_v2(_session->db, sql_replace_main_user_fpr,
   1.497 +            (int)strlen(sql_replace_main_user_fpr), &_session->replace_main_user_fpr, NULL);
   1.498 +    assert(int_result == SQLITE_OK);
   1.499 +
   1.500 +    int_result = sqlite3_prepare_v2(_session->db, sql_get_main_user_fpr,
   1.501 +            (int)strlen(sql_get_main_user_fpr), &_session->get_main_user_fpr, NULL);
   1.502 +    assert(int_result == SQLITE_OK);
   1.503 +
   1.504 +    int_result = sqlite3_prepare_v2(_session->db, sql_refresh_userid_default_key,
   1.505 +            (int)strlen(sql_refresh_userid_default_key), &_session->refresh_userid_default_key, NULL);
   1.506 +    assert(int_result == SQLITE_OK);
   1.507 +
   1.508      int_result = sqlite3_prepare_v2(_session->db, sql_replace_identities_fpr,
   1.509              (int)strlen(sql_replace_identities_fpr), 
   1.510              &_session->replace_identities_fpr, NULL);
   1.511      assert(int_result == SQLITE_OK);
   1.512 +    
   1.513 +    int_result = sqlite3_prepare_v2(_session->db, sql_remove_fpr_as_default,
   1.514 +            (int)strlen(sql_remove_fpr_as_default), 
   1.515 +            &_session->remove_fpr_as_default, NULL);
   1.516 +    assert(int_result == SQLITE_OK);
   1.517  
   1.518      int_result = sqlite3_prepare_v2(_session->db, sql_set_person,
   1.519              (int)strlen(sql_set_person), &_session->set_person, NULL);
   1.520 @@ -660,7 +929,7 @@
   1.521      int_result = sqlite3_prepare_v2(_session->system_db, sql_i18n_token,
   1.522              (int)strlen(sql_i18n_token), &_session->i18n_token, NULL);
   1.523      assert(int_result == SQLITE_OK);
   1.524 -
   1.525 +    
   1.526      // blacklist
   1.527  
   1.528      int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_add,
   1.529 @@ -699,10 +968,10 @@
   1.530              &_session->own_keys_retrieve, NULL);
   1.531      assert(int_result == SQLITE_OK);
   1.532   
   1.533 -    int_result = sqlite3_prepare_v2(_session->db, sql_set_own_key,
   1.534 -            (int)strlen(sql_set_own_key),
   1.535 -            &_session->set_own_key, NULL);
   1.536 -    assert(int_result == SQLITE_OK);
   1.537 +    // int_result = sqlite3_prepare_v2(_session->db, sql_set_own_key,
   1.538 +    //         (int)strlen(sql_set_own_key),
   1.539 +    //         &_session->set_own_key, NULL);
   1.540 +    // assert(int_result == SQLITE_OK);
   1.541   
   1.542      // Sequence
   1.543  
   1.544 @@ -745,9 +1014,6 @@
   1.545  
   1.546      // runtime config
   1.547  
   1.548 -#ifdef ANDROID
   1.549 -#elif TARGET_OS_IPHONE
   1.550 -#else /* Desktop */
   1.551      if (very_first)
   1.552      {
   1.553          // On first run, all private keys already present in PGP keyring 
   1.554 @@ -760,7 +1026,7 @@
   1.555          //
   1.556          // Indeed, if pEpEngine did import spoofed private keys in previous
   1.557          // install, then those keys become automatically trusted in case 
   1.558 -        // pEp_management.db is deleted.
   1.559 +        // management.db is deleted.
   1.560          //
   1.561          // A solution to distinguish bare GPG keyring from pEp keyring is
   1.562          // needed here. Then keys managed by pEpEngine wouldn't be
   1.563 @@ -784,7 +1050,6 @@
   1.564              }
   1.565          }
   1.566      }
   1.567 -#endif
   1.568  
   1.569      // sync_session set to own session by default
   1.570      // sync_session is then never null on a valid session
   1.571 @@ -833,8 +1098,22 @@
   1.572                  sqlite3_finalize(session->trustword);
   1.573              if (session->get_identity)
   1.574                  sqlite3_finalize(session->get_identity);
   1.575 +            if (session->get_identity_without_trust_check)
   1.576 +                sqlite3_finalize(session->get_identity_without_trust_check);
   1.577 +            if (session->get_identities_by_address)
   1.578 +                sqlite3_finalize(session->get_identities_by_address);            
   1.579 +            if (session->get_user_default_key)
   1.580 +                sqlite3_finalize(session->get_user_default_key);    
   1.581 +            if (session->get_default_own_userid)
   1.582 +                sqlite3_finalize(session->get_default_own_userid);
   1.583 +            if (session->get_userid_alias_default)
   1.584 +                sqlite3_finalize(session->get_userid_alias_default);
   1.585 +            if (session->add_userid_alias)
   1.586 +                sqlite3_finalize(session->add_userid_alias);
   1.587              if (session->replace_identities_fpr)
   1.588                  sqlite3_finalize(session->replace_identities_fpr);        
   1.589 +            if (session->remove_fpr_as_default)
   1.590 +                sqlite3_finalize(session->remove_fpr_as_default);            
   1.591              if (session->set_person)
   1.592                  sqlite3_finalize(session->set_person);
   1.593              if (session->set_device_group)
   1.594 @@ -865,6 +1144,14 @@
   1.595                  sqlite3_finalize(session->languagelist);
   1.596              if (session->i18n_token)
   1.597                  sqlite3_finalize(session->i18n_token);
   1.598 +            if (session->replace_userid)
   1.599 +                sqlite3_finalize(session->replace_userid);
   1.600 +            if (session->replace_main_user_fpr)
   1.601 +                sqlite3_finalize(session->replace_main_user_fpr);                
   1.602 +            if (session->get_main_user_fpr)
   1.603 +                sqlite3_finalize(session->get_main_user_fpr);
   1.604 +            if (session->refresh_userid_default_key)
   1.605 +                sqlite3_finalize(session->refresh_userid_default_key);
   1.606              if (session->blacklist_add)
   1.607                  sqlite3_finalize(session->blacklist_add);
   1.608              if (session->blacklist_delete)
   1.609 @@ -879,8 +1166,8 @@
   1.610                  sqlite3_finalize(session->own_identities_retrieve);
   1.611              if (session->own_keys_retrieve)
   1.612                  sqlite3_finalize(session->own_keys_retrieve);
   1.613 -            if (session->set_own_key)
   1.614 -                sqlite3_finalize(session->set_own_key);
   1.615 +            // if (session->set_own_key)
   1.616 +            //     sqlite3_finalize(session->set_own_key);
   1.617              if (session->sequence_value1)
   1.618                  sqlite3_finalize(session->sequence_value1);
   1.619              if (session->sequence_value2)
   1.620 @@ -1183,7 +1470,8 @@
   1.621      dup->lang[1] = src->lang[1];
   1.622      dup->lang[2] = 0;
   1.623      dup->flags = src->flags;
   1.624 -
   1.625 +    dup->me = src->me;
   1.626 +    
   1.627      return dup;
   1.628  }
   1.629  
   1.630 @@ -1198,6 +1486,124 @@
   1.631      }
   1.632  }
   1.633  
   1.634 +DYNAMIC_API PEP_STATUS get_default_own_userid(
   1.635 +        PEP_SESSION session, 
   1.636 +        char** userid
   1.637 +    )
   1.638 +{
   1.639 +    assert(session);
   1.640 +    assert(userid);
   1.641 +    
   1.642 +    if (!session || !userid)
   1.643 +        return PEP_ILLEGAL_VALUE;
   1.644 +        
   1.645 +    PEP_STATUS status = PEP_STATUS_OK;
   1.646 +    char* retval = NULL;
   1.647 +    
   1.648 +    sqlite3_reset(session->get_default_own_userid);
   1.649 +
   1.650 +    const int result = sqlite3_step(session->get_default_own_userid);
   1.651 +    const char* id;
   1.652 +    
   1.653 +    switch (result) {
   1.654 +        case SQLITE_ROW:
   1.655 +            id = (const char *) sqlite3_column_text(session->get_default_own_userid, 0);
   1.656 +            if (!id) {
   1.657 +                // Shouldn't happen.
   1.658 +                status = PEP_UNKNOWN_ERROR;
   1.659 +            }
   1.660 +            else {
   1.661 +                retval = strdup(id);
   1.662 +                if (!retval)
   1.663 +                    status = PEP_OUT_OF_MEMORY;
   1.664 +            }
   1.665 +            break;
   1.666 +        default:
   1.667 +            // Technically true, given how we find it, but FIXME we need a more descriptive error
   1.668 +            status = PEP_CANNOT_FIND_IDENTITY;
   1.669 +            *userid = NULL;
   1.670 +    }
   1.671 +
   1.672 +    *userid = retval;
   1.673 +
   1.674 +    sqlite3_reset(session->get_default_own_userid);
   1.675 +    
   1.676 +    return status;
   1.677 +}
   1.678 +
   1.679 +DYNAMIC_API PEP_STATUS get_userid_alias_default(
   1.680 +        PEP_SESSION session, 
   1.681 +        const char* alias_id,
   1.682 +        char** default_id) {
   1.683 +            
   1.684 +    assert(session);
   1.685 +    assert(alias_id);
   1.686 +    assert(alias_id[0]);
   1.687 +    assert(default_id);
   1.688 +
   1.689 +    if (!(session && alias_id && alias_id[0] && default_id))
   1.690 +        return PEP_ILLEGAL_VALUE;
   1.691 +
   1.692 +    PEP_STATUS status = PEP_STATUS_OK;
   1.693 +    char* retval = NULL;
   1.694 +
   1.695 +    sqlite3_reset(session->get_userid_alias_default);
   1.696 +    sqlite3_bind_text(session->get_userid_alias_default, 1, alias_id, -1, SQLITE_STATIC);
   1.697 +
   1.698 +    const char* tempid;
   1.699 +    
   1.700 +    const int result = sqlite3_step(session->get_userid_alias_default);
   1.701 +    switch (result) {
   1.702 +    case SQLITE_ROW:
   1.703 +        tempid = (const char *) sqlite3_column_text(session->get_userid_alias_default, 0);
   1.704 +        if (tempid) {
   1.705 +            retval = strdup(tempid);
   1.706 +            assert(retval);
   1.707 +            if (retval == NULL)
   1.708 +                return PEP_OUT_OF_MEMORY;
   1.709 +        }
   1.710 +    
   1.711 +        *default_id = retval;
   1.712 +        break;
   1.713 +    default:
   1.714 +        status = PEP_CANNOT_FIND_ALIAS;
   1.715 +        *default_id = NULL;
   1.716 +    }
   1.717 +
   1.718 +    sqlite3_reset(session->get_userid_alias_default);
   1.719 +    return status;            
   1.720 +}
   1.721 +
   1.722 +DYNAMIC_API PEP_STATUS set_userid_alias (
   1.723 +        PEP_SESSION session, 
   1.724 +        const char* default_id,
   1.725 +        const char* alias_id) {
   1.726 +            
   1.727 +    int result;
   1.728 +
   1.729 +    assert(session);
   1.730 +    assert(default_id);
   1.731 +    assert(alias_id);
   1.732 +
   1.733 +    if (!(session && default_id && alias_id && 
   1.734 +          default_id[0] != '\0' && alias_id[0] != '\0'))
   1.735 +        return PEP_ILLEGAL_VALUE;
   1.736 +
   1.737 +    sqlite3_reset(session->add_userid_alias);
   1.738 +    sqlite3_bind_text(session->add_userid_alias, 1, default_id, -1,
   1.739 +            SQLITE_STATIC);
   1.740 +    sqlite3_bind_text(session->add_userid_alias, 2, alias_id, -1,
   1.741 +            SQLITE_STATIC);
   1.742 +        
   1.743 +    result = sqlite3_step(session->add_userid_alias);
   1.744 +
   1.745 +    sqlite3_reset(session->add_userid_alias);
   1.746 +    if (result != SQLITE_DONE)
   1.747 +        return PEP_CANNOT_SET_ALIAS;
   1.748 +    
   1.749 +    return PEP_STATUS_OK;
   1.750 +}
   1.751 +
   1.752  DYNAMIC_API PEP_STATUS get_identity(
   1.753          PEP_SESSION session,
   1.754          const char *address,
   1.755 @@ -1249,6 +1655,9 @@
   1.756          }
   1.757          _identity->flags = (unsigned int)
   1.758              sqlite3_column_int(session->get_identity, 4);
   1.759 +        _identity->me = (unsigned int)
   1.760 +            sqlite3_column_int(session->get_identity, 5);
   1.761 +    
   1.762          *identity = _identity;
   1.763          break;
   1.764      default:
   1.765 @@ -1260,6 +1669,140 @@
   1.766      return status;
   1.767  }
   1.768  
   1.769 +PEP_STATUS get_identity_without_trust_check(
   1.770 +        PEP_SESSION session,
   1.771 +        const char *address,
   1.772 +        const char *user_id,
   1.773 +        pEp_identity **identity
   1.774 +    )
   1.775 +{
   1.776 +    PEP_STATUS status = PEP_STATUS_OK;
   1.777 +    static pEp_identity *_identity;
   1.778 +
   1.779 +    assert(session);
   1.780 +    assert(address);
   1.781 +    assert(address[0]);
   1.782 +    assert(identity);
   1.783 +
   1.784 +    if (!(session && address && address[0] && identity))
   1.785 +        return PEP_ILLEGAL_VALUE;
   1.786 +
   1.787 +    *identity = NULL;
   1.788 +
   1.789 +    sqlite3_reset(session->get_identity_without_trust_check);
   1.790 +    sqlite3_bind_text(session->get_identity_without_trust_check, 1, address, -1, SQLITE_STATIC);
   1.791 +    sqlite3_bind_text(session->get_identity_without_trust_check, 2, user_id, -1, SQLITE_STATIC);
   1.792 +
   1.793 +    const int result = sqlite3_step(session->get_identity_without_trust_check);
   1.794 +    switch (result) {
   1.795 +    case SQLITE_ROW:
   1.796 +        _identity = new_identity(
   1.797 +                address,
   1.798 +                (const char *) sqlite3_column_text(session->get_identity_without_trust_check, 0),
   1.799 +                user_id,
   1.800 +                (const char *) sqlite3_column_text(session->get_identity_without_trust_check, 1)
   1.801 +                );
   1.802 +        assert(_identity);
   1.803 +        if (_identity == NULL)
   1.804 +            return PEP_OUT_OF_MEMORY;
   1.805 +
   1.806 +        _identity->comm_type = PEP_ct_unknown;
   1.807 +        const char* const _lang = (const char *)
   1.808 +            sqlite3_column_text(session->get_identity_without_trust_check, 2);
   1.809 +        if (_lang && _lang[0]) {
   1.810 +            assert(_lang[0] >= 'a' && _lang[0] <= 'z');
   1.811 +            assert(_lang[1] >= 'a' && _lang[1] <= 'z');
   1.812 +            assert(_lang[2] == 0);
   1.813 +            _identity->lang[0] = _lang[0];
   1.814 +            _identity->lang[1] = _lang[1];
   1.815 +            _identity->lang[2] = 0;
   1.816 +        }
   1.817 +        _identity->flags = (unsigned int)
   1.818 +            sqlite3_column_int(session->get_identity_without_trust_check, 3);
   1.819 +        _identity->me = (unsigned int)
   1.820 +            sqlite3_column_int(session->get_identity_without_trust_check, 4);
   1.821 +    
   1.822 +        *identity = _identity;
   1.823 +        break;
   1.824 +    default:
   1.825 +        status = PEP_CANNOT_FIND_IDENTITY;
   1.826 +        *identity = NULL;
   1.827 +    }
   1.828 +
   1.829 +    sqlite3_reset(session->get_identity_without_trust_check);
   1.830 +    return status;
   1.831 +}
   1.832 +
   1.833 +PEP_STATUS get_identities_by_address(
   1.834 +        PEP_SESSION session,
   1.835 +        const char *address,
   1.836 +        identity_list** id_list
   1.837 +    )
   1.838 +{
   1.839 +    pEp_identity* ident;
   1.840 +
   1.841 +    assert(session);
   1.842 +    assert(address);
   1.843 +    assert(address[0]);
   1.844 +    assert(id_list);
   1.845 +
   1.846 +    if (!(session && address && address[0] && id_list))
   1.847 +        return PEP_ILLEGAL_VALUE;
   1.848 +
   1.849 +    *id_list = NULL;
   1.850 +    identity_list* ident_list = NULL;
   1.851 +
   1.852 +    sqlite3_reset(session->get_identities_by_address);
   1.853 +    sqlite3_bind_text(session->get_identities_by_address, 1, address, -1, SQLITE_STATIC);
   1.854 +    int result;
   1.855 +
   1.856 +    while ((result = sqlite3_step(session->get_identities_by_address)) == SQLITE_ROW) {
   1.857 +        //"select user_id, main_key_id, username, comm_type, lang,"
   1.858 +        //"   identity.flags, is_own"
   1.859 +        ident = new_identity(
   1.860 +                address,
   1.861 +                (const char *) sqlite3_column_text(session->get_identities_by_address, 1),
   1.862 +                (const char *) sqlite3_column_text(session->get_identities_by_address, 0),
   1.863 +                (const char *) sqlite3_column_text(session->get_identities_by_address, 2)
   1.864 +                );
   1.865 +        assert(ident);
   1.866 +        if (ident == NULL)
   1.867 +            return PEP_OUT_OF_MEMORY;
   1.868 +
   1.869 +        ident->comm_type = PEP_ct_unknown;
   1.870 +        
   1.871 +        const char* const _lang = (const char *)
   1.872 +            sqlite3_column_text(session->get_identities_by_address, 3);
   1.873 +        if (_lang && _lang[0]) {
   1.874 +            assert(_lang[0] >= 'a' && _lang[0] <= 'z');
   1.875 +            assert(_lang[1] >= 'a' && _lang[1] <= 'z');
   1.876 +            assert(_lang[2] == 0);
   1.877 +            ident->lang[0] = _lang[0];
   1.878 +            ident->lang[1] = _lang[1];
   1.879 +            ident->lang[2] = 0;
   1.880 +        }
   1.881 +        ident->flags = (unsigned int)
   1.882 +            sqlite3_column_int(session->get_identities_by_address, 4);
   1.883 +        ident->me = (unsigned int)
   1.884 +            sqlite3_column_int(session->get_identities_by_address, 5);
   1.885 +    
   1.886 +        if (ident_list)
   1.887 +            identity_list_add(ident_list, ident);
   1.888 +        else
   1.889 +            ident_list = new_identity_list(ident);
   1.890 +    }
   1.891 +
   1.892 +    sqlite3_reset(session->get_identities_by_address);
   1.893 +    
   1.894 +    *id_list = ident_list;
   1.895 +    
   1.896 +    if (!ident_list)
   1.897 +        return PEP_CANNOT_FIND_IDENTITY;
   1.898 +    
   1.899 +    return PEP_STATUS_OK;
   1.900 +}
   1.901 +
   1.902 +
   1.903  DYNAMIC_API PEP_STATUS set_identity(
   1.904          PEP_SESSION session, const pEp_identity *identity
   1.905      )
   1.906 @@ -1283,7 +1826,7 @@
   1.907      bool has_fpr = (identity->fpr && identity->fpr[0] != '\0');
   1.908      
   1.909      if (has_fpr) {    
   1.910 -        // blacklist check
   1.911 +        // blacklist check - FIXME: ENGINE-294 will remove
   1.912          status = blacklist_is_listed(session, identity->fpr, &listed);
   1.913          assert(status == PEP_STATUS_OK);
   1.914          if (status != PEP_STATUS_OK)
   1.915 @@ -1340,6 +1883,7 @@
   1.916      sqlite3_bind_text(session->set_identity, 3, identity->user_id, -1,
   1.917              SQLITE_STATIC);
   1.918      sqlite3_bind_int(session->set_identity, 4, identity->flags);
   1.919 +    sqlite3_bind_int(session->set_identity, 5, identity->me);
   1.920      result = sqlite3_step(session->set_identity);
   1.921      sqlite3_reset(session->set_identity);
   1.922      if (result != SQLITE_DONE) {
   1.923 @@ -1348,22 +1892,6 @@
   1.924      }
   1.925  
   1.926      if (has_fpr) {
   1.927 -        if(strcmp(identity->user_id, PEP_OWN_USERID) == 0) {
   1.928 -            sqlite3_reset(session->set_own_key);
   1.929 -            sqlite3_bind_text(session->set_own_key, 1, identity->address, -1,
   1.930 -                SQLITE_STATIC);
   1.931 -            sqlite3_bind_text(session->set_own_key, 2, identity->fpr, -1,
   1.932 -                SQLITE_STATIC);
   1.933 -            result = sqlite3_step(session->set_own_key);
   1.934 -            sqlite3_reset(session->set_own_key);
   1.935 -            if (result != SQLITE_DONE) {
   1.936 -                sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
   1.937 -                return PEP_CANNOT_SET_PGP_KEYPAIR;
   1.938 -            }
   1.939 -        }
   1.940 -
   1.941 -        // status = set_trust(session, identity->user_id, identity->fpr,
   1.942 -        //                    identity->comm_type)
   1.943          sqlite3_reset(session->set_trust);
   1.944          sqlite3_bind_text(session->set_trust, 1, identity->user_id, -1,
   1.945                  SQLITE_STATIC);
   1.946 @@ -1385,6 +1913,28 @@
   1.947          return PEP_COMMIT_FAILED;
   1.948  }
   1.949  
   1.950 +PEP_STATUS remove_fpr_as_default(PEP_SESSION session, 
   1.951 +                                 const char* fpr) 
   1.952 +{
   1.953 +    assert(fpr);
   1.954 +    
   1.955 +    if (!session || !fpr)
   1.956 +        return PEP_ILLEGAL_VALUE;
   1.957 +            
   1.958 +    sqlite3_reset(session->remove_fpr_as_default);
   1.959 +    sqlite3_bind_text(session->remove_fpr_as_default, 1, fpr, -1,
   1.960 +                      SQLITE_STATIC);
   1.961 +
   1.962 +    int result = sqlite3_step(session->remove_fpr_as_default);
   1.963 +    sqlite3_reset(session->remove_fpr_as_default);
   1.964 +    
   1.965 +    if (result != SQLITE_DONE)
   1.966 +        return PEP_CANNOT_SET_IDENTITY; // misleading - could also be person
   1.967 +
   1.968 +    return PEP_STATUS_OK;
   1.969 +}
   1.970 +
   1.971 +
   1.972  PEP_STATUS replace_identities_fpr(PEP_SESSION session, 
   1.973                                   const char* old_fpr, 
   1.974                                   const char* new_fpr) 
   1.975 @@ -1410,7 +1960,6 @@
   1.976      return PEP_STATUS_OK;
   1.977  }
   1.978  
   1.979 -
   1.980  PEP_STATUS update_trust_for_fpr(PEP_SESSION session, 
   1.981                                  const char* fpr, 
   1.982                                  PEP_comm_type comm_type)
   1.983 @@ -1443,6 +1992,15 @@
   1.984      if (!(session && group_name))
   1.985          return PEP_ILLEGAL_VALUE;
   1.986  
   1.987 +    // 1. Get own user_id
   1.988 +    char* user_id = NULL;
   1.989 +    PEP_STATUS status = get_default_own_userid(session, &user_id);
   1.990 +    
   1.991 +    // No user_id is returned in this case, no need to free;
   1.992 +    if (status != PEP_STATUS_OK)
   1.993 +        return status;
   1.994 +        
   1.995 +    // 2. Set device group
   1.996      sqlite3_reset(session->set_device_group);
   1.997      if(group_name){
   1.998          sqlite3_bind_text(session->set_device_group, 1, group_name, -1,
   1.999 @@ -1450,9 +2008,15 @@
  1.1000      } else {
  1.1001          sqlite3_bind_null(session->set_device_group, 1);
  1.1002      }
  1.1003 +    
  1.1004 +    sqlite3_bind_text(session->set_device_group, 2, user_id, -1,
  1.1005 +            SQLITE_STATIC);
  1.1006  
  1.1007      result = sqlite3_step(session->set_device_group);
  1.1008      sqlite3_reset(session->set_device_group);
  1.1009 +    
  1.1010 +    free(user_id);
  1.1011 +    
  1.1012      if (result != SQLITE_DONE)
  1.1013          return PEP_CANNOT_SET_PERSON;
  1.1014  
  1.1015 @@ -1470,7 +2034,18 @@
  1.1016      if (!(session && group_name))
  1.1017          return PEP_ILLEGAL_VALUE;
  1.1018  
  1.1019 +    // 1. Get own user_id
  1.1020 +    char* user_id = NULL;
  1.1021 +    status = get_default_own_userid(session, &user_id);
  1.1022 +    
  1.1023 +    // No user_id is returned in this case, no need to free;
  1.1024 +    if (status != PEP_STATUS_OK)
  1.1025 +        return status;
  1.1026 +
  1.1027 +    // 2. get device group
  1.1028      sqlite3_reset(session->get_device_group);
  1.1029 +    sqlite3_bind_text(session->get_device_group, 1, user_id, -1,
  1.1030 +            SQLITE_STATIC);
  1.1031  
  1.1032      result = sqlite3_step(session->get_device_group);
  1.1033      switch (result) {
  1.1034 @@ -1488,6 +2063,7 @@
  1.1035          status = PEP_RECORD_NOT_FOUND;
  1.1036      }
  1.1037  
  1.1038 +    free(user_id);
  1.1039      sqlite3_reset(session->get_device_group);
  1.1040      return status;
  1.1041  }
  1.1042 @@ -1513,8 +2089,10 @@
  1.1043      sqlite3_bind_text(session->set_identity_flags, 2, identity->address, -1,
  1.1044              SQLITE_STATIC);
  1.1045      sqlite3_bind_text(session->set_identity_flags, 3, identity->user_id, -1,
  1.1046 -            SQLITE_STATIC);
  1.1047 +        SQLITE_STATIC);
  1.1048 +        
  1.1049      result = sqlite3_step(session->set_identity_flags);
  1.1050 +
  1.1051      sqlite3_reset(session->set_identity_flags);
  1.1052      if (result != SQLITE_DONE)
  1.1053          return PEP_CANNOT_SET_IDENTITY;
  1.1054 @@ -1549,11 +2127,120 @@
  1.1055      sqlite3_reset(session->unset_identity_flags);
  1.1056      if (result != SQLITE_DONE)
  1.1057          return PEP_CANNOT_SET_IDENTITY;
  1.1058 -
  1.1059 -    identity->flags &= ~flags;
  1.1060 +        identity->flags &= ~flags;
  1.1061 +
  1.1062      return PEP_STATUS_OK;
  1.1063  }
  1.1064  
  1.1065 +
  1.1066 +PEP_STATUS replace_userid(PEP_SESSION session, const char* old_uid,
  1.1067 +                              const char* new_uid) {
  1.1068 +    assert(session);
  1.1069 +    assert(old_uid);
  1.1070 +    assert(new_uid);
  1.1071 +    
  1.1072 +    if (!session || !old_uid || !new_uid)
  1.1073 +        return PEP_ILLEGAL_VALUE;
  1.1074 +
  1.1075 +
  1.1076 +    int result;
  1.1077 +
  1.1078 +    sqlite3_reset(session->replace_userid);
  1.1079 +    sqlite3_bind_text(session->replace_userid, 1, new_uid, -1,
  1.1080 +            SQLITE_STATIC);
  1.1081 +    sqlite3_bind_text(session->replace_userid, 2, old_uid, -1,
  1.1082 +            SQLITE_STATIC);
  1.1083 +    result = sqlite3_step(session->replace_userid);
  1.1084 +    sqlite3_reset(session->replace_userid);
  1.1085 +    if (result != SQLITE_DONE)
  1.1086 +        return PEP_CANNOT_SET_PERSON; // May need clearer retval
  1.1087 +
  1.1088 +    return PEP_STATUS_OK;
  1.1089 +}
  1.1090 +
  1.1091 +PEP_STATUS refresh_userid_default_key(PEP_SESSION session, const char* user_id) {
  1.1092 +    assert(session);
  1.1093 +    assert(user_id);
  1.1094 +    
  1.1095 +    if (!session || !user_id)
  1.1096 +        return PEP_ILLEGAL_VALUE;
  1.1097 +
  1.1098 +    int result;
  1.1099 +
  1.1100 +    sqlite3_reset(session->refresh_userid_default_key);
  1.1101 +    sqlite3_bind_text(session->refresh_userid_default_key, 1, user_id, -1,
  1.1102 +            SQLITE_STATIC);
  1.1103 +    result = sqlite3_step(session->refresh_userid_default_key);
  1.1104 +    sqlite3_reset(session->refresh_userid_default_key);
  1.1105 +    if (result != SQLITE_DONE)
  1.1106 +        return PEP_CANNOT_SET_PERSON;
  1.1107 +
  1.1108 +    return PEP_STATUS_OK;    
  1.1109 +}
  1.1110 +
  1.1111 +PEP_STATUS replace_main_user_fpr(PEP_SESSION session, const char* user_id,
  1.1112 +                                 const char* new_fpr) {
  1.1113 +    assert(session);
  1.1114 +    assert(user_id);
  1.1115 +    assert(new_fpr);
  1.1116 +    
  1.1117 +    if (!session || !user_id || !new_fpr)
  1.1118 +        return PEP_ILLEGAL_VALUE;
  1.1119 +
  1.1120 +    int result;
  1.1121 +
  1.1122 +    sqlite3_reset(session->replace_main_user_fpr);
  1.1123 +    sqlite3_bind_text(session->replace_main_user_fpr, 1, new_fpr, -1,
  1.1124 +            SQLITE_STATIC);
  1.1125 +    sqlite3_bind_text(session->replace_main_user_fpr, 2, user_id, -1,
  1.1126 +            SQLITE_STATIC);
  1.1127 +    result = sqlite3_step(session->replace_main_user_fpr);
  1.1128 +    sqlite3_reset(session->replace_main_user_fpr);
  1.1129 +    if (result != SQLITE_DONE)
  1.1130 +        return PEP_CANNOT_SET_PERSON;
  1.1131 +
  1.1132 +    return PEP_STATUS_OK;
  1.1133 +}
  1.1134 +
  1.1135 +PEP_STATUS get_main_user_fpr(PEP_SESSION session, 
  1.1136 +                             const char* user_id,
  1.1137 +                             char** main_fpr)
  1.1138 +{
  1.1139 +    PEP_STATUS status = PEP_STATUS_OK;
  1.1140 +    int result;
  1.1141 +    
  1.1142 +    assert(session);
  1.1143 +    assert(user_id);
  1.1144 +    assert(main_fpr);
  1.1145 +    
  1.1146 +    if (!(session && user_id && user_id[0] && main_fpr))
  1.1147 +        return PEP_ILLEGAL_VALUE;
  1.1148 +        
  1.1149 +    *main_fpr = NULL;
  1.1150 +    
  1.1151 +    sqlite3_reset(session->get_main_user_fpr);
  1.1152 +    sqlite3_bind_text(session->get_main_user_fpr, 1, user_id, -1,
  1.1153 +                      SQLITE_STATIC);
  1.1154 +    result = sqlite3_step(session->get_main_user_fpr);
  1.1155 +    switch (result) {
  1.1156 +    case SQLITE_ROW: {
  1.1157 +        const char* _fpr = 
  1.1158 +            (const char *) sqlite3_column_text(session->get_main_user_fpr, 0);
  1.1159 +        if (_fpr)
  1.1160 +            *main_fpr = strdup(_fpr);
  1.1161 +        if (!(*main_fpr))
  1.1162 +            status = PEP_OUT_OF_MEMORY;
  1.1163 +        break;
  1.1164 +    }
  1.1165 +    default:
  1.1166 +        status = PEP_CANNOT_FIND_PERSON;
  1.1167 +    }
  1.1168 +
  1.1169 +    sqlite3_reset(session->get_main_user_fpr);
  1.1170 +    return status;
  1.1171 +}
  1.1172 +
  1.1173 +
  1.1174  DYNAMIC_API PEP_STATUS mark_as_compromized(
  1.1175          PEP_SESSION session,
  1.1176          const char *fpr
  1.1177 @@ -1584,17 +2271,49 @@
  1.1178      free(p);
  1.1179  }
  1.1180  
  1.1181 +PEP_STATUS set_trust(PEP_SESSION session, 
  1.1182 +                     const char* user_id,
  1.1183 +                     const char* fpr, 
  1.1184 +                     PEP_comm_type comm_type) 
  1.1185 +{
  1.1186 +    assert(session);
  1.1187 +    assert(user_id);
  1.1188 +    assert(fpr);
  1.1189 +    
  1.1190 +    if (!session || !user_id || user_id[0] == '\0' || !fpr || fpr[0] == '\0')
  1.1191 +        return PEP_ILLEGAL_VALUE;
  1.1192 +        
  1.1193 +    int result;
  1.1194 +                
  1.1195 +    sqlite3_reset(session->set_trust);
  1.1196 +    sqlite3_bind_text(session->set_trust, 1, user_id, -1,
  1.1197 +            SQLITE_STATIC);
  1.1198 +    sqlite3_bind_text(session->set_trust, 2, fpr, -1,
  1.1199 +            SQLITE_STATIC);
  1.1200 +    sqlite3_bind_int(session->set_trust, 3, comm_type);
  1.1201 +    result = sqlite3_step(session->set_trust);
  1.1202 +    assert(result == SQLITE_DONE);
  1.1203 +    sqlite3_reset(session->set_trust);
  1.1204 +    if (result != SQLITE_DONE)
  1.1205 +        return PEP_CANNOT_SET_TRUST;
  1.1206 +
  1.1207 +    return PEP_STATUS_OK;
  1.1208 +}
  1.1209 +
  1.1210 +
  1.1211  DYNAMIC_API PEP_STATUS get_trust(PEP_SESSION session, pEp_identity *identity)
  1.1212  {
  1.1213      PEP_STATUS status = PEP_STATUS_OK;
  1.1214      int result;
  1.1215  
  1.1216 -    assert(session);
  1.1217 -    assert(identity);
  1.1218 -    assert(identity->user_id);
  1.1219 -    assert(identity->user_id[0]);
  1.1220 -    assert(identity->fpr);
  1.1221 -    assert(identity->fpr[0]);
  1.1222 +    // We need to be able to test that we break correctly without shutting
  1.1223 +    // asserts off everywhere.
  1.1224 +    // assert(session);
  1.1225 +    // assert(identity);
  1.1226 +    // assert(identity->user_id);
  1.1227 +    // assert(identity->user_id[0]);
  1.1228 +    // assert(identity->fpr);
  1.1229 +    // assert(identity->fpr[0]);
  1.1230  
  1.1231      if (!(session && identity && identity->user_id && identity->user_id[0] &&
  1.1232                  identity->fpr && identity->fpr[0]))