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