ENGINE-581: assign keys to users when imported if possible, at least giving available keys an entry in the trust DB so that get_key_rating_for_user doesn't massively fail. ENGINE-581
authorKrista 'DarthMama' Bennett <krista@pep.foundation>
Tue, 25 Jun 2019 18:44:58 +0200
branchENGINE-581
changeset 3872156454dd1b99
parent 3870 018251280dbf
child 3873 d020bf7cf4f8
child 3874 4a6244c5d36e
ENGINE-581: assign keys to users when imported if possible, at least giving available keys an entry in the trust DB so that get_key_rating_for_user doesn't massively fail.
src/message_api.c
     1.1 --- a/src/message_api.c	Tue Jun 25 14:33:14 2019 +0200
     1.2 +++ b/src/message_api.c	Tue Jun 25 18:44:58 2019 +0200
     1.3 @@ -3126,7 +3126,6 @@
     1.4  }
     1.5  
     1.6  static PEP_STATUS reconcile_sent_and_recv_info(message* src, message* inner_message) {
     1.7 -    PEP_STATUS status = PEP_STATUS_OK;
     1.8      if (!src || !inner_message)
     1.9          return PEP_ILLEGAL_VALUE;
    1.10          
    1.11 @@ -3329,6 +3328,98 @@
    1.12  
    1.13  }
    1.14  
    1.15 +static PEP_STATUS set_key_if_exists_and_no_default(
    1.16 +        PEP_SESSION session,
    1.17 +        pEp_identity* identity
    1.18 +    )
    1.19 +{
    1.20 +    // assert(session);
    1.21 +    // assert(identity);
    1.22 +    // assert(!(EMPTYSTR(identity->address) || EMPTYSTR(identity->user_id)));
    1.23 +    PEP_STATUS status = PEP_STATUS_OK;
    1.24 +    
    1.25 +    if (!session || !identity || EMPTYSTR(identity->address) || EMPTYSTR(identity->user_id))
    1.26 +        return PEP_ILLEGAL_VALUE;
    1.27 +
    1.28 +    if (is_me(session, identity))
    1.29 +        return PEP_STATUS_OK; // we won't set this, but it's not an error
    1.30 +        
    1.31 +    bool has_default = false;
    1.32 +    PEP_comm_type cached_ct = PEP_ct_unknown;
    1.33 +    char* cached_fpr = NULL;
    1.34 +    
    1.35 +    if (EMPTYSTR(identity->fpr)) {
    1.36 +        // OK, we may have imported one. Let's check it out.
    1.37 +        status = update_identity(session, identity);
    1.38 +        
    1.39 +        if (status != PEP_STATUS_OK)
    1.40 +            return status;
    1.41 +            
    1.42 +        if (EMPTYSTR(identity->fpr))
    1.43 +            return PEP_STATUS_OK; // ok, we've got nothing, bye!
    1.44 +        
    1.45 +        cached_ct = identity->comm_type;
    1.46 +    
    1.47 +        // see if we have trust info for this fpr
    1.48 +        status = get_trust(session, identity);
    1.49 +        
    1.50 +        if (status == PEP_CANNOT_FIND_IDENTITY) // nope, use update_ident info
    1.51 +            identity->comm_type = cached_ct;
    1.52 +        else {
    1.53 +            // there's already a trust entry for this fpr in the DB.
    1.54 +            // should be all good
    1.55 +            return PEP_STATUS_OK;
    1.56 +        }            
    1.57 +    }
    1.58 +    else {
    1.59 +        // See if there is a trust entry for the input fpr
    1.60 +        status = get_trust(session, identity);
    1.61 +    
    1.62 +        if (status == PEP_CANNOT_FIND_IDENTITY) {
    1.63 +            // there's no trust for this key/user
    1.64 +            // So: 
    1.65 +            // 1. find out if we have a default key at all 
    1.66 +            cached_fpr = identity->fpr;
    1.67 +            identity->fpr = NULL;
    1.68 +            status = update_identity(session, identity);
    1.69 +
    1.70 +            if (EMPTYSTR(identity->fpr)) {
    1.71 +                // We don't.
    1.72 +                has_default = false;
    1.73 +                identity->fpr = cached_fpr;
    1.74 +                cached_fpr = NULL;
    1.75 +                status = get_key_rating(session, identity->fpr, &(identity->comm_type));
    1.76 +                if (status != PEP_STATUS_OK)
    1.77 +                    goto pEp_free;
    1.78 +            }
    1.79 +            else if (strcasecmp(identity->fpr, cached_fpr) != 0) {
    1.80 +                // We do, but they don't match.
    1.81 +                // make sure identity->fpr has an entry
    1.82 +                cached_ct = identity->comm_type;
    1.83 +                status = get_trust(session, identity);
    1.84 +                if (status == PEP_CANNOT_FIND_IDENTITY)
    1.85 +                    identity->comm_type = cached_ct;    
    1.86 +                else {
    1.87 +                    status = PEP_STATUS_OK;
    1.88 +                    goto pEp_free;
    1.89 +                }                        
    1.90 +            }
    1.91 +        }
    1.92 +        else { 
    1.93 +            status = PEP_STATUS_OK;
    1.94 +            goto pEp_free;
    1.95 +        }    
    1.96 +    }
    1.97 +    
    1.98 +    // At this point, if there was a valid, set trust entry, we've returned.
    1.99 +    // there isn't, so:
   1.100 +    status = set_identity(session, identity);
   1.101 +    
   1.102 +pEp_free:
   1.103 +    free(cached_fpr);
   1.104 +    return status;
   1.105 +}    
   1.106 +
   1.107  static PEP_STATUS _decrypt_message(
   1.108          PEP_SESSION session,
   1.109          message *src,
   1.110 @@ -3423,7 +3514,6 @@
   1.111              
   1.112      import_header_keys(session, src);
   1.113      
   1.114 -    // FIXME: is this really necessary here?
   1.115      if (src->from) {
   1.116          if (!is_me(session, src->from))
   1.117              status = update_identity(session, src->from);
   1.118 @@ -3463,6 +3553,11 @@
   1.119                                      
   1.120          pull_up_attached_main_msg(src);
   1.121          
   1.122 +        //
   1.123 +        // We may have imported a key.
   1.124 +        //
   1.125 +        set_key_if_exists_and_no_default(session, src->from);
   1.126 +        
   1.127          return PEP_UNENCRYPTED;
   1.128      }
   1.129  
   1.130 @@ -3707,7 +3802,8 @@
   1.131              goto pEp_error;
   1.132          
   1.133          /* We decrypted ok, hallelujah. */
   1.134 -        msg->enc_format = PEP_enc_none;    
   1.135 +        msg->enc_format = PEP_enc_none;  
   1.136 +          
   1.137      } 
   1.138      else {
   1.139          // We did not get a plaintext out of the decryption process.
   1.140 @@ -3742,6 +3838,9 @@
   1.141      // 2. Clean up message and prepare for return 
   1.142      if (msg) {
   1.143          
   1.144 +        /* if the sender has no default and we have a key for them, set it. */
   1.145 +        set_key_if_exists_and_no_default(session, msg->from);
   1.146 +        
   1.147          /* add pEp-related status flags to header */
   1.148          decorate_message(msg, *rating, _keylist, false, false);
   1.149