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