src/pEpEngine.c
author Krista Bennett <krista@pep-project.org>
Tue, 27 Jun 2017 14:35:21 +0200
branchENGINE-171
changeset 1884 3e00ee967471
parent 1868 a3bf01e38752
child 1887 3feebd18c35f
permissions -rw-r--r--
ENGINE-171: version which should not evaluate each of the three cases every time, plus overloaded lower() function. This one passes the current tests, meaning it doesn't screw up what already words.
vb@1517
     1
// This file is under GNU General Public License 3.0
vb@1517
     2
// see LICENSE.txt
vb@1517
     3
vb@125
     4
#include "pEp_internal.h"
vb@98
     5
#include "dynamic_api.h"
vb@28
     6
#include "cryptotech.h"
vb@28
     7
#include "transport.h"
vb@515
     8
#include "blacklist.h"
vb@944
     9
#include "sync_fsm.h"
vb@0
    10
vb@221
    11
static int init_count = -1;
vb@62
    12
krista@1884
    13
// sql overloaded functions - modified from sqlite3.c
krista@1884
    14
static void _sql_lower(sqlite3_context* ctx, int argc, sqlite3_value** argv) {
krista@1884
    15
    char *z1;
krista@1884
    16
    const char *z2;
krista@1884
    17
    int i, n;
krista@1884
    18
    z2 = (char*)sqlite3_value_text(argv[0]);
krista@1884
    19
    n = sqlite3_value_bytes(argv[0]);
krista@1884
    20
    /* Verify that the call to _bytes() does not invalidate the _text() pointer */
krista@1884
    21
    assert( z2==(char*)sqlite3_value_text(argv[0]) );
krista@1884
    22
    if( z2 ){
krista@1884
    23
        z1 = (char*)sqlite3_malloc(n+1);
krista@1884
    24
        if( z1 ){
krista@1884
    25
            for(i=0; i<n; i++){
krista@1884
    26
                char c = z2[i];
krista@1884
    27
                char c_mod = c | 0x20;
krista@1884
    28
                if (c_mod < 0x61 || c_mod > 0x7a)
krista@1884
    29
                    c_mod = c;
krista@1884
    30
                z1[i] = c_mod;
krista@1884
    31
            }
krista@1884
    32
            z1[n] = '\0';
krista@1884
    33
            sqlite3_result_text(ctx, z1, n, sqlite3_free);
krista@1884
    34
        }
krista@1884
    35
    }
krista@1884
    36
}
krista@1884
    37
krista@1884
    38
edouard@1518
    39
// sql manipulation statements
edouard@1518
    40
static const char *sql_log = 
edouard@1518
    41
    "insert into log (title, entity, description, comment)"
edouard@1518
    42
     "values (?1, ?2, ?3, ?4);";
edouard@1518
    43
edouard@1518
    44
static const char *sql_trustword = 
edouard@1518
    45
    "select id, word from wordlist where lang = lower(?1) "
edouard@1518
    46
    "and id = ?2 ;";
edouard@1518
    47
krista@1884
    48
    //    where (case when address = "JOEGtestuser@testdomain.org" then (1) else 0 end) = 1
krista@1884
    49
edouard@1518
    50
static const char *sql_get_identity =  
edouard@1518
    51
    "select fpr, username, comm_type, lang,"
edouard@1518
    52
    "   identity.flags | pgp_keypair.flags"
edouard@1518
    53
    "   from identity"
edouard@1518
    54
    "   join person on id = identity.user_id"
edouard@1518
    55
    "   join pgp_keypair on fpr = identity.main_key_id"
edouard@1518
    56
    "   join trust on id = trust.user_id"
krista@1884
    57
    "       and pgp_keypair_fpr = identity.main_key_id"    
krista@1884
    58
    "   where (case when (address = ?1) then (1)"
krista@1884
    59
    "               when (lower(address) = lower(?1)) then (1)"
krista@1884
    60
    "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1)"
krista@1884
    61
    "               else 0"
krista@1884
    62
    "          end) = 1"
krista@1868
    63
    "   and identity.user_id = ?2;";
edouard@1518
    64
krista@1799
    65
static const char *sql_replace_identities_fpr =  
krista@1799
    66
    "update identity"
krista@1799
    67
    "   set main_key_id = ?1 "
krista@1799
    68
    "   where main_key_id = ?2 ;";
krista@1793
    69
edouard@1518
    70
// Set person, but if already exist, only update.
edouard@1518
    71
// if main_key_id already set, don't touch.
edouard@1518
    72
static const char *sql_set_person = 
edouard@1518
    73
    "insert or replace into person (id, username, lang, main_key_id, device_group)"
edouard@1518
    74
    "  values (?1, ?2, ?3,"
edouard@1518
    75
    "    (select coalesce((select main_key_id from person "
edouard@1518
    76
    "      where id = ?1), upper(replace(?4,' ','')))),"
edouard@1518
    77
    "    (select device_group from person where id = ?1)) ;";
edouard@1518
    78
edouard@1518
    79
static const char *sql_set_device_group = 
edouard@1518
    80
    "update person set device_group = ?1 "
edouard@1518
    81
    "where id = '" PEP_OWN_USERID "';";
edouard@1518
    82
edouard@1518
    83
static const char *sql_get_device_group = 
edouard@1518
    84
    "select device_group from person "
edouard@1518
    85
    "where id = '" PEP_OWN_USERID "';";
edouard@1518
    86
edouard@1518
    87
static const char *sql_set_pgp_keypair = 
edouard@1518
    88
    "insert or replace into pgp_keypair (fpr) "
edouard@1518
    89
    "values (upper(replace(?1,' ',''))) ;";
edouard@1518
    90
edouard@1518
    91
static const char *sql_set_identity = 
edouard@1518
    92
    "insert or replace into identity ("
edouard@1518
    93
    " address, main_key_id, "
edouard@1518
    94
    " user_id, flags"
edouard@1518
    95
    ") values ("
edouard@1518
    96
    " ?1,"
edouard@1518
    97
    " upper(replace(?2,' ','')),"
edouard@1518
    98
    " ?3,"
edouard@1518
    99
    // " (select"
edouard@1518
   100
    // "   coalesce("
edouard@1518
   101
    // "    (select flags from identity"
edouard@1518
   102
    // "     where address = ?1 and"
edouard@1518
   103
    // "           user_id = ?3),"
edouard@1518
   104
    // "    0)"
edouard@1518
   105
    // " ) | (?4 & 255)"
edouard@1518
   106
    /* set_identity ignores previous flags, and doesn't filter machine flags */
edouard@1518
   107
    " ?4"
edouard@1518
   108
    ");";
edouard@1518
   109
        
edouard@1518
   110
static const char *sql_set_identity_flags = 
edouard@1518
   111
    "update identity set flags = "
edouard@1518
   112
    "    ((?1 & 255) | (select flags from identity"
edouard@1518
   113
    "                   where address = ?2 and user_id = ?3)) "
edouard@1518
   114
    "where address = ?2 and user_id = ?3 ;";
edouard@1518
   115
edouard@1518
   116
static const char *sql_unset_identity_flags = 
edouard@1518
   117
    "update identity set flags = "
edouard@1518
   118
    "    ( ~(?1 & 255) & (select flags from identity"
edouard@1518
   119
    "                   where address = ?2 and user_id = ?3)) "
edouard@1518
   120
    "where address = ?2 and user_id = ?3 ;";
edouard@1518
   121
edouard@1518
   122
static const char *sql_set_trust =
edouard@1518
   123
    "insert or replace into trust (user_id, pgp_keypair_fpr, comm_type) "
edouard@1518
   124
    "values (?1, upper(replace(?2,' ','')), ?3) ;";
edouard@1518
   125
krista@1799
   126
static const char *sql_update_trust_for_fpr =
krista@1799
   127
    "update trust "
krista@1799
   128
    "set comm_type = ?1 "
krista@1799
   129
    "where pgp_keypair_fpr = upper(replace(?2,' ','')) ;";
krista@1799
   130
edouard@1518
   131
static const char *sql_get_trust = 
edouard@1518
   132
    "select comm_type from trust where user_id = ?1 "
edouard@1518
   133
    "and pgp_keypair_fpr = upper(replace(?2,' ','')) ;";
edouard@1518
   134
edouard@1518
   135
static const char *sql_least_trust = 
edouard@1632
   136
    "select min(comm_type) from trust where"
edouard@1632
   137
    " pgp_keypair_fpr = upper(replace(?1,' ',''))"
edouard@1632
   138
    " and comm_type != 0;"; // ignores PEP_ct_unknown
edouard@1632
   139
    // returns PEP_ct_unknown only when no known trust is recorded
edouard@1518
   140
edouard@1518
   141
static const char *sql_mark_as_compromized = 
edouard@1518
   142
    "update trust not indexed set comm_type = 15"
edouard@1518
   143
    " where pgp_keypair_fpr = upper(replace(?1,' ','')) ;";
edouard@1518
   144
edouard@1518
   145
static const char *sql_crashdump = 
edouard@1518
   146
    "select timestamp, title, entity, description, comment"
edouard@1518
   147
    " from log order by timestamp desc limit ?1 ;";
edouard@1518
   148
edouard@1518
   149
static const char *sql_languagelist = 
edouard@1518
   150
    "select i18n_language.lang, name, phrase" 
edouard@1518
   151
    " from i18n_language join i18n_token using (lang) where i18n_token.id = 1000;" ;
edouard@1518
   152
edouard@1518
   153
static const char *sql_i18n_token = 
edouard@1518
   154
    "select phrase from i18n_token where lang = lower(?1) and id = ?2 ;";
edouard@1518
   155
edouard@1518
   156
edouard@1518
   157
// blacklist
edouard@1518
   158
static const char *sql_blacklist_add = 
edouard@1518
   159
    "insert or replace into blacklist_keys (fpr) values (upper(replace(?1,' ',''))) ;"
edouard@1518
   160
    "delete from identity where main_key_id = upper(replace(?1,' ','')) ;"
edouard@1518
   161
    "delete from pgp_keypair where fpr = upper(replace(?1,' ','')) ;";
edouard@1518
   162
edouard@1518
   163
static const char *sql_blacklist_delete =
edouard@1518
   164
    "delete from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
edouard@1518
   165
edouard@1518
   166
static const char *sql_blacklist_is_listed = 
edouard@1518
   167
    "select count(*) from blacklist_keys where fpr = upper(replace(?1,' ','')) ;";
edouard@1518
   168
edouard@1518
   169
static const char *sql_blacklist_retrieve = 
edouard@1518
   170
    "select * from blacklist_keys ;";
edouard@1518
   171
                
edouard@1518
   172
edouard@1518
   173
// Own keys
edouard@1518
   174
static const char *sql_own_key_is_listed = 
edouard@1518
   175
    "select count(*) from ("
edouard@1518
   176
    " select main_key_id from person "
edouard@1518
   177
    "   where main_key_id = upper(replace(?1,' ',''))"
edouard@1518
   178
    "    and id = '" PEP_OWN_USERID "' "
edouard@1518
   179
    " union "
edouard@1518
   180
    "  select main_key_id from identity "
edouard@1518
   181
    "   where main_key_id = upper(replace(?1,' ',''))"
edouard@1752
   182
    "    and user_id = '" PEP_OWN_USERID "' "
edouard@1752
   183
    " union "
edouard@1757
   184
    "  select fpr from own_keys "
edouard@1752
   185
    "   where fpr = upper(replace(?1,' ',''))"
edouard@1752
   186
    " );";
edouard@1518
   187
edouard@1518
   188
static const char *sql_own_identities_retrieve =  
edouard@1518
   189
    "select address, fpr, username, "
edouard@1518
   190
    "   lang, identity.flags | pgp_keypair.flags"
edouard@1518
   191
    "   from identity"
edouard@1518
   192
    "   join person on id = identity.user_id"
edouard@1518
   193
    "   join pgp_keypair on fpr = identity.main_key_id"
edouard@1518
   194
    "   join trust on id = trust.user_id"
edouard@1518
   195
    "       and pgp_keypair_fpr = identity.main_key_id"
edouard@1518
   196
    "   where identity.user_id = '" PEP_OWN_USERID "'"
edouard@1518
   197
    "       and (identity.flags & ?1) = 0;";
edouard@1518
   198
        
edouard@1518
   199
static const char *sql_own_keys_retrieve =  
edouard@1518
   200
    "select fpr from own_keys"
edouard@1518
   201
    "   natural join identity"
edouard@1518
   202
    "   where (identity.flags & ?1) = 0;";
edouard@1518
   203
edouard@1518
   204
static const char *sql_set_own_key = 
edouard@1518
   205
    "insert or replace into own_keys (address, user_id, fpr)"
edouard@1518
   206
    " values (?1, '" PEP_OWN_USERID "', upper(replace(?2,' ','')));";
edouard@1518
   207
edouard@1518
   208
edouard@1518
   209
// Sequence
edouard@1518
   210
static const char *sql_sequence_value1 = 
edouard@1518
   211
    "insert or replace into sequences (name, value, own) "
edouard@1518
   212
    "values (?1, "
edouard@1602
   213
    "       (select coalesce((select value + 1 from sequences "
edouard@1602
   214
    "           where name = ?1), 1 )), "
edouard@1602
   215
    "       (select coalesce((select own or ?2 from sequences "
edouard@1602
   216
    "           where name = ?1), ?2))) ; ";
edouard@1518
   217
edouard@1518
   218
static const char *sql_sequence_value2 = 
edouard@1518
   219
    "select value, own from sequences where name = ?1 ;";
edouard@1518
   220
edouard@1518
   221
static const char *sql_sequence_value3 = 
edouard@1636
   222
    "insert or replace into sequences (name, value, own) "
edouard@1636
   223
    "values (?1, "
edouard@1636
   224
    "        ?2, "
edouard@1636
   225
    "       (select coalesce((select own or ?3 from sequences "
edouard@1636
   226
    "           where name = ?1), ?3))) ; ";
edouard@1518
   227
        
edouard@1518
   228
// Revocation tracking
edouard@1518
   229
static const char *sql_set_revoked =
edouard@1518
   230
    "insert or replace into revoked_keys ("
edouard@1518
   231
    "    revoked_fpr, replacement_fpr, revocation_date) "
edouard@1518
   232
    "values (upper(replace(?1,' ','')),"
edouard@1518
   233
    "        upper(replace(?2,' ','')),"
edouard@1518
   234
    "        ?3) ;";
edouard@1518
   235
        
edouard@1518
   236
static const char *sql_get_revoked = 
edouard@1518
   237
    "select revoked_fpr, revocation_date from revoked_keys"
edouard@1518
   238
    "    where replacement_fpr = upper(replace(?1,' ','')) ;";
edouard@1518
   239
vb@928
   240
static int user_version(void *_version, int count, char **text, char **name)
vb@928
   241
{
vb@928
   242
    assert(_version);
vb@928
   243
    assert(count == 1);
vb@928
   244
    assert(text && text[0]);
vb@928
   245
    if (!(_version && count == 1 && text && text[0]))
vb@928
   246
        return -1;
vb@928
   247
vb@928
   248
    int *version = (int *) _version;
vb@928
   249
    *version = atoi(text[0]);
vb@928
   250
    return 0;
vb@928
   251
}
vb@928
   252
vb@0
   253
