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