Merge with sync sequoia_windows
authorThomas
Thu, 08 Aug 2019 08:10:32 +0200
branchsequoia_windows
changeset 396667a11b194bbb
parent 3946 407b8c05e11a
parent 3965 9a59d1fa3d09
child 3969 e878a24997f2
Merge with sync
src/pEpEngine.c
src/pEp_internal.h
     1.1 --- a/src/aux_mime_msg.c	Wed Aug 07 08:16:15 2019 +0200
     1.2 +++ b/src/aux_mime_msg.c	Thu Aug 08 08:10:32 2019 +0200
     1.3 @@ -73,7 +73,7 @@
     1.4      message* dec_msg = NULL;
     1.5      *mime_plaintext = NULL;
     1.6  
     1.7 -    status = mime_decode_message(mimetext, size, &tmp_msg);
     1.8 +    status = mime_decode_message(mimetext, size, &tmp_msg, NULL);
     1.9      if (status != PEP_STATUS_OK)
    1.10          goto pEp_error;
    1.11  
    1.12 @@ -120,7 +120,7 @@
    1.13      }
    1.14  
    1.15      if (*flags & PEP_decrypt_flag_src_modified) {
    1.16 -        _mime_encode_message_internal(tmp_msg, false, modified_src, true);
    1.17 +        _mime_encode_message_internal(tmp_msg, false, modified_src, true, false);
    1.18          if (!modified_src) {
    1.19              *flags &= (~PEP_decrypt_flag_src_modified);
    1.20              decrypt_status = PEP_CANNOT_REENCRYPT; // Because we couldn't return it, I guess.
    1.21 @@ -128,7 +128,7 @@
    1.22      }
    1.23  
    1.24      // FIXME: test with att
    1.25 -    status = _mime_encode_message_internal(dec_msg, false, mime_plaintext, true);
    1.26 +    status = _mime_encode_message_internal(dec_msg, false, mime_plaintext, true, false);
    1.27  
    1.28      if (status == PEP_STATUS_OK)
    1.29      {
    1.30 @@ -159,7 +159,7 @@
    1.31      message* tmp_msg = NULL;
    1.32      message* enc_msg = NULL;
    1.33  
    1.34 -    status = mime_decode_message(mimetext, size, &tmp_msg);
    1.35 +    status = mime_decode_message(mimetext, size, &tmp_msg, NULL);
    1.36      if (status != PEP_STATUS_OK)
    1.37          goto pEp_error;
    1.38  
    1.39 @@ -214,7 +214,7 @@
    1.40          goto pEp_error;
    1.41      }
    1.42  
    1.43 -    status = _mime_encode_message_internal(enc_msg, false, mime_ciphertext, false);
    1.44 +    status = _mime_encode_message_internal(enc_msg, false, mime_ciphertext, false, false);
    1.45  
    1.46  pEp_error:
    1.47      free_message(tmp_msg);
    1.48 @@ -239,7 +239,7 @@
    1.49      message* tmp_msg = NULL;
    1.50      message* enc_msg = NULL;
    1.51  
    1.52 -    status = mime_decode_message(mimetext, size, &tmp_msg);
    1.53 +    status = mime_decode_message(mimetext, size, &tmp_msg, NULL);
    1.54      if (status != PEP_STATUS_OK)
    1.55          goto pEp_error;
    1.56  
    1.57 @@ -271,4 +271,3 @@
    1.58  #else
    1.59  const int the_answer_my_friend = 42;
    1.60  #endif
    1.61 -
     2.1 --- a/src/bloblist.h	Wed Aug 07 08:16:15 2019 +0200
     2.2 +++ b/src/bloblist.h	Thu Aug 08 08:10:32 2019 +0200
     2.3 @@ -3,6 +3,8 @@
     2.4  
     2.5  #pragma once
     2.6  
     2.7 +#include <stddef.h> 
     2.8 +
     2.9  #include "dynamic_api.h"
    2.10  #include "stringpair.h"
    2.11  
     3.1 --- a/src/etpan_mime.c	Wed Aug 07 08:16:15 2019 +0200
     3.2 +++ b/src/etpan_mime.c	Thu Aug 08 08:10:32 2019 +0200
     3.3 @@ -38,6 +38,7 @@
     3.4  struct mailmime * part_new_empty(
     3.5          struct mailmime_content * content,
     3.6          struct mailmime_fields * mime_fields,
     3.7 +        stringpair_list_t* param_keyvals,
     3.8          int force_single
     3.9      )
    3.10  {
    3.11 @@ -127,6 +128,40 @@
    3.12          if (content->ct_parameters == NULL)
    3.13              content->ct_parameters = parameters;
    3.14      }
    3.15 +    
    3.16 +    if (param_keyvals) {
    3.17 +        stringpair_list_t* cur;
    3.18 +        for (cur = param_keyvals; cur; cur = cur->next) {
    3.19 +            attr_name = strdup(cur->value->key);
    3.20 +            attr_value = strdup(cur->value->value);
    3.21 +            
    3.22 +            param = mailmime_parameter_new(attr_name, attr_value);
    3.23 +            assert(param);
    3.24 +            if (param == NULL)
    3.25 +                goto enomem;
    3.26 +                
    3.27 +            attr_name = NULL;
    3.28 +            attr_value = NULL;
    3.29 +
    3.30 +            if (content->ct_parameters == NULL) {
    3.31 +                parameters = clist_new();
    3.32 +                assert(parameters);
    3.33 +                if (parameters == NULL)
    3.34 +                    goto enomem;
    3.35 +            }
    3.36 +            else {
    3.37 +                parameters = content->ct_parameters;
    3.38 +            }
    3.39 +
    3.40 +            r = clist_append(parameters, param);
    3.41 +            if (r)
    3.42 +                goto enomem;
    3.43 +            param = NULL;
    3.44 +
    3.45 +            if (content->ct_parameters == NULL)
    3.46 +                content->ct_parameters = parameters;            
    3.47 +        }
    3.48 +    }
    3.49  
    3.50      build_info = mailmime_new(mime_type, NULL, 0, mime_fields, content, NULL,
    3.51              NULL, NULL, list, NULL, NULL);
    3.52 @@ -163,7 +198,7 @@
    3.53      if (mime_fields == NULL)
    3.54          goto enomem;
    3.55  
    3.56 -    mime = part_new_empty(content, mime_fields, 1);
    3.57 +    mime = part_new_empty(content, mime_fields, NULL, 1);
    3.58      if (mime == NULL)
    3.59          goto enomem;
    3.60      mime_fields = NULL;
    3.61 @@ -252,7 +287,7 @@
    3.62              goto enomem;
    3.63      }
    3.64  
    3.65 -    mime = part_new_empty(content, mime_fields, 1);
    3.66 +    mime = part_new_empty(content, mime_fields, NULL, 1);
    3.67      if (mime == NULL)
    3.68          goto enomem;
    3.69      content = NULL;
    3.70 @@ -289,7 +324,8 @@
    3.71          const char * mime_type,
    3.72          char * data,
    3.73          size_t length,
    3.74 -        bool transport_encode
    3.75 +        bool transport_encode,
    3.76 +        bool set_attachment_forward_comment
    3.77      )
    3.78  {
    3.79      char * disposition_name = NULL;
    3.80 @@ -351,7 +387,13 @@
    3.81      encoding = NULL;
    3.82      disposition = NULL;
    3.83  
    3.84 -    mime = part_new_empty(content, mime_fields, 1);
    3.85 +    stringpair_list_t* extra_params = NULL;
    3.86 +    
    3.87 +    if (set_attachment_forward_comment)
    3.88 +        extra_params = new_stringpair_list(new_stringpair("forwarded", "no"));
    3.89 +    
    3.90 +    mime = part_new_empty(content, mime_fields, extra_params, 1);
    3.91 +    free_stringpair_list(extra_params);
    3.92      if (mime == NULL)
    3.93          goto enomem;
    3.94      content = NULL;
    3.95 @@ -396,7 +438,7 @@
    3.96      if (content == NULL)
    3.97          goto enomem;
    3.98      
    3.99 -    mp = part_new_empty(content, mime_fields, 0);
   3.100 +    mp = part_new_empty(content, mime_fields, NULL, 0);
   3.101      if (mp == NULL)
   3.102          goto enomem;
   3.103      
   3.104 @@ -815,6 +857,22 @@
   3.105      return false;
   3.106  }
   3.107  
   3.108 +bool _is_message_part(struct mailmime_content *content, const char* subtype) {
   3.109 +    assert(content);
   3.110 +    if (content->ct_type && content->ct_type->tp_type == MAILMIME_TYPE_COMPOSITE_TYPE &&
   3.111 +            content->ct_type->tp_data.tp_composite_type &&
   3.112 +            content->ct_type->tp_data.tp_composite_type->ct_type ==
   3.113 +            MAILMIME_COMPOSITE_TYPE_MESSAGE) {
   3.114 +        if (subtype)
   3.115 +            return content->ct_subtype &&
   3.116 +                    strcasecmp(content->ct_subtype, subtype) == 0;
   3.117 +        else
   3.118 +            return true;                
   3.119 +    }
   3.120 +    
   3.121 +    return false;
   3.122 +}
   3.123 +
   3.124  int _get_content_type(
   3.125          const struct mailmime_content *content,
   3.126          char **type,
   3.127 @@ -948,7 +1006,8 @@
   3.128  #endif
   3.129  
   3.130  static PEP_STATUS interpret_MIME(struct mailmime *mime,
   3.131 -                                 message *msg);
   3.132 +                                 message *msg,
   3.133 +                                 bool* raise_msg_attachment);
   3.134  
   3.135  // This function was rewritten to use in-memory buffers instead of
   3.136  // temporary files when the pgp/mime support was implemented for
   3.137 @@ -1006,7 +1065,8 @@
   3.138  static PEP_STATUS mime_attachment(
   3.139          bloblist_t *blob,
   3.140          struct mailmime **result,
   3.141 -        bool transport_encode
   3.142 +        bool transport_encode,
   3.143 +        bool set_attachment_forward_comment
   3.144      )
   3.145  {
   3.146      PEP_STATUS status = PEP_STATUS_OK;
   3.147 @@ -1031,7 +1091,8 @@
   3.148      bool already_ascii = !(must_chunk_be_encoded(blob->value, blob->size, true));
   3.149  
   3.150      mime = get_file_part(resource, mime_type, blob->value, blob->size, 
   3.151 -                          (already_ascii ? false : transport_encode));
   3.152 +                          (already_ascii ? false : transport_encode),
   3.153 +                          set_attachment_forward_comment);
   3.154      free_rid_list(resource);
   3.155      
   3.156      assert(mime);
   3.157 @@ -1155,7 +1216,7 @@
   3.158      for (_a = attachments; _a != NULL; _a = _a->next) {
   3.159          if (_a->disposition != PEP_CONTENT_DISP_INLINE)
   3.160              continue;
   3.161 -        status = mime_attachment(_a, &submime, transport_encode);
   3.162 +        status = mime_attachment(_a, &submime, transport_encode, false);
   3.163          if (status != PEP_STATUS_OK)
   3.164              return PEP_UNKNOWN_ERROR; // FIXME
   3.165  
   3.166 @@ -1632,7 +1693,8 @@
   3.167          const message *msg,
   3.168          bool omit_fields,
   3.169          struct mailmime **result,
   3.170 -        bool transport_encode
   3.171 +        bool transport_encode,
   3.172 +        bool set_attachment_forward_comment
   3.173      )
   3.174  {
   3.175      struct mailmime * mime = NULL;
   3.176 @@ -1711,14 +1773,19 @@
   3.177          }
   3.178  
   3.179          bloblist_t *_a;
   3.180 +        bool first_one = true;
   3.181 +        
   3.182          for (_a = msg->attachments; _a != NULL; _a = _a->next) {
   3.183  
   3.184              if (_a->disposition == PEP_CONTENT_DISP_INLINE)
   3.185                  continue;
   3.186  
   3.187 -            status = mime_attachment(_a, &submime, transport_encode);
   3.188 +            status = mime_attachment(_a, &submime, transport_encode,
   3.189 +                                     (first_one && set_attachment_forward_comment));                         
   3.190              if (status != PEP_STATUS_OK)
   3.191                  goto pEp_error;
   3.192 +            
   3.193 +            first_one = false;    
   3.194  
   3.195              r = mailmime_smart_add_part(mime, submime);
   3.196              assert(r == MAILIMF_NO_ERROR);
   3.197 @@ -1830,7 +1897,8 @@
   3.198          const message * msg,
   3.199          bool omit_fields,
   3.200          char **mimetext,
   3.201 -        bool transport_encode
   3.202 +        bool transport_encode,
   3.203 +        bool set_attachment_forward_comment
   3.204      )
   3.205  {
   3.206      PEP_STATUS status = PEP_STATUS_OK;
   3.207 @@ -1850,11 +1918,12 @@
   3.208  
   3.209      switch (msg->enc_format) {
   3.210          case PEP_enc_none:
   3.211 -            status = mime_encode_message_plain(msg, omit_fields, &mime, transport_encode);
   3.212 +            status = mime_encode_message_plain(msg, omit_fields, &mime, transport_encode, set_attachment_forward_comment);
   3.213              break;
   3.214  
   3.215 +        // I'm presuming we should hardcore ignoring set_attachment_forward_comment here...
   3.216          case PEP_enc_inline:
   3.217 -            status = mime_encode_message_plain(msg, omit_fields, &mime, transport_encode);
   3.218 +            status = mime_encode_message_plain(msg, omit_fields, &mime, transport_encode, false);
   3.219              break;
   3.220  
   3.221          case PEP_enc_S_MIME:
   3.222 @@ -2402,7 +2471,7 @@
   3.223          // ???
   3.224          // This is what we would have done before, so... no
   3.225          // worse than the status quo. But FIXME!
   3.226 -        status = interpret_MIME(part, msg);
   3.227 +        status = interpret_MIME(part, msg, NULL);
   3.228          if (status)
   3.229              return status;
   3.230      }
   3.231 @@ -2417,7 +2486,7 @@
   3.232          if (content == NULL)
   3.233              return PEP_ILLEGAL_VALUE;
   3.234  
   3.235 -        status = interpret_MIME(part, msg);
   3.236 +        status = interpret_MIME(part, msg, NULL);
   3.237          if (status)
   3.238              return status;
   3.239      }
   3.240 @@ -2426,7 +2495,8 @@
   3.241  
   3.242  static PEP_STATUS interpret_MIME(
   3.243          struct mailmime *mime,
   3.244 -        message *msg
   3.245 +        message *msg,
   3.246 +        bool* raise_msg_attachment
   3.247      )
   3.248  {
   3.249      PEP_STATUS status = PEP_STATUS_OK;
   3.250 @@ -2476,7 +2546,7 @@
   3.251                          return status;
   3.252                  }
   3.253                  else /* add as attachment */ {
   3.254 -                    status = interpret_MIME(part, msg);
   3.255 +                    status = interpret_MIME(part, msg, NULL);
   3.256                      if (status)
   3.257                          return status;
   3.258                  }
   3.259 @@ -2499,7 +2569,7 @@
   3.260                  if (part == NULL)
   3.261                      return PEP_ILLEGAL_VALUE;
   3.262  
   3.263 -                status = interpret_MIME(part, msg);
   3.264 +                status = interpret_MIME(part, msg, NULL);
   3.265                  if (status != PEP_STATUS_OK)
   3.266                      return status;
   3.267              }
   3.268 @@ -2510,11 +2580,13 @@
   3.269                  return PEP_ILLEGAL_VALUE;
   3.270  
   3.271              clistiter *cur;
   3.272 -            for (cur = clist_begin(partlist); cur; cur = clist_next(cur)) {
   3.273 +            // only add raise_msg_attachment on 2nd part!
   3.274 +            int _att_count = 0;
   3.275 +            for (cur = clist_begin(partlist); cur; cur = clist_next(cur), _att_count++) {
   3.276                  struct mailmime *part= clist_content(cur);
   3.277                  if (part == NULL)
   3.278                      return PEP_ILLEGAL_VALUE;
   3.279 -                status = interpret_MIME(part, msg);
   3.280 +                status = interpret_MIME(part, msg, _att_count == 1 ? raise_msg_attachment : NULL);
   3.281                  if (status != PEP_STATUS_OK)
   3.282                      return status;
   3.283              }
   3.284 @@ -2547,6 +2619,25 @@
   3.285                      return status;
   3.286              }
   3.287              else {
   3.288 +                // Fixme - we need a control on recursion level here - KG: maybe NOT. We only go to depth 1.
   3.289 +                if (raise_msg_attachment != NULL) {
   3.290 +                    bool is_msg = (_is_message_part(content, "rfc822") || _is_text_part(content, "rfc822"));
   3.291 +                    if (is_msg) {
   3.292 +                        if (content->ct_parameters) {
   3.293 +                            clistiter *cur;
   3.294 +                            for (cur = clist_begin(content->ct_parameters); cur; cur =
   3.295 +                                 clist_next(cur)) {
   3.296 +                                struct mailmime_parameter * param = clist_content(cur);
   3.297 +                                if (param && param->pa_name && strcasecmp(param->pa_name, "forwarded") == 0) {
   3.298 +                                    if (param->pa_value && strcasecmp(param->pa_value, "no") == 0) {
   3.299 +                                        *raise_msg_attachment = true;
   3.300 +                                        break;
   3.301 +                                    }
   3.302 +                                }
   3.303 +                            }
   3.304 +                        }
   3.305 +                    }
   3.306 +                }
   3.307                  char *data = NULL;
   3.308                  size_t size = 0;
   3.309                  char * mime_type;
   3.310 @@ -2633,7 +2724,8 @@
   3.311  DYNAMIC_API PEP_STATUS mime_decode_message(
   3.312          const char *mimetext,
   3.313          size_t size,
   3.314 -        message **msg
   3.315 +        message **msg,
   3.316 +        bool* raise_msg_attachment
   3.317      )
   3.318  {
   3.319      PEP_STATUS status = PEP_STATUS_OK;
   3.320 @@ -2677,7 +2769,7 @@
   3.321  
   3.322      if (content) {
   3.323          status = interpret_MIME(mime->mm_data.mm_message.mm_msg_mime,
   3.324 -                _msg);
   3.325 +                _msg, raise_msg_attachment);
   3.326          if (status != PEP_STATUS_OK)
   3.327              goto pEp_error;
   3.328      }
   3.329 @@ -2702,4 +2794,3 @@
   3.330  
   3.331      return status;
   3.332  }
   3.333 -
     4.1 --- a/src/etpan_mime.h	Wed Aug 07 08:16:15 2019 +0200
     4.2 +++ b/src/etpan_mime.h	Thu Aug 08 08:10:32 2019 +0200
     4.3 @@ -8,10 +8,12 @@
     4.4  #include <libetpan/mailmime_encode.h>
     4.5  
     4.6  #include "resource_id.h"
     4.7 +#include "stringpair.h"
     4.8  
     4.9  struct mailmime * part_new_empty(
    4.10          struct mailmime_content * content,
    4.11          struct mailmime_fields * mime_fields,
    4.12 +        stringpair_list_t* param_keyvals,        
    4.13          int force_single
    4.14      );
    4.15  
    4.16 @@ -30,7 +32,8 @@
    4.17          const char * mime_type,
    4.18          char * data,
    4.19          size_t length,
    4.20 -        bool transport_encode
    4.21 +        bool transport_encode,
    4.22 +        bool set_attachment_forward_comment
    4.23      );
    4.24  
    4.25  struct mailmime * part_multiple_new(const char *type);
     5.1 --- a/src/keymanagement.c	Wed Aug 07 08:16:15 2019 +0200
     5.2 +++ b/src/keymanagement.c	Thu Aug 08 08:10:32 2019 +0200
     5.3 @@ -454,7 +454,11 @@
     5.4      
     5.5      if (pEp_user) {
     5.6          PEP_comm_type confirmation_status = identity->comm_type & PEP_ct_confirmed;
     5.7 -        identity->comm_type = PEP_ct_pEp_unconfirmed | confirmation_status;    
     5.8 +        identity->comm_type = PEP_ct_pEp_unconfirmed | confirmation_status;
     5.9 +        if (identity->major_ver == 0) {
    5.10 +            identity->major_ver = 2;
    5.11 +            identity->minor_ver = 0;
    5.12 +        }    
    5.13      }
    5.14  }
    5.15  
    5.16 @@ -528,6 +532,9 @@
    5.17      
    5.18      return_id->me = stored_ident->me;
    5.19      
    5.20 +    return_id->major_ver = stored_ident->major_ver;
    5.21 +    return_id->minor_ver = stored_ident->minor_ver;
    5.22 +
    5.23      // FIXME: Do we ALWAYS do this? We probably should...
    5.24      if (EMPTYSTR(return_id->user_id)) {
    5.25          free(return_id->user_id);
    5.26 @@ -569,7 +576,7 @@
    5.27      }
    5.28      
    5.29      transfer_ident_lang_and_flags(return_id, stored_ident);
    5.30 -    
    5.31 +        
    5.32      if (return_id->comm_type == PEP_ct_unknown)
    5.33          return_id->comm_type = PEP_ct_key_not_found;
    5.34      
    5.35 @@ -1221,6 +1228,12 @@
    5.36          identity->comm_type = PEP_ct_unknown;
    5.37      }
    5.38      
    5.39 +    int major_ver = 0;
    5.40 +    int minor_ver = 0;
    5.41 +    pEp_version_major_minor(PEP_VERSION, &major_ver, &minor_ver);
    5.42 +    identity->major_ver = major_ver;
    5.43 +    identity->minor_ver = minor_ver;
    5.44 +    
    5.45      // We want to set an identity in the DB even if a key isn't found, but we have to preserve the status if
    5.46      // it's NOT ok
    5.47      if (!read_only) {
     6.1 --- a/src/message.c	Wed Aug 07 08:16:15 2019 +0200
     6.2 +++ b/src/message.c	Thu Aug 08 08:10:32 2019 +0200
     6.3 @@ -44,6 +44,7 @@
     6.4          free_stringlist(msg->keywords);
     6.5          free(msg->comments);
     6.6          free_stringpair_list(msg->opt_fields);
     6.7 +        free(msg->_sender_fpr);
     6.8          free(msg);
     6.9      }
    6.10  }
    6.11 @@ -185,6 +186,12 @@
    6.12              goto enomem;
    6.13      }
    6.14  
    6.15 +    if (src->_sender_fpr) {
    6.16 +        msg->_sender_fpr = strdup(src->_sender_fpr);
    6.17 +        if (msg->_sender_fpr == NULL)
    6.18 +            goto enomem;
    6.19 +    }
    6.20 +    
    6.21      msg->enc_format = src->enc_format;
    6.22  
    6.23      return msg;
    6.24 @@ -218,13 +225,15 @@
    6.25      free(dst->longmsg);
    6.26      free(dst->longmsg_formatted);
    6.27      free(dst->comments);
    6.28 +    free(dst->_sender_fpr);
    6.29      dst->id = src->id;
    6.30      dst->shortmsg = src->shortmsg;
    6.31      dst->longmsg = src->longmsg;
    6.32      dst->longmsg_formatted = src->longmsg_formatted;
    6.33      dst->comments = src->comments;    
    6.34 +    dst->_sender_fpr = src->_sender_fpr;
    6.35      src->id = src->shortmsg = src->longmsg = src->longmsg_formatted = NULL;
    6.36 -    src->comments = NULL;
    6.37 +    src->comments = src->_sender_fpr = NULL;
    6.38      
    6.39      /* bloblists */
    6.40      free_bloblist(dst->attachments);
     7.1 --- a/src/message.h	Wed Aug 07 08:16:15 2019 +0200
     7.2 +++ b/src/message.h	Thu Aug 08 08:10:32 2019 +0200
     7.3 @@ -70,6 +70,9 @@
     7.4      char *comments;                         // UTF-8 string with comments
     7.5      stringpair_list_t *opt_fields;          // optional fields
     7.6      PEP_enc_format enc_format;              // format of encrypted data
     7.7 +    char* _sender_fpr;                      // INTERNAL USE ONLY - fingerprint of 
     7.8 +                                            // sending signer.
     7.9 +                                            // (read_only to the outside)
    7.10  } message;
    7.11  
    7.12  typedef struct _message_ref_list {
     8.1 --- a/src/message_api.c	Wed Aug 07 08:16:15 2019 +0200
     8.2 +++ b/src/message_api.c	Thu Aug 08 08:10:32 2019 +0200
     8.3 @@ -33,58 +33,6 @@
     8.4      return false;
     8.5  }
     8.6  
     8.7 -static bool is_wrapper(message* src)
     8.8 -{
     8.9 -    bool retval = false;
    8.10 -    
    8.11 -    if (src) {
    8.12 -        unsigned char pEpstr[] = PEP_SUBJ_STRING;
    8.13 -        if (is_a_pEpmessage(src) || (src->shortmsg == NULL || strcmp(src->shortmsg, "pEp") == 0 ||
    8.14 -            _unsigned_signed_strcmp(pEpstr, src->shortmsg, PEP_SUBJ_BYTELEN) == 0) ||
    8.15 -            (strcmp(src->shortmsg, "p=p") == 0)) {
    8.16 -            char* plaintext = src->longmsg;
    8.17 -            if (plaintext) {
    8.18 -                const char *line_end = strchr(plaintext, '\n');
    8.19 -
    8.20 -                if (line_end != NULL) {
    8.21 -                    size_t n = line_end - plaintext;
    8.22 -                    
    8.23 -                    char* copycat = calloc(n + 1, 1);
    8.24 -                    
    8.25 -                    if (copycat) {
    8.26 -                        strlcpy(copycat, plaintext, n+1);
    8.27 -                        
    8.28 -                        if (strstr(copycat, PEP_MSG_WRAP_KEY) && strstr(copycat, "OUTER"))
    8.29 -                            retval = true;
    8.30 -                        
    8.31 -                        free(copycat);
    8.32 -                    }
    8.33 -                }
    8.34 -            }
    8.35 -        }
    8.36 -    }
    8.37 -    return retval;
    8.38 -}
    8.39 -
    8.40 -
    8.41 -/*
    8.42 - * static stringpair_t* search_optfields(const message* msg, const char* key) {
    8.43 - *     if (msg && key) {
    8.44 - *         stringpair_list_t* opt_fields = msg->opt_fields;
    8.45 - *         
    8.46 - *         const stringpair_list_t* curr;
    8.47 - *         
    8.48 - *         for (curr = opt_fields; curr && curr->value; curr = curr->next) {
    8.49 - *             if (curr->value->key) {
    8.50 - *                 if (strcasecmp(curr->value->key, key) == 0)
    8.51 - *                     return curr->value;
    8.52 - *             }
    8.53 - *         } 
    8.54 - *     }
    8.55 - *     return NULL;
    8.56 - * }
    8.57 - */
    8.58 -
    8.59  static char * keylist_to_string(const stringlist_t *keylist)
    8.60  {
    8.61      if (keylist) {
    8.62 @@ -237,7 +185,7 @@
    8.63      }
    8.64  }
    8.65  
    8.66 -static void decorate_message(
    8.67 +void decorate_message(
    8.68      message *msg,
    8.69      PEP_rating rating,
    8.70      stringlist_t *keylist,
    8.71 @@ -890,7 +838,7 @@
    8.72  }
    8.73  
    8.74  static message* wrap_message_as_attachment(message* envelope, 
    8.75 -    message* attachment, message_wrap_type wrap_type, bool keep_orig_subject) {
    8.76 +    message* attachment, message_wrap_type wrap_type, bool keep_orig_subject, unsigned int max_major, unsigned int max_minor) {
    8.77      
    8.78      if (!attachment)
    8.79          return NULL;
    8.80 @@ -916,10 +864,22 @@
    8.81              default:
    8.82                  inner_type_string = "INNER";
    8.83          }
    8.84 -        attachment->longmsg = encapsulate_message_wrap_info(inner_type_string, attachment->longmsg);
    8.85 -        _envelope->longmsg = encapsulate_message_wrap_info("OUTER", _envelope->longmsg);
    8.86 +        if (max_major < 2 || (max_major == 2 && max_minor == 0)) {
    8.87 +            attachment->longmsg = encapsulate_message_wrap_info(inner_type_string, attachment->longmsg);        
    8.88 +            _envelope->longmsg = encapsulate_message_wrap_info("OUTER", _envelope->longmsg);
    8.89 +        }
    8.90 +        else {
    8.91 +            _envelope->longmsg = strdup(
    8.92 +                "This message was encrypted with p≡p (https://pep.software). If you are seeing this message,\n" 
    8.93 +                "your client does not support raising message attachments. Please click on the message attachment to\n"
    8.94 +                "to view it, or better yet, consider using p≡p!\n"
    8.95 +            );
    8.96 +        }
    8.97 +        // 2.1, to replace the above
    8.98 +        add_opt_field(attachment, X_PEP_MSG_WRAP_KEY, inner_type_string); 
    8.99      }
   8.100      else if (_envelope) {
   8.101 +        // 2.1 - how do we peel this particular union when we get there?
   8.102          _envelope->longmsg = encapsulate_message_wrap_info("TRANSPORT", _envelope->longmsg);
   8.103      }
   8.104      else {
   8.105 @@ -947,9 +907,15 @@
   8.106          if (!attachment->shortmsg)
   8.107              goto enomem;
   8.108      }
   8.109 +    
   8.110 +    /* add sender fpr to inner message */
   8.111 +    add_opt_field(attachment, 
   8.112 +                  "X-pEp-Sender-FPR", 
   8.113 +                  (attachment->_sender_fpr ? attachment->_sender_fpr : "")
   8.114 +              );
   8.115              
   8.116      /* Turn message into a MIME-blob */
   8.117 -    status = _mime_encode_message_internal(attachment, false, &message_text, true);
   8.118 +    status = _mime_encode_message_internal(attachment, false, &message_text, true, false);
   8.119          
   8.120      if (status != PEP_STATUS_OK)
   8.121          goto enomem;
   8.122 @@ -1029,7 +995,8 @@
   8.123      const message *src,
   8.124      stringlist_t *keys,
   8.125      message *dst,
   8.126 -    PEP_encrypt_flags_t flags
   8.127 +    PEP_encrypt_flags_t flags,
   8.128 +    message_wrap_type wrap_type
   8.129      )
   8.130  {
   8.131      PEP_STATUS status = PEP_STATUS_OK;
   8.132 @@ -1053,8 +1020,11 @@
   8.133      _src->longmsg_formatted = src->longmsg_formatted;
   8.134      _src->attachments = src->attachments;
   8.135      _src->enc_format = PEP_enc_none;
   8.136 -    bool mime_encode = !is_wrapper(_src);
   8.137 -    status = _mime_encode_message_internal(_src, true, &mimetext, mime_encode);
   8.138 +    
   8.139 +    // These vars are here to be clear, and because I don't know how this may change in the near future.
   8.140 +    bool wrapped = (wrap_type != PEP_message_unwrapped);
   8.141 +    bool mime_encode = !wrapped;
   8.142 +    status = _mime_encode_message_internal(_src, true, &mimetext, mime_encode, wrapped);
   8.143      assert(status == PEP_STATUS_OK);
   8.144      if (status != PEP_STATUS_OK)
   8.145          goto pEp_error;
   8.146 @@ -1731,7 +1701,10 @@
   8.147      if (status != PEP_STATUS_OK)
   8.148          goto pEp_error;
   8.149  
   8.150 -    keys = new_stringlist(src->from->fpr);
   8.151 +    char* send_fpr = strdup(src->from->fpr ? src->from->fpr : "");
   8.152 +    src->_sender_fpr = send_fpr;
   8.153 +    
   8.154 +    keys = new_stringlist(send_fpr);
   8.155      if (keys == NULL)
   8.156          goto enomem;
   8.157  
   8.158 @@ -1747,7 +1720,10 @@
   8.159      bool has_pEp_user = false;
   8.160      
   8.161      PEP_comm_type max_comm_type = PEP_ct_pEp;
   8.162 -
   8.163 +    unsigned int max_version_major = 0;
   8.164 +    unsigned int max_version_minor = 0;
   8.165 +    pEp_version_major_minor(PEP_VERSION, &max_version_major, &max_version_minor);
   8.166 +    
   8.167      identity_list * _il = NULL;
   8.168  
   8.169      if (enc_format != PEP_enc_none && (_il = src->bcc) && _il->ident)
   8.170 @@ -1755,7 +1731,6 @@
   8.171      {
   8.172          //     - App splits mails with BCC in multiple mails.
   8.173          //     - Each email is encrypted separately
   8.174 -
   8.175          if(_il->next || (src->to && src->to->ident) || (src->cc && src->cc->ident))
   8.176          {
   8.177              // Only one Bcc with no other recipient allowed for now
   8.178 @@ -1769,6 +1744,12 @@
   8.179                  _il->ident->comm_type = PEP_ct_key_not_found;
   8.180                  _status = PEP_STATUS_OK;
   8.181              }
   8.182 +            // 0 unless set, so safe.
   8.183 +            
   8.184 +            set_min_version( _il->ident->major_ver, _il->ident->minor_ver, 
   8.185 +                             max_version_major, max_version_minor,
   8.186 +                             &max_version_major, &max_version_minor);
   8.187 +
   8.188              bool is_blacklisted = false;
   8.189              if (_il->ident->fpr && IS_PGP_CT(_il->ident->comm_type)) {
   8.190                  _status = blacklist_is_listed(session, _il->ident->fpr, &is_blacklisted);
   8.191 @@ -1794,6 +1775,7 @@
   8.192          }
   8.193          else
   8.194              _status = myself(session, _il->ident);
   8.195 +        
   8.196          if (_status != PEP_STATUS_OK) {
   8.197              status = PEP_UNENCRYPTED;
   8.198              goto pEp_error;
   8.199 @@ -1821,6 +1803,11 @@
   8.200                      _il->ident->comm_type = PEP_ct_key_not_found;
   8.201                      _status = PEP_STATUS_OK;
   8.202                  }
   8.203 +                // 0 unless set, so safe.
   8.204 +                set_min_version( _il->ident->major_ver, _il->ident->minor_ver, 
   8.205 +                                 max_version_major, max_version_minor,
   8.206 +                                 &max_version_major, &max_version_minor);
   8.207 +                
   8.208                  bool is_blacklisted = false;
   8.209                  if (_il->ident->fpr && IS_PGP_CT(_il->ident->comm_type)) {
   8.210                      _status = blacklist_is_listed(session, _il->ident->fpr, &is_blacklisted);
   8.211 @@ -1923,6 +1910,9 @@
   8.212              }
   8.213          }
   8.214      }
   8.215 +    
   8.216 +    if (max_version_major == 1)
   8.217 +        force_v_1 = true;
   8.218          
   8.219      if (enc_format == PEP_enc_none || !dest_keys_found ||
   8.220          stringlist_length(keys)  == 0 ||
   8.221 @@ -1938,10 +1928,15 @@
   8.222          return PEP_UNENCRYPTED;
   8.223      }
   8.224      else {
   8.225 +        // First, dedup the keylist
   8.226 +        if (keys && keys->next)
   8.227 +            dedup_stringlist(keys->next);
   8.228 +            
   8.229          // FIXME - we need to deal with transport types (via flag)
   8.230 +        message_wrap_type wrap_type = PEP_message_unwrapped;
   8.231          if ((enc_format != PEP_enc_inline) && (!force_v_1) && ((max_comm_type | PEP_ct_confirmed) == PEP_ct_pEp)) {
   8.232 -            message_wrap_type wrap_type = ((flags & PEP_encrypt_flag_key_reset_only) ? PEP_message_key_reset : PEP_message_default);
   8.233 -            _src = wrap_message_as_attachment(NULL, src, wrap_type, false);
   8.234 +            wrap_type = ((flags & PEP_encrypt_flag_key_reset_only) ? PEP_message_key_reset : PEP_message_default);
   8.235 +            _src = wrap_message_as_attachment(NULL, src, wrap_type, false, max_version_major, max_version_minor);
   8.236              if (!_src)
   8.237                  goto pEp_error;
   8.238          }
   8.239 @@ -1965,7 +1960,7 @@
   8.240          switch (enc_format) {
   8.241              case PEP_enc_PGP_MIME:
   8.242              case PEP_enc_PEP: // BUG: should be implemented extra
   8.243 -                status = encrypt_PGP_MIME(session, _src, keys, msg, flags);
   8.244 +                status = encrypt_PGP_MIME(session, _src, keys, msg, flags, wrap_type);
   8.245                  break;
   8.246  
   8.247              case PEP_enc_inline:
   8.248 @@ -2287,7 +2282,9 @@
   8.249      // if (!(flags & PEP_encrypt_flag_force_no_attached_key))
   8.250      //     _attach_key(session, target_fpr, src);
   8.251  
   8.252 -    _src = wrap_message_as_attachment(NULL, src, PEP_message_default, false);
   8.253 +    unsigned int major_ver, minor_ver;
   8.254 +    pEp_version_major_minor(PEP_VERSION, &major_ver, &minor_ver);
   8.255 +    _src = wrap_message_as_attachment(NULL, src, PEP_message_default, false, major_ver, minor_ver);
   8.256      if (!_src)
   8.257          goto pEp_error;
   8.258  
   8.259 @@ -2298,7 +2295,7 @@
   8.260      switch (enc_format) {
   8.261          case PEP_enc_PGP_MIME:
   8.262          case PEP_enc_PEP: // BUG: should be implemented extra
   8.263 -            status = encrypt_PGP_MIME(session, _src, keys, msg, flags);
   8.264 +            status = encrypt_PGP_MIME(session, _src, keys, msg, flags, PEP_message_default);
   8.265              if (status == PEP_STATUS_OK || (src->longmsg && strstr(src->longmsg, "INNER")))
   8.266                  _cleanup_src(src, false);
   8.267              break;
   8.268 @@ -3016,11 +3013,28 @@
   8.269      return status;
   8.270  }
   8.271  
   8.272 +// ident is in_only and should have been updated
   8.273 +static PEP_STATUS pEp_version_upgrade_or_ignore(
   8.274 +        PEP_SESSION session,
   8.275 +        pEp_identity* ident,
   8.276 +        unsigned int major,
   8.277 +        unsigned int minor) {
   8.278 +            
   8.279 +    PEP_STATUS status = PEP_STATUS_OK;        
   8.280 +    int ver_compare = compare_versions(major, minor, ident->major_ver, ident->minor_ver);
   8.281 +    if (ver_compare > 0)
   8.282 +        status = set_pEp_version(session, ident, major, minor);        
   8.283 +    
   8.284 +    return status;    
   8.285 +}
   8.286 +
   8.287  // FIXME: myself ??????
   8.288  static PEP_STATUS update_sender_to_pEp_trust(
   8.289          PEP_SESSION session, 
   8.290          pEp_identity* sender, 
   8.291 -        stringlist_t* keylist) 
   8.292 +        stringlist_t* keylist,
   8.293 +        unsigned int major,
   8.294 +        unsigned int minor) 
   8.295  {
   8.296      assert(session);
   8.297      assert(sender);
   8.298 @@ -3031,9 +3045,11 @@
   8.299          
   8.300      free(sender->fpr);
   8.301      sender->fpr = NULL;
   8.302 -    
   8.303 -    PEP_STATUS status = 
   8.304 -            is_me(session, sender) ? myself(session, sender) : update_identity(session, sender);
   8.305 +
   8.306 +    PEP_STATUS status = PEP_STATUS_OK;
   8.307 +
   8.308 +    // Seems status doesn't matter
   8.309 +    is_me(session, sender) ? myself(session, sender) : update_identity(session, sender);
   8.310  
   8.311      if (EMPTYSTR(sender->fpr) || strcmp(sender->fpr, keylist->value) != 0) {
   8.312          free(sender->fpr);
   8.313 @@ -3058,11 +3074,21 @@
   8.314      
   8.315      // Could be done elegantly, but we do this explicitly here for readability.
   8.316      // This file's code is difficult enough to parse. But change at will.
   8.317 -    switch (sender->comm_type) {
   8.318 +    switch (sender->comm_type) {            
   8.319          case PEP_ct_OpenPGP_unconfirmed:
   8.320          case PEP_ct_OpenPGP:
   8.321              sender->comm_type = PEP_ct_pEp_unconfirmed | (sender->comm_type & PEP_ct_confirmed);
   8.322              status = set_trust(session, sender);
   8.323 +            if (status != PEP_STATUS_OK)
   8.324 +                break;
   8.325 +        case PEP_ct_pEp:
   8.326 +        case PEP_ct_pEp_unconfirmed:
   8.327 +            // set version
   8.328 +            if (major == 0) {
   8.329 +                major = 2;
   8.330 +                minor = 0;
   8.331 +            }
   8.332 +            status = pEp_version_upgrade_or_ignore(session, sender, major, minor);    
   8.333              break;
   8.334          default:
   8.335              status = PEP_CANNOT_SET_TRUST;
   8.336 @@ -3365,7 +3391,9 @@
   8.337      char* signer_fpr = NULL;
   8.338      bool is_pEp_msg = is_a_pEpmessage(src);
   8.339      bool myself_read_only = (src->dir == PEP_dir_incoming);
   8.340 -
   8.341 +    unsigned int major_ver;
   8.342 +    unsigned int minor_ver;
   8.343 +    
   8.344      // Grab input flags
   8.345      bool reencrypt = (((*flags & PEP_decrypt_flag_untrusted_server) > 0) && *keylist && !EMPTYSTR((*keylist)->value));
   8.346      
   8.347 @@ -3381,34 +3409,39 @@
   8.348      *keylist = NULL;
   8.349      *rating = PEP_rating_undefined;
   8.350  //    *flags = 0;
   8.351 -    
   8.352 +
   8.353      /*** End init ***/
   8.354  
   8.355 -    // Ok, before we do anything, if it's a pEp message, regardless of whether it's
   8.356 +    // KB: FIXME - we should do this once we've seen an inner message in the case 
   8.357 +    // of pEp users. Since we've not used 1.0 in a billion years (but will receive 
   8.358 +    // 1.0 messages from pEp users who don't yet know WE are pEp users), we should 
   8.359 +    // sort this out sanely, not upfront.
   8.360 +    //
   8.361 +    // Was: Ok, before we do anything, if it's a pEp message, regardless of whether it's
   8.362      // encrypted or not, we set the sender as a pEp user. This has NOTHING to do
   8.363      // with the key.
   8.364 -    if (src->from && !(is_me(session, src->from))) {
   8.365 -        if (is_pEp_msg) {
   8.366 -            pEp_identity* tmp_from = src->from;
   8.367 -            
   8.368 -            // Ensure there's a user id
   8.369 -            if (EMPTYSTR(tmp_from->user_id) && tmp_from->address) {
   8.370 -                status = update_identity(session, tmp_from);
   8.371 -                if (status == PEP_CANNOT_FIND_IDENTITY) {
   8.372 -                    tmp_from->user_id = calloc(1, strlen(tmp_from->address) + 6);
   8.373 -                    if (!tmp_from->user_id)
   8.374 -                        return PEP_OUT_OF_MEMORY;
   8.375 -                    snprintf(tmp_from->user_id, strlen(tmp_from->address) + 6,
   8.376 -                             "TOFU_%s", tmp_from->address);        
   8.377 -                    status = PEP_STATUS_OK;
   8.378 -                }
   8.379 -            }
   8.380 -            if (status == PEP_STATUS_OK) {
   8.381 -                // Now set user as PEP (may also create an identity if none existed yet)
   8.382 -                status = set_as_pEp_user(session, tmp_from);
   8.383 -            }
   8.384 -        }
   8.385 -    }
   8.386 +    // if (src->from && !(is_me(session, src->from))) {
   8.387 +    //     if (is_pEp_msg) {
   8.388 +    //         pEp_identity* tmp_from = src->from;
   8.389 +    // 
   8.390 +    //         // Ensure there's a user id
   8.391 +    //         if (EMPTYSTR(tmp_from->user_id) && tmp_from->address) {
   8.392 +    //             status = update_identity(session, tmp_from);
   8.393 +    //             if (status == PEP_CANNOT_FIND_IDENTITY) {
   8.394 +    //                 tmp_from->user_id = calloc(1, strlen(tmp_from->address) + 6);
   8.395 +    //                 if (!tmp_from->user_id)
   8.396 +    //                     return PEP_OUT_OF_MEMORY;
   8.397 +    //                 snprintf(tmp_from->user_id, strlen(tmp_from->address) + 6,
   8.398 +    //                          "TOFU_%s", tmp_from->address);        
   8.399 +    //                 status = PEP_STATUS_OK;
   8.400 +    //             }
   8.401 +    //         }
   8.402 +    //         if (status == PEP_STATUS_OK) {
   8.403 +    //             // Now set user as PEP (may also create an identity if none existed yet)
   8.404 +    //             status = set_as_pEp_user(session, tmp_from);
   8.405 +    //         }
   8.406 +    //     }
   8.407 +    // }
   8.408      // We really need key used in signing to do anything further on the pEp comm_type.
   8.409      // So we can't adjust the rating of the sender just yet.
   8.410  
   8.411 @@ -3425,16 +3458,16 @@
   8.412      import_header_keys(session, src);
   8.413      
   8.414      // FIXME: is this really necessary here?
   8.415 -    if (src->from) {
   8.416 -        if (!is_me(session, src->from))
   8.417 -            status = update_identity(session, src->from);
   8.418 -        else
   8.419 -            status = _myself(session, src->from, false, false, myself_read_only);
   8.420 -        
   8.421 -        // We absolutely should NOT be bailing here unless it's a serious error
   8.422 -        if (status == PEP_OUT_OF_MEMORY)
   8.423 -            return status;
   8.424 -    }
   8.425 +    // if (src->from) {
   8.426 +    //     if (!is_me(session, src->from))
   8.427 +    //         status = update_identity(session, src->from);
   8.428 +    //     else
   8.429 +    //         status = _myself(session, src->from, false, false, myself_read_only);
   8.430 +    // 
   8.431 +    //     // We absolutely should NOT be bailing here unless it's a serious error
   8.432 +    //     if (status == PEP_OUT_OF_MEMORY)
   8.433 +    //         return status;
   8.434 +    // }
   8.435      
   8.436      /*** End Import any attached public keys and update identities accordingly ***/
   8.437      
   8.438 @@ -3483,6 +3516,7 @@
   8.439      decrypt_status = status;
   8.440      
   8.441      bool imported_private_key_address = false;
   8.442 +    bool has_inner = false;
   8.443  
   8.444      if (ptext) { 
   8.445          /* we got a plaintext from decryption */
   8.446 @@ -3491,7 +3525,7 @@
   8.447              case PEP_enc_PGP_MIME:
   8.448              case PEP_enc_PGP_MIME_Outlook1:
   8.449              
   8.450 -                status = mime_decode_message(ptext, psize, &msg);
   8.451 +                status = mime_decode_message(ptext, psize, &msg, &has_inner);
   8.452                  if (status != PEP_STATUS_OK)
   8.453                      goto pEp_error;
   8.454                  
   8.455 @@ -3567,136 +3601,212 @@
   8.456          if (decrypt_status == PEP_DECRYPTED || decrypt_status == PEP_DECRYPTED_AND_VERIFIED) {
   8.457              char* wrap_info = NULL;
   8.458              
   8.459 -            status = unencapsulate_hidden_fields(src, msg, &wrap_info);
   8.460 +            if (!has_inner) {
   8.461 +                status = unencapsulate_hidden_fields(src, msg, &wrap_info);
   8.462 +                if (status == PEP_OUT_OF_MEMORY)
   8.463 +                    goto enomem;                
   8.464 +                if (status != PEP_STATUS_OK)
   8.465 +                    goto pEp_error;
   8.466 +            }        
   8.467  
   8.468  //            bool is_transport_wrapper = false;
   8.469              
   8.470 +        
   8.471              // FIXME: replace with enums, check status
   8.472 -            if (wrap_info) {
   8.473 -                if (strcmp(wrap_info, "OUTER") == 0) {
   8.474 -                    // this only occurs in with a direct outer wrapper
   8.475 -                    // where the actual content is in the inner wrapper
   8.476 -                    message* inner_message = NULL;                    
   8.477 +            if (has_inner || wrap_info) { // Given that only wrap_info OUTER happens as of the end of wrap_info use, we don't need to strcmp it
   8.478 +                // if (strcmp(wrap_info, "OUTER") == 0) {
   8.479 +                //     // this only occurs in with a direct outer wrapper
   8.480 +                //     // where the actual content is in the inner wrapper
   8.481 +                message* inner_message = NULL;
   8.482 +                    
   8.483 +                // For a wrapped message, this is ALWAYS the second attachment; the 
   8.484 +                // mime tree is:
   8.485 +                // multipart/mixed
   8.486 +                //     |
   8.487 +                //     |----- text/plain 
   8.488 +                //     |----- message/rfc822
   8.489 +                //     |----- ...
   8.490 +                //
   8.491 +                // We leave this in below, but once we're rid of 2.0 format,
   8.492 +                // we can dispense with the loop, as has_inner -> 1st message struct attachment is message/rfc822
   8.493 +                //                   
   8.494 +
   8.495 +                bloblist_t* message_blob = msg->attachments;
   8.496 +                                    
   8.497 +                if (msg->attachments) {
   8.498 +                    message_blob = msg->attachments;
   8.499 +                    if (!has_inner && strcmp(message_blob->mime_type, "message/rfc822") != 0
   8.500 +                                   && strcmp(message_blob->mime_type, "text/rfc822") != 0)
   8.501 +                        message_blob = NULL;
   8.502 +                }
   8.503 +                    
   8.504 +                if (!message_blob) {
   8.505                      bloblist_t* actual_message = msg->attachments;
   8.506 -                    
   8.507 +                
   8.508                      while (actual_message) {
   8.509                          char* mime_type = actual_message->mime_type;
   8.510                          if (mime_type) {
   8.511 -                            
   8.512 +                        
   8.513                              // libetpan appears to change the mime_type on this one.
   8.514                              // *growl*
   8.515                              if (strcmp("message/rfc822", mime_type) == 0 ||
   8.516                                  strcmp("text/rfc822", mime_type) == 0) {
   8.517 -                                    
   8.518 -                                status = mime_decode_message(actual_message->value, 
   8.519 -                                                             actual_message->size, 
   8.520 -                                                             &inner_message);
   8.521 -                                if (status != PEP_STATUS_OK)
   8.522 -                                    goto pEp_error;
   8.523 -                                
   8.524 -                                if (inner_message) {
   8.525 -                                    // Though this will strip any message info on the
   8.526 -                                    // attachment, this is safe, as we do not
   8.527 -                                    // produce more than one attachment-as-message,
   8.528 -                                    // and those are the only ones with such info.
   8.529 -                                    // Since we capture the information, this is ok.
   8.530 -                                    wrap_info = NULL;
   8.531 -                                    inner_message->enc_format = src->enc_format;
   8.532 -                                    // FIXME
   8.533 -                                    status = unencapsulate_hidden_fields(inner_message, NULL, &wrap_info);
   8.534 -                                    
   8.535 -                                    // ?
   8.536 -                                    if (status != PEP_STATUS_OK) {
   8.537 -                                        free_message(inner_message);
   8.538 -                                        goto pEp_error;
   8.539 -                                    }
   8.540 -    
   8.541 -                                    if (wrap_info) {
   8.542 -                                        bool is_inner = (strcmp(wrap_info, "INNER") == 0);
   8.543 -                                        bool is_key_reset = (strcmp(wrap_info, "KEY_RESET") == 0);
   8.544 -
   8.545 -                                        if (is_key_reset) {
   8.546 -                                            if (decrypt_status == PEP_DECRYPTED || decrypt_status == PEP_DECRYPTED_AND_VERIFIED) {
   8.547 -                                                status = receive_key_reset(session,
   8.548 -                                                                           inner_message);
   8.549 -                                                if (status != PEP_STATUS_OK) {
   8.550 -                                                    free_message(inner_message);
   8.551 -                                                    goto pEp_error;
   8.552 -                                                }
   8.553 -                                                *flags |= PEP_decrypt_flag_consume;
   8.554 -                                            }
   8.555 -                                        }
   8.556 -                                        else if (is_inner) {
   8.557 -
   8.558 -                                            // check for private key in decrypted message attachment while importing
   8.559 -                                            // N.B. Apparently, we always import private keys into the keyring; however,
   8.560 -                                            // we do NOT always allow those to be used for encryption. THAT is controlled
   8.561 -                                            // by setting it as an own identity associated with the key in the DB.
   8.562 -                                            
   8.563 -                                            // If we have a message 2.0 message, we are ONLY going to be ok with keys
   8.564 -                                            // we imported from THIS part of the message.
   8.565 -                                            imported_private_key_address = false;
   8.566 -                                            free(private_il); 
   8.567 -                                            private_il = NULL;
   8.568 -                                            
   8.569 -                                            // import keys from decrypted INNER source
   8.570 -                                            status = import_priv_keys_from_decrypted_msg(session, inner_message,
   8.571 -                                                                                         &imported_keys,
   8.572 -                                                                                         &imported_private_key_address,
   8.573 -                                                                                         private_il);
   8.574 -                                            if (status != PEP_STATUS_OK)
   8.575 -                                                goto pEp_error;            
   8.576 -
   8.577 -                                            // THIS is our message
   8.578 -                                            // Now, let's make sure we've copied in 
   8.579 -                                            // any information sent in by the app if
   8.580 -                                            // needed...
   8.581 -                                            reconcile_src_and_inner_messages(src, inner_message);
   8.582 -                                            
   8.583 -
   8.584 -                                            // FIXME: free msg, but check references
   8.585 -                                            //src = msg = inner_message;
   8.586 -                                            calculated_src = msg = inner_message;
   8.587 -                                            
   8.588 -                                            // FIXME: should this be msg???
   8.589 -                                            if (src->from) {
   8.590 -                                                if (!is_me(session, src->from))
   8.591 -                                                    update_identity(session, (src->from));
   8.592 -                                                else
   8.593 -                                                    _myself(session, src->from, false, false, myself_read_only);
   8.594 -                                            }
   8.595 -                                            break;        
   8.596 -                                        }
   8.597 -                                        else { // should never happen
   8.598 -                                            status = PEP_UNKNOWN_ERROR;
   8.599 -                                            free_message(inner_message);
   8.600 -                                            goto pEp_error;
   8.601 -                                        }
   8.602 -                                    }
   8.603 -                                    inner_message->enc_format = PEP_enc_none;
   8.604 -                                }
   8.605 -                                else { // forwarded message, leave it alone
   8.606 -                                    free_message(inner_message);
   8.607 -                                }
   8.608 +                                message_blob = actual_message;
   8.609 +                                break;
   8.610                              }
   8.611                          }
   8.612                          actual_message = actual_message->next;
   8.613 -                    }                    
   8.614 +                    }        
   8.615 +                }    
   8.616 +                if (message_blob) {              
   8.617 +                    status = mime_decode_message(message_blob->value, 
   8.618 +                                                 message_blob->size, 
   8.619 +                                                 &inner_message,
   8.620 +                                                 NULL);
   8.621 +                    if (status != PEP_STATUS_OK)
   8.622 +                        goto pEp_error;
   8.623 +                                
   8.624 +                    if (inner_message) {
   8.625 +                        is_pEp_msg = is_a_pEpmessage(inner_message);
   8.626 +                        
   8.627 +                        // Though this will strip any message info on the
   8.628 +                        // attachment, this is safe, as we do not
   8.629 +                        // produce more than one attachment-as-message,
   8.630 +                        // and those are the only ones with such info.
   8.631 +                        // Since we capture the information, this is ok.
   8.632 +                        wrap_info = NULL;
   8.633 +                        inner_message->enc_format = src->enc_format;
   8.634 +
   8.635 +                        const stringpair_list_t* pEp_protocol_version = NULL;
   8.636 +                        pEp_protocol_version = stringpair_list_find(inner_message->opt_fields, "X-pEp-Version");
   8.637 +                        
   8.638 +                        if (pEp_protocol_version && pEp_protocol_version->value)
   8.639 +                            pEp_version_major_minor(pEp_protocol_version->value->value, &major_ver, &minor_ver);
   8.640 +
   8.641 +                        // Sort out pEp user status and version number based on INNER message.
   8.642 +                        
   8.643 +                        bool is_inner = false;
   8.644 +                        bool is_key_reset = false;
   8.645 +
   8.646 +                        // Deal with plaintext modification in 1.0 and 2.0 messages
   8.647 +                        status = unencapsulate_hidden_fields(inner_message, NULL, &wrap_info);   
   8.648 +                        
   8.649 +                        if (status == PEP_OUT_OF_MEMORY)
   8.650 +                            goto enomem;                
   8.651 +                        if (status != PEP_STATUS_OK)
   8.652 +                            goto pEp_error;                                         
   8.653 +                            
   8.654 +                        if (major_ver > 2 || (major_ver == 2 && minor_ver > 0)) {
   8.655 +                            stringpair_list_t* searched = stringpair_list_find(inner_message->opt_fields, "X-pEp-Sender-FPR");                             
   8.656 +                            inner_message->_sender_fpr = ((searched && searched->value && searched->value->value) ? strdup(searched->value->value) : NULL);
   8.657 +                            searched = stringpair_list_find(inner_message->opt_fields, X_PEP_MSG_WRAP_KEY);
   8.658 +                            if (searched && searched->value && searched->value->value) {
   8.659 +                                is_inner = (strcmp(searched->value->value, "INNER") == 0);
   8.660 +                                if (!is_inner)
   8.661 +                                    is_key_reset = (strcmp(searched->value->value, "KEY_RESET") == 0);
   8.662 +                                if (is_inner || is_key_reset)
   8.663 +                                    inner_message->opt_fields = stringpair_list_delete_by_key(inner_message->opt_fields, X_PEP_MSG_WRAP_KEY);
   8.664 +                            }
   8.665 +                        }
   8.666 +                        else {
   8.667 +                            is_inner = (strcmp(wrap_info, "INNER") == 0);
   8.668 +                            if (!is_inner)
   8.669 +                                is_key_reset = (strcmp(wrap_info, "KEY_RESET") == 0);
   8.670 +                        }
   8.671 +                            
   8.672 +
   8.673 +                        if (is_key_reset) {
   8.674 +                            if (decrypt_status == PEP_DECRYPTED || decrypt_status == PEP_DECRYPTED_AND_VERIFIED) {
   8.675 +                                status = receive_key_reset(session,
   8.676 +                                                           inner_message);
   8.677 +                                if (status != PEP_STATUS_OK) {
   8.678 +                                    free_message(inner_message);
   8.679 +                                    goto pEp_error;
   8.680 +                                }
   8.681 +                                *flags |= PEP_decrypt_flag_consume;
   8.682 +                            }
   8.683 +                        }
   8.684 +                        else if (is_inner) {
   8.685 +
   8.686 +                            // check for private key in decrypted message attachment while importing
   8.687 +                            // N.B. Apparently, we always import private keys into the keyring; however,
   8.688 +                            // we do NOT always allow those to be used for encryption. THAT is controlled
   8.689 +                            // by setting it as an own identity associated with the key in the DB.
   8.690 +                            
   8.691 +                            // If we have a message 2.0 message, we are ONLY going to be ok with keys
   8.692 +                            // we imported from THIS part of the message.
   8.693 +                            imported_private_key_address = false;
   8.694 +                            free(private_il); 
   8.695 +                            private_il = NULL;
   8.696 +                            
   8.697 +                            // import keys from decrypted INNER source
   8.698 +                            status = import_priv_keys_from_decrypted_msg(session, inner_message,
   8.699 +                                                                         &imported_keys,
   8.700 +                                                                         &imported_private_key_address,
   8.701 +                                                                         private_il);
   8.702 +                            if (status != PEP_STATUS_OK)
   8.703 +                                goto pEp_error;            
   8.704 +
   8.705 +                            // THIS is our message
   8.706 +                            // Now, let's make sure we've copied in 
   8.707 +                            // any information sent in by the app if
   8.708 +                            // needed...
   8.709 +                            reconcile_src_and_inner_messages(src, inner_message);
   8.710 +                            
   8.711 +
   8.712 +                            // FIXME: free msg, but check references
   8.713 +                            //src = msg = inner_message;
   8.714 +                            calculated_src = msg = inner_message;
   8.715 +                            
   8.716 +                        }
   8.717 +                        else { // should never happen
   8.718 +                            status = PEP_UNKNOWN_ERROR;
   8.719 +                            free_message(inner_message);
   8.720 +                            goto pEp_error;
   8.721 +                        }
   8.722 +                        inner_message->enc_format = PEP_enc_none;
   8.723 +                    }
   8.724 +                    else { // forwarded message, leave it alone
   8.725 +                        free_message(inner_message);
   8.726 +                    }
   8.727 +                } // end if (message_blob)
   8.728 +                
   8.729 +                //  else if (strcmp(wrap_info, "TRANSPORT") == 0) {
   8.730 +                //      // FIXME: this gets even messier.
   8.731 +                //      // (TBI in ENGINE-278)
   8.732 +                //  }
   8.733 +                //  else {} // shouldn't be anything to be done here
   8.734 +    
   8.735 +            } // end if (has_inner || wrap_info)
   8.736 +            else {
   8.737 +                
   8.738 +            } // this we do if this isn't an inner message
   8.739 +            
   8.740 +            pEp_identity* cs_from = calculated_src->from;
   8.741 +            if (cs_from && !EMPTYSTR(cs_from->address)) {
   8.742 +                if (!is_me(session, cs_from)) {
   8.743 +                    status = update_identity(session, cs_from);
   8.744 +                    if (status == PEP_CANNOT_FIND_IDENTITY) {
   8.745 +                        cs_from->user_id = calloc(1, strlen(cs_from->address) + 6);
   8.746 +                        if (!cs_from->user_id)
   8.747 +                            return PEP_OUT_OF_MEMORY;
   8.748 +                        snprintf(cs_from->user_id, strlen(cs_from->address) + 6,
   8.749 +                                 "TOFU_%s", cs_from->address);        
   8.750 +                        status = PEP_STATUS_OK;
   8.751 +                    }
   8.752                  }
   8.753 -                else if (strcmp(wrap_info, "TRANSPORT") == 0) {
   8.754 -                    // FIXME: this gets even messier.
   8.755 -                    // (TBI in ENGINE-278)
   8.756 -                }
   8.757 -                else {} // shouldn't be anything to be done here
   8.758 -            }
   8.759 -        }
   8.760 +                else
   8.761 +                    status = _myself(session, cs_from, false, false, myself_read_only);
   8.762 +            }                                                                        
   8.763 +        } // end if (decrypt_status == PEP_DECRYPTED || decrypt_status == PEP_DECRYPTED_AND_VERIFIED)
   8.764          
   8.765          *rating = decrypt_rating(decrypt_status);
   8.766          
   8.767          // Ok, so if it was signed and it's all verified, we can update
   8.768          // eligible signer comm_types to PEP_ct_pEp_*
   8.769 +        // This also sets and upgrades pEp version
   8.770          if (decrypt_status == PEP_DECRYPTED_AND_VERIFIED && is_pEp_msg && calculated_src->from)
   8.771 -            status = update_sender_to_pEp_trust(session, calculated_src->from, _keylist);
   8.772 +            status = update_sender_to_pEp_trust(session, calculated_src->from, _keylist, major_ver, minor_ver);
   8.773  
   8.774          /* Ok, now we have a keylist used for decryption/verification.
   8.775             now we need to update the message rating with the 
   8.776 @@ -3742,7 +3852,9 @@
   8.777  
   8.778      // 2. Clean up message and prepare for return 
   8.779      if (msg) {
   8.780 -        
   8.781 +        if (_keylist && _keylist->next)
   8.782 +            dedup_stringlist(_keylist->next);
   8.783 +            
   8.784          /* add pEp-related status flags to header */
   8.785          decorate_message(msg, *rating, _keylist, false, false);
   8.786  
   8.787 @@ -4068,7 +4180,7 @@
   8.788          *rating = PEP_rating_undefined;
   8.789      }
   8.790      else
   8.791 -        *rating = MAX(_rating(max_comm_type), PEP_rating_unencrypted);
   8.792 +        *rating = _MAX(_rating(max_comm_type), PEP_rating_unencrypted);
   8.793  
   8.794      return PEP_STATUS_OK;
   8.795  }
     9.1 --- a/src/message_api.h	Wed Aug 07 08:16:15 2019 +0200
     9.2 +++ b/src/message_api.h	Thu Aug 08 08:10:32 2019 +0200
     9.3 @@ -49,6 +49,7 @@
     9.4  typedef unsigned int PEP_encrypt_flags_t;
     9.5  
     9.6  typedef enum _message_wrap_type {
     9.7 +    PEP_message_unwrapped,  // 1.0 or anything we don't wrap    
     9.8      PEP_message_default,    // typical inner/outer message 2.0
     9.9      PEP_message_transport,  // e.g. for onion layers
    9.10      PEP_message_key_reset   // for wrapped key reset information
    10.1 --- a/src/mime.c	Wed Aug 07 08:16:15 2019 +0200
    10.2 +++ b/src/mime.c	Thu Aug 08 08:10:32 2019 +0200
    10.3 @@ -39,6 +39,5 @@
    10.4          char **mimetext
    10.5      )
    10.6  {
    10.7 -    return _mime_encode_message_internal(msg, omit_fields, mimetext, true);
    10.8 +    return _mime_encode_message_internal(msg, omit_fields, mimetext, true, false);
    10.9  }
   10.10 -
    11.1 --- a/src/mime.h	Wed Aug 07 08:16:15 2019 +0200
    11.2 +++ b/src/mime.h	Thu Aug 08 08:10:32 2019 +0200
    11.3 @@ -55,9 +55,10 @@
    11.4  // mime_decode_message() - decode a MIME message
    11.5  //
    11.6  //  parameters:
    11.7 -//      mimetext (in)           MIME encoded text to decode
    11.8 -//      size (in)               size of text to decode
    11.9 -//      msg (out)               decoded message
   11.10 +//      mimetext (in)           	MIME encoded text to decode
   11.11 +//      size (in)               	size of text to decode
   11.12 +//      msg (out)               	decoded message
   11.13 +//      raise_msg_attachment (out)		
   11.14  //
   11.15  //  return value:
   11.16  //      PEP_STATUS_OK           if everything worked
   11.17 @@ -75,7 +76,8 @@
   11.18  DYNAMIC_API PEP_STATUS mime_decode_message(
   11.19          const char *mimetext,
   11.20          size_t size,
   11.21 -        message **msg
   11.22 +        message **msg,
   11.23 +        bool* raise_msg_attachment
   11.24      );
   11.25  
   11.26  /* sometimes we don't want to transport encode */
   11.27 @@ -83,7 +85,8 @@
   11.28          const message * msg,
   11.29          bool omit_fields,
   11.30          char **mimetext,
   11.31 -        bool transport_encode
   11.32 +        bool transport_encode,
   11.33 +        bool set_attachment_forward_comment        
   11.34      );
   11.35  
   11.36  
    12.1 --- a/src/pEpEngine.c	Wed Aug 07 08:16:15 2019 +0200
    12.2 +++ b/src/pEpEngine.c	Thu Aug 08 08:10:32 2019 +0200
    12.3 @@ -83,7 +83,7 @@
    12.4  static const char *sql_get_identity =  
    12.5      "select fpr, username, comm_type, lang,"
    12.6      "   identity.flags | pgp_keypair.flags,"
    12.7 -    "   is_own"
    12.8 +    "   is_own, pEp_version_major, pEp_version_minor"
    12.9      "   from identity"
   12.10      "   join person on id = identity.user_id"
   12.11      "   join pgp_keypair on fpr = identity.main_key_id"
   12.12 @@ -101,7 +101,7 @@
   12.13  static const char *sql_get_identities_by_main_key_id =  
   12.14      "select address, identity.user_id, username, comm_type, lang,"
   12.15      "   identity.flags | pgp_keypair.flags,"
   12.16 -    "   is_own"
   12.17 +    "   is_own, pEp_version_major, pEp_version_minor"
   12.18      "   from identity"
   12.19      "   join person on id = identity.user_id"
   12.20      "   join pgp_keypair on fpr = identity.main_key_id"
   12.21 @@ -113,7 +113,7 @@
   12.22  
   12.23  static const char *sql_get_identity_without_trust_check =  
   12.24      "select identity.main_key_id, username, lang,"
   12.25 -    "   identity.flags, is_own"
   12.26 +    "   identity.flags, is_own, pEp_version_major, pEp_version_minor"
   12.27      "   from identity"
   12.28      "   join person on id = identity.user_id"
   12.29      "   where (case when (address = ?1) then (1)"
   12.30 @@ -127,7 +127,7 @@
   12.31  
   12.32  static const char *sql_get_identities_by_address =  
   12.33      "select user_id, identity.main_key_id, username, lang,"
   12.34 -    "   identity.flags, is_own"
   12.35 +    "   identity.flags, is_own, pEp_version_major, pEp_version_minor"
   12.36      "   from identity"
   12.37      "   join person on id = identity.user_id"
   12.38      "   where (case when (address = ?1) then (1)"
   12.39 @@ -141,7 +141,7 @@
   12.40  static const char *sql_get_identities_by_userid =  
   12.41      "select address, fpr, username, comm_type, lang,"
   12.42      "   identity.flags | pgp_keypair.flags,"
   12.43 -    "   is_own"
   12.44 +    "   is_own, pEp_version_major, pEp_version_minor"
   12.45      "   from identity"
   12.46      "   join person on id = identity.user_id"
   12.47      "   join pgp_keypair on fpr = identity.main_key_id"
   12.48 @@ -239,20 +239,25 @@
   12.49  static const char *sql_set_identity_entry = 
   12.50      "insert into identity ("
   12.51      "       address, main_key_id, "
   12.52 -    "       user_id, flags, is_own"
   12.53 +    "       user_id, flags, is_own,"
   12.54 +    "       pEp_version_major, pEp_version_minor"
   12.55      "   ) values ("
   12.56      "       ?1,"
   12.57      "       upper(replace(?2,' ','')),"
   12.58      "       ?3,"
   12.59      "       ?4,"
   12.60 -    "       ?5"
   12.61 +    "       ?5,"
   12.62 +    "       ?6,"
   12.63 +    "       ?7"
   12.64      "   );";
   12.65      
   12.66  static const char* sql_update_identity_entry =    
   12.67      "update identity "
   12.68      "   set main_key_id = upper(replace(?2,' ','')), "
   12.69      "       flags = ?4, " 
   12.70 -    "       is_own = ?5 "
   12.71 +    "       is_own = ?5, "
   12.72 +    "       pEp_version_major = ?6, "
   12.73 +    "       pEp_version_major = ?7 "    
   12.74      "   where (case when (address = ?1) then (1)"
   12.75      "               when (lower(address) = lower(?1)) then (1)"
   12.76      "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1) "
   12.77 @@ -301,6 +306,28 @@
   12.78      "          end) = 1"
   12.79      "          and user_id = ?3 ;";
   12.80  
   12.81 +static const char *sql_set_pEp_version =
   12.82 +    "update identity "
   12.83 +    "   set pEp_version_major = ?1, "
   12.84 +    "       pEp_version_minor = ?2 "
   12.85 +    "   where (case when (address = ?3) then (1)"
   12.86 +    "               when (lower(address) = lower(?3)) then (1)"
   12.87 +    "               when (replace(lower(address),'.','') = replace(lower(?3),'.','')) then (1) "
   12.88 +    "               else 0 "
   12.89 +    "          end) = 1 "
   12.90 +    "          and user_id = ?4 ;";
   12.91 +
   12.92 +static const char *sql_upgrade_pEp_version_by_user_id =
   12.93 +    "update identity "
   12.94 +    "   set pEp_version_major = ?1, "
   12.95 +    "       pEp_version_minor = ?2 "
   12.96 +    "       where user_id = ?3 "
   12.97 +    "           and (case when (pEp_version_major < ?1) then (1)"
   12.98 +    "                     when (pEp_version_major > ?1) then (0)"
   12.99 +    "                     when (pEp_version_minor < ?2) then (1)"
  12.100 +    "                     else 0 "
  12.101 +    "           end) = 1 ;";
  12.102 +
  12.103  static const char *sql_set_trust =
  12.104      "insert into trust (user_id, pgp_keypair_fpr, comm_type) "
  12.105      "values (?1, upper(replace(?2,' ','')), ?3) ;";
  12.106 @@ -353,7 +380,7 @@
  12.107  
  12.108  static const char *sql_i18n_token = 
  12.109      "select phrase from i18n_token where lang = lower(?1) and id = ?2 ;";
  12.110 -
  12.111 +    
  12.112  // blacklist
  12.113  static const char *sql_blacklist_add = 
  12.114      "insert or ignore into blacklist_keys (fpr) values (upper(replace(?1,' ',''))) ;"
  12.115 @@ -393,7 +420,7 @@
  12.116  
  12.117  static const char *sql_own_identities_retrieve =  
  12.118      "select address, fpr, identity.user_id, username,"
  12.119 -    "   lang, identity.flags | pgp_keypair.flags"
  12.120 +    "   lang, identity.flags | pgp_keypair.flags, pEp_version_major, pEp_version_minor"
  12.121      "   from identity"
  12.122      "   join person on id = identity.user_id"
  12.123      "   join pgp_keypair on fpr = identity.main_key_id"
  12.124 @@ -965,6 +992,8 @@
  12.125                  "   comment text,\n"
  12.126                  "   flags integer default 0,\n"
  12.127                  "   is_own integer default 0,\n"
  12.128 +                "   pEp_version_major integer default 0,\n"
  12.129 +                "   pEp_version_minor integer default 0,\n"                
  12.130                  "   timestamp integer default (datetime('now')),\n"
  12.131                  "   primary key (address, user_id)\n"
  12.132                  ");\n"
  12.133 @@ -1071,7 +1100,10 @@
  12.134          // Sometimes the user_version wasn't set correctly. 
  12.135          if (version == 1) {
  12.136              bool version_changed = true;
  12.137 -            if (db_contains_table(_session, "social_graph") > 0) {
  12.138 +            if (table_contains_column(_session, "identity", "pEp_version_major")) {
  12.139 +                version = 12;
  12.140 +            }
  12.141 +            else if (db_contains_table(_session, "social_graph") > 0) {
  12.142                  if (!table_contains_column(_session, "person", "device_group"))
  12.143                      version = 10;
  12.144                  else
  12.145 @@ -1433,7 +1465,71 @@
  12.146                      NULL,
  12.147                      NULL
  12.148                  );
  12.149 -                assert(int_result == SQLITE_OK);                
  12.150 +                assert(int_result == SQLITE_OK);
  12.151 +                
  12.152 +                int_result = sqlite3_exec(
  12.153 +                    _session->db,
  12.154 +                    "alter table identity\n"
  12.155 +                    "   add column pEp_version_major integer default 0;\n"
  12.156 +                    "alter table identity\n"
  12.157 +                    "   add column pEp_version_minor integer default 0;\n",                    
  12.158 +                    NULL,
  12.159 +                    NULL,
  12.160 +                    NULL
  12.161 +                );
  12.162 +                if (status != PEP_STATUS_OK)
  12.163 +                    return status;  
  12.164 +      
  12.165 +                int_result = sqlite3_exec(
  12.166 +                    _session->db,
  12.167 +                    "update identity\n"
  12.168 +                    "   set pEp_version_major = 2\n"
  12.169 +                    "   where exists (select * from person\n"
  12.170 +                    "                     where identity.user_id = person.id\n"
  12.171 +                    "                     and identity.is_own = 0\n"
  12.172 +                    "                     and person.is_pEp_user = 1);\n",
  12.173 +                    NULL,
  12.174 +                    NULL,
  12.175 +                    NULL
  12.176 +                );
  12.177 +                if (status != PEP_STATUS_OK)
  12.178 +                    return status;  
  12.179 +                
  12.180 +                // N.B. WE DEFINE PEP_VERSION - IF WE'RE AT 9-DIGIT MAJOR OR MINOR VERSIONS, ER, BAD.
  12.181 +                char major_buf[10];
  12.182 +                char minor_buf[10];
  12.183 +                if (sscanf("%s.%s", major_buf, minor_buf) != 2)
  12.184 +                    return PEP_UNKNOWN_ERROR; // DO BETTER
  12.185 +                size_t major_len = strlen(major_buf);
  12.186 +                size_t minor_len = strlen(minor_buf);
  12.187 +                    
  12.188 +                const char* _ver_12_startstr =                     
  12.189 +                    "update identity\n"
  12.190 +                    "    set pEp_version_major = ";
  12.191 +                const char* _ver_12_midstr = ",\n"
  12.192 +                    "        pEp_version_minor = ";
  12.193 +                const char* _ver_12_endstr =     
  12.194 +                    "\n"
  12.195 +                    "    where identity.is_own = 1;\n";
  12.196 +                    
  12.197 +                size_t new_stringlen = strlen(_ver_12_startstr) + major_len +
  12.198 +                                       strlen(_ver_12_midstr) + minor_len +
  12.199 +                                       strlen(_ver_12_endstr);
  12.200 +                                       
  12.201 +                char* _ver_12_stmt = calloc(new_stringlen + 1, 1);
  12.202 +                snprintf(_ver_12_stmt, new_stringlen + 1, "%s%s%s%s%s",
  12.203 +                         _ver_12_startstr, major_buf, _ver_12_midstr, minor_buf, _ver_12_endstr);
  12.204 +                
  12.205 +                int_result = sqlite3_exec(
  12.206 +                    _session->db,
  12.207 +                    _ver_12_stmt,
  12.208 +                    NULL,
  12.209 +                    NULL,
  12.210 +                    NULL
  12.211 +                );
  12.212 +                free(_ver_12_stmt);
  12.213 +                if (status != PEP_STATUS_OK)
  12.214 +                    return status;                      
  12.215              }
  12.216          }        
  12.217          else { 
  12.218 @@ -1633,6 +1729,16 @@
  12.219              NULL);
  12.220      assert(int_result == SQLITE_OK);
  12.221  
  12.222 +    int_result = sqlite3_prepare_v2(_session->db, sql_set_pEp_version,
  12.223 +            (int)strlen(sql_set_pEp_version), &_session->set_pEp_version,
  12.224 +            NULL);
  12.225 +    assert(int_result == SQLITE_OK);
  12.226 +    
  12.227 +    int_result = sqlite3_prepare_v2(_session->db, sql_upgrade_pEp_version_by_user_id,
  12.228 +            (int)strlen(sql_upgrade_pEp_version_by_user_id), &_session->upgrade_pEp_version_by_user_id,
  12.229 +            NULL);
  12.230 +    assert(int_result == SQLITE_OK);
  12.231 +
  12.232      int_result = sqlite3_prepare_v2(_session->db, sql_set_trust,
  12.233              (int)strlen(sql_set_trust), &_session->set_trust, NULL);
  12.234      assert(int_result == SQLITE_OK);
  12.235 @@ -1873,6 +1979,8 @@
  12.236                  sqlite3_finalize(session->delete_person);                
  12.237              if (session->set_as_pEp_user)
  12.238                  sqlite3_finalize(session->set_as_pEp_user);
  12.239 +            if (session->upgrade_pEp_version_by_user_id)
  12.240 +                sqlite3_finalize(session->upgrade_pEp_version_by_user_id);
  12.241              if (session->is_pEp_user)
  12.242                  sqlite3_finalize(session->is_pEp_user);
  12.243              if (session->exists_person)
  12.244 @@ -1901,6 +2009,8 @@
  12.245                  sqlite3_finalize(session->set_identity_flags);
  12.246              if (session->unset_identity_flags)
  12.247                  sqlite3_finalize(session->unset_identity_flags);
  12.248 +            if (session->set_pEp_version)
  12.249 +                sqlite3_finalize(session->set_pEp_version);                
  12.250              if (session->exists_trust_entry)
  12.251                  sqlite3_finalize(session->exists_trust_entry);                                
  12.252              if (session->set_trust)
  12.253 @@ -2273,6 +2383,8 @@
  12.254      dup->lang[2] = 0;
  12.255      dup->flags = src->flags;
  12.256      dup->me = src->me;
  12.257 +    dup->major_ver = src->major_ver;
  12.258 +    dup->minor_ver = src->minor_ver;
  12.259      
  12.260      return dup;
  12.261  }
  12.262 @@ -2466,6 +2578,10 @@
  12.263              sqlite3_column_int(session->get_identity, 4);
  12.264          _identity->me = (unsigned int)
  12.265              sqlite3_column_int(session->get_identity, 5);
  12.266 +        _identity->major_ver =
  12.267 +            sqlite3_column_int(session->get_identity, 6);
  12.268 +        _identity->minor_ver =
  12.269 +            sqlite3_column_int(session->get_identity, 7);
  12.270      
  12.271          *identity = _identity;
  12.272          break;
  12.273 @@ -2540,6 +2656,10 @@
  12.274              sqlite3_column_int(session->get_identities_by_userid, 5);
  12.275          ident->me = (unsigned int)
  12.276              sqlite3_column_int(session->get_identities_by_userid, 6);
  12.277 +        ident->major_ver =
  12.278 +            sqlite3_column_int(session->get_identities_by_userid, 7);
  12.279 +        ident->minor_ver =
  12.280 +            sqlite3_column_int(session->get_identities_by_userid, 8);
  12.281      
  12.282          identity_list_add(*identities, ident);
  12.283          ident = NULL;
  12.284 @@ -2606,6 +2726,10 @@
  12.285              sqlite3_column_int(session->get_identities_by_main_key_id, 5);
  12.286          ident->me = (unsigned int)
  12.287              sqlite3_column_int(session->get_identities_by_main_key_id, 6);
  12.288 +        ident->major_ver =
  12.289 +            sqlite3_column_int(session->get_identities_by_main_key_id, 7);
  12.290 +        ident->minor_ver =
  12.291 +            sqlite3_column_int(session->get_identities_by_main_key_id, 8);
  12.292      
  12.293          identity_list_add(*identities, ident);
  12.294          ident = NULL;
  12.295 @@ -2676,6 +2800,10 @@
  12.296              sqlite3_column_int(session->get_identity_without_trust_check, 3);
  12.297          _identity->me = (unsigned int)
  12.298              sqlite3_column_int(session->get_identity_without_trust_check, 4);
  12.299 +        _identity->major_ver =
  12.300 +            sqlite3_column_int(session->get_identity_without_trust_check, 5);
  12.301 +        _identity->minor_ver =
  12.302 +            sqlite3_column_int(session->get_identity_without_trust_check, 6);
  12.303      
  12.304          *identity = _identity;
  12.305          break;
  12.306 @@ -2741,6 +2869,10 @@
  12.307              sqlite3_column_int(session->get_identities_by_address, 4);
  12.308          ident->me = (unsigned int)
  12.309              sqlite3_column_int(session->get_identities_by_address, 5);
  12.310 +        ident->major_ver =
  12.311 +            sqlite3_column_int(session->get_identities_by_address, 6);
  12.312 +        ident->minor_ver =
  12.313 +            sqlite3_column_int(session->get_identities_by_address, 7);
  12.314      
  12.315          if (ident_list)
  12.316              identity_list_add(ident_list, ident);
  12.317 @@ -2897,6 +3029,9 @@
  12.318              SQLITE_STATIC);
  12.319      sqlite3_bind_int(set_or_update, 4, identity->flags);
  12.320      sqlite3_bind_int(set_or_update, 5, identity->me);
  12.321 +    sqlite3_bind_int(set_or_update, 6, identity->major_ver);
  12.322 +    sqlite3_bind_int(set_or_update, 7, identity->minor_ver);
  12.323 +        
  12.324      int result = Sqlite3_step(set_or_update);
  12.325      sqlite3_reset(set_or_update);
  12.326      if (result != SQLITE_DONE)
  12.327 @@ -3010,7 +3145,7 @@
  12.328                                         guard_transaction);
  12.329  }
  12.330  
  12.331 -// This will NOT call set_as_pEp_user; you have to do that separately.
  12.332 +// This will NOT call set_as_pEp_user, nor set_pEp_version; you have to do that separately.
  12.333  DYNAMIC_API PEP_STATUS set_identity(
  12.334          PEP_SESSION session, const pEp_identity *identity
  12.335      )
  12.336 @@ -3077,6 +3212,12 @@
  12.337          }
  12.338      }
  12.339      
  12.340 +    status = set_pEp_version(session, ident_copy, ident_copy->major_ver, ident_copy->minor_ver);
  12.341 +    if (status != PEP_STATUS_OK) {
  12.342 +        sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  12.343 +        goto pEp_free;            
  12.344 +    }
  12.345 +    
  12.346      result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  12.347      if (result == SQLITE_OK)
  12.348          status = PEP_STATUS_OK;
  12.349 @@ -3101,7 +3242,9 @@
  12.350      if (result != SQLITE_DONE)
  12.351          return PEP_CANNOT_SET_TRUST;
  12.352  
  12.353 -    return PEP_STATUS_OK;
  12.354 +    PEP_STATUS status = upgrade_pEp_version_by_user_id(session, user, 2, 0);
  12.355 +    
  12.356 +    return status;
  12.357  }
  12.358  
  12.359  
  12.360 @@ -3142,6 +3285,54 @@
  12.361      return status;
  12.362  }
  12.363  
  12.364 +// This ONLY sets the version flag. Must be called outside of a transaction.
  12.365 +PEP_STATUS set_pEp_version(PEP_SESSION session, pEp_identity* ident, unsigned int new_ver_major, unsigned int new_ver_minor) {
  12.366 +    assert(session);
  12.367 +    assert(!EMPTYSTR(ident->user_id));
  12.368 +    assert(!EMPTYSTR(ident->address));
  12.369 +    
  12.370 +    sqlite3_reset(session->set_pEp_version);
  12.371 +    sqlite3_bind_double(session->set_pEp_version, 1, new_ver_major);
  12.372 +    sqlite3_bind_double(session->set_pEp_version, 2, new_ver_minor);    
  12.373 +    sqlite3_bind_text(session->set_pEp_version, 3, ident->address, -1,
  12.374 +            SQLITE_STATIC);
  12.375 +    sqlite3_bind_text(session->set_pEp_version, 4, ident->user_id, -1,
  12.376 +            SQLITE_STATIC);
  12.377 +    
  12.378 +    int result = Sqlite3_step(session->set_pEp_version);
  12.379 +    sqlite3_reset(session->set_pEp_version);
  12.380 +        
  12.381 +    if (result != SQLITE_DONE)
  12.382 +        return PEP_CANNOT_SET_PEP_VERSION;
  12.383 +    
  12.384 +    return PEP_STATUS_OK;
  12.385 +}
  12.386 +
  12.387 +// Generally ONLY called by set_as_pEp_user, and ONLY from < 2.0 to 2.0.
  12.388 +PEP_STATUS upgrade_pEp_version_by_user_id(PEP_SESSION session, 
  12.389 +        pEp_identity* ident, 
  12.390 +        unsigned int new_ver_major,
  12.391 +        unsigned int new_ver_minor
  12.392 +    ) 
  12.393 +{
  12.394 +    assert(session);
  12.395 +    assert(!EMPTYSTR(ident->user_id));
  12.396 +    
  12.397 +    sqlite3_reset(session->upgrade_pEp_version_by_user_id);
  12.398 +    sqlite3_bind_int(session->upgrade_pEp_version_by_user_id, 1, new_ver_major);
  12.399 +    sqlite3_bind_int(session->upgrade_pEp_version_by_user_id, 2, new_ver_minor);    
  12.400 +    sqlite3_bind_text(session->upgrade_pEp_version_by_user_id, 3, ident->user_id, -1,
  12.401 +            SQLITE_STATIC);
  12.402 +    
  12.403 +    int result = Sqlite3_step(session->upgrade_pEp_version_by_user_id);
  12.404 +    sqlite3_reset(session->upgrade_pEp_version_by_user_id);
  12.405 +        
  12.406 +    if (result != SQLITE_DONE)
  12.407 +        return PEP_CANNOT_SET_PEP_VERSION;
  12.408 +    
  12.409 +    return PEP_STATUS_OK;    
  12.410 +}
  12.411 +
  12.412  PEP_STATUS exists_person(PEP_SESSION session, pEp_identity* identity,
  12.413                           bool* exists) {            
  12.414      
    13.1 --- a/src/pEpEngine.h	Wed Aug 07 08:16:15 2019 +0200
    13.2 +++ b/src/pEpEngine.h	Thu Aug 08 08:10:32 2019 +0200
    13.3 @@ -17,7 +17,7 @@
    13.4  #include "labeled_int_list.h"    
    13.5  #include "timestamp.h"
    13.6  
    13.7 -#define PEP_VERSION "2.0" // protocol version
    13.8 +#define PEP_VERSION "2.1" // protocol version
    13.9  
   13.10  #define PEP_OWN_USERID "pEp_own_userId"
   13.11      
   13.12 @@ -69,6 +69,7 @@
   13.13      PEP_CANNOT_SET_TRUST                            = 0x0384,
   13.14      PEP_KEY_BLACKLISTED                             = 0x0385,
   13.15      PEP_CANNOT_FIND_PERSON                          = 0x0386,
   13.16 +    PEP_CANNOT_SET_PEP_VERSION                      = 0X0387,
   13.17      
   13.18      PEP_CANNOT_FIND_ALIAS                           = 0x0391,
   13.19      PEP_CANNOT_SET_ALIAS                            = 0x0392,
   13.20 @@ -597,6 +598,8 @@
   13.21      char lang[3];               // language of conversation
   13.22                                  // ISO 639-1 ALPHA-2, last byte is 0
   13.23      bool me;                    // if this is the local user herself/himself
   13.24 +    int major_ver;              // highest version of pEp message received, if any
   13.25 +    int minor_ver;              // highest version of pEp message received, if any
   13.26      identity_flags_t flags;     // identity_flag1 | identity_flag2 | ...
   13.27  } pEp_identity;
   13.28  
   13.29 @@ -1354,6 +1357,15 @@
   13.30  
   13.31  PEP_STATUS set_pgp_keypair(PEP_SESSION session, const char* fpr);
   13.32  
   13.33 +PEP_STATUS set_pEp_version(PEP_SESSION session, pEp_identity* ident, unsigned int new_ver_major, unsigned int new_ver_minor);
   13.34 +
   13.35 +// Generally ONLY called by set_as_pEp_user, and ONLY from < 2.0 to 2.0.
   13.36 +PEP_STATUS upgrade_pEp_version_by_user_id(PEP_SESSION session, 
   13.37 +        pEp_identity* ident, 
   13.38 +        unsigned int new_ver_major,
   13.39 +        unsigned int new_ver_minor
   13.40 +    );
   13.41 +     
   13.42  // exposed for testing
   13.43  PEP_STATUS set_person(PEP_SESSION session, pEp_identity* identity,
   13.44                        bool guard_transaction);
    14.1 --- a/src/pEp_internal.h	Wed Aug 07 08:16:15 2019 +0200
    14.2 +++ b/src/pEp_internal.h	Thu Aug 08 08:10:32 2019 +0200
    14.3 @@ -51,7 +51,14 @@
    14.4  #define PEP_MSG_WRAP_KEY_LEN 26
    14.5  #endif
    14.6  
    14.7 +#ifndef X_PEP_MSG_WRAP_KEY
    14.8 +#define X_PEP_MSG_WRAP_KEY "X-pEp-Wrapped-Message-Info"
    14.9 +#endif
   14.10  
   14.11 +#ifndef X_PEP_SNDR_FPR_KEY
   14.12 +#define X_PEP_SNDR_FPR_KEY "X-pEp-Sender-FPR"
   14.13 +#endif
   14.14 + 
   14.15  #include "platform.h"
   14.16  
   14.17  #ifdef WIN32
   14.18 @@ -176,6 +183,7 @@
   14.19      sqlite3_stmt *exists_person;    
   14.20      sqlite3_stmt *set_as_pEp_user;
   14.21      sqlite3_stmt *is_pEp_user;
   14.22 +    sqlite3_stmt *upgrade_pEp_version_by_user_id;
   14.23      sqlite3_stmt *add_into_social_graph;
   14.24      sqlite3_stmt *get_own_address_binding_from_contact;
   14.25      sqlite3_stmt *set_revoke_contact_as_notified;
   14.26 @@ -190,6 +198,7 @@
   14.27      sqlite3_stmt *exists_identity_entry;        
   14.28      sqlite3_stmt *set_identity_flags;
   14.29      sqlite3_stmt *unset_identity_flags;
   14.30 +    sqlite3_stmt *set_pEp_version;    
   14.31      sqlite3_stmt *set_trust;
   14.32      sqlite3_stmt *update_trust;
   14.33      sqlite3_stmt *exists_trust_entry;
   14.34 @@ -280,6 +289,13 @@
   14.35          size_t psize, char **ctext, size_t *csize
   14.36  );
   14.37  
   14.38 +void decorate_message(
   14.39 +    message *msg,
   14.40 +    PEP_rating rating,
   14.41 +    stringlist_t *keylist,
   14.42 +    bool add_version,
   14.43 +    bool clobber);
   14.44 +
   14.45  #if defined(NDEBUG) || defined(NOLOG)
   14.46  #define DEBUG_LOG(TITLE, ENTITY, DESC)
   14.47  #else
   14.48 @@ -450,6 +466,68 @@
   14.49      return retval;
   14.50  }
   14.51  
   14.52 +static inline float pEp_version_numeric(const char* version_str) {
   14.53 +    float retval = 0;    
   14.54 +        
   14.55 +    if (!version_str || sscanf(version_str, "%f", &retval) != 1)
   14.56 +        return 0;
   14.57 +        
   14.58 +    return retval;    
   14.59 +}
   14.60 +
   14.61 +static inline void pEp_version_major_minor(const char* version_str, unsigned int* major, unsigned int* minor) {
   14.62 +    if (!major || !minor)
   14.63 +        return;
   14.64 +                
   14.65 +    if (!version_str || sscanf(version_str, "%u.%u", major, minor) != 2) {
   14.66 +        *major = 0;
   14.67 +        *minor = 0;
   14.68 +    }
   14.69 +        
   14.70 +    return;    
   14.71 +}
   14.72 +
   14.73 +static inline int compare_versions(unsigned int first_maj, unsigned int first_min,
   14.74 +                                   unsigned int second_maj, unsigned int second_min) {
   14.75 +    if (first_maj > second_maj)
   14.76 +        return 1;
   14.77 +    if (first_maj < second_maj)
   14.78 +        return -1;
   14.79 +    if (first_min > second_min)
   14.80 +        return 1;
   14.81 +    if (first_min < second_min)
   14.82 +        return -1;
   14.83 +    return 0;    
   14.84 +}
   14.85 +
   14.86 +static inline void set_min_version(unsigned int first_maj, unsigned int first_minor,
   14.87 +                                   unsigned int second_maj, unsigned int second_minor,
   14.88 +                                   unsigned int* result_maj, unsigned int* result_minor) {
   14.89 +    int result = compare_versions(first_maj, first_minor, second_maj, second_minor);
   14.90 +    if (result < 0) {
   14.91 +        *result_maj = first_maj;
   14.92 +        *result_minor = first_minor;
   14.93 +    }
   14.94 +    else {
   14.95 +        *result_maj = second_maj;
   14.96 +        *result_minor = second_minor;
   14.97 +    }    
   14.98 +}
   14.99 +
  14.100 +static inline void set_max_version(unsigned int first_maj, unsigned int first_minor,
  14.101 +                                   unsigned int second_maj, unsigned int second_minor,
  14.102 +                                   unsigned int* result_maj, unsigned int* result_minor) {
  14.103 +    int result = compare_versions(first_maj, first_minor, second_maj, second_minor);
  14.104 +    if (result > 0) {
  14.105 +        *result_maj = first_maj;
  14.106 +        *result_minor = first_minor;
  14.107 +    }
  14.108 +    else {
  14.109 +        *result_maj = second_maj;
  14.110 +        *result_minor = second_minor;
  14.111 +    }    
  14.112 +}
  14.113 +
  14.114  #ifndef EMPTYSTR
  14.115  #define EMPTYSTR(STR) ((STR) == NULL || (STR)[0] == '\0')
  14.116  #endif
  14.117 @@ -465,7 +543,6 @@
  14.118  #define _MAX(A, B) ((B) > (A) ? (B) : (A))
  14.119  #endif
  14.120  
  14.121 -
  14.122  // These are globals used in generating message IDs and should only be
  14.123  // computed once, as they're either really constants or OS-dependent
  14.124  
  14.125 @@ -487,4 +564,3 @@
  14.126      } while (rc == SQLITE_BUSY || rc == SQLITE_LOCKED);
  14.127      return rc;
  14.128  }
  14.129 -
    15.1 --- a/src/stringpair.c	Wed Aug 07 08:16:15 2019 +0200
    15.2 +++ b/src/stringpair.c	Thu Aug 08 08:10:32 2019 +0200
    15.3 @@ -194,6 +194,41 @@
    15.4      }
    15.5  }
    15.6  
    15.7 +// ONLY DELETES ONE.
    15.8 +DYNAMIC_API stringpair_list_t *stringpair_list_delete_by_key(
    15.9 +        stringpair_list_t *sp_list,
   15.10 +        const char *key
   15.11 +    )
   15.12 +{
   15.13 +    assert(sp_list);
   15.14 +    assert(key);
   15.15 +
   15.16 +    if (sp_list->value == NULL) {
   15.17 +        free_stringpair_list(sp_list);
   15.18 +        return NULL;
   15.19 +    }
   15.20 +
   15.21 +    if (key == NULL)
   15.22 +        return sp_list;
   15.23 +
   15.24 +    stringpair_list_t *_sl;
   15.25 +    stringpair_list_t *last = NULL;
   15.26 +    for (_sl = sp_list; _sl && _sl->value && _sl->value->key; _sl = _sl->next) {
   15.27 +        if (strcmp(_sl->value->key, key) == 0) {
   15.28 +            if (last == NULL)
   15.29 +                sp_list = sp_list->next;
   15.30 +            else
   15.31 +                last->next = _sl->next;
   15.32 +            _sl->next = NULL;
   15.33 +            free_stringpair_list(_sl);
   15.34 +            break;
   15.35 +        }
   15.36 +        last = _sl;
   15.37 +    }
   15.38 +    return sp_list;
   15.39 +}
   15.40 +
   15.41 +
   15.42  DYNAMIC_API stringpair_list_t *stringpair_list_find(
   15.43          stringpair_list_t *stringpair_list,
   15.44          const char *key
    16.1 --- a/src/stringpair.h	Wed Aug 07 08:16:15 2019 +0200
    16.2 +++ b/src/stringpair.h	Thu Aug 08 08:10:32 2019 +0200
    16.3 @@ -159,8 +159,13 @@
    16.4          const char *key
    16.5      );
    16.6  
    16.7 +// ONLY DELETES ONE.
    16.8 +DYNAMIC_API stringpair_list_t *stringpair_list_delete_by_key(
    16.9 +        stringpair_list_t *sp_list,
   16.10 +        const char *key
   16.11 +    );
   16.12 +
   16.13  
   16.14  #ifdef __cplusplus
   16.15  }
   16.16  #endif
   16.17 -
    17.1 --- a/sync/gen_statemachine.ysl2	Wed Aug 07 08:16:15 2019 +0200
    17.2 +++ b/sync/gen_statemachine.ysl2	Thu Aug 08 08:10:32 2019 +0200
    17.3 @@ -515,6 +515,7 @@
    17.4                                  goto the_end;
    17.5                              }
    17.6                              attach_own_key(session, _m);
    17.7 +                            decorate_message(_m, PEP_rating_undefined, NULL, true, true);
    17.8                              m = _m;
    17.9                              break;
   17.10  
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/test/convenience_scripts/ExportKeyUtilTests.cc	Thu Aug 08 08:10:32 2019 +0200
    18.3 @@ -0,0 +1,80 @@
    18.4 +// This file is under GNU General Public License 3.0
    18.5 +// see LICENSE.txt
    18.6 +
    18.7 +#include <stdlib.h>
    18.8 +#include <cstring>
    18.9 +#include <string>
   18.10 +#include <fstream>
   18.11 +#include <iostream>
   18.12 +
   18.13 +#include <cpptest.h>
   18.14 +#include "test_util.h"
   18.15 +
   18.16 +#include "pEpEngine.h"
   18.17 +
   18.18 +#include "EngineTestIndividualSuite.h"
   18.19 +#include "ExportKeyUtilTests.h"
   18.20 +
   18.21 +using namespace std;
   18.22 +
   18.23 +ExportKeyUtilTests::ExportKeyUtilTests(string suitename, string test_home_dir) :
   18.24 +    EngineTestIndividualSuite::EngineTestIndividualSuite(suitename, test_home_dir) {
   18.25 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("ExportKeyUtilTests::check_export_key_util"),
   18.26 +                                                                      static_cast<Func>(&ExportKeyUtilTests::check_export_key_util)));
   18.27 +}
   18.28 +
   18.29 +void ExportKeyUtilTests::setup() {
   18.30 +    string key_db_name;
   18.31 +    cout << "Please indicate the name of the key DB file: ";
   18.32 +    cin >> key_db_name;
   18.33 +    add_file_to_home_dir_queue(key_db_name, ".pEp_keys.db");
   18.34 +    EngineTestIndividualSuite::setup();
   18.35 +}
   18.36 +
   18.37 +void ExportKeyUtilTests::check_export_key_util() {
   18.38 +    string search_term;
   18.39 +    string output_file;
   18.40 +    cout << "Please give address (containing @) or key_id to dump: ";
   18.41 +    cin >> search_term;
   18.42 +    stringlist_t* keylist = NULL;
   18.43 +    PEP_STATUS status = find_keys(session, search_term.c_str(), &keylist);
   18.44 +    TEST_ASSERT(status == PEP_STATUS_OK);
   18.45 +    TEST_ASSERT(keylist);
   18.46 +    string priv;
   18.47 +    cout << "Private keys? (y/N)";
   18.48 +    cin >> priv;
   18.49 +    string outdir;
   18.50 +    cout << "Output directory? (curdir is default)";
   18.51 +    cin >> outdir;
   18.52 +    stringlist_t* curr = keylist;
   18.53 +    while (curr) {
   18.54 +        string fpr = curr->value;
   18.55 +        if (!fpr.empty()) {
   18.56 +            char* key = NULL;
   18.57 +            size_t size = 0;
   18.58 +            status = export_key(session, fpr.c_str(), &key, &size);
   18.59 +            if (key && size != 0) {
   18.60 +                ofstream outfile;
   18.61 +                outfile.open(((outdir.empty() ? fpr : outdir + "/" + fpr) + "_pub.asc").c_str());
   18.62 +                outfile.write(key, size);
   18.63 +                outfile.close();
   18.64 +            }
   18.65 +            free(key);
   18.66 +            size = 0;
   18.67 +            key = NULL;
   18.68 +            if (priv.c_str()[0] == 'y' || priv.c_str()[0] == 'Y') {
   18.69 +                status = export_secret_key(session, fpr.c_str(), &key, &size);
   18.70 +                if (key && size != 0) {
   18.71 +                    ofstream outfile;
   18.72 +                    outfile.open(((outdir.empty() ? fpr : outdir + "/" + fpr) + "_pub.asc").c_str());
   18.73 +                    outfile.write(key, size);
   18.74 +                    outfile.close();                    
   18.75 +                }                
   18.76 +            }   
   18.77 +            free(key);
   18.78 +        }
   18.79 +        curr = curr->next;
   18.80 +    }
   18.81 +    
   18.82 +    TEST_ASSERT(true);
   18.83 +}
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/test/convenience_scripts/ExportKeyUtilTests.h	Thu Aug 08 08:10:32 2019 +0200
    19.3 @@ -0,0 +1,21 @@
    19.4 +// This file is under GNU General Public License 3.0
    19.5 +// see LICENSE.txt
    19.6 +
    19.7 +#ifndef EXPORT_KEY_UTIL_H
    19.8 +#define EXPORT_KEY_UTIL_H
    19.9 +
   19.10 +#include <string>
   19.11 +#include "EngineTestIndividualSuite.h"
   19.12 +
   19.13 +using namespace std;
   19.14 +
   19.15 +class ExportKeyUtilTests : public EngineTestIndividualSuite {
   19.16 +    public:
   19.17 +        ExportKeyUtilTests(string test_suite, string test_home_dir);
   19.18 +    protected:
   19.19 +        void setup();    
   19.20 +    private:
   19.21 +        void check_export_key_util();
   19.22 +};
   19.23 +
   19.24 +#endif
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/test/include/GetKeyRatingForUserTests.h	Thu Aug 08 08:10:32 2019 +0200
    20.3 @@ -0,0 +1,19 @@
    20.4 +// This file is under GNU General Public License 3.0
    20.5 +// see LICENSE.txt
    20.6 +
    20.7 +#ifndef GET_KEY_RATING_FOR_USER_H
    20.8 +#define GET_KEY_RATING_FOR_USER_H
    20.9 +
   20.10 +#include <string>
   20.11 +#include "EngineTestIndividualSuite.h"
   20.12 +
   20.13 +using namespace std;
   20.14 +
   20.15 +class GetKeyRatingForUserTests : public EngineTestIndividualSuite {
   20.16 +    public:
   20.17 +        GetKeyRatingForUserTests(string test_suite, string test_home_dir);
   20.18 +    private:
   20.19 +        void check_get_key_rating_for_user();
   20.20 +};
   20.21 +
   20.22 +#endif
    21.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.2 +++ b/test/include/Message2_1Tests.h	Thu Aug 08 08:10:32 2019 +0200
    21.3 @@ -0,0 +1,28 @@
    21.4 +// This file is under GNU General Public License 3.0
    21.5 +// see LICENSE.txt
    21.6 +
    21.7 +#ifndef MESSAGE2_1_H
    21.8 +#define MESSAGE2_1_H
    21.9 +
   21.10 +#include <string>
   21.11 +#include "EngineTestIndividualSuite.h"
   21.12 +
   21.13 +using namespace std;
   21.14 +
   21.15 +class Message2_1Tests : public EngineTestIndividualSuite {
   21.16 +    public:
   21.17 +        Message2_1Tests(string test_suite, string test_home_dir);
   21.18 +    private:
   21.19 +        bool verify_message_version_produced(message* enc_msg, unsigned int* maj_inout, unsigned int* min_inout);
   21.20 +        
   21.21 +        void check_message2_1_recip_2_0();
   21.22 +        void check_message2_1_recip_OpenPGP();
   21.23 +        void check_message2_1_recip_2_1();
   21.24 +        void check_message2_1_recip_1_0_from_msg_OpenPGP();
   21.25 +        void check_message2_1_recip_2_0_from_msg();
   21.26 +        void check_message2_1_recip_2_1_from_msg();
   21.27 +        void check_message2_1_recip_mixed_2_0();
   21.28 +        void check_message2_1_recip_mixed_1_0_OpenPGP();
   21.29 +};
   21.30 +
   21.31 +#endif
    22.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.2 +++ b/test/include/SenderFPRTests.h	Thu Aug 08 08:10:32 2019 +0200
    22.3 @@ -0,0 +1,19 @@
    22.4 +// This file is under GNU General Public License 3.0
    22.5 +// see LICENSE.txt
    22.6 +
    22.7 +#ifndef SENDER_F_P_R_H
    22.8 +#define SENDER_F_P_R_H
    22.9 +
   22.10 +#include <string>
   22.11 +#include "EngineTestIndividualSuite.h"
   22.12 +
   22.13 +using namespace std;
   22.14 +
   22.15 +class SenderFPRTests : public EngineTestIndividualSuite {
   22.16 +    public:
   22.17 +        SenderFPRTests(string test_suite, string test_home_dir);
   22.18 +    private:
   22.19 +        void check_sender_f_p_r();
   22.20 +};
   22.21 +
   22.22 +#endif
    23.1 --- a/test/include/test_util.h	Wed Aug 07 08:16:15 2019 +0200
    23.2 +++ b/test/include/test_util.h	Thu Aug 08 08:10:32 2019 +0200
    23.3 @@ -14,6 +14,44 @@
    23.4  
    23.5  bool file_exists(std::string filename);
    23.6  
    23.7 +typedef enum _pEp_test_ident_preset {
    23.8 +    ALICE,
    23.9 +    APPLE,
   23.10 +    BOB,
   23.11 +    CAROL,
   23.12 +    DAVE,
   23.13 +    ERIN,
   23.14 +    FRANK,
   23.15 +    GABRIELLE,
   23.16 +    JOHN,
   23.17 +    ALEX,
   23.18 +    ALEX_0,
   23.19 +    ALEX_1,
   23.20 +    ALEX_2,
   23.21 +    ALEX_3,
   23.22 +    ALEX_4,
   23.23 +    ALEX_5,
   23.24 +    ALEX_6A,
   23.25 +    ALEX_6B,
   23.26 +    ALEX_6C,
   23.27 +    ALEX_6D,
   23.28 +    BELLA,
   23.29 +    FENRIS,
   23.30 +    SERCULLEN,
   23.31 +    INQUISITOR,
   23.32 +    BERND
   23.33 +} pEp_test_ident_preset;
   23.34 +
   23.35 +PEP_STATUS set_up_preset(PEP_SESSION session,
   23.36 +                         pEp_test_ident_preset preset_name,
   23.37 +                         bool set_identity, 
   23.38 +                         bool set_pep,
   23.39 +                         bool trust,
   23.40 +                         bool set_own, 
   23.41 +                         bool setup_private, 
   23.42 +                         pEp_identity** ident);
   23.43 +
   23.44 +
   23.45  PEP_STATUS read_file_and_import_key(PEP_SESSION session, const char* fname);
   23.46  PEP_STATUS set_up_ident_from_scratch(PEP_SESSION session, 
   23.47                                       const char* key_fname,
    24.1 --- a/test/src/SuiteMaker.cc	Wed Aug 07 08:16:15 2019 +0200
    24.2 +++ b/test/src/SuiteMaker.cc	Thu Aug 08 08:10:32 2019 +0200
    24.3 @@ -26,6 +26,7 @@
    24.4  #include "NoOwnIdentWritesOnDecryptTests.h"
    24.5  #include "LiteralFilenameTests.h"
    24.6  #include "I18nTests.h"
    24.7 +#include "Message2_1Tests.h"
    24.8  #include "IdentityListTests.h"
    24.9  #include "PgpBinaryTests.h"
   24.10  #include "SubkeyRatingEvalTests.h"
   24.11 @@ -48,6 +49,7 @@
   24.12  #include "BlacklistAcceptNewKeyTests.h"
   24.13  #include "DecryptAttachPrivateKeyUntrustedTests.h"
   24.14  #include "BlacklistTests.h"
   24.15 +#include "GetKeyRatingForUserTests.h"
   24.16  #include "RevokeRegenAttachTests.h"
   24.17  #include "PepSubjectReceivedTests.h"
   24.18  #include "SequenceTests.h"
   24.19 @@ -75,6 +77,7 @@
   24.20  #include "TrustManipulationTests.h"
   24.21  #include "StrnstrTests.h"
   24.22  #include "SyncTests.h"
   24.23 +#include "SenderFPRTests.h"
   24.24  #include "RevocationTests.h"
   24.25  #include "AppleMailTests.h"
   24.26  
   24.27 @@ -94,6 +97,7 @@
   24.28      "NoOwnIdentWritesOnDecryptTests",
   24.29      "LiteralFilenameTests",
   24.30      "I18nTests",
   24.31 +    "Message2_1Tests",
   24.32      "IdentityListTests",
   24.33      "PgpBinaryTests",
   24.34      "SubkeyRatingEvalTests",
   24.35 @@ -116,6 +120,7 @@
   24.36      "BlacklistAcceptNewKeyTests",
   24.37      "DecryptAttachPrivateKeyUntrustedTests",
   24.38      "BlacklistTests",
   24.39 +    "GetKeyRatingForUserTests",
   24.40      "RevokeRegenAttachTests",
   24.41      "PepSubjectReceivedTests",
   24.42      "SequenceTests",
   24.43 @@ -143,12 +148,13 @@
   24.44      "TrustManipulationTests",
   24.45      "StrnstrTests",
   24.46      "SyncTests",
   24.47 +    "SenderFPRTests",
   24.48      "RevocationTests",
   24.49      "AppleMailTests",
   24.50  };
   24.51  
   24.52  // This file is generated, so magic constants are ok.
   24.53 -int SuiteMaker::num_suites = 65;
   24.54 +int SuiteMaker::num_suites = 68;
   24.55  
   24.56  void SuiteMaker::suitemaker_build(const char* test_class_name, const char* test_home, Test::Suite** test_suite) {
   24.57      if (strcmp(test_class_name, "URIAddressTests") == 0)
   24.58 @@ -179,6 +185,8 @@
   24.59          *test_suite = new LiteralFilenameTests(test_class_name, test_home);
   24.60      else if (strcmp(test_class_name, "I18nTests") == 0)
   24.61          *test_suite = new I18nTests(test_class_name, test_home);
   24.62 +    else if (strcmp(test_class_name, "Message2_1Tests") == 0)
   24.63 +        *test_suite = new Message2_1Tests(test_class_name, test_home);
   24.64      else if (strcmp(test_class_name, "IdentityListTests") == 0)
   24.65          *test_suite = new IdentityListTests(test_class_name, test_home);
   24.66      else if (strcmp(test_class_name, "PgpBinaryTests") == 0)
   24.67 @@ -223,6 +231,8 @@
   24.68          *test_suite = new DecryptAttachPrivateKeyUntrustedTests(test_class_name, test_home);
   24.69      else if (strcmp(test_class_name, "BlacklistTests") == 0)
   24.70          *test_suite = new BlacklistTests(test_class_name, test_home);
   24.71 +    else if (strcmp(test_class_name, "GetKeyRatingForUserTests") == 0)
   24.72 +        *test_suite = new GetKeyRatingForUserTests(test_class_name, test_home);
   24.73      else if (strcmp(test_class_name, "RevokeRegenAttachTests") == 0)
   24.74          *test_suite = new RevokeRegenAttachTests(test_class_name, test_home);
   24.75      else if (strcmp(test_class_name, "PepSubjectReceivedTests") == 0)
   24.76 @@ -277,6 +287,8 @@
   24.77          *test_suite = new StrnstrTests(test_class_name, test_home);
   24.78      else if (strcmp(test_class_name, "SyncTests") == 0)
   24.79          *test_suite = new SyncTests(test_class_name, test_home);
   24.80 +    else if (strcmp(test_class_name, "SenderFPRTests") == 0)
   24.81 +        *test_suite = new SenderFPRTests(test_class_name, test_home);
   24.82      else if (strcmp(test_class_name, "RevocationTests") == 0)
   24.83          *test_suite = new RevocationTests(test_class_name, test_home);
   24.84      else if (strcmp(test_class_name, "AppleMailTests") == 0)
    25.1 --- a/test/src/engine_tests/AppleMailTests.cc	Wed Aug 07 08:16:15 2019 +0200
    25.2 +++ b/test/src/engine_tests/AppleMailTests.cc	Thu Aug 08 08:10:32 2019 +0200
    25.3 @@ -67,7 +67,7 @@
    25.4      PEP_decrypt_flags_t flags = 0;
    25.5      
    25.6      message* final_ptr = nullptr;
    25.7 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
    25.8 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
    25.9      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   25.10      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   25.11      
   25.12 @@ -129,7 +129,7 @@
   25.13      const char* mailfile2 = "test_mails/apple_mail_TC_html_signed_encrypted.eml";
   25.14      const string mailtext2 = slurp(mailfile2);
   25.15      
   25.16 -    status = mime_decode_message(mailtext2.c_str(), mailtext2.length(), &msg_ptr);
   25.17 +    status = mime_decode_message(mailtext2.c_str(), mailtext2.length(), &msg_ptr, NULL);
   25.18      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   25.19      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   25.20      final_ptr = msg_ptr;
    26.1 --- a/test/src/engine_tests/BlacklistAcceptNewKeyTests.cc	Wed Aug 07 08:16:15 2019 +0200
    26.2 +++ b/test/src/engine_tests/BlacklistAcceptNewKeyTests.cc	Thu Aug 08 08:10:32 2019 +0200
    26.3 @@ -80,7 +80,7 @@
    26.4      PEP_rating rating;
    26.5      PEP_decrypt_flags_t flags = 0;
    26.6      
    26.7 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
    26.8 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
    26.9      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   26.10      status = decrypt_message(session, msg_ptr, &dest_msg, &keylist, &rating, &flags);
   26.11  
    27.1 --- a/test/src/engine_tests/EncryptForIdentityTests.cc	Wed Aug 07 08:16:15 2019 +0200
    27.2 +++ b/test/src/engine_tests/EncryptForIdentityTests.cc	Thu Aug 08 08:10:32 2019 +0200
    27.3 @@ -96,7 +96,7 @@
    27.4      cout << encoded_text << "\n";
    27.5  
    27.6      message* decoded_msg = nullptr;
    27.7 -    status = mime_decode_message(encoded_text, strlen(encoded_text), &decoded_msg);
    27.8 +    status = mime_decode_message(encoded_text, strlen(encoded_text), &decoded_msg, NULL);
    27.9      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   27.10      const string string3 = encoded_text;
   27.11  
    28.1 --- a/test/src/engine_tests/EncryptMissingPrivateKeyTests.cc	Wed Aug 07 08:16:15 2019 +0200
    28.2 +++ b/test/src/engine_tests/EncryptMissingPrivateKeyTests.cc	Thu Aug 08 08:10:32 2019 +0200
    28.3 @@ -55,7 +55,7 @@
    28.4      
    28.5      const string mailtext = slurp("test_mails/blacklist_no_key.eml");
    28.6  
    28.7 -    PEP_STATUS status = mime_decode_message(mailtext.c_str(), mailtext.length(), &tmp_msg);
    28.8 +    PEP_STATUS status = mime_decode_message(mailtext.c_str(), mailtext.length(), &tmp_msg, NULL);
    28.9      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   28.10      
   28.11      status = update_identity(session, tmp_msg->from);
    29.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.2 +++ b/test/src/engine_tests/GetKeyRatingForUserTests.cc	Thu Aug 08 08:10:32 2019 +0200
    29.3 @@ -0,0 +1,46 @@
    29.4 +// This file is under GNU General Public License 3.0
    29.5 +// see LICENSE.txt
    29.6 +
    29.7 +#include <stdlib.h>
    29.8 +#include <cstring>
    29.9 +#include <string>
   29.10 +
   29.11 +#include <cpptest.h>
   29.12 +#include "test_util.h"
   29.13 +
   29.14 +#include "pEpEngine.h"
   29.15 +
   29.16 +#include "EngineTestIndividualSuite.h"
   29.17 +#include "GetKeyRatingForUserTests.h"
   29.18 +
   29.19 +using namespace std;
   29.20 +
   29.21 +GetKeyRatingForUserTests::GetKeyRatingForUserTests(string suitename, string test_home_dir) :
   29.22 +    EngineTestIndividualSuite::EngineTestIndividualSuite(suitename, test_home_dir) {
   29.23 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("GetKeyRatingForUserTests::check_get_key_rating_for_user"),
   29.24 +                                                                      static_cast<Func>(&GetKeyRatingForUserTests::check_get_key_rating_for_user)));
   29.25 +}
   29.26 +
   29.27 +void GetKeyRatingForUserTests::check_get_key_rating_for_user() {
   29.28 +    pEp_identity* alice = NULL;
   29.29 +    PEP_STATUS status = set_up_preset(session, ALICE, false, false, false, false, false, &alice);
   29.30 +    pEp_identity* test_null = NULL;
   29.31 +    const char* fpr_save = alice->fpr;
   29.32 +    alice->fpr = NULL;
   29.33 +    status = get_identity(session, alice->address, alice->user_id, &test_null);
   29.34 +    TEST_ASSERT(!test_null);
   29.35 +    TEST_ASSERT(status == PEP_CANNOT_FIND_IDENTITY);
   29.36 +    TEST_ASSERT_MSG(alice->comm_type == PEP_ct_unknown, tl_ct_string(alice->comm_type));
   29.37 +
   29.38 +    // Ok, so we have no info really, let's set it.
   29.39 +    status = set_identity(session, alice);
   29.40 +    
   29.41 +    status = update_identity(session, alice);
   29.42 +    TEST_ASSERT(alice->fpr);
   29.43 +
   29.44 +    PEP_rating rating;
   29.45 +    status = get_key_rating_for_user(session, alice->user_id, alice->fpr, &rating);
   29.46 +    TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   29.47 +    cout << tl_rating_string(rating) << endl;
   29.48 +    TEST_ASSERT(true);
   29.49 +}
    30.1 --- a/test/src/engine_tests/IOS1664Tests.cc	Wed Aug 07 08:16:15 2019 +0200
    30.2 +++ b/test/src/engine_tests/IOS1664Tests.cc	Thu Aug 08 08:10:32 2019 +0200
    30.3 @@ -27,8 +27,9 @@
    30.4      TEST_ASSERT(!email.empty());
    30.5      
    30.6      message* message_mail = NULL;
    30.7 +    bool raise_att;
    30.8      
    30.9 -    PEP_STATUS status = mime_decode_message(email.c_str(), email.size(), &message_mail);
   30.10 +    PEP_STATUS status = mime_decode_message(email.c_str(), email.size(), &message_mail, &raise_att);
   30.11      TEST_ASSERT(status == PEP_STATUS_OK && message_mail);
   30.12      
   30.13      // create own identity here, because we want to reply, before we start.
    31.1 --- a/test/src/engine_tests/KeyAttachmentTests.cc	Wed Aug 07 08:16:15 2019 +0200
    31.2 +++ b/test/src/engine_tests/KeyAttachmentTests.cc	Thu Aug 08 08:10:32 2019 +0200
    31.3 @@ -73,7 +73,7 @@
    31.4      message* enc_msg = NULL;
    31.5      message* dec_msg = NULL;
    31.6  
    31.7 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
    31.8 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
    31.9      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   31.10      TEST_ASSERT(enc_msg);
   31.11      stringlist_t* keylist = NULL;
   31.12 @@ -93,7 +93,7 @@
   31.13      message* enc_msg = NULL;
   31.14      message* dec_msg = NULL;
   31.15  
   31.16 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
   31.17 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
   31.18      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   31.19      TEST_ASSERT(enc_msg);
   31.20      stringlist_t* keylist = NULL;
   31.21 @@ -119,7 +119,7 @@
   31.22      message* enc_msg = NULL;
   31.23      message* dec_msg = NULL;
   31.24  
   31.25 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
   31.26 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
   31.27      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   31.28      TEST_ASSERT(enc_msg);
   31.29      stringlist_t* keylist = NULL;
   31.30 @@ -145,7 +145,7 @@
   31.31      message* enc_msg = NULL;
   31.32      message* dec_msg = NULL;
   31.33  
   31.34 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
   31.35 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
   31.36      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   31.37      TEST_ASSERT(enc_msg);
   31.38      stringlist_t* keylist = NULL;
   31.39 @@ -171,7 +171,7 @@
   31.40      message* enc_msg = NULL;
   31.41      message* dec_msg = NULL;
   31.42  
   31.43 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
   31.44 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
   31.45      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   31.46      TEST_ASSERT(enc_msg);
   31.47      stringlist_t* keylist = NULL;
   31.48 @@ -201,7 +201,7 @@
   31.49      message* enc_msg = NULL;
   31.50      message* dec_msg = NULL;
   31.51  
   31.52 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
   31.53 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
   31.54      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   31.55      TEST_ASSERT(enc_msg);
   31.56      stringlist_t* keylist = NULL;
   31.57 @@ -221,7 +221,7 @@
   31.58      message* enc_msg = NULL;
   31.59      message* dec_msg = NULL;
   31.60  
   31.61 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
   31.62 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
   31.63      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   31.64      TEST_ASSERT(enc_msg);
   31.65      stringlist_t* keylist = NULL;
   31.66 @@ -247,7 +247,7 @@
   31.67      message* enc_msg = NULL;
   31.68      message* dec_msg = NULL;
   31.69  
   31.70 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
   31.71 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
   31.72      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   31.73      TEST_ASSERT(enc_msg);
   31.74      stringlist_t* keylist = NULL;
   31.75 @@ -273,7 +273,7 @@
   31.76      message* enc_msg = NULL;
   31.77      message* dec_msg = NULL;
   31.78  
   31.79 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
   31.80 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
   31.81      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   31.82      TEST_ASSERT(enc_msg);
   31.83      stringlist_t* keylist = NULL;
   31.84 @@ -328,7 +328,7 @@
   31.85      message* enc_msg = NULL;
   31.86      message* dec_msg = NULL;
   31.87  
   31.88 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
   31.89 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
   31.90      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   31.91      TEST_ASSERT(enc_msg);
   31.92      stringlist_t* keylist = NULL;
   31.93 @@ -348,7 +348,7 @@
   31.94      message* enc_msg = NULL;
   31.95      message* dec_msg = NULL;
   31.96  
   31.97 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
   31.98 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
   31.99      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  31.100      TEST_ASSERT(enc_msg);
  31.101      stringlist_t* keylist = NULL;
  31.102 @@ -373,7 +373,7 @@
  31.103      message* enc_msg = NULL;
  31.104      message* dec_msg = NULL;
  31.105  
  31.106 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
  31.107 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
  31.108      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  31.109      TEST_ASSERT(enc_msg);
  31.110      stringlist_t* keylist = NULL;
  31.111 @@ -399,7 +399,7 @@
  31.112      message* enc_msg = NULL;
  31.113      message* dec_msg = NULL;
  31.114  
  31.115 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
  31.116 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
  31.117      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  31.118      TEST_ASSERT(enc_msg);
  31.119      stringlist_t* keylist = NULL;
  31.120 @@ -424,7 +424,7 @@
  31.121      message* enc_msg = NULL;
  31.122      message* dec_msg = NULL;
  31.123  
  31.124 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
  31.125 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
  31.126      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  31.127      TEST_ASSERT(enc_msg);
  31.128      stringlist_t* keylist = NULL;
  31.129 @@ -449,7 +449,7 @@
  31.130      message* enc_msg = NULL;
  31.131      message* dec_msg = NULL;
  31.132  
  31.133 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
  31.134 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
  31.135      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  31.136      TEST_ASSERT(enc_msg);
  31.137      stringlist_t* keylist = NULL;
  31.138 @@ -469,7 +469,7 @@
  31.139      message* enc_msg = NULL;
  31.140      message* dec_msg = NULL;
  31.141  
  31.142 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
  31.143 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
  31.144      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  31.145      TEST_ASSERT(enc_msg);
  31.146      stringlist_t* keylist = NULL;
  31.147 @@ -494,7 +494,7 @@
  31.148      message* enc_msg = NULL;
  31.149      message* dec_msg = NULL;
  31.150  
  31.151 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
  31.152 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
  31.153      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  31.154      TEST_ASSERT(enc_msg);
  31.155      stringlist_t* keylist = NULL;
  31.156 @@ -519,7 +519,7 @@
  31.157      message* enc_msg = NULL;
  31.158      message* dec_msg = NULL;
  31.159  
  31.160 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
  31.161 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
  31.162      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  31.163      TEST_ASSERT(enc_msg);
  31.164      stringlist_t* keylist = NULL;
    32.1 --- a/test/src/engine_tests/LeastColorGroupTests.cc	Wed Aug 07 08:16:15 2019 +0200
    32.2 +++ b/test/src/engine_tests/LeastColorGroupTests.cc	Thu Aug 08 08:10:32 2019 +0200
    32.3 @@ -69,7 +69,7 @@
    32.4      PEP_rating rating;
    32.5      PEP_decrypt_flags_t flags;
    32.6      
    32.7 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
    32.8 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
    32.9      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   32.10      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   32.11      final_ptr = msg_ptr;
    33.1 --- a/test/src/engine_tests/LeastCommonDenomColorTests.cc	Wed Aug 07 08:16:15 2019 +0200
    33.2 +++ b/test/src/engine_tests/LeastCommonDenomColorTests.cc	Thu Aug 08 08:10:32 2019 +0200
    33.3 @@ -68,7 +68,7 @@
    33.4      PEP_rating rating;
    33.5      PEP_decrypt_flags_t flags;
    33.6      
    33.7 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
    33.8 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
    33.9      TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
   33.10      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   33.11  
   33.12 @@ -117,7 +117,7 @@
   33.13      keylist = nullptr;
   33.14      rating = PEP_rating_unreliable;
   33.15  
   33.16 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   33.17 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
   33.18      TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
   33.19      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   33.20      flags = 0;
    34.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.2 +++ b/test/src/engine_tests/Message2_1Tests.cc	Thu Aug 08 08:10:32 2019 +0200
    34.3 @@ -0,0 +1,579 @@
    34.4 +// This file is under GNU General Public License 3.0
    34.5 +// see LICENSE.txt
    34.6 +
    34.7 +#include <stdlib.h>
    34.8 +#include <cstring>
    34.9 +#include <string>
   34.10 +
   34.11 +#include <cpptest.h>
   34.12 +#include "test_util.h"
   34.13 +
   34.14 +#include "pEpEngine.h"
   34.15 +
   34.16 +#include "EngineTestIndividualSuite.h"
   34.17 +#include "Message2_1Tests.h"
   34.18 +
   34.19 +using namespace std;
   34.20 +
   34.21 +Message2_1Tests::Message2_1Tests(string suitename, string test_home_dir) :
   34.22 +    EngineTestIndividualSuite::EngineTestIndividualSuite(suitename, test_home_dir) {
   34.23 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("Message2_1Tests::check_message2_1_recip_2_0"),
   34.24 +                                                                      static_cast<Func>(&Message2_1Tests::check_message2_1_recip_2_0)));
   34.25 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("Message2_1Tests::check_message2_1_recip_OpenPGP"),
   34.26 +                                                                      static_cast<Func>(&Message2_1Tests::check_message2_1_recip_OpenPGP)));
   34.27 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("Message2_1Tests::check_message2_1_recip_2_1"),
   34.28 +                                                                      static_cast<Func>(&Message2_1Tests::check_message2_1_recip_2_1)));
   34.29 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("Message2_1Tests::check_message2_1_recip_1_0_from_msg_OpenPGP"),
   34.30 +                                                                      static_cast<Func>(&Message2_1Tests::check_message2_1_recip_1_0_from_msg_OpenPGP)));
   34.31 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("Message2_1Tests::check_message2_1_recip_2_0_from_msg"),
   34.32 +                                                                      static_cast<Func>(&Message2_1Tests::check_message2_1_recip_2_0_from_msg)));
   34.33 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("Message2_1Tests::check_message2_1_recip_2_1_from_msg"),
   34.34 +                                                                      static_cast<Func>(&Message2_1Tests::check_message2_1_recip_2_1_from_msg)));
   34.35 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("Message2_1Tests::check_message2_1_recip_mixed_2_0"),
   34.36 +                                                                      static_cast<Func>(&Message2_1Tests::check_message2_1_recip_mixed_2_0)));
   34.37 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("Message2_1Tests::check_message2_1_recip_mixed_1_0_OpenPGP"),
   34.38 +                                                                      static_cast<Func>(&Message2_1Tests::check_message2_1_recip_mixed_1_0_OpenPGP)));
   34.39 +}
   34.40 +
   34.41 +bool Message2_1Tests::verify_message_version_produced(message* enc_msg, unsigned int* maj_inout, unsigned int* min_inout) {
   34.42 +    if (!maj_inout || !min_inout)
   34.43 +        return false;
   34.44 +    int major = *maj_inout;
   34.45 +    int minor = *min_inout;
   34.46 +    
   34.47 +    char* ptext = NULL;
   34.48 +    size_t psize = 0;
   34.49 +    stringlist_t* keylist = NULL;
   34.50 +    
   34.51 +    PEP_STATUS status = decrypt_and_verify(session, enc_msg->attachments->next->value,
   34.52 +                                           enc_msg->attachments->next->size, NULL, 0,
   34.53 +                                           &ptext, &psize, &keylist,
   34.54 +                                           NULL);
   34.55 +
   34.56 +    cout << ptext << endl;
   34.57 +
   34.58 +    // fixme, check status
   34.59 +    if (strstr(ptext, "pEp-Wrapped-Message-Info: OUTER") != NULL && strstr(ptext, "pEp-Wrapped-Message-Info: INNER") != NULL) {
   34.60 +        *maj_inout = 2;
   34.61 +        *min_inout = 0;
   34.62 +    }
   34.63 +    else if (strstr(ptext, "X-pEp-Wrapped-Message-Info: INNER") != NULL && strstr(ptext, "forwarded=\"no\"") != NULL) {
   34.64 +        *maj_inout = 2;
   34.65 +        *min_inout = 1;
   34.66 +    }
   34.67 +    else {
   34.68 +        *maj_inout = 1;
   34.69 +        *min_inout = 0;
   34.70 +    }    
   34.71 +    
   34.72 +    switch (major) {
   34.73 +        case 1:
   34.74 +            if (*maj_inout == 1)
   34.75 +                return true;
   34.76 +            return false;    
   34.77 +        case 2:
   34.78 +            if (*maj_inout != 2)
   34.79 +                return false;
   34.80 +            if (*min_inout == minor)
   34.81 +                return true;
   34.82 +            return false;    
   34.83 +        default:
   34.84 +            *maj_inout = 0;
   34.85 +            *min_inout = 0;
   34.86 +            return false;
   34.87 +    }
   34.88 +}
   34.89 +
   34.90 +void Message2_1Tests::check_message2_1_recip_2_0() {
   34.91 +
   34.92 +    pEp_identity* alice = NULL;
   34.93 +    pEp_identity* carol = NULL;
   34.94 +    
   34.95 +    PEP_STATUS status = set_up_preset(session, ALICE, 
   34.96 +                                      true, true, true, true, true, &alice);
   34.97 +
   34.98 +    TEST_ASSERT(status == PEP_STATUS_OK);
   34.99 +    TEST_ASSERT(alice);
  34.100 +    
  34.101 +    status = set_up_preset(session, CAROL, 
  34.102 +                           false, true, false, false, false, &carol);
  34.103 +
  34.104 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.105 +    TEST_ASSERT(carol);
  34.106 +
  34.107 +    // default should be 2.0 after setting pep status
  34.108 +    status = update_identity(session, carol);
  34.109 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.110 +    TEST_ASSERT(carol->major_ver == 2);
  34.111 +    TEST_ASSERT(carol->minor_ver == 0);
  34.112 +    // generate message
  34.113 +    pEp_identity* carol_to = new_identity(carol->address, NULL, NULL, NULL);
  34.114 +    
  34.115 +    message* msg = new_message(PEP_dir_outgoing);
  34.116 +    
  34.117 +    msg->from = alice;
  34.118 +    msg->to = new_identity_list(carol_to);
  34.119 +    msg->shortmsg = strdup("Boom shaka laka");
  34.120 +    msg->longmsg = strdup("Don't you get sick of these?");
  34.121 +    
  34.122 +    message* enc_msg = NULL;
  34.123 +
  34.124 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
  34.125 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.126 +    
  34.127 +    // ensure sent message is in 2.0 format
  34.128 +    unsigned int major = 2;
  34.129 +    unsigned int minor = 0;
  34.130 +    TEST_ASSERT_MSG(verify_message_version_produced(enc_msg, &major, &minor),
  34.131 +                                                    (to_string(major) + "." + to_string(minor)).c_str());
  34.132 +    
  34.133 +    free_identity(carol);
  34.134 +    free_message(msg);
  34.135 +    free_message(enc_msg);
  34.136 +}
  34.137 +
  34.138 +/* PEP_STATUS set_up_preset(PEP_SESSION session,
  34.139 +                         pEp_test_ident_preset preset_name,
  34.140 +                         bool set_ident, 
  34.141 +                         bool set_pep,
  34.142 +                         bool trust,
  34.143 +                         bool set_own, 
  34.144 +                         bool setup_private, 
  34.145 +                         pEp_identity** ident) {
  34.146 +*/
  34.147 +
  34.148 +void Message2_1Tests::check_message2_1_recip_OpenPGP() {
  34.149 +    // set recip to 1.0
  34.150 +    pEp_identity* alice = NULL;
  34.151 +    pEp_identity* carol = NULL;
  34.152 +    
  34.153 +    PEP_STATUS status = set_up_preset(session, ALICE, 
  34.154 +                                      true, true, true, true, true, &alice);
  34.155 +
  34.156 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.157 +    TEST_ASSERT(alice);
  34.158 +    
  34.159 +    status = set_up_preset(session, CAROL, 
  34.160 +                           false, false, false, false, false, &carol);
  34.161 +
  34.162 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.163 +    TEST_ASSERT(carol);
  34.164 +
  34.165 +    status = update_identity(session, carol);
  34.166 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.167 +    TEST_ASSERT(carol->major_ver < 2);
  34.168 +    TEST_ASSERT(carol->minor_ver == 0);
  34.169 +
  34.170 +    // generate message
  34.171 +    pEp_identity* carol_to = new_identity(carol->address, NULL, NULL, NULL);
  34.172 +    
  34.173 +    message* msg = new_message(PEP_dir_outgoing);
  34.174 +    
  34.175 +    msg->from = alice;
  34.176 +    msg->to = new_identity_list(carol_to);
  34.177 +    msg->shortmsg = strdup("Boom shaka laka");
  34.178 +    msg->longmsg = strdup("Don't you get sick of these?");
  34.179 +    
  34.180 +    message* enc_msg = NULL;
  34.181 +
  34.182 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
  34.183 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.184 +    
  34.185 +    // ensure sent message is in 1.0 format
  34.186 +    unsigned int major = 1;
  34.187 +    unsigned int minor = 0;
  34.188 +    TEST_ASSERT_MSG(verify_message_version_produced(enc_msg, &major, &minor),
  34.189 +                                                    (to_string(major) + "." + to_string(minor)).c_str());
  34.190 +    
  34.191 +    free_identity(carol);
  34.192 +    free_message(msg);
  34.193 +    free_message(enc_msg);
  34.194 +}
  34.195 +
  34.196 +void Message2_1Tests::check_message2_1_recip_2_1() {
  34.197 +    // set recip to 2.1
  34.198 +    
  34.199 +    pEp_identity* alice = NULL;
  34.200 +    pEp_identity* carol = NULL;
  34.201 +    
  34.202 +    PEP_STATUS status = set_up_preset(session, ALICE, 
  34.203 +                                      true, true, true, true, true, &alice);
  34.204 +
  34.205 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.206 +    TEST_ASSERT(alice);
  34.207 +    
  34.208 +    status = set_up_preset(session, CAROL, 
  34.209 +                           true, true, false, false, false, &carol);
  34.210 +
  34.211 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.212 +    TEST_ASSERT(carol);
  34.213 +
  34.214 +    status = set_pEp_version(session, carol, 2, 1);
  34.215 +    
  34.216 +    // default should be 2.1 after setting pep status
  34.217 +    status = update_identity(session, carol);
  34.218 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.219 +    TEST_ASSERT(carol->major_ver == 2);
  34.220 +    TEST_ASSERT(carol->minor_ver == 1);
  34.221 +    // generate message
  34.222 +    pEp_identity* carol_to = new_identity(carol->address, NULL, NULL, NULL);
  34.223 +    
  34.224 +    message* msg = new_message(PEP_dir_outgoing);
  34.225 +    
  34.226 +    msg->from = alice;
  34.227 +    msg->to = new_identity_list(carol_to);
  34.228 +    msg->shortmsg = strdup("Boom shaka laka");
  34.229 +    msg->longmsg = strdup("Don't you get sick of these?");
  34.230 +    
  34.231 +    message* enc_msg = NULL;
  34.232 +
  34.233 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
  34.234 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.235 +    
  34.236 +    // ensure sent message is in 2.0 format
  34.237 +    unsigned int major = 2;
  34.238 +    unsigned int minor = 1;
  34.239 +    TEST_ASSERT_MSG(verify_message_version_produced(enc_msg, &major, &minor),
  34.240 +                                                    (to_string(major) + "." + to_string(minor)).c_str());
  34.241 +    
  34.242 +    free_identity(carol);
  34.243 +    free_message(msg);
  34.244 +    free_message(enc_msg);
  34.245 +    TEST_ASSERT(true);
  34.246 +}
  34.247 +
  34.248 +void Message2_1Tests::check_message2_1_recip_1_0_from_msg_OpenPGP() {
  34.249 +    pEp_identity* alex = NULL;
  34.250 +    
  34.251 +    PEP_STATUS status = set_up_preset(session, ALEX_0, 
  34.252 +                                      true, true, true, true, true, &alex);
  34.253 +
  34.254 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.255 +    TEST_ASSERT(alex);
  34.256 +
  34.257 +    // receive 1.0 message from OpenPGP
  34.258 +    string incoming = slurp("test_mails/From_M1_0.eml");
  34.259 +    
  34.260 +    char* dec_msg;
  34.261 +    char* mod_src = NULL;
  34.262 +    PEP_decrypt_flags_t flags = 0;
  34.263 +    stringlist_t* keylist_used = NULL;
  34.264 +    PEP_rating rating;
  34.265 +    
  34.266 +    status = MIME_decrypt_message(session, incoming.c_str(), incoming.size(), &dec_msg, &keylist_used, &rating, &flags, &mod_src);
  34.267 +
  34.268 +    TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  34.269 +    // generate message
  34.270 +    
  34.271 +    message* msg = new_message(PEP_dir_outgoing);
  34.272 +    
  34.273 +    msg->from = alex;
  34.274 +    msg->to = new_identity_list(new_identity("pep-test-carol@pep-project.org", NULL, NULL, NULL));
  34.275 +    msg->shortmsg = strdup("Boom shaka laka");
  34.276 +    msg->longmsg = strdup("Don't you get sick of these?");
  34.277 +    
  34.278 +    message* enc_msg = NULL;
  34.279 +
  34.280 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
  34.281 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.282 +    
  34.283 +    // ensure sent message is in 1.0 format
  34.284 +    unsigned int major = 1;
  34.285 +    unsigned int minor = 0;
  34.286 +    TEST_ASSERT_MSG(verify_message_version_produced(enc_msg, &major, &minor),
  34.287 +                                                    (to_string(major) + "." + to_string(minor)).c_str());
  34.288 +    
  34.289 +    free_message(msg);
  34.290 +    free_message(enc_msg);
  34.291 +    free(dec_msg);
  34.292 +    free(mod_src);
  34.293 +    TEST_ASSERT(true);
  34.294 +}
  34.295 +
  34.296 +void Message2_1Tests::check_message2_1_recip_2_0_from_msg() {
  34.297 +    // receive 2.0 message
  34.298 +    pEp_identity* carol = NULL;
  34.299 +    
  34.300 +    PEP_STATUS status = set_up_preset(session, CAROL, 
  34.301 +                                      true, true, true, true, true, &carol);
  34.302 +
  34.303 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.304 +    TEST_ASSERT(carol);
  34.305 +
  34.306 +    // receive 1.0 message from OpenPGP
  34.307 +    string incoming = slurp("test_mails/2_0_msg.eml");
  34.308 +    
  34.309 +    char* dec_msg;
  34.310 +    char* mod_src = NULL;
  34.311 +    PEP_decrypt_flags_t flags = 0;
  34.312 +    stringlist_t* keylist_used = NULL;
  34.313 +    PEP_rating rating;
  34.314 +    
  34.315 +    status = MIME_decrypt_message(session, incoming.c_str(), incoming.size(), &dec_msg, &keylist_used, &rating, &flags, &mod_src);
  34.316 +
  34.317 +    TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  34.318 +    // generate message
  34.319 +    
  34.320 +    message* msg = new_message(PEP_dir_outgoing);
  34.321 +    
  34.322 +    msg->from = carol;
  34.323 +    msg->to = new_identity_list(new_identity("pep.test.alice@pep-project.org", NULL, NULL, NULL));
  34.324 +    msg->shortmsg = strdup("Boom shaka laka");
  34.325 +    msg->longmsg = strdup("Don't you get sick of these?");
  34.326 +    
  34.327 +    message* enc_msg = NULL;
  34.328 +
  34.329 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
  34.330 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.331 +    
  34.332 +    // ensure sent message is in 1.0 format
  34.333 +    unsigned int major = 2;
  34.334 +    unsigned int minor = 0;
  34.335 +    TEST_ASSERT_MSG(verify_message_version_produced(enc_msg, &major, &minor),
  34.336 +                                                    (to_string(major) + "." + to_string(minor)).c_str());
  34.337 +    
  34.338 +    free_message(msg);
  34.339 +    free_message(enc_msg);
  34.340 +    free(dec_msg);
  34.341 +    free(mod_src);
  34.342 +}
  34.343 +
  34.344 +void Message2_1Tests::check_message2_1_recip_2_1_from_msg() {
  34.345 +    // receive 2.1 message
  34.346 +    pEp_identity* carol = NULL;
  34.347 +    
  34.348 +    PEP_STATUS status = set_up_preset(session, CAROL, 
  34.349 +                                      true, true, true, true, true, &carol);
  34.350 +
  34.351 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.352 +    TEST_ASSERT(carol);
  34.353 +
  34.354 +    // receive 1.0 message from OpenPGP
  34.355 +    string incoming = slurp("test_mails/From_M2_1.eml");
  34.356 +    
  34.357 +    char* dec_msg;
  34.358 +    char* mod_src = NULL;
  34.359 +    PEP_decrypt_flags_t flags = 0;
  34.360 +    stringlist_t* keylist_used = NULL;
  34.361 +    PEP_rating rating;
  34.362 +    
  34.363 +    status = MIME_decrypt_message(session, incoming.c_str(), incoming.size(), &dec_msg, &keylist_used, &rating, &flags, &mod_src);
  34.364 +
  34.365 +    TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  34.366 +    // generate message
  34.367 +    
  34.368 +    message* msg = new_message(PEP_dir_outgoing);
  34.369 +    
  34.370 +    msg->from = carol;
  34.371 +    msg->to = new_identity_list(new_identity("pep.test.alice@pep-project.org", NULL, NULL, NULL));
  34.372 +    msg->shortmsg = strdup("Boom shaka laka");
  34.373 +    msg->longmsg = strdup("Don't you get sick of these?");
  34.374 +    
  34.375 +    message* enc_msg = NULL;
  34.376 +
  34.377 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
  34.378 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.379 +    
  34.380 +    // ensure sent message is in 2.1 format
  34.381 +    unsigned int major = 2;
  34.382 +    unsigned int minor = 1;
  34.383 +    TEST_ASSERT_MSG(verify_message_version_produced(enc_msg, &major, &minor),
  34.384 +                                                    (to_string(major) + "." + to_string(minor)).c_str());
  34.385 +    
  34.386 +    free_message(msg);
  34.387 +    free_message(enc_msg);
  34.388 +    free(dec_msg);
  34.389 +    free(mod_src);
  34.390 +}
  34.391 +
  34.392 +void Message2_1Tests::check_message2_1_recip_mixed_2_0() {
  34.393 +    // Set mixed recipient values
  34.394 +    pEp_identity* alice = NULL;
  34.395 +    pEp_identity* bob = NULL;
  34.396 +    pEp_identity* carol = NULL;
  34.397 +    pEp_identity* dave = NULL;
  34.398 +    pEp_identity* alex = NULL;
  34.399 +
  34.400 +    PEP_STATUS status = set_up_preset(session, ALICE, 
  34.401 +                                      true, true, true, true, true, &alice);
  34.402 +
  34.403 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.404 +    TEST_ASSERT(alice);
  34.405 +
  34.406 +    status = set_up_preset(session, BOB, 
  34.407 +                           true, true, false, false, false, &bob);
  34.408 +
  34.409 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.410 +    TEST_ASSERT(bob);
  34.411 +
  34.412 +    status = set_pEp_version(session, bob, 2, 1);
  34.413 +
  34.414 +    // default should be 2.1 after setting pep status
  34.415 +    status = update_identity(session, bob);
  34.416 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.417 +    TEST_ASSERT(bob->major_ver == 2);
  34.418 +    TEST_ASSERT(bob->minor_ver == 1);
  34.419 +    
  34.420 +    status = set_up_preset(session, CAROL, 
  34.421 +                           true, true, false, false, false, &carol);
  34.422 +
  34.423 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.424 +    TEST_ASSERT(carol);
  34.425 +
  34.426 +    status = set_pEp_version(session, carol, 2, 1);
  34.427 +
  34.428 +    // default should be 2.1 after setting pep status
  34.429 +    status = update_identity(session, carol);
  34.430 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.431 +    TEST_ASSERT(carol->major_ver == 2);
  34.432 +    TEST_ASSERT(carol->minor_ver == 1);
  34.433 +    
  34.434 +    status = set_up_preset(session, DAVE, 
  34.435 +                           true, true, false, false, false, &dave);
  34.436 +
  34.437 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.438 +    TEST_ASSERT(dave);
  34.439 +
  34.440 +    status = set_pEp_version(session, dave, 2, 0);
  34.441 +
  34.442 +    // default should be 2.1 after setting pep status
  34.443 +    status = update_identity(session, dave);
  34.444 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.445 +    TEST_ASSERT(dave->major_ver == 2);
  34.446 +    TEST_ASSERT(dave->minor_ver == 0);
  34.447 +
  34.448 +    status = set_up_preset(session, ALEX, 
  34.449 +                           true, true, true, false, false, &alex);
  34.450 +
  34.451 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.452 +    TEST_ASSERT(alex);
  34.453 +
  34.454 +    status = set_pEp_version(session, alex, 2, 1);
  34.455 +
  34.456 +    // default should be 2.1 after setting pep status
  34.457 +    status = update_identity(session, alex);
  34.458 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.459 +    TEST_ASSERT(alex->major_ver == 2);
  34.460 +    TEST_ASSERT(alex->minor_ver == 1);
  34.461 +
  34.462 +    // generate message
  34.463 +    message* msg = new_message(PEP_dir_outgoing);
  34.464 +    
  34.465 +    msg->from = alice;
  34.466 +    msg->to = new_identity_list(new_identity(bob->address, NULL, NULL, NULL));
  34.467 +    identity_list_add(msg->to, new_identity(carol->address, NULL, NULL, NULL));
  34.468 +    identity_list_add(msg->to, new_identity(dave->address, NULL, NULL, NULL));
  34.469 +    identity_list_add(msg->to, new_identity(alex->address, NULL, NULL, NULL));    
  34.470 +    msg->shortmsg = strdup("Boom shaka laka");
  34.471 +    msg->longmsg = strdup("Don't you get sick of these?");
  34.472 +    
  34.473 +    message* enc_msg = NULL;
  34.474 +
  34.475 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
  34.476 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.477 +    
  34.478 +    // ensure sent message is in 2.0 format
  34.479 +    unsigned int major = 2;
  34.480 +    unsigned int minor = 0;
  34.481 +    TEST_ASSERT_MSG(verify_message_version_produced(enc_msg, &major, &minor),
  34.482 +                                                    (to_string(major) + "." + to_string(minor)).c_str());
  34.483 +    
  34.484 +    free_message(msg);
  34.485 +    free_message(enc_msg);
  34.486 +}
  34.487 +
  34.488 +void Message2_1Tests::check_message2_1_recip_mixed_1_0_OpenPGP() {
  34.489 +    // Set mixed recipient values
  34.490 +    pEp_identity* alice = NULL;
  34.491 +    pEp_identity* bob = NULL;
  34.492 +    pEp_identity* carol = NULL;
  34.493 +    pEp_identity* dave = NULL;
  34.494 +    pEp_identity* alex = NULL;
  34.495 +
  34.496 +    PEP_STATUS status = set_up_preset(session, ALICE, 
  34.497 +                                      true, true, true, true, true, &alice);
  34.498 +
  34.499 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.500 +    TEST_ASSERT(alice);
  34.501 +
  34.502 +    status = set_up_preset(session, BOB, 
  34.503 +                           true, true, false, false, false, &bob);
  34.504 +
  34.505 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.506 +    TEST_ASSERT(bob);
  34.507 +
  34.508 +    status = set_pEp_version(session, bob, 2, 1);
  34.509 +
  34.510 +    // default should be 2.1 after setting pep status
  34.511 +    status = update_identity(session, bob);
  34.512 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.513 +    TEST_ASSERT(bob->major_ver == 2);
  34.514 +    TEST_ASSERT(bob->minor_ver == 1);
  34.515 +    
  34.516 +    status = set_up_preset(session, CAROL, 
  34.517 +                           true, true, false, false, false, &carol);
  34.518 +
  34.519 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.520 +    TEST_ASSERT(carol);
  34.521 +
  34.522 +    status = set_pEp_version(session, carol, 2, 1);
  34.523 +
  34.524 +    // default should be 2.1 after setting pep status
  34.525 +    status = update_identity(session, carol);
  34.526 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.527 +    TEST_ASSERT(carol->major_ver == 2);
  34.528 +    TEST_ASSERT(carol->minor_ver == 1);
  34.529 +    
  34.530 +    status = set_up_preset(session, DAVE, 
  34.531 +                           true, true, false, false, false, &dave);
  34.532 +
  34.533 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.534 +    TEST_ASSERT(dave);
  34.535 +
  34.536 +    status = set_pEp_version(session, dave, 2, 0);
  34.537 +
  34.538 +    // default should be 2.1 after setting pep status
  34.539 +    status = update_identity(session, dave);
  34.540 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.541 +    TEST_ASSERT(dave->major_ver == 2);
  34.542 +    TEST_ASSERT(dave->minor_ver == 0);
  34.543 +
  34.544 +    status = set_up_preset(session, ALEX, 
  34.545 +                           true, false, true, false, false, &alex);
  34.546 +
  34.547 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.548 +    TEST_ASSERT(alex);
  34.549 +
  34.550 +    status = set_pEp_version(session, alex, 1, 0);
  34.551 +
  34.552 +    // default should be 1.0 after setting pep status
  34.553 +    status = update_identity(session, alex);
  34.554 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.555 +    TEST_ASSERT(alex->major_ver == 1);
  34.556 +    TEST_ASSERT(alex->minor_ver == 0);
  34.557 +
  34.558 +    // generate message
  34.559 +    message* msg = new_message(PEP_dir_outgoing);
  34.560 +    
  34.561 +    msg->from = alice;
  34.562 +    msg->to = new_identity_list(new_identity(bob->address, NULL, NULL, NULL));
  34.563 +    identity_list_add(msg->to, new_identity(carol->address, NULL, NULL, NULL));
  34.564 +    identity_list_add(msg->to, new_identity(dave->address, NULL, NULL, NULL));
  34.565 +    identity_list_add(msg->to, new_identity(alex->address, NULL, NULL, NULL));    
  34.566 +    msg->shortmsg = strdup("Boom shaka laka");
  34.567 +    msg->longmsg = strdup("Don't you get sick of these?");
  34.568 +    
  34.569 +    message* enc_msg = NULL;
  34.570 +
  34.571 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
  34.572 +    TEST_ASSERT(status == PEP_STATUS_OK);
  34.573 +    
  34.574 +    // ensure sent message is in 2.0 format
  34.575 +    unsigned int major = 1;
  34.576 +    unsigned int minor = 0;
  34.577 +    TEST_ASSERT_MSG(verify_message_version_produced(enc_msg, &major, &minor),
  34.578 +                                                    (to_string(major) + "." + to_string(minor)).c_str());
  34.579 +    
  34.580 +    free_message(msg);
  34.581 +    free_message(enc_msg);
  34.582 +}
    35.1 --- a/test/src/engine_tests/MessageApiTests.cc	Wed Aug 07 08:16:15 2019 +0200
    35.2 +++ b/test/src/engine_tests/MessageApiTests.cc	Thu Aug 08 08:10:32 2019 +0200
    35.3 @@ -81,7 +81,7 @@
    35.4      cout << text2 << "\n";
    35.5  
    35.6      message *msg3 = nullptr;
    35.7 -    PEP_STATUS status3 = mime_decode_message(text2, strlen(text2), &msg3);
    35.8 +    PEP_STATUS status3 = mime_decode_message(text2, strlen(text2), &msg3, NULL);
    35.9      TEST_ASSERT_MSG((status3 == PEP_STATUS_OK), "status3 == PEP_STATUS_OK");
   35.10      const string string3 = text2;
   35.11      //free(text2);
   35.12 @@ -133,7 +133,7 @@
   35.13      inFile3.close();
   35.14  
   35.15      message *msg5 = nullptr;
   35.16 -    PEP_STATUS status5 = mime_decode_message(text3.c_str(), text3.length(), &msg5);
   35.17 +    PEP_STATUS status5 = mime_decode_message(text3.c_str(), text3.length(), &msg5, NULL);
   35.18      TEST_ASSERT_MSG((status5 == PEP_STATUS_OK), "status5 == PEP_STATUS_OK");
   35.19  
   35.20      message *msg6 = nullptr;
    36.1 --- a/test/src/engine_tests/MessageTwoPointOhTests.cc	Wed Aug 07 08:16:15 2019 +0200
    36.2 +++ b/test/src/engine_tests/MessageTwoPointOhTests.cc	Thu Aug 08 08:10:32 2019 +0200
    36.3 @@ -121,7 +121,7 @@
    36.4  //    cout << decrypted_text << endl;
    36.5      
    36.6      message* decoded_msg = nullptr;
    36.7 -    status = mime_decode_message(encoded_text, strlen(encoded_text), &decoded_msg);
    36.8 +    status = mime_decode_message(encoded_text, strlen(encoded_text), &decoded_msg, NULL);
    36.9      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   36.10      const string string3 = encoded_text;
   36.11        
   36.12 @@ -155,7 +155,7 @@
   36.13      }
   36.14       
   36.15      decrypted_msg->enc_format = PEP_enc_none; 
   36.16 -    status = _mime_encode_message_internal(decrypted_msg, false, &encoded_text, false);
   36.17 +    status = _mime_encode_message_internal(decrypted_msg, false, &encoded_text, false, false);
   36.18      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   36.19      TEST_ASSERT_MSG((encoded_text), "encoded_text");
   36.20      cout << "Decrypted message: " << endl;
    37.1 --- a/test/src/engine_tests/MimeTests.cc	Wed Aug 07 08:16:15 2019 +0200
    37.2 +++ b/test/src/engine_tests/MimeTests.cc	Thu Aug 08 08:10:32 2019 +0200
    37.3 @@ -44,7 +44,7 @@
    37.4  
    37.5      cout << "decoding message…\n";
    37.6      message *msg3;
    37.7 -    PEP_STATUS status3 = mime_decode_message(mimetext3.c_str(), mimetext3.length(), &msg3);
    37.8 +    PEP_STATUS status3 = mime_decode_message(mimetext3.c_str(), mimetext3.length(), &msg3, NULL);
    37.9      assert(status3 == PEP_STATUS_OK);
   37.10      assert(msg3);
   37.11      cout << "decoded.\n\n";
    38.1 --- a/test/src/engine_tests/PepSubjectReceivedTests.cc	Wed Aug 07 08:16:15 2019 +0200
    38.2 +++ b/test/src/engine_tests/PepSubjectReceivedTests.cc	Thu Aug 08 08:10:32 2019 +0200
    38.3 @@ -61,7 +61,7 @@
    38.4      PEP_rating rating;
    38.5      PEP_decrypt_flags_t flags;
    38.6      
    38.7 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
    38.8 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
    38.9      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   38.10      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   38.11      final_ptr = msg_ptr;
   38.12 @@ -95,7 +95,7 @@
   38.13      keylist = nullptr;
   38.14      rating = PEP_rating_unreliable;
   38.15      
   38.16 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   38.17 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
   38.18      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   38.19      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   38.20      final_ptr = msg_ptr;
   38.21 @@ -129,7 +129,7 @@
   38.22      
   38.23      mailtext = slurp("test_mails/pEp_subject_normal_signed_2a.eml");
   38.24      
   38.25 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   38.26 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
   38.27      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   38.28      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   38.29      final_ptr = msg_ptr;
   38.30 @@ -162,7 +162,7 @@
   38.31      
   38.32      mailtext = slurp("test_mails/p3p_subject_normal_signed_2b.eml");
   38.33      
   38.34 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   38.35 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
   38.36      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   38.37      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   38.38      final_ptr = msg_ptr;
   38.39 @@ -196,7 +196,7 @@
   38.40      
   38.41      mailtext = slurp("test_mails/pEp_encrypted_subject_IS_pEp_3a.eml");
   38.42      
   38.43 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   38.44 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
   38.45      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   38.46      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   38.47      final_ptr = msg_ptr;
   38.48 @@ -230,7 +230,7 @@
   38.49      
   38.50      mailtext = slurp("test_mails/p3p_encrypted_subject_IS_pEp_3b.eml");
   38.51      
   38.52 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   38.53 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
   38.54      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   38.55      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   38.56      final_ptr = msg_ptr;
   38.57 @@ -265,7 +265,7 @@
   38.58      
   38.59      mailtext = slurp("test_mails/pEp_subject_pEp_replaced_w_pEp_4a.eml");
   38.60      
   38.61 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   38.62 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
   38.63      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   38.64      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   38.65      final_ptr = msg_ptr;
   38.66 @@ -299,7 +299,7 @@
   38.67      
   38.68      mailtext = slurp("test_mails/pEp_subject_pEp_replaced_w_p3p_4b.eml");
   38.69      
   38.70 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   38.71 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
   38.72      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   38.73      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   38.74      final_ptr = msg_ptr;
   38.75 @@ -333,7 +333,7 @@
   38.76      
   38.77      mailtext = slurp("test_mails/pEp_subject_p3p_replaced_w_pEp_4c.eml");
   38.78      
   38.79 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   38.80 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
   38.81      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   38.82      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   38.83      final_ptr = msg_ptr;
   38.84 @@ -367,7 +367,7 @@
   38.85      
   38.86      mailtext = slurp("test_mails/pEp_subject_p3p_replaced_w_p3p_4d.eml");
   38.87      
   38.88 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   38.89 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
   38.90      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   38.91      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   38.92      final_ptr = msg_ptr;
   38.93 @@ -402,7 +402,7 @@
   38.94      
   38.95      mailtext = slurp("test_mails/pEp_unencrypted_pEp_subject_5a.eml");
   38.96      
   38.97 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   38.98 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
   38.99      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.100      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
  38.101      final_ptr = msg_ptr;
  38.102 @@ -437,7 +437,7 @@
  38.103      
  38.104      mailtext = slurp("test_mails/pEp_unencrypted_p3p_subject_5b.eml");
  38.105      
  38.106 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
  38.107 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
  38.108      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.109      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
  38.110      final_ptr = msg_ptr;
  38.111 @@ -471,7 +471,7 @@
  38.112      
  38.113      mailtext = slurp("test_mails/pEp_subject_normal_unencrypted_6.eml");
  38.114      
  38.115 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
  38.116 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
  38.117      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  38.118      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
  38.119      final_ptr = msg_ptr;
    39.1 --- a/test/src/engine_tests/ReencryptPlusExtraKeysTests.cc	Wed Aug 07 08:16:15 2019 +0200
    39.2 +++ b/test/src/engine_tests/ReencryptPlusExtraKeysTests.cc	Thu Aug 08 08:10:32 2019 +0200
    39.3 @@ -173,9 +173,8 @@
    39.4      
    39.5      int i = 0;
    39.6      
    39.7 -    if (keys->next)
    39.8 -    dedup_stringlist(keys->next);
    39.9 -;
   39.10 +    if (keys && keys->next)
   39.11 +        dedup_stringlist(keys->next);
   39.12      
   39.13      for (stringlist_t* kl = keys; kl && kl->value; kl = kl->next, i++)
   39.14      {
    40.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.2 +++ b/test/src/engine_tests/SenderFPRTests.cc	Thu Aug 08 08:10:32 2019 +0200
    40.3 @@ -0,0 +1,79 @@
    40.4 +// This file is under GNU General Public License 3.0
    40.5 +// see LICENSE.txt
    40.6 +
    40.7 +#include <stdlib.h>
    40.8 +#include <cstring>
    40.9 +#include <string>
   40.10 +
   40.11 +#include <cpptest.h>
   40.12 +#include "test_util.h"
   40.13 +
   40.14 +#include "pEpEngine.h"
   40.15 +#include "mime.h"
   40.16 +
   40.17 +#include "EngineTestIndividualSuite.h"
   40.18 +#include "SenderFPRTests.h"
   40.19 +
   40.20 +using namespace std;
   40.21 +
   40.22 +SenderFPRTests::SenderFPRTests(string suitename, string test_home_dir) :
   40.23 +    EngineTestIndividualSuite::EngineTestIndividualSuite(suitename, test_home_dir) {
   40.24 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("SenderFPRTests::check_sender_f_p_r"),
   40.25 +                                                                      static_cast<Func>(&SenderFPRTests::check_sender_f_p_r)));
   40.26 +}
   40.27 +
   40.28 +void SenderFPRTests::check_sender_f_p_r() {
   40.29 +    const char* alice_fpr = "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97";
   40.30 +    const char* bob_fpr = "BFCDB7F301DEEEBBF947F29659BFF488C9C2EE39";
   40.31 +    PEP_STATUS status = read_file_and_import_key(session,
   40.32 +                "test_keys/pub/pep-test-alice-0x6FF00E97_pub.asc");
   40.33 +    TEST_ASSERT(status == PEP_KEY_IMPORTED);
   40.34 +    status = set_up_ident_from_scratch(session,
   40.35 +                "test_keys/priv/pep-test-alice-0x6FF00E97_priv.asc",
   40.36 +                "pep.test.alice@pep-project.org", alice_fpr,
   40.37 +                PEP_OWN_USERID, "Alice in Wonderland", NULL, true
   40.38 +            );
   40.39 +    TEST_ASSERT(status == PEP_STATUS_OK);
   40.40 +    TEST_ASSERT_MSG(slurp_and_import_key(session, "test_keys/pub/pep-test-bob-0xC9C2EE39_pub.asc"),
   40.41 +                    "Unable to import test_keys/pub/pep-test-bob-0xC9C2EE39_pub.asc");
   40.42 +                    
   40.43 +
   40.44 +    message* msg = new_message(PEP_dir_outgoing);
   40.45 +    pEp_identity* alice = new_identity("pep.test.alice@pep-project.org", NULL, PEP_OWN_USERID, NULL);                
   40.46 +    pEp_identity* bob = new_identity("pep.test.bob@pep-project.org", NULL, "Bob", NULL);
   40.47 +    status = myself(session, alice);
   40.48 +    TEST_ASSERT(status == PEP_STATUS_OK);
   40.49 +    status = update_identity(session, bob);
   40.50 +    TEST_ASSERT(status == PEP_STATUS_OK);
   40.51 +    
   40.52 +    status = set_as_pEp_user(session, bob);
   40.53 +    TEST_ASSERT(status == PEP_STATUS_OK);
   40.54 +
   40.55 +    msg->to = new_identity_list(bob);
   40.56 +    msg->from = alice;
   40.57 +    msg->shortmsg = strdup("Yo Bob!");
   40.58 +    msg->longmsg = strdup("Look at my hot new sender fpr field!");
   40.59 +
   40.60 +    message* enc_msg = NULL;
   40.61 +    
   40.62 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
   40.63 +    TEST_ASSERT(status == PEP_STATUS_OK);
   40.64 +    TEST_ASSERT(stringpair_list_find(enc_msg->opt_fields, "X-pEp-Sender-FPR") == NULL);
   40.65 +    
   40.66 +    message* dec_msg = NULL;
   40.67 +
   40.68 +    stringlist_t* keylist = NULL;
   40.69 +    PEP_rating rating;
   40.70 +    PEP_decrypt_flags_t flags = 0;
   40.71 +    status = decrypt_message(session, enc_msg, &dec_msg, &keylist, &rating, &flags);
   40.72 +    TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   40.73 +
   40.74 +    char* text = NULL;
   40.75 +    mime_encode_message(dec_msg, false, &text);
   40.76 +    cout << text << endl;
   40.77 +    free(text);
   40.78 +    
   40.79 +    stringpair_list_t* fpr_node = stringpair_list_find(dec_msg->opt_fields, "X-pEp-Sender-FPR");
   40.80 +    TEST_ASSERT(fpr_node);
   40.81 +    TEST_ASSERT(strcmp(fpr_node->value->value, alice_fpr) == 0);
   40.82 +}
    41.1 --- a/test/src/engine_tests/SimpleBodyNotAltTests.cc	Wed Aug 07 08:16:15 2019 +0200
    41.2 +++ b/test/src/engine_tests/SimpleBodyNotAltTests.cc	Thu Aug 08 08:10:32 2019 +0200
    41.3 @@ -29,7 +29,7 @@
    41.4      string msg = slurp("test_mails/text message with html attach.eml");
    41.5      message* parsed = NULL;
    41.6  
    41.7 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &parsed);
    41.8 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &parsed, NULL);
    41.9      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   41.10      TEST_ASSERT(parsed);
   41.11      TEST_ASSERT(parsed->longmsg);
   41.12 @@ -47,7 +47,7 @@
   41.13      string msg = slurp("test_mails/HTML-only body w text attachment.eml");
   41.14      message* parsed = NULL;
   41.15  
   41.16 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &parsed);
   41.17 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &parsed, NULL);
   41.18      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   41.19      TEST_ASSERT(parsed);
   41.20      TEST_ASSERT(parsed->longmsg == NULL);
    42.1 --- a/test/src/util/test_util.cc	Wed Aug 07 08:16:15 2019 +0200
    42.2 +++ b/test/src/util/test_util.cc	Thu Aug 08 08:10:32 2019 +0200
    42.3 @@ -6,6 +6,7 @@
    42.4  #include "TestConstants.h"
    42.5  #include "mime.h"
    42.6  #include "message_api.h"
    42.7 +#include "keymanagement.h"
    42.8  
    42.9  #include <fstream>
   42.10  #include <sstream>
   42.11 @@ -17,6 +18,8 @@
   42.12  #include <unistd.h>
   42.13  #include <ftw.h>
   42.14  
   42.15 +using namespace std;
   42.16 +
   42.17  PEP_STATUS read_file_and_import_key(PEP_SESSION session, const char* fname) {
   42.18      const std::string key = slurp(fname);
   42.19      PEP_STATUS status = (key.empty() ? PEP_KEY_NOT_FOUND : PEP_STATUS_OK);
   42.20 @@ -184,6 +187,8 @@
   42.21              return "PEP_CANNOT_SET_PERSON";
   42.22          case PEP_CANNOT_SET_PGP_KEYPAIR:
   42.23              return "PEP_CANNOT_SET_PGP_KEYPAIR";
   42.24 +        case PEP_CANNOT_SET_PEP_VERSION:
   42.25 +            return "PEP_CANNOT_SET_PEP_VERSION";
   42.26          case PEP_CANNOT_SET_IDENTITY:
   42.27              return "PEP_CANNOT_SET_IDENTITY";
   42.28          case PEP_CANNOT_SET_TRUST:
   42.29 @@ -495,7 +500,7 @@
   42.30      message* dec_msg = NULL;
   42.31      *mime_plaintext = NULL;
   42.32  
   42.33 -    status = mime_decode_message(mimetext, size, &tmp_msg);
   42.34 +    status = mime_decode_message(mimetext, size, &tmp_msg, NULL);
   42.35      if (status != PEP_STATUS_OK)
   42.36          goto pEp_error;
   42.37  
   42.38 @@ -542,7 +547,7 @@
   42.39      }
   42.40  
   42.41      if (*flags & PEP_decrypt_flag_src_modified) {
   42.42 -        _mime_encode_message_internal(tmp_msg, false, modified_src, true);
   42.43 +        _mime_encode_message_internal(tmp_msg, false, modified_src, true, false);
   42.44          if (!modified_src) {
   42.45              *flags &= (~PEP_decrypt_flag_src_modified);
   42.46              decrypt_status = PEP_CANNOT_REENCRYPT; // Because we couldn't return it, I guess.
   42.47 @@ -550,7 +555,7 @@
   42.48      }
   42.49  
   42.50      // FIXME: test with att
   42.51 -    status = _mime_encode_message_internal(dec_msg, false, mime_plaintext, true);
   42.52 +    status = _mime_encode_message_internal(dec_msg, false, mime_plaintext, true, false);
   42.53  
   42.54      if (status == PEP_STATUS_OK)
   42.55      {
   42.56 @@ -580,7 +585,7 @@
   42.57      message* tmp_msg = NULL;
   42.58      message* enc_msg = NULL;
   42.59  
   42.60 -    status = mime_decode_message(mimetext, size, &tmp_msg);
   42.61 +    status = mime_decode_message(mimetext, size, &tmp_msg, NULL);
   42.62      if (status != PEP_STATUS_OK)
   42.63          goto pEp_error;
   42.64  
   42.65 @@ -635,7 +640,7 @@
   42.66          goto pEp_error;
   42.67      }
   42.68  
   42.69 -    status = _mime_encode_message_internal(enc_msg, false, mime_ciphertext, false);
   42.70 +    status = _mime_encode_message_internal(enc_msg, false, mime_ciphertext, false, false);
   42.71  
   42.72  pEp_error:
   42.73      free_message(tmp_msg);
   42.74 @@ -660,7 +665,7 @@
   42.75      message* tmp_msg = NULL;
   42.76      message* enc_msg = NULL;
   42.77  
   42.78 -    status = mime_decode_message(mimetext, size, &tmp_msg);
   42.79 +    status = mime_decode_message(mimetext, size, &tmp_msg, NULL);
   42.80      if (status != PEP_STATUS_OK)
   42.81          goto pEp_error;
   42.82  
   42.83 @@ -690,4 +695,253 @@
   42.84      return status;
   42.85  }
   42.86  
   42.87 +PEP_STATUS set_up_preset(PEP_SESSION session,
   42.88 +                         pEp_test_ident_preset preset_name,
   42.89 +                         bool set_ident, 
   42.90 +                         bool set_pep,
   42.91 +                         bool trust,
   42.92 +                         bool set_own, 
   42.93 +                         bool setup_private, 
   42.94 +                         pEp_identity** ident) {
   42.95 +    if (set_own && !set_ident)
   42.96 +        return PEP_ILLEGAL_VALUE;
   42.97 +        
   42.98 +    const char* name = NULL;
   42.99 +    const char* user_id = NULL;
  42.100 +    const char* email = NULL;
  42.101 +    const char* key_prefix = NULL;
  42.102 +    string pubkey_dir = "test_keys/pub/";
  42.103 +    string privkey_dir = "test_keys/priv/";
  42.104 +    const char* fpr = NULL;
  42.105 +    PEP_STATUS status = PEP_STATUS_OK;
  42.106 +    
  42.107 +    if (ident)
  42.108 +        *ident = NULL;
  42.109 +
  42.110 +    pEp_identity* retval = NULL;
  42.111 +        
  42.112 +    switch (preset_name) {
  42.113 +        case ALICE:
  42.114 +            name = "Alice Spivak Hyatt";
  42.115 +            user_id = "ALICE";
  42.116 +            email = "pep.test.alice@pep-project.org";
  42.117 +            key_prefix = "pep-test-alice-0x6FF00E97";
  42.118 +            fpr = "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97";
  42.119 +            break;
  42.120 +        case APPLE:
  42.121 +            name = "Apple of my Computer";
  42.122 +            user_id = "APPLE";
  42.123 +            email = "pep.test.apple@pep-project.org";
  42.124 +            key_prefix = "pep-test-apple-0x1CCBC7D7";
  42.125 +            fpr = "3D8D9423D03DDF61B60161150313D94A1CCBC7D7";
  42.126 +            break;
  42.127 +        case BOB:
  42.128 +            name = "Bob Dog";
  42.129 +            user_id = "BOB";
  42.130 +            email = "pep.test.bob@pep-project.org";
  42.131 +            key_prefix = "pep-test-bob-0xC9C2EE39";
  42.132 +            fpr = "BFCDB7F301DEEEBBF947F29659BFF488C9C2EE39";
  42.133 +            break;
  42.134 +        case CAROL:
  42.135 +            name = "Carol Burnett";
  42.136 +            user_id = "CAROL";
  42.137 +            email = "pep-test-carol@pep-project.org";
  42.138 +            key_prefix = "pep-test-carol-0x42A85A42";
  42.139 +            fpr = "8DD4F5827B45839E9ACCA94687BDDFFB42A85A42";
  42.140 +            break;
  42.141 +        case DAVE:
  42.142 +            name = "The Hoff";
  42.143 +            user_id = "DAVE";
  42.144 +            email = "pep-test-dave@pep-project.org";
  42.145 +            key_prefix = "pep-test-dave-0xBB5BCCF6";
  42.146 +            fpr = "E8AC9779A2D13A15D8D55C84B049F489BB5BCCF6";
  42.147 +            break;
  42.148 +        case ERIN:
  42.149 +            name = "Erin Ireland";
  42.150 +            user_id = "ERIN";
  42.151 +            email = "pep-test-erin@pep-project.org";
  42.152 +            key_prefix = "pep-test-erin-0x9F8D7CBA";
  42.153 +            fpr = "1B0E197E8AE66277B8A024B9AEA69F509F8D7CBA";
  42.154 +            break;
  42.155 +        case FRANK:
  42.156 +            name = "Frank N. Furter";
  42.157 +            user_id = "FRANK";
  42.158 +            email = "pep-test-frank@pep-project.org";
  42.159 +            key_prefix = "pep-test-frank-0x9A7FC670";
  42.160 +            fpr = "B022B74476D8A8E1F01E55FBAB6972569A7FC670"; // currently expired
  42.161 +            break;
  42.162 +        case GABRIELLE:
  42.163 +            name = "Gabrielle Gonzales";
  42.164 +            user_id = "GABI";
  42.165 +            email = "pep-test-gabrielle@pep-project.org";
  42.166 +            key_prefix = "pep-test-gabrielle-0xE203586C";
  42.167 +            fpr = "906C9B8349954E82C5623C3C8C541BD4E203586C";
  42.168 +            break;
  42.169 +        case JOHN:
  42.170 +            name = "John Denver";
  42.171 +            user_id = "JOHN";
  42.172 +            email = "pep.test.john@pep-project.org";
  42.173 +            key_prefix = "pep-test-john-0x70DCF575";
  42.174 +            fpr = "AA2E4BEB93E5FE33DEFD8BE1135CD6D170DCF575";
  42.175 +            break;
  42.176 +        case ALEX:
  42.177 +            name = "Alex Braithwaite";
  42.178 +            user_id = "ALEX";
  42.179 +            email = "pep.test.alexander@peptest.ch";
  42.180 +            key_prefix = "pep.test.alexander-0x26B54E4E";
  42.181 +            fpr = "3AD9F60FAEB22675DB873A1362D6981326B54E4E";
  42.182 +            break;
  42.183 +        case ALEX_0:
  42.184 +            name = "Alex Braithwaite";
  42.185 +            user_id = "ALEX";
  42.186 +            email = "pep.test.alexander0@darthmama.org";
  42.187 +            key_prefix = "pep.test.alexander0-0x3B7302DB";
  42.188 +            fpr = "F4598A17D4690EB3B5B0F6A344F04E963B7302DB";
  42.189 +            break;
  42.190 +        case ALEX_1:
  42.191 +            name = "Alex Braithwaite";
  42.192 +            user_id = "ALEX";
  42.193 +            email = "pep.test.alexander1@darthmama.org";
  42.194 +            key_prefix = "pep.test.alexander1-0x541260F6";
  42.195 +            fpr = "59AF4C51492283522F6904531C09730A541260F6";
  42.196 +            break;
  42.197 +        case ALEX_2:
  42.198 +            name = "Alex Braithwaite";
  42.199 +            user_id = "ALEX";
  42.200 +            email = "pep.test.alexander2@darthmama.org";
  42.201 +            key_prefix = "pep.test.alexander2-0xA6512F30";
  42.202 +            fpr = "46A994F19077C05610870273C4B8AB0BA6512F30";
  42.203 +            break;
  42.204 +        case ALEX_3:
  42.205 +            name = "Alex Braithwaite";
  42.206 +            user_id = "ALEX";
  42.207 +            email = "pep.test.alexander3@darthmama.org";
  42.208 +            key_prefix = "pep.test.alexander3-0x724B3975";
  42.209 +            fpr = "5F7076BBD92E14EA49F0DF7C2CE49419724B3975";
  42.210 +            break;
  42.211 +        case ALEX_4:
  42.212 +            name = "Alex Braithwaite";
  42.213 +            user_id = "ALEX";
  42.214 +            email = "pep.test.alexander4@darthmama.org";
  42.215 +            key_prefix = "pep.test.alexander4-0x844B9DCF";
  42.216 +            fpr = "E95FFF95B8E2FDD4A12C3374395F1485844B9DCF";
  42.217 +            break;
  42.218 +        case ALEX_5:
  42.219 +            name = "Alex Braithwaite";
  42.220 +            user_id = "ALEX";
  42.221 +            email = "pep.test.alexander5@darthmama.org";
  42.222 +            key_prefix = "pep.test.alexander5-0x0773CD29";
  42.223 +            fpr = "58BCC2BF2AE1E3C4FBEAB89AD7838ACA0773CD29";
  42.224 +            break;
  42.225 +        case ALEX_6A:
  42.226 +            name = "Alex Braithwaite";
  42.227 +            user_id = "ALEX";
  42.228 +            email = "pep.test.alexander6@darthmama.org";
  42.229 +            key_prefix = "pep.test.alexander6-0x0019697D";
  42.230 +            fpr = "74D79B4496E289BD8A71B70BA8E2C4530019697D";
  42.231 +            break;
  42.232 +        case ALEX_6B:
  42.233 +            name = "Alex Braithwaite";
  42.234 +            user_id = "ALEX";
  42.235 +            email = "pep.test.alexander6@darthmama.org";
  42.236 +            key_prefix = "pep.test.alexander6-0x503B14D8";
  42.237 +            fpr = "2E21325D202A44BFD9C607FCF095B202503B14D8";
  42.238 +            break;
  42.239 +        case ALEX_6C:
  42.240 +            name = "Alex Braithwaite";
  42.241 +            user_id = "ALEX";
  42.242 +            email = "pep.test.alexander6@darthmama.org";
  42.243 +            key_prefix = "pep.test.alexander6-0xA216E95A";
  42.244 +            fpr = "3C1E713D8519D7F907E3142D179EAA24A216E95A";
  42.245 +            break;
  42.246 +        case ALEX_6D:
  42.247 +            name = "Alex Braithwaite";
  42.248 +            user_id = "ALEX";
  42.249 +            email = "pep.test.alexander6@darthmama.org";
  42.250 +            key_prefix = "pep.test.alexander6-0xBDA17020";
  42.251 +            fpr = "B4CE2F6947B6947C500F0687AEFDE530BDA17020";
  42.252 +            break;
  42.253 +        case BELLA:
  42.254 +            name = "Bella Cat";
  42.255 +            user_id = "BELLA";
  42.256 +            email = "pep.test.bella@peptest.ch";
  42.257 +            key_prefix = "pep.test.bella-0xAF516AAE";
  42.258 +            fpr = "5631BF1357326A02AA470EEEB815EF7FA4516AAE";
  42.259 +            break;
  42.260 +        case FENRIS:
  42.261 +            name = "Fenris Leto Hawke";
  42.262 +            user_id = "FENRIS";
  42.263 +            email = "pep.test.fenris@thisstilldoesntwork.lu";
  42.264 +            key_prefix = "pep.test.fenris-0x4F3D2900";
  42.265 +            fpr = "0969FA229DF21C832A64A04711B1B9804F3D2900";
  42.266 +            break;
  42.267 +        case SERCULLEN:
  42.268 +            name = "Cullen Rutherford";
  42.269 +            user_id = "CULLEN";
  42.270 +            email = "sercullen-test@darthmama.org";
  42.271 +            key_prefix = "sercullen-0x3CEAADED4"; // NB expired on purpose
  42.272 +            fpr = "1C9666D8B3E28F4AA3847DA89A6E75E3CEAADED4";
  42.273 +            break;
  42.274 +        case INQUISITOR:
  42.275 +            name = "Inquisitor Claire Trevelyan";
  42.276 +            user_id = "INQUISITOR";
  42.277 +            email = "inquisitor@darthmama.org";
  42.278 +            key_prefix = "inquisitor-0xA4728718_renewed";
  42.279 +            fpr = "8E8D2381AE066ABE1FEE509821BA977CA4728718";
  42.280 +            break;
  42.281 +        case BERND:
  42.282 +            name = "Bernd das Brot";
  42.283 +            user_id = "BERNDI";
  42.284 +            email = "bernd.das.brot@darthmama.org";
  42.285 +            key_prefix = "bernd.das.brot-0xCAFAA422";
  42.286 +            fpr = "F8CE0F7E24EB190A2FCBFD38D4B088A7CAFAA422";
  42.287 +            break;
  42.288 +        default:
  42.289 +            return PEP_CANNOT_SET_IDENTITY;
  42.290 +    }
  42.291 +    
  42.292 +    string pubkey_file = pubkey_dir + key_prefix + "_pub.asc";
  42.293 +    string privkey_file = privkey_dir + key_prefix + "_priv.asc";
  42.294 +    
  42.295 +    if (!slurp_and_import_key(session, pubkey_file.c_str()))
  42.296 +        return PEP_KEY_NOT_FOUND;
  42.297 +
  42.298 +    if (setup_private) {    
  42.299 +        if (!slurp_and_import_key(session, privkey_file.c_str()))
  42.300 +            return PEP_KEY_NOT_FOUND;
  42.301 +    }
  42.302 +
  42.303 +    retval = new_identity(email, NULL, user_id, name);
  42.304 +    if (!retval)
  42.305 +        return PEP_OUT_OF_MEMORY;
  42.306 +        
  42.307 +    // honestly probably happens anyway  
  42.308 +    if (set_ident && status == PEP_STATUS_OK)
  42.309 +        status = set_identity(session, retval);
  42.310 +
  42.311 +    if (set_own) {
  42.312 +        retval->me = true;
  42.313 +        status = set_own_key(session, retval, fpr);
  42.314 +    }        
  42.315 +    
  42.316 +    if (set_pep && status == PEP_STATUS_OK)
  42.317 +        status = set_as_pEp_user(session, retval);
  42.318 +        
  42.319 +    if (trust && status == PEP_STATUS_OK) {
  42.320 +        if (!retval->me)
  42.321 +            status = update_identity(session, retval);
  42.322 +        if (retval->comm_type >= PEP_ct_strong_but_unconfirmed) {
  42.323 +            retval->comm_type = (PEP_comm_type)(retval->comm_type | PEP_ct_confirmed);
  42.324 +            status = set_trust(session, retval);
  42.325 +        }
  42.326 +    }
  42.327 +    
  42.328 +    
  42.329 +    if (ident)
  42.330 +        *ident = retval;
  42.331 +    else 
  42.332 +        free_identity(retval);
  42.333 +        
  42.334 +    return status;
  42.335 +}
  42.336  #endif
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/test/test_mails/2_0_msg.eml	Thu Aug 08 08:10:32 2019 +0200
    43.3 @@ -0,0 +1,131 @@
    43.4 +Message-ID: <pEp.PVTIO0.06RK6SSZLZKYW.31E3BDB9-6E1C-4DED-8190-75682B33A9BA@pep-project.org>
    43.5 +From: Alice Test <pep.test.alice@pep-project.org>
    43.6 +To: Carol Test <pep-test-carol@pep-project.org>
    43.7 +Subject: =?utf-8?Q?p=E2=89=A1p?=
    43.8 +X-pEp-Version: 2.0
    43.9 +MIME-Version: 1.0
   43.10 +Content-Type: multipart/mixed; boundary="2eb141f241b71efb79e2a9e37545e146"
   43.11 +
   43.12 +--2eb141f241b71efb79e2a9e37545e146
   43.13 +Content-Type: text/plain; charset="utf-8"
   43.14 +Content-Transfer-Encoding: quoted-printable
   43.15 +Content-Disposition: inline; filename="msg.txt"
   43.16 +
   43.17 +this message was encrypted with p=E2=89=A1p https://pEp-project.org
   43.18 +--2eb141f241b71efb79e2a9e37545e146
   43.19 +Content-Type: application/pgp-encrypted
   43.20 +
   43.21 +Version: 1
   43.22 +--2eb141f241b71efb79e2a9e37545e146
   43.23 +Content-Type: application/octet-stream
   43.24 +Content-Disposition: attachment; filename="msg.asc"
   43.25 +
   43.26 +-----BEGIN PGP MESSAGE-----
   43.27 +
   43.28 +wcBMA1oCBdlzCD9NAQf+JXC3scv9R9LHmEp63+PZspJCWIPPrSh07ypbMMWpK8ii
   43.29 +VINunHuepzmDtSjBFFLW2bb1DqZKs7pF7LzSm/NHux4sIzPNiXQMB488EB03nQal
   43.30 +p5xmt2P+SF8aVt7LKcDmppxf+LSXpUJ1n0WeoJssMxqSpT3gD1Tv/RlOqdTgoMnq
   43.31 +uagxe/MUDJSfwtTEzrKjkjQL6kxIHR0Cmwlr425ETlKSFSjObCVkYO5T/1EVNLcg
   43.32 +WN86KtYGV/k0zAaT2rJqE7WyzG9+NJHRz1vkqUAqX9smNbhAOV+zeWZbMWlEAk2c
   43.33 ++xqniTTnHG5lZEjl/n4MviWsL4IqprArSU4ttyxXc8HATAOo6/9vKSPoQgEH/363
   43.34 +1GGe+eJZnr7wTDgpVbs56xuISEU5qrM3Jp3sLZ6F53ahTW9x8JuXQdNQfD9RLSdX
   43.35 +COW1LzCcjlfInTKn8pGDANrBFys1YjVlclEDcyKU1EPNFVHtR59C8XZcFlGC4LCQ
   43.36 +dt1ynmDpk8wRgpcYdsSRKORiPyGCoeBsot0jL6wNMurItLEmVPcKZfPs6eHNMfgQ
   43.37 +hgqkqNXjBTCXNujpz8s2634exR4mKoDIv6qYECY3P6Nw9ulnM9bI1HN2Q4BfTDY9
   43.38 +op7/fzp2IVubZq24SeJzjJCcy/iOsFr/qDtaRlLolNgjOGBLllHrtPlGH6E4JmNW
   43.39 +QrzeywsIcqE01YHzuQ3S0F8BShoMdQSNHJTCLU/J1+rg2nZkRfLsMEmuWQ3RoXMf
   43.40 +yzEoL1qbXppyc6YousL9e7ixKi293btzh7dssu1bNS9wFwoysZsmKnGw0lk3wIIM
   43.41 +/9rybPJQhA/dePKHPIC7VAQhXPGIsJk9cyElRk+TH12CNjlwUbGiwIhxVFCX4deo
   43.42 +E9cZGGBi5XPVD5M3wP6/M0nFRyQDGCEi3NegMbd1UTePxMzoI9C5+LOa0YCXURk1
   43.43 +qH5sVR1Est3P8Fk4uOjsFJLPkZWG70jSeh8Mvz/Aw7BDS/kPoc+JsQ6b1vo2vcp7
   43.44 +UkYHg1n1sD8V3z0mKkbH5v1bBIdQkgAsnrahdXSh5Xrwx37Di70TB/u916mrnhmb
   43.45 +10VCGq8EhiZO+K2Ij6XfVSbdoEhPKNNDECvy/KppPnWJ/qWdqe5cConCpwTXYye4
   43.46 +P/rF4ojeWAy3CRdf3W5L9l5fVcpQ3XfJEByIHQRcDJoYGKPoMbptEY1yjNe+vpk7
   43.47 +mD/U7GGc/+0L1SngH3E0tmSg1QUQOlDW0InuXZtEv7i8ebsG+rR1BX5XXw+gazcf
   43.48 +EIKMtpyA2nEKZ3i0VNK74uKrrHBfO7sw9L7XvE8ldfMZ07lOQ/F3CkSiFiVbZtKh
   43.49 +DKSejNHuEx2goaRUkSRQN2A1YBs08Nw8wd0CPU5PJ7bZ+3Udy8IMLczL50dzrBDt
   43.50 +4nz6MeQCozE3726+cpiC+vFW8us7RqWKoqP6i7ubi1Rl5GV1scg3I+UNhHqOXyvn
   43.51 +e26NMqE/56/zdDAP0ECXz0l/5QNTcU6w3qCAszDOqqM/LQRpEI0Gok8/B/UBjOKh
   43.52 +vLUhDLI1b5Lq3zYn9ss0p5rvzXxfQYo0bPow8/KmpL9Yq24IGMf8XfnU2FsSzcn/
   43.53 +3o+CJcW7OjK65MmMmvE5/79vtgpk+sRnh/MiC000z39OHGt4rFTuWRMH039AQ9TR
   43.54 +0FNE8wQ4AfHQpxvJjqBwbTMrFiFMq1ve0lLgP8fO55H8xa9nYntg2BJqsBdBbLvK
   43.55 +zHJ4Iw1s1oY0FZDFDu2J4phadJpvKRJRG3cdZthT04Ry5MzKO5/KLDmyLEI5Kq+n
   43.56 +bbR72KeV7vpb0DDvoC0+69S+ndDBhK5n8v+IfiRsxmcBARJlNshKTXN69OeSdAT5
   43.57 +KDssACi4q+C6uv136WHm45VfK9EiEV8TRws8DeL3cjIpk7W94N9YmdFgf7XhRY5a
   43.58 +P2rdrk761/5g4agpCE7otoHIg/IbfPm9RW8B770c87A/uKE0hBDTbeDgDYvY/gpg
   43.59 ++MAu+WeHBoxeiEvIZ5c+3L6c2Jw8G8gDoVj6oOkvgo2Dbt4nA9qR0Ew31LqgJuAp
   43.60 +wyR0zSZWSqPWQA8nMhATthp+fbjbXL4OM3FRNponzrj9gJWjImL/joykvIyp+eFW
   43.61 +u1SK/XGMNF0//GDnwfy4/7PpphnQLCk5eAEByqSjtY7X9hT6Ag6Y8bQaDKnrCtNW
   43.62 +NBRMZIYpXvql3kWfB+JS4it06q9Bs+cCPEjgOOcOJbtKyNlWUxE43Z0UBtCY2mCE
   43.63 +75RX6T/HVy0JMnlznecZMbkxX5OI/p73FWS6XwIMhy1XSdDnlyDLNnP8lfD6w8Ac
   43.64 +9DrWUeP9EEVWfZ71dEnWB/xS5cv7+f580Hq+cmkn+AdHa3f9MozzYf+mnPQ1Jf/U
   43.65 +cEZ3AnNsTqBSr6UJcYOyhzh2HNGZ8HOGnVZKHbrGpgA8AiTPQ+X3L75+wEX6JmSX
   43.66 +mbb3NDS6vdvPzSo2GHKwvAaNVh37LOtjyhqKQKyGnDvRqgmwzl4BS6tvWvUR9x70
   43.67 +IIbIL1bgfL0g/UENvlIsuKOeHLkEEzuDcR8f5WKtiL8cMXpseIk7O4BDGjl9fz25
   43.68 +sVOarFkEuu+h+90GvnKjfIY8GTFlDcbKWpDjSAwgzdcCsFSKFhESD0v4Ek1hLzue
   43.69 +L3UerFZ0AIYxx8wzLZfpPSssALhjFg17pla+t3fjr50vlIDzBYT9R0ex+mavX83y
   43.70 +PiSbZ73R+K0kMaEnVyJY+w/xU11xnWv5gyTT4gvZL6kxNTW1tNUM582Wvv2BX0hJ
   43.71 +oJDIpevTuZVkzAXi+B4YbtCMvBDSsR/Ec93Sx0hj4AC3wBjcq/3aVZbfpA4oY7vU
   43.72 +3w6ghUkuO6q9uwMwdEY4D9ekatrbo5F5ny+HYPz+MOREURJs6M/UgD5QRknB6R/Z
   43.73 +UnwzPMq9IRC+6GI/9HGKfSWXDuFVZuSLZdONy2YeKVR1nIDkn0RiffEJGrzBpiuO
   43.74 +DeZnSAvZRJmY2mJr8LoTXVCZZ8xgW42axWLrAqiruRoVEWrow9XXwe475NbqVvHp
   43.75 +jwSKdEqrJJCOONz+EoOKZ6rbYw1J9UOAZFJW+wpiAvNOZwWulYRTfFXPbo/W0cPE
   43.76 +D4Pw3EDpFnnG6SpXLq9daHY/zZjnHZhRjHC+iSkJiXF250YF8MTNO1Ogwt3WyZsZ
   43.77 +b2a5hjp0FcSNaf1d5oh4qJC3RgqzoQE3nH+Y169dEYyWUDO8J6i21K+9APVF5JQu
   43.78 +wVyNxs7dAPPrsMFxiAQeAKpKivomhPqHAuVmN/SsDij1Phtjdk2qVibgHuXBk++D
   43.79 +Qs7VuyxZY0PYg2hdt1pxJVRWfdNQhT/CYSqgwoQsovoBnNKhseg46p2aX8FJ46B/
   43.80 +eYlmpsz3uPD6ImXTH3OyWjF7ZUa783r21MU0pUCz73DI5f6VjX3VcfXxGwJ5X0Mn
   43.81 +bjoY6Bz+b1yuby5B9wH3uS3xxY72o23CXYhzWlu7ypOWLkc8V+7Q0GKbtRn+rAv1
   43.82 +O5C/020U0bImP4qr/CfwOpQ6Vdr0xZGnBon38LG/AfuMqmQVinfWV21r+hxNsBYj
   43.83 +SqGyDPJf315pPewdDi2OCzjqQ9TUy+Mc4Hvy0zVBV95cW6nvNbHgIP6yybYOdzz4
   43.84 +zkYCsunNqA4ZSVdskO3oZsmwXjmTdWWRUVjz/Piv65mzGxRuUaW76wfk+QujfGC+
   43.85 +qrJvLD8emW1tvDrOkZnBkuw+0zkp5SHMjMWN6bbtQs86Ima9GCutG5pCbyg4TpVm
   43.86 +0CWLHpD6cJSyD3mB9gJJ8u4SgZ5XEOc1ks+cY6X4G5mEoj9bas7IGRGcfCMV5xYx
   43.87 +hDShus0kLPfVUHn7dNjqfzXRCMRtlLVz2Cq3B4hioxowYEMPiPWSdJgLrKpNyHBO
   43.88 +xDqnU2mjD+zTC48O3hNlavXNnNImpDciDu416RoUkDp7axQNT+5rcGMrIjQHn2wx
   43.89 +lKYGWmvI/1/kS/hKFK+Nqk/c+Ti9igRZ6toezF4ss3ryqy5jqDG0ZMbCPMHQo4Qw
   43.90 +UNA/DgrA+M13ys43SU0d/3wOG20/ZPc7oJqnECZvGWFezhTouZtqCGqg+znk5Sqa
   43.91 +a2wzEHFku4WF8dWweRiswhuc6+Oqdmhm/IjUaQ96nRwvvl/4qdsWsxn0f3+B5Wyo
   43.92 +F4UktNHoYwqEihaftYIndguy2TJTsP4uWXS0gqdE0I/rFHLy+Ynvtmue9OkWTdy7
   43.93 +JqOOA+V6h6/jA7IyqhFt2HP+sxAhNardIlu2lNq8oy3x5O280KceljyDQt+A1YNe
   43.94 +fAK8mYEVa27qGO5DgNC6v6L41iBFGFTzCDz0LcZl+r+teG2H8WHTIYVkpMCTBwHF
   43.95 +T3iNaZ/y4mzUZkI7xW8W/wFyir5t5eLRdJ5B/KGkfZDp1iZqOb1Ae9Fn6oMGqDzW
   43.96 +C3kU2+OUgp3ZQLfm8wnjDG2YQE3rjK2oHNdzqpiFb96dUReeJIt8LDqhCYTVmdvE
   43.97 +z3ZIJS0430lMQqlTsq9B8RqTaeFqzSOvOSGLnXuiXCD1NYJKe34ZTy3l7RqXE/Y/
   43.98 +ApdIfrMnLxDHUON29pq1g5jhdVZhAHKbUDKo6392f6XU3dnxTOkBqE364+Dk683z
   43.99 +tC9e2aPRnRJpPlcXboDSaGOoCnU9xGgLh+NnrGEiOXhoVli2v/e2cGaAB+CmW7jk
  43.100 +grwTmOq0DziO8FccVZ/1MMRRZsKPmwRj+c2UP8zOPpUK1STg3D6QMi1h33AGYLYc
  43.101 +7REbR8o2DMCjQ05PybyP4wm8xxVtS2+Ws7iIUZ3YFmk3M+DNeGLOKXvtREcACb0Q
  43.102 +WSAW1snoP2oqmR+LXoW6PTFy2R33FdAZQhhSIGTRimy5TtFdisSnzUBMAo+npOLm
  43.103 +cE9F3gcn9Tj5WbQfkJHAn0DsTgZ63XRN7IGyMz6vdYFTCs7R2VoTMXF1Qn7AoVhE
  43.104 +2Z8JcOy76UlBiVpbrftyh269Tb18k/oRCKLE1dyySWwopB5TaAbv7UGAqDLo+Dne
  43.105 +XsnohvKwuJnavntE1Xlu06r+6cjj7VhuOCCZ0VwvVNcad1xHMqA0CruTEENzn27l
  43.106 +FsKlTRCJzMHkXPhNgE21cpgHLd9qHHZFftwimM0ujEHSeSD5qSaz6QnFGooAFMnz
  43.107 +MAXcZUzMHowYUEGRU87GZ5V+n1baim71Brw5JZhkG9Xij93+yuwKywYMy1jIbJf8
  43.108 +G5jSGenj2xuHu8obDusVnm1it8Kid+Y9L1QtYkbmv/2enXCsmqxgYFPnxOSb35Th
  43.109 +amyFyva7z0ndykl5Eqz0WM/ZR6Y8iOGZD6WI9a+i4eMQUP/S1nFpP9XFSAGMJwYt
  43.110 +MW1EO0iU+crYZ20GDm+tcwVhEvePILFiwR3tzfTzbzS2NiXKoQwoQorbMbiR/a1z
  43.111 +GXL90+tag6K4QksOtJUrvrKa8lJUZffUZTmHfAyjlfVPgmLJb77HXfJqjXMXAIpX
  43.112 +EG8811iVswetlkfFXRN+I4nYQH5h3AQwpHAdXoN3ePltMSfWIqcJcIsbaG/Ppm74
  43.113 +SGlmZsB70kdOgTxdLWY7oX6plZXo1q7q5UcazAyYbEkgczaFQh31OGs3L8NdoUUk
  43.114 +AD8ZTc/5OWW7XIOI5SzMP7uwp6f+pcsRgMp0gBSGjQxFyROBa3atA5M4XbMBCVg/
  43.115 +3Kx1miy+4PDd8aVw3r1zYWy/eO4PXqO6MNAx2R1PMxYlUkp5W/b3V1f8FIfY4Cfj
  43.116 +3I0pBeVn5u8ZiL9LnbZEKCqqgdkX2J0U+UYFlwR38mWEWcU8+LmdZhTLOYRM8hiE
  43.117 +RwlX4pkUzjygNy4VgjTT6Z7WFYA6j7BgQkCGMWrOAPOJhZ2Cs66lehxbzpeleLJi
  43.118 +hlveRnUMzkfWg1dUj1xvud3eqM6S2kSv4PrHK7RZNruYJa6/Y0rAZi9zz8XVqu9Z
  43.119 +eIr0x/9hDjfPFnczsopXGUheNStoeVpSYH8Q5PesNgN1X3eVVUYTSCgI0hKNMQG4
  43.120 +n8kv0HVGPLKMH2LdYzZKpRar4f3Ekbj8BBOFjA40ShUw9ABsNOeM7GDlgNprKdwA
  43.121 +xtC7CltLwbhJORs53Cs2RXo3x67UyoWREbnMb+SpviejJ0tEqP66DjJTP65ywZqX
  43.122 +8VsDvpdu6PrMDHBnCpiQq8anN3+ofaWspM//fp0MewCQlsCAhHiGsCMAoCsePSM5
  43.123 +Tg8P0avZFaq1v4G1TgRDfPishz59E8idxQWruWkobWoM3WZ7geFKp+p4NmIGcxLi
  43.124 +NZ7kfhfTtA/wCWrweHwXQcrYSyPwZ4CJraZDqPg0f97XoLF+lVWuuYaU34go2/Kw
  43.125 +nN79sr7i2r4QSGH1whmaOOA4ZoNn/C/3yWKHcvSq1TTgyyJxrML6o+gqDwGWJXh5
  43.126 +Iae9hljnMUyNBpdDYXc8ackLHw0PsdaqBZDCogeDD9ZSjUZ0wp3ThmMaM0O4nrJW
  43.127 +b6+MQWMjOH04zLpXq3zqpa66ZYc5weVll715MfrOVzcRwm6AyHd3koc36Kmkb3Vv
  43.128 +bGyGkgXfHXj/rkBJUsDFJiHw/t/9KOmfWugbN/DV8rfDy2sH68SS+2QIlYeODTKn
  43.129 +qf7HSiCmeZgUIAjgWzD4BGUiGF6IjL3n3IT9DrvRibrjTw5d5NGGYhIZuXHbYx80
  43.130 +l6U9zh/Wplsi3+d1dTXwcI+rZLS48T0rVTQ+PkS+hdo=
  43.131 +=X2Iw
  43.132 +-----END PGP MESSAGE-----
  43.133 +
  43.134 +--2eb141f241b71efb79e2a9e37545e146--
    44.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.2 +++ b/test/test_mails/From_M1_0.eml	Thu Aug 08 08:10:32 2019 +0200
    44.3 @@ -0,0 +1,159 @@
    44.4 +X-Envelope-From: <SRS0=fIwmw7=WD=pep-project.org=pep-test-carol@srs.smtpin.rzone.de>
    44.5 +X-Envelope-To: <krista@darthmama.org>
    44.6 +X-Delivery-Time: 1565167147
    44.7 +X-UID: 1648
    44.8 +Return-Path: <SRS0=fIwmw7=WD=pep-project.org=pep-test-carol@srs.smtpin.rzone.de>
    44.9 +Authentication-Results: strato.com; dmarc=none header.from=pep-project.org
   44.10 +Authentication-Results: strato.com; arc=none
   44.11 +Authentication-Results: strato.com; dkim=none
   44.12 +Authentication-Results: strato.com; dkim-adsp=none header.from="pep-test-carol@pep-project.org"
   44.13 +Authentication-Results: strato.com; spf=pass smtp.mailfrom="SRS0=fIwmw7=WD=pep-project.org=pep-test-carol@srs.smtpin.rzone.de"
   44.14 +X-RZG-Expurgate: clean/normal
   44.15 +X-RZG-Expurgate-ID: 149500::1565167147-00003DDB-C7945173/0/0
   44.16 +X-RZG-CLASS-ID: mi00
   44.17 +Received-SPF: pass
   44.18 +	(strato.com: domain _spf.strato.com designates 2a01:238:20a:202:5100::3 as permitted sender)
   44.19 +	mechanism=ip6;
   44.20 +	client-ip=2a01:238:20a:202:5100::3;
   44.21 +	helo="mi6-p00-ob.smtp.rzone.de";
   44.22 +	envelope-from="SRS0=fIwmw7=WD=pep-project.org=pep-test-carol@srs.smtpin.rzone.de";
   44.23 +	receiver=smtpin.rzone.de;
   44.24 +	identity=mailfrom;
   44.25 +Received: from mi6-p00-ob.smtp.rzone.de ([IPv6:2a01:238:20a:202:5100::3])
   44.26 +	by smtpin.rzone.de (RZmta 44.24 OK)
   44.27 +	with ESMTPS id A06378v778d77Mx
   44.28 +	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits))
   44.29 +	(Client CN "*.smtp.rzone.de", Issuer "TeleSec ServerPass Class 2 CA" (verified OK (+EmiG)))
   44.30 +	(Client hostname verified OK)
   44.31 +	for <krista@darthmama.org>;
   44.32 +	Wed, 7 Aug 2019 10:39:07 +0200 (CEST)
   44.33 +X-RZG-FWD-BY: pep.test.alexander0@darthmama.org
   44.34 +Received: from mailin.rzone.de ([unix socket])
   44.35 +	by mailin.rzone.de (RZmta 44.24) with LMTPA;
   44.36 +	Wed, 7 Aug 2019 10:38:51 +0200 (CEST)
   44.37 +Authentication-Results: strato.com; dmarc=none header.from=pep-project.org
   44.38 +Authentication-Results: strato.com; arc=none
   44.39 +Authentication-Results: strato.com; dkim=none
   44.40 +Authentication-Results: strato.com; dkim-adsp=none header.from="pep-test-carol@pep-project.org"
   44.41 +Authentication-Results: strato.com; spf=none smtp.mailfrom="pep-test-carol@pep-project.org"
   44.42 +X-RZG-Expurgate: clean/normal
   44.43 +X-RZG-Expurgate-ID: 149500::1565167131-00003DDB-FC731615/0/0
   44.44 +X-Strato-MessageType: email
   44.45 +X-RZG-CLASS-ID: mi00
   44.46 +Received-SPF: none
   44.47 +	client-ip=94.231.81.244;
   44.48 +	helo="dragon.pibit.ch";
   44.49 +	envelope-from="pep-test-carol@pep-project.org";
   44.50 +	receiver=smtpin.rzone.de;
   44.51 +	identity=mailfrom;
   44.52 +Received: from dragon.pibit.ch ([94.231.81.244])
   44.53 +	by smtpin.rzone.de (RZmta 44.24 OK)
   44.54 +	with ESMTPS id m04b52v778cp8lj
   44.55 +	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits))
   44.56 +	(Client did not present a certificate)
   44.57 +	for <pep.test.alexander0@darthmama.org>;
   44.58 +	Wed, 7 Aug 2019 10:38:51 +0200 (CEST)
   44.59 +Received: from localhost (localhost [127.0.0.1])
   44.60 +	by dragon.pibit.ch (Postfix) with ESMTP id 08F6A171C07C
   44.61 +	for <pep.test.alexander0@darthmama.org>; Wed,  7 Aug 2019 10:38:51 +0200 (CEST)
   44.62 +Received: from dragon.pibit.ch ([127.0.0.1])
   44.63 +	by localhost (dragon.pibit.ch [127.0.0.1]) (amavisd-new, port 10024)
   44.64 +	with ESMTP id OvZUPxZCJx_I for <pep.test.alexander0@darthmama.org>;
   44.65 +	Wed,  7 Aug 2019 10:38:50 +0200 (CEST)
   44.66 +Received: from [192.168.43.214] (ip-109-40-131-98.web.vodafone.de [109.40.131.98])
   44.67 +	by dragon.pibit.ch (Postfix) with ESMTPSA id AD2B8171C069
   44.68 +	for <pep.test.alexander0@darthmama.org>; Wed,  7 Aug 2019 10:38:50 +0200 (CEST)
   44.69 +To: pep.test.alexander0@darthmama.org
   44.70 +From: pep-test-carol@pep-project.org
   44.71 +Subject: 1.0 Test Msg
   44.72 +Openpgp: preference=signencrypt
   44.73 +Message-ID: <967793b1-8d03-537c-1fca-2c18e029f5a4@pep.foundation>
   44.74 +Date: Wed, 7 Aug 2019 10:38:49 +0200
   44.75 +User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:60.0)
   44.76 + Gecko/20100101 Thunderbird/60.8.0
   44.77 +MIME-Version: 1.0
   44.78 +Content-Type: multipart/encrypted;
   44.79 + protocol="application/pgp-encrypted";
   44.80 + boundary="FJo2kRnx54tqD8mPE6mgtnDKuVoGxrGwO"
   44.81 +
   44.82 +This is an OpenPGP/MIME encrypted message (RFC 4880 and 3156)
   44.83 +--FJo2kRnx54tqD8mPE6mgtnDKuVoGxrGwO
   44.84 +Content-Type: application/pgp-encrypted
   44.85 +Content-Description: PGP/MIME version identification
   44.86 +
   44.87 +Version: 1
   44.88 +
   44.89 +--FJo2kRnx54tqD8mPE6mgtnDKuVoGxrGwO
   44.90 +Content-Type: application/octet-stream; name="encrypted.asc"
   44.91 +Content-Description: OpenPGP encrypted message
   44.92 +Content-Disposition: inline; filename="encrypted.asc"
   44.93 +
   44.94 +-----BEGIN PGP MESSAGE-----
   44.95 +
   44.96 +hQGMAwjkZzJfiW8+AQwA4TFiILeKBTdW3UQi8PcQKOzJE6pxgQL+B1gpOzjCRUel
   44.97 +n3drMe02EwZkmQcGwCmoIP9vdYw/mlEgsWvTbuv85CXXUyw8lJ5gT/u52H0/zHrU
   44.98 +yaJQu2WyCOVYEZv2qlVGw9pWSSW14Xh39aTiLwOKr4gtOoa7O9lbbyZI4TKVqn7d
   44.99 +8hUbEO/dScFFnzPTcUBwKsWmO4NBkQd9kW0v9kw2RtZwy47gYA+V1SlWiZAqsIV1
  44.100 +j1xUK4ZkWFfQlbh3aYX8RX1F5lwV56nR5bk0Jcpeu/NLSTUBJwck8IcgIQ+LnYZA
  44.101 +a4Fag+m+neEw0rkgdkAaD0Vb2GrOqG61p8uA5xkpcaOy+3QQb7DeeK1QKh22DFaS
  44.102 +MHZZynlcqYsurS/6iO9i7+OB+QbslWtnfItXJpKtwc24mLZp9Xp20gfO3KXElTIx
  44.103 +rI1S/LRwG0054CUwChVeO4OVr3mwmR/zMvw4XqFj0K/Cjx6qwy1esyl/FQfQrbZC
  44.104 +c05QW+ojpC6rGMFa4aGchQEMA6jr/28pI+hCAQf/ZNhBOn8pOARAW2csYHWtc8Fy
  44.105 +N0Sknn2VFvDLCI43P+HqgqZfqeu53WlbADJ8zd8xzi9riB+3HSMRS4bpD2WKOzut
  44.106 +RQmjdEZxLceA82clvY02AH1mpjMb9Axl0/FZRlmoqZtJEVMYDEeKXJmONr6M6J5n
  44.107 +agAsPiSX9H7fHkRBRvna6K3GUTZpftLuptTdR54YvMr6HR6+1M6847f6IXrza0I+
  44.108 ++IckY5iEL0JCTnSNYehEDfXVoq7AubsiuVMrXK313uKtrOnxPbeDz7OXxusfa/u9
  44.109 +y2A4YR8L3lj1F5ZiHEojfFnKU+k+P2dt/ydQjRo0WihtMhFHNKcZaS9AUUkE1tLr
  44.110 +AQXNiMOM3IdciqVMFNX8uKlpVOxi8/0ak7vzaPsEpp/x+gnFHNsBykQ+rMDC1D6p
  44.111 +kkEz9ukEqZmq5PvwRX51AbZMwoFBxWoLTEZU0/g2d2eSCY7FJUaCsMVxkrBjRR2K
  44.112 +GnCQjHqBazOyfF/qlUtRycXa7sQsSWV4ywU1h76xW9qrc8py+zz2bOJhgRUdTP0s
  44.113 +s2CTyKihoEkR9ORBMwbCG3ScwVF/xOFgz8xZQovHbvJGEZNNjIgfxibaSCPg3Bng
  44.114 +UdA/hkozmN4nxbmPWRafXvf9Zbf7ZAnRhelz32DfcSGzVwEdEWzPnHrEWmMkk0wf
  44.115 +tzVwLShpDKU8uf0XwOf3kNzbFeCD2IjOYBq3ddhCpzxr1ZBNPxeX8FW+3LYXZkJK
  44.116 +W7jVLoeFFfZxaYtlhDJ8/ZwbhIUcpu5e+U9hUek83DffCIm/Wsea2wdOv48+gc+h
  44.117 +vbTQsnJzVA+bJzsXryMpY77rngVoyU8YjEcXt3JTDxYgym6i895rxOZ0ZS4+j81a
  44.118 +CKgCVWO2vFslqg/nBqeCIVO6vRgv3Gie7/u91b3N1s0J5eeCl+QkLP4re1S/s9TD
  44.119 +e7AUum+3qrPSMwMS8Yns9WTlyqF5OS80R0iPPW8HtGT+hNFHMHxGy1wMUdabeD/M
  44.120 +WRnxyivnpQICfAJeN0rNMaJkB0phbb/zmqIO7j6yb3MTDA9R/C03h72fRd46Elai
  44.121 +jfBYdLjYrsdx7r5/z5igKCsvFSqozW68HdtNgqktPaG7HWbzsx1aQDjKi5O5bVuu
  44.122 +kQL75tZ58knss5v35HPLRbn4A4K8HGcX/N8UaYPQQXoZ4RjIOaeSPaWRTRw1zuj8
  44.123 +C9N7uXiVCyv4PNOZ+12Y6Tq3Xj/zkKHH5YsMs/sc9Nfz0AGVHaYHCqau8t1w40ab
  44.124 +/3AESAn6LO6P+97fFgsIq/Ox40MOdtMcQ7PIdySCcO3zzx5pp1dtoyJKCa4poXbs
  44.125 +T/ZEEMuwAMRLXVwVbfKST+OSUCJGs8vBEP/25wavKEVcwiRFbFpevlr1vSai2lVp
  44.126 +2UxXH5IBCdA6nXrNYIPLs2z0KyRgPI/SRovlWSeLGmaBcQiG23AuQJgtoRfE2BPk
  44.127 +iL3rdge+g3vzyqLwRiGsTMakwN8oYHgC6C+PO38L+u77Yu2gIzc55X9Dk15uQn99
  44.128 +8Q5w+EXZFMLZciZj2n1e1fQguoaF/QrJS0LFmftC5FC8e1o5vDorg56an8s3KlOW
  44.129 +tZnWBPqCoIkqwQPIvMuDSJpF/xTaOqRBqHEXwo9j3imodo7i40FxtinYgsMAvrY8
  44.130 +RuzKSgrpAIg1ADG79f4rpo8MVHNYKgFGUkc3P9YwrBMUCWJB2YYOV6v12ODo0NTt
  44.131 +P9Aep0+StCb5LiKT6YbfbA+wKIfkRdDddHw5ZR0NKOZjwK7HG3sxGsyWnpRsEYEv
  44.132 +o1pA7NKQa3kgSjpTeyYIVIF3CPJ+w7AlTUN30J5k3z+IeRYiTagr64lPjTYChPgT
  44.133 +fqG4ZdbWE9Dh0wO+jMm9a73ppVNBaGsFY4dg3x611vH6VoK1f1/9LVqW5bMNpIZz
  44.134 +vKh70giOnVnh0UpuK1Bnc8BUm3OMfYyVq5qiVj/4bGCAaNQcVNdbnLW7sXp+mLci
  44.135 +QBKGmlOZHQegoSRSyLIg60Z8FR1KDrIEZ0E5CaRAUdUA5WlPxTriDAUQa3zmNaaW
  44.136 +fe/87+0RbNpoJWPsG63XHVVkxgWk8472qpH9/qzqVrvrbiSB+VplJfQZL2LSVc7D
  44.137 +nJsTmTLNu5/VGt9L8lJzcwbhpfs9wiSVuPSgoovYRv4l9vrNpBaZzxdeicM0gZsy
  44.138 +Gdj/TSPd92zT7IOD70K8hWf8EHY0Uw/JkzJiFUHWNtw77M5ksTzOcarLw26s28EQ
  44.139 +iAPHAMmu0pdoyHlHYQY3wrDlesRbKSeilUvsxICXRvTlzx+SvV99Zs2/RfEAVD7X
  44.140 +DJL8FaS9ZwQvhGzcgAKq3SVo4v4FyaAWinSWSlE3f4ri+Xl7o/qvKMZ/kgnZxo+5
  44.141 +DGJ9M6qs2SLL8ICP9FOqC3eK/BnCcAbomN1hvDKPWJnluSBW7i6LXEq8dzp2YWR7
  44.142 +wljAJKuM29IWmYVTl+WzGDBQqHHUNGpymzUip+mBXlJG3n/3kaN8Snhk1qwes8Hi
  44.143 ++KaILwL2I8kFDuEO0xhqtErpbeMHUephLmSckgh4SdL+UdEC8JWfmth/PwX2b7US
  44.144 +ZA6co8X2ysPbni1Z61Df9rejZDMPTG2gm1Jn4kGUhwTBQnNBUUigNDukZxmJnagC
  44.145 +XZaUphij9kOsLQe6qXUqNXTmRmDKowSjkSu4/VIBUgdYKkIHMkfoNyWTn7MO2NUm
  44.146 +YGMQJLPqSheKM2WBwjlCrMHe5vuDH4OO0zjQWfJ0oPGrK5htMlmwjWYKjLXhmMPy
  44.147 +RRKil/PfKMCpZamiLFDt1YP9M62qTHktEuwIzjad/KERI3DOPmWszZWV36+b6s2q
  44.148 +ieasWYWIZHJBcTCc2AetjHlVvJrPPnMlOI6vS0OMYJVTiL5nzR2Rk6GkH1PXizqw
  44.149 +co/+Q4zLeC0Zx7u1FOdhX7s8a+qsV/kLbqczSMBOEDiMpcuQUGfB39XeuloOGkby
  44.150 +I/muioTiZqVKH06U6iZiAXktqdmsWOBABydeknKiBftpVc88eFQ9s7GTmidayjTF
  44.151 +FAuYmA3OP4dNlVImzuuB81qui28uNYF8LIwfpAukNU6yQQpU7sZhW7OuUq/KHjTq
  44.152 +aAtQuaHDgL8RD5HeYHx6w/RY1Ug9NGPEpNKsws1QzOvAS73vYKH0eILUONWd/JbV
  44.153 +0OB8ZQ0njP8CLcxrA5QZIMrhnw+k05wuPevfeFP/kvcfRuQu1qMhpqMt60M8PSHx
  44.154 +g1a2lGYzZV3d4VKZVuD4CZWg6eduqEQTKRx/nj2Fkfzdw5UVK8KdMhm2dX1a9Nzr
  44.155 +NNOf7wM5ypgkNGWvh/oxUJYVgKJUewN+9GzGn7L86WFyzcwVVllpcRKXCzz/1kNU
  44.156 +B3/tDbNvKntbgbNvMQNgMgHvW7H2NuZdHPjDxvkZQPRaKpquAx/zOHNjl1MASkJc
  44.157 +w4pEHRH2mssVX37Zi7C4qRu0F43nt+BiCYSixcCVXsHF2BKsKkSAV9elmcJWfAHo
  44.158 +sUuYMxKH4stfkWDNRQ==
  44.159 +=4k3/
  44.160 +-----END PGP MESSAGE-----
  44.161 +
  44.162 +--FJo2kRnx54tqD8mPE6mgtnDKuVoGxrGwO--
    45.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.2 +++ b/test/test_mails/From_M2_1.eml	Thu Aug 08 08:10:32 2019 +0200
    45.3 @@ -0,0 +1,124 @@
    45.4 +Message-ID: <pEp.PVUYXR.0AZSSOYBYY6MW.CEB1AB30-47AC-4B4D-AC1B-C3CF8F02D49D@pep-project.org>
    45.5 +From: Alice Spivak Hyatt <pep.test.alice@pep-project.org>
    45.6 +To: Carol Burnett <pep-test-carol@pep-project.org>
    45.7 +Subject: =?utf-8?Q?p=E2=89=A1p?=
    45.8 +X-pEp-Version: 2.1
    45.9 +MIME-Version: 1.0
   45.10 +Content-Type: multipart/encrypted; boundary="2eb141f241b71efb79e2a9e37545e146"; 
   45.11 + protocol="application/pgp-encrypted"
   45.12 +
   45.13 +--2eb141f241b71efb79e2a9e37545e146
   45.14 +Content-Type: application/pgp-encrypted
   45.15 +
   45.16 +Version: 1
   45.17 +--2eb141f241b71efb79e2a9e37545e146
   45.18 +Content-Type: application/octet-stream
   45.19 +Content-Transfer-Encoding: 7bit
   45.20 +Content-Disposition: inline; filename="msg.asc"
   45.21 +
   45.22 +-----BEGIN PGP MESSAGE-----
   45.23 +
   45.24 +wcBMA1oCBdlzCD9NAQgAlTYeWEzZy4kP4gD5m6d/QpGWVBZ9UFu9YqOSmiX3i+g1
   45.25 +DJyKPtYc9n1X5IDFr2VutmB73PLFgIySh3gV4LV2Nw9DMCFLo4LuamACXSmTYgfX
   45.26 +LwEi6X/tUl9gfnGWfokFDn5og/8g9fIAu3Iju+IoCYTxse3CbRzen6K88A/Eze1O
   45.27 +XW7W6lmo01CiqgJ++fxkuh68qfHROHIoiCo5cACdj98HKvtMPMLFXa+VIqDxKrt1
   45.28 +8jKGZxlA244MFfjHW5ICO6G0k1wQaUgw0PKRSBSshX6okKytfH3ckEkFNJVQZtRT
   45.29 +72j5I6ssuNUs53ymSzsrV5IrQhK/EsnhmnKBJ+GsosHATAOo6/9vKSPoQgEH/1DK
   45.30 +FH2UPlmflD3+07vlFZyoCwCYlcgN9sWl77bT5CTSFV4PK19F9vkaYcOwEbGxcS1D
   45.31 +z7OnHTFNTe3kVuM9kzWZ+F87+phGV6FWoAfuGAOWF3luZSop0quIJLwu1n3EtX0D
   45.32 +Xl5OchfLitcWxzrCXZHcvM+P4VEsIWudnJFC4hHHWgbbOF65B4dVEs3dINyVoTF6
   45.33 +z+iQImCn3EDPhcB9SlMZOob8hGUvUSTZDJJETZPHAJeW76NGQZ95fF/x9nqr/3/N
   45.34 +alGQ7Lq7R9Inv9BYlnXmJXTEnhLwFlwlPVoMf7pQnj3D0CYKP9AldrDNP2mQHYWO
   45.35 +Yac/3uDXiN5/QrLCMg3Sz8YBY9rS1pWV8ZZt+ZzY5jEIpdOUSw89mfEUDeZTNDo0
   45.36 +VoDzJvKn42NlRVQk4/6TVfaezgJjw/eVs0xLjOCGdsgCJ/PojExY+dfuo071Asbq
   45.37 +dCpc9qgNzDNJoS2XftTFHb1cH1ttC8an1ySLQNBg/9vguFAUxr+kAomfO1lRxpv5
   45.38 +BT2F7UBQTqWHqO4CPffsWQ5e6vCIx2c2FO3aFR0+WY3uTmlIZyjjMz1mB9KjjuO8
   45.39 +BgERxWd75ahoB3w8Hveel0vTussKpkLxxcQChhstcozoFX8M2VqVwVYqn7uChP9q
   45.40 +TPbuRVUpLvAAwKyO10eM+GZaHNbar7//v9KlCG1SLVE5PR8v5/n7L5slJwVfkqwR
   45.41 +9lZGtrSy4dB0lSfeQRwCd3iduu3oMdo2GeWU5duBdqqbrEGXAtubctZqXwzew1Vb
   45.42 +kNYuyozstv5B9psFSBshEaRGTFRGHuKB952AUeh8ISPX9IbucxNSbXxBRCOx/9Wj
   45.43 +1E9bm8WYZTT9r9Qwj1v0z0XfFze9i1nYWh8OVMCcsokhClBn46vDbY427cwSaS/O
   45.44 +luuqSL2B3Jhg4uCHNWHMjYvZh9jS50R7Do6aljQVK+TPk77LidAaNtG9fm04nL7+
   45.45 ++6+tLlMLKJ914i8t0rR8kTWtSp9xfzE59My56HOFsNZ3VAxrOaY2Xzxn67m8rXt5
   45.46 +0wXGy6yEQ9imoiQakZnOHWilE1BOplzIvdTugi2q8ILfqToE3t8vlSi9K39vUUTV
   45.47 +uj/Fw9vbGjfoeHt06mxHHSN3ePDj1v78jm8W10m+c0Zwrz3KrKW4B2WMrpqz8D6N
   45.48 +/PY/qJIccfCpCBZcZMO+6Wa4SWeYUyNn/JhhMCES9cpyllnZyVGrTb8l0NHhNG/P
   45.49 +eOuRa+5z7c/CtCSQlMlX2gti23q6j4mdm3HdaBQrW8uKvqKuh72pLDXUaY3EoDN7
   45.50 +g3V9I127hxd6K8KTKG/S18nlfHoSc9gVho4YOys9WEYE9S/Gznf4aU1lnnrjaKLF
   45.51 +B9w/RmWryqdu7hEl92j0zhdvQt6RI3/2rE7RN4XW7TtcmlnyWh6nfiqBLnS9zvU7
   45.52 +4hzukfMKQ91M8UfqpocQdxnxLk8TCw/RKhQP7onu9jR3nnPhtH54Ag3ohPxz+xBq
   45.53 +9k5K8Uo3JQXYFxs9hBYUc6WOLACQxOEmzMTApAr4nHObLp4Q74gd8FJ2KOmaWS13
   45.54 +vLJTmHroCw0w69dNZSUWQaSrn/enmXZ8Y4IOoZ17B5el5Ms76heYinjHY+sofi0I
   45.55 +cg2QrHxM+t0u7f9qaU0hbHWVt33i6AmGChu+0M/HyjSiEWv/Q5jE2lG0b/6yVl+f
   45.56 +C/6QUMg6Fr/6eVKuCeEYjVgoTMKDmQdo/w1SUSjfpVAdB/o6WL1lcv26k8HRsNZa
   45.57 +gEAPQuC/xEY8Vrou62etOh6tDO2jZ7ytd96aTcHvRIecilORhSOS7ClrNrBD8JJG
   45.58 +WGak9E5zBjLXXl8hSo+WMw0DOKacA6ccie0VRNlkg7QrGZD3S+FqKX/6Pv/YI7Q0
   45.59 ++RgS5hoKnj3vNmyAijJi2Nzksl+wjFZa5UnVsReynCZfOkZC+l5SrLwx5dX+NbG2
   45.60 +vdzGiw6ldLK/GO4n9tEIkpT0NfOLUbh26huhl59GWsv1XMA5R48J0vyqZCKfd6bG
   45.61 +V6wjEiELo0D7JMyhVsEqYMsr8DwyXH6yJ1UsKWDc/gKk6dx55SxJc8cBcu+s6qqg
   45.62 +mlXUGMXWj3VNHE4YeSd8BNA7f/yZSUTP6sO2fJsy5wuf8QcYNVE04bv2Vo7rnuaJ
   45.63 +9HpPwqwEeSqI5mjsdxwXHd434H7F7CCVUSqbkZe9jzsLC+Lb0xQYwtjk62pUq1CX
   45.64 +hI9k8YU5RuTeRv2Pg6Gzm17uXNG1wCZAWX2lWC+CgLpv+A0+ihy9srDnBZZPh2A+
   45.65 +ii9PKO36HlAszm6K/El/OGKN9El2PkberPblfFhfzXmPYLB5jiyMyIA/Vn9E4mp0
   45.66 +FyU7oFEttC0np9WGcExLPJWbL5dxqlAOKBuL0Rn+0+lvQjjb0aHQTku/yXE+6qlA
   45.67 +VwjbTT+4C4t6Jg4enJpAUZkzDVsr9hfkqkN1ezkjiNAJKD2NXD3nnOjHV0NMwfjL
   45.68 +Lm4vtOLJAKl3uMRFhqH0VkSbt4WuVe3hyro8LR7zstIfY7csEtcpk2RGCIFBqJjv
   45.69 +q1VSYpfg2ig5u06A2bDGY82GYmNAwnk3tEf1sBIdvLHDSHwKAQcmnlUAiMWoQRDA
   45.70 ++z+axP1qIUb1A7Ph7fqRQBLDQwqL0cT6f0dSy6oPT3IRd/R5C23AJB6G1HsSiBTP
   45.71 +i+lVdk14iseZW2yQcfXKq1mQCDMxP9ic6r+AaI7U70bGyVT/LM2LQ0JK0n5a9e31
   45.72 +llhu3XWoVrePhrPYo/nChSxkCjE/cmopeD/znKOSGPFYuxa1EEEjCN2R5Vm37kT4
   45.73 +say+GspHnatm8SGRSSRsiANl9hWnM/TdbeGZGUYZPV8kBqEMmX7mMic7T6ny8RZE
   45.74 +IWjMPZN9y4OygFNTD2KHd/krPfpvQSl7hRtjZJaDakNKxkMsKoTZjhGFDOqMeqoP
   45.75 +dufoxsCIV/oUPTRrgpQy4BPXbRkRYAKWOhwTr5OgbfT43M0WA+eUmPyqYQJn6iS+
   45.76 +75vAUAwNjX/+L0ECYqnnDSb2PPPIdGVSv0wOk01CSLKwlPoq0BezFw4iYqGXcWVN
   45.77 +kKLYvm+o+y6izCOlwtyPZpWDkSb9+gnsRXkjhGAlhVYawYxDWrKJY+9Qk1l7HHFU
   45.78 +45IMaDsiRamgjsmBuSrR95TUsaxwx2+/BXPK/7UmHFSR3JTEhzbaOHiGSrS8JxXm
   45.79 +3dt95pfSnAM5OxcLge6m0tSPXil/2KN/MGoJLR45+hZq9Kh6P4mb4MOu/nrIjq1U
   45.80 +O/haaF7seh1N4CvhFK+0DQ32aMwrgyla/EinRq2uIcXGMXBqf6k3zL8KlAfPWdeR
   45.81 +8uhShYs6HdIN7bG91jy83QTrYfptDBWQUPQdcqaNDb1ByOBpzkbyjrGTszCdYou2
   45.82 +/WZlV3vRuadiK1OfvnWWQrEGX6A4ug3fy6H7rfJmCxqL7w06eac+leihCw1y8rZK
   45.83 +A+Er1smYn5k1A8Jc66QsKlXGWvpTF28nGmKkLHJeQquS2OK4TPKNObY3U1J7MpNj
   45.84 +asAvoiyrQppHKOEqSf9nls2EdywtN45sGaotPZVmNUzSU4xyA4WmJBLScDHysgf/
   45.85 +1ZwaHpexLCUNKd8dQ/dm1SXO0zG0+iB7sDpjPcYUTIzVRLP6ihB+xvQZpd29Z6mG
   45.86 +lM8AcJSaLhl9bFe5PPBKIygtuuj8nJojpY2MlU4jK23axeNvtIFgypZmU8E1gCSj
   45.87 +kxEXuL8cBhF090DJ/xeDtc5hlXi7QXL6p3WnDpSe5W0NT9mI36wg21vlqwVvJVn+
   45.88 ++WKkD4pkAQEaXxa5B7U5XAut43qdQQSWcZHBsfifsYFmwhyT63XkAhkkCg1pTKCI
   45.89 +Lm9W2GN6VBk9gp4fzKEzf29yUjs18xa1g8sYGi9iWMKJVvCpVSVbtl2f6UAkUFky
   45.90 +0H1e1U4sFiQtapTpvnJyyUg4jaOoU9lATID32ZMcxPeLFpPI0k2zFV1j3SqaC67K
   45.91 +MxPzhQhCepq+8T9cdp7fBee6u5DVKEOd6jpdgom7VYE68Hjc7HyWd2XsOyDmGemp
   45.92 +QbPloTJDoa/g1sMbG6AW5zuNNoKlrktAb04S6AQdE30KdivwKtAEg34/rmzOXeNf
   45.93 +Y6L4W7OIPNhrv7uvmiMiLnAKxFBTlru5rPuNzIVmjmuysJBisi+3dqtN+KuZYWAo
   45.94 +C5ssivN+OBuJrypoKOYmyDmmOgT5YRIn7Uhm0DTOez10aprg8jOyfcyCSZ10c633
   45.95 +ZeUNl7FQ2+Nt/yyY3mQH1HP2aU+orA/qpqAYW4kaq8wWH/00soUXrik5FkPg5s5H
   45.96 +Mrqtnz4QimqAMTixQg2BTGATVm+Kv2F9PVlTmiSVl4Uv93t7w5ipoCieuYaVmDjq
   45.97 +KSV8RNbasl/+qwtWK0szEeE/8Tl6ZlKT0/EfMYKMGGPbSKryzmjYrSzXK0rkv56S
   45.98 +b9JqdZ633m6EQIBLzImtZscd11kYuiZynJLmWUW5PbdPqo3OGCIcWuOcQ4aPHVqD
   45.99 +0XPna30bcjIY937Jo5+kWyg2/mLQ24aV99hUIhOc5aLlNi6P5n+22iA68t/sUIT9
  45.100 +v+UC3ScD8MmUQg6gRPt8bWk78DmMP6AmnZx8a0HwCYwPmSi4uZzh1AkREs4KsWHe
  45.101 +z2NqeolSvSH3O3gaWtjs08mPOfZ+JGtDLyfmAM2Ojttfz7gHb6a7ZtjVXgTpXqH7
  45.102 +xGvY3udeibO6THZ9Y9rymXH9OpCt2Qc69GuBAgfDpXZOVb8JMROWnDmgkObo27Kc
  45.103 +bdFSWnzbbWgXo2xVUlKDih3lSaBFdntthAxjKj0dckCJ8J31P+LYBoX9yEeiMZaJ
  45.104 +j1fhiRMk/Ae4hTUbzc0Fabut8A3p0Ah+YgH2Pf7DEr7LE9/GH5/J4hB5fEC+n4Dq
  45.105 +q+fjNkZyvx6seZrwr1h5APg96cmrZeuAELLRkJzqbBq5aaQQgYr/B9tiA+PIIn9p
  45.106 +6grNHm8YKwIzO/Tgk7MgLyEZIkg0CVvM74t6u7JLc+hXoDLe957BrgDuqgwRu8OP
  45.107 +kh2OfFKBAw/38qtDdILpZ4MI4L9OoQI0QNTScN2aB9eXRBir9DvUhAtmNfepQjxM
  45.108 +O/tWO2D+L27Yoofx2LIZ0trg4GcaOSE3jmsHr+VAz9axwVUdG9wQPbSshzbsCpZQ
  45.109 +YXY+o1ofi+RSm957ANUYqSnpRl7PYiypVbdu+wVK+iqacotFeoCDV+vmOtfUkarW
  45.110 +DRNLDCZeguG0zQ5MsGAn1jhxsFXizSoXFlqfHUP3B3qJpP5R4CiFZjdYzXHUwoxl
  45.111 +N0UdleUpq5gWJXpZd+0ELR2HvA7d2NVLjUEgJuyMnwx+lXnqd9v9jdk9SMkHxwje
  45.112 +ETGI+Vy4dpjAGwTQNTUTMD/R4krlJP8uJ4D2mrzK/aFL1+WilKKWIEUlH7llwRT0
  45.113 +IEQplQt/4tXd4sCuojqV6dqJtWEQV0Y51BKDgUL7bTzktCTKCS5LzhxRD/5EtC/R
  45.114 +vYNXyfEvU2j4MxG/ghQwBlFF/v8xrWCufL4Jqr2sx3OWQIkJY5Ol6F3ZjY7amUEt
  45.115 +CMvgkx0cL2YeYejCwLUcgMXKO1FaWfL/DDg0DvOjqhlXWgUXUslDst6lmDZFNiuc
  45.116 +MJJsNyMPCO9o+Y1YCSiXz8M801Md3YsAxv59+1Tlqq1oxkSXOhmpVtKkiQNTjRmH
  45.117 +L9bVjckIJ95ejynGKpjoEPZsXDPBVq1ty59+EXZTVO1ZqxkrcrHFzAtQqkwpHOur
  45.118 +9rd0D26W//PzOGDC30O3VNkhgxtB94bzlXkmg7PleiJBgOrThPM/ojTOQmW3BX4y
  45.119 +EqzSQGJUDErQwOtXBYCJW5K5ITorfi/ykYKaCuj2MfmHFyWTV0kBQh/zOKWXcH70
  45.120 +kfdjDo9Oh7D+RhOsSwrUj0v3t91+x4LcCMsL83vbKqtoYZ1+a7PJl7/zY81Rwuo4
  45.121 +lCx911ITGeHR5nxclHeZ5XRkNjdJVz0UNshRyPbaH7d8XnkJA0ZeKcTJnUEMtjwJ
  45.122 +t5HnJE5aUbilAxBm+3bhmHrmcExXW7OgtbX9Nb8R7Yg7CX6Bgc1t8cRTuGT+sfFC
  45.123 +7jOFijjxNApGQfKC4cuCTx5J6P62FSc=
  45.124 +=orc1
  45.125 +-----END PGP MESSAGE-----
  45.126 +
  45.127 +--2eb141f241b71efb79e2a9e37545e146--