Merge in default ENGINE-237
authorDamiano Boppart <damiano@pep-security.net>
Wed, 30 Aug 2017 15:44:21 +0200
branchENGINE-237
changeset 2023ba30fa883329
parent 2019 6c2b325f2056
parent 2022 b2779c4e69f1
child 2024 1b1051f096cc
child 2726 497fe9a22367
Merge in default
     1.1 --- a/src/bloblist.c	Tue Aug 29 16:40:43 2017 +0200
     1.2 +++ b/src/bloblist.c	Wed Aug 30 15:44:21 2017 +0200
     1.3 @@ -9,6 +9,40 @@
     1.4  
     1.5  #include "bloblist.h"
     1.6  
     1.7 +static bool set_blob_data(bloblist_t* bloblist, char* blob, size_t size, const char* mime_type,
     1.8 +                          const char* filename) {
     1.9 +    
    1.10 +    if (!bloblist)
    1.11 +        return false;
    1.12 +        
    1.13 +    if (mime_type) {
    1.14 +       bloblist->mime_type = strdup(mime_type);
    1.15 +       if (bloblist->mime_type == NULL) {
    1.16 +           return false;
    1.17 +       }
    1.18 +    }
    1.19 +    
    1.20 +    if (filename) {
    1.21 +       bloblist->filename = strdup(filename);
    1.22 +       if (bloblist->filename == NULL) {
    1.23 +           free(bloblist->mime_type);
    1.24 +           return false;
    1.25 +       }
    1.26 +       /* Default behaviour, can be overwritten post-allocation with
    1.27 +          set_blob_content_disposition */
    1.28 +       if (strstr(filename, "cid://") == filename)
    1.29 +           bloblist->disposition = PEP_CONTENT_DISP_INLINE;
    1.30 +                        
    1.31 +    }               
    1.32 +    
    1.33 +    if (blob) {
    1.34 +        bloblist->value = blob;
    1.35 +        bloblist->size = size;
    1.36 +    }
    1.37 +    
    1.38 +    return true;
    1.39 +}
    1.40 +
    1.41  DYNAMIC_API bloblist_t *new_bloblist(char *blob, size_t size, const char *mime_type,
    1.42          const char *filename)
    1.43  {
    1.44 @@ -17,26 +51,9 @@
    1.45      if (bloblist == NULL)
    1.46          return NULL;
    1.47  
    1.48 -    if (mime_type) {
    1.49 -        bloblist->mime_type = strdup(mime_type);
    1.50 -        if (bloblist->mime_type == NULL) {
    1.51 -            free(bloblist);
    1.52 -            return NULL;
    1.53 -        }
    1.54 -    }
    1.55 -
    1.56 -    if (filename) {
    1.57 -        bloblist->filename = strdup(filename);
    1.58 -        if (bloblist->filename == NULL) {
    1.59 -            free(bloblist->mime_type);
    1.60 -            free(bloblist);
    1.61 -            return NULL;
    1.62 -        }
    1.63 -    }
    1.64 -
    1.65 -    if (blob) {
    1.66 -        bloblist->value = blob;
    1.67 -        bloblist->size = size;
    1.68 +    if (!set_blob_data(bloblist, blob, size, mime_type, filename)) {
    1.69 +        free(bloblist);
    1.70 +        bloblist = NULL;
    1.71      }
    1.72  
    1.73      return bloblist;
    1.74 @@ -118,25 +135,11 @@
    1.75      if (bloblist->value == NULL) { // empty list
    1.76          if (bloblist->next != NULL)
    1.77              return NULL; // invalid list
    1.78 -
    1.79 -        if (mime_type) {
    1.80 -            bloblist->mime_type = strdup(mime_type);
    1.81 -            if (bloblist->mime_type == NULL) {
    1.82 -                free(bloblist);
    1.83 -                return NULL;
    1.84 -            }
    1.85 +            
    1.86 +        if (!set_blob_data(bloblist, blob, size, mime_type, filename)) {
    1.87 +            free(bloblist);
    1.88 +            bloblist = NULL;
    1.89          }
    1.90 -        if (filename) {
    1.91 -            bloblist->filename = strdup(filename);
    1.92 -            if (bloblist->filename == NULL) {
    1.93 -                free(bloblist->mime_type);
    1.94 -                free(bloblist);
    1.95 -                return NULL;
    1.96 -            }
    1.97 -        }
    1.98 -
    1.99 -        bloblist->value = blob;
   1.100 -        bloblist->size = size;
   1.101  
   1.102          return bloblist;
   1.103      }
   1.104 @@ -165,3 +168,9 @@
   1.105  
   1.106      return len;
   1.107  }
   1.108 +
   1.109 +DYNAMIC_API void set_blob_disposition(bloblist_t* blob, 
   1.110 +                                      content_disposition_type disposition) {
   1.111 +    if (blob)                                    
   1.112 +        blob->disposition = disposition;
   1.113 +}
     2.1 --- a/src/bloblist.h	Tue Aug 29 16:40:43 2017 +0200
     2.2 +++ b/src/bloblist.h	Wed Aug 30 15:44:21 2017 +0200
     2.3 @@ -4,11 +4,17 @@
     2.4  #pragma once
     2.5  
     2.6  #include "dynamic_api.h"
     2.7 +#include "stringpair.h"
     2.8  
     2.9  #ifdef __cplusplus
    2.10  extern "C" {
    2.11  #endif
    2.12  
    2.13 +typedef enum {
    2.14 +    PEP_CONTENT_DISP_ATTACHMENT = 0,
    2.15 +    PEP_CONTENT_DISP_INLINE = 1,
    2.16 +    PEP_CONTENT_DISP_OTHER = -1      // must be affirmatively set
    2.17 +} content_disposition_type;
    2.18  
    2.19  typedef struct _bloblist_t {
    2.20      char *value;                    // blob
    2.21 @@ -17,6 +23,8 @@
    2.22                                      // NULL if unknown
    2.23      char *filename;                // UTF-8 string of file name of blob or
    2.24                                      // NULL if unknown
    2.25 +    content_disposition_type disposition; // default is attachment when allocated
    2.26 +                                          // (see mime.h and RFC2183)
    2.27      struct _bloblist_t *next;
    2.28  } bloblist_t;
    2.29  
    2.30 @@ -94,7 +102,19 @@
    2.31  
    2.32  DYNAMIC_API int bloblist_length(const bloblist_t *bloblist);
    2.33  
    2.34 +// set_blob_content_disposition() - set blob content disposition and parameters
    2.35 +//                                  when necessary
    2.36 +//
    2.37 +//  parameters:
    2.38 +//      blob (in)               bloblist struct to change disposition for
    2.39 +//      disposition (in)        disposition type (see enum)
    2.40 +
    2.41 +DYNAMIC_API void set_blob_disposition(bloblist_t* blob, 
    2.42 +                                              content_disposition_type disposition);
    2.43 +
    2.44 +
    2.45 +
    2.46 +
    2.47  #ifdef __cplusplus
    2.48  }
    2.49  #endif
    2.50 -
     3.1 --- a/src/etpan_mime.c	Tue Aug 29 16:40:43 2017 +0200
     3.2 +++ b/src/etpan_mime.c	Wed Aug 30 15:44:21 2017 +0200
     3.3 @@ -301,6 +301,11 @@
     3.4          switch (resource->rid_type) {
     3.5              case PEP_RID_CID:
     3.6                  content_id = strdup(resource->rid);
     3.7 +                disposition =
     3.8 +                    mailmime_disposition_new_with_data(MAILMIME_DISPOSITION_TYPE_INLINE,
     3.9 +                                                       NULL, NULL, NULL, NULL, (size_t) -1);
    3.10 +                    if (disposition == NULL)
    3.11 +                        goto enomem;
    3.12                  break;
    3.13              case PEP_RID_FILENAME:
    3.14              default:
     4.1 --- a/src/mime.c	Tue Aug 29 16:40:43 2017 +0200
     4.2 +++ b/src/mime.c	Wed Aug 30 15:44:21 2017 +0200
     4.3 @@ -97,82 +97,6 @@
     4.4      return status;
     4.5  }
     4.6  
     4.7 -static PEP_STATUS mime_html_text(
     4.8 -        const char *plaintext,
     4.9 -        const char *htmltext,
    4.10 -        struct mailmime **result
    4.11 -    )
    4.12 -{
    4.13 -    PEP_STATUS status = PEP_STATUS_OK;
    4.14 -    struct mailmime * mime = NULL;
    4.15 -    struct mailmime * submime = NULL;
    4.16 -    int r;
    4.17 -
    4.18 -    assert(plaintext);
    4.19 -    assert(htmltext);
    4.20 -    assert(result);
    4.21 -
    4.22 -    *result = NULL;
    4.23 -
    4.24 -    mime = part_multiple_new("multipart/alternative");
    4.25 -    assert(mime);
    4.26 -    if (mime == NULL)
    4.27 -        goto enomem;
    4.28 -
    4.29 -    pEp_rid_list_t* resource = new_rid_node(PEP_RID_FILENAME, "msg.txt");
    4.30 -    
    4.31 -    submime = get_text_part(resource, "text/plain", plaintext, strlen(plaintext),
    4.32 -            MAILMIME_MECHANISM_QUOTED_PRINTABLE);
    4.33 -    free_rid_list(resource);
    4.34 -    resource = NULL;
    4.35 -    
    4.36 -    assert(submime);
    4.37 -    if (submime == NULL)
    4.38 -        goto enomem;
    4.39 -
    4.40 -    r = mailmime_smart_add_part(mime, submime);
    4.41 -    assert(r == MAILIMF_NO_ERROR);
    4.42 -    if (r == MAILIMF_ERROR_MEMORY) {
    4.43 -        goto enomem;
    4.44 -    }
    4.45 -    else {
    4.46 -        // mailmime_smart_add_part() takes ownership of submime
    4.47 -        submime = NULL;
    4.48 -    }
    4.49 -
    4.50 -    resource = new_rid_node(PEP_RID_FILENAME, "msg.html");
    4.51 -    submime = get_text_part(resource, "text/html", htmltext, strlen(htmltext),
    4.52 -            MAILMIME_MECHANISM_QUOTED_PRINTABLE);
    4.53 -    free_rid_list(resource);
    4.54 -    resource = NULL;
    4.55 -    
    4.56 -    assert(submime);
    4.57 -    if (submime == NULL)
    4.58 -        goto enomem;
    4.59 -
    4.60 -    r = mailmime_smart_add_part(mime, submime);
    4.61 -    assert(r == MAILIMF_NO_ERROR);
    4.62 -    if (r == MAILIMF_ERROR_MEMORY)
    4.63 -        goto enomem;
    4.64 -    else {
    4.65 -        // mailmime_smart_add_part() takes ownership of submime
    4.66 -        submime = NULL;
    4.67 -    }
    4.68 -
    4.69 -    *result = mime;
    4.70 -    return PEP_STATUS_OK;
    4.71 -
    4.72 -enomem:
    4.73 -    status = PEP_OUT_OF_MEMORY;
    4.74 -
    4.75 -    if (mime)
    4.76 -        mailmime_free(mime);
    4.77 -
    4.78 -    if (submime)
    4.79 -        mailmime_free(submime);
    4.80 -
    4.81 -    return status;
    4.82 -}
    4.83  
    4.84  static PEP_STATUS mime_attachment(
    4.85          bloblist_t *blob,
    4.86 @@ -216,6 +140,127 @@
    4.87      return status;
    4.88  }
    4.89  
    4.90 +static PEP_STATUS mime_html_text(
    4.91 +        const char *plaintext,
    4.92 +        const char *htmltext,
    4.93 +        bloblist_t *inlined_attachments,
    4.94 +        struct mailmime **result
    4.95 +    )
    4.96 +{
    4.97 +    PEP_STATUS status = PEP_STATUS_OK;
    4.98 +    struct mailmime * top_level_html_mime = NULL;
    4.99 +    struct mailmime * mime = NULL;
   4.100 +    struct mailmime * submime = NULL;
   4.101 +    int r;
   4.102 +
   4.103 +    assert(plaintext);
   4.104 +    assert(htmltext);
   4.105 +    assert(result);
   4.106 +
   4.107 +    *result = NULL;
   4.108 +
   4.109 +    mime = part_multiple_new("multipart/alternative");
   4.110 +    assert(mime);
   4.111 +    if (mime == NULL)
   4.112 +        goto enomem;
   4.113 +
   4.114 +    pEp_rid_list_t* resource = new_rid_node(PEP_RID_FILENAME, "msg.txt");
   4.115 +    
   4.116 +    submime = get_text_part(NULL, "text/plain", plaintext, strlen(plaintext),
   4.117 +            MAILMIME_MECHANISM_QUOTED_PRINTABLE);
   4.118 +    free_rid_list(resource);
   4.119 +    resource = NULL;
   4.120 +    
   4.121 +    assert(submime);
   4.122 +    if (submime == NULL)
   4.123 +        goto enomem;
   4.124 +
   4.125 +    r = mailmime_smart_add_part(mime, submime);
   4.126 +    assert(r == MAILIMF_NO_ERROR);
   4.127 +    if (r == MAILIMF_ERROR_MEMORY) {
   4.128 +        goto enomem;
   4.129 +    }
   4.130 +    else {
   4.131 +        // mailmime_smart_add_part() takes ownership of submime
   4.132 +        submime = NULL;
   4.133 +    }
   4.134 +
   4.135 +
   4.136 +    if (inlined_attachments) {
   4.137 +        /* Noooooo... dirk, why do you do this to me? */
   4.138 +        submime = part_multiple_new("multipart/related");
   4.139 +        assert(submime);
   4.140 +        if (submime == NULL)
   4.141 +            goto enomem;
   4.142 +
   4.143 +        top_level_html_mime = submime;
   4.144 +        
   4.145 +        r = mailmime_smart_add_part(mime, top_level_html_mime);
   4.146 +        assert(r == MAILIMF_NO_ERROR);
   4.147 +        if (r == MAILIMF_ERROR_MEMORY) {
   4.148 +            goto enomem;
   4.149 +        }
   4.150 +        else {
   4.151 +            // mailmime_smart_add_part() takes ownership of submime
   4.152 +            submime = NULL;
   4.153 +        }
   4.154 +    }
   4.155 +    else {
   4.156 +        top_level_html_mime = mime;
   4.157 +    }
   4.158 +
   4.159 +//    resource = new_rid_node(PEP_RID_FILENAME, "msg.html");
   4.160 +    submime = get_text_part(NULL, "text/html", htmltext, strlen(htmltext),
   4.161 +            MAILMIME_MECHANISM_QUOTED_PRINTABLE);
   4.162 +    free_rid_list(resource);
   4.163 +    resource = NULL;
   4.164 +    
   4.165 +    assert(submime);
   4.166 +    if (submime == NULL)
   4.167 +        goto enomem;
   4.168 +
   4.169 +    r = mailmime_smart_add_part(top_level_html_mime, submime);
   4.170 +    assert(r == MAILIMF_NO_ERROR);
   4.171 +    if (r == MAILIMF_ERROR_MEMORY)
   4.172 +        goto enomem;
   4.173 +    else {
   4.174 +        // mailmime_smart_add_part() takes ownership of submime
   4.175 +        submime = NULL;
   4.176 +    }
   4.177 +
   4.178 +    bloblist_t *_a;
   4.179 +    for (_a = inlined_attachments; _a != NULL; _a = _a->next) {
   4.180 +
   4.181 +        status = mime_attachment(_a, &submime);
   4.182 +        if (status != PEP_STATUS_OK)
   4.183 +            return PEP_UNKNOWN_ERROR; // FIXME
   4.184 +
   4.185 +        r = mailmime_smart_add_part(top_level_html_mime, submime);
   4.186 +        assert(r == MAILIMF_NO_ERROR);
   4.187 +        if (r == MAILIMF_ERROR_MEMORY) {
   4.188 +            goto enomem;
   4.189 +        }
   4.190 +        else {
   4.191 +            // mailmime_smart_add_part() takes ownership of submime
   4.192 +            submime = NULL;
   4.193 +        }
   4.194 +    }
   4.195 +
   4.196 +    *result = mime;
   4.197 +    return PEP_STATUS_OK;
   4.198 +
   4.199 +enomem:
   4.200 +    status = PEP_OUT_OF_MEMORY;
   4.201 +
   4.202 +    if (mime)
   4.203 +        mailmime_free(mime);
   4.204 +
   4.205 +    if (submime)
   4.206 +        mailmime_free(submime);
   4.207 +
   4.208 +    return status;
   4.209 +}
   4.210 +
   4.211  static struct mailimf_mailbox * identity_to_mailbox(const pEp_identity *ident)
   4.212  {
   4.213      char *_username = NULL;
   4.214 @@ -605,6 +650,35 @@
   4.215      return retval;
   4.216  }
   4.217  
   4.218 +static void split_inlined_and_attached(bloblist_t** inlined, bloblist_t** attached) {
   4.219 +    bloblist_t** curr_pp = attached;
   4.220 +    bloblist_t* curr = *curr_pp;
   4.221 +    
   4.222 +    bloblist_t* inline_ret = NULL;
   4.223 +    bloblist_t** inline_curr_pp = &inline_ret;
   4.224 +    
   4.225 +    bloblist_t* att_ret = NULL;
   4.226 +    bloblist_t** att_curr_pp = &att_ret;
   4.227 +    
   4.228 +    while (curr) {
   4.229 +        if (curr->disposition == PEP_CONTENT_DISP_INLINE) {
   4.230 +            *inline_curr_pp = curr;
   4.231 +            inline_curr_pp = &(curr->next);
   4.232 +        }
   4.233 +        else {
   4.234 +            *att_curr_pp = curr;
   4.235 +            att_curr_pp = &(curr->next);            
   4.236 +        }
   4.237 +        *curr_pp = curr->next;
   4.238 +        curr->next = NULL;
   4.239 +        curr = *curr_pp;
   4.240 +    }
   4.241 +    
   4.242 +    *inlined = inline_ret;
   4.243 +    *attached = att_ret;
   4.244 +}
   4.245 +
   4.246 +
   4.247  static PEP_STATUS mime_encode_message_plain(
   4.248          const message *msg,
   4.249          bool omit_fields,
   4.250 @@ -627,7 +701,15 @@
   4.251      htmltext = msg->longmsg_formatted;
   4.252  
   4.253      if (htmltext && (htmltext[0] != '\0')) {
   4.254 -        status = mime_html_text(plaintext, htmltext, &mime);
   4.255 +        /* first, we need to strip out the inlined attachments to ensure this
   4.256 +           gets set up correctly */
   4.257 +        
   4.258 +        bloblist_t* inlined_attachments = NULL;
   4.259 +        /* Noooooo... dirk, why do you do this to me? */
   4.260 +        split_inlined_and_attached(&inlined_attachments, &msg->attachments);
   4.261 +
   4.262 +        
   4.263 +        status = mime_html_text(plaintext, htmltext, inlined_attachments, &mime);
   4.264          if (status != PEP_STATUS_OK)
   4.265              goto pep_error;
   4.266      }
     5.1 --- a/src/mime.h	Tue Aug 29 16:40:43 2017 +0200
     5.2 +++ b/src/mime.h	Wed Aug 30 15:44:21 2017 +0200
     5.3 @@ -9,7 +9,6 @@
     5.4  extern "C" {
     5.5  #endif
     5.6  
     5.7 -
     5.8  // is_PGP_message_text() - determine if text encodes a PGP message
     5.9  //
    5.10  //  parameters:
    5.11 @@ -78,4 +77,3 @@
    5.12  #ifdef __cplusplus
    5.13  }
    5.14  #endif
    5.15 -