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