ENGINE-289: intermittent commit - almost compiling cleanly (yes, it's that far away from tested. It's complicated. ENGINE-289
authorKrista Bennett <krista@pep-project.org>
Mon, 18 Dec 2017 23:00:56 +0100
branchENGINE-289
changeset 23266d2a523aad35
parent 2325 781d887c83f4
child 2327 cc04433060ff
ENGINE-289: intermittent commit - almost compiling cleanly (yes, it's that far away from tested. It's complicated.
src/keymanagement.c
src/pEpEngine.c
src/pEpEngine.h
src/pEp_internal.h
     1.1 --- a/src/keymanagement.c	Mon Dec 18 21:31:22 2017 +0100
     1.2 +++ b/src/keymanagement.c	Mon Dec 18 23:00:56 2017 +0100
     1.3 @@ -32,13 +32,15 @@
     1.4      PEP_STATUS status = find_keys(session, address, &keylist);
     1.5      if (status == PEP_STATUS_OK && keylist) {
     1.6          stringlist_t* curr = keylist;
     1.7 -        if (curr->value) {
     1.8 -            if (strcasecmp(curr->value, fpr)) {
     1.9 -                retval = true;
    1.10 -                break;
    1.11 +        while (curr) {
    1.12 +            if (curr->value) {
    1.13 +                if (strcasecmp(curr->value, fpr)) {
    1.14 +                    retval = true;
    1.15 +                    break;
    1.16 +                }
    1.17              }
    1.18 +            curr = curr->next;
    1.19          }
    1.20 -        curr = curr->next;
    1.21      }
    1.22      
    1.23      free_stringlist(keylist);
    1.24 @@ -99,7 +101,8 @@
    1.25      return PEP_STATUS_OK;
    1.26  }
    1.27  
    1.28 -static PEP_STATUS validate_fpr(PEP_SESSION session, pEp_identity* ident) {
    1.29 +static PEP_STATUS validate_fpr(PEP_SESSION session, 
    1.30 +                               pEp_identity* ident) {
    1.31      
    1.32      if (!session || !ident || !ident->fpr)
    1.33          return PEP_ILLEGAL_VALUE;    
    1.34 @@ -109,9 +112,11 @@
    1.35      PEP_STATUS status = get_trust(session, ident);
    1.36      if (status != PEP_STATUS_OK)
    1.37          return ADD_TO_LOG(status);
    1.38 -        
    1.39 +    
    1.40 +    PEP_comm_type ct = ident->comm_type;
    1.41 +    
    1.42      bool revoked, expired;
    1.43 -    bool blacklisted;
    1.44 +    bool blacklisted = false;
    1.45      
    1.46      status = key_revoked(session, fpr, &revoked);    
    1.47      
    1.48 @@ -129,16 +134,15 @@
    1.49      if (status != PEP_STATUS_OK)
    1.50          return ADD_TO_LOG(status);
    1.51      
    1.52 -    status = blacklist_is_listed(session, 
    1.53 -                                 stored_identity->fpr, 
    1.54 -                                 &blacklisted);
    1.55 -                                 
    1.56 -    if (status != PEP_STATUS_OK)
    1.57 -        return ADD_TO_LOG(status);
    1.58 +    if ((ct | PEP_ct_confirmed) == PEP_ct_OpenPGP) {
    1.59 +        status = blacklist_is_listed(session, 
    1.60 +                                     fpr, 
    1.61 +                                     &blacklisted);
    1.62 +                                     
    1.63 +        if (status != PEP_STATUS_OK)
    1.64 +            return ADD_TO_LOG(status);
    1.65 +    }
    1.66          
    1.67 -    char* retval = fpr;
    1.68 -    
    1.69 -    // FIXME: bits for pEp FIXME: blacklisted?
    1.70      if (ident->me && (ct == PEP_ct_pEp) && !revoked && expired) {
    1.71          // extend key
    1.72          timestamp *ts = new_timestamp(time(NULL) + KEY_EXPIRE_DELTA);
    1.73 @@ -148,7 +152,7 @@
    1.74          if (status == PEP_STATUS_OK) {
    1.75              // if key is valid (second check because pEp key might be extended above)
    1.76              //      Return fpr        
    1.77 -            status = key_expired(session, fpr, &expired);            
    1.78 +            status = key_expired(session, fpr, time(NULL), &expired);            
    1.79              if (status != PEP_STATUS_OK)
    1.80                   return ADD_TO_LOG(status);
    1.81              // communicate key(?)
    1.82 @@ -156,30 +160,29 @@
    1.83      }
    1.84      
    1.85      if (revoked)
    1.86 -        ct = PEP_ct_revoked;
    1.87 +        ct = PEP_ct_key_revoked;
    1.88      else if (expired)
    1.89 -        ct = PEP_ct_expired;        
    1.90 -    else if (blacklisted && 
    1.91 -            ((ct | PEP_ct_confirmed) == PEP_ct_OpenPGP_confirmed)) {
    1.92 -        ident->ct = ct = PEP_ct_key_not_found;
    1.93 +        ct = PEP_ct_key_expired;        
    1.94 +    else if (blacklisted) {
    1.95 +        ident->comm_type = ct = PEP_ct_key_not_found;
    1.96          free(ident->fpr);
    1.97              ident->fpr = strdup("");
    1.98 -        }
    1.99          status = PEP_KEY_UNSUITABLE;
   1.100      }
   1.101      
   1.102      switch (ct) {
   1.103          case PEP_ct_key_expired:
   1.104 -        case PEP_ct_key_revoked
   1.105 +        case PEP_ct_key_revoked:
   1.106          case PEP_ct_key_b0rken:
   1.107              // delete key from being default key for all users/identities
   1.108              status = remove_fpr_as_default(session, fpr);
   1.109 +            status = update_trust_for_fpr(session, 
   1.110 +                                          fpr, 
   1.111 +                                          ct);
   1.112              free(ident->fpr);
   1.113              ident->fpr = strdup("");
   1.114 +            ident->comm_type = PEP_ct_key_not_found;            
   1.115              status = PEP_KEY_UNSUITABLE;
   1.116 -            status = update_trust_for_fpr(session, 
   1.117 -                                          stored_identity->fpr, 
   1.118 -                                          ct);
   1.119          default:
   1.120              break;
   1.121      }            
   1.122 @@ -191,8 +194,8 @@
   1.123  // Also, we presume that if the stored_identity was sent in
   1.124  // without an fpr, there wasn't one in the trust DB for this
   1.125  // identity.
   1.126 -PEP_STATUS get_valid_pubkey(PEP_STATUS session,
   1.127 -                            PEP_STATUS stored_identity,
   1.128 +PEP_STATUS get_valid_pubkey(PEP_SESSION session,
   1.129 +                            pEp_identity* stored_identity,
   1.130                              bool* is_identity_default,
   1.131                              bool* is_user_default,
   1.132                              bool* is_address_default) {
   1.133 @@ -227,14 +230,14 @@
   1.134      const int result = sqlite3_step(session->get_user_default_key);
   1.135      const char* user_fpr = NULL;
   1.136      if (result == SQLITE_ROW) {
   1.137 -        user_fpr = 
   1.138 -            (const char *) sqlite3_column_text(session->get_user_default_key, 0);
   1.139 +        user_fpr =
   1.140 +            (char *) sqlite3_column_text(session->get_user_default_key, 0);
   1.141      }
   1.142      sqlite3_reset(session->get_user_default_key);
   1.143      
   1.144      if (user_fpr) {             
   1.145          // There exists a default key for user, so validate
   1.146 -        stored_identity->fpr = user_fpr;
   1.147 +        stored_identity->fpr = strdup(user_fpr);
   1.148          status = validate_fpr(session, stored_identity);
   1.149          if (status == PEP_STATUS_OK && stored_identity->fpr) {
   1.150              *is_user_default = true;
   1.151 @@ -269,7 +272,9 @@
   1.152      
   1.153      if (!session || !input_id || !stored_ident)
   1.154          return PEP_ILLEGAL_VALUE;
   1.155 -        
   1.156 +    
   1.157 +    PEP_STATUS status;
   1.158 +    
   1.159      bool is_identity_default, is_user_default, is_address_default;
   1.160      status = get_valid_pubkey(session, stored_ident,
   1.161                                  &is_identity_default,
   1.162 @@ -284,10 +289,10 @@
   1.163          if (input_id->fpr &&
   1.164                   strcasecmp(stored_ident->fpr, input_id->fpr) != 0) {
   1.165              free(input_id->fpr);
   1.166 -            strdup(input_id->fpr, stored_ident->fpr);
   1.167              
   1.168 -            // We have to call this because we didn't get it during
   1.169 -            // get identity above
   1.170 +            // Copy in the result from get_valid_pubkey
   1.171 +            input_id->fpr = strdup(stored_ident->fpr);
   1.172 +            
   1.173              status = get_trust(session, stored_ident);
   1.174              input_id->comm_type = stored_ident->comm_type;
   1.175          }
   1.176 @@ -316,7 +321,7 @@
   1.177           // if we got an fpr which is default for either user
   1.178           // or identity AND is valid for this address, set in DB
   1.179           // as default
   1.180 -         status = set_identity(input_id);
   1.181 +         status = set_identity(session, input_id);
   1.182      }
   1.183      else {
   1.184          // Store without default fpr/ct, but return the fpr and ct 
   1.185 @@ -325,7 +330,7 @@
   1.186          PEP_comm_type save_ct = input_id->comm_type;
   1.187          input_id->fpr = NULL;
   1.188          input_id->comm_type = PEP_ct_unknown;
   1.189 -        status = set_identity(input_id);
   1.190 +        status = set_identity(session, input_id);
   1.191          input_id->fpr = save_fpr;
   1.192          input_id->comm_type = save_ct;
   1.193      }
   1.194 @@ -340,8 +345,6 @@
   1.195          PEP_SESSION session, pEp_identity * identity
   1.196      )
   1.197  {
   1.198 -    pEp_identity *stored_identity = NULL;
   1.199 -    pEp_identity *temp_id = NULL;
   1.200      PEP_STATUS status;
   1.201  
   1.202      assert(session);
   1.203 @@ -366,9 +369,6 @@
   1.204      // We have, at least, an address.
   1.205      // Retrieve stored identity information!    
   1.206      pEp_identity* stored_ident = NULL;
   1.207 -    char* identity_default_fpr = NULL;
   1.208 -    char* user_default_fpr = NULL;
   1.209 -    char* passed_in_fpr = identity->fpr;
   1.210  
   1.211      if (identity->user_id) {            
   1.212          // (we're gonna update the trust/fpr anyway, so we user the no-fpr-from-trust-db variant)
   1.213 @@ -402,7 +402,9 @@
   1.214                                  
   1.215                                  // Ok, we have a temp ID. We have to replace this
   1.216                                  // with the real ID.
   1.217 -                                status = replace_userid(this_uid, identity->user_id);
   1.218 +                                status = replace_userid(session, 
   1.219 +                                                        this_uid, 
   1.220 +                                                        identity->user_id);
   1.221                                  if (status != PEP_STATUS_OK) {
   1.222                                      free_identity_list(id_list);
   1.223                                      return status;
   1.224 @@ -443,7 +445,7 @@
   1.225              //  if we only have user_id and address and identity not available
   1.226              //      * return error status (identity not found)
   1.227              if (!identity->username)
   1.228 -                status PEP_CANNOT_FIND_IDENTITY;
   1.229 +                status = PEP_CANNOT_FIND_IDENTITY;
   1.230              
   1.231              // Otherwise, if we had user_id, address, and username:
   1.232              //    * create identity with user_id, address, username
   1.233 @@ -540,9 +542,9 @@
   1.234              //    * If exactly one found
   1.235              //      * elect valid key for identity (see below)
   1.236              //      * Return this identity
   1.237 -            stored_ident = id_curr->ident;
   1.238 +            stored_ident = id_list->ident;
   1.239              
   1.240 -            if (this_id)
   1.241 +            if (stored_ident)
   1.242                  status = prepare_updated_identity(session, identity,
   1.243                                                    stored_ident, false);
   1.244              else
   1.245 @@ -551,7 +553,14 @@
   1.246          else // too little info
   1.247              status = PEP_CANNOT_FIND_IDENTITY; 
   1.248      }
   1.249 -                        
   1.250 +    
   1.251 +    // FIXME: This is legacy. I presume it's a notification for the caller...
   1.252 +    // Revisit once I can talk to Volker
   1.253 +    if (identity->comm_type != PEP_ct_compromized &&
   1.254 +        identity->comm_type < PEP_ct_strong_but_unconfirmed)
   1.255 +    if (session->examine_identity)
   1.256 +        session->examine_identity(identity, session->examine_management);
   1.257 +
   1.258      return ADD_TO_LOG(status);
   1.259  }
   1.260  
     2.1 --- a/src/pEpEngine.c	Mon Dec 18 21:31:22 2017 +0100
     2.2 +++ b/src/pEpEngine.c	Mon Dec 18 23:00:56 2017 +0100
     2.3 @@ -76,7 +76,7 @@
     2.4      "   and identity.user_id = ?2;";
     2.5  
     2.6  static const char *sql_get_identities_by_address =  
     2.7 -    "select main_key_id, username, comm_type, lang,"
     2.8 +    "select user_id, main_key_id, username, comm_type, lang,"
     2.9      "   identity.flags, is_own"
    2.10      "   from identity"
    2.11      "   where (case when (address = ?1) then (1)"
    2.12 @@ -89,6 +89,10 @@
    2.13      "update identity"
    2.14      "   set main_key_id = ?1 "
    2.15      "   where main_key_id = ?2 ;";
    2.16 +    
    2.17 +static const char *sql_remove_fpr_as_default =
    2.18 +    "update person set main_key_id = NULL where main_key_id = ?1 ;"
    2.19 +    "update identity set main_key_id = NULL where main_key_id = ?1 ;";
    2.20  
    2.21  // Set person, but if already exist, only update.
    2.22  // if main_key_id already set, don't touch.
    2.23 @@ -690,6 +694,7 @@
    2.24                  // person->id replacements (for temp ids like "TOFU_")
    2.25                  // so here we go...
    2.26                  int_result = sqlite3_exec(
    2.27 +                    _session->db,
    2.28                      "PRAGMA foreign_keys=off;\n"
    2.29                      "BEGIN TRANSACTION;\n"
    2.30                      "ALTER TABLE identity RENAME TO _identity_old;\n"
    2.31 @@ -790,6 +795,11 @@
    2.32              (int)strlen(sql_replace_identities_fpr), 
    2.33              &_session->replace_identities_fpr, NULL);
    2.34      assert(int_result == SQLITE_OK);
    2.35 +    
    2.36 +    int_result = sqlite3_prepare_v2(_session->db, sql_remove_fpr_as_default,
    2.37 +            (int)strlen(sql_remove_fpr_as_default), 
    2.38 +            &_session->remove_fpr_as_default, NULL);
    2.39 +    assert(int_result == SQLITE_OK);
    2.40  
    2.41      int_result = sqlite3_prepare_v2(_session->db, sql_set_person,
    2.42              (int)strlen(sql_set_person), &_session->set_person, NULL);
    2.43 @@ -1041,6 +1051,8 @@
    2.44                  sqlite3_finalize(session->get_own_userid);
    2.45              if (session->replace_identities_fpr)
    2.46                  sqlite3_finalize(session->replace_identities_fpr);        
    2.47 +            if (session->remove_fpr_as_default)
    2.48 +                sqlite3_finalize(session->remove_fpr_as_default);            
    2.49              if (session->set_person)
    2.50                  sqlite3_finalize(session->set_person);
    2.51              if (session->set_device_group)
    2.52 @@ -1559,38 +1571,39 @@
    2.53      *id_list = NULL;
    2.54      identity_list* ident_list = NULL;
    2.55  
    2.56 -    sqlite3_reset(sql->get_identities_by_address);
    2.57 -    sqlite3_bind_text(sql->get_identities_by_address, 1, address, -1, SQLITE_STATIC);
    2.58 +    sqlite3_reset(session->get_identities_by_address);
    2.59 +    sqlite3_bind_text(session->get_identities_by_address, 1, address, -1, SQLITE_STATIC);
    2.60      int result;
    2.61  
    2.62 -    while ((result = sqlite3_step(sql->get_identities_by_address)) == SQLITE_ROW) {
    2.63 -        
    2.64 +    while ((result = sqlite3_step(session->get_identities_by_address)) == SQLITE_ROW) {
    2.65 +        //"select user_id, main_key_id, username, comm_type, lang,"
    2.66 +        //"   identity.flags, is_own"
    2.67          ident = new_identity(
    2.68                  address,
    2.69 -                (const char *) sqlite3_column_text(sql->get_identities_by_address, 0),
    2.70 -                user_id,
    2.71 -                (const char *) sqlite3_column_text(sql->get_identities_by_address, 1)
    2.72 +                (const char *) sqlite3_column_text(session->get_identities_by_address, 1),
    2.73 +                (const char *) sqlite3_column_text(session->get_identities_by_address, 0),
    2.74 +                (const char *) sqlite3_column_text(session->get_identities_by_address, 2)
    2.75                  );
    2.76 -        assert(_identity);
    2.77 +        assert(ident);
    2.78          if (ident == NULL)
    2.79              return PEP_OUT_OF_MEMORY;
    2.80  
    2.81          ident->comm_type = (PEP_comm_type)
    2.82 -            sqlite3_column_int(sql->get_identities_by_address, 2);
    2.83 +            sqlite3_column_int(session->get_identities_by_address, 3);
    2.84          const char* const _lang = (const char *)
    2.85 -            sqlite3_column_text(sql->get_identities_by_address, 3);
    2.86 +            sqlite3_column_text(session->get_identities_by_address, 4);
    2.87          if (_lang && _lang[0]) {
    2.88              assert(_lang[0] >= 'a' && _lang[0] <= 'z');
    2.89              assert(_lang[1] >= 'a' && _lang[1] <= 'z');
    2.90              assert(_lang[2] == 0);
    2.91 -            _identity->lang[0] = _lang[0];
    2.92 -            _identity->lang[1] = _lang[1];
    2.93 -            _identity->lang[2] = 0;
    2.94 +            ident->lang[0] = _lang[0];
    2.95 +            ident->lang[1] = _lang[1];
    2.96 +            ident->lang[2] = 0;
    2.97          }
    2.98          ident->flags = (unsigned int)
    2.99 -            sqlite3_column_int(sql->get_identities_by_address, 4);
   2.100 +            sqlite3_column_int(session->get_identities_by_address, 5);
   2.101          ident->me = (unsigned int)
   2.102 -            sqlite3_column_int(sql->get_identities_by_address, 5);
   2.103 +            sqlite3_column_int(session->get_identities_by_address, 6);
   2.104      
   2.105          if (ident_list)
   2.106              identity_list_add(ident_list, ident);
   2.107 @@ -1598,7 +1611,7 @@
   2.108              ident_list = new_identity_list(ident);
   2.109      }
   2.110  
   2.111 -    sqlite3_reset(sql->get_identities_by_address);
   2.112 +    sqlite3_reset(session->get_identities_by_address);
   2.113      
   2.114      *id_list = ident_list;
   2.115      
   2.116 @@ -1719,6 +1732,28 @@
   2.117          return PEP_COMMIT_FAILED;
   2.118  }
   2.119  
   2.120 +PEP_STATUS remove_fpr_as_default(PEP_SESSION session, 
   2.121 +                                 const char* fpr) 
   2.122 +{
   2.123 +    assert(fpr);
   2.124 +    
   2.125 +    if (!session || !fpr)
   2.126 +        return PEP_ILLEGAL_VALUE;
   2.127 +            
   2.128 +    sqlite3_reset(session->remove_fpr_as_default);
   2.129 +    sqlite3_bind_text(session->remove_fpr_as_default, 1, fpr, -1,
   2.130 +                      SQLITE_STATIC);
   2.131 +
   2.132 +    int result = sqlite3_step(session->remove_fpr_as_default);
   2.133 +    sqlite3_reset(session->remove_fpr_as_default);
   2.134 +    
   2.135 +    if (result != SQLITE_DONE)
   2.136 +        return PEP_CANNOT_SET_IDENTITY; // misleading - could also be person
   2.137 +
   2.138 +    return PEP_STATUS_OK;
   2.139 +}
   2.140 +
   2.141 +
   2.142  PEP_STATUS replace_identities_fpr(PEP_SESSION session, 
   2.143                                   const char* old_fpr, 
   2.144                                   const char* new_fpr) 
   2.145 @@ -1874,8 +1909,10 @@
   2.146      sqlite3_bind_text(session->set_identity_flags, 2, identity->address, -1,
   2.147              SQLITE_STATIC);
   2.148      sqlite3_bind_text(session->set_identity_flags, 3, identity->user_id, -1,
   2.149 -        result = sqlite3_step(session->set_identity_flags);
   2.150 -            SQLITE_STATIC);
   2.151 +        SQLITE_STATIC);
   2.152 +        
   2.153 +    result = sqlite3_step(session->set_identity_flags);
   2.154 +
   2.155      sqlite3_reset(session->set_identity_flags);
   2.156      if (result != SQLITE_DONE)
   2.157          return PEP_CANNOT_SET_IDENTITY;
   2.158 @@ -1929,12 +1966,12 @@
   2.159      int result;
   2.160  
   2.161      sqlite3_reset(session->replace_userid);
   2.162 -    sqlite3_bind_text(session->replace_userid, 1, new_id, -1,
   2.163 +    sqlite3_bind_text(session->replace_userid, 1, new_uid, -1,
   2.164              SQLITE_STATIC);
   2.165 -    sqlite3_bind_text(session->replace_userid, 2, old_id, -1,
   2.166 +    sqlite3_bind_text(session->replace_userid, 2, old_uid, -1,
   2.167              SQLITE_STATIC);
   2.168 -    result = sqlite3_step(session->replace);
   2.169 -    sqlite3_reset(session->replace);
   2.170 +    result = sqlite3_step(session->replace_userid);
   2.171 +    sqlite3_reset(session->replace_userid);
   2.172      if (result != SQLITE_DONE)
   2.173          return PEP_CANNOT_SET_PERSON; // May need clearer retval
   2.174  
     3.1 --- a/src/pEpEngine.h	Mon Dec 18 21:31:22 2017 +0100
     3.2 +++ b/src/pEpEngine.h	Mon Dec 18 23:00:56 2017 +0100
     3.3 @@ -1153,15 +1153,25 @@
     3.4  // This is used internally when there is a temporary identity to be retrieved
     3.5  // that may not yet have an FPR attached. See get_identity() for functionality,
     3.6  // params and caveats.
     3.7 -PEP_STATUS get_identity_without_fpr(
     3.8 +PEP_STATUS get_identity_without_trust_check(
     3.9          PEP_SESSION session,
    3.10          const char *address,
    3.11          const char *user_id,
    3.12          pEp_identity **identity
    3.13      );
    3.14 -
    3.15 +    
    3.16 +PEP_STATUS get_identities_by_address(
    3.17 +        PEP_SESSION session,
    3.18 +        const char *address,
    3.19 +        identity_list** id_list
    3.20 +    );
    3.21 +        
    3.22  PEP_STATUS replace_userid(PEP_SESSION session, const char* old_uid,
    3.23                                const char* new_uid);
    3.24 +                              
    3.25 +PEP_STATUS remove_fpr_as_default(PEP_SESSION session, 
    3.26 +                                    const char* fpr);
    3.27 +                              
    3.28      
    3.29  #ifdef __cplusplus
    3.30  }
     4.1 --- a/src/pEp_internal.h	Mon Dec 18 21:31:22 2017 +0100
     4.2 +++ b/src/pEp_internal.h	Mon Dec 18 23:00:56 2017 +0100
     4.3 @@ -127,6 +127,7 @@
     4.4      sqlite3_stmt *get_identity_without_trust_check;
     4.5      sqlite3_stmt *get_identities_by_address;
     4.6      sqlite3_stmt *replace_identities_fpr;
     4.7 +    sqlite3_stmt *remove_fpr_as_default;
     4.8      sqlite3_stmt *set_person;
     4.9      sqlite3_stmt *set_device_group;
    4.10      sqlite3_stmt *get_device_group;