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