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