merged in default ENGINE-214
authorKrista Bennett <krista@pep-project.org>
Wed, 06 Sep 2017 02:23:15 +0200
branchENGINE-214
changeset 2044135f59490f59
parent 2034 b6742bbca2d2
parent 2037 148b879873f8
child 2056 416d7d4e26b1
merged in default
     1.1 --- a/build-config/Linux.conf	Tue Sep 05 18:46:05 2017 +0200
     1.2 +++ b/build-config/Linux.conf	Wed Sep 06 02:23:15 2017 +0200
     1.3 @@ -7,7 +7,7 @@
     1.4  TARGET=libpEpEngine.so
     1.5  
     1.6  ######### C #########
     1.7 -CC=gcc -std=c99 -pthread -g -O0
     1.8 +CC=gcc -std=c99 -pthread
     1.9  CFLAGS=-fPIC -fstrict-aliasing -fdiagnostics-color=always
    1.10  ifdef WARN
    1.11      CFLAGS+= -Wall -pedantic -Wstrict-aliasing=3
    1.12 @@ -17,13 +17,13 @@
    1.13  ifdef DEBUG
    1.14      CFLAGS+= -Og -ggdb -DDEBUG_ERRORSTACK
    1.15  else
    1.16 -    CFLAGS+= -DNDEBUG
    1.17 +    CFLAGS+= -O3 -DNDEBUG
    1.18  endif
    1.19  # The '_DEFAULT_SOURCE' feature test macro is required to suppress the warning "_BSD_SOURCE and _SVID_SOURCE are deprecated, use _DEFAULT_SOURCE" otherwise printed during the compilation of every asn1c-generated C file. It's a glibc specific warning, only present in few versions around ~2.19. See https://lwn.net/Articles/590381/ for a discussion.
    1.20  CFLAGS_GENERATED=-D_DEFAULT_SOURCE
    1.21  
    1.22  ######### C++ #########
    1.23 -CXX=g++ -std=gnu++11 -pthread -g -O0
    1.24 +CXX=g++ -std=gnu++11 -pthread
    1.25  CXXFLAGS=-fdiagnostics-color=always -I../src -I../asn.1 $(ETPAN_INC)
    1.26  ifdef WARN
    1.27      CXXFLAGS+=
    1.28 @@ -33,7 +33,7 @@
    1.29  ifdef DEBUG
    1.30      CXXFLAGS+= -Og -ggdb
    1.31  else
    1.32 -    CXXFLAGS+= -DNDEBUG
    1.33 +    CXXFLAGS+= -O3 -DNDEBUG
    1.34  endif
    1.35  
    1.36  ######### C and C++ #########
     2.1 --- a/src/message.h	Tue Sep 05 18:46:05 2017 +0200
     2.2 +++ b/src/message.h	Wed Sep 06 02:23:15 2017 +0200
     2.3 @@ -163,3 +163,4 @@
     2.4  #ifdef __cplusplus
     2.5  }
     2.6  #endif
     2.7 +
     3.1 --- a/src/message_api.c	Tue Sep 05 18:46:05 2017 +0200
     3.2 +++ b/src/message_api.c	Wed Sep 06 02:23:15 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,102 +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 -        if (!_envelope)
   3.112 -            return PEP_UNKNOWN_ERROR;
   3.113 -        envelope = _envelope;
   3.114 -    }
   3.115 -    
   3.116 -    char* message_text = NULL;
   3.117 -    /* Turn message into a MIME-blob */
   3.118 -    PEP_STATUS status = mime_encode_message(attachment, false, &message_text);
   3.119 -    
   3.120 -    if (status != PEP_STATUS_OK || !message_text) {
   3.121 -        free(_envelope);
   3.122 -        return NULL;
   3.123 -    }
   3.124 -    
   3.125 -    size_t message_len = strlen(message_text);
   3.126 -    
   3.127 -    bloblist_t* message_blob = new_bloblist(message_text, message_len,
   3.128 -                                            "message/rfc822", NULL);
   3.129 -    
   3.130 -    envelope->attachments = message_blob;
   3.131 -    add_message_version(envelope, 2, 0);
   3.132 -    
   3.133 -    return envelope;
   3.134 -}
   3.135 -
   3.136  static message * clone_to_empty_message(const message * src)
   3.137  {
   3.138      PEP_STATUS status;
   3.139 @@ -580,8 +458,6 @@
   3.140      return status;
   3.141  }
   3.142  
   3.143 -// N.B. TO BE MOVED TO READ-ONLY
   3.144 -// FIXME: Does this happen concurrent w/ message 2.0 merge?
   3.145  static PEP_STATUS encrypt_PGP_in_pieces(
   3.146      PEP_SESSION session,
   3.147      const message *src,
   3.148 @@ -1244,8 +1120,6 @@
   3.149      PEP_STATUS status = PEP_STATUS_OK;
   3.150      message * msg = NULL;
   3.151      stringlist_t * keys = NULL;
   3.152 -    message* _src = NULL;
   3.153 -    bool no_wrap_message = (flags & PEP_encrypt_flag_dont_raise_headers);
   3.154  
   3.155      assert(session);
   3.156      assert(src);
   3.157 @@ -1373,37 +1247,21 @@
   3.158          return ADD_TO_LOG(PEP_UNENCRYPTED);
   3.159      }
   3.160      else {
   3.161 -        if (no_wrap_message) {
   3.162 -            msg = clone_to_empty_message(src);
   3.163 -            _src = src;
   3.164 -        }
   3.165 -        else {
   3.166 -            // encrypt inner message
   3.167 -            message* inner_message = NULL;
   3.168 -            status = encrypt_message(session, src, extra, &inner_message,
   3.169 -                                     enc_format, flags | PEP_encrypt_flag_dont_raise_headers);                         
   3.170 -            _src = wrap_message_as_attachment(NULL, inner_message);
   3.171 -            if (_src == NULL) {
   3.172 -                status = PEP_UNKNOWN_ERROR;
   3.173 -                goto pep_error;
   3.174 -            }
   3.175 -            msg = clone_to_empty_message(_src);
   3.176 -        }
   3.177 +        msg = clone_to_empty_message(src);
   3.178          if (msg == NULL)
   3.179              goto enomem;
   3.180  
   3.181          if (!(flags & PEP_encrypt_flag_force_no_attached_key))
   3.182 -            attach_own_key(session, _src);
   3.183 +            attach_own_key(session, src);
   3.184  
   3.185          switch (enc_format) {
   3.186          case PEP_enc_PGP_MIME:
   3.187          case PEP_enc_PEP: // BUG: should be implemented extra
   3.188 -            status = encrypt_PGP_MIME(session, _src, keys, msg, flags);
   3.189 +            status = encrypt_PGP_MIME(session, src, keys, msg, flags);
   3.190              break;
   3.191  
   3.192 -        // This actually doesn't really make sense for message 2.0... See function comment below
   3.193          case PEP_enc_pieces:
   3.194 -            status = encrypt_PGP_in_pieces(session, _src, keys, msg, flags);
   3.195 +            status = encrypt_PGP_in_pieces(session, src, keys, msg, flags);
   3.196              break;
   3.197  
   3.198          /* case PEP_enc_PEP:
   3.199 @@ -1434,8 +1292,8 @@
   3.200  
   3.201      if (msg) {
   3.202          decorate_message(msg, PEP_rating_undefined, NULL);
   3.203 -        if (_src->id) {
   3.204 -            msg->id = strdup(_src->id);
   3.205 +        if (src->id) {
   3.206 +            msg->id = strdup(src->id);
   3.207              assert(msg->id);
   3.208              if (msg->id == NULL)
   3.209                  goto enomem;
   3.210 @@ -1443,7 +1301,6 @@
   3.211      }
   3.212  
   3.213      *dst = msg;
   3.214 -//    free_message(wrapped_msg);
   3.215      return ADD_TO_LOG(status);
   3.216  
   3.217  enomem:
   3.218 @@ -1452,8 +1309,7 @@
   3.219  pep_error:
   3.220      free_stringlist(keys);
   3.221      free_message(msg);
   3.222 -    if (!no_wrap_message)
   3.223 -        free_message(_src);
   3.224 +
   3.225      return ADD_TO_LOG(status);
   3.226  }
   3.227  
   3.228 @@ -1515,11 +1371,7 @@
   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 -            // N.B. Don't raise headers, as we want to send a 1.0 message back.
   3.233 -            // If this is a draft, obviously that will change when it's reencrypted
   3.234 -            // for everybody else.
   3.235 -            status = encrypt_PGP_MIME(session, src, keys, msg, 
   3.236 -                                      flags | PEP_encrypt_flag_dont_raise_headers);
   3.237 +            status = encrypt_PGP_MIME(session, src, keys, msg, flags);
   3.238              break;
   3.239  
   3.240          case PEP_enc_pieces:
   3.241 @@ -1580,60 +1432,8 @@
   3.242      return false;
   3.243  }
   3.244  
   3.245 -static const char* pEpmessage_version_str(const message *msg)
   3.246 -{
   3.247 -    char* retval = NULL;
   3.248 -    for (stringpair_list_t *i = msg->opt_fields; i && i->value ; i=i->next) {
   3.249 -        if (strcasecmp(i->value->key, "X-pEp-Message-Version") == 0) {
   3.250 -            retval = i->value->value;
   3.251 -            break;
   3.252 -        }
   3.253 -    }
   3.254 -    return retval;
   3.255 -}
   3.256 -
   3.257 -static int pEpmessage_major_version(const message *msg) {
   3.258 -    const char* version_string = pEpmessage_version_str(msg);
   3.259 -    if (!version_string)
   3.260 -        return -1;
   3.261 -    
   3.262 -    int ver_strlen = strlen(version_string);
   3.263 -    if (ver_strlen < 3)
   3.264 -        return -1;
   3.265 -        
   3.266 -    const short MAX_MAJ_VERSION_DIGITS = 4; // I certainly hope...    
   3.267 -    char version_buf[MAX_MAJ_VERSION_DIGITS + 1];
   3.268 -
   3.269 -    int i = 0;    
   3.270 -    
   3.271 -    for ( ; i < MAX_MAJ_VERSION_DIGITS && i < ver_strlen; i++ ) {
   3.272 -        if (version_string[i] == '.') {
   3.273 -            version_buf[i] = '\0';
   3.274 -            break;
   3.275 -        }
   3.276 -        version_buf[i] = version_string[i];
   3.277 -    }
   3.278 -    
   3.279 -    if (version_string[i] != '.')
   3.280 -        return -1;
   3.281 -    
   3.282 -    // ok, this is some chars + \0, but not necessarily numeric.
   3.283 -    int retval = atoi(version_buf);
   3.284 -    if (retval == 0 && version_buf[0] != 0)
   3.285 -        return -1;
   3.286 -    
   3.287 -    return retval;
   3.288 -}
   3.289 -
   3.290 -// static bool verify_explicit_message_version(const char* desired_version, 
   3.291 -//     const message* msg) {
   3.292 -//     if (!desired_version || !msg)
   3.293 -//         return false;
   3.294 -//     const char* msg_version_str = pEpmessage_version_str(msg);
   3.295 -//     return (msg_version_str && (strcmp(desired_version, msg_version_str) == 0));
   3.296 -// }
   3.297 -
   3.298  // update comm_type to pEp_ct_pEp if needed
   3.299 +
   3.300  static PEP_STATUS _update_identity_for_incoming_message(
   3.301          PEP_SESSION session,
   3.302          const message *src
   3.303 @@ -1861,29 +1661,6 @@
   3.304      return status;
   3.305  }
   3.306  
   3.307 -static void pull_up_longmsg_attachment(message* msg) {
   3.308 -    bloblist_t* matt = msg->attachments;
   3.309 -    if (matt) {
   3.310 -        const char* inner_mime_type = matt->mime_type;
   3.311 -        if (strcasecmp(inner_mime_type, "text/plain") == 0) {
   3.312 -            free(msg->longmsg); /* in case of "" */
   3.313 -            msg->longmsg = strndup(matt->value, matt->size);
   3.314 -            
   3.315 -            bloblist_t* next_node = matt->next;
   3.316 -            if (next_node) {
   3.317 -                inner_mime_type = next_node->mime_type;
   3.318 -                if (strcasecmp(inner_mime_type, "text/html") == 0) {
   3.319 -                    free(msg->longmsg_formatted);
   3.320 -                    msg->longmsg_formatted = strndup(next_node->value, next_node->size);
   3.321 -                }
   3.322 -            }
   3.323 -        }
   3.324 -        else if (strcasecmp(inner_mime_type, "text/html") == 0) {
   3.325 -            free(msg->longmsg_formatted);
   3.326 -            msg->longmsg_formatted = strndup(matt->value, matt->size);
   3.327 -        }
   3.328 -    }
   3.329 -}
   3.330  
   3.331  DYNAMIC_API PEP_STATUS _decrypt_message(
   3.332          PEP_SESSION session,
   3.333 @@ -1903,7 +1680,6 @@
   3.334      char *ptext = NULL;
   3.335      size_t psize;
   3.336      stringlist_t *_keylist = NULL;
   3.337 -    message *inner_message = NULL; // For version 2.0+ messages
   3.338  
   3.339      assert(session);
   3.340      assert(src);
   3.341 @@ -1964,9 +1740,31 @@
   3.342              
   3.343              char* slong = src->longmsg;
   3.344              char* sform = src->longmsg_formatted;
   3.345 +            bloblist_t* satt = src->attachments;
   3.346              
   3.347 -            if ((!slong || slong[0] == '\0') && (!sform || sform[0] == '\0'))                
   3.348 -                pull_up_longmsg_attachment(src);
   3.349 +            if ((!slong || slong[0] == '\0')
   3.350 +                 && (!sform || sform[0] == '\0')) {
   3.351 +                if (satt) {
   3.352 +                    const char* inner_mime_type = satt->mime_type;
   3.353 +                    if (strcasecmp(inner_mime_type, "text/plain") == 0) {
   3.354 +                        free(slong); /* in case of "" */
   3.355 +                        src->longmsg = strndup(satt->value, satt->size); // N.B.: longmsg might be shorter, if attachment contains NUL bytes which are not allowed in text/plain!
   3.356 +                        
   3.357 +                        bloblist_t* next_node = satt->next;
   3.358 +                        if (next_node) {
   3.359 +                            inner_mime_type = next_node->mime_type;
   3.360 +                            if (strcasecmp(inner_mime_type, "text/html") == 0) {
   3.361 +                                free(sform);
   3.362 +                                src->longmsg_formatted = strndup(next_node->value, next_node->size);  // N.B.: longmsg might be shorter, if attachment contains NUL bytes which are not allowed in text/plain!
   3.363 +                            }
   3.364 +                        }
   3.365 +                    }
   3.366 +                    else if (strcasecmp(inner_mime_type, "text/html") == 0) {
   3.367 +                        free(sform);
   3.368 +                        src->longmsg_formatted = strndup(satt->value, satt->size);  // N.B.: longmsg might be shorter, if attachment contains NUL bytes which are not allowed in text/plain!
   3.369 +                    }
   3.370 +                }
   3.371 +            }
   3.372              
   3.373              return ADD_TO_LOG(PEP_UNENCRYPTED);
   3.374  
   3.375 @@ -2015,44 +1813,32 @@
   3.376                  if (status != PEP_STATUS_OK)
   3.377                      goto pep_error;
   3.378                  
   3.379 -                int msg_major_version = pEpmessage_major_version(src);
   3.380 -                
   3.381 -                if (msg_major_version > 1) {
   3.382 -                    status = mime_decode_message(msg->attachments->value, 
   3.383 -                                                 msg->attachments->size,
   3.384 -                                                 &inner_message);
   3.385 -                    if (status != PEP_STATUS_OK)
   3.386 -                        goto pep_error;
   3.387 -                    
   3.388 -                    int inner_message_version = pEpmessage_major_version(inner_message);
   3.389 -                    
   3.390 -                    /* recurse one level if need be */
   3.391 -                    if (inner_message_version < 2) {
   3.392 -                        status = _decrypt_message(session, inner_message,
   3.393 -                                                  dst, keylist, rating, 
   3.394 -                                                  flags, private_il);
   3.395 -                        
   3.396 -                        free_message(inner_message);
   3.397 -                        return status;
   3.398 -                    }
   3.399 -                    /* 
   3.400 -                       otherwise, we're just going to verify the outer
   3.401 -                       message's keylist etc, and then pull up at the end.
   3.402 -                    */
   3.403 -                }
   3.404 -                                    
   3.405                  char* mlong = msg->longmsg;
   3.406                  char* mform = msg->longmsg_formatted;
   3.407 +                bloblist_t* matt = msg->attachments;
   3.408                  
   3.409 -                /* Note: we don't do this for Version 2.0+ inner messages, as we want to
   3.410 -                   return the whole message, not just the attachment, in that case.
   3.411 -                   (N.B. Version 2.0+ inner messages are themselves compound messages,
   3.412 -                   and the inner message is probably one that needs to be routed
   3.413 -                   elsewhere by the transport) 
   3.414 -                */
   3.415 -                if (!inner_message && (!mlong || mlong[0] == '\0') && (!mform || mform[0] == '\0')) {             
   3.416 -                    pull_up_longmsg_attachment(msg);
   3.417 -                    
   3.418 +                if ((!mlong || mlong[0] == '\0')
   3.419 +                     && (!mform || mform[0] == '\0')) {
   3.420 +                    if (matt) {
   3.421 +                        const char* inner_mime_type = matt->mime_type;
   3.422 +                        if (strcasecmp(inner_mime_type, "text/plain") == 0) {
   3.423 +                            free(mlong); /* in case of "" */
   3.424 +                            msg->longmsg = strndup(matt->value, matt->size);
   3.425 +                            
   3.426 +                            bloblist_t* next_node = matt->next;
   3.427 +                            if (next_node) {
   3.428 +                                inner_mime_type = next_node->mime_type;
   3.429 +                                if (strcasecmp(inner_mime_type, "text/html") == 0) {
   3.430 +                                    free(mform);
   3.431 +                                    msg->longmsg_formatted = strndup(next_node->value, next_node->size);
   3.432 +                                }
   3.433 +                            }
   3.434 +                        }
   3.435 +                        else if (strcasecmp(inner_mime_type, "text/html") == 0) {
   3.436 +                            free(mform);
   3.437 +                            msg->longmsg_formatted = strndup(matt->value, matt->size);
   3.438 +                        }
   3.439 +                    }
   3.440                      if (msg->shortmsg) {
   3.441                          free(src->shortmsg);
   3.442                          src->shortmsg = strdup(msg->shortmsg);
   3.443 @@ -2183,45 +1969,43 @@
   3.444                  {
   3.445                      GOTO(pep_error);
   3.446                  }
   3.447 -                
   3.448 -                if (!inner_message) {
   3.449 -                    if (src->shortmsg == NULL || strcmp(src->shortmsg, "pEp") == 0)
   3.450 -                    {
   3.451 -                        char * shortmsg;
   3.452 -                        char * longmsg;
   3.453 -
   3.454 -                        int r = separate_short_and_long(msg->longmsg, &shortmsg,
   3.455 -                                &longmsg);
   3.456 -                        
   3.457 -                        if (r == -1)
   3.458 -                            goto enomem;
   3.459 -
   3.460 -                        if (shortmsg == NULL) {
   3.461 -                            if (src->shortmsg == NULL)
   3.462 -                                shortmsg = strdup("");
   3.463 -                            else {
   3.464 -                                // FIXME: is msg->shortmsg always a copy of
   3.465 -                                // src->shortmsg already?
   3.466 -                                // if so, we need to change the logic so
   3.467 -                                // that in this case, we don't free msg->shortmsg
   3.468 -                                // and do this strdup, etc.
   3.469 -                                shortmsg = strdup(src->shortmsg);
   3.470 -                            }
   3.471 +
   3.472 +                if (src->shortmsg == NULL || strcmp(src->shortmsg, "pEp") == 0)
   3.473 +                {
   3.474 +                    char * shortmsg;
   3.475 +                    char * longmsg;
   3.476 +
   3.477 +                    int r = separate_short_and_long(msg->longmsg, &shortmsg,
   3.478 +                            &longmsg);
   3.479 +                    
   3.480 +                    if (r == -1)
   3.481 +                        goto enomem;
   3.482 +
   3.483 +                    if (shortmsg == NULL) {
   3.484 +                        if (src->shortmsg == NULL)
   3.485 +                            shortmsg = strdup("");
   3.486 +                        else {
   3.487 +                            // FIXME: is msg->shortmsg always a copy of
   3.488 +                            // src->shortmsg already?
   3.489 +                            // if so, we need to change the logic so
   3.490 +                            // that in this case, we don't free msg->shortmsg
   3.491 +                            // and do this strdup, etc.
   3.492 +                            shortmsg = strdup(src->shortmsg);
   3.493                          }
   3.494 -
   3.495 -
   3.496 -                        free(msg->shortmsg);
   3.497 -                        free(msg->longmsg);
   3.498 -
   3.499 -                        msg->shortmsg = shortmsg;
   3.500 -                        msg->longmsg = longmsg;
   3.501                      }
   3.502 -                    else {
   3.503 -                        msg->shortmsg = strdup(src->shortmsg);
   3.504 -                        assert(msg->shortmsg);
   3.505 -                        if (msg->shortmsg == NULL)
   3.506 -                            goto enomem;
   3.507 -                    }
   3.508 +
   3.509 +
   3.510 +                    free(msg->shortmsg);
   3.511 +                    free(msg->longmsg);
   3.512 +
   3.513 +                    msg->shortmsg = shortmsg;
   3.514 +                    msg->longmsg = longmsg;
   3.515 +                }
   3.516 +                else {
   3.517 +                    msg->shortmsg = strdup(src->shortmsg);
   3.518 +                    assert(msg->shortmsg);
   3.519 +                    if (msg->shortmsg == NULL)
   3.520 +                        goto enomem;
   3.521                  }
   3.522                  break;
   3.523              default:
   3.524 @@ -2309,10 +2093,6 @@
   3.525          *flags |= PEP_decrypt_flag_own_private_key;
   3.526      }
   3.527  
   3.528 -    // FIXME: To here, we're ok with the separate messages. We need to
   3.529 -    //        specify what clients expect when this is a 2.0 message.
   3.530 -    //        IMHO, we don't need the keylist at that point, just 
   3.531 -    //        the rating and move on.
   3.532      if (msg) {
   3.533          decorate_message(msg, *rating, _keylist);
   3.534          if (imported_keys)
   3.535 @@ -2343,12 +2123,7 @@
   3.536          }
   3.537      }
   3.538  
   3.539 -    if (inner_message)
   3.540 -        *dst = inner_message;
   3.541 -    else
   3.542 -        *dst = msg;
   3.543 -        
   3.544 -    // I think we keep it this way for 2.0 inner messages.
   3.545 +    *dst = msg;
   3.546      *keylist = _keylist;
   3.547  
   3.548      if(decrypt_status == PEP_DECRYPTED_AND_VERIFIED)
   3.549 @@ -2361,8 +2136,6 @@
   3.550  
   3.551  pep_error:
   3.552      free(ptext);
   3.553 -    if (inner_message) // necessary? FIXME: check
   3.554 -        free_message(inner_message);
   3.555      free_message(msg);
   3.556      free_stringlist(_keylist);
   3.557  
     4.1 --- a/src/message_api.h	Tue Sep 05 18:46:05 2017 +0200
     4.2 +++ b/src/message_api.h	Wed Sep 06 02:23:15 2017 +0200
     4.3 @@ -33,11 +33,7 @@
     4.4      // This flag is for special use cases and should not be used
     4.5      // by normal pEp clients!
     4.6      PEP_encrypt_flag_force_unsigned = 0x2,
     4.7 -    PEP_encrypt_flag_force_no_attached_key = 0x4,
     4.8 -    
     4.9 -    // This flag is for when we start wrapping messages in multiple different 
    4.10 -    // sender layers
    4.11 -    PEP_encrypt_flag_dont_raise_headers = 0x8
    4.12 +    PEP_encrypt_flag_force_no_attached_key = 0x4
    4.13  } PEP_encrypt_flags; 
    4.14  
    4.15  typedef unsigned int PEP_encrypt_flags_t;
     5.1 --- a/src/mime.c	Tue Sep 05 18:46:05 2017 +0200
     5.2 +++ b/src/mime.c	Wed Sep 06 02:23:15 2017 +0200
     5.3 @@ -143,7 +143,7 @@
     5.4  static PEP_STATUS mime_html_text(
     5.5          const char *plaintext,
     5.6          const char *htmltext,
     5.7 -        bloblist_t *inlined_attachments,
     5.8 +        bloblist_t *attachments,
     5.9          struct mailmime **result
    5.10      )
    5.11  {
    5.12 @@ -185,6 +185,17 @@
    5.13          submime = NULL;
    5.14      }
    5.15  
    5.16 +    bool inlined_attachments = false;
    5.17 +    
    5.18 +    bloblist_t* traversal_ptr = attachments;
    5.19 +    
    5.20 +    while (traversal_ptr) {
    5.21 +        if (traversal_ptr->disposition == PEP_CONTENT_DISP_INLINE) {
    5.22 +            inlined_attachments = true;
    5.23 +            break;
    5.24 +        }
    5.25 +        traversal_ptr = traversal_ptr->next;
    5.26 +    }
    5.27  
    5.28      if (inlined_attachments) {
    5.29          /* Noooooo... dirk, why do you do this to me? */
    5.30 @@ -229,8 +240,9 @@
    5.31      }
    5.32  
    5.33      bloblist_t *_a;
    5.34 -    for (_a = inlined_attachments; _a != NULL; _a = _a->next) {
    5.35 -
    5.36 +    for (_a = attachments; _a != NULL; _a = _a->next) {
    5.37 +        if (_a->disposition != PEP_CONTENT_DISP_INLINE)
    5.38 +            continue;
    5.39          status = mime_attachment(_a, &submime);
    5.40          if (status != PEP_STATUS_OK)
    5.41              return PEP_UNKNOWN_ERROR; // FIXME
    5.42 @@ -650,33 +662,33 @@
    5.43      return retval;
    5.44  }
    5.45  
    5.46 -static void split_inlined_and_attached(bloblist_t** inlined, bloblist_t** attached) {
    5.47 -    bloblist_t** curr_pp = attached;
    5.48 -    bloblist_t* curr = *curr_pp;
    5.49 -    
    5.50 -    bloblist_t* inline_ret = NULL;
    5.51 -    bloblist_t** inline_curr_pp = &inline_ret;
    5.52 -    
    5.53 -    bloblist_t* att_ret = NULL;
    5.54 -    bloblist_t** att_curr_pp = &att_ret;
    5.55 -    
    5.56 -    while (curr) {
    5.57 -        if (curr->disposition == PEP_CONTENT_DISP_INLINE) {
    5.58 -            *inline_curr_pp = curr;
    5.59 -            inline_curr_pp = &(curr->next);
    5.60 -        }
    5.61 -        else {
    5.62 -            *att_curr_pp = curr;
    5.63 -            att_curr_pp = &(curr->next);            
    5.64 -        }
    5.65 -        *curr_pp = curr->next;
    5.66 -        curr->next = NULL;
    5.67 -        curr = *curr_pp;
    5.68 -    }
    5.69 -    
    5.70 -    *inlined = inline_ret;
    5.71 -    *attached = att_ret;
    5.72 -}
    5.73 +// static void split_inlined_and_attached(bloblist_t** inlined, bloblist_t** attached) {
    5.74 +//     bloblist_t** curr_pp = attached;
    5.75 +//     bloblist_t* curr = *curr_pp;
    5.76 +//     
    5.77 +//     bloblist_t* inline_ret = NULL;
    5.78 +//     bloblist_t** inline_curr_pp = &inline_ret;
    5.79 +//     
    5.80 +//     bloblist_t* att_ret = NULL;
    5.81 +//     bloblist_t** att_curr_pp = &att_ret;
    5.82 +//     
    5.83 +//     while (curr) {
    5.84 +//         if (curr->disposition == PEP_CONTENT_DISP_INLINE) {
    5.85 +//             *inline_curr_pp = curr;
    5.86 +//             inline_curr_pp = &(curr->next);
    5.87 +//         }
    5.88 +//         else {
    5.89 +//             *att_curr_pp = curr;
    5.90 +//             att_curr_pp = &(curr->next);            
    5.91 +//         }
    5.92 +//         *curr_pp = curr->next;
    5.93 +//         curr->next = NULL;
    5.94 +//         curr = *curr_pp;
    5.95 +//     }
    5.96 +//     
    5.97 +//     *inlined = inline_ret;
    5.98 +//     *attached = att_ret;
    5.99 +// }
   5.100  
   5.101  
   5.102  static PEP_STATUS mime_encode_message_plain(
   5.103 @@ -695,14 +707,7 @@
   5.104  
   5.105      assert(msg);
   5.106      assert(result);
   5.107 -
   5.108 -    message* duped_msg = message_dup(msg);
   5.109 -
   5.110 -    if (!duped_msg) {
   5.111 -        status = PEP_OUT_OF_MEMORY;
   5.112 -        goto pep_error;
   5.113 -    }
   5.114 -
   5.115 +    
   5.116      //subject = (msg->shortmsg) ? msg->shortmsg : "pEp";  // not used, yet.
   5.117      plaintext = (msg->longmsg) ? msg->longmsg : "";
   5.118      htmltext = msg->longmsg_formatted;
   5.119 @@ -710,13 +715,8 @@
   5.120      if (htmltext && (htmltext[0] != '\0')) {
   5.121          /* first, we need to strip out the inlined attachments to ensure this
   5.122             gets set up correctly */
   5.123 -        
   5.124 -        bloblist_t* inlined_attachments = NULL;
   5.125 -        /* Noooooo... dirk, why do you do this to me? */
   5.126 -                
   5.127 -        split_inlined_and_attached(&inlined_attachments, &duped_msg->attachments);
   5.128 -
   5.129 -        status = mime_html_text(plaintext, htmltext, inlined_attachments, &mime);
   5.130 +           
   5.131 +        status = mime_html_text(plaintext, htmltext, msg->attachments, &mime);
   5.132                  
   5.133          if (status != PEP_STATUS_OK)
   5.134              goto pep_error;
   5.135 @@ -740,7 +740,19 @@
   5.136              goto enomem;
   5.137      }
   5.138  
   5.139 -    if (duped_msg->attachments) {
   5.140 +    bool normal_attachments = false;
   5.141 +    
   5.142 +    bloblist_t* traversal_ptr = msg->attachments;
   5.143 +    
   5.144 +    while (traversal_ptr) {
   5.145 +        if (traversal_ptr->disposition != PEP_CONTENT_DISP_INLINE) {
   5.146 +            normal_attachments = true;
   5.147 +            break;
   5.148 +        }
   5.149 +        traversal_ptr = traversal_ptr->next;
   5.150 +    }
   5.151 +
   5.152 +    if (normal_attachments) {
   5.153          submime = mime;
   5.154          mime = part_multiple_new("multipart/mixed");
   5.155          assert(mime);
   5.156 @@ -758,7 +770,10 @@
   5.157          }
   5.158  
   5.159          bloblist_t *_a;
   5.160 -        for (_a = duped_msg->attachments; _a != NULL; _a = _a->next) {
   5.161 +        for (_a = msg->attachments; _a != NULL; _a = _a->next) {
   5.162 +
   5.163 +            if (_a->disposition == PEP_CONTENT_DISP_INLINE)
   5.164 +                continue;
   5.165  
   5.166              status = mime_attachment(_a, &submime);
   5.167              if (status != PEP_STATUS_OK)
   5.168 @@ -776,10 +791,6 @@
   5.169          }
   5.170      }
   5.171  
   5.172 -
   5.173 -
   5.174 -    if (duped_msg)
   5.175 -        free_message(duped_msg);
   5.176      *result = mime;
   5.177      return PEP_STATUS_OK;
   5.178  
   5.179 @@ -793,9 +804,6 @@
   5.180      if (submime)
   5.181          mailmime_free(submime);
   5.182  
   5.183 -    if (duped_msg)
   5.184 -        free_message(duped_msg);
   5.185 -
   5.186      return status;
   5.187  }
   5.188  
     6.1 --- a/test/revoke_regen_attach_test.cc	Tue Sep 05 18:46:05 2017 +0200
     6.2 +++ b/test/revoke_regen_attach_test.cc	Wed Sep 06 02:23:15 2017 +0200
     6.3 @@ -60,8 +60,7 @@
     6.4      cout << "encrypting message as MIME multipart…\n";
     6.5      message *enc_msg;
     6.6      cout << "calling encrypt_message()\n";
     6.7 -    // We need to keep this as a message 1.0 msg in order to see the attachments
     6.8 -    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, PEP_encrypt_flag_dont_raise_headers);
     6.9 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
    6.10      cout << status;
    6.11      assert(status == PEP_STATUS_OK);
    6.12      assert(enc_msg);