DYNAMIC_API PEP_STATUS init(PEP_SESSION *session)
vb@0
   254
{
vb@65
   255
    PEP_STATUS status = PEP_STATUS_OK;
roker@529
   256
    int int_result;
Edouard@693
   257
    
vb@62
   258
    bool in_first = false;
edouard@1752
   259
    bool very_first = false;
vb@8
   260
vb@62
   261
    assert(sqlite3_threadsafe());
vb@62
   262
    if (!sqlite3_threadsafe())
vb@62
   263
        return PEP_INIT_SQLITE3_WITHOUT_MUTEX;
vb@62
   264
vb@62
   265
    // a little race condition - but still a race condition
vb@113
   266
    // mitigated by calling caveat (see documentation)
vb@62
   267
vb@62
   268
    ++init_count;
vb@67
   269
    if (init_count == 0)
vb@62
   270
        in_first = true;
vb@0
   271
roker@529
   272
    assert(session);
vb@191
   273
    if (session == NULL)
vb@191
   274
        return PEP_ILLEGAL_VALUE;
vb@191
   275
roker@529
   276
    *session = NULL;
vb@0
   277
vb@107
   278
    pEpSession *_session = calloc(1, sizeof(pEpSession));
roker@529
   279
    assert(_session);
roker@529
   280
    if (_session == NULL)
roker@529
   281
        goto enomem;
vb@62
   282
roker@529
   283
    _session->version = PEP_ENGINE_VERSION;
vb@0
   284
roker@1722
   285
#ifdef DEBUG_ERRORSTACK
roker@1801
   286
    _session->errorstack = new_stringlist("init()");
roker@1722
   287
#endif
roker@1722
   288
vb@0
   289
    assert(LOCAL_DB);
vb@0
   290
    if (LOCAL_DB == NULL) {
vb@65
   291
        status = PEP_INIT_CANNOT_OPEN_DB;
vb@65
   292
        goto pep_error;
vb@0
   293
    }
vb@0
   294
roker@529
   295
    int_result = sqlite3_open_v2(
roker@529
   296
            LOCAL_DB,
roker@529
   297
            &_session->db,
roker@529
   298
            SQLITE_OPEN_READWRITE
roker@529
   299
                | SQLITE_OPEN_CREATE
roker@529
   300
                | SQLITE_OPEN_FULLMUTEX
roker@529
   301
                | SQLITE_OPEN_PRIVATECACHE,
roker@529
   302
            NULL 
roker@529
   303
        );
vb@0
   304
roker@529
   305
    if (int_result != SQLITE_OK) {
roker@529
   306
        status = PEP_INIT_CANNOT_OPEN_DB;
vb@65
   307
        goto pep_error;
roker@529
   308
    }
vb@0
   309
roker@529
   310
    sqlite3_busy_timeout(_session->db, BUSY_WAIT_TIME);
vb@0
   311
vb@0
   312
    assert(SYSTEM_DB);
vb@0
   313
    if (SYSTEM_DB == NULL) {
roker@529
   314
        status = PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
vb@65
   315
        goto pep_error;
vb@0
   316
    }
vb@0
   317
roker@529
   318
    int_result = sqlite3_open_v2(
roker@529
   319
            SYSTEM_DB, &_session->system_db,
roker@529
   320
            SQLITE_OPEN_READONLY
roker@529
   321
                | SQLITE_OPEN_FULLMUTEX
roker@529
   322
                | SQLITE_OPEN_SHAREDCACHE,
roker@529
   323
            NULL
roker@529
   324
        );
vb@0
   325
roker@529
   326
    if (int_result != SQLITE_OK) {
roker@529
   327
        status = PEP_INIT_CANNOT_OPEN_SYSTEM_DB;
vb@65
   328
        goto pep_error;
roker@529
   329
    }
vb@0
   330
roker@529
   331
    sqlite3_busy_timeout(_session->system_db, 1000);
vb@0
   332
vb@928
   333
// increment this when patching DDL
vb@1453
   334
#define _DDL_USER_VERSION "5"
vb@928
   335
vb@62
   336
    if (in_first) {
vb@1091
   337
vb@62
   338
        int_result = sqlite3_exec(
vb@62
   339
            _session->db,
vb@1008
   340
                "create table if not exists version_info (\n"
vb@456
   341
                "   id integer primary key,\n"
vb@1085
   342
                "   timestamp integer default (datetime('now')),\n"
vb@456
   343
                "   version text,\n"
vb@456
   344
                "   comment text\n"
vb@928
   345
                ");\n",
vb@928
   346
                NULL,
vb@928
   347
                NULL,
vb@928
   348
                NULL
vb@928
   349
        );
vb@928
   350
        int_result = sqlite3_exec(
vb@928
   351
            _session->db,
vb@948
   352
                "PRAGMA application_id = 0x23423423;\n"
vb@456
   353
                "create table if not exists log (\n"
vb@1085
   354
                "   timestamp integer default (datetime('now')),\n"
vb@456
   355
                "   title text not null,\n"
vb@456
   356
                "   entity text not null,\n"
vb@456
   357
                "   description text,\n"
vb@456
   358
                "   comment text\n"
vb@456
   359
                ");\n"
vb@456
   360
                "create index if not exists log_timestamp on log (\n"
vb@456
   361
                "   timestamp\n"
vb@456
   362
                ");\n"
vb@456
   363
                "create table if not exists pgp_keypair (\n"
vb@456
   364
                "   fpr text primary key,\n"
vb@456
   365
                "   created integer,\n"
vb@456
   366
                "   expires integer,\n"
vb@944
   367
                "   comment text,\n"
vb@1085
   368
                "   flags integer default 0\n"
vb@456
   369
                ");\n"
vb@456
   370
                "create index if not exists pgp_keypair_expires on pgp_keypair (\n"
vb@456
   371
                "   expires\n"
vb@456
   372
                ");\n"
vb@456
   373
                "create table if not exists person (\n"
vb@456
   374
                "   id text primary key,\n"
vb@456
   375
                "   username text not null,\n"
vb@456
   376
                "   main_key_id text\n"
vb@456
   377
                "       references pgp_keypair (fpr)\n"
vb@456
   378
                "       on delete set null,\n"
vb@456
   379
                "   lang text,\n"
vb@951
   380
                "   comment text,\n"
vb@951
   381
                "   device_group text\n"
vb@456
   382
                ");\n"
vb@456
   383
                "create table if not exists identity (\n"
Edouard@559
   384
                "   address text,\n"
vb@456
   385
                "   user_id text\n"
vb@456
   386
                "       references person (id)\n"
vb@456
   387
                "       on delete cascade,\n"
vb@456
   388
                "   main_key_id text\n"
vb@456
   389
                "       references pgp_keypair (fpr)\n"
vb@456
   390
                "       on delete set null,\n"
Edouard@559
   391
                "   comment text,\n"
vb@1085
   392
                "   flags integer default 0,"
Edouard@559
   393
                "   primary key (address, user_id)\n"
vb@456
   394
                ");\n"
vb@456
   395
                "create table if not exists trust (\n"
vb@456
   396
                "   user_id text not null\n"
vb@456
   397
                "       references person (id)\n"
vb@456
   398
                "       on delete cascade,\n"
vb@456
   399
                "   pgp_keypair_fpr text not null\n"
vb@456
   400
                "       references pgp_keypair (fpr)\n"
vb@456
   401
                "       on delete cascade,\n"
vb@456
   402
                "   comm_type integer not null,\n"
Edouard@684
   403
                "   comment text,\n"
Edouard@684
   404
                "   primary key (user_id, pgp_keypair_fpr)\n"
vb@456
   405
                ");\n"
fdik@494
   406
                // blacklist
vb@456
   407
                "create table if not exists blacklist_keys (\n"
vb@456
   408
                "   fpr text primary key\n"
vb@456
   409
                ");\n"
vb@632
   410
                // sequences
vb@632
   411
                "create table if not exists sequences(\n"
vb@632
   412
                "   name text primary key,\n"
vb@1085
   413
                "   value integer default 0,\n"
vb@1085
   414
                "   own integer default 0\n"
vb@632
   415
                ");\n"
Edouard@693
   416
                "create table if not exists revoked_keys (\n"
Edouard@693
   417
                "   revoked_fpr text primary key,\n"
Edouard@693
   418
                "   replacement_fpr text not null\n"
Edouard@693
   419
                "       references pgp_keypair (fpr)\n"
Edouard@693
   420
                "       on delete cascade,\n"
Edouard@693
   421
                "   revocation_date integer\n"
Edouard@693
   422
                ");\n"
edouard@1394
   423
                "create table if not exists own_keys (\n"
edouard@1394
   424
                "   address text,\n"
edouard@1394
   425
                "   user_id text,\n"
edouard@1395
   426
                "   fpr text not null\n"
edouard@1394
   427
                "       references pgp_keypair (fpr)\n"
edouard@1394
   428
                "       on delete cascade,\n"
edouard@1394
   429
                "   foreign key (address, user_id)\n"
edouard@1394
   430
                "       references identity\n"
edouard@1394
   431
                "       on delete cascade,\n"
edouard@1394
   432
                "   check (user_id = '" PEP_OWN_USERID "')\n"
edouard@1401
   433
                "   primary key (address, fpr)\n"
edouard@1394
   434
                ");\n" 
vb@456
   435
                ,
vb@62
   436
            NULL,
vb@62
   437
            NULL,
vb@62
   438
            NULL
vb@62
   439
        );
vb@62
   440
        assert(int_result == SQLITE_OK);
vb@0
   441
vb@928
   442
        int version;
vb@62
   443
        int_result = sqlite3_exec(
vb@62
   444
            _session->db,
vb@928
   445
            "pragma user_version;",
vb@928
   446
            user_version,
vb@928
   447
            &version,
vb@62
   448
            NULL
vb@62
   449
        );
krista@1884
   450
krista@1884
   451
        assert(int_result == SQLITE_OK);
krista@1884
   452
        
krista@1884
   453
        void (*xFunc_lower)(sqlite3_context*,int,sqlite3_value**) = &_sql_lower;
krista@1884
   454
        
krista@1884
   455
        int_result = sqlite3_create_function_v2(
krista@1884
   456
            _session->db,
krista@1884
   457
            "lower",
krista@1884
   458
            1,
krista@1884
   459
            SQLITE_UTF8 | SQLITE_DETERMINISTIC,
krista@1884
   460
            NULL,
krista@1884
   461
            xFunc_lower,
krista@1884
   462
            NULL,
krista@1884
   463
            NULL,
krista@1884
   464
            NULL);
vb@62
   465
        assert(int_result == SQLITE_OK);
vb@0
   466
edouard@1604
   467
        if(version != 0) { 
edouard@1604
   468
            // Version has been already set
vb@934
   469
edouard@1604
   470
            // Early mistake : version 0 shouldn't have existed.
edouard@1604
   471
            // Numbering should have started at 1 to detect newly created DB.
edouard@1604
   472
            // Version 0 DBs are not anymore compatible.
krista@1032
   473
edouard@1604
   474
            // // Was version 0 compat code.
edouard@1604
   475
            // if (version < 1) {
edouard@1604
   476
            //     int_result = sqlite3_exec(
edouard@1604
   477
            //         _session->db,
edouard@1604
   478
            //         "alter table identity\n"
edouard@1604
   479
            //         "   add column flags integer default 0;\n",
edouard@1604
   480
            //         NULL,
edouard@1604
   481
            //         NULL,
edouard@1604
   482
            //         NULL
edouard@1604
   483
            //     );
edouard@1604
   484
            //     assert(int_result == SQLITE_OK);
edouard@1604
   485
            // }
vb@928
   486
edouard@1604
   487
            if (version < 2) {
edouard@1604
   488
                int_result = sqlite3_exec(
edouard@1604
   489
                    _session->db,
edouard@1604
   490
                    "alter table pgp_keypair\n"
edouard@1604
   491
                    "   add column flags integer default 0;\n"
edouard@1604
   492
                    "alter table person\n"
edouard@1604
   493
                    "   add column device_group text;\n",
edouard@1604
   494
                    NULL,
edouard@1604
   495
                    NULL,
edouard@1604
   496
                    NULL
edouard@1604
   497
                );
edouard@1604
   498
                assert(int_result == SQLITE_OK);
edouard@1604
   499
            }
edouard@1604
   500
edouard@1604
   501
            if (version < 3) {
edouard@1604
   502
                int_result = sqlite3_exec(
edouard@1604
   503
                    _session->db,
edouard@1604
   504
                    "alter table sequences\n"
edouard@1604
   505
                    "   add column own integer default 0;\n",
edouard@1604
   506
                    NULL,
edouard@1604
   507
                    NULL,
edouard@1604
   508
                    NULL
edouard@1604
   509
                );
edouard@1604
   510
                assert(int_result == SQLITE_OK);
edouard@1604
   511
            }
edouard@1604
   512
edouard@1604
   513
            if (version < 5) {
edouard@1604
   514
                int_result = sqlite3_exec(
edouard@1604
   515
                    _session->db,
edouard@1604
   516
                    "delete from pgp_keypair where fpr = '';",
edouard@1604
   517
                    NULL,
edouard@1604
   518
                    NULL,
edouard@1604
   519
                    NULL
edouard@1604
   520
                );
edouard@1604
   521
                assert(int_result == SQLITE_OK);
edouard@1604
   522
                int_result = sqlite3_exec(
edouard@1604
   523
                    _session->db,
edouard@1604
   524
                    "delete from trust where pgp_keypair_fpr = '';",
edouard@1604
   525
                    NULL,
edouard@1604
   526
                    NULL,
edouard@1604
   527
                    NULL
edouard@1604
   528
                );
edouard@1604
   529
                assert(int_result == SQLITE_OK);
edouard@1604
   530
            }
vb@1453
   531
        }
edouard@1752
   532
        else { 
edouard@1752
   533
            // Version from DB was 0, it means this is initial setup.
edouard@1752
   534
            // DB has just been created, and all tables are empty.
edouard@1752
   535
            very_first = true;
edouard@1752
   536
        }
vb@1453
   537
vb@928
   538
        if (version < atoi(_DDL_USER_VERSION)) {
vb@928
   539
            int_result = sqlite3_exec(
vb@928
   540
                _session->db,
vb@928
   541
                "pragma user_version = "_DDL_USER_VERSION";\n"
vb@928
   542
                "insert or replace into version_info (id, version)"
vb@928
   543
                    "values (1, '" PEP_ENGINE_VERSION "');",
vb@928
   544
                NULL,
vb@928
   545
                NULL,
vb@928
   546
                NULL
vb@928
   547
            );
vb@928
   548
            assert(int_result == SQLITE_OK);
vb@928
   549
        }
vb@62
   550
    }
vb@62
   551
vb@951
   552
    int_result = sqlite3_prepare_v2(_session->db, sql_log,
vb@951
   553
            (int)strlen(sql_log), &_session->log, NULL);
roker@529
   554
    assert(int_result == SQLITE_OK);
vb@0
   555
vb@233
   556
    int_result = sqlite3_prepare_v2(_session->system_db, sql_trustword,
Edouard@417
   557
            (int)strlen(sql_trustword), &_session->trustword, NULL);
roker@529
   558
    assert(int_result == SQLITE_OK);
vb@0
   559
vb@0
   560
    int_result = sqlite3_prepare_v2(_session->db, sql_get_identity,
Edouard@417
   561
            (int)strlen(sql_get_identity), &_session->get_identity, NULL);
roker@529
   562
    assert(int_result == SQLITE_OK);
vb@0
   563
krista@1799
   564
    int_result = sqlite3_prepare_v2(_session->db, sql_replace_identities_fpr,
krista@1799
   565
            (int)strlen(sql_replace_identities_fpr), 
krista@1799
   566
            &_session->replace_identities_fpr, NULL);
krista@1793
   567
    assert(int_result == SQLITE_OK);
krista@1793
   568
vb@0
   569
    int_result = sqlite3_prepare_v2(_session->db, sql_set_person,
Edouard@417
   570
            (int)strlen(sql_set_person), &_session->set_person, NULL);
vb@0
   571
    assert(int_result == SQLITE_OK);
vb@62
   572
edouard@1234
   573
    int_result = sqlite3_prepare_v2(_session->db, sql_set_device_group,
edouard@1234
   574
            (int)strlen(sql_set_device_group), &_session->set_device_group, NULL);
edouard@1234
   575
    assert(int_result == SQLITE_OK);
edouard@1234
   576
edouard@1235
   577
    int_result = sqlite3_prepare_v2(_session->db, sql_get_device_group,
edouard@1235
   578
            (int)strlen(sql_get_device_group), &_session->get_device_group, NULL);
edouard@1235
   579
    assert(int_result == SQLITE_OK);
edouard@1235
   580
vb@0
   581
    int_result = sqlite3_prepare_v2(_session->db, sql_set_pgp_keypair,
vb@951
   582
            (int)strlen(sql_set_pgp_keypair), &_session->set_pgp_keypair,
vb@951
   583
            NULL);
roker@529
   584
    assert(int_result == SQLITE_OK);
vb@62
   585
vb@0
   586
    int_result = sqlite3_prepare_v2(_session->db, sql_set_identity,
Edouard@417
   587
            (int)strlen(sql_set_identity), &_session->set_identity, NULL);
roker@529
   588
    assert(int_result == SQLITE_OK);
vb@62
   589
vb@932
   590
    int_result = sqlite3_prepare_v2(_session->db, sql_set_identity_flags,
vb@951
   591
            (int)strlen(sql_set_identity_flags), &_session->set_identity_flags,
vb@951
   592
            NULL);
vb@932
   593
    assert(int_result == SQLITE_OK);
vb@932
   594
edouard@1394
   595
    int_result = sqlite3_prepare_v2(_session->db, sql_unset_identity_flags,
edouard@1394
   596
            (int)strlen(sql_unset_identity_flags), &_session->unset_identity_flags,
edouard@1394
   597
            NULL);
edouard@1394
   598
    assert(int_result == SQLITE_OK);
edouard@1394
   599
vb@0
   600
    int_result = sqlite3_prepare_v2(_session->db, sql_set_trust,
Edouard@417
   601
            (int)strlen(sql_set_trust), &_session->set_trust, NULL);
roker@529
   602
    assert(int_result == SQLITE_OK);
vb@62
   603
krista@1799
   604
    int_result = sqlite3_prepare_v2(_session->db, sql_update_trust_for_fpr,
krista@1799
   605
            (int)strlen(sql_update_trust_for_fpr), &_session->update_trust_for_fpr, NULL);
krista@1799
   606
    assert(int_result == SQLITE_OK);
krista@1799
   607
vb@8
   608
    int_result = sqlite3_prepare_v2(_session->db, sql_get_trust,
Edouard@417
   609
            (int)strlen(sql_get_trust), &_session->get_trust, NULL);
vb@8
   610
    assert(int_result == SQLITE_OK);
vb@0
   611
vb@251
   612
    int_result = sqlite3_prepare_v2(_session->db, sql_least_trust,
Edouard@417
   613
            (int)strlen(sql_least_trust), &_session->least_trust, NULL);
vb@251
   614
    assert(int_result == SQLITE_OK);
vb@251
   615
vb@357
   616
    int_result = sqlite3_prepare_v2(_session->db, sql_mark_as_compromized,
vb@951
   617
            (int)strlen(sql_mark_as_compromized), &_session->mark_compromized,
vb@951
   618
            NULL);
vb@357
   619
    assert(int_result == SQLITE_OK);
vb@357
   620
vb@453
   621
    int_result = sqlite3_prepare_v2(_session->db, sql_crashdump,
vb@453
   622
            (int)strlen(sql_crashdump), &_session->crashdump, NULL);
vb@453
   623
    assert(int_result == SQLITE_OK);
vb@453
   624
vb@458
   625
    int_result = sqlite3_prepare_v2(_session->system_db, sql_languagelist,
vb@458
   626
            (int)strlen(sql_languagelist), &_session->languagelist, NULL);
roker@529
   627
    assert(int_result == SQLITE_OK);
vb@458
   628
vb@458
   629
    int_result = sqlite3_prepare_v2(_session->system_db, sql_i18n_token,
vb@458
   630
            (int)strlen(sql_i18n_token), &_session->i18n_token, NULL);
roker@529
   631
    assert(int_result == SQLITE_OK);
vb@458
   632
fdik@494
   633
    // blacklist
fdik@494
   634
fdik@494
   635
    int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_add,
fdik@494
   636
            (int)strlen(sql_blacklist_add), &_session->blacklist_add, NULL);
