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