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