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