src/pEpEngine.c
branchENGINE-74
changeset 1429 86c0e9def29c
parent 1398 b1c1c1db2754
parent 1412 51341b8d69d0
child 1449 c4874b0a2501
     1.1 --- a/src/pEpEngine.c	Wed Nov 23 15:38:27 2016 +0100
     1.2 +++ b/src/pEpEngine.c	Wed Nov 23 20:54:28 2016 +0100
     1.3 @@ -32,9 +32,8 @@
     1.4      static const char *sql_get_device_group;
     1.5      static const char *sql_set_pgp_keypair;
     1.6      static const char *sql_set_identity;
     1.7 -    static const char *sql_exists_empty_fpr_entry;
     1.8 -    static const char *sql_update_fprless_identity;
     1.9      static const char *sql_set_identity_flags;
    1.10 +    static const char *sql_unset_identity_flags;
    1.11      static const char *sql_set_trust;
    1.12      static const char *sql_get_trust;
    1.13      static const char *sql_least_trust;
    1.14 @@ -52,7 +51,8 @@
    1.15      // Own keys
    1.16      static const char *sql_own_key_is_listed;
    1.17      static const char *sql_own_identities_retrieve;
    1.18 -    static const char *sql_keys_retrieve_by_flag;
    1.19 +    static const char *sql_own_keys_retrieve;
    1.20 +    static const char *sql_set_own_key;
    1.21  
    1.22      // Sequence
    1.23      static const char *sql_sequence_value1;
    1.24 @@ -223,6 +223,18 @@
    1.25                  "       on delete cascade,\n"
    1.26                  "   revocation_date integer\n"
    1.27                  ");\n"
    1.28 +                "create table if not exists own_keys (\n"
    1.29 +                "   address text,\n"
    1.30 +                "   user_id text,\n"
    1.31 +                "   fpr text not null\n"
    1.32 +                "       references pgp_keypair (fpr)\n"
    1.33 +                "       on delete cascade,\n"
    1.34 +                "   foreign key (address, user_id)\n"
    1.35 +                "       references identity\n"
    1.36 +                "       on delete cascade,\n"
    1.37 +                "   check (user_id = '" PEP_OWN_USERID "')\n"
    1.38 +                "   primary key (address, fpr)\n"
    1.39 +                ");\n" 
    1.40                  ,
    1.41              NULL,
    1.42              NULL,
    1.43 @@ -288,19 +300,6 @@
    1.44              assert(int_result == SQLITE_OK);
    1.45          }
    1.46  
    1.47 -        if (version <= atoi(_DDL_USER_VERSION)) {
    1.48 -            int_result = sqlite3_exec(
    1.49 -                _session->db,
    1.50 -                "pragma user_version = "_DDL_USER_VERSION";\n"
    1.51 -                "insert or replace into version_info (id, version)"
    1.52 -                    "values (1, '" PEP_ENGINE_VERSION "');",
    1.53 -                NULL,
    1.54 -                NULL,
    1.55 -                NULL
    1.56 -            );
    1.57 -            assert(int_result == SQLITE_OK);
    1.58 -        }
    1.59 -
    1.60          sql_log = "insert into log (title, entity, description, comment)"
    1.61                    "values (?1, ?2, ?3, ?4);";
    1.62  
    1.63 @@ -330,21 +329,36 @@
    1.64          sql_get_device_group = "select device_group from person "
    1.65                                 "where id = '" PEP_OWN_USERID "';";
    1.66  
    1.67 -        sql_set_pgp_keypair = "insert or replace into pgp_keypair (fpr, flags) "
    1.68 -                              "values (upper(replace(?1,' ','')), ?2) ;";
    1.69 +        sql_set_pgp_keypair = "insert or replace into pgp_keypair (fpr) "
    1.70 +                              "values (upper(replace(?1,' ',''))) ;";
    1.71  
    1.72 -        sql_set_identity = "insert or replace into identity (address, main_key_id, "
    1.73 -                           "user_id, flags) values (?1, upper(replace(?2,' ','')),"
    1.74 -                           "?3, ?4 & 255) ;";
    1.75 +        sql_set_identity = "insert or replace into identity ("
    1.76 +                           " address, main_key_id, "
    1.77 +                           " user_id, flags"
    1.78 +                           ") values ("
    1.79 +                           " ?1,"
    1.80 +                           " upper(replace(?2,' ','')),"
    1.81 +                           " ?3,"
    1.82 +                           // " (select"
    1.83 +                           // "   coalesce("
    1.84 +                           // "    (select flags from identity"
    1.85 +                           // "     where address = ?1 and"
    1.86 +                           // "           user_id = ?3),"
    1.87 +                           // "    0)"
    1.88 +                           // " ) | (?4 & 255)"
    1.89 +                           /* set_identity ignores previous flags, and doesn't filter machine flags */
    1.90 +                           " ?4"
    1.91 +                           ");";
    1.92          
    1.93 -        sql_exists_empty_fpr_entry = "select count(*) from identity where address = ?1 and user_id = ?2 "
    1.94 -                                        "and (main_key_id is null or main_key_id = '');";
    1.95 -                
    1.96 -        sql_update_fprless_identity = "update identity set main_key_id = upper(replace(?2,' ','')), "
    1.97 -                                         "flags = ?4 & 255 where address = ?1 and user_id = ?3 and "
    1.98 -                                         "(main_key_id is null or main_key_id = '');";
    1.99 +        sql_set_identity_flags = "update identity set flags = "
   1.100 +                                 "    ((?1 & 255) | (select flags from identity"
   1.101 +                                 "                   where address = ?2 and user_id = ?3)) "
   1.102 +                                 "where address = ?2 and user_id = ?3 ;";
   1.103  
   1.104 -        sql_set_identity_flags = "update identity set flags = ?1 & 255 "
   1.105 +        sql_unset_identity_flags = 
   1.106 +                                 "update identity set flags = "
   1.107 +                                 "    ( ~(?1 & 255) & (select flags from identity"
   1.108 +                                 "                   where address = ?2 and user_id = ?3)) "
   1.109                                   "where address = ?2 and user_id = ?3 ;";
   1.110  
   1.111          sql_set_trust = "insert or replace into trust (user_id, pgp_keypair_fpr, comm_type) "
   1.112 @@ -396,11 +410,16 @@
   1.113                              "   join pgp_keypair on fpr = identity.main_key_id"
   1.114                              "   join trust on id = trust.user_id"
   1.115                              "       and pgp_keypair_fpr = identity.main_key_id"
   1.116 -                            "   where identity.user_id = '" PEP_OWN_USERID "';";
   1.117 +                            "   where identity.user_id = '" PEP_OWN_USERID "'"
   1.118 +                            "       and (identity.flags & ?1) = 0;";
   1.119          
   1.120 -        sql_keys_retrieve_by_flag =  
   1.121 -                            "select fpr from pgp_keypair"
   1.122 -                            "  where (flags & ?1) = ?1;";
   1.123 +        sql_own_keys_retrieve =  
   1.124 +                            "select fpr from own_keys"
   1.125 +                            "   natural join identity"
   1.126 +                            "   where (identity.flags & ?1) = 0;";
   1.127 +
   1.128 +        sql_set_own_key = "insert or replace into own_keys (address, user_id, fpr)"
   1.129 +                          " values (?1, '" PEP_OWN_USERID "', upper(replace(?2,' ','')));";
   1.130  
   1.131          sql_sequence_value1 = "insert or replace into sequences (name, value, own) "
   1.132                                "values (?1, "
   1.133 @@ -452,21 +471,16 @@
   1.134              (int)strlen(sql_set_identity), &_session->set_identity, NULL);
   1.135      assert(int_result == SQLITE_OK);
   1.136  
   1.137 -    int_result = sqlite3_prepare_v2(_session->db, sql_exists_empty_fpr_entry,
   1.138 -                                    (int)strlen(sql_exists_empty_fpr_entry), &_session->exists_empty_fpr_entry,
   1.139 -                                    NULL);
   1.140 -    assert(int_result == SQLITE_OK);
   1.141 -    
   1.142 -    int_result = sqlite3_prepare_v2(_session->db, sql_update_fprless_identity,
   1.143 -                                    (int)strlen(sql_update_fprless_identity), &_session->update_fprless_identity,
   1.144 -                                    NULL);
   1.145 -    assert(int_result == SQLITE_OK);
   1.146 -    
   1.147      int_result = sqlite3_prepare_v2(_session->db, sql_set_identity_flags,
   1.148              (int)strlen(sql_set_identity_flags), &_session->set_identity_flags,
   1.149              NULL);
   1.150      assert(int_result == SQLITE_OK);
   1.151  
   1.152 +    int_result = sqlite3_prepare_v2(_session->db, sql_unset_identity_flags,
   1.153 +            (int)strlen(sql_unset_identity_flags), &_session->unset_identity_flags,
   1.154 +            NULL);
   1.155 +    assert(int_result == SQLITE_OK);
   1.156 +
   1.157      int_result = sqlite3_prepare_v2(_session->db, sql_set_trust,
   1.158              (int)strlen(sql_set_trust), &_session->set_trust, NULL);
   1.159      assert(int_result == SQLITE_OK);
   1.160 @@ -529,9 +543,14 @@
   1.161              &_session->own_identities_retrieve, NULL);
   1.162      assert(int_result == SQLITE_OK);
   1.163   
   1.164 -    int_result = sqlite3_prepare_v2(_session->db, sql_keys_retrieve_by_flag,
   1.165 -            (int)strlen(sql_keys_retrieve_by_flag),
   1.166 -            &_session->keys_retrieve_by_flag, NULL);
   1.167 +    int_result = sqlite3_prepare_v2(_session->db, sql_own_keys_retrieve,
   1.168 +            (int)strlen(sql_own_keys_retrieve),
   1.169 +            &_session->own_keys_retrieve, NULL);
   1.170 +    assert(int_result == SQLITE_OK);
   1.171 + 
   1.172 +    int_result = sqlite3_prepare_v2(_session->db, sql_set_own_key,
   1.173 +            (int)strlen(sql_set_own_key),
   1.174 +            &_session->set_own_key, NULL);
   1.175      assert(int_result == SQLITE_OK);
   1.176   
   1.177      // Sequence
   1.178 @@ -634,6 +653,8 @@
   1.179                  sqlite3_finalize(session->set_identity);
   1.180              if (session->set_identity_flags)
   1.181                  sqlite3_finalize(session->set_identity_flags);
   1.182 +            if (session->unset_identity_flags)
   1.183 +                sqlite3_finalize(session->unset_identity_flags);
   1.184              if (session->set_trust)
   1.185                  sqlite3_finalize(session->set_trust);
   1.186              if (session->get_trust)
   1.187 @@ -660,8 +681,10 @@
   1.188                  sqlite3_finalize(session->own_key_is_listed);
   1.189              if (session->own_identities_retrieve)
   1.190                  sqlite3_finalize(session->own_identities_retrieve);
   1.191 -            if (session->keys_retrieve_by_flag)
   1.192 -                sqlite3_finalize(session->keys_retrieve_by_flag);
   1.193 +            if (session->own_keys_retrieve)
   1.194 +                sqlite3_finalize(session->own_keys_retrieve);
   1.195 +            if (session->set_own_key)
   1.196 +                sqlite3_finalize(session->set_own_key);
   1.197              if (session->sequence_value1)
   1.198                  sqlite3_finalize(session->sequence_value1);
   1.199              if (session->sequence_value2)
   1.200 @@ -1025,47 +1048,6 @@
   1.201      return status;
   1.202  }
   1.203  
   1.204 -
   1.205 -static PEP_STATUS exists_empty_fpr_entry (
   1.206 -    PEP_SESSION session,
   1.207 -    const char* address,
   1.208 -    const char* user_id,
   1.209 -    bool *exists_empty_fpr
   1.210 -)
   1.211 -{
   1.212 -    PEP_STATUS status = PEP_STATUS_OK;
   1.213 -    int count;
   1.214 -    
   1.215 -    assert(session && address && user_id && exists_empty_fpr);
   1.216 -    
   1.217 -    if (!(session && address && user_id && exists_empty_fpr))
   1.218 -        return PEP_ILLEGAL_VALUE;
   1.219 -    
   1.220 -    *exists_empty_fpr = false;
   1.221 -    
   1.222 -    sqlite3_reset(session->exists_empty_fpr_entry);
   1.223 -    sqlite3_bind_text(session->exists_empty_fpr_entry, 1, address, -1, SQLITE_STATIC);
   1.224 -    sqlite3_bind_text(session->exists_empty_fpr_entry, 2, user_id, -1, SQLITE_STATIC);
   1.225 -    
   1.226 -    int result;
   1.227 -    
   1.228 -    result = sqlite3_step(session->exists_empty_fpr_entry);
   1.229 -    switch (result) {
   1.230 -        case SQLITE_ROW:
   1.231 -            count = sqlite3_column_int(session->exists_empty_fpr_entry, 0);
   1.232 -            *exists_empty_fpr = count > 0;
   1.233 -            status = PEP_STATUS_OK;
   1.234 -            break;
   1.235 -            
   1.236 -        default:
   1.237 -            status = PEP_UNKNOWN_ERROR;
   1.238 -    }
   1.239 -    
   1.240 -    sqlite3_reset(session->exists_empty_fpr_entry);
   1.241 -    return status;
   1.242 -}
   1.243 -
   1.244 -
   1.245  DYNAMIC_API PEP_STATUS set_identity(
   1.246          PEP_SESSION session, const pEp_identity *identity
   1.247      )
   1.248 @@ -1083,7 +1065,6 @@
   1.249          return PEP_ILLEGAL_VALUE;
   1.250  
   1.251      bool listed;
   1.252 -    bool exists_empty_fpr;
   1.253      
   1.254      if (identity->fpr && identity->fpr[0] != '\0') {
   1.255          
   1.256 @@ -1096,12 +1077,6 @@
   1.257          if (listed)
   1.258              return PEP_KEY_BLACKLISTED;
   1.259          
   1.260 -        // empty fpr already in DB
   1.261 -        status = exists_empty_fpr_entry(session, identity->address,
   1.262 -                                           identity->user_id, &exists_empty_fpr);
   1.263 -        if (status != PEP_STATUS_OK)
   1.264 -            return status;
   1.265 -        
   1.266      }
   1.267  
   1.268      sqlite3_exec(session->db, "BEGIN ;", NULL, NULL, NULL);
   1.269 @@ -1134,9 +1109,6 @@
   1.270      sqlite3_reset(session->set_pgp_keypair);
   1.271      sqlite3_bind_text(session->set_pgp_keypair, 1, identity->fpr, -1,
   1.272              SQLITE_STATIC);
   1.273 -    sqlite3_bind_int(session->set_pgp_keypair, 2, 
   1.274 -                     strcmp(identity->user_id, PEP_OWN_USERID) == 0 ?
   1.275 -                        PEP_kpf_own_key : 0);
   1.276      result = sqlite3_step(session->set_pgp_keypair);
   1.277      sqlite3_reset(session->set_pgp_keypair);
   1.278      if (result != SQLITE_DONE) {
   1.279 @@ -1144,24 +1116,37 @@
   1.280          return PEP_CANNOT_SET_PGP_KEYPAIR;
   1.281      }
   1.282  
   1.283 -    sqlite3_stmt *update_or_set_identity = 
   1.284 -        (exists_empty_fpr ? session->update_fprless_identity : session->set_identity);
   1.285 -    
   1.286 -    sqlite3_reset(update_or_set_identity);
   1.287 -    sqlite3_bind_text(update_or_set_identity, 1, identity->address, -1,
   1.288 +
   1.289 +    sqlite3_reset(session->set_identity);
   1.290 +    sqlite3_bind_text(session->set_identity, 1, identity->address, -1,
   1.291              SQLITE_STATIC);
   1.292 -    sqlite3_bind_text(update_or_set_identity, 2, identity->fpr, -1,
   1.293 +    sqlite3_bind_text(session->set_identity, 2, identity->fpr, -1,
   1.294              SQLITE_STATIC);
   1.295 -    sqlite3_bind_text(update_or_set_identity, 3, identity->user_id, -1,
   1.296 +    sqlite3_bind_text(session->set_identity, 3, identity->user_id, -1,
   1.297              SQLITE_STATIC);
   1.298 -    sqlite3_bind_int(update_or_set_identity, 4, identity->flags);
   1.299 -    result = sqlite3_step(update_or_set_identity);
   1.300 -    sqlite3_reset(update_or_set_identity);
   1.301 +    sqlite3_bind_int(session->set_identity, 4, identity->flags);
   1.302 +    result = sqlite3_step(session->set_identity);
   1.303 +    sqlite3_reset(session->set_identity);
   1.304      if (result != SQLITE_DONE) {
   1.305          sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
   1.306          return PEP_CANNOT_SET_IDENTITY;
   1.307      }
   1.308  
   1.309 +    if(strcmp(identity->user_id, PEP_OWN_USERID) == 0 &&
   1.310 +       identity->fpr && identity->fpr[0] != '\0') {
   1.311 +        sqlite3_reset(session->set_own_key);
   1.312 +        sqlite3_bind_text(session->set_own_key, 1, identity->address, -1,
   1.313 +            SQLITE_STATIC);
   1.314 +        sqlite3_bind_text(session->set_own_key, 2, identity->fpr, -1,
   1.315 +            SQLITE_STATIC);
   1.316 +        result = sqlite3_step(session->set_own_key);
   1.317 +        sqlite3_reset(session->set_own_key);
   1.318 +        if (result != SQLITE_DONE) {
   1.319 +            sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
   1.320 +            return PEP_CANNOT_SET_PGP_KEYPAIR;
   1.321 +        }
   1.322 +    }
   1.323 +
   1.324      sqlite3_reset(session->set_trust);
   1.325      sqlite3_bind_text(session->set_trust, 1, identity->user_id, -1,
   1.326              SQLITE_STATIC);
   1.327 @@ -1264,7 +1249,38 @@
   1.328      if (result != SQLITE_DONE)
   1.329          return PEP_CANNOT_SET_IDENTITY;
   1.330  
   1.331 -    identity->flags = flags;
   1.332 +    identity->flags |= flags;
   1.333 +    return PEP_STATUS_OK;
   1.334 +}
   1.335 +
   1.336 +DYNAMIC_API PEP_STATUS unset_identity_flags(
   1.337 +        PEP_SESSION session,
   1.338 +        pEp_identity *identity,
   1.339 +        unsigned int flags
   1.340 +    )
   1.341 +{
   1.342 +    int result;
   1.343 +
   1.344 +    assert(session);
   1.345 +    assert(identity);
   1.346 +    assert(identity->address);
   1.347 +    assert(identity->user_id);
   1.348 +
   1.349 +    if (!(session && identity && identity->address && identity->user_id))
   1.350 +        return PEP_ILLEGAL_VALUE;
   1.351 +
   1.352 +    sqlite3_reset(session->unset_identity_flags);
   1.353 +    sqlite3_bind_int(session->unset_identity_flags, 1, flags);
   1.354 +    sqlite3_bind_text(session->unset_identity_flags, 2, identity->address, -1,
   1.355 +            SQLITE_STATIC);
   1.356 +    sqlite3_bind_text(session->unset_identity_flags, 3, identity->user_id, -1,
   1.357 +            SQLITE_STATIC);
   1.358 +    result = sqlite3_step(session->unset_identity_flags);
   1.359 +    sqlite3_reset(session->unset_identity_flags);
   1.360 +    if (result != SQLITE_DONE)
   1.361 +        return PEP_CANNOT_SET_IDENTITY;
   1.362 +
   1.363 +    identity->flags &= ~flags;
   1.364      return PEP_STATUS_OK;
   1.365  }
   1.366