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