src/pEpEngine.c
author Krista Bennett <krista@pep-project.org>
Thu, 08 Feb 2018 20:05:10 +0100
changeset 2489 1f29e7c1fb8a
parent 2488 b05d7d1f2842
child 2490 a527d621b486
permissions -rw-r--r--
Removed Roker test that broke message_api_test.cc when run outside of the testing environment (this isn't a case of avoiding a bug, but rather the case would fail because the keys tested are actual keys which some of us have present in our real keyrings, and test presumes we do not.
     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 
    10 #include <time.h>
    11 #include <stdlib.h>
    12 
    13 #define _PEP_SQLITE_DEBUG 0
    14 #if _PEP_SQLITE_DEBUG
    15 #include <sqlite3.h>
    16 #endif
    17 
    18 static volatile int init_count = -1;
    19 
    20 // sql overloaded functions - modified from sqlite3.c
    21 static void _sql_lower(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
    22     char *z1;
    23     const char *z2;
    24     int i, 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         z1 = (char*)sqlite3_malloc(n+1);
    31         if( z1 ){
    32             for(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 static const char *sql_get_identity =  
    83     "select fpr, username, comm_type, lang,"
    84     "   identity.flags | pgp_keypair.flags,"
    85     "   is_own"
    86     "   from identity"
    87     "   join person on id = identity.user_id"
    88     "   join pgp_keypair on fpr = identity.main_key_id"
    89     "   join trust on id = trust.user_id"
    90     "       and pgp_keypair_fpr = identity.main_key_id"    
    91     "   where (case when (address = ?1) then (1)"
    92     "               when (lower(address) = lower(?1)) then (1)"
    93     "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
    94     "               else 0"
    95     "          end) = 1"
    96     "   and identity.user_id = ?2;";
    97 
    98 static const char *sql_get_identity_without_trust_check =  
    99     "select identity.main_key_id, username, lang,"
   100     "   identity.flags, is_own"
   101     "   from identity"
   102     "   join person on id = identity.user_id"
   103     "   where (case when (address = ?1) then (1)"
   104     "               when (lower(address) = lower(?1)) then (1)"
   105     "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
   106     "               else 0"
   107     "          end) = 1"
   108     "   and identity.user_id = ?2;";
   109 
   110 static const char *sql_get_identities_by_address =  
   111     "select user_id, identity.main_key_id, username, lang,"
   112     "   identity.flags, is_own"
   113     "   from identity"
   114     "   join person on id = identity.user_id"
   115     "   where (case when (address = ?1) then (1)"
   116     "               when (lower(address) = lower(?1)) then (1)"
   117     "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
   118     "               else 0"
   119     "          end) = 1;";
   120 
   121 static const char *sql_replace_identities_fpr =  
   122     "update identity"
   123     "   set main_key_id = ?1 "
   124     "   where main_key_id = ?2 ;";
   125     
   126 static const char *sql_remove_fpr_as_default =
   127     "update person set main_key_id = NULL where main_key_id = ?1 ;"
   128     "update identity set main_key_id = NULL where main_key_id = ?1 ;";
   129 
   130 // Set person, but if already exist, only update.
   131 // if main_key_id already set, don't touch.
   132 static const char *sql_set_person = 
   133      "insert into person (id, username, lang, main_key_id, device_group)"
   134      "  values (?1, ?2, ?3,"
   135 //     "    (select coalesce( "
   136 //     "          (select main_key_id from person where id = ?1), " 
   137 //     "           upper(replace(?4,' ','')))),"
   138     "   ?4,"
   139      "    (select device_group from person where id = ?1)) ;";
   140 
   141 static const char *sql_update_person = 
   142     "update person "
   143     "   set username = ?2, "
   144     "       lang = ?3, "
   145     "       main_key_id =  "
   146     "           (select coalesce( "
   147     "               (select main_key_id from person where id = ?1), " 
   148     "                upper(replace(?4,' ','')))),"         
   149     "       device_group = "
   150     "           (select device_group from person where id = ?1)"
   151     "   where id = ?1 ;";
   152     
   153 static const char *sql_set_as_pep_user =
   154     "update person set is_pep_user = 1 "
   155     "   where id = ?1 ; ";
   156 
   157 static const char *sql_is_pep_user =
   158     "select is_pep_user from person "
   159     "   where id = ?1 ; ";
   160 
   161 static const char* sql_exists_person = 
   162     "select count(*) from person "
   163     "   where id = ?1 ;";
   164 
   165 static const char *sql_set_device_group = 
   166     "update person set device_group = ?1 "
   167     "   where id = ?2;";
   168 
   169 // This will cascade to identity and trust
   170 static const char* sql_replace_userid =
   171     "update person set id = ?1 " 
   172     "   where id = ?2;";
   173 
   174 static const char *sql_replace_main_user_fpr =  
   175     "update person "
   176     "   set main_key_id = ?1 "
   177     "   where id = ?2 ;";
   178 
   179 static const char *sql_get_main_user_fpr =  
   180     "select main_key_id from person"
   181     "   where id = ?1 ;";
   182 
   183 static const char *sql_refresh_userid_default_key =
   184     "update person "
   185     "   set main_key_id = "
   186     "       (select identity.main_key_id from identity "
   187     "           join trust on trust.user_id = identity.user_id "
   188     "               and trust.pgp_keypair_fpr = identity.main_key_id "
   189     "           join person on identity.user_id = identity.user_id "
   190     "       where identity.user_id = ?1 "
   191     "       order by trust.comm_type desc "
   192     "       limit 1) "
   193     "where id = ?1 ; ";
   194 
   195 static const char *sql_get_device_group = 
   196     "select device_group from person "
   197     "where id = ?1;";
   198 
   199 static const char *sql_set_pgp_keypair = 
   200     "insert or ignore into pgp_keypair (fpr) "
   201     "values (upper(replace(?1,' ',''))) ;";
   202 
   203 static const char* sql_exists_identity_entry = 
   204     "select count(*) from identity "
   205     "   where (case when (address = ?1) then (1)"
   206     "               when (lower(address) = lower(?1)) then (1)"
   207     "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
   208     "               else 0"
   209     "          end) = 1"
   210     "    and user_id = ?2;";
   211  
   212 static const char *sql_set_identity_entry = 
   213     "insert into identity ("
   214     "       address, main_key_id, "
   215     "       user_id, flags, is_own"
   216     "   ) values ("
   217     "       ?1,"
   218     "       upper(replace(?2,' ','')),"
   219     "       ?3,"
   220     "       ?4,"
   221     "       ?5"
   222     "   );";
   223     
   224 static const char* sql_update_identity_entry =    
   225     "update identity "
   226     "   set main_key_id = upper(replace(?2,' ','')), "
   227     "       flags = ?4, " 
   228     "       is_own = ?5 "
   229     "   where (case when (address = ?1) then (1)"
   230     "               when (lower(address) = lower(?1)) then (1)"
   231     "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1) "
   232     "               else 0 "
   233     "          end) = 1 "
   234     "          and user_id = ?3 ;";
   235 
   236     // " (select"
   237     // "   coalesce("
   238     // "    (select flags from identity"
   239     // "     where address = ?1 and"
   240     // "           user_id = ?3),"
   241     // "    0)"
   242     // " ) | (?4 & 255)"
   243     /* set_identity ignores previous flags, and doesn't filter machine flags */
   244         
   245 static const char *sql_set_identity_flags = 
   246     "update identity set flags = "
   247     "    ((?1 & 255) | (select flags from identity"
   248     "                    where (case when (address = ?2) then (1)"
   249     "                                when (lower(address) = lower(?2)) then (1)"
   250     "                                when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   251     "                                else 0 "    
   252     "                           end) = 1 "
   253     "                           and user_id = ?3)) "
   254     "   where (case when (address = ?2) then (1)"
   255     "               when (lower(address) = lower(?2)) then (1)"
   256     "               when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   257     "               else 0"
   258     "          end) = 1"
   259     "          and user_id = ?3 ;";
   260 
   261 static const char *sql_unset_identity_flags = 
   262     "update identity set flags = "
   263     "    ( ~(?1 & 255) & (select flags from identity"
   264     "                    where (case when (address = ?2) then (1)"
   265     "                                when (lower(address) = lower(?2)) then (1)"
   266     "                                when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   267     "                                else 0 "    
   268     "                           end) = 1 "
   269     "                           and user_id = ?3)) "
   270     "   where (case when (address = ?2) then (1)"
   271     "               when (lower(address) = lower(?2)) then (1)"
   272     "               when (replace(lower(address),'.','') = replace(lower(?2),'.','')) then (1)"
   273     "               else 0"
   274     "          end) = 1"
   275     "          and user_id = ?3 ;";
   276 
   277 static const char *sql_set_trust =
   278     "insert into trust (user_id, pgp_keypair_fpr, comm_type) "
   279     "values (?1, upper(replace(?2,' ','')), ?3) ;";
   280 
   281 static const char *sql_update_trust =
   282     "update trust set comm_type = ?3 " 
   283     "   where user_id = ?1 and pgp_keypair_fpr = upper(replace(?2,' ',''));";
   284 
   285 static const char* sql_exists_trust_entry = 
   286     "select count(*) from trust "
   287     "   where user_id = ?1 and pgp_keypair_fpr = upper(replace(?2,' ',''));";
   288     
   289 static const char *sql_update_trust_for_fpr =
   290     "update trust "
   291     "set comm_type = ?1 "
   292     "where pgp_keypair_fpr = upper(replace(?2,' ','')) ;";
   293 
   294 static const char *sql_get_trust = 
   295     "select comm_type from trust where user_id = ?1 "
   296     "and pgp_keypair_fpr = upper(replace(?2,' ','')) ;";
   297 
   298 static const char *sql_least_trust = 
   299     "select min(comm_type) from trust where"
   300     " pgp_keypair_fpr = upper(replace(?1,' ',''))"
   301     " and comm_type != 0;"; // ignores PEP_ct_unknown
   302     // returns PEP_ct_unknown only when no known trust is recorded
   303 
   304 static const char *sql_mark_as_compromized = 
   305     "update trust not indexed set comm_type = 15"
   306     " where pgp_keypair_fpr = upper(replace(?1,' ','')) ;";
   307     
   308 static const char *sql_crashdump = 
   309     "select timestamp, title, entity, description, comment"
   310     " from log order by timestamp desc limit ?1 ;";
   311 
   312 static const char *sql_languagelist = 
   313     "select i18n_language.lang, name, phrase" 
   314     " from i18n_language join i18n_token using (lang) where i18n_token.id = 1000;" ;
   315 
   316 static const char *sql_i18n_token = 
   317     "select phrase from i18n_token where lang = lower(?1) and id = ?2 ;";
   318 
   319 // blacklist
   320 static const char *sql_blacklist_add = 
   321     "insert or ignore into blacklist_keys (fpr) values (upper(replace(?1,' ',''))) ;"
   322     "delete from identity where main_key_id = upper(replace(?1,' ','')) ;"
   323     "delete from pgp_keypair where fpr = upper(replace(?1,' ','')) ;";
   324 
   325 static const char *sql_blacklist_delete =
   326     "delete from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
   327 
   328 static const char *sql_blacklist_is_listed = 
   329     "select count(*) from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
   330 
   331 static const char *sql_blacklist_retrieve = 
   332     "select * from blacklist_keys ;";
   333                 
   334 
   335 // Own keys
   336 // We only care if it's 0 or non-zero
   337 static const char *sql_own_key_is_listed = 
   338     "select count(*) from ("
   339     "   select pgp_keypair_fpr from trust"
   340     "      join identity on trust.user_id = identity.user_id"
   341     "      where pgp_keypair_fpr = upper(replace(?1,' ',''))"
   342     "           and identity.is_own = 1"
   343     ");";
   344 
   345 static const char *sql_own_identities_retrieve =  
   346     "select address, fpr, username, identity.user_id, "
   347     "   lang, identity.flags | pgp_keypair.flags"
   348     "   from identity"
   349     "   join person on id = identity.user_id"
   350     "   join pgp_keypair on fpr = identity.main_key_id"
   351     "   join trust on id = trust.user_id"
   352     "       and pgp_keypair_fpr = identity.main_key_id"
   353     "   where identity.is_own = 1"
   354     "       and (identity.flags & ?1) = 0;";
   355 
   356 static const char *sql_own_keys_retrieve = 
   357     "select pgp_keypair_fpr from trust"
   358     "   join identity on trust.user_id = identity.user_id"
   359     "   where identity.is_own = 1";
   360 
   361 static const char* sql_get_user_default_key =
   362     "select main_key_id from person" 
   363     "   where id = ?1;";
   364 
   365 static const char* sql_get_default_own_userid =
   366     "select id from person"
   367     "   join identity on id = identity.user_id"
   368     "   where identity.is_own = 1";
   369 
   370 // Sequence
   371 static const char *sql_sequence_value1 = 
   372     "insert or replace into sequences (name, value, own) "
   373     "values (?1, "
   374     "       (select coalesce((select value + 1 from sequences "
   375     "           where name = ?1), 1 )), "
   376     "       (select coalesce((select own or ?2 from sequences "
   377     "           where name = ?1), ?2))) ; ";
   378 
   379 static const char *sql_sequence_value2 = 
   380     "select value, own from sequences where name = ?1 ;";
   381 
   382 static const char *sql_sequence_value3 = 
   383     "insert or replace into sequences (name, value, own) "
   384     "values (?1, "
   385     "        ?2, "
   386     "       (select coalesce((select own or ?3 from sequences "
   387     "           where name = ?1), ?3))) ; ";
   388         
   389 // Revocation tracking
   390 static const char *sql_set_revoked =
   391     "insert or replace into revoked_keys ("
   392     "    revoked_fpr, replacement_fpr, revocation_date) "
   393     "values (upper(replace(?1,' ','')),"
   394     "        upper(replace(?2,' ','')),"
   395     "        ?3) ;";
   396         
   397 static const char *sql_get_revoked = 
   398     "select revoked_fpr, revocation_date from revoked_keys"
   399     "    where replacement_fpr = upper(replace(?1,' ','')) ;";
   400 
   401 static const char *sql_get_userid_alias_default =
   402     "select default_id from alternate_user_id "
   403     "   where alternate_id = ?1 ; ";
   404 
   405 // Revocation tracking
   406 static const char *sql_add_mistrusted_key =
   407     "insert or replace into mistrusted_keys (fpr) "
   408     "   values (upper(replace(?1,' ',''))) ;";
   409         
   410 static const char *sql_delete_mistrusted_key = 
   411     "delete from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
   412 
   413 static const char *sql_is_mistrusted_key = 
   414     "select count(*) from mistrusted_keys where fpr = upper(replace(?1,' ','')) ;";
   415 
   416 static const char *sql_add_userid_alias =
   417     "insert or replace into alternate_user_id (alternate_id, default_id) "
   418     "values (?2, ?1) ;";
   419     
   420 static int user_version(void *_version, int count, char **text, char **name)
   421 {
   422     assert(_version);
   423     assert(count == 1);
   424     assert(text && text[0]);
   425     if (!(_version && count == 1 && text && text[0]))
   426         return -1;
   427 
   428     int *version = (int *) _version;
   429     *version = atoi(text[0]);
   430     return 0;
   431 }
   432 
   433 static int table_contains_column(PEP_SESSION session, const char* table_name,
   434                                                       const char* col_name) {
   435 
   436 
   437     if (!session || !table_name || !col_name)
   438         return -1;
   439         
   440     // Table names can't be SQL parameters, so we do it this way.
   441     
   442     // these two must be the same number.
   443     char sql_buf[500];
   444     const size_t max_q_len = 500;
   445     
   446     size_t t_size, c_size, q_size;
   447     
   448     const char* q1 = "SELECT "; // 7
   449     const char* q2 = " from "; // 6
   450     const char* q3 = ";";       // 1
   451     
   452     q_size = 14;
   453     t_size = strlen(table_name);
   454     c_size = strlen(col_name);
   455     
   456     size_t query_len = q_size + c_size + t_size + 1;
   457     
   458     if (query_len > max_q_len)
   459         return -1;
   460 
   461     strlcpy(sql_buf, q1, max_q_len);
   462     strlcat(sql_buf, col_name, max_q_len);
   463     strlcat(sql_buf, q2, max_q_len);
   464     strlcat(sql_buf, table_name, max_q_len);
   465     strlcat(sql_buf, q3, max_q_len);
   466 
   467     sqlite3_stmt *stmt; 
   468 
   469     sqlite3_prepare_v2(session->db, sql_buf, -1, &stmt, NULL);
   470 
   471     int retval = 0;
   472 
   473     int rc = sqlite3_step(stmt);  
   474     if (rc == SQLITE_DONE || rc == SQLITE_OK || rc == SQLITE_ROW) {
   475         retval = 1;
   476     }
   477 
   478     sqlite3_finalize(stmt);      
   479         
   480     return retval;
   481 }
   482 
   483 void errorLogCallback(void *pArg, int iErrCode, const char *zMsg){
   484   fprintf(stderr, "(%d) %s\n", iErrCode, zMsg);
   485 }
   486 
   487 DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
   488 {
   489     PEP_STATUS status = PEP_STATUS_OK;
   490     int int_result;
   491     
   492     bool in_first = false;
   493     bool very_first = false;
   494 
   495     assert(sqlite3_threadsafe());
   496     if (!sqlite3_threadsafe())
   497         return PEP_INIT_SQLITE3_WITHOUT_MUTEX;
   498 
   499     // a little race condition - but still a race condition
   500     // mitigated by calling caveat (see documentation)
   501 
   502     // this increment is made atomic IN THE ADAPTERS by
   503     // guarding the call to init with the appropriate mutex.
   504     int _count = ++init_count;
   505     if (_count == 0)
   506         in_first = true;
   507     
   508     // Race condition mitigated by calling caveat starts here :
   509     // If another call to init() preempts right now, then preemptive call
   510     // will have in_first false, will not create SQL tables, and following
   511     // calls relying on those tables will fail.
   512     //
   513     // Therefore, as above, adapters MUST guard init() with a mutex.
   514     // 
   515     // Therefore, first session
   516     // is to be created and last session to be deleted alone, and not
   517     // concurently to other sessions creation or deletion.
   518     // We expect adapters to enforce this either by implicitely creating a
   519     // client session, or by using synchronization primitive to protect
   520     // creation/deletion of first/last session from the app.
   521 
   522     assert(session);
   523     if (session == NULL)
   524         return PEP_ILLEGAL_VALUE;
   525 
   526     *session = NULL;
   527 
   528     pEpSession *_session = calloc(1, sizeof(pEpSession));
   529     assert(_session);
   530     if (_session == NULL)
   531         goto enomem;
   532 
   533     _session->version = PEP_ENGINE_VERSION;
   534 
   535 #ifdef DEBUG_ERRORSTACK
   536     _session->errorstack = new_stringlist("init()");
   537 #endif
   538 
   539     assert(LOCAL_DB);
   540     if (LOCAL_DB == NULL) {
   541         status = PEP_INIT_CANNOT_OPEN_DB;
   542         goto pep_error;
   543     }
   544     
   545 #if _PEP_SQLITE_DEBUG    
   546     sqlite3_config(SQLITE_CONFIG_LOG, errorLogCallback, NULL);
   547 #endif
   548 
   549     int_result = sqlite3_open_v2(
   550             LOCAL_DB,
   551             &_session->db,
   552             SQLITE_OPEN_READWRITE
   553                 | SQLITE_OPEN_CREATE
   554                 | SQLITE_OPEN_FULLMUTEX
   555                 | SQLITE_OPEN_PRIVATECACHE,
   556             NULL 
   557         );
   558 
   559     if (int_result != SQLITE_OK) {
   560         status = PEP_INIT_CANNOT_OPEN_DB;
   561         goto pep_error;
   562     }
   563 
   564     int_result = sqlite3_exec(
   565             _session->db,
   566             "PRAGMA locking_mode=NORMAL;\n"
   567             "PRAGMA journal_mode=WAL;\n",
   568             NULL,
   569             NULL,
   570             NULL
   571         );
   572 
   573 
   574     sqlite3_busy_timeout(_session->db, BUSY_WAIT_TIME);
   575 
   576 #if _PEP_SQLITE_DEBUG
   577     sqlite3_trace_v2(_session->db, 
   578         SQLITE_TRACE_STMT | SQLITE_TRACE_ROW | SQLITE_TRACE_CLOSE,
   579         sql_trace_callback,
   580         NULL);
   581 #endif
   582 
   583     assert(SYSTEM_DB);
   584     if (SYSTEM_DB == NULL) {
   585         status = PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
   586         goto pep_error;
   587     }
   588 
   589     int_result = sqlite3_open_v2(
   590             SYSTEM_DB, &_session->system_db,
   591             SQLITE_OPEN_READONLY
   592                 | SQLITE_OPEN_FULLMUTEX
   593                 | SQLITE_OPEN_SHAREDCACHE,
   594             NULL
   595         );
   596 
   597     if (int_result != SQLITE_OK) {
   598         status = PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
   599         goto pep_error;
   600     }
   601 
   602     sqlite3_busy_timeout(_session->system_db, 1000);
   603 
   604 // increment this when patching DDL
   605 #define _DDL_USER_VERSION "7"
   606 
   607     if (in_first) {
   608 
   609         int_result = sqlite3_exec(
   610             _session->db,
   611                 "create table if not exists version_info (\n"
   612                 "   id integer primary key,\n"
   613                 "   timestamp integer default (datetime('now')),\n"
   614                 "   version text,\n"
   615                 "   comment text\n"
   616                 ");\n",
   617                 NULL,
   618                 NULL,
   619                 NULL
   620         );
   621         int_result = sqlite3_exec(
   622             _session->db,
   623                 "PRAGMA application_id = 0x23423423;\n"
   624                 "create table if not exists log (\n"
   625                 "   timestamp integer default (datetime('now')),\n"
   626                 "   title text not null,\n"
   627                 "   description text,\n"
   628                 "   entity text not null,\n"
   629                 "   comment text\n"
   630                 ");\n"
   631                 "create index if not exists log_timestamp on log (\n"
   632                 "   timestamp\n"
   633                 ");\n"
   634                 "create table if not exists pgp_keypair (\n"
   635                 "   fpr text primary key,\n"
   636                 "   created integer,\n"
   637                 "   expires integer,\n"
   638                 "   comment text,\n"
   639                 "   flags integer default 0\n"
   640                 ");\n"
   641                 "create index if not exists pgp_keypair_expires on pgp_keypair (\n"
   642                 "   expires\n"
   643                 ");\n"
   644                 "create table if not exists person (\n"
   645                 "   id text primary key,\n"
   646                 "   username text not null,\n"
   647                 "   main_key_id text\n"
   648                 "       references pgp_keypair (fpr)\n"
   649                 "       on delete set null,\n"
   650                 "   lang text,\n"
   651                 "   comment text,\n"
   652                 "   device_group text,\n"
   653                 "   is_pep_user integer default 0\n"
   654                 ");\n"
   655                 "create table if not exists identity (\n"
   656                 "   address text,\n"
   657                 "   user_id text\n"
   658                 "       references person (id)\n"
   659                 "       on delete cascade on update cascade,\n"
   660                 "   main_key_id text\n"
   661                 "       references pgp_keypair (fpr)\n"
   662                 "       on delete set null,\n"
   663                 "   comment text,\n"
   664                 "   flags integer default 0,\n"
   665                 "   is_own integer default 0,\n"
   666                 "   primary key (address, user_id)\n"
   667                 ");\n"
   668                 "create table if not exists trust (\n"
   669                 "   user_id text not null\n"
   670                 "       references person (id)\n"
   671                 "       on delete cascade on update cascade,\n"
   672                 "   pgp_keypair_fpr text not null\n"
   673                 "       references pgp_keypair (fpr)\n"
   674                 "       on delete cascade,\n"
   675                 "   comm_type integer not null,\n"
   676                 "   comment text,\n"
   677                 "   primary key (user_id, pgp_keypair_fpr)\n"
   678                 ");\n"
   679                 // blacklist
   680                 "create table if not exists blacklist_keys (\n"
   681                 "   fpr text primary key\n"
   682                 ");\n"
   683                 // sequences
   684                 "create table if not exists sequences(\n"
   685                 "   name text primary key,\n"
   686                 "   value integer default 0,\n"
   687                 "   own integer default 0\n"
   688                 ");\n"
   689                 "create table if not exists revoked_keys (\n"
   690                 "   revoked_fpr text primary key,\n"
   691                 "   replacement_fpr text not null\n"
   692                 "       references pgp_keypair (fpr)\n"
   693                 "       on delete cascade,\n"
   694                 "   revocation_date integer\n"
   695                 ");\n"
   696                 // user id aliases
   697                 "create table if not exists alternate_user_id (\n"
   698                 "    default_id text references person (id)\n"
   699                 "       on delete cascade on update cascade,\n"
   700                 "    alternate_id text primary key\n"
   701                 ");\n"
   702                 // mistrusted keys
   703                 "create table if not exists mistrusted_keys (\n"
   704                 "    fpr text primary key\n"
   705                 ");\n"
   706                 ,
   707             NULL,
   708             NULL,
   709             NULL
   710         );
   711         assert(int_result == SQLITE_OK);
   712 
   713         int version;
   714         int_result = sqlite3_exec(
   715             _session->db,
   716             "pragma user_version;",
   717             user_version,
   718             &version,
   719             NULL
   720         );
   721 
   722         assert(int_result == SQLITE_OK);
   723         
   724         void (*xFunc_lower)(sqlite3_context*,int,sqlite3_value**) = &_sql_lower;
   725         
   726         int_result = sqlite3_create_function_v2(
   727             _session->db,
   728             "lower",
   729             1,
   730             SQLITE_UTF8 | SQLITE_DETERMINISTIC,
   731             NULL,
   732             xFunc_lower,
   733             NULL,
   734             NULL,
   735             NULL);
   736         assert(int_result == SQLITE_OK);
   737 
   738         int_result = sqlite3_exec(
   739             _session->db,
   740             "pragma foreign_keys=ON;\n",
   741             NULL,
   742             NULL,
   743             NULL
   744         );
   745 
   746         assert(int_result == SQLITE_OK);
   747 
   748         
   749         // Sometimes the user_version wasn't set correctly. Check to see if this
   750         // is really necessary...
   751         if (version == 1) {
   752             bool version_changed = true;
   753 
   754             if (table_contains_column(_session, "person", "is_pep_user") > 0) {
   755                 version = 7;
   756             }            
   757             else if (table_contains_column(_session, "identity", "is_own") > 0) {
   758                 version = 6;
   759             }
   760             else if (table_contains_column(_session, "sequences", "own") > 0) {
   761                 version = 3;
   762             }
   763             else if (table_contains_column(_session, "pgp_keypair", "flags") > 0) {
   764                 version = 2;
   765             }
   766             else {
   767                 version_changed = false;
   768             }
   769             
   770             if (version_changed) {
   771                 // set it in the DB, finally. Yeesh.
   772                 char verbuf[21]; // enough digits for a max-sized 64 bit int, cmon. 
   773                 sprintf(verbuf,"%d",version);
   774                 
   775                 size_t query_size = strlen(verbuf) + 25;
   776                 char* query = calloc(query_size, 1);
   777                 
   778                 strlcpy(query, "pragma user_version = ", query_size);
   779                 strlcat(query, verbuf, query_size);
   780                 strlcat(query, ";", query_size);
   781                 
   782                 int_result = sqlite3_exec(
   783                     _session->db,
   784                     query,
   785                     user_version,
   786                     &version,
   787                     NULL
   788                 );
   789                 free(query);
   790             }
   791         }
   792 
   793 
   794         if(version != 0) { 
   795             // Version has been already set
   796 
   797             // Early mistake : version 0 shouldn't have existed.
   798             // Numbering should have started at 1 to detect newly created DB.
   799             // Version 0 DBs are not anymore compatible.
   800 
   801             // // Was version 0 compat code.
   802             // if (version < 1) {
   803             //     int_result = sqlite3_exec(
   804             //         _session->db,
   805             //         "alter table identity\n"
   806             //         "   add column flags integer default 0;\n",
   807             //         NULL,
   808             //         NULL,
   809             //         NULL
   810             //     );
   811             //     assert(int_result == SQLITE_OK);
   812             // }
   813             
   814             if (version < 2) {
   815                 int_result = sqlite3_exec(
   816                     _session->db,
   817                     "alter table pgp_keypair\n"
   818                     "   add column flags integer default 0;\n"
   819                     "alter table person\n"
   820                     "   add column device_group text;\n",
   821                     NULL,
   822                     NULL,
   823                     NULL
   824                 );
   825                 assert(int_result == SQLITE_OK);
   826             }
   827 
   828             if (version < 3) {
   829                 int_result = sqlite3_exec(
   830                     _session->db,
   831                     "alter table sequences\n"
   832                     "   add column own integer default 0;\n",
   833                     NULL,
   834                     NULL,
   835                     NULL
   836                 );
   837                 assert(int_result == SQLITE_OK);
   838             }
   839 
   840             if (version < 5) {
   841                 int_result = sqlite3_exec(
   842                     _session->db,
   843                     "delete from pgp_keypair where fpr = '';",
   844                     NULL,
   845                     NULL,
   846                     NULL
   847                 );
   848                 assert(int_result == SQLITE_OK);
   849                 int_result = sqlite3_exec(
   850                     _session->db,
   851                     "delete from trust where pgp_keypair_fpr = '';",
   852                     NULL,
   853                     NULL,
   854                     NULL
   855                 );
   856                 assert(int_result == SQLITE_OK);
   857             }
   858             
   859             if (version < 6) {
   860                 int_result = sqlite3_exec(
   861                     _session->db,
   862                     "alter table identity\n"
   863                     "   add column is_own integer default 0;\n",
   864                     NULL,
   865                     NULL,
   866                     NULL
   867                 );
   868                 assert(int_result == SQLITE_OK);                
   869                 int_result = sqlite3_exec(
   870                     _session->db,
   871                     "update identity\n"
   872                     "   set is_own = 1\n"
   873                     "   where (user_id = '" PEP_OWN_USERID "');\n",
   874                     NULL,
   875                     NULL,
   876                     NULL
   877                 );
   878                 assert(int_result == SQLITE_OK);    
   879 
   880                 // Turns out that just adding "on update cascade" in
   881                 // sqlite is a PITA. We need to be able to cascade
   882                 // person->id replacements (for temp ids like "TOFU_")
   883                 // so here we go...
   884                 int_result = sqlite3_exec(
   885                     _session->db,
   886                     "PRAGMA foreign_keys=off;\n"
   887                     "BEGIN TRANSACTION;\n"
   888                     "ALTER TABLE identity RENAME TO _identity_old;\n"
   889                     "create table identity (\n"
   890                     "   address text,\n"
   891                     "   user_id text\n"
   892                     "       references person (id)\n"
   893                     "       on delete cascade on update cascade,\n"
   894                     "   main_key_id text\n"
   895                     "       references pgp_keypair (fpr)\n"
   896                     "       on delete set null,\n"
   897                     "   comment text,\n"
   898                     "   flags integer default 0,\n"
   899                     "   is_own integer default 0,\n"
   900                     "   primary key (address, user_id)\n"
   901                     ");\n"
   902                     "INSERT INTO identity SELECT * FROM _identity_old;\n"
   903                     "DROP TABLE _identity_old;\n"
   904                     "ALTER TABLE trust RENAME TO _trust_old;\n"
   905                     "create table trust (\n"
   906                     "   user_id text not null\n"
   907                     "       references person (id)\n"
   908                     "       on delete cascade on update cascade,\n"
   909                     "   pgp_keypair_fpr text not null\n"
   910                     "       references pgp_keypair (fpr)\n"
   911                     "       on delete cascade,\n"
   912                     "   comm_type integer not null,\n"
   913                     "   comment text,\n"
   914                     "   primary key (user_id, pgp_keypair_fpr)\n"
   915                     ");\n"
   916                     "INSERT INTO trust SELECT * FROM _trust_old;\n"
   917                     "DROP TABLE _trust_old;\n"
   918                     "COMMIT;\n"
   919                     "\n"
   920                     "PRAGMA foreign_keys=on;\n"
   921                     "create table if not exists alternate_user_id (\n"
   922                     "    default_id text references person (id)\n"
   923                     "       on delete cascade on update cascade,\n"
   924                     "    alternate_id text primary key\n"
   925                     ");\n"
   926                     ,
   927                     NULL,
   928                     NULL,
   929                     NULL
   930                 );
   931                 assert(int_result == SQLITE_OK);    
   932             }
   933             if (version < 7) {
   934                 int_result = sqlite3_exec(
   935                     _session->db,
   936                     "alter table person\n"
   937                     "   add column is_pep_user integer default 0;\n",
   938                     NULL,
   939                     NULL,
   940                     NULL
   941                 );
   942                 assert(int_result == SQLITE_OK);
   943                 int_result = sqlite3_exec(
   944                     _session->db,
   945                     "update person\n"
   946                     "   set is_pep_user = 1\n"
   947                     "   where id = "
   948                     "       (select distinct id from person "
   949                     "               join trust on id = user_id "
   950                     "               where (case when (comm_type = 127) then (id) "
   951                     "                           when (comm_type = 255) then (id) "
   952                     "                           else 0"
   953                     "                      end) = id );\n",
   954                     NULL,
   955                     NULL,
   956                     NULL
   957                 );
   958                 assert(int_result == SQLITE_OK);
   959                 
   960                 int_result = sqlite3_exec(
   961                     _session->db,
   962                     "create table if not exists mistrusted_keys (\n"
   963                     "    fpr text primary key\n"
   964                     ");\n",            
   965                     NULL,
   966                     NULL,
   967                     NULL
   968                 );
   969                 assert(int_result == SQLITE_OK);    
   970             }
   971         }        
   972         else { 
   973             // Version from DB was 0, it means this is initial setup.
   974             // DB has just been created, and all tables are empty.
   975             very_first = true;
   976         }
   977 
   978         if (version < atoi(_DDL_USER_VERSION)) {
   979             int_result = sqlite3_exec(
   980                 _session->db,
   981                 "pragma user_version = "_DDL_USER_VERSION";\n"
   982                 "insert or replace into version_info (id, version)"
   983                     "values (1, '" PEP_ENGINE_VERSION "');",
   984                 NULL,
   985                 NULL,
   986                 NULL
   987             );
   988             assert(int_result == SQLITE_OK);
   989         }
   990         
   991         // We need to init a few globals for message id that we'd rather not
   992         // calculate more than once.
   993         _init_globals();
   994     }
   995 
   996     int_result = sqlite3_prepare_v2(_session->db, sql_log,
   997             (int)strlen(sql_log), &_session->log, NULL);
   998     assert(int_result == SQLITE_OK);
   999 
  1000     int_result = sqlite3_prepare_v2(_session->system_db, sql_trustword,
  1001             (int)strlen(sql_trustword), &_session->trustword, NULL);
  1002     assert(int_result == SQLITE_OK);
  1003 
  1004     int_result = sqlite3_prepare_v2(_session->db, sql_get_identity,
  1005             (int)strlen(sql_get_identity), &_session->get_identity, NULL);
  1006     assert(int_result == SQLITE_OK);
  1007 
  1008     int_result = sqlite3_prepare_v2(_session->db, sql_get_identity_without_trust_check,
  1009             (int)strlen(sql_get_identity_without_trust_check), 
  1010             &_session->get_identity_without_trust_check, NULL);
  1011     assert(int_result == SQLITE_OK);
  1012 
  1013     int_result = sqlite3_prepare_v2(_session->db, sql_get_identities_by_address,
  1014             (int)strlen(sql_get_identities_by_address), 
  1015             &_session->get_identities_by_address, NULL);
  1016     assert(int_result == SQLITE_OK);
  1017 
  1018     int_result = sqlite3_prepare_v2(_session->db, sql_get_user_default_key,
  1019             (int)strlen(sql_get_user_default_key), &_session->get_user_default_key, NULL);
  1020     assert(int_result == SQLITE_OK);
  1021 
  1022     int_result = sqlite3_prepare_v2(_session->db, sql_get_default_own_userid,
  1023             (int)strlen(sql_get_default_own_userid), &_session->get_default_own_userid, NULL);
  1024     assert(int_result == SQLITE_OK);
  1025     
  1026     int_result = sqlite3_prepare_v2(_session->db, sql_get_userid_alias_default,
  1027             (int)strlen(sql_get_userid_alias_default), &_session->get_userid_alias_default, NULL);
  1028     assert(int_result == SQLITE_OK);
  1029 
  1030     int_result = sqlite3_prepare_v2(_session->db, sql_add_userid_alias,
  1031             (int)strlen(sql_add_userid_alias), &_session->add_userid_alias, NULL);
  1032     assert(int_result == SQLITE_OK);
  1033 
  1034     int_result = sqlite3_prepare_v2(_session->db, sql_replace_userid,
  1035             (int)strlen(sql_replace_userid), &_session->replace_userid, NULL);
  1036     assert(int_result == SQLITE_OK);
  1037 
  1038     int_result = sqlite3_prepare_v2(_session->db, sql_replace_main_user_fpr,
  1039             (int)strlen(sql_replace_main_user_fpr), &_session->replace_main_user_fpr, NULL);
  1040     assert(int_result == SQLITE_OK);
  1041 
  1042     int_result = sqlite3_prepare_v2(_session->db, sql_get_main_user_fpr,
  1043             (int)strlen(sql_get_main_user_fpr), &_session->get_main_user_fpr, NULL);
  1044     assert(int_result == SQLITE_OK);
  1045 
  1046     int_result = sqlite3_prepare_v2(_session->db, sql_refresh_userid_default_key,
  1047             (int)strlen(sql_refresh_userid_default_key), &_session->refresh_userid_default_key, NULL);
  1048     assert(int_result == SQLITE_OK);
  1049 
  1050     int_result = sqlite3_prepare_v2(_session->db, sql_replace_identities_fpr,
  1051             (int)strlen(sql_replace_identities_fpr), 
  1052             &_session->replace_identities_fpr, NULL);
  1053     assert(int_result == SQLITE_OK);
  1054     
  1055     int_result = sqlite3_prepare_v2(_session->db, sql_remove_fpr_as_default,
  1056             (int)strlen(sql_remove_fpr_as_default), 
  1057             &_session->remove_fpr_as_default, NULL);
  1058     assert(int_result == SQLITE_OK);
  1059 
  1060     int_result = sqlite3_prepare_v2(_session->db, sql_set_person,
  1061             (int)strlen(sql_set_person), &_session->set_person, NULL);
  1062     assert(int_result == SQLITE_OK);
  1063 
  1064     int_result = sqlite3_prepare_v2(_session->db, sql_update_person,
  1065             (int)strlen(sql_update_person), &_session->update_person, NULL);
  1066     assert(int_result == SQLITE_OK);
  1067 
  1068     int_result = sqlite3_prepare_v2(_session->db, sql_exists_person,
  1069             (int)strlen(sql_exists_person), &_session->exists_person, NULL);
  1070     assert(int_result == SQLITE_OK);
  1071 
  1072     int_result = sqlite3_prepare_v2(_session->db, sql_set_as_pep_user,
  1073             (int)strlen(sql_set_as_pep_user), &_session->set_as_pep_user, NULL);
  1074     assert(int_result == SQLITE_OK);
  1075     
  1076     int_result = sqlite3_prepare_v2(_session->db, sql_is_pep_user,
  1077             (int)strlen(sql_is_pep_user), &_session->is_pep_user, NULL);
  1078     assert(int_result == SQLITE_OK);
  1079 
  1080     int_result = sqlite3_prepare_v2(_session->db, sql_set_device_group,
  1081             (int)strlen(sql_set_device_group), &_session->set_device_group, NULL);
  1082     assert(int_result == SQLITE_OK);
  1083 
  1084     int_result = sqlite3_prepare_v2(_session->db, sql_get_device_group,
  1085             (int)strlen(sql_get_device_group), &_session->get_device_group, NULL);
  1086     assert(int_result == SQLITE_OK);
  1087 
  1088     int_result = sqlite3_prepare_v2(_session->db, sql_set_pgp_keypair,
  1089             (int)strlen(sql_set_pgp_keypair), &_session->set_pgp_keypair,
  1090             NULL);
  1091     assert(int_result == SQLITE_OK);
  1092 
  1093     int_result = sqlite3_prepare_v2(_session->db, sql_set_identity_entry,
  1094             (int)strlen(sql_set_identity_entry), &_session->set_identity_entry, NULL);
  1095     assert(int_result == SQLITE_OK);
  1096 
  1097     int_result = sqlite3_prepare_v2(_session->db, sql_update_identity_entry,
  1098             (int)strlen(sql_update_identity_entry), &_session->update_identity_entry, NULL);
  1099     assert(int_result == SQLITE_OK);
  1100 
  1101     int_result = sqlite3_prepare_v2(_session->db, sql_exists_identity_entry,
  1102             (int)strlen(sql_exists_identity_entry), &_session->exists_identity_entry, NULL);
  1103     assert(int_result == SQLITE_OK);
  1104 
  1105     int_result = sqlite3_prepare_v2(_session->db, sql_set_identity_flags,
  1106             (int)strlen(sql_set_identity_flags), &_session->set_identity_flags,
  1107             NULL);
  1108     assert(int_result == SQLITE_OK);
  1109 
  1110     int_result = sqlite3_prepare_v2(_session->db, sql_unset_identity_flags,
  1111             (int)strlen(sql_unset_identity_flags), &_session->unset_identity_flags,
  1112             NULL);
  1113     assert(int_result == SQLITE_OK);
  1114 
  1115     int_result = sqlite3_prepare_v2(_session->db, sql_set_trust,
  1116             (int)strlen(sql_set_trust), &_session->set_trust, NULL);
  1117     assert(int_result == SQLITE_OK);
  1118 
  1119     int_result = sqlite3_prepare_v2(_session->db, sql_update_trust,
  1120             (int)strlen(sql_update_trust), &_session->update_trust, NULL);
  1121     assert(int_result == SQLITE_OK);
  1122 
  1123     int_result = sqlite3_prepare_v2(_session->db, sql_exists_trust_entry,
  1124                  (int)strlen(sql_exists_trust_entry), &_session->exists_trust_entry, NULL);
  1125     assert(int_result == SQLITE_OK);
  1126 
  1127     int_result = sqlite3_prepare_v2(_session->db, sql_update_trust_for_fpr,
  1128             (int)strlen(sql_update_trust_for_fpr), &_session->update_trust_for_fpr, NULL);
  1129     assert(int_result == SQLITE_OK);
  1130 
  1131     int_result = sqlite3_prepare_v2(_session->db, sql_get_trust,
  1132             (int)strlen(sql_get_trust), &_session->get_trust, NULL);
  1133     assert(int_result == SQLITE_OK);
  1134 
  1135     int_result = sqlite3_prepare_v2(_session->db, sql_least_trust,
  1136             (int)strlen(sql_least_trust), &_session->least_trust, NULL);
  1137     assert(int_result == SQLITE_OK);
  1138 
  1139     int_result = sqlite3_prepare_v2(_session->db, sql_mark_as_compromized,
  1140             (int)strlen(sql_mark_as_compromized), &_session->mark_compromized,
  1141             NULL);
  1142     assert(int_result == SQLITE_OK);
  1143 
  1144     int_result = sqlite3_prepare_v2(_session->db, sql_crashdump,
  1145             (int)strlen(sql_crashdump), &_session->crashdump, NULL);
  1146     assert(int_result == SQLITE_OK);
  1147 
  1148     int_result = sqlite3_prepare_v2(_session->system_db, sql_languagelist,
  1149             (int)strlen(sql_languagelist), &_session->languagelist, NULL);
  1150     assert(int_result == SQLITE_OK);
  1151 
  1152     int_result = sqlite3_prepare_v2(_session->system_db, sql_i18n_token,
  1153             (int)strlen(sql_i18n_token), &_session->i18n_token, NULL);
  1154     assert(int_result == SQLITE_OK);
  1155     
  1156     // blacklist
  1157 
  1158     int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_add,
  1159             (int)strlen(sql_blacklist_add), &_session->blacklist_add, NULL);
  1160     assert(int_result == SQLITE_OK);
  1161 
  1162     int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_delete,
  1163             (int)strlen(sql_blacklist_delete), &_session->blacklist_delete,
  1164             NULL);
  1165     assert(int_result == SQLITE_OK);
  1166 
  1167     int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_is_listed,
  1168             (int)strlen(sql_blacklist_is_listed),
  1169             &_session->blacklist_is_listed, NULL);
  1170     assert(int_result == SQLITE_OK);
  1171 
  1172     int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_retrieve,
  1173             (int)strlen(sql_blacklist_retrieve), &_session->blacklist_retrieve,
  1174             NULL);
  1175     assert(int_result == SQLITE_OK);
  1176     
  1177     // Own keys
  1178     
  1179     int_result = sqlite3_prepare_v2(_session->db, sql_own_key_is_listed,
  1180             (int)strlen(sql_own_key_is_listed), &_session->own_key_is_listed,
  1181             NULL);
  1182     assert(int_result == SQLITE_OK);
  1183     
  1184     int_result = sqlite3_prepare_v2(_session->db, sql_own_identities_retrieve,
  1185             (int)strlen(sql_own_identities_retrieve),
  1186             &_session->own_identities_retrieve, NULL);
  1187     assert(int_result == SQLITE_OK);
  1188  
  1189     int_result = sqlite3_prepare_v2(_session->db, sql_own_keys_retrieve,
  1190             (int)strlen(sql_own_keys_retrieve),
  1191             &_session->own_keys_retrieve, NULL);
  1192     assert(int_result == SQLITE_OK);
  1193  
  1194     // int_result = sqlite3_prepare_v2(_session->db, sql_set_own_key,
  1195     //         (int)strlen(sql_set_own_key),
  1196     //         &_session->set_own_key, NULL);
  1197     // assert(int_result == SQLITE_OK);
  1198  
  1199     // Sequence
  1200 
  1201     int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value1,
  1202             (int)strlen(sql_sequence_value1), &_session->sequence_value1,
  1203             NULL);
  1204     assert(int_result == SQLITE_OK);
  1205 
  1206     int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value2,
  1207             (int)strlen(sql_sequence_value2), &_session->sequence_value2,
  1208             NULL);
  1209     assert(int_result == SQLITE_OK);
  1210 
  1211     int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value3,
  1212             (int)strlen(sql_sequence_value3), &_session->sequence_value3,
  1213             NULL);
  1214     assert(int_result == SQLITE_OK);
  1215 
  1216     // Revocation tracking
  1217     
  1218     int_result = sqlite3_prepare_v2(_session->db, sql_set_revoked,
  1219             (int)strlen(sql_set_revoked), &_session->set_revoked, NULL);
  1220     assert(int_result == SQLITE_OK);
  1221     
  1222     int_result = sqlite3_prepare_v2(_session->db, sql_get_revoked,
  1223             (int)strlen(sql_get_revoked), &_session->get_revoked, NULL);
  1224     assert(int_result == SQLITE_OK);
  1225     
  1226     int_result = sqlite3_prepare_v2(_session->db, sql_add_mistrusted_key,
  1227             (int)strlen(sql_add_mistrusted_key), &_session->add_mistrusted_key, NULL);
  1228     assert(int_result == SQLITE_OK);
  1229 
  1230     int_result = sqlite3_prepare_v2(_session->db, sql_delete_mistrusted_key,
  1231             (int)strlen(sql_delete_mistrusted_key), &_session->delete_mistrusted_key, NULL);
  1232     assert(int_result == SQLITE_OK);
  1233 
  1234     int_result = sqlite3_prepare_v2(_session->db, sql_is_mistrusted_key,
  1235             (int)strlen(sql_is_mistrusted_key), &_session->is_mistrusted_key, NULL);
  1236     assert(int_result == SQLITE_OK);
  1237     
  1238     status = init_cryptotech(_session, in_first);
  1239     if (status != PEP_STATUS_OK)
  1240         goto pep_error;
  1241 
  1242     status = init_transport_system(_session, in_first);
  1243     if (status != PEP_STATUS_OK)
  1244         goto pep_error;
  1245 
  1246     status = log_event(_session, "init", "pEp " PEP_ENGINE_VERSION, NULL, NULL);
  1247     if (status != PEP_STATUS_OK)
  1248         goto pep_error;
  1249 
  1250     // runtime config
  1251 
  1252     if (very_first)
  1253     {
  1254         // On first run, all private keys already present in PGP keyring 
  1255         // are taken as own in order to seamlessly integrate with
  1256         // pre-existing GPG setup.
  1257 
  1258         // Note: earlier fears about danger because of DB reinitialisation should
  1259         // be a non-issue here, as we ONLY take the ultimately trusted keys now.
  1260         // Thus, unless the user has assigned ultimate trust through PGP, there is
  1261         // no chance of automatically imported pEp keys from a previous run making
  1262         // their way into PEP trusted status without explicit action (Bare imported
  1263         // private keys have an 'unknown' trust designation in PGP).
  1264 
  1265         // We don't really worry about the status here.
  1266     //    status = import_trusted_own_keys(_session);        
  1267     }
  1268 
  1269     // sync_session set to own session by default
  1270     // sync_session is then never null on a valid session
  1271     _session->sync_session = _session;
  1272 
  1273     *session = _session;
  1274     
  1275     // Note: Following statement is NOT for any cryptographic/secure functionality; it is
  1276     //       ONLY used for some randomness in generated outer message ID, which are
  1277     //       required by the RFC to be globally unique!
  1278     srand(time(NULL));
  1279     
  1280     return PEP_STATUS_OK;
  1281 
  1282 enomem:
  1283     status = PEP_OUT_OF_MEMORY;
  1284 
  1285 pep_error:
  1286     release(_session);
  1287     return status;
  1288 }
  1289 
  1290 DYNAMIC_API void release(PEP_SESSION session)
  1291 {
  1292     bool out_last = false;
  1293     int _count = --init_count;
  1294     
  1295     assert(_count >= -1);
  1296     assert(session);
  1297 
  1298     if (!((_count >= -1) && session))
  1299         return;
  1300 
  1301     // a small race condition but still a race condition
  1302     // mitigated by calling caveat (see documentation)
  1303     // (release() is to be guarded by a mutex by the caller)
  1304     if (_count == -1)
  1305         out_last = true;
  1306 
  1307     if (session) {
  1308 
  1309         if (session->db) {
  1310             if (session->log)
  1311                 sqlite3_finalize(session->log);
  1312             if (session->trustword)
  1313                 sqlite3_finalize(session->trustword);
  1314             if (session->get_identity)
  1315                 sqlite3_finalize(session->get_identity);
  1316             if (session->get_identity_without_trust_check)
  1317                 sqlite3_finalize(session->get_identity_without_trust_check);
  1318             if (session->get_identities_by_address)
  1319                 sqlite3_finalize(session->get_identities_by_address);            
  1320             if (session->get_user_default_key)
  1321                 sqlite3_finalize(session->get_user_default_key);    
  1322             if (session->get_default_own_userid)
  1323                 sqlite3_finalize(session->get_default_own_userid);
  1324             if (session->get_userid_alias_default)
  1325                 sqlite3_finalize(session->get_userid_alias_default);
  1326             if (session->add_userid_alias)
  1327                 sqlite3_finalize(session->add_userid_alias);
  1328             if (session->replace_identities_fpr)
  1329                 sqlite3_finalize(session->replace_identities_fpr);        
  1330             if (session->remove_fpr_as_default)
  1331                 sqlite3_finalize(session->remove_fpr_as_default);            
  1332             if (session->set_person)
  1333                 sqlite3_finalize(session->set_person);
  1334             if (session->set_as_pep_user)
  1335                 sqlite3_finalize(session->set_as_pep_user);
  1336             if (session->is_pep_user)
  1337                 sqlite3_finalize(session->is_pep_user);
  1338             if (session->exists_person)
  1339                 sqlite3_finalize(session->exists_person);                        
  1340             if (session->set_device_group)
  1341                 sqlite3_finalize(session->set_device_group);
  1342             if (session->get_device_group)
  1343                 sqlite3_finalize(session->get_device_group);
  1344             if (session->set_pgp_keypair)
  1345                 sqlite3_finalize(session->set_pgp_keypair);
  1346             if (session->exists_identity_entry)
  1347                 sqlite3_finalize(session->exists_identity_entry);                
  1348             if (session->set_identity_entry)
  1349                 sqlite3_finalize(session->set_identity_entry);
  1350             if (session->update_identity_entry)
  1351                 sqlite3_finalize(session->update_identity_entry);    
  1352             if (session->set_identity_flags)
  1353                 sqlite3_finalize(session->set_identity_flags);
  1354             if (session->unset_identity_flags)
  1355                 sqlite3_finalize(session->unset_identity_flags);
  1356             if (session->exists_trust_entry)
  1357                 sqlite3_finalize(session->exists_trust_entry);                                
  1358             if (session->set_trust)
  1359                 sqlite3_finalize(session->set_trust);
  1360             if (session->update_trust)
  1361                 sqlite3_finalize(session->update_trust);                
  1362             if (session->update_trust_for_fpr)
  1363                 sqlite3_finalize(session->update_trust_for_fpr);
  1364             if (session->get_trust)
  1365                 sqlite3_finalize(session->get_trust);
  1366             if (session->least_trust)
  1367                 sqlite3_finalize(session->least_trust);
  1368             if (session->mark_compromized)
  1369                 sqlite3_finalize(session->mark_compromized);
  1370             if (session->crashdump)
  1371                 sqlite3_finalize(session->crashdump);
  1372             if (session->languagelist)
  1373                 sqlite3_finalize(session->languagelist);
  1374             if (session->i18n_token)
  1375                 sqlite3_finalize(session->i18n_token);
  1376             if (session->replace_userid)
  1377                 sqlite3_finalize(session->replace_userid);
  1378             if (session->replace_main_user_fpr)
  1379                 sqlite3_finalize(session->replace_main_user_fpr);                
  1380             if (session->get_main_user_fpr)
  1381                 sqlite3_finalize(session->get_main_user_fpr);
  1382             if (session->refresh_userid_default_key)
  1383                 sqlite3_finalize(session->refresh_userid_default_key);
  1384             if (session->blacklist_add)
  1385                 sqlite3_finalize(session->blacklist_add);
  1386             if (session->blacklist_delete)
  1387                 sqlite3_finalize(session->blacklist_delete);
  1388             if (session->blacklist_is_listed)
  1389                 sqlite3_finalize(session->blacklist_is_listed);
  1390             if (session->blacklist_retrieve)
  1391                 sqlite3_finalize(session->blacklist_retrieve);
  1392             if (session->own_key_is_listed)
  1393                 sqlite3_finalize(session->own_key_is_listed);
  1394             if (session->own_identities_retrieve)
  1395                 sqlite3_finalize(session->own_identities_retrieve);
  1396             if (session->own_keys_retrieve)
  1397                 sqlite3_finalize(session->own_keys_retrieve);
  1398             // if (session->set_own_key)
  1399             //     sqlite3_finalize(session->set_own_key);
  1400             if (session->sequence_value1)
  1401                 sqlite3_finalize(session->sequence_value1);
  1402             if (session->sequence_value2)
  1403                 sqlite3_finalize(session->sequence_value2);
  1404             if (session->sequence_value3)
  1405                 sqlite3_finalize(session->sequence_value3);
  1406             if (session->set_revoked)
  1407                 sqlite3_finalize(session->set_revoked);
  1408             if (session->get_revoked)
  1409                 sqlite3_finalize(session->get_revoked);
  1410 
  1411             if (session->add_mistrusted_key)
  1412                 sqlite3_finalize(session->add_mistrusted_key);
  1413             if (session->delete_mistrusted_key)
  1414                 sqlite3_finalize(session->delete_mistrusted_key);
  1415             if (session->is_mistrusted_key)
  1416                 sqlite3_finalize(session->is_mistrusted_key);
  1417 
  1418             if (session->db)
  1419                 sqlite3_close_v2(session->db);
  1420             if (session->system_db)
  1421                 sqlite3_close_v2(session->system_db);
  1422         }
  1423 
  1424         release_transport_system(session, out_last);
  1425         release_cryptotech(session, out_last);
  1426 
  1427 #ifdef DEBUG_ERRORSTACK
  1428         free_stringlist(session->errorstack);
  1429 #endif
  1430         free(session);
  1431     }
  1432 }
  1433 
  1434 DYNAMIC_API void config_passive_mode(PEP_SESSION session, bool enable)
  1435 {
  1436     assert(session);
  1437     session->passive_mode = enable;
  1438 }
  1439 
  1440 DYNAMIC_API void config_unencrypted_subject(PEP_SESSION session, bool enable)
  1441 {
  1442     assert(session);
  1443     session->unencrypted_subject = enable;
  1444 }
  1445 
  1446 DYNAMIC_API void config_keep_sync_msg(PEP_SESSION session, bool enable)
  1447 {
  1448     assert(session);
  1449     session->keep_sync_msg = enable;
  1450 }
  1451 
  1452 DYNAMIC_API void config_service_log(PEP_SESSION session, bool enable)
  1453 {
  1454     assert(session);
  1455     session->service_log = enable;
  1456 }
  1457 
  1458 DYNAMIC_API PEP_STATUS log_event(
  1459         PEP_SESSION session,
  1460         const char *title,
  1461         const char *entity,
  1462         const char *description,
  1463         const char *comment
  1464     )
  1465 {
  1466     PEP_STATUS status = PEP_STATUS_OK;
  1467     int result;
  1468 
  1469     assert(session);
  1470     assert(title);
  1471     assert(entity);
  1472 
  1473     if (!(session && title && entity))
  1474         return PEP_ILLEGAL_VALUE;
  1475 
  1476     sqlite3_reset(session->log);
  1477     sqlite3_bind_text(session->log, 1, title, -1, SQLITE_STATIC);
  1478     sqlite3_bind_text(session->log, 2, entity, -1, SQLITE_STATIC);
  1479     if (description)
  1480         sqlite3_bind_text(session->log, 3, description, -1, SQLITE_STATIC);
  1481     else
  1482         sqlite3_bind_null(session->log, 3);
  1483     if (comment)
  1484         sqlite3_bind_text(session->log, 4, comment, -1, SQLITE_STATIC);
  1485     else
  1486         sqlite3_bind_null(session->log, 4);
  1487     do {
  1488         result = sqlite3_step(session->log);
  1489         assert(result == SQLITE_DONE || result == SQLITE_BUSY);
  1490         if (result != SQLITE_DONE && result != SQLITE_BUSY)
  1491             status = PEP_UNKNOWN_ERROR;
  1492     } while (result == SQLITE_BUSY);
  1493     sqlite3_reset(session->log);
  1494 
  1495     return ADD_TO_LOG(status);
  1496 }
  1497 
  1498 DYNAMIC_API PEP_STATUS log_service(
  1499         PEP_SESSION session,
  1500         const char *title,
  1501         const char *entity,
  1502         const char *description,
  1503         const char *comment
  1504     )
  1505 {
  1506     assert(session);
  1507     if (!session)
  1508         return PEP_ILLEGAL_VALUE;
  1509 
  1510     if (session->service_log)
  1511         return log_event(session, title, entity, description, comment);
  1512     else
  1513         return PEP_STATUS_OK;
  1514 }
  1515 
  1516 DYNAMIC_API PEP_STATUS trustword(
  1517             PEP_SESSION session, uint16_t value, const char *lang,
  1518             char **word, size_t *wsize
  1519         )
  1520 {
  1521     PEP_STATUS status = PEP_STATUS_OK;
  1522 
  1523     assert(session);
  1524     assert(word);
  1525     assert(wsize);
  1526 
  1527     if (!(session && word && wsize))
  1528         return PEP_ILLEGAL_VALUE;
  1529 
  1530     *word = NULL;
  1531     *wsize = 0;
  1532 
  1533     if (lang == NULL)
  1534         lang = "en";
  1535 
  1536     assert((lang[0] >= 'A' && lang[0] <= 'Z')
  1537             || (lang[0] >= 'a' && lang[0] <= 'z'));
  1538     assert((lang[1] >= 'A' && lang[1] <= 'Z')
  1539             || (lang[1] >= 'a' && lang[1] <= 'z'));
  1540     assert(lang[2] == 0);
  1541 
  1542     sqlite3_reset(session->trustword);
  1543     sqlite3_bind_text(session->trustword, 1, lang, -1, SQLITE_STATIC);
  1544     sqlite3_bind_int(session->trustword, 2, value);
  1545 
  1546     const int result = sqlite3_step(session->trustword);
  1547     if (result == SQLITE_ROW) {
  1548         *word = strdup((const char *) sqlite3_column_text(session->trustword,
  1549                     1));
  1550         if (*word)
  1551             *wsize = sqlite3_column_bytes(session->trustword, 1);
  1552         else
  1553             status = PEP_OUT_OF_MEMORY;
  1554     } else
  1555         status = PEP_TRUSTWORD_NOT_FOUND;
  1556 
  1557     sqlite3_reset(session->trustword);
  1558     return status;
  1559 }
  1560 
  1561 DYNAMIC_API PEP_STATUS trustwords(
  1562         PEP_SESSION session, const char *fingerprint, const char *lang,
  1563         char **words, size_t *wsize, int max_words
  1564     )
  1565 {
  1566     const char *source = fingerprint;
  1567 
  1568     assert(session);
  1569     assert(fingerprint);
  1570     assert(words);
  1571     assert(wsize);
  1572     assert(max_words >= 0);
  1573 
  1574     if (!(session && fingerprint && words && wsize && max_words >= 0))
  1575         return PEP_ILLEGAL_VALUE;
  1576 
  1577     *words = NULL;
  1578     *wsize = 0;
  1579 
  1580     char *buffer = calloc(1, MAX_TRUSTWORDS_SPACE);
  1581     assert(buffer);
  1582     if (buffer == NULL)
  1583         return PEP_OUT_OF_MEMORY;
  1584     char *dest = buffer;
  1585 
  1586     const size_t fsize = strlen(fingerprint);
  1587 
  1588     if (!lang || !lang[0])
  1589         lang = "en";
  1590 
  1591     assert((lang[0] >= 'A' && lang[0] <= 'Z')
  1592             || (lang[0] >= 'a' && lang[0] <= 'z'));
  1593     assert((lang[1] >= 'A' && lang[1] <= 'Z')
  1594             || (lang[1] >= 'a' && lang[1] <= 'z'));
  1595     assert(lang[2] == 0);
  1596 
  1597     int n_words = 0;
  1598     while (source < fingerprint + fsize) {
  1599         PEP_STATUS _status;
  1600         uint16_t value;
  1601         char *word = NULL;
  1602         size_t _wsize = 0;
  1603         int j;
  1604 
  1605         for (value=0, j=0; j < 4 && source < fingerprint + fsize; ) {
  1606             if (*source >= 'a' && *source <= 'f')
  1607                 value += (*source - 'a' + 10) << (3 - j++) * 4;
  1608             else if (*source >= 'A' && *source <= 'F')
  1609                 value += (*source - 'A' + 10) << (3 - j++) * 4;
  1610             else if (*source >= '0' && *source <= '9')
  1611                 value += (*source - '0') << (3 - j++) * 4;
  1612             
  1613             source++;
  1614         }
  1615 
  1616         _status = trustword(session, value, lang, &word, &_wsize);
  1617         if (_status == PEP_OUT_OF_MEMORY) {
  1618             free(buffer);
  1619             return PEP_OUT_OF_MEMORY;
  1620         }
  1621         if (word == NULL) {
  1622             free(buffer);
  1623             return PEP_TRUSTWORD_NOT_FOUND;
  1624         }
  1625 
  1626         if (dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1) {
  1627             strncpy(dest, word, _wsize);
  1628             free(word);
  1629             dest += _wsize;
  1630         }
  1631         else {
  1632             free(word);
  1633             break; // buffer full
  1634         }
  1635 
  1636         if (source < fingerprint + fsize
  1637                 && dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1)
  1638             *dest++ = ' ';
  1639 
  1640         ++n_words;
  1641         if (max_words && n_words >= max_words)
  1642             break;
  1643     }
  1644 
  1645     *words = buffer;
  1646     *wsize = dest - buffer;
  1647     return PEP_STATUS_OK;
  1648 }
  1649 
  1650 pEp_identity *new_identity(
  1651         const char *address, const char *fpr, const char *user_id,
  1652         const char *username
  1653     )
  1654 {
  1655     pEp_identity *result = calloc(1, sizeof(pEp_identity));
  1656     assert(result);
  1657     if (result) {
  1658         if (address) {
  1659             result->address = strdup(address);
  1660             assert(result->address);
  1661             if (result->address == NULL) {
  1662                 free(result);
  1663                 return NULL;
  1664             }
  1665         }
  1666         if (fpr) {
  1667             result->fpr = strdup(fpr);
  1668             assert(result->fpr);
  1669             if (result->fpr == NULL) {
  1670                 free_identity(result);
  1671                 return NULL;
  1672             }
  1673         }
  1674         if (user_id) {
  1675             result->user_id = strdup(user_id);
  1676             assert(result->user_id);
  1677             if (result->user_id == NULL) {
  1678                 free_identity(result);
  1679                 return NULL;
  1680             }
  1681         }
  1682         if (username) {
  1683             result->username = strdup(username);
  1684             assert(result->username);
  1685             if (result->username == NULL) {
  1686                 free_identity(result);
  1687                 return NULL;
  1688             }
  1689         }
  1690     }
  1691     return result;
  1692 }
  1693 
  1694 pEp_identity *identity_dup(const pEp_identity *src)
  1695 {
  1696     assert(src);
  1697 
  1698     pEp_identity *dup = new_identity(src->address, src->fpr, src->user_id,
  1699             src->username);
  1700     assert(dup);
  1701     if (dup == NULL)
  1702         return NULL;
  1703     
  1704     dup->comm_type = src->comm_type;
  1705     dup->lang[0] = src->lang[0];
  1706     dup->lang[1] = src->lang[1];
  1707     dup->lang[2] = 0;
  1708     dup->flags = src->flags;
  1709     dup->me = src->me;
  1710     
  1711     return dup;
  1712 }
  1713 
  1714 void free_identity(pEp_identity *identity)
  1715 {
  1716     if (identity) {
  1717         free(identity->address);
  1718         free(identity->fpr);
  1719         free(identity->user_id);
  1720         free(identity->username);
  1721         free(identity);
  1722     }
  1723 }
  1724 
  1725 DYNAMIC_API PEP_STATUS get_default_own_userid(
  1726         PEP_SESSION session, 
  1727         char** userid
  1728     )
  1729 {
  1730     assert(session);
  1731     assert(userid);
  1732     
  1733     if (!session || !userid)
  1734         return PEP_ILLEGAL_VALUE;
  1735         
  1736     PEP_STATUS status = PEP_STATUS_OK;
  1737     char* retval = NULL;
  1738     
  1739     sqlite3_reset(session->get_default_own_userid);
  1740 
  1741     const int result = sqlite3_step(session->get_default_own_userid);
  1742     const char* id;
  1743     
  1744     switch (result) {
  1745         case SQLITE_ROW:
  1746             id = (const char *) sqlite3_column_text(session->get_default_own_userid, 0);
  1747             if (!id) {
  1748                 // Shouldn't happen.
  1749                 status = PEP_UNKNOWN_ERROR;
  1750             }
  1751             else {
  1752                 retval = strdup(id);
  1753                 if (!retval)
  1754                     status = PEP_OUT_OF_MEMORY;
  1755             }
  1756             break;
  1757         default:
  1758             // Technically true, given how we find it, but FIXME we need a more descriptive error
  1759             status = PEP_CANNOT_FIND_IDENTITY;
  1760             *userid = NULL;
  1761     }
  1762 
  1763     *userid = retval;
  1764 
  1765     sqlite3_reset(session->get_default_own_userid);
  1766     
  1767     return status;
  1768 }
  1769 
  1770 DYNAMIC_API PEP_STATUS get_userid_alias_default(
  1771         PEP_SESSION session, 
  1772         const char* alias_id,
  1773         char** default_id) {
  1774             
  1775     assert(session);
  1776     assert(alias_id);
  1777     assert(alias_id[0]);
  1778     assert(default_id);
  1779 
  1780     if (!(session && alias_id && alias_id[0] && default_id))
  1781         return PEP_ILLEGAL_VALUE;
  1782 
  1783     PEP_STATUS status = PEP_STATUS_OK;
  1784     char* retval = NULL;
  1785 
  1786     sqlite3_reset(session->get_userid_alias_default);
  1787     sqlite3_bind_text(session->get_userid_alias_default, 1, alias_id, -1, SQLITE_STATIC);
  1788 
  1789     const char* tempid;
  1790     
  1791     const int result = sqlite3_step(session->get_userid_alias_default);
  1792     switch (result) {
  1793     case SQLITE_ROW:
  1794         tempid = (const char *) sqlite3_column_text(session->get_userid_alias_default, 0);
  1795         if (tempid) {
  1796             retval = strdup(tempid);
  1797             assert(retval);
  1798             if (retval == NULL)
  1799                 return PEP_OUT_OF_MEMORY;
  1800         }
  1801     
  1802         *default_id = retval;
  1803         break;
  1804     default:
  1805         status = PEP_CANNOT_FIND_ALIAS;
  1806         *default_id = NULL;
  1807     }
  1808 
  1809     sqlite3_reset(session->get_userid_alias_default);
  1810     return status;            
  1811 }
  1812 
  1813 DYNAMIC_API PEP_STATUS set_userid_alias (
  1814         PEP_SESSION session, 
  1815         const char* default_id,
  1816         const char* alias_id) {
  1817             
  1818     int result;
  1819 
  1820     assert(session);
  1821     assert(default_id);
  1822     assert(alias_id);
  1823 
  1824     if (!(session && default_id && alias_id && 
  1825           default_id[0] != '\0' && alias_id[0] != '\0'))
  1826         return PEP_ILLEGAL_VALUE;
  1827     
  1828     sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  1829 
  1830     sqlite3_reset(session->add_userid_alias);
  1831     sqlite3_bind_text(session->add_userid_alias, 1, default_id, -1,
  1832             SQLITE_STATIC);
  1833     sqlite3_bind_text(session->add_userid_alias, 2, alias_id, -1,
  1834             SQLITE_STATIC);
  1835         
  1836     result = sqlite3_step(session->add_userid_alias);
  1837 
  1838     sqlite3_reset(session->add_userid_alias);
  1839     if (result != SQLITE_DONE) {
  1840         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);        
  1841         return PEP_CANNOT_SET_ALIAS;
  1842     }
  1843     sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  1844         
  1845 
  1846     return PEP_STATUS_OK;
  1847 }
  1848 
  1849 DYNAMIC_API PEP_STATUS get_identity(
  1850         PEP_SESSION session,
  1851         const char *address,
  1852         const char *user_id,
  1853         pEp_identity **identity
  1854     )
  1855 {
  1856     PEP_STATUS status = PEP_STATUS_OK;
  1857     static pEp_identity *_identity;
  1858 
  1859     assert(session);
  1860     assert(address);
  1861     assert(address[0]);
  1862     assert(identity);
  1863 
  1864     if (!(session && address && address[0] && identity))
  1865         return PEP_ILLEGAL_VALUE;
  1866 
  1867     *identity = NULL;
  1868 
  1869     sqlite3_reset(session->get_identity);
  1870     sqlite3_bind_text(session->get_identity, 1, address, -1, SQLITE_STATIC);
  1871     sqlite3_bind_text(session->get_identity, 2, user_id, -1, SQLITE_STATIC);
  1872 
  1873     const int result = sqlite3_step(session->get_identity);
  1874     switch (result) {
  1875     case SQLITE_ROW:
  1876         _identity = new_identity(
  1877                 address,
  1878                 (const char *) sqlite3_column_text(session->get_identity, 0),
  1879                 user_id,
  1880                 (const char *) sqlite3_column_text(session->get_identity, 1)
  1881                 );
  1882         assert(_identity);
  1883         if (_identity == NULL)
  1884             return PEP_OUT_OF_MEMORY;
  1885 
  1886         _identity->comm_type = (PEP_comm_type)
  1887             sqlite3_column_int(session->get_identity, 2);
  1888         const char* const _lang = (const char *)
  1889             sqlite3_column_text(session->get_identity, 3);
  1890         if (_lang && _lang[0]) {
  1891             assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  1892             assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  1893             assert(_lang[2] == 0);
  1894             _identity->lang[0] = _lang[0];
  1895             _identity->lang[1] = _lang[1];
  1896             _identity->lang[2] = 0;
  1897         }
  1898         _identity->flags = (unsigned int)
  1899             sqlite3_column_int(session->get_identity, 4);
  1900         _identity->me = (unsigned int)
  1901             sqlite3_column_int(session->get_identity, 5);
  1902     
  1903         *identity = _identity;
  1904         break;
  1905     default:
  1906         status = PEP_CANNOT_FIND_IDENTITY;
  1907         *identity = NULL;
  1908     }
  1909 
  1910     sqlite3_reset(session->get_identity);
  1911     return status;
  1912 }
  1913 
  1914 PEP_STATUS get_identity_without_trust_check(
  1915         PEP_SESSION session,
  1916         const char *address,
  1917         const char *user_id,
  1918         pEp_identity **identity
  1919     )
  1920 {
  1921     PEP_STATUS status = PEP_STATUS_OK;
  1922     static pEp_identity *_identity;
  1923 
  1924     assert(session);
  1925     assert(address);
  1926     assert(address[0]);
  1927     assert(identity);
  1928 
  1929     if (!(session && address && address[0] && identity))
  1930         return PEP_ILLEGAL_VALUE;
  1931 
  1932     *identity = NULL;
  1933 
  1934     sqlite3_reset(session->get_identity_without_trust_check);
  1935     sqlite3_bind_text(session->get_identity_without_trust_check, 1, address, -1, SQLITE_STATIC);
  1936     sqlite3_bind_text(session->get_identity_without_trust_check, 2, user_id, -1, SQLITE_STATIC);
  1937 
  1938     const int result = sqlite3_step(session->get_identity_without_trust_check);
  1939     switch (result) {
  1940     case SQLITE_ROW:
  1941         _identity = new_identity(
  1942                 address,
  1943                 (const char *) sqlite3_column_text(session->get_identity_without_trust_check, 0),
  1944                 user_id,
  1945                 (const char *) sqlite3_column_text(session->get_identity_without_trust_check, 1)
  1946                 );
  1947         assert(_identity);
  1948         if (_identity == NULL)
  1949             return PEP_OUT_OF_MEMORY;
  1950 
  1951         _identity->comm_type = PEP_ct_unknown;
  1952         const char* const _lang = (const char *)
  1953             sqlite3_column_text(session->get_identity_without_trust_check, 2);
  1954         if (_lang && _lang[0]) {
  1955             assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  1956             assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  1957             assert(_lang[2] == 0);
  1958             _identity->lang[0] = _lang[0];
  1959             _identity->lang[1] = _lang[1];
  1960             _identity->lang[2] = 0;
  1961         }
  1962         _identity->flags = (unsigned int)
  1963             sqlite3_column_int(session->get_identity_without_trust_check, 3);
  1964         _identity->me = (unsigned int)
  1965             sqlite3_column_int(session->get_identity_without_trust_check, 4);
  1966     
  1967         *identity = _identity;
  1968         break;
  1969     default:
  1970         status = PEP_CANNOT_FIND_IDENTITY;
  1971         *identity = NULL;
  1972     }
  1973 
  1974     sqlite3_reset(session->get_identity_without_trust_check);
  1975     return status;
  1976 }
  1977 
  1978 PEP_STATUS get_identities_by_address(
  1979         PEP_SESSION session,
  1980         const char *address,
  1981         identity_list** id_list
  1982     )
  1983 {
  1984     pEp_identity* ident;
  1985 
  1986     assert(session);
  1987     assert(address);
  1988     assert(address[0]);
  1989     assert(id_list);
  1990 
  1991     if (!(session && address && address[0] && id_list))
  1992         return PEP_ILLEGAL_VALUE;
  1993 
  1994     *id_list = NULL;
  1995     identity_list* ident_list = NULL;
  1996 
  1997     sqlite3_reset(session->get_identities_by_address);
  1998     sqlite3_bind_text(session->get_identities_by_address, 1, address, -1, SQLITE_STATIC);
  1999     int result;
  2000 
  2001     while ((result = sqlite3_step(session->get_identities_by_address)) == SQLITE_ROW) {
  2002         //"select user_id, main_key_id, username, comm_type, lang,"
  2003         //"   identity.flags, is_own"
  2004         ident = new_identity(
  2005                 address,
  2006                 (const char *) sqlite3_column_text(session->get_identities_by_address, 1),
  2007                 (const char *) sqlite3_column_text(session->get_identities_by_address, 0),
  2008                 (const char *) sqlite3_column_text(session->get_identities_by_address, 2)
  2009                 );
  2010         assert(ident);
  2011         if (ident == NULL)
  2012             return PEP_OUT_OF_MEMORY;
  2013 
  2014         ident->comm_type = PEP_ct_unknown;
  2015         
  2016         const char* const _lang = (const char *)
  2017             sqlite3_column_text(session->get_identities_by_address, 3);
  2018         if (_lang && _lang[0]) {
  2019             assert(_lang[0] >= 'a' && _lang[0] <= 'z');
  2020             assert(_lang[1] >= 'a' && _lang[1] <= 'z');
  2021             assert(_lang[2] == 0);
  2022             ident->lang[0] = _lang[0];
  2023             ident->lang[1] = _lang[1];
  2024             ident->lang[2] = 0;
  2025         }
  2026         ident->flags = (unsigned int)
  2027             sqlite3_column_int(session->get_identities_by_address, 4);
  2028         ident->me = (unsigned int)
  2029             sqlite3_column_int(session->get_identities_by_address, 5);
  2030     
  2031         if (ident_list)
  2032             identity_list_add(ident_list, ident);
  2033         else
  2034             ident_list = new_identity_list(ident);
  2035     }
  2036 
  2037     sqlite3_reset(session->get_identities_by_address);
  2038     
  2039     *id_list = ident_list;
  2040     
  2041     if (!ident_list)
  2042         return PEP_CANNOT_FIND_IDENTITY;
  2043     
  2044     return PEP_STATUS_OK;
  2045 }
  2046 
  2047 PEP_STATUS exists_identity_entry(PEP_SESSION session, pEp_identity* identity,
  2048                                  bool* exists) {
  2049     assert(session);
  2050     assert(identity);
  2051     assert(!EMPTYSTR(identity->user_id));        
  2052     assert(!EMPTYSTR(identity->address));
  2053     if (!session || !exists || EMPTYSTR(identity->user_id) || EMPTYSTR(identity->address))
  2054         return PEP_ILLEGAL_VALUE;
  2055     
  2056     *exists = false;
  2057     
  2058     sqlite3_reset(session->exists_identity_entry);
  2059     sqlite3_bind_text(session->exists_identity_entry, 1, identity->address, -1,
  2060                       SQLITE_STATIC);
  2061     sqlite3_bind_text(session->exists_identity_entry, 2, identity->user_id, -1,
  2062                       SQLITE_STATIC);
  2063                   
  2064     int result = sqlite3_step(session->exists_identity_entry);
  2065     switch (result) {
  2066         case SQLITE_ROW: {
  2067             // yeah yeah, I know, we could be lazy here, but it looks bad.
  2068             *exists = (sqlite3_column_int(session->exists_identity_entry, 0) != 0);
  2069             break;
  2070         }
  2071         default:
  2072             return PEP_UNKNOWN_ERROR;
  2073     }
  2074 
  2075     return PEP_STATUS_OK;
  2076 }
  2077 
  2078 PEP_STATUS exists_trust_entry(PEP_SESSION session, pEp_identity* identity,
  2079                               bool* exists) {
  2080     assert(session);
  2081     assert(identity);
  2082     assert(!EMPTYSTR(identity->user_id));        
  2083     assert(!EMPTYSTR(identity->fpr));
  2084     if (!session || !exists || EMPTYSTR(identity->user_id) || EMPTYSTR(identity->fpr))
  2085         return PEP_ILLEGAL_VALUE;
  2086     
  2087     *exists = false;
  2088     
  2089     sqlite3_reset(session->exists_trust_entry);
  2090     sqlite3_bind_text(session->exists_trust_entry, 1, identity->user_id, -1,
  2091                       SQLITE_STATIC);
  2092     sqlite3_bind_text(session->exists_trust_entry, 2, identity->fpr, -1,
  2093                       SQLITE_STATIC);
  2094                   
  2095     int result = sqlite3_step(session->exists_trust_entry);
  2096     switch (result) {
  2097         case SQLITE_ROW: {
  2098             // yeah yeah, I know, we could be lazy here, but it looks bad.
  2099             *exists = (sqlite3_column_int(session->exists_trust_entry, 0) != 0);
  2100             break;
  2101         }
  2102         default:
  2103             return PEP_UNKNOWN_ERROR;
  2104     }
  2105 
  2106     return PEP_STATUS_OK;
  2107 }
  2108 
  2109 // FIXME: We can rollback in set_identity on the return status,
  2110 // so we should probably do that.
  2111 PEP_STATUS set_pgp_keypair(PEP_SESSION session, const char* fpr) {
  2112     if (!session || EMPTYSTR(fpr))
  2113         return PEP_ILLEGAL_VALUE;
  2114         
  2115     int result;
  2116     
  2117     sqlite3_reset(session->set_pgp_keypair);
  2118     sqlite3_bind_text(session->set_pgp_keypair, 1, fpr, -1,
  2119             SQLITE_STATIC);
  2120     result = sqlite3_step(session->set_pgp_keypair);
  2121     sqlite3_reset(session->set_pgp_keypair);
  2122     if (result != SQLITE_DONE) {
  2123         return PEP_CANNOT_SET_PGP_KEYPAIR;
  2124     }
  2125     
  2126     return PEP_STATUS_OK;
  2127 }
  2128 
  2129 static PEP_STATUS _set_or_update_trust(PEP_SESSION session,
  2130                                        pEp_identity* identity,
  2131                                        sqlite3_stmt* set_or_update) {
  2132 
  2133     assert(session);
  2134     assert(identity);
  2135     assert(identity->user_id);
  2136     assert(identity->fpr);
  2137     
  2138     if (!session || !identity || EMPTYSTR(identity->user_id) || EMPTYSTR(identity->fpr))
  2139         return PEP_ILLEGAL_VALUE;
  2140         
  2141     int result;
  2142                 
  2143     sqlite3_reset(set_or_update);
  2144     sqlite3_bind_text(set_or_update, 1, identity->user_id, -1,
  2145             SQLITE_STATIC);
  2146     sqlite3_bind_text(set_or_update, 2, identity->fpr, -1,
  2147             SQLITE_STATIC);
  2148     sqlite3_bind_int(set_or_update, 3, identity->comm_type);
  2149     result = sqlite3_step(set_or_update);
  2150     assert(result == SQLITE_DONE);
  2151     sqlite3_reset(set_or_update);
  2152     if (result != SQLITE_DONE)
  2153         return PEP_CANNOT_SET_TRUST;
  2154 
  2155     return PEP_STATUS_OK;
  2156 }
  2157 
  2158 static PEP_STATUS _set_or_update_identity_entry(PEP_SESSION session,
  2159                                                 pEp_identity* identity,
  2160                                                 sqlite3_stmt* set_or_update) {
  2161     assert(session);
  2162     assert(identity);
  2163     assert(set_or_update);
  2164                       
  2165     if (!session || !identity || !identity->user_id || !identity->address)
  2166         return PEP_ILLEGAL_VALUE;
  2167                                               
  2168     sqlite3_reset(set_or_update);
  2169     sqlite3_bind_text(set_or_update, 1, identity->address, -1,
  2170             SQLITE_STATIC);
  2171     sqlite3_bind_text(set_or_update, 2, identity->fpr, -1,
  2172             SQLITE_STATIC);
  2173     sqlite3_bind_text(set_or_update, 3, identity->user_id, -1,
  2174             SQLITE_STATIC);
  2175     sqlite3_bind_int(set_or_update, 4, identity->flags);
  2176     sqlite3_bind_int(set_or_update, 5, identity->me);
  2177     int result = sqlite3_step(set_or_update);
  2178     sqlite3_reset(set_or_update);
  2179     if (result != SQLITE_DONE)
  2180         return PEP_CANNOT_SET_IDENTITY;
  2181     
  2182     return PEP_STATUS_OK;
  2183 }
  2184 
  2185 static PEP_STATUS _set_or_update_person(PEP_SESSION session, 
  2186                                         pEp_identity* identity,
  2187                                         sqlite3_stmt* set_or_update) {
  2188     assert(session);
  2189     assert(identity);
  2190     assert(set_or_update);
  2191                         
  2192     if (!session || !identity || !identity->user_id || !identity->username)
  2193         return PEP_ILLEGAL_VALUE;
  2194         
  2195     sqlite3_reset(set_or_update);
  2196     sqlite3_bind_text(set_or_update, 1, identity->user_id, -1,
  2197             SQLITE_STATIC);
  2198     sqlite3_bind_text(set_or_update, 2, identity->username, -1,
  2199             SQLITE_STATIC);
  2200     if (identity->lang[0])
  2201         sqlite3_bind_text(set_or_update, 3, identity->lang, 2,
  2202                 SQLITE_STATIC);
  2203     else
  2204         sqlite3_bind_null(set_or_update, 3);
  2205     sqlite3_bind_text(set_or_update, 4, identity->fpr, -1,
  2206                       SQLITE_STATIC);
  2207     int result = sqlite3_step(set_or_update);
  2208     sqlite3_reset(set_or_update);
  2209     
  2210     if (result != SQLITE_DONE)
  2211         return PEP_CANNOT_SET_PERSON;
  2212     
  2213     return PEP_STATUS_OK;                                         
  2214 }
  2215 
  2216 PEP_STATUS set_or_update_with_identity(PEP_SESSION session,
  2217                                        pEp_identity* identity,
  2218                                        PEP_STATUS (* set_function)(PEP_SESSION, pEp_identity*, sqlite3_stmt*),
  2219                                        PEP_STATUS (* exists_function)(PEP_SESSION, pEp_identity*, bool*),                                       
  2220                                        sqlite3_stmt* update_query,
  2221                                        sqlite3_stmt* set_query,
  2222                                        bool guard_transaction) {
  2223 
  2224     if (guard_transaction) {
  2225         sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  2226     }
  2227     bool exists = false;
  2228     PEP_STATUS status = exists_function(session, identity, &exists);
  2229     
  2230     if (status == PEP_STATUS_OK) {
  2231         if (exists) {
  2232             status = set_function(session, identity, update_query);
  2233         }
  2234         else {
  2235             status = set_function(session, identity, set_query);                                              
  2236         }                    
  2237     }   
  2238     if (guard_transaction) {        
  2239         if (status != PEP_STATUS_OK)
  2240             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2241         else 
  2242             sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  2243     }                      
  2244     return status;
  2245 }
  2246 
  2247 PEP_STATUS _set_trust_internal(PEP_SESSION session, pEp_identity* identity,
  2248                                bool guard_transaction) {
  2249     return set_or_update_with_identity(session, identity,
  2250                                        _set_or_update_trust,
  2251                                        exists_trust_entry,
  2252                                        session->update_trust,
  2253                                        session->set_trust,
  2254                                        guard_transaction);
  2255 }
  2256 PEP_STATUS set_trust(PEP_SESSION session, pEp_identity* identity) {
  2257     return _set_trust_internal(session, identity, true);
  2258 }
  2259 
  2260 PEP_STATUS set_person(PEP_SESSION session, pEp_identity* identity,
  2261                       bool guard_transaction) {
  2262     return set_or_update_with_identity(session, identity,
  2263                                        _set_or_update_person,
  2264                                        exists_person,
  2265                                        session->update_person,
  2266                                        session->set_person,
  2267                                        guard_transaction);
  2268 }
  2269 
  2270 PEP_STATUS set_identity_entry(PEP_SESSION session, pEp_identity* identity,
  2271                               bool guard_transaction) {
  2272     return set_or_update_with_identity(session, identity,
  2273                                        _set_or_update_identity_entry,
  2274                                        exists_identity_entry,
  2275                                        session->update_identity_entry,
  2276                                        session->set_identity_entry,
  2277                                        guard_transaction);
  2278 }
  2279 
  2280 DYNAMIC_API PEP_STATUS set_identity(
  2281         PEP_SESSION session, const pEp_identity *identity
  2282     )
  2283 {
  2284     int result;
  2285 
  2286     assert(session);
  2287     assert(identity);
  2288     assert(identity->address);
  2289     assert(identity->user_id);
  2290     assert(identity->username);
  2291 
  2292     if (!(session && identity && identity->address &&
  2293                 identity->user_id && identity->username))
  2294         return PEP_ILLEGAL_VALUE;
  2295 
  2296     PEP_STATUS status = PEP_STATUS_OK;
  2297     
  2298     bool listed;
  2299 
  2300     bool has_fpr = (!EMPTYSTR(identity->fpr));
  2301     
  2302     if (has_fpr) {    
  2303         // blacklist check - FIXME: ENGINE-294 will remove
  2304         status = blacklist_is_listed(session, identity->fpr, &listed);
  2305         assert(status == PEP_STATUS_OK);
  2306         if (status != PEP_STATUS_OK)
  2307             return status;
  2308 
  2309         if (listed)
  2310             return PEP_KEY_BLACKLISTED;
  2311     }
  2312 
  2313     sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  2314 
  2315     if (identity->lang[0]) {
  2316         assert(identity->lang[0] >= 'a' && identity->lang[0] <= 'z');
  2317         assert(identity->lang[1] >= 'a' && identity->lang[1] <= 'z');
  2318         assert(identity->lang[2] == 0);
  2319     }
  2320 
  2321     if (has_fpr) {
  2322         sqlite3_reset(session->set_pgp_keypair);
  2323         sqlite3_bind_text(session->set_pgp_keypair, 1, identity->fpr, -1,
  2324                 SQLITE_STATIC);
  2325         result = sqlite3_step(session->set_pgp_keypair);
  2326         sqlite3_reset(session->set_pgp_keypair);
  2327         if (result != SQLITE_DONE) {
  2328             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2329             return PEP_CANNOT_SET_PGP_KEYPAIR;
  2330         }
  2331     }
  2332 
  2333     // We do this because there are checks in set_person for
  2334     // aliases, which modify the identity object on return.
  2335     pEp_identity* ident_copy = identity_dup(identity); 
  2336     if (!ident_copy)
  2337         return PEP_OUT_OF_MEMORY;
  2338 
  2339     status = set_person(session, ident_copy, false);
  2340     if (status != PEP_STATUS_OK) {
  2341         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2342         goto pep_free;
  2343     }
  2344 
  2345     status = set_identity_entry(session, ident_copy, false);
  2346     if (status != PEP_STATUS_OK) {
  2347         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2348         goto pep_free;
  2349     }
  2350 
  2351     if (has_fpr) {
  2352         status = _set_trust_internal(session, ident_copy, false);
  2353         if (status != PEP_STATUS_OK) {
  2354             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2355             goto pep_free;
  2356         }
  2357     }
  2358     
  2359     result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  2360     if (result == SQLITE_OK)
  2361         status = PEP_STATUS_OK;
  2362     else
  2363         status = PEP_COMMIT_FAILED;
  2364 
  2365 pep_free:
  2366     free_identity(ident_copy);
  2367     return status;
  2368 }
  2369 
  2370 // This ONLY sets the user flag, and creates a shell identity if necessary.
  2371 PEP_STATUS set_as_pep_user(PEP_SESSION session, pEp_identity* user) {
  2372 
  2373     assert(session);
  2374     assert(user);
  2375     assert(user->address);
  2376     assert(!EMPTYSTR(user->user_id));
  2377         
  2378     if (!session || !user || user->address || EMPTYSTR(user->user_id))
  2379         return PEP_ILLEGAL_VALUE;
  2380             
  2381     PEP_STATUS status = PEP_STATUS_OK;
  2382     
  2383     bool person_exists = false;
  2384     
  2385     status = exists_person(session, user, &person_exists);
  2386     
  2387     if (status != PEP_STATUS_OK)
  2388         return status;
  2389         
  2390     if (!person_exists) {
  2391         if (!user->address)
  2392             return PEP_ILLEGAL_VALUE;
  2393             
  2394         // create shell identity
  2395         pEp_identity* tmp_id = new_identity(user->address, NULL, user->user_id, user->username);
  2396         status = set_identity(session, tmp_id); // this creates the person
  2397         free_identity(tmp_id);
  2398         if (status != PEP_STATUS_OK)
  2399             return status;
  2400     }
  2401         
  2402     // Ok, let's set it.
  2403     sqlite3_reset(session->set_as_pep_user);
  2404     sqlite3_bind_text(session->set_as_pep_user, 1, user->user_id, -1,
  2405             SQLITE_STATIC);
  2406     int result = sqlite3_step(session->set_as_pep_user);
  2407     sqlite3_reset(session->set_as_pep_user);
  2408     
  2409     if (result != SQLITE_DONE)
  2410         return PEP_CANNOT_SET_PERSON;
  2411         
  2412     return PEP_STATUS_OK;    
  2413 }
  2414 
  2415 PEP_STATUS exists_person(PEP_SESSION session, pEp_identity* identity,
  2416                          bool* exists) {            
  2417     
  2418     // const char* user_id,
  2419     //                      char** default_id, bool* exists) {
  2420     assert(session);
  2421     assert(exists);
  2422     assert(identity);
  2423     assert(!EMPTYSTR(identity->user_id));
  2424         
  2425     if (!session || !exists || !identity || EMPTYSTR(identity->user_id))
  2426         return PEP_ILLEGAL_VALUE;
  2427     
  2428     *exists = false;
  2429 
  2430     const char* user_id = identity->user_id;
  2431     char* alias_default = NULL;
  2432     
  2433     PEP_STATUS status = get_userid_alias_default(session, user_id, &alias_default);
  2434     
  2435     if (status == PEP_CANNOT_FIND_ALIAS || EMPTYSTR(alias_default)) {
  2436         sqlite3_reset(session->exists_person);
  2437         sqlite3_bind_text(session->exists_person, 1, user_id, -1,
  2438                 SQLITE_STATIC);
  2439         int result = sqlite3_step(session->exists_person);
  2440         switch (result) {
  2441             case SQLITE_ROW: {
  2442                 // yeah yeah, I know, we could be lazy here, but it looks bad.
  2443                 *exists = (sqlite3_column_int(session->exists_person, 0) != 0);
  2444                 status = PEP_STATUS_OK;
  2445                 break;
  2446             }
  2447             default:
  2448                 return PEP_UNKNOWN_ERROR;
  2449         }
  2450     }
  2451     else if (status == PEP_STATUS_OK) {
  2452         *exists = true; // thank you, delete on cascade!
  2453         // FIXME: Should we correct the userid default here? I think we should.
  2454         free(identity->user_id);
  2455         identity->user_id = alias_default; // ownership transfer
  2456     }
  2457     else
  2458         free(alias_default);
  2459         
  2460     return status;
  2461 }
  2462 
  2463 PEP_STATUS is_pep_user(PEP_SESSION session, pEp_identity *identity, bool* is_pep)
  2464 {
  2465     assert(session);
  2466     assert(is_pep);
  2467     assert(identity);
  2468     assert(!EMPTYSTR(identity->user_id));
  2469 
  2470     if (!session || !is_pep || !identity || EMPTYSTR(identity->user_id))
  2471         return PEP_ILLEGAL_VALUE;
  2472     
  2473     *is_pep = false;
  2474     
  2475     const char* user_id = identity->user_id;
  2476     
  2477     if (!session || EMPTYSTR(user_id))
  2478         return PEP_ILLEGAL_VALUE;
  2479         
  2480     char* alias_default = NULL;
  2481     
  2482     PEP_STATUS status = get_userid_alias_default(session, user_id, &alias_default);
  2483     
  2484     if (status == PEP_CANNOT_FIND_ALIAS || EMPTYSTR(alias_default)) {
  2485         free(alias_default);
  2486         alias_default = strdup(user_id);
  2487     }
  2488     
  2489     sqlite3_reset(session->is_pep_user);
  2490     sqlite3_bind_text(session->is_pep_user, 1, user_id, -1,
  2491             SQLITE_STATIC);
  2492     int result = sqlite3_step(session->is_pep_user);
  2493     switch (result) {
  2494         case SQLITE_ROW: {
  2495             // yeah yeah, I know, we could be lazy here, but it looks bad.
  2496             *is_pep = (sqlite3_column_int(session->is_pep_user, 0) != 0);
  2497             break;
  2498         }
  2499         default:
  2500             free(alias_default);
  2501             return PEP_CANNOT_FIND_PERSON;
  2502     }
  2503 
  2504     return PEP_STATUS_OK;
  2505 }
  2506 
  2507 
  2508 PEP_STATUS remove_fpr_as_default(PEP_SESSION session, 
  2509                                  const char* fpr) 
  2510 {
  2511     assert(fpr);
  2512     
  2513     if (!session || !fpr)
  2514         return PEP_ILLEGAL_VALUE;
  2515             
  2516     sqlite3_reset(session->remove_fpr_as_default);
  2517     sqlite3_bind_text(session->remove_fpr_as_default, 1, fpr, -1,
  2518                       SQLITE_STATIC);
  2519 
  2520     int result = sqlite3_step(session->remove_fpr_as_default);
  2521     sqlite3_reset(session->remove_fpr_as_default);
  2522     
  2523     if (result != SQLITE_DONE)
  2524         return PEP_CANNOT_SET_IDENTITY; // misleading - could also be person
  2525 
  2526     return PEP_STATUS_OK;
  2527 }
  2528 
  2529 
  2530 PEP_STATUS replace_identities_fpr(PEP_SESSION session, 
  2531                                  const char* old_fpr, 
  2532                                  const char* new_fpr) 
  2533 {
  2534     assert(old_fpr);
  2535     assert(new_fpr);
  2536     
  2537     if (!old_fpr || !new_fpr)
  2538         return PEP_ILLEGAL_VALUE;
  2539             
  2540     sqlite3_reset(session->replace_identities_fpr);
  2541     sqlite3_bind_text(session->replace_identities_fpr, 1, new_fpr, -1,
  2542                       SQLITE_STATIC);
  2543     sqlite3_bind_text(session->replace_identities_fpr, 2, old_fpr, -1,
  2544                       SQLITE_STATIC);
  2545 
  2546     int result = sqlite3_step(session->replace_identities_fpr);
  2547     sqlite3_reset(session->replace_identities_fpr);
  2548     
  2549     if (result != SQLITE_DONE)
  2550         return PEP_CANNOT_SET_IDENTITY;
  2551 
  2552     return PEP_STATUS_OK;
  2553 }
  2554 
  2555 PEP_STATUS update_trust_for_fpr(PEP_SESSION session, 
  2556                                 const char* fpr, 
  2557                                 PEP_comm_type comm_type)
  2558 {
  2559     if (!fpr)
  2560         return PEP_ILLEGAL_VALUE;
  2561         
  2562     sqlite3_reset(session->update_trust_for_fpr);
  2563     sqlite3_bind_int(session->update_trust_for_fpr, 1, comm_type);
  2564     sqlite3_bind_text(session->update_trust_for_fpr, 2, fpr, -1,
  2565             SQLITE_STATIC);
  2566     int result = sqlite3_step(session->update_trust_for_fpr);
  2567     sqlite3_reset(session->update_trust_for_fpr);
  2568     if (result != SQLITE_DONE) {
  2569         return PEP_CANNOT_SET_TRUST;
  2570     }
  2571     
  2572     return PEP_STATUS_OK;
  2573 }
  2574 
  2575 DYNAMIC_API PEP_STATUS set_device_group(
  2576         PEP_SESSION session,
  2577         const char *group_name
  2578     )
  2579 {
  2580     int result;
  2581 
  2582     assert(session);
  2583 
  2584     if (!(session && group_name))
  2585         return PEP_ILLEGAL_VALUE;
  2586 
  2587     // 1. Get own user_id
  2588     char* user_id = NULL;
  2589     PEP_STATUS status = get_default_own_userid(session, &user_id);
  2590     
  2591     // No user_id is returned in this case, no need to free;
  2592     if (status != PEP_STATUS_OK)
  2593         return status;
  2594         
  2595     // 2. Set device group
  2596     sqlite3_reset(session->set_device_group);
  2597     if(group_name){
  2598         sqlite3_bind_text(session->set_device_group, 1, group_name, -1,
  2599                 SQLITE_STATIC);
  2600     } else {
  2601         sqlite3_bind_null(session->set_device_group, 1);
  2602     }
  2603     
  2604     sqlite3_bind_text(session->set_device_group, 2, user_id, -1,
  2605             SQLITE_STATIC);
  2606 
  2607     result = sqlite3_step(session->set_device_group);
  2608     sqlite3_reset(session->set_device_group);
  2609     
  2610     free(user_id);
  2611     
  2612     if (result != SQLITE_DONE)
  2613         return PEP_CANNOT_SET_PERSON;
  2614 
  2615     return PEP_STATUS_OK;
  2616 }
  2617 
  2618 DYNAMIC_API PEP_STATUS get_device_group(PEP_SESSION session, char **group_name)
  2619 {
  2620     PEP_STATUS status = PEP_STATUS_OK;
  2621     int result;
  2622 
  2623     assert(session);
  2624     assert(group_name);
  2625 
  2626     if (!(session && group_name))
  2627         return PEP_ILLEGAL_VALUE;
  2628 
  2629     // 1. Get own user_id
  2630     char* user_id = NULL;
  2631     status = get_default_own_userid(session, &user_id);
  2632     
  2633     // No user_id is returned in this case, no need to free;
  2634     if (status != PEP_STATUS_OK)
  2635         return status;
  2636 
  2637     // 2. get device group
  2638     sqlite3_reset(session->get_device_group);
  2639     sqlite3_bind_text(session->get_device_group, 1, user_id, -1,
  2640             SQLITE_STATIC);
  2641 
  2642     result = sqlite3_step(session->get_device_group);
  2643     switch (result) {
  2644     case SQLITE_ROW: {
  2645         const char *_group_name = (const char *)sqlite3_column_text(session->get_device_group, 0);
  2646         if(_group_name){
  2647             *group_name = strdup(_group_name);
  2648                 if(*group_name == NULL)
  2649                     status = PEP_OUT_OF_MEMORY;
  2650         }
  2651         break;
  2652     }
  2653  
  2654     default:
  2655         status = PEP_RECORD_NOT_FOUND;
  2656     }
  2657 
  2658     free(user_id);
  2659     sqlite3_reset(session->get_device_group);
  2660     return status;
  2661 }
  2662 
  2663 DYNAMIC_API PEP_STATUS set_identity_flags(
  2664         PEP_SESSION session,
  2665         pEp_identity *identity,
  2666         unsigned int flags
  2667     )
  2668 {
  2669     int result;
  2670 
  2671     assert(session);
  2672     assert(identity);
  2673     assert(identity->address);
  2674     assert(identity->user_id);
  2675 
  2676     if (!(session && identity && identity->address && identity->user_id))
  2677         return PEP_ILLEGAL_VALUE;
  2678 
  2679     sqlite3_reset(session->set_identity_flags);
  2680     sqlite3_bind_int(session->set_identity_flags, 1, flags);
  2681     sqlite3_bind_text(session->set_identity_flags, 2, identity->address, -1,
  2682             SQLITE_STATIC);
  2683     sqlite3_bind_text(session->set_identity_flags, 3, identity->user_id, -1,
  2684         SQLITE_STATIC);
  2685         
  2686     result = sqlite3_step(session->set_identity_flags);
  2687 
  2688     sqlite3_reset(session->set_identity_flags);
  2689     if (result != SQLITE_DONE)
  2690         return PEP_CANNOT_SET_IDENTITY;
  2691 
  2692     identity->flags |= flags;
  2693     return PEP_STATUS_OK;
  2694 }
  2695 
  2696 DYNAMIC_API PEP_STATUS unset_identity_flags(
  2697         PEP_SESSION session,
  2698         pEp_identity *identity,
  2699         unsigned int flags
  2700     )
  2701 {
  2702     int result;
  2703 
  2704     assert(session);
  2705     assert(identity);
  2706     assert(identity->address);
  2707     assert(identity->user_id);
  2708 
  2709     if (!(session && identity && identity->address && identity->user_id))
  2710         return PEP_ILLEGAL_VALUE;
  2711 
  2712     sqlite3_reset(session->unset_identity_flags);
  2713     sqlite3_bind_int(session->unset_identity_flags, 1, flags);
  2714     sqlite3_bind_text(session->unset_identity_flags, 2, identity->address, -1,
  2715             SQLITE_STATIC);
  2716     sqlite3_bind_text(session->unset_identity_flags, 3, identity->user_id, -1,
  2717             SQLITE_STATIC);
  2718     result = sqlite3_step(session->unset_identity_flags);
  2719     sqlite3_reset(session->unset_identity_flags);
  2720     if (result != SQLITE_DONE)
  2721         return PEP_CANNOT_SET_IDENTITY;
  2722         identity->flags &= ~flags;
  2723 
  2724     return PEP_STATUS_OK;
  2725 }
  2726 
  2727 
  2728 PEP_STATUS replace_userid(PEP_SESSION session, const char* old_uid,
  2729                               const char* new_uid) {
  2730     assert(session);
  2731     assert(old_uid);
  2732     assert(new_uid);
  2733     
  2734     if (!session || !old_uid || !new_uid)
  2735         return PEP_ILLEGAL_VALUE;
  2736 
  2737 
  2738     int result;
  2739 
  2740     sqlite3_reset(session->replace_userid);
  2741     sqlite3_bind_text(session->replace_userid, 1, new_uid, -1,
  2742             SQLITE_STATIC);
  2743     sqlite3_bind_text(session->replace_userid, 2, old_uid, -1,
  2744             SQLITE_STATIC);
  2745     result = sqlite3_step(session->replace_userid);
  2746     sqlite3_reset(session->replace_userid);
  2747     if (result != SQLITE_DONE)
  2748         return PEP_CANNOT_SET_PERSON; // May need clearer retval
  2749 
  2750     return PEP_STATUS_OK;
  2751 }
  2752 
  2753 PEP_STATUS refresh_userid_default_key(PEP_SESSION session, const char* user_id) {
  2754     assert(session);
  2755     assert(user_id);
  2756     
  2757     if (!session || !user_id)
  2758         return PEP_ILLEGAL_VALUE;
  2759 
  2760     int result;
  2761 
  2762     sqlite3_reset(session->refresh_userid_default_key);
  2763     sqlite3_bind_text(session->refresh_userid_default_key, 1, user_id, -1,
  2764             SQLITE_STATIC);
  2765     result = sqlite3_step(session->refresh_userid_default_key);
  2766     sqlite3_reset(session->refresh_userid_default_key);
  2767     if (result != SQLITE_DONE)
  2768         return PEP_CANNOT_SET_PERSON;
  2769 
  2770     return PEP_STATUS_OK;    
  2771 }
  2772 
  2773 PEP_STATUS replace_main_user_fpr(PEP_SESSION session, const char* user_id,
  2774                                  const char* new_fpr) {
  2775     assert(session);
  2776     assert(user_id);
  2777     assert(new_fpr);
  2778     
  2779     if (!session || !user_id || !new_fpr)
  2780         return PEP_ILLEGAL_VALUE;
  2781 
  2782     int result;
  2783 
  2784     sqlite3_reset(session->replace_main_user_fpr);
  2785     sqlite3_bind_text(session->replace_main_user_fpr, 1, new_fpr, -1,
  2786             SQLITE_STATIC);
  2787     sqlite3_bind_text(session->replace_main_user_fpr, 2, user_id, -1,
  2788             SQLITE_STATIC);
  2789     result = sqlite3_step(session->replace_main_user_fpr);
  2790     sqlite3_reset(session->replace_main_user_fpr);
  2791     if (result != SQLITE_DONE)
  2792         return PEP_CANNOT_SET_PERSON;
  2793 
  2794     return PEP_STATUS_OK;
  2795 }
  2796 
  2797 PEP_STATUS get_main_user_fpr(PEP_SESSION session, 
  2798                              const char* user_id,
  2799                              char** main_fpr)
  2800 {
  2801     PEP_STATUS status = PEP_STATUS_OK;
  2802     int result;
  2803     
  2804     assert(session);
  2805     assert(user_id);
  2806     assert(main_fpr);
  2807     
  2808     if (!(session && user_id && user_id[0] && main_fpr))
  2809         return PEP_ILLEGAL_VALUE;
  2810         
  2811     *main_fpr = NULL;
  2812     
  2813     sqlite3_reset(session->get_main_user_fpr);
  2814     sqlite3_bind_text(session->get_main_user_fpr, 1, user_id, -1,
  2815                       SQLITE_STATIC);
  2816     result = sqlite3_step(session->get_main_user_fpr);
  2817     switch (result) {
  2818     case SQLITE_ROW: {
  2819         const char* _fpr = 
  2820             (const char *) sqlite3_column_text(session->get_main_user_fpr, 0);
  2821         if (_fpr)
  2822             *main_fpr = strdup(_fpr);
  2823         if (!(*main_fpr))
  2824             status = PEP_OUT_OF_MEMORY;
  2825         break;
  2826     }
  2827     default:
  2828         status = PEP_CANNOT_FIND_PERSON;
  2829     }
  2830 
  2831     sqlite3_reset(session->get_main_user_fpr);
  2832     return status;
  2833 }
  2834 
  2835 
  2836 DYNAMIC_API PEP_STATUS mark_as_compromized(
  2837         PEP_SESSION session,
  2838         const char *fpr
  2839     )
  2840 {
  2841     int result;
  2842 
  2843     assert(session);
  2844     assert(fpr && fpr[0]);
  2845 
  2846     if (!(session && fpr && fpr[0]))
  2847         return PEP_ILLEGAL_VALUE;
  2848 
  2849     sqlite3_reset(session->mark_compromized);
  2850     sqlite3_bind_text(session->mark_compromized, 1, fpr, -1,
  2851             SQLITE_STATIC);
  2852     result = sqlite3_step(session->mark_compromized);
  2853     sqlite3_reset(session->mark_compromized);
  2854 
  2855     if (result != SQLITE_DONE)
  2856         return PEP_CANNOT_SET_TRUST;
  2857 
  2858     return PEP_STATUS_OK;
  2859 }
  2860 
  2861 void pEp_free(void *p)
  2862 {
  2863     free(p);
  2864 }
  2865 
  2866 
  2867 DYNAMIC_API PEP_STATUS get_trust(PEP_SESSION session, pEp_identity *identity)
  2868 {
  2869     PEP_STATUS status = PEP_STATUS_OK;
  2870     int result;
  2871 
  2872     // We need to be able to test that we break correctly without shutting
  2873     // asserts off everywhere.
  2874     // assert(session);
  2875     // assert(identity);
  2876     // assert(identity->user_id);
  2877     // assert(identity->user_id[0]);
  2878     // assert(identity->fpr);
  2879     // assert(identity->fpr[0]);
  2880 
  2881     if (!(session && identity && identity->user_id && identity->user_id[0] &&
  2882                 identity->fpr && identity->fpr[0]))
  2883         return PEP_ILLEGAL_VALUE;
  2884 
  2885     identity->comm_type = PEP_ct_unknown;
  2886 
  2887     sqlite3_reset(session->get_trust);
  2888     sqlite3_bind_text(session->get_trust, 1, identity->user_id, -1,
  2889             SQLITE_STATIC);
  2890     sqlite3_bind_text(session->get_trust, 2, identity->fpr, -1, SQLITE_STATIC);
  2891 
  2892     result = sqlite3_step(session->get_trust);
  2893     switch (result) {
  2894     case SQLITE_ROW: {
  2895         int comm_type = (PEP_comm_type) sqlite3_column_int(session->get_trust,
  2896                 0);
  2897         identity->comm_type = comm_type;
  2898         break;
  2899     }
  2900  
  2901     default:
  2902         status = PEP_CANNOT_FIND_IDENTITY;
  2903     }
  2904 
  2905     sqlite3_reset(session->get_trust);
  2906     return status;
  2907 }
  2908 
  2909 DYNAMIC_API PEP_STATUS least_trust(
  2910         PEP_SESSION session,
  2911         const char *fpr,
  2912         PEP_comm_type *comm_type
  2913     )
  2914 {
  2915     PEP_STATUS status = PEP_STATUS_OK;
  2916     int result;
  2917 
  2918     assert(session);
  2919     assert(fpr);
  2920     assert(comm_type);
  2921 
  2922     if (!(session && fpr && comm_type))
  2923         return PEP_ILLEGAL_VALUE;
  2924 
  2925     *comm_type = PEP_ct_unknown;
  2926 
  2927     sqlite3_reset(session->least_trust);
  2928     sqlite3_bind_text(session->least_trust, 1, fpr, -1, SQLITE_STATIC);
  2929 
  2930     result = sqlite3_step(session->least_trust);
  2931     switch (result) {
  2932         case SQLITE_ROW: {
  2933             int _comm_type = sqlite3_column_int(session->least_trust, 0);
  2934             *comm_type = (PEP_comm_type) _comm_type;
  2935             break;
  2936         }
  2937         default:
  2938             // never reached because of sql min()
  2939             status = PEP_CANNOT_FIND_IDENTITY;
  2940     }
  2941 
  2942     sqlite3_reset(session->least_trust);
  2943     return status;
  2944 }
  2945 
  2946 DYNAMIC_API PEP_STATUS decrypt_and_verify(
  2947     PEP_SESSION session, const char *ctext, size_t csize,
  2948     const char *dsigtext, size_t dsigsize,
  2949     char **ptext, size_t *psize, stringlist_t **keylist
  2950     )
  2951 {
  2952     assert(session);
  2953     assert(ctext);
  2954     assert(csize);
  2955     assert(ptext);
  2956     assert(psize);
  2957     assert(keylist);
  2958 
  2959     if (!(session && ctext && csize && ptext && psize && keylist))
  2960         return PEP_ILLEGAL_VALUE;
  2961 
  2962     return session->cryptotech[PEP_crypt_OpenPGP].decrypt_and_verify(
  2963             session, ctext, csize, dsigtext, dsigsize, ptext, psize, keylist);
  2964 }
  2965 
  2966 DYNAMIC_API PEP_STATUS encrypt_and_sign(
  2967     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  2968     size_t psize, char **ctext, size_t *csize
  2969     )
  2970 {
  2971     assert(session);
  2972     assert(keylist);
  2973     assert(ptext);
  2974     assert(psize);
  2975     assert(ctext);
  2976     assert(csize);
  2977 
  2978     if (!(session && keylist && ptext && psize && ctext && csize))
  2979         return PEP_ILLEGAL_VALUE;
  2980 
  2981     return session->cryptotech[PEP_crypt_OpenPGP].encrypt_and_sign(session,
  2982             keylist, ptext, psize, ctext, csize);
  2983 }
  2984 
  2985 PEP_STATUS encrypt_only(
  2986     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  2987     size_t psize, char **ctext, size_t *csize
  2988     )
  2989 {
  2990     assert(session);
  2991     assert(keylist);
  2992     assert(ptext);
  2993     assert(psize);
  2994     assert(ctext);
  2995     assert(csize);
  2996 
  2997     if (!(session && keylist && ptext && psize && ctext && csize))
  2998         return PEP_ILLEGAL_VALUE;
  2999 
  3000     return session->cryptotech[PEP_crypt_OpenPGP].encrypt_only(session,
  3001             keylist, ptext, psize, ctext, csize);
  3002 }
  3003 
  3004 
  3005 DYNAMIC_API PEP_STATUS verify_text(
  3006     PEP_SESSION session, const char *text, size_t size,
  3007     const char *signature, size_t sig_size, stringlist_t **keylist
  3008     )
  3009 {
  3010     assert(session);
  3011     assert(text);
  3012     assert(size);
  3013     assert(signature);
  3014     assert(sig_size);
  3015     assert(keylist);
  3016 
  3017     if (!(session && text && size && signature && sig_size && keylist))
  3018         return PEP_ILLEGAL_VALUE;
  3019 
  3020     return session->cryptotech[PEP_crypt_OpenPGP].verify_text(session, text,
  3021             size, signature, sig_size, keylist);
  3022 }
  3023 
  3024 DYNAMIC_API PEP_STATUS delete_keypair(PEP_SESSION session, const char *fpr)
  3025 {
  3026     assert(session);
  3027     assert(fpr);
  3028 
  3029     if (!(session && fpr))
  3030         return PEP_ILLEGAL_VALUE;
  3031 
  3032     return session->cryptotech[PEP_crypt_OpenPGP].delete_keypair(session, fpr);
  3033 }
  3034 
  3035 DYNAMIC_API PEP_STATUS export_key(
  3036         PEP_SESSION session, const char *fpr, char **key_data, size_t *size
  3037     )
  3038 {
  3039     assert(session);
  3040     assert(fpr);
  3041     assert(key_data);
  3042     assert(size);
  3043 
  3044     if (!(session && fpr && key_data && size))
  3045         return PEP_ILLEGAL_VALUE;
  3046 
  3047     return session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr,
  3048             key_data, size, false);
  3049 }
  3050 
  3051 DYNAMIC_API PEP_STATUS export_secrect_key(
  3052         PEP_SESSION session, const char *fpr, char **key_data, size_t *size
  3053     )
  3054 {
  3055     assert(session);
  3056     assert(fpr);
  3057     assert(key_data);
  3058     assert(size);
  3059 
  3060     if (!(session && fpr && key_data && size))
  3061         return PEP_ILLEGAL_VALUE;
  3062 
  3063     // don't accept key IDs but full fingerprints only
  3064     if (strlen(fpr) < 16)
  3065         return PEP_ILLEGAL_VALUE;
  3066 
  3067     return session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr,
  3068             key_data, size, true);
  3069 }
  3070 
  3071 DYNAMIC_API PEP_STATUS find_keys(
  3072         PEP_SESSION session, const char *pattern, stringlist_t **keylist
  3073     )
  3074 {
  3075     assert(session);
  3076     assert(pattern);
  3077     assert(keylist);
  3078 
  3079     if (!(session && pattern && keylist))
  3080         return PEP_ILLEGAL_VALUE;
  3081 
  3082     return session->cryptotech[PEP_crypt_OpenPGP].find_keys(session, pattern,
  3083             keylist);
  3084 }
  3085 
  3086 
  3087 DYNAMIC_API PEP_STATUS generate_keypair(
  3088         PEP_SESSION session, pEp_identity *identity
  3089     )
  3090 {
  3091     assert(session);
  3092     assert(identity);
  3093     assert(identity->address);
  3094     assert(identity->fpr == NULL || identity->fpr[0] == 0);
  3095     assert(identity->username);
  3096 
  3097     if (!(session && identity && identity->address &&
  3098             (identity->fpr == NULL || identity->fpr[0] == 0) &&
  3099             identity->username))
  3100         return PEP_ILLEGAL_VALUE;
  3101 
  3102     PEP_STATUS status =
  3103         session->cryptotech[PEP_crypt_OpenPGP].generate_keypair(session,
  3104                 identity);
  3105     if (status != PEP_STATUS_OK)
  3106         return status;
  3107 
  3108     if (identity->fpr)
  3109         status = set_pgp_keypair(session, identity->fpr);
  3110 
  3111     // add to known keypair DB, as this might not end up being a default
  3112     return status;
  3113 }
  3114 
  3115 DYNAMIC_API PEP_STATUS get_key_rating(
  3116         PEP_SESSION session,
  3117         const char *fpr,
  3118         PEP_comm_type *comm_type
  3119     )
  3120 {
  3121     assert(session);
  3122     assert(fpr);
  3123     assert(comm_type);
  3124 
  3125     if (!(session && fpr && comm_type))
  3126         return PEP_ILLEGAL_VALUE;
  3127 
  3128     return session->cryptotech[PEP_crypt_OpenPGP].get_key_rating(session, fpr,
  3129             comm_type);
  3130 }
  3131 
  3132 DYNAMIC_API PEP_STATUS import_key(
  3133         PEP_SESSION session,
  3134         const char *key_data,
  3135         size_t size,
  3136         identity_list **private_keys
  3137     )
  3138 {
  3139     assert(session);
  3140     assert(key_data);
  3141 
  3142     if (!(session && key_data))
  3143         return PEP_ILLEGAL_VALUE;
  3144 
  3145     return session->cryptotech[PEP_crypt_OpenPGP].import_key(session, key_data,
  3146             size, private_keys);
  3147 }
  3148 
  3149 DYNAMIC_API PEP_STATUS recv_key(PEP_SESSION session, const char *pattern)
  3150 {
  3151     assert(session);
  3152     assert(pattern);
  3153 
  3154     if (!(session && pattern))
  3155         return PEP_ILLEGAL_VALUE;
  3156 
  3157     return session->cryptotech[PEP_crypt_OpenPGP].recv_key(session, pattern);
  3158 }
  3159 
  3160 DYNAMIC_API PEP_STATUS send_key(PEP_SESSION session, const char *pattern)
  3161 {
  3162     assert(session);
  3163     assert(pattern);
  3164 
  3165     if (!(session && pattern))
  3166         return PEP_ILLEGAL_VALUE;
  3167 
  3168     return session->cryptotech[PEP_crypt_OpenPGP].send_key(session, pattern);
  3169 }
  3170 
  3171 DYNAMIC_API PEP_STATUS renew_key(
  3172         PEP_SESSION session,
  3173         const char *fpr,
  3174         const timestamp *ts
  3175     )
  3176 {
  3177     assert(session);
  3178     assert(fpr);
  3179 
  3180     if (!(session && fpr))
  3181         return PEP_ILLEGAL_VALUE;
  3182 
  3183     return session->cryptotech[PEP_crypt_OpenPGP].renew_key(session, fpr, ts);
  3184 }
  3185 
  3186 DYNAMIC_API PEP_STATUS revoke_key(
  3187         PEP_SESSION session,
  3188         const char *fpr,
  3189         const char *reason
  3190     )
  3191 {
  3192     assert(session);
  3193     assert(fpr);
  3194 
  3195     if (!(session && fpr))
  3196         return PEP_ILLEGAL_VALUE;
  3197 
  3198     return session->cryptotech[PEP_crypt_OpenPGP].revoke_key(session, fpr,
  3199             reason);
  3200 }
  3201 
  3202 DYNAMIC_API PEP_STATUS key_expired(
  3203         PEP_SESSION session,
  3204         const char *fpr,
  3205         const time_t when,
  3206         bool *expired
  3207     )
  3208 {
  3209     assert(session);
  3210     assert(fpr);
  3211     assert(expired);
  3212 
  3213     if (!(session && fpr && expired))
  3214         return PEP_ILLEGAL_VALUE;
  3215 
  3216     return session->cryptotech[PEP_crypt_OpenPGP].key_expired(session, fpr,
  3217             when, expired);
  3218 }
  3219 
  3220 DYNAMIC_API PEP_STATUS key_revoked(
  3221        PEP_SESSION session,
  3222        const char *fpr,
  3223        bool *revoked
  3224    )
  3225 {
  3226     assert(session);
  3227     assert(fpr);
  3228     assert(revoked);
  3229     
  3230     if (!(session && fpr && revoked))
  3231         return PEP_ILLEGAL_VALUE;
  3232     
  3233     return session->cryptotech[PEP_crypt_OpenPGP].key_revoked(session, fpr,
  3234             revoked);
  3235 }
  3236 
  3237 static void _clean_log_value(char *text)
  3238 {
  3239     if (text) {
  3240         for (char *c = text; *c; c++) {
  3241             if (*c < 32 && *c != '\n')
  3242                 *c = 32;
  3243             else if (*c == '"')
  3244                 *c = '\'';
  3245         }
  3246     }
  3247 }
  3248 
  3249 static char *_concat_string(char *str1, const char *str2, char delim)
  3250 {
  3251     str2 = str2 ? str2 : "";
  3252     size_t len1 = str1 ? strlen(str1) : 0;
  3253     size_t len2 = strlen(str2);
  3254     size_t len = len1 + len2 + 3;
  3255     char * result = realloc(str1, len + 1);
  3256 
  3257     if (result) {
  3258         result[len1] = '"';
  3259         strcpy(result + len1 + 1, str2);
  3260         result[len - 2] = '"';
  3261         result[len - 1] = delim;
  3262         result[len] = 0;
  3263     }
  3264     else {
  3265         free(str1);
  3266     }
  3267 
  3268     return result;
  3269 }
  3270 
  3271 DYNAMIC_API PEP_STATUS get_crashdump_log(
  3272         PEP_SESSION session,
  3273         int maxlines,
  3274         char **logdata
  3275     )
  3276 {
  3277     PEP_STATUS status = PEP_STATUS_OK;
  3278     char *_logdata= NULL;
  3279 
  3280     assert(session);
  3281     assert(maxlines >= 0 && maxlines <= CRASHDUMP_MAX_LINES);
  3282     assert(logdata);
  3283 
  3284     if (!(session && logdata && maxlines >= 0 && maxlines <=
  3285             CRASHDUMP_MAX_LINES))
  3286         return PEP_ILLEGAL_VALUE;
  3287 
  3288     *logdata = NULL;
  3289 
  3290     int limit = maxlines ? maxlines : CRASHDUMP_DEFAULT_LINES;
  3291     const char *timestamp = NULL;
  3292     const char *title = NULL;
  3293     const char *entity = NULL;
  3294     const char *desc = NULL;
  3295     const char *comment = NULL;
  3296 
  3297     sqlite3_reset(session->crashdump);
  3298     sqlite3_bind_int(session->crashdump, 1, limit);
  3299 
  3300     int result;
  3301 
  3302     do {
  3303         result = sqlite3_step(session->crashdump);
  3304         switch (result) {
  3305         case SQLITE_ROW:
  3306             timestamp = (const char *) sqlite3_column_text(session->crashdump,
  3307                     0);
  3308             title   = (const char *) sqlite3_column_text(session->crashdump,
  3309                     1);
  3310             entity  = (const char *) sqlite3_column_text(session->crashdump,
  3311                     2);
  3312             desc    = (const char *) sqlite3_column_text(session->crashdump,
  3313                     3);
  3314             comment = (const char *) sqlite3_column_text(session->crashdump,
  3315                     4);
  3316 
  3317             _logdata = _concat_string(_logdata, timestamp, ',');
  3318             if (_logdata == NULL)
  3319                 goto enomem;
  3320 
  3321             _logdata = _concat_string(_logdata, title, ',');
  3322             if (_logdata == NULL)
  3323                 goto enomem;
  3324 
  3325             _logdata = _concat_string(_logdata, entity, ',');
  3326             if (_logdata == NULL)
  3327                 goto enomem;
  3328 
  3329             _logdata = _concat_string(_logdata, desc, ',');
  3330             if (_logdata == NULL)
  3331                 goto enomem;
  3332 
  3333             _logdata = _concat_string(_logdata, comment, '\n');
  3334             if (_logdata == NULL)
  3335                 goto enomem;
  3336 
  3337             _clean_log_value(_logdata);
  3338             break;
  3339 
  3340         case SQLITE_DONE:
  3341             break;
  3342 
  3343         default:
  3344             status = PEP_UNKNOWN_ERROR;
  3345             result = SQLITE_DONE;
  3346         }
  3347     } while (result != SQLITE_DONE);
  3348 
  3349     sqlite3_reset(session->crashdump);
  3350     if (status == PEP_STATUS_OK)
  3351         *logdata = _logdata;
  3352 
  3353     goto the_end;
  3354 
  3355 enomem:
  3356     status = PEP_OUT_OF_MEMORY;
  3357 
  3358 the_end:
  3359     return ADD_TO_LOG(status);
  3360 }
  3361 
  3362 DYNAMIC_API PEP_STATUS get_languagelist(
  3363         PEP_SESSION session,
  3364         char **languages
  3365     )
  3366 {
  3367     PEP_STATUS status = PEP_STATUS_OK;
  3368     char *_languages= NULL;
  3369 
  3370     assert(session);
  3371     assert(languages);
  3372 
  3373     if (!(session && languages))
  3374         return PEP_ILLEGAL_VALUE;
  3375 
  3376     *languages = NULL;
  3377 
  3378     const char *lang = NULL;
  3379     const char *name = NULL;
  3380     const char *phrase = NULL;
  3381 
  3382     sqlite3_reset(session->languagelist);
  3383 
  3384     int result;
  3385 
  3386     do {
  3387         result = sqlite3_step(session->languagelist);
  3388         switch (result) {
  3389         case SQLITE_ROW:
  3390             lang = (const char *) sqlite3_column_text(session->languagelist,
  3391                     0);
  3392             name = (const char *) sqlite3_column_text(session->languagelist,
  3393                     1);
  3394             phrase = (const char *) sqlite3_column_text(session->languagelist,
  3395                     2);
  3396 
  3397             _languages = _concat_string(_languages, lang, ',');
  3398             if (_languages == NULL)
  3399                 goto enomem;
  3400 
  3401             _languages = _concat_string(_languages, name, ',');
  3402             if (_languages == NULL)
  3403                 goto enomem;
  3404 
  3405             _languages = _concat_string(_languages, phrase, '\n');
  3406             if (_languages == NULL)
  3407                 goto enomem;
  3408 
  3409             break;
  3410 
  3411         case SQLITE_DONE:
  3412             break;
  3413 
  3414         default:
  3415             status = PEP_UNKNOWN_ERROR;
  3416             result = SQLITE_DONE;
  3417         }
  3418     } while (result != SQLITE_DONE);
  3419 
  3420     sqlite3_reset(session->languagelist);
  3421     if (status == PEP_STATUS_OK)
  3422         *languages = _languages;
  3423 
  3424     goto the_end;
  3425 
  3426 enomem:
  3427     status = PEP_OUT_OF_MEMORY;
  3428 
  3429 the_end:
  3430     return status;
  3431 }
  3432 
  3433 DYNAMIC_API PEP_STATUS get_phrase(
  3434         PEP_SESSION session,
  3435         const char *lang,
  3436         int phrase_id,
  3437         char **phrase
  3438     )
  3439 {
  3440     PEP_STATUS status = PEP_STATUS_OK;
  3441 
  3442     assert(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase);
  3443     if (!(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase))
  3444         return PEP_ILLEGAL_VALUE;
  3445 
  3446     *phrase = NULL;
  3447 
  3448     sqlite3_reset(session->i18n_token);
  3449     sqlite3_bind_text(session->i18n_token, 1, lang, -1, SQLITE_STATIC);
  3450     sqlite3_bind_int(session->i18n_token, 2, phrase_id);
  3451 
  3452     const char *_phrase = NULL;
  3453     int result;
  3454 
  3455     result = sqlite3_step(session->i18n_token);
  3456     switch (result) {
  3457     case SQLITE_ROW:
  3458         _phrase = (const char *) sqlite3_column_text(session->i18n_token, 0);
  3459         break;
  3460 
  3461     case SQLITE_DONE:
  3462         status = PEP_PHRASE_NOT_FOUND;
  3463         break;
  3464 
  3465     default:
  3466         status = PEP_UNKNOWN_ERROR;
  3467     }
  3468 
  3469     if (status == PEP_STATUS_OK) {
  3470         *phrase = strdup(_phrase);
  3471         if (*phrase == NULL)
  3472             goto enomem;
  3473     }
  3474 
  3475     sqlite3_reset(session->i18n_token);
  3476     goto the_end;
  3477 
  3478 enomem:
  3479     status = PEP_OUT_OF_MEMORY;
  3480 
  3481 the_end:
  3482     return status;
  3483 }
  3484 
  3485 static PEP_STATUS _get_sequence_value(PEP_SESSION session, const char *name,
  3486         int32_t *value)
  3487 {
  3488     assert(session && name && value);
  3489     if (!(session && name && value))
  3490         return PEP_ILLEGAL_VALUE;
  3491 
  3492     PEP_STATUS status = PEP_STATUS_OK;
  3493 
  3494     sqlite3_reset(session->sequence_value2);
  3495     sqlite3_bind_text(session->sequence_value2, 1, name, -1,
  3496             SQLITE_STATIC);
  3497     int result = sqlite3_step(session->sequence_value2);
  3498     switch (result) {
  3499         case SQLITE_ROW: {
  3500             int32_t _value = (int32_t)
  3501                     sqlite3_column_int(session->sequence_value2, 0);
  3502             int _own = (int)
  3503                     sqlite3_column_int(session->sequence_value2, 1);
  3504             *value = _value;
  3505             if (_own)
  3506                 status = PEP_OWN_SEQUENCE;
  3507             break;
  3508         }
  3509         case SQLITE_DONE:
  3510             status = PEP_RECORD_NOT_FOUND;
  3511             break;
  3512         default:
  3513             status = PEP_UNKNOWN_ERROR;
  3514     }
  3515     sqlite3_reset(session->sequence_value2);
  3516 
  3517     return status;
  3518 }
  3519 
  3520 static PEP_STATUS _increment_sequence_value(PEP_SESSION session,
  3521         const char *name, int own)
  3522 {
  3523     assert(session && name);
  3524     if (!(session && name))
  3525         return PEP_ILLEGAL_VALUE;
  3526 
  3527     sqlite3_reset(session->sequence_value1);
  3528     sqlite3_bind_text(session->sequence_value1, 1, name, -1, SQLITE_STATIC);
  3529     sqlite3_bind_int(session->sequence_value1, 2, own);
  3530     int result = sqlite3_step(session->sequence_value1);
  3531     assert(result == SQLITE_DONE);
  3532     sqlite3_reset(session->sequence_value1);
  3533     if (result == SQLITE_DONE)
  3534         return PEP_STATUS_OK;
  3535     else
  3536         return PEP_CANNOT_INCREASE_SEQUENCE;
  3537 }
  3538 
  3539 static PEP_STATUS _set_sequence_value(PEP_SESSION session,
  3540         const char *name, int32_t value, int own)
  3541 {
  3542     assert(session && name && value > 0);
  3543     if (!(session && name && value > 0))
  3544         return PEP_ILLEGAL_VALUE;
  3545 
  3546     sqlite3_reset(session->sequence_value3);
  3547     sqlite3_bind_text(session->sequence_value3, 1, name, -1, SQLITE_STATIC);
  3548     sqlite3_bind_int(session->sequence_value3, 2, value);
  3549     sqlite3_bind_int(session->sequence_value3, 3, own);
  3550     int result = sqlite3_step(session->sequence_value3);
  3551     assert(result == SQLITE_DONE);
  3552     sqlite3_reset(session->sequence_value3);
  3553     if (result == SQLITE_DONE)
  3554         return PEP_STATUS_OK;
  3555     else
  3556         return PEP_CANNOT_SET_SEQUENCE_VALUE;
  3557 }
  3558 
  3559 DYNAMIC_API PEP_STATUS sequence_value(
  3560         PEP_SESSION session,
  3561         char *name,
  3562         int32_t *value
  3563     )
  3564 {
  3565     PEP_STATUS status = PEP_STATUS_OK;
  3566     int result;
  3567 
  3568     assert(session);
  3569     assert(name && value && *value >= 0);
  3570 
  3571     if (!(session && name && value && *value >= 0))
  3572         return PEP_ILLEGAL_VALUE;
  3573 
  3574     int own = 0;
  3575     if (!name[0]) {
  3576         pEpUUID uuid;
  3577         uuid_generate_random(uuid);
  3578         uuid_unparse_upper(uuid, name);
  3579         own = 1;
  3580     }
  3581     else {
  3582         if (name == session->sync_session->sync_uuid || 
  3583             strcmp(name, session->sync_session->sync_uuid) == 0)
  3584             own = 1;
  3585     }
  3586 
  3587     if (*value) {
  3588         sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  3589         int32_t old_value = 0;
  3590         status = _get_sequence_value(session, name, &old_value);
  3591         if (status != PEP_STATUS_OK && status != PEP_RECORD_NOT_FOUND)
  3592         {
  3593             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3594             return status;
  3595         }
  3596 
  3597         if (old_value >= *value) {
  3598             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3599             return PEP_SEQUENCE_VIOLATED;
  3600         }
  3601         else {
  3602             status = _set_sequence_value(session, name, *value, own);
  3603             if (status == PEP_STATUS_OK) {
  3604                 result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  3605                 if (result == SQLITE_OK)
  3606                     return PEP_STATUS_OK;
  3607                 else
  3608                     return PEP_COMMIT_FAILED;
  3609             } else {
  3610                 sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3611                 return status;
  3612             }
  3613         }
  3614     }
  3615 
  3616     assert(*value == 0);
  3617     sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  3618     status = _increment_sequence_value(session, name, own);
  3619     if (status == PEP_STATUS_OK) {
  3620         status = _get_sequence_value(session, name, value);
  3621     }
  3622     if (status == PEP_STATUS_OK || status == PEP_OWN_SEQUENCE) {
  3623         result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  3624         if (result == SQLITE_OK){
  3625             assert(*value < INT32_MAX);
  3626             if (*value == INT32_MAX){
  3627                 return PEP_CANNOT_INCREASE_SEQUENCE;
  3628             }
  3629             return status;
  3630         } else {
  3631             return PEP_COMMIT_FAILED;
  3632         }
  3633     } else {
  3634         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3635         return status;
  3636     }
  3637     return status;
  3638 }
  3639 
  3640 DYNAMIC_API PEP_STATUS set_revoked(
  3641        PEP_SESSION session,
  3642        const char *revoked_fpr,
  3643        const char *replacement_fpr,
  3644        const uint64_t revocation_date
  3645     )
  3646 {
  3647     PEP_STATUS status = PEP_STATUS_OK;
  3648     
  3649     assert(session &&
  3650            revoked_fpr && revoked_fpr[0] &&
  3651            replacement_fpr && replacement_fpr[0]
  3652           );
  3653     
  3654     if (!(session &&
  3655           revoked_fpr && revoked_fpr[0] &&
  3656           replacement_fpr && replacement_fpr[0]
  3657          ))
  3658         return PEP_ILLEGAL_VALUE;
  3659     
  3660     sqlite3_reset(session->set_revoked);
  3661     sqlite3_bind_text(session->set_revoked, 1, revoked_fpr, -1, SQLITE_STATIC);
  3662     sqlite3_bind_text(session->set_revoked, 2, replacement_fpr, -1,
  3663             SQLITE_STATIC);
  3664     sqlite3_bind_int64(session->set_revoked, 3, revocation_date);
  3665 
  3666     int result;
  3667     
  3668     result = sqlite3_step(session->set_revoked);
  3669     switch (result) {
  3670         case SQLITE_DONE:
  3671             status = PEP_STATUS_OK;
  3672             break;
  3673             
  3674         default:
  3675             status = PEP_UNKNOWN_ERROR;
  3676     }
  3677     
  3678     sqlite3_reset(session->set_revoked);
  3679     return status;
  3680 }
  3681 
  3682 DYNAMIC_API PEP_STATUS get_revoked(
  3683         PEP_SESSION session,
  3684         const char *fpr,
  3685         char **revoked_fpr,
  3686         uint64_t *revocation_date
  3687     )
  3688 {
  3689     PEP_STATUS status = PEP_STATUS_OK;
  3690 
  3691     assert(session &&
  3692            revoked_fpr &&
  3693            fpr && fpr[0]
  3694           );
  3695     
  3696     if (!(session &&
  3697            revoked_fpr &&
  3698            fpr && fpr[0]
  3699           ))
  3700         return PEP_ILLEGAL_VALUE;
  3701 
  3702     *revoked_fpr = NULL;
  3703     *revocation_date = 0;
  3704 
  3705     sqlite3_reset(session->get_revoked);
  3706     sqlite3_bind_text(session->get_revoked, 1, fpr, -1, SQLITE_STATIC);
  3707 
  3708     int result;
  3709     
  3710     result = sqlite3_step(session->get_revoked);
  3711     switch (result) {
  3712         case SQLITE_ROW: {
  3713             *revoked_fpr = strdup((const char *)
  3714                     sqlite3_column_text(session->get_revoked, 0));
  3715             if(*revoked_fpr)
  3716                 *revocation_date = sqlite3_column_int64(session->get_revoked,
  3717                         1);
  3718             else
  3719                 status = PEP_OUT_OF_MEMORY;
  3720 
  3721             break;
  3722         }
  3723         default:
  3724             status = PEP_CANNOT_FIND_IDENTITY;
  3725     }
  3726 
  3727     sqlite3_reset(session->get_revoked);
  3728 
  3729     return status;
  3730 }
  3731 
  3732 PEP_STATUS key_created(
  3733         PEP_SESSION session,
  3734         const char *fpr,
  3735         time_t *created
  3736     )
  3737 {
  3738     assert(session && fpr && created);
  3739     if (!(session && fpr && created))
  3740         return PEP_ILLEGAL_VALUE;
  3741 
  3742     return session->cryptotech[PEP_crypt_OpenPGP].key_created(session, fpr,
  3743             created);
  3744 }
  3745 
  3746 PEP_STATUS find_private_keys(PEP_SESSION session, const char* pattern,
  3747                              stringlist_t **keylist) {
  3748     assert(session && keylist);
  3749     if (!(session && keylist))
  3750         return PEP_ILLEGAL_VALUE;
  3751     
  3752     return session->cryptotech[PEP_crypt_OpenPGP].find_private_keys(session, pattern,
  3753                                                                     keylist);
  3754 }
  3755 
  3756 PEP_STATUS import_trusted_own_keys(PEP_SESSION session) {
  3757     assert(session);
  3758     if (!session)
  3759         return PEP_ILLEGAL_VALUE;
  3760         
  3761     return session->cryptotech[PEP_crypt_OpenPGP].import_trusted_own_keys(session); 
  3762 }
  3763 
  3764 DYNAMIC_API const char* get_engine_version() {
  3765     return PEP_ENGINE_VERSION;
  3766 }
  3767 
  3768 
  3769 DYNAMIC_API PEP_STATUS reset_peptest_hack(PEP_SESSION session)
  3770 {
  3771     assert(session);
  3772 
  3773     if (!session)
  3774         return PEP_ILLEGAL_VALUE;
  3775 
  3776     int int_result = sqlite3_exec(
  3777         session->db,
  3778         "delete from identity where address like '%@peptest.ch' ;",
  3779         NULL,
  3780         NULL,
  3781         NULL
  3782     );
  3783     assert(int_result == SQLITE_OK);
  3784 
  3785     if (int_result != SQLITE_OK)
  3786         return PEP_UNKNOWN_ERROR;
  3787 
  3788     return PEP_STATUS_OK;
  3789 }
  3790 
  3791 #ifdef DEBUG_ERRORSTACK
  3792 PEP_STATUS session_add_error(PEP_SESSION session, const char* file, unsigned line, PEP_STATUS status)
  3793 {
  3794     char logline[48];
  3795     if(status>0)
  3796     {
  3797         snprintf(logline,47, "%.24s:%u status=%u (0x%x)", file, line, status, status);
  3798     }else{
  3799         snprintf(logline,47, "%.24s:%u status=%i.", file, line, status);
  3800     }
  3801     stringlist_add(session->errorstack, logline); // logline is copied! :-)
  3802     return status;
  3803 }
  3804 
  3805 DYNAMIC_API const stringlist_t* get_errorstack(PEP_SESSION session)
  3806 {
  3807     return session->errorstack;
  3808 }
  3809 
  3810 DYNAMIC_API void clear_errorstack(PEP_SESSION session)
  3811 {
  3812     const int old_len = stringlist_length(session->errorstack);
  3813     char buf[48];
  3814     free_stringlist(session->errorstack);
  3815     snprintf(buf, 47, "(%i elements cleared)", old_len);
  3816     session->errorstack = new_stringlist(buf);
  3817 }
  3818 
  3819 #else
  3820 
  3821 static stringlist_t* dummy_errorstack = NULL;
  3822 
  3823 DYNAMIC_API const stringlist_t* get_errorstack(PEP_SESSION session)
  3824 {
  3825     if(dummy_errorstack == NULL)
  3826     {
  3827         dummy_errorstack = new_stringlist("( Please recompile pEpEngine with -DDEBUG_ERRORSTACK )");
  3828     }
  3829 
  3830     return dummy_errorstack;
  3831 }
  3832 
  3833 DYNAMIC_API void clear_errorstack(PEP_SESSION session)
  3834 {
  3835     // nothing to do here
  3836 }
  3837 
  3838 #endif