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