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