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