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