src/pEpEngine.c
author Krista Bennett <krista@pep-project.org>
Fri, 09 Feb 2018 09:03:11 +0100
changeset 2491 4852c6c94029
parent 2490 a527d621b486
child 2495 ce2a95430d2d
permissions -rw-r--r--
Added set_as_pep_user to set trust
     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     PEP_STATUS status = 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     if (status == PEP_STATUS_OK) {
  2256         if ((identity->comm_type | PEP_ct_confirmed) == PEP_ct_pEp)
  2257             status = set_as_pep_user(session, identity);
  2258     }
  2259     return status;
  2260 }
  2261 
  2262 PEP_STATUS set_trust(PEP_SESSION session, pEp_identity* identity) {
  2263     return _set_trust_internal(session, identity, true);
  2264 }
  2265 
  2266 PEP_STATUS set_person(PEP_SESSION session, pEp_identity* identity,
  2267                       bool guard_transaction) {
  2268     return set_or_update_with_identity(session, identity,
  2269                                        _set_or_update_person,
  2270                                        exists_person,
  2271                                        session->update_person,
  2272                                        session->set_person,
  2273                                        guard_transaction);
  2274 }
  2275 
  2276 PEP_STATUS set_identity_entry(PEP_SESSION session, pEp_identity* identity,
  2277                               bool guard_transaction) {
  2278     return set_or_update_with_identity(session, identity,
  2279                                        _set_or_update_identity_entry,
  2280                                        exists_identity_entry,
  2281                                        session->update_identity_entry,
  2282                                        session->set_identity_entry,
  2283                                        guard_transaction);
  2284 }
  2285 
  2286 DYNAMIC_API PEP_STATUS set_identity(
  2287         PEP_SESSION session, const pEp_identity *identity
  2288     )
  2289 {
  2290     int result;
  2291 
  2292     assert(session);
  2293     assert(identity);
  2294     assert(identity->address);
  2295     assert(identity->user_id);
  2296     assert(identity->username);
  2297 
  2298     if (!(session && identity && identity->address &&
  2299                 identity->user_id && identity->username))
  2300         return PEP_ILLEGAL_VALUE;
  2301 
  2302     PEP_STATUS status = PEP_STATUS_OK;
  2303     
  2304     bool listed;
  2305 
  2306     bool has_fpr = (!EMPTYSTR(identity->fpr));
  2307     
  2308     if (has_fpr) {    
  2309         // blacklist check - FIXME: ENGINE-294 will remove
  2310         status = blacklist_is_listed(session, identity->fpr, &listed);
  2311         assert(status == PEP_STATUS_OK);
  2312         if (status != PEP_STATUS_OK)
  2313             return status;
  2314 
  2315         if (listed)
  2316             return PEP_KEY_BLACKLISTED;
  2317     }
  2318 
  2319     sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  2320 
  2321     if (identity->lang[0]) {
  2322         assert(identity->lang[0] >= 'a' && identity->lang[0] <= 'z');
  2323         assert(identity->lang[1] >= 'a' && identity->lang[1] <= 'z');
  2324         assert(identity->lang[2] == 0);
  2325     }
  2326 
  2327     if (has_fpr) {
  2328         sqlite3_reset(session->set_pgp_keypair);
  2329         sqlite3_bind_text(session->set_pgp_keypair, 1, identity->fpr, -1,
  2330                 SQLITE_STATIC);
  2331         result = sqlite3_step(session->set_pgp_keypair);
  2332         sqlite3_reset(session->set_pgp_keypair);
  2333         if (result != SQLITE_DONE) {
  2334             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2335             return PEP_CANNOT_SET_PGP_KEYPAIR;
  2336         }
  2337     }
  2338 
  2339     // We do this because there are checks in set_person for
  2340     // aliases, which modify the identity object on return.
  2341     pEp_identity* ident_copy = identity_dup(identity); 
  2342     if (!ident_copy)
  2343         return PEP_OUT_OF_MEMORY;
  2344 
  2345     status = set_person(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     status = set_identity_entry(session, ident_copy, false);
  2352     if (status != PEP_STATUS_OK) {
  2353         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2354         goto pep_free;
  2355     }
  2356 
  2357     if (has_fpr) {
  2358         status = _set_trust_internal(session, ident_copy, false);
  2359         if (status != PEP_STATUS_OK) {
  2360             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  2361             goto pep_free;
  2362         }
  2363     }
  2364     
  2365     result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  2366     if (result == SQLITE_OK)
  2367         status = PEP_STATUS_OK;
  2368     else
  2369         status = PEP_COMMIT_FAILED;
  2370 
  2371 pep_free:
  2372     free_identity(ident_copy);
  2373     return status;
  2374 }
  2375 
  2376 // This ONLY sets the user flag, and creates a shell identity if necessary.
  2377 PEP_STATUS set_as_pep_user(PEP_SESSION session, pEp_identity* user) {
  2378 
  2379     assert(session);
  2380     assert(user);
  2381     assert(!EMPTYSTR(user->user_id));
  2382         
  2383     if (!session || !user || EMPTYSTR(user->user_id))
  2384         return PEP_ILLEGAL_VALUE;
  2385             
  2386     PEP_STATUS status = PEP_STATUS_OK;
  2387     
  2388     bool person_exists = false;
  2389     
  2390     status = exists_person(session, user, &person_exists);
  2391     
  2392     if (status != PEP_STATUS_OK)
  2393         return status;
  2394         
  2395     if (!person_exists) {
  2396         if (!user->address)
  2397             return PEP_ILLEGAL_VALUE;
  2398             
  2399         // create shell identity
  2400         pEp_identity* tmp_id = new_identity(user->address, NULL, user->user_id, user->username);
  2401         status = set_identity(session, tmp_id); // this creates the person
  2402         free_identity(tmp_id);
  2403         if (status != PEP_STATUS_OK)
  2404             return status;
  2405     }
  2406         
  2407     // Ok, let's set it.
  2408     sqlite3_reset(session->set_as_pep_user);
  2409     sqlite3_bind_text(session->set_as_pep_user, 1, user->user_id, -1,
  2410             SQLITE_STATIC);
  2411     int result = sqlite3_step(session->set_as_pep_user);
  2412     sqlite3_reset(session->set_as_pep_user);
  2413     
  2414     if (result != SQLITE_DONE)
  2415         return PEP_CANNOT_SET_PERSON;
  2416         
  2417     return PEP_STATUS_OK;    
  2418 }
  2419 
  2420 PEP_STATUS exists_person(PEP_SESSION session, pEp_identity* identity,
  2421                          bool* exists) {            
  2422     
  2423     // const char* user_id,
  2424     //                      char** default_id, bool* exists) {
  2425     assert(session);
  2426     assert(exists);
  2427     assert(identity);
  2428     assert(!EMPTYSTR(identity->user_id));
  2429         
  2430     if (!session || !exists || !identity || EMPTYSTR(identity->user_id))
  2431         return PEP_ILLEGAL_VALUE;
  2432     
  2433     *exists = false;
  2434 
  2435     const char* user_id = identity->user_id;
  2436     char* alias_default = NULL;
  2437     
  2438     PEP_STATUS status = get_userid_alias_default(session, user_id, &alias_default);
  2439     
  2440     if (status == PEP_CANNOT_FIND_ALIAS || EMPTYSTR(alias_default)) {
  2441         sqlite3_reset(session->exists_person);
  2442         sqlite3_bind_text(session->exists_person, 1, user_id, -1,
  2443                 SQLITE_STATIC);
  2444         int result = sqlite3_step(session->exists_person);
  2445         switch (result) {
  2446             case SQLITE_ROW: {
  2447                 // yeah yeah, I know, we could be lazy here, but it looks bad.
  2448                 *exists = (sqlite3_column_int(session->exists_person, 0) != 0);
  2449                 status = PEP_STATUS_OK;
  2450                 break;
  2451             }
  2452             default:
  2453                 return PEP_UNKNOWN_ERROR;
  2454         }
  2455     }
  2456     else if (status == PEP_STATUS_OK) {
  2457         *exists = true; // thank you, delete on cascade!
  2458         // FIXME: Should we correct the userid default here? I think we should.
  2459         free(identity->user_id);
  2460         identity->user_id = alias_default; // ownership transfer
  2461     }
  2462     else
  2463         free(alias_default);
  2464         
  2465     return status;
  2466 }
  2467 
  2468 DYNAMIC_API PEP_STATUS is_pep_user(PEP_SESSION session, pEp_identity *identity, bool* is_pep)
  2469 {
  2470     assert(session);
  2471     assert(is_pep);
  2472     assert(identity);
  2473     assert(!EMPTYSTR(identity->user_id));
  2474 
  2475     if (!session || !is_pep || !identity || EMPTYSTR(identity->user_id))
  2476         return PEP_ILLEGAL_VALUE;
  2477     
  2478     *is_pep = false;
  2479     
  2480     const char* user_id = identity->user_id;
  2481     
  2482     if (!session || EMPTYSTR(user_id))
  2483         return PEP_ILLEGAL_VALUE;
  2484         
  2485     char* alias_default = NULL;
  2486     
  2487     PEP_STATUS status = get_userid_alias_default(session, user_id, &alias_default);
  2488     
  2489     if (status == PEP_CANNOT_FIND_ALIAS || EMPTYSTR(alias_default)) {
  2490         free(alias_default);
  2491         alias_default = strdup(user_id);
  2492     }
  2493     
  2494     sqlite3_reset(session->is_pep_user);
  2495     sqlite3_bind_text(session->is_pep_user, 1, user_id, -1,
  2496             SQLITE_STATIC);
  2497     int result = sqlite3_step(session->is_pep_user);
  2498     switch (result) {
  2499         case SQLITE_ROW: {
  2500             // yeah yeah, I know, we could be lazy here, but it looks bad.
  2501             *is_pep = (sqlite3_column_int(session->is_pep_user, 0) != 0);
  2502             break;
  2503         }
  2504         default:
  2505             free(alias_default);
  2506             return PEP_CANNOT_FIND_PERSON;
  2507     }
  2508 
  2509     return PEP_STATUS_OK;
  2510 }
  2511 
  2512 
  2513 PEP_STATUS remove_fpr_as_default(PEP_SESSION session, 
  2514                                  const char* fpr) 
  2515 {
  2516     assert(fpr);
  2517     
  2518     if (!session || !fpr)
  2519         return PEP_ILLEGAL_VALUE;
  2520             
  2521     sqlite3_reset(session->remove_fpr_as_default);
  2522     sqlite3_bind_text(session->remove_fpr_as_default, 1, fpr, -1,
  2523                       SQLITE_STATIC);
  2524 
  2525     int result = sqlite3_step(session->remove_fpr_as_default);
  2526     sqlite3_reset(session->remove_fpr_as_default);
  2527     
  2528     if (result != SQLITE_DONE)
  2529         return PEP_CANNOT_SET_IDENTITY; // misleading - could also be person
  2530 
  2531     return PEP_STATUS_OK;
  2532 }
  2533 
  2534 
  2535 PEP_STATUS replace_identities_fpr(PEP_SESSION session, 
  2536                                  const char* old_fpr, 
  2537                                  const char* new_fpr) 
  2538 {
  2539     assert(old_fpr);
  2540     assert(new_fpr);
  2541     
  2542     if (!old_fpr || !new_fpr)
  2543         return PEP_ILLEGAL_VALUE;
  2544             
  2545     sqlite3_reset(session->replace_identities_fpr);
  2546     sqlite3_bind_text(session->replace_identities_fpr, 1, new_fpr, -1,
  2547                       SQLITE_STATIC);
  2548     sqlite3_bind_text(session->replace_identities_fpr, 2, old_fpr, -1,
  2549                       SQLITE_STATIC);
  2550 
  2551     int result = sqlite3_step(session->replace_identities_fpr);
  2552     sqlite3_reset(session->replace_identities_fpr);
  2553     
  2554     if (result != SQLITE_DONE)
  2555         return PEP_CANNOT_SET_IDENTITY;
  2556 
  2557     return PEP_STATUS_OK;
  2558 }
  2559 
  2560 PEP_STATUS update_trust_for_fpr(PEP_SESSION session, 
  2561                                 const char* fpr, 
  2562                                 PEP_comm_type comm_type)
  2563 {
  2564     if (!fpr)
  2565         return PEP_ILLEGAL_VALUE;
  2566         
  2567     sqlite3_reset(session->update_trust_for_fpr);
  2568     sqlite3_bind_int(session->update_trust_for_fpr, 1, comm_type);
  2569     sqlite3_bind_text(session->update_trust_for_fpr, 2, fpr, -1,
  2570             SQLITE_STATIC);
  2571     int result = sqlite3_step(session->update_trust_for_fpr);
  2572     sqlite3_reset(session->update_trust_for_fpr);
  2573     if (result != SQLITE_DONE) {
  2574         return PEP_CANNOT_SET_TRUST;
  2575     }
  2576     
  2577     return PEP_STATUS_OK;
  2578 }
  2579 
  2580 DYNAMIC_API PEP_STATUS set_device_group(
  2581         PEP_SESSION session,
  2582         const char *group_name
  2583     )
  2584 {
  2585     int result;
  2586 
  2587     assert(session);
  2588 
  2589     if (!(session && group_name))
  2590         return PEP_ILLEGAL_VALUE;
  2591 
  2592     // 1. Get own user_id
  2593     char* user_id = NULL;
  2594     PEP_STATUS status = get_default_own_userid(session, &user_id);
  2595     
  2596     // No user_id is returned in this case, no need to free;
  2597     if (status != PEP_STATUS_OK)
  2598         return status;
  2599         
  2600     // 2. Set device group
  2601     sqlite3_reset(session->set_device_group);
  2602     if(group_name){
  2603         sqlite3_bind_text(session->set_device_group, 1, group_name, -1,
  2604                 SQLITE_STATIC);
  2605     } else {
  2606         sqlite3_bind_null(session->set_device_group, 1);
  2607     }
  2608     
  2609     sqlite3_bind_text(session->set_device_group, 2, user_id, -1,
  2610             SQLITE_STATIC);
  2611 
  2612     result = sqlite3_step(session->set_device_group);
  2613     sqlite3_reset(session->set_device_group);
  2614     
  2615     free(user_id);
  2616     
  2617     if (result != SQLITE_DONE)
  2618         return PEP_CANNOT_SET_PERSON;
  2619 
  2620     return PEP_STATUS_OK;
  2621 }
  2622 
  2623 DYNAMIC_API PEP_STATUS get_device_group(PEP_SESSION session, char **group_name)
  2624 {
  2625     PEP_STATUS status = PEP_STATUS_OK;
  2626     int result;
  2627 
  2628     assert(session);
  2629     assert(group_name);
  2630 
  2631     if (!(session && group_name))
  2632         return PEP_ILLEGAL_VALUE;
  2633 
  2634     // 1. Get own user_id
  2635     char* user_id = NULL;
  2636     status = get_default_own_userid(session, &user_id);
  2637     
  2638     // No user_id is returned in this case, no need to free;
  2639     if (status != PEP_STATUS_OK)
  2640         return status;
  2641 
  2642     // 2. get device group
  2643     sqlite3_reset(session->get_device_group);
  2644     sqlite3_bind_text(session->get_device_group, 1, user_id, -1,
  2645             SQLITE_STATIC);
  2646 
  2647     result = sqlite3_step(session->get_device_group);
  2648     switch (result) {
  2649     case SQLITE_ROW: {
  2650         const char *_group_name = (const char *)sqlite3_column_text(session->get_device_group, 0);
  2651         if(_group_name){
  2652             *group_name = strdup(_group_name);
  2653                 if(*group_name == NULL)
  2654                     status = PEP_OUT_OF_MEMORY;
  2655         }
  2656         break;
  2657     }
  2658  
  2659     default:
  2660         status = PEP_RECORD_NOT_FOUND;
  2661     }
  2662 
  2663     free(user_id);
  2664     sqlite3_reset(session->get_device_group);
  2665     return status;
  2666 }
  2667 
  2668 DYNAMIC_API PEP_STATUS set_identity_flags(
  2669         PEP_SESSION session,
  2670         pEp_identity *identity,
  2671         unsigned int flags
  2672     )
  2673 {
  2674     int result;
  2675 
  2676     assert(session);
  2677     assert(identity);
  2678     assert(identity->address);
  2679     assert(identity->user_id);
  2680 
  2681     if (!(session && identity && identity->address && identity->user_id))
  2682         return PEP_ILLEGAL_VALUE;
  2683 
  2684     sqlite3_reset(session->set_identity_flags);
  2685     sqlite3_bind_int(session->set_identity_flags, 1, flags);
  2686     sqlite3_bind_text(session->set_identity_flags, 2, identity->address, -1,
  2687             SQLITE_STATIC);
  2688     sqlite3_bind_text(session->set_identity_flags, 3, identity->user_id, -1,
  2689         SQLITE_STATIC);
  2690         
  2691     result = sqlite3_step(session->set_identity_flags);
  2692 
  2693     sqlite3_reset(session->set_identity_flags);
  2694     if (result != SQLITE_DONE)
  2695         return PEP_CANNOT_SET_IDENTITY;
  2696 
  2697     identity->flags |= flags;
  2698     return PEP_STATUS_OK;
  2699 }
  2700 
  2701 DYNAMIC_API PEP_STATUS unset_identity_flags(
  2702         PEP_SESSION session,
  2703         pEp_identity *identity,
  2704         unsigned int flags
  2705     )
  2706 {
  2707     int result;
  2708 
  2709     assert(session);
  2710     assert(identity);
  2711     assert(identity->address);
  2712     assert(identity->user_id);
  2713 
  2714     if (!(session && identity && identity->address && identity->user_id))
  2715         return PEP_ILLEGAL_VALUE;
  2716 
  2717     sqlite3_reset(session->unset_identity_flags);
  2718     sqlite3_bind_int(session->unset_identity_flags, 1, flags);
  2719     sqlite3_bind_text(session->unset_identity_flags, 2, identity->address, -1,
  2720             SQLITE_STATIC);
  2721     sqlite3_bind_text(session->unset_identity_flags, 3, identity->user_id, -1,
  2722             SQLITE_STATIC);
  2723     result = sqlite3_step(session->unset_identity_flags);
  2724     sqlite3_reset(session->unset_identity_flags);
  2725     if (result != SQLITE_DONE)
  2726         return PEP_CANNOT_SET_IDENTITY;
  2727         identity->flags &= ~flags;
  2728 
  2729     return PEP_STATUS_OK;
  2730 }
  2731 
  2732 
  2733 PEP_STATUS replace_userid(PEP_SESSION session, const char* old_uid,
  2734                               const char* new_uid) {
  2735     assert(session);
  2736     assert(old_uid);
  2737     assert(new_uid);
  2738     
  2739     if (!session || !old_uid || !new_uid)
  2740         return PEP_ILLEGAL_VALUE;
  2741 
  2742 
  2743     int result;
  2744 
  2745     sqlite3_reset(session->replace_userid);
  2746     sqlite3_bind_text(session->replace_userid, 1, new_uid, -1,
  2747             SQLITE_STATIC);
  2748     sqlite3_bind_text(session->replace_userid, 2, old_uid, -1,
  2749             SQLITE_STATIC);
  2750     result = sqlite3_step(session->replace_userid);
  2751     sqlite3_reset(session->replace_userid);
  2752     if (result != SQLITE_DONE)
  2753         return PEP_CANNOT_SET_PERSON; // May need clearer retval
  2754 
  2755     return PEP_STATUS_OK;
  2756 }
  2757 
  2758 PEP_STATUS refresh_userid_default_key(PEP_SESSION session, const char* user_id) {
  2759     assert(session);
  2760     assert(user_id);
  2761     
  2762     if (!session || !user_id)
  2763         return PEP_ILLEGAL_VALUE;
  2764 
  2765     int result;
  2766 
  2767     sqlite3_reset(session->refresh_userid_default_key);
  2768     sqlite3_bind_text(session->refresh_userid_default_key, 1, user_id, -1,
  2769             SQLITE_STATIC);
  2770     result = sqlite3_step(session->refresh_userid_default_key);
  2771     sqlite3_reset(session->refresh_userid_default_key);
  2772     if (result != SQLITE_DONE)
  2773         return PEP_CANNOT_SET_PERSON;
  2774 
  2775     return PEP_STATUS_OK;    
  2776 }
  2777 
  2778 PEP_STATUS replace_main_user_fpr(PEP_SESSION session, const char* user_id,
  2779                                  const char* new_fpr) {
  2780     assert(session);
  2781     assert(user_id);
  2782     assert(new_fpr);
  2783     
  2784     if (!session || !user_id || !new_fpr)
  2785         return PEP_ILLEGAL_VALUE;
  2786 
  2787     int result;
  2788 
  2789     sqlite3_reset(session->replace_main_user_fpr);
  2790     sqlite3_bind_text(session->replace_main_user_fpr, 1, new_fpr, -1,
  2791             SQLITE_STATIC);
  2792     sqlite3_bind_text(session->replace_main_user_fpr, 2, user_id, -1,
  2793             SQLITE_STATIC);
  2794     result = sqlite3_step(session->replace_main_user_fpr);
  2795     sqlite3_reset(session->replace_main_user_fpr);
  2796     if (result != SQLITE_DONE)
  2797         return PEP_CANNOT_SET_PERSON;
  2798 
  2799     return PEP_STATUS_OK;
  2800 }
  2801 
  2802 PEP_STATUS get_main_user_fpr(PEP_SESSION session, 
  2803                              const char* user_id,
  2804                              char** main_fpr)
  2805 {
  2806     PEP_STATUS status = PEP_STATUS_OK;
  2807     int result;
  2808     
  2809     assert(session);
  2810     assert(user_id);
  2811     assert(main_fpr);
  2812     
  2813     if (!(session && user_id && user_id[0] && main_fpr))
  2814         return PEP_ILLEGAL_VALUE;
  2815         
  2816     *main_fpr = NULL;
  2817     
  2818     sqlite3_reset(session->get_main_user_fpr);
  2819     sqlite3_bind_text(session->get_main_user_fpr, 1, user_id, -1,
  2820                       SQLITE_STATIC);
  2821     result = sqlite3_step(session->get_main_user_fpr);
  2822     switch (result) {
  2823     case SQLITE_ROW: {
  2824         const char* _fpr = 
  2825             (const char *) sqlite3_column_text(session->get_main_user_fpr, 0);
  2826         if (_fpr)
  2827             *main_fpr = strdup(_fpr);
  2828         if (!(*main_fpr))
  2829             status = PEP_OUT_OF_MEMORY;
  2830         break;
  2831     }
  2832     default:
  2833         status = PEP_CANNOT_FIND_PERSON;
  2834     }
  2835 
  2836     sqlite3_reset(session->get_main_user_fpr);
  2837     return status;
  2838 }
  2839 
  2840 
  2841 DYNAMIC_API PEP_STATUS mark_as_compromized(
  2842         PEP_SESSION session,
  2843         const char *fpr
  2844     )
  2845 {
  2846     int result;
  2847 
  2848     assert(session);
  2849     assert(fpr && fpr[0]);
  2850 
  2851     if (!(session && fpr && fpr[0]))
  2852         return PEP_ILLEGAL_VALUE;
  2853 
  2854     sqlite3_reset(session->mark_compromized);
  2855     sqlite3_bind_text(session->mark_compromized, 1, fpr, -1,
  2856             SQLITE_STATIC);
  2857     result = sqlite3_step(session->mark_compromized);
  2858     sqlite3_reset(session->mark_compromized);
  2859 
  2860     if (result != SQLITE_DONE)
  2861         return PEP_CANNOT_SET_TRUST;
  2862 
  2863     return PEP_STATUS_OK;
  2864 }
  2865 
  2866 void pEp_free(void *p)
  2867 {
  2868     free(p);
  2869 }
  2870 
  2871 
  2872 DYNAMIC_API PEP_STATUS get_trust(PEP_SESSION session, pEp_identity *identity)
  2873 {
  2874     PEP_STATUS status = PEP_STATUS_OK;
  2875     int result;
  2876 
  2877     // We need to be able to test that we break correctly without shutting
  2878     // asserts off everywhere.
  2879     // assert(session);
  2880     // assert(identity);
  2881     // assert(identity->user_id);
  2882     // assert(identity->user_id[0]);
  2883     // assert(identity->fpr);
  2884     // assert(identity->fpr[0]);
  2885 
  2886     if (!(session && identity && identity->user_id && identity->user_id[0] &&
  2887                 identity->fpr && identity->fpr[0]))
  2888         return PEP_ILLEGAL_VALUE;
  2889 
  2890     identity->comm_type = PEP_ct_unknown;
  2891 
  2892     sqlite3_reset(session->get_trust);
  2893     sqlite3_bind_text(session->get_trust, 1, identity->user_id, -1,
  2894             SQLITE_STATIC);
  2895     sqlite3_bind_text(session->get_trust, 2, identity->fpr, -1, SQLITE_STATIC);
  2896 
  2897     result = sqlite3_step(session->get_trust);
  2898     switch (result) {
  2899     case SQLITE_ROW: {
  2900         int comm_type = (PEP_comm_type) sqlite3_column_int(session->get_trust,
  2901                 0);
  2902         identity->comm_type = comm_type;
  2903         break;
  2904     }
  2905  
  2906     default:
  2907         status = PEP_CANNOT_FIND_IDENTITY;
  2908     }
  2909 
  2910     sqlite3_reset(session->get_trust);
  2911     return status;
  2912 }
  2913 
  2914 DYNAMIC_API PEP_STATUS least_trust(
  2915         PEP_SESSION session,
  2916         const char *fpr,
  2917         PEP_comm_type *comm_type
  2918     )
  2919 {
  2920     PEP_STATUS status = PEP_STATUS_OK;
  2921     int result;
  2922 
  2923     assert(session);
  2924     assert(fpr);
  2925     assert(comm_type);
  2926 
  2927     if (!(session && fpr && comm_type))
  2928         return PEP_ILLEGAL_VALUE;
  2929 
  2930     *comm_type = PEP_ct_unknown;
  2931 
  2932     sqlite3_reset(session->least_trust);
  2933     sqlite3_bind_text(session->least_trust, 1, fpr, -1, SQLITE_STATIC);
  2934 
  2935     result = sqlite3_step(session->least_trust);
  2936     switch (result) {
  2937         case SQLITE_ROW: {
  2938             int _comm_type = sqlite3_column_int(session->least_trust, 0);
  2939             *comm_type = (PEP_comm_type) _comm_type;
  2940             break;
  2941         }
  2942         default:
  2943             // never reached because of sql min()
  2944             status = PEP_CANNOT_FIND_IDENTITY;
  2945     }
  2946 
  2947     sqlite3_reset(session->least_trust);
  2948     return status;
  2949 }
  2950 
  2951 DYNAMIC_API PEP_STATUS decrypt_and_verify(
  2952     PEP_SESSION session, const char *ctext, size_t csize,
  2953     const char *dsigtext, size_t dsigsize,
  2954     char **ptext, size_t *psize, stringlist_t **keylist
  2955     )
  2956 {
  2957     assert(session);
  2958     assert(ctext);
  2959     assert(csize);
  2960     assert(ptext);
  2961     assert(psize);
  2962     assert(keylist);
  2963 
  2964     if (!(session && ctext && csize && ptext && psize && keylist))
  2965         return PEP_ILLEGAL_VALUE;
  2966 
  2967     return session->cryptotech[PEP_crypt_OpenPGP].decrypt_and_verify(
  2968             session, ctext, csize, dsigtext, dsigsize, ptext, psize, keylist);
  2969 }
  2970 
  2971 DYNAMIC_API PEP_STATUS encrypt_and_sign(
  2972     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  2973     size_t psize, char **ctext, size_t *csize
  2974     )
  2975 {
  2976     assert(session);
  2977     assert(keylist);
  2978     assert(ptext);
  2979     assert(psize);
  2980     assert(ctext);
  2981     assert(csize);
  2982 
  2983     if (!(session && keylist && ptext && psize && ctext && csize))
  2984         return PEP_ILLEGAL_VALUE;
  2985 
  2986     return session->cryptotech[PEP_crypt_OpenPGP].encrypt_and_sign(session,
  2987             keylist, ptext, psize, ctext, csize);
  2988 }
  2989 
  2990 PEP_STATUS encrypt_only(
  2991     PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
  2992     size_t psize, char **ctext, size_t *csize
  2993     )
  2994 {
  2995     assert(session);
  2996     assert(keylist);
  2997     assert(ptext);
  2998     assert(psize);
  2999     assert(ctext);
  3000     assert(csize);
  3001 
  3002     if (!(session && keylist && ptext && psize && ctext && csize))
  3003         return PEP_ILLEGAL_VALUE;
  3004 
  3005     return session->cryptotech[PEP_crypt_OpenPGP].encrypt_only(session,
  3006             keylist, ptext, psize, ctext, csize);
  3007 }
  3008 
  3009 
  3010 DYNAMIC_API PEP_STATUS verify_text(
  3011     PEP_SESSION session, const char *text, size_t size,
  3012     const char *signature, size_t sig_size, stringlist_t **keylist
  3013     )
  3014 {
  3015     assert(session);
  3016     assert(text);
  3017     assert(size);
  3018     assert(signature);
  3019     assert(sig_size);
  3020     assert(keylist);
  3021 
  3022     if (!(session && text && size && signature && sig_size && keylist))
  3023         return PEP_ILLEGAL_VALUE;
  3024 
  3025     return session->cryptotech[PEP_crypt_OpenPGP].verify_text(session, text,
  3026             size, signature, sig_size, keylist);
  3027 }
  3028 
  3029 DYNAMIC_API PEP_STATUS delete_keypair(PEP_SESSION session, const char *fpr)
  3030 {
  3031     assert(session);
  3032     assert(fpr);
  3033 
  3034     if (!(session && fpr))
  3035         return PEP_ILLEGAL_VALUE;
  3036 
  3037     return session->cryptotech[PEP_crypt_OpenPGP].delete_keypair(session, fpr);
  3038 }
  3039 
  3040 DYNAMIC_API PEP_STATUS export_key(
  3041         PEP_SESSION session, const char *fpr, char **key_data, size_t *size
  3042     )
  3043 {
  3044     assert(session);
  3045     assert(fpr);
  3046     assert(key_data);
  3047     assert(size);
  3048 
  3049     if (!(session && fpr && key_data && size))
  3050         return PEP_ILLEGAL_VALUE;
  3051 
  3052     return session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr,
  3053             key_data, size, false);
  3054 }
  3055 
  3056 DYNAMIC_API PEP_STATUS export_secrect_key(
  3057         PEP_SESSION session, const char *fpr, char **key_data, size_t *size
  3058     )
  3059 {
  3060     assert(session);
  3061     assert(fpr);
  3062     assert(key_data);
  3063     assert(size);
  3064 
  3065     if (!(session && fpr && key_data && size))
  3066         return PEP_ILLEGAL_VALUE;
  3067 
  3068     // don't accept key IDs but full fingerprints only
  3069     if (strlen(fpr) < 16)
  3070         return PEP_ILLEGAL_VALUE;
  3071 
  3072     return session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr,
  3073             key_data, size, true);
  3074 }
  3075 
  3076 DYNAMIC_API PEP_STATUS find_keys(
  3077         PEP_SESSION session, const char *pattern, stringlist_t **keylist
  3078     )
  3079 {
  3080     assert(session);
  3081     assert(pattern);
  3082     assert(keylist);
  3083 
  3084     if (!(session && pattern && keylist))
  3085         return PEP_ILLEGAL_VALUE;
  3086 
  3087     return session->cryptotech[PEP_crypt_OpenPGP].find_keys(session, pattern,
  3088             keylist);
  3089 }
  3090 
  3091 
  3092 DYNAMIC_API PEP_STATUS generate_keypair(
  3093         PEP_SESSION session, pEp_identity *identity
  3094     )
  3095 {
  3096     assert(session);
  3097     assert(identity);
  3098     assert(identity->address);
  3099     assert(identity->fpr == NULL || identity->fpr[0] == 0);
  3100     assert(identity->username);
  3101 
  3102     if (!(session && identity && identity->address &&
  3103             (identity->fpr == NULL || identity->fpr[0] == 0) &&
  3104             identity->username))
  3105         return PEP_ILLEGAL_VALUE;
  3106 
  3107     PEP_STATUS status =
  3108         session->cryptotech[PEP_crypt_OpenPGP].generate_keypair(session,
  3109                 identity);
  3110     if (status != PEP_STATUS_OK)
  3111         return status;
  3112 
  3113     if (identity->fpr)
  3114         status = set_pgp_keypair(session, identity->fpr);
  3115 
  3116     // add to known keypair DB, as this might not end up being a default
  3117     return status;
  3118 }
  3119 
  3120 DYNAMIC_API PEP_STATUS get_key_rating(
  3121         PEP_SESSION session,
  3122         const char *fpr,
  3123         PEP_comm_type *comm_type
  3124     )
  3125 {
  3126     assert(session);
  3127     assert(fpr);
  3128     assert(comm_type);
  3129 
  3130     if (!(session && fpr && comm_type))
  3131         return PEP_ILLEGAL_VALUE;
  3132 
  3133     return session->cryptotech[PEP_crypt_OpenPGP].get_key_rating(session, fpr,
  3134             comm_type);
  3135 }
  3136 
  3137 DYNAMIC_API PEP_STATUS import_key(
  3138         PEP_SESSION session,
  3139         const char *key_data,
  3140         size_t size,
  3141         identity_list **private_keys
  3142     )
  3143 {
  3144     assert(session);
  3145     assert(key_data);
  3146 
  3147     if (!(session && key_data))
  3148         return PEP_ILLEGAL_VALUE;
  3149 
  3150     return session->cryptotech[PEP_crypt_OpenPGP].import_key(session, key_data,
  3151             size, private_keys);
  3152 }
  3153 
  3154 DYNAMIC_API PEP_STATUS recv_key(PEP_SESSION session, const char *pattern)
  3155 {
  3156     assert(session);
  3157     assert(pattern);
  3158 
  3159     if (!(session && pattern))
  3160         return PEP_ILLEGAL_VALUE;
  3161 
  3162     return session->cryptotech[PEP_crypt_OpenPGP].recv_key(session, pattern);
  3163 }
  3164 
  3165 DYNAMIC_API PEP_STATUS send_key(PEP_SESSION session, const char *pattern)
  3166 {
  3167     assert(session);
  3168     assert(pattern);
  3169 
  3170     if (!(session && pattern))
  3171         return PEP_ILLEGAL_VALUE;
  3172 
  3173     return session->cryptotech[PEP_crypt_OpenPGP].send_key(session, pattern);
  3174 }
  3175 
  3176 DYNAMIC_API PEP_STATUS renew_key(
  3177         PEP_SESSION session,
  3178         const char *fpr,
  3179         const timestamp *ts
  3180     )
  3181 {
  3182     assert(session);
  3183     assert(fpr);
  3184 
  3185     if (!(session && fpr))
  3186         return PEP_ILLEGAL_VALUE;
  3187 
  3188     return session->cryptotech[PEP_crypt_OpenPGP].renew_key(session, fpr, ts);
  3189 }
  3190 
  3191 DYNAMIC_API PEP_STATUS revoke_key(
  3192         PEP_SESSION session,
  3193         const char *fpr,
  3194         const char *reason
  3195     )
  3196 {
  3197     assert(session);
  3198     assert(fpr);
  3199 
  3200     if (!(session && fpr))
  3201         return PEP_ILLEGAL_VALUE;
  3202 
  3203     return session->cryptotech[PEP_crypt_OpenPGP].revoke_key(session, fpr,
  3204             reason);
  3205 }
  3206 
  3207 DYNAMIC_API PEP_STATUS key_expired(
  3208         PEP_SESSION session,
  3209         const char *fpr,
  3210         const time_t when,
  3211         bool *expired
  3212     )
  3213 {
  3214     assert(session);
  3215     assert(fpr);
  3216     assert(expired);
  3217 
  3218     if (!(session && fpr && expired))
  3219         return PEP_ILLEGAL_VALUE;
  3220 
  3221     return session->cryptotech[PEP_crypt_OpenPGP].key_expired(session, fpr,
  3222             when, expired);
  3223 }
  3224 
  3225 DYNAMIC_API PEP_STATUS key_revoked(
  3226        PEP_SESSION session,
  3227        const char *fpr,
  3228        bool *revoked
  3229    )
  3230 {
  3231     assert(session);
  3232     assert(fpr);
  3233     assert(revoked);
  3234     
  3235     if (!(session && fpr && revoked))
  3236         return PEP_ILLEGAL_VALUE;
  3237     
  3238     return session->cryptotech[PEP_crypt_OpenPGP].key_revoked(session, fpr,
  3239             revoked);
  3240 }
  3241 
  3242 static void _clean_log_value(char *text)
  3243 {
  3244     if (text) {
  3245         for (char *c = text; *c; c++) {
  3246             if (*c < 32 && *c != '\n')
  3247                 *c = 32;
  3248             else if (*c == '"')
  3249                 *c = '\'';
  3250         }
  3251     }
  3252 }
  3253 
  3254 static char *_concat_string(char *str1, const char *str2, char delim)
  3255 {
  3256     str2 = str2 ? str2 : "";
  3257     size_t len1 = str1 ? strlen(str1) : 0;
  3258     size_t len2 = strlen(str2);
  3259     size_t len = len1 + len2 + 3;
  3260     char * result = realloc(str1, len + 1);
  3261 
  3262     if (result) {
  3263         result[len1] = '"';
  3264         strcpy(result + len1 + 1, str2);
  3265         result[len - 2] = '"';
  3266         result[len - 1] = delim;
  3267         result[len] = 0;
  3268     }
  3269     else {
  3270         free(str1);
  3271     }
  3272 
  3273     return result;
  3274 }
  3275 
  3276 DYNAMIC_API PEP_STATUS get_crashdump_log(
  3277         PEP_SESSION session,
  3278         int maxlines,
  3279         char **logdata
  3280     )
  3281 {
  3282     PEP_STATUS status = PEP_STATUS_OK;
  3283     char *_logdata= NULL;
  3284 
  3285     assert(session);
  3286     assert(maxlines >= 0 && maxlines <= CRASHDUMP_MAX_LINES);
  3287     assert(logdata);
  3288 
  3289     if (!(session && logdata && maxlines >= 0 && maxlines <=
  3290             CRASHDUMP_MAX_LINES))
  3291         return PEP_ILLEGAL_VALUE;
  3292 
  3293     *logdata = NULL;
  3294 
  3295     int limit = maxlines ? maxlines : CRASHDUMP_DEFAULT_LINES;
  3296     const char *timestamp = NULL;
  3297     const char *title = NULL;
  3298     const char *entity = NULL;
  3299     const char *desc = NULL;
  3300     const char *comment = NULL;
  3301 
  3302     sqlite3_reset(session->crashdump);
  3303     sqlite3_bind_int(session->crashdump, 1, limit);
  3304 
  3305     int result;
  3306 
  3307     do {
  3308         result = sqlite3_step(session->crashdump);
  3309         switch (result) {
  3310         case SQLITE_ROW:
  3311             timestamp = (const char *) sqlite3_column_text(session->crashdump,
  3312                     0);
  3313             title   = (const char *) sqlite3_column_text(session->crashdump,
  3314                     1);
  3315             entity  = (const char *) sqlite3_column_text(session->crashdump,
  3316                     2);
  3317             desc    = (const char *) sqlite3_column_text(session->crashdump,
  3318                     3);
  3319             comment = (const char *) sqlite3_column_text(session->crashdump,
  3320                     4);
  3321 
  3322             _logdata = _concat_string(_logdata, timestamp, ',');
  3323             if (_logdata == NULL)
  3324                 goto enomem;
  3325 
  3326             _logdata = _concat_string(_logdata, title, ',');
  3327             if (_logdata == NULL)
  3328                 goto enomem;
  3329 
  3330             _logdata = _concat_string(_logdata, entity, ',');
  3331             if (_logdata == NULL)
  3332                 goto enomem;
  3333 
  3334             _logdata = _concat_string(_logdata, desc, ',');
  3335             if (_logdata == NULL)
  3336                 goto enomem;
  3337 
  3338             _logdata = _concat_string(_logdata, comment, '\n');
  3339             if (_logdata == NULL)
  3340                 goto enomem;
  3341 
  3342             _clean_log_value(_logdata);
  3343             break;
  3344 
  3345         case SQLITE_DONE:
  3346             break;
  3347 
  3348         default:
  3349             status = PEP_UNKNOWN_ERROR;
  3350             result = SQLITE_DONE;
  3351         }
  3352     } while (result != SQLITE_DONE);
  3353 
  3354     sqlite3_reset(session->crashdump);
  3355     if (status == PEP_STATUS_OK)
  3356         *logdata = _logdata;
  3357 
  3358     goto the_end;
  3359 
  3360 enomem:
  3361     status = PEP_OUT_OF_MEMORY;
  3362 
  3363 the_end:
  3364     return ADD_TO_LOG(status);
  3365 }
  3366 
  3367 DYNAMIC_API PEP_STATUS get_languagelist(
  3368         PEP_SESSION session,
  3369         char **languages
  3370     )
  3371 {
  3372     PEP_STATUS status = PEP_STATUS_OK;
  3373     char *_languages= NULL;
  3374 
  3375     assert(session);
  3376     assert(languages);
  3377 
  3378     if (!(session && languages))
  3379         return PEP_ILLEGAL_VALUE;
  3380 
  3381     *languages = NULL;
  3382 
  3383     const char *lang = NULL;
  3384     const char *name = NULL;
  3385     const char *phrase = NULL;
  3386 
  3387     sqlite3_reset(session->languagelist);
  3388 
  3389     int result;
  3390 
  3391     do {
  3392         result = sqlite3_step(session->languagelist);
  3393         switch (result) {
  3394         case SQLITE_ROW:
  3395             lang = (const char *) sqlite3_column_text(session->languagelist,
  3396                     0);
  3397             name = (const char *) sqlite3_column_text(session->languagelist,
  3398                     1);
  3399             phrase = (const char *) sqlite3_column_text(session->languagelist,
  3400                     2);
  3401 
  3402             _languages = _concat_string(_languages, lang, ',');
  3403             if (_languages == NULL)
  3404                 goto enomem;
  3405 
  3406             _languages = _concat_string(_languages, name, ',');
  3407             if (_languages == NULL)
  3408                 goto enomem;
  3409 
  3410             _languages = _concat_string(_languages, phrase, '\n');
  3411             if (_languages == NULL)
  3412                 goto enomem;
  3413 
  3414             break;
  3415 
  3416         case SQLITE_DONE:
  3417             break;
  3418 
  3419         default:
  3420             status = PEP_UNKNOWN_ERROR;
  3421             result = SQLITE_DONE;
  3422         }
  3423     } while (result != SQLITE_DONE);
  3424 
  3425     sqlite3_reset(session->languagelist);
  3426     if (status == PEP_STATUS_OK)
  3427         *languages = _languages;
  3428 
  3429     goto the_end;
  3430 
  3431 enomem:
  3432     status = PEP_OUT_OF_MEMORY;
  3433 
  3434 the_end:
  3435     return status;
  3436 }
  3437 
  3438 DYNAMIC_API PEP_STATUS get_phrase(
  3439         PEP_SESSION session,
  3440         const char *lang,
  3441         int phrase_id,
  3442         char **phrase
  3443     )
  3444 {
  3445     PEP_STATUS status = PEP_STATUS_OK;
  3446 
  3447     assert(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase);
  3448     if (!(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase))
  3449         return PEP_ILLEGAL_VALUE;
  3450 
  3451     *phrase = NULL;
  3452 
  3453     sqlite3_reset(session->i18n_token);
  3454     sqlite3_bind_text(session->i18n_token, 1, lang, -1, SQLITE_STATIC);
  3455     sqlite3_bind_int(session->i18n_token, 2, phrase_id);
  3456 
  3457     const char *_phrase = NULL;
  3458     int result;
  3459 
  3460     result = sqlite3_step(session->i18n_token);
  3461     switch (result) {
  3462     case SQLITE_ROW:
  3463         _phrase = (const char *) sqlite3_column_text(session->i18n_token, 0);
  3464         break;
  3465 
  3466     case SQLITE_DONE:
  3467         status = PEP_PHRASE_NOT_FOUND;
  3468         break;
  3469 
  3470     default:
  3471         status = PEP_UNKNOWN_ERROR;
  3472     }
  3473 
  3474     if (status == PEP_STATUS_OK) {
  3475         *phrase = strdup(_phrase);
  3476         if (*phrase == NULL)
  3477             goto enomem;
  3478     }
  3479 
  3480     sqlite3_reset(session->i18n_token);
  3481     goto the_end;
  3482 
  3483 enomem:
  3484     status = PEP_OUT_OF_MEMORY;
  3485 
  3486 the_end:
  3487     return status;
  3488 }
  3489 
  3490 static PEP_STATUS _get_sequence_value(PEP_SESSION session, const char *name,
  3491         int32_t *value)
  3492 {
  3493     assert(session && name && value);
  3494     if (!(session && name && value))
  3495         return PEP_ILLEGAL_VALUE;
  3496 
  3497     PEP_STATUS status = PEP_STATUS_OK;
  3498 
  3499     sqlite3_reset(session->sequence_value2);
  3500     sqlite3_bind_text(session->sequence_value2, 1, name, -1,
  3501             SQLITE_STATIC);
  3502     int result = sqlite3_step(session->sequence_value2);
  3503     switch (result) {
  3504         case SQLITE_ROW: {
  3505             int32_t _value = (int32_t)
  3506                     sqlite3_column_int(session->sequence_value2, 0);
  3507             int _own = (int)
  3508                     sqlite3_column_int(session->sequence_value2, 1);
  3509             *value = _value;
  3510             if (_own)
  3511                 status = PEP_OWN_SEQUENCE;
  3512             break;
  3513         }
  3514         case SQLITE_DONE:
  3515             status = PEP_RECORD_NOT_FOUND;
  3516             break;
  3517         default:
  3518             status = PEP_UNKNOWN_ERROR;
  3519     }
  3520     sqlite3_reset(session->sequence_value2);
  3521 
  3522     return status;
  3523 }
  3524 
  3525 static PEP_STATUS _increment_sequence_value(PEP_SESSION session,
  3526         const char *name, int own)
  3527 {
  3528     assert(session && name);
  3529     if (!(session && name))
  3530         return PEP_ILLEGAL_VALUE;
  3531 
  3532     sqlite3_reset(session->sequence_value1);
  3533     sqlite3_bind_text(session->sequence_value1, 1, name, -1, SQLITE_STATIC);
  3534     sqlite3_bind_int(session->sequence_value1, 2, own);
  3535     int result = sqlite3_step(session->sequence_value1);
  3536     assert(result == SQLITE_DONE);
  3537     sqlite3_reset(session->sequence_value1);
  3538     if (result == SQLITE_DONE)
  3539         return PEP_STATUS_OK;
  3540     else
  3541         return PEP_CANNOT_INCREASE_SEQUENCE;
  3542 }
  3543 
  3544 static PEP_STATUS _set_sequence_value(PEP_SESSION session,
  3545         const char *name, int32_t value, int own)
  3546 {
  3547     assert(session && name && value > 0);
  3548     if (!(session && name && value > 0))
  3549         return PEP_ILLEGAL_VALUE;
  3550 
  3551     sqlite3_reset(session->sequence_value3);
  3552     sqlite3_bind_text(session->sequence_value3, 1, name, -1, SQLITE_STATIC);
  3553     sqlite3_bind_int(session->sequence_value3, 2, value);
  3554     sqlite3_bind_int(session->sequence_value3, 3, own);
  3555     int result = sqlite3_step(session->sequence_value3);
  3556     assert(result == SQLITE_DONE);
  3557     sqlite3_reset(session->sequence_value3);
  3558     if (result == SQLITE_DONE)
  3559         return PEP_STATUS_OK;
  3560     else
  3561         return PEP_CANNOT_SET_SEQUENCE_VALUE;
  3562 }
  3563 
  3564 DYNAMIC_API PEP_STATUS sequence_value(
  3565         PEP_SESSION session,
  3566         char *name,
  3567         int32_t *value
  3568     )
  3569 {
  3570     PEP_STATUS status = PEP_STATUS_OK;
  3571     int result;
  3572 
  3573     assert(session);
  3574     assert(name && value && *value >= 0);
  3575 
  3576     if (!(session && name && value && *value >= 0))
  3577         return PEP_ILLEGAL_VALUE;
  3578 
  3579     int own = 0;
  3580     if (!name[0]) {
  3581         pEpUUID uuid;
  3582         uuid_generate_random(uuid);
  3583         uuid_unparse_upper(uuid, name);
  3584         own = 1;
  3585     }
  3586     else {
  3587         if (name == session->sync_session->sync_uuid || 
  3588             strcmp(name, session->sync_session->sync_uuid) == 0)
  3589             own = 1;
  3590     }
  3591 
  3592     if (*value) {
  3593         sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  3594         int32_t old_value = 0;
  3595         status = _get_sequence_value(session, name, &old_value);
  3596         if (status != PEP_STATUS_OK && status != PEP_RECORD_NOT_FOUND)
  3597         {
  3598             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3599             return status;
  3600         }
  3601 
  3602         if (old_value >= *value) {
  3603             sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3604             return PEP_SEQUENCE_VIOLATED;
  3605         }
  3606         else {
  3607             status = _set_sequence_value(session, name, *value, own);
  3608             if (status == PEP_STATUS_OK) {
  3609                 result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  3610                 if (result == SQLITE_OK)
  3611                     return PEP_STATUS_OK;
  3612                 else
  3613                     return PEP_COMMIT_FAILED;
  3614             } else {
  3615                 sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3616                 return status;
  3617             }
  3618         }
  3619     }
  3620 
  3621     assert(*value == 0);
  3622     sqlite3_exec(session->db, "BEGIN TRANSACTION ;", NULL, NULL, NULL);
  3623     status = _increment_sequence_value(session, name, own);
  3624     if (status == PEP_STATUS_OK) {
  3625         status = _get_sequence_value(session, name, value);
  3626     }
  3627     if (status == PEP_STATUS_OK || status == PEP_OWN_SEQUENCE) {
  3628         result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  3629         if (result == SQLITE_OK){
  3630             assert(*value < INT32_MAX);
  3631             if (*value == INT32_MAX){
  3632                 return PEP_CANNOT_INCREASE_SEQUENCE;
  3633             }
  3634             return status;
  3635         } else {
  3636             return PEP_COMMIT_FAILED;
  3637         }
  3638     } else {
  3639         sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  3640         return status;
  3641     }
  3642     return status;
  3643 }
  3644 
  3645 DYNAMIC_API PEP_STATUS set_revoked(
  3646        PEP_SESSION session,
  3647        const char *revoked_fpr,
  3648        const char *replacement_fpr,
  3649        const uint64_t revocation_date
  3650     )
  3651 {
  3652     PEP_STATUS status = PEP_STATUS_OK;
  3653     
  3654     assert(session &&
  3655            revoked_fpr && revoked_fpr[0] &&
  3656            replacement_fpr && replacement_fpr[0]
  3657           );
  3658     
  3659     if (!(session &&
  3660           revoked_fpr && revoked_fpr[0] &&
  3661           replacement_fpr && replacement_fpr[0]
  3662          ))
  3663         return PEP_ILLEGAL_VALUE;
  3664     
  3665     sqlite3_reset(session->set_revoked);
  3666     sqlite3_bind_text(session->set_revoked, 1, revoked_fpr, -1, SQLITE_STATIC);
  3667     sqlite3_bind_text(session->set_revoked, 2, replacement_fpr, -1,
  3668             SQLITE_STATIC);
  3669     sqlite3_bind_int64(session->set_revoked, 3, revocation_date);
  3670 
  3671     int result;
  3672     
  3673     result = sqlite3_step(session->set_revoked);
  3674     switch (result) {
  3675         case SQLITE_DONE:
  3676             status = PEP_STATUS_OK;
  3677             break;
  3678             
  3679         default:
  3680             status = PEP_UNKNOWN_ERROR;
  3681     }
  3682     
  3683     sqlite3_reset(session->set_revoked);
  3684     return status;
  3685 }
  3686 
  3687 DYNAMIC_API PEP_STATUS get_revoked(
  3688         PEP_SESSION session,
  3689         const char *fpr,
  3690         char **revoked_fpr,
  3691         uint64_t *revocation_date
  3692     )
  3693 {
  3694     PEP_STATUS status = PEP_STATUS_OK;
  3695 
  3696     assert(session &&
  3697            revoked_fpr &&
  3698            fpr && fpr[0]
  3699           );
  3700     
  3701     if (!(session &&
  3702            revoked_fpr &&
  3703            fpr && fpr[0]
  3704           ))
  3705         return PEP_ILLEGAL_VALUE;
  3706 
  3707     *revoked_fpr = NULL;
  3708     *revocation_date = 0;
  3709 
  3710     sqlite3_reset(session->get_revoked);
  3711     sqlite3_bind_text(session->get_revoked, 1, fpr, -1, SQLITE_STATIC);
  3712 
  3713     int result;
  3714     
  3715     result = sqlite3_step(session->get_revoked);
  3716     switch (result) {
  3717         case SQLITE_ROW: {
  3718             *revoked_fpr = strdup((const char *)
  3719                     sqlite3_column_text(session->get_revoked, 0));
  3720             if(*revoked_fpr)
  3721                 *revocation_date = sqlite3_column_int64(session->get_revoked,
  3722                         1);
  3723             else
  3724                 status = PEP_OUT_OF_MEMORY;
  3725 
  3726             break;
  3727         }
  3728         default:
  3729             status = PEP_CANNOT_FIND_IDENTITY;
  3730     }
  3731 
  3732     sqlite3_reset(session->get_revoked);
  3733 
  3734     return status;
  3735 }
  3736 
  3737 PEP_STATUS key_created(
  3738         PEP_SESSION session,
  3739         const char *fpr,
  3740         time_t *created
  3741     )
  3742 {
  3743     assert(session && fpr && created);
  3744     if (!(session && fpr && created))
  3745         return PEP_ILLEGAL_VALUE;
  3746 
  3747     return session->cryptotech[PEP_crypt_OpenPGP].key_created(session, fpr,
  3748             created);
  3749 }
  3750 
  3751 PEP_STATUS find_private_keys(PEP_SESSION session, const char* pattern,
  3752                              stringlist_t **keylist) {
  3753     assert(session && keylist);
  3754     if (!(session && keylist))
  3755         return PEP_ILLEGAL_VALUE;
  3756     
  3757     return session->cryptotech[PEP_crypt_OpenPGP].find_private_keys(session, pattern,
  3758                                                                     keylist);
  3759 }
  3760 
  3761 PEP_STATUS import_trusted_own_keys(PEP_SESSION session) {
  3762     assert(session);
  3763     if (!session)
  3764         return PEP_ILLEGAL_VALUE;
  3765         
  3766     return session->cryptotech[PEP_crypt_OpenPGP].import_trusted_own_keys(session); 
  3767 }
  3768 
  3769 DYNAMIC_API const char* get_engine_version() {
  3770     return PEP_ENGINE_VERSION;
  3771 }
  3772 
  3773 
  3774 DYNAMIC_API PEP_STATUS reset_peptest_hack(PEP_SESSION session)
  3775 {
  3776     assert(session);
  3777 
  3778     if (!session)
  3779         return PEP_ILLEGAL_VALUE;
  3780 
  3781     int int_result = sqlite3_exec(
  3782         session->db,
  3783         "delete from identity where address like '%@peptest.ch' ;",
  3784         NULL,
  3785         NULL,
  3786         NULL
  3787     );
  3788     assert(int_result == SQLITE_OK);
  3789 
  3790     if (int_result != SQLITE_OK)
  3791         return PEP_UNKNOWN_ERROR;
  3792 
  3793     return PEP_STATUS_OK;
  3794 }
  3795 
  3796 #ifdef DEBUG_ERRORSTACK
  3797 PEP_STATUS session_add_error(PEP_SESSION session, const char* file, unsigned line, PEP_STATUS status)
  3798 {
  3799     char logline[48];
  3800     if(status>0)
  3801     {
  3802         snprintf(logline,47, "%.24s:%u status=%u (0x%x)", file, line, status, status);
  3803     }else{
  3804         snprintf(logline,47, "%.24s:%u status=%i.", file, line, status);
  3805     }
  3806     stringlist_add(session->errorstack, logline); // logline is copied! :-)
  3807     return status;
  3808 }
  3809 
  3810 DYNAMIC_API const stringlist_t* get_errorstack(PEP_SESSION session)
  3811 {
  3812     return session->errorstack;
  3813 }
  3814 
  3815 DYNAMIC_API void clear_errorstack(PEP_SESSION session)
  3816 {
  3817     const int old_len = stringlist_length(session->errorstack);
  3818     char buf[48];
  3819     free_stringlist(session->errorstack);
  3820     snprintf(buf, 47, "(%i elements cleared)", old_len);
  3821     session->errorstack = new_stringlist(buf);
  3822 }
  3823 
  3824 #else
  3825 
  3826 static stringlist_t* dummy_errorstack = NULL;
  3827 
  3828 DYNAMIC_API const stringlist_t* get_errorstack(PEP_SESSION session)
  3829 {
  3830     if(dummy_errorstack == NULL)
  3831     {
  3832         dummy_errorstack = new_stringlist("( Please recompile pEpEngine with -DDEBUG_ERRORSTACK )");
  3833     }
  3834 
  3835     return dummy_errorstack;
  3836 }
  3837 
  3838 DYNAMIC_API void clear_errorstack(PEP_SESSION session)
  3839 {
  3840     // nothing to do here
  3841 }
  3842 
  3843 #endif