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