fdik@494
   637
    assert(int_result == SQLITE_OK);
fdik@494
   638
fdik@494
   639
    int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_delete,
vb@951
   640
            (int)strlen(sql_blacklist_delete), &_session->blacklist_delete,
vb@951
   641
            NULL);
fdik@494
   642
    assert(int_result == SQLITE_OK);
fdik@494
   643
fdik@494
   644
    int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_is_listed,
vb@951
   645
            (int)strlen(sql_blacklist_is_listed),
vb@951
   646
            &_session->blacklist_is_listed, NULL);
fdik@494
   647
    assert(int_result == SQLITE_OK);
fdik@494
   648
fdik@494
   649
    int_result = sqlite3_prepare_v2(_session->db, sql_blacklist_retrieve,
vb@951
   650
            (int)strlen(sql_blacklist_retrieve), &_session->blacklist_retrieve,
vb@951
   651
            NULL);
vb@482
   652
    assert(int_result == SQLITE_OK);
krista@1275
   653
    
Edouard@584
   654
    // Own keys
Edouard@584
   655
    
Edouard@584
   656
    int_result = sqlite3_prepare_v2(_session->db, sql_own_key_is_listed,
vb@951
   657
            (int)strlen(sql_own_key_is_listed), &_session->own_key_is_listed,
vb@951
   658
            NULL);
Edouard@584
   659
    assert(int_result == SQLITE_OK);
Edouard@584
   660
    
vb@955
   661
    int_result = sqlite3_prepare_v2(_session->db, sql_own_identities_retrieve,
vb@955
   662
            (int)strlen(sql_own_identities_retrieve),
vb@955
   663
            &_session->own_identities_retrieve, NULL);
Edouard@584
   664
    assert(int_result == SQLITE_OK);
vb@633
   665
 
edouard@1394
   666
    int_result = sqlite3_prepare_v2(_session->db, sql_own_keys_retrieve,
edouard@1394
   667
            (int)strlen(sql_own_keys_retrieve),
edouard@1394
   668
            &_session->own_keys_retrieve, NULL);
edouard@1394
   669
    assert(int_result == SQLITE_OK);
edouard@1394
   670
 
edouard@1394
   671
    int_result = sqlite3_prepare_v2(_session->db, sql_set_own_key,
edouard@1394
   672
            (int)strlen(sql_set_own_key),
edouard@1394
   673
            &_session->set_own_key, NULL);
edouard@1370
   674
    assert(int_result == SQLITE_OK);
edouard@1370
   675
 
vb@633
   676
    // Sequence
vb@633
   677
vb@633
   678
    int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value1,
vb@951
   679
            (int)strlen(sql_sequence_value1), &_session->sequence_value1,
vb@951
   680
            NULL);
vb@633
   681
    assert(int_result == SQLITE_OK);
vb@633
   682
vb@633
   683
    int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value2,
vb@951
   684
            (int)strlen(sql_sequence_value2), &_session->sequence_value2,
vb@951
   685
            NULL);
krista@1032
   686
    assert(int_result == SQLITE_OK);
krista@1032
   687
vb@1085
   688
    int_result = sqlite3_prepare_v2(_session->db, sql_sequence_value3,
vb@1085
   689
            (int)strlen(sql_sequence_value3), &_session->sequence_value3,
vb@1085
   690
            NULL);
vb@633
   691
    assert(int_result == SQLITE_OK);
vb@633
   692
Edouard@693
   693
    // Revocation tracking
Edouard@693
   694
    
Edouard@693
   695
    int_result = sqlite3_prepare_v2(_session->db, sql_set_revoked,
vb@951
   696
            (int)strlen(sql_set_revoked), &_session->set_revoked, NULL);
Edouard@693
   697
    assert(int_result == SQLITE_OK);
Edouard@693
   698
    
Edouard@693
   699
    int_result = sqlite3_prepare_v2(_session->db, sql_get_revoked,
vb@951
   700
            (int)strlen(sql_get_revoked), &_session->get_revoked, NULL);
Edouard@693
   701
    assert(int_result == SQLITE_OK);
Edouard@693
   702
    
vb@65
   703
    status = init_cryptotech(_session, in_first);
vb@65
   704
    if (status != PEP_STATUS_OK)
vb@65
   705
        goto pep_error;
vb@0
   706
vb@65
   707
    status = init_transport_system(_session, in_first);
vb@65
   708
    if (status != PEP_STATUS_OK)
vb@65
   709
        goto pep_error;
vb@62
   710
vb@65
   711
    status = log_event(_session, "init", "pEp " PEP_ENGINE_VERSION, NULL, NULL);
vb@65
   712
    if (status != PEP_STATUS_OK)
vb@65
   713
        goto pep_error;
vb@65
   714
vb@464
   715
    // runtime config
vb@464
   716
Edouard@720
   717
#ifdef ANDROID
Edouard@720
   718
#elif TARGET_OS_IPHONE
edouard@1752
   719
#else /* Desktop */
edouard@1752
   720
    if (very_first)
edouard@1752
   721
    {
edouard@1752
   722
        // On first run, all private keys already present in PGP keyring 
edouard@1752
   723
        // are taken as own in order to seamlessly integrate with
edouard@1752
   724
        // pre-existing GPG setup.
edouard@1752
   725
edouard@1752
   726
        ////////////////////////////// WARNING: ///////////////////////////
edouard@1752
   727
        // Considering all PGP priv keys as own is dangerous in case of 
edouard@1752
   728
        // re-initialization of pEp DB, while keeping PGP keyring as-is!
edouard@1752
   729
        //
edouard@1752
   730
        // Indeed, if pEpEngine did import spoofed private keys in previous
edouard@1752
   731
        // install, then those keys become automatically trusted in case 
edouard@1752
   732
        // pEp_management.db is deleted.
edouard@1752
   733
        //
edouard@1752
   734
        // A solution to distinguish bare GPG keyring from pEp keyring is
edouard@1752
   735
        // needed here. Then keys managed by pEpEngine wouldn't be
edouard@1752
   736
        // confused with GPG keys managed by the user through GPA.
edouard@1752
   737
        ///////////////////////////////////////////////////////////////////
edouard@1752
   738
        
edouard@1752
   739
        stringlist_t *keylist = NULL;
edouard@1752
   740
edouard@1760
   741
        status = find_private_keys(_session, NULL, &keylist);
edouard@1752
   742
        assert(status != PEP_OUT_OF_MEMORY);
edouard@1752
   743
        if (status == PEP_OUT_OF_MEMORY)
edouard@1752
   744
            return PEP_OUT_OF_MEMORY;
edouard@1752
   745
        
edouard@1752
   746
        if (keylist != NULL && keylist->value != NULL)
edouard@1752
   747
        {
edouard@1752
   748
            stringlist_t *_keylist;
edouard@1752
   749
            for (_keylist = keylist; _keylist && _keylist->value; _keylist = _keylist->next) {
edouard@1752
   750
                status = set_own_key(_session, 
edouard@1752
   751
                                     "" /* address is unused in own_keys */,
edouard@1752
   752
                                     _keylist->value);
edouard@1752
   753
            }
edouard@1752
   754
        }
edouard@1752
   755
    }
Edouard@720
   756
#endif
vb@464
   757
edouard@1603
   758
    // sync_session set to own session by default
edouard@1603
   759
    // sync_session is then never null on a valid session
edouard@1603
   760
    _session->sync_session = _session;
edouard@1603
   761
roker@529
   762
    *session = _session;
roker@529
   763
    return PEP_STATUS_OK;
vb@65
   764
vb@65
   765
enomem:
vb@65
   766
    status = PEP_OUT_OF_MEMORY;
vb@65
   767
vb@65
   768
pep_error:
vb@65
   769
    release(_session);
vb@65
   770
    return status;
vb@0
   771
}
vb@0
   772
vb@0
   773
DYNAMIC_API void release(PEP_SESSION session)
vb@0
   774
{
vb@62
   775
    bool out_last = false;
vb@62
   776
vb@62
   777
    assert(init_count >= 0);
roker@529
   778
    assert(session);
vb@0
   779
Edouard@385
   780
    if (!((init_count >= 0) && session))
vb@191
   781
        return;
vb@191
   782
vb@62
   783
    // a small race condition but still a race condition
vb@113
   784
    // mitigated by calling caveat (see documentation)
vb@62
   785
vb@62
   786
    if (init_count == 0)
vb@62
   787
        out_last = true;
vb@62
   788
    --init_count;
vb@62
   789
roker@529
   790
    if (session) {
vb@986
   791
        if (session->sync_state != DeviceState_state_NONE)
vb@986
   792
            unregister_sync_callbacks(session);
vb@986
   793
roker@529
   794
        if (session->db) {
vb@517
   795
            if (session->log)
vb@517
   796
                sqlite3_finalize(session->log);
vb@233
   797
            if (session->trustword)
vb@233
   798
                sqlite3_finalize(session->trustword);
vb@65
   799
            if (session->get_identity)
vb@65
   800
                sqlite3_finalize(session->get_identity);
krista@1799
   801
            if (session->replace_identities_fpr)
krista@1799
   802
                sqlite3_finalize(session->replace_identities_fpr);        
vb@65
   803
            if (session->set_person)
vb@65
   804
                sqlite3_finalize(session->set_person);
edouard@1234
   805
            if (session->set_device_group)
edouard@1234
   806
                sqlite3_finalize(session->set_device_group);
edouard@1235
   807
            if (session->get_device_group)
edouard@1235
   808
                sqlite3_finalize(session->get_device_group);
vb@65
   809
            if (session->set_pgp_keypair)
vb@65
   810
                sqlite3_finalize(session->set_pgp_keypair);
vb@517
   811
            if (session->set_identity)
vb@517
   812
                sqlite3_finalize(session->set_identity);
vb@932
   813
            if (session->set_identity_flags)
vb@932
   814
                sqlite3_finalize(session->set_identity_flags);
edouard@1394
   815
            if (session->unset_identity_flags)
edouard@1394
   816
                sqlite3_finalize(session->unset_identity_flags);
vb@65
   817
            if (session->set_trust)
vb@65
   818
                sqlite3_finalize(session->set_trust);
krista@1799
   819
            if (session->update_trust_for_fpr)
krista@1799
   820
                sqlite3_finalize(session->update_trust_for_fpr);
vb@65
   821
            if (session->get_trust)
vb@65
   822
                sqlite3_finalize(session->get_trust);
vb@251
   823
            if (session->least_trust)
vb@251
   824
                sqlite3_finalize(session->least_trust);
vb@517
   825
            if (session->mark_compromized)
vb@517
   826
                sqlite3_finalize(session->mark_compromized);
vb@517
   827
            if (session->crashdump)
vb@517
   828
                sqlite3_finalize(session->crashdump);
vb@517
   829
            if (session->languagelist)
vb@517
   830
                sqlite3_finalize(session->languagelist);
vb@517
   831
            if (session->i18n_token)
vb@517
   832
                sqlite3_finalize(session->i18n_token);
vb@517
   833
            if (session->blacklist_add)
vb@517
   834
                sqlite3_finalize(session->blacklist_add);
vb@517
   835
            if (session->blacklist_delete)
vb@517
   836
                sqlite3_finalize(session->blacklist_delete);
vb@517
   837
            if (session->blacklist_is_listed)
vb@517
   838
                sqlite3_finalize(session->blacklist_is_listed);
vb@517
   839
            if (session->blacklist_retrieve)
vb@517
   840
                sqlite3_finalize(session->blacklist_retrieve);
krista@957
   841
            if (session->own_key_is_listed)
krista@957
   842
                sqlite3_finalize(session->own_key_is_listed);
roker@1002
   843
            if (session->own_identities_retrieve)
roker@1002
   844
                sqlite3_finalize(session->own_identities_retrieve);
edouard@1394
   845
            if (session->own_keys_retrieve)
edouard@1394
   846
                sqlite3_finalize(session->own_keys_retrieve);
edouard@1394
   847
            if (session->set_own_key)
edouard@1394
   848
                sqlite3_finalize(session->set_own_key);
krista@957
   849
            if (session->sequence_value1)
krista@957
   850
                sqlite3_finalize(session->sequence_value1);
krista@957
   851
            if (session->sequence_value2)
krista@960
   852
                sqlite3_finalize(session->sequence_value2);
vb@1085
   853
            if (session->sequence_value3)
vb@1085
   854
                sqlite3_finalize(session->sequence_value3);
krista@957
   855
            if (session->set_revoked)
krista@957
   856
                sqlite3_finalize(session->set_revoked);
krista@957
   857
            if (session->get_revoked)
krista@957
   858
                sqlite3_finalize(session->get_revoked);
vb@26
   859
vb@65
   860
            if (session->db)
vb@65
   861
                sqlite3_close_v2(session->db);
vb@65
   862
            if (session->system_db)
vb@65
   863
                sqlite3_close_v2(session->system_db);
roker@529
   864
        }
vb@65
   865
vb@65
   866
        release_transport_system(session, out_last);
vb@65
   867
        release_cryptotech(session, out_last);
vb@65
   868
roker@1722
   869
#ifdef DEBUG_ERRORSTACK
roker@1722
   870
        free_stringlist(session->errorstack);
roker@1722
   871
#endif
vb@65
   872
        free(session);
vb@62
   873
    }
vb@0
   874
}
vb@0
   875
vb@467
   876
DYNAMIC_API void config_passive_mode(PEP_SESSION session, bool enable)
vb@464
   877
{
vb@464
   878
    assert(session);
vb@467
   879
    session->passive_mode = enable;
vb@464
   880
}
vb@464
   881
vb@467
   882
DYNAMIC_API void config_unencrypted_subject(PEP_SESSION session, bool enable)
vb@464
   883
{
vb@464
   884
    assert(session);
vb@467
   885
    session->unencrypted_subject = enable;
vb@464
   886
}
vb@464
   887
vb@1110
   888
DYNAMIC_API void config_keep_sync_msg(PEP_SESSION session, bool enable)
vb@1109
   889
{
vb@1109
   890
    assert(session);
vb@1110
   891
    session->keep_sync_msg = enable;
vb@1109
   892
}
vb@1109
   893
