Fixed unencrypted longtext stuck in attachments ENGINE-152
authorKrista Grothoff <krista@pep-project.org>
Fri, 09 Dec 2016 18:34:23 +0100
branchENGINE-152
changeset 14849dac603e44a3
parent 1483 65bf8eef6d70
child 1485 7ab80d2354a3
Fixed unencrypted longtext stuck in attachments
src/message_api.c
     1.1 --- a/src/message_api.c	Tue Dec 13 14:54:00 2016 +0100
     1.2 +++ b/src/message_api.c	Fri Dec 09 18:34:23 2016 +0100
     1.3 @@ -1432,6 +1432,68 @@
     1.4      return PEP_STATUS_OK;
     1.5  }
     1.6  
     1.7 +PEP_STATUS combine_keylists(PEP_SESSION session, stringlist_t** verify_in, 
     1.8 +                            stringlist_t** keylist_in_out, 
     1.9 +                            pEp_identity* from) {
    1.10 +    
    1.11 +    if (!verify_in || !(*verify_in)) // this isn't really a problem.
    1.12 +        return PEP_STATUS_OK;
    1.13 +    
    1.14 +    stringlist_t* orig_verify = *verify_in;
    1.15 +    
    1.16 +    stringlist_t* verify_curr;
    1.17 +    stringlist_t* from_keys;
    1.18 +    
    1.19 +    /* FIXME: what to do if head needs to be null */
    1.20 +    PEP_STATUS status = find_keys(session, from->address, &from_keys);
    1.21 +    
    1.22 +    stringlist_t* from_fpr_node = NULL;
    1.23 +    stringlist_t* from_curr;
    1.24 +    
    1.25 +    for (from_curr = from_keys; from_curr; from_curr = from_curr->next) {
    1.26 +        for (verify_curr = orig_verify; verify_curr; verify_curr = verify_curr->next) {
    1.27 +            if (from_curr->value && verify_curr->value &&
    1.28 +                strcasecmp(from_curr->value, verify_curr->value) == 0) {
    1.29 +                from_fpr_node = from_curr;
    1.30 +                break;
    1.31 +            }
    1.32 +        }
    1.33 +    }
    1.34 +    
    1.35 +    if (!from_fpr_node) {
    1.36 +        status = PEP_KEY_NOT_FOUND;
    1.37 +        goto free;
    1.38 +    }
    1.39 +
    1.40 +    verify_curr = orig_verify;
    1.41 +    
    1.42 +    /* put "from" signer at the beginning of the list */
    1.43 +    if (strcasecmp(orig_verify->value, from_fpr_node->value) != 0) {
    1.44 +        orig_verify = stringlist_delete(orig_verify, from_fpr_node->value);
    1.45 +        verify_curr = new_stringlist(from_fpr_node->value);
    1.46 +        verify_curr->next = orig_verify;
    1.47 +    }
    1.48 +
    1.49 +    /* append keylist to signers */
    1.50 +    if (keylist_in_out && *keylist_in_out && (*keylist_in_out)->value) {
    1.51 +        stringlist_t** tail_pp = &verify_curr->next;
    1.52 +        
    1.53 +        while (*tail_pp) {
    1.54 +            tail_pp = &((*tail_pp)->next);
    1.55 +        }
    1.56 +        *tail_pp = *keylist_in_out;
    1.57 +    }
    1.58 +    
    1.59 +    *keylist_in_out = verify_curr;
    1.60 +    
    1.61 +    status = PEP_STATUS_OK;
    1.62 +    
    1.63 +free:
    1.64 +    free_stringlist(from_keys);
    1.65 +    return status;    
    1.66 +}
    1.67 +
    1.68 +
    1.69  DYNAMIC_API PEP_STATUS _decrypt_message(
    1.70          PEP_SESSION session,
    1.71          message *src,
    1.72 @@ -1537,6 +1599,36 @@
    1.73                      return status;
    1.74                  }
    1.75              }
    1.76 +            
    1.77 +            char* slong = src->longmsg;
    1.78 +            char* sform = src->longmsg_formatted;
    1.79 +            bloblist_t* satt = src->attachments;
    1.80 +                                    
    1.81 +            if ((!slong || slong[0] == '\0')
    1.82 +                 && (!sform || sform[0] == '\0')) {
    1.83 +                if (satt) {
    1.84 +                    const char* inner_mime_type = satt->mime_type;
    1.85 +                    if (strcasecmp(inner_mime_type, "text/plain") == 0) {
    1.86 +                        free(slong); /* in case of "" */
    1.87 +                        src->longmsg = strdup(satt->value);
    1.88 +                    
    1.89 +                        bloblist_t* next_node = satt->next;
    1.90 +                        if (next_node) {
    1.91 +                            inner_mime_type = next_node->mime_type;
    1.92 +                            if (strcasecmp(inner_mime_type, "text/html") == 0) {
    1.93 +                                free(sform);
    1.94 +                                src->longmsg_formatted = strdup(next_node->value);
    1.95 +                            }
    1.96 +                        }
    1.97 +                    }
    1.98 +                    else if (strcasecmp(inner_mime_type, "text/html") == 0) {
    1.99 +                        free(sform);
   1.100 +                        src->longmsg_formatted = strdup(satt->value);
   1.101 +                    }                    
   1.102 +                }
   1.103 +            }       
   1.104 +
   1.105 +            
   1.106              return PEP_UNENCRYPTED;
   1.107  
   1.108          case PEP_enc_PGP_MIME:
   1.109 @@ -1576,27 +1668,63 @@
   1.110              case PEP_enc_PGP_MIME:
   1.111                  status = mime_decode_message(ptext, psize, &msg);
   1.112                  if (status != PEP_STATUS_OK)
   1.113 -                    goto pep_error;
   1.114 -                status = _get_detached_signature(msg, &detached_sig);
   1.115 -                if (decrypt_status == PEP_DECRYPTED && detached_sig) {
   1.116 -                    dsig_text = detached_sig->value;
   1.117 -                    dsig_size = detached_sig->size;
   1.118 -                    size_t ssize = 0;
   1.119 -                    char* stext = NULL;
   1.120 -
   1.121 -                    status = _get_signed_text(ptext, psize, &stext, &ssize);
   1.122 -                    stringlist_t *_verify_keylist = NULL;
   1.123 -
   1.124 -                    if (ssize > 0 && stext) {
   1.125 -                        status = cryptotech[crypto].verify_text(session, stext,
   1.126 -                                                                ssize, dsig_text, dsig_size,
   1.127 -                                                                &_verify_keylist);
   1.128 -
   1.129 -                        if (status == PEP_VERIFIED || status == PEP_VERIFIED_AND_TRUSTED)
   1.130 -                            decrypt_status = PEP_DECRYPTED_AND_VERIFIED;
   1.131 +                    goto pep_error;                
   1.132 +                
   1.133 +                char* mlong = msg->longmsg;
   1.134 +                char* mform = msg->longmsg_formatted;
   1.135 +                bloblist_t* matt = msg->attachments;
   1.136 +                                        
   1.137 +                if ((!mlong || mlong[0] == '\0')
   1.138 +                     && (!mform || mform[0] == '\0')) {
   1.139 +                    if (matt) {
   1.140 +                        const char* inner_mime_type = matt->mime_type;
   1.141 +                        if (strcasecmp(inner_mime_type, "text/plain") == 0) {
   1.142 +                            free(mlong); /* in case of "" */
   1.143 +                            msg->longmsg = strdup(matt->value);
   1.144 +                        
   1.145 +                            bloblist_t* next_node = matt->next;
   1.146 +                            if (next_node) {
   1.147 +                                inner_mime_type = next_node->mime_type;
   1.148 +                                if (strcasecmp(inner_mime_type, "text/html") == 0) {
   1.149 +                                    free(mform);
   1.150 +                                    msg->longmsg_formatted = strdup(next_node->value);
   1.151 +                                }
   1.152 +                            }
   1.153 +                        }
   1.154 +                        else if (strcasecmp(inner_mime_type, "text/html") == 0) {
   1.155 +                            free(mform);
   1.156 +                            msg->longmsg_formatted = strdup(matt->value);
   1.157 +                        }                    
   1.158 +                    }
   1.159 +                    if (msg->shortmsg) {
   1.160 +                        free(src->shortmsg);
   1.161 +                        src->shortmsg = strdup(msg->shortmsg);
   1.162 +                    }
   1.163 +                }    
   1.164 +
   1.165 +                if (decrypt_status != PEP_DECRYPTED_AND_VERIFIED) {
   1.166 +                    status = _get_detached_signature(msg, &detached_sig);
   1.167 +                    if (decrypt_status == PEP_DECRYPTED && detached_sig) {
   1.168 +                        dsig_text = detached_sig->value;
   1.169 +                        dsig_size = detached_sig->size;
   1.170 +                        size_t ssize = 0;
   1.171 +                        char* stext = NULL;
   1.172 +
   1.173 +                        status = _get_signed_text(ptext, psize, &stext, &ssize);
   1.174 +                        stringlist_t *_verify_keylist = NULL;
   1.175 +
   1.176 +                        if (ssize > 0 && stext) {
   1.177 +                            status = cryptotech[crypto].verify_text(session, stext,
   1.178 +                                                                    ssize, dsig_text, dsig_size,
   1.179 +                                                                    &_verify_keylist);
   1.180 +
   1.181 +                            if (status == PEP_VERIFIED || status == PEP_VERIFIED_AND_TRUSTED)
   1.182 +                                decrypt_status = PEP_DECRYPTED_AND_VERIFIED;
   1.183 +                            
   1.184 +                                status = combine_keylists(session, &_verify_keylist, &_keylist, src->from);
   1.185 +                        }
   1.186                      }
   1.187                  }
   1.188 -
   1.189                  break;
   1.190  
   1.191              case PEP_enc_pieces:
   1.192 @@ -1633,7 +1761,7 @@
   1.193                          status = decrypt_and_verify(session, attctext, attcsize,
   1.194                                                      NULL, 0,
   1.195                                                      &ptext, &psize, &_keylist);
   1.196 -                        free_stringlist(_keylist);
   1.197 +                        free_stringlist(_keylist); // FIXME: Why do we do this?
   1.198  
   1.199                          if (ptext) {
   1.200                              if (is_encrypted_html_attachment(_s)) {
   1.201 @@ -1719,10 +1847,9 @@
   1.202                          goto enomem;
   1.203                  }
   1.204                  break;
   1.205 -
   1.206              default:
   1.207 -                // BUG: must implement more
   1.208 -                NOT_IMPLEMENTED
   1.209 +                    // BUG: must implement more
   1.210 +                    NOT_IMPLEMENTED
   1.211          }
   1.212  
   1.213          // check for private key in decrypted message attachement while inporting