src/pEpEngine.c
author Krista 'DarthMama' Bennett <krista@pep.foundation>
Wed, 29 May 2019 09:59:00 +0200
branchsync
changeset 3762 55501092d6e3
parent 3747 82fe58af7b53
child 3804 7535bfbf092c
child 3806 b9c98a86b791
child 3839 f264464b1cfa
permissions -rw-r--r--
Yeah, so static local variables are dangerous with multiple threads. (This has apparently been in since revision 0, so we should probably look out for other similar assumptions in the code.
     1 // This file is under GNU General Public License 3.0
     2 // see LICENSE.txt
     3 
     4 #include "pEp_internal.h"
     5 #include "dynamic_api.h"
     6 #include "cryptotech.h"
     7 #include "transport.h"
     8 #include "blacklist.h"
     9 #include "KeySync_fsm.h"
    10 
    11 #include <time.h>
    12 #include <stdlib.h>
    13 
    14 #define _PEP_SQLITE_DEBUG 0
    15 #if _PEP_SQLITE_DEBUG
    16 #include <sqlite3.h>
    17 #endif
    18 
    19 static volatile int init_count = -1;
    20 
    21 // sql overloaded functions - modified from sqlite3.c
    22 static void _sql_lower(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
    23     const char *z2;
    24     int n;
    25     z2 = (char*)sqlite3_value_text(argv[0]);
    26     n = sqlite3_value_bytes(argv[0]);
    27     /* Verify that the call to _bytes() does not invalidate the _text() pointer */
    28     assert( z2==(char*)sqlite3_value_text(argv[0]) );
    29     if( z2 ){
    30         char *z1 = (char*)sqlite3_malloc(n+1);
    31         if( z1 ){
    32             for(int i=0; i<n; i++){
    33                 char c = z2[i];
    34                 char c_mod = c | 0x20;
    35                 if (c_mod < 0x61 || c_mod > 0x7a)
    36                     c_mod = c;
    37                 z1[i] = c_mod;
    38             }
    39             z1[n] = '\0';
    40             sqlite3_result_text(ctx, z1, n, sqlite3_free);
    41         }
    42     }
    43 }
    44 
    45 #if _PEP_SQLITE_DEBUG
    46 int sql_trace_callback (unsigned trace_constant, 
    47                         void* context_ptr,
    48                         void* P,
    49                         void* X) {
    50     switch (trace_constant) {
    51         case SQLITE_TRACE_STMT:
    52             fprintf(stderr, "SQL_DEBUG: STMT - ");
    53             const char* X_str = (const char*) X;
    54             if (!EMPTYSTR(X_str) && X_str[0] == '-' && X_str[1] == '-')
    55                 fprintf(stderr, "%s\n", X_str);
    56             else
    57                 fprintf(stderr, "%s\n", sqlite3_expanded_sql((sqlite3_stmt*)P));
    58             break;
    59         case SQLITE_TRACE_ROW:
    60             fprintf(stderr, "SQL_DEBUG: ROW - ");
    61             fprintf(stderr, "%s\n", sqlite3_expanded_sql((sqlite3_stmt*)P));
    62             break;            
    63         case SQLITE_TRACE_CLOSE:
    64             fprintf(stderr, "SQL_DEBUG: CLOSE - ");
    65             break;
    66         default:
    67             break;
    68     }
    69     return 0;
    70 }
    71 #endif
    72 
    73 // sql manipulation statements
    74 static const char *sql_log = 
    75     "insert into log (title, entity, description, comment)"
    76      "values (?1, ?2, ?3, ?4);";
    77 
    78 static const char *sql_trustword = 
    79     "select id, word from wordlist where lang = lower(?1) "
    80     "and id = ?2 ;";
    81 
    82 // FIXME?: problems if we don't have a key for the user - we get nothing
    83 static const char *sql_get_identity =  
    84     "select fpr, username, comm_type, lang,"
    85     "   identity.flags | pgp_keypair.flags,"
    86     "   is_own"
    87     "   from identity"
    88     "   join person on id = identity.user_id"
    89     "   join pgp_keypair on fpr = identity.main_key_id"
    90     "   join trust on id = trust.user_id"
    91     "       and pgp_keypair_fpr = identity.main_key_id"    
    92     "   where (case when (address = ?1) then (1)"
    93     "               when (lower(address) = lower(?1)) then (1)"
    94     "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
    95     "               else 0"
    96     "          end) = 1"
    97     "   and identity.user_id = ?2" 
    98     "   order by is_own desc, "
    99     "   timestamp desc; ";
   100 
   101 static const char *sql_get_identities_by_main_key_id =  
   102     "select address, identity.user_id, username, comm_type, lang,"
   103     "   identity.flags | pgp_keypair.flags,"
   104     "   is_own"
   105     "   from identity"
   106     "   join person on id = identity.user_id"
   107     "   join pgp_keypair on fpr = identity.main_key_id"
   108     "   join trust on id = trust.user_id"
   109     "       and pgp_keypair_fpr = identity.main_key_id"    
   110     "   where identity.main_key_id = ?1" 
   111     "   order by is_own desc, "
   112     "   timestamp desc; ";
   113 
   114 static const char *sql_get_identity_without_trust_check =  
   115     "select identity.main_key_id, username, lang,"
   116     "   identity.flags, is_own"
   117     "   from identity"
   118     "   join person on id = identity.user_id"
   119     "   where (case when (address = ?1) then (1)"
   120     "               when (lower(address) = lower(?1)) then (1)"
   121     "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
   122     "               else 0"
   123     "          end) = 1"
   124     "   and identity.user_id = ?2 "
   125     "   order by is_own desc, "
   126     "   timestamp desc; ";
   127 
   128 static const char *sql_get_identities_by_address =  
   129     "select user_id, identity.main_key_id, username, lang,"
   130     "   identity.flags, is_own"
   131     "   from identity"
   132     "   join person on id = identity.user_id"
   133     "   where (case when (address = ?1) then (1)"
   134     "               when (lower(address) = lower(?1)) then (1)"
   135     "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
   136     "               else 0"
   137     "          end) = 1 "
   138     "   order by is_own desc, "
   139     "   timestamp desc; ";
   140     
   141 static const char *sql_get_identities_by_userid =  
   142     "select address, fpr, username, comm_type, lang,"
   143     "   identity.flags | pgp_keypair.flags,"
   144     "   is_own"
   145     "   from identity"
   146     "   join person on id = identity.user_id"
   147     "   join pgp_keypair on fpr = identity.main_key_id"
   148     "   join trust on id = trust.user_id"
   149     "       and pgp_keypair_fpr = identity.main_key_id"    
   150     "   where identity.user_id = ?1" 
   151     "   order by is_own desc, "
   152     "   timestamp desc; ";
   153 
   154 static const char *sql_replace_identities_fpr =  
   155     "update identity"
   156     "   set main_key_id = ?1 "
   157     "   where main_key_id = ?2 ;";
   158     
   159 static const char *sql_remove_fpr_as_default =
   160     "update person set main_key_id = NULL where main_key_id = ?1 ;"
   161     "update identity set main_key_id = NULL where main_key_id = ?1 ;";
   162 
   163 // Set person, but if already exist, only update.
   164 // if main_key_id already set, don't touch.
   165 static const char *sql_set_person = 
   166      "insert into person (id, username, lang, main_key_id)"
   167      "  values (?1, ?2, ?3, ?4) ;";
   168 
   169 static const char *sql_update_person = 
   170     "update person "
   171     "   set username = ?2, "
   172     "       lang = ?3, "
   173     "       main_key_id =  "
   174     "           (select coalesce( "
   175     "               (select main_key_id from person where id = ?1), " 
   176     "                upper(replace(?4,' ',''))))"         
   177     "   where id = ?1 ;";
   178 
   179 // Will cascade.
   180 static const char *sql_delete_person = 
   181      "delete from person where id = ?1 ;";
   182 
   183 static const char *sql_set_as_pEp_user =
   184     "update person set is_pEp_user = 1 "
   185     "   where id = ?1 ; ";
   186 
   187 static const char *sql_is_pEp_user =
   188     "select is_pEp_user from person "
   189     "   where id = ?1 ; ";
   190 
   191 static const char* sql_exists_person = 
   192     "select count(*) from person "
   193     "   where id = ?1 ;";
   194 
   195 // This will cascade to identity and trust
   196 static const char* sql_replace_userid =
   197     "update person set id = ?1 " 
   198     "   where id = ?2;";
   199 
   200 // Hopefully this cascades and removes trust entries...
   201 static const char *sql_delete_key =
   202     "delete from pgp_keypair "
   203     "   where fpr = ?1 ; ";
   204 
   205 static const char *sql_replace_main_user_fpr =  
   206     "update person "
   207     "   set main_key_id = ?1 "
   208     "   where id = ?2 ;";
   209 
   210 static const char *sql_get_main_user_fpr =  
   211     "select main_key_id from person"
   212     "   where id = ?1 ;";
   213 
   214 static const char *sql_refresh_userid_default_key =
   215     "update person "
   216     "   set main_key_id = "
   217     "       (select identity.main_key_id from identity "
   218     "           join trust on trust.user_id = identity.user_id "
   219     "               and trust.pgp_keypair_fpr = identity.main_key_id "
   220     "           join person on identity.user_id = identity.user_id "
   221     "       where identity.user_id = ?1 "
   222     "       order by trust.comm_type desc "
   223     "       limit 1) "
   224     "where id = ?1 ; ";
   225 
   226 static const char *sql_set_pgp_keypair = 
   227     "insert or ignore into pgp_keypair (fpr) "
   228     "values (upper(replace(?1,' ',''))) ;";
   229 
   230 static const char* sql_exists_identity_entry = 
   231     "select count(*) from identity "
   232     "   where (case when (address = ?1) then (1)"
   233     "               when (lower(address) = lower(?1)) then (1)"
   234     "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
   235     "               else 0"
   236     "          end) = 1"
   237     "    and user_id = ?2;";
   238  
   239 static const char *sql_set_identity_entry = 
   240     "insert into identity ("
   241     "       address, main_key_id, "
   242     "       user_id, flags, is_own"
   243     "   ) values ("
   244     "       ?1,"
   245     "       upper(replace(?2,' ','')),"
   246     "       ?3,"
   247     "       ?4,"
   248     "       ?5"
   249     "   );";
   250     
   251 static const char* sql_update_identity_entry =    
   252     "update identity "
   253     "   set main_key_id = upper(replace(?2,' ','')), "
   254     "       flags = ?4, " 
   255     "       is_own = ?5 "
   256     "   where (case when (address = ?1) then (1)"
   257     "               when (lower(address) = lower(?1)) then (1)"
   258     "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1) "
   259     "               else 0 "
   260     "          end) = 1 "
   261     "          and user_id = ?3 ;";
   262 
   263     // " (select"
   264     // "   coalesce("
   265     // "    (select flags from identity"
   266     // "     where address = ?1 and"
   267     // "           user_id = ?3),"
   268     // "    0)"
   269     // " ) | (?4 & 255)"
   270     /* set_identity ignores previous flags, and doesn't filter machine flags */
   271         
   272 static const char *sql_set_identity_flags = 
   273     "update identity set flags = "
   274     "    ((?1 & 65535) | (select flags from identity"
   275     "                    where (case when (address = ?2) then (1)"
   276     "                                when (lower(address) = lower(?2)) then (1)"
   277     "                                when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   278     "                                else 0 "    
   279     "                           end) = 1 "
   280     "                           and user_id = ?3)) "
   281     "   where (case when (address = ?2) then (1)"
   282     "               when (lower(address) = lower(?2)) then (1)"
   283     "               when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   284     "               else 0"
   285     "          end) = 1"
   286     "          and user_id = ?3 ;";
   287 
   288 static const char *sql_unset_identity_flags = 
   289     "update identity set flags = "
   290     "    ( ~(?1 & 65535) & (select flags from identity"
   291     "                    where (case when (address = ?2) then (1)"
   292     "                                when (lower(address) = lower(?2)) then (1)"
   293     "                                when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   294     "                                else 0 "    
   295     "                           end) = 1 "
   296     "                           and user_id = ?3)) "
   297     "   where (case when (address = ?2) then (1)"
   298     "               when (lower(address) = lower(?2)) then (1)"
   299     "               when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   300     "               else 0"
   301     "          end) = 1"
   302     "          and user_id = ?3 ;";
   303 
   304 static const char *sql_set_trust =
   305     "insert into trust (user_id, pgp_keypair_fpr, comm_type) "
   306     "values (?1, upper(replace(?2,' ','')), ?3) ;";
   307 
   308 static const char *sql_update_trust =
   309     "update trust set comm_type = ?3 " 
   310     "   where user_id = ?1 and pgp_keypair_fpr = upper(replace(?2,' ',''));";
   311 
   312 static const char *sql_update_trust_to_pEp =
   313     "update trust set comm_type = comm_type + 71 "
   314     "   where (user_id = ?1 "
   315     "          and (case when (comm_type = 56) then (1) "
   316     "                    when (comm_type = 184) then (1) "
   317     "                    else 0"
   318     "               end) = 1); ";
   319 
   320 static const char* sql_exists_trust_entry = 
   321     "select count(*) from trust "
   322     "   where user_id = ?1 and pgp_keypair_fpr = upper(replace(?2,' ',''));";
   323     
   324 static const char *sql_update_trust_for_fpr =
   325     "update trust "
   326     "set comm_type = ?1 "
   327     "where pgp_keypair_fpr = upper(replace(?2,' ','')) ;";
   328 
   329 static const char *sql_get_trust = 
   330     "select comm_type from trust where user_id = ?1 "
   331     "and pgp_keypair_fpr = upper(replace(?2,' ','')) ;";
   332 
   333 static const char *sql_get_trust_by_userid = 
   334     "select pgp_keypair_fpr, comm_type from trust where user_id = ?1 ";
   335 
   336 static const char *sql_least_trust = 
   337     "select min(comm_type) from trust where"
   338     " pgp_keypair_fpr = upper(replace(?1,' ',''))"
   339     " and comm_type != 0;"; // ignores PEP_ct_unknown
   340     // returns PEP_ct_unknown only when no known trust is recorded
   341 
   342 static const char *sql_mark_as_compromised = 
   343     "update trust not indexed set comm_type = 15"
   344     " where pgp_keypair_fpr = upper(replace(?1,' ','')) ;";
   345     
   346 static const char *sql_crashdump = 
   347     "select timestamp, title, entity, description, comment"
   348     " from log order by timestamp desc limit ?1 ;";
   349 
   350 static const char *sql_languagelist = 
   351     "select i18n_language.lang, name, phrase" 
   352     " from i18n_language join i18n_token using (lang) where i18n_token.id = 1000;" ;
   353 
   354 static const char *sql_i18n_token = 
   355     "select phrase from i18n_token where lang = lower(?1) and id = ?2 ;";
   356 
   357 // blacklist
   358 static const char *sql_blacklist_add = 
   359     "insert or ignore into blacklist_keys (fpr) values (upper(replace(?1,' ',''))) ;"
   360     "delete from identity where main_key_id = upper(replace(?1,' ','')) ;"
   361     "delete from pgp_keypair where fpr = upper(replace(?1,' ','')) ;";
   362 
   363 static const char *sql_blacklist_delete =
   364     "delete from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
   365 
   366 static const char *sql_blacklist_is_listed = 
   367     "select count(*) from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
   368 
   369 static const char *sql_blacklist_retrieve = 
   370     "select * from blacklist_keys ;";
   371                 
   372 
   373 // Own keys
   374 // We only care if it's 0 or non-zero
   375 static const char *sql_own_key_is_listed = 
   376     "select count(*) from ("
   377     "   select pgp_keypair_fpr from trust"
   378     "      join identity on trust.user_id = identity.user_id"
   379     "      where pgp_keypair_fpr = upper(replace(?1,' ',''))"
   380     "           and identity.is_own = 1"
   381     ");";
   382     
   383 static const char *sql_is_own_address =
   384     "select count(*) from ("
   385     "   select address from identity"
   386     "       where (case when (address = ?1) then (1)"
   387     "                   when (lower(address) = lower(?1)) then (1)"
   388     "                   when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
   389     "                   else 0"
   390     "           end) = 1 "
   391     "           and identity.is_own = 1"
   392     ");";
   393 
   394 static const char *sql_own_identities_retrieve =  
   395     "select address, fpr, identity.user_id, username,"
   396     "   lang, identity.flags | pgp_keypair.flags"
   397     "   from identity"
   398     "   join person on id = identity.user_id"
   399     "   join pgp_keypair on fpr = identity.main_key_id"
   400     "   join trust on id = trust.user_id"
   401     "       and pgp_keypair_fpr = identity.main_key_id"
   402     "   where identity.is_own = 1"
   403     "       and (identity.flags & ?1) = 0;";
   404 
   405 static const char *sql_own_keys_retrieve = 
   406     "select pgp_keypair_fpr from trust"
   407     "   join identity on trust.user_id = identity.user_id"
   408     "   where identity.is_own = 1";
   409 
   410 static const char* sql_get_user_default_key =
   411     "select main_key_id from person" 
   412     "   where id = ?1;";
   413 
   414 static const char* sql_get_all_keys_for_user =
   415     "select pgp_keypair_fpr from trust"
   416     "   where user_id = ?1; ";
   417 
   418 static const char* sql_get_default_own_userid =
   419     "select id from person"
   420     "   join identity on id = identity.user_id"
   421     "   where identity.is_own = 1";
   422 
   423 // Sequence
   424 static const char *sql_sequence_value1 = 
   425     "insert or replace into sequences (name, value) "
   426     "values (?1, "
   427     "       (select coalesce((select value + 1 from sequences "
   428     "           where name = ?1), 1 ))); ";
   429 
   430 static const char *sql_sequence_value2 = 
   431     "select value from sequences where name = ?1 ;";
   432 
   433 // Revocation tracking
   434 static const char *sql_set_revoked =
   435     "insert or replace into revoked_keys ("
   436     "    revoked_fpr, replacement_fpr, revocation_date) "
   437     "values (upper(replace(?1,' ','')),"
   438     "        upper(replace(?2,' ','')),"
   439     "        ?3) ;";
   440         
   441 static const char *sql_get_revoked = 
   442     "select revoked_fpr, revocation_date from revoked_keys"
   443     "    where replacement_fpr = upper(replace(?1,' ','')) ;";
   444 
   445 static const char *sql_get_replacement_fpr = 
   446     "select replacement_fpr, revocation_date from revoked_keys"
   447     "    where revoked_fpr = upper(replace(?1,' ','')) ;";
   448 
   449 static const char *sql_get_userid_alias_default =
   450     "select default_id from alternate_user_id "
   451     "   where alternate_id = ?1 ; ";
   452 
   453 // Revocation tracking
   454 static const char *sql_add_mistrusted_key =
   455     "insert or replace into mistrusted_keys (fpr) "
   456     "   values (upper(replace(?1,' ',''))) ;";
   457         
   458 static const char *sql_delete_mistrusted_key = 
   459     "delete from mistrusted_keys where fpr = upper(replace(?1,' ','')) ;";
   460 
   461 static const char *sql_is_mistrusted_key = 
   462     "select count(*) from mistrusted_keys where fpr = upper(replace(?1,' ','')) ;";
   463 
   464 static const char *sql_add_userid_alias =
   465     "insert or replace into alternate_user_id (alternate_id, default_id) "
   466     "values (?2, ?1) ;";
   467 
   468 static const char *sql_add_into_social_graph =
   469     "insert or replace into social_graph(own_userid, own_address, contact_userid) "
   470     "values (?1, ?2, ?3) ;";
   471 
   472 static const char *sql_get_own_address_binding_from_contact =
   473     "select own_address from social_graph where own_userid = ?1 and contact_userid = ?2 ;";
   474 
   475 static const char *sql_set_revoke_contact_as_notified =
   476     "insert or replace into revocation_contact_list(fpr, contact_id) values (?1, ?2) ;";
   477     
   478 static const char *sql_get_contacted_ids_from_revoke_fpr =
   479     "select * from revocation_contact_list where fpr = ?1 ;";
   480 
   481 static const char *sql_was_id_for_revoke_contacted = 
   482     "select count(*) from revocation_contact_list where fpr = ?1 and contact_id = ?2 ;";
   483 
   484 // We only need user_id and address, since in the main usage, we'll call update_identity
   485 // on this anyway when sending out messages.
   486 static const char *sql_get_last_contacted =
   487     "select user_id, address from identity where datetime('now') < datetime(timestamp, '+14 days') ; ";
   488     
   489 static int user_version(void *_version, int count, char **text, char **name)
   490 {
   491     assert(_version);
   492     assert(count == 1);
   493     assert(text && text[0]);
   494     if (!(_version && count == 1 && text && text[0]))
   495         return -1;
   496 
   497     int *version = (int *) _version;
   498     *version = atoi(text[0]);
   499     return 0;
   500 }
   501 
   502 // TODO: refactor and generalise these two functions if possible.
   503 static int db_contains_table(PEP_SESSION session, const char* table_name) {
   504     if (!session || !table_name)
   505         return -1;
   506     
   507     // Table names can't be SQL parameters, so we do it this way.
   508     
   509     // these two must be the same number.
   510     char sql_buf[500];
   511     const size_t max_q_len = 500;
   512     
   513     size_t t_size, q_size;
   514     
   515     const char* q1 = "SELECT name FROM sqlite_master WHERE type='table' AND name='{"; // 61
   516     const char* q2 = "}';";       // 3
   517     
   518     q_size = 64;
   519     t_size = strlen(table_name);
   520     
   521     size_t query_len = q_size + t_size + 1;
   522 
   523     if (query_len > max_q_len)
   524         return -1;
   525 
   526     strlcpy(sql_buf, q1, max_q_len);
   527     strlcat(sql_buf, table_name, max_q_len);
   528     strlcat(sql_buf, q2, max_q_len);
   529 
   530     sqlite3_stmt *stmt; 
   531 
   532     sqlite3_prepare_v2(session->db, sql_buf, -1, &stmt, NULL);
   533 
   534     int retval = 0;
   535 
   536     int rc = Sqlite3_step(stmt);  
   537     if (rc == SQLITE_DONE || rc == SQLITE_OK || rc == SQLITE_ROW) {
   538         retval = 1;
   539     }
   540 
   541     sqlite3_finalize(stmt);      
   542         
   543     return retval;
   544         
   545 }
   546 
   547 static int table_contains_column(PEP_SESSION session, const char* table_name,
   548                                                       const char* col_name) {
   549 
   550 
   551     if (!session || !table_name || !col_name)
   552         return -1;
   553         
   554     // Table names can't be SQL parameters, so we do it this way.
   555     
   556     // these two must be the same number.
   557     char sql_buf[500];
   558     const size_t max_q_len = 500;
   559     
   560     size_t t_size, c_size, q_size;
   561     
   562     const char* q1 = "SELECT "; // 7
   563     const char* q2 = " from "; // 6
   564     const char* q3 = ";";       // 1
   565     
   566     q_size = 14;
   567     t_size = strlen(table_name);
   568     c_size = strlen(col_name);
   569     
   570     size_t query_len = q_size + c_size + t_size + 1;
   571     
   572     if (query_len > max_q_len)
   573         return -1;
   574 
   575     strlcpy(sql_buf, q1, max_q_len);
   576     strlcat(sql_buf, col_name, max_q_len);
   577     strlcat(sql_buf, q2, max_q_len);
   578     strlcat(sql_buf, table_name, max_q_len);
   579     strlcat(sql_buf, q3, max_q_len);
   580 
   581     sqlite3_stmt *stmt; 
   582 
   583     sqlite3_prepare_v2(session->db, sql_buf, -1, &stmt, NULL);
   584 
   585     int retval = 0;
   586 
   587     int rc = Sqlite3_step(stmt);  
   588     if (rc == SQLITE_DONE || rc == SQLITE_OK || rc == SQLITE_ROW) {
   589         retval = 1;
   590     }
   591 
   592     sqlite3_finalize(stmt);      
   593         
   594     return retval;
   595 }
   596 
   597 PEP_STATUS repair_altered_tables(PEP_SESSION session) {
   598     PEP_STATUS status = PEP_STATUS_OK;
   599     
   600     const unsigned int _PEP_MAX_AFFECTED = 5;
   601     char** table_names = calloc(_PEP_MAX_AFFECTED, sizeof(char*));
   602     if (!table_names)
   603         return PEP_OUT_OF_MEMORY;
   604 
   605     const char* sql_query = "select tbl_name from sqlite_master WHERE sql LIKE '%REFERENCES%' AND sql LIKE '%_old%';";
   606     sqlite3_stmt *stmt; 
   607     sqlite3_prepare_v2(session->db, sql_query, -1, &stmt, NULL);
   608     int i = 0;
   609     int int_result = 0;
   610     while ((int_result = Sqlite3_step(stmt)) == SQLITE_ROW && i < _PEP_MAX_AFFECTED) {
   611         table_names[i++] = strdup((const char*)(sqlite3_column_text(stmt, 0)));
   612     }
   613     
   614     sqlite3_finalize(stmt);      
   615 
   616     if ((int_result != SQLITE_DONE && int_result != SQLITE_OK) || i > (_PEP_MAX_AFFECTED + 1)) {
   617         status = PEP_UNKNOWN_DB_ERROR;
   618         goto pEp_free;
   619     }
   620         
   621     for (i = 0; i < _PEP_MAX_AFFECTED; i++) {
   622         const char* table_name = table_names[i];
   623         if (!table_name)
   624             break;
   625             
   626         if (strcmp(table_name, "identity") == 0) {
   627             int_result = sqlite3_exec(session->db,
   628                 "PRAGMA foreign_keys=off;\n"
   629                 "BEGIN TRANSACTION;\n"
   630                 "create table _identity_new (\n"
   631                 "   address text,\n"
   632                 "   user_id text\n"
   633                 "       references person (id)\n"
   634                 "       on delete cascade on update cascade,\n"
   635                 "   main_key_id text\n"
   636                 "       references pgp_keypair (fpr)\n"
   637                 "       on delete set null,\n"
   638                 "   comment text,\n"
   639                 "   flags integer default 0,\n"
   640                 "   is_own integer default 0,\n"
   641                 "   timestamp integer default (datetime('now')),\n"
   642                 "   primary key (address, user_id)\n"
   643                 ");\n"
   644                 "INSERT INTO _identity_new SELECT * from identity;\n"
   645                 "DROP TABLE identity;\n"
   646                 "ALTER TABLE _identity_new RENAME TO identity;\n"
   647                 "COMMIT;\n"
   648                 "PRAGMA foreign_keys=on;"
   649                 ,
   650                 NULL,
   651                 NULL,
   652                 NULL
   653             );
   654             assert(int_result == PEP_STATUS_OK);
   655         }
   656         else if (strcmp(table_name, "trust") == 0) {
   657             int_result = sqlite3_exec(session->db,
   658                 "PRAGMA foreign_keys=off;\n"
   659                 "BEGIN TRANSACTION;\n"
   660                 "create table _trust_new (\n"
   661                 "   user_id text not null\n"
   662                 "       references person (id)\n"
   663                 "       on delete cascade on update cascade,\n"
   664                 "   pgp_keypair_fpr text not null\n"
   665                 "       references pgp_keypair (fpr)\n"
   666                 "       on delete cascade,\n"
   667                 "   comm_type integer not null,\n"
   668                 "   comment text,\n"
   669                 "   primary key (user_id, pgp_keypair_fpr)\n"                
   670                 ");\n"
   671                 "INSERT INTO _trust_new SELECT * from trust;\n"
   672                 "DROP TABLE trust;\n"
   673                 "ALTER TABLE _trust_new RENAME TO trust;\n"
   674                 "COMMIT;\n"
   675                 "PRAGMA foreign_keys=on;"
   676                 ,
   677                 NULL,
   678                 NULL,
   679                 NULL
   680             );             
   681             assert(int_result == PEP_STATUS_OK);                       
   682         }
   683         else if (strcmp(table_name, "alternate_user_id") == 0) {
   684             int_result = sqlite3_exec(session->db,
   685                 "PRAGMA foreign_keys=off;\n"
   686                 "BEGIN TRANSACTION;\n"
   687                 "create table _alternate_user_id_new (\n"
   688                 "    default_id text references person (id)\n"
   689                 "       on delete cascade on update cascade,\n"
   690                 "    alternate_id text primary key\n"
   691                 ");\n"
   692                 "INSERT INTO _alternate_user_id_new SELECT * from alternate_user_id;\n"
   693                 "DROP TABLE alternate_user_id;\n"
   694                 "ALTER TABLE _alternate_user_id_new RENAME TO alternate_user_id;\n"
   695                 "COMMIT;\n"
   696                 "PRAGMA foreign_keys=on;"                
   697                 ,
   698                 NULL,
   699                 NULL,
   700                 NULL
   701             );
   702             assert(int_result == PEP_STATUS_OK);
   703         }
   704         else if (strcmp(table_name, "revocation_contact_list") == 0) {
   705             int_result = sqlite3_exec(session->db,
   706                 "PRAGMA foreign_keys=off;\n"
   707                 "BEGIN TRANSACTION;\n"
   708                 "create table _revocation_contact_list_new (\n"
   709                 "   fpr text not null references pgp_keypair (fpr)\n"
   710                 "       on delete cascade,\n"
   711                 "   contact_id text not null references person (id)\n"
   712                 "       on delete cascade on update cascade,\n"
   713                 "   timestamp integer default (datetime('now')),\n"
   714                 "   PRIMARY KEY(fpr, contact_id)\n"            
   715                 ");\n"
   716                 "INSERT INTO _revocation_contact_list_new SELECT * from revocation_contact_list;\n"
   717                 "DROP TABLE revocation_contact_list;\n"
   718                 "ALTER TABLE _revocation_contact_list_new RENAME TO revocation_contact_list;\n"
   719                 "COMMIT;\n"
   720                 "PRAGMA foreign_keys=on;"                
   721                 ,
   722                 NULL,
   723                 NULL,
   724                 NULL
   725             );      
   726             assert(int_result == PEP_STATUS_OK);                              
   727         }
   728         else if (strcmp(table_name, "social_graph")) {
   729             int_result = sqlite3_exec(session->db,
   730                 "PRAGMA foreign_keys=off;\n"
   731                 "BEGIN TRANSACTION;\n"
   732                 "create table _social_new (\n"
   733                 "    own_userid text,\n"
   734                 "    own_address text,\n"
   735                 "    contact_userid text,\n"
   736                 "    CONSTRAINT fk_own_identity\n"
   737                 "       FOREIGN KEY(own_address, own_userid)\n" 
   738                 "       REFERENCES identity(address, user_id)\n"
   739                 "       ON DELETE CASCADE ON UPDATE CASCADE\n"
   740                 ");\n"
   741                 "INSERT INTO _social_graph_new SELECT * from social_graph;\n"
   742                 "DROP TABLE social_graph;\n"
   743                 "ALTER TABLE _social_graph_new RENAME TO social_graph;\n"
   744                 "COMMIT;\n"
   745                 "PRAGMA foreign_keys=on;"                
   746                 ,
   747                 NULL,
   748                 NULL,
   749                 NULL
   750             );
   751             assert(int_result == PEP_STATUS_OK);                                    
   752         }        
   753     }
   754     
   755     int_result = sqlite3_exec(
   756         session->db,
   757         "PRAGMA foreign_key_check;\n"
   758         ,
   759         NULL,
   760         NULL,
   761         NULL
   762     );
   763     assert(int_result == SQLITE_OK);
   764 
   765 pEp_free:
   766     for (i = 0; i < _PEP_MAX_AFFECTED; i++) {
   767         if (table_names[i])
   768             free(table_names[i]);
   769         else
   770             break;
   771     }
   772     free(table_names);
   773     return status;
   774 }
   775 void errorLogCallback(void *pArg, int iErrCode, const char *zMsg){
   776   fprintf(stderr, "(%d) %s\n", iErrCode, zMsg);
   777 }
   778 
   779 #ifdef USE_GPG
   780 PEP_STATUS pgp_import_ultimately_trusted_keypairs(PEP_SESSION session);
   781 #endif // USE_GPG
   782 
   783 DYNAMIC_API PEP_STATUS init(
   784         PEP_SESSION *session,
   785         messageToSend_t messageToSend,
   786         inject_sync_event_t inject_sync_event
   787     )
   788 {
   789     PEP_STATUS status = PEP_STATUS_OK;
   790     int int_result;
   791     
   792     bool in_first = false;
   793     bool very_first = false;
   794 
   795     assert(sqlite3_threadsafe());
   796     if (!sqlite3_threadsafe())
   797         return PEP_INIT_SQLITE3_WITHOUT_MUTEX;
   798 
   799     // a little race condition - but still a race condition
   800     // mitigated by calling caveat (see documentation)
   801 
   802     // this increment is made atomic IN THE ADAPTERS by
   803     // guarding the call to init with the appropriate mutex.
   804     int _count = ++init_count;
   805     if (_count == 0)
   806         in_first = true;
   807     
   808     // Race condition mitigated by calling caveat starts here :
   809     // If another call to init() preempts right now, then preemptive call
   810     // will have in_first false, will not create SQL tables, and following
   811     // calls relying on those tables will fail.
   812     //
   813     // Therefore, as above, adapters MUST guard init() with a mutex.
   814     // 
   815     // Therefore, first session
   816     // is to be created and last session to be deleted alone, and not
   817     // concurently to other sessions creation or deletion.
   818     // We expect adapters to enforce this either by implicitely creating a
   819     // client session, or by using synchronization primitive to protect
   820     // creation/deletion of first/last session from the app.
   821 
   822     assert(session);
   823     if (session == NULL)
   824         return PEP_ILLEGAL_VALUE;
   825 
   826     *session = NULL;
   827 
   828     pEpSession *_session = calloc(1, sizeof(pEpSession));
   829     assert(_session);
   830     if (_session == NULL)
   831         goto enomem;
   832 
   833     _session->version = PEP_ENGINE_VERSION;
   834     _session->messageToSend = messageToSend;
   835     _session->inject_sync_event = inject_sync_event;
   836 
   837 #ifdef DEBUG_ERRORSTACK
   838     _session->errorstack = new_stringlist("init()");
   839 #endif
   840 
   841     assert(LOCAL_DB);
   842     if (LOCAL_DB == NULL) {
   843         status = PEP_INIT_CANNOT_OPEN_DB;
   844         goto pEp_error;
   845     }
   846     
   847 #if _PEP_SQLITE_DEBUG    
   848     sqlite3_config(SQLITE_CONFIG_LOG, errorLogCallback, NULL);
   849 #endif
   850 
   851     int_result = sqlite3_open_v2(
   852             LOCAL_DB,
   853             &_session->db,
   854             SQLITE_OPEN_READWRITE
   855                 | SQLITE_OPEN_CREATE
   856                 | SQLITE_OPEN_FULLMUTEX
   857                 | SQLITE_OPEN_PRIVATECACHE,
   858             NULL 
   859         );
   860 
   861     if (int_result != SQLITE_OK) {
   862         status = PEP_INIT_CANNOT_OPEN_DB;
   863         goto pEp_error;
   864     }
   865 
   866     int_result = sqlite3_exec(
   867             _session->db,
   868             "PRAGMA locking_mode=NORMAL;\n"
   869             "PRAGMA journal_mode=WAL;\n",
   870             NULL,
   871             NULL,
   872             NULL
   873         );
   874 
   875 
   876     sqlite3_busy_timeout(_session->db, BUSY_WAIT_TIME);
   877 
   878 #if _PEP_SQLITE_DEBUG
   879     sqlite3_trace_v2(_session->db, 
   880         SQLITE_TRACE_STMT | SQLITE_TRACE_ROW | SQLITE_TRACE_CLOSE,
   881         sql_trace_callback,
   882         NULL);
   883 #endif
   884 
   885     assert(SYSTEM_DB);
   886     if (SYSTEM_DB == NULL) {
   887         status = PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
   888         goto pEp_error;
   889     }
   890 
   891     int_result = sqlite3_open_v2(
   892             SYSTEM_DB, &_session->system_db,
   893             SQLITE_OPEN_READONLY
   894                 | SQLITE_OPEN_FULLMUTEX
   895                 | SQLITE_OPEN_SHAREDCACHE,
   896             NULL
   897         );
   898 
   899     if (int_result != SQLITE_OK) {
   900         status = PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
   901         goto pEp_error;
   902     }
   903 
   904     sqlite3_busy_timeout(_session->system_db, 1000);
   905 
   906 // increment this when patching DDL
   907 #define _DDL_USER_VERSION "11"
   908 
   909     if (in_first) {
   910 
   911         int_result = sqlite3_exec(
   912             _session->db,
   913                 "create table if not exists version_info (\n"
   914                 "   id integer primary key,\n"
   915                 "   timestamp integer default (datetime('now')),\n"
   916                 "   version text,\n"
   917                 "   comment text\n"
   918                 ");\n",
   919                 NULL,
   920                 NULL,
   921                 NULL
   922         );
   923         int_result = sqlite3_exec(
   924             _session->db,
   925                 "PRAGMA application_id = 0x23423423;\n"
   926                 "create table if not exists log (\n"
   927                 "   timestamp integer default (datetime('now')),\n"
   928                 "   title text not null,\n"
   929                 "   description text,\n"
   930                 "   entity text not null,\n"
   931                 "   comment text\n"
   932                 ");\n"
   933                 "create index if not exists log_timestamp on log (\n"
   934                 "   timestamp\n"
   935                 ");\n"
   936                 "create table if not exists pgp_keypair (\n"
   937                 "   fpr text primary key,\n"
   938                 "   created integer,\n"
   939                 "   expires integer,\n"
   940                 "   comment text,\n"
   941                 "   flags integer default 0\n"
   942                 ");\n"
   943                 "create index if not exists pgp_keypair_expires on pgp_keypair (\n"
   944                 "   expires\n"
   945                 ");\n"
   946                 "create table if not exists person (\n"
   947                 "   id text primary key,\n"
   948                 "   username text not null,\n"
   949                 "   main_key_id text\n"
   950                 "       references pgp_keypair (fpr)\n"
   951                 "       on delete set null,\n"
   952                 "   lang text,\n"
   953                 "   comment text,\n"
   954 //                "   device_group text,\n"
   955                 "   is_pEp_user integer default 0\n"
   956                 ");\n"
   957                 "create table if not exists identity (\n"
   958                 "   address text,\n"
   959                 "   user_id text\n"
   960                 "       references person (id)\n"
   961                 "       on delete cascade on update cascade,\n"
   962                 "   main_key_id text\n"
   963                 "       references pgp_keypair (fpr)\n"
   964                 "       on delete set null,\n"
   965                 "   comment text,\n"
   966                 "   flags integer default 0,\n"
   967                 "   is_own integer default 0,\n"
   968                 "   timestamp integer default (datetime('now')),\n"
   969                 "   primary key (address, user_id)\n"
   970                 ");\n"
   971                 "create table if not exists trust (\n"
   972                 "   user_id text not null\n"
   973                 "       references person (id)\n"
   974                 "       on delete cascade on update cascade,\n"
   975                 "   pgp_keypair_fpr text not null\n"
   976                 "       references pgp_keypair (fpr)\n"
   977                 "       on delete cascade,\n"
   978                 "   comm_type integer not null,\n"
   979                 "   comment text,\n"
   980                 "   primary key (user_id, pgp_keypair_fpr)\n"
   981                 ");\n"
   982                 // blacklist
   983                 "create table if not exists blacklist_keys (\n"
   984                 "   fpr text primary key\n"
   985                 ");\n"
   986                 // sequences
   987                 "create table if not exists sequences(\n"
   988                 "   name text primary key,\n"
   989                 "   value integer default 0\n"
   990                 ");\n"
   991                 "create table if not exists revoked_keys (\n"
   992                 "   revoked_fpr text primary key,\n"
   993                 "   replacement_fpr text not null\n"
   994                 "       references pgp_keypair (fpr)\n"
   995                 "       on delete cascade,\n"
   996                 "   revocation_date integer\n"
   997                 ");\n"
   998                 // user id aliases
   999                 "create table if not exists alternate_user_id (\n"
  1000                 "    default_id text references person (id)\n"
  1001                 "       on delete cascade on update cascade,\n"
  1002                 "    alternate_id text primary key\n"
  1003                 ");\n"
  1004                 // mistrusted keys
  1005                 "create table if not exists mistrusted_keys (\n"
  1006                 "    fpr text primary key\n"
  1007                 ");\n"
  1008                 // social graph for key resets
  1009                 "create table if not exists social_graph (\n"
  1010                 "    own_userid text,\n"
  1011                 "    own_address text,\n"
  1012                 "    contact_userid text,\n"
  1013                 "    CONSTRAINT fk_own_identity\n"
  1014                 "       FOREIGN KEY(own_address, own_userid)\n" 
  1015                 "       REFERENCES identity(address, user_id)\n"
  1016                 "       ON DELETE CASCADE ON UPDATE CASCADE\n"
  1017                 ");\n"
  1018                 // list of user_ids sent revocation
  1019                 "create table if not exists revocation_contact_list (\n"
  1020                 "   fpr text not null references pgp_keypair (fpr)\n"
  1021                 "       on delete cascade,\n"
  1022                 "   contact_id text not null references person (id)\n"
  1023                 "       on delete cascade on update cascade,\n"
  1024                 "   timestamp integer default (datetime('now')),\n"
  1025                 "   PRIMARY KEY(fpr, contact_id)\n"
  1026                 ");\n"
  1027                 ,
  1028             NULL,
  1029             NULL,
  1030             NULL
  1031         );
  1032         assert(int_result == SQLITE_OK);
  1033 
  1034         int version;
  1035         int_result = sqlite3_exec(
  1036             _session->db,
  1037             "pragma user_version;",
  1038             user_version,
  1039             &version,
  1040             NULL
  1041         );
  1042 
  1043         assert(int_result == SQLITE_OK);
  1044         
  1045         void (*xFunc_lower)(sqlite3_context*,int,sqlite3_value**) = &_sql_lower;
  1046         
  1047         int_result = sqlite3_create_function_v2(
  1048             _session->db,
  1049             "lower",
  1050             1,
  1051             SQLITE_UTF8 | SQLITE_DETERMINISTIC,
  1052             NULL,
  1053             xFunc_lower,
  1054             NULL,
  1055             NULL,
  1056             NULL);
  1057         assert(int_result == SQLITE_OK);
  1058 
  1059         int_result = sqlite3_exec(
  1060             _session->db,
  1061             "pragma foreign_keys=ON;\n",
  1062             NULL,
  1063             NULL,
  1064             NULL
  1065         );
  1066 
  1067         assert(int_result == SQLITE_OK);
  1068 
  1069         
  1070         // Sometimes the user_version wasn't set correctly. 
  1071         if (version == 1) {
  1072             bool version_changed = true;
  1073             if (db_contains_table(_session, "social_graph") > 0) {
  1074                 if (!table_contains_column(_session, "person", "device_group"))
  1075                     version = 10;
  1076                 else
  1077                     version = 9;
  1078             }            
  1079             else if (table_contains_column(_session, "identity", "timestamp") > 0) {
  1080                 version = 8;
  1081             }            
  1082             else if (table_contains_column(_session, "person", "is_pEp_user") > 0) {
  1083                 version = 7;
  1084             }            
  1085             else if (table_contains_column(_session, "identity", "is_own") > 0) {
  1086                 version = 6;
  1087             }
  1088             else if (table_contains_column(_session, "pgp_keypair", "flags") > 0) {
  1089                 version = 2;
  1090             }
  1091             else {
  1092                 version_changed = false;
  1093             }
  1094             
  1095             if (version_changed) {
  1096                 // set it in the DB, finally. Yeesh.
  1097                 char verbuf[21]; // enough digits for a max-sized 64 bit int, cmon. 
  1098                 sprintf(verbuf,"%d",version);
  1099                 
  1100                 size_t query_size = strlen(verbuf) + 25;
  1101                 char* query = calloc(query_size, 1);
  1102                 
  1103                 strlcpy(query, "pragma user_version = ", query_size);
  1104                 strlcat(query, verbuf, query_size);
  1105                 strlcat(query, ";", query_size);
  1106                 
  1107                 int_result = sqlite3_exec(
  1108                     _session->db,
  1109                     query,
  1110                     user_version,
  1111                     &version,
  1112                     NULL
  1113                 );
  1114                 free(query);
  1115             }
  1116         }
  1117 
  1118 
  1119         if(version != 0) { 
  1120             // Version has been already set
  1121 
  1122             // Early mistake : version 0 shouldn't have existed.
  1123             // Numbering should have started at 1 to detect newly created DB.
  1124             // Version 0 DBs are not anymore compatible.
  1125 
  1126             // // Was version 0 compat code.
  1127             // if (version < 1) {
  1128             //     int_result = sqlite3_exec(
  1129             //         _session->db,
  1130             //         "alter table identity\n"
  1131             //         "   add column flags integer default 0;\n",
  1132             //         NULL,
  1133             //         NULL,
  1134             //         NULL
  1135             //     );
  1136             //     assert(int_result == SQLITE_OK);
  1137             // }
  1138             
  1139             if (version < 2) {
  1140                 // N.B. addition of device_group column removed in DDL v10
  1141                 int_result = sqlite3_exec(
  1142                     _session->db,
  1143                     "alter table pgp_keypair\n"
  1144                     "   add column flags integer default 0;\n",
  1145                     // "alter table person\n"
  1146                     // "   add column device_group text;\n",
  1147                     NULL,
  1148                     NULL,
  1149                     NULL
  1150                 );
  1151                 assert(int_result == SQLITE_OK);
  1152             }
  1153 
  1154             if (version < 5) {
  1155                 int_result = sqlite3_exec(
  1156                     _session->db,
  1157                     "delete from pgp_keypair where fpr = '';",
  1158                     NULL,
  1159                     NULL,
  1160                     NULL
  1161                 );
  1162                 assert(int_result == SQLITE_OK);
  1163                 int_result = sqlite3_exec(
  1164                     _session->db,
  1165                     "delete from trust where pgp_keypair_fpr = '';",
  1166                     NULL,
  1167                     NULL,
  1168                     NULL
  1169                 );
  1170                 assert(int_result == SQLITE_OK);
  1171             }
  1172             
  1173             if (version < 6) {
  1174                 int_result = sqlite3_exec(
  1175                     _session->db,
  1176                     "alter table identity\n"
  1177                     "   add column is_own integer default 0;\n",
  1178                     NULL,
  1179                     NULL,
  1180                     NULL
  1181                 );
  1182                 assert(int_result == SQLITE_OK);                
  1183                 int_result = sqlite3_exec(
  1184                     _session->db,
  1185                     "update identity\n"
  1186                     "   set is_own = 1\n"
  1187                     "   where (user_id = '" PEP_OWN_USERID "');\n",
  1188                     NULL,
  1189                     NULL,
  1190                     NULL
  1191                 );
  1192                 assert(int_result == SQLITE_OK);    
  1193 
  1194                 // Turns out that just adding "on update cascade" in
  1195                 // sqlite is a PITA. We need to be able to cascade
  1196                 // person->id replacements (for temp ids like "TOFU_")
  1197                 // so here we go...
  1198                 int_result = sqlite3_exec(
  1199                     _session->db,
  1200                     "PRAGMA foreign_keys=off;\n"
  1201                     "BEGIN TRANSACTION;\n"
  1202                     "create table _identity_new (\n"
  1203                     "   address text,\n"
  1204                     "   user_id text\n"
  1205                     "       references person (id)\n"
  1206                     "       on delete cascade on update cascade,\n"
  1207                     "   main_key_id text\n"
  1208                     "       references pgp_keypair (fpr)\n"
  1209                     "       on delete set null,\n"
  1210                     "   comment text,\n"
  1211                     "   flags integer default 0,\n"
  1212                     "   is_own integer default 0,\n"
  1213                     "   primary key (address, user_id)\n"
  1214                     ");\n"                    
  1215                     "INSERT INTO _identity_new SELECT * FROM identity;\n"
  1216                     "DROP TABLE identity;\n"
  1217                     "ALTER TABLE _identity_new RENAME TO identity;\n"
  1218                     "COMMIT;\n"
  1219                     "\n"
  1220                     "BEGIN TRANSACTION;\n"
  1221                     "create table _trust_new (\n"
  1222                     "   user_id text not null\n"
  1223                     "       references person (id)\n"
  1224                     "       on delete cascade on update cascade,\n"
  1225                     "   pgp_keypair_fpr text not null\n"
  1226                     "       references pgp_keypair (fpr)\n"
  1227                     "       on delete cascade,\n"
  1228                     "   comm_type integer not null,\n"
  1229                     "   comment text,\n"
  1230                     "   primary key (user_id, pgp_keypair_fpr)\n"
  1231                     ");\n"
  1232                     "INSERT INTO _trust_new SELECT * FROM trust;\n"
  1233                     "DROP TABLE trust;\n"
  1234                     "ALTER TABLE _trust_new RENAME TO trust;\n"
  1235                     "COMMIT;\n"
  1236                     "\n"
  1237                     "PRAGMA foreign_keys=on;\n"
  1238                     "create table if not exists alternate_user_id (\n"
  1239                     "    default_id text references person (id)\n"
  1240                     "       on delete cascade on update cascade,\n"
  1241                     "    alternate_id text primary key\n"
  1242                     ");\n"
  1243                     ,
  1244                     NULL,
  1245                     NULL,
  1246                     NULL
  1247                 );
  1248                 assert(int_result == SQLITE_OK);   
  1249                 
  1250                 int_result = sqlite3_exec(
  1251                     _session->db,
  1252                     "PRAGMA foreign_key_check;\n"
  1253                     ,
  1254                     NULL,
  1255                     NULL,
  1256                     NULL
  1257                 );
  1258                 assert(int_result == SQLITE_OK);
  1259 
  1260                 // FIXME: foreign key check here 
  1261             }
  1262             if (version < 7) {
  1263                 int_result = sqlite3_exec(
  1264                     _session->db,
  1265                     "alter table person\n"
  1266                     "   add column is_pEp_user integer default 0;\n",
  1267                     NULL,
  1268                     NULL,
  1269                     NULL
  1270                 );
  1271                 assert(int_result == SQLITE_OK);
  1272                 int_result = sqlite3_exec(
  1273                     _session->db,
  1274                     "update person\n"
  1275                     "   set is_pEp_user = 1\n"
  1276                     "   where id = "
  1277                     "       (select distinct id from person "
  1278                     "               join trust on id = user_id "
  1279                     "               where (case when (comm_type = 127) then (id) "
  1280                     "                           when (comm_type = 255) then (id) "
  1281                     "                           else 0"
  1282                     "                      end) = id );\n",
  1283                     NULL,
  1284                     NULL,
  1285                     NULL
  1286                 );
  1287                 assert(int_result == SQLITE_OK);
  1288                 
  1289                 int_result = sqlite3_exec(
  1290                     _session->db,
  1291                     "create table if not exists mistrusted_keys (\n"
  1292                     "    fpr text primary key\n"
  1293                     ");\n",            
  1294                     NULL,
  1295                     NULL,
  1296                     NULL
  1297                 );
  1298                 assert(int_result == SQLITE_OK);    
  1299             }
  1300             if (version < 8) {
  1301                 int_result = sqlite3_exec(
  1302                     _session->db,
  1303                     "PRAGMA foreign_keys=off;\n"
  1304                     "BEGIN TRANSACTION;\n"
  1305                     "create table _identity_new (\n"
  1306                     "   address text,\n"
  1307                     "   user_id text\n"
  1308                     "       references person (id)\n"
  1309                     "       on delete cascade on update cascade,\n"
  1310                     "   main_key_id text\n"
  1311                     "       references pgp_keypair (fpr)\n"
  1312                     "       on delete set null,\n"
  1313                     "   comment text,\n"
  1314                     "   flags integer default 0,\n"
  1315                     "   is_own integer default 0,\n"
  1316                     "   timestamp integer default (datetime('now')),\n"
  1317                     "   primary key (address, user_id)\n"
  1318                     ");\n"
  1319                     "INSERT INTO _identity_new (address, user_id, main_key_id, "
  1320                     "                      comment, flags, is_own) "
  1321                     "   SELECT identity.address, identity.user_id, "
  1322                     "          identity.main_key_id, identity.comment, "
  1323                     "          identity.flags, identity.is_own "
  1324                     "   FROM identity "
  1325                     "   WHERE 1;\n"
  1326                     "DROP TABLE identity;\n"
  1327                     "ALTER TABLE _identity_new RENAME TO identity;\n"
  1328                     "COMMIT;\n"
  1329                     "\n"
  1330                     "PRAGMA foreign_keys=on;\n"
  1331                     ,
  1332                     NULL,
  1333                     NULL,
  1334                     NULL
  1335                 );
  1336                 assert(int_result == SQLITE_OK);    
  1337                 
  1338                 int_result = sqlite3_exec(
  1339                     _session->db,
  1340                     "PRAGMA foreign_key_check;\n"
  1341                     ,
  1342                     NULL,
  1343                     NULL,
  1344                     NULL
  1345                 );
  1346                 assert(int_result == SQLITE_OK);
  1347 
  1348                 // FIXME: foreign key check
  1349             }
  1350             if (version < 9) {
  1351                 int_result = sqlite3_exec(
  1352                     _session->db,
  1353                     "create table if not exists social_graph (\n"
  1354                     "    own_userid text,\n"
  1355                     "    own_address text,\n"
  1356                     "    contact_userid text,\n"
  1357                     "    CONSTRAINT fk_own_identity\n"
  1358                     "       FOREIGN KEY(own_address, own_userid)\n" 
  1359                     "       REFERENCES identity(address, user_id)\n"
  1360                     "       ON DELETE CASCADE ON UPDATE CASCADE\n"
  1361                     ");\n"
  1362                     "create table if not exists revocation_contact_list (\n"
  1363                     "   fpr text not null references pgp_keypair (fpr)\n"
  1364                     "       on delete cascade,\n"
  1365                     "   contact_id text not null references person (id)\n"
  1366                     "       on delete cascade on update cascade,\n"
  1367                     "   timestamp integer default (datetime('now')),\n"
  1368                     "   PRIMARY KEY(fpr, contact_id)\n"
  1369                     ");\n"
  1370                     ,
  1371                     NULL,
  1372                     NULL,
  1373                     NULL
  1374                 );
  1375                 assert(int_result == SQLITE_OK);    
  1376             }
  1377             if (version < 10 && version > 1) {
  1378                 int_result = sqlite3_exec(
  1379                     _session->db,
  1380                     "PRAGMA foreign_keys=off;\n"
  1381                     "BEGIN TRANSACTION;\n"
  1382                     "create table _person_new (\n"
  1383                     "   id text primary key,\n"
  1384                     "   username text not null,\n"
  1385                     "   main_key_id text\n"
  1386                     "       references pgp_keypair (fpr)\n"
  1387                     "       on delete set null,\n"
  1388                     "   lang text,\n"
  1389                     "   comment text,\n"
  1390                     "   is_pEp_user integer default 0\n"
  1391                     ");\n"
  1392                     "INSERT INTO _person_new (id, username, main_key_id, "
  1393                     "                    lang, comment, is_pEp_user) "
  1394                     "   SELECT person.id, person.username, "
  1395                     "          person.main_key_id, person.lang, "
  1396                     "          person.comment, person.is_pEp_user "
  1397                     "   FROM person "
  1398                     "   WHERE 1;\n"
  1399                     "DROP TABLE person;\n"
  1400                     "ALTER TABLE _person_new RENAME TO person;\n"
  1401                     "COMMIT;\n"
  1402                     "\n"
  1403                     "PRAGMA foreign_keys=on;\n"
  1404                     ,
  1405                     NULL,
  1406                     NULL,
  1407                     NULL
  1408                 );
  1409                 assert(int_result == SQLITE_OK);    
  1410                 int_result = sqlite3_exec(
  1411                     _session->db,
  1412                     "PRAGMA foreign_key_check;\n"
  1413                     ,
  1414                     NULL,
  1415                     NULL,
  1416                     NULL
  1417                 );
  1418                 assert(int_result == SQLITE_OK);
  1419             }
  1420             if (version < 11) {
  1421                 status = repair_altered_tables(_session);
  1422                 assert(status == PEP_STATUS_OK);
  1423                 if (status != PEP_STATUS_OK)
  1424                     return status;
  1425             }
  1426         }        
  1427         else { 
  1428             // Version from DB was 0, it means this is initial setup.
  1429             // DB has just been created, and all tables are empty.
  1430             very_first = true;
  1431         }
  1432 
  1433         if (version < atoi(_DDL_USER_VERSION)) {
  1434             int_result = sqlite3_exec(
  1435                 _session->db,
  1436                 "pragma user_version = "_DDL_USER_VERSION";\n"
  1437                 "insert or replace into version_info (id, version)"
  1438                     "values (1, '" PEP_ENGINE_VERSION "');",
  1439                 NULL,
  1440                 NULL,
  1441                 NULL
  1442             );
  1443             assert(int_result == SQLITE_OK);
  1444         }
  1445         
  1446         // We need to init a few globals for message id that we'd rather not
  1447         // calculate more than once.
  1448         _init_globals();
  1449     }
  1450 
  1451     int_result = sqlite3_prepare_v2(_session->db, sql_log,
  1452             (int)strlen(sql_log), &_session->log, NULL);
  1453     assert(int_result == SQLITE_OK);
  1454 
  1455     int_result = sqlite3_prepare_v2(_session->system_db, sql_trustword,
  1456             (int)strlen(sql_trustword), &_session->trustword, NULL);
  1457     assert(int_result == SQLITE_OK);
  1458 
  1459     int_result = sqlite3_prepare_v2(_session->db, sql_get_identity,
  1460             (int)strlen(sql_get_identity), &_session->get_identity, NULL);
  1461     assert(int_result == SQLITE_OK);
  1462 
  1463     int_result = sqlite3_prepare_v2(_session->db, sql_get_identity_without_trust_check,
  1464             (int)strlen(sql_get_identity_without_trust_check), 
  1465             &_session->get_identity_without_trust_check, NULL);
  1466     assert(int_result == SQLITE_OK);
  1467 
  1468     int_result = sqlite3_prepare_v2(_session->db, sql_get_identities_by_address,
  1469             (int)strlen(sql_get_identities_by_address), 
  1470             &_session->get_identities_by_address, NULL);
  1471     assert(int_result == SQLITE_OK);
  1472     
  1473     int_result = sqlite3_prepare_v2(_session->db, sql_get_identities_by_userid,
  1474             (int)strlen(sql_get_identities_by_userid), 
  1475             &_session->get_identities_by_userid, NULL);
  1476     assert(int_result == SQLITE_OK);
  1477 
  1478     int_result = sqlite3_prepare_v2(_session->db, sql_get_identities_by_main_key_id,
  1479             (int)strlen(sql_get_identities_by_main_key_id), 
  1480             &_session->get_identities_by_main_key_id, NULL);
  1481     assert(int_result == SQLITE_OK);
  1482 
  1483     int_result = sqlite3_prepare_v2(_session->db, sql_get_user_default_key,
  1484             (int)strlen(sql_get_user_default_key), &_session->get_user_default_key, NULL);
  1485     assert(int_result == SQLITE_OK);
  1486 
  1487     int_result = sqlite3_prepare_v2(_session->db, sql_get_all_keys_for_user,
  1488             (int)strlen(sql_get_all_keys_for_user), &_session->get_all_keys_for_user, NULL);
  1489     assert(int_result == SQLITE_OK);
  1490 
  1491     int_result = sqlite3_prepare_v2(_session->db, sql_get_default_own_userid,
  1492             (int)strlen(sql_get_default_own_userid), &_session->get_default_own_userid, NULL);
  1493     assert(int_result == SQLITE_OK);
  1494     
  1495     int_result = sqlite3_prepare_v2(_session->db, sql_get_userid_alias_default,
  1496             (int)strlen(sql_get_userid_alias_default), &_session->get_userid_alias_default, NULL);
  1497     assert(int_result == SQLITE_OK);
  1498 
  1499     int_result = sqlite3_prepare_v2(_session->db, sql_add_userid_alias,
  1500             (int)strlen(sql_add_userid_alias), &_session->add_userid_alias, NULL);
  1501     assert(int_result == SQLITE_OK);
  1502 
  1503     int_result = sqlite3_prepare_v2(_session->db, sql_replace_userid,
  1504             (int)strlen(sql_replace_userid), &_session->replace_userid, NULL);
  1505     assert(int_result == SQLITE_OK);
  1506 
  1507     int_result = sqlite3_prepare_v2(_session->db, sql_delete_key,
  1508             (int)strlen(sql_delete_key), &_session->delete_key, NULL);
  1509     assert(int_result == SQLITE_OK);
  1510 
  1511     int_result = sqlite3_prepare_v2(_session->db, sql_replace_main_user_fpr,
  1512             (int)strlen(sql_replace_main_user_fpr), &_session->replace_main_user_fpr, NULL);
  1513     assert(int_result == SQLITE_OK);
  1514 
  1515     int_result = sqlite3_prepare_v2(_session->db, sql_get_main_user_fpr,
  1516             (int)strlen(sql_get_main_user_fpr), &_session->get_main_user_fpr, NULL);
  1517     assert(int_result == SQLITE_OK);
  1518 
  1519     int_result = sqlite3_prepare_v2(_session->db, sql_refresh_userid_default_key,
  1520             (int)strlen(sql_refresh_userid_default_key), &_session->refresh_userid_default_key, NULL);
  1521     assert(int_result == SQLITE_OK);
  1522 
  1523     int_result = sqlite3_prepare_v2(_session->db, sql_replace_identities_fpr,
  1524             (int)strlen(sql_replace_identities_fpr), 
  1525             &_session->replace_identities_fpr, NULL);
  1526     assert(int_result == SQLITE_OK);
  1527     
  1528     int_result = sqlite3_prepare_v2(_session->db, sql_remove_fpr_as_default,
  1529             (int)strlen(sql_remove_fpr_as_default), 
  1530             &_session->remove_fpr_as_default, NULL);
  1531     assert(int_result == SQLITE_OK);
  1532 
  1533     int_result = sqlite3_prepare_v2(_session->db, sql_set_person,
  1534             (int)strlen(sql_set_person), &_session->set_person, NULL);
  1535     assert(int_result == SQLITE_OK);
  1536 
  1537     int_result = sqlite3_prepare_v2(_session->db, sql_update_person,
  1538             (int)strlen(sql_update_person), &_session->update_person, NULL);
  1539     assert(int_result == SQLITE_OK);
  1540 
  1541     int_result = sqlite3_prepare_v2(_session->db, sql_delete_person,
  1542             (int)strlen(sql_delete_person), &_session->delete_person, NULL);
  1543     assert(int_result == SQLITE_OK);
  1544 
  1545     int_result = sqlite3_prepare_v2(_session->db, sql_exists_person,
  1546             (int)strlen(sql_exists_person), &_session->exists_person, NULL);
  1547     assert(int_result == SQLITE_OK);
  1548 
  1549     int_result = sqlite3_prepare_v2(_session->db, sql_set_as_pEp_user,
  1550             (int)strlen(sql_set_as_pEp_user), &_session->set_as_pEp_user, NULL);
  1551     assert(int_result == SQLITE_OK);
  1552     
  1553     int_result = sqlite3_prepare_v2(_session->db, sql_is_pEp_user,
  1554             (int)strlen(sql_is_pEp_user), &_session->is_pEp_user, NULL);
  1555     assert(int_result == SQLITE_OK);
  1556 
  1557     int_result = sqlite3_prepare_v2(_session->db, sql_add_into_social_graph,
  1558             (int)strlen(sql_add_into_social_graph), &_session->add_into_social_graph, NULL);
  1559     assert(int_result == SQLITE_OK);
  1560 
  1561     int_result = sqlite3_prepare_v2(_session->db, 
  1562             sql_get_own_address_binding_from_contact,
  1563             (int)strlen(sql_get_own_address_binding_from_contact), 
  1564             &_session->get_own_address_binding_from_contact, NULL);
  1565     assert(int_result == SQLITE_OK);
  1566 
  1567     int_result = sqlite3_prepare_v2(_session->db, 
  1568             sql_set_revoke_contact_as_notified,
  1569             (int)strlen(sql_set_revoke_contact_as_notified), 
  1570             &_session->set_revoke_contact_as_notified, NULL);
  1571     assert(int_result == SQLITE_OK);
  1572 
  1573     int_result = sqlite3_prepare_v2(_session->db, 
  1574             sql_get_contacted_ids_from_revoke_fpr,
  1575             (int)strlen(sql_get_contacted_ids_from_revoke_fpr), 
  1576             &_session->get_contacted_ids_from_revoke_fpr, NULL);
  1577     assert(int_result == SQLITE_OK);
  1578 
  1579     int_result = sqlite3_prepare_v2(_session->db, 
  1580             sql_was_id_for_revoke_contacted,
  1581             (int)strlen(sql_was_id_for_revoke_contacted), 
  1582             &_session->was_id_for_revoke_contacted, NULL);
  1583     assert(int_result == SQLITE_OK);
  1584 
  1585     int_result = sqlite3_prepare_v2(_session->db, 
  1586             sql_get_last_contacted,
  1587             (int)strlen(sql_get_last_contacted), 
  1588             &_session->get_last_contacted, NULL);
  1589     assert(int_result == SQLITE_OK);
  1590 
  1591     int_result = sqlite3_prepare_v2(_session->db, 
  1592             sql_get_own_address_binding_from_contact,
  1593             (int)strlen(sql_get_own_address_binding_from_contact), 
  1594             &_session->get_own_address_binding_from_contact, NULL);
  1595     assert(int_result == SQLITE_OK);
  1596 
  1597     int_result = sqlite3_prepare_v2(_session->db, sql_set_pgp_keypair,
  1598             (int)strlen(sql_set_pgp_keypair), &_session->set_pgp_keypair,
  1599             NULL);
  1600     assert(int_result == SQLITE_OK);
  1601 
  1602     int_result = sqlite3_prepare_v2(_session->db, sql_set_identity_entry,
  1603             (int)strlen(sql_set_identity_entry), &_session->set_identity_entry, NULL);
  1604     assert(int_result == SQLITE_OK);
  1605 
  1606     int_result = sqlite3_prepare_v2(_session->db, sql_update_identity_entry,
  1607             (int)strlen(sql_update_identity_entry), &_session->update_identity_entry, NULL);
  1608     assert(int_result == SQLITE_OK);
  1609 
  1610     int_result = sqlite3_prepare_v2(_session->db, sql_exists_identity_entry,
  1611             (int)strlen(sql_exists_identity_entry), &_session->exists_identity_entry, NULL);
  1612     assert(int_result == SQLITE_OK);
  1613 
  1614     int_result = sqlite3_prepare_v2(_session->db, sql_set_identity_flags,
  1615             (int)strlen(sql_set_identity_flags), &_session->set_identity_flags,
  1616             NULL);
  1617     assert(int_result == SQLITE_OK);
  1618 
  1619     int_result = sqlite3_prepare_v2(_session->db, sql_unset_identity_flags,
  1620             (int)strlen(sql_unset_identity_flags), &_session->unset_identity_flags,
  1621             NULL);
  1622     assert(int_result == SQLITE_OK);
  1623 
  1624     int_result = sqlite3_prepare_v2(_session->db, sql_set_trust,
  1625             (int)strlen(sql_set_trust), &_session->set_trust, NULL);
  1626     assert(int_result == SQLITE_OK);
  1627 
  1628     int_result = sqlite3_prepare_v2(_session->db, sql_update_trust,
  1629             (int)strlen(sql_update_trust), &_session->update_trust, NULL);
  1630     assert(int_result == SQLITE_OK);
  1631 
  1632     int_result = sqlite3_prepare_v2(_session->db, sql_update_trust_to_pEp,
  1633             (int)strlen(sql_update_trust_to_pEp), &_session->update_trust_to_pEp, NULL);
  1634     assert(int_result == SQLITE_OK);
  1635 
  1636     int_result = sqlite3_prepare_v2(_session->db, sql_exists_trust_entry,
  1637                  (int)strlen(sql_exists_trust_entry), &_session->exists_trust_entry, NULL);
  1638     assert(int_result == SQLITE_OK);
  1639 
  1640     int_result = sqlite3_prepare_v2(_session->db, sql_update_trust_for_fpr,
  1641             (int)strlen(sql_update_trust_for_fpr), &_session->update_trust_for_fpr, NULL);
  1642     assert(int_result == SQLITE_OK);
  1643 
  1644     int_result = sqlite3_prepare_v2(_session->db, sql_get_trust,
  1645             (int)strlen(sql_get_trust), &_session->get_trust, NULL);
  1646     assert(int_result == SQLITE_OK);
  1647 
  1648     int_result = sqlite3_prepare_v2(_session->db, sql_get_trust_by_userid,
  1649             (int)strlen(sql_get_trust_by_userid), &_session->get_trust_by_userid, NULL);
  1650     assert(int_result == SQLITE_OK);
  1651 
  1652     int_result = sqlite3_prepare_v2(_session->db, sql_least_trust,
  1653             (int)strlen(sql_least_trust), &_session->least_trust, NULL);
  1654     assert(int_result == SQLITE_OK);
  1655 
  1656     int_result = sqlite3_prepare_v2(_session->db, sql_mark_as_compromised,
  1657             (int)strlen(sql_mark_as_compromised), &_session->mark_compromised,
  1658             NULL);
  1659     assert(int_result == SQLITE_OK);
  1660 
  1661     int_result = sqlite3_prepare_v2(_session->db, sql_crashdump,
  1662             (int)strlen(sql_crashdump), &_session->crashdump, NULL);
  1663     assert(int_result == SQLITE_OK);
  1664 
  1665     int_result = sqlite3_prepare_v2(_session->system_db, sql_languagelist,
  1666             (int)strlen(sql_languagelist), &_session->languagelist, NULL);
  1667     assert(int_result == SQLITE_OK);
  1668 
  1669     int_result = sqlite3_prepare_v2(_session->system_db, sql_i18n_token,
  1670             (int)strlen(sql_i18n_token), &_session->i18n_token, NULL);
  1671     assert(int_result == SQLITE_OK);
  1672     
  1673     // blacklist
  1674 
  1675     int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_add,
  1676             (int)strlen(sql_blacklist_add), &_session->blacklist_add, NULL);
  1677     assert(int_result == SQLITE_OK);
  1678 
  1679     int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_delete,
  1680             (int)strlen(sql_blacklist_delete), &_session->blacklist_delete,
  1681             NULL);
  1682     assert(int_result == SQLITE_OK);
  1683 
  1684     int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_is_listed,
  1685             (int)strlen(sql_blacklist_is_listed),
  1686             &_session->blacklist_is_listed, NULL);
  1687     assert(int_result == SQLITE_OK);
  1688 
  1689     int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_retrieve,
  1690             (int)strlen(sql_blacklist_retrieve), &_session->blacklist_retrieve,
  1691             NULL);
  1692     assert(int_result == SQLITE_OK);
  1693     
  1694     // Own keys
  1695     
  1696     int_result = sqlite3_prepare_v2(_session->db, sql_own_key_is_listed,
  1697             (int)strlen(sql_own_key_is_listed), &_session->own_key_is_listed,
  1698             NULL);
  1699     assert(int_result == SQLITE_OK);
  1700 
  1701     int_result = sqlite3_prepare_v2(_session->db, sql_is_own_address,
  1702             (int)strlen(sql_is_own_address), &_session->is_own_address,
  1703             NULL);
  1704     assert(int_result == SQLITE_OK);
  1705     
  1706     int_result = sqlite3_prepare_v2(_session->db, sql_own_identities_retrieve,
  1707             (int)strlen(sql_own_identities_retrieve),
  1708             &_session->own_identities_retrieve, NULL);
  1709     assert(int_result == SQLITE_OK);
  1710  
  1711     int_result = sqlite3_prepare_v2(_session->db, sql_own_keys_retrieve,
  1712             (int)strlen(sql_own_keys_retrieve),
  1713             &_session->own_keys_retrieve, NULL);
  1714     assert(int_result == SQLITE_OK);
  1715  
  1716     // int_result = sqlite3_prepare_v2(_session->db, sql_set_own_key,
  1717     //         (int)strlen(sql_set_own_key),
  1718     //         &_session->set_own_key, NULL);
  1719     // assert(int_result == SQLITE_OK);
  1720  
  1721     // Sequence
  1722 
  1723     int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value1,
  1724             (int)strlen(sql_sequence_value1), &_session->sequence_value1,
  1725             NULL);
  1726     assert(int_result == SQLITE_OK);
  1727 
  1728     int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value2,
  1729             (int)strlen(sql_sequence_value2), &_session->sequence_value2,
  1730             NULL);
  1731     assert(int_result == SQLITE_OK);
  1732 
  1733     // Revocation tracking
  1734     
  1735     int_result = sqlite3_prepare_v2(_session->db, sql_set_revoked,
  1736             (int)strlen(sql_set_revoked), &_session->set_revoked, NULL);
  1737     assert(int_result == SQLITE_OK);
  1738     
  1739     int_result = sqlite3_prepare_v2(_session->db, sql_get_revoked,
  1740             (int)strlen(sql_get_revoked), &_session->get_revoked, NULL);
  1741     assert(int_result == SQLITE_OK);
  1742     
  1743     int_result = sqlite3_prepare_v2(_session->db, sql_get_replacement_fpr,
  1744             (int)strlen(sql_get_replacement_fpr), &_session->get_replacement_fpr, NULL);
  1745     assert(int_result == SQLITE_OK);
  1746 
  1747     int_result = sqlite3_prepare_v2(_session->db, sql_add_mistrusted_key,
  1748             (int)strlen(sql_add_mistrusted_key), &_session->add_mistrusted_key, NULL);
  1749     assert(int_result == SQLITE_OK);
  1750 
  1751     int_result = sqlite3_prepare_v2(_session->db, sql_delete_mistrusted_key,
  1752             (int)strlen(sql_delete_mistrusted_key), &_session->delete_mistrusted_key, NULL);
  1753     assert(int_result == SQLITE_OK);
  1754 
  1755     int_result = sqlite3_prepare_v2(_session->db, sql_is_mistrusted_key,
  1756             (int)strlen(sql_is_mistrusted_key), &_session->is_mistrusted_key, NULL);
  1757     assert(int_result == SQLITE_OK);
  1758     
  1759     status = init_cryptotech(_session, in_first);
  1760     if (status != PEP_STATUS_OK)
  1761         goto pEp_error;
  1762 
  1763     status = init_transport_system(_session, in_first);
  1764     if (status != PEP_STATUS_OK)
  1765         goto pEp_error;
  1766 
  1767     status = log_event(_session, "init", "pEp " PEP_ENGINE_VERSION, NULL, NULL);
  1768     if (status != PEP_STATUS_OK)
  1769         goto pEp_error;
  1770 
  1771     // runtime config
  1772 
  1773     if (very_first)
  1774     {
  1775 #ifdef USE_GPG
  1776         // On first run, all private keys already present in PGP keyring 
  1777         // are taken as own in order to seamlessly integrate with
  1778         // pre-existing GPG setup.
  1779 
  1780         // Note: earlier fears about danger because of DB reinitialisation should
  1781         // be a non-issue here, as we ONLY take the ultimately trusted keys now.
  1782         // Thus, unless the user has assigned ultimate trust through PGP, there is
  1783         // no chance of automatically imported pEp keys from a previous run making
  1784         // their way into PEP trusted status without explicit action (Bare imported
  1785         // private keys have an 'unknown' trust designation in PGP).
  1786 
  1787         // We don't really worry about the status here.
  1788         status = pgp_import_ultimately_trusted_keypairs(_session);        
  1789 #endif // USE_GPG
  1790     }
  1791 
  1792     *session = _session;
  1793     
  1794     // Note: Following statement is NOT for any cryptographic/secure functionality; it is
  1795     //       ONLY used for some randomness in generated outer message ID, which are
  1796     //       required by the RFC to be globally unique!
  1797     srand((unsigned int) time(NULL));
  1798     
  1799     return PEP_STATUS_OK;
  1800 
  1801 enomem:
  1802     status = PEP_OUT_OF_MEMORY;
  1803 
  1804 pEp_error:
  1805     release(_session);
  1806     return status;
  1807 }
  1808 
  1809 DYNAMIC_API void release(PEP_SESSION session)
  1810 {
  1811     bool out_last = false;
  1812     int _count = --init_count;
  1813     
  1814     assert(_count >= -1);
  1815     assert(session);
  1816 
  1817     if (!((_count >= -1) && session))
  1818         return;
  1819 
  1820     // a small race condition but still a race condition
  1821     // mitigated by calling caveat (see documentation)
  1822     // (release() is to be guarded by a mutex by the caller)
  1823     if (_count == -1)
  1824         out_last = true;
  1825 
  1826     if (session) {
  1827         free_Sync_state(session);
  1828 
  1829         if (session->db) {
  1830             if (session->log)
  1831                 sqlite3_finalize(session->log);
  1832             if (session->trustword)
  1833                 sqlite3_finalize(session->trustword);
  1834             if (session->get_identity)
  1835                 sqlite3_finalize(session->get_identity);
  1836             if (session->get_identity_without_trust_check)
  1837                 sqlite3_finalize(session->get_identity_without_trust_check);
  1838             if (session->get_identities_by_address)
  1839                 sqlite3_finalize(session->get_identities_by_address);            
  1840             if (session->get_identities_by_userid)
  1841                 sqlite3_finalize(session->get_identities_by_userid);                
  1842             if (session->get_identities_by_main_key_id)
  1843                 sqlite3_finalize(session->get_identities_by_main_key_id);                                
  1844             if (session->get_user_default_key)
  1845                 sqlite3_finalize(session->get_user_default_key);
  1846             if (session->get_all_keys_for_user)
  1847                 sqlite3_finalize(session->get_all_keys_for_user);                        
  1848             if (session->get_default_own_userid)
  1849                 sqlite3_finalize(session->get_default_own_userid);
  1850             if (session->get_userid_alias_default)
  1851                 sqlite3_finalize(session->get_userid_alias_default);
  1852             if (session->add_userid_alias)
  1853                 sqlite3_finalize(session->add_userid_alias);
  1854             if (session->replace_identities_fpr)
  1855                 sqlite3_finalize(session->replace_identities_fpr);        
  1856             if (session->remove_fpr_as_default)
  1857                 sqlite3_finalize(session->remove_fpr_as_default);            
  1858             if (session->set_person)
  1859                 sqlite3_finalize(session->set_person);
  1860             if (session->delete_person)
  1861                 sqlite3_finalize(session->delete_person);                
  1862             if (session->set_as_pEp_user)
  1863                 sqlite3_finalize(session->set_as_pEp_user);
  1864             if (session->is_pEp_user)
  1865                 sqlite3_finalize(session->is_pEp_user);
  1866             if (session->exists_person)
  1867                 sqlite3_finalize(session->exists_person);
  1868             if (session->add_into_social_graph)
  1869                 sqlite3_finalize(session->add_into_social_graph);  
  1870             if (session->get_own_address_binding_from_contact)
  1871                 sqlite3_finalize(session->get_own_address_binding_from_contact);  
  1872             if (session->set_revoke_contact_as_notified)
  1873                 sqlite3_finalize(session->set_revoke_contact_as_notified);  
  1874             if (session->get_contacted_ids_from_revoke_fpr)
  1875                 sqlite3_finalize(session->get_contacted_ids_from_revoke_fpr);  
  1876             if (session->was_id_for_revoke_contacted)
  1877                 sqlite3_finalize(session->was_id_for_revoke_contacted);   
  1878             if (session->get_last_contacted)
  1879                 sqlite3_finalize(session->get_last_contacted);                                       
  1880             if (session->set_pgp_keypair)
  1881                 sqlite3_finalize(session->set_pgp_keypair);
  1882             if (session->exists_identity_entry)
  1883                 sqlite3_finalize(session->exists_identity_entry);                
  1884             if (session->set_identity_entry)
  1885                 sqlite3_finalize(session->set_identity_entry);
  1886             if (session->update_identity_entry)
  1887                 sqlite3_finalize(session->update_identity_entry);    
  1888             if (session->set_identity_flags)
  1889                 sqlite3_finalize(session->set_identity_flags);
  1890             if (session->unset_identity_flags)
  1891                 sqlite3_finalize(session->unset_identity_flags);
  1892             if (session->exists_trust_entry)
  1893                 sqlite3_finalize(session->exists_trust_entry);                                
  1894             if (session->set_trust)
  1895                 sqlite3_finalize(session->set_trust);
  1896             if (session->update_trust)
  1897                 sqlite3_finalize(session->update_trust);
  1898             if (session->update_trust_to_pEp)
  1899                 sqlite3_finalize(session->update_trust_to_pEp);                                                
  1900             if (session->update_trust_for_fpr)
  1901                 sqlite3_finalize(session->update_trust_for_fpr);
  1902             if (session->get_trust)
  1903                 sqlite3_finalize(session->get_trust);
  1904             if (session->get_trust_by_userid)
  1905                 sqlite3_finalize(session->get_trust_by_userid);                
  1906             if (session->least_trust)
  1907                 sqlite3_finalize(session->least_trust);
  1908             if (session->mark_compromised)
  1909                 sqlite3_finalize(session->mark_compromised);
  1910             if (session->crashdump)
  1911                 sqlite3_finalize(session->crashdump);
  1912             if (session->languagelist)
  1913                 sqlite3_finalize(session->languagelist);
  1914             if (session->i18n_token)
  1915                 sqlite3_finalize(session->i18n_token);
  1916             if (session->replace_userid)
  1917                 sqlite3_finalize(session->replace_userid);
  1918             if (session->delete_key)
  1919                 sqlite3_finalize(session->delete_key);                
  1920             if (session->replace_main_user_fpr)
  1921                 sqlite3_finalize(session->replace_main_user_fpr);                
  1922             if (session->get_main_user_fpr)
  1923                 sqlite3_finalize(session->get_main_user_fpr);
  1924             if (session->refresh_userid_default_key)
  1925                 sqlite3_finalize(session->refresh_userid_default_key);
  1926             if (session->blacklist_add)
  1927                 sqlite3_finalize(session->blacklist_add);
  1928             if (session->blacklist_delete)
  1929                 sqlite3_finalize(session->blacklist_delete);
  1930             if (session->blacklist_is_listed)
  1931                 sqlite3_finalize(session->blacklist_is_listed);
  1932             if (session->blacklist_retrieve)
  1933                 sqlite3_finalize(session->blacklist_retrieve);
  1934             if (session->own_key_is_listed)
  1935                 sqlite3_finalize(session->own_key_is_listed);
  1936             if (session->is_own_address)
  1937                 sqlite3_finalize(session->is_own_address);
  1938             if (session->own_identities_retrieve)
  1939                 sqlite3_finalize(session->own_identities_retrieve);
  1940             if (session->own_keys_retrieve)
  1941                 sqlite3_finalize(session->own_keys_retrieve);
  1942             // if (session->set_own_key)
  1943             //     sqlite3_finalize(session->set_own_key);
  1944             if (session->sequence_value1)
  1945                 sqlite3_finalize(session->sequence_value1);
  1946             if (session->sequence_value2)
  1947                 sqlite3_finalize(session->sequence_value2);
  1948             if (session->set_revoked)
  1949                 sqlite3_finalize(session->set_revoked);
  1950             if (session->get_revoked)
  1951                 sqlite3_finalize(session->get_revoked);
  1952             if (session->get_replacement_fpr)
  1953                 sqlite3_finalize(session->get_replacement_fpr);                
  1954             if (session->add_mistrusted_key)
  1955                 sqlite3_finalize(session->add_mistrusted_key);
  1956             if (session->delete_mistrusted_key)
  1957                 sqlite3_finalize(session->delete_mistrusted_key);
  1958             if (session->is_mistrusted_key)
  1959                 sqlite3_finalize(session->is_mistrusted_key);
  1960                 
  1961             if (session->db) {
  1962                 sqlite3_exec(        
  1963                     session->db,
  1964                     "PRAGMA optimize;\n",
  1965                     NULL,
  1966                     NULL,
  1967                     NULL
  1968                 );
  1969                 sqlite3_close_v2(session->db);
  1970             }
  1971             if (session->system_db)
  1972                 sqlite3_close_v2(session->system_db);
  1973         }
  1974 
  1975         release_transport_system(session, out_last);
  1976         release_cryptotech(session, out_last);
  1977 
  1978 #ifdef DEBUG_ERRORSTACK
  1979         free_stringlist(session->errorstack);
  1980 #endif
  1981         free(session);
  1982     }
  1983 }
  1984 
  1985 DYNAMIC_API void config_passive_mode(PEP_SESSION session, bool enable)
  1986 {
  1987     assert(session);
  1988     if (session)
  1989         session->passive_mode = enable;
  1990 }
  1991 
  1992 DYNAMIC_API void config_unencrypted_subject(PEP_SESSION session, bool enable)
  1993 {
  1994     assert(session);
  1995     if (session)
  1996         session->unencrypted_subject = enable;
  1997 }
  1998 
  1999 DYNAMIC_API void config_service_log(PEP_SESSION session, bool enable)
  2000 {
  2001     assert(session);
  2002     if (session)
  2003         session->service_log = enable;
  2004 }
  2005 
  2006 DYNAMIC_API PEP_STATUS log_event(
  2007         PEP_SESSION session,
  2008         const char *title,
  2009         const char *entity,
  2010         const char *description,
  2011         const char *comment
  2012     )
  2013 {
  2014 
  2015 // N.B. If testing (so NDEBUG not defined) but this message is spam,
  2016 //      put -D_PEP_SERVICE_LOG_OFF into CFLAGS/CXXFLAGS     
  2017 #if !defined(NDEBUG) && !defined(_PEP_SERVICE_LOG_OFF)
  2018     fprintf(stdout, "\n*** %s %s %s %s\n", title, entity, description, comment);
  2019     session->service_log = true;
  2020 
  2021     int result;
  2022     
  2023     assert(session);
  2024     assert(title);
  2025     assert(entity);
  2026     
  2027     if (!(session && title && entity))
  2028         return PEP_ILLEGAL_VALUE;
  2029     
  2030     sqlite3_reset(session->log);
  2031     sqlite3_bind_text(session->log, 1, title, -1, SQLITE_STATIC);
  2032     sqlite3_bind_text(session->log, 2, entity, -1, SQLITE_STATIC);
  2033     if (description)
  2034         sqlite3_bind_text(session->log, 3, description, -1, SQLITE_STATIC);
  2035     else
  2036         sqlite3_bind_null(session->log, 3);
  2037     if (comment)
  2038         sqlite3_bind_text(session->log, 4, comment, -1, SQLITE_STATIC);
  2039     else
  2040         sqlite3_bind_null(session->log, 4);
  2041     result = Sqlite3_step(session->log);
  2042     sqlite3_reset(session->log);
  2043     
  2044 #endif
  2045     return PEP_STATUS_OK; // We ignore errors for this function.
  2046 }
  2047 
  2048 DYNAMIC_API PEP_STATUS log_service(
  2049         PEP_SESSION session,
  2050         const char *title,
  2051         const char *entity,
  2052         const char *description,
  2053         const char *comment
  2054     )
  2055 {
  2056     assert(session);
  2057     if (!session)
  2058         return PEP_ILLEGAL_VALUE;
  2059 
  2060     if (session->service_log)
  2061         return log_event(session, title, entity, description, comment);
  2062     else
  2063         return PEP_STATUS_OK;
  2064 }
  2065 
  2066 DYNAMIC_API PEP_STATUS trustword(
  2067             PEP_SESSION session, uint16_t value, const char *lang,
  2068             char **word, size_t *wsize
  2069         )
  2070 {
  2071     PEP_STATUS status = PEP_STATUS_OK;
  2072 
  2073     assert(session);
  2074     assert(word);
  2075     assert(wsize);
  2076 
  2077     if (!(session && word && wsize))
  2078         return PEP_ILLEGAL_VALUE;
  2079 
  2080     *word = NULL;
  2081     *wsize = 0;
  2082 
  2083     if (lang == NULL)
  2084         lang = "en";
  2085 
  2086     assert((lang[0] >= 'A' && lang[0] <= 'Z')
  2087             || (lang[0] >= 'a' && lang[0] <= 'z'));
  2088     assert((lang[1] >= 'A' && lang[1] <= 'Z')
  2089             || (lang[1] >= 'a' && lang[1] <= 'z'));
  2090     assert(lang[2] == 0);
  2091 
  2092     sqlite3_reset(session->trustword);
  2093     sqlite3_bind_text(session->trustword, 1, lang, -1, SQLITE_STATIC);
  2094     sqlite3_bind_int(session->trustword, 2, value);
  2095 
  2096     const int result = Sqlite3_step(session->trustword);
  2097     if (result == SQLITE_ROW) {
  2098         *word = strdup((const char *) sqlite3_column_text(session->trustword,
  2099                     1));
  2100         if (*word)
  2101             *wsize = sqlite3_column_bytes(session->trustword, 1);
  2102         else
  2103             status = PEP_OUT_OF_MEMORY;
  2104     } else
  2105         status = PEP_TRUSTWORD_NOT_FOUND;
  2106 
  2107     sqlite3_reset(session->trustword);
  2108     return status;
  2109 }
  2110 
  2111 DYNAMIC_API PEP_STATUS trustwords(
  2112         PEP_SESSION session, const char *fingerprint, const char *lang,
  2113         char **words, size_t *wsize, int max_words
  2114     )
  2115 {
  2116     const char *source = fingerprint;
  2117 
  2118     assert(session);
  2119     assert(fingerprint);
  2120     assert(words);
  2121     assert(wsize);
  2122     assert(max_words >= 0);
  2123 
  2124     if (!(session && fingerprint && words && wsize && max_words >= 0))
  2125         return PEP_ILLEGAL_VALUE;
  2126 
  2127     *words = NULL;
  2128     *wsize = 0;
  2129 
  2130     char *buffer = calloc(1, MAX_TRUSTWORDS_SPACE);
  2131     assert(buffer);
  2132     if (buffer == NULL)
  2133         return PEP_OUT_OF_MEMORY;
  2134     char *dest = buffer;
  2135 
  2136     const size_t fsize = strlen(fingerprint);
  2137 
  2138     if (!lang || !lang[0])
  2139         lang = "en";
  2140 
  2141     assert((lang[0] >= 'A' && lang[0] <= 'Z')
  2142             || (lang[0] >= 'a' && lang[0] <= 'z'));
  2143     assert((lang[1] >= 'A' && lang[1] <= 'Z')
  2144             || (lang[1] >= 'a' && lang[1] <= 'z'));
  2145     assert(lang[2] == 0);
  2146 
  2147     int n_words = 0;
  2148     while (source < fingerprint + fsize) {
  2149         PEP_STATUS _status;
  2150         uint16_t value;
  2151         char *word = NULL;
  2152         size_t _wsize = 0;
  2153         int j;
  2154 
  2155         for (value=0, j=0; j < 4 && source < fingerprint + fsize; ) {
  2156             if (*source >= 'a' && *source <= 'f')
  2157                 value += (*source - 'a' + 10) << (3 - j++) * 4;
  2158             else if (*source >= 'A' && *source <= 'F')
  2159                 value += (*source - 'A' + 10) << (3 - j++) * 4;
  2160             else if (*source >= '0' && *source <= '9')
  2161                 value += (*source - '0') << (3 - j++) * 4;
  2162             
  2163             source++;
  2164         }
  2165 
  2166         _status = trustword(session, value, lang, &word, &_wsize);
  2167         if (_status == PEP_OUT_OF_MEMORY) {
  2168             free(buffer);
  2169             return PEP_OUT_OF_MEMORY;
  2170         }
  2171         if (word == NULL) {
  2172             free(buffer);
  2173             return PEP_TRUSTWORD_NOT_FOUND;
  2174         }
  2175 
  2176         if (dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1) {
  2177             strncpy(dest, word, _wsize);
  2178             free(word);
  2179             dest += _wsize;
  2180         }
  2181         else {
  2182             free(word);
  2183             break; // buffer full
  2184         }
  2185 
  2186         if (source < fingerprint + fsize
  2187                 && dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1)
  2188             *dest++ = ' ';
  2189 
  2190         ++n_words;
  2191         if (max_words && n_words >= max_words)
  2192             break;
  2193     }
  2194 
  2195     *words = buffer;
  2196     *wsize = dest - buffer;
  2197     return PEP_STATUS_OK;
  2198 }
  2199 
  2200 pEp_identity *new_identity(
  2201         const char *address, const char *fpr, const char *user_id,
  2202         const char *username
  2203     )
  2204 {
  2205     pEp_identity *result = calloc(1, sizeof(pEp_identity));
  2206     assert(result);
  2207     if (result) {
  2208         if (address) {
  2209             result->address = strdup(address);
  2210             assert(result->address);
  2211             if (result->address == NULL) {
  2212                 free(result);
  2213                 return NULL;
  2214             }
  2215         }
  2216         if (fpr) {
  2217             result->fpr = strdup(fpr);
  2218             assert(result->fpr);
  2219             if (result->fpr == NULL) {
  2220                 free_identity(result);
  2221                 return NULL;
  2222             }
  2223         }
  2224         if (user_id) {
  2225             result->user_id = strdup(user_id);
  2226             assert(result->user_id);
  2227             if (result->user_id == NULL) {
  2228                 free_identity(result);
  2229                 return NULL;
  2230             }
  2231         }
  2232         if (username) {
  2233             result->username = strdup(username);
  2234             assert(result->username);
  2235             if (result->username == NULL) {
  2236                 free_identity(result);
  2237                 return NULL;
  2238             }
  2239         }
  2240     }
  2241     return result;
  2242 }
  2243 
  2244 pEp_identity *identity_dup(const pEp_identity *src)
  2245 {
  2246     assert(src);
  2247 
  2248     pEp_identity *dup = new_identity(src->address, src->fpr, src->user_id,
  2249             src->username);
  2250     assert(dup);
  2251     if (dup == NULL)
  2252         return NULL;
  2253     
  2254     dup->comm_type = src->comm_type;
  2255     dup->lang[0] = src->lang[0];
  2256     dup->lang[1] = src->lang[1];
  2257     dup->lang[2] = 0;
  2258     dup->flags = src->flags;
  2259     dup->me = src->me;
  2260     
  2261     return dup;
  2262 }
  2263 
  2264 void free_identity(pEp_identity *identity)
  2265 {
  2266     if (identity) {
  2267         free(identity->address);
  2268         free(identity->fpr);
  2269         free(identity->user_id);
  2270         free(identity->username);
  2271         free(identity);
  2272     }
  2273 }
  2274 
  2275 DYNAMIC_API PEP_STATUS get_default_own_userid(
  2276         PEP_SESSION session, 
  2277         char** userid
  2278     )
  2279 {
  2280     assert(session);
  2281     assert(userid);
  2282     
  2283     if (!session || !userid)
  2284         return PEP_ILLEGAL_VALUE;
  2285         
  2286     PEP_STATUS status = PEP_STATUS_OK;
  2287     char* retval = NULL;
  2288     
  2289     sqlite3_reset(session->get_default_own_userid);
  2290 
  2291     const int result = Sqlite3_step(session->get_default_own_userid);
  2292     const char* id;
  2293     
  2294     switch (result) {
  2295         case SQLITE_ROW:
  2296             id = (const char *) sqlite3_column_text(session->get_default_own_userid, 0);
  2297             if (!id) {
  2298                 // Shouldn't happen.
  2299                 status = PEP_UNKNOWN_ERROR;
  2300             }
  2301             else {
  2302                 retval = strdup(id);
  2303                 if (!retval)
  2304                     status = PEP_OUT_OF_MEMORY;
  2305             }
  2306             break;
  2307         default:
  2308             // Technically true, given how we find it, but FIXME we need a more descriptive error
  2309             status = PEP_CANNOT_FIND_IDENTITY;
  2310     }
  2311 
  2312     *userid = retval;
  2313 
  2314     sqlite3_reset(session->get_default_own_userid);
  2315     
  2316     return status;
  2317 }
  2318 
  2319 DYNAMIC_API PEP_STATUS get_userid_alias_default(
  2320         PEP_SESSION session, 
  2321         const char* alias_id,
  2322         char** default_id) {
  2323             
  2324     assert(session);
  2325     assert(alias_id);
  2326     assert(alias_id[0]);
  2327     assert(default_id);
  2328 
  2329     if (!(session && alias_id && alias_id[0] && default_id))
  2330         return PEP_ILLEGAL_VALUE;
  2331 
  2332     PEP_STATUS status = PEP_STATUS_OK;
  2333     char* retval = NULL;
  2334 
  2335     sqlite3_reset(session->get_userid_alias_default);
  2336     sqlite3_bind_text(session->get_userid_alias_default, 1, alias_id, -1, SQLITE_STATIC);
  2337 
  2338     const char* tempid;
  2339     
  2340     const int result = Sqlite3_step(session->get_userid_alias_default);
  2341     switch (result) {
  2342     case SQLITE_ROW:
  2343         tempid = (const char *) sqlite3_column_text(session->get_userid_alias_default, 0);
  2344         if (tempid) {
  2345             retval = strdup(tempid);
  2346             assert(retval);
  2347             if (retval == NULL)
  2348                 return PEP_OUT_OF_MEMORY;
  2349         }
  2350     
  2351         *default_id = retval;
  2352         break;
  2353     default:
  2354         status = PEP_CANNOT_FIND_ALIAS;
  2355         *default_id = NULL;
  2356     }
  2357 
  2358     sqlite3_reset(session->get_userid_alias_default);
  2359     return status;            
  2360 }
  2361 
  2362 DYNAMIC_API PEP_STATUS set_userid_alias (
  2363         PEP_SESSION session, 
  2364         const char* default_id,
  2365         const char* alias_id) {
  2366             
  2367     int result;
  2368 
  2369     assert(session);
  2370     assert(default_id);
  2371     assert(alias_id);
  2372 
  2373     if (!(session && default_id && alias_id && 
  2374           default_id[0] != '\0' && alias_id[0] != '\0'))
  2375         return PEP_ILLEGAL_VALUE;
  2376     
  2377     sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  2378 
  2379     sqlite3_reset(session->add_userid_alias);
  2380     sqlite3_bind_text(session->add_userid_alias, 1, default_id, -1,
  2381             SQLITE_STATIC);
  2382     sqlite3_bind_text(session->add_userid_alias, 2, alias_id, -1,
  2383             SQLITE_STATIC);
  2384         
  2385     result = Sqlite3_step(session->add_userid_alias);
  2386 
  2387     sqlite3_reset(session->add_userid_alias);
  2388     if (result != SQLITE_DONE) {
  2389         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);        
  2390         return PEP_CANNOT_SET_ALIAS;
  2391     }
  2392     sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  2393         
  2394 
  2395     return PEP_STATUS_OK;
  2396 }
  2397 
  2398 DYNAMIC_API PEP_STATUS get_identity(
  2399         PEP_SESSION session,
  2400         const char *address,
  2401         const char *user_id,
  2402         pEp_identity **identity
  2403     )
  2404 {
  2405     PEP_STATUS status = PEP_STATUS_OK;
  2406     pEp_identity *_identity = NULL;
  2407 
  2408     assert(session);
  2409     assert(address);
  2410     assert(address[0]);
  2411     assert(identity);
  2412 
  2413     if (!(session && address && address[0] && identity))
  2414         return PEP_ILLEGAL_VALUE;
  2415 
  2416     *identity = NULL;
  2417 
  2418     sqlite3_reset(session->get_identity);
  2419     sqlite3_bind_text(session->get_identity, 1, address, -1, SQLITE_STATIC);
  2420     sqlite3_bind_text(session->get_identity, 2, user_id, -1, SQLITE_STATIC);
  2421 
  2422     const int result = Sqlite3_step(session->get_identity);
  2423     switch (result) {
  2424     case SQLITE_ROW:
  2425         _identity = new_identity(
  2426                 address,
  2427                 (const char *) sqlite3_column_text(session->get_identity, 0),
  2428                 user_id,
  2429                 (const char *) sqlite3_column_text(session->get_identity, 1)
  2430                 );
  2431         assert(_identity);
  2432         if (_identity == NULL) {
  2433             sqlite3_reset(session->get_identity);
  2434             return PEP_OUT_OF_MEMORY;
  2435         }
  2436 
  2437         _identity->comm_type = (PEP_comm_type)
  2438             sqlite3_column_int(session->get_identity, 2);
  2439         const char* const _lang = (const char *)
  2440             sqlite3_column_text(session->get_identity, 3);
  2441         if (_lang && _lang[0]) {
  2442             assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  2443             assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  2444             assert(_lang[2] == 0);
  2445             _identity->lang[0] = _lang[0];
  2446             _identity->lang[1] = _lang[1];
  2447             _identity->lang[2] = 0;
  2448         }
  2449         _identity->flags = (unsigned int)
  2450             sqlite3_column_int(session->get_identity, 4);
  2451         _identity->me = (unsigned int)
  2452             sqlite3_column_int(session->get_identity, 5);
  2453     
  2454         *identity = _identity;
  2455         break;
  2456     default:
  2457         sqlite3_reset(session->get_identity);
  2458         status = PEP_CANNOT_FIND_IDENTITY;
  2459         *identity = NULL;
  2460     }
  2461 
  2462     sqlite3_reset(session->get_identity);
  2463     return status;
  2464 }
  2465 
  2466 PEP_STATUS get_identities_by_userid(
  2467         PEP_SESSION session,
  2468         const char *user_id,
  2469         identity_list **identities
  2470     )
  2471 {
  2472     if (!session || !identities || EMPTYSTR(user_id))
  2473         return PEP_ILLEGAL_VALUE;
  2474 
  2475     PEP_STATUS status = PEP_STATUS_OK;
  2476     
  2477     pEp_identity* ident = NULL;
  2478 
  2479     *identities = new_identity_list(NULL);
  2480 
  2481     sqlite3_reset(session->get_identities_by_userid);
  2482     sqlite3_bind_text(session->get_identities_by_userid, 1, user_id, -1, SQLITE_STATIC);
  2483 
  2484     int result = -1;
  2485     while ((result = Sqlite3_step(session->get_identities_by_userid)) == SQLITE_ROW) {
  2486             // "select address, fpr, username, comm_type, lang,"
  2487             // "   identity.flags | pgp_keypair.flags,"
  2488             // "   is_own"
  2489             // "   from identity"
  2490             // "   join person on id = identity.user_id"
  2491             // "   join pgp_keypair on fpr = identity.main_key_id"
  2492             // "   join trust on id = trust.user_id"
  2493             // "       and pgp_keypair_fpr = identity.main_key_id"    
  2494             // "   where identity.user_id = ?1" 
  2495             // "   order by is_own desc, "
  2496             // "   timestamp desc; ";
  2497 
  2498         ident = new_identity(
  2499                     (const char *) sqlite3_column_text(session->get_identities_by_userid, 0),
  2500                     (const char *) sqlite3_column_text(session->get_identities_by_userid, 1),                
  2501                     user_id,
  2502                     (const char *) sqlite3_column_text(session->get_identities_by_userid, 2)
  2503                 );
  2504                 
  2505         assert(ident);
  2506         if (ident == NULL) {
  2507             sqlite3_reset(session->get_identities_by_userid);
  2508             return PEP_OUT_OF_MEMORY;
  2509         }
  2510 
  2511         ident->comm_type = (PEP_comm_type)
  2512             sqlite3_column_int(session->get_identities_by_userid, 3);
  2513         const char* const _lang = (const char *)
  2514             sqlite3_column_text(session->get_identities_by_userid, 4);
  2515         if (_lang && _lang[0]) {
  2516             assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  2517             assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  2518             assert(_lang[2] == 0);
  2519             ident->lang[0] = _lang[0];
  2520             ident->lang[1] = _lang[1];
  2521             ident->lang[2] = 0;
  2522         }
  2523         ident->flags = (unsigned int)
  2524             sqlite3_column_int(session->get_identities_by_userid, 5);
  2525         ident->me = (unsigned int)
  2526             sqlite3_column_int(session->get_identities_by_userid, 6);
  2527     
  2528         identity_list_add(*identities, ident);
  2529         ident = NULL;
  2530     }
  2531 
  2532     if ((*identities)->ident == NULL) {
  2533         free_identity_list(*identities);
  2534         *identities = NULL;
  2535         status = PEP_CANNOT_FIND_IDENTITY;
  2536     }
  2537             
  2538     sqlite3_reset(session->get_identities_by_userid);
  2539 
  2540     return status;
  2541 }
  2542 
  2543 PEP_STATUS get_identities_by_main_key_id(
  2544         PEP_SESSION session,
  2545         const char *fpr,
  2546         identity_list **identities
  2547     )
  2548 {
  2549     if (!session || !identities || EMPTYSTR(fpr))
  2550         return PEP_ILLEGAL_VALUE;
  2551 
  2552     PEP_STATUS status = PEP_STATUS_OK;
  2553     
  2554     pEp_identity* ident = NULL;
  2555 
  2556     *identities = new_identity_list(NULL);
  2557 
  2558     sqlite3_reset(session->get_identities_by_main_key_id);
  2559     sqlite3_bind_text(session->get_identities_by_main_key_id, 1, fpr, -1, SQLITE_STATIC);
  2560 
  2561     int result = -1;
  2562     
  2563     while ((result = Sqlite3_step(session->get_identities_by_main_key_id)) == SQLITE_ROW) {
  2564         ident = new_identity(
  2565                     (const char *) sqlite3_column_text(session->get_identities_by_main_key_id, 0),
  2566                     fpr,
  2567                     (const char *) sqlite3_column_text(session->get_identities_by_main_key_id, 1),                
  2568                     (const char *) sqlite3_column_text(session->get_identities_by_main_key_id, 2)
  2569                 );
  2570                 
  2571         assert(ident);
  2572         if (ident == NULL) {
  2573             sqlite3_reset(session->get_identities_by_main_key_id);
  2574             return PEP_OUT_OF_MEMORY;
  2575         }
  2576 
  2577         ident->comm_type = (PEP_comm_type)
  2578             sqlite3_column_int(session->get_identities_by_main_key_id, 3);
  2579         const char* const _lang = (const char *)
  2580             sqlite3_column_text(session->get_identities_by_main_key_id, 4);
  2581         if (_lang && _lang[0]) {
  2582             assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  2583             assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  2584             assert(_lang[2] == 0);
  2585             ident->lang[0] = _lang[0];
  2586             ident->lang[1] = _lang[1];
  2587             ident->lang[2] = 0;
  2588         }
  2589         ident->flags = (unsigned int)
  2590             sqlite3_column_int(session->get_identities_by_main_key_id, 5);
  2591         ident->me = (unsigned int)
  2592             sqlite3_column_int(session->get_identities_by_main_key_id, 6);
  2593     
  2594         identity_list_add(*identities, ident);
  2595         ident = NULL;
  2596     }
  2597 
  2598     if ((*identities)->ident == NULL) {
  2599         free_identity_list(*identities);
  2600         *identities = NULL;
  2601         status = PEP_CANNOT_FIND_IDENTITY;
  2602     }
  2603             
  2604     sqlite3_reset(session->get_identities_by_main_key_id);
  2605 
  2606     return status;
  2607 }
  2608 
  2609 PEP_STATUS get_identity_without_trust_check(
  2610         PEP_SESSION session,
  2611         const char *address,
  2612         const char *user_id,
  2613         pEp_identity **identity
  2614     )
  2615 {
  2616     PEP_STATUS status = PEP_STATUS_OK;
  2617     pEp_identity *_identity = NULL;
  2618 
  2619     assert(session);
  2620     assert(address);
  2621     assert(address[0]);
  2622     assert(identity);
  2623 
  2624     if (!(session && address && address[0] && identity))
  2625         return PEP_ILLEGAL_VALUE;
  2626 
  2627     *identity = NULL;
  2628 
  2629     sqlite3_reset(session->get_identity_without_trust_check);
  2630     sqlite3_bind_text(session->get_identity_without_trust_check, 1, address, -1, SQLITE_STATIC);
  2631     sqlite3_bind_text(session->get_identity_without_trust_check, 2, user_id, -1, SQLITE_STATIC);
  2632 
  2633     const int result = Sqlite3_step(session->get_identity_without_trust_check);
  2634     switch (result) {
  2635     case SQLITE_ROW:
  2636         _identity = new_identity(
  2637                 address,
  2638                 (const char *) sqlite3_column_text(session->get_identity_without_trust_check, 0),
  2639                 user_id,
  2640                 (const char *) sqlite3_column_text(session->get_identity_without_trust_check, 1)
  2641                 );
  2642         assert(_identity);
  2643         if (_identity == NULL) {
  2644             sqlite3_reset(session->get_identity_without_trust_check);
  2645             return PEP_OUT_OF_MEMORY;
  2646         }
  2647 
  2648         _identity->comm_type = PEP_ct_unknown;
  2649         const char* const _lang = (const char *)
  2650             sqlite3_column_text(session->get_identity_without_trust_check, 2);
  2651         if (_lang && _lang[0]) {
  2652             assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  2653             assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  2654             assert(_lang[2] == 0);
  2655             _identity->lang[0] = _lang[0];
  2656             _identity->lang[1] = _lang[1];
  2657             _identity->lang[2] = 0;
  2658         }
  2659         _identity->flags = (unsigned int)
  2660             sqlite3_column_int(session->get_identity_without_trust_check, 3);
  2661         _identity->me = (unsigned int)
  2662             sqlite3_column_int(session->get_identity_without_trust_check, 4);
  2663     
  2664         *identity = _identity;
  2665         break;
  2666     default:
  2667         status = PEP_CANNOT_FIND_IDENTITY;
  2668         *identity = NULL;
  2669     }
  2670 
  2671     sqlite3_reset(session->get_identity_without_trust_check);
  2672     return status;
  2673 }
  2674 
  2675 
  2676 PEP_STATUS get_identities_by_address(
  2677         PEP_SESSION session,
  2678         const char *address,
  2679         identity_list** id_list
  2680     )
  2681 {
  2682     assert(session);
  2683     assert(address);
  2684     assert(address[0]);
  2685     assert(id_list);
  2686 
  2687     if (!(session && address && address[0] && id_list))
  2688         return PEP_ILLEGAL_VALUE;
  2689 
  2690     *id_list = NULL;
  2691     identity_list* ident_list = NULL;
  2692 
  2693     sqlite3_reset(session->get_identities_by_address);
  2694     sqlite3_bind_text(session->get_identities_by_address, 1, address, -1, SQLITE_STATIC);
  2695     int result;
  2696 
  2697     while ((result = Sqlite3_step(session->get_identities_by_address)) == SQLITE_ROW) {
  2698         //"select user_id, main_key_id, username, comm_type, lang,"
  2699         //"   identity.flags, is_own"
  2700         pEp_identity *ident = new_identity(
  2701                 address,
  2702                 (const char *) sqlite3_column_text(session->get_identities_by_address, 1),
  2703                 (const char *) sqlite3_column_text(session->get_identities_by_address, 0),
  2704                 (const char *) sqlite3_column_text(session->get_identities_by_address, 2)
  2705                 );
  2706         assert(ident);
  2707         if (ident == NULL) {
  2708             sqlite3_reset(session->get_identities_by_address);
  2709             return PEP_OUT_OF_MEMORY;
  2710         }
  2711 
  2712         ident->comm_type = PEP_ct_unknown;
  2713         
  2714         const char* const _lang = (const char *)
  2715             sqlite3_column_text(session->get_identities_by_address, 3);
  2716         if (_lang && _lang[0]) {
  2717             assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  2718             assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  2719             assert(_lang[2] == 0);
  2720             ident->lang[0] = _lang[0];
  2721             ident->lang[1] = _lang[1];
  2722             ident->lang[2] = 0;
  2723         }
  2724         ident->flags = (unsigned int)
  2725             sqlite3_column_int(session->get_identities_by_address, 4);
  2726         ident->me = (unsigned int)
  2727             sqlite3_column_int(session->get_identities_by_address, 5);
  2728     
  2729         if (ident_list)
  2730             identity_list_add(ident_list, ident);
  2731         else
  2732             ident_list = new_identity_list(ident);
  2733     }
  2734 
  2735     sqlite3_reset(session->get_identities_by_address);
  2736     
  2737     *id_list = ident_list;
  2738     
  2739     if (!ident_list)
  2740         return PEP_CANNOT_FIND_IDENTITY;
  2741     
  2742     return PEP_STATUS_OK;
  2743 }
  2744 
  2745 PEP_STATUS exists_identity_entry(PEP_SESSION session, pEp_identity* identity,
  2746                                  bool* exists) {
  2747     assert(session);
  2748     assert(identity);
  2749     assert(!EMPTYSTR(identity->user_id));        
  2750     assert(!EMPTYSTR(identity->address));
  2751     if (!session || !exists || EMPTYSTR(identity->user_id) || EMPTYSTR(identity->address))
  2752         return PEP_ILLEGAL_VALUE;
  2753     
  2754     *exists = false;
  2755     
  2756     PEP_STATUS status = PEP_STATUS_OK;
  2757     
  2758     sqlite3_reset(session->exists_identity_entry);
  2759     sqlite3_bind_text(session->exists_identity_entry, 1, identity->address, -1,
  2760                       SQLITE_STATIC);
  2761     sqlite3_bind_text(session->exists_identity_entry, 2, identity->user_id, -1,
  2762                       SQLITE_STATIC);
  2763                   
  2764     int result = Sqlite3_step(session->exists_identity_entry);
  2765 
  2766     switch (result) {
  2767         case SQLITE_ROW: {
  2768             // yeah yeah, I know, we could be lazy here, but it looks bad.
  2769             *exists = (sqlite3_column_int(session->exists_identity_entry, 0) != 0);
  2770             break;
  2771         }
  2772         default: 
  2773             status = PEP_UNKNOWN_DB_ERROR;
  2774     }
  2775 
  2776     sqlite3_reset(session->exists_identity_entry);
  2777     return status;
  2778 }
  2779 
  2780 PEP_STATUS exists_trust_entry(PEP_SESSION session, pEp_identity* identity,
  2781                               bool* exists) {
  2782     assert(session);
  2783     assert(identity);
  2784     assert(!EMPTYSTR(identity->user_id));        
  2785     assert(!EMPTYSTR(identity->fpr));
  2786     if (!session || !exists || EMPTYSTR(identity->user_id) || EMPTYSTR(identity->fpr))
  2787         return PEP_ILLEGAL_VALUE;
  2788     
  2789     *exists = false;
  2790     
  2791     PEP_STATUS status = PEP_STATUS_OK;
  2792     
  2793     sqlite3_reset(session->exists_trust_entry);
  2794     sqlite3_bind_text(session->exists_trust_entry, 1, identity->user_id, -1,
  2795                       SQLITE_STATIC);
  2796     sqlite3_bind_text(session->exists_trust_entry, 2, identity->fpr, -1,
  2797                       SQLITE_STATIC);
  2798                   
  2799     int result = Sqlite3_step(session->exists_trust_entry);
  2800     switch (result) {
  2801         case SQLITE_ROW: {
  2802             // yeah yeah, I know, we could be lazy here, but it looks bad.
  2803             *exists = (sqlite3_column_int(session->exists_trust_entry, 0) != 0);
  2804             break;
  2805         }
  2806         default:
  2807             status = PEP_UNKNOWN_DB_ERROR;
  2808     }
  2809     
  2810     sqlite3_reset(session->exists_trust_entry);
  2811     return status;
  2812 }
  2813 
  2814 PEP_STATUS set_pgp_keypair(PEP_SESSION session, const char* fpr) {
  2815     if (!session || EMPTYSTR(fpr))
  2816         return PEP_ILLEGAL_VALUE;
  2817         
  2818     int result;
  2819     
  2820     sqlite3_reset(session->set_pgp_keypair);
  2821     sqlite3_bind_text(session->set_pgp_keypair, 1, fpr, -1,
  2822             SQLITE_STATIC);
  2823     result = Sqlite3_step(session->set_pgp_keypair);
  2824     sqlite3_reset(session->set_pgp_keypair);
  2825     if (result != SQLITE_DONE) {
  2826         return PEP_CANNOT_SET_PGP_KEYPAIR;
  2827     }
  2828     
  2829     return PEP_STATUS_OK;
  2830 }
  2831 
  2832 static PEP_STATUS _set_or_update_trust(PEP_SESSION session,
  2833                                        pEp_identity* identity,
  2834                                        sqlite3_stmt* set_or_update) {
  2835 
  2836     assert(session);
  2837     assert(identity);
  2838     assert(identity->user_id);
  2839     assert(identity->fpr);
  2840     
  2841     if (!session || !identity || EMPTYSTR(identity->user_id) || EMPTYSTR(identity->fpr))
  2842         return PEP_ILLEGAL_VALUE;
  2843         
  2844     PEP_STATUS status = set_pgp_keypair(session, identity->fpr);
  2845     if (status != PEP_STATUS_OK)
  2846         return status;
  2847         
  2848     int result;
  2849                 
  2850     sqlite3_reset(set_or_update);
  2851     sqlite3_bind_text(set_or_update, 1, identity->user_id, -1,
  2852             SQLITE_STATIC);
  2853     sqlite3_bind_text(set_or_update, 2, identity->fpr, -1,
  2854             SQLITE_STATIC);
  2855     sqlite3_bind_int(set_or_update, 3, identity->comm_type);
  2856     result = Sqlite3_step(set_or_update);
  2857     assert(result == SQLITE_DONE);
  2858     sqlite3_reset(set_or_update);
  2859     if (result != SQLITE_DONE)
  2860         return PEP_CANNOT_SET_TRUST;
  2861 
  2862     return PEP_STATUS_OK;
  2863 }
  2864 
  2865 static PEP_STATUS _set_or_update_identity_entry(PEP_SESSION session,
  2866                                                 pEp_identity* identity,
  2867                                                 sqlite3_stmt* set_or_update) {
  2868     assert(session);
  2869     assert(identity);
  2870     assert(set_or_update);
  2871                       
  2872     if (!session || !identity || !identity->user_id || !identity->address)
  2873         return PEP_ILLEGAL_VALUE;
  2874                                               
  2875     sqlite3_reset(set_or_update);
  2876     sqlite3_bind_text(set_or_update, 1, identity->address, -1,
  2877             SQLITE_STATIC);
  2878     sqlite3_bind_text(set_or_update, 2, identity->fpr, -1,
  2879             SQLITE_STATIC);
  2880     sqlite3_bind_text(set_or_update, 3, identity->user_id, -1,
  2881             SQLITE_STATIC);
  2882     sqlite3_bind_int(set_or_update, 4, identity->flags);
  2883     sqlite3_bind_int(set_or_update, 5, identity->me);
  2884     int result = Sqlite3_step(set_or_update);
  2885     sqlite3_reset(set_or_update);
  2886     if (result != SQLITE_DONE)
  2887         return PEP_CANNOT_SET_IDENTITY;
  2888     
  2889     return PEP_STATUS_OK;
  2890 }
  2891 
  2892 static PEP_STATUS _set_or_update_person(PEP_SESSION session, 
  2893                                         pEp_identity* identity,
  2894                                         sqlite3_stmt* set_or_update) {
  2895     assert(session);
  2896     assert(identity);
  2897     assert(set_or_update);
  2898                         
  2899     if (!session || !identity || !identity->user_id || !identity->username)
  2900         return PEP_ILLEGAL_VALUE;
  2901         
  2902     sqlite3_reset(set_or_update);
  2903     sqlite3_bind_text(set_or_update, 1, identity->user_id, -1,
  2904             SQLITE_STATIC);
  2905     sqlite3_bind_text(set_or_update, 2, identity->username, -1,
  2906             SQLITE_STATIC);
  2907     if (identity->lang[0])
  2908         sqlite3_bind_text(set_or_update, 3, identity->lang, 2,
  2909                 SQLITE_STATIC);
  2910     else
  2911         sqlite3_bind_null(set_or_update, 3);
  2912     sqlite3_bind_text(set_or_update, 4, identity->fpr, -1,
  2913                       SQLITE_STATIC);
  2914     int result = Sqlite3_step(set_or_update);
  2915     sqlite3_reset(set_or_update);
  2916     
  2917     if (result != SQLITE_DONE)
  2918         return PEP_CANNOT_SET_PERSON;
  2919     
  2920     return PEP_STATUS_OK;                                         
  2921 }
  2922 
  2923 PEP_STATUS set_or_update_with_identity(PEP_SESSION session,
  2924                                        pEp_identity* identity,
  2925                                        PEP_STATUS (* set_function)(PEP_SESSION, pEp_identity*, sqlite3_stmt*),
  2926                                        PEP_STATUS (* exists_function)(PEP_SESSION, pEp_identity*, bool*),                                       
  2927                                        sqlite3_stmt* update_query,
  2928                                        sqlite3_stmt* set_query,
  2929                                        bool guard_transaction) {
  2930 
  2931     if (guard_transaction) {
  2932         sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  2933     }
  2934     bool exists = false;
  2935     PEP_STATUS status = exists_function(session, identity, &exists);
  2936     
  2937     if (status == PEP_STATUS_OK) {
  2938         if (exists) {
  2939             status = set_function(session, identity, update_query);
  2940         }
  2941         else {
  2942             status = set_function(session, identity, set_query);                                              
  2943         }                    
  2944     }   
  2945     if (guard_transaction) {        
  2946         if (status != PEP_STATUS_OK)
  2947             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2948         else 
  2949             sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  2950     }                      
  2951     return status;
  2952 }
  2953 
  2954 PEP_STATUS _set_trust_internal(PEP_SESSION session, pEp_identity* identity,
  2955                                bool guard_transaction) {
  2956     return set_or_update_with_identity(session, identity,
  2957                                        _set_or_update_trust,
  2958                                         exists_trust_entry,
  2959                                         session->update_trust,
  2960                                         session->set_trust,
  2961                                         guard_transaction);
  2962 }
  2963 
  2964 // This is the TOP-LEVEL function. If you're calling from set_identity,
  2965 // you can't use this one.
  2966 PEP_STATUS set_trust(PEP_SESSION session, pEp_identity* identity) {
  2967     PEP_STATUS status = PEP_STATUS_OK;
  2968     
  2969     status = _set_trust_internal(session, identity, true);
  2970     if (status == PEP_STATUS_OK) {
  2971         if ((identity->comm_type | PEP_ct_confirmed) == PEP_ct_pEp)
  2972             status = set_as_pEp_user(session, identity);
  2973     }
  2974     return status;
  2975 }
  2976 
  2977 PEP_STATUS set_person(PEP_SESSION session, pEp_identity* identity,
  2978                       bool guard_transaction) {
  2979     return set_or_update_with_identity(session, identity,
  2980                                        _set_or_update_person,
  2981                                        exists_person,
  2982                                        session->update_person,
  2983                                        session->set_person,
  2984                                        guard_transaction);
  2985 }
  2986 
  2987 PEP_STATUS set_identity_entry(PEP_SESSION session, pEp_identity* identity,
  2988                               bool guard_transaction) {
  2989     return set_or_update_with_identity(session, identity,
  2990                                        _set_or_update_identity_entry,
  2991                                        exists_identity_entry,
  2992                                        session->update_identity_entry,
  2993                                        session->set_identity_entry,
  2994                                        guard_transaction);
  2995 }
  2996 
  2997 // This will NOT call set_as_pEp_user; you have to do that separately.
  2998 DYNAMIC_API PEP_STATUS set_identity(
  2999         PEP_SESSION session, const pEp_identity *identity
  3000     )
  3001 {
  3002     int result;
  3003 
  3004     assert(session);
  3005     assert(identity);
  3006     assert(identity->address);
  3007     assert(identity->user_id);
  3008     assert(identity->username);
  3009 
  3010     if (!(session && identity && identity->address &&
  3011                 identity->user_id && identity->username))
  3012         return PEP_ILLEGAL_VALUE;
  3013 
  3014     PEP_STATUS status = PEP_STATUS_OK;
  3015     
  3016     bool has_fpr = (!EMPTYSTR(identity->fpr));
  3017     
  3018     sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  3019 
  3020     if (identity->lang[0]) {
  3021         assert(identity->lang[0] >= 'a' && identity->lang[0] <= 'z');
  3022         assert(identity->lang[1] >= 'a' && identity->lang[1] <= 'z');
  3023         assert(identity->lang[2] == 0);
  3024     }
  3025 
  3026     if (has_fpr) {
  3027         sqlite3_reset(session->set_pgp_keypair);
  3028         sqlite3_bind_text(session->set_pgp_keypair, 1, identity->fpr, -1,
  3029                 SQLITE_STATIC);
  3030         result = Sqlite3_step(session->set_pgp_keypair);
  3031         sqlite3_reset(session->set_pgp_keypair);
  3032         if (result != SQLITE_DONE) {
  3033             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3034             return PEP_CANNOT_SET_PGP_KEYPAIR;
  3035         }
  3036     }
  3037 
  3038     // We do this because there are checks in set_person for
  3039     // aliases, which modify the identity object on return.
  3040     pEp_identity* ident_copy = identity_dup(identity); 
  3041     if (!ident_copy)
  3042         return PEP_OUT_OF_MEMORY;
  3043 
  3044     status = set_person(session, ident_copy, false);
  3045     if (status != PEP_STATUS_OK) {
  3046         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3047         goto pEp_free;
  3048     }
  3049 
  3050     status = set_identity_entry(session, ident_copy, false);
  3051     if (status != PEP_STATUS_OK) {
  3052         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3053         goto pEp_free;
  3054     }
  3055 
  3056     if (has_fpr) {
  3057         status = _set_trust_internal(session, ident_copy, false);
  3058         if (status != PEP_STATUS_OK) {
  3059             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3060             goto pEp_free;
  3061         }
  3062     }
  3063     
  3064     result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  3065     if (result == SQLITE_OK)
  3066         status = PEP_STATUS_OK;
  3067     else
  3068         status = PEP_COMMIT_FAILED;
  3069 
  3070 pEp_free:
  3071     free_identity(ident_copy);
  3072     return status;
  3073 }
  3074 
  3075 PEP_STATUS update_pEp_user_trust_vals(PEP_SESSION session,
  3076                                       pEp_identity* user) {
  3077     if (!user->user_id)
  3078         return PEP_ILLEGAL_VALUE;
  3079     
  3080     sqlite3_reset(session->update_trust_to_pEp);
  3081     sqlite3_bind_text(session->update_trust_to_pEp, 1, user->user_id, -1,
  3082             SQLITE_STATIC);
  3083     int result = Sqlite3_step(session->update_trust_to_pEp);
  3084     sqlite3_reset(session->update_trust_to_pEp);
  3085     if (result != SQLITE_DONE)
  3086         return PEP_CANNOT_SET_TRUST;
  3087 
  3088     return PEP_STATUS_OK;
  3089 }
  3090 
  3091 
  3092 // This ONLY sets the user flag. Must be called outside of a transaction.
  3093 DYNAMIC_API PEP_STATUS set_as_pEp_user(PEP_SESSION session, pEp_identity* user) {
  3094 
  3095     assert(session);
  3096     assert(user);
  3097     assert(!EMPTYSTR(user->user_id));
  3098         
  3099     if (!session || !user || EMPTYSTR(user->user_id))
  3100         return PEP_ILLEGAL_VALUE;
  3101             
  3102     PEP_STATUS status = PEP_STATUS_OK;
  3103     
  3104     bool person_exists = false;
  3105     
  3106     status = exists_person(session, user, &person_exists);
  3107     
  3108     if (status != PEP_STATUS_OK)
  3109         return status;
  3110         
  3111     if (!person_exists)
  3112         status = set_person(session, user, true);
  3113         
  3114     // Ok, let's set it.
  3115     sqlite3_reset(session->set_as_pEp_user);
  3116     sqlite3_bind_text(session->set_as_pEp_user, 1, user->user_id, -1,
  3117             SQLITE_STATIC);
  3118     int result = Sqlite3_step(session->set_as_pEp_user);
  3119     sqlite3_reset(session->set_as_pEp_user);
  3120     
  3121     if (result != SQLITE_DONE)
  3122         return PEP_CANNOT_SET_PERSON;
  3123 
  3124     status = update_pEp_user_trust_vals(session, user);
  3125         
  3126     return status;
  3127 }
  3128 
  3129 PEP_STATUS exists_person(PEP_SESSION session, pEp_identity* identity,
  3130                          bool* exists) {            
  3131     
  3132     // const char* user_id,
  3133     //                      char** default_id, bool* exists) {
  3134     assert(session);
  3135     assert(exists);
  3136     assert(identity);
  3137     assert(!EMPTYSTR(identity->user_id));
  3138         
  3139     if (!session || !exists || !identity || EMPTYSTR(identity->user_id))
  3140         return PEP_ILLEGAL_VALUE;
  3141     
  3142     *exists = false;
  3143 
  3144     const char* user_id = identity->user_id;
  3145     char* alias_default = NULL;
  3146     
  3147     PEP_STATUS status = get_userid_alias_default(session, user_id, &alias_default);
  3148     
  3149     if (status == PEP_CANNOT_FIND_ALIAS || EMPTYSTR(alias_default)) {
  3150         sqlite3_reset(session->exists_person);
  3151         sqlite3_bind_text(session->exists_person, 1, user_id, -1,
  3152                 SQLITE_STATIC);
  3153         int result = Sqlite3_step(session->exists_person);
  3154         switch (result) {
  3155             case SQLITE_ROW: {
  3156                 // yeah yeah, I know, we could be lazy here, but it looks bad.
  3157                 *exists = (sqlite3_column_int(session->exists_person, 0) != 0);
  3158                 status = PEP_STATUS_OK;
  3159                 break;
  3160             }
  3161             default:
  3162                 sqlite3_reset(session->exists_person);
  3163                 return PEP_UNKNOWN_DB_ERROR;
  3164         }
  3165         sqlite3_reset(session->exists_person);
  3166     }
  3167     else if (status == PEP_STATUS_OK) {
  3168         *exists = true; // thank you, delete on cascade!
  3169         // FIXME: Should we correct the userid default here? I think we should.
  3170         free(identity->user_id);
  3171         identity->user_id = alias_default; // ownership transfer
  3172     }
  3173     else
  3174         free(alias_default);
  3175             
  3176     return status;
  3177 }
  3178 
  3179 PEP_STATUS delete_person(PEP_SESSION session, const char* user_id) {
  3180     assert(session);
  3181     assert(!EMPTYSTR(user_id));        
  3182     if (!session || EMPTYSTR(user_id))
  3183         return PEP_ILLEGAL_VALUE;
  3184         
  3185     PEP_STATUS status = PEP_STATUS_OK;
  3186     
  3187     sqlite3_reset(session->delete_person);
  3188     sqlite3_bind_text(session->delete_person, 1, user_id, -1,
  3189                       SQLITE_STATIC);
  3190                       
  3191     int result = Sqlite3_step(session->delete_person);
  3192     
  3193     if (result != SQLITE_DONE)
  3194         status = PEP_UNKNOWN_ERROR;
  3195         
  3196     sqlite3_reset(session->delete_person);
  3197     return status;
  3198 }
  3199 
  3200 DYNAMIC_API PEP_STATUS is_pEp_user(PEP_SESSION session, pEp_identity *identity, bool* is_pEp)
  3201 {
  3202     assert(session);
  3203     assert(is_pEp);
  3204     assert(identity);
  3205     assert(!EMPTYSTR(identity->user_id));
  3206 
  3207     if (!session || !is_pEp || !identity || EMPTYSTR(identity->user_id))
  3208         return PEP_ILLEGAL_VALUE;
  3209     
  3210     *is_pEp = false;
  3211             
  3212     const char* user_id = identity->user_id;
  3213             
  3214     char* alias_default = NULL;
  3215     
  3216     PEP_STATUS status = get_userid_alias_default(session, user_id, &alias_default);
  3217     
  3218     if (status == PEP_CANNOT_FIND_ALIAS || EMPTYSTR(alias_default)) {
  3219         free(alias_default);
  3220         alias_default = strdup(user_id);
  3221     }
  3222     
  3223     sqlite3_reset(session->is_pEp_user);
  3224     sqlite3_bind_text(session->is_pEp_user, 1, user_id, -1,
  3225             SQLITE_STATIC);
  3226     int result = Sqlite3_step(session->is_pEp_user);
  3227     switch (result) {
  3228         case SQLITE_ROW: {
  3229             // yeah yeah, I know, we could be lazy here, but it looks bad.
  3230             *is_pEp = (sqlite3_column_int(session->is_pEp_user, 0) != 0);
  3231             break;
  3232         }
  3233         default:
  3234             sqlite3_reset(session->is_pEp_user);
  3235             free(alias_default);
  3236             return PEP_CANNOT_FIND_PERSON;
  3237     }
  3238 
  3239     sqlite3_reset(session->is_pEp_user);
  3240     
  3241     free(alias_default);
  3242     return PEP_STATUS_OK;
  3243 }
  3244 
  3245 PEP_STATUS is_own_address(PEP_SESSION session, const char* address, bool* is_own_addr)
  3246 {
  3247     assert(session);
  3248     assert(is_own_addr);
  3249     assert(!EMPTYSTR(address));
  3250 
  3251     if (!session || !is_own_addr || EMPTYSTR(address))
  3252         return PEP_ILLEGAL_VALUE;
  3253     
  3254     *is_own_addr = false;
  3255                 
  3256     if (!session || EMPTYSTR(address))
  3257         return PEP_ILLEGAL_VALUE;
  3258         
  3259     sqlite3_reset(session->is_own_address);
  3260     sqlite3_bind_text(session->is_own_address, 1, address, -1,
  3261             SQLITE_STATIC);
  3262     int result = Sqlite3_step(session->is_own_address);
  3263     switch (result) {
  3264         case SQLITE_ROW: {
  3265             // yeah yeah, I know, we could be lazy here, but it looks bad.
  3266             *is_own_addr = (sqlite3_column_int(session->is_own_address, 0) != 0);
  3267             break;
  3268         }
  3269         default:
  3270             sqlite3_reset(session->is_own_address);
  3271             return PEP_RECORD_NOT_FOUND;
  3272     }
  3273 
  3274     sqlite3_reset(session->is_own_address);
  3275     
  3276     return PEP_STATUS_OK;
  3277 }
  3278 
  3279 PEP_STATUS bind_own_ident_with_contact_ident(PEP_SESSION session,
  3280                                              pEp_identity* own_ident, 
  3281                                              pEp_identity* contact_ident) {
  3282     if (!own_ident || !contact_ident || 
  3283         !own_ident->address || !own_ident->user_id || !contact_ident->user_id)
  3284         return PEP_ILLEGAL_VALUE;
  3285         
  3286     sqlite3_reset(session->add_into_social_graph);
  3287     sqlite3_bind_text(session->add_into_social_graph, 1, own_ident->user_id, -1,
  3288             SQLITE_STATIC);
  3289     sqlite3_bind_text(session->add_into_social_graph, 2, own_ident->address, -1,
  3290             SQLITE_STATIC);
  3291     sqlite3_bind_text(session->add_into_social_graph, 3, contact_ident->user_id, -1,
  3292             SQLITE_STATIC);
  3293         
  3294     int result = Sqlite3_step(session->add_into_social_graph);
  3295     sqlite3_reset(session->add_into_social_graph);
  3296     
  3297     if (result != SQLITE_DONE)
  3298         return PEP_CANNOT_SET_PERSON;
  3299 
  3300     return PEP_STATUS_OK;
  3301 }
  3302 
  3303 PEP_STATUS get_own_ident_for_contact_id(PEP_SESSION session,
  3304                                           const pEp_identity* contact,
  3305                                           pEp_identity** own_ident) {
  3306                                               
  3307     if (!contact || !contact->user_id || !own_ident)
  3308         return PEP_ILLEGAL_VALUE;
  3309         
  3310     char* own_user_id = NULL;
  3311     *own_ident = NULL;
  3312     PEP_STATUS status = get_default_own_userid(session, &own_user_id);
  3313     
  3314     if (status != PEP_STATUS_OK)
  3315         return status;
  3316 
  3317     sqlite3_reset(session->get_own_address_binding_from_contact);
  3318     sqlite3_bind_text(session->get_own_address_binding_from_contact, 1, own_user_id, -1,
  3319             SQLITE_STATIC);
  3320     sqlite3_bind_text(session->get_own_address_binding_from_contact, 2, contact->user_id, -1,
  3321             SQLITE_STATIC);
  3322 
  3323     int result = Sqlite3_step(session->get_own_address_binding_from_contact);
  3324     
  3325     const char* own_address = NULL;
  3326     
  3327     switch (result) {
  3328         case SQLITE_ROW:
  3329             own_address = (const char *)
  3330                 sqlite3_column_text(session->get_own_address_binding_from_contact, 0);
  3331             if (own_address) {
  3332                 status = get_identity(session, own_address, own_user_id, own_ident);
  3333                 if (status == PEP_STATUS_OK) {
  3334                     if (!own_ident)
  3335                         status = PEP_CANNOT_FIND_IDENTITY;
  3336                 }
  3337             }
  3338             break;
  3339         default:
  3340             status = PEP_CANNOT_FIND_IDENTITY;
  3341     }
  3342     
  3343     free(own_user_id);
  3344     return status;
  3345 }
  3346 
  3347 PEP_STATUS remove_fpr_as_default(PEP_SESSION session, 
  3348                                  const char* fpr) 
  3349 {
  3350     assert(fpr);
  3351     
  3352     if (!session || !fpr)
  3353         return PEP_ILLEGAL_VALUE;
  3354             
  3355     sqlite3_reset(session->remove_fpr_as_default);
  3356     sqlite3_bind_text(session->remove_fpr_as_default, 1, fpr, -1,
  3357                       SQLITE_STATIC);
  3358 
  3359     int result = Sqlite3_step(session->remove_fpr_as_default);
  3360     sqlite3_reset(session->remove_fpr_as_default);
  3361     
  3362     if (result != SQLITE_DONE)
  3363         return PEP_CANNOT_SET_IDENTITY; // misleading - could also be person
  3364 
  3365     return PEP_STATUS_OK;
  3366 }
  3367 
  3368 
  3369 PEP_STATUS replace_identities_fpr(PEP_SESSION session, 
  3370                                  const char* old_fpr, 
  3371                                  const char* new_fpr) 
  3372 {
  3373     assert(old_fpr);
  3374     assert(new_fpr);
  3375     
  3376     if (!old_fpr || !new_fpr)
  3377         return PEP_ILLEGAL_VALUE;
  3378             
  3379     sqlite3_reset(session->replace_identities_fpr);
  3380     sqlite3_bind_text(session->replace_identities_fpr, 1, new_fpr, -1,
  3381                       SQLITE_STATIC);
  3382     sqlite3_bind_text(session->replace_identities_fpr, 2, old_fpr, -1,
  3383                       SQLITE_STATIC);
  3384 
  3385     int result = Sqlite3_step(session->replace_identities_fpr);
  3386     sqlite3_reset(session->replace_identities_fpr);
  3387     
  3388     if (result != SQLITE_DONE)
  3389         return PEP_CANNOT_SET_IDENTITY;
  3390 
  3391     return PEP_STATUS_OK;
  3392 }
  3393 
  3394 PEP_STATUS update_trust_for_fpr(PEP_SESSION session, 
  3395                                 const char* fpr, 
  3396                                 PEP_comm_type comm_type)
  3397 {
  3398     if (!fpr)
  3399         return PEP_ILLEGAL_VALUE;
  3400         
  3401     sqlite3_reset(session->update_trust_for_fpr);
  3402     sqlite3_bind_int(session->update_trust_for_fpr, 1, comm_type);
  3403     sqlite3_bind_text(session->update_trust_for_fpr, 2, fpr, -1,
  3404             SQLITE_STATIC);
  3405     int result = Sqlite3_step(session->update_trust_for_fpr);
  3406     sqlite3_reset(session->update_trust_for_fpr);
  3407     if (result != SQLITE_DONE) {
  3408         return PEP_CANNOT_SET_TRUST;
  3409     }
  3410     
  3411     return PEP_STATUS_OK;
  3412 }
  3413 
  3414 DYNAMIC_API PEP_STATUS set_identity_flags(
  3415         PEP_SESSION session,
  3416         pEp_identity *identity,
  3417         unsigned int flags
  3418     )
  3419 {
  3420     int result;
  3421 
  3422     assert(session);
  3423     assert(identity);
  3424     assert(identity->address);
  3425     assert(identity->user_id);
  3426 
  3427     if (!(session && identity && identity->address && identity->user_id))
  3428         return PEP_ILLEGAL_VALUE;
  3429 
  3430     sqlite3_reset(session->set_identity_flags);
  3431     sqlite3_bind_int(session->set_identity_flags, 1, flags);
  3432     sqlite3_bind_text(session->set_identity_flags, 2, identity->address, -1,
  3433             SQLITE_STATIC);
  3434     sqlite3_bind_text(session->set_identity_flags, 3, identity->user_id, -1,
  3435         SQLITE_STATIC);
  3436         
  3437     result = Sqlite3_step(session->set_identity_flags);
  3438 
  3439     sqlite3_reset(session->set_identity_flags);
  3440     if (result != SQLITE_DONE)
  3441         return PEP_CANNOT_SET_IDENTITY;
  3442 
  3443     identity->flags |= flags;
  3444     return PEP_STATUS_OK;
  3445 }
  3446 
  3447 DYNAMIC_API PEP_STATUS unset_identity_flags(
  3448         PEP_SESSION session,
  3449         pEp_identity *identity,
  3450         unsigned int flags
  3451     )
  3452 {
  3453     int result;
  3454 
  3455     assert(session);
  3456     assert(identity);
  3457     assert(identity->address);
  3458     assert(identity->user_id);
  3459 
  3460     if (!(session && identity && identity->address && identity->user_id))
  3461         return PEP_ILLEGAL_VALUE;
  3462 
  3463     sqlite3_reset(session->unset_identity_flags);
  3464     sqlite3_bind_int(session->unset_identity_flags, 1, flags);
  3465     sqlite3_bind_text(session->unset_identity_flags, 2, identity->address, -1,
  3466             SQLITE_STATIC);
  3467     sqlite3_bind_text(session->unset_identity_flags, 3, identity->user_id, -1,
  3468             SQLITE_STATIC);
  3469     result = Sqlite3_step(session->unset_identity_flags);
  3470     sqlite3_reset(session->unset_identity_flags);
  3471     if (result != SQLITE_DONE)
  3472         return PEP_CANNOT_SET_IDENTITY;
  3473 
  3474     identity->flags &= ~flags;
  3475 
  3476     return PEP_STATUS_OK;
  3477 }
  3478 
  3479 PEP_STATUS get_trust_by_userid(PEP_SESSION session, const char* user_id,
  3480                                            labeled_int_list_t** trust_list)
  3481 {
  3482     int result;
  3483 
  3484     if (!(session && user_id && user_id[0]))
  3485         return PEP_ILLEGAL_VALUE;
  3486 
  3487     *trust_list = NULL;
  3488     labeled_int_list_t* t_list = NULL;
  3489 
  3490     sqlite3_reset(session->get_trust_by_userid);
  3491     sqlite3_bind_text(session->get_trust_by_userid, 1, user_id, -1, SQLITE_STATIC);
  3492 
  3493     while ((result = Sqlite3_step(session->get_trust_by_userid)) == SQLITE_ROW) {
  3494         if (!t_list)
  3495             t_list = new_labeled_int_list(sqlite3_column_int(session->get_trust_by_userid, 1),
  3496                                          (const char *) sqlite3_column_text(session->get_trust_by_userid, 0));
  3497         else
  3498             labeled_int_list_add(t_list, sqlite3_column_int(session->get_trust_by_userid, 1),
  3499                                 (const char *) sqlite3_column_text(session->get_trust_by_userid, 0));
  3500     }
  3501 
  3502     sqlite3_reset(session->get_trust_by_userid);
  3503 
  3504     *trust_list = t_list;
  3505         
  3506     return PEP_STATUS_OK;
  3507 }
  3508 
  3509 PEP_comm_type reconcile_trust(PEP_comm_type t_old, PEP_comm_type t_new) {
  3510     switch (t_new) {
  3511         case PEP_ct_mistrusted:
  3512         case PEP_ct_key_revoked:
  3513         case PEP_ct_compromised:
  3514         case PEP_ct_key_b0rken:
  3515             return t_new;
  3516         default:
  3517             break;
  3518     }
  3519     switch (t_old) {
  3520         case PEP_ct_mistrusted:
  3521         case PEP_ct_key_revoked:
  3522         case PEP_ct_compromised:
  3523         case PEP_ct_key_b0rken:
  3524             return t_old;
  3525         default:
  3526             break;
  3527     }
  3528     if (t_old < PEP_ct_strong_but_unconfirmed && t_new >= PEP_ct_strong_but_unconfirmed)
  3529         return t_new;
  3530     
  3531     bool confirmed = (t_old & PEP_ct_confirmed) || (t_new & PEP_ct_confirmed);
  3532     PEP_comm_type result = _MAX(t_old, t_new);
  3533     if (confirmed)
  3534         result |= PEP_ct_confirmed;
  3535     return result;
  3536 }
  3537 
  3538 PEP_STATUS reconcile_pEp_status(PEP_SESSION session, const char* old_uid, 
  3539                                 const char* new_uid) {
  3540     PEP_STATUS status = PEP_STATUS_OK;
  3541     // We'll make this easy - if the old one has a pEp status, we set no matter
  3542     // what.
  3543     pEp_identity* ident = new_identity(NULL, NULL, old_uid, NULL);
  3544     bool is_pEp_peep = false;
  3545     status = is_pEp_user(session, ident, &is_pEp_peep);
  3546     if (is_pEp_peep) {
  3547         free(ident->user_id);
  3548         ident->user_id = strdup(new_uid);
  3549         if (!ident->user_id) {
  3550             status = PEP_OUT_OF_MEMORY;
  3551             goto pEp_free;
  3552         }
  3553         status = set_as_pEp_user(session, ident);
  3554     }
  3555 pEp_free:
  3556     free_identity(ident);
  3557     return status;
  3558 }
  3559 
  3560 const char* reconcile_usernames(const char* old_name, const char* new_name, 
  3561                                 const char* address) {
  3562     if (EMPTYSTR(old_name)) {
  3563         if (EMPTYSTR(new_name))
  3564             return address;
  3565         else
  3566             return new_name;
  3567     }
  3568     if (EMPTYSTR(new_name))
  3569         return old_name;        
  3570     if (strcmp(new_name, address) == 0)
  3571         return old_name;
  3572     return new_name;        
  3573 }
  3574 
  3575 PEP_STATUS reconcile_default_keys(PEP_SESSION session, pEp_identity* old_ident,
  3576                                   pEp_identity* new_ident) {
  3577     PEP_STATUS status = PEP_STATUS_OK;
  3578                                       
  3579     const char* old_fpr = old_ident->fpr;
  3580     const char* new_fpr = new_ident->fpr;
  3581     if (!old_fpr)
  3582         return status;
  3583 
  3584     PEP_comm_type old_ct = old_ident->comm_type;    
  3585     PEP_comm_type new_ct = new_ident->comm_type;
  3586     
  3587     if (!new_fpr) {
  3588         new_ident->fpr = strdup(old_fpr);
  3589         if (!new_ident->fpr)
  3590             status = PEP_OUT_OF_MEMORY;
  3591         else    
  3592             new_ident->comm_type = old_ct;
  3593         return status;
  3594     }        
  3595     
  3596     if (strcmp(old_fpr, new_fpr) == 0) {
  3597         new_ident->comm_type = reconcile_trust(old_ct, new_ct);
  3598         return status;
  3599     }
  3600     
  3601     bool old_confirmed = old_ct & PEP_ct_confirmed;
  3602     bool new_confirmed = new_ct & PEP_ct_confirmed;
  3603     
  3604     if (new_confirmed)
  3605         return status;
  3606     else if (old_confirmed) {
  3607         free(new_ident->fpr);
  3608         new_ident->fpr = strdup(old_fpr);
  3609         if (!new_ident->fpr)
  3610             status = PEP_OUT_OF_MEMORY;
  3611         else    
  3612             new_ident->comm_type = old_ct;
  3613         return status;
  3614     }
  3615     
  3616     if (old_ct > new_ct) {
  3617         free(new_ident->fpr);
  3618         new_ident->fpr = strdup(old_fpr);
  3619         if (!new_ident->fpr)
  3620             status = PEP_OUT_OF_MEMORY;
  3621         else    
  3622             new_ident->comm_type = old_ct;
  3623     }
  3624     return status;
  3625 }
  3626 
  3627 void reconcile_language(pEp_identity* old_ident,
  3628                         pEp_identity* new_ident) {
  3629     if (new_ident->lang[0] == 0) {
  3630         if (old_ident->lang[0] != 0) {
  3631             new_ident->lang[0] = old_ident->lang[0];
  3632             new_ident->lang[1] = old_ident->lang[1];
  3633             new_ident->lang[2] = old_ident->lang[2];
  3634         }
  3635     }
  3636 }
  3637 
  3638 // ONLY CALL THIS IF BOTH IDs ARE IN THE PERSON DB, FOOL! </Mr_T>
  3639 PEP_STATUS merge_records(PEP_SESSION session, const char* old_uid,
  3640                          const char* new_uid) {
  3641     PEP_STATUS status = PEP_STATUS_OK;
  3642     
  3643     pEp_identity* new_ident = NULL;
  3644     identity_list* old_identities = NULL;
  3645     labeled_int_list_t* trust_list = NULL;
  3646     stringlist_t* touched_keys = new_stringlist(NULL);
  3647     char* main_user_fpr = NULL;
  3648 
  3649     status = reconcile_pEp_status(session, old_uid, new_uid);
  3650     if (status != PEP_STATUS_OK)
  3651         goto pEp_free;
  3652                         
  3653     bool new_is_pEp = false;
  3654     new_ident = new_identity(NULL, NULL, new_uid, NULL);
  3655     status = is_pEp_user(session, new_ident, &new_is_pEp);
  3656     if (status != PEP_STATUS_OK)
  3657         goto pEp_free;
  3658     free(new_ident);
  3659     new_ident = NULL;
  3660         
  3661     status = get_identities_by_userid(session, old_uid, &old_identities);
  3662     if (status == PEP_STATUS_OK && old_identities) {
  3663         identity_list* curr_old = old_identities;
  3664         for (; curr_old && curr_old->ident; curr_old = curr_old->next) {
  3665             pEp_identity* old_ident = curr_old->ident;
  3666             const char* address = old_ident->address;
  3667             status = get_identity(session, address, new_uid, &new_ident);
  3668             if (status == PEP_CANNOT_FIND_IDENTITY) {
  3669                 // No new identity matching the old one, so we just set one w. new user_id
  3670                 free(old_ident->user_id);
  3671                 old_ident->user_id = strdup(new_uid);
  3672                 if (!old_ident->user_id) {
  3673                     status = PEP_OUT_OF_MEMORY;
  3674                     goto pEp_free;
  3675                 }
  3676                 if (new_is_pEp) {
  3677                     PEP_comm_type confirmed_bit = old_ident->comm_type & PEP_ct_confirmed;
  3678                     if ((old_ident->comm_type | PEP_ct_confirmed) == PEP_ct_OpenPGP)
  3679                         old_ident->comm_type = PEP_ct_pEp_unconfirmed | confirmed_bit;
  3680                 }
  3681                 
  3682                 status = set_identity(session, old_ident);
  3683                 if (status != PEP_STATUS_OK)
  3684                     goto pEp_free;
  3685             }
  3686             else if (status != PEP_STATUS_OK)
  3687                 goto pEp_free;
  3688             else {
  3689                 // Ok, so we have two idents which might be in conflict. Have to merge them.
  3690                 const char* username = reconcile_usernames(old_ident->username,
  3691                                                            new_ident->username,
  3692                                                            address);
  3693                                                            
  3694                 if (!new_ident->username || strcmp(username, new_ident->username) != 0) {
  3695                     free(new_ident->username);
  3696                     new_ident->username = strdup(username);
  3697                     if (!new_ident->username) {
  3698                         status = PEP_OUT_OF_MEMORY;
  3699                         goto pEp_free;
  3700                     }
  3701                 }
  3702         
  3703                 // Reconcile default keys if they differ, trust if they don't
  3704                 status = reconcile_default_keys(session, old_ident, new_ident);
  3705                 if (status != PEP_STATUS_OK)
  3706                     goto pEp_free;
  3707                     
  3708                 // reconcile languages
  3709                 reconcile_language(old_ident, new_ident);
  3710 
  3711                 // reconcile flags - FIXME - is this right?
  3712                 new_ident->flags |= old_ident->flags;
  3713                 
  3714                 // NOTE: In principle, this is only called from update_identity,
  3715                 // which would never have me flags set. So I am ignoring them here.
  3716                 // if this function is ever USED for that, though, you'll have
  3717                 // to go through making sure that the user ids are appropriately
  3718                 // aliased, etc. So be careful.
  3719                 
  3720                 // Set the reconciled record
  3721                     
  3722                 status = set_identity(session, new_ident);
  3723                 if (status != PEP_STATUS_OK)
  3724                     goto pEp_free;
  3725 
  3726                 if (new_ident->fpr)
  3727                     stringlist_add(touched_keys, new_ident->fpr);
  3728                         
  3729                 free_identity(new_ident);
  3730                 new_ident = NULL;    
  3731             }
  3732         }
  3733     }
  3734     // otherwise, no need to reconcile identity records. But maybe trust...    
  3735     new_ident = new_identity(NULL, NULL, new_uid, NULL);
  3736     if (!new_ident) {
  3737         status = PEP_OUT_OF_MEMORY;
  3738         goto pEp_free;
  3739     }
  3740     status = get_trust_by_userid(session, old_uid, &trust_list);
  3741 
  3742     labeled_int_list_t* trust_curr = trust_list;
  3743     for (; trust_curr && trust_curr->label; trust_curr = trust_curr->next) {
  3744         const char* curr_fpr = trust_curr->label;
  3745         new_ident->fpr = strdup(curr_fpr); 
  3746         status = get_trust(session, new_ident);
  3747         switch (status) {
  3748             case PEP_STATUS_OK:
  3749                 new_ident->comm_type = reconcile_trust(trust_curr->value,
  3750                                                        new_ident->comm_type);
  3751                 break;
  3752             case PEP_CANNOT_FIND_IDENTITY:
  3753                 new_ident->comm_type = trust_curr->value;
  3754                 break;
  3755             default:
  3756                 goto pEp_free;
  3757         }
  3758         new_ident->comm_type = reconcile_trust(trust_curr->value,
  3759                                                new_ident->comm_type);
  3760         if (new_is_pEp) {
  3761             PEP_comm_type confirmed_bit = new_ident->comm_type & PEP_ct_confirmed;
  3762             if ((new_ident->comm_type | PEP_ct_confirmed) == PEP_ct_OpenPGP)
  3763                 new_ident->comm_type = PEP_ct_pEp_unconfirmed | confirmed_bit;
  3764         }
  3765 
  3766         status = set_trust(session, new_ident);
  3767         if (status != PEP_STATUS_OK) {
  3768             goto pEp_free;
  3769         }                  
  3770                               
  3771         free(new_ident->fpr);
  3772         new_ident->fpr = NULL;
  3773         new_ident->comm_type = 0;
  3774     }
  3775 
  3776     // reconcile the default keys if the new id doesn't have one?
  3777     status = get_main_user_fpr(session, new_uid, &main_user_fpr);
  3778     if (status == PEP_KEY_NOT_FOUND || (status == PEP_STATUS_OK && !main_user_fpr)) {
  3779         status = get_main_user_fpr(session, old_uid, &main_user_fpr);
  3780         if (status == PEP_STATUS_OK && main_user_fpr)
  3781             status = replace_main_user_fpr(session, new_uid, main_user_fpr);
  3782         if (status != PEP_STATUS_OK)
  3783             goto pEp_free;
  3784     }
  3785     
  3786     // delete the old user
  3787     status = delete_person(session, old_uid);
  3788     
  3789 pEp_free:
  3790     free_identity(new_ident);
  3791     free_identity_list(old_identities);
  3792     free_labeled_int_list(trust_list);
  3793     free_stringlist(touched_keys);
  3794     free(main_user_fpr);
  3795     return status;
  3796 }
  3797 
  3798 PEP_STATUS replace_userid(PEP_SESSION session, const char* old_uid,
  3799                           const char* new_uid) {
  3800     assert(session);
  3801     assert(old_uid);
  3802     assert(new_uid);
  3803     
  3804     if (!session || !old_uid || !new_uid)
  3805         return PEP_ILLEGAL_VALUE;
  3806 
  3807     pEp_identity* temp_ident = new_identity(NULL, NULL, new_uid, NULL);
  3808     bool new_exists = false;
  3809     PEP_STATUS status = exists_person(session, temp_ident, &new_exists);
  3810     free_identity(temp_ident);
  3811     if (status != PEP_STATUS_OK) // DB error
  3812         return status;
  3813         
  3814     if (new_exists)
  3815         return merge_records(session, old_uid, new_uid);
  3816 
  3817     int result;
  3818 
  3819     sqlite3_reset(session->replace_userid);
  3820     sqlite3_bind_text(session->replace_userid, 1, new_uid, -1,
  3821             SQLITE_STATIC);
  3822     sqlite3_bind_text(session->replace_userid, 2, old_uid, -1,
  3823             SQLITE_STATIC);
  3824     result = Sqlite3_step(session->replace_userid);
  3825 #ifndef NDEBUG
  3826     if (result) {
  3827         const char *errmsg = sqlite3_errmsg(session->db);
  3828         log_event(session, "SQLite3 error", "replace_userid", errmsg, NULL);
  3829     }
  3830 #endif // !NDEBUG
  3831     sqlite3_reset(session->replace_userid);
  3832     if (result != SQLITE_DONE)
  3833         return PEP_CANNOT_SET_PERSON; // May need clearer retval
  3834 
  3835     return PEP_STATUS_OK;
  3836 }
  3837 
  3838 PEP_STATUS remove_key(PEP_SESSION session, const char* fpr) {
  3839     assert(session);
  3840     assert(fpr);
  3841     
  3842     if (!session || EMPTYSTR(fpr))
  3843         return PEP_ILLEGAL_VALUE;
  3844 
  3845     int result;
  3846 
  3847     sqlite3_reset(session->delete_key);
  3848     sqlite3_bind_text(session->delete_key, 1, fpr, -1,
  3849             SQLITE_STATIC);
  3850     result = Sqlite3_step(session->delete_key);
  3851     sqlite3_reset(session->delete_key);
  3852     if (result != SQLITE_DONE)
  3853         return PEP_CANNOT_SET_PGP_KEYPAIR;
  3854 
  3855     return PEP_STATUS_OK;
  3856 }
  3857 
  3858 
  3859 PEP_STATUS refresh_userid_default_key(PEP_SESSION session, const char* user_id) {
  3860     assert(session);
  3861     assert(user_id);
  3862     
  3863     if (!session || !user_id)
  3864         return PEP_ILLEGAL_VALUE;
  3865 
  3866     int result;
  3867 
  3868     sqlite3_reset(session->refresh_userid_default_key);
  3869     sqlite3_bind_text(session->refresh_userid_default_key, 1, user_id, -1,
  3870             SQLITE_STATIC);
  3871     result = Sqlite3_step(session->refresh_userid_default_key);
  3872     sqlite3_reset(session->refresh_userid_default_key);
  3873     if (result != SQLITE_DONE)
  3874         return PEP_CANNOT_SET_PERSON;
  3875 
  3876     return PEP_STATUS_OK;    
  3877 }
  3878 
  3879 PEP_STATUS replace_main_user_fpr(PEP_SESSION session, const char* user_id,
  3880                                  const char* new_fpr) {
  3881     assert(session);
  3882     assert(user_id);
  3883     assert(new_fpr);
  3884     
  3885     if (!session || !user_id || !new_fpr)
  3886         return PEP_ILLEGAL_VALUE;
  3887 
  3888     int result;
  3889 
  3890     sqlite3_reset(session->replace_main_user_fpr);
  3891     sqlite3_bind_text(session->replace_main_user_fpr, 1, new_fpr, -1,
  3892             SQLITE_STATIC);
  3893     sqlite3_bind_text(session->replace_main_user_fpr, 2, user_id, -1,
  3894             SQLITE_STATIC);
  3895     result = Sqlite3_step(session->replace_main_user_fpr);
  3896     sqlite3_reset(session->replace_main_user_fpr);
  3897     if (result != SQLITE_DONE)
  3898         return PEP_CANNOT_SET_PERSON;
  3899 
  3900     return PEP_STATUS_OK;
  3901 }
  3902 
  3903 PEP_STATUS get_main_user_fpr(PEP_SESSION session, 
  3904                              const char* user_id,
  3905                              char** main_fpr)
  3906 {
  3907     PEP_STATUS status = PEP_STATUS_OK;
  3908     int result;
  3909     
  3910     assert(session);
  3911     assert(user_id);
  3912     assert(main_fpr);
  3913     
  3914     if (!(session && user_id && user_id[0] && main_fpr))
  3915         return PEP_ILLEGAL_VALUE;
  3916         
  3917     *main_fpr = NULL;
  3918     
  3919     sqlite3_reset(session->get_main_user_fpr);
  3920     sqlite3_bind_text(session->get_main_user_fpr, 1, user_id, -1,
  3921                       SQLITE_STATIC);
  3922     result = Sqlite3_step(session->get_main_user_fpr);
  3923     switch (result) {
  3924     case SQLITE_ROW: {
  3925         const char* _fpr = 
  3926             (const char *) sqlite3_column_text(session->get_main_user_fpr, 0);
  3927         if (_fpr) {
  3928             *main_fpr = strdup(_fpr);
  3929             if (!(*main_fpr))
  3930                 status = PEP_OUT_OF_MEMORY;
  3931         }
  3932         else {
  3933             status = PEP_KEY_NOT_FOUND;
  3934         }
  3935         break;
  3936     }
  3937     default:
  3938         status = PEP_CANNOT_FIND_PERSON;
  3939     }
  3940 
  3941     sqlite3_reset(session->get_main_user_fpr);
  3942     return status;
  3943 }
  3944 
  3945 // Deprecated
  3946 DYNAMIC_API PEP_STATUS mark_as_compromized(
  3947         PEP_SESSION session,
  3948         const char *fpr
  3949     )
  3950 {
  3951     return mark_as_compromised(session, fpr);
  3952 }
  3953 
  3954 DYNAMIC_API PEP_STATUS mark_as_compromised(
  3955         PEP_SESSION session,
  3956         const char *fpr
  3957     )
  3958 {
  3959     int result;
  3960 
  3961     assert(session);
  3962     assert(fpr && fpr[0]);
  3963 
  3964     if (!(session && fpr && fpr[0]))
  3965         return PEP_ILLEGAL_VALUE;
  3966 
  3967     sqlite3_reset(session->mark_compromised);
  3968     sqlite3_bind_text(session->mark_compromised, 1, fpr, -1,
  3969             SQLITE_STATIC);
  3970     result = Sqlite3_step(session->mark_compromised);
  3971     sqlite3_reset(session->mark_compromised);
  3972 
  3973     if (result != SQLITE_DONE)
  3974         return PEP_CANNOT_SET_TRUST;
  3975 
  3976     return PEP_STATUS_OK;
  3977 }
  3978 
  3979 void pEp_free(void *p)
  3980 {
  3981     free(p);
  3982 }
  3983 
  3984 
  3985 DYNAMIC_API PEP_STATUS get_trust(PEP_SESSION session, pEp_identity *identity)
  3986 {
  3987     PEP_STATUS status = PEP_STATUS_OK;
  3988     int result;
  3989 
  3990     // We need to be able to test that we break correctly without shutting
  3991     // asserts off everywhere.
  3992     // assert(session);
  3993     // assert(identity);
  3994     // assert(identity->user_id);
  3995     // assert(identity->user_id[0]);
  3996     // assert(identity->fpr);
  3997     // assert(identity->fpr[0]);
  3998 
  3999     if (!(session && identity && identity->user_id && identity->user_id[0] &&
  4000                 identity->fpr && identity->fpr[0]))
  4001         return PEP_ILLEGAL_VALUE;
  4002 
  4003     identity->comm_type = PEP_ct_unknown;
  4004     sqlite3_reset(session->get_trust);
  4005 
  4006     sqlite3_bind_text(session->get_trust, 1, identity->user_id, -1,
  4007             SQLITE_STATIC);
  4008     sqlite3_bind_text(session->get_trust, 2, identity->fpr, -1, SQLITE_STATIC);
  4009 
  4010     result = Sqlite3_step(session->get_trust);
  4011     switch (result) {
  4012     case SQLITE_ROW: {
  4013         int comm_type = (PEP_comm_type) sqlite3_column_int(session->get_trust,
  4014                 0);
  4015         identity->comm_type = comm_type;
  4016         break;
  4017     }
  4018  
  4019     default:
  4020         status = PEP_CANNOT_FIND_IDENTITY;
  4021     }
  4022 
  4023     sqlite3_reset(session->get_trust);
  4024     return status;
  4025 }
  4026 
  4027 
  4028 DYNAMIC_API PEP_STATUS least_trust(
  4029         PEP_SESSION session,
  4030         const char *fpr,
  4031         PEP_comm_type *comm_type
  4032     )
  4033 {
  4034     PEP_STATUS status = PEP_STATUS_OK;
  4035     int result;
  4036 
  4037     assert(session);
  4038     assert(fpr);
  4039     assert(comm_type);
  4040 
  4041     if (!(session && fpr && comm_type))
  4042         return PEP_ILLEGAL_VALUE;
  4043 
  4044     *comm_type = PEP_ct_unknown;
  4045 
  4046     sqlite3_reset(session->least_trust);
  4047     sqlite3_bind_text(session->least_trust, 1, fpr, -1, SQLITE_STATIC);
  4048 
  4049     result = Sqlite3_step(session->least_trust);
  4050     switch (result) {
  4051         case SQLITE_ROW: {
  4052             int _comm_type = sqlite3_column_int(session->least_trust, 0);
  4053             *comm_type = (PEP_comm_type) _comm_type;
  4054             break;
  4055         }
  4056         default:
  4057             // never reached because of sql min()
  4058             status = PEP_CANNOT_FIND_IDENTITY;
  4059     }
  4060 
  4061     sqlite3_reset(session->least_trust);
  4062     return status;
  4063 }
  4064 
  4065 DYNAMIC_API PEP_STATUS decrypt_and_verify(
  4066     PEP_SESSION session, const char *ctext, size_t csize,
  4067     const char *dsigtext, size_t dsigsize,
  4068     char **ptext, size_t *psize, stringlist_t **keylist,
  4069     char** filename_ptr
  4070     )
  4071 {
  4072     assert(session);
  4073     assert(ctext);
  4074     assert(csize);
  4075     assert(ptext);
  4076     assert(psize);
  4077     assert(keylist);
  4078 
  4079     if (!(session && ctext && csize && ptext && psize && keylist))
  4080         return PEP_ILLEGAL_VALUE;
  4081 
  4082     PEP_STATUS status = session->cryptotech[PEP_crypt_OpenPGP].decrypt_and_verify(
  4083             session, ctext, csize, dsigtext, dsigsize, ptext, psize, keylist,
  4084             filename_ptr);
  4085 
  4086     if (status == PEP_DECRYPT_NO_KEY)
  4087         signal_Sync_event(session, Sync_PR_keysync, CannotDecrypt, NULL);
  4088 
  4089     return status;
  4090 }
  4091 
  4092 DYNAMIC_API PEP_STATUS encrypt_and_sign(
  4093     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  4094     size_t psize, char **ctext, size_t *csize
  4095     )
  4096 {
  4097     assert(session);
  4098     assert(keylist);
  4099     assert(ptext);
  4100     assert(psize);
  4101     assert(ctext);
  4102     assert(csize);
  4103 
  4104     if (!(session && keylist && ptext && psize && ctext && csize))
  4105         return PEP_ILLEGAL_VALUE;
  4106 
  4107     return session->cryptotech[PEP_crypt_OpenPGP].encrypt_and_sign(session,
  4108             keylist, ptext, psize, ctext, csize);
  4109 }
  4110 
  4111 PEP_STATUS encrypt_only(
  4112     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  4113     size_t psize, char **ctext, size_t *csize
  4114     )
  4115 {
  4116     assert(session);
  4117     assert(keylist);
  4118     assert(ptext);
  4119     assert(psize);
  4120     assert(ctext);
  4121     assert(csize);
  4122 
  4123     if (!(session && keylist && ptext && psize && ctext && csize))
  4124         return PEP_ILLEGAL_VALUE;
  4125 
  4126     return session->cryptotech[PEP_crypt_OpenPGP].encrypt_only(session,
  4127             keylist, ptext, psize, ctext, csize);
  4128 }
  4129 
  4130 PEP_STATUS sign_only(PEP_SESSION session, 
  4131                      const char *data, 
  4132                      size_t data_size, 
  4133                      const char *fpr, 
  4134                      char **sign, 
  4135                      size_t *sign_size) {
  4136     assert(session);
  4137     assert(fpr);
  4138     assert(data);
  4139     assert(data_size);
  4140     assert(sign);
  4141     assert(sign_size);
  4142 
  4143     if (!(session && fpr && data && data_size && sign && sign_size))
  4144         return PEP_ILLEGAL_VALUE;
  4145 
  4146     return session->cryptotech[PEP_crypt_OpenPGP].sign_only(session,
  4147                                 fpr, data, data_size, sign, sign_size);
  4148                          
  4149 }
  4150 
  4151 
  4152 
  4153 DYNAMIC_API PEP_STATUS verify_text(
  4154     PEP_SESSION session, const char *text, size_t size,
  4155     const char *signature, size_t sig_size, stringlist_t **keylist
  4156     )
  4157 {
  4158     assert(session);
  4159     assert(text);
  4160     assert(size);
  4161     assert(signature);
  4162     assert(sig_size);
  4163     assert(keylist);
  4164 
  4165     if (!(session && text && size && signature && sig_size && keylist))
  4166         return PEP_ILLEGAL_VALUE;
  4167 
  4168     return session->cryptotech[PEP_crypt_OpenPGP].verify_text(session, text,
  4169             size, signature, sig_size, keylist);
  4170 }
  4171 
  4172 DYNAMIC_API PEP_STATUS delete_keypair(PEP_SESSION session, const char *fpr)
  4173 {
  4174     assert(session);
  4175     assert(fpr);
  4176 
  4177     if (!(session && fpr))
  4178         return PEP_ILLEGAL_VALUE;
  4179 
  4180     return session->cryptotech[PEP_crypt_OpenPGP].delete_keypair(session, fpr);
  4181 }
  4182 
  4183 DYNAMIC_API PEP_STATUS export_key(
  4184         PEP_SESSION session, const char *fpr, char **key_data, size_t *size
  4185     )
  4186 {
  4187     assert(session);
  4188     assert(fpr);
  4189     assert(key_data);
  4190     assert(size);
  4191 
  4192     if (!(session && fpr && key_data && size))
  4193         return PEP_ILLEGAL_VALUE;
  4194 
  4195     return session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr,
  4196             key_data, size, false);
  4197 }
  4198 
  4199 DYNAMIC_API PEP_STATUS export_secret_key(
  4200         PEP_SESSION session, const char *fpr, char **key_data, size_t *size
  4201     )
  4202 {
  4203     assert(session);
  4204     assert(fpr);
  4205     assert(key_data);
  4206     assert(size);
  4207 
  4208     if (!(session && fpr && key_data && size))
  4209         return PEP_ILLEGAL_VALUE;
  4210 
  4211     // don't accept key IDs but full fingerprints only
  4212     if (strlen(fpr) < 16)
  4213         return PEP_ILLEGAL_VALUE;
  4214 
  4215     return session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr,
  4216             key_data, size, true);
  4217 }
  4218 
  4219 // Deprecated
  4220 DYNAMIC_API PEP_STATUS export_secrect_key(
  4221         PEP_SESSION session, const char *fpr, char **key_data, size_t *size
  4222     )
  4223 {
  4224     return export_secret_key(session, fpr, key_data, size);
  4225 }
  4226 
  4227 DYNAMIC_API PEP_STATUS find_keys(
  4228         PEP_SESSION session, const char *pattern, stringlist_t **keylist
  4229     )
  4230 {
  4231     assert(session);
  4232     assert(pattern);
  4233     assert(keylist);
  4234 
  4235     if (!(session && pattern && keylist))
  4236         return PEP_ILLEGAL_VALUE;
  4237 
  4238     return session->cryptotech[PEP_crypt_OpenPGP].find_keys(session, pattern,
  4239             keylist);
  4240 }
  4241 
  4242 
  4243 DYNAMIC_API PEP_STATUS generate_keypair(
  4244         PEP_SESSION session, pEp_identity *identity
  4245     )
  4246 {
  4247     assert(session);
  4248     assert(identity);
  4249     assert(identity->address);
  4250     assert(identity->fpr == NULL || identity->fpr[0] == 0);
  4251     assert(identity->username);
  4252 
  4253     if (!(session && identity && identity->address &&
  4254             (identity->fpr == NULL || identity->fpr[0] == 0) &&
  4255             identity->username))
  4256         return PEP_ILLEGAL_VALUE;
  4257 
  4258     PEP_STATUS status =
  4259         session->cryptotech[PEP_crypt_OpenPGP].generate_keypair(session,
  4260                 identity);
  4261     if (status != PEP_STATUS_OK)
  4262         return status;
  4263 
  4264     if (identity->fpr)
  4265         status = set_pgp_keypair(session, identity->fpr);
  4266 
  4267     signal_Sync_event(session, Sync_PR_keysync, KeyGen, NULL);
  4268 
  4269     // add to known keypair DB, as this might not end up being a default
  4270     return status;
  4271 }
  4272 
  4273 DYNAMIC_API PEP_STATUS get_key_rating(
  4274         PEP_SESSION session,
  4275         const char *fpr,
  4276         PEP_comm_type *comm_type
  4277     )
  4278 {
  4279     assert(session);
  4280     assert(fpr);
  4281     assert(comm_type);
  4282 
  4283     if (!(session && fpr && comm_type))
  4284         return PEP_ILLEGAL_VALUE;
  4285 
  4286     return session->cryptotech[PEP_crypt_OpenPGP].get_key_rating(session, fpr,
  4287             comm_type);
  4288 }
  4289 
  4290 DYNAMIC_API PEP_STATUS import_key(
  4291         PEP_SESSION session,
  4292         const char *key_data,
  4293         size_t size,
  4294         identity_list **private_keys
  4295     )
  4296 {
  4297     assert(session);
  4298     assert(key_data);
  4299 
  4300     if (!(session && key_data))
  4301         return PEP_ILLEGAL_VALUE;
  4302 
  4303     return session->cryptotech[PEP_crypt_OpenPGP].import_key(session, key_data,
  4304             size, private_keys);
  4305 }
  4306 
  4307 DYNAMIC_API PEP_STATUS recv_key(PEP_SESSION session, const char *pattern)
  4308 {
  4309     assert(session);
  4310     assert(pattern);
  4311 
  4312     if (!(session && pattern))
  4313         return PEP_ILLEGAL_VALUE;
  4314 
  4315     return session->cryptotech[PEP_crypt_OpenPGP].recv_key(session, pattern);
  4316 }
  4317 
  4318 DYNAMIC_API PEP_STATUS send_key(PEP_SESSION session, const char *pattern)
  4319 {
  4320     assert(session);
  4321     assert(pattern);
  4322 
  4323     if (!(session && pattern))
  4324         return PEP_ILLEGAL_VALUE;
  4325 
  4326     return session->cryptotech[PEP_crypt_OpenPGP].send_key(session, pattern);
  4327 }
  4328 
  4329 DYNAMIC_API PEP_STATUS renew_key(
  4330         PEP_SESSION session,
  4331         const char *fpr,
  4332         const timestamp *ts
  4333     )
  4334 {
  4335     assert(session);
  4336     assert(fpr);
  4337 
  4338     if (!(session && fpr))
  4339         return PEP_ILLEGAL_VALUE;
  4340 
  4341     return session->cryptotech[PEP_crypt_OpenPGP].renew_key(session, fpr, ts);
  4342 }
  4343 
  4344 DYNAMIC_API PEP_STATUS revoke_key(
  4345         PEP_SESSION session,
  4346         const char *fpr,
  4347         const char *reason
  4348     )
  4349 {
  4350     assert(session);
  4351     assert(fpr);
  4352 
  4353     if (!(session && fpr))
  4354         return PEP_ILLEGAL_VALUE;
  4355 
  4356     // Check to see first if it is revoked
  4357     bool revoked = false;
  4358     PEP_STATUS status = key_revoked(session, fpr, &revoked);
  4359     if (status != PEP_STATUS_OK)
  4360         return status;
  4361         
  4362     if (revoked)
  4363         return PEP_STATUS_OK;
  4364 
  4365     return session->cryptotech[PEP_crypt_OpenPGP].revoke_key(session, fpr,
  4366             reason);
  4367 }
  4368 
  4369 DYNAMIC_API PEP_STATUS key_expired(
  4370         PEP_SESSION session,
  4371         const char *fpr,
  4372         const time_t when,
  4373         bool *expired
  4374     )
  4375 {
  4376     assert(session);
  4377     assert(fpr);
  4378     assert(expired);
  4379 
  4380     if (!(session && fpr && expired))
  4381         return PEP_ILLEGAL_VALUE;
  4382 
  4383     return session->cryptotech[PEP_crypt_OpenPGP].key_expired(session, fpr,
  4384             when, expired);
  4385 }
  4386 
  4387 DYNAMIC_API PEP_STATUS key_revoked(
  4388        PEP_SESSION session,
  4389        const char *fpr,
  4390        bool *revoked
  4391    )
  4392 {
  4393     assert(session);
  4394     assert(fpr);
  4395     assert(revoked);
  4396     
  4397     if (!(session && fpr && revoked))
  4398         return PEP_ILLEGAL_VALUE;
  4399     
  4400     return session->cryptotech[PEP_crypt_OpenPGP].key_revoked(session, fpr,
  4401             revoked);
  4402 }
  4403 
  4404 DYNAMIC_API PEP_STATUS config_cipher_suite(PEP_SESSION session,
  4405         PEP_CIPHER_SUITE suite)
  4406 {
  4407     assert(session);
  4408     if (!session)
  4409         return PEP_ILLEGAL_VALUE;
  4410 
  4411     return session->cryptotech[PEP_crypt_OpenPGP].config_cipher_suite(session, suite);
  4412 }
  4413 
  4414 static void _clean_log_value(char *text)
  4415 {
  4416     if (text) {
  4417         for (char *c = text; *c; c++) {
  4418             if (*c < 32 && *c != '\n')
  4419                 *c = 32;
  4420             else if (*c == '"')
  4421                 *c = '\'';
  4422         }
  4423     }
  4424 }
  4425 
  4426 static char *_concat_string(char *str1, const char *str2, char delim)
  4427 {
  4428     str2 = str2 ? str2 : "";
  4429     size_t len1 = str1 ? strlen(str1) : 0;
  4430     size_t len2 = strlen(str2);
  4431     size_t len = len1 + len2 + 3;
  4432     char * result = realloc(str1, len + 1);
  4433 
  4434     if (result) {
  4435         result[len1] = '"';
  4436         strcpy(result + len1 + 1, str2);
  4437         result[len - 2] = '"';
  4438         result[len - 1] = delim;
  4439         result[len] = 0;
  4440     }
  4441     else {
  4442         free(str1);
  4443     }
  4444 
  4445     return result;
  4446 }
  4447 
  4448 DYNAMIC_API PEP_STATUS get_crashdump_log(
  4449         PEP_SESSION session,
  4450         int maxlines,
  4451         char **logdata
  4452     )
  4453 {
  4454     PEP_STATUS status = PEP_STATUS_OK;
  4455     char *_logdata= NULL;
  4456 
  4457     assert(session);
  4458     assert(maxlines >= 0 && maxlines <= CRASHDUMP_MAX_LINES);
  4459     assert(logdata);
  4460 
  4461     if (!(session && logdata && maxlines >= 0 && maxlines <=
  4462             CRASHDUMP_MAX_LINES))
  4463         return PEP_ILLEGAL_VALUE;
  4464 
  4465     *logdata = NULL;
  4466 
  4467     int limit = maxlines ? maxlines : CRASHDUMP_DEFAULT_LINES;
  4468     const char *timestamp = NULL;
  4469     const char *title = NULL;
  4470     const char *entity = NULL;
  4471     const char *desc = NULL;
  4472     const char *comment = NULL;
  4473 
  4474     sqlite3_reset(session->crashdump);
  4475     sqlite3_bind_int(session->crashdump, 1, limit);
  4476 
  4477     int result;
  4478 
  4479     do {
  4480         result = Sqlite3_step(session->crashdump);
  4481         switch (result) {
  4482         case SQLITE_ROW:
  4483             timestamp = (const char *) sqlite3_column_text(session->crashdump,
  4484                     0);
  4485             title   = (const char *) sqlite3_column_text(session->crashdump,
  4486                     1);
  4487             entity  = (const char *) sqlite3_column_text(session->crashdump,
  4488                     2);
  4489             desc    = (const char *) sqlite3_column_text(session->crashdump,
  4490                     3);
  4491             comment = (const char *) sqlite3_column_text(session->crashdump,
  4492                     4);
  4493 
  4494             _logdata = _concat_string(_logdata, timestamp, ',');
  4495             if (_logdata == NULL)
  4496                 goto enomem;
  4497 
  4498             _logdata = _concat_string(_logdata, title, ',');
  4499             if (_logdata == NULL)
  4500                 goto enomem;
  4501 
  4502             _logdata = _concat_string(_logdata, entity, ',');
  4503             if (_logdata == NULL)
  4504                 goto enomem;
  4505 
  4506             _logdata = _concat_string(_logdata, desc, ',');
  4507             if (_logdata == NULL)
  4508                 goto enomem;
  4509 
  4510             _logdata = _concat_string(_logdata, comment, '\n');
  4511             if (_logdata == NULL)
  4512                 goto enomem;
  4513 
  4514             _clean_log_value(_logdata);
  4515             break;
  4516 
  4517         case SQLITE_DONE:
  4518             break;
  4519 
  4520         default:
  4521             status = PEP_UNKNOWN_ERROR;
  4522             result = SQLITE_DONE;
  4523         }
  4524     } while (result != SQLITE_DONE);
  4525 
  4526     sqlite3_reset(session->crashdump);
  4527     if (status == PEP_STATUS_OK) {
  4528         if (_logdata) {
  4529             *logdata = _logdata;
  4530         }
  4531         else {
  4532             *logdata = strdup("");
  4533             if (!*logdata)
  4534                 goto enomem;
  4535         }
  4536     }
  4537 
  4538     goto the_end;
  4539 
  4540 enomem:
  4541     status = PEP_OUT_OF_MEMORY;
  4542 
  4543 the_end:
  4544     return status;
  4545 }
  4546 
  4547 DYNAMIC_API PEP_STATUS get_languagelist(
  4548         PEP_SESSION session,
  4549         char **languages
  4550     )
  4551 {
  4552     PEP_STATUS status = PEP_STATUS_OK;
  4553     char *_languages= NULL;
  4554 
  4555     assert(session);
  4556     assert(languages);
  4557 
  4558     if (!(session && languages))
  4559         return PEP_ILLEGAL_VALUE;
  4560 
  4561     *languages = NULL;
  4562 
  4563     const char *lang = NULL;
  4564     const char *name = NULL;
  4565     const char *phrase = NULL;
  4566 
  4567     sqlite3_reset(session->languagelist);
  4568 
  4569     int result;
  4570 
  4571     do {
  4572         result = Sqlite3_step(session->languagelist);
  4573         switch (result) {
  4574         case SQLITE_ROW:
  4575             lang = (const char *) sqlite3_column_text(session->languagelist,
  4576                     0);
  4577             name = (const char *) sqlite3_column_text(session->languagelist,
  4578                     1);
  4579             phrase = (const char *) sqlite3_column_text(session->languagelist,
  4580                     2);
  4581 
  4582             _languages = _concat_string(_languages, lang, ',');
  4583             if (_languages == NULL)
  4584                 goto enomem;
  4585 
  4586             _languages = _concat_string(_languages, name, ',');
  4587             if (_languages == NULL)
  4588                 goto enomem;
  4589 
  4590             _languages = _concat_string(_languages, phrase, '\n');
  4591             if (_languages == NULL)
  4592                 goto enomem;
  4593 
  4594             break;
  4595 
  4596         case SQLITE_DONE:
  4597             break;
  4598 
  4599         default:
  4600             status = PEP_UNKNOWN_DB_ERROR;
  4601             result = SQLITE_DONE;
  4602         }
  4603     } while (result != SQLITE_DONE);
  4604 
  4605     sqlite3_reset(session->languagelist);
  4606     if (status == PEP_STATUS_OK)
  4607         *languages = _languages;
  4608 
  4609     goto the_end;
  4610 
  4611 enomem:
  4612     status = PEP_OUT_OF_MEMORY;
  4613 
  4614 the_end:
  4615     return status;
  4616 }
  4617 
  4618 DYNAMIC_API PEP_STATUS get_phrase(
  4619         PEP_SESSION session,
  4620         const char *lang,
  4621         int phrase_id,
  4622         char **phrase
  4623     )
  4624 {
  4625     PEP_STATUS status = PEP_STATUS_OK;
  4626 
  4627     assert(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase);
  4628     if (!(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase))
  4629         return PEP_ILLEGAL_VALUE;
  4630 
  4631     *phrase = NULL;
  4632 
  4633     sqlite3_reset(session->i18n_token);
  4634     sqlite3_bind_text(session->i18n_token, 1, lang, -1, SQLITE_STATIC);
  4635     sqlite3_bind_int(session->i18n_token, 2, phrase_id);
  4636 
  4637     const char *_phrase = NULL;
  4638     int result;
  4639 
  4640     result = Sqlite3_step(session->i18n_token);
  4641     switch (result) {
  4642     case SQLITE_ROW:
  4643         _phrase = (const char *) sqlite3_column_text(session->i18n_token, 0);
  4644         break;
  4645 
  4646     case SQLITE_DONE:
  4647         status = PEP_PHRASE_NOT_FOUND;
  4648         break;
  4649 
  4650     default:
  4651         status = PEP_UNKNOWN_DB_ERROR;
  4652     }
  4653 
  4654     if (status == PEP_STATUS_OK) {
  4655         *phrase = strdup(_phrase);
  4656         if (*phrase == NULL)
  4657             goto enomem;
  4658     }
  4659 
  4660     sqlite3_reset(session->i18n_token);
  4661     goto the_end;
  4662 
  4663 enomem:
  4664     status = PEP_OUT_OF_MEMORY;
  4665 
  4666 the_end:
  4667     return status;
  4668 }
  4669 
  4670 static PEP_STATUS _get_sequence_value(PEP_SESSION session, const char *name,
  4671         int32_t *value)
  4672 {
  4673     assert(session && name && value);
  4674     if (!(session && name && value))
  4675         return PEP_ILLEGAL_VALUE;
  4676 
  4677     PEP_STATUS status = PEP_STATUS_OK;
  4678 
  4679     sqlite3_reset(session->sequence_value2);
  4680     sqlite3_bind_text(session->sequence_value2, 1, name, -1,
  4681             SQLITE_STATIC);
  4682     int result = Sqlite3_step(session->sequence_value2);
  4683     switch (result) {
  4684         case SQLITE_ROW: {
  4685             int32_t _value = (int32_t)
  4686                     sqlite3_column_int(session->sequence_value2, 0);
  4687             *value = _value;
  4688             break;
  4689         }
  4690         case SQLITE_DONE:
  4691             status = PEP_RECORD_NOT_FOUND;
  4692             break;
  4693         default:
  4694             status = PEP_UNKNOWN_DB_ERROR;
  4695     }
  4696     sqlite3_reset(session->sequence_value2);
  4697 
  4698     return status;
  4699 }
  4700 
  4701 static PEP_STATUS _increment_sequence_value(PEP_SESSION session,
  4702         const char *name)
  4703 {
  4704     assert(session && name);
  4705     if (!(session && name))
  4706         return PEP_ILLEGAL_VALUE;
  4707 
  4708     sqlite3_reset(session->sequence_value1);
  4709     sqlite3_bind_text(session->sequence_value1, 1, name, -1, SQLITE_STATIC);
  4710     int result = Sqlite3_step(session->sequence_value1);
  4711     assert(result == SQLITE_DONE);
  4712     sqlite3_reset(session->sequence_value1);
  4713     if (result == SQLITE_DONE)
  4714         return PEP_STATUS_OK;
  4715     else
  4716         return PEP_CANNOT_INCREASE_SEQUENCE;
  4717 }
  4718 
  4719 DYNAMIC_API PEP_STATUS sequence_value(
  4720         PEP_SESSION session,
  4721         const char *name,
  4722         int32_t *value
  4723     )
  4724 {
  4725     PEP_STATUS status = PEP_STATUS_OK;
  4726 
  4727     assert(session);
  4728     assert(name && value);
  4729 
  4730     if (!(session && name && name[0] && value))
  4731         return PEP_ILLEGAL_VALUE;
  4732 
  4733     *value = 0;
  4734     sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  4735     status = _increment_sequence_value(session, name);
  4736     if (status == PEP_STATUS_OK)
  4737         status = _get_sequence_value(session, name, value);
  4738 
  4739     if (status == PEP_STATUS_OK) {
  4740         int result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  4741         if (result == SQLITE_OK){
  4742             assert(*value < INT32_MAX);
  4743             if (*value == INT32_MAX){
  4744                 return PEP_CANNOT_INCREASE_SEQUENCE;
  4745             }
  4746             return status;
  4747         } else {
  4748             return PEP_COMMIT_FAILED;
  4749         }
  4750     } else {
  4751         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  4752         return status;
  4753     }
  4754 
  4755     return status;
  4756 }
  4757 
  4758 PEP_STATUS is_own_key(PEP_SESSION session, const char* fpr, bool* own_key) {
  4759     
  4760     assert(session);
  4761     assert(!EMPTYSTR(fpr));
  4762 
  4763     if (!session || EMPTYSTR(fpr))
  4764         return PEP_ILLEGAL_VALUE;
  4765     
  4766     *own_key = false;
  4767     sqlite3_reset(session->own_key_is_listed);
  4768     
  4769     sqlite3_bind_text(session->own_key_is_listed, 1, fpr, -1,
  4770             SQLITE_STATIC);
  4771     int result = Sqlite3_step(session->own_key_is_listed);
  4772     switch (result) {
  4773         case SQLITE_ROW: {
  4774             *own_key = (sqlite3_column_int(session->own_key_is_listed, 0) != 0);
  4775             break;
  4776         }
  4777         default:
  4778             sqlite3_reset(session->own_key_is_listed);
  4779             return PEP_UNKNOWN_DB_ERROR;
  4780     }
  4781 
  4782     sqlite3_reset(session->own_key_is_listed);
  4783     return PEP_STATUS_OK;
  4784 
  4785 }
  4786 
  4787 DYNAMIC_API PEP_STATUS set_revoked(
  4788        PEP_SESSION session,
  4789        const char *revoked_fpr,
  4790        const char *replacement_fpr,
  4791        const uint64_t revocation_date
  4792     )
  4793 {
  4794     PEP_STATUS status = PEP_STATUS_OK;
  4795     
  4796     assert(session &&
  4797            revoked_fpr && revoked_fpr[0] &&
  4798            replacement_fpr && replacement_fpr[0]
  4799           );
  4800     
  4801     if (!(session &&
  4802           revoked_fpr && revoked_fpr[0] &&
  4803           replacement_fpr && replacement_fpr[0]
  4804          ))
  4805         return PEP_ILLEGAL_VALUE;
  4806     
  4807     sqlite3_reset(session->set_revoked);
  4808     sqlite3_bind_text(session->set_revoked, 1, revoked_fpr, -1, SQLITE_STATIC);
  4809     sqlite3_bind_text(session->set_revoked, 2, replacement_fpr, -1,
  4810             SQLITE_STATIC);
  4811     sqlite3_bind_int64(session->set_revoked, 3, revocation_date);
  4812 
  4813     int result;
  4814     
  4815     result = Sqlite3_step(session->set_revoked);
  4816     switch (result) {
  4817         case SQLITE_DONE:
  4818             status = PEP_STATUS_OK;
  4819             break;
  4820             
  4821         default:
  4822             status = PEP_UNKNOWN_DB_ERROR;
  4823     }
  4824     
  4825     sqlite3_reset(session->set_revoked);
  4826     return status;
  4827 }
  4828 
  4829 DYNAMIC_API PEP_STATUS get_revoked(
  4830         PEP_SESSION session,
  4831         const char *fpr,
  4832         char **revoked_fpr,
  4833         uint64_t *revocation_date
  4834     )
  4835 {
  4836     PEP_STATUS status = PEP_STATUS_OK;
  4837 
  4838     assert(session &&
  4839            revoked_fpr &&
  4840            fpr && fpr[0]
  4841           );
  4842     
  4843     if (!(session &&
  4844            revoked_fpr &&
  4845            fpr && fpr[0]
  4846           ))
  4847         return PEP_ILLEGAL_VALUE;
  4848 
  4849     *revoked_fpr = NULL;
  4850     *revocation_date = 0;
  4851 
  4852     sqlite3_reset(session->get_revoked);
  4853     sqlite3_bind_text(session->get_revoked, 1, fpr, -1, SQLITE_STATIC);
  4854 
  4855     int result;
  4856     
  4857     result = Sqlite3_step(session->get_revoked);
  4858     switch (result) {
  4859         case SQLITE_ROW: {
  4860             *revoked_fpr = strdup((const char *)
  4861                     sqlite3_column_text(session->get_revoked, 0));
  4862             if(*revoked_fpr)
  4863                 *revocation_date = sqlite3_column_int64(session->get_revoked,
  4864                         1);
  4865             else
  4866                 status = PEP_OUT_OF_MEMORY;
  4867 
  4868             break;
  4869         }
  4870         default:
  4871             status = PEP_CANNOT_FIND_IDENTITY;
  4872     }
  4873 
  4874     sqlite3_reset(session->get_revoked);
  4875 
  4876     return status;
  4877 }
  4878 
  4879 DYNAMIC_API PEP_STATUS get_replacement_fpr(
  4880         PEP_SESSION session,
  4881         const char *fpr,
  4882         char **revoked_fpr,
  4883         uint64_t *revocation_date
  4884     )
  4885 {
  4886     PEP_STATUS status = PEP_STATUS_OK;
  4887 
  4888     assert(session && revoked_fpr && !EMPTYSTR(fpr) && revocation_date);
  4889     
  4890     if (!session || !revoked_fpr || EMPTYSTR(fpr) || !revocation_date)
  4891         return PEP_ILLEGAL_VALUE;
  4892 
  4893     *revoked_fpr = NULL;
  4894     *revocation_date = 0;
  4895 
  4896     sqlite3_reset(session->get_replacement_fpr);
  4897     sqlite3_bind_text(session->get_replacement_fpr, 1, fpr, -1, SQLITE_STATIC);
  4898 
  4899     int result;
  4900     
  4901     result = Sqlite3_step(session->get_replacement_fpr);
  4902     switch (result) {
  4903         case SQLITE_ROW: {
  4904             *revoked_fpr = strdup((const char *)
  4905                     sqlite3_column_text(session->get_replacement_fpr, 0));
  4906             if(*revoked_fpr)
  4907                 *revocation_date = sqlite3_column_int64(session->get_replacement_fpr,
  4908                         1);
  4909             else
  4910                 status = PEP_OUT_OF_MEMORY;
  4911 
  4912             break;
  4913         }
  4914         default:
  4915             status = PEP_CANNOT_FIND_IDENTITY;
  4916     }
  4917 
  4918     sqlite3_reset(session->get_replacement_fpr);
  4919 
  4920     return status;
  4921 }
  4922 
  4923 PEP_STATUS get_last_contacted(
  4924         PEP_SESSION session,
  4925         identity_list** id_list
  4926     )
  4927 {
  4928     assert(session);
  4929     assert(id_list);
  4930 
  4931     if (!(session && id_list))
  4932         return PEP_ILLEGAL_VALUE;
  4933 
  4934     *id_list = NULL;
  4935     identity_list* ident_list = NULL;
  4936 
  4937     sqlite3_reset(session->get_last_contacted);
  4938     int result;
  4939 
  4940     while ((result = Sqlite3_step(session->get_last_contacted)) == SQLITE_ROW) {
  4941         pEp_identity *ident = new_identity(
  4942                 (const char *) sqlite3_column_text(session->get_last_contacted, 1),
  4943                 NULL,
  4944                 (const char *) sqlite3_column_text(session->get_last_contacted, 0),
  4945                 NULL);
  4946                 
  4947         assert(ident);
  4948         if (ident == NULL) {
  4949             sqlite3_reset(session->get_last_contacted);
  4950             return PEP_OUT_OF_MEMORY;
  4951         }
  4952     
  4953         if (ident_list)
  4954             identity_list_add(ident_list, ident);
  4955         else
  4956             ident_list = new_identity_list(ident);
  4957     }
  4958 
  4959     sqlite3_reset(session->get_last_contacted);
  4960     
  4961     *id_list = ident_list;
  4962     
  4963     if (!ident_list)
  4964         return PEP_CANNOT_FIND_IDENTITY;
  4965     
  4966     return PEP_STATUS_OK;    
  4967 }
  4968 
  4969 
  4970 PEP_STATUS key_created(
  4971         PEP_SESSION session,
  4972         const char *fpr,
  4973         time_t *created
  4974     )
  4975 {
  4976     assert(session && fpr && created);
  4977     if (!(session && fpr && created))
  4978         return PEP_ILLEGAL_VALUE;
  4979 
  4980     return session->cryptotech[PEP_crypt_OpenPGP].key_created(session, fpr,
  4981             created);
  4982 }
  4983 
  4984 PEP_STATUS find_private_keys(PEP_SESSION session, const char* pattern,
  4985                              stringlist_t **keylist) {
  4986     assert(session && keylist);
  4987     if (!(session && keylist))
  4988         return PEP_ILLEGAL_VALUE;
  4989     
  4990     return session->cryptotech[PEP_crypt_OpenPGP].find_private_keys(session, pattern,
  4991                                                                     keylist);
  4992 }
  4993 
  4994 
  4995 DYNAMIC_API const char* get_engine_version() {
  4996     return PEP_ENGINE_VERSION;
  4997 }
  4998 
  4999 DYNAMIC_API const char* get_protocol_version() {
  5000     return PEP_VERSION;
  5001 }
  5002 
  5003 DYNAMIC_API PEP_STATUS reset_pEptest_hack(PEP_SESSION session)
  5004 {
  5005     assert(session);
  5006 
  5007     if (!session)
  5008         return PEP_ILLEGAL_VALUE;
  5009 
  5010     int int_result = sqlite3_exec(
  5011         session->db,
  5012         "delete from identity where address like '%@pEptest.ch' ;",
  5013         NULL,
  5014         NULL,
  5015         NULL
  5016     );
  5017     assert(int_result == SQLITE_OK);
  5018 
  5019     if (int_result != SQLITE_OK)
  5020         return PEP_UNKNOWN_DB_ERROR;
  5021 
  5022     return PEP_STATUS_OK;
  5023 }
  5024 
  5025 #ifdef DEBUG_ERRORSTACK
  5026 PEP_STATUS session_add_error(PEP_SESSION session, const char* file, unsigned line, PEP_STATUS status)
  5027 {
  5028     char logline[48];
  5029     if(status>0)
  5030     {
  5031         snprintf(logline,47, "%.24s:%u status=%u (0x%x)", file, line, status, status);
  5032     }else{
  5033         snprintf(logline,47, "%.24s:%u status=%i.", file, line, status);
  5034     }
  5035     stringlist_add(session->errorstack, logline); // logline is copied! :-)
  5036     return status;
  5037 }
  5038 
  5039 DYNAMIC_API const stringlist_t* get_errorstack(PEP_SESSION session)
  5040 {
  5041     return session->errorstack;
  5042 }
  5043 
  5044 DYNAMIC_API void clear_errorstack(PEP_SESSION session)
  5045 {
  5046     const int old_len = stringlist_length(session->errorstack);
  5047     char buf[48];
  5048     free_stringlist(session->errorstack);
  5049     snprintf(buf, 47, "(%i elements cleared)", old_len);
  5050     session->errorstack = new_stringlist(buf);
  5051 }
  5052 
  5053 #else
  5054 
  5055 static stringlist_t* dummy_errorstack = NULL;
  5056 
  5057 DYNAMIC_API const stringlist_t* get_errorstack(PEP_SESSION session)
  5058 {
  5059     if(dummy_errorstack == NULL)
  5060     {
  5061         dummy_errorstack = new_stringlist("( Please recompile pEpEngine with -DDEBUG_ERRORSTACK )");
  5062     }
  5063 
  5064     return dummy_errorstack;
  5065 }
  5066 
  5067 DYNAMIC_API void clear_errorstack(PEP_SESSION session)
  5068 {
  5069     // nothing to do here
  5070 }
  5071 
  5072 #endif
  5073 
  5074 DYNAMIC_API void _service_error_log(PEP_SESSION session, const char *entity,
  5075         PEP_STATUS status, const char *where)
  5076 {
  5077     char buffer[128];
  5078     static const size_t size = 127;
  5079     memset(buffer, 0, size+1);
  5080 #ifdef PEP_STATUS_TO_STRING
  5081     snprintf(buffer, size, "%s %.4x", pEp_status_to_string(status), status);
  5082 #else
  5083     snprintf(buffer, size, "error %.4x", status);
  5084 #endif
  5085     log_service(session, "### service error log ###", entity, buffer, where);
  5086 }