ENGINE-233: passes tests ENGINE-233
authorKrista Bennett <krista@pep-project.org>
Tue, 22 Aug 2017 14:41:11 +0200
branchENGINE-233
changeset 1987313073d93cd9
parent 1984 06e6c0f1d8fc
child 2010 26671a7b16cb
ENGINE-233: passes tests
src/bloblist.c
src/bloblist.h
src/message_api.c
src/mime.c
src/mime.h
     1.1 --- a/src/bloblist.c	Tue Aug 22 12:29:17 2017 +0200
     1.2 +++ b/src/bloblist.c	Tue Aug 22 14:41:11 2017 +0200
     1.3 @@ -165,3 +165,13 @@
     1.4  
     1.5      return len;
     1.6  }
     1.7 +
     1.8 +DYNAMIC_API void set_blob_content_disposition(bloblist_t* blob, 
     1.9 +                                              content_disposition_type disposition,
    1.10 +                                              char* extension_typename,
    1.11 +                                              stringpair_list_t* dispo_params) {
    1.12 +
    1.13 +    blob->disposition_extention_type = extension_typename;
    1.14 +    blob->disposition = disposition;
    1.15 +    blob->disposition_parms = dispo_params;
    1.16 +}
     2.1 --- a/src/bloblist.h	Tue Aug 22 12:29:17 2017 +0200
     2.2 +++ b/src/bloblist.h	Tue Aug 22 14:41:11 2017 +0200
     2.3 @@ -4,12 +4,18 @@
     2.4  #pragma once
     2.5  
     2.6  #include "dynamic_api.h"
     2.7 -#include "mime.h"
     2.8 +#include "stringpair.h"
     2.9  
    2.10  #ifdef __cplusplus
    2.11  extern "C" {
    2.12  #endif
    2.13  
    2.14 +typedef enum {
    2.15 +    PEP_CONTENT_DISP_ATTACHMENT = 0,
    2.16 +    PEP_CONTENT_DISP_INLINE = 1,
    2.17 +    PEP_CONTENT_DISP_EXTENSION = 2,
    2.18 +    PEP_CONTENT_DISP_NONE = -1      // must be affirmatively set
    2.19 +} content_disposition_type;
    2.20  
    2.21  typedef struct _bloblist_t {
    2.22      char *value;                    // blob
    2.23 @@ -101,6 +107,27 @@
    2.24  
    2.25  DYNAMIC_API int bloblist_length(const bloblist_t *bloblist);
    2.26  
    2.27 +// set_blob_content_disposition() - set blob content disposition and parameters
    2.28 +//                                  when necessary
    2.29 +//
    2.30 +//  parameters:
    2.31 +//      blob (in)               bloblist struct to change disposition for
    2.32 +//      disposition (in)        disposition type (see enum)
    2.33 +//      extension_typename      if disposition type is an extension type,
    2.34 +//                              the name for the type goes here, NULL otherwise
    2.35 +//                              OWNERSHIP GOES TO BLOBLIST
    2.36 +//      dispo_params(in)        type/value pairs for disposition parameters,
    2.37 +//                              if any exist, otherwise NULL.
    2.38 +//                              OWNERSHIP GOES TO BLOBLIST
    2.39 +
    2.40 +DYNAMIC_API void set_blob_content_disposition(bloblist_t* blob, 
    2.41 +                                              content_disposition_type disposition,
    2.42 +                                              char* extension_typename,
    2.43 +                                              stringpair_list_t* dispo_params);
    2.44 +
    2.45 +
    2.46 +
    2.47 +
    2.48  #ifdef __cplusplus
    2.49  }
    2.50  #endif
     3.1 --- a/src/message_api.c	Tue Aug 22 12:29:17 2017 +0200
     3.2 +++ b/src/message_api.c	Tue Aug 22 14:41:11 2017 +0200
     3.3 @@ -211,32 +211,6 @@
     3.4      return -1;
     3.5  }
     3.6  
     3.7 -static void remove_msg_version_field(message* msg) {
     3.8 -    assert(msg);
     3.9 -
    3.10 -    stringpair_list_t* msg_opt_flds_curr = msg->opt_fields;
    3.11 -    stringpair_list_t** msg_opt_flds_prev_p = NULL;
    3.12 -    
    3.13 -    while (msg_opt_flds_curr) {
    3.14 -        char* fld_key = msg_opt_flds_curr->value->key;
    3.15 -        if (fld_key) {
    3.16 -            if (strcmp(fld_key, "X-pEp-Message-Version") == 0) {
    3.17 -                if (!msg_opt_flds_prev_p) {
    3.18 -                    msg->opt_fields = msg_opt_flds_curr->next;
    3.19 -                }
    3.20 -                else {
    3.21 -                    (*msg_opt_flds_prev_p)->next = msg_opt_flds_curr->next;
    3.22 -                }
    3.23 -                msg_opt_flds_curr->next = NULL;
    3.24 -                free_stringpair_list(msg_opt_flds_curr);
    3.25 -                break;
    3.26 -            }
    3.27 -            *msg_opt_flds_prev_p = msg_opt_flds_curr;
    3.28 -            msg_opt_flds_curr = msg_opt_flds_curr->next;
    3.29 -        }
    3.30 -    }
    3.31 -}
    3.32 -
    3.33  static PEP_STATUS copy_fields(message *dst, const message *src)
    3.34  {
    3.35      assert(dst);
    3.36 @@ -353,100 +327,6 @@
    3.37      return PEP_STATUS_OK;
    3.38  }
    3.39  
    3.40 -
    3.41 -static message* extract_minimal_envelope(const message* src, 
    3.42 -                                         PEP_msg_direction direct) {
    3.43 -    
    3.44 -    message* envelope = new_message(direct);
    3.45 -    if (!envelope)
    3.46 -        return NULL;
    3.47 -        
    3.48 -    envelope->shortmsg = strdup("pEp");
    3.49 -    if (!envelope->shortmsg)
    3.50 -        return NULL;
    3.51 -
    3.52 -    if (src->from) {
    3.53 -        envelope->from = identity_dup(src->from);
    3.54 -        if (!envelope->from)
    3.55 -            return NULL;
    3.56 -    }
    3.57 -
    3.58 -    if (src->to) {
    3.59 -        envelope->to = identity_list_dup(src->to);
    3.60 -        if (!envelope->to)
    3.61 -            return NULL;
    3.62 -    }
    3.63 -
    3.64 -    if (src->cc) {
    3.65 -        envelope->cc = identity_list_dup(src->cc);
    3.66 -        if (!envelope->cc)
    3.67 -            return NULL;
    3.68 -    }
    3.69 -
    3.70 -    if (src->bcc) {
    3.71 -        envelope->bcc = identity_list_dup(src->bcc);
    3.72 -        if (!envelope->bcc)
    3.73 -            return NULL;
    3.74 -    }
    3.75 -
    3.76 -    /* DO WE WANT TO EXPOSE THIS??? */
    3.77 -    if (src->reply_to) {
    3.78 -        envelope->reply_to = identity_list_dup(src->reply_to);
    3.79 -        if (!envelope->reply_to)
    3.80 -            return NULL;
    3.81 -    }
    3.82 -
    3.83 -    envelope->enc_format = src->enc_format;        
    3.84 -    
    3.85 -    return envelope;
    3.86 -}
    3.87 -
    3.88 -static void add_message_version(
    3.89 -    message* msg,
    3.90 -    int major_version,
    3.91 -    int minor_version
    3.92 -)
    3.93 -{
    3.94 -    assert(msg);
    3.95 -    
    3.96 -    char buf[8]; // xxx.xxx\0
    3.97 -    if (major_version < 1000 && minor_version < 1000) {
    3.98 -        int chars_set = sprintf(buf, "%d.%d", major_version, minor_version);
    3.99 -        if (chars_set >= 3)
   3.100 -            add_opt_field(msg, "X-pEp-Message-Version", buf);
   3.101 -    }
   3.102 -}
   3.103 -
   3.104 -static message* wrap_message_as_attachment(message* envelope, 
   3.105 -    const message* attachment) {
   3.106 -    
   3.107 -    message* _envelope = NULL;
   3.108 -    
   3.109 -    if (!envelope) {
   3.110 -        _envelope = extract_minimal_envelope(attachment, PEP_dir_outgoing);
   3.111 -        envelope = _envelope;
   3.112 -    }
   3.113 -    
   3.114 -    char* message_text = NULL;
   3.115 -    /* Turn message into a MIME-blob */
   3.116 -    PEP_STATUS status = mime_encode_message(attachment, false, &message_text);
   3.117 -    
   3.118 -    if (status != PEP_STATUS_OK) {
   3.119 -        free(_envelope);
   3.120 -        return NULL;
   3.121 -    }
   3.122 -    
   3.123 -    size_t message_len = strlen(message_text);
   3.124 -    
   3.125 -    bloblist_t* message_blob = new_bloblist(message_text, message_len,
   3.126 -                                            "message/rfc822", NULL);
   3.127 -    
   3.128 -    envelope->attachments = message_blob;
   3.129 -    add_message_version(envelope, 2, 0);
   3.130 -    
   3.131 -    return envelope;
   3.132 -}
   3.133 -
   3.134  static message * clone_to_empty_message(const message * src)
   3.135  {
   3.136      PEP_STATUS status;
   3.137 @@ -483,6 +363,7 @@
   3.138      )
   3.139  {
   3.140      PEP_STATUS status = PEP_STATUS_OK;
   3.141 +    bool free_ptext = false;
   3.142      char *ptext = NULL;
   3.143      char *ctext = NULL;
   3.144      char *mimetext = NULL;
   3.145 @@ -490,12 +371,20 @@
   3.146      assert(dst->longmsg == NULL);
   3.147      dst->enc_format = PEP_enc_PGP_MIME;
   3.148  
   3.149 -    if (src->shortmsg) {
   3.150 -        dst->shortmsg = strdup(src->shortmsg);
   3.151 -        assert(dst->shortmsg);
   3.152 -        if (dst->shortmsg == NULL)
   3.153 -            goto enomem;
   3.154 -        ptext = src->longmsg;
   3.155 +    if (src->shortmsg && strcmp(src->shortmsg, "pEp") != 0) {
   3.156 +        if (session->unencrypted_subject) {
   3.157 +            dst->shortmsg = strdup(src->shortmsg);
   3.158 +            assert(dst->shortmsg);
   3.159 +            if (dst->shortmsg == NULL)
   3.160 +                goto enomem;
   3.161 +            ptext = src->longmsg;
   3.162 +        }
   3.163 +        else {
   3.164 +            ptext = combine_short_and_long(src->shortmsg, src->longmsg);
   3.165 +            if (ptext == NULL)
   3.166 +                goto enomem;
   3.167 +            free_ptext = true;
   3.168 +        }
   3.169      }
   3.170      else if (src->longmsg) {
   3.171          ptext = src->longmsg;
   3.172 @@ -517,6 +406,10 @@
   3.173      if (status != PEP_STATUS_OK)
   3.174          goto pep_error;
   3.175  
   3.176 +    if (free_ptext){
   3.177 +        free(ptext);
   3.178 +        free_ptext=0;
   3.179 +    }
   3.180      free(_src);
   3.181      assert(mimetext);
   3.182      if (mimetext == NULL)
   3.183 @@ -1227,9 +1120,7 @@
   3.184      PEP_STATUS status = PEP_STATUS_OK;
   3.185      message * msg = NULL;
   3.186      stringlist_t * keys = NULL;
   3.187 -    message* _src = NULL;
   3.188 -    message* inner_message = NULL;
   3.189 -    
   3.190 +
   3.191      assert(session);
   3.192      assert(src);
   3.193      assert(dst);
   3.194 @@ -1241,14 +1132,6 @@
   3.195      if (src->dir == PEP_dir_incoming)
   3.196          return ADD_TO_LOG(PEP_ILLEGAL_VALUE);
   3.197  
   3.198 -    bool no_wrap_message = (flags & PEP_encrypt_flag_dont_raise_headers);
   3.199 -    
   3.200 -    if (!no_wrap_message) {
   3.201 -        PEP_STATUS wrap_status = encrypt_message(session, src, extra, &inner_message,
   3.202 -                                                 enc_format, 
   3.203 -                                                 (flags ^ PEP_encrypt_flag_dont_raise_headers));
   3.204 -    }
   3.205 -    
   3.206      determine_encryption_format(src);
   3.207      if (src->enc_format != PEP_enc_none)
   3.208          return ADD_TO_LOG(PEP_ILLEGAL_VALUE);
   3.209 @@ -1364,29 +1247,21 @@
   3.210          return ADD_TO_LOG(PEP_UNENCRYPTED);
   3.211      }
   3.212      else {
   3.213 -        if (no_wrap_message) {
   3.214 -            msg = clone_to_empty_message(src);
   3.215 -            _src = src;
   3.216 -        }
   3.217 -        else if (inner_message) {
   3.218 -            _src = wrap_message_as_attachment(NULL, inner_message);
   3.219 -            msg = clone_to_empty_message(_src);
   3.220 -        }
   3.221 +        msg = clone_to_empty_message(src);
   3.222          if (msg == NULL)
   3.223              goto enomem;
   3.224  
   3.225          if (!(flags & PEP_encrypt_flag_force_no_attached_key))
   3.226 -            attach_own_key(session, _src);
   3.227 +            attach_own_key(session, src);
   3.228  
   3.229          switch (enc_format) {
   3.230          case PEP_enc_PGP_MIME:
   3.231          case PEP_enc_PEP: // BUG: should be implemented extra
   3.232 -            status = encrypt_PGP_MIME(session, _src, keys, msg, flags);
   3.233 +            status = encrypt_PGP_MIME(session, src, keys, msg, flags);
   3.234              break;
   3.235  
   3.236 -        // This actually doesn't really make sense for message 2.0... See function comment below
   3.237          case PEP_enc_pieces:
   3.238 -            status = encrypt_PGP_in_pieces(session, _src, keys, msg, flags);
   3.239 +            status = encrypt_PGP_in_pieces(session, src, keys, msg, flags);
   3.240              break;
   3.241  
   3.242          /* case PEP_enc_PEP:
   3.243 @@ -1417,8 +1292,8 @@
   3.244  
   3.245      if (msg) {
   3.246          decorate_message(msg, PEP_rating_undefined, NULL);
   3.247 -        if (_src->id) {
   3.248 -            msg->id = strdup(_src->id);
   3.249 +        if (src->id) {
   3.250 +            msg->id = strdup(src->id);
   3.251              assert(msg->id);
   3.252              if (msg->id == NULL)
   3.253                  goto enomem;
   3.254 @@ -1426,7 +1301,6 @@
   3.255      }
   3.256  
   3.257      *dst = msg;
   3.258 -//    free_message(wrapped_msg);
   3.259      return ADD_TO_LOG(status);
   3.260  
   3.261  enomem:
   3.262 @@ -1435,8 +1309,7 @@
   3.263  pep_error:
   3.264      free_stringlist(keys);
   3.265      free_message(msg);
   3.266 -    if (!no_wrap_message)
   3.267 -        free_message(_src);
   3.268 +
   3.269      return ADD_TO_LOG(status);
   3.270  }
   3.271  
   3.272 @@ -1559,60 +1432,8 @@
   3.273      return false;
   3.274  }
   3.275  
   3.276 -static const char* pEpmessage_version_str(const message *msg)
   3.277 -{
   3.278 -    char* retval = NULL;
   3.279 -    for (stringpair_list_t *i = msg->opt_fields; i && i->value ; i=i->next) {
   3.280 -        if (strcasecmp(i->value->key, "X-pEp-Message-Version") == 0) {
   3.281 -            retval = i->value->value;
   3.282 -            break;
   3.283 -        }
   3.284 -    }
   3.285 -    return retval;
   3.286 -}
   3.287 -
   3.288 -static int pEpmessage_major_version(const message *msg) {
   3.289 -    const char* version_string = pEpmessage_version_str(msg);
   3.290 -    if (!version_string)
   3.291 -        return -1;
   3.292 -    
   3.293 -    int ver_strlen = strlen(version_string);
   3.294 -    if (ver_strlen < 3)
   3.295 -        return -1;
   3.296 -        
   3.297 -    const short MAX_MAJ_VERSION_DIGITS = 4; // I certainly hope...    
   3.298 -    char version_buf[MAX_MAJ_VERSION_DIGITS + 1];
   3.299 -
   3.300 -    int i = 0;    
   3.301 -    
   3.302 -    for ( ; i < MAX_MAJ_VERSION_DIGITS && i < ver_strlen; i++ ) {
   3.303 -        if (version_string[i] == '.') {
   3.304 -            version_buf[i] = '\0';
   3.305 -            break;
   3.306 -        }
   3.307 -        version_buf[i] = version_string[i];
   3.308 -    }
   3.309 -    
   3.310 -    if (version_string[i] != '.')
   3.311 -        return -1;
   3.312 -    
   3.313 -    // ok, this is some chars + \0, but not necessarily numeric.
   3.314 -    int retval = atoi(version_buf);
   3.315 -    if (retval == 0 && version_buf[0] != 0)
   3.316 -        return -1;
   3.317 -    
   3.318 -    return retval;
   3.319 -}
   3.320 -
   3.321 -static bool verify_explicit_message_version(const char* desired_version, 
   3.322 -    const message* msg) {
   3.323 -    if (!desired_version || !msg)
   3.324 -        return false;
   3.325 -    const char* msg_version_str = pEpmessage_version_str(msg);
   3.326 -    return (msg_version_str && (strcmp(desired_version, msg_version_str) == 0));
   3.327 -}
   3.328 -
   3.329  // update comm_type to pEp_ct_pEp if needed
   3.330 +
   3.331  static PEP_STATUS _update_identity_for_incoming_message(
   3.332          PEP_SESSION session,
   3.333          const message *src
   3.334 @@ -1840,29 +1661,6 @@
   3.335      return status;
   3.336  }
   3.337  
   3.338 -static void pull_up_longmsg_attachment(message* msg) {
   3.339 -    bloblist_t* matt = msg->attachments;
   3.340 -    if (matt) {
   3.341 -        const char* inner_mime_type = matt->mime_type;
   3.342 -        if (strcasecmp(inner_mime_type, "text/plain") == 0) {
   3.343 -            free(msg->longmsg); /* in case of "" */
   3.344 -            msg->longmsg = strndup(matt->value, matt->size);
   3.345 -            
   3.346 -            bloblist_t* next_node = matt->next;
   3.347 -            if (next_node) {
   3.348 -                inner_mime_type = next_node->mime_type;
   3.349 -                if (strcasecmp(inner_mime_type, "text/html") == 0) {
   3.350 -                    free(msg->longmsg_formatted);
   3.351 -                    msg->longmsg_formatted = strndup(next_node->value, next_node->size);
   3.352 -                }
   3.353 -            }
   3.354 -        }
   3.355 -        else if (strcasecmp(inner_mime_type, "text/html") == 0) {
   3.356 -            free(msg->longmsg_formatted);
   3.357 -            msg->longmsg_formatted = strndup(matt->value, matt->size);
   3.358 -        }
   3.359 -    }
   3.360 -}
   3.361  
   3.362  DYNAMIC_API PEP_STATUS _decrypt_message(
   3.363          PEP_SESSION session,
   3.364 @@ -1883,11 +1681,6 @@
   3.365      size_t psize;
   3.366      stringlist_t *_keylist = NULL;
   3.367  
   3.368 -    // this will only ever be non-null if the message passed in is an
   3.369 -    // outer message wrapping an inner one.
   3.370 -    message* inner_message = NULL;
   3.371 -    int inner_major_version = -1;
   3.372 -    
   3.373      assert(session);
   3.374      assert(src);
   3.375      assert(dst);
   3.376 @@ -1947,6 +1740,7 @@
   3.377              
   3.378              char* slong = src->longmsg;
   3.379              char* sform = src->longmsg_formatted;
   3.380 +            bloblist_t* satt = src->attachments;
   3.381              
   3.382              if ((!slong || slong[0] == '\0')
   3.383                   && (!sform || sform[0] == '\0')) {
   3.384 @@ -2019,55 +1813,32 @@
   3.385                  if (status != PEP_STATUS_OK)
   3.386                      goto pep_error;
   3.387                  
   3.388 -                int msg_major_version = pEpmessage_major_version(src);
   3.389 -
   3.390 -                /* Check for message version greater than 1 - if it is, it
   3.391 -                   means that this is an outer message containing an inner
   3.392 -                   message. The inner message has unencrypted headers, and
   3.393 -                   if ITS version == 1 (or is not present), it is the
   3.394 -                   innermost message.
   3.395 -                   
   3.396 -                   If version > 1, the outer message is just one layer of
   3.397 -                   a multilayer message, and we only strip one layer
   3.398 -                   and return the next one.
   3.399 -                   
   3.400 -                   If version == 1 (or none indicated), there are two possibilities:
   3.401 -                   either the inner message is a forwarded message, or it is the real message
   3.402 -                   which needs to be pulled up for evaluation.
   3.403 -                   
   3.404 -                   This should, in fact, not be difficult to determine, as a legitimately
   3.405 -                   wrapped inner message will have a version 2 outer message, whereas
   3.406 -                   an attachment will have a version 1 (or unspecified) outer message.
   3.407 -                   
   3.408 -                 */
   3.409 -                if (msg_major_version > 1) {
   3.410 -                    
   3.411 -                    /* This is an outer message - get the inner message */
   3.412 -                    status = mime_decode_message(msg->attachments->value, 
   3.413 -                                                 msg->attachments->size,
   3.414 -                                                 &inner_message);
   3.415 -                    if (status != PEP_STATUS_OK)
   3.416 -                        goto pep_error;
   3.417 -            
   3.418 -                    // FIXME: Deal with keys... we care about the outer and inner layers
   3.419 -                    // but how?
   3.420 -                    
   3.421 -                    inner_major_version = pEpmessage_major_version(inner_message);
   3.422 -            
   3.423 -                    if (inner_major_version < 2) {
   3.424 -                        // raise message, combine address lists, etc
   3.425 -                    }
   3.426 -                    else {
   3.427 -                        // raise message, check against outer address lists
   3.428 -                    }
   3.429 -                }
   3.430 -                                    
   3.431                  char* mlong = msg->longmsg;
   3.432                  char* mform = msg->longmsg_formatted;
   3.433 +                bloblist_t* matt = msg->attachments;
   3.434                  
   3.435 -                if ((!mlong || mlong[0] == '\0') && (!mform || mform[0] == '\0')) {             
   3.436 -                    pull_up_longmsg_attachment(msg);
   3.437 -                    
   3.438 +                if ((!mlong || mlong[0] == '\0')
   3.439 +                     && (!mform || mform[0] == '\0')) {
   3.440 +                    if (matt) {
   3.441 +                        const char* inner_mime_type = matt->mime_type;
   3.442 +                        if (strcasecmp(inner_mime_type, "text/plain") == 0) {
   3.443 +                            free(mlong); /* in case of "" */
   3.444 +                            msg->longmsg = strndup(matt->value, matt->size);
   3.445 +                            
   3.446 +                            bloblist_t* next_node = matt->next;
   3.447 +                            if (next_node) {
   3.448 +                                inner_mime_type = next_node->mime_type;
   3.449 +                                if (strcasecmp(inner_mime_type, "text/html") == 0) {
   3.450 +                                    free(mform);
   3.451 +                                    msg->longmsg_formatted = strndup(next_node->value, next_node->size);
   3.452 +                                }
   3.453 +                            }
   3.454 +                        }
   3.455 +                        else if (strcasecmp(inner_mime_type, "text/html") == 0) {
   3.456 +                            free(mform);
   3.457 +                            msg->longmsg_formatted = strndup(matt->value, matt->size);
   3.458 +                        }
   3.459 +                    }
   3.460                      if (msg->shortmsg) {
   3.461                          free(src->shortmsg);
   3.462                          src->shortmsg = strdup(msg->shortmsg);
   3.463 @@ -2097,8 +1868,6 @@
   3.464                          }
   3.465                      }
   3.466                  }
   3.467 -                
   3.468 -                /* Ok, so either way, detached sig or not, we should have decrypted and verified our PGP MIME encoded message if it was possible. */
   3.469                  break;
   3.470  
   3.471              case PEP_enc_pieces:
   3.472 @@ -2195,57 +1964,48 @@
   3.473              case PEP_enc_PGP_MIME:
   3.474              case PEP_enc_pieces:
   3.475              case PEP_enc_PGP_MIME_Outlook1:
   3.476 -            
   3.477 -                if (inner_message) {
   3.478 -                    /* we don't need to lift the subject etc, since the inner message has the real one */
   3.479 -                    if (inner_major_version < 2) {
   3.480 -                        // We need to verify that recips/sender are the same or combined or some such
   3.481 +                status = copy_fields(msg, src);
   3.482 +                if (status != PEP_STATUS_OK)
   3.483 +                {
   3.484 +                    GOTO(pep_error);
   3.485 +                }
   3.486 +
   3.487 +                if (src->shortmsg == NULL || strcmp(src->shortmsg, "pEp") == 0)
   3.488 +                {
   3.489 +                    char * shortmsg;
   3.490 +                    char * longmsg;
   3.491 +
   3.492 +                    int r = separate_short_and_long(msg->longmsg, &shortmsg,
   3.493 +                            &longmsg);
   3.494 +                    
   3.495 +                    if (r == -1)
   3.496 +                        goto enomem;
   3.497 +
   3.498 +                    if (shortmsg == NULL) {
   3.499 +                        if (src->shortmsg == NULL)
   3.500 +                            shortmsg = strdup("");
   3.501 +                        else {
   3.502 +                            // FIXME: is msg->shortmsg always a copy of
   3.503 +                            // src->shortmsg already?
   3.504 +                            // if so, we need to change the logic so
   3.505 +                            // that in this case, we don't free msg->shortmsg
   3.506 +                            // and do this strdup, etc.
   3.507 +                            shortmsg = strdup(src->shortmsg);
   3.508 +                        }
   3.509                      }
   3.510 +
   3.511 +
   3.512 +                    free(msg->shortmsg);
   3.513 +                    free(msg->longmsg);
   3.514 +
   3.515 +                    msg->shortmsg = shortmsg;
   3.516 +                    msg->longmsg = longmsg;
   3.517                  }
   3.518                  else {
   3.519 -                    status = copy_fields(msg, src);
   3.520 -                    if (status != PEP_STATUS_OK)
   3.521 -                    {
   3.522 -                        GOTO(pep_error);
   3.523 -                    }
   3.524 -
   3.525 -                    if (src->shortmsg == NULL || strcmp(src->shortmsg, "pEp") == 0)
   3.526 -                    {
   3.527 -                        char * shortmsg;
   3.528 -                        char * longmsg;
   3.529 -
   3.530 -                        int r = separate_short_and_long(msg->longmsg, &shortmsg,
   3.531 -                                &longmsg);
   3.532 -                        
   3.533 -                        if (r == -1)
   3.534 -                            goto enomem;
   3.535 -
   3.536 -                        if (shortmsg == NULL) {
   3.537 -                            if (src->shortmsg == NULL)
   3.538 -                                shortmsg = strdup("");
   3.539 -                            else {
   3.540 -                                // FIXME: is msg->shortmsg always a copy of
   3.541 -                                // src->shortmsg already?
   3.542 -                                // if so, we need to change the logic so
   3.543 -                                // that in this case, we don't free msg->shortmsg
   3.544 -                                // and do this strdup, etc.
   3.545 -                                shortmsg = strdup(src->shortmsg);
   3.546 -                            }
   3.547 -                        }
   3.548 -
   3.549 -
   3.550 -                        free(msg->shortmsg);
   3.551 -                        free(msg->longmsg);
   3.552 -
   3.553 -                        msg->shortmsg = shortmsg;
   3.554 -                        msg->longmsg = longmsg;
   3.555 -                    }
   3.556 -                    else {
   3.557 -                        msg->shortmsg = strdup(src->shortmsg);
   3.558 -                        assert(msg->shortmsg);
   3.559 -                        if (msg->shortmsg == NULL)
   3.560 -                            goto enomem;
   3.561 -                    }
   3.562 +                    msg->shortmsg = strdup(src->shortmsg);
   3.563 +                    assert(msg->shortmsg);
   3.564 +                    if (msg->shortmsg == NULL)
   3.565 +                        goto enomem;
   3.566                  }
   3.567                  break;
   3.568              default:
   3.569 @@ -2269,7 +2029,7 @@
   3.570              free_identity_list(_private_il);
   3.571          }
   3.572  
   3.573 -        if (decrypt_status == PEP_DECRYPTED){
   3.574 +        if(decrypt_status == PEP_DECRYPTED){
   3.575  
   3.576              // TODO optimize if import_attached_keys didn't import any key
   3.577  
     4.1 --- a/src/mime.c	Tue Aug 22 12:29:17 2017 +0200
     4.2 +++ b/src/mime.c	Tue Aug 22 14:41:11 2017 +0200
     4.3 @@ -1530,13 +1530,3 @@
     4.4  
     4.5      return status;
     4.6  }
     4.7 -
     4.8 -DYNAMIC_API void set_blob_content_disposition(bloblist_t* blob, 
     4.9 -                                              content_disposition_type disposition,
    4.10 -                                              char* extension_typename,
    4.11 -                                              stringpair_list_t dispo_params) {
    4.12 -
    4.13 -    blob->disposition_extention_type = extension_typename;
    4.14 -    blob->content_disposition_type = disposition;
    4.15 -    blob->disposition_parms = dispo_params;
    4.16 -}
     5.1 --- a/src/mime.h	Tue Aug 22 12:29:17 2017 +0200
     5.2 +++ b/src/mime.h	Tue Aug 22 14:41:11 2017 +0200
     5.3 @@ -9,19 +9,6 @@
     5.4  extern "C" {
     5.5  #endif
     5.6  
     5.7 -typedef enum {
     5.8 -    PEP_CONTENT_DISP_ATTACHMENT = 0,
     5.9 -    PEP_CONTENT_DISP_INLINE = 1,
    5.10 -    PEP_CONTENT_DISP_EXTENSION = 2,
    5.11 -    PEP_CONTENT_DISP_NONE = -1      // must be affirmatively set
    5.12 -} content_disposition_type;
    5.13 -
    5.14 -DYNAMIC_API void set_blob_content_disposition(bloblist_t* blob, 
    5.15 -                                              content_disposition_type disposition,
    5.16 -                                              const char* extension_typename,
    5.17 -                                              stringpair_list_t dispo_params);
    5.18 -
    5.19 -
    5.20  // is_PGP_message_text() - determine if text encodes a PGP message
    5.21  //
    5.22  //  parameters: