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