merged in ENGINE-275 (second attempt with message 2.0)
authorKrista Bennett <krista@pep-project.org>
Fri, 13 Oct 2017 13:27:59 +0200
changeset 21605f5fe1d047ee
parent 2154 326bdd83df88
parent 2159 b417e92107ab
child 2161 c75b7cfd561c
merged in ENGINE-275 (second attempt with message 2.0)
     1.1 --- a/src/message_api.c	Wed Oct 11 15:46:04 2017 +0200
     1.2 +++ b/src/message_api.c	Fri Oct 13 13:27:59 2017 +0200
     1.3 @@ -20,6 +20,158 @@
     1.4  #define _MAX(A, B) ((B) > (A) ? (B) : (A))
     1.5  #endif
     1.6  
     1.7 +// static const char* search_opt_fields(message* src, char* key) {
     1.8 +//     assert(src);
     1.9 +//     assert(key);
    1.10 +//     if (src && key) {
    1.11 +//         stringpair_list_t opt_fields = src->opt_fields;
    1.12 +//         while (opt_fields) {
    1.13 +//             char* currkey = opt_fields->value->key;
    1.14 +//             if (strcmp(currkey, key) == 0) {
    1.15 +//                 return opt_fields->value->value;
    1.16 +//             }
    1.17 +//             opt_fields = opt_fields->next;
    1.18 +//         }
    1.19 +//     }
    1.20 +//     return NULL;
    1.21 +// }
    1.22 +// 
    1.23 +// static const char* get_message_version_string(message* src) {
    1.24 +//     const char* version_key = "X-pEp-Version";
    1.25 +//     return(search_opt_fields(src, version_key));
    1.26 +// }
    1.27 +
    1.28 +
    1.29 +static char * keylist_to_string(const stringlist_t *keylist)
    1.30 +{
    1.31 +    if (keylist) {
    1.32 +        size_t size = stringlist_length(keylist);
    1.33 +
    1.34 +        const stringlist_t *_kl;
    1.35 +        for (_kl = keylist; _kl && _kl->value; _kl = _kl->next) {
    1.36 +            size += strlen(_kl->value);
    1.37 +        }
    1.38 +
    1.39 +        char *result = calloc(1, size);
    1.40 +        if (result == NULL)
    1.41 +            return NULL;
    1.42 +
    1.43 +        char *_r = result;
    1.44 +        for (_kl = keylist; _kl && _kl->value; _kl = _kl->next) {
    1.45 +            _r = stpcpy(_r, _kl->value);
    1.46 +            if (_kl->next && _kl->next->value)
    1.47 +                _r = stpcpy(_r, ",");
    1.48 +        }
    1.49 +
    1.50 +        return result;
    1.51 +    }
    1.52 +    else {
    1.53 +        return NULL;
    1.54 +    }
    1.55 +}
    1.56 +
    1.57 +static const char * rating_to_string(PEP_rating rating)
    1.58 +{
    1.59 +    switch (rating) {
    1.60 +    case PEP_rating_cannot_decrypt:
    1.61 +        return "cannot_decrypt";
    1.62 +    case PEP_rating_have_no_key:
    1.63 +        return "have_no_key";
    1.64 +    case PEP_rating_unencrypted:
    1.65 +        return "unencrypted";
    1.66 +    case PEP_rating_unencrypted_for_some:
    1.67 +        return "unencrypted_for_some";
    1.68 +    case PEP_rating_unreliable:
    1.69 +        return "unreliable";
    1.70 +    case PEP_rating_reliable:
    1.71 +        return "reliable";
    1.72 +    case PEP_rating_trusted:
    1.73 +        return "trusted";
    1.74 +    case PEP_rating_trusted_and_anonymized:
    1.75 +        return "trusted_and_anonymized";
    1.76 +    case PEP_rating_fully_anonymous:
    1.77 +        return "fully_anonymous";
    1.78 +    case PEP_rating_mistrust:
    1.79 +        return "mistrust";
    1.80 +    case PEP_rating_b0rken:
    1.81 +        return "b0rken";
    1.82 +    case PEP_rating_under_attack:
    1.83 +        return "under_attack";
    1.84 +    default:
    1.85 +        return "undefined";
    1.86 +    }
    1.87 +}
    1.88 +
    1.89 +void add_opt_field(message *msg, const char *name, const char *value)
    1.90 +{
    1.91 +    assert(msg && name && value);
    1.92 +
    1.93 +    if (msg && name && value) {
    1.94 +        stringpair_t *pair = new_stringpair(name, value);
    1.95 +        if (pair == NULL)
    1.96 +            return;
    1.97 +
    1.98 +        stringpair_list_t *field = stringpair_list_add(msg->opt_fields, pair);
    1.99 +        if (field == NULL)
   1.100 +        {
   1.101 +            free_stringpair(pair);
   1.102 +            return;
   1.103 +        }
   1.104 +
   1.105 +        if (msg->opt_fields == NULL)
   1.106 +            msg->opt_fields = field;
   1.107 +    }
   1.108 +}
   1.109 +
   1.110 +void replace_opt_field(message *msg, const char *name, const char *value)
   1.111 +{
   1.112 +    assert(msg && name && value);
   1.113 +    
   1.114 +    if (msg && name && value) {
   1.115 +        stringpair_list_t* opt_fields = msg->opt_fields;
   1.116 +        stringpair_t* pair = NULL;
   1.117 +        if (opt_fields) {
   1.118 +            while (opt_fields) {
   1.119 +                pair = opt_fields->value;
   1.120 +                if (pair && (strcmp(name, pair->key) == 0))
   1.121 +                    break;
   1.122 +                    
   1.123 +                pair = NULL;
   1.124 +                opt_fields = opt_fields->next;
   1.125 +            }
   1.126 +        }
   1.127 +        
   1.128 +        if (pair) {
   1.129 +            free(pair->value);
   1.130 +            pair->value = strdup(value);
   1.131 +        }
   1.132 +        else {
   1.133 +            add_opt_field(msg, name, value);
   1.134 +        }
   1.135 +    }
   1.136 +}
   1.137 +
   1.138 +
   1.139 +static void decorate_message(
   1.140 +    message *msg,
   1.141 +    PEP_rating rating,
   1.142 +    stringlist_t *keylist
   1.143 +    )
   1.144 +{
   1.145 +    assert(msg);
   1.146 +
   1.147 +    replace_opt_field(msg, "X-pEp-Version", PEP_VERSION);
   1.148 +
   1.149 +    if (rating != PEP_rating_undefined)
   1.150 +        replace_opt_field(msg, "X-EncStatus", rating_to_string(rating));
   1.151 +
   1.152 +    if (keylist) {
   1.153 +        char *_keylist = keylist_to_string(keylist);
   1.154 +        replace_opt_field(msg, "X-KeyList", _keylist);
   1.155 +        free(_keylist);
   1.156 +    }
   1.157 +}
   1.158 +
   1.159  static char* _get_resource_ptr_noown(char* uri) {
   1.160      char* uri_delim = strstr(uri, "://");
   1.161      if (!uri_delim)
   1.162 @@ -79,26 +231,6 @@
   1.163      return strcmp(bl->filename + (fn_len - fe_len), fe) == 0;
   1.164  }
   1.165  
   1.166 -void add_opt_field(message *msg, const char *name, const char *value)
   1.167 -{
   1.168 -    assert(msg && name && value);
   1.169 -
   1.170 -    if (msg && name && value) {
   1.171 -        stringpair_t *pair = new_stringpair(name, value);
   1.172 -        if (pair == NULL)
   1.173 -            return;
   1.174 -
   1.175 -        stringpair_list_t *field = stringpair_list_add(msg->opt_fields, pair);
   1.176 -        if (field == NULL)
   1.177 -        {
   1.178 -            free_stringpair(pair);
   1.179 -            return;
   1.180 -        }
   1.181 -
   1.182 -        if (msg->opt_fields == NULL)
   1.183 -            msg->opt_fields = field;
   1.184 -    }
   1.185 -}
   1.186  
   1.187  static char * encapsulate_message_wrap_info(const char *msg_wrap_info, const char *longmsg)
   1.188  {
   1.189 @@ -134,7 +266,6 @@
   1.190      return ptext;
   1.191  }
   1.192  
   1.193 -
   1.194  static char * combine_short_and_long(const char *shortmsg, const char *longmsg)
   1.195  {
   1.196      assert(shortmsg);
   1.197 @@ -174,6 +305,26 @@
   1.198      return ptext;
   1.199  }
   1.200  
   1.201 +static PEP_STATUS replace_subject(message* msg) {
   1.202 +    unsigned char pepstr[] = PEP_SUBJ_STRING;
   1.203 +    if (msg->shortmsg && *(msg->shortmsg) != '\0') {
   1.204 +        char* longmsg = combine_short_and_long(msg->shortmsg, msg->longmsg);
   1.205 +        if (!longmsg)
   1.206 +            return PEP_OUT_OF_MEMORY;
   1.207 +        else {
   1.208 +            free(msg->longmsg);
   1.209 +            msg->longmsg = longmsg;
   1.210 +        }
   1.211 +    }
   1.212 +    free(msg->shortmsg);
   1.213 +    msg->shortmsg = strdup((char*)pepstr);
   1.214 +    
   1.215 +    if (!msg->shortmsg)
   1.216 +        return PEP_OUT_OF_MEMORY;
   1.217 +    
   1.218 +    return PEP_STATUS_OK;
   1.219 +}
   1.220 +
   1.221  /* 
   1.222     WARNING: For the moment, this only works for the first line of decrypted
   1.223     plaintext because we don't need more. IF WE DO, THIS MUST BE EXPANDED, or
   1.224 @@ -411,9 +562,7 @@
   1.225  
   1.226  static message* extract_minimal_envelope(const message* src, 
   1.227                                           PEP_msg_direction direct) {
   1.228 -                                             
   1.229 -    unsigned char pepstr[] = PEP_SUBJ_STRING;
   1.230 -    
   1.231 +                                                 
   1.232      message* envelope = new_message(direct);
   1.233      if (!envelope)
   1.234          return NULL;
   1.235 @@ -479,17 +628,23 @@
   1.236  }
   1.237  
   1.238  static message* wrap_message_as_attachment(message* envelope, 
   1.239 -    const message* attachment) {
   1.240 +    message* attachment) {
   1.241      
   1.242 -    message* _envelope = NULL;
   1.243 -    
   1.244 -    if (!envelope) {
   1.245 +    message* _envelope = envelope;
   1.246 +
   1.247 +    replace_opt_field(attachment, "X-pEp-Version", PEP_VERSION);
   1.248 +
   1.249 +    if (!_envelope) {
   1.250          _envelope = extract_minimal_envelope(attachment, PEP_dir_outgoing);
   1.251 -        envelope = _envelope;
   1.252 +        attachment->longmsg = encapsulate_message_wrap_info("INNER", attachment->longmsg);
   1.253 +        _envelope->longmsg = encapsulate_message_wrap_info("OUTER", _envelope->longmsg);
   1.254      }
   1.255 -    
   1.256 +    else {
   1.257 +        _envelope->longmsg = encapsulate_message_wrap_info("TRANSPORT", _envelope->longmsg);
   1.258 +    }
   1.259      char* message_text = NULL;
   1.260      /* Turn message into a MIME-blob */
   1.261 +    //attachment->enc_format = PEP_enc_none;
   1.262      PEP_STATUS status = mime_encode_message(attachment, false, &message_text);
   1.263      
   1.264      if (status != PEP_STATUS_OK) {
   1.265 @@ -502,9 +657,9 @@
   1.266      bloblist_t* message_blob = new_bloblist(message_text, message_len,
   1.267                                              "message/rfc822", NULL);
   1.268      
   1.269 -    envelope->attachments = message_blob;
   1.270 +    _envelope->attachments = message_blob;
   1.271      
   1.272 -    return envelope;
   1.273 +    return _envelope;
   1.274  }
   1.275  
   1.276  static PEP_STATUS encrypt_PGP_MIME(
   1.277 @@ -526,20 +681,13 @@
   1.278  
   1.279      if (src->shortmsg)
   1.280          dst->shortmsg = strdup(src->shortmsg);
   1.281 -
   1.282 -    // Right now, we only encrypt inner messages or outer messages. There
   1.283 -    // is no in-between. All messages are to be wrapped or are a wrapper.
   1.284 -    // FIXME: rename this flag!!!
   1.285 -    const char* msg_wrap_info = (flags & PEP_encrypt_flag_inner_message ? 
   1.286 -                                 "INNER" : "OUTER");
   1.287 -    
   1.288 -    ptext = encapsulate_message_wrap_info(msg_wrap_info, src->longmsg);
   1.289          
   1.290      message *_src = calloc(1, sizeof(message));
   1.291      assert(_src);
   1.292      if (_src == NULL)
   1.293          goto enomem;
   1.294 -    _src->longmsg = ptext;
   1.295 +//    _src->longmsg = ptext;
   1.296 +    _src->longmsg = src->longmsg;
   1.297      _src->longmsg_formatted = src->longmsg_formatted;
   1.298      _src->attachments = src->attachments;
   1.299      _src->enc_format = PEP_enc_none;
   1.300 @@ -600,265 +748,6 @@
   1.301      return status;
   1.302  }
   1.303  
   1.304 -// static PEP_STATUS encrypt_PGP_in_pieces(
   1.305 -//     PEP_SESSION session,
   1.306 -//     const message *src,
   1.307 -//     stringlist_t *keys,
   1.308 -//     message *dst,
   1.309 -//     PEP_encrypt_flags_t flags
   1.310 -//     )
   1.311 -// {
   1.312 -//     PEP_STATUS status = PEP_STATUS_OK;
   1.313 -//     char *ctext = NULL;
   1.314 -//     size_t csize;
   1.315 -//     char *ptext = NULL;
   1.316 -//     bool free_ptext = false;
   1.317 -//     unsigned char pepstr[] = PEP_SUBJ_STRING;
   1.318 -//     
   1.319 -//     assert(dst->longmsg == NULL);
   1.320 -//     assert(dst->attachments == NULL);
   1.321 -// 
   1.322 -//     dst->enc_format = PEP_enc_pieces;
   1.323 -// 
   1.324 -//     bool nosign = (flags & PEP_encrypt_flag_force_unsigned);
   1.325 -// 
   1.326 -//     if (src->shortmsg && src->shortmsg[0] && strcmp(src->shortmsg, "pEp") != 0 && 
   1.327 -//         _unsigned_signed_strcmp(pepstr, src->shortmsg, PEP_SUBJ_BYTELEN) != 0) {
   1.328 -//         if (session->unencrypted_subject) {
   1.329 -//             dst->shortmsg = strdup(src->shortmsg);
   1.330 -//             assert(dst->shortmsg);
   1.331 -//             if (dst->shortmsg == NULL)
   1.332 -//                 goto enomem;
   1.333 -//             ptext = src->longmsg;
   1.334 -//         }
   1.335 -//         else {
   1.336 -//             ptext = combine_short_and_long(src->shortmsg, src->longmsg);
   1.337 -//             if (ptext == NULL)
   1.338 -//                 goto enomem;
   1.339 -//             free_ptext = true;
   1.340 -//         }
   1.341 -// 
   1.342 -//         if (nosign)
   1.343 -//             status = encrypt_only(session, keys, ptext, strlen(ptext), &ctext,
   1.344 -//                 &csize);
   1.345 -//         else 
   1.346 -//             status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
   1.347 -//                 &csize);
   1.348 -//         if (free_ptext)
   1.349 -//             free(ptext);
   1.350 -//         free_ptext = false;
   1.351 -//         if (ctext) {
   1.352 -//             dst->longmsg = ctext;
   1.353 -//         }
   1.354 -//         else {
   1.355 -//             goto pep_error;
   1.356 -//         }
   1.357 -//     }
   1.358 -//     else if (src->longmsg && src->longmsg[0]) {
   1.359 -//         ptext = src->longmsg;
   1.360 -//         if (nosign)
   1.361 -//             status = encrypt_only(session, keys, ptext, strlen(ptext), &ctext,
   1.362 -//                 &csize);
   1.363 -//         else 
   1.364 -//             status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
   1.365 -//                 &csize);
   1.366 -//         if (ctext) {
   1.367 -//             dst->longmsg = ctext;
   1.368 -//         }
   1.369 -//         else {
   1.370 -//             goto pep_error;
   1.371 -//         }
   1.372 -//     }
   1.373 -//     else {
   1.374 -//         dst->longmsg = strdup("");
   1.375 -//         assert(dst->longmsg);
   1.376 -//         if (dst->longmsg == NULL)
   1.377 -//             goto enomem;
   1.378 -//     }
   1.379 -// 
   1.380 -//     if (src->longmsg_formatted && src->longmsg_formatted[0]) {
   1.381 -//         ptext = src->longmsg_formatted;
   1.382 -//         if (nosign)
   1.383 -//             status = encrypt_only(session, keys, ptext, strlen(ptext), &ctext,
   1.384 -//                 &csize);
   1.385 -//         else 
   1.386 -//             status = encrypt_and_sign(session, keys, ptext, strlen(ptext), &ctext,
   1.387 -//                 &csize);
   1.388 -//         if (ctext) {
   1.389 -// 
   1.390 -//             bloblist_t *_a = bloblist_add(dst->attachments, ctext, csize,
   1.391 -//                 "application/octet-stream", "file://PGPexch.htm.pgp");
   1.392 -//             if (_a == NULL)
   1.393 -//                 goto enomem;
   1.394 -//             if (dst->attachments == NULL)
   1.395 -//                 dst->attachments = _a;
   1.396 -//         }
   1.397 -//         else {
   1.398 -//             goto pep_error;
   1.399 -//         }
   1.400 -//     }
   1.401 -// 
   1.402 -//     if (src->attachments) {
   1.403 -//         if (dst->attachments == NULL) {
   1.404 -//             dst->attachments = new_bloblist(NULL, 0, NULL, NULL);
   1.405 -//             if (dst->attachments == NULL)
   1.406 -//                 goto enomem;
   1.407 -//         }
   1.408 -// 
   1.409 -//         bloblist_t *_s = src->attachments;
   1.410 -//         bloblist_t *_d = dst->attachments;
   1.411 -// 
   1.412 -//         for (int n = 0; _s; _s = _s->next) {
   1.413 -//             if (_s->value == NULL && _s->size == 0) {
   1.414 -//                 _d = bloblist_add(_d, NULL, 0, _s->mime_type, _s->filename);
   1.415 -//                 if (_d == NULL)
   1.416 -//                     goto enomem;
   1.417 -//             }
   1.418 -//             else {
   1.419 -//                 size_t psize = _s->size;
   1.420 -//                 ptext = _s->value;
   1.421 -//                 if (nosign)
   1.422 -//                     status = encrypt_only(session, keys, ptext, psize, &ctext,
   1.423 -//                         &csize);
   1.424 -//                 else 
   1.425 -//                     status = encrypt_and_sign(session, keys, ptext, psize, &ctext,
   1.426 -//                         &csize);
   1.427 -//                 if (ctext) {
   1.428 -//                     char *filename = NULL;
   1.429 -// 
   1.430 -//                     char *attach_fn = _s->filename;
   1.431 -//                     if (attach_fn && !is_cid_uri(attach_fn)) {
   1.432 -//                         size_t len = strlen(_s->filename);
   1.433 -//                         size_t bufsize = len + 5; // length of .pgp extension + NUL
   1.434 -//                         bool already_uri = false;
   1.435 -//                         if (is_file_uri(attach_fn))
   1.436 -//                             already_uri = true;
   1.437 -//                         else
   1.438 -//                             bufsize += 7; // length of file://
   1.439 -//                             
   1.440 -//                         filename = calloc(1, bufsize);
   1.441 -//                         if (filename == NULL)
   1.442 -//                             goto enomem;
   1.443 -// 
   1.444 -//                         if (!already_uri)
   1.445 -//                             strlcpy(filename, "file://", bufsize);
   1.446 -//                         // First char is NUL, so we're ok, even if not copying above. (calloc)
   1.447 -//                         strlcat(filename, _s->filename, bufsize);
   1.448 -//                         strlcat(filename, ".pgp", bufsize);
   1.449 -//                     }
   1.450 -//                     else {
   1.451 -//                         filename = calloc(1, 27);
   1.452 -//                         if (filename == NULL)
   1.453 -//                             goto enomem;
   1.454 -// 
   1.455 -//                         ++n;
   1.456 -//                         n &= 0xffff;
   1.457 -//                         snprintf(filename, 20, "file://Attachment%d.pgp", n);
   1.458 -//                     }
   1.459 -// 
   1.460 -//                     _d = bloblist_add(_d, ctext, csize, "application/octet-stream",
   1.461 -//                         filename);
   1.462 -//                     free(filename);
   1.463 -//                     if (_d == NULL)
   1.464 -//                         goto enomem;
   1.465 -//                 }
   1.466 -//                 else {
   1.467 -//                     goto pep_error;
   1.468 -//                 }
   1.469 -//             }
   1.470 -//         }
   1.471 -//     }
   1.472 -// 
   1.473 -//     return PEP_STATUS_OK;
   1.474 -// 
   1.475 -// enomem:
   1.476 -//     status = PEP_OUT_OF_MEMORY;
   1.477 -// 
   1.478 -// pep_error:
   1.479 -//     if (free_ptext)
   1.480 -//         free(ptext);
   1.481 -//     return status;
   1.482 -// }
   1.483 -
   1.484 -static char * keylist_to_string(const stringlist_t *keylist)
   1.485 -{
   1.486 -    if (keylist) {
   1.487 -        size_t size = stringlist_length(keylist);
   1.488 -
   1.489 -        const stringlist_t *_kl;
   1.490 -        for (_kl = keylist; _kl && _kl->value; _kl = _kl->next) {
   1.491 -            size += strlen(_kl->value);
   1.492 -        }
   1.493 -
   1.494 -        char *result = calloc(1, size);
   1.495 -        if (result == NULL)
   1.496 -            return NULL;
   1.497 -
   1.498 -        char *_r = result;
   1.499 -        for (_kl = keylist; _kl && _kl->value; _kl = _kl->next) {
   1.500 -            _r = stpcpy(_r, _kl->value);
   1.501 -            if (_kl->next && _kl->next->value)
   1.502 -                _r = stpcpy(_r, ",");
   1.503 -        }
   1.504 -
   1.505 -        return result;
   1.506 -    }
   1.507 -    else {
   1.508 -        return NULL;
   1.509 -    }
   1.510 -}
   1.511 -
   1.512 -static const char * rating_to_string(PEP_rating rating)
   1.513 -{
   1.514 -    switch (rating) {
   1.515 -    case PEP_rating_cannot_decrypt:
   1.516 -        return "cannot_decrypt";
   1.517 -    case PEP_rating_have_no_key:
   1.518 -        return "have_no_key";
   1.519 -    case PEP_rating_unencrypted:
   1.520 -        return "unencrypted";
   1.521 -    case PEP_rating_unencrypted_for_some:
   1.522 -        return "unencrypted_for_some";
   1.523 -    case PEP_rating_unreliable:
   1.524 -        return "unreliable";
   1.525 -    case PEP_rating_reliable:
   1.526 -        return "reliable";
   1.527 -    case PEP_rating_trusted:
   1.528 -        return "trusted";
   1.529 -    case PEP_rating_trusted_and_anonymized:
   1.530 -        return "trusted_and_anonymized";
   1.531 -    case PEP_rating_fully_anonymous:
   1.532 -        return "fully_anonymous";
   1.533 -    case PEP_rating_mistrust:
   1.534 -        return "mistrust";
   1.535 -    case PEP_rating_b0rken:
   1.536 -        return "b0rken";
   1.537 -    case PEP_rating_under_attack:
   1.538 -        return "under_attack";
   1.539 -    default:
   1.540 -        return "undefined";
   1.541 -    }
   1.542 -}
   1.543 -
   1.544 -static void decorate_message(
   1.545 -    message *msg,
   1.546 -    PEP_rating rating,
   1.547 -    stringlist_t *keylist
   1.548 -    )
   1.549 -{
   1.550 -    assert(msg);
   1.551 -
   1.552 -    add_opt_field(msg, "X-pEp-Version", PEP_VERSION);
   1.553 -
   1.554 -    if (rating != PEP_rating_undefined)
   1.555 -        add_opt_field(msg, "X-EncStatus", rating_to_string(rating));
   1.556 -
   1.557 -    if (keylist) {
   1.558 -        char *_keylist = keylist_to_string(keylist);
   1.559 -        add_opt_field(msg, "X-KeyList", _keylist);
   1.560 -        free(_keylist);
   1.561 -    }
   1.562 -}
   1.563  
   1.564  static PEP_rating _rating(PEP_comm_type ct, PEP_rating rating)
   1.565  {
   1.566 @@ -1264,7 +1153,6 @@
   1.567      PEP_STATUS status = PEP_STATUS_OK;
   1.568      message * msg = NULL;
   1.569      stringlist_t * keys = NULL;
   1.570 -    message* inner_message = NULL;
   1.571      message* _src = src;
   1.572      
   1.573      assert(session);
   1.574 @@ -1393,18 +1281,19 @@
   1.575          return ADD_TO_LOG(PEP_UNENCRYPTED);
   1.576      }
   1.577      else {
   1.578 -        
   1.579 -        // FIXME - this logic may need to change if we allow
   1.580 -        // wrappers to attach keys (e.g w/ transport)        
   1.581 -        if (!(flags & PEP_encrypt_flag_inner_message)) {
   1.582 -            PEP_STATUS status = encrypt_message(session, src, extra, &inner_message,
   1.583 -                                                enc_format,
   1.584 -                                                flags | PEP_encrypt_flag_inner_message);
   1.585 -            _src = wrap_message_as_attachment(NULL, inner_message);
   1.586 -        } else {
   1.587 -            if (!(flags & PEP_encrypt_flag_force_no_attached_key))
   1.588 -                attach_own_key(session, _src);
   1.589 +        // FIXME - we need to deal with transport types (via flag)
   1.590 +        if ((max_comm_type | PEP_ct_confirmed) == PEP_ct_pEp) {
   1.591 +            _src = wrap_message_as_attachment(NULL, src);
   1.592          }
   1.593 +        else {
   1.594 +            // hide subject
   1.595 +            status = replace_subject(_src);
   1.596 +            if (status == PEP_OUT_OF_MEMORY)
   1.597 +                goto enomem;
   1.598 +        }
   1.599 +        if (!(flags & PEP_encrypt_flag_force_no_attached_key))
   1.600 +            attach_own_key(session, _src);
   1.601 +
   1.602          msg = clone_to_empty_message(_src);
   1.603          if (msg == NULL)
   1.604              goto enomem;
   1.605 @@ -1897,25 +1786,37 @@
   1.606  
   1.607  static PEP_STATUS unencapsulate_hidden_fields(message* src, message* msg,
   1.608                                                char** msg_wrap_info) {
   1.609 +    if (!src)
   1.610 +        return PEP_ILLEGAL_VALUE;
   1.611      unsigned char pepstr[] = PEP_SUBJ_STRING;
   1.612      PEP_STATUS status = PEP_STATUS_OK;
   1.613 +
   1.614 +    bool change_source_in_place = (msg ? false : true);
   1.615 +    
   1.616 +    if (change_source_in_place)
   1.617 +        msg = src;
   1.618 +        
   1.619 +//    const char* version_string = get_message_version_string(src);
   1.620      
   1.621      switch (src->enc_format) {
   1.622          case PEP_enc_PGP_MIME:
   1.623          case PEP_enc_pieces:
   1.624          case PEP_enc_PGP_MIME_Outlook1:
   1.625 -        
   1.626 -            status = copy_fields(msg, src);
   1.627 +//        case PEP_enc_none: // FIXME - this is wrong
   1.628 +
   1.629 +            if (!change_source_in_place)
   1.630 +                status = copy_fields(msg, src);
   1.631 +                
   1.632              if (status != PEP_STATUS_OK)
   1.633                  return status;
   1.634 -
   1.635 +                
   1.636              // FIXME: This is a mess. Talk with VB about how far we go to identify
   1.637              if (is_a_pEpmessage(src) || (src->shortmsg == NULL || strcmp(src->shortmsg, "pEp") == 0 ||
   1.638                  _unsigned_signed_strcmp(pepstr, src->shortmsg, PEP_SUBJ_BYTELEN) == 0))
   1.639              {
   1.640                  char * shortmsg = NULL;
   1.641                  char * longmsg = NULL;
   1.642 -                
   1.643 +        
   1.644                  if (msg->longmsg) {
   1.645                      int r = separate_short_and_long(msg->longmsg, 
   1.646                                                      &shortmsg, 
   1.647 @@ -1928,13 +1829,14 @@
   1.648  
   1.649                  // We only use the shortmsg in version 1.0 messages; if it occurs where we
   1.650                  // didn't replace the subject, we ignore this all
   1.651 -                if (!(*msg_wrap_info)) {
   1.652 +                if (!(*msg_wrap_info || change_source_in_place)) {
   1.653                      if (!shortmsg || 
   1.654                          (src->shortmsg != NULL && strcmp(src->shortmsg, "pEp") != 0 &&
   1.655                           _unsigned_signed_strcmp(pepstr, src->shortmsg, PEP_SUBJ_BYTELEN) != 0)) {
   1.656                               
   1.657                          if (shortmsg != NULL)
   1.658                              free(shortmsg);                        
   1.659 +                            
   1.660                          if (src->shortmsg == NULL) {
   1.661                              shortmsg = strdup("");
   1.662                          }
   1.663 @@ -1943,23 +1845,25 @@
   1.664                              // src->shortmsg already?
   1.665                              // if so, we need to change the logic so
   1.666                              // that in this case, we don't free msg->shortmsg
   1.667 -                            // and do this strdup, etc.
   1.668 -                            shortmsg = strdup(src->shortmsg); 
   1.669 +                            // and do this strdup, etc
   1.670 +                            shortmsg = strdup(src->shortmsg);
   1.671                          }        
   1.672                      }
   1.673 +                    free(msg->shortmsg);
   1.674 +                    msg->shortmsg = shortmsg;
   1.675                  }
   1.676                  
   1.677 -                free(msg->shortmsg);
   1.678                  free(msg->longmsg);
   1.679  
   1.680 -                msg->shortmsg = shortmsg;
   1.681                  msg->longmsg = longmsg;
   1.682              }
   1.683              else {
   1.684 -                msg->shortmsg = strdup(src->shortmsg);
   1.685 -                assert(msg->shortmsg);
   1.686 -                if (msg->shortmsg == NULL)
   1.687 -                    return PEP_OUT_OF_MEMORY;
   1.688 +                if (!change_source_in_place) {
   1.689 +                    msg->shortmsg = strdup(src->shortmsg);
   1.690 +                    assert(msg->shortmsg);
   1.691 +                    if (msg->shortmsg == NULL)
   1.692 +                        return PEP_OUT_OF_MEMORY;
   1.693 +                }
   1.694              }
   1.695              break;
   1.696          default:
   1.697 @@ -2321,57 +2225,74 @@
   1.698          if (decrypt_status == PEP_DECRYPTED || decrypt_status == PEP_DECRYPTED_AND_VERIFIED) {
   1.699              char* wrap_info = NULL;
   1.700              status = unencapsulate_hidden_fields(src, msg, &wrap_info);
   1.701 +
   1.702 +            bool is_transport_wrapper = false;
   1.703              
   1.704              // FIXME: replace with enums, check status
   1.705              if (wrap_info) {
   1.706                  if (strcmp(wrap_info, "OUTER") == 0) {
   1.707                      // this only occurs in with a direct outer wrapper
   1.708                      // where the actual content is in the inner wrapper
   1.709 -                    
   1.710 +                    message* inner_message = NULL;                    
   1.711                      bloblist_t* actual_message = msg->attachments;
   1.712                      
   1.713                      while (actual_message) {
   1.714                          char* mime_type = actual_message->mime_type;
   1.715                          if (mime_type) {
   1.716 +                            
   1.717                              // libetpan appears to change the mime_type on this one.
   1.718                              // *growl*
   1.719                              if (strcmp("message/rfc822", mime_type) == 0 ||
   1.720 -                                strcmp("text/rfc822", mime_type) == 0)
   1.721 -                                break;
   1.722 +                                strcmp("text/rfc822", mime_type) == 0) {
   1.723 +                                    
   1.724 +                                status = mime_decode_message(actual_message->value, 
   1.725 +                                                             actual_message->size, 
   1.726 +                                                             &inner_message);
   1.727 +                                if (status != PEP_STATUS_OK)
   1.728 +                                    GOTO(pep_error);
   1.729 +                                
   1.730 +                                if (inner_message) {
   1.731 +                                    // Though this will strip any message info on the
   1.732 +                                    // attachment, this is safe, as we do not
   1.733 +                                    // produce more than one attachment-as-message,
   1.734 +                                    // and those are the only ones with such info.
   1.735 +                                    // Since we capture the information, this is ok.
   1.736 +                                    wrap_info = NULL;
   1.737 +                                    inner_message->enc_format = src->enc_format;
   1.738 +                                    // FIXME
   1.739 +                                    status = unencapsulate_hidden_fields(inner_message, NULL, &wrap_info);
   1.740 +                                    if (wrap_info) {
   1.741 +                                        // useless check, but just in case we screw up?
   1.742 +                                        if (strcmp(wrap_info, "INNER") == 0) {
   1.743 +                                            // THIS is our message
   1.744 +                                            // FIXME: free msg, but check references
   1.745 +                                            src = msg = inner_message;
   1.746 +                                            
   1.747 +                                            if (src->from)
   1.748 +                                                update_identity(session, src->from);
   1.749 +                                            break;        
   1.750 +                                        }
   1.751 +                                        else { // should never happen
   1.752 +                                            status = PEP_UNKNOWN_ERROR;
   1.753 +                                            free_message(inner_message);
   1.754 +                                            GOTO(pep_error);
   1.755 +                                        }
   1.756 +                                    }
   1.757 +                                    inner_message->enc_format = PEP_enc_none;
   1.758 +                                }
   1.759 +                                else { // forwarded message, leave it alone
   1.760 +                                    free_message(inner_message);
   1.761 +                                }
   1.762 +                            }
   1.763                          }
   1.764                          actual_message = actual_message->next;
   1.765 -                    }
   1.766 -                    
   1.767 -                    if (actual_message) {
   1.768 -                        message* inner_message = NULL;
   1.769 -                        status = mime_decode_message(actual_message->value, 
   1.770 -                                                     actual_message->size, 
   1.771 -                                                     &inner_message);
   1.772 -                        if (status != PEP_STATUS_OK)
   1.773 -                            GOTO(pep_error);
   1.774 -                            
   1.775 -                        free_stringlist(*keylist);
   1.776 -                        *keylist == NULL;
   1.777 -                        
   1.778 -                        free_message(*dst);
   1.779 -                        
   1.780 -                        *dst = NULL;
   1.781 -                        *rating = PEP_rating_undefined;
   1.782 -                        *flags = 0;
   1.783 -
   1.784 -                        message* inner_dec_msg = NULL;
   1.785 -                        
   1.786 -                        decrypt_status = decrypt_message(session,
   1.787 -                                                         inner_message,
   1.788 -                                                         &inner_dec_msg,
   1.789 -                                                         keylist,
   1.790 -                                                         rating,
   1.791 -                                                         flags);
   1.792 -                                                         
   1.793 -                        *dst = inner_dec_msg;
   1.794 -                        return decrypt_status;
   1.795 -                    }
   1.796 +                    }                    
   1.797                  }
   1.798 +                else if (strcmp(wrap_info, "TRANSPORT") == 0) {
   1.799 +                    // FIXME: this gets even messier.
   1.800 +                    // (TBI in ENGINE-278)
   1.801 +                }
   1.802 +                else {} // shouldn't be anything to be done here
   1.803              }
   1.804          }
   1.805          
   1.806 @@ -2428,7 +2349,7 @@
   1.807          }
   1.808          
   1.809          // copy message id to output message        
   1.810 -        if (src->id) {
   1.811 +        if (src->id && src != msg) {
   1.812              msg->id = strdup(src->id);
   1.813              assert(msg->id);
   1.814              if (msg->id == NULL)
   1.815 @@ -2973,6 +2894,7 @@
   1.816          GOTO(pep_error);
   1.817      }
   1.818  
   1.819 +    dec_msg->enc_format = PEP_enc_none; // is this the right thing to do? FIXME
   1.820      status = mime_encode_message(dec_msg, false, mime_plaintext);
   1.821  
   1.822      if (status == PEP_STATUS_OK)
     2.1 --- a/src/mime.h	Wed Oct 11 15:46:04 2017 +0200
     2.2 +++ b/src/mime.h	Fri Oct 13 13:27:59 2017 +0200
     2.3 @@ -40,6 +40,10 @@
     2.4  //      the resulttext will go to the ownership of the caller
     2.5  //      the message will remain in the ownership of the caller
     2.6  //      omit_fields is true for payload of PGP/MIME messages
     2.7 +//
     2.8 +//      also: note that the encryption type will be used to determine what
     2.9 +//      gets encoded from the message struct, so if using this on an 
    2.10 +//      already-encrypted message, set the enc_format of the msg to PEP_enc_none.
    2.11  
    2.12  DYNAMIC_API PEP_STATUS mime_encode_message(
    2.13          const message * msg,
     3.1 --- a/src/pEpEngine.h	Wed Oct 11 15:46:04 2017 +0200
     3.2 +++ b/src/pEpEngine.h	Fri Oct 13 13:27:59 2017 +0200
     3.3 @@ -16,7 +16,7 @@
     3.4  #include "stringpair.h"    
     3.5  #include "timestamp.h"
     3.6  
     3.7 -#define PEP_VERSION "1.0" // protocol version
     3.8 +#define PEP_VERSION "2.0" // protocol version
     3.9  
    3.10  #define PEP_OWN_USERID "pEp_own_userId"
    3.11      
     4.1 --- a/test/mime_test.cc	Wed Oct 11 15:46:04 2017 +0200
     4.2 +++ b/test/mime_test.cc	Fri Oct 13 13:27:59 2017 +0200
     4.3 @@ -102,4 +102,3 @@
     4.4      release(session);
     4.5      return 0;
     4.6  }
     4.7 -
     5.1 --- a/test/revoke_regen_attach_test.cc	Wed Oct 11 15:46:04 2017 +0200
     5.2 +++ b/test/revoke_regen_attach_test.cc	Fri Oct 13 13:27:59 2017 +0200
     5.3 @@ -61,7 +61,6 @@
     5.4      message *enc_msg;
     5.5      cout << "calling encrypt_message()\n";
     5.6      status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
     5.7 -    cout << status;
     5.8      assert(status == PEP_STATUS_OK);
     5.9      assert(enc_msg);
    5.10      cout << "message encrypted.\n";
    5.11 @@ -71,7 +70,7 @@
    5.12      assert(strcmp(msg->attachments->filename, "file://pEpkey.asc") == 0);
    5.13      assert(strcmp(msg->attachments->next->filename, "file://pEpkey.asc") == 0);
    5.14  
    5.15 -    cout << "message contains 2 key attachements.\n";
    5.16 +    cout << "message contains 2 key attachments.\n";
    5.17  
    5.18      free_message(msg);
    5.19      free_message(enc_msg);