vb@1819
   894
DYNAMIC_API void config_service_log(PEP_SESSION session, bool enable)
vb@1819
   895
{
vb@1819
   896
    assert(session);
vb@1819
   897
    session->service_log = enable;
vb@1819
   898
}
vb@1819
   899
vb@0
   900
DYNAMIC_API PEP_STATUS log_event(
vb@450
   901
        PEP_SESSION session,
vb@451
   902
        const char *title,
vb@451
   903
        const char *entity,
vb@451
   904
        const char *description,
vb@451
   905
        const char *comment
vb@0
   906
    )
vb@0
   907
{
roker@529
   908
    PEP_STATUS status = PEP_STATUS_OK;
roker@529
   909
    int result;
vb@0
   910
roker@529
   911
    assert(session);
roker@529
   912
    assert(title);
roker@529
   913
    assert(entity);
vb@0
   914
vb@191
   915
    if (!(session && title && entity))
vb@191
   916
        return PEP_ILLEGAL_VALUE;
vb@191
   917
roker@529
   918
    sqlite3_reset(session->log);
roker@529
   919
    sqlite3_bind_text(session->log, 1, title, -1, SQLITE_STATIC);
roker@529
   920
    sqlite3_bind_text(session->log, 2, entity, -1, SQLITE_STATIC);
roker@529
   921
    if (description)
vb@46
   922
        sqlite3_bind_text(session->log, 3, description, -1, SQLITE_STATIC);
roker@529
   923
    else
roker@529
   924
        sqlite3_bind_null(session->log, 3);
roker@529
   925
    if (comment)
roker@529
   926
        sqlite3_bind_text(session->log, 4, comment, -1, SQLITE_STATIC);
roker@529
   927
    else
roker@529
   928
        sqlite3_bind_null(session->log, 4);
roker@529
   929
    do {
roker@529
   930
        result = sqlite3_step(session->log);
roker@529
   931
        assert(result == SQLITE_DONE || result == SQLITE_BUSY);
roker@529
   932
        if (result != SQLITE_DONE && result != SQLITE_BUSY)
roker@529
   933
            status = PEP_UNKNOWN_ERROR;
roker@529
   934
    } while (result == SQLITE_BUSY);
roker@529
   935
    sqlite3_reset(session->log);
vb@0
   936
roker@1853
   937
    return ADD_TO_LOG(status);
vb@0
   938
}
vb@0
   939
vb@1819
   940
DYNAMIC_API PEP_STATUS log_service(
vb@1819
   941
        PEP_SESSION session,
vb@1819
   942
        const char *title,
vb@1819
   943
        const char *entity,
vb@1819
   944
        const char *description,
vb@1819
   945
        const char *comment
vb@1819
   946
    )
vb@1819
   947
{
vb@1819
   948
    assert(session);
vb@1819
   949
    if (!session)
vb@1819
   950
        return PEP_ILLEGAL_VALUE;
vb@1819
   951
vb@1819
   952
    if (session->service_log)
vb@1819
   953
        return log_event(session, title, entity, description, comment);
vb@1819
   954
    else
vb@1819
   955
        return PEP_STATUS_OK;
vb@1819
   956
}
vb@1819
   957
vb@233
   958
DYNAMIC_API PEP_STATUS trustword(
vb@0
   959
            PEP_SESSION session, uint16_t value, const char *lang,
vb@0
   960
            char **word, size_t *wsize
vb@0
   961
        )
vb@0
   962
{
roker@529
   963
    PEP_STATUS status = PEP_STATUS_OK;
vb@0
   964
roker@529
   965
    assert(session);
roker@529
   966
    assert(word);
roker@529
   967
    assert(wsize);
vb@0
   968
vb@191
   969
    if (!(session && word && wsize))
vb@191
   970
        return PEP_ILLEGAL_VALUE;
vb@191
   971
roker@529
   972
    *word = NULL;
roker@529
   973
    *wsize = 0;
vb@0
   974
roker@529
   975
    if (lang == NULL)
roker@529
   976
        lang = "en";
vb@0
   977
roker@529
   978
    assert((lang[0] >= 'A' && lang[0] <= 'Z')
vb@0
   979
            || (lang[0] >= 'a' && lang[0] <= 'z'));
roker@529
   980
    assert((lang[1] >= 'A' && lang[1] <= 'Z')
vb@0
   981
            || (lang[1] >= 'a' && lang[1] <= 'z'));
roker@529
   982
    assert(lang[2] == 0);
vb@0
   983
roker@529
   984
    sqlite3_reset(session->trustword);
vb@233
   985
    sqlite3_bind_text(session->trustword, 1, lang, -1, SQLITE_STATIC);
roker@529
   986
    sqlite3_bind_int(session->trustword, 2, value);
vb@0
   987
roker@877
   988
    const int result = sqlite3_step(session->trustword);
roker@529
   989
    if (result == SQLITE_ROW) {
vb@233
   990
        *word = strdup((const char *) sqlite3_column_text(session->trustword,
vb@0
   991
                    1));
roker@529
   992
        if (*word)
vb@233
   993
            *wsize = sqlite3_column_bytes(session->trustword, 1);
roker@529
   994
        else
Edouard@693
   995
            status = PEP_OUT_OF_MEMORY;
roker@529
   996
    } else
roker@529
   997
        status = PEP_TRUSTWORD_NOT_FOUND;
vb@0
   998
roker@529
   999
    sqlite3_reset(session->trustword);
roker@529
  1000
    return status;
vb@0
  1001
}
vb@0
  1002
vb@233
  1003
DYNAMIC_API PEP_STATUS trustwords(
vb@0
  1004
        PEP_SESSION session, const char *fingerprint, const char *lang,
vb@0
  1005
        char **words, size_t *wsize, int max_words
vb@0
  1006
    )
vb@0
  1007
{
roker@529
  1008
    const char *source = fingerprint;
vb@0
  1009
roker@529
  1010
    assert(session);
roker@529
  1011
    assert(fingerprint);
roker@529
  1012
    assert(words);
roker@529
  1013
    assert(wsize);
roker@529
  1014
    assert(max_words >= 0);
vb@0
  1015
vb@191
  1016
    if (!(session && fingerprint && words && wsize && max_words >= 0))
vb@191
  1017
        return PEP_ILLEGAL_VALUE;
vb@191
  1018
roker@529
  1019
    *words = NULL;
roker@529
  1020
    *wsize = 0;
vb@0
  1021
roker@1559
  1022
    char *buffer = calloc(1, MAX_TRUSTWORDS_SPACE);
vb@0
  1023
    assert(buffer);
vb@0
  1024
    if (buffer == NULL)
vb@0
  1025
        return PEP_OUT_OF_MEMORY;
roker@1559
  1026
    char *dest = buffer;
vb@0
  1027
roker@1559
  1028
    const size_t fsize = strlen(fingerprint);
vb@0
  1029
roker@529
  1030
    if (!lang || !lang[0])
roker@529
  1031
        lang = "en";
vb@0
  1032
roker@529
  1033
    assert((lang[0] >= 'A' && lang[0] <= 'Z')
vb@0
  1034
            || (lang[0] >= 'a' && lang[0] <= 'z'));
roker@529
  1035
    assert((lang[1] >= 'A' && lang[1] <= 'Z')
vb@0
  1036
            || (lang[1] >= 'a' && lang[1] <= 'z'));
roker@529
  1037
    assert(lang[2] == 0);
vb@0
  1038
roker@529
  1039
    int n_words = 0;
roker@529
  1040
    while (source < fingerprint + fsize) {
vb@939
  1041
        PEP_STATUS _status;
roker@529
  1042
        uint16_t value;
roker@1559
  1043
        char *word = NULL;
roker@1559
  1044
        size_t _wsize = 0;
roker@529
  1045
        int j;
vb@0
  1046
vb@0
  1047
        for (value=0, j=0; j < 4 && source < fingerprint + fsize; ) {
roker@529
  1048
            if (*source >= 'a' && *source <= 'f')
roker@529
  1049
                value += (*source - 'a' + 10) << (3 - j++) * 4;
roker@529
  1050
            else if (*source >= 'A' && *source <= 'F')
roker@529
  1051
                value += (*source - 'A' + 10) << (3 - j++) * 4;
roker@529
  1052
            else if (*source >= '0' && *source <= '9')
roker@529
  1053
                value += (*source - '0') << (3 - j++) * 4;
roker@529
  1054
            
roker@529
  1055
            source++;
roker@529
  1056
        }
vb@0
  1057
roker@529
  1058
        _status = trustword(session, value, lang, &word, &_wsize);
vb@0
  1059
        if (_status == PEP_OUT_OF_MEMORY) {
vb@0
  1060
            free(buffer);
vb@0
  1061
            return PEP_OUT_OF_MEMORY;
vb@0
  1062
        }
roker@529
  1063
        if (word == NULL) {
vb@0
  1064
            free(buffer);
roker@529
  1065
            return PEP_TRUSTWORD_NOT_FOUND;
vb@0
  1066
        }
vb@0
  1067
roker@529
  1068
        if (dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1) {
roker@529
  1069
            strncpy(dest, word, _wsize);
vb@0
  1070
            free(word);
roker@529
  1071
            dest += _wsize;
roker@529
  1072
        }
roker@529
  1073
        else {
vb@0
  1074
            free(word);
roker@529
  1075
            break; // buffer full
vb@0
  1076
        }
vb@0
  1077
roker@529
  1078
        if (source < fingerprint + fsize
vb@251
  1079
                && dest + _wsize < buffer + MAX_TRUSTWORDS_SPACE - 1)
roker@529
  1080
            *dest++ = ' ';
vb@0
  1081
roker@529
  1082
        ++n_words;
roker@529
  1083
        if (max_words && n_words >= max_words)
roker@529
  1084
            break;
roker@529
  1085
    }
vb@0
  1086
roker@529
  1087
    *words = buffer;
roker@529
  1088
    *wsize = dest - buffer;
roker@529
  1089
    return PEP_STATUS_OK;
vb@0
  1090
}
vb@0
  1091
vb@0
  1092
pEp_identity *new_identity(
vb@0
  1093
        const char *address, const char *fpr, const char *user_id,
vb@0
  1094
        const char *username
vb@0
  1095
    )
vb@0
  1096
{
vb@0
  1097
    pEp_identity *result = calloc(1, sizeof(pEp_identity));
vb@0
  1098
    assert(result);
vb@0
  1099
    if (result) {
vb@0
  1100
        if (address) {
vb@0
  1101
            result->address = strdup(address);
vb@0
  1102
            assert(result->address);
vb@0
  1103
            if (result->address == NULL) {
vb@0
  1104
                free(result);
vb@0
  1105
                return NULL;
vb@0
  1106
            }
vb@0
  1107
        }
vb@0
  1108
        if (fpr) {
vb@0
  1109
            result->fpr = strdup(fpr);
vb@0
  1110
            assert(result->fpr);
vb@0
  1111
            if (result->fpr == NULL) {
vb@0
  1112
                free_identity(result);
vb@0
  1113
                return NULL;
vb@0
  1114
            }
vb@0
  1115
        }
vb@0
  1116
        if (user_id) {
vb@0
  1117
            result->user_id = strdup(user_id);
vb@0
  1118
            assert(result->user_id);
vb@0
  1119
            if (result->user_id == NULL) {
vb@0
  1120
                free_identity(result);
vb@0
  1121
                return NULL;
vb@0
  1122
            }
vb@0
  1123
        }
vb@0
  1124
        if (username) {
vb@0
  1125
            result->username = strdup(username);
vb@0
  1126
            assert(result->username);
vb@0
  1127
            if (result->username == NULL) {
vb@0
  1128
                free_identity(result);
vb@0
  1129
                return NULL;
vb@0
  1130
            }
vb@0
  1131
        }
vb@0
  1132
    }
vb@0
  1133
    return result;
vb@0
  1134
}
vb@0
  1135
vb@37
  1136
pEp_identity *identity_dup(const pEp_identity *src)
vb@37
  1137
{
vb@37
  1138
    assert(src);
vb@37
  1139
vb@951
  1140
    pEp_identity *dup = new_identity(src->address, src->fpr, src->user_id,
vb@951
  1141
            src->username);
vb@37
  1142
    assert(dup);
vb@37
  1143
    if (dup == NULL)
vb@37
  1144
        return NULL;
vb@37
  1145
    
vb@37
  1146
    dup->comm_type = src->comm_type;
vb@37
  1147
    dup->lang[0] = src->lang[0];
vb@37
  1148
    dup->lang[1] = src->lang[1];
vb@37
  1149
    dup->lang[2] = 0;
vb@37
  1150
    dup->me = src->me;
vb@930
  1151
    dup->flags = src->flags;
vb@37
  1152
vb@37
  1153
    return dup;
vb@37
  1154
}
vb@37
  1155
vb@0
  1156
void free_identity(pEp_identity *identity)
vb@0
  1157
{
vb@0
  1158
    if (identity) {
vb@0
  1159
        free(identity->address);
vb@0
  1160
        free(identity->fpr);
vb@0
  1161
        free(identity->user_id);
vb@0
  1162
        free(identity->username);
vb@0
  1163
        free(identity);
vb@0
  1164
    }
vb@0
  1165
}
vb@0
  1166
vb@0
  1167
DYNAMIC_API PEP_STATUS get_identity(
Edouard@559
  1168
        PEP_SESSION session,
Edouard@559
  1169
        const char *address,
Edouard@559
  1170
        const char *user_id,
vb@0
  1171
        pEp_identity **identity
vb@0
  1172
    )
vb@0
  1173
{
roker@529
  1174
    PEP_STATUS status = PEP_STATUS_OK;
roker@529
  1175
    static pEp_identity *_identity;
vb@0
  1176
roker@529
  1177
    assert(session);
roker@529
  1178
    assert(address);
vb@8
  1179
    assert(address[0]);
vb@632
  1180
    assert(identity);
vb@0
  1181
vb@632
  1182
    if (!(session && address && address[0] && identity))
vb@191
  1183
        return PEP_ILLEGAL_VALUE;
vb@191
  1184
vb@632
  1185
    *identity = NULL;
vb@632
  1186
vb@46
  1187
    sqlite3_reset(session->get_identity);
vb@46
  1188
    sqlite3_bind_text(session->get_identity, 1, address, -1, SQLITE_STATIC);
Edouard@559
  1189
    sqlite3_bind_text(session->get_identity, 2, user_id, -1, SQLITE_STATIC);
vb@0
  1190
roker@876
  1191
    const int result = sqlite3_step(session->get_identity);
roker@529
  1192
    switch (result) {
roker@529
  1193
    case SQLITE_ROW:
vb@0
  1194
        _identity = new_identity(
vb@0
  1195
                address,
vb@46
  1196
                (const char *) sqlite3_column_text(session->get_identity, 0),
Edouard@559
  1197
                user_id,
Edouard@559
  1198
                (const char *) sqlite3_column_text(session->get_identity, 1)
vb@0
  1199
                );
vb@0
  1200
        assert(_identity);
vb@0
  1201
        if (_identity == NULL)
vb@0
  1202
            return PEP_OUT_OF_MEMORY;
vb@0
  1203
vb@951
  1204
        _identity->comm_type = (PEP_comm_type)
vb@951
  1205
            sqlite3_column_int(session->get_identity, 2);
vb@951
  1206
        const char* const _lang = (const char *)
vb@951
  1207
            sqlite3_column_text(session->get_identity, 3);
vb@0
  1208
        if (_lang && _lang[0]) {
roker@529
  1209
            assert(_lang[0] >= 'a' && _lang[0] <= 'z');
roker@529
  1210
            assert(_lang[1] >= 'a' && _lang[1] <= 'z');
roker@529
  1211
            assert(_lang[2] == 0);
roker@529
  1212
            _identity->lang[0] = _lang[0];
roker@529
  1213
            _identity->lang[1] = _lang[1];
vb@0
  1214
            _identity->lang[2] = 0;
roker@529
  1215
        }
vb@951
  1216
        _identity->flags = (unsigned int)
vb@951
  1217
            sqlite3_column_int(session->get_identity, 4);
roker@529
  1218
        *identity = _identity;
roker@529
  1219
        break;
roker@529
  1220
    default:
vb@0
  1221
        status = PEP_CANNOT_FIND_IDENTITY;
roker@529
  1222
        *identity = NULL;
roker@529
  1223
    }
vb@0
  1224
vb@46
  1225
    sqlite3_reset(session->get_identity);
roker@529
  1226
    return status;
vb@0
  1227
}
vb@0
  1228
vb@0
  1229
