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