Merged in ENGINE-250 - foreign keys are now on, as they should have been forever.
authorKrista Bennett <krista@pep-project.org>
Wed, 07 Feb 2018 16:46:21 +0100
changeset 248493b9a267675f
parent 2476 5a4da2a7f99b
parent 2483 7fb3205f2893
child 2486 7534aeca7061
Merged in ENGINE-250 - foreign keys are now on, as they should have been forever.
     1.1 --- a/src/blacklist.c	Sun Feb 04 15:26:28 2018 +0100
     1.2 +++ b/src/blacklist.c	Wed Feb 07 16:46:21 2018 +0100
     1.3 @@ -13,6 +13,8 @@
     1.4      if (!(session && fpr && fpr[0]))
     1.5          return PEP_ILLEGAL_VALUE;
     1.6  
     1.7 +    sqlite3_exec(session->db, "BEGIN ;", NULL, NULL, NULL);
     1.8 +
     1.9      sqlite3_reset(session->blacklist_add);
    1.10  	sqlite3_bind_text(session->blacklist_add, 1, fpr, -1, SQLITE_STATIC);
    1.11  
    1.12 @@ -22,9 +24,11 @@
    1.13      switch (result) {
    1.14      case SQLITE_DONE:
    1.15          status = PEP_STATUS_OK;
    1.16 +        sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
    1.17          break;
    1.18  
    1.19      default:
    1.20 +        sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
    1.21          status = PEP_UNKNOWN_ERROR;
    1.22      }
    1.23  
    1.24 @@ -157,4 +161,3 @@
    1.25  the_end:
    1.26      return status;
    1.27  }
    1.28 -
     2.1 --- a/src/keymanagement.c	Sun Feb 04 15:26:28 2018 +0100
     2.2 +++ b/src/keymanagement.c	Wed Feb 07 16:46:21 2018 +0100
     2.3 @@ -436,6 +436,9 @@
     2.4      
     2.5      transfer_ident_lang_and_flags(return_id, stored_ident);
     2.6      
     2.7 +    if (return_id->comm_type == PEP_ct_unknown)
     2.8 +        return_id->comm_type = PEP_ct_key_not_found;
     2.9 +    
    2.10      return status;
    2.11  }
    2.12  
    2.13 @@ -1067,7 +1070,16 @@
    2.14          // set mistrust for this user_id/keypair (even if there's not an
    2.15          // identity set yet, this is important, as we need to record the mistrust
    2.16          // action)
    2.17 -        status = set_trust(session, ident->user_id, ident->fpr, PEP_ct_mistrusted);
    2.18 +        
    2.19 +        // double-check to be sure key is even in the DB
    2.20 +        if (ident->fpr)
    2.21 +            status = set_pgp_keypair(session, ident->fpr);
    2.22 +
    2.23 +        // We set this temporarily but will grab it back from the cache afterwards
    2.24 +        ident->comm_type = PEP_ct_mistrusted;
    2.25 +        status = set_trust(session, ident);
    2.26 +        ident->comm_type = session->cached_mistrusted->comm_type;
    2.27 +        
    2.28          if (status == PEP_STATUS_OK)
    2.29              // cascade that mistrust for anyone using this key
    2.30              status = mark_as_compromized(session, ident->fpr);
    2.31 @@ -1137,7 +1149,9 @@
    2.32      if (input_copy->comm_type != PEP_ct_mistrusted)
    2.33          new_trust = input_copy->comm_type & ~PEP_ct_confirmed;
    2.34  
    2.35 -    status = set_trust(session, ident->user_id, ident->fpr, new_trust);
    2.36 +    // We'll return the status from the input_copy cache afterward
    2.37 +    input_copy->comm_type = new_trust;
    2.38 +    status = set_trust(session, input_copy);
    2.39      
    2.40      if (status != PEP_STATUS_OK)
    2.41          goto pep_free;
    2.42 @@ -1154,8 +1168,6 @@
    2.43  
    2.44      if (status != PEP_STATUS_OK)
    2.45          goto pep_free;
    2.46 -    
    2.47 -    input_copy->comm_type = new_trust;
    2.48          
    2.49      tmp_ident = new_identity(ident->address, NULL, ident->user_id, NULL);
    2.50  
    2.51 @@ -1219,6 +1231,10 @@
    2.52      if (input_default_ct < PEP_ct_strong_but_unconfirmed)
    2.53          return PEP_KEY_UNSUITABLE;
    2.54  
    2.55 +    status = set_pgp_keypair(session, ident->fpr);
    2.56 +    if (status != PEP_STATUS_OK)
    2.57 +        return status;
    2.58 +        
    2.59      // Save the input fpr
    2.60      char* cached_fpr = strdup(ident->fpr);
    2.61      ident->fpr = NULL;
    2.62 @@ -1256,7 +1272,7 @@
    2.63  
    2.64                      trusted_default = true;
    2.65                                      
    2.66 -                    status = set_trust(session, tmp_id->user_id, cached_fpr, tmp_id->comm_type);
    2.67 +                    status = set_trust(session, tmp_id);
    2.68                      input_default_ct = tmp_id->comm_type;                    
    2.69                  }
    2.70                  else {
     3.1 --- a/src/message_api.c	Sun Feb 04 15:26:28 2018 +0100
     3.2 +++ b/src/message_api.c	Wed Feb 07 16:46:21 2018 +0100
     3.3 @@ -1532,7 +1532,7 @@
     3.4          else
     3.5              _status = myself(session, _il->ident);
     3.6          if (_status != PEP_STATUS_OK) {
     3.7 -            status = _status;
     3.8 +            status = PEP_UNENCRYPTED;
     3.9              GOTO(pep_error);
    3.10          }
    3.11  
    3.12 @@ -1564,7 +1564,7 @@
    3.13              else
    3.14                  _status = myself(session, _il->ident);
    3.15              if (_status != PEP_STATUS_OK) {
    3.16 -                status = _status;
    3.17 +                status = PEP_UNENCRYPTED;
    3.18                  GOTO(pep_error);
    3.19              }
    3.20  
    3.21 @@ -1596,7 +1596,7 @@
    3.22                  _status = myself(session, _il->ident);
    3.23              if (_status != PEP_STATUS_OK)
    3.24              {
    3.25 -                status = _status;
    3.26 +                status = PEP_UNENCRYPTED;
    3.27                  GOTO(pep_error);
    3.28              }
    3.29  
    3.30 @@ -1609,7 +1609,6 @@
    3.31              }
    3.32              else {
    3.33                  dest_keys_found = false;
    3.34 -                status = PEP_KEY_NOT_FOUND;
    3.35              }
    3.36          }
    3.37      }
    3.38 @@ -2479,12 +2478,12 @@
    3.39      // This file's code is difficult enough to parse. But change at will.
    3.40      switch (sender->comm_type) {
    3.41          case PEP_ct_OpenPGP_unconfirmed:
    3.42 -            status = set_trust(session, sender->user_id, sender->fpr, PEP_ct_pEp_unconfirmed);
    3.43 -            break;
    3.44          case PEP_ct_OpenPGP:
    3.45 -            status = set_trust(session, sender->user_id, sender->fpr, PEP_ct_pEp);
    3.46 +            sender->comm_type = PEP_ct_pEp_unconfirmed | (sender->comm_type & PEP_ct_confirmed);
    3.47 +            status = set_trust(session, sender);
    3.48              break;
    3.49          default:
    3.50 +            status = PEP_CANNOT_SET_TRUST;
    3.51              break;
    3.52      }
    3.53      
     4.1 --- a/src/message_api.h	Sun Feb 04 15:26:28 2018 +0100
     4.2 +++ b/src/message_api.h	Wed Feb 07 16:46:21 2018 +0100
     4.3 @@ -56,11 +56,8 @@
     4.4  //
     4.5  //  return value:
     4.6  //      PEP_STATUS_OK                   on success
     4.7 -//      PEP_KEY_NOT_FOUND               at least one of the receipient keys
     4.8 -//                                      could not be found
     4.9  //      PEP_KEY_HAS_AMBIG_NAME          at least one of the receipient keys has
    4.10  //                                      an ambiguous name
    4.11 -//      PEP_GET_KEY_FAILED              cannot retrieve key
    4.12  //      PEP_UNENCRYPTED                 on demand or no recipients with usable
    4.13  //                                      key, is left unencrypted, and key is
    4.14  //                                      attached to it
     5.1 --- a/src/pEpEngine.c	Sun Feb 04 15:26:28 2018 +0100
     5.2 +++ b/src/pEpEngine.c	Wed Feb 07 16:46:21 2018 +0100
     5.3 @@ -9,6 +9,9 @@
     5.4  
     5.5  #include <time.h>
     5.6  #include <stdlib.h>
     5.7 +#include <sqlite3.h>
     5.8 +
     5.9 +#define _PEP_SQLITE_DEBUG 0
    5.10  
    5.11  static volatile int init_count = -1;
    5.12  
    5.13 @@ -37,6 +40,33 @@
    5.14      }
    5.15  }
    5.16  
    5.17 +#if _PEP_SQLITE_DEBUG
    5.18 +int sql_trace_callback (unsigned trace_constant, 
    5.19 +                        void* context_ptr,
    5.20 +                        void* P,
    5.21 +                        void* X) {
    5.22 +    switch (trace_constant) {
    5.23 +        case SQLITE_TRACE_STMT:
    5.24 +            fprintf(stderr, "SQL_DEBUG: STMT - ");
    5.25 +            const char* X_str = (const char*) X;
    5.26 +            if (!EMPTYSTR(X_str) && X_str[0] == '-' && X_str[1] == '-')
    5.27 +                fprintf(stderr, "%s\n", X_str);
    5.28 +            else
    5.29 +                fprintf(stderr, "%s\n", sqlite3_expanded_sql((sqlite3_stmt*)P));
    5.30 +            break;
    5.31 +        case SQLITE_TRACE_ROW:
    5.32 +            fprintf(stderr, "SQL_DEBUG: ROW - ");
    5.33 +            fprintf(stderr, "%s\n", sqlite3_expanded_sql((sqlite3_stmt*)P));
    5.34 +            break;            
    5.35 +        case SQLITE_TRACE_CLOSE:
    5.36 +            fprintf(stderr, "SQL_DEBUG: CLOSE - ");
    5.37 +            break;
    5.38 +        default:
    5.39 +            break;
    5.40 +    }
    5.41 +    return 0;
    5.42 +}
    5.43 +#endif
    5.44  
    5.45  // sql manipulation statements
    5.46  static const char *sql_log = 
    5.47 @@ -98,12 +128,26 @@
    5.48  // Set person, but if already exist, only update.
    5.49  // if main_key_id already set, don't touch.
    5.50  static const char *sql_set_person = 
    5.51 -    "insert or replace into person (id, username, lang, main_key_id, device_group)"
    5.52 -    "  values (?1, ?2, ?3,"
    5.53 -    "    (select coalesce((select main_key_id from person "
    5.54 -    "      where id = ?1), upper(replace(?4,' ','')))),"
    5.55 -    "    (select device_group from person where id = ?1)) ;";
    5.56 -
    5.57 +     "insert into person (id, username, lang, main_key_id, device_group)"
    5.58 +     "  values (?1, ?2, ?3,"
    5.59 +//     "    (select coalesce( "
    5.60 +//     "          (select main_key_id from person where id = ?1), " 
    5.61 +//     "           upper(replace(?4,' ','')))),"
    5.62 +    "   ?4,"
    5.63 +     "    (select device_group from person where id = ?1)) ;";
    5.64 +
    5.65 +static const char *sql_update_person = 
    5.66 +    "update person "
    5.67 +    "   set username = ?2, "
    5.68 +    "       lang = ?3, "
    5.69 +    "       main_key_id =  "
    5.70 +    "           (select coalesce( "
    5.71 +    "               (select main_key_id from person where id = ?1), " 
    5.72 +    "                upper(replace(?4,' ','')))),"         
    5.73 +    "       device_group = "
    5.74 +    "           (select device_group from person where id = ?1)"
    5.75 +    "   where id = ?1 ;";
    5.76 +    
    5.77  static const char *sql_set_as_pep_user =
    5.78      "update person set is_pep_user = 1 "
    5.79      "   where id = ?1 ; ";
    5.80 @@ -151,17 +195,42 @@
    5.81      "where id = ?1;";
    5.82  
    5.83  static const char *sql_set_pgp_keypair = 
    5.84 -    "insert or replace into pgp_keypair (fpr) "
    5.85 +    "insert or ignore into pgp_keypair (fpr) "
    5.86      "values (upper(replace(?1,' ',''))) ;";
    5.87  
    5.88 -static const char *sql_set_identity = 
    5.89 -    "insert or replace into identity ("
    5.90 -    " address, main_key_id, "
    5.91 -    " user_id, flags, is_own"
    5.92 -    ") values ("
    5.93 -    " ?1,"
    5.94 -    " upper(replace(?2,' ','')),"
    5.95 -    " ?3,"
    5.96 +static const char* sql_exists_identity_entry = 
    5.97 +    "select count(*) from identity "
    5.98 +    "   where (case when (address = ?1) then (1)"
    5.99 +    "               when (lower(address) = lower(?1)) then (1)"
   5.100 +    "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
   5.101 +    "               else 0"
   5.102 +    "          end) = 1"
   5.103 +    "    and user_id = ?2;";
   5.104 + 
   5.105 +static const char *sql_set_identity_entry = 
   5.106 +    "insert into identity ("
   5.107 +    "       address, main_key_id, "
   5.108 +    "       user_id, flags, is_own"
   5.109 +    "   ) values ("
   5.110 +    "       ?1,"
   5.111 +    "       upper(replace(?2,' ','')),"
   5.112 +    "       ?3,"
   5.113 +    "       ?4,"
   5.114 +    "       ?5"
   5.115 +    "   );";
   5.116 +    
   5.117 +static const char* sql_update_identity_entry =    
   5.118 +    "update identity "
   5.119 +    "   set main_key_id = upper(replace(?2,' ','')), "
   5.120 +    "       flags = ?4, " 
   5.121 +    "       is_own = ?5 "
   5.122 +    "   where (case when (address = ?1) then (1)"
   5.123 +    "               when (lower(address) = lower(?1)) then (1)"
   5.124 +    "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1) "
   5.125 +    "               else 0 "
   5.126 +    "          end) = 1 "
   5.127 +    "          and user_id = ?3 ;";
   5.128 +
   5.129      // " (select"
   5.130      // "   coalesce("
   5.131      // "    (select flags from identity"
   5.132 @@ -170,26 +239,51 @@
   5.133      // "    0)"
   5.134      // " ) | (?4 & 255)"
   5.135      /* set_identity ignores previous flags, and doesn't filter machine flags */
   5.136 -    " ?4,"
   5.137 -    " ?5"
   5.138 -    ");";
   5.139          
   5.140  static const char *sql_set_identity_flags = 
   5.141      "update identity set flags = "
   5.142      "    ((?1 & 255) | (select flags from identity"
   5.143 -    "                   where address = ?2 and user_id = ?3)) "
   5.144 -    "where address = ?2 and user_id = ?3 ;";
   5.145 +    "                    where (case when (address = ?2) then (1)"
   5.146 +    "                                when (lower(address) = lower(?2)) then (1)"
   5.147 +    "                                when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   5.148 +    "                                else 0 "    
   5.149 +    "                           end) = 1 "
   5.150 +    "                           and user_id = ?3)) "
   5.151 +    "   where (case when (address = ?2) then (1)"
   5.152 +    "               when (lower(address) = lower(?2)) then (1)"
   5.153 +    "               when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   5.154 +    "               else 0"
   5.155 +    "          end) = 1"
   5.156 +    "          and user_id = ?3 ;";
   5.157  
   5.158  static const char *sql_unset_identity_flags = 
   5.159      "update identity set flags = "
   5.160      "    ( ~(?1 & 255) & (select flags from identity"
   5.161 -    "                   where address = ?2 and user_id = ?3)) "
   5.162 -    "where address = ?2 and user_id = ?3 ;";
   5.163 +    "                    where (case when (address = ?2) then (1)"
   5.164 +    "                                when (lower(address) = lower(?2)) then (1)"
   5.165 +    "                                when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   5.166 +    "                                else 0 "    
   5.167 +    "                           end) = 1 "
   5.168 +    "                           and user_id = ?3)) "
   5.169 +    "   where (case when (address = ?2) then (1)"
   5.170 +    "               when (lower(address) = lower(?2)) then (1)"
   5.171 +    "               when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   5.172 +    "               else 0"
   5.173 +    "          end) = 1"
   5.174 +    "          and user_id = ?3 ;";
   5.175  
   5.176  static const char *sql_set_trust =
   5.177 -    "insert or replace into trust (user_id, pgp_keypair_fpr, comm_type) "
   5.178 +    "insert into trust (user_id, pgp_keypair_fpr, comm_type) "
   5.179      "values (?1, upper(replace(?2,' ','')), ?3) ;";
   5.180  
   5.181 +static const char *sql_update_trust =
   5.182 +    "update trust set comm_type = ?3 " 
   5.183 +    "   where user_id = ?1 and pgp_keypair_fpr = upper(replace(?2,' ',''));";
   5.184 +
   5.185 +static const char* sql_exists_trust_entry = 
   5.186 +    "select count(*) from trust "
   5.187 +    "   where user_id = ?1 and pgp_keypair_fpr = upper(replace(?2,' ',''));";
   5.188 +    
   5.189  static const char *sql_update_trust_for_fpr =
   5.190      "update trust "
   5.191      "set comm_type = ?1 "
   5.192 @@ -222,7 +316,7 @@
   5.193  
   5.194  // blacklist
   5.195  static const char *sql_blacklist_add = 
   5.196 -    "insert or replace into blacklist_keys (fpr) values (upper(replace(?1,' ',''))) ;"
   5.197 +    "insert or ignore into blacklist_keys (fpr) values (upper(replace(?1,' ',''))) ;"
   5.198      "delete from identity where main_key_id = upper(replace(?1,' ','')) ;"
   5.199      "delete from pgp_keypair where fpr = upper(replace(?1,' ','')) ;";
   5.200  
   5.201 @@ -318,8 +412,8 @@
   5.202      "select count(*) from mistrusted_keys where fpr = upper(replace(?1,' ','')) ;";
   5.203  
   5.204  static const char *sql_add_userid_alias =
   5.205 -    "insert or replace into alternate_user_id (default_id, alternate_id) "
   5.206 -    "values (?1, ?2) ;";
   5.207 +    "insert or replace into alternate_user_id (alternate_id, default_id) "
   5.208 +    "values (?2, ?1) ;";
   5.209      
   5.210  static int user_version(void *_version, int count, char **text, char **name)
   5.211  {
   5.212 @@ -384,6 +478,10 @@
   5.213      return retval;
   5.214  }
   5.215  
   5.216 +void errorLogCallback(void *pArg, int iErrCode, const char *zMsg){
   5.217 +  fprintf(stderr, "(%d) %s\n", iErrCode, zMsg);
   5.218 +}
   5.219 +
   5.220  DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
   5.221  {
   5.222      PEP_STATUS status = PEP_STATUS_OK;
   5.223 @@ -441,6 +539,10 @@
   5.224          status = PEP_INIT_CANNOT_OPEN_DB;
   5.225          goto pep_error;
   5.226      }
   5.227 +    
   5.228 +#if _PEP_SQLITE_DEBUG    
   5.229 +    sqlite3_config(SQLITE_CONFIG_LOG, errorLogCallback, NULL);
   5.230 +#endif
   5.231  
   5.232      int_result = sqlite3_open_v2(
   5.233              LOCAL_DB,
   5.234 @@ -469,6 +571,13 @@
   5.235  
   5.236      sqlite3_busy_timeout(_session->db, BUSY_WAIT_TIME);
   5.237  
   5.238 +#if _PEP_SQLITE_DEBUG
   5.239 +    sqlite3_trace_v2(_session->db, 
   5.240 +        SQLITE_TRACE_STMT | SQLITE_TRACE_ROW | SQLITE_TRACE_CLOSE,
   5.241 +        sql_trace_callback,
   5.242 +        NULL);
   5.243 +#endif
   5.244 +
   5.245      assert(SYSTEM_DB);
   5.246      if (SYSTEM_DB == NULL) {
   5.247          status = PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
   5.248 @@ -623,6 +732,17 @@
   5.249              NULL,
   5.250              NULL);
   5.251          assert(int_result == SQLITE_OK);
   5.252 +
   5.253 +        int_result = sqlite3_exec(
   5.254 +            _session->db,
   5.255 +            "pragma foreign_keys=ON;\n",
   5.256 +            NULL,
   5.257 +            NULL,
   5.258 +            NULL
   5.259 +        );
   5.260 +
   5.261 +        assert(int_result == SQLITE_OK);
   5.262 +
   5.263          
   5.264          // Sometimes the user_version wasn't set correctly. Check to see if this
   5.265          // is really necessary...
   5.266 @@ -939,6 +1059,14 @@
   5.267              (int)strlen(sql_set_person), &_session->set_person, NULL);
   5.268      assert(int_result == SQLITE_OK);
   5.269  
   5.270 +    int_result = sqlite3_prepare_v2(_session->db, sql_update_person,
   5.271 +            (int)strlen(sql_update_person), &_session->update_person, NULL);
   5.272 +    assert(int_result == SQLITE_OK);
   5.273 +
   5.274 +    int_result = sqlite3_prepare_v2(_session->db, sql_exists_person,
   5.275 +            (int)strlen(sql_exists_person), &_session->exists_person, NULL);
   5.276 +    assert(int_result == SQLITE_OK);
   5.277 +
   5.278      int_result = sqlite3_prepare_v2(_session->db, sql_set_as_pep_user,
   5.279              (int)strlen(sql_set_as_pep_user), &_session->set_as_pep_user, NULL);
   5.280      assert(int_result == SQLITE_OK);
   5.281 @@ -947,10 +1075,6 @@
   5.282              (int)strlen(sql_is_pep_user), &_session->is_pep_user, NULL);
   5.283      assert(int_result == SQLITE_OK);
   5.284  
   5.285 -    int_result = sqlite3_prepare_v2(_session->db, sql_exists_person,
   5.286 -            (int)strlen(sql_exists_person), &_session->exists_person, NULL);
   5.287 -    assert(int_result == SQLITE_OK);
   5.288 -
   5.289      int_result = sqlite3_prepare_v2(_session->db, sql_set_device_group,
   5.290              (int)strlen(sql_set_device_group), &_session->set_device_group, NULL);
   5.291      assert(int_result == SQLITE_OK);
   5.292 @@ -964,8 +1088,16 @@
   5.293              NULL);
   5.294      assert(int_result == SQLITE_OK);
   5.295  
   5.296 -    int_result = sqlite3_prepare_v2(_session->db, sql_set_identity,
   5.297 -            (int)strlen(sql_set_identity), &_session->set_identity, NULL);
   5.298 +    int_result = sqlite3_prepare_v2(_session->db, sql_set_identity_entry,
   5.299 +            (int)strlen(sql_set_identity_entry), &_session->set_identity_entry, NULL);
   5.300 +    assert(int_result == SQLITE_OK);
   5.301 +
   5.302 +    int_result = sqlite3_prepare_v2(_session->db, sql_update_identity_entry,
   5.303 +            (int)strlen(sql_update_identity_entry), &_session->update_identity_entry, NULL);
   5.304 +    assert(int_result == SQLITE_OK);
   5.305 +
   5.306 +    int_result = sqlite3_prepare_v2(_session->db, sql_exists_identity_entry,
   5.307 +            (int)strlen(sql_exists_identity_entry), &_session->exists_identity_entry, NULL);
   5.308      assert(int_result == SQLITE_OK);
   5.309  
   5.310      int_result = sqlite3_prepare_v2(_session->db, sql_set_identity_flags,
   5.311 @@ -982,6 +1114,14 @@
   5.312              (int)strlen(sql_set_trust), &_session->set_trust, NULL);
   5.313      assert(int_result == SQLITE_OK);
   5.314  
   5.315 +    int_result = sqlite3_prepare_v2(_session->db, sql_update_trust,
   5.316 +            (int)strlen(sql_update_trust), &_session->update_trust, NULL);
   5.317 +    assert(int_result == SQLITE_OK);
   5.318 +
   5.319 +    int_result = sqlite3_prepare_v2(_session->db, sql_exists_trust_entry,
   5.320 +                 (int)strlen(sql_exists_trust_entry), &_session->exists_trust_entry, NULL);
   5.321 +    assert(int_result == SQLITE_OK);
   5.322 +
   5.323      int_result = sqlite3_prepare_v2(_session->db, sql_update_trust_for_fpr,
   5.324              (int)strlen(sql_update_trust_for_fpr), &_session->update_trust_for_fpr, NULL);
   5.325      assert(int_result == SQLITE_OK);
   5.326 @@ -1121,7 +1261,7 @@
   5.327          // private keys have an 'unknown' trust designation in PGP).
   5.328  
   5.329          // We don't really worry about the status here.
   5.330 -        status = import_trusted_own_keys(_session);        
   5.331 +//        status = import_trusted_own_keys(_session);        
   5.332      }
   5.333  
   5.334      // sync_session set to own session by default
   5.335 @@ -1201,14 +1341,22 @@
   5.336                  sqlite3_finalize(session->get_device_group);
   5.337              if (session->set_pgp_keypair)
   5.338                  sqlite3_finalize(session->set_pgp_keypair);
   5.339 -            if (session->set_identity)
   5.340 -                sqlite3_finalize(session->set_identity);
   5.341 +            if (session->exists_identity_entry)
   5.342 +                sqlite3_finalize(session->exists_identity_entry);                
   5.343 +            if (session->set_identity_entry)
   5.344 +                sqlite3_finalize(session->set_identity_entry);
   5.345 +            if (session->update_identity_entry)
   5.346 +                sqlite3_finalize(session->update_identity_entry);    
   5.347              if (session->set_identity_flags)
   5.348                  sqlite3_finalize(session->set_identity_flags);
   5.349              if (session->unset_identity_flags)
   5.350                  sqlite3_finalize(session->unset_identity_flags);
   5.351 +            if (session->exists_trust_entry)
   5.352 +                sqlite3_finalize(session->exists_trust_entry);                                
   5.353              if (session->set_trust)
   5.354                  sqlite3_finalize(session->set_trust);
   5.355 +            if (session->update_trust)
   5.356 +                sqlite3_finalize(session->update_trust);                
   5.357              if (session->update_trust_for_fpr)
   5.358                  sqlite3_finalize(session->update_trust_for_fpr);
   5.359              if (session->get_trust)
   5.360 @@ -1674,6 +1822,8 @@
   5.361      if (!(session && default_id && alias_id && 
   5.362            default_id[0] != '\0' && alias_id[0] != '\0'))
   5.363          return PEP_ILLEGAL_VALUE;
   5.364 +    
   5.365 +    sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
   5.366  
   5.367      sqlite3_reset(session->add_userid_alias);
   5.368      sqlite3_bind_text(session->add_userid_alias, 1, default_id, -1,
   5.369 @@ -1684,9 +1834,13 @@
   5.370      result = sqlite3_step(session->add_userid_alias);
   5.371  
   5.372      sqlite3_reset(session->add_userid_alias);
   5.373 -    if (result != SQLITE_DONE)
   5.374 +    if (result != SQLITE_DONE) {
   5.375 +        sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);        
   5.376          return PEP_CANNOT_SET_ALIAS;
   5.377 -    
   5.378 +    }
   5.379 +    sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
   5.380 +        
   5.381 +
   5.382      return PEP_STATUS_OK;
   5.383  }
   5.384  
   5.385 @@ -1888,6 +2042,238 @@
   5.386      return PEP_STATUS_OK;
   5.387  }
   5.388  
   5.389 +PEP_STATUS exists_identity_entry(PEP_SESSION session, pEp_identity* identity,
   5.390 +                                 bool* exists) {
   5.391 +    assert(session);
   5.392 +    assert(identity);
   5.393 +    assert(!EMPTYSTR(identity->user_id));        
   5.394 +    assert(!EMPTYSTR(identity->address));
   5.395 +    if (!session || !exists || EMPTYSTR(identity->user_id) || EMPTYSTR(identity->address))
   5.396 +        return PEP_ILLEGAL_VALUE;
   5.397 +    
   5.398 +    *exists = false;
   5.399 +    
   5.400 +    sqlite3_reset(session->exists_identity_entry);
   5.401 +    sqlite3_bind_text(session->exists_identity_entry, 1, identity->address, -1,
   5.402 +                      SQLITE_STATIC);
   5.403 +    sqlite3_bind_text(session->exists_identity_entry, 2, identity->user_id, -1,
   5.404 +                      SQLITE_STATIC);
   5.405 +                  
   5.406 +    int result = sqlite3_step(session->exists_identity_entry);
   5.407 +    switch (result) {
   5.408 +        case SQLITE_ROW: {
   5.409 +            // yeah yeah, I know, we could be lazy here, but it looks bad.
   5.410 +            *exists = (sqlite3_column_int(session->exists_identity_entry, 0) != 0);
   5.411 +            break;
   5.412 +        }
   5.413 +        default:
   5.414 +            return PEP_UNKNOWN_ERROR;
   5.415 +    }
   5.416 +
   5.417 +    return PEP_STATUS_OK;
   5.418 +}
   5.419 +
   5.420 +PEP_STATUS exists_trust_entry(PEP_SESSION session, pEp_identity* identity,
   5.421 +                              bool* exists) {
   5.422 +    assert(session);
   5.423 +    assert(identity);
   5.424 +    assert(!EMPTYSTR(identity->user_id));        
   5.425 +    assert(!EMPTYSTR(identity->fpr));
   5.426 +    if (!session || !exists || EMPTYSTR(identity->user_id) || EMPTYSTR(identity->fpr))
   5.427 +        return PEP_ILLEGAL_VALUE;
   5.428 +    
   5.429 +    *exists = false;
   5.430 +    
   5.431 +    sqlite3_reset(session->exists_trust_entry);
   5.432 +    sqlite3_bind_text(session->exists_trust_entry, 1, identity->user_id, -1,
   5.433 +                      SQLITE_STATIC);
   5.434 +    sqlite3_bind_text(session->exists_trust_entry, 2, identity->fpr, -1,
   5.435 +                      SQLITE_STATIC);
   5.436 +                  
   5.437 +    int result = sqlite3_step(session->exists_trust_entry);
   5.438 +    switch (result) {
   5.439 +        case SQLITE_ROW: {
   5.440 +            // yeah yeah, I know, we could be lazy here, but it looks bad.
   5.441 +            *exists = (sqlite3_column_int(session->exists_trust_entry, 0) != 0);
   5.442 +            break;
   5.443 +        }
   5.444 +        default:
   5.445 +            return PEP_UNKNOWN_ERROR;
   5.446 +    }
   5.447 +
   5.448 +    return PEP_STATUS_OK;
   5.449 +}
   5.450 +
   5.451 +// FIXME: We can rollback in set_identity on the return status,
   5.452 +// so we should probably do that.
   5.453 +PEP_STATUS set_pgp_keypair(PEP_SESSION session, const char* fpr) {
   5.454 +    if (!session || EMPTYSTR(fpr))
   5.455 +        return PEP_ILLEGAL_VALUE;
   5.456 +        
   5.457 +    int result;
   5.458 +    
   5.459 +    sqlite3_reset(session->set_pgp_keypair);
   5.460 +    sqlite3_bind_text(session->set_pgp_keypair, 1, fpr, -1,
   5.461 +            SQLITE_STATIC);
   5.462 +    result = sqlite3_step(session->set_pgp_keypair);
   5.463 +    sqlite3_reset(session->set_pgp_keypair);
   5.464 +    if (result != SQLITE_DONE) {
   5.465 +        return PEP_CANNOT_SET_PGP_KEYPAIR;
   5.466 +    }
   5.467 +    
   5.468 +    return PEP_STATUS_OK;
   5.469 +}
   5.470 +
   5.471 +static PEP_STATUS _set_or_update_trust(PEP_SESSION session,
   5.472 +                                       pEp_identity* identity,
   5.473 +                                       sqlite3_stmt* set_or_update) {
   5.474 +
   5.475 +    assert(session);
   5.476 +    assert(identity);
   5.477 +    assert(identity->user_id);
   5.478 +    assert(identity->fpr);
   5.479 +    
   5.480 +    if (!session || !identity || EMPTYSTR(identity->user_id) || EMPTYSTR(identity->fpr))
   5.481 +        return PEP_ILLEGAL_VALUE;
   5.482 +        
   5.483 +    int result;
   5.484 +                
   5.485 +    sqlite3_reset(set_or_update);
   5.486 +    sqlite3_bind_text(set_or_update, 1, identity->user_id, -1,
   5.487 +            SQLITE_STATIC);
   5.488 +    sqlite3_bind_text(set_or_update, 2, identity->fpr, -1,
   5.489 +            SQLITE_STATIC);
   5.490 +    sqlite3_bind_int(set_or_update, 3, identity->comm_type);
   5.491 +    result = sqlite3_step(set_or_update);
   5.492 +    assert(result == SQLITE_DONE);
   5.493 +    sqlite3_reset(set_or_update);
   5.494 +    if (result != SQLITE_DONE)
   5.495 +        return PEP_CANNOT_SET_TRUST;
   5.496 +
   5.497 +    return PEP_STATUS_OK;
   5.498 +}
   5.499 +
   5.500 +static PEP_STATUS _set_or_update_identity_entry(PEP_SESSION session,
   5.501 +                                                pEp_identity* identity,
   5.502 +                                                sqlite3_stmt* set_or_update) {
   5.503 +    assert(session);
   5.504 +    assert(identity);
   5.505 +    assert(set_or_update);
   5.506 +                      
   5.507 +    if (!session || !identity || !identity->user_id || !identity->address)
   5.508 +        return PEP_ILLEGAL_VALUE;
   5.509 +                                              
   5.510 +    sqlite3_reset(set_or_update);
   5.511 +    sqlite3_bind_text(set_or_update, 1, identity->address, -1,
   5.512 +            SQLITE_STATIC);
   5.513 +    sqlite3_bind_text(set_or_update, 2, identity->fpr, -1,
   5.514 +            SQLITE_STATIC);
   5.515 +    sqlite3_bind_text(set_or_update, 3, identity->user_id, -1,
   5.516 +            SQLITE_STATIC);
   5.517 +    sqlite3_bind_int(set_or_update, 4, identity->flags);
   5.518 +    sqlite3_bind_int(set_or_update, 5, identity->me);
   5.519 +    int result = sqlite3_step(set_or_update);
   5.520 +    sqlite3_reset(set_or_update);
   5.521 +    if (result != SQLITE_DONE)
   5.522 +        return PEP_CANNOT_SET_IDENTITY;
   5.523 +    
   5.524 +    return PEP_STATUS_OK;
   5.525 +}
   5.526 +
   5.527 +static PEP_STATUS _set_or_update_person(PEP_SESSION session, 
   5.528 +                                        pEp_identity* identity,
   5.529 +                                        sqlite3_stmt* set_or_update) {
   5.530 +    assert(session);
   5.531 +    assert(identity);
   5.532 +    assert(set_or_update);
   5.533 +                        
   5.534 +    if (!session || !identity || !identity->user_id || !identity->username)
   5.535 +        return PEP_ILLEGAL_VALUE;
   5.536 +        
   5.537 +    sqlite3_reset(set_or_update);
   5.538 +    sqlite3_bind_text(set_or_update, 1, identity->user_id, -1,
   5.539 +            SQLITE_STATIC);
   5.540 +    sqlite3_bind_text(set_or_update, 2, identity->username, -1,
   5.541 +            SQLITE_STATIC);
   5.542 +    if (identity->lang[0])
   5.543 +        sqlite3_bind_text(set_or_update, 3, identity->lang, 2,
   5.544 +                SQLITE_STATIC);
   5.545 +    else
   5.546 +        sqlite3_bind_null(set_or_update, 3);
   5.547 +    sqlite3_bind_text(set_or_update, 4, identity->fpr, -1,
   5.548 +                      SQLITE_STATIC);
   5.549 +    int result = sqlite3_step(set_or_update);
   5.550 +    sqlite3_reset(set_or_update);
   5.551 +    
   5.552 +    if (result != SQLITE_DONE)
   5.553 +        return PEP_CANNOT_SET_PERSON;
   5.554 +    
   5.555 +    return PEP_STATUS_OK;                                         
   5.556 +}
   5.557 +
   5.558 +PEP_STATUS set_or_update_with_identity(PEP_SESSION session,
   5.559 +                                       pEp_identity* identity,
   5.560 +                                       PEP_STATUS (* set_function)(PEP_SESSION, pEp_identity*, sqlite3_stmt*),
   5.561 +                                       PEP_STATUS (* exists_function)(PEP_SESSION, pEp_identity*, bool*),                                       
   5.562 +                                       sqlite3_stmt* update_query,
   5.563 +                                       sqlite3_stmt* set_query,
   5.564 +                                       bool guard_transaction) {
   5.565 +
   5.566 +    if (guard_transaction) {
   5.567 +        sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
   5.568 +    }
   5.569 +    bool exists = false;
   5.570 +    PEP_STATUS status = exists_function(session, identity, &exists);
   5.571 +    
   5.572 +    if (status == PEP_STATUS_OK) {
   5.573 +        if (exists) {
   5.574 +            status = set_function(session, identity, update_query);
   5.575 +        }
   5.576 +        else {
   5.577 +            status = set_function(session, identity, set_query);                                              
   5.578 +        }                    
   5.579 +    }   
   5.580 +    if (guard_transaction) {        
   5.581 +        if (status != PEP_STATUS_OK)
   5.582 +            sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
   5.583 +        else 
   5.584 +            sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
   5.585 +    }                      
   5.586 +    return status;
   5.587 +}
   5.588 +
   5.589 +PEP_STATUS _set_trust_internal(PEP_SESSION session, pEp_identity* identity,
   5.590 +                               bool guard_transaction) {
   5.591 +    return set_or_update_with_identity(session, identity,
   5.592 +                                       _set_or_update_trust,
   5.593 +                                       exists_trust_entry,
   5.594 +                                       session->update_trust,
   5.595 +                                       session->set_trust,
   5.596 +                                       guard_transaction);
   5.597 +}
   5.598 +PEP_STATUS set_trust(PEP_SESSION session, pEp_identity* identity) {
   5.599 +    return _set_trust_internal(session, identity, true);
   5.600 +}
   5.601 +
   5.602 +PEP_STATUS set_person(PEP_SESSION session, pEp_identity* identity,
   5.603 +                      bool guard_transaction) {
   5.604 +    return set_or_update_with_identity(session, identity,
   5.605 +                                       _set_or_update_person,
   5.606 +                                       exists_person,
   5.607 +                                       session->update_person,
   5.608 +                                       session->set_person,
   5.609 +                                       guard_transaction);
   5.610 +}
   5.611 +
   5.612 +PEP_STATUS set_identity_entry(PEP_SESSION session, pEp_identity* identity,
   5.613 +                              bool guard_transaction) {
   5.614 +    return set_or_update_with_identity(session, identity,
   5.615 +                                       _set_or_update_identity_entry,
   5.616 +                                       exists_identity_entry,
   5.617 +                                       session->update_identity_entry,
   5.618 +                                       session->set_identity_entry,
   5.619 +                                       guard_transaction);
   5.620 +}
   5.621  
   5.622  DYNAMIC_API PEP_STATUS set_identity(
   5.623          PEP_SESSION session, const pEp_identity *identity
   5.624 @@ -1909,7 +2295,7 @@
   5.625      
   5.626      bool listed;
   5.627  
   5.628 -    bool has_fpr = (identity->fpr && identity->fpr[0] != '\0');
   5.629 +    bool has_fpr = (!EMPTYSTR(identity->fpr));
   5.630      
   5.631      if (has_fpr) {    
   5.632          // blacklist check - FIXME: ENGINE-294 will remove
   5.633 @@ -1922,7 +2308,7 @@
   5.634              return PEP_KEY_BLACKLISTED;
   5.635      }
   5.636  
   5.637 -    sqlite3_exec(session->db, "BEGIN ;", NULL, NULL, NULL);
   5.638 +    sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
   5.639  
   5.640      if (identity->lang[0]) {
   5.641          assert(identity->lang[0] >= 'a' && identity->lang[0] <= 'z');
   5.642 @@ -1942,61 +2328,41 @@
   5.643          }
   5.644      }
   5.645  
   5.646 -    sqlite3_reset(session->set_person);
   5.647 -    sqlite3_bind_text(session->set_person, 1, identity->user_id, -1,
   5.648 -            SQLITE_STATIC);
   5.649 -    sqlite3_bind_text(session->set_person, 2, identity->username, -1,
   5.650 -            SQLITE_STATIC);
   5.651 -    if (identity->lang[0])
   5.652 -        sqlite3_bind_text(session->set_person, 3, identity->lang, 2,
   5.653 -                SQLITE_STATIC);
   5.654 -    else
   5.655 -        sqlite3_bind_null(session->set_person, 3);
   5.656 -    sqlite3_bind_text(session->set_person, 4, identity->fpr, -1,
   5.657 -                      SQLITE_STATIC);
   5.658 -    result = sqlite3_step(session->set_person);
   5.659 -    sqlite3_reset(session->set_person);
   5.660 -    if (result != SQLITE_DONE) {
   5.661 +    // We do this because there are checks in set_person for
   5.662 +    // aliases, which modify the identity object on return.
   5.663 +    pEp_identity* ident_copy = identity_dup(identity); 
   5.664 +    if (!ident_copy)
   5.665 +        return PEP_OUT_OF_MEMORY;
   5.666 +
   5.667 +    status = set_person(session, ident_copy, false);
   5.668 +    if (status != PEP_STATUS_OK) {
   5.669          sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
   5.670 -        return PEP_CANNOT_SET_PERSON;
   5.671 +        goto pep_free;
   5.672      }
   5.673  
   5.674 -    sqlite3_reset(session->set_identity);
   5.675 -    sqlite3_bind_text(session->set_identity, 1, identity->address, -1,
   5.676 -            SQLITE_STATIC);
   5.677 -    sqlite3_bind_text(session->set_identity, 2, identity->fpr, -1,
   5.678 -            SQLITE_STATIC);
   5.679 -    sqlite3_bind_text(session->set_identity, 3, identity->user_id, -1,
   5.680 -            SQLITE_STATIC);
   5.681 -    sqlite3_bind_int(session->set_identity, 4, identity->flags);
   5.682 -    sqlite3_bind_int(session->set_identity, 5, identity->me);
   5.683 -    result = sqlite3_step(session->set_identity);
   5.684 -    sqlite3_reset(session->set_identity);
   5.685 -    if (result != SQLITE_DONE) {
   5.686 +    status = set_identity_entry(session, ident_copy, false);
   5.687 +    if (status != PEP_STATUS_OK) {
   5.688          sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
   5.689 -        return PEP_CANNOT_SET_IDENTITY;
   5.690 +        goto pep_free;
   5.691      }
   5.692  
   5.693      if (has_fpr) {
   5.694 -        sqlite3_reset(session->set_trust);
   5.695 -        sqlite3_bind_text(session->set_trust, 1, identity->user_id, -1,
   5.696 -                SQLITE_STATIC);
   5.697 -        sqlite3_bind_text(session->set_trust, 2, identity->fpr, -1,
   5.698 -                SQLITE_STATIC);
   5.699 -        sqlite3_bind_int(session->set_trust, 3, identity->comm_type);
   5.700 -        result = sqlite3_step(session->set_trust);
   5.701 -        sqlite3_reset(session->set_trust);
   5.702 -        if (result != SQLITE_DONE) {
   5.703 +        status = _set_trust_internal(session, ident_copy, false);
   5.704 +        if (status != PEP_STATUS_OK) {
   5.705              sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
   5.706 -            return PEP_CANNOT_SET_TRUST;
   5.707 +            goto pep_free;
   5.708          }
   5.709      }
   5.710      
   5.711      result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
   5.712      if (result == SQLITE_OK)
   5.713 -        return PEP_STATUS_OK;
   5.714 +        status = PEP_STATUS_OK;
   5.715      else
   5.716 -        return PEP_COMMIT_FAILED;
   5.717 +        status = PEP_COMMIT_FAILED;
   5.718 +
   5.719 +pep_free:
   5.720 +    free_identity(ident_copy);
   5.721 +    return status;
   5.722  }
   5.723  
   5.724  // This ONLY sets the user flag, and creates a shell identity if necessary.
   5.725 @@ -2006,19 +2372,15 @@
   5.726      assert(user);
   5.727      assert(user->address);
   5.728      assert(!EMPTYSTR(user->user_id));
   5.729 -    
   5.730 -    char* user_id = user->user_id;
   5.731 -    
   5.732 -    if (!session || !user || user->address || EMPTYSTR(user_id))
   5.733 +        
   5.734 +    if (!session || !user || user->address || EMPTYSTR(user->user_id))
   5.735          return PEP_ILLEGAL_VALUE;
   5.736              
   5.737      PEP_STATUS status = PEP_STATUS_OK;
   5.738      
   5.739 -    char* alias_default = NULL;
   5.740 -    
   5.741      bool person_exists = false;
   5.742      
   5.743 -    status = exists_person(session, user_id, &alias_default, &person_exists);
   5.744 +    status = exists_person(session, user, &person_exists);
   5.745      
   5.746      if (status != PEP_STATUS_OK)
   5.747          return status;
   5.748 @@ -2033,12 +2395,11 @@
   5.749          free_identity(tmp_id);
   5.750          if (status != PEP_STATUS_OK)
   5.751              return status;
   5.752 -        alias_default = strdup(user->user_id);
   5.753      }
   5.754          
   5.755      // Ok, let's set it.
   5.756      sqlite3_reset(session->set_as_pep_user);
   5.757 -    sqlite3_bind_text(session->set_as_pep_user, 1, alias_default, -1,
   5.758 +    sqlite3_bind_text(session->set_as_pep_user, 1, user->user_id, -1,
   5.759              SQLITE_STATIC);
   5.760      int result = sqlite3_step(session->set_as_pep_user);
   5.761      sqlite3_reset(session->set_as_pep_user);
   5.762 @@ -2049,24 +2410,27 @@
   5.763      return PEP_STATUS_OK;    
   5.764  }
   5.765  
   5.766 -PEP_STATUS exists_person(PEP_SESSION session, const char* user_id,
   5.767 -                         char** default_id, bool* exists) {
   5.768 +PEP_STATUS exists_person(PEP_SESSION session, pEp_identity* identity,
   5.769 +                         bool* exists) {            
   5.770 +    
   5.771 +    // const char* user_id,
   5.772 +    //                      char** default_id, bool* exists) {
   5.773      assert(session);
   5.774      assert(exists);
   5.775 -    assert(!EMPTYSTR(user_id));
   5.776 +    assert(identity);
   5.777 +    assert(!EMPTYSTR(identity->user_id));
   5.778          
   5.779 -    if (!session || !exists || EMPTYSTR(user_id))
   5.780 +    if (!session || !exists || !identity || EMPTYSTR(identity->user_id))
   5.781          return PEP_ILLEGAL_VALUE;
   5.782      
   5.783      *exists = false;
   5.784 -    
   5.785 +
   5.786 +    const char* user_id = identity->user_id;
   5.787      char* alias_default = NULL;
   5.788      
   5.789      PEP_STATUS status = get_userid_alias_default(session, user_id, &alias_default);
   5.790      
   5.791      if (status == PEP_CANNOT_FIND_ALIAS || EMPTYSTR(alias_default)) {
   5.792 -        free(alias_default);
   5.793 -        alias_default = NULL;
   5.794          sqlite3_reset(session->exists_person);
   5.795          sqlite3_bind_text(session->exists_person, 1, user_id, -1,
   5.796                  SQLITE_STATIC);
   5.797 @@ -2075,23 +2439,23 @@
   5.798              case SQLITE_ROW: {
   5.799                  // yeah yeah, I know, we could be lazy here, but it looks bad.
   5.800                  *exists = (sqlite3_column_int(session->exists_person, 0) != 0);
   5.801 +                status = PEP_STATUS_OK;
   5.802                  break;
   5.803              }
   5.804              default:
   5.805                  return PEP_UNKNOWN_ERROR;
   5.806          }
   5.807 -        if (*exists)
   5.808 -            alias_default = strdup(user_id);
   5.809 +    }
   5.810 +    else if (status == PEP_STATUS_OK) {
   5.811 +        *exists = true; // thank you, delete on cascade!
   5.812 +        // FIXME: Should we correct the userid default here? I think we should.
   5.813 +        free(identity->user_id);
   5.814 +        identity->user_id = alias_default; // ownership transfer
   5.815      }
   5.816      else
   5.817 -        *exists = true; // thank you, delete on cascade!
   5.818 -
   5.819 -    if (!default_id)
   5.820          free(alias_default);
   5.821 -    else    
   5.822 -        *default_id = alias_default;
   5.823 -    
   5.824 -    return PEP_STATUS_OK;
   5.825 +        
   5.826 +    return status;
   5.827  }
   5.828  
   5.829  PEP_STATUS is_pep_user(PEP_SESSION session, pEp_identity *identity, bool* is_pep)
   5.830 @@ -2497,35 +2861,6 @@
   5.831      free(p);
   5.832  }
   5.833  
   5.834 -PEP_STATUS set_trust(PEP_SESSION session, 
   5.835 -                     const char* user_id,
   5.836 -                     const char* fpr, 
   5.837 -                     PEP_comm_type comm_type) 
   5.838 -{
   5.839 -    assert(session);
   5.840 -    assert(user_id);
   5.841 -    assert(fpr);
   5.842 -    
   5.843 -    if (!session || !user_id || user_id[0] == '\0' || !fpr || fpr[0] == '\0')
   5.844 -        return PEP_ILLEGAL_VALUE;
   5.845 -        
   5.846 -    int result;
   5.847 -                
   5.848 -    sqlite3_reset(session->set_trust);
   5.849 -    sqlite3_bind_text(session->set_trust, 1, user_id, -1,
   5.850 -            SQLITE_STATIC);
   5.851 -    sqlite3_bind_text(session->set_trust, 2, fpr, -1,
   5.852 -            SQLITE_STATIC);
   5.853 -    sqlite3_bind_int(session->set_trust, 3, comm_type);
   5.854 -    result = sqlite3_step(session->set_trust);
   5.855 -    assert(result == SQLITE_DONE);
   5.856 -    sqlite3_reset(session->set_trust);
   5.857 -    if (result != SQLITE_DONE)
   5.858 -        return PEP_CANNOT_SET_TRUST;
   5.859 -
   5.860 -    return PEP_STATUS_OK;
   5.861 -}
   5.862 -
   5.863  
   5.864  DYNAMIC_API PEP_STATUS get_trust(PEP_SESSION session, pEp_identity *identity)
   5.865  {
   5.866 @@ -2768,6 +3103,10 @@
   5.867      if (status != PEP_STATUS_OK)
   5.868          return status;
   5.869  
   5.870 +    if (identity->fpr)
   5.871 +        status = set_pgp_keypair(session, identity->fpr);
   5.872 +
   5.873 +    // add to known keypair DB, as this might not end up being a default
   5.874      return status;
   5.875  }
   5.876  
   5.877 @@ -3244,7 +3583,7 @@
   5.878      }
   5.879  
   5.880      if (*value) {
   5.881 -        sqlite3_exec(session->db, "BEGIN ;", NULL, NULL, NULL);
   5.882 +        sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
   5.883          int32_t old_value = 0;
   5.884          status = _get_sequence_value(session, name, &old_value);
   5.885          if (status != PEP_STATUS_OK && status != PEP_RECORD_NOT_FOUND)
   5.886 @@ -3273,7 +3612,7 @@
   5.887      }
   5.888  
   5.889      assert(*value == 0);
   5.890 -    sqlite3_exec(session->db, "BEGIN ;", NULL, NULL, NULL);
   5.891 +    sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
   5.892      status = _increment_sequence_value(session, name, own);
   5.893      if (status == PEP_STATUS_OK) {
   5.894          status = _get_sequence_value(session, name, value);
     6.1 --- a/src/pEpEngine.h	Sun Feb 04 15:26:28 2018 +0100
     6.2 +++ b/src/pEpEngine.h	Wed Feb 07 16:46:21 2018 +0100
     6.3 @@ -934,9 +934,7 @@
     6.4  
     6.5  
     6.6  PEP_STATUS set_trust(PEP_SESSION session, 
     6.7 -                            const char* user_id,
     6.8 -                            const char* fpr, 
     6.9 -                            PEP_comm_type comm_type);
    6.10 +                     pEp_identity* identity);
    6.11                              
    6.12  PEP_STATUS update_trust_for_fpr(PEP_SESSION session, 
    6.13                                  const char* fpr, 
    6.14 @@ -1234,17 +1232,15 @@
    6.15  // This ONLY sets the *user* flag, and creates a shell identity if necessary.
    6.16  PEP_STATUS set_as_pep_user(PEP_SESSION session, pEp_identity* user);
    6.17  
    6.18 -// returns true (by reference) if a person with this user_id exists; if default_id != NULL,
    6.19 -// function will also return by reference a copy of the default id which
    6.20 -// is this user_id is aliased to (which will usually, but not always, 
    6.21 -// string equivalent to the user_id)
    6.22 -PEP_STATUS exists_person(PEP_SESSION session, const char* user_id,
    6.23 -                         char** default_id, bool* exists);
    6.24 +// returns true (by reference) if a person with this user_id exists; 
    6.25 +// Also replaces aliased user_ids by defaults in identity.
    6.26 +PEP_STATUS exists_person(PEP_SESSION session, pEp_identity* identity, bool* exists);
    6.27  
    6.28  // returns true if the USER corresponding to this identity has been listed in
    6.29  // the *person* table as a pEp user. This *does not check comm_type*                         
    6.30  PEP_STATUS is_pep_user(PEP_SESSION session, pEp_identity *identity, bool* is_pep);
    6.31  
    6.32 +PEP_STATUS set_pgp_keypair(PEP_SESSION session, const char* fpr);
    6.33  
    6.34  #ifdef __cplusplus
    6.35  }
     7.1 --- a/src/pEp_internal.h	Sun Feb 04 15:26:28 2018 +0100
     7.2 +++ b/src/pEp_internal.h	Wed Feb 07 16:46:21 2018 +0100
     7.3 @@ -131,16 +131,21 @@
     7.4      sqlite3_stmt *refresh_userid_default_key;
     7.5      sqlite3_stmt *remove_fpr_as_default;
     7.6      sqlite3_stmt *set_person;
     7.7 +    sqlite3_stmt *update_person;
     7.8 +    sqlite3_stmt *exists_person;    
     7.9      sqlite3_stmt *set_as_pep_user;
    7.10      sqlite3_stmt *is_pep_user;
    7.11 -    sqlite3_stmt *exists_person;
    7.12      sqlite3_stmt *set_device_group;
    7.13      sqlite3_stmt *get_device_group;
    7.14      sqlite3_stmt *set_pgp_keypair;
    7.15 -    sqlite3_stmt *set_identity;
    7.16 +    sqlite3_stmt *set_identity_entry;
    7.17 +    sqlite3_stmt *update_identity_entry;
    7.18 +    sqlite3_stmt *exists_identity_entry;        
    7.19      sqlite3_stmt *set_identity_flags;
    7.20      sqlite3_stmt *unset_identity_flags;
    7.21      sqlite3_stmt *set_trust;
    7.22 +    sqlite3_stmt *update_trust;    
    7.23 +    sqlite3_stmt *exists_trust_entry;
    7.24      sqlite3_stmt *update_trust_for_fpr;
    7.25      sqlite3_stmt *get_trust;
    7.26      sqlite3_stmt *least_trust;
     8.1 --- a/test/case_and_dot_address_test.cc	Sun Feb 04 15:26:28 2018 +0100
     8.2 +++ b/test/case_and_dot_address_test.cc	Wed Feb 07 16:46:21 2018 +0100
     8.3 @@ -25,9 +25,9 @@
     8.4      assert(session);
     8.5      cout << "init() completed.\n";
     8.6      
     8.7 +    char* user_id = get_new_uuid();
     8.8      
     8.9      const string alice_pub_key = slurp("test_keys/pub/pep-test-alice-0x6FF00E97_pub.asc");
    8.10 -    const string alice_priv_key = slurp("test_keys/priv/pep-test-alice-0x6FF00E97_priv.asc");
    8.11  
    8.12      const char* alice_email_case = "pEp.teST.AlICe@pEP-pRoJeCt.ORG";
    8.13      const char* alice_email_dot = "pe.p.te.st.a.l.i.ce@pep-project.org";
    8.14 @@ -35,15 +35,13 @@
    8.15      const char* alice_email_case_and_dot = "PE.p.teS.t.ALICE@pep-project.OrG";
    8.16  
    8.17      PEP_STATUS statuspub = import_key(session, alice_pub_key.c_str(), alice_pub_key.length(), NULL);
    8.18 -    PEP_STATUS statuspriv = import_key(session, alice_priv_key.c_str(), alice_priv_key.length(), NULL);
    8.19      assert(statuspub == PEP_STATUS_OK);
    8.20 -    assert(statuspriv == PEP_STATUS_OK);
    8.21  
    8.22 -    pEp_identity * alice_id = new_identity("pep.test.alice@pep-project.org", "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97", PEP_OWN_USERID, "Alice Test");
    8.23 -    identity_list* own_id = new_identity_list(alice_id);
    8.24 -    status = initialise_own_identities(session, own_id);
    8.25 +    pEp_identity * alice_id = new_identity("pep.test.alice@pep-project.org", "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97", user_id, "Alice Test");
    8.26 +
    8.27      status = trust_personal_key(session, alice_id);
    8.28 -    pEp_identity * new_alice_id = new_identity("pep.test.alice@pep-project.org", "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97", PEP_OWN_USERID, "Alice Test");
    8.29 +
    8.30 +    pEp_identity * new_alice_id = new_identity("pep.test.alice@pep-project.org", "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97", user_id, "Alice Test");
    8.31      status = update_identity(session, new_alice_id);
    8.32      assert(new_alice_id->fpr);
    8.33      assert(strcmp(new_alice_id->fpr, "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97") == 0);
    8.34 @@ -52,30 +50,34 @@
    8.35      alice_id = NULL;
    8.36      new_alice_id = NULL;
    8.37  
    8.38 -    alice_id = new_identity(alice_email_case, NULL, PEP_OWN_USERID, "Alice Test");
    8.39 -    status = myself(session, alice_id);
    8.40 +    alice_id = new_identity(alice_email_case, NULL, user_id, "Alice Test");
    8.41 +    status = update_identity(session, alice_id);
    8.42      assert(alice_id->fpr);
    8.43 +    cout << "Alice email: " << alice_email_case << " Alice fpr (should be 4ABE3AAF59AC32CFE4F86500A9411D176FF00E97): " << alice_id->fpr << endl;
    8.44      assert(strcmp(alice_id->fpr, "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97") == 0);
    8.45      free_identity(alice_id);
    8.46      alice_id = NULL;
    8.47  
    8.48 -    alice_id = new_identity(alice_email_dot, NULL, PEP_OWN_USERID, "Alice Test");
    8.49 -    status = myself(session, alice_id);
    8.50 +    alice_id = new_identity(alice_email_dot, NULL, user_id, "Alice Test");
    8.51 +    status = update_identity(session, alice_id);
    8.52      assert(alice_id->fpr);
    8.53 +    cout << "Alice email: " << alice_email_dot << " Alice fpr (should be 4ABE3AAF59AC32CFE4F86500A9411D176FF00E97): " << alice_id->fpr << endl;
    8.54      assert(strcmp(alice_id->fpr, "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97") == 0);
    8.55      free_identity(alice_id);
    8.56      alice_id = NULL;
    8.57  
    8.58 -    alice_id = new_identity(alice_email_dotless, NULL, PEP_OWN_USERID, "Alice Test");
    8.59 -    status = myself(session, alice_id);
    8.60 +    alice_id = new_identity(alice_email_dotless, NULL, user_id, "Alice Test");
    8.61 +    status = update_identity(session, alice_id);
    8.62      assert(alice_id->fpr);
    8.63 +    cout << "Alice email: " << alice_email_dotless << " Alice fpr (should be 4ABE3AAF59AC32CFE4F86500A9411D176FF00E97): " << alice_id->fpr << endl;
    8.64      assert(strcmp(alice_id->fpr, "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97") == 0);
    8.65      free_identity(alice_id);
    8.66      alice_id = NULL;
    8.67  
    8.68 -    alice_id = new_identity(alice_email_case_and_dot, NULL, PEP_OWN_USERID, "Alice Test");
    8.69 -    status = myself(session, alice_id);
    8.70 +    alice_id = new_identity(alice_email_case_and_dot, NULL, user_id, "Alice Test");
    8.71 +    status = update_identity(session, alice_id);
    8.72      assert(alice_id->fpr);
    8.73 +    cout << "Alice email: " << alice_email_case_and_dot << " Alice fpr (should be 4ABE3AAF59AC32CFE4F86500A9411D176FF00E97): " << alice_id->fpr << endl;
    8.74      assert(strcmp(alice_id->fpr, "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97") == 0);
    8.75      free_identity(alice_id);
    8.76      alice_id = NULL;
     9.1 --- a/test/external_revoke_test.cc	Sun Feb 04 15:26:28 2018 +0100
     9.2 +++ b/test/external_revoke_test.cc	Wed Feb 07 16:46:21 2018 +0100
     9.3 @@ -148,7 +148,7 @@
     9.4      // (note - as of 23.5.17, revoke_key() doesn't touch the trust db, just the keyring, so we can do this)
     9.5  
     9.6      cout << "Revoking key." << endl;
     9.7 -    status = get_identity(session, uniqname, r1_userid, &recip1);    
     9.8 +    status = update_identity(session, recip1);    
     9.9      status = revoke_key(session, recip1->fpr, "encrypt_for_identity_test");
    9.10      cout << "Status of revocation call for " << recip1->fpr << " is "<< tl_status_string(status) << endl;
    9.11  
    9.12 @@ -177,12 +177,13 @@
    9.13      cout << "2b. Encrypt message for recip whose key has been externally revoked in the keyring, not the app." << endl;
    9.14      cout << "---------------------------------------------------------" << endl << endl;
    9.15  
    9.16 +
    9.17      status = encrypt_message(session, outgoing_msg, NULL, &encrypted_outgoing_msg, PEP_enc_PGP_MIME, 0);
    9.18      cout << "Encryption returns with status " << tl_status_string(status) << endl;
    9.19 -    assert (status == PEP_KEY_UNSUITABLE);
    9.20 +    assert (status == PEP_UNENCRYPTED);
    9.21      assert (encrypted_outgoing_msg == NULL);
    9.22      status = update_identity(session, recip1);
    9.23 -    assert (recip1->comm_type = PEP_ct_key_revoked);
    9.24 +    assert(recip1->comm_type = PEP_ct_key_not_found);
    9.25  
    9.26      cout << endl << "---------------------------------------------------------" << endl;
    9.27      cout << "2c. Check trust of recip, whose only key has been revoked, once an encryption attempt has been made." << endl;
    9.28 @@ -194,7 +195,7 @@
    9.29      recip1->fpr = NULL;
    9.30  
    9.31      cout << "Recip's trust DB comm_type = " << hex << tl_ct_string(recip1->comm_type) << endl;
    9.32 -    assert(recip1->comm_type == PEP_ct_key_revoked);
    9.33 +    assert(recip1->comm_type == PEP_ct_unknown || recip1->comm_type == PEP_ct_key_revoked);
    9.34  
    9.35      free_message(decrypted_msg);
    9.36      free_message(outgoing_msg);
    10.1 --- a/test/least_common_denom_color_test.cc	Sun Feb 04 15:26:28 2018 +0100
    10.2 +++ b/test/least_common_denom_color_test.cc	Wed Feb 07 16:46:21 2018 +0100
    10.3 @@ -40,12 +40,12 @@
    10.4      PEP_STATUS status = update_identity(session, sender);
    10.5          
    10.6      // reset the trust on both keys before we start
    10.7 -    pEp_identity * recip1 = new_identity("banmeonce@kgrothoff.org", NULL, "TOFU_banemeonce@kgrothoff.org", "Ban Me Once");    
    10.8 +    pEp_identity * recip1 = new_identity("banmeonce@kgrothoff.org", NULL, "TOFU_banmeonce@kgrothoff.org", "Ban Me Once");    
    10.9      recip1->me = false;    
   10.10      status = update_identity(session, recip1);
   10.11      key_reset_trust(session, recip1);
   10.12      
   10.13 -    pEp_identity * recip2 = new_identity("banmetwice@kgrothoff.org", NULL, "TOFU_banemetwice@kgrothoff.org", "Ban Me Twice");    
   10.14 +    pEp_identity * recip2 = new_identity("banmetwice@kgrothoff.org", NULL, "TOFU_banmetwice@kgrothoff.org", "Ban Me Twice");    
   10.15      recip2->me = false;    
   10.16      status = update_identity(session, recip2);
   10.17      key_reset_trust(session, recip2);
    11.1 --- a/test/new_update_id_and_myself_test.cc	Sun Feb 04 15:26:28 2018 +0100
    11.2 +++ b/test/new_update_id_and_myself_test.cc	Wed Feb 07 16:46:21 2018 +0100
    11.3 @@ -17,6 +17,8 @@
    11.4  int main() {
    11.5      cout << "\n*** test update_identity and myself ***\n\n";
    11.6      
    11.7 +    test_init();
    11.8 +    
    11.9      PEP_SESSION session;
   11.10      
   11.11      cout << "calling init()\n";
   11.12 @@ -225,7 +227,8 @@
   11.13  
   11.14      const char* new_username = "Test Patchy";
   11.15              
   11.16 -    alex = new_identity(alex_address, NULL, alex_userid, new_username); 
   11.17 +    alex = new_identity(alex_address, NULL, alex_userid, new_username);
   11.18 +    cout << "Timing is everything" << endl; 
   11.19      status = update_identity(session, alex);
   11.20      assert(status == PEP_STATUS_OK);
   11.21      assert(alex->fpr);
    12.1 --- a/test/test_util.cc	Sun Feb 04 15:26:28 2018 +0100
    12.2 +++ b/test/test_util.cc	Wed Feb 07 16:46:21 2018 +0100
    12.3 @@ -6,6 +6,13 @@
    12.4  #include <sstream>
    12.5  #include <stdexcept>
    12.6  
    12.7 +
    12.8 +void test_init() {
    12.9 +    unlink ("../test_home/.pEp_management.db");
   12.10 +    unlink ("../test_home/.pEp_management.db-shm");
   12.11 +    unlink ("../test_home/.pEp_management.db-wal");
   12.12 +}
   12.13 +
   12.14  std::string slurp(const std::string& filename)
   12.15  {
   12.16  	std::ifstream input(filename.c_str());
    13.1 --- a/test/test_util.h	Sun Feb 04 15:26:28 2018 +0100
    13.2 +++ b/test/test_util.h	Wed Feb 07 16:46:21 2018 +0100
    13.3 @@ -2,6 +2,8 @@
    13.4  #include "pEpEngine.h"
    13.5  #include "message_api.h"
    13.6  
    13.7 +void test_init();
    13.8 +
    13.9  // reads a whole file and returns it as std::string
   13.10  // throws std::runtime_error() if the file cannot be read. Empty file is not an error.
   13.11  std::string slurp(const std::string& filename);