DYNAMIC_API PEP_STATUS set_identity(
vb@0
  1230
        PEP_SESSION session, const pEp_identity *identity
vb@0
  1231
    )
vb@0
  1232
{
roker@529
  1233
    int result;
vb@0
  1234
roker@529
  1235
    assert(session);
roker@529
  1236
    assert(identity);
roker@529
  1237
    assert(identity->address);
roker@529
  1238
    assert(identity->user_id);
roker@529
  1239
    assert(identity->username);
vb@0
  1240
krista@1223
  1241
    if (!(session && identity && identity->address &&
vb@191
  1242
                identity->user_id && identity->username))
vb@191
  1243
        return PEP_ILLEGAL_VALUE;
vb@191
  1244
krista@1791
  1245
    PEP_STATUS status = PEP_STATUS_OK;
krista@1791
  1246
    
vb@515
  1247
    bool listed;
krista@1449
  1248
krista@1449
  1249
    bool has_fpr = (identity->fpr && identity->fpr[0] != '\0');
krista@1222
  1250
    
krista@1449
  1251
    if (has_fpr) {    
krista@1275
  1252
        // blacklist check
krista@1791
  1253
        status = blacklist_is_listed(session, identity->fpr, &listed);
krista@1223
  1254
        assert(status == PEP_STATUS_OK);
krista@1223
  1255
        if (status != PEP_STATUS_OK)
krista@1223
  1256
            return status;
vb@515
  1257
krista@1223
  1258
        if (listed)
krista@1223
  1259
            return PEP_KEY_BLACKLISTED;
krista@1223
  1260
    }
vb@515
  1261
roker@529
  1262
    sqlite3_exec(session->db, "BEGIN ;", NULL, NULL, NULL);
vb@0
  1263
vb@1079
  1264
    if (identity->lang[0]) {
vb@1079
  1265
        assert(identity->lang[0] >= 'a' && identity->lang[0] <= 'z');
vb@1079
  1266
        assert(identity->lang[1] >= 'a' && identity->lang[1] <= 'z');
vb@1079
  1267
        assert(identity->lang[2] == 0);
vb@1079
  1268
    }
vb@1079
  1269
roker@529
  1270
    sqlite3_reset(session->set_person);
vb@46
  1271
    sqlite3_bind_text(session->set_person, 1, identity->user_id, -1,
vb@0
  1272
            SQLITE_STATIC);
vb@46
  1273
    sqlite3_bind_text(session->set_person, 2, identity->username, -1,
vb@0
  1274
            SQLITE_STATIC);
roker@529
  1275
    if (identity->lang[0])
vb@1081
  1276
        sqlite3_bind_text(session->set_person, 3, identity->lang, 2,
vb@0
  1277
                SQLITE_STATIC);
roker@529
  1278
    else
roker@529
  1279
        sqlite3_bind_null(session->set_person, 3);
Edouard@641
  1280
    sqlite3_bind_text(session->set_person, 4, identity->fpr, -1,
Edouard@641
  1281
                      SQLITE_STATIC);
roker@529
  1282
    result = sqlite3_step(session->set_person);
roker@529
  1283
    sqlite3_reset(session->set_person);
roker@529
  1284
    if (result != SQLITE_DONE) {
roker@529
  1285
        sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
roker@529
  1286
        return PEP_CANNOT_SET_PERSON;
roker@529
  1287
    }
vb@0
  1288
krista@1449
  1289
    if (has_fpr) {
krista@1449
  1290
        sqlite3_reset(session->set_pgp_keypair);
krista@1449
  1291
        sqlite3_bind_text(session->set_pgp_keypair, 1, identity->fpr, -1,
krista@1449
  1292
                SQLITE_STATIC);
krista@1449
  1293
        result = sqlite3_step(session->set_pgp_keypair);
krista@1449
  1294
        sqlite3_reset(session->set_pgp_keypair);
krista@1449
  1295
        if (result != SQLITE_DONE) {
krista@1449
  1296
            sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
krista@1449
  1297
            return PEP_CANNOT_SET_PGP_KEYPAIR;
krista@1449
  1298
        }
roker@529
  1299
    }
vb@0
  1300
edouard@1394
  1301
    sqlite3_reset(session->set_identity);
edouard@1394
  1302
    sqlite3_bind_text(session->set_identity, 1, identity->address, -1,
vb@0
  1303
            SQLITE_STATIC);
edouard@1394
  1304
    sqlite3_bind_text(session->set_identity, 2, identity->fpr, -1,
vb@0
  1305
            SQLITE_STATIC);
edouard@1394
  1306
    sqlite3_bind_text(session->set_identity, 3, identity->user_id, -1,
vb@0
  1307
            SQLITE_STATIC);
edouard@1394
  1308
    sqlite3_bind_int(session->set_identity, 4, identity->flags);
edouard@1394
  1309
    result = sqlite3_step(session->set_identity);
edouard@1394
  1310
    sqlite3_reset(session->set_identity);
roker@529
  1311
    if (result != SQLITE_DONE) {
roker@529
  1312
        sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
roker@529
  1313
        return PEP_CANNOT_SET_IDENTITY;
roker@529
  1314
    }
vb@0
  1315
krista@1449
  1316
    if (has_fpr) {
krista@1449
  1317
        if(strcmp(identity->user_id, PEP_OWN_USERID) == 0) {
krista@1449
  1318
            sqlite3_reset(session->set_own_key);
krista@1449
  1319
            sqlite3_bind_text(session->set_own_key, 1, identity->address, -1,
krista@1449
  1320
                SQLITE_STATIC);
krista@1449
  1321
            sqlite3_bind_text(session->set_own_key, 2, identity->fpr, -1,
krista@1449
  1322
                SQLITE_STATIC);
krista@1449
  1323
            result = sqlite3_step(session->set_own_key);
krista@1449
  1324
            sqlite3_reset(session->set_own_key);
krista@1449
  1325
            if (result != SQLITE_DONE) {
krista@1449
  1326
                sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
krista@1449
  1327
                return PEP_CANNOT_SET_PGP_KEYPAIR;
krista@1449
  1328
            }
krista@1449
  1329
        }
krista@1449
  1330
krista@1797
  1331
        // status = set_trust(session, identity->user_id, identity->fpr,
krista@1797
  1332
        //                    identity->comm_type)
krista@1449
  1333
        sqlite3_reset(session->set_trust);
krista@1449
  1334
        sqlite3_bind_text(session->set_trust, 1, identity->user_id, -1,
krista@1449
  1335
                SQLITE_STATIC);
krista@1449
  1336
        sqlite3_bind_text(session->set_trust, 2, identity->fpr, -1,
krista@1449
  1337
                SQLITE_STATIC);
krista@1449
  1338
        sqlite3_bind_int(session->set_trust, 3, identity->comm_type);
krista@1449
  1339
        result = sqlite3_step(session->set_trust);
krista@1449
  1340
        sqlite3_reset(session->set_trust);
edouard@1394
  1341
        if (result != SQLITE_DONE) {
edouard@1394
  1342
            sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
krista@1449
  1343
            return PEP_CANNOT_SET_TRUST;
edouard@1394
  1344
        }
edouard@1394
  1345
    }
krista@1449
  1346
    
vb@46
  1347
    result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
roker@529
  1348
    if (result == SQLITE_OK)
roker@529
  1349
        return PEP_STATUS_OK;
roker@529
  1350
    else
roker@529
  1351
        return PEP_COMMIT_FAILED;
vb@0
  1352
}
vb@0
  1353
krista@1799
  1354
PEP_STATUS replace_identities_fpr(PEP_SESSION session, 
krista@1799
  1355
                                 const char* old_fpr, 
krista@1799
  1356
                                 const char* new_fpr) 
krista@1793
  1357
{
krista@1799
  1358
    assert(old_fpr);
krista@1799
  1359
    assert(new_fpr);
krista@1798
  1360
    
krista@1799
  1361
    if (!old_fpr || !new_fpr)
krista@1799
  1362
        return PEP_ILLEGAL_VALUE;
krista@1799
  1363
            
krista@1799
  1364
    sqlite3_reset(session->replace_identities_fpr);
krista@1799
  1365
    sqlite3_bind_text(session->replace_identities_fpr, 1, new_fpr, -1,
krista@1799
  1366
                      SQLITE_STATIC);
krista@1799
  1367
    sqlite3_bind_text(session->replace_identities_fpr, 2, old_fpr, -1,
krista@1799
  1368
                      SQLITE_STATIC);
krista@1799
  1369
krista@1799
  1370
    int result = sqlite3_step(session->replace_identities_fpr);
krista@1799
  1371
    sqlite3_reset(session->replace_identities_fpr);
krista@1799
  1372
    
krista@1799
  1373
    if (result != SQLITE_DONE)
krista@1799
  1374
        return PEP_CANNOT_SET_IDENTITY;
krista@1799
  1375
krista@1799
  1376
    return PEP_STATUS_OK;
krista@1799
  1377
}
krista@1799
  1378
krista@1799
  1379
krista@1799
  1380
PEP_STATUS update_trust_for_fpr(PEP_SESSION session, 
krista@1799
  1381
                                const char* fpr, 
krista@1799
  1382
                                PEP_comm_type comm_type)
krista@1799
  1383
{
krista@1799
  1384
    if (!fpr)
krista@1798
  1385
        return PEP_ILLEGAL_VALUE;
krista@1798
  1386
        
krista@1799
  1387
    sqlite3_reset(session->update_trust_for_fpr);
krista@1805
  1388
    sqlite3_bind_int(session->update_trust_for_fpr, 1, comm_type);
krista@1799
  1389
    sqlite3_bind_text(session->update_trust_for_fpr, 2, fpr, -1,
krista@1791
  1390
            SQLITE_STATIC);
krista@1799
  1391
    int result = sqlite3_step(session->update_trust_for_fpr);
krista@1799
  1392
    sqlite3_reset(session->update_trust_for_fpr);
krista@1791
  1393
    if (result != SQLITE_DONE) {
krista@1791
  1394
        return PEP_CANNOT_SET_TRUST;
krista@1791
  1395
    }
krista@1791
  1396
    
krista@1791
  1397
    return PEP_STATUS_OK;
krista@1791
  1398
}
krista@1791
  1399
edouard@1234
  1400
DYNAMIC_API PEP_STATUS set_device_group(
edouard@1234
  1401
        PEP_SESSION session,
edouard@1234
  1402
        const char *group_name
edouard@1234
  1403
    )
edouard@1234
  1404
{
edouard@1234
  1405
    int result;
edouard@1234
  1406
edouard@1234
  1407
    assert(session);
edouard@1234
  1408
edouard@1234
  1409
    if (!(session && group_name))
edouard@1234
  1410
        return PEP_ILLEGAL_VALUE;
edouard@1234
  1411
edouard@1234
  1412
    sqlite3_reset(session->set_device_group);
edouard@1574
  1413
    if(group_name){
edouard@1574
  1414
        sqlite3_bind_text(session->set_device_group, 1, group_name, -1,
edouard@1574
  1415
                SQLITE_STATIC);
edouard@1574
  1416
    } else {
edouard@1574
  1417
        sqlite3_bind_null(session->set_device_group, 1);
edouard@1574
  1418
    }
edouard@1574
  1419
edouard@1234
  1420
    result = sqlite3_step(session->set_device_group);
edouard@1234
  1421
    sqlite3_reset(session->set_device_group);
edouard@1234
  1422
    if (result != SQLITE_DONE)
edouard@1234
  1423
        return PEP_CANNOT_SET_PERSON;
edouard@1234
  1424
edouard@1234
  1425
    return PEP_STATUS_OK;
edouard@1234
  1426
}
edouard@1234
  1427
edouard@1235
  1428
DYNAMIC_API PEP_STATUS get_device_group(PEP_SESSION session, char **group_name)
edouard@1235
  1429
{
edouard@1235
  1430
    PEP_STATUS status = PEP_STATUS_OK;
edouard@1235
  1431
    int result;
edouard@1235
  1432
edouard@1235
  1433
    assert(session);
edouard@1235
  1434
    assert(group_name);
edouard@1235
  1435
edouard@1235
  1436
    if (!(session && group_name))
edouard@1235
  1437
        return PEP_ILLEGAL_VALUE;
edouard@1235
  1438
edouard@1235
  1439
    sqlite3_reset(session->get_device_group);
edouard@1235
  1440
edouard@1235
  1441
    result = sqlite3_step(session->get_device_group);
edouard@1235
  1442
    switch (result) {
edouard@1235
  1443
    case SQLITE_ROW: {
edouard@1574
  1444
        const char *_group_name = (const char *)sqlite3_column_text(session->get_device_group, 0);
edouard@1574
  1445
        if(_group_name){
edouard@1574
  1446
            *group_name = strdup(_group_name);
edouard@1574
  1447
                if(*group_name == NULL)
edouard@1574
  1448
                    status = PEP_OUT_OF_MEMORY;
edouard@1574
  1449
        }
edouard@1235
  1450
        break;
edouard@1235
  1451
    }
edouard@1235
  1452
 
edouard@1235
  1453
    default:
edouard@1235
  1454
        status = PEP_RECORD_NOT_FOUND;
edouard@1235
  1455
    }
edouard@1235
  1456
edouard@1235
  1457
    sqlite3_reset(session->get_device_group);
edouard@1235
  1458
    return status;
edouard@1235
  1459
}
edouard@1235
  1460
vb@932
  1461
DYNAMIC_API PEP_STATUS set_identity_flags(
vb@934
  1462
        PEP_SESSION session,
vb@934
  1463
        pEp_identity *identity,
vb@934
  1464
        unsigned int flags
vb@932
  1465
    )
vb@932
  1466
{
vb@932
  1467
    int result;
vb@932
  1468
vb@932
  1469
    assert(session);
vb@932
  1470
    assert(identity);
vb@932
  1471
    assert(identity->address);
vb@932
  1472
    assert(identity->user_id);
vb@932
  1473
vb@932
  1474
    if (!(session && identity && identity->address && identity->user_id))
vb@932
  1475
        return PEP_ILLEGAL_VALUE;
vb@932
  1476
vb@932
  1477
    sqlite3_reset(session->set_identity_flags);
vb@934
  1478
    sqlite3_bind_int(session->set_identity_flags, 1, flags);
vb@932
  1479
    sqlite3_bind_text(session->set_identity_flags, 2, identity->address, -1,
vb@932
  1480
            SQLITE_STATIC);
vb@932
  1481
    sqlite3_bind_text(session->set_identity_flags, 3, identity->user_id, -1,
vb@932
  1482
            SQLITE_STATIC);
vb@932
  1483
    result = sqlite3_step(session->set_identity_flags);
vb@932
  1484
    sqlite3_reset(session->set_identity_flags);
vb@932
  1485
    if (result != SQLITE_DONE)
vb@932
  1486
        return PEP_CANNOT_SET_IDENTITY;
vb@932
  1487
edouard@1406
  1488
    identity->flags |= flags;
vb@932
  1489
    return PEP_STATUS_OK;
vb@932
  1490
}
vb@932
  1491
edouard@1394
  1492
DYNAMIC_API PEP_STATUS unset_identity_flags(
edouard@1394
  1493
        PEP_SESSION session,
edouard@1394
  1494
        pEp_identity *identity,
edouard@1394
  1495
        unsigned int flags
edouard@1394
  1496
    )
edouard@1394
  1497
{
edouard@1394
  1498
    int result;
edouard@1394
  1499
edouard@1394
  1500
    assert(session);
edouard@1394
  1501
    assert(identity);
edouard@1394
  1502
    assert(identity->address);
edouard@1394
  1503
    assert(identity->user_id);
edouard@1394
  1504
edouard@1394
  1505
    if (!(session && identity && identity->address && identity->user_id))
edouard@1394
  1506
        return PEP_ILLEGAL_VALUE;
edouard@1394
  1507
edouard@1394
  1508
    sqlite3_reset(session->unset_identity_flags);
edouard@1394
  1509
    sqlite3_bind_int(session->unset_identity_flags, 1, flags);
edouard@1394
  1510
    sqlite3_bind_text(session->unset_identity_flags, 2, identity->address, -1,
edouard@1394
  1511
            SQLITE_STATIC);
edouard@1394
  1512
    sqlite3_bind_text(session->unset_identity_flags, 3, identity->user_id, -1,
edouard@1394
  1513
            SQLITE_STATIC);
edouard@1394
  1514
    result = sqlite3_step(session->unset_identity_flags);
edouard@1394
  1515
    sqlite3_reset(session->unset_identity_flags);
edouard@1394
  1516
    if (result != SQLITE_DONE)
edouard@1394
  1517
        return PEP_CANNOT_SET_IDENTITY;
edouard@1394
  1518
edouard@1406
  1519
    identity->flags &= ~flags;
edouard@1394
  1520
    return PEP_STATUS_OK;
edouard@1394
  1521
}
edouard@1394
  1522
