ENGINE-352: we now update the right comm_type in the right place. ENGINE-352
authorKrista Bennett <krista@pep-project.org>
Fri, 02 Feb 2018 17:15:33 +0100
branchENGINE-352
changeset 2469419243d81d6f
parent 2468 3a10b4f8ba41
child 2470 8ee0981369bb
ENGINE-352: we now update the right comm_type in the right place.
src/message_api.c
     1.1 --- a/src/message_api.c	Fri Feb 02 11:03:20 2018 +0100
     1.2 +++ b/src/message_api.c	Fri Feb 02 17:15:33 2018 +0100
     1.3 @@ -1823,31 +1823,31 @@
     1.4      return ADD_TO_LOG(status);
     1.5  }
     1.6  
     1.7 -static PEP_STATUS _update_identity_for_incoming_message(
     1.8 -        PEP_SESSION session,
     1.9 -        const message *src
    1.10 -    )
    1.11 -{
    1.12 -    PEP_STATUS status;
    1.13 -
    1.14 -    if (src->from && src->from->address) {
    1.15 -        if (!is_me(session, src->from))
    1.16 -            status = update_identity(session, src->from);
    1.17 -        else
    1.18 -            status = myself(session, src->from);
    1.19 -        if (status == PEP_STATUS_OK
    1.20 -                && is_a_pEpmessage(src)
    1.21 -                && src->from->comm_type >= PEP_ct_OpenPGP_unconfirmed
    1.22 -                && src->from->comm_type != PEP_ct_pEp_unconfirmed
    1.23 -                && src->from->comm_type != PEP_ct_pEp)
    1.24 -        {
    1.25 -            src->from->comm_type |= PEP_ct_pEp_unconfirmed;
    1.26 -            status = set_identity(session, src->from);
    1.27 -        }
    1.28 -        return status;
    1.29 -    }
    1.30 -    return PEP_ILLEGAL_VALUE;
    1.31 -}
    1.32 +// static PEP_STATUS _update_identity_for_incoming_message(
    1.33 +//         PEP_SESSION session,
    1.34 +//         const message *src
    1.35 +//     )
    1.36 +// {
    1.37 +//     PEP_STATUS status;
    1.38 +// 
    1.39 +//     if (src->from && src->from->address) {
    1.40 +//         if (!is_me(session, src->from))
    1.41 +//             status = update_identity(session, src->from);
    1.42 +//         else
    1.43 +//             status = myself(session, src->from);
    1.44 +//         if (status == PEP_STATUS_OK
    1.45 +//                 && is_a_pEpmessage(src)
    1.46 +//                 && src->from->comm_type >= PEP_ct_OpenPGP_unconfirmed
    1.47 +//                 && src->from->comm_type != PEP_ct_pEp_unconfirmed
    1.48 +//                 && src->from->comm_type != PEP_ct_pEp)
    1.49 +//         {
    1.50 +//             src->from->comm_type |= PEP_ct_pEp_unconfirmed;
    1.51 +//             status = set_identity(session, src->from);
    1.52 +//         }
    1.53 +//         return status;
    1.54 +//     }
    1.55 +//     return PEP_ILLEGAL_VALUE;
    1.56 +// }
    1.57  
    1.58  
    1.59  static PEP_STATUS _get_detached_signature(message* msg, 
    1.60 @@ -2037,7 +2037,7 @@
    1.61          }
    1.62          else {
    1.63              pEp_identity *_sender = new_identity(sender->address, fpr,
    1.64 -                                               sender->user_id, sender->username);
    1.65 +                                                 sender->user_id, sender->username);
    1.66              if (_sender == NULL)
    1.67                  return PEP_OUT_OF_MEMORY;
    1.68  
    1.69 @@ -2426,6 +2426,58 @@
    1.70      return status;
    1.71  }
    1.72  
    1.73 +static PEP_STATUS update_sender_to_pep_trust(
    1.74 +        PEP_SESSION session, 
    1.75 +        pEp_identity* sender, 
    1.76 +        stringlist_t* keylist) 
    1.77 +{
    1.78 +    assert(session);
    1.79 +    assert(sender);
    1.80 +    assert(keylist && !EMPTYSTR(keylist->value));
    1.81 +    
    1.82 +    if (!session || !sender || !keylist || EMPTYSTR(keylist->value))
    1.83 +        return PEP_ILLEGAL_VALUE;
    1.84 +        
    1.85 +    free(sender->fpr);
    1.86 +    sender->fpr = NULL;
    1.87 +    
    1.88 +    PEP_STATUS status = 
    1.89 +            is_me(session, sender) ? myself(session, sender) : update_identity(session, sender);
    1.90 +    
    1.91 +    if (EMPTYSTR(sender->fpr) || strcmp(sender->fpr, keylist->value) != 0) {
    1.92 +        free(sender->fpr);
    1.93 +        sender->fpr = strdup(keylist->value);
    1.94 +        if (!sender->fpr)
    1.95 +            return PEP_OUT_OF_MEMORY;
    1.96 +        status = get_trust(session, sender);
    1.97 +        
    1.98 +        if (status == PEP_CANNOT_FIND_IDENTITY || sender->comm_type == PEP_ct_unknown) {
    1.99 +            PEP_comm_type ct = PEP_ct_unknown;
   1.100 +            status = get_key_rating(session, sender->fpr, &ct);
   1.101 +            if (status != PEP_STATUS_OK)
   1.102 +                return status;
   1.103 +                
   1.104 +            sender->comm_type = ct;    
   1.105 +        }
   1.106 +    }
   1.107 +    
   1.108 +    // Could be done elegantly, but we do this explicitly here for readability.
   1.109 +    // This file's code is difficult enough to parse. But change at will.
   1.110 +    switch (sender->comm_type) {
   1.111 +        case PEP_ct_OpenPGP_unconfirmed:
   1.112 +            status = set_trust(session, sender->user_id, sender->fpr, PEP_ct_pEp_unconfirmed);
   1.113 +            break;
   1.114 +        case PEP_ct_OpenPGP:
   1.115 +            status = set_trust(session, sender->user_id, sender->fpr, PEP_ct_pEp);
   1.116 +            break;
   1.117 +        default:
   1.118 +            break;
   1.119 +    }
   1.120 +    
   1.121 +    return status;
   1.122 +}
   1.123 +
   1.124 +
   1.125  DYNAMIC_API PEP_STATUS _decrypt_message(
   1.126          PEP_SESSION session,
   1.127          message *src,
   1.128 @@ -2456,36 +2508,58 @@
   1.129      char *ptext = NULL;
   1.130      size_t psize;
   1.131      stringlist_t *_keylist = NULL;
   1.132 +    char* signer_fpr = NULL;
   1.133 +    bool is_pep_msg = is_a_pEpmessage(src);
   1.134  
   1.135      *dst = NULL;
   1.136      *keylist = NULL;
   1.137      *rating = PEP_rating_undefined;
   1.138  
   1.139      *flags = 0;
   1.140 +    
   1.141      /*** End init ***/
   1.142  
   1.143 +    // Ok, before we do anything, if it's a pEp message, regardless of whether it's
   1.144 +    // encrypted or not, we set the sender as a pEp user. This has NOTHING to do
   1.145 +    // with the key.
   1.146 +    if (src->from && !(is_me(session, src->from))) {
   1.147 +        if (is_pep_msg) {
   1.148 +            pEp_identity* tmp_from = src->from;
   1.149 +            
   1.150 +            // Ensure there's a user id
   1.151 +            if (EMPTYSTR(tmp_from->user_id) && tmp_from->address) {
   1.152 +                status = update_identity(session, tmp_from);
   1.153 +                if (status == PEP_CANNOT_FIND_IDENTITY) {
   1.154 +                    tmp_from->user_id = calloc(1, strlen(tmp_from->address) + 6);
   1.155 +                    if (!tmp_from->user_id)
   1.156 +                        return PEP_OUT_OF_MEMORY;
   1.157 +                    snprintf(tmp_from->user_id, strlen(tmp_from->address) + 6,
   1.158 +                             "TOFU_%s", tmp_from->address);        
   1.159 +                    status = PEP_STATUS_OK;
   1.160 +                }
   1.161 +            }
   1.162 +            if (status == PEP_STATUS_OK) {
   1.163 +                // Now set user as PEP (may also create an identity if none existed yet)
   1.164 +                status = set_as_pep_user(session, tmp_from);
   1.165 +            }
   1.166 +        }
   1.167 +    }
   1.168 +    // We really need key used in signing to do anything further on the pEp comm_type.
   1.169 +    // So we can't adjust the rating of the sender just yet.
   1.170 +
   1.171      /*** Begin Import any attached public keys and update identities accordingly ***/
   1.172 -
   1.173      // Private key in unencrypted mail are ignored -> NULL
   1.174      bool imported_keys = import_attached_keys(session, src, NULL);
   1.175  
   1.176 -    // Update src->from in case we just imported a key
   1.177 -    // we would need to check signature
   1.178 -    status = _update_identity_for_incoming_message(session, src);
   1.179 -    
   1.180 -    if (status == PEP_ILLEGAL_VALUE && src->from && is_me(session, src->from)) {
   1.181 -        // the above function should fail if it's us.
   1.182 -        // We don't need to update, as any revocations or expirations
   1.183 -        // of our own key imported above, which are all that we 
   1.184 -        // would care about for anything imported,
   1.185 -        // SHOULD get caught when they matter later.
   1.186 -        // (Private keys imported above are not stored in the trust DB)
   1.187 -        status = PEP_STATUS_OK;
   1.188 -    }
   1.189 +    // FIXME: is this really necessary here?
   1.190 +    if (!is_me(session, src->from))
   1.191 +        status = update_identity(session, src->from);
   1.192 +    else
   1.193 +        status = myself(session, src->from);
   1.194          
   1.195      if (status != PEP_STATUS_OK)
   1.196          return ADD_TO_LOG(status);
   1.197 -
   1.198 +    
   1.199      /*** End Import any attached public keys and update identities accordingly ***/
   1.200      
   1.201      /*** Begin get detached signatures that are attached to the encrypted message ***/
   1.202 @@ -2519,7 +2593,7 @@
   1.203      status = get_crypto_text(src, &ctext, &csize);
   1.204      if (status != PEP_STATUS_OK)
   1.205          return status;
   1.206 -    
   1.207 +        
   1.208      /** Ok, we should be ready to decrypt. Try decrypt and verify first! **/
   1.209      status = cryptotech[crypto].decrypt_and_verify(session, ctext,
   1.210                                                     csize, dsig_text, dsig_size,
   1.211 @@ -2677,12 +2751,17 @@
   1.212          }
   1.213          
   1.214          *rating = decrypt_rating(decrypt_status);
   1.215 +        
   1.216 +        // Ok, so if it was signed and it's all verified, we can update
   1.217 +        // eligible signer comm_types to PEP_ct_pEp_*
   1.218 +        if (decrypt_status == PEP_DECRYPTED_AND_VERIFIED && is_pep_msg)
   1.219 +            status = update_sender_to_pep_trust(session, src->from, _keylist);
   1.220  
   1.221          /* Ok, now we have a keylist used for decryption/verification.
   1.222             now we need to update the message rating with the 
   1.223             sender and recipients in mind */
   1.224          status = amend_rating_according_to_sender_and_recipients(session,
   1.225 -                rating, src->from, _keylist);
   1.226 +                 rating, src->from, _keylist);
   1.227  
   1.228          if (status != PEP_STATUS_OK)
   1.229              GOTO(pep_error);
   1.230 @@ -2741,6 +2820,7 @@
   1.231  
   1.232  pep_error:
   1.233      free(ptext);
   1.234 +    free(signer_fpr);
   1.235      free_message(msg);
   1.236      free_stringlist(_keylist);
   1.237