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