vb@357
  1523
DYNAMIC_API PEP_STATUS mark_as_compromized(
vb@357
  1524
        PEP_SESSION session,
vb@357
  1525
        const char *fpr
vb@357
  1526
    )
vb@357
  1527
{
roker@529
  1528
    int result;
vb@357
  1529
roker@529
  1530
    assert(session);
vb@357
  1531
    assert(fpr && fpr[0]);
vb@357
  1532
vb@357
  1533
    if (!(session && fpr && fpr[0]))
vb@357
  1534
        return PEP_ILLEGAL_VALUE;
vb@357
  1535
roker@529
  1536
    sqlite3_reset(session->mark_compromized);
vb@357
  1537
    sqlite3_bind_text(session->mark_compromized, 1, fpr, -1,
vb@357
  1538
            SQLITE_STATIC);
vb@357
  1539
    result = sqlite3_step(session->mark_compromized);
roker@529
  1540
    sqlite3_reset(session->mark_compromized);
vb@357
  1541
vb@357
  1542
    if (result != SQLITE_DONE)
Edouard@584
  1543
        return PEP_CANNOT_SET_TRUST;
vb@357
  1544
vb@357
  1545
    return PEP_STATUS_OK;
vb@357
  1546
}
vb@357
  1547
vb@0
  1548
void pEp_free(void *p)
vb@0
  1549
{
vb@0
  1550
    free(p);
vb@0
  1551
}
vb@0
  1552
vb@8
  1553
DYNAMIC_API PEP_STATUS get_trust(PEP_SESSION session, pEp_identity *identity)
vb@8
  1554
{
vb@8
  1555
    PEP_STATUS status = PEP_STATUS_OK;
vb@8
  1556
    int result;
vb@8
  1557
vb@8
  1558
    assert(session);
vb@8
  1559
    assert(identity);
vb@8
  1560
    assert(identity->user_id);
vb@8
  1561
    assert(identity->user_id[0]);
vb@8
  1562
    assert(identity->fpr);
vb@8
  1563
    assert(identity->fpr[0]);
vb@8
  1564
vb@191
  1565
    if (!(session && identity && identity->user_id && identity->user_id[0] &&
vb@191
  1566
                identity->fpr && identity->fpr[0]))
vb@191
  1567
        return PEP_ILLEGAL_VALUE;
vb@191
  1568
vb@8
  1569
    identity->comm_type = PEP_ct_unknown;
vb@8
  1570
vb@46
  1571
    sqlite3_reset(session->get_trust);
vb@951
  1572
    sqlite3_bind_text(session->get_trust, 1, identity->user_id, -1,
vb@951
  1573
            SQLITE_STATIC);
vb@46
  1574
    sqlite3_bind_text(session->get_trust, 2, identity->fpr, -1, SQLITE_STATIC);
vb@8
  1575
vb@46
  1576
    result = sqlite3_step(session->get_trust);
vb@8
  1577
    switch (result) {
vb@8
  1578
    case SQLITE_ROW: {
vb@951
  1579
        int comm_type = (PEP_comm_type) sqlite3_column_int(session->get_trust,
vb@951
  1580
                0);
vb@8
  1581
        identity->comm_type = comm_type;
vb@8
  1582
        break;
vb@8
  1583
    }
vb@8
  1584
 
vb@8
  1585
    default:
vb@8
  1586
        status = PEP_CANNOT_FIND_IDENTITY;
vb@8
  1587
    }
vb@8
  1588
vb@46
  1589
    sqlite3_reset(session->get_trust);
vb@8
  1590
    return status;
vb@9
  1591
}
vb@9
  1592
vb@251
  1593
DYNAMIC_API PEP_STATUS least_trust(
vb@251
  1594
        PEP_SESSION session,
vb@251
  1595
        const char *fpr,
vb@251
  1596
        PEP_comm_type *comm_type
vb@251
  1597
    )
vb@251
  1598
{
vb@251
  1599
    PEP_STATUS status = PEP_STATUS_OK;
vb@251
  1600
    int result;
vb@251
  1601
vb@251
  1602
    assert(session);
vb@251
  1603
    assert(fpr);
vb@251
  1604
    assert(comm_type);
vb@251
  1605
vb@251
  1606
    if (!(session && fpr && comm_type))
vb@251
  1607
        return PEP_ILLEGAL_VALUE;
vb@251
  1608
vb@632
  1609
    *comm_type = PEP_ct_unknown;
vb@632
  1610
vb@251
  1611
    sqlite3_reset(session->least_trust);
vb@251
  1612
    sqlite3_bind_text(session->least_trust, 1, fpr, -1, SQLITE_STATIC);
vb@251
  1613
vb@251
  1614
    result = sqlite3_step(session->least_trust);
vb@251
  1615
    switch (result) {
vb@251
  1616
        case SQLITE_ROW: {
vb@259
  1617
            int _comm_type = sqlite3_column_int(session->least_trust, 0);
vb@259
  1618
            *comm_type = (PEP_comm_type) _comm_type;
vb@251
  1619
            break;
vb@251
  1620
        }
vb@251
  1621
        default:
edouard@1632
  1622
            // never reached because of sql min()
vb@251
  1623
            status = PEP_CANNOT_FIND_IDENTITY;
vb@251
  1624
    }
vb@251
  1625
vb@251
  1626
    sqlite3_reset(session->least_trust);
vb@251
  1627
    return status;
vb@251
  1628
}
vb@251
  1629
vb@24
  1630
DYNAMIC_API PEP_STATUS decrypt_and_verify(
vb@24
  1631
    PEP_SESSION session, const char *ctext, size_t csize,
krista@1397
  1632
    const char *dsigtext, size_t dsigsize,
vb@24
  1633
    char **ptext, size_t *psize, stringlist_t **keylist
vb@24
  1634
    )
vb@24
  1635
{
vb@191
  1636
    assert(session);
vb@191
  1637
    assert(ctext);
vb@191
  1638
    assert(csize);
vb@191
  1639
    assert(ptext);
vb@191
  1640
    assert(psize);
vb@191
  1641
    assert(keylist);
vb@191
  1642
vb@939
  1643
    if (!(session && ctext && csize && ptext && psize && keylist))
vb@191
  1644
        return PEP_ILLEGAL_VALUE;
vb@191
  1645
vb@939
  1646
    return session->cryptotech[PEP_crypt_OpenPGP].decrypt_and_verify(
krista@1397
  1647
            session, ctext, csize, dsigtext, dsigsize, ptext, psize, keylist);
vb@24
  1648
}
vb@24
  1649
vb@24
  1650
DYNAMIC_API PEP_STATUS encrypt_and_sign(
vb@24
  1651
    PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
vb@24
  1652
    size_t psize, char **ctext, size_t *csize
vb@24
  1653
    )
vb@24
  1654
{
vb@191
  1655
    assert(session);
vb@191
  1656
    assert(keylist);
vb@191
  1657
    assert(ptext);
vb@191
  1658
    assert(psize);
vb@191
  1659
    assert(ctext);
vb@191
  1660
    assert(csize);
vb@191
  1661
vb@191
  1662
    if (!(session && keylist && ptext && psize && ctext && csize))
vb@191
  1663
        return PEP_ILLEGAL_VALUE;
vb@191
  1664
vb@951
  1665
    return session->cryptotech[PEP_crypt_OpenPGP].encrypt_and_sign(session,
vb@951
  1666
            keylist, ptext, psize, ctext, csize);
vb@24
  1667
}
vb@24
  1668
krista@1639
  1669
PEP_STATUS encrypt_only(
krista@1639
  1670
    PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
krista@1639
  1671
    size_t psize, char **ctext, size_t *csize
krista@1639
  1672
    )
krista@1639
  1673
{
krista@1639
  1674
    assert(session);
krista@1639
  1675
    assert(keylist);
krista@1639
  1676
    assert(ptext);
krista@1639
  1677
    assert(psize);
krista@1639
  1678
    assert(ctext);
krista@1639
  1679
    assert(csize);
krista@1639
  1680
krista@1639
  1681
    if (!(session && keylist && ptext && psize && ctext && csize))
krista@1639
  1682
        return PEP_ILLEGAL_VALUE;
krista@1639
  1683
krista@1639
  1684
    return session->cryptotech[PEP_crypt_OpenPGP].encrypt_only(session,
krista@1639
  1685
            keylist, ptext, psize, ctext, csize);
krista@1639
  1686
}
krista@1639
  1687
krista@1639
  1688
vb@24
  1689
DYNAMIC_API PEP_STATUS verify_text(
vb@24
  1690
    PEP_SESSION session, const char *text, size_t size,
vb@24
  1691
    const char *signature, size_t sig_size, stringlist_t **keylist
vb@24
  1692
    )
vb@24
  1693
{
vb@191
  1694
    assert(session);
vb@191
  1695
    assert(text);
vb@191
  1696
    assert(size);
vb@191
  1697
    assert(signature);
vb@191
  1698
    assert(sig_size);
vb@191
  1699
    assert(keylist);
vb@191
  1700
vb@191
  1701
    if (!(session && text && size && signature && sig_size && keylist))
vb@191
  1702
        return PEP_ILLEGAL_VALUE;
vb@191
  1703
vb@951
  1704
    return session->cryptotech[PEP_crypt_OpenPGP].verify_text(session, text,
vb@951
  1705
            size, signature, sig_size, keylist);
vb@24
  1706
}
vb@24
  1707
vb@24
  1708
DYNAMIC_API PEP_STATUS delete_keypair(PEP_SESSION session, const char *fpr)
vb@24
  1709
{
vb@191
  1710
    assert(session);
vb@191
  1711
    assert(fpr);
vb@191
  1712
vb@191
  1713
    if (!(session && fpr))
vb@191
  1714
        return PEP_ILLEGAL_VALUE;
vb@191
  1715
vb@46
  1716
    return session->cryptotech[PEP_crypt_OpenPGP].delete_keypair(session, fpr);
vb@24
  1717
}
vb@24
  1718
vb@24
  1719
DYNAMIC_API PEP_STATUS export_key(
vb@46
  1720
        PEP_SESSION session, const char *fpr, char **key_data, size_t *size
vb@24
  1721
    )
vb@24
  1722
{
vb@191
  1723
    assert(session);
vb@191
  1724
    assert(fpr);
vb@191
  1725
    assert(key_data);
vb@191
  1726
    assert(size);
vb@191
  1727
vb@191
  1728
    if (!(session && fpr && key_data && size))
vb@191
  1729
        return PEP_ILLEGAL_VALUE;
vb@191
  1730
vb@951
  1731
    return session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr,
vb@1103
  1732
            key_data, size, false);
vb@1103
  1733
}
vb@1103
  1734
vb@1133
  1735
DYNAMIC_API PEP_STATUS export_secrect_key(
vb@1103
  1736
        PEP_SESSION session, const char *fpr, char **key_data, size_t *size
vb@1103
  1737
    )
vb@1103
  1738
{
vb@1103
  1739
    assert(session);
vb@1103
  1740
    assert(fpr);
vb@1103
  1741
    assert(key_data);
vb@1103
  1742
    assert(size);
vb@1103
  1743
vb@1103
  1744
    if (!(session && fpr && key_data && size))
vb@1103
  1745
        return PEP_ILLEGAL_VALUE;
vb@1103
  1746
vb@1103
  1747
    // don't accept key IDs but full fingerprints only
vb@1103
  1748
    if (strlen(fpr) < 16)
vb@1103
  1749
        return PEP_ILLEGAL_VALUE;
vb@1103
  1750
vb@1103
  1751
    return session->cryptotech[PEP_crypt_OpenPGP].export_key(session, fpr,
vb@1103
  1752
            key_data, size, true);
vb@24
  1753
}
vb@24
  1754
vb@24
  1755
DYNAMIC_API PEP_STATUS find_keys(
vb@46
  1756
        PEP_SESSION session, const char *pattern, stringlist_t **keylist
vb@24
  1757
    )
vb@24
  1758
{
vb@191
  1759
    assert(session);
vb@191
  1760
    assert(pattern);
vb@191
  1761
    assert(keylist);
vb@191
  1762
vb@191
  1763
    if (!(session && pattern && keylist))
vb@191
  1764
        return PEP_ILLEGAL_VALUE;
vb@191
  1765
vb@951
  1766
    return session->cryptotech[PEP_crypt_OpenPGP].find_keys(session, pattern,
vb@951
  1767
            keylist);
vb@24
  1768
}
vb@24
  1769
krista@1005
  1770
vb@24
  1771
DYNAMIC_API PEP_STATUS generate_keypair(
vb@46
  1772
        PEP_SESSION session, pEp_identity *identity
vb@24
  1773
    )
vb@24
  1774
{
vb@191
  1775
    assert(session);
vb@191
  1776
    assert(identity);
vb@191
  1777
    assert(identity->address);
vb@298
  1778
    assert(identity->fpr == NULL || identity->fpr[0] == 0);
vb@191
  1779
    assert(identity->username);
vb@191
  1780
vb@298
  1781
    if (!(session && identity && identity->address &&
vb@951
  1782
            (identity->fpr == NULL || identity->fpr[0] == 0) &&
vb@951
  1783
            identity->username))
vb@191
  1784
        return PEP_ILLEGAL_VALUE;
vb@191
  1785
vb@944
  1786
    PEP_STATUS status =
vb@944
  1787
        session->cryptotech[PEP_crypt_OpenPGP].generate_keypair(session,
vb@944
  1788
                identity);
vb@944
  1789
    if (status != PEP_STATUS_OK)
vb@944
  1790
        return status;
vb@944
  1791
vb@944
  1792
    return status;
vb@24
  1793
}
vb@24
  1794
vb@9
  1795
DYNAMIC_API PEP_STATUS get_key_rating(
vb@46
  1796
        PEP_SESSION session,
vb@46
  1797
        const char *fpr,
vb@46
  1798
        PEP_comm_type *comm_type
vb@9
  1799
    )
vb@9
  1800
{
vb@191
  1801
    assert(session);
vb@191
  1802
    assert(fpr);
vb@191
  1803
    assert(comm_type);
vb@191
  1804
vb@191
  1805
    if (!(session && fpr && comm_type))
vb@191
  1806
        return PEP_ILLEGAL_VALUE;
vb@191
  1807
vb@951
  1808
    return session->cryptotech[PEP_crypt_OpenPGP].get_key_rating(session, fpr,
vb@951
  1809
            comm_type);
vb@24
  1810
}
vb@9
  1811
Edouard@728
  1812
DYNAMIC_API PEP_STATUS import_key(
Edouard@728
  1813
        PEP_SESSION session,
Edouard@728
  1814
        const char *key_data,
Edouard@728
  1815
        size_t size,
Edouard@728
  1816
        identity_list **private_keys
Edouard@728
  1817
    )
vb@24
  1818
{
vb@191
  1819
    assert(session);
vb@191
  1820
    assert(key_data);
vb@191
  1821
vb@191
  1822
    if (!(session && key_data))
vb@191
  1823
        return PEP_ILLEGAL_VALUE;
vb@191
  1824
vb@951
  1825
    return session->cryptotech[PEP_crypt_OpenPGP].import_key(session, key_data,
vb@951
  1826
            size, private_keys);
vb@24
  1827
}
vb@9
  1828
vb@24
  1829
DYNAMIC_API PEP_STATUS recv_key(PEP_SESSION session, const char *pattern)
vb@24
  1830
{
vb@191
  1831
    assert(session);
vb@191
  1832
    assert(pattern);
vb@191
  1833
vb@191
  1834
    if (!(session && pattern))
vb@191
  1835
        return PEP_ILLEGAL_VALUE;
vb@191
  1836
vb@46
  1837
    return session->cryptotech[PEP_crypt_OpenPGP].recv_key(session, pattern);
vb@24
  1838
}
vb@9
  1839
vb@24
  1840
DYNAMIC_API PEP_STATUS send_key(PEP_SESSION session, const char *pattern)
vb@24
  1841
{
vb@191
  1842
    assert(session);
vb@191
  1843
    assert(pattern);
vb@191
  1844
vb@191
  1845
    if (!(session && pattern))
vb@191
  1846
        return PEP_ILLEGAL_VALUE;
vb@191
  1847
vb@46
  1848
    return session->cryptotech[PEP_crypt_OpenPGP].send_key(session, pattern);
vb@14
  1849
}
vb@196
  1850
vb@201
  1851
DYNAMIC_API PEP_STATUS renew_key(
vb@201
  1852
        PEP_SESSION session,
vb@201
  1853
        const char *fpr,
vb@201
  1854
        const timestamp *ts
vb@201
  1855
    )
vb@196
  1856
{
vb@196
  1857
    assert(session);
vb@200
  1858
    assert(fpr);
vb@196
  1859
vb@200
  1860
    if (!(session && fpr))
vb@196
  1861
        return PEP_ILLEGAL_VALUE;
vb@196
  1862
vb@201
  1863
    return session->cryptotech[PEP_crypt_OpenPGP].renew_key(session, fpr, ts);
vb@196
  1864
}
vb@196
  1865
vb@211
  1866
DYNAMIC_API PEP_STATUS revoke_key(
vb@211
  1867
        PEP_SESSION session,
vb@211
  1868
        const char *fpr,
vb@211
  1869
        const char *reason
vb@211
  1870
    )
vb@197
  1871
{
vb@197
  1872
    assert(session);
vb@200
  1873
    assert(fpr);
vb@197
  1874
vb@200
  1875
    if (!(session && fpr))
vb@197
  1876
        return PEP_ILLEGAL_VALUE;
vb@197
  1877
vb@214
  1878
    return session->cryptotech[PEP_crypt_OpenPGP].revoke_key(session, fpr,
vb@214
  1879
            reason);
vb@197
  1880
}
vb@197
  1881
vb@214
  1882
DYNAMIC_API PEP_STATUS key_expired(
vb@214
  1883
        PEP_SESSION session,
vb@214
  1884
        const char *fpr,
Edouard@701
  1885
        const time_t when,
vb@214
  1886
        bool *expired
vb@214
  1887
    )
vb@214
  1888
{
vb@214
  1889
    assert(session);
vb@214
  1890
    assert(fpr);
vb@214
  1891
    assert(expired);
vb@214
  1892
vb@214
  1893
    if (!(session && fpr && expired))
vb@214
  1894
        return PEP_ILLEGAL_VALUE;
vb@214
  1895
vb@214
  1896
    return session->cryptotech[PEP_crypt_OpenPGP].key_expired(session, fpr,
Edouard@701
  1897
            when, expired);
vb@214
  1898
}
vb@214
  1899
Edouard@694
  1900
DYNAMIC_API PEP_STATUS key_revoked(
vb@951
  1901
       PEP_SESSION session,
vb@951
  1902
       const char *fpr,
vb@951
  1903
       bool *revoked
vb@951
  1904
   )
Edouard@694
  1905
{
Edouard@694
  1906
    assert(session);
Edouard@694
  1907
    assert(fpr);
Edouard@694
  1908
    assert(revoked);
Edouard@694
  1909
    
Edouard@694
  1910
    if (!(session && fpr && revoked))
Edouard@694
  1911
        return PEP_ILLEGAL_VALUE;
Edouard@694
  1912
    
Edouard@694
  1913
    return session->cryptotech[PEP_crypt_OpenPGP].key_revoked(session, fpr,
vb@951
  1914
            revoked);
Edouard@694
  1915
}
Edouard@694
  1916
vb@451
  1917
static void _clean_log_value(char *text)
vb@451
  1918
{
vb@451
  1919
    if (text) {
vb@451
  1920
        for (char *c = text; *c; c++) {
vb@722
  1921
            if (*c < 32 && *c != '\n')
vb@451
  1922
                *c = 32;
vb@451
  1923
            else if (*c == '"')
vb@451
  1924
                *c = '\'';
vb@451
  1925
        }
vb@451
  1926
    }
vb@451
  1927
}
vb@451
  1928
vb@450
  1929
static char *_concat_string(char *str1, const char *str2, char delim)
vb@450
  1930
{
vb@454
  1931
    str2 = str2 ? str2 : "";
vb@450
  1932
    size_t len1 = str1 ? strlen(str1) : 0;
vb@450
  1933
    size_t len2 = strlen(str2);
vb@450
  1934
    size_t len = len1 + len2 + 3;
vb@450
  1935
    char * result = realloc(str1, len + 1);
vb@450
  1936
vb@450
  1937
    if (result) {
vb@450
  1938
        result[len1] = '"';
vb@450
  1939
        strcpy(result + len1 + 1, str2);
vb@450
  1940
        result[len - 2] = '"';
vb@450
  1941
        result[len - 1] = delim;
vb@450
  1942
        result[len] = 0;
vb@450
  1943
    }
vb@450
  1944
    else {
vb@450
  1945
        free(str1);
vb@450
  1946
    }
vb@450
  1947
vb@450
  1948
    return result;
vb@450
  1949
}
vb@450
  1950
vb@450
  1951
DYNAMIC_API PEP_STATUS get_crashdump_log(
vb@450
  1952
        PEP_SESSION session,
vb@450
  1953
        int maxlines,
vb@450
  1954
        char **logdata
vb@450
  1955
    )
vb@450
  1956
{
vb@450
  1957
    PEP_STATUS status = PEP_STATUS_OK;
vb@450
  1958
    char *_logdata= NULL;
vb@450
  1959
vb@450
  1960
    assert(session);
vb@450
  1961
    assert(maxlines >= 0 && maxlines <= CRASHDUMP_MAX_LINES);
vb@450
  1962
    assert(logdata);
vb@450
  1963
vb@450
  1964
    if (!(session && logdata && maxlines >= 0 && maxlines <=
vb@450
  1965
            CRASHDUMP_MAX_LINES))
vb@450
  1966
        return PEP_ILLEGAL_VALUE;
vb@450
  1967
vb@632
  1968
    *logdata = NULL;
vb@632
  1969
vb@450
  1970
    int limit = maxlines ? maxlines : CRASHDUMP_DEFAULT_LINES;
vb@458
  1971
    const char *timestamp = NULL;
vb@458
  1972
    const char *title = NULL;
vb@458
  1973
    const char *entity = NULL;
vb@458
  1974
    const char *desc = NULL;
vb@458
  1975
    const char *comment = NULL;
vb@450
  1976
vb@450
  1977
    sqlite3_reset(session->crashdump);
vb@452
  1978
    sqlite3_bind_int(session->crashdump, 1, limit);
vb@450
  1979
vb@450
  1980
    int result;
vb@450
  1981
vb@450
  1982
    do {
vb@450
  1983
        result = sqlite3_step(session->crashdump);
vb@450
  1984
        switch (result) {
vb@450
  1985
        case SQLITE_ROW:
vb@951
  1986
            timestamp = (const char *) sqlite3_column_text(session->crashdump,
vb@951
  1987
                    0);
vb@951
  1988
            title   = (const char *) sqlite3_column_text(session->crashdump,
vb@951
  1989
                    1);
vb@951
  1990
            entity  = (const char *) sqlite3_column_text(session->crashdump,
vb@951
  1991
                    2);
vb@951
  1992
            desc    = (const char *) sqlite3_column_text(session->crashdump,
vb@951
  1993
                    3);
vb@951
  1994
            comment = (const char *) sqlite3_column_text(session->crashdump,
vb@951
  1995
                    4);
vb@452
  1996
vb@452
  1997
            _logdata = _concat_string(_logdata, timestamp, ',');
vb@452
  1998
            if (_logdata == NULL)
vb@452
  1999
                goto enomem;
vb@450
  2000
vb@450
  2001
            _logdata = _concat_string(_logdata, title, ',');
vb@450
  2002
            if (_logdata == NULL)
vb@450
  2003
                goto enomem;
vb@450
  2004
vb@450
  2005
            _logdata = _concat_string(_logdata, entity, ',');
vb@450
  2006
            if (_logdata == NULL)
vb@450
  2007
                goto enomem;
vb@450
  2008
vb@450
  2009
            _logdata = _concat_string(_logdata, desc, ',');
vb@450
  2010
            if (_logdata == NULL)
vb@450
  2011
                goto enomem;
vb@450
  2012
vb@450
  2013
            _logdata = _concat_string(_logdata, comment, '\n');
vb@450
  2014
            if (_logdata == NULL)
vb@450
  2015
                goto enomem;
vb@450
  2016
vb@687
  2017
            _clean_log_value(_logdata);
vb@450
  2018
            break;
vb@450
  2019
vb@450
  2020
        case SQLITE_DONE:
vb@450
  2021
            break;
vb@450
  2022
vb@450
  2023
        default:
vb@450
  2024
            status = PEP_UNKNOWN_ERROR;
vb@450
  2025
            result = SQLITE_DONE;
vb@450
  2026
        }
vb@450
  2027
    } while (result != SQLITE_DONE);
vb@450
  2028
vb@450
  2029
    sqlite3_reset(session->crashdump);
vb@450
  2030
    if (status == PEP_STATUS_OK)
vb@450
  2031
        *logdata = _logdata;
vb@450
  2032
vb@450
  2033
    goto the_end;
vb@450
  2034
vb@450
  2035
enomem:
vb@450
  2036
    status = PEP_OUT_OF_MEMORY;
vb@450
  2037
vb@450
  2038
the_end:
roker@1853
  2039
    return ADD_TO_LOG(status);
vb@450
  2040
}
vb@450
  2041
vb@458
  2042
DYNAMIC_API PEP_STATUS get_languagelist(
vb@458
  2043
        PEP_SESSION session,
vb@458
  2044
        char **languages
vb@458
  2045
    )
vb@458
  2046
{
vb@458
  2047
    PEP_STATUS status = PEP_STATUS_OK;
vb@458
  2048
    char *_languages= NULL;
vb@458
  2049
vb@458
  2050
    assert(session);
vb@458
  2051
    assert(languages);
vb@458
  2052
vb@458
  2053
    if (!(session && languages))
vb@458
  2054
        return PEP_ILLEGAL_VALUE;
vb@458
  2055
vb@632
  2056
    *languages = NULL;
vb@632
  2057
vb@458
  2058
    const char *lang = NULL;
vb@458
  2059
    const char *name = NULL;
vb@617
  2060
    const char *phrase = NULL;
vb@458
  2061
vb@458
  2062
    sqlite3_reset(session->languagelist);
vb@458
  2063
vb@458
  2064
    int result;
vb@458
  2065
vb@458
  2066
    do {
vb@458
  2067
        result = sqlite3_step(session->languagelist);
vb@458
  2068
        switch (result) {
vb@458
  2069
        case SQLITE_ROW:
vb@951
  2070
            lang = (const char *) sqlite3_column_text(session->languagelist,
vb@951
  2071
                    0);
vb@951
  2072
            name = (const char *) sqlite3_column_text(session->languagelist,
vb@951
  2073
                    1);
vb@951
  2074
            phrase = (const char *) sqlite3_column_text(session->languagelist,
vb@951
  2075
                    2);
vb@458
  2076
vb@458
  2077
            _languages = _concat_string(_languages, lang, ',');
vb@458
  2078
            if (_languages == NULL)
vb@458
  2079
                goto enomem;
vb@458
  2080
vb@617
  2081
            _languages = _concat_string(_languages, name, ',');
vb@617
  2082
            if (_languages == NULL)
vb@617
  2083
                goto enomem;
vb@617
  2084
vb@617
  2085
            _languages = _concat_string(_languages, phrase, '\n');
vb@458
  2086
            if (_languages == NULL)
vb@458
  2087
                goto enomem;
vb@458
  2088
vb@458
  2089
            break;
vb@458
  2090
vb@458
  2091
        case SQLITE_DONE:
vb@458
  2092
            break;
vb@458
  2093
vb@458
  2094
        default:
vb@458
  2095
            status = PEP_UNKNOWN_ERROR;
vb@458
  2096
            result = SQLITE_DONE;
vb@458
  2097
        }
vb@458
  2098
    } while (result != SQLITE_DONE);
vb@458
  2099
vb@458
  2100
    sqlite3_reset(session->languagelist);
vb@458
  2101
    if (status == PEP_STATUS_OK)
vb@458
  2102
        *languages = _languages;
vb@458
  2103
vb@458
  2104
    goto the_end;
vb@458
  2105
vb@458
  2106
enomem:
vb@458
  2107
    status = PEP_OUT_OF_MEMORY;
vb@458
  2108
vb@458
  2109
the_end:
vb@458
  2110
    return status;
vb@458
  2111
}
vb@458
  2112
vb@458
  2113
DYNAMIC_API PEP_STATUS get_phrase(
vb@458
  2114
        PEP_SESSION session,
vb@458
  2115
        const char *lang,
vb@458
  2116
        int phrase_id,
vb@458
  2117
        char **phrase
vb@458
  2118
    )
vb@458
  2119
{
vb@458
  2120
    PEP_STATUS status = PEP_STATUS_OK;
vb@458
  2121
vb@479
  2122
    assert(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase);
vb@479
  2123
    if (!(session && lang && lang[0] && lang[1] && lang[2] == 0 && phrase))
vb@458
  2124
        return PEP_ILLEGAL_VALUE;
vb@458
  2125
vb@632
  2126
    *phrase = NULL;
vb@632
  2127
vb@458
  2128
    sqlite3_reset(session->i18n_token);
roker@529
  2129
    sqlite3_bind_text(session->i18n_token, 1, lang, -1, SQLITE_STATIC);
roker@529
  2130
    sqlite3_bind_int(session->i18n_token, 2, phrase_id);
vb@458
  2131
vb@458
  2132
    const char *_phrase = NULL;
vb@458
  2133
    int result;
vb@458
  2134
vb@458
  2135
    result = sqlite3_step(session->i18n_token);
vb@458
  2136
    switch (result) {
vb@458
  2137
    case SQLITE_ROW:
vb@458
  2138
        _phrase = (const char *) sqlite3_column_text(session->i18n_token, 0);
vb@458
  2139
        break;
vb@458
  2140
vb@458
  2141
    case SQLITE_DONE:
vb@458
  2142
        status = PEP_PHRASE_NOT_FOUND;
vb@458
  2143
        break;
vb@458
  2144
vb@458
  2145
    default:
vb@458
  2146
        status = PEP_UNKNOWN_ERROR;
vb@458
  2147
    }
vb@458
  2148
vb@458
  2149
    if (status == PEP_STATUS_OK) {
vb@458
  2150
        *phrase = strdup(_phrase);
vb@458
  2151
        if (*phrase == NULL)
vb@458
  2152
            goto enomem;
vb@458
  2153
    }
vb@459
  2154
vb@459
  2155
    sqlite3_reset(session->i18n_token);
vb@458
  2156
    goto the_end;
vb@458
  2157
vb@458
  2158
enomem:
vb@458
  2159
    status = PEP_OUT_OF_MEMORY;
vb@458
  2160
vb@458
  2161
the_end:
vb@458
  2162
    return status;
vb@458
  2163
}
vb@458
  2164
vb@1085
  2165
static PEP_STATUS _get_sequence_value(PEP_SESSION session, const char *name,
vb@1085
  2166
        int32_t *value)
vb@1085
  2167
{
vb@1086
  2168
    assert(session && name && value);
vb@1086
  2169
    if (!(session && name && value))
vb@1086
  2170
        return PEP_ILLEGAL_VALUE;
vb@1086
  2171
vb@1085
  2172
    PEP_STATUS status = PEP_STATUS_OK;
vb@1085
  2173
vb@1085
  2174
    sqlite3_reset(session->sequence_value2);
vb@1085
  2175
    sqlite3_bind_text(session->sequence_value2, 1, name, -1,
vb@1085
  2176
            SQLITE_STATIC);
vb@1085
  2177
    int result = sqlite3_step(session->sequence_value2);
vb@1085
  2178
    switch (result) {
vb@1085
  2179
        case SQLITE_ROW: {
vb@1085
  2180
            int32_t _value = (int32_t)
vb@1086
  2181
                    sqlite3_column_int(session->sequence_value2, 0);
vb@1086
  2182
            int _own = (int)
vb@1086
  2183
                    sqlite3_column_int(session->sequence_value2, 1);
vb@1085
  2184
            *value = _value;
vb@1086
  2185
            if (_own)
vb@1086
  2186
                status = PEP_OWN_SEQUENCE;
vb@1085
  2187
            break;
vb@1085
  2188
        }
vb@1091
  2189
        case SQLITE_DONE:
vb@1091
  2190
            status = PEP_RECORD_NOT_FOUND;
vb@1091
  2191
            break;
vb@1085
  2192
        default:
vb@1085
  2193
            status = PEP_UNKNOWN_ERROR;
vb@1085
  2194
    }
vb@1085
  2195
    sqlite3_reset(session->sequence_value2);
vb@1085
  2196
vb@1085
  2197
    return status;
vb@1085
  2198
}
vb@1085
  2199
vb@1086
  2200
static PEP_STATUS _increment_sequence_value(PEP_SESSION session,
vb@1086
  2201
        const char *name, int own)
vb@1085
  2202
{
vb@1086
  2203
    assert(session && name);
vb@1086
  2204
    if (!(session && name))
vb@1086
  2205
        return PEP_ILLEGAL_VALUE;
vb@1086
  2206
vb@1085
  2207
    sqlite3_reset(session->sequence_value1);
vb@1085
  2208
    sqlite3_bind_text(session->sequence_value1, 1, name, -1, SQLITE_STATIC);
vb@1086
  2209
    sqlite3_bind_int(session->sequence_value1, 2, own);
vb@1085
  2210
    int result = sqlite3_step(session->sequence_value1);
vb@1085
  2211
    assert(result == SQLITE_DONE);
vb@1085
  2212
    sqlite3_reset(session->sequence_value1);
vb@1085
  2213
    if (result == SQLITE_DONE)
vb@1085
  2214
        return PEP_STATUS_OK;
vb@1085
  2215
    else
vb@1085
  2216
        return PEP_CANNOT_INCREASE_SEQUENCE;
vb@1085
  2217
}
vb@1085
  2218
vb@1087
  2219
static PEP_STATUS _set_sequence_value(PEP_SESSION session,
vb@1091
  2220
        const char *name, int32_t value, int own)
vb@1087
  2221
{
vb@1087
  2222
    assert(session && name && value > 0);
vb@1087
  2223
    if (!(session && name && value > 0))
vb@1087
  2224
        return PEP_ILLEGAL_VALUE;
vb@1087
  2225
vb@1087
  2226
    sqlite3_reset(session->sequence_value3);
vb@1087
  2227
    sqlite3_bind_text(session->sequence_value3, 1, name, -1, SQLITE_STATIC);
vb@1087
  2228
    sqlite3_bind_int(session->sequence_value3, 2, value);
vb@1091
  2229
    sqlite3_bind_int(session->sequence_value3, 3, own);
vb@1087
  2230
    int result = sqlite3_step(session->sequence_value3);
vb@1087
  2231
    assert(result == SQLITE_DONE);
vb@1087
  2232
    sqlite3_reset(session->sequence_value3);
vb@1087
  2233
    if (result == SQLITE_DONE)
vb@1087
  2234
        return PEP_STATUS_OK;
vb@1087
  2235
    else
vb@1087
  2236
        return PEP_CANNOT_SET_SEQUENCE_VALUE;
vb@1087
  2237
}
vb@1087
  2238
vb@632
  2239
DYNAMIC_API PEP_STATUS sequence_value(
vb@632
  2240
        PEP_SESSION session,
vb@1085
  2241
        char *name,
vb@652
  2242
        int32_t *value
vb@632
  2243
    )
vb@632
  2244
{
vb@632
  2245
    PEP_STATUS status = PEP_STATUS_OK;
edouard@1568
  2246
    int result;
vb@632
  2247
vb@632
  2248
    assert(session);
vb@1085
  2249
    assert(name && value && *value >= 0);
vb@632
  2250
vb@1085
  2251
    if (!(session && name && value && *value >= 0))
vb@632
  2252
        return PEP_ILLEGAL_VALUE;
vb@632
  2253
vb@1086
  2254
    int own = 0;
vb@1085
  2255
    if (!name[0]) {
markus@1259
  2256
        pEpUUID uuid;
vb@1085
  2257
        uuid_generate_random(uuid);
vb@1085
  2258
        uuid_unparse_upper(uuid, name);
vb@1086
  2259
        own = 1;
vb@633
  2260
    }
vb@633
  2261
    else {
edouard@1603
  2262
        if (name == session->sync_session->sync_uuid || 
edouard@1603
  2263
            strcmp(name, session->sync_session->sync_uuid) == 0)
vb@1091
  2264
            own = 1;
vb@1091
  2265
    }
krista@1032
  2266
vb@1085
  2267
    if (*value) {
edouard@1568
  2268
        sqlite3_exec(session->db, "BEGIN ;", NULL, NULL, NULL);
vb@1085
  2269
        int32_t old_value = 0;
vb@1085
  2270
        status = _get_sequence_value(session, name, &old_value);
vb@1091
  2271
        if (status != PEP_STATUS_OK && status != PEP_RECORD_NOT_FOUND)
edouard@1568
  2272
        {
edouard@1568
  2273
            sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
vb@1085
  2274
            return status;
edouard@1568
  2275
        }
vb@1085
  2276
vb@1087
  2277
        if (old_value >= *value) {
edouard@1568
  2278
            sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
vb@1085
  2279
            return PEP_SEQUENCE_VIOLATED;
vb@632
  2280
        }
vb@1087
  2281
        else {
vb@1091
  2282
            status = _set_sequence_value(session, name, *value, own);
edouard@1568
  2283
            if (status == PEP_STATUS_OK) {
edouard@1568
  2284
                result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
edouard@1568
  2285
                if (result == SQLITE_OK)
edouard@1568
  2286
                    return PEP_STATUS_OK;
edouard@1568
  2287
                else
edouard@1568
  2288
                    return PEP_COMMIT_FAILED;
edouard@1568
  2289
            } else {
edouard@1568
  2290
                sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
edouard@1568
  2291
                return status;
edouard@1568
  2292
            }
vb@1087
  2293
        }
krista@1032
  2294
    }
vb@1085
  2295
vb@1085
  2296
    assert(*value == 0);
edouard@1568
  2297
    sqlite3_exec(session->db, "BEGIN ;", NULL, NULL, NULL);
vb@1086
  2298
    status = _increment_sequence_value(session, name, own);
vb@1086
  2299
    if (status == PEP_STATUS_OK) {
vb@1085
  2300
        status = _get_sequence_value(session, name, value);
edouard@1572
  2301
    }
edouard@1572
  2302
    if (status == PEP_STATUS_OK || status == PEP_OWN_SEQUENCE) {
edouard@1568
  2303
        result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
edouard@1568
  2304
        if (result == SQLITE_OK){
edouard@1568
  2305
            assert(*value < INT32_MAX);
edouard@1568
  2306
            if (*value == INT32_MAX){
edouard@1568
  2307
                return PEP_CANNOT_INCREASE_SEQUENCE;
edouard@1568
  2308
            }
edouard@1572
  2309
            return status;
edouard@1568
  2310
        } else {
edouard@1568
  2311
            return PEP_COMMIT_FAILED;
edouard@1568
  2312
        }
edouard@1568
  2313
    } else {
edouard@1568
  2314
        sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
edouard@1568
  2315
        return status;
vb@632
  2316
    }
vb@632
  2317
    return status;
vb@632
  2318
}
vb@632
  2319
Edouard@693
  2320
DYNAMIC_API PEP_STATUS set_revoked(
Edouard@693
  2321
       PEP_SESSION session,
Edouard@693
  2322
       const char *revoked_fpr,
Edouard@693
  2323
       const char *replacement_fpr,
Edouard@693
  2324
       const uint64_t revocation_date
Edouard@693
  2325
    )
Edouard@693
  2326
{
Edouard@693
  2327
    PEP_STATUS status = PEP_STATUS_OK;
Edouard@693
  2328
    
Edouard@693
  2329
    assert(session &&
Edouard@693
  2330
           revoked_fpr && revoked_fpr[0] &&
Edouard@693
  2331
           replacement_fpr && replacement_fpr[0]
Edouard@693
  2332
          );
Edouard@693
  2333
    
Edouard@693
  2334
    if (!(session &&
Edouard@693
  2335
          revoked_fpr && revoked_fpr[0] &&
Edouard@693
  2336
          replacement_fpr && replacement_fpr[0]
Edouard@693
  2337
         ))
Edouard@693
  2338
        return PEP_ILLEGAL_VALUE;
Edouard@693
  2339
    
Edouard@693
  2340
    sqlite3_reset(session->set_revoked);
Edouard@693
  2341
    sqlite3_bind_text(session->set_revoked, 1, revoked_fpr, -1, SQLITE_STATIC);
vb@951
  2342
    sqlite3_bind_text(session->set_revoked, 2, replacement_fpr, -1,
vb@951
  2343
            SQLITE_STATIC);
Edouard@693
  2344
    sqlite3_bind_int64(session->set_revoked, 3, revocation_date);
Edouard@693
  2345
Edouard@693
  2346
    int result;
Edouard@693
  2347
    
Edouard@693
  2348
    result = sqlite3_step(session->set_revoked);
Edouard@693
  2349
    switch (result) {
Edouard@693
  2350
        case SQLITE_DONE:
Edouard@693
  2351
            status = PEP_STATUS_OK;
Edouard@693
  2352
            break;
Edouard@693
  2353
            
Edouard@693
  2354
        default:
Edouard@693
  2355
            status = PEP_UNKNOWN_ERROR;
Edouard@693
  2356
    }
Edouard@693
  2357
    
Edouard@693
  2358
    sqlite3_reset(session->set_revoked);
Edouard@693
  2359
    return status;
Edouard@693
  2360
}
Edouard@693
  2361
Edouard@693
  2362
DYNAMIC_API PEP_STATUS get_revoked(
Edouard@693
  2363
        PEP_SESSION session,
Edouard@693
  2364
        const char *fpr,
Edouard@693
  2365
        char **revoked_fpr,
Edouard@693
  2366
        uint64_t *revocation_date
Edouard@693
  2367
    )
Edouard@693
  2368
{
Edouard@693
  2369
    PEP_STATUS status = PEP_STATUS_OK;
Edouard@693
  2370
Edouard@693
  2371
    assert(session &&
Edouard@693
  2372
           revoked_fpr &&
Edouard@693
  2373
           fpr && fpr[0]
Edouard@693
  2374
          );
Edouard@693
  2375
    
Edouard@693
  2376
    if (!(session &&
Edouard@693
  2377
           revoked_fpr &&
Edouard@693
  2378
           fpr && fpr[0]
Edouard@693
  2379
          ))
Edouard@693
  2380
        return PEP_ILLEGAL_VALUE;
Edouard@693
  2381
Edouard@693
  2382
    *revoked_fpr = NULL;
Edouard@693
  2383
    *revocation_date = 0;
Edouard@693
  2384
Edouard@693
  2385
    sqlite3_reset(session->get_revoked);
Edouard@693
  2386
    sqlite3_bind_text(session->get_revoked, 1, fpr, -1, SQLITE_STATIC);
Edouard@693
  2387
Edouard@693
  2388
    int result;
Edouard@693
  2389
    
Edouard@693
  2390
    result = sqlite3_step(session->get_revoked);
Edouard@693
  2391
    switch (result) {
Edouard@693
  2392
        case SQLITE_ROW: {
vb@951
  2393
            *revoked_fpr = strdup((const char *)
vb@951
  2394
                    sqlite3_column_text(session->get_revoked, 0));
Edouard@693
  2395
            if(*revoked_fpr)
vb@951
  2396
                *revocation_date = sqlite3_column_int64(session->get_revoked,
vb@951
  2397
                        1);
Edouard@693
  2398
            else
Edouard@693
  2399
                status = PEP_OUT_OF_MEMORY;
Edouard@693
  2400
Edouard@693
  2401
            break;
Edouard@693
  2402
        }
Edouard@693
  2403
        default:
Edouard@693
  2404
            status = PEP_CANNOT_FIND_IDENTITY;
Edouard@693
  2405
    }
Edouard@693
  2406
Edouard@693
  2407
    sqlite3_reset(session->get_revoked);
Edouard@693
  2408
Edouard@693
  2409
    return status;
Edouard@693
  2410
}
Edouard@693
  2411
vb@958
  2412
PEP_STATUS key_created(
vb@958
  2413
        PEP_SESSION session,
vb@958
  2414
        const char *fpr,
vb@958
  2415
        time_t *created
vb@958
  2416
    )
vb@958
  2417
{
vb@958
  2418
    assert(session && fpr && created);
vb@958
  2419
    if (!(session && fpr && created))
vb@958
  2420
        return PEP_ILLEGAL_VALUE;
vb@958
  2421
vb@958
  2422
    return session->cryptotech[PEP_crypt_OpenPGP].key_created(session, fpr,
vb@958
  2423
            created);
vb@958
  2424
}
vb@958
  2425
krista@1357
  2426
PEP_STATUS find_private_keys(PEP_SESSION session, const char* pattern,
krista@1357
  2427
                             stringlist_t **keylist) {
edouard@1760
  2428
    assert(session && keylist);
edouard@1760
  2429
    if (!(session && keylist))
krista@1357
  2430
        return PEP_ILLEGAL_VALUE;
krista@1357
  2431
    
krista@1357
  2432
    return session->cryptotech[PEP_crypt_OpenPGP].find_private_keys(session, pattern,
krista@1357
  2433
                                                                    keylist);
krista@1357
  2434
}
krista@1357
  2435
krista@1011
  2436
DYNAMIC_API const char* get_engine_version() {
krista@1011
  2437
    return PEP_ENGINE_VERSION;
krista@1011
  2438
}
krista@1011
  2439
krista@1011
  2440
vb@482
  2441
DYNAMIC_API PEP_STATUS reset_peptest_hack(PEP_SESSION session)
vb@482
  2442
{
vb@482
  2443
    assert(session);
vb@482
  2444
vb@482
  2445
    if (!session)
vb@482
  2446
        return PEP_ILLEGAL_VALUE;
vb@482
  2447
fdik@494
  2448
    int int_result = sqlite3_exec(
fdik@494
  2449
        session->db,
fdik@494
  2450
        "delete from identity where address like '%@peptest.ch' ;",
fdik@494
  2451
        NULL,
fdik@494
  2452
        NULL,
fdik@494
  2453
        NULL
fdik@494
  2454
    );
fdik@494
  2455
    assert(int_result == SQLITE_OK);
vb@482
  2456
edouard@1670
  2457
    if (int_result != SQLITE_OK)
edouard@1670
  2458
        return PEP_UNKNOWN_ERROR;
edouard@1670
  2459
fdik@494
  2460
    return PEP_STATUS_OK;
vb@482
  2461
}
roker@1722
  2462
roker@1722
  2463
#ifdef DEBUG_ERRORSTACK
roker@1722
  2464
PEP_STATUS session_add_error(PEP_SESSION session, const char* file, unsigned line, PEP_STATUS status)
roker@1722
  2465
{
roker@1722
  2466
    char logline[48];
roker@1722
  2467
    if(status>0)
roker@1722
  2468
    {
roker@1734
  2469
        snprintf(logline,47, "%.24s:%u status=%u (0x%x)", file, line, status, status);
roker@1722
  2470
    }else{
roker@1734
  2471
        snprintf(logline,47, "%.24s:%u status=%i.", file, line, status);
roker@1722
  2472
    }
roker@1722
  2473
    stringlist_add(session->errorstack, logline); // logline is copied! :-)
roker@1722
  2474
    return status;
roker@1722
  2475
}
roker@1722
  2476
roker@1722
  2477
DYNAMIC_API const stringlist_t* get_errorstack(PEP_SESSION session)
roker@1722
  2478
{
roker@1722
  2479
    return session->errorstack;
roker@1722
  2480
}
roker@1722
  2481
roker@1777
  2482
DYNAMIC_API void clear_errorstack(PEP_SESSION session)
roker@1777
  2483
{
roker@1801
  2484
    const int old_len = stringlist_length(session->errorstack);
roker@1801
  2485
    char buf[48];
roker@1777
  2486
    free_stringlist(session->errorstack);
roker@1801
  2487
    snprintf(buf, 47, "(%i elements cleared)", old_len);
roker@1801
  2488
    session->errorstack = new_stringlist(buf);
roker@1777
  2489
}
roker@1777
  2490
roker@1722
  2491
#else
roker@1722
  2492
roker@1722
  2493
static stringlist_t* dummy_errorstack = NULL;
roker@1722
  2494
roker@1722
  2495
DYNAMIC_API const stringlist_t* get_errorstack(PEP_SESSION session)
roker@1722
  2496
{
roker@1777
  2497
    if(dummy_errorstack == NULL)
roker@1777
  2498
    {
roker@1777
  2499
        dummy_errorstack = new_stringlist("( Please recompile pEpEngine with -DDEBUG_ERRORSTACK )");
roker@1777
  2500
    }
roker@1777
  2501
roker@1722
  2502
    return dummy_errorstack;
roker@1722
  2503
}
roker@1722
  2504
roker@1777
  2505
DYNAMIC_API void clear_errorstack(PEP_SESSION session)
roker@1777
  2506
{
roker@1777
  2507
    // nothing to do here
roker@1777
  2508
}
roker@1777
  2509
roker@1722
  2510
#endif