merged in Message 2.1 sync
authorKrista 'DarthMama' Bennett <krista@pep.foundation>
Wed, 07 Aug 2019 14:08:11 +0200
branchsync
changeset 39610eb8fc56d6fb
parent 3953 1690e12b4bc4
parent 3960 932e02830434
child 3963 60b100beecb3
merged in Message 2.1
     1.1 --- a/src/aux_mime_msg.c	Wed Aug 07 12:10:12 2019 +0200
     1.2 +++ b/src/aux_mime_msg.c	Wed Aug 07 14:08:11 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/etpan_mime.c	Wed Aug 07 12:10:12 2019 +0200
     2.2 +++ b/src/etpan_mime.c	Wed Aug 07 14:08:11 2019 +0200
     2.3 @@ -38,6 +38,7 @@
     2.4  struct mailmime * part_new_empty(
     2.5          struct mailmime_content * content,
     2.6          struct mailmime_fields * mime_fields,
     2.7 +        stringpair_list_t* param_keyvals,
     2.8          int force_single
     2.9      )
    2.10  {
    2.11 @@ -127,6 +128,40 @@
    2.12          if (content->ct_parameters == NULL)
    2.13              content->ct_parameters = parameters;
    2.14      }
    2.15 +    
    2.16 +    if (param_keyvals) {
    2.17 +        stringpair_list_t* cur;
    2.18 +        for (cur = param_keyvals; cur; cur = cur->next) {
    2.19 +            attr_name = strdup(cur->value->key);
    2.20 +            attr_value = strdup(cur->value->value);
    2.21 +            
    2.22 +            param = mailmime_parameter_new(attr_name, attr_value);
    2.23 +            assert(param);
    2.24 +            if (param == NULL)
    2.25 +                goto enomem;
    2.26 +                
    2.27 +            attr_name = NULL;
    2.28 +            attr_value = NULL;
    2.29 +
    2.30 +            if (content->ct_parameters == NULL) {
    2.31 +                parameters = clist_new();
    2.32 +                assert(parameters);
    2.33 +                if (parameters == NULL)
    2.34 +                    goto enomem;
    2.35 +            }
    2.36 +            else {
    2.37 +                parameters = content->ct_parameters;
    2.38 +            }
    2.39 +
    2.40 +            r = clist_append(parameters, param);
    2.41 +            if (r)
    2.42 +                goto enomem;
    2.43 +            param = NULL;
    2.44 +
    2.45 +            if (content->ct_parameters == NULL)
    2.46 +                content->ct_parameters = parameters;            
    2.47 +        }
    2.48 +    }
    2.49  
    2.50      build_info = mailmime_new(mime_type, NULL, 0, mime_fields, content, NULL,
    2.51              NULL, NULL, list, NULL, NULL);
    2.52 @@ -163,7 +198,7 @@
    2.53      if (mime_fields == NULL)
    2.54          goto enomem;
    2.55  
    2.56 -    mime = part_new_empty(content, mime_fields, 1);
    2.57 +    mime = part_new_empty(content, mime_fields, NULL, 1);
    2.58      if (mime == NULL)
    2.59          goto enomem;
    2.60      mime_fields = NULL;
    2.61 @@ -252,7 +287,7 @@
    2.62              goto enomem;
    2.63      }
    2.64  
    2.65 -    mime = part_new_empty(content, mime_fields, 1);
    2.66 +    mime = part_new_empty(content, mime_fields, NULL, 1);
    2.67      if (mime == NULL)
    2.68          goto enomem;
    2.69      content = NULL;
    2.70 @@ -289,7 +324,8 @@
    2.71          const char * mime_type,
    2.72          char * data,
    2.73          size_t length,
    2.74 -        bool transport_encode
    2.75 +        bool transport_encode,
    2.76 +        bool set_attachment_forward_comment
    2.77      )
    2.78  {
    2.79      char * disposition_name = NULL;
    2.80 @@ -351,7 +387,13 @@
    2.81      encoding = NULL;
    2.82      disposition = NULL;
    2.83  
    2.84 -    mime = part_new_empty(content, mime_fields, 1);
    2.85 +    stringpair_list_t* extra_params = NULL;
    2.86 +    
    2.87 +    if (set_attachment_forward_comment)
    2.88 +        extra_params = new_stringpair_list(new_stringpair("forwarded", "no"));
    2.89 +    
    2.90 +    mime = part_new_empty(content, mime_fields, extra_params, 1);
    2.91 +    free_stringpair_list(extra_params);
    2.92      if (mime == NULL)
    2.93          goto enomem;
    2.94      content = NULL;
    2.95 @@ -396,7 +438,7 @@
    2.96      if (content == NULL)
    2.97          goto enomem;
    2.98      
    2.99 -    mp = part_new_empty(content, mime_fields, 0);
   2.100 +    mp = part_new_empty(content, mime_fields, NULL, 0);
   2.101      if (mp == NULL)
   2.102          goto enomem;
   2.103      
   2.104 @@ -815,6 +857,22 @@
   2.105      return false;
   2.106  }
   2.107  
   2.108 +bool _is_message_part(struct mailmime_content *content, const char* subtype) {
   2.109 +    assert(content);
   2.110 +    if (content->ct_type && content->ct_type->tp_type == MAILMIME_TYPE_COMPOSITE_TYPE &&
   2.111 +            content->ct_type->tp_data.tp_composite_type &&
   2.112 +            content->ct_type->tp_data.tp_composite_type->ct_type ==
   2.113 +            MAILMIME_COMPOSITE_TYPE_MESSAGE) {
   2.114 +        if (subtype)
   2.115 +            return content->ct_subtype &&
   2.116 +                    strcasecmp(content->ct_subtype, subtype) == 0;
   2.117 +        else
   2.118 +            return true;                
   2.119 +    }
   2.120 +    
   2.121 +    return false;
   2.122 +}
   2.123 +
   2.124  int _get_content_type(
   2.125          const struct mailmime_content *content,
   2.126          char **type,
   2.127 @@ -948,7 +1006,8 @@
   2.128  #endif
   2.129  
   2.130  static PEP_STATUS interpret_MIME(struct mailmime *mime,
   2.131 -                                 message *msg);
   2.132 +                                 message *msg,
   2.133 +                                 bool* raise_msg_attachment);
   2.134  
   2.135  // This function was rewritten to use in-memory buffers instead of
   2.136  // temporary files when the pgp/mime support was implemented for
   2.137 @@ -1006,7 +1065,8 @@
   2.138  static PEP_STATUS mime_attachment(
   2.139          bloblist_t *blob,
   2.140          struct mailmime **result,
   2.141 -        bool transport_encode
   2.142 +        bool transport_encode,
   2.143 +        bool set_attachment_forward_comment
   2.144      )
   2.145  {
   2.146      PEP_STATUS status = PEP_STATUS_OK;
   2.147 @@ -1031,7 +1091,8 @@
   2.148      bool already_ascii = !(must_chunk_be_encoded(blob->value, blob->size, true));
   2.149  
   2.150      mime = get_file_part(resource, mime_type, blob->value, blob->size, 
   2.151 -                          (already_ascii ? false : transport_encode));
   2.152 +                          (already_ascii ? false : transport_encode),
   2.153 +                          set_attachment_forward_comment);
   2.154      free_rid_list(resource);
   2.155      
   2.156      assert(mime);
   2.157 @@ -1155,7 +1216,7 @@
   2.158      for (_a = attachments; _a != NULL; _a = _a->next) {
   2.159          if (_a->disposition != PEP_CONTENT_DISP_INLINE)
   2.160              continue;
   2.161 -        status = mime_attachment(_a, &submime, transport_encode);
   2.162 +        status = mime_attachment(_a, &submime, transport_encode, false);
   2.163          if (status != PEP_STATUS_OK)
   2.164              return PEP_UNKNOWN_ERROR; // FIXME
   2.165  
   2.166 @@ -1632,7 +1693,8 @@
   2.167          const message *msg,
   2.168          bool omit_fields,
   2.169          struct mailmime **result,
   2.170 -        bool transport_encode
   2.171 +        bool transport_encode,
   2.172 +        bool set_attachment_forward_comment
   2.173      )
   2.174  {
   2.175      struct mailmime * mime = NULL;
   2.176 @@ -1711,14 +1773,19 @@
   2.177          }
   2.178  
   2.179          bloblist_t *_a;
   2.180 +        bool first_one = true;
   2.181 +        
   2.182          for (_a = msg->attachments; _a != NULL; _a = _a->next) {
   2.183  
   2.184              if (_a->disposition == PEP_CONTENT_DISP_INLINE)
   2.185                  continue;
   2.186  
   2.187 -            status = mime_attachment(_a, &submime, transport_encode);
   2.188 +            status = mime_attachment(_a, &submime, transport_encode,
   2.189 +                                     (first_one && set_attachment_forward_comment));                         
   2.190              if (status != PEP_STATUS_OK)
   2.191                  goto pEp_error;
   2.192 +            
   2.193 +            first_one = false;    
   2.194  
   2.195              r = mailmime_smart_add_part(mime, submime);
   2.196              assert(r == MAILIMF_NO_ERROR);
   2.197 @@ -1830,7 +1897,8 @@
   2.198          const message * msg,
   2.199          bool omit_fields,
   2.200          char **mimetext,
   2.201 -        bool transport_encode
   2.202 +        bool transport_encode,
   2.203 +        bool set_attachment_forward_comment
   2.204      )
   2.205  {
   2.206      PEP_STATUS status = PEP_STATUS_OK;
   2.207 @@ -1850,11 +1918,12 @@
   2.208  
   2.209      switch (msg->enc_format) {
   2.210          case PEP_enc_none:
   2.211 -            status = mime_encode_message_plain(msg, omit_fields, &mime, transport_encode);
   2.212 +            status = mime_encode_message_plain(msg, omit_fields, &mime, transport_encode, set_attachment_forward_comment);
   2.213              break;
   2.214  
   2.215 +        // I'm presuming we should hardcore ignoring set_attachment_forward_comment here...
   2.216          case PEP_enc_inline:
   2.217 -            status = mime_encode_message_plain(msg, omit_fields, &mime, transport_encode);
   2.218 +            status = mime_encode_message_plain(msg, omit_fields, &mime, transport_encode, false);
   2.219              break;
   2.220  
   2.221          case PEP_enc_S_MIME:
   2.222 @@ -2402,7 +2471,7 @@
   2.223          // ???
   2.224          // This is what we would have done before, so... no
   2.225          // worse than the status quo. But FIXME!
   2.226 -        status = interpret_MIME(part, msg);
   2.227 +        status = interpret_MIME(part, msg, NULL);
   2.228          if (status)
   2.229              return status;
   2.230      }
   2.231 @@ -2417,7 +2486,7 @@
   2.232          if (content == NULL)
   2.233              return PEP_ILLEGAL_VALUE;
   2.234  
   2.235 -        status = interpret_MIME(part, msg);
   2.236 +        status = interpret_MIME(part, msg, NULL);
   2.237          if (status)
   2.238              return status;
   2.239      }
   2.240 @@ -2426,7 +2495,8 @@
   2.241  
   2.242  static PEP_STATUS interpret_MIME(
   2.243          struct mailmime *mime,
   2.244 -        message *msg
   2.245 +        message *msg,
   2.246 +        bool* raise_msg_attachment
   2.247      )
   2.248  {
   2.249      PEP_STATUS status = PEP_STATUS_OK;
   2.250 @@ -2476,7 +2546,7 @@
   2.251                          return status;
   2.252                  }
   2.253                  else /* add as attachment */ {
   2.254 -                    status = interpret_MIME(part, msg);
   2.255 +                    status = interpret_MIME(part, msg, NULL);
   2.256                      if (status)
   2.257                          return status;
   2.258                  }
   2.259 @@ -2499,7 +2569,7 @@
   2.260                  if (part == NULL)
   2.261                      return PEP_ILLEGAL_VALUE;
   2.262  
   2.263 -                status = interpret_MIME(part, msg);
   2.264 +                status = interpret_MIME(part, msg, NULL);
   2.265                  if (status != PEP_STATUS_OK)
   2.266                      return status;
   2.267              }
   2.268 @@ -2510,11 +2580,13 @@
   2.269                  return PEP_ILLEGAL_VALUE;
   2.270  
   2.271              clistiter *cur;
   2.272 -            for (cur = clist_begin(partlist); cur; cur = clist_next(cur)) {
   2.273 +            // only add raise_msg_attachment on 2nd part!
   2.274 +            int _att_count = 0;
   2.275 +            for (cur = clist_begin(partlist); cur; cur = clist_next(cur), _att_count++) {
   2.276                  struct mailmime *part= clist_content(cur);
   2.277                  if (part == NULL)
   2.278                      return PEP_ILLEGAL_VALUE;
   2.279 -                status = interpret_MIME(part, msg);
   2.280 +                status = interpret_MIME(part, msg, _att_count == 1 ? raise_msg_attachment : NULL);
   2.281                  if (status != PEP_STATUS_OK)
   2.282                      return status;
   2.283              }
   2.284 @@ -2547,6 +2619,25 @@
   2.285                      return status;
   2.286              }
   2.287              else {
   2.288 +                // Fixme - we need a control on recursion level here - KG: maybe NOT. We only go to depth 1.
   2.289 +                if (raise_msg_attachment != NULL) {
   2.290 +                    bool is_msg = (_is_message_part(content, "rfc822") || _is_text_part(content, "rfc822"));
   2.291 +                    if (is_msg) {
   2.292 +                        if (content->ct_parameters) {
   2.293 +                            clistiter *cur;
   2.294 +                            for (cur = clist_begin(content->ct_parameters); cur; cur =
   2.295 +                                 clist_next(cur)) {
   2.296 +                                struct mailmime_parameter * param = clist_content(cur);
   2.297 +                                if (param && param->pa_name && strcasecmp(param->pa_name, "forwarded") == 0) {
   2.298 +                                    if (param->pa_value && strcasecmp(param->pa_value, "no") == 0) {
   2.299 +                                        *raise_msg_attachment = true;
   2.300 +                                        break;
   2.301 +                                    }
   2.302 +                                }
   2.303 +                            }
   2.304 +                        }
   2.305 +                    }
   2.306 +                }
   2.307                  char *data = NULL;
   2.308                  size_t size = 0;
   2.309                  char * mime_type;
   2.310 @@ -2633,7 +2724,8 @@
   2.311  DYNAMIC_API PEP_STATUS mime_decode_message(
   2.312          const char *mimetext,
   2.313          size_t size,
   2.314 -        message **msg
   2.315 +        message **msg,
   2.316 +        bool* raise_msg_attachment
   2.317      )
   2.318  {
   2.319      PEP_STATUS status = PEP_STATUS_OK;
   2.320 @@ -2677,7 +2769,7 @@
   2.321  
   2.322      if (content) {
   2.323          status = interpret_MIME(mime->mm_data.mm_message.mm_msg_mime,
   2.324 -                _msg);
   2.325 +                _msg, raise_msg_attachment);
   2.326          if (status != PEP_STATUS_OK)
   2.327              goto pEp_error;
   2.328      }
   2.329 @@ -2702,4 +2794,3 @@
   2.330  
   2.331      return status;
   2.332  }
   2.333 -
     3.1 --- a/src/etpan_mime.h	Wed Aug 07 12:10:12 2019 +0200
     3.2 +++ b/src/etpan_mime.h	Wed Aug 07 14:08:11 2019 +0200
     3.3 @@ -8,10 +8,12 @@
     3.4  #include <libetpan/mailmime_encode.h>
     3.5  
     3.6  #include "resource_id.h"
     3.7 +#include "stringpair.h"
     3.8  
     3.9  struct mailmime * part_new_empty(
    3.10          struct mailmime_content * content,
    3.11          struct mailmime_fields * mime_fields,
    3.12 +        stringpair_list_t* param_keyvals,        
    3.13          int force_single
    3.14      );
    3.15  
    3.16 @@ -30,7 +32,8 @@
    3.17          const char * mime_type,
    3.18          char * data,
    3.19          size_t length,
    3.20 -        bool transport_encode
    3.21 +        bool transport_encode,
    3.22 +        bool set_attachment_forward_comment
    3.23      );
    3.24  
    3.25  struct mailmime * part_multiple_new(const char *type);
     4.1 --- a/src/keymanagement.c	Wed Aug 07 12:10:12 2019 +0200
     4.2 +++ b/src/keymanagement.c	Wed Aug 07 14:08:11 2019 +0200
     4.3 @@ -454,7 +454,11 @@
     4.4      
     4.5      if (pEp_user) {
     4.6          PEP_comm_type confirmation_status = identity->comm_type & PEP_ct_confirmed;
     4.7 -        identity->comm_type = PEP_ct_pEp_unconfirmed | confirmation_status;    
     4.8 +        identity->comm_type = PEP_ct_pEp_unconfirmed | confirmation_status;
     4.9 +        if (identity->major_ver == 0) {
    4.10 +            identity->major_ver = 2;
    4.11 +            identity->minor_ver = 0;
    4.12 +        }    
    4.13      }
    4.14  }
    4.15  
    4.16 @@ -528,6 +532,9 @@
    4.17      
    4.18      return_id->me = stored_ident->me;
    4.19      
    4.20 +    return_id->major_ver = stored_ident->major_ver;
    4.21 +    return_id->minor_ver = stored_ident->minor_ver;
    4.22 +
    4.23      // FIXME: Do we ALWAYS do this? We probably should...
    4.24      if (EMPTYSTR(return_id->user_id)) {
    4.25          free(return_id->user_id);
    4.26 @@ -569,7 +576,7 @@
    4.27      }
    4.28      
    4.29      transfer_ident_lang_and_flags(return_id, stored_ident);
    4.30 -    
    4.31 +        
    4.32      if (return_id->comm_type == PEP_ct_unknown)
    4.33          return_id->comm_type = PEP_ct_key_not_found;
    4.34      
    4.35 @@ -1221,6 +1228,12 @@
    4.36          identity->comm_type = PEP_ct_unknown;
    4.37      }
    4.38      
    4.39 +    int major_ver = 0;
    4.40 +    int minor_ver = 0;
    4.41 +    pEp_version_major_minor(PEP_VERSION, &major_ver, &minor_ver);
    4.42 +    identity->major_ver = major_ver;
    4.43 +    identity->minor_ver = minor_ver;
    4.44 +    
    4.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
    4.46      // it's NOT ok
    4.47      if (!read_only) {
     5.1 --- a/src/message.c	Wed Aug 07 12:10:12 2019 +0200
     5.2 +++ b/src/message.c	Wed Aug 07 14:08:11 2019 +0200
     5.3 @@ -44,6 +44,7 @@
     5.4          free_stringlist(msg->keywords);
     5.5          free(msg->comments);
     5.6          free_stringpair_list(msg->opt_fields);
     5.7 +        free(msg->_sender_fpr);
     5.8          free(msg);
     5.9      }
    5.10  }
    5.11 @@ -185,6 +186,12 @@
    5.12              goto enomem;
    5.13      }
    5.14  
    5.15 +    if (src->_sender_fpr) {
    5.16 +        msg->_sender_fpr = strdup(src->_sender_fpr);
    5.17 +        if (msg->_sender_fpr == NULL)
    5.18 +            goto enomem;
    5.19 +    }
    5.20 +    
    5.21      msg->enc_format = src->enc_format;
    5.22  
    5.23      return msg;
    5.24 @@ -218,13 +225,15 @@
    5.25      free(dst->longmsg);
    5.26      free(dst->longmsg_formatted);
    5.27      free(dst->comments);
    5.28 +    free(dst->_sender_fpr);
    5.29      dst->id = src->id;
    5.30      dst->shortmsg = src->shortmsg;
    5.31      dst->longmsg = src->longmsg;
    5.32      dst->longmsg_formatted = src->longmsg_formatted;
    5.33      dst->comments = src->comments;    
    5.34 +    dst->_sender_fpr = src->_sender_fpr;
    5.35      src->id = src->shortmsg = src->longmsg = src->longmsg_formatted = NULL;
    5.36 -    src->comments = NULL;
    5.37 +    src->comments = src->_sender_fpr = NULL;
    5.38      
    5.39      /* bloblists */
    5.40      free_bloblist(dst->attachments);
     6.1 --- a/src/message.h	Wed Aug 07 12:10:12 2019 +0200
     6.2 +++ b/src/message.h	Wed Aug 07 14:08:11 2019 +0200
     6.3 @@ -70,6 +70,9 @@
     6.4      char *comments;                         // UTF-8 string with comments
     6.5      stringpair_list_t *opt_fields;          // optional fields
     6.6      PEP_enc_format enc_format;              // format of encrypted data
     6.7 +    char* _sender_fpr;                      // INTERNAL USE ONLY - fingerprint of 
     6.8 +                                            // sending signer.
     6.9 +                                            // (read_only to the outside)
    6.10  } message;
    6.11  
    6.12  typedef struct _message_ref_list {
     7.1 --- a/src/message_api.c	Wed Aug 07 12:10:12 2019 +0200
     7.2 +++ b/src/message_api.c	Wed Aug 07 14:08:11 2019 +0200
     7.3 @@ -33,58 +33,6 @@
     7.4      return false;
     7.5  }
     7.6  
     7.7 -static bool is_wrapper(message* src)
     7.8 -{
     7.9 -    bool retval = false;
    7.10 -    
    7.11 -    if (src) {
    7.12 -        unsigned char pEpstr[] = PEP_SUBJ_STRING;
    7.13 -        if (is_a_pEpmessage(src) || (src->shortmsg == NULL || strcmp(src->shortmsg, "pEp") == 0 ||
    7.14 -            _unsigned_signed_strcmp(pEpstr, src->shortmsg, PEP_SUBJ_BYTELEN) == 0) ||
    7.15 -            (strcmp(src->shortmsg, "p=p") == 0)) {
    7.16 -            char* plaintext = src->longmsg;
    7.17 -            if (plaintext) {
    7.18 -                const char *line_end = strchr(plaintext, '\n');
    7.19 -
    7.20 -                if (line_end != NULL) {
    7.21 -                    size_t n = line_end - plaintext;
    7.22 -                    
    7.23 -                    char* copycat = calloc(n + 1, 1);
    7.24 -                    
    7.25 -                    if (copycat) {
    7.26 -                        strlcpy(copycat, plaintext, n+1);
    7.27 -                        
    7.28 -                        if (strstr(copycat, PEP_MSG_WRAP_KEY) && strstr(copycat, "OUTER"))
    7.29 -                            retval = true;
    7.30 -                        
    7.31 -                        free(copycat);
    7.32 -                    }
    7.33 -                }
    7.34 -            }
    7.35 -        }
    7.36 -    }
    7.37 -    return retval;
    7.38 -}
    7.39 -
    7.40 -
    7.41 -/*
    7.42 - * static stringpair_t* search_optfields(const message* msg, const char* key) {
    7.43 - *     if (msg && key) {
    7.44 - *         stringpair_list_t* opt_fields = msg->opt_fields;
    7.45 - *         
    7.46 - *         const stringpair_list_t* curr;
    7.47 - *         
    7.48 - *         for (curr = opt_fields; curr && curr->value; curr = curr->next) {
    7.49 - *             if (curr->value->key) {
    7.50 - *                 if (strcasecmp(curr->value->key, key) == 0)
    7.51 - *                     return curr->value;
    7.52 - *             }
    7.53 - *         } 
    7.54 - *     }
    7.55 - *     return NULL;
    7.56 - * }
    7.57 - */
    7.58 -
    7.59  static char * keylist_to_string(const stringlist_t *keylist)
    7.60  {
    7.61      if (keylist) {
    7.62 @@ -890,7 +838,7 @@
    7.63  }
    7.64  
    7.65  static message* wrap_message_as_attachment(message* envelope, 
    7.66 -    message* attachment, message_wrap_type wrap_type, bool keep_orig_subject) {
    7.67 +    message* attachment, message_wrap_type wrap_type, bool keep_orig_subject, unsigned int max_major, unsigned int max_minor) {
    7.68      
    7.69      if (!attachment)
    7.70          return NULL;
    7.71 @@ -916,10 +864,22 @@
    7.72              default:
    7.73                  inner_type_string = "INNER";
    7.74          }
    7.75 -        attachment->longmsg = encapsulate_message_wrap_info(inner_type_string, attachment->longmsg);
    7.76 -        _envelope->longmsg = encapsulate_message_wrap_info("OUTER", _envelope->longmsg);
    7.77 +        if (max_major < 2 || (max_major == 2 && max_minor == 0)) {
    7.78 +            attachment->longmsg = encapsulate_message_wrap_info(inner_type_string, attachment->longmsg);        
    7.79 +            _envelope->longmsg = encapsulate_message_wrap_info("OUTER", _envelope->longmsg);
    7.80 +        }
    7.81 +        else {
    7.82 +            _envelope->longmsg = strdup(
    7.83 +                "This message was encrypted with p≡p (https://pep.software). If you are seeing this message,\n" 
    7.84 +                "your client does not support raising message attachments. Please click on the message attachment to\n"
    7.85 +                "to view it, or better yet, consider using p≡p!\n"
    7.86 +            );
    7.87 +        }
    7.88 +        // 2.1, to replace the above
    7.89 +        add_opt_field(attachment, X_PEP_MSG_WRAP_KEY, inner_type_string); 
    7.90      }
    7.91      else if (_envelope) {
    7.92 +        // 2.1 - how do we peel this particular union when we get there?
    7.93          _envelope->longmsg = encapsulate_message_wrap_info("TRANSPORT", _envelope->longmsg);
    7.94      }
    7.95      else {
    7.96 @@ -947,9 +907,15 @@
    7.97          if (!attachment->shortmsg)
    7.98              goto enomem;
    7.99      }
   7.100 +    
   7.101 +    /* add sender fpr to inner message */
   7.102 +    add_opt_field(attachment, 
   7.103 +                  "X-pEp-Sender-FPR", 
   7.104 +                  (attachment->_sender_fpr ? attachment->_sender_fpr : "")
   7.105 +              );
   7.106              
   7.107      /* Turn message into a MIME-blob */
   7.108 -    status = _mime_encode_message_internal(attachment, false, &message_text, true);
   7.109 +    status = _mime_encode_message_internal(attachment, false, &message_text, true, false);
   7.110          
   7.111      if (status != PEP_STATUS_OK)
   7.112          goto enomem;
   7.113 @@ -1029,7 +995,8 @@
   7.114      const message *src,
   7.115      stringlist_t *keys,
   7.116      message *dst,
   7.117 -    PEP_encrypt_flags_t flags
   7.118 +    PEP_encrypt_flags_t flags,
   7.119 +    message_wrap_type wrap_type
   7.120      )
   7.121  {
   7.122      PEP_STATUS status = PEP_STATUS_OK;
   7.123 @@ -1053,8 +1020,11 @@
   7.124      _src->longmsg_formatted = src->longmsg_formatted;
   7.125      _src->attachments = src->attachments;
   7.126      _src->enc_format = PEP_enc_none;
   7.127 -    bool mime_encode = !is_wrapper(_src);
   7.128 -    status = _mime_encode_message_internal(_src, true, &mimetext, mime_encode);
   7.129 +    
   7.130 +    // These vars are here to be clear, and because I don't know how this may change in the near future.
   7.131 +    bool wrapped = (wrap_type != PEP_message_unwrapped);
   7.132 +    bool mime_encode = !wrapped;
   7.133 +    status = _mime_encode_message_internal(_src, true, &mimetext, mime_encode, wrapped);
   7.134      assert(status == PEP_STATUS_OK);
   7.135      if (status != PEP_STATUS_OK)
   7.136          goto pEp_error;
   7.137 @@ -1731,7 +1701,10 @@
   7.138      if (status != PEP_STATUS_OK)
   7.139          goto pEp_error;
   7.140  
   7.141 -    keys = new_stringlist(src->from->fpr);
   7.142 +    char* send_fpr = strdup(src->from->fpr ? src->from->fpr : "");
   7.143 +    src->_sender_fpr = send_fpr;
   7.144 +    
   7.145 +    keys = new_stringlist(send_fpr);
   7.146      if (keys == NULL)
   7.147          goto enomem;
   7.148  
   7.149 @@ -1747,7 +1720,10 @@
   7.150      bool has_pEp_user = false;
   7.151      
   7.152      PEP_comm_type max_comm_type = PEP_ct_pEp;
   7.153 -
   7.154 +    unsigned int max_version_major = 0;
   7.155 +    unsigned int max_version_minor = 0;
   7.156 +    pEp_version_major_minor(PEP_VERSION, &max_version_major, &max_version_minor);
   7.157 +    
   7.158      identity_list * _il = NULL;
   7.159  
   7.160      if (enc_format != PEP_enc_none && (_il = src->bcc) && _il->ident)
   7.161 @@ -1755,7 +1731,6 @@
   7.162      {
   7.163          //     - App splits mails with BCC in multiple mails.
   7.164          //     - Each email is encrypted separately
   7.165 -
   7.166          if(_il->next || (src->to && src->to->ident) || (src->cc && src->cc->ident))
   7.167          {
   7.168              // Only one Bcc with no other recipient allowed for now
   7.169 @@ -1769,6 +1744,12 @@
   7.170                  _il->ident->comm_type = PEP_ct_key_not_found;
   7.171                  _status = PEP_STATUS_OK;
   7.172              }
   7.173 +            // 0 unless set, so safe.
   7.174 +            
   7.175 +            set_min_version( _il->ident->major_ver, _il->ident->minor_ver, 
   7.176 +                             max_version_major, max_version_minor,
   7.177 +                             &max_version_major, &max_version_minor);
   7.178 +
   7.179              bool is_blacklisted = false;
   7.180              if (_il->ident->fpr && IS_PGP_CT(_il->ident->comm_type)) {
   7.181                  _status = blacklist_is_listed(session, _il->ident->fpr, &is_blacklisted);
   7.182 @@ -1794,6 +1775,7 @@
   7.183          }
   7.184          else
   7.185              _status = myself(session, _il->ident);
   7.186 +        
   7.187          if (_status != PEP_STATUS_OK) {
   7.188              status = PEP_UNENCRYPTED;
   7.189              goto pEp_error;
   7.190 @@ -1821,6 +1803,11 @@
   7.191                      _il->ident->comm_type = PEP_ct_key_not_found;
   7.192                      _status = PEP_STATUS_OK;
   7.193                  }
   7.194 +                // 0 unless set, so safe.
   7.195 +                set_min_version( _il->ident->major_ver, _il->ident->minor_ver, 
   7.196 +                                 max_version_major, max_version_minor,
   7.197 +                                 &max_version_major, &max_version_minor);
   7.198 +                
   7.199                  bool is_blacklisted = false;
   7.200                  if (_il->ident->fpr && IS_PGP_CT(_il->ident->comm_type)) {
   7.201                      _status = blacklist_is_listed(session, _il->ident->fpr, &is_blacklisted);
   7.202 @@ -1923,6 +1910,9 @@
   7.203              }
   7.204          }
   7.205      }
   7.206 +    
   7.207 +    if (max_version_major == 1)
   7.208 +        force_v_1 = true;
   7.209          
   7.210      if (enc_format == PEP_enc_none || !dest_keys_found ||
   7.211          stringlist_length(keys)  == 0 ||
   7.212 @@ -1939,9 +1929,10 @@
   7.213      }
   7.214      else {
   7.215          // FIXME - we need to deal with transport types (via flag)
   7.216 +        message_wrap_type wrap_type = PEP_message_unwrapped;
   7.217          if ((enc_format != PEP_enc_inline) && (!force_v_1) && ((max_comm_type | PEP_ct_confirmed) == PEP_ct_pEp)) {
   7.218 -            message_wrap_type wrap_type = ((flags & PEP_encrypt_flag_key_reset_only) ? PEP_message_key_reset : PEP_message_default);
   7.219 -            _src = wrap_message_as_attachment(NULL, src, wrap_type, false);
   7.220 +            wrap_type = ((flags & PEP_encrypt_flag_key_reset_only) ? PEP_message_key_reset : PEP_message_default);
   7.221 +            _src = wrap_message_as_attachment(NULL, src, wrap_type, false, max_version_major, max_version_minor);
   7.222              if (!_src)
   7.223                  goto pEp_error;
   7.224          }
   7.225 @@ -1965,7 +1956,7 @@
   7.226          switch (enc_format) {
   7.227              case PEP_enc_PGP_MIME:
   7.228              case PEP_enc_PEP: // BUG: should be implemented extra
   7.229 -                status = encrypt_PGP_MIME(session, _src, keys, msg, flags);
   7.230 +                status = encrypt_PGP_MIME(session, _src, keys, msg, flags, wrap_type);
   7.231                  break;
   7.232  
   7.233              case PEP_enc_inline:
   7.234 @@ -2287,7 +2278,9 @@
   7.235      // if (!(flags & PEP_encrypt_flag_force_no_attached_key))
   7.236      //     _attach_key(session, target_fpr, src);
   7.237  
   7.238 -    _src = wrap_message_as_attachment(NULL, src, PEP_message_default, false);
   7.239 +    unsigned int major_ver, minor_ver;
   7.240 +    pEp_version_major_minor(PEP_VERSION, &major_ver, &minor_ver);
   7.241 +    _src = wrap_message_as_attachment(NULL, src, PEP_message_default, false, major_ver, minor_ver);
   7.242      if (!_src)
   7.243          goto pEp_error;
   7.244  
   7.245 @@ -2298,7 +2291,7 @@
   7.246      switch (enc_format) {
   7.247          case PEP_enc_PGP_MIME:
   7.248          case PEP_enc_PEP: // BUG: should be implemented extra
   7.249 -            status = encrypt_PGP_MIME(session, _src, keys, msg, flags);
   7.250 +            status = encrypt_PGP_MIME(session, _src, keys, msg, flags, PEP_message_default);
   7.251              if (status == PEP_STATUS_OK || (src->longmsg && strstr(src->longmsg, "INNER")))
   7.252                  _cleanup_src(src, false);
   7.253              break;
   7.254 @@ -3016,11 +3009,28 @@
   7.255      return status;
   7.256  }
   7.257  
   7.258 +// ident is in_only and should have been updated
   7.259 +static PEP_STATUS pEp_version_upgrade_or_ignore(
   7.260 +        PEP_SESSION session,
   7.261 +        pEp_identity* ident,
   7.262 +        unsigned int major,
   7.263 +        unsigned int minor) {
   7.264 +            
   7.265 +    PEP_STATUS status = PEP_STATUS_OK;        
   7.266 +    int ver_compare = compare_versions(major, minor, ident->major_ver, ident->minor_ver);
   7.267 +    if (ver_compare > 0)
   7.268 +        status = set_pEp_version(session, ident, major, minor);        
   7.269 +    
   7.270 +    return status;    
   7.271 +}
   7.272 +
   7.273  // FIXME: myself ??????
   7.274  static PEP_STATUS update_sender_to_pEp_trust(
   7.275          PEP_SESSION session, 
   7.276          pEp_identity* sender, 
   7.277 -        stringlist_t* keylist) 
   7.278 +        stringlist_t* keylist,
   7.279 +        unsigned int major,
   7.280 +        unsigned int minor) 
   7.281  {
   7.282      assert(session);
   7.283      assert(sender);
   7.284 @@ -3031,9 +3041,11 @@
   7.285          
   7.286      free(sender->fpr);
   7.287      sender->fpr = NULL;
   7.288 -    
   7.289 -    PEP_STATUS status = 
   7.290 -            is_me(session, sender) ? myself(session, sender) : update_identity(session, sender);
   7.291 +
   7.292 +    PEP_STATUS status = PEP_STATUS_OK;
   7.293 +
   7.294 +    // Seems status doesn't matter
   7.295 +    is_me(session, sender) ? myself(session, sender) : update_identity(session, sender);
   7.296  
   7.297      if (EMPTYSTR(sender->fpr) || strcmp(sender->fpr, keylist->value) != 0) {
   7.298          free(sender->fpr);
   7.299 @@ -3058,11 +3070,21 @@
   7.300      
   7.301      // Could be done elegantly, but we do this explicitly here for readability.
   7.302      // This file's code is difficult enough to parse. But change at will.
   7.303 -    switch (sender->comm_type) {
   7.304 +    switch (sender->comm_type) {            
   7.305          case PEP_ct_OpenPGP_unconfirmed:
   7.306          case PEP_ct_OpenPGP:
   7.307              sender->comm_type = PEP_ct_pEp_unconfirmed | (sender->comm_type & PEP_ct_confirmed);
   7.308              status = set_trust(session, sender);
   7.309 +            if (status != PEP_STATUS_OK)
   7.310 +                break;
   7.311 +        case PEP_ct_pEp:
   7.312 +        case PEP_ct_pEp_unconfirmed:
   7.313 +            // set version
   7.314 +            if (major == 0) {
   7.315 +                major = 2;
   7.316 +                minor = 0;
   7.317 +            }
   7.318 +            status = pEp_version_upgrade_or_ignore(session, sender, major, minor);    
   7.319              break;
   7.320          default:
   7.321              status = PEP_CANNOT_SET_TRUST;
   7.322 @@ -3365,7 +3387,9 @@
   7.323      char* signer_fpr = NULL;
   7.324      bool is_pEp_msg = is_a_pEpmessage(src);
   7.325      bool myself_read_only = (src->dir == PEP_dir_incoming);
   7.326 -
   7.327 +    unsigned int major_ver;
   7.328 +    unsigned int minor_ver;
   7.329 +    
   7.330      // Grab input flags
   7.331      bool reencrypt = (((*flags & PEP_decrypt_flag_untrusted_server) > 0) && *keylist && !EMPTYSTR((*keylist)->value));
   7.332      
   7.333 @@ -3381,34 +3405,39 @@
   7.334      *keylist = NULL;
   7.335      *rating = PEP_rating_undefined;
   7.336  //    *flags = 0;
   7.337 -    
   7.338 +
   7.339      /*** End init ***/
   7.340  
   7.341 -    // Ok, before we do anything, if it's a pEp message, regardless of whether it's
   7.342 +    // KB: FIXME - we should do this once we've seen an inner message in the case 
   7.343 +    // of pEp users. Since we've not used 1.0 in a billion years (but will receive 
   7.344 +    // 1.0 messages from pEp users who don't yet know WE are pEp users), we should 
   7.345 +    // sort this out sanely, not upfront.
   7.346 +    //
   7.347 +    // Was: Ok, before we do anything, if it's a pEp message, regardless of whether it's
   7.348      // encrypted or not, we set the sender as a pEp user. This has NOTHING to do
   7.349      // with the key.
   7.350 -    if (src->from && !(is_me(session, src->from))) {
   7.351 -        if (is_pEp_msg) {
   7.352 -            pEp_identity* tmp_from = src->from;
   7.353 -            
   7.354 -            // Ensure there's a user id
   7.355 -            if (EMPTYSTR(tmp_from->user_id) && tmp_from->address) {
   7.356 -                status = update_identity(session, tmp_from);
   7.357 -                if (status == PEP_CANNOT_FIND_IDENTITY) {
   7.358 -                    tmp_from->user_id = calloc(1, strlen(tmp_from->address) + 6);
   7.359 -                    if (!tmp_from->user_id)
   7.360 -                        return PEP_OUT_OF_MEMORY;
   7.361 -                    snprintf(tmp_from->user_id, strlen(tmp_from->address) + 6,
   7.362 -                             "TOFU_%s", tmp_from->address);        
   7.363 -                    status = PEP_STATUS_OK;
   7.364 -                }
   7.365 -            }
   7.366 -            if (status == PEP_STATUS_OK) {
   7.367 -                // Now set user as PEP (may also create an identity if none existed yet)
   7.368 -                status = set_as_pEp_user(session, tmp_from);
   7.369 -            }
   7.370 -        }
   7.371 -    }
   7.372 +    // if (src->from && !(is_me(session, src->from))) {
   7.373 +    //     if (is_pEp_msg) {
   7.374 +    //         pEp_identity* tmp_from = src->from;
   7.375 +    // 
   7.376 +    //         // Ensure there's a user id
   7.377 +    //         if (EMPTYSTR(tmp_from->user_id) && tmp_from->address) {
   7.378 +    //             status = update_identity(session, tmp_from);
   7.379 +    //             if (status == PEP_CANNOT_FIND_IDENTITY) {
   7.380 +    //                 tmp_from->user_id = calloc(1, strlen(tmp_from->address) + 6);
   7.381 +    //                 if (!tmp_from->user_id)
   7.382 +    //                     return PEP_OUT_OF_MEMORY;
   7.383 +    //                 snprintf(tmp_from->user_id, strlen(tmp_from->address) + 6,
   7.384 +    //                          "TOFU_%s", tmp_from->address);        
   7.385 +    //                 status = PEP_STATUS_OK;
   7.386 +    //             }
   7.387 +    //         }
   7.388 +    //         if (status == PEP_STATUS_OK) {
   7.389 +    //             // Now set user as PEP (may also create an identity if none existed yet)
   7.390 +    //             status = set_as_pEp_user(session, tmp_from);
   7.391 +    //         }
   7.392 +    //     }
   7.393 +    // }
   7.394      // We really need key used in signing to do anything further on the pEp comm_type.
   7.395      // So we can't adjust the rating of the sender just yet.
   7.396  
   7.397 @@ -3425,16 +3454,16 @@
   7.398      import_header_keys(session, src);
   7.399      
   7.400      // FIXME: is this really necessary here?
   7.401 -    if (src->from) {
   7.402 -        if (!is_me(session, src->from))
   7.403 -            status = update_identity(session, src->from);
   7.404 -        else
   7.405 -            status = _myself(session, src->from, false, false, myself_read_only);
   7.406 -        
   7.407 -        // We absolutely should NOT be bailing here unless it's a serious error
   7.408 -        if (status == PEP_OUT_OF_MEMORY)
   7.409 -            return status;
   7.410 -    }
   7.411 +    // if (src->from) {
   7.412 +    //     if (!is_me(session, src->from))
   7.413 +    //         status = update_identity(session, src->from);
   7.414 +    //     else
   7.415 +    //         status = _myself(session, src->from, false, false, myself_read_only);
   7.416 +    // 
   7.417 +    //     // We absolutely should NOT be bailing here unless it's a serious error
   7.418 +    //     if (status == PEP_OUT_OF_MEMORY)
   7.419 +    //         return status;
   7.420 +    // }
   7.421      
   7.422      /*** End Import any attached public keys and update identities accordingly ***/
   7.423      
   7.424 @@ -3483,6 +3512,7 @@
   7.425      decrypt_status = status;
   7.426      
   7.427      bool imported_private_key_address = false;
   7.428 +    bool has_inner = false;
   7.429  
   7.430      if (ptext) { 
   7.431          /* we got a plaintext from decryption */
   7.432 @@ -3491,7 +3521,7 @@
   7.433              case PEP_enc_PGP_MIME:
   7.434              case PEP_enc_PGP_MIME_Outlook1:
   7.435              
   7.436 -                status = mime_decode_message(ptext, psize, &msg);
   7.437 +                status = mime_decode_message(ptext, psize, &msg, &has_inner);
   7.438                  if (status != PEP_STATUS_OK)
   7.439                      goto pEp_error;
   7.440                  
   7.441 @@ -3567,136 +3597,212 @@
   7.442          if (decrypt_status == PEP_DECRYPTED || decrypt_status == PEP_DECRYPTED_AND_VERIFIED) {
   7.443              char* wrap_info = NULL;
   7.444              
   7.445 -            status = unencapsulate_hidden_fields(src, msg, &wrap_info);
   7.446 +            if (!has_inner) {
   7.447 +                status = unencapsulate_hidden_fields(src, msg, &wrap_info);
   7.448 +                if (status == PEP_OUT_OF_MEMORY)
   7.449 +                    goto enomem;                
   7.450 +                if (status != PEP_STATUS_OK)
   7.451 +                    goto pEp_error;
   7.452 +            }        
   7.453  
   7.454  //            bool is_transport_wrapper = false;
   7.455              
   7.456 +        
   7.457              // FIXME: replace with enums, check status
   7.458 -            if (wrap_info) {
   7.459 -                if (strcmp(wrap_info, "OUTER") == 0) {
   7.460 -                    // this only occurs in with a direct outer wrapper
   7.461 -                    // where the actual content is in the inner wrapper
   7.462 -                    message* inner_message = NULL;                    
   7.463 +            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
   7.464 +                // if (strcmp(wrap_info, "OUTER") == 0) {
   7.465 +                //     // this only occurs in with a direct outer wrapper
   7.466 +                //     // where the actual content is in the inner wrapper
   7.467 +                message* inner_message = NULL;
   7.468 +                    
   7.469 +                // For a wrapped message, this is ALWAYS the second attachment; the 
   7.470 +                // mime tree is:
   7.471 +                // multipart/mixed
   7.472 +                //     |
   7.473 +                //     |----- text/plain 
   7.474 +                //     |----- message/rfc822
   7.475 +                //     |----- ...
   7.476 +                //
   7.477 +                // We leave this in below, but once we're rid of 2.0 format,
   7.478 +                // we can dispense with the loop, as has_inner -> 1st message struct attachment is message/rfc822
   7.479 +                //                   
   7.480 +
   7.481 +                bloblist_t* message_blob = msg->attachments;
   7.482 +                                    
   7.483 +                if (msg->attachments) {
   7.484 +                    message_blob = msg->attachments;
   7.485 +                    if (!has_inner && strcmp(message_blob->mime_type, "message/rfc822") != 0
   7.486 +                                   && strcmp(message_blob->mime_type, "text/rfc822") != 0)
   7.487 +                        message_blob = NULL;
   7.488 +                }
   7.489 +                    
   7.490 +                if (!message_blob) {
   7.491                      bloblist_t* actual_message = msg->attachments;
   7.492 -                    
   7.493 +                
   7.494                      while (actual_message) {
   7.495                          char* mime_type = actual_message->mime_type;
   7.496                          if (mime_type) {
   7.497 -                            
   7.498 +                        
   7.499                              // libetpan appears to change the mime_type on this one.
   7.500                              // *growl*
   7.501                              if (strcmp("message/rfc822", mime_type) == 0 ||
   7.502                                  strcmp("text/rfc822", mime_type) == 0) {
   7.503 -                                    
   7.504 -                                status = mime_decode_message(actual_message->value, 
   7.505 -                                                             actual_message->size, 
   7.506 -                                                             &inner_message);
   7.507 -                                if (status != PEP_STATUS_OK)
   7.508 -                                    goto pEp_error;
   7.509 -                                
   7.510 -                                if (inner_message) {
   7.511 -                                    // Though this will strip any message info on the
   7.512 -                                    // attachment, this is safe, as we do not
   7.513 -                                    // produce more than one attachment-as-message,
   7.514 -                                    // and those are the only ones with such info.
   7.515 -                                    // Since we capture the information, this is ok.
   7.516 -                                    wrap_info = NULL;
   7.517 -                                    inner_message->enc_format = src->enc_format;
   7.518 -                                    // FIXME
   7.519 -                                    status = unencapsulate_hidden_fields(inner_message, NULL, &wrap_info);
   7.520 -                                    
   7.521 -                                    // ?
   7.522 -                                    if (status != PEP_STATUS_OK) {
   7.523 -                                        free_message(inner_message);
   7.524 -                                        goto pEp_error;
   7.525 -                                    }
   7.526 -    
   7.527 -                                    if (wrap_info) {
   7.528 -                                        bool is_inner = (strcmp(wrap_info, "INNER") == 0);
   7.529 -                                        bool is_key_reset = (strcmp(wrap_info, "KEY_RESET") == 0);
   7.530 -
   7.531 -                                        if (is_key_reset) {
   7.532 -                                            if (decrypt_status == PEP_DECRYPTED || decrypt_status == PEP_DECRYPTED_AND_VERIFIED) {
   7.533 -                                                status = receive_key_reset(session,
   7.534 -                                                                           inner_message);
   7.535 -                                                if (status != PEP_STATUS_OK) {
   7.536 -                                                    free_message(inner_message);
   7.537 -                                                    goto pEp_error;
   7.538 -                                                }
   7.539 -                                                *flags |= PEP_decrypt_flag_consume;
   7.540 -                                            }
   7.541 -                                        }
   7.542 -                                        else if (is_inner) {
   7.543 -
   7.544 -                                            // check for private key in decrypted message attachment while importing
   7.545 -                                            // N.B. Apparently, we always import private keys into the keyring; however,
   7.546 -                                            // we do NOT always allow those to be used for encryption. THAT is controlled
   7.547 -                                            // by setting it as an own identity associated with the key in the DB.
   7.548 -                                            
   7.549 -                                            // If we have a message 2.0 message, we are ONLY going to be ok with keys
   7.550 -                                            // we imported from THIS part of the message.
   7.551 -                                            imported_private_key_address = false;
   7.552 -                                            free(private_il); 
   7.553 -                                            private_il = NULL;
   7.554 -                                            
   7.555 -                                            // import keys from decrypted INNER source
   7.556 -                                            status = import_priv_keys_from_decrypted_msg(session, inner_message,
   7.557 -                                                                                         &imported_keys,
   7.558 -                                                                                         &imported_private_key_address,
   7.559 -                                                                                         private_il);
   7.560 -                                            if (status != PEP_STATUS_OK)
   7.561 -                                                goto pEp_error;            
   7.562 -
   7.563 -                                            // THIS is our message
   7.564 -                                            // Now, let's make sure we've copied in 
   7.565 -                                            // any information sent in by the app if
   7.566 -                                            // needed...
   7.567 -                                            reconcile_src_and_inner_messages(src, inner_message);
   7.568 -                                            
   7.569 -
   7.570 -                                            // FIXME: free msg, but check references
   7.571 -                                            //src = msg = inner_message;
   7.572 -                                            calculated_src = msg = inner_message;
   7.573 -                                            
   7.574 -                                            // FIXME: should this be msg???
   7.575 -                                            if (src->from) {
   7.576 -                                                if (!is_me(session, src->from))
   7.577 -                                                    update_identity(session, (src->from));
   7.578 -                                                else
   7.579 -                                                    _myself(session, src->from, false, false, myself_read_only);
   7.580 -                                            }
   7.581 -                                            break;        
   7.582 -                                        }
   7.583 -                                        else { // should never happen
   7.584 -                                            status = PEP_UNKNOWN_ERROR;
   7.585 -                                            free_message(inner_message);
   7.586 -                                            goto pEp_error;
   7.587 -                                        }
   7.588 -                                    }
   7.589 -                                    inner_message->enc_format = PEP_enc_none;
   7.590 -                                }
   7.591 -                                else { // forwarded message, leave it alone
   7.592 -                                    free_message(inner_message);
   7.593 -                                }
   7.594 +                                message_blob = actual_message;
   7.595 +                                break;
   7.596                              }
   7.597                          }
   7.598                          actual_message = actual_message->next;
   7.599 -                    }                    
   7.600 +                    }        
   7.601 +                }    
   7.602 +                if (message_blob) {              
   7.603 +                    status = mime_decode_message(message_blob->value, 
   7.604 +                                                 message_blob->size, 
   7.605 +                                                 &inner_message,
   7.606 +                                                 NULL);
   7.607 +                    if (status != PEP_STATUS_OK)
   7.608 +                        goto pEp_error;
   7.609 +                                
   7.610 +                    if (inner_message) {
   7.611 +                        is_pEp_msg = is_a_pEpmessage(inner_message);
   7.612 +                        
   7.613 +                        // Though this will strip any message info on the
   7.614 +                        // attachment, this is safe, as we do not
   7.615 +                        // produce more than one attachment-as-message,
   7.616 +                        // and those are the only ones with such info.
   7.617 +                        // Since we capture the information, this is ok.
   7.618 +                        wrap_info = NULL;
   7.619 +                        inner_message->enc_format = src->enc_format;
   7.620 +
   7.621 +                        const stringpair_list_t* pEp_protocol_version = NULL;
   7.622 +                        pEp_protocol_version = stringpair_list_find(inner_message->opt_fields, "X-pEp-Version");
   7.623 +                        
   7.624 +                        if (pEp_protocol_version && pEp_protocol_version->value)
   7.625 +                            pEp_version_major_minor(pEp_protocol_version->value->value, &major_ver, &minor_ver);
   7.626 +
   7.627 +                        // Sort out pEp user status and version number based on INNER message.
   7.628 +                        
   7.629 +                        bool is_inner = false;
   7.630 +                        bool is_key_reset = false;
   7.631 +
   7.632 +                        // Deal with plaintext modification in 1.0 and 2.0 messages
   7.633 +                        status = unencapsulate_hidden_fields(inner_message, NULL, &wrap_info);   
   7.634 +                        
   7.635 +                        if (status == PEP_OUT_OF_MEMORY)
   7.636 +                            goto enomem;                
   7.637 +                        if (status != PEP_STATUS_OK)
   7.638 +                            goto pEp_error;                                         
   7.639 +                            
   7.640 +                        if (major_ver > 2 || (major_ver == 2 && minor_ver > 0)) {
   7.641 +                            stringpair_list_t* searched = stringpair_list_find(inner_message->opt_fields, "X-pEp-Sender-FPR");                             
   7.642 +                            inner_message->_sender_fpr = ((searched && searched->value && searched->value->value) ? strdup(searched->value->value) : NULL);
   7.643 +                            searched = stringpair_list_find(inner_message->opt_fields, X_PEP_MSG_WRAP_KEY);
   7.644 +                            if (searched && searched->value && searched->value->value) {
   7.645 +                                is_inner = (strcmp(searched->value->value, "INNER") == 0);
   7.646 +                                if (!is_inner)
   7.647 +                                    is_key_reset = (strcmp(searched->value->value, "KEY_RESET") == 0);
   7.648 +                                if (is_inner || is_key_reset)
   7.649 +                                    inner_message->opt_fields = stringpair_list_delete_by_key(inner_message->opt_fields, X_PEP_MSG_WRAP_KEY);
   7.650 +                            }
   7.651 +                        }
   7.652 +                        else {
   7.653 +                            is_inner = (strcmp(wrap_info, "INNER") == 0);
   7.654 +                            if (!is_inner)
   7.655 +                                is_key_reset = (strcmp(wrap_info, "KEY_RESET") == 0);
   7.656 +                        }
   7.657 +                            
   7.658 +
   7.659 +                        if (is_key_reset) {
   7.660 +                            if (decrypt_status == PEP_DECRYPTED || decrypt_status == PEP_DECRYPTED_AND_VERIFIED) {
   7.661 +                                status = receive_key_reset(session,
   7.662 +                                                           inner_message);
   7.663 +                                if (status != PEP_STATUS_OK) {
   7.664 +                                    free_message(inner_message);
   7.665 +                                    goto pEp_error;
   7.666 +                                }
   7.667 +                                *flags |= PEP_decrypt_flag_consume;
   7.668 +                            }
   7.669 +                        }
   7.670 +                        else if (is_inner) {
   7.671 +
   7.672 +                            // check for private key in decrypted message attachment while importing
   7.673 +                            // N.B. Apparently, we always import private keys into the keyring; however,
   7.674 +                            // we do NOT always allow those to be used for encryption. THAT is controlled
   7.675 +                            // by setting it as an own identity associated with the key in the DB.
   7.676 +                            
   7.677 +                            // If we have a message 2.0 message, we are ONLY going to be ok with keys
   7.678 +                            // we imported from THIS part of the message.
   7.679 +                            imported_private_key_address = false;
   7.680 +                            free(private_il); 
   7.681 +                            private_il = NULL;
   7.682 +                            
   7.683 +                            // import keys from decrypted INNER source
   7.684 +                            status = import_priv_keys_from_decrypted_msg(session, inner_message,
   7.685 +                                                                         &imported_keys,
   7.686 +                                                                         &imported_private_key_address,
   7.687 +                                                                         private_il);
   7.688 +                            if (status != PEP_STATUS_OK)
   7.689 +                                goto pEp_error;            
   7.690 +
   7.691 +                            // THIS is our message
   7.692 +                            // Now, let's make sure we've copied in 
   7.693 +                            // any information sent in by the app if
   7.694 +                            // needed...
   7.695 +                            reconcile_src_and_inner_messages(src, inner_message);
   7.696 +                            
   7.697 +
   7.698 +                            // FIXME: free msg, but check references
   7.699 +                            //src = msg = inner_message;
   7.700 +                            calculated_src = msg = inner_message;
   7.701 +                            
   7.702 +                        }
   7.703 +                        else { // should never happen
   7.704 +                            status = PEP_UNKNOWN_ERROR;
   7.705 +                            free_message(inner_message);
   7.706 +                            goto pEp_error;
   7.707 +                        }
   7.708 +                        inner_message->enc_format = PEP_enc_none;
   7.709 +                    }
   7.710 +                    else { // forwarded message, leave it alone
   7.711 +                        free_message(inner_message);
   7.712 +                    }
   7.713 +                } // end if (message_blob)
   7.714 +                
   7.715 +                //  else if (strcmp(wrap_info, "TRANSPORT") == 0) {
   7.716 +                //      // FIXME: this gets even messier.
   7.717 +                //      // (TBI in ENGINE-278)
   7.718 +                //  }
   7.719 +                //  else {} // shouldn't be anything to be done here
   7.720 +    
   7.721 +            } // end if (has_inner || wrap_info)
   7.722 +            else {
   7.723 +                
   7.724 +            } // this we do if this isn't an inner message
   7.725 +            
   7.726 +            pEp_identity* cs_from = calculated_src->from;
   7.727 +            if (cs_from && !EMPTYSTR(cs_from->address)) {
   7.728 +                if (!is_me(session, cs_from)) {
   7.729 +                    status = update_identity(session, cs_from);
   7.730 +                    if (status == PEP_CANNOT_FIND_IDENTITY) {
   7.731 +                        cs_from->user_id = calloc(1, strlen(cs_from->address) + 6);
   7.732 +                        if (!cs_from->user_id)
   7.733 +                            return PEP_OUT_OF_MEMORY;
   7.734 +                        snprintf(cs_from->user_id, strlen(cs_from->address) + 6,
   7.735 +                                 "TOFU_%s", cs_from->address);        
   7.736 +                        status = PEP_STATUS_OK;
   7.737 +                    }
   7.738                  }
   7.739 -                else if (strcmp(wrap_info, "TRANSPORT") == 0) {
   7.740 -                    // FIXME: this gets even messier.
   7.741 -                    // (TBI in ENGINE-278)
   7.742 -                }
   7.743 -                else {} // shouldn't be anything to be done here
   7.744 -            }
   7.745 -        }
   7.746 +                else
   7.747 +                    status = _myself(session, cs_from, false, false, myself_read_only);
   7.748 +            }                                                                        
   7.749 +        } // end if (decrypt_status == PEP_DECRYPTED || decrypt_status == PEP_DECRYPTED_AND_VERIFIED)
   7.750          
   7.751          *rating = decrypt_rating(decrypt_status);
   7.752          
   7.753          // Ok, so if it was signed and it's all verified, we can update
   7.754          // eligible signer comm_types to PEP_ct_pEp_*
   7.755 +        // This also sets and upgrades pEp version
   7.756          if (decrypt_status == PEP_DECRYPTED_AND_VERIFIED && is_pEp_msg && calculated_src->from)
   7.757 -            status = update_sender_to_pEp_trust(session, calculated_src->from, _keylist);
   7.758 +            status = update_sender_to_pEp_trust(session, calculated_src->from, _keylist, major_ver, minor_ver);
   7.759  
   7.760          /* Ok, now we have a keylist used for decryption/verification.
   7.761             now we need to update the message rating with the 
   7.762 @@ -4068,7 +4174,7 @@
   7.763          *rating = PEP_rating_undefined;
   7.764      }
   7.765      else
   7.766 -        *rating = MAX(_rating(max_comm_type), PEP_rating_unencrypted);
   7.767 +        *rating = _MAX(_rating(max_comm_type), PEP_rating_unencrypted);
   7.768  
   7.769      return PEP_STATUS_OK;
   7.770  }
     8.1 --- a/src/message_api.h	Wed Aug 07 12:10:12 2019 +0200
     8.2 +++ b/src/message_api.h	Wed Aug 07 14:08:11 2019 +0200
     8.3 @@ -49,6 +49,7 @@
     8.4  typedef unsigned int PEP_encrypt_flags_t;
     8.5  
     8.6  typedef enum _message_wrap_type {
     8.7 +    PEP_message_unwrapped,  // 1.0 or anything we don't wrap    
     8.8      PEP_message_default,    // typical inner/outer message 2.0
     8.9      PEP_message_transport,  // e.g. for onion layers
    8.10      PEP_message_key_reset   // for wrapped key reset information
     9.1 --- a/src/mime.c	Wed Aug 07 12:10:12 2019 +0200
     9.2 +++ b/src/mime.c	Wed Aug 07 14:08:11 2019 +0200
     9.3 @@ -39,6 +39,5 @@
     9.4          char **mimetext
     9.5      )
     9.6  {
     9.7 -    return _mime_encode_message_internal(msg, omit_fields, mimetext, true);
     9.8 +    return _mime_encode_message_internal(msg, omit_fields, mimetext, true, false);
     9.9  }
    9.10 -
    10.1 --- a/src/mime.h	Wed Aug 07 12:10:12 2019 +0200
    10.2 +++ b/src/mime.h	Wed Aug 07 14:08:11 2019 +0200
    10.3 @@ -55,9 +55,10 @@
    10.4  // mime_decode_message() - decode a MIME message
    10.5  //
    10.6  //  parameters:
    10.7 -//      mimetext (in)           MIME encoded text to decode
    10.8 -//      size (in)               size of text to decode
    10.9 -//      msg (out)               decoded message
   10.10 +//      mimetext (in)           	MIME encoded text to decode
   10.11 +//      size (in)               	size of text to decode
   10.12 +//      msg (out)               	decoded message
   10.13 +//      raise_msg_attachment (out)		
   10.14  //
   10.15  //  return value:
   10.16  //      PEP_STATUS_OK           if everything worked
   10.17 @@ -75,7 +76,8 @@
   10.18  DYNAMIC_API PEP_STATUS mime_decode_message(
   10.19          const char *mimetext,
   10.20          size_t size,
   10.21 -        message **msg
   10.22 +        message **msg,
   10.23 +        bool* raise_msg_attachment
   10.24      );
   10.25  
   10.26  /* sometimes we don't want to transport encode */
   10.27 @@ -83,7 +85,8 @@
   10.28          const message * msg,
   10.29          bool omit_fields,
   10.30          char **mimetext,
   10.31 -        bool transport_encode
   10.32 +        bool transport_encode,
   10.33 +        bool set_attachment_forward_comment        
   10.34      );
   10.35  
   10.36  
    11.1 --- a/src/pEpEngine.c	Wed Aug 07 12:10:12 2019 +0200
    11.2 +++ b/src/pEpEngine.c	Wed Aug 07 14:08:11 2019 +0200
    11.3 @@ -83,7 +83,7 @@
    11.4  static const char *sql_get_identity =  
    11.5      "select fpr, username, comm_type, lang,"
    11.6      "   identity.flags | pgp_keypair.flags,"
    11.7 -    "   is_own"
    11.8 +    "   is_own, pEp_version_major, pEp_version_minor"
    11.9      "   from identity"
   11.10      "   join person on id = identity.user_id"
   11.11      "   join pgp_keypair on fpr = identity.main_key_id"
   11.12 @@ -101,7 +101,7 @@
   11.13  static const char *sql_get_identities_by_main_key_id =  
   11.14      "select address, identity.user_id, username, comm_type, lang,"
   11.15      "   identity.flags | pgp_keypair.flags,"
   11.16 -    "   is_own"
   11.17 +    "   is_own, pEp_version_major, pEp_version_minor"
   11.18      "   from identity"
   11.19      "   join person on id = identity.user_id"
   11.20      "   join pgp_keypair on fpr = identity.main_key_id"
   11.21 @@ -113,7 +113,7 @@
   11.22  
   11.23  static const char *sql_get_identity_without_trust_check =  
   11.24      "select identity.main_key_id, username, lang,"
   11.25 -    "   identity.flags, is_own"
   11.26 +    "   identity.flags, is_own, pEp_version_major, pEp_version_minor"
   11.27      "   from identity"
   11.28      "   join person on id = identity.user_id"
   11.29      "   where (case when (address = ?1) then (1)"
   11.30 @@ -127,7 +127,7 @@
   11.31  
   11.32  static const char *sql_get_identities_by_address =  
   11.33      "select user_id, identity.main_key_id, username, lang,"
   11.34 -    "   identity.flags, is_own"
   11.35 +    "   identity.flags, is_own, pEp_version_major, pEp_version_minor"
   11.36      "   from identity"
   11.37      "   join person on id = identity.user_id"
   11.38      "   where (case when (address = ?1) then (1)"
   11.39 @@ -141,7 +141,7 @@
   11.40  static const char *sql_get_identities_by_userid =  
   11.41      "select address, fpr, username, comm_type, lang,"
   11.42      "   identity.flags | pgp_keypair.flags,"
   11.43 -    "   is_own"
   11.44 +    "   is_own, pEp_version_major, pEp_version_minor"
   11.45      "   from identity"
   11.46      "   join person on id = identity.user_id"
   11.47      "   join pgp_keypair on fpr = identity.main_key_id"
   11.48 @@ -239,20 +239,25 @@
   11.49  static const char *sql_set_identity_entry = 
   11.50      "insert into identity ("
   11.51      "       address, main_key_id, "
   11.52 -    "       user_id, flags, is_own"
   11.53 +    "       user_id, flags, is_own,"
   11.54 +    "       pEp_version_major, pEp_version_minor"
   11.55      "   ) values ("
   11.56      "       ?1,"
   11.57      "       upper(replace(?2,' ','')),"
   11.58      "       ?3,"
   11.59      "       ?4,"
   11.60 -    "       ?5"
   11.61 +    "       ?5,"
   11.62 +    "       ?6,"
   11.63 +    "       ?7"
   11.64      "   );";
   11.65      
   11.66  static const char* sql_update_identity_entry =    
   11.67      "update identity "
   11.68      "   set main_key_id = upper(replace(?2,' ','')), "
   11.69      "       flags = ?4, " 
   11.70 -    "       is_own = ?5 "
   11.71 +    "       is_own = ?5, "
   11.72 +    "       pEp_version_major = ?6, "
   11.73 +    "       pEp_version_major = ?7 "    
   11.74      "   where (case when (address = ?1) then (1)"
   11.75      "               when (lower(address) = lower(?1)) then (1)"
   11.76      "               when (replace(lower(address),'.','') = replace(lower(?1),'.','')) then (1) "
   11.77 @@ -301,6 +306,28 @@
   11.78      "          end) = 1"
   11.79      "          and user_id = ?3 ;";
   11.80  
   11.81 +static const char *sql_set_pEp_version =
   11.82 +    "update identity "
   11.83 +    "   set pEp_version_major = ?1, "
   11.84 +    "       pEp_version_minor = ?2 "
   11.85 +    "   where (case when (address = ?3) then (1)"
   11.86 +    "               when (lower(address) = lower(?3)) then (1)"
   11.87 +    "               when (replace(lower(address),'.','') = replace(lower(?3),'.','')) then (1) "
   11.88 +    "               else 0 "
   11.89 +    "          end) = 1 "
   11.90 +    "          and user_id = ?4 ;";
   11.91 +
   11.92 +static const char *sql_upgrade_pEp_version_by_user_id =
   11.93 +    "update identity "
   11.94 +    "   set pEp_version_major = ?1, "
   11.95 +    "       pEp_version_minor = ?2 "
   11.96 +    "       where user_id = ?3 "
   11.97 +    "           and (case when (pEp_version_major < ?1) then (1)"
   11.98 +    "                     when (pEp_version_major > ?1) then (0)"
   11.99 +    "                     when (pEp_version_minor < ?2) then (1)"
  11.100 +    "                     else 0 "
  11.101 +    "           end) = 1 ;";
  11.102 +
  11.103  static const char *sql_set_trust =
  11.104      "insert into trust (user_id, pgp_keypair_fpr, comm_type) "
  11.105      "values (?1, upper(replace(?2,' ','')), ?3) ;";
  11.106 @@ -353,7 +380,7 @@
  11.107  
  11.108  static const char *sql_i18n_token = 
  11.109      "select phrase from i18n_token where lang = lower(?1) and id = ?2 ;";
  11.110 -
  11.111 +    
  11.112  // blacklist
  11.113  static const char *sql_blacklist_add = 
  11.114      "insert or ignore into blacklist_keys (fpr) values (upper(replace(?1,' ',''))) ;"
  11.115 @@ -393,7 +420,7 @@
  11.116  
  11.117  static const char *sql_own_identities_retrieve =  
  11.118      "select address, fpr, identity.user_id, username,"
  11.119 -    "   lang, identity.flags | pgp_keypair.flags"
  11.120 +    "   lang, identity.flags | pgp_keypair.flags, pEp_version_major, pEp_version_minor"
  11.121      "   from identity"
  11.122      "   join person on id = identity.user_id"
  11.123      "   join pgp_keypair on fpr = identity.main_key_id"
  11.124 @@ -965,6 +992,8 @@
  11.125                  "   comment text,\n"
  11.126                  "   flags integer default 0,\n"
  11.127                  "   is_own integer default 0,\n"
  11.128 +                "   pEp_version_major integer default 0,\n"
  11.129 +                "   pEp_version_minor integer default 0,\n"                
  11.130                  "   timestamp integer default (datetime('now')),\n"
  11.131                  "   primary key (address, user_id)\n"
  11.132                  ");\n"
  11.133 @@ -1071,7 +1100,10 @@
  11.134          // Sometimes the user_version wasn't set correctly. 
  11.135          if (version == 1) {
  11.136              bool version_changed = true;
  11.137 -            if (db_contains_table(_session, "social_graph") > 0) {
  11.138 +            if (table_contains_column(_session, "identity", "pEp_version_major")) {
  11.139 +                version = 12;
  11.140 +            }
  11.141 +            else if (db_contains_table(_session, "social_graph") > 0) {
  11.142                  if (!table_contains_column(_session, "person", "device_group"))
  11.143                      version = 10;
  11.144                  else
  11.145 @@ -1433,7 +1465,71 @@
  11.146                      NULL,
  11.147                      NULL
  11.148                  );
  11.149 -                assert(int_result == SQLITE_OK);                
  11.150 +                assert(int_result == SQLITE_OK);
  11.151 +                
  11.152 +                int_result = sqlite3_exec(
  11.153 +                    _session->db,
  11.154 +                    "alter table identity\n"
  11.155 +                    "   add column pEp_version_major integer default 0;\n"
  11.156 +                    "alter table identity\n"
  11.157 +                    "   add column pEp_version_minor integer default 0;\n",                    
  11.158 +                    NULL,
  11.159 +                    NULL,
  11.160 +                    NULL
  11.161 +                );
  11.162 +                if (status != PEP_STATUS_OK)
  11.163 +                    return status;  
  11.164 +      
  11.165 +                int_result = sqlite3_exec(
  11.166 +                    _session->db,
  11.167 +                    "update identity\n"
  11.168 +                    "   set pEp_version_major = 2\n"
  11.169 +                    "   where exists (select * from person\n"
  11.170 +                    "                     where identity.user_id = person.id\n"
  11.171 +                    "                     and identity.is_own = 0\n"
  11.172 +                    "                     and person.is_pEp_user = 1);\n",
  11.173 +                    NULL,
  11.174 +                    NULL,
  11.175 +                    NULL
  11.176 +                );
  11.177 +                if (status != PEP_STATUS_OK)
  11.178 +                    return status;  
  11.179 +                
  11.180 +                // N.B. WE DEFINE PEP_VERSION - IF WE'RE AT 9-DIGIT MAJOR OR MINOR VERSIONS, ER, BAD.
  11.181 +                char major_buf[10];
  11.182 +                char minor_buf[10];
  11.183 +                if (sscanf("%s.%s", major_buf, minor_buf) != 2)
  11.184 +                    return PEP_UNKNOWN_ERROR; // DO BETTER
  11.185 +                size_t major_len = strlen(major_buf);
  11.186 +                size_t minor_len = strlen(minor_buf);
  11.187 +                    
  11.188 +                const char* _ver_12_startstr =                     
  11.189 +                    "update identity\n"
  11.190 +                    "    set pEp_version_major = ";
  11.191 +                const char* _ver_12_midstr = ",\n"
  11.192 +                    "        pEp_version_minor = ";
  11.193 +                const char* _ver_12_endstr =     
  11.194 +                    "\n"
  11.195 +                    "    where identity.is_own = 1;\n";
  11.196 +                    
  11.197 +                size_t new_stringlen = strlen(_ver_12_startstr) + major_len +
  11.198 +                                       strlen(_ver_12_midstr) + minor_len +
  11.199 +                                       strlen(_ver_12_endstr);
  11.200 +                                       
  11.201 +                char* _ver_12_stmt = calloc(new_stringlen + 1, 1);
  11.202 +                snprintf(_ver_12_stmt, new_stringlen + 1, "%s%s%s%s%s",
  11.203 +                         _ver_12_startstr, major_buf, _ver_12_midstr, minor_buf, _ver_12_endstr);
  11.204 +                
  11.205 +                int_result = sqlite3_exec(
  11.206 +                    _session->db,
  11.207 +                    _ver_12_stmt,
  11.208 +                    NULL,
  11.209 +                    NULL,
  11.210 +                    NULL
  11.211 +                );
  11.212 +                free(_ver_12_stmt);
  11.213 +                if (status != PEP_STATUS_OK)
  11.214 +                    return status;                      
  11.215              }
  11.216          }        
  11.217          else { 
  11.218 @@ -1633,6 +1729,16 @@
  11.219              NULL);
  11.220      assert(int_result == SQLITE_OK);
  11.221  
  11.222 +    int_result = sqlite3_prepare_v2(_session->db, sql_set_pEp_version,
  11.223 +            (int)strlen(sql_set_pEp_version), &_session->set_pEp_version,
  11.224 +            NULL);
  11.225 +    assert(int_result == SQLITE_OK);
  11.226 +    
  11.227 +    int_result = sqlite3_prepare_v2(_session->db, sql_upgrade_pEp_version_by_user_id,
  11.228 +            (int)strlen(sql_upgrade_pEp_version_by_user_id), &_session->upgrade_pEp_version_by_user_id,
  11.229 +            NULL);
  11.230 +    assert(int_result == SQLITE_OK);
  11.231 +
  11.232      int_result = sqlite3_prepare_v2(_session->db, sql_set_trust,
  11.233              (int)strlen(sql_set_trust), &_session->set_trust, NULL);
  11.234      assert(int_result == SQLITE_OK);
  11.235 @@ -1873,6 +1979,8 @@
  11.236                  sqlite3_finalize(session->delete_person);                
  11.237              if (session->set_as_pEp_user)
  11.238                  sqlite3_finalize(session->set_as_pEp_user);
  11.239 +            if (session->upgrade_pEp_version_by_user_id)
  11.240 +                sqlite3_finalize(session->upgrade_pEp_version_by_user_id);
  11.241              if (session->is_pEp_user)
  11.242                  sqlite3_finalize(session->is_pEp_user);
  11.243              if (session->exists_person)
  11.244 @@ -1901,6 +2009,8 @@
  11.245                  sqlite3_finalize(session->set_identity_flags);
  11.246              if (session->unset_identity_flags)
  11.247                  sqlite3_finalize(session->unset_identity_flags);
  11.248 +            if (session->set_pEp_version)
  11.249 +                sqlite3_finalize(session->set_pEp_version);                
  11.250              if (session->exists_trust_entry)
  11.251                  sqlite3_finalize(session->exists_trust_entry);                                
  11.252              if (session->set_trust)
  11.253 @@ -2269,6 +2379,8 @@
  11.254      dup->lang[2] = 0;
  11.255      dup->flags = src->flags;
  11.256      dup->me = src->me;
  11.257 +    dup->major_ver = src->major_ver;
  11.258 +    dup->minor_ver = src->minor_ver;
  11.259      
  11.260      return dup;
  11.261  }
  11.262 @@ -2462,6 +2574,10 @@
  11.263              sqlite3_column_int(session->get_identity, 4);
  11.264          _identity->me = (unsigned int)
  11.265              sqlite3_column_int(session->get_identity, 5);
  11.266 +        _identity->major_ver =
  11.267 +            sqlite3_column_int(session->get_identity, 6);
  11.268 +        _identity->minor_ver =
  11.269 +            sqlite3_column_int(session->get_identity, 7);
  11.270      
  11.271          *identity = _identity;
  11.272          break;
  11.273 @@ -2536,6 +2652,10 @@
  11.274              sqlite3_column_int(session->get_identities_by_userid, 5);
  11.275          ident->me = (unsigned int)
  11.276              sqlite3_column_int(session->get_identities_by_userid, 6);
  11.277 +        ident->major_ver =
  11.278 +            sqlite3_column_int(session->get_identities_by_userid, 7);
  11.279 +        ident->minor_ver =
  11.280 +            sqlite3_column_int(session->get_identities_by_userid, 8);
  11.281      
  11.282          identity_list_add(*identities, ident);
  11.283          ident = NULL;
  11.284 @@ -2602,6 +2722,10 @@
  11.285              sqlite3_column_int(session->get_identities_by_main_key_id, 5);
  11.286          ident->me = (unsigned int)
  11.287              sqlite3_column_int(session->get_identities_by_main_key_id, 6);
  11.288 +        ident->major_ver =
  11.289 +            sqlite3_column_int(session->get_identities_by_main_key_id, 7);
  11.290 +        ident->minor_ver =
  11.291 +            sqlite3_column_int(session->get_identities_by_main_key_id, 8);
  11.292      
  11.293          identity_list_add(*identities, ident);
  11.294          ident = NULL;
  11.295 @@ -2672,6 +2796,10 @@
  11.296              sqlite3_column_int(session->get_identity_without_trust_check, 3);
  11.297          _identity->me = (unsigned int)
  11.298              sqlite3_column_int(session->get_identity_without_trust_check, 4);
  11.299 +        _identity->major_ver =
  11.300 +            sqlite3_column_int(session->get_identity_without_trust_check, 5);
  11.301 +        _identity->minor_ver =
  11.302 +            sqlite3_column_int(session->get_identity_without_trust_check, 6);
  11.303      
  11.304          *identity = _identity;
  11.305          break;
  11.306 @@ -2737,6 +2865,10 @@
  11.307              sqlite3_column_int(session->get_identities_by_address, 4);
  11.308          ident->me = (unsigned int)
  11.309              sqlite3_column_int(session->get_identities_by_address, 5);
  11.310 +        ident->major_ver =
  11.311 +            sqlite3_column_int(session->get_identities_by_address, 6);
  11.312 +        ident->minor_ver =
  11.313 +            sqlite3_column_int(session->get_identities_by_address, 7);
  11.314      
  11.315          if (ident_list)
  11.316              identity_list_add(ident_list, ident);
  11.317 @@ -2893,6 +3025,9 @@
  11.318              SQLITE_STATIC);
  11.319      sqlite3_bind_int(set_or_update, 4, identity->flags);
  11.320      sqlite3_bind_int(set_or_update, 5, identity->me);
  11.321 +    sqlite3_bind_int(set_or_update, 6, identity->major_ver);
  11.322 +    sqlite3_bind_int(set_or_update, 7, identity->minor_ver);
  11.323 +        
  11.324      int result = Sqlite3_step(set_or_update);
  11.325      sqlite3_reset(set_or_update);
  11.326      if (result != SQLITE_DONE)
  11.327 @@ -3006,7 +3141,7 @@
  11.328                                         guard_transaction);
  11.329  }
  11.330  
  11.331 -// This will NOT call set_as_pEp_user; you have to do that separately.
  11.332 +// This will NOT call set_as_pEp_user, nor set_pEp_version; you have to do that separately.
  11.333  DYNAMIC_API PEP_STATUS set_identity(
  11.334          PEP_SESSION session, const pEp_identity *identity
  11.335      )
  11.336 @@ -3073,6 +3208,12 @@
  11.337          }
  11.338      }
  11.339      
  11.340 +    status = set_pEp_version(session, ident_copy, ident_copy->major_ver, ident_copy->minor_ver);
  11.341 +    if (status != PEP_STATUS_OK) {
  11.342 +        sqlite3_exec(session->db, "ROLLBACK ;", NULL, NULL, NULL);
  11.343 +        goto pEp_free;            
  11.344 +    }
  11.345 +    
  11.346      result = sqlite3_exec(session->db, "COMMIT ;", NULL, NULL, NULL);
  11.347      if (result == SQLITE_OK)
  11.348          status = PEP_STATUS_OK;
  11.349 @@ -3097,7 +3238,9 @@
  11.350      if (result != SQLITE_DONE)
  11.351          return PEP_CANNOT_SET_TRUST;
  11.352  
  11.353 -    return PEP_STATUS_OK;
  11.354 +    PEP_STATUS status = upgrade_pEp_version_by_user_id(session, user, 2, 0);
  11.355 +    
  11.356 +    return status;
  11.357  }
  11.358  
  11.359  
  11.360 @@ -3138,6 +3281,54 @@
  11.361      return status;
  11.362  }
  11.363  
  11.364 +// This ONLY sets the version flag. Must be called outside of a transaction.
  11.365 +PEP_STATUS set_pEp_version(PEP_SESSION session, pEp_identity* ident, unsigned int new_ver_major, unsigned int new_ver_minor) {
  11.366 +    assert(session);
  11.367 +    assert(!EMPTYSTR(ident->user_id));
  11.368 +    assert(!EMPTYSTR(ident->address));
  11.369 +    
  11.370 +    sqlite3_reset(session->set_pEp_version);
  11.371 +    sqlite3_bind_double(session->set_pEp_version, 1, new_ver_major);
  11.372 +    sqlite3_bind_double(session->set_pEp_version, 2, new_ver_minor);    
  11.373 +    sqlite3_bind_text(session->set_pEp_version, 3, ident->address, -1,
  11.374 +            SQLITE_STATIC);
  11.375 +    sqlite3_bind_text(session->set_pEp_version, 4, ident->user_id, -1,
  11.376 +            SQLITE_STATIC);
  11.377 +    
  11.378 +    int result = Sqlite3_step(session->set_pEp_version);
  11.379 +    sqlite3_reset(session->set_pEp_version);
  11.380 +        
  11.381 +    if (result != SQLITE_DONE)
  11.382 +        return PEP_CANNOT_SET_PEP_VERSION;
  11.383 +    
  11.384 +    return PEP_STATUS_OK;
  11.385 +}
  11.386 +
  11.387 +// Generally ONLY called by set_as_pEp_user, and ONLY from < 2.0 to 2.0.
  11.388 +PEP_STATUS upgrade_pEp_version_by_user_id(PEP_SESSION session, 
  11.389 +        pEp_identity* ident, 
  11.390 +        unsigned int new_ver_major,
  11.391 +        unsigned int new_ver_minor
  11.392 +    ) 
  11.393 +{
  11.394 +    assert(session);
  11.395 +    assert(!EMPTYSTR(ident->user_id));
  11.396 +    
  11.397 +    sqlite3_reset(session->upgrade_pEp_version_by_user_id);
  11.398 +    sqlite3_bind_int(session->upgrade_pEp_version_by_user_id, 1, new_ver_major);
  11.399 +    sqlite3_bind_int(session->upgrade_pEp_version_by_user_id, 2, new_ver_minor);    
  11.400 +    sqlite3_bind_text(session->upgrade_pEp_version_by_user_id, 3, ident->user_id, -1,
  11.401 +            SQLITE_STATIC);
  11.402 +    
  11.403 +    int result = Sqlite3_step(session->upgrade_pEp_version_by_user_id);
  11.404 +    sqlite3_reset(session->upgrade_pEp_version_by_user_id);
  11.405 +        
  11.406 +    if (result != SQLITE_DONE)
  11.407 +        return PEP_CANNOT_SET_PEP_VERSION;
  11.408 +    
  11.409 +    return PEP_STATUS_OK;    
  11.410 +}
  11.411 +
  11.412  PEP_STATUS exists_person(PEP_SESSION session, pEp_identity* identity,
  11.413                           bool* exists) {            
  11.414      
    12.1 --- a/src/pEpEngine.h	Wed Aug 07 12:10:12 2019 +0200
    12.2 +++ b/src/pEpEngine.h	Wed Aug 07 14:08:11 2019 +0200
    12.3 @@ -17,7 +17,7 @@
    12.4  #include "labeled_int_list.h"    
    12.5  #include "timestamp.h"
    12.6  
    12.7 -#define PEP_VERSION "2.0" // protocol version
    12.8 +#define PEP_VERSION "2.1" // protocol version
    12.9  
   12.10  #define PEP_OWN_USERID "pEp_own_userId"
   12.11      
   12.12 @@ -69,6 +69,7 @@
   12.13      PEP_CANNOT_SET_TRUST                            = 0x0384,
   12.14      PEP_KEY_BLACKLISTED                             = 0x0385,
   12.15      PEP_CANNOT_FIND_PERSON                          = 0x0386,
   12.16 +    PEP_CANNOT_SET_PEP_VERSION                      = 0X0387,
   12.17      
   12.18      PEP_CANNOT_FIND_ALIAS                           = 0x0391,
   12.19      PEP_CANNOT_SET_ALIAS                            = 0x0392,
   12.20 @@ -597,6 +598,8 @@
   12.21      char lang[3];               // language of conversation
   12.22                                  // ISO 639-1 ALPHA-2, last byte is 0
   12.23      bool me;                    // if this is the local user herself/himself
   12.24 +    int major_ver;              // highest version of pEp message received, if any
   12.25 +    int minor_ver;              // highest version of pEp message received, if any
   12.26      identity_flags_t flags;     // identity_flag1 | identity_flag2 | ...
   12.27  } pEp_identity;
   12.28  
   12.29 @@ -1354,6 +1357,15 @@
   12.30  
   12.31  PEP_STATUS set_pgp_keypair(PEP_SESSION session, const char* fpr);
   12.32  
   12.33 +PEP_STATUS set_pEp_version(PEP_SESSION session, pEp_identity* ident, unsigned int new_ver_major, unsigned int new_ver_minor);
   12.34 +
   12.35 +// Generally ONLY called by set_as_pEp_user, and ONLY from < 2.0 to 2.0.
   12.36 +PEP_STATUS upgrade_pEp_version_by_user_id(PEP_SESSION session, 
   12.37 +        pEp_identity* ident, 
   12.38 +        unsigned int new_ver_major,
   12.39 +        unsigned int new_ver_minor
   12.40 +    );
   12.41 +     
   12.42  // exposed for testing
   12.43  PEP_STATUS set_person(PEP_SESSION session, pEp_identity* identity,
   12.44                        bool guard_transaction);
    13.1 --- a/src/pEp_internal.h	Wed Aug 07 12:10:12 2019 +0200
    13.2 +++ b/src/pEp_internal.h	Wed Aug 07 14:08:11 2019 +0200
    13.3 @@ -51,7 +51,14 @@
    13.4  #define PEP_MSG_WRAP_KEY_LEN 26
    13.5  #endif
    13.6  
    13.7 +#ifndef X_PEP_MSG_WRAP_KEY
    13.8 +#define X_PEP_MSG_WRAP_KEY "X-pEp-Wrapped-Message-Info"
    13.9 +#endif
   13.10  
   13.11 +#ifndef X_PEP_SNDR_FPR_KEY
   13.12 +#define X_PEP_SNDR_FPR_KEY "X-pEp-Sender-FPR"
   13.13 +#endif
   13.14 + 
   13.15  #include "platform.h"
   13.16  
   13.17  #ifdef WIN32
   13.18 @@ -175,6 +182,7 @@
   13.19      sqlite3_stmt *exists_person;    
   13.20      sqlite3_stmt *set_as_pEp_user;
   13.21      sqlite3_stmt *is_pEp_user;
   13.22 +    sqlite3_stmt *upgrade_pEp_version_by_user_id;
   13.23      sqlite3_stmt *add_into_social_graph;
   13.24      sqlite3_stmt *get_own_address_binding_from_contact;
   13.25      sqlite3_stmt *set_revoke_contact_as_notified;
   13.26 @@ -189,6 +197,7 @@
   13.27      sqlite3_stmt *exists_identity_entry;        
   13.28      sqlite3_stmt *set_identity_flags;
   13.29      sqlite3_stmt *unset_identity_flags;
   13.30 +    sqlite3_stmt *set_pEp_version;    
   13.31      sqlite3_stmt *set_trust;
   13.32      sqlite3_stmt *update_trust;
   13.33      sqlite3_stmt *exists_trust_entry;
   13.34 @@ -449,6 +458,68 @@
   13.35      return retval;
   13.36  }
   13.37  
   13.38 +static inline float pEp_version_numeric(const char* version_str) {
   13.39 +    float retval = 0;    
   13.40 +        
   13.41 +    if (!version_str || sscanf(version_str, "%f", &retval) != 1)
   13.42 +        return 0;
   13.43 +        
   13.44 +    return retval;    
   13.45 +}
   13.46 +
   13.47 +static inline void pEp_version_major_minor(const char* version_str, unsigned int* major, unsigned int* minor) {
   13.48 +    if (!major || !minor)
   13.49 +        return;
   13.50 +                
   13.51 +    if (!version_str || sscanf(version_str, "%u.%u", major, minor) != 2) {
   13.52 +        *major = 0;
   13.53 +        *minor = 0;
   13.54 +    }
   13.55 +        
   13.56 +    return;    
   13.57 +}
   13.58 +
   13.59 +static inline int compare_versions(unsigned int first_maj, unsigned int first_min,
   13.60 +                                   unsigned int second_maj, unsigned int second_min) {
   13.61 +    if (first_maj > second_maj)
   13.62 +        return 1;
   13.63 +    if (first_maj < second_maj)
   13.64 +        return -1;
   13.65 +    if (first_min > second_min)
   13.66 +        return 1;
   13.67 +    if (first_min < second_min)
   13.68 +        return -1;
   13.69 +    return 0;    
   13.70 +}
   13.71 +
   13.72 +static inline void set_min_version(unsigned int first_maj, unsigned int first_minor,
   13.73 +                                   unsigned int second_maj, unsigned int second_minor,
   13.74 +                                   unsigned int* result_maj, unsigned int* result_minor) {
   13.75 +    int result = compare_versions(first_maj, first_minor, second_maj, second_minor);
   13.76 +    if (result < 0) {
   13.77 +        *result_maj = first_maj;
   13.78 +        *result_minor = first_minor;
   13.79 +    }
   13.80 +    else {
   13.81 +        *result_maj = second_maj;
   13.82 +        *result_minor = second_minor;
   13.83 +    }    
   13.84 +}
   13.85 +
   13.86 +static inline void set_max_version(unsigned int first_maj, unsigned int first_minor,
   13.87 +                                   unsigned int second_maj, unsigned int second_minor,
   13.88 +                                   unsigned int* result_maj, unsigned int* result_minor) {
   13.89 +    int result = compare_versions(first_maj, first_minor, second_maj, second_minor);
   13.90 +    if (result > 0) {
   13.91 +        *result_maj = first_maj;
   13.92 +        *result_minor = first_minor;
   13.93 +    }
   13.94 +    else {
   13.95 +        *result_maj = second_maj;
   13.96 +        *result_minor = second_minor;
   13.97 +    }    
   13.98 +}
   13.99 +
  13.100  #ifndef EMPTYSTR
  13.101  #define EMPTYSTR(STR) ((STR) == NULL || (STR)[0] == '\0')
  13.102  #endif
  13.103 @@ -464,7 +535,6 @@
  13.104  #define _MAX(A, B) ((B) > (A) ? (B) : (A))
  13.105  #endif
  13.106  
  13.107 -
  13.108  // These are globals used in generating message IDs and should only be
  13.109  // computed once, as they're either really constants or OS-dependent
  13.110  
    14.1 --- a/src/stringpair.c	Wed Aug 07 12:10:12 2019 +0200
    14.2 +++ b/src/stringpair.c	Wed Aug 07 14:08:11 2019 +0200
    14.3 @@ -194,6 +194,41 @@
    14.4      }
    14.5  }
    14.6  
    14.7 +// ONLY DELETES ONE.
    14.8 +DYNAMIC_API stringpair_list_t *stringpair_list_delete_by_key(
    14.9 +        stringpair_list_t *sp_list,
   14.10 +        const char *key
   14.11 +    )
   14.12 +{
   14.13 +    assert(sp_list);
   14.14 +    assert(key);
   14.15 +
   14.16 +    if (sp_list->value == NULL) {
   14.17 +        free_stringpair_list(sp_list);
   14.18 +        return NULL;
   14.19 +    }
   14.20 +
   14.21 +    if (key == NULL)
   14.22 +        return sp_list;
   14.23 +
   14.24 +    stringpair_list_t *_sl;
   14.25 +    stringpair_list_t *last = NULL;
   14.26 +    for (_sl = sp_list; _sl && _sl->value && _sl->value->key; _sl = _sl->next) {
   14.27 +        if (strcmp(_sl->value->key, key) == 0) {
   14.28 +            if (last == NULL)
   14.29 +                sp_list = sp_list->next;
   14.30 +            else
   14.31 +                last->next = _sl->next;
   14.32 +            _sl->next = NULL;
   14.33 +            free_stringpair_list(_sl);
   14.34 +            break;
   14.35 +        }
   14.36 +        last = _sl;
   14.37 +    }
   14.38 +    return sp_list;
   14.39 +}
   14.40 +
   14.41 +
   14.42  DYNAMIC_API stringpair_list_t *stringpair_list_find(
   14.43          stringpair_list_t *stringpair_list,
   14.44          const char *key
    15.1 --- a/src/stringpair.h	Wed Aug 07 12:10:12 2019 +0200
    15.2 +++ b/src/stringpair.h	Wed Aug 07 14:08:11 2019 +0200
    15.3 @@ -159,8 +159,13 @@
    15.4          const char *key
    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  
   15.14  #ifdef __cplusplus
   15.15  }
   15.16  #endif
   15.17 -
    16.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.2 +++ b/test/convenience_scripts/ExportKeyUtilTests.cc	Wed Aug 07 14:08:11 2019 +0200
    16.3 @@ -0,0 +1,80 @@
    16.4 +// This file is under GNU General Public License 3.0
    16.5 +// see LICENSE.txt
    16.6 +
    16.7 +#include <stdlib.h>
    16.8 +#include <cstring>
    16.9 +#include <string>
   16.10 +#include <fstream>
   16.11 +#include <iostream>
   16.12 +
   16.13 +#include <cpptest.h>
   16.14 +#include "test_util.h"
   16.15 +
   16.16 +#include "pEpEngine.h"
   16.17 +
   16.18 +#include "EngineTestIndividualSuite.h"
   16.19 +#include "ExportKeyUtilTests.h"
   16.20 +
   16.21 +using namespace std;
   16.22 +
   16.23 +ExportKeyUtilTests::ExportKeyUtilTests(string suitename, string test_home_dir) :
   16.24 +    EngineTestIndividualSuite::EngineTestIndividualSuite(suitename, test_home_dir) {
   16.25 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("ExportKeyUtilTests::check_export_key_util"),
   16.26 +                                                                      static_cast<Func>(&ExportKeyUtilTests::check_export_key_util)));
   16.27 +}
   16.28 +
   16.29 +void ExportKeyUtilTests::setup() {
   16.30 +    string key_db_name;
   16.31 +    cout << "Please indicate the name of the key DB file: ";
   16.32 +    cin >> key_db_name;
   16.33 +    add_file_to_home_dir_queue(key_db_name, ".pEp_keys.db");
   16.34 +    EngineTestIndividualSuite::setup();
   16.35 +}
   16.36 +
   16.37 +void ExportKeyUtilTests::check_export_key_util() {
   16.38 +    string search_term;
   16.39 +    string output_file;
   16.40 +    cout << "Please give address (containing @) or key_id to dump: ";
   16.41 +    cin >> search_term;
   16.42 +    stringlist_t* keylist = NULL;
   16.43 +    PEP_STATUS status = find_keys(session, search_term.c_str(), &keylist);
   16.44 +    TEST_ASSERT(status == PEP_STATUS_OK);
   16.45 +    TEST_ASSERT(keylist);
   16.46 +    string priv;
   16.47 +    cout << "Private keys? (y/N)";
   16.48 +    cin >> priv;
   16.49 +    string outdir;
   16.50 +    cout << "Output directory? (curdir is default)";
   16.51 +    cin >> outdir;
   16.52 +    stringlist_t* curr = keylist;
   16.53 +    while (curr) {
   16.54 +        string fpr = curr->value;
   16.55 +        if (!fpr.empty()) {
   16.56 +            char* key = NULL;
   16.57 +            size_t size = 0;
   16.58 +            status = export_key(session, fpr.c_str(), &key, &size);
   16.59 +            if (key && size != 0) {
   16.60 +                ofstream outfile;
   16.61 +                outfile.open(((outdir.empty() ? fpr : outdir + "/" + fpr) + "_pub.asc").c_str());
   16.62 +                outfile.write(key, size);
   16.63 +                outfile.close();
   16.64 +            }
   16.65 +            free(key);
   16.66 +            size = 0;
   16.67 +            key = NULL;
   16.68 +            if (priv.c_str()[0] == 'y' || priv.c_str()[0] == 'Y') {
   16.69 +                status = export_secret_key(session, fpr.c_str(), &key, &size);
   16.70 +                if (key && size != 0) {
   16.71 +                    ofstream outfile;
   16.72 +                    outfile.open(((outdir.empty() ? fpr : outdir + "/" + fpr) + "_pub.asc").c_str());
   16.73 +                    outfile.write(key, size);
   16.74 +                    outfile.close();                    
   16.75 +                }                
   16.76 +            }   
   16.77 +            free(key);
   16.78 +        }
   16.79 +        curr = curr->next;
   16.80 +    }
   16.81 +    
   16.82 +    TEST_ASSERT(true);
   16.83 +}
    17.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.2 +++ b/test/convenience_scripts/ExportKeyUtilTests.h	Wed Aug 07 14:08:11 2019 +0200
    17.3 @@ -0,0 +1,21 @@
    17.4 +// This file is under GNU General Public License 3.0
    17.5 +// see LICENSE.txt
    17.6 +
    17.7 +#ifndef EXPORT_KEY_UTIL_H
    17.8 +#define EXPORT_KEY_UTIL_H
    17.9 +
   17.10 +#include <string>
   17.11 +#include "EngineTestIndividualSuite.h"
   17.12 +
   17.13 +using namespace std;
   17.14 +
   17.15 +class ExportKeyUtilTests : public EngineTestIndividualSuite {
   17.16 +    public:
   17.17 +        ExportKeyUtilTests(string test_suite, string test_home_dir);
   17.18 +    protected:
   17.19 +        void setup();    
   17.20 +    private:
   17.21 +        void check_export_key_util();
   17.22 +};
   17.23 +
   17.24 +#endif
    18.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.2 +++ b/test/include/GetKeyRatingForUserTests.h	Wed Aug 07 14:08:11 2019 +0200
    18.3 @@ -0,0 +1,19 @@
    18.4 +// This file is under GNU General Public License 3.0
    18.5 +// see LICENSE.txt
    18.6 +
    18.7 +#ifndef GET_KEY_RATING_FOR_USER_H
    18.8 +#define GET_KEY_RATING_FOR_USER_H
    18.9 +
   18.10 +#include <string>
   18.11 +#include "EngineTestIndividualSuite.h"
   18.12 +
   18.13 +using namespace std;
   18.14 +
   18.15 +class GetKeyRatingForUserTests : public EngineTestIndividualSuite {
   18.16 +    public:
   18.17 +        GetKeyRatingForUserTests(string test_suite, string test_home_dir);
   18.18 +    private:
   18.19 +        void check_get_key_rating_for_user();
   18.20 +};
   18.21 +
   18.22 +#endif
    19.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.2 +++ b/test/include/Message2_1Tests.h	Wed Aug 07 14:08:11 2019 +0200
    19.3 @@ -0,0 +1,28 @@
    19.4 +// This file is under GNU General Public License 3.0
    19.5 +// see LICENSE.txt
    19.6 +
    19.7 +#ifndef MESSAGE2_1_H
    19.8 +#define MESSAGE2_1_H
    19.9 +
   19.10 +#include <string>
   19.11 +#include "EngineTestIndividualSuite.h"
   19.12 +
   19.13 +using namespace std;
   19.14 +
   19.15 +class Message2_1Tests : public EngineTestIndividualSuite {
   19.16 +    public:
   19.17 +        Message2_1Tests(string test_suite, string test_home_dir);
   19.18 +    private:
   19.19 +        bool verify_message_version_produced(message* enc_msg, unsigned int* maj_inout, unsigned int* min_inout);
   19.20 +        
   19.21 +        void check_message2_1_recip_2_0();
   19.22 +        void check_message2_1_recip_OpenPGP();
   19.23 +        void check_message2_1_recip_2_1();
   19.24 +        void check_message2_1_recip_1_0_from_msg_OpenPGP();
   19.25 +        void check_message2_1_recip_2_0_from_msg();
   19.26 +        void check_message2_1_recip_2_1_from_msg();
   19.27 +        void check_message2_1_recip_mixed_2_0();
   19.28 +        void check_message2_1_recip_mixed_1_0_OpenPGP();
   19.29 +};
   19.30 +
   19.31 +#endif
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/test/include/SenderFPRTests.h	Wed Aug 07 14:08:11 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 SENDER_F_P_R_H
    20.8 +#define SENDER_F_P_R_H
    20.9 +
   20.10 +#include <string>
   20.11 +#include "EngineTestIndividualSuite.h"
   20.12 +
   20.13 +using namespace std;
   20.14 +
   20.15 +class SenderFPRTests : public EngineTestIndividualSuite {
   20.16 +    public:
   20.17 +        SenderFPRTests(string test_suite, string test_home_dir);
   20.18 +    private:
   20.19 +        void check_sender_f_p_r();
   20.20 +};
   20.21 +
   20.22 +#endif
    21.1 --- a/test/include/test_util.h	Wed Aug 07 12:10:12 2019 +0200
    21.2 +++ b/test/include/test_util.h	Wed Aug 07 14:08:11 2019 +0200
    21.3 @@ -14,6 +14,44 @@
    21.4  
    21.5  bool file_exists(std::string filename);
    21.6  
    21.7 +typedef enum _pEp_test_ident_preset {
    21.8 +    ALICE,
    21.9 +    APPLE,
   21.10 +    BOB,
   21.11 +    CAROL,
   21.12 +    DAVE,
   21.13 +    ERIN,
   21.14 +    FRANK,
   21.15 +    GABRIELLE,
   21.16 +    JOHN,
   21.17 +    ALEX,
   21.18 +    ALEX_0,
   21.19 +    ALEX_1,
   21.20 +    ALEX_2,
   21.21 +    ALEX_3,
   21.22 +    ALEX_4,
   21.23 +    ALEX_5,
   21.24 +    ALEX_6A,
   21.25 +    ALEX_6B,
   21.26 +    ALEX_6C,
   21.27 +    ALEX_6D,
   21.28 +    BELLA,
   21.29 +    FENRIS,
   21.30 +    SERCULLEN,
   21.31 +    INQUISITOR,
   21.32 +    BERND
   21.33 +} pEp_test_ident_preset;
   21.34 +
   21.35 +PEP_STATUS set_up_preset(PEP_SESSION session,
   21.36 +                         pEp_test_ident_preset preset_name,
   21.37 +                         bool set_identity, 
   21.38 +                         bool set_pep,
   21.39 +                         bool trust,
   21.40 +                         bool set_own, 
   21.41 +                         bool setup_private, 
   21.42 +                         pEp_identity** ident);
   21.43 +
   21.44 +
   21.45  PEP_STATUS read_file_and_import_key(PEP_SESSION session, const char* fname);
   21.46  PEP_STATUS set_up_ident_from_scratch(PEP_SESSION session, 
   21.47                                       const char* key_fname,
    22.1 --- a/test/src/SuiteMaker.cc	Wed Aug 07 12:10:12 2019 +0200
    22.2 +++ b/test/src/SuiteMaker.cc	Wed Aug 07 14:08:11 2019 +0200
    22.3 @@ -26,6 +26,7 @@
    22.4  #include "NoOwnIdentWritesOnDecryptTests.h"
    22.5  #include "LiteralFilenameTests.h"
    22.6  #include "I18nTests.h"
    22.7 +#include "Message2_1Tests.h"
    22.8  #include "IdentityListTests.h"
    22.9  #include "PgpBinaryTests.h"
   22.10  #include "SubkeyRatingEvalTests.h"
   22.11 @@ -48,6 +49,7 @@
   22.12  #include "BlacklistAcceptNewKeyTests.h"
   22.13  #include "DecryptAttachPrivateKeyUntrustedTests.h"
   22.14  #include "BlacklistTests.h"
   22.15 +#include "GetKeyRatingForUserTests.h"
   22.16  #include "RevokeRegenAttachTests.h"
   22.17  #include "PepSubjectReceivedTests.h"
   22.18  #include "SequenceTests.h"
   22.19 @@ -75,6 +77,7 @@
   22.20  #include "TrustManipulationTests.h"
   22.21  #include "StrnstrTests.h"
   22.22  #include "SyncTests.h"
   22.23 +#include "SenderFPRTests.h"
   22.24  #include "RevocationTests.h"
   22.25  #include "AppleMailTests.h"
   22.26  
   22.27 @@ -94,6 +97,7 @@
   22.28      "NoOwnIdentWritesOnDecryptTests",
   22.29      "LiteralFilenameTests",
   22.30      "I18nTests",
   22.31 +    "Message2_1Tests",
   22.32      "IdentityListTests",
   22.33      "PgpBinaryTests",
   22.34      "SubkeyRatingEvalTests",
   22.35 @@ -116,6 +120,7 @@
   22.36      "BlacklistAcceptNewKeyTests",
   22.37      "DecryptAttachPrivateKeyUntrustedTests",
   22.38      "BlacklistTests",
   22.39 +    "GetKeyRatingForUserTests",
   22.40      "RevokeRegenAttachTests",
   22.41      "PepSubjectReceivedTests",
   22.42      "SequenceTests",
   22.43 @@ -143,12 +148,13 @@
   22.44      "TrustManipulationTests",
   22.45      "StrnstrTests",
   22.46      "SyncTests",
   22.47 +    "SenderFPRTests",
   22.48      "RevocationTests",
   22.49      "AppleMailTests",
   22.50  };
   22.51  
   22.52  // This file is generated, so magic constants are ok.
   22.53 -int SuiteMaker::num_suites = 65;
   22.54 +int SuiteMaker::num_suites = 68;
   22.55  
   22.56  void SuiteMaker::suitemaker_build(const char* test_class_name, const char* test_home, Test::Suite** test_suite) {
   22.57      if (strcmp(test_class_name, "URIAddressTests") == 0)
   22.58 @@ -179,6 +185,8 @@
   22.59          *test_suite = new LiteralFilenameTests(test_class_name, test_home);
   22.60      else if (strcmp(test_class_name, "I18nTests") == 0)
   22.61          *test_suite = new I18nTests(test_class_name, test_home);
   22.62 +    else if (strcmp(test_class_name, "Message2_1Tests") == 0)
   22.63 +        *test_suite = new Message2_1Tests(test_class_name, test_home);
   22.64      else if (strcmp(test_class_name, "IdentityListTests") == 0)
   22.65          *test_suite = new IdentityListTests(test_class_name, test_home);
   22.66      else if (strcmp(test_class_name, "PgpBinaryTests") == 0)
   22.67 @@ -223,6 +231,8 @@
   22.68          *test_suite = new DecryptAttachPrivateKeyUntrustedTests(test_class_name, test_home);
   22.69      else if (strcmp(test_class_name, "BlacklistTests") == 0)
   22.70          *test_suite = new BlacklistTests(test_class_name, test_home);
   22.71 +    else if (strcmp(test_class_name, "GetKeyRatingForUserTests") == 0)
   22.72 +        *test_suite = new GetKeyRatingForUserTests(test_class_name, test_home);
   22.73      else if (strcmp(test_class_name, "RevokeRegenAttachTests") == 0)
   22.74          *test_suite = new RevokeRegenAttachTests(test_class_name, test_home);
   22.75      else if (strcmp(test_class_name, "PepSubjectReceivedTests") == 0)
   22.76 @@ -277,6 +287,8 @@
   22.77          *test_suite = new StrnstrTests(test_class_name, test_home);
   22.78      else if (strcmp(test_class_name, "SyncTests") == 0)
   22.79          *test_suite = new SyncTests(test_class_name, test_home);
   22.80 +    else if (strcmp(test_class_name, "SenderFPRTests") == 0)
   22.81 +        *test_suite = new SenderFPRTests(test_class_name, test_home);
   22.82      else if (strcmp(test_class_name, "RevocationTests") == 0)
   22.83          *test_suite = new RevocationTests(test_class_name, test_home);
   22.84      else if (strcmp(test_class_name, "AppleMailTests") == 0)
    23.1 --- a/test/src/engine_tests/AppleMailTests.cc	Wed Aug 07 12:10:12 2019 +0200
    23.2 +++ b/test/src/engine_tests/AppleMailTests.cc	Wed Aug 07 14:08:11 2019 +0200
    23.3 @@ -67,7 +67,7 @@
    23.4      PEP_decrypt_flags_t flags = 0;
    23.5      
    23.6      message* final_ptr = nullptr;
    23.7 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
    23.8 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
    23.9      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   23.10      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   23.11      
   23.12 @@ -129,7 +129,7 @@
   23.13      const char* mailfile2 = "test_mails/apple_mail_TC_html_signed_encrypted.eml";
   23.14      const string mailtext2 = slurp(mailfile2);
   23.15      
   23.16 -    status = mime_decode_message(mailtext2.c_str(), mailtext2.length(), &msg_ptr);
   23.17 +    status = mime_decode_message(mailtext2.c_str(), mailtext2.length(), &msg_ptr, NULL);
   23.18      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   23.19      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   23.20      final_ptr = msg_ptr;
    24.1 --- a/test/src/engine_tests/BlacklistAcceptNewKeyTests.cc	Wed Aug 07 12:10:12 2019 +0200
    24.2 +++ b/test/src/engine_tests/BlacklistAcceptNewKeyTests.cc	Wed Aug 07 14:08:11 2019 +0200
    24.3 @@ -80,7 +80,7 @@
    24.4      PEP_rating rating;
    24.5      PEP_decrypt_flags_t flags = 0;
    24.6      
    24.7 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
    24.8 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
    24.9      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   24.10      status = decrypt_message(session, msg_ptr, &dest_msg, &keylist, &rating, &flags);
   24.11  
    25.1 --- a/test/src/engine_tests/EncryptForIdentityTests.cc	Wed Aug 07 12:10:12 2019 +0200
    25.2 +++ b/test/src/engine_tests/EncryptForIdentityTests.cc	Wed Aug 07 14:08:11 2019 +0200
    25.3 @@ -96,7 +96,7 @@
    25.4      cout << encoded_text << "\n";
    25.5  
    25.6      message* decoded_msg = nullptr;
    25.7 -    status = mime_decode_message(encoded_text, strlen(encoded_text), &decoded_msg);
    25.8 +    status = mime_decode_message(encoded_text, strlen(encoded_text), &decoded_msg, NULL);
    25.9      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   25.10      const string string3 = encoded_text;
   25.11  
    26.1 --- a/test/src/engine_tests/EncryptMissingPrivateKeyTests.cc	Wed Aug 07 12:10:12 2019 +0200
    26.2 +++ b/test/src/engine_tests/EncryptMissingPrivateKeyTests.cc	Wed Aug 07 14:08:11 2019 +0200
    26.3 @@ -55,7 +55,7 @@
    26.4      
    26.5      const string mailtext = slurp("test_mails/blacklist_no_key.eml");
    26.6  
    26.7 -    PEP_STATUS status = mime_decode_message(mailtext.c_str(), mailtext.length(), &tmp_msg);
    26.8 +    PEP_STATUS status = mime_decode_message(mailtext.c_str(), mailtext.length(), &tmp_msg, NULL);
    26.9      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   26.10      
   26.11      status = update_identity(session, tmp_msg->from);
    27.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.2 +++ b/test/src/engine_tests/GetKeyRatingForUserTests.cc	Wed Aug 07 14:08:11 2019 +0200
    27.3 @@ -0,0 +1,46 @@
    27.4 +// This file is under GNU General Public License 3.0
    27.5 +// see LICENSE.txt
    27.6 +
    27.7 +#include <stdlib.h>
    27.8 +#include <cstring>
    27.9 +#include <string>
   27.10 +
   27.11 +#include <cpptest.h>
   27.12 +#include "test_util.h"
   27.13 +
   27.14 +#include "pEpEngine.h"
   27.15 +
   27.16 +#include "EngineTestIndividualSuite.h"
   27.17 +#include "GetKeyRatingForUserTests.h"
   27.18 +
   27.19 +using namespace std;
   27.20 +
   27.21 +GetKeyRatingForUserTests::GetKeyRatingForUserTests(string suitename, string test_home_dir) :
   27.22 +    EngineTestIndividualSuite::EngineTestIndividualSuite(suitename, test_home_dir) {
   27.23 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("GetKeyRatingForUserTests::check_get_key_rating_for_user"),
   27.24 +                                                                      static_cast<Func>(&GetKeyRatingForUserTests::check_get_key_rating_for_user)));
   27.25 +}
   27.26 +
   27.27 +void GetKeyRatingForUserTests::check_get_key_rating_for_user() {
   27.28 +    pEp_identity* alice = NULL;
   27.29 +    PEP_STATUS status = set_up_preset(session, ALICE, false, false, false, false, false, &alice);
   27.30 +    pEp_identity* test_null = NULL;
   27.31 +    const char* fpr_save = alice->fpr;
   27.32 +    alice->fpr = NULL;
   27.33 +    status = get_identity(session, alice->address, alice->user_id, &test_null);
   27.34 +    TEST_ASSERT(!test_null);
   27.35 +    TEST_ASSERT(status == PEP_CANNOT_FIND_IDENTITY);
   27.36 +    TEST_ASSERT_MSG(alice->comm_type == PEP_ct_unknown, tl_ct_string(alice->comm_type));
   27.37 +
   27.38 +    // Ok, so we have no info really, let's set it.
   27.39 +    status = set_identity(session, alice);
   27.40 +    
   27.41 +    status = update_identity(session, alice);
   27.42 +    TEST_ASSERT(alice->fpr);
   27.43 +
   27.44 +    PEP_rating rating;
   27.45 +    status = get_key_rating_for_user(session, alice->user_id, alice->fpr, &rating);
   27.46 +    TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   27.47 +    cout << tl_rating_string(rating) << endl;
   27.48 +    TEST_ASSERT(true);
   27.49 +}
    28.1 --- a/test/src/engine_tests/IOS1664Tests.cc	Wed Aug 07 12:10:12 2019 +0200
    28.2 +++ b/test/src/engine_tests/IOS1664Tests.cc	Wed Aug 07 14:08:11 2019 +0200
    28.3 @@ -27,8 +27,9 @@
    28.4      TEST_ASSERT(!email.empty());
    28.5      
    28.6      message* message_mail = NULL;
    28.7 +    bool raise_att;
    28.8      
    28.9 -    PEP_STATUS status = mime_decode_message(email.c_str(), email.size(), &message_mail);
   28.10 +    PEP_STATUS status = mime_decode_message(email.c_str(), email.size(), &message_mail, &raise_att);
   28.11      TEST_ASSERT(status == PEP_STATUS_OK && message_mail);
   28.12      
   28.13      // create own identity here, because we want to reply, before we start.
    29.1 --- a/test/src/engine_tests/KeyAttachmentTests.cc	Wed Aug 07 12:10:12 2019 +0200
    29.2 +++ b/test/src/engine_tests/KeyAttachmentTests.cc	Wed Aug 07 14:08:11 2019 +0200
    29.3 @@ -73,7 +73,7 @@
    29.4      message* enc_msg = NULL;
    29.5      message* dec_msg = NULL;
    29.6  
    29.7 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
    29.8 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
    29.9      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   29.10      TEST_ASSERT(enc_msg);
   29.11      stringlist_t* keylist = NULL;
   29.12 @@ -93,7 +93,7 @@
   29.13      message* enc_msg = NULL;
   29.14      message* dec_msg = NULL;
   29.15  
   29.16 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
   29.17 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
   29.18      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   29.19      TEST_ASSERT(enc_msg);
   29.20      stringlist_t* keylist = NULL;
   29.21 @@ -119,7 +119,7 @@
   29.22      message* enc_msg = NULL;
   29.23      message* dec_msg = NULL;
   29.24  
   29.25 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
   29.26 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
   29.27      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   29.28      TEST_ASSERT(enc_msg);
   29.29      stringlist_t* keylist = NULL;
   29.30 @@ -145,7 +145,7 @@
   29.31      message* enc_msg = NULL;
   29.32      message* dec_msg = NULL;
   29.33  
   29.34 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
   29.35 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
   29.36      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   29.37      TEST_ASSERT(enc_msg);
   29.38      stringlist_t* keylist = NULL;
   29.39 @@ -171,7 +171,7 @@
   29.40      message* enc_msg = NULL;
   29.41      message* dec_msg = NULL;
   29.42  
   29.43 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
   29.44 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
   29.45      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   29.46      TEST_ASSERT(enc_msg);
   29.47      stringlist_t* keylist = NULL;
   29.48 @@ -201,7 +201,7 @@
   29.49      message* enc_msg = NULL;
   29.50      message* dec_msg = NULL;
   29.51  
   29.52 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
   29.53 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
   29.54      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   29.55      TEST_ASSERT(enc_msg);
   29.56      stringlist_t* keylist = NULL;
   29.57 @@ -221,7 +221,7 @@
   29.58      message* enc_msg = NULL;
   29.59      message* dec_msg = NULL;
   29.60  
   29.61 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
   29.62 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
   29.63      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   29.64      TEST_ASSERT(enc_msg);
   29.65      stringlist_t* keylist = NULL;
   29.66 @@ -247,7 +247,7 @@
   29.67      message* enc_msg = NULL;
   29.68      message* dec_msg = NULL;
   29.69  
   29.70 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
   29.71 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
   29.72      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   29.73      TEST_ASSERT(enc_msg);
   29.74      stringlist_t* keylist = NULL;
   29.75 @@ -273,7 +273,7 @@
   29.76      message* enc_msg = NULL;
   29.77      message* dec_msg = NULL;
   29.78  
   29.79 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
   29.80 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
   29.81      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   29.82      TEST_ASSERT(enc_msg);
   29.83      stringlist_t* keylist = NULL;
   29.84 @@ -328,7 +328,7 @@
   29.85      message* enc_msg = NULL;
   29.86      message* dec_msg = NULL;
   29.87  
   29.88 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
   29.89 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
   29.90      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   29.91      TEST_ASSERT(enc_msg);
   29.92      stringlist_t* keylist = NULL;
   29.93 @@ -348,7 +348,7 @@
   29.94      message* enc_msg = NULL;
   29.95      message* dec_msg = NULL;
   29.96  
   29.97 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
   29.98 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
   29.99      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  29.100      TEST_ASSERT(enc_msg);
  29.101      stringlist_t* keylist = NULL;
  29.102 @@ -373,7 +373,7 @@
  29.103      message* enc_msg = NULL;
  29.104      message* dec_msg = NULL;
  29.105  
  29.106 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
  29.107 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
  29.108      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  29.109      TEST_ASSERT(enc_msg);
  29.110      stringlist_t* keylist = NULL;
  29.111 @@ -399,7 +399,7 @@
  29.112      message* enc_msg = NULL;
  29.113      message* dec_msg = NULL;
  29.114  
  29.115 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
  29.116 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
  29.117      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  29.118      TEST_ASSERT(enc_msg);
  29.119      stringlist_t* keylist = NULL;
  29.120 @@ -424,7 +424,7 @@
  29.121      message* enc_msg = NULL;
  29.122      message* dec_msg = NULL;
  29.123  
  29.124 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
  29.125 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
  29.126      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  29.127      TEST_ASSERT(enc_msg);
  29.128      stringlist_t* keylist = NULL;
  29.129 @@ -449,7 +449,7 @@
  29.130      message* enc_msg = NULL;
  29.131      message* dec_msg = NULL;
  29.132  
  29.133 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
  29.134 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
  29.135      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  29.136      TEST_ASSERT(enc_msg);
  29.137      stringlist_t* keylist = NULL;
  29.138 @@ -469,7 +469,7 @@
  29.139      message* enc_msg = NULL;
  29.140      message* dec_msg = NULL;
  29.141  
  29.142 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
  29.143 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
  29.144      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  29.145      TEST_ASSERT(enc_msg);
  29.146      stringlist_t* keylist = NULL;
  29.147 @@ -494,7 +494,7 @@
  29.148      message* enc_msg = NULL;
  29.149      message* dec_msg = NULL;
  29.150  
  29.151 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
  29.152 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
  29.153      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  29.154      TEST_ASSERT(enc_msg);
  29.155      stringlist_t* keylist = NULL;
  29.156 @@ -519,7 +519,7 @@
  29.157      message* enc_msg = NULL;
  29.158      message* dec_msg = NULL;
  29.159  
  29.160 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg);
  29.161 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &enc_msg, NULL);
  29.162      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  29.163      TEST_ASSERT(enc_msg);
  29.164      stringlist_t* keylist = NULL;
    30.1 --- a/test/src/engine_tests/LeastColorGroupTests.cc	Wed Aug 07 12:10:12 2019 +0200
    30.2 +++ b/test/src/engine_tests/LeastColorGroupTests.cc	Wed Aug 07 14:08:11 2019 +0200
    30.3 @@ -69,7 +69,7 @@
    30.4      PEP_rating rating;
    30.5      PEP_decrypt_flags_t flags;
    30.6      
    30.7 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
    30.8 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
    30.9      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   30.10      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   30.11      final_ptr = msg_ptr;
    31.1 --- a/test/src/engine_tests/LeastCommonDenomColorTests.cc	Wed Aug 07 12:10:12 2019 +0200
    31.2 +++ b/test/src/engine_tests/LeastCommonDenomColorTests.cc	Wed Aug 07 14:08:11 2019 +0200
    31.3 @@ -68,7 +68,7 @@
    31.4      PEP_rating rating;
    31.5      PEP_decrypt_flags_t flags;
    31.6      
    31.7 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
    31.8 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
    31.9      TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
   31.10      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   31.11  
   31.12 @@ -117,7 +117,7 @@
   31.13      keylist = nullptr;
   31.14      rating = PEP_rating_unreliable;
   31.15  
   31.16 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   31.17 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
   31.18      TEST_ASSERT_MSG((status == PEP_STATUS_OK), tl_status_string(status));
   31.19      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   31.20      flags = 0;
    32.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.2 +++ b/test/src/engine_tests/Message2_1Tests.cc	Wed Aug 07 14:08:11 2019 +0200
    32.3 @@ -0,0 +1,579 @@
    32.4 +// This file is under GNU General Public License 3.0
    32.5 +// see LICENSE.txt
    32.6 +
    32.7 +#include <stdlib.h>
    32.8 +#include <cstring>
    32.9 +#include <string>
   32.10 +
   32.11 +#include <cpptest.h>
   32.12 +#include "test_util.h"
   32.13 +
   32.14 +#include "pEpEngine.h"
   32.15 +
   32.16 +#include "EngineTestIndividualSuite.h"
   32.17 +#include "Message2_1Tests.h"
   32.18 +
   32.19 +using namespace std;
   32.20 +
   32.21 +Message2_1Tests::Message2_1Tests(string suitename, string test_home_dir) :
   32.22 +    EngineTestIndividualSuite::EngineTestIndividualSuite(suitename, test_home_dir) {
   32.23 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("Message2_1Tests::check_message2_1_recip_2_0"),
   32.24 +                                                                      static_cast<Func>(&Message2_1Tests::check_message2_1_recip_2_0)));
   32.25 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("Message2_1Tests::check_message2_1_recip_OpenPGP"),
   32.26 +                                                                      static_cast<Func>(&Message2_1Tests::check_message2_1_recip_OpenPGP)));
   32.27 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("Message2_1Tests::check_message2_1_recip_2_1"),
   32.28 +                                                                      static_cast<Func>(&Message2_1Tests::check_message2_1_recip_2_1)));
   32.29 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("Message2_1Tests::check_message2_1_recip_1_0_from_msg_OpenPGP"),
   32.30 +                                                                      static_cast<Func>(&Message2_1Tests::check_message2_1_recip_1_0_from_msg_OpenPGP)));
   32.31 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("Message2_1Tests::check_message2_1_recip_2_0_from_msg"),
   32.32 +                                                                      static_cast<Func>(&Message2_1Tests::check_message2_1_recip_2_0_from_msg)));
   32.33 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("Message2_1Tests::check_message2_1_recip_2_1_from_msg"),
   32.34 +                                                                      static_cast<Func>(&Message2_1Tests::check_message2_1_recip_2_1_from_msg)));
   32.35 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("Message2_1Tests::check_message2_1_recip_mixed_2_0"),
   32.36 +                                                                      static_cast<Func>(&Message2_1Tests::check_message2_1_recip_mixed_2_0)));
   32.37 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("Message2_1Tests::check_message2_1_recip_mixed_1_0_OpenPGP"),
   32.38 +                                                                      static_cast<Func>(&Message2_1Tests::check_message2_1_recip_mixed_1_0_OpenPGP)));
   32.39 +}
   32.40 +
   32.41 +bool Message2_1Tests::verify_message_version_produced(message* enc_msg, unsigned int* maj_inout, unsigned int* min_inout) {
   32.42 +    if (!maj_inout || !min_inout)
   32.43 +        return false;
   32.44 +    int major = *maj_inout;
   32.45 +    int minor = *min_inout;
   32.46 +    
   32.47 +    char* ptext = NULL;
   32.48 +    size_t psize = 0;
   32.49 +    stringlist_t* keylist = NULL;
   32.50 +    
   32.51 +    PEP_STATUS status = decrypt_and_verify(session, enc_msg->attachments->next->value,
   32.52 +                                           enc_msg->attachments->next->size, NULL, 0,
   32.53 +                                           &ptext, &psize, &keylist,
   32.54 +                                           NULL);
   32.55 +
   32.56 +    cout << ptext << endl;
   32.57 +
   32.58 +    // fixme, check status
   32.59 +    if (strstr(ptext, "pEp-Wrapped-Message-Info: OUTER") != NULL && strstr(ptext, "pEp-Wrapped-Message-Info: INNER") != NULL) {
   32.60 +        *maj_inout = 2;
   32.61 +        *min_inout = 0;
   32.62 +    }
   32.63 +    else if (strstr(ptext, "X-pEp-Wrapped-Message-Info: INNER") != NULL && strstr(ptext, "forwarded=\"no\"") != NULL) {
   32.64 +        *maj_inout = 2;
   32.65 +        *min_inout = 1;
   32.66 +    }
   32.67 +    else {
   32.68 +        *maj_inout = 1;
   32.69 +        *min_inout = 0;
   32.70 +    }    
   32.71 +    
   32.72 +    switch (major) {
   32.73 +        case 1:
   32.74 +            if (*maj_inout == 1)
   32.75 +                return true;
   32.76 +            return false;    
   32.77 +        case 2:
   32.78 +            if (*maj_inout != 2)
   32.79 +                return false;
   32.80 +            if (*min_inout == minor)
   32.81 +                return true;
   32.82 +            return false;    
   32.83 +        default:
   32.84 +            *maj_inout = 0;
   32.85 +            *min_inout = 0;
   32.86 +            return false;
   32.87 +    }
   32.88 +}
   32.89 +
   32.90 +void Message2_1Tests::check_message2_1_recip_2_0() {
   32.91 +
   32.92 +    pEp_identity* alice = NULL;
   32.93 +    pEp_identity* carol = NULL;
   32.94 +    
   32.95 +    PEP_STATUS status = set_up_preset(session, ALICE, 
   32.96 +                                      true, true, true, true, true, &alice);
   32.97 +
   32.98 +    TEST_ASSERT(status == PEP_STATUS_OK);
   32.99 +    TEST_ASSERT(alice);
  32.100 +    
  32.101 +    status = set_up_preset(session, CAROL, 
  32.102 +                           false, true, false, false, false, &carol);
  32.103 +
  32.104 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.105 +    TEST_ASSERT(carol);
  32.106 +
  32.107 +    // default should be 2.0 after setting pep status
  32.108 +    status = update_identity(session, carol);
  32.109 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.110 +    TEST_ASSERT(carol->major_ver == 2);
  32.111 +    TEST_ASSERT(carol->minor_ver == 0);
  32.112 +    // generate message
  32.113 +    pEp_identity* carol_to = new_identity(carol->address, NULL, NULL, NULL);
  32.114 +    
  32.115 +    message* msg = new_message(PEP_dir_outgoing);
  32.116 +    
  32.117 +    msg->from = alice;
  32.118 +    msg->to = new_identity_list(carol_to);
  32.119 +    msg->shortmsg = strdup("Boom shaka laka");
  32.120 +    msg->longmsg = strdup("Don't you get sick of these?");
  32.121 +    
  32.122 +    message* enc_msg = NULL;
  32.123 +
  32.124 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
  32.125 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.126 +    
  32.127 +    // ensure sent message is in 2.0 format
  32.128 +    unsigned int major = 2;
  32.129 +    unsigned int minor = 0;
  32.130 +    TEST_ASSERT_MSG(verify_message_version_produced(enc_msg, &major, &minor),
  32.131 +                                                    (to_string(major) + "." + to_string(minor)).c_str());
  32.132 +    
  32.133 +    free_identity(carol);
  32.134 +    free_message(msg);
  32.135 +    free_message(enc_msg);
  32.136 +}
  32.137 +
  32.138 +/* PEP_STATUS set_up_preset(PEP_SESSION session,
  32.139 +                         pEp_test_ident_preset preset_name,
  32.140 +                         bool set_ident, 
  32.141 +                         bool set_pep,
  32.142 +                         bool trust,
  32.143 +                         bool set_own, 
  32.144 +                         bool setup_private, 
  32.145 +                         pEp_identity** ident) {
  32.146 +*/
  32.147 +
  32.148 +void Message2_1Tests::check_message2_1_recip_OpenPGP() {
  32.149 +    // set recip to 1.0
  32.150 +    pEp_identity* alice = NULL;
  32.151 +    pEp_identity* carol = NULL;
  32.152 +    
  32.153 +    PEP_STATUS status = set_up_preset(session, ALICE, 
  32.154 +                                      true, true, true, true, true, &alice);
  32.155 +
  32.156 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.157 +    TEST_ASSERT(alice);
  32.158 +    
  32.159 +    status = set_up_preset(session, CAROL, 
  32.160 +                           false, false, false, false, false, &carol);
  32.161 +
  32.162 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.163 +    TEST_ASSERT(carol);
  32.164 +
  32.165 +    status = update_identity(session, carol);
  32.166 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.167 +    TEST_ASSERT(carol->major_ver < 2);
  32.168 +    TEST_ASSERT(carol->minor_ver == 0);
  32.169 +
  32.170 +    // generate message
  32.171 +    pEp_identity* carol_to = new_identity(carol->address, NULL, NULL, NULL);
  32.172 +    
  32.173 +    message* msg = new_message(PEP_dir_outgoing);
  32.174 +    
  32.175 +    msg->from = alice;
  32.176 +    msg->to = new_identity_list(carol_to);
  32.177 +    msg->shortmsg = strdup("Boom shaka laka");
  32.178 +    msg->longmsg = strdup("Don't you get sick of these?");
  32.179 +    
  32.180 +    message* enc_msg = NULL;
  32.181 +
  32.182 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
  32.183 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.184 +    
  32.185 +    // ensure sent message is in 1.0 format
  32.186 +    unsigned int major = 1;
  32.187 +    unsigned int minor = 0;
  32.188 +    TEST_ASSERT_MSG(verify_message_version_produced(enc_msg, &major, &minor),
  32.189 +                                                    (to_string(major) + "." + to_string(minor)).c_str());
  32.190 +    
  32.191 +    free_identity(carol);
  32.192 +    free_message(msg);
  32.193 +    free_message(enc_msg);
  32.194 +}
  32.195 +
  32.196 +void Message2_1Tests::check_message2_1_recip_2_1() {
  32.197 +    // set recip to 2.1
  32.198 +    
  32.199 +    pEp_identity* alice = NULL;
  32.200 +    pEp_identity* carol = NULL;
  32.201 +    
  32.202 +    PEP_STATUS status = set_up_preset(session, ALICE, 
  32.203 +                                      true, true, true, true, true, &alice);
  32.204 +
  32.205 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.206 +    TEST_ASSERT(alice);
  32.207 +    
  32.208 +    status = set_up_preset(session, CAROL, 
  32.209 +                           true, true, false, false, false, &carol);
  32.210 +
  32.211 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.212 +    TEST_ASSERT(carol);
  32.213 +
  32.214 +    status = set_pEp_version(session, carol, 2, 1);
  32.215 +    
  32.216 +    // default should be 2.1 after setting pep status
  32.217 +    status = update_identity(session, carol);
  32.218 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.219 +    TEST_ASSERT(carol->major_ver == 2);
  32.220 +    TEST_ASSERT(carol->minor_ver == 1);
  32.221 +    // generate message
  32.222 +    pEp_identity* carol_to = new_identity(carol->address, NULL, NULL, NULL);
  32.223 +    
  32.224 +    message* msg = new_message(PEP_dir_outgoing);
  32.225 +    
  32.226 +    msg->from = alice;
  32.227 +    msg->to = new_identity_list(carol_to);
  32.228 +    msg->shortmsg = strdup("Boom shaka laka");
  32.229 +    msg->longmsg = strdup("Don't you get sick of these?");
  32.230 +    
  32.231 +    message* enc_msg = NULL;
  32.232 +
  32.233 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
  32.234 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.235 +    
  32.236 +    // ensure sent message is in 2.0 format
  32.237 +    unsigned int major = 2;
  32.238 +    unsigned int minor = 1;
  32.239 +    TEST_ASSERT_MSG(verify_message_version_produced(enc_msg, &major, &minor),
  32.240 +                                                    (to_string(major) + "." + to_string(minor)).c_str());
  32.241 +    
  32.242 +    free_identity(carol);
  32.243 +    free_message(msg);
  32.244 +    free_message(enc_msg);
  32.245 +    TEST_ASSERT(true);
  32.246 +}
  32.247 +
  32.248 +void Message2_1Tests::check_message2_1_recip_1_0_from_msg_OpenPGP() {
  32.249 +    pEp_identity* alex = NULL;
  32.250 +    
  32.251 +    PEP_STATUS status = set_up_preset(session, ALEX_0, 
  32.252 +                                      true, true, true, true, true, &alex);
  32.253 +
  32.254 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.255 +    TEST_ASSERT(alex);
  32.256 +
  32.257 +    // receive 1.0 message from OpenPGP
  32.258 +    string incoming = slurp("test_mails/From_M1_0.eml");
  32.259 +    
  32.260 +    char* dec_msg;
  32.261 +    char* mod_src = NULL;
  32.262 +    PEP_decrypt_flags_t flags = 0;
  32.263 +    stringlist_t* keylist_used = NULL;
  32.264 +    PEP_rating rating;
  32.265 +    
  32.266 +    status = MIME_decrypt_message(session, incoming.c_str(), incoming.size(), &dec_msg, &keylist_used, &rating, &flags, &mod_src);
  32.267 +
  32.268 +    TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  32.269 +    // generate message
  32.270 +    
  32.271 +    message* msg = new_message(PEP_dir_outgoing);
  32.272 +    
  32.273 +    msg->from = alex;
  32.274 +    msg->to = new_identity_list(new_identity("pep-test-carol@pep-project.org", NULL, NULL, NULL));
  32.275 +    msg->shortmsg = strdup("Boom shaka laka");
  32.276 +    msg->longmsg = strdup("Don't you get sick of these?");
  32.277 +    
  32.278 +    message* enc_msg = NULL;
  32.279 +
  32.280 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
  32.281 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.282 +    
  32.283 +    // ensure sent message is in 1.0 format
  32.284 +    unsigned int major = 1;
  32.285 +    unsigned int minor = 0;
  32.286 +    TEST_ASSERT_MSG(verify_message_version_produced(enc_msg, &major, &minor),
  32.287 +                                                    (to_string(major) + "." + to_string(minor)).c_str());
  32.288 +    
  32.289 +    free_message(msg);
  32.290 +    free_message(enc_msg);
  32.291 +    free(dec_msg);
  32.292 +    free(mod_src);
  32.293 +    TEST_ASSERT(true);
  32.294 +}
  32.295 +
  32.296 +void Message2_1Tests::check_message2_1_recip_2_0_from_msg() {
  32.297 +    // receive 2.0 message
  32.298 +    pEp_identity* carol = NULL;
  32.299 +    
  32.300 +    PEP_STATUS status = set_up_preset(session, CAROL, 
  32.301 +                                      true, true, true, true, true, &carol);
  32.302 +
  32.303 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.304 +    TEST_ASSERT(carol);
  32.305 +
  32.306 +    // receive 1.0 message from OpenPGP
  32.307 +    string incoming = slurp("test_mails/2_0_msg.eml");
  32.308 +    
  32.309 +    char* dec_msg;
  32.310 +    char* mod_src = NULL;
  32.311 +    PEP_decrypt_flags_t flags = 0;
  32.312 +    stringlist_t* keylist_used = NULL;
  32.313 +    PEP_rating rating;
  32.314 +    
  32.315 +    status = MIME_decrypt_message(session, incoming.c_str(), incoming.size(), &dec_msg, &keylist_used, &rating, &flags, &mod_src);
  32.316 +
  32.317 +    TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  32.318 +    // generate message
  32.319 +    
  32.320 +    message* msg = new_message(PEP_dir_outgoing);
  32.321 +    
  32.322 +    msg->from = carol;
  32.323 +    msg->to = new_identity_list(new_identity("pep.test.alice@pep-project.org", NULL, NULL, NULL));
  32.324 +    msg->shortmsg = strdup("Boom shaka laka");
  32.325 +    msg->longmsg = strdup("Don't you get sick of these?");
  32.326 +    
  32.327 +    message* enc_msg = NULL;
  32.328 +
  32.329 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
  32.330 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.331 +    
  32.332 +    // ensure sent message is in 1.0 format
  32.333 +    unsigned int major = 2;
  32.334 +    unsigned int minor = 0;
  32.335 +    TEST_ASSERT_MSG(verify_message_version_produced(enc_msg, &major, &minor),
  32.336 +                                                    (to_string(major) + "." + to_string(minor)).c_str());
  32.337 +    
  32.338 +    free_message(msg);
  32.339 +    free_message(enc_msg);
  32.340 +    free(dec_msg);
  32.341 +    free(mod_src);
  32.342 +}
  32.343 +
  32.344 +void Message2_1Tests::check_message2_1_recip_2_1_from_msg() {
  32.345 +    // receive 2.1 message
  32.346 +    pEp_identity* carol = NULL;
  32.347 +    
  32.348 +    PEP_STATUS status = set_up_preset(session, CAROL, 
  32.349 +                                      true, true, true, true, true, &carol);
  32.350 +
  32.351 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.352 +    TEST_ASSERT(carol);
  32.353 +
  32.354 +    // receive 1.0 message from OpenPGP
  32.355 +    string incoming = slurp("test_mails/From_M2_1.eml");
  32.356 +    
  32.357 +    char* dec_msg;
  32.358 +    char* mod_src = NULL;
  32.359 +    PEP_decrypt_flags_t flags = 0;
  32.360 +    stringlist_t* keylist_used = NULL;
  32.361 +    PEP_rating rating;
  32.362 +    
  32.363 +    status = MIME_decrypt_message(session, incoming.c_str(), incoming.size(), &dec_msg, &keylist_used, &rating, &flags, &mod_src);
  32.364 +
  32.365 +    TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
  32.366 +    // generate message
  32.367 +    
  32.368 +    message* msg = new_message(PEP_dir_outgoing);
  32.369 +    
  32.370 +    msg->from = carol;
  32.371 +    msg->to = new_identity_list(new_identity("pep.test.alice@pep-project.org", NULL, NULL, NULL));
  32.372 +    msg->shortmsg = strdup("Boom shaka laka");
  32.373 +    msg->longmsg = strdup("Don't you get sick of these?");
  32.374 +    
  32.375 +    message* enc_msg = NULL;
  32.376 +
  32.377 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
  32.378 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.379 +    
  32.380 +    // ensure sent message is in 2.1 format
  32.381 +    unsigned int major = 2;
  32.382 +    unsigned int minor = 1;
  32.383 +    TEST_ASSERT_MSG(verify_message_version_produced(enc_msg, &major, &minor),
  32.384 +                                                    (to_string(major) + "." + to_string(minor)).c_str());
  32.385 +    
  32.386 +    free_message(msg);
  32.387 +    free_message(enc_msg);
  32.388 +    free(dec_msg);
  32.389 +    free(mod_src);
  32.390 +}
  32.391 +
  32.392 +void Message2_1Tests::check_message2_1_recip_mixed_2_0() {
  32.393 +    // Set mixed recipient values
  32.394 +    pEp_identity* alice = NULL;
  32.395 +    pEp_identity* bob = NULL;
  32.396 +    pEp_identity* carol = NULL;
  32.397 +    pEp_identity* dave = NULL;
  32.398 +    pEp_identity* alex = NULL;
  32.399 +
  32.400 +    PEP_STATUS status = set_up_preset(session, ALICE, 
  32.401 +                                      true, true, true, true, true, &alice);
  32.402 +
  32.403 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.404 +    TEST_ASSERT(alice);
  32.405 +
  32.406 +    status = set_up_preset(session, BOB, 
  32.407 +                           true, true, false, false, false, &bob);
  32.408 +
  32.409 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.410 +    TEST_ASSERT(bob);
  32.411 +
  32.412 +    status = set_pEp_version(session, bob, 2, 1);
  32.413 +
  32.414 +    // default should be 2.1 after setting pep status
  32.415 +    status = update_identity(session, bob);
  32.416 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.417 +    TEST_ASSERT(bob->major_ver == 2);
  32.418 +    TEST_ASSERT(bob->minor_ver == 1);
  32.419 +    
  32.420 +    status = set_up_preset(session, CAROL, 
  32.421 +                           true, true, false, false, false, &carol);
  32.422 +
  32.423 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.424 +    TEST_ASSERT(carol);
  32.425 +
  32.426 +    status = set_pEp_version(session, carol, 2, 1);
  32.427 +
  32.428 +    // default should be 2.1 after setting pep status
  32.429 +    status = update_identity(session, carol);
  32.430 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.431 +    TEST_ASSERT(carol->major_ver == 2);
  32.432 +    TEST_ASSERT(carol->minor_ver == 1);
  32.433 +    
  32.434 +    status = set_up_preset(session, DAVE, 
  32.435 +                           true, true, false, false, false, &dave);
  32.436 +
  32.437 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.438 +    TEST_ASSERT(dave);
  32.439 +
  32.440 +    status = set_pEp_version(session, dave, 2, 0);
  32.441 +
  32.442 +    // default should be 2.1 after setting pep status
  32.443 +    status = update_identity(session, dave);
  32.444 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.445 +    TEST_ASSERT(dave->major_ver == 2);
  32.446 +    TEST_ASSERT(dave->minor_ver == 0);
  32.447 +
  32.448 +    status = set_up_preset(session, ALEX, 
  32.449 +                           true, true, true, false, false, &alex);
  32.450 +
  32.451 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.452 +    TEST_ASSERT(alex);
  32.453 +
  32.454 +    status = set_pEp_version(session, alex, 2, 1);
  32.455 +
  32.456 +    // default should be 2.1 after setting pep status
  32.457 +    status = update_identity(session, alex);
  32.458 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.459 +    TEST_ASSERT(alex->major_ver == 2);
  32.460 +    TEST_ASSERT(alex->minor_ver == 1);
  32.461 +
  32.462 +    // generate message
  32.463 +    message* msg = new_message(PEP_dir_outgoing);
  32.464 +    
  32.465 +    msg->from = alice;
  32.466 +    msg->to = new_identity_list(new_identity(bob->address, NULL, NULL, NULL));
  32.467 +    identity_list_add(msg->to, new_identity(carol->address, NULL, NULL, NULL));
  32.468 +    identity_list_add(msg->to, new_identity(dave->address, NULL, NULL, NULL));
  32.469 +    identity_list_add(msg->to, new_identity(alex->address, NULL, NULL, NULL));    
  32.470 +    msg->shortmsg = strdup("Boom shaka laka");
  32.471 +    msg->longmsg = strdup("Don't you get sick of these?");
  32.472 +    
  32.473 +    message* enc_msg = NULL;
  32.474 +
  32.475 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
  32.476 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.477 +    
  32.478 +    // ensure sent message is in 2.0 format
  32.479 +    unsigned int major = 2;
  32.480 +    unsigned int minor = 0;
  32.481 +    TEST_ASSERT_MSG(verify_message_version_produced(enc_msg, &major, &minor),
  32.482 +                                                    (to_string(major) + "." + to_string(minor)).c_str());
  32.483 +    
  32.484 +    free_message(msg);
  32.485 +    free_message(enc_msg);
  32.486 +}
  32.487 +
  32.488 +void Message2_1Tests::check_message2_1_recip_mixed_1_0_OpenPGP() {
  32.489 +    // Set mixed recipient values
  32.490 +    pEp_identity* alice = NULL;
  32.491 +    pEp_identity* bob = NULL;
  32.492 +    pEp_identity* carol = NULL;
  32.493 +    pEp_identity* dave = NULL;
  32.494 +    pEp_identity* alex = NULL;
  32.495 +
  32.496 +    PEP_STATUS status = set_up_preset(session, ALICE, 
  32.497 +                                      true, true, true, true, true, &alice);
  32.498 +
  32.499 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.500 +    TEST_ASSERT(alice);
  32.501 +
  32.502 +    status = set_up_preset(session, BOB, 
  32.503 +                           true, true, false, false, false, &bob);
  32.504 +
  32.505 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.506 +    TEST_ASSERT(bob);
  32.507 +
  32.508 +    status = set_pEp_version(session, bob, 2, 1);
  32.509 +
  32.510 +    // default should be 2.1 after setting pep status
  32.511 +    status = update_identity(session, bob);
  32.512 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.513 +    TEST_ASSERT(bob->major_ver == 2);
  32.514 +    TEST_ASSERT(bob->minor_ver == 1);
  32.515 +    
  32.516 +    status = set_up_preset(session, CAROL, 
  32.517 +                           true, true, false, false, false, &carol);
  32.518 +
  32.519 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.520 +    TEST_ASSERT(carol);
  32.521 +
  32.522 +    status = set_pEp_version(session, carol, 2, 1);
  32.523 +
  32.524 +    // default should be 2.1 after setting pep status
  32.525 +    status = update_identity(session, carol);
  32.526 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.527 +    TEST_ASSERT(carol->major_ver == 2);
  32.528 +    TEST_ASSERT(carol->minor_ver == 1);
  32.529 +    
  32.530 +    status = set_up_preset(session, DAVE, 
  32.531 +                           true, true, false, false, false, &dave);
  32.532 +
  32.533 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.534 +    TEST_ASSERT(dave);
  32.535 +
  32.536 +    status = set_pEp_version(session, dave, 2, 0);
  32.537 +
  32.538 +    // default should be 2.1 after setting pep status
  32.539 +    status = update_identity(session, dave);
  32.540 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.541 +    TEST_ASSERT(dave->major_ver == 2);
  32.542 +    TEST_ASSERT(dave->minor_ver == 0);
  32.543 +
  32.544 +    status = set_up_preset(session, ALEX, 
  32.545 +                           true, false, true, false, false, &alex);
  32.546 +
  32.547 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.548 +    TEST_ASSERT(alex);
  32.549 +
  32.550 +    status = set_pEp_version(session, alex, 1, 0);
  32.551 +
  32.552 +    // default should be 1.0 after setting pep status
  32.553 +    status = update_identity(session, alex);
  32.554 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.555 +    TEST_ASSERT(alex->major_ver == 1);
  32.556 +    TEST_ASSERT(alex->minor_ver == 0);
  32.557 +
  32.558 +    // generate message
  32.559 +    message* msg = new_message(PEP_dir_outgoing);
  32.560 +    
  32.561 +    msg->from = alice;
  32.562 +    msg->to = new_identity_list(new_identity(bob->address, NULL, NULL, NULL));
  32.563 +    identity_list_add(msg->to, new_identity(carol->address, NULL, NULL, NULL));
  32.564 +    identity_list_add(msg->to, new_identity(dave->address, NULL, NULL, NULL));
  32.565 +    identity_list_add(msg->to, new_identity(alex->address, NULL, NULL, NULL));    
  32.566 +    msg->shortmsg = strdup("Boom shaka laka");
  32.567 +    msg->longmsg = strdup("Don't you get sick of these?");
  32.568 +    
  32.569 +    message* enc_msg = NULL;
  32.570 +
  32.571 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
  32.572 +    TEST_ASSERT(status == PEP_STATUS_OK);
  32.573 +    
  32.574 +    // ensure sent message is in 2.0 format
  32.575 +    unsigned int major = 1;
  32.576 +    unsigned int minor = 0;
  32.577 +    TEST_ASSERT_MSG(verify_message_version_produced(enc_msg, &major, &minor),
  32.578 +                                                    (to_string(major) + "." + to_string(minor)).c_str());
  32.579 +    
  32.580 +    free_message(msg);
  32.581 +    free_message(enc_msg);
  32.582 +}
    33.1 --- a/test/src/engine_tests/MessageApiTests.cc	Wed Aug 07 12:10:12 2019 +0200
    33.2 +++ b/test/src/engine_tests/MessageApiTests.cc	Wed Aug 07 14:08:11 2019 +0200
    33.3 @@ -81,7 +81,7 @@
    33.4      cout << text2 << "\n";
    33.5  
    33.6      message *msg3 = nullptr;
    33.7 -    PEP_STATUS status3 = mime_decode_message(text2, strlen(text2), &msg3);
    33.8 +    PEP_STATUS status3 = mime_decode_message(text2, strlen(text2), &msg3, NULL);
    33.9      TEST_ASSERT_MSG((status3 == PEP_STATUS_OK), "status3 == PEP_STATUS_OK");
   33.10      const string string3 = text2;
   33.11      //free(text2);
   33.12 @@ -133,7 +133,7 @@
   33.13      inFile3.close();
   33.14  
   33.15      message *msg5 = nullptr;
   33.16 -    PEP_STATUS status5 = mime_decode_message(text3.c_str(), text3.length(), &msg5);
   33.17 +    PEP_STATUS status5 = mime_decode_message(text3.c_str(), text3.length(), &msg5, NULL);
   33.18      TEST_ASSERT_MSG((status5 == PEP_STATUS_OK), "status5 == PEP_STATUS_OK");
   33.19  
   33.20      message *msg6 = nullptr;
    34.1 --- a/test/src/engine_tests/MessageTwoPointOhTests.cc	Wed Aug 07 12:10:12 2019 +0200
    34.2 +++ b/test/src/engine_tests/MessageTwoPointOhTests.cc	Wed Aug 07 14:08:11 2019 +0200
    34.3 @@ -121,7 +121,7 @@
    34.4  //    cout << decrypted_text << endl;
    34.5      
    34.6      message* decoded_msg = nullptr;
    34.7 -    status = mime_decode_message(encoded_text, strlen(encoded_text), &decoded_msg);
    34.8 +    status = mime_decode_message(encoded_text, strlen(encoded_text), &decoded_msg, NULL);
    34.9      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   34.10      const string string3 = encoded_text;
   34.11        
   34.12 @@ -155,7 +155,7 @@
   34.13      }
   34.14       
   34.15      decrypted_msg->enc_format = PEP_enc_none; 
   34.16 -    status = _mime_encode_message_internal(decrypted_msg, false, &encoded_text, false);
   34.17 +    status = _mime_encode_message_internal(decrypted_msg, false, &encoded_text, false, false);
   34.18      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   34.19      TEST_ASSERT_MSG((encoded_text), "encoded_text");
   34.20      cout << "Decrypted message: " << endl;
    35.1 --- a/test/src/engine_tests/MimeTests.cc	Wed Aug 07 12:10:12 2019 +0200
    35.2 +++ b/test/src/engine_tests/MimeTests.cc	Wed Aug 07 14:08:11 2019 +0200
    35.3 @@ -44,7 +44,7 @@
    35.4  
    35.5      cout << "decoding message…\n";
    35.6      message *msg3;
    35.7 -    PEP_STATUS status3 = mime_decode_message(mimetext3.c_str(), mimetext3.length(), &msg3);
    35.8 +    PEP_STATUS status3 = mime_decode_message(mimetext3.c_str(), mimetext3.length(), &msg3, NULL);
    35.9      assert(status3 == PEP_STATUS_OK);
   35.10      assert(msg3);
   35.11      cout << "decoded.\n\n";
    36.1 --- a/test/src/engine_tests/PepSubjectReceivedTests.cc	Wed Aug 07 12:10:12 2019 +0200
    36.2 +++ b/test/src/engine_tests/PepSubjectReceivedTests.cc	Wed Aug 07 14:08:11 2019 +0200
    36.3 @@ -61,7 +61,7 @@
    36.4      PEP_rating rating;
    36.5      PEP_decrypt_flags_t flags;
    36.6      
    36.7 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
    36.8 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
    36.9      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   36.10      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   36.11      final_ptr = msg_ptr;
   36.12 @@ -95,7 +95,7 @@
   36.13      keylist = nullptr;
   36.14      rating = PEP_rating_unreliable;
   36.15      
   36.16 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   36.17 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
   36.18      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   36.19      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   36.20      final_ptr = msg_ptr;
   36.21 @@ -129,7 +129,7 @@
   36.22      
   36.23      mailtext = slurp("test_mails/pEp_subject_normal_signed_2a.eml");
   36.24      
   36.25 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   36.26 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
   36.27      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   36.28      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   36.29      final_ptr = msg_ptr;
   36.30 @@ -162,7 +162,7 @@
   36.31      
   36.32      mailtext = slurp("test_mails/p3p_subject_normal_signed_2b.eml");
   36.33      
   36.34 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   36.35 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
   36.36      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   36.37      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   36.38      final_ptr = msg_ptr;
   36.39 @@ -196,7 +196,7 @@
   36.40      
   36.41      mailtext = slurp("test_mails/pEp_encrypted_subject_IS_pEp_3a.eml");
   36.42      
   36.43 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   36.44 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
   36.45      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   36.46      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   36.47      final_ptr = msg_ptr;
   36.48 @@ -230,7 +230,7 @@
   36.49      
   36.50      mailtext = slurp("test_mails/p3p_encrypted_subject_IS_pEp_3b.eml");
   36.51      
   36.52 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   36.53 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
   36.54      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   36.55      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   36.56      final_ptr = msg_ptr;
   36.57 @@ -265,7 +265,7 @@
   36.58      
   36.59      mailtext = slurp("test_mails/pEp_subject_pEp_replaced_w_pEp_4a.eml");
   36.60      
   36.61 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   36.62 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
   36.63      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   36.64      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   36.65      final_ptr = msg_ptr;
   36.66 @@ -299,7 +299,7 @@
   36.67      
   36.68      mailtext = slurp("test_mails/pEp_subject_pEp_replaced_w_p3p_4b.eml");
   36.69      
   36.70 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   36.71 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
   36.72      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   36.73      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   36.74      final_ptr = msg_ptr;
   36.75 @@ -333,7 +333,7 @@
   36.76      
   36.77      mailtext = slurp("test_mails/pEp_subject_p3p_replaced_w_pEp_4c.eml");
   36.78      
   36.79 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   36.80 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
   36.81      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   36.82      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   36.83      final_ptr = msg_ptr;
   36.84 @@ -367,7 +367,7 @@
   36.85      
   36.86      mailtext = slurp("test_mails/pEp_subject_p3p_replaced_w_p3p_4d.eml");
   36.87      
   36.88 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   36.89 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
   36.90      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
   36.91      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
   36.92      final_ptr = msg_ptr;
   36.93 @@ -402,7 +402,7 @@
   36.94      
   36.95      mailtext = slurp("test_mails/pEp_unencrypted_pEp_subject_5a.eml");
   36.96      
   36.97 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
   36.98 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
   36.99      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  36.100      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
  36.101      final_ptr = msg_ptr;
  36.102 @@ -437,7 +437,7 @@
  36.103      
  36.104      mailtext = slurp("test_mails/pEp_unencrypted_p3p_subject_5b.eml");
  36.105      
  36.106 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
  36.107 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
  36.108      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  36.109      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
  36.110      final_ptr = msg_ptr;
  36.111 @@ -471,7 +471,7 @@
  36.112      
  36.113      mailtext = slurp("test_mails/pEp_subject_normal_unencrypted_6.eml");
  36.114      
  36.115 -    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr);
  36.116 +    status = mime_decode_message(mailtext.c_str(), mailtext.length(), &msg_ptr, NULL);
  36.117      TEST_ASSERT_MSG((status == PEP_STATUS_OK), "status == PEP_STATUS_OK");
  36.118      TEST_ASSERT_MSG((msg_ptr), "msg_ptr");
  36.119      final_ptr = msg_ptr;
    37.1 --- a/test/src/engine_tests/ReencryptPlusExtraKeysTests.cc	Wed Aug 07 12:10:12 2019 +0200
    37.2 +++ b/test/src/engine_tests/ReencryptPlusExtraKeysTests.cc	Wed Aug 07 14:08:11 2019 +0200
    37.3 @@ -173,9 +173,8 @@
    37.4      
    37.5      int i = 0;
    37.6      
    37.7 -    if (keys->next)
    37.8 -    dedup_stringlist(keys->next);
    37.9 -;
   37.10 +    if (keys && keys->next)
   37.11 +        dedup_stringlist(keys->next);
   37.12      
   37.13      for (stringlist_t* kl = keys; kl && kl->value; kl = kl->next, i++)
   37.14      {
    38.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.2 +++ b/test/src/engine_tests/SenderFPRTests.cc	Wed Aug 07 14:08:11 2019 +0200
    38.3 @@ -0,0 +1,79 @@
    38.4 +// This file is under GNU General Public License 3.0
    38.5 +// see LICENSE.txt
    38.6 +
    38.7 +#include <stdlib.h>
    38.8 +#include <cstring>
    38.9 +#include <string>
   38.10 +
   38.11 +#include <cpptest.h>
   38.12 +#include "test_util.h"
   38.13 +
   38.14 +#include "pEpEngine.h"
   38.15 +#include "mime.h"
   38.16 +
   38.17 +#include "EngineTestIndividualSuite.h"
   38.18 +#include "SenderFPRTests.h"
   38.19 +
   38.20 +using namespace std;
   38.21 +
   38.22 +SenderFPRTests::SenderFPRTests(string suitename, string test_home_dir) :
   38.23 +    EngineTestIndividualSuite::EngineTestIndividualSuite(suitename, test_home_dir) {
   38.24 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("SenderFPRTests::check_sender_f_p_r"),
   38.25 +                                                                      static_cast<Func>(&SenderFPRTests::check_sender_f_p_r)));
   38.26 +}
   38.27 +
   38.28 +void SenderFPRTests::check_sender_f_p_r() {
   38.29 +    const char* alice_fpr = "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97";
   38.30 +    const char* bob_fpr = "BFCDB7F301DEEEBBF947F29659BFF488C9C2EE39";
   38.31 +    PEP_STATUS status = read_file_and_import_key(session,
   38.32 +                "test_keys/pub/pep-test-alice-0x6FF00E97_pub.asc");
   38.33 +    TEST_ASSERT(status == PEP_KEY_IMPORTED);
   38.34 +    status = set_up_ident_from_scratch(session,
   38.35 +                "test_keys/priv/pep-test-alice-0x6FF00E97_priv.asc",
   38.36 +                "pep.test.alice@pep-project.org", alice_fpr,
   38.37 +                PEP_OWN_USERID, "Alice in Wonderland", NULL, true
   38.38 +            );
   38.39 +    TEST_ASSERT(status == PEP_STATUS_OK);
   38.40 +    TEST_ASSERT_MSG(slurp_and_import_key(session, "test_keys/pub/pep-test-bob-0xC9C2EE39_pub.asc"),
   38.41 +                    "Unable to import test_keys/pub/pep-test-bob-0xC9C2EE39_pub.asc");
   38.42 +                    
   38.43 +
   38.44 +    message* msg = new_message(PEP_dir_outgoing);
   38.45 +    pEp_identity* alice = new_identity("pep.test.alice@pep-project.org", NULL, PEP_OWN_USERID, NULL);                
   38.46 +    pEp_identity* bob = new_identity("pep.test.bob@pep-project.org", NULL, "Bob", NULL);
   38.47 +    status = myself(session, alice);
   38.48 +    TEST_ASSERT(status == PEP_STATUS_OK);
   38.49 +    status = update_identity(session, bob);
   38.50 +    TEST_ASSERT(status == PEP_STATUS_OK);
   38.51 +    
   38.52 +    status = set_as_pEp_user(session, bob);
   38.53 +    TEST_ASSERT(status == PEP_STATUS_OK);
   38.54 +
   38.55 +    msg->to = new_identity_list(bob);
   38.56 +    msg->from = alice;
   38.57 +    msg->shortmsg = strdup("Yo Bob!");
   38.58 +    msg->longmsg = strdup("Look at my hot new sender fpr field!");
   38.59 +
   38.60 +    message* enc_msg = NULL;
   38.61 +    
   38.62 +    status = encrypt_message(session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
   38.63 +    TEST_ASSERT(status == PEP_STATUS_OK);
   38.64 +    TEST_ASSERT(stringpair_list_find(enc_msg->opt_fields, "X-pEp-Sender-FPR") == NULL);
   38.65 +    
   38.66 +    message* dec_msg = NULL;
   38.67 +
   38.68 +    stringlist_t* keylist = NULL;
   38.69 +    PEP_rating rating;
   38.70 +    PEP_decrypt_flags_t flags = 0;
   38.71 +    status = decrypt_message(session, enc_msg, &dec_msg, &keylist, &rating, &flags);
   38.72 +    TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   38.73 +
   38.74 +    char* text = NULL;
   38.75 +    mime_encode_message(dec_msg, false, &text);
   38.76 +    cout << text << endl;
   38.77 +    free(text);
   38.78 +    
   38.79 +    stringpair_list_t* fpr_node = stringpair_list_find(dec_msg->opt_fields, "X-pEp-Sender-FPR");
   38.80 +    TEST_ASSERT(fpr_node);
   38.81 +    TEST_ASSERT(strcmp(fpr_node->value->value, alice_fpr) == 0);
   38.82 +}
    39.1 --- a/test/src/engine_tests/SimpleBodyNotAltTests.cc	Wed Aug 07 12:10:12 2019 +0200
    39.2 +++ b/test/src/engine_tests/SimpleBodyNotAltTests.cc	Wed Aug 07 14:08:11 2019 +0200
    39.3 @@ -29,7 +29,7 @@
    39.4      string msg = slurp("test_mails/text message with html attach.eml");
    39.5      message* parsed = NULL;
    39.6  
    39.7 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &parsed);
    39.8 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &parsed, NULL);
    39.9      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   39.10      TEST_ASSERT(parsed);
   39.11      TEST_ASSERT(parsed->longmsg);
   39.12 @@ -47,7 +47,7 @@
   39.13      string msg = slurp("test_mails/HTML-only body w text attachment.eml");
   39.14      message* parsed = NULL;
   39.15  
   39.16 -    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &parsed);
   39.17 +    PEP_STATUS status = mime_decode_message(msg.c_str(), msg.size(), &parsed, NULL);
   39.18      TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   39.19      TEST_ASSERT(parsed);
   39.20      TEST_ASSERT(parsed->longmsg == NULL);
    40.1 --- a/test/src/util/test_util.cc	Wed Aug 07 12:10:12 2019 +0200
    40.2 +++ b/test/src/util/test_util.cc	Wed Aug 07 14:08:11 2019 +0200
    40.3 @@ -6,6 +6,7 @@
    40.4  #include "TestConstants.h"
    40.5  #include "mime.h"
    40.6  #include "message_api.h"
    40.7 +#include "keymanagement.h"
    40.8  
    40.9  #include <fstream>
   40.10  #include <sstream>
   40.11 @@ -17,6 +18,8 @@
   40.12  #include <unistd.h>
   40.13  #include <ftw.h>
   40.14  
   40.15 +using namespace std;
   40.16 +
   40.17  PEP_STATUS read_file_and_import_key(PEP_SESSION session, const char* fname) {
   40.18      const std::string key = slurp(fname);
   40.19      PEP_STATUS status = (key.empty() ? PEP_KEY_NOT_FOUND : PEP_STATUS_OK);
   40.20 @@ -184,6 +187,8 @@
   40.21              return "PEP_CANNOT_SET_PERSON";
   40.22          case PEP_CANNOT_SET_PGP_KEYPAIR:
   40.23              return "PEP_CANNOT_SET_PGP_KEYPAIR";
   40.24 +        case PEP_CANNOT_SET_PEP_VERSION:
   40.25 +            return "PEP_CANNOT_SET_PEP_VERSION";
   40.26          case PEP_CANNOT_SET_IDENTITY:
   40.27              return "PEP_CANNOT_SET_IDENTITY";
   40.28          case PEP_CANNOT_SET_TRUST:
   40.29 @@ -495,7 +500,7 @@
   40.30      message* dec_msg = NULL;
   40.31      *mime_plaintext = NULL;
   40.32  
   40.33 -    status = mime_decode_message(mimetext, size, &tmp_msg);
   40.34 +    status = mime_decode_message(mimetext, size, &tmp_msg, NULL);
   40.35      if (status != PEP_STATUS_OK)
   40.36          goto pEp_error;
   40.37  
   40.38 @@ -542,7 +547,7 @@
   40.39      }
   40.40  
   40.41      if (*flags & PEP_decrypt_flag_src_modified) {
   40.42 -        _mime_encode_message_internal(tmp_msg, false, modified_src, true);
   40.43 +        _mime_encode_message_internal(tmp_msg, false, modified_src, true, false);
   40.44          if (!modified_src) {
   40.45              *flags &= (~PEP_decrypt_flag_src_modified);
   40.46              decrypt_status = PEP_CANNOT_REENCRYPT; // Because we couldn't return it, I guess.
   40.47 @@ -550,7 +555,7 @@
   40.48      }
   40.49  
   40.50      // FIXME: test with att
   40.51 -    status = _mime_encode_message_internal(dec_msg, false, mime_plaintext, true);
   40.52 +    status = _mime_encode_message_internal(dec_msg, false, mime_plaintext, true, false);
   40.53  
   40.54      if (status == PEP_STATUS_OK)
   40.55      {
   40.56 @@ -580,7 +585,7 @@
   40.57      message* tmp_msg = NULL;
   40.58      message* enc_msg = NULL;
   40.59  
   40.60 -    status = mime_decode_message(mimetext, size, &tmp_msg);
   40.61 +    status = mime_decode_message(mimetext, size, &tmp_msg, NULL);
   40.62      if (status != PEP_STATUS_OK)
   40.63          goto pEp_error;
   40.64  
   40.65 @@ -635,7 +640,7 @@
   40.66          goto pEp_error;
   40.67      }
   40.68  
   40.69 -    status = _mime_encode_message_internal(enc_msg, false, mime_ciphertext, false);
   40.70 +    status = _mime_encode_message_internal(enc_msg, false, mime_ciphertext, false, false);
   40.71  
   40.72  pEp_error:
   40.73      free_message(tmp_msg);
   40.74 @@ -660,7 +665,7 @@
   40.75      message* tmp_msg = NULL;
   40.76      message* enc_msg = NULL;
   40.77  
   40.78 -    status = mime_decode_message(mimetext, size, &tmp_msg);
   40.79 +    status = mime_decode_message(mimetext, size, &tmp_msg, NULL);
   40.80      if (status != PEP_STATUS_OK)
   40.81          goto pEp_error;
   40.82  
   40.83 @@ -690,4 +695,253 @@
   40.84      return status;
   40.85  }
   40.86  
   40.87 +PEP_STATUS set_up_preset(PEP_SESSION session,
   40.88 +                         pEp_test_ident_preset preset_name,
   40.89 +                         bool set_ident, 
   40.90 +                         bool set_pep,
   40.91 +                         bool trust,
   40.92 +                         bool set_own, 
   40.93 +                         bool setup_private, 
   40.94 +                         pEp_identity** ident) {
   40.95 +    if (set_own && !set_ident)
   40.96 +        return PEP_ILLEGAL_VALUE;
   40.97 +        
   40.98 +    const char* name = NULL;
   40.99 +    const char* user_id = NULL;
  40.100 +    const char* email = NULL;
  40.101 +    const char* key_prefix = NULL;
  40.102 +    string pubkey_dir = "test_keys/pub/";
  40.103 +    string privkey_dir = "test_keys/priv/";
  40.104 +    const char* fpr = NULL;
  40.105 +    PEP_STATUS status = PEP_STATUS_OK;
  40.106 +    
  40.107 +    if (ident)
  40.108 +        *ident = NULL;
  40.109 +
  40.110 +    pEp_identity* retval = NULL;
  40.111 +        
  40.112 +    switch (preset_name) {
  40.113 +        case ALICE:
  40.114 +            name = "Alice Spivak Hyatt";
  40.115 +            user_id = "ALICE";
  40.116 +            email = "pep.test.alice@pep-project.org";
  40.117 +            key_prefix = "pep-test-alice-0x6FF00E97";
  40.118 +            fpr = "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97";
  40.119 +            break;
  40.120 +        case APPLE:
  40.121 +            name = "Apple of my Computer";
  40.122 +            user_id = "APPLE";
  40.123 +            email = "pep.test.apple@pep-project.org";
  40.124 +            key_prefix = "pep-test-apple-0x1CCBC7D7";
  40.125 +            fpr = "3D8D9423D03DDF61B60161150313D94A1CCBC7D7";
  40.126 +            break;
  40.127 +        case BOB:
  40.128 +            name = "Bob Dog";
  40.129 +            user_id = "BOB";
  40.130 +            email = "pep.test.bob@pep-project.org";
  40.131 +            key_prefix = "pep-test-bob-0xC9C2EE39";
  40.132 +            fpr = "BFCDB7F301DEEEBBF947F29659BFF488C9C2EE39";
  40.133 +            break;
  40.134 +        case CAROL:
  40.135 +            name = "Carol Burnett";
  40.136 +            user_id = "CAROL";
  40.137 +            email = "pep-test-carol@pep-project.org";
  40.138 +            key_prefix = "pep-test-carol-0x42A85A42";
  40.139 +            fpr = "8DD4F5827B45839E9ACCA94687BDDFFB42A85A42";
  40.140 +            break;
  40.141 +        case DAVE:
  40.142 +            name = "The Hoff";
  40.143 +            user_id = "DAVE";
  40.144 +            email = "pep-test-dave@pep-project.org";
  40.145 +            key_prefix = "pep-test-dave-0xBB5BCCF6";
  40.146 +            fpr = "E8AC9779A2D13A15D8D55C84B049F489BB5BCCF6";
  40.147 +            break;
  40.148 +        case ERIN:
  40.149 +            name = "Erin Ireland";
  40.150 +            user_id = "ERIN";
  40.151 +            email = "pep-test-erin@pep-project.org";
  40.152 +            key_prefix = "pep-test-erin-0x9F8D7CBA";
  40.153 +            fpr = "1B0E197E8AE66277B8A024B9AEA69F509F8D7CBA";
  40.154 +            break;
  40.155 +        case FRANK:
  40.156 +            name = "Frank N. Furter";
  40.157 +            user_id = "FRANK";
  40.158 +            email = "pep-test-frank@pep-project.org";
  40.159 +            key_prefix = "pep-test-frank-0x9A7FC670";
  40.160 +            fpr = "B022B74476D8A8E1F01E55FBAB6972569A7FC670"; // currently expired
  40.161 +            break;
  40.162 +        case GABRIELLE:
  40.163 +            name = "Gabrielle Gonzales";
  40.164 +            user_id = "GABI";
  40.165 +            email = "pep-test-gabrielle@pep-project.org";
  40.166 +            key_prefix = "pep-test-gabrielle-0xE203586C";
  40.167 +            fpr = "906C9B8349954E82C5623C3C8C541BD4E203586C";
  40.168 +            break;
  40.169 +        case JOHN:
  40.170 +            name = "John Denver";
  40.171 +            user_id = "JOHN";
  40.172 +            email = "pep.test.john@pep-project.org";
  40.173 +            key_prefix = "pep-test-john-0x70DCF575";
  40.174 +            fpr = "AA2E4BEB93E5FE33DEFD8BE1135CD6D170DCF575";
  40.175 +            break;
  40.176 +        case ALEX:
  40.177 +            name = "Alex Braithwaite";
  40.178 +            user_id = "ALEX";
  40.179 +            email = "pep.test.alexander@peptest.ch";
  40.180 +            key_prefix = "pep.test.alexander-0x26B54E4E";
  40.181 +            fpr = "3AD9F60FAEB22675DB873A1362D6981326B54E4E";
  40.182 +            break;
  40.183 +        case ALEX_0:
  40.184 +            name = "Alex Braithwaite";
  40.185 +            user_id = "ALEX";
  40.186 +            email = "pep.test.alexander0@darthmama.org";
  40.187 +            key_prefix = "pep.test.alexander0-0x3B7302DB";
  40.188 +            fpr = "F4598A17D4690EB3B5B0F6A344F04E963B7302DB";
  40.189 +            break;
  40.190 +        case ALEX_1:
  40.191 +            name = "Alex Braithwaite";
  40.192 +            user_id = "ALEX";
  40.193 +            email = "pep.test.alexander1@darthmama.org";
  40.194 +            key_prefix = "pep.test.alexander1-0x541260F6";
  40.195 +            fpr = "59AF4C51492283522F6904531C09730A541260F6";
  40.196 +            break;
  40.197 +        case ALEX_2:
  40.198 +            name = "Alex Braithwaite";
  40.199 +            user_id = "ALEX";
  40.200 +            email = "pep.test.alexander2@darthmama.org";
  40.201 +            key_prefix = "pep.test.alexander2-0xA6512F30";
  40.202 +            fpr = "46A994F19077C05610870273C4B8AB0BA6512F30";
  40.203 +            break;
  40.204 +        case ALEX_3:
  40.205 +            name = "Alex Braithwaite";
  40.206 +            user_id = "ALEX";
  40.207 +            email = "pep.test.alexander3@darthmama.org";
  40.208 +            key_prefix = "pep.test.alexander3-0x724B3975";
  40.209 +            fpr = "5F7076BBD92E14EA49F0DF7C2CE49419724B3975";
  40.210 +            break;
  40.211 +        case ALEX_4:
  40.212 +            name = "Alex Braithwaite";
  40.213 +            user_id = "ALEX";
  40.214 +            email = "pep.test.alexander4@darthmama.org";
  40.215 +            key_prefix = "pep.test.alexander4-0x844B9DCF";
  40.216 +            fpr = "E95FFF95B8E2FDD4A12C3374395F1485844B9DCF";
  40.217 +            break;
  40.218 +        case ALEX_5:
  40.219 +            name = "Alex Braithwaite";
  40.220 +            user_id = "ALEX";
  40.221 +            email = "pep.test.alexander5@darthmama.org";
  40.222 +            key_prefix = "pep.test.alexander5-0x0773CD29";
  40.223 +            fpr = "58BCC2BF2AE1E3C4FBEAB89AD7838ACA0773CD29";
  40.224 +            break;
  40.225 +        case ALEX_6A:
  40.226 +            name = "Alex Braithwaite";
  40.227 +            user_id = "ALEX";
  40.228 +            email = "pep.test.alexander6@darthmama.org";
  40.229 +            key_prefix = "pep.test.alexander6-0x0019697D";
  40.230 +            fpr = "74D79B4496E289BD8A71B70BA8E2C4530019697D";
  40.231 +            break;
  40.232 +        case ALEX_6B:
  40.233 +            name = "Alex Braithwaite";
  40.234 +            user_id = "ALEX";
  40.235 +            email = "pep.test.alexander6@darthmama.org";
  40.236 +            key_prefix = "pep.test.alexander6-0x503B14D8";
  40.237 +            fpr = "2E21325D202A44BFD9C607FCF095B202503B14D8";
  40.238 +            break;
  40.239 +        case ALEX_6C:
  40.240 +            name = "Alex Braithwaite";
  40.241 +            user_id = "ALEX";
  40.242 +            email = "pep.test.alexander6@darthmama.org";
  40.243 +            key_prefix = "pep.test.alexander6-0xA216E95A";
  40.244 +            fpr = "3C1E713D8519D7F907E3142D179EAA24A216E95A";
  40.245 +            break;
  40.246 +        case ALEX_6D:
  40.247 +            name = "Alex Braithwaite";
  40.248 +            user_id = "ALEX";
  40.249 +            email = "pep.test.alexander6@darthmama.org";
  40.250 +            key_prefix = "pep.test.alexander6-0xBDA17020";
  40.251 +            fpr = "B4CE2F6947B6947C500F0687AEFDE530BDA17020";
  40.252 +            break;
  40.253 +        case BELLA:
  40.254 +            name = "Bella Cat";
  40.255 +            user_id = "BELLA";
  40.256 +            email = "pep.test.bella@peptest.ch";
  40.257 +            key_prefix = "pep.test.bella-0xAF516AAE";
  40.258 +            fpr = "5631BF1357326A02AA470EEEB815EF7FA4516AAE";
  40.259 +            break;
  40.260 +        case FENRIS:
  40.261 +            name = "Fenris Leto Hawke";
  40.262 +            user_id = "FENRIS";
  40.263 +            email = "pep.test.fenris@thisstilldoesntwork.lu";
  40.264 +            key_prefix = "pep.test.fenris-0x4F3D2900";
  40.265 +            fpr = "0969FA229DF21C832A64A04711B1B9804F3D2900";
  40.266 +            break;
  40.267 +        case SERCULLEN:
  40.268 +            name = "Cullen Rutherford";
  40.269 +            user_id = "CULLEN";
  40.270 +            email = "sercullen-test@darthmama.org";
  40.271 +            key_prefix = "sercullen-0x3CEAADED4"; // NB expired on purpose
  40.272 +            fpr = "1C9666D8B3E28F4AA3847DA89A6E75E3CEAADED4";
  40.273 +            break;
  40.274 +        case INQUISITOR:
  40.275 +            name = "Inquisitor Claire Trevelyan";
  40.276 +            user_id = "INQUISITOR";
  40.277 +            email = "inquisitor@darthmama.org";
  40.278 +            key_prefix = "inquisitor-0xA4728718_renewed";
  40.279 +            fpr = "8E8D2381AE066ABE1FEE509821BA977CA4728718";
  40.280 +            break;
  40.281 +        case BERND:
  40.282 +            name = "Bernd das Brot";
  40.283 +            user_id = "BERNDI";
  40.284 +            email = "bernd.das.brot@darthmama.org";
  40.285 +            key_prefix = "bernd.das.brot-0xCAFAA422";
  40.286 +            fpr = "F8CE0F7E24EB190A2FCBFD38D4B088A7CAFAA422";
  40.287 +            break;
  40.288 +        default:
  40.289 +            return PEP_CANNOT_SET_IDENTITY;
  40.290 +    }
  40.291 +    
  40.292 +    string pubkey_file = pubkey_dir + key_prefix + "_pub.asc";
  40.293 +    string privkey_file = privkey_dir + key_prefix + "_priv.asc";
  40.294 +    
  40.295 +    if (!slurp_and_import_key(session, pubkey_file.c_str()))
  40.296 +        return PEP_KEY_NOT_FOUND;
  40.297 +
  40.298 +    if (setup_private) {    
  40.299 +        if (!slurp_and_import_key(session, privkey_file.c_str()))
  40.300 +            return PEP_KEY_NOT_FOUND;
  40.301 +    }
  40.302 +
  40.303 +    retval = new_identity(email, NULL, user_id, name);
  40.304 +    if (!retval)
  40.305 +        return PEP_OUT_OF_MEMORY;
  40.306 +        
  40.307 +    // honestly probably happens anyway  
  40.308 +    if (set_ident && status == PEP_STATUS_OK)
  40.309 +        status = set_identity(session, retval);
  40.310 +
  40.311 +    if (set_own) {
  40.312 +        retval->me = true;
  40.313 +        status = set_own_key(session, retval, fpr);
  40.314 +    }        
  40.315 +    
  40.316 +    if (set_pep && status == PEP_STATUS_OK)
  40.317 +        status = set_as_pEp_user(session, retval);
  40.318 +        
  40.319 +    if (trust && status == PEP_STATUS_OK) {
  40.320 +        if (!retval->me)
  40.321 +            status = update_identity(session, retval);
  40.322 +        if (retval->comm_type >= PEP_ct_strong_but_unconfirmed) {
  40.323 +            retval->comm_type = (PEP_comm_type)(retval->comm_type | PEP_ct_confirmed);
  40.324 +            status = set_trust(session, retval);
  40.325 +        }
  40.326 +    }
  40.327 +    
  40.328 +    
  40.329 +    if (ident)
  40.330 +        *ident = retval;
  40.331 +    else 
  40.332 +        free_identity(retval);
  40.333 +        
  40.334 +    return status;
  40.335 +}
  40.336  #endif
    41.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.2 +++ b/test/test_mails/2_0_msg.eml	Wed Aug 07 14:08:11 2019 +0200
    41.3 @@ -0,0 +1,131 @@
    41.4 +Message-ID: <pEp.PVTIO0.06RK6SSZLZKYW.31E3BDB9-6E1C-4DED-8190-75682B33A9BA@pep-project.org>
    41.5 +From: Alice Test <pep.test.alice@pep-project.org>
    41.6 +To: Carol Test <pep-test-carol@pep-project.org>
    41.7 +Subject: =?utf-8?Q?p=E2=89=A1p?=
    41.8 +X-pEp-Version: 2.0
    41.9 +MIME-Version: 1.0
   41.10 +Content-Type: multipart/mixed; boundary="2eb141f241b71efb79e2a9e37545e146"
   41.11 +
   41.12 +--2eb141f241b71efb79e2a9e37545e146
   41.13 +Content-Type: text/plain; charset="utf-8"
   41.14 +Content-Transfer-Encoding: quoted-printable
   41.15 +Content-Disposition: inline; filename="msg.txt"
   41.16 +
   41.17 +this message was encrypted with p=E2=89=A1p https://pEp-project.org
   41.18 +--2eb141f241b71efb79e2a9e37545e146
   41.19 +Content-Type: application/pgp-encrypted
   41.20 +
   41.21 +Version: 1
   41.22 +--2eb141f241b71efb79e2a9e37545e146
   41.23 +Content-Type: application/octet-stream
   41.24 +Content-Disposition: attachment; filename="msg.asc"
   41.25 +
   41.26 +-----BEGIN PGP MESSAGE-----
   41.27 +
   41.28 +wcBMA1oCBdlzCD9NAQf+JXC3scv9R9LHmEp63+PZspJCWIPPrSh07ypbMMWpK8ii
   41.29 +VINunHuepzmDtSjBFFLW2bb1DqZKs7pF7LzSm/NHux4sIzPNiXQMB488EB03nQal
   41.30 +p5xmt2P+SF8aVt7LKcDmppxf+LSXpUJ1n0WeoJssMxqSpT3gD1Tv/RlOqdTgoMnq
   41.31 +uagxe/MUDJSfwtTEzrKjkjQL6kxIHR0Cmwlr425ETlKSFSjObCVkYO5T/1EVNLcg
   41.32 +WN86KtYGV/k0zAaT2rJqE7WyzG9+NJHRz1vkqUAqX9smNbhAOV+zeWZbMWlEAk2c
   41.33 ++xqniTTnHG5lZEjl/n4MviWsL4IqprArSU4ttyxXc8HATAOo6/9vKSPoQgEH/363
   41.34 +1GGe+eJZnr7wTDgpVbs56xuISEU5qrM3Jp3sLZ6F53ahTW9x8JuXQdNQfD9RLSdX
   41.35 +COW1LzCcjlfInTKn8pGDANrBFys1YjVlclEDcyKU1EPNFVHtR59C8XZcFlGC4LCQ
   41.36 +dt1ynmDpk8wRgpcYdsSRKORiPyGCoeBsot0jL6wNMurItLEmVPcKZfPs6eHNMfgQ
   41.37 +hgqkqNXjBTCXNujpz8s2634exR4mKoDIv6qYECY3P6Nw9ulnM9bI1HN2Q4BfTDY9
   41.38 +op7/fzp2IVubZq24SeJzjJCcy/iOsFr/qDtaRlLolNgjOGBLllHrtPlGH6E4JmNW
   41.39 +QrzeywsIcqE01YHzuQ3S0F8BShoMdQSNHJTCLU/J1+rg2nZkRfLsMEmuWQ3RoXMf
   41.40 +yzEoL1qbXppyc6YousL9e7ixKi293btzh7dssu1bNS9wFwoysZsmKnGw0lk3wIIM
   41.41 +/9rybPJQhA/dePKHPIC7VAQhXPGIsJk9cyElRk+TH12CNjlwUbGiwIhxVFCX4deo
   41.42 +E9cZGGBi5XPVD5M3wP6/M0nFRyQDGCEi3NegMbd1UTePxMzoI9C5+LOa0YCXURk1
   41.43 +qH5sVR1Est3P8Fk4uOjsFJLPkZWG70jSeh8Mvz/Aw7BDS/kPoc+JsQ6b1vo2vcp7
   41.44 +UkYHg1n1sD8V3z0mKkbH5v1bBIdQkgAsnrahdXSh5Xrwx37Di70TB/u916mrnhmb
   41.45 +10VCGq8EhiZO+K2Ij6XfVSbdoEhPKNNDECvy/KppPnWJ/qWdqe5cConCpwTXYye4
   41.46 +P/rF4ojeWAy3CRdf3W5L9l5fVcpQ3XfJEByIHQRcDJoYGKPoMbptEY1yjNe+vpk7
   41.47 +mD/U7GGc/+0L1SngH3E0tmSg1QUQOlDW0InuXZtEv7i8ebsG+rR1BX5XXw+gazcf
   41.48 +EIKMtpyA2nEKZ3i0VNK74uKrrHBfO7sw9L7XvE8ldfMZ07lOQ/F3CkSiFiVbZtKh
   41.49 +DKSejNHuEx2goaRUkSRQN2A1YBs08Nw8wd0CPU5PJ7bZ+3Udy8IMLczL50dzrBDt
   41.50 +4nz6MeQCozE3726+cpiC+vFW8us7RqWKoqP6i7ubi1Rl5GV1scg3I+UNhHqOXyvn
   41.51 +e26NMqE/56/zdDAP0ECXz0l/5QNTcU6w3qCAszDOqqM/LQRpEI0Gok8/B/UBjOKh
   41.52 +vLUhDLI1b5Lq3zYn9ss0p5rvzXxfQYo0bPow8/KmpL9Yq24IGMf8XfnU2FsSzcn/
   41.53 +3o+CJcW7OjK65MmMmvE5/79vtgpk+sRnh/MiC000z39OHGt4rFTuWRMH039AQ9TR
   41.54 +0FNE8wQ4AfHQpxvJjqBwbTMrFiFMq1ve0lLgP8fO55H8xa9nYntg2BJqsBdBbLvK
   41.55 +zHJ4Iw1s1oY0FZDFDu2J4phadJpvKRJRG3cdZthT04Ry5MzKO5/KLDmyLEI5Kq+n
   41.56 +bbR72KeV7vpb0DDvoC0+69S+ndDBhK5n8v+IfiRsxmcBARJlNshKTXN69OeSdAT5
   41.57 +KDssACi4q+C6uv136WHm45VfK9EiEV8TRws8DeL3cjIpk7W94N9YmdFgf7XhRY5a
   41.58 +P2rdrk761/5g4agpCE7otoHIg/IbfPm9RW8B770c87A/uKE0hBDTbeDgDYvY/gpg
   41.59 ++MAu+WeHBoxeiEvIZ5c+3L6c2Jw8G8gDoVj6oOkvgo2Dbt4nA9qR0Ew31LqgJuAp
   41.60 +wyR0zSZWSqPWQA8nMhATthp+fbjbXL4OM3FRNponzrj9gJWjImL/joykvIyp+eFW
   41.61 +u1SK/XGMNF0//GDnwfy4/7PpphnQLCk5eAEByqSjtY7X9hT6Ag6Y8bQaDKnrCtNW
   41.62 +NBRMZIYpXvql3kWfB+JS4it06q9Bs+cCPEjgOOcOJbtKyNlWUxE43Z0UBtCY2mCE
   41.63 +75RX6T/HVy0JMnlznecZMbkxX5OI/p73FWS6XwIMhy1XSdDnlyDLNnP8lfD6w8Ac
   41.64 +9DrWUeP9EEVWfZ71dEnWB/xS5cv7+f580Hq+cmkn+AdHa3f9MozzYf+mnPQ1Jf/U
   41.65 +cEZ3AnNsTqBSr6UJcYOyhzh2HNGZ8HOGnVZKHbrGpgA8AiTPQ+X3L75+wEX6JmSX
   41.66 +mbb3NDS6vdvPzSo2GHKwvAaNVh37LOtjyhqKQKyGnDvRqgmwzl4BS6tvWvUR9x70
   41.67 +IIbIL1bgfL0g/UENvlIsuKOeHLkEEzuDcR8f5WKtiL8cMXpseIk7O4BDGjl9fz25
   41.68 +sVOarFkEuu+h+90GvnKjfIY8GTFlDcbKWpDjSAwgzdcCsFSKFhESD0v4Ek1hLzue
   41.69 +L3UerFZ0AIYxx8wzLZfpPSssALhjFg17pla+t3fjr50vlIDzBYT9R0ex+mavX83y
   41.70 +PiSbZ73R+K0kMaEnVyJY+w/xU11xnWv5gyTT4gvZL6kxNTW1tNUM582Wvv2BX0hJ
   41.71 +oJDIpevTuZVkzAXi+B4YbtCMvBDSsR/Ec93Sx0hj4AC3wBjcq/3aVZbfpA4oY7vU
   41.72 +3w6ghUkuO6q9uwMwdEY4D9ekatrbo5F5ny+HYPz+MOREURJs6M/UgD5QRknB6R/Z
   41.73 +UnwzPMq9IRC+6GI/9HGKfSWXDuFVZuSLZdONy2YeKVR1nIDkn0RiffEJGrzBpiuO
   41.74 +DeZnSAvZRJmY2mJr8LoTXVCZZ8xgW42axWLrAqiruRoVEWrow9XXwe475NbqVvHp
   41.75 +jwSKdEqrJJCOONz+EoOKZ6rbYw1J9UOAZFJW+wpiAvNOZwWulYRTfFXPbo/W0cPE
   41.76 +D4Pw3EDpFnnG6SpXLq9daHY/zZjnHZhRjHC+iSkJiXF250YF8MTNO1Ogwt3WyZsZ
   41.77 +b2a5hjp0FcSNaf1d5oh4qJC3RgqzoQE3nH+Y169dEYyWUDO8J6i21K+9APVF5JQu
   41.78 +wVyNxs7dAPPrsMFxiAQeAKpKivomhPqHAuVmN/SsDij1Phtjdk2qVibgHuXBk++D
   41.79 +Qs7VuyxZY0PYg2hdt1pxJVRWfdNQhT/CYSqgwoQsovoBnNKhseg46p2aX8FJ46B/
   41.80 +eYlmpsz3uPD6ImXTH3OyWjF7ZUa783r21MU0pUCz73DI5f6VjX3VcfXxGwJ5X0Mn
   41.81 +bjoY6Bz+b1yuby5B9wH3uS3xxY72o23CXYhzWlu7ypOWLkc8V+7Q0GKbtRn+rAv1
   41.82 +O5C/020U0bImP4qr/CfwOpQ6Vdr0xZGnBon38LG/AfuMqmQVinfWV21r+hxNsBYj
   41.83 +SqGyDPJf315pPewdDi2OCzjqQ9TUy+Mc4Hvy0zVBV95cW6nvNbHgIP6yybYOdzz4
   41.84 +zkYCsunNqA4ZSVdskO3oZsmwXjmTdWWRUVjz/Piv65mzGxRuUaW76wfk+QujfGC+
   41.85 +qrJvLD8emW1tvDrOkZnBkuw+0zkp5SHMjMWN6bbtQs86Ima9GCutG5pCbyg4TpVm
   41.86 +0CWLHpD6cJSyD3mB9gJJ8u4SgZ5XEOc1ks+cY6X4G5mEoj9bas7IGRGcfCMV5xYx
   41.87 +hDShus0kLPfVUHn7dNjqfzXRCMRtlLVz2Cq3B4hioxowYEMPiPWSdJgLrKpNyHBO
   41.88 +xDqnU2mjD+zTC48O3hNlavXNnNImpDciDu416RoUkDp7axQNT+5rcGMrIjQHn2wx
   41.89 +lKYGWmvI/1/kS/hKFK+Nqk/c+Ti9igRZ6toezF4ss3ryqy5jqDG0ZMbCPMHQo4Qw
   41.90 +UNA/DgrA+M13ys43SU0d/3wOG20/ZPc7oJqnECZvGWFezhTouZtqCGqg+znk5Sqa
   41.91 +a2wzEHFku4WF8dWweRiswhuc6+Oqdmhm/IjUaQ96nRwvvl/4qdsWsxn0f3+B5Wyo
   41.92 +F4UktNHoYwqEihaftYIndguy2TJTsP4uWXS0gqdE0I/rFHLy+Ynvtmue9OkWTdy7
   41.93 +JqOOA+V6h6/jA7IyqhFt2HP+sxAhNardIlu2lNq8oy3x5O280KceljyDQt+A1YNe
   41.94 +fAK8mYEVa27qGO5DgNC6v6L41iBFGFTzCDz0LcZl+r+teG2H8WHTIYVkpMCTBwHF
   41.95 +T3iNaZ/y4mzUZkI7xW8W/wFyir5t5eLRdJ5B/KGkfZDp1iZqOb1Ae9Fn6oMGqDzW
   41.96 +C3kU2+OUgp3ZQLfm8wnjDG2YQE3rjK2oHNdzqpiFb96dUReeJIt8LDqhCYTVmdvE
   41.97 +z3ZIJS0430lMQqlTsq9B8RqTaeFqzSOvOSGLnXuiXCD1NYJKe34ZTy3l7RqXE/Y/
   41.98 +ApdIfrMnLxDHUON29pq1g5jhdVZhAHKbUDKo6392f6XU3dnxTOkBqE364+Dk683z
   41.99 +tC9e2aPRnRJpPlcXboDSaGOoCnU9xGgLh+NnrGEiOXhoVli2v/e2cGaAB+CmW7jk
  41.100 +grwTmOq0DziO8FccVZ/1MMRRZsKPmwRj+c2UP8zOPpUK1STg3D6QMi1h33AGYLYc
  41.101 +7REbR8o2DMCjQ05PybyP4wm8xxVtS2+Ws7iIUZ3YFmk3M+DNeGLOKXvtREcACb0Q
  41.102 +WSAW1snoP2oqmR+LXoW6PTFy2R33FdAZQhhSIGTRimy5TtFdisSnzUBMAo+npOLm
  41.103 +cE9F3gcn9Tj5WbQfkJHAn0DsTgZ63XRN7IGyMz6vdYFTCs7R2VoTMXF1Qn7AoVhE
  41.104 +2Z8JcOy76UlBiVpbrftyh269Tb18k/oRCKLE1dyySWwopB5TaAbv7UGAqDLo+Dne
  41.105 +XsnohvKwuJnavntE1Xlu06r+6cjj7VhuOCCZ0VwvVNcad1xHMqA0CruTEENzn27l
  41.106 +FsKlTRCJzMHkXPhNgE21cpgHLd9qHHZFftwimM0ujEHSeSD5qSaz6QnFGooAFMnz
  41.107 +MAXcZUzMHowYUEGRU87GZ5V+n1baim71Brw5JZhkG9Xij93+yuwKywYMy1jIbJf8
  41.108 +G5jSGenj2xuHu8obDusVnm1it8Kid+Y9L1QtYkbmv/2enXCsmqxgYFPnxOSb35Th
  41.109 +amyFyva7z0ndykl5Eqz0WM/ZR6Y8iOGZD6WI9a+i4eMQUP/S1nFpP9XFSAGMJwYt
  41.110 +MW1EO0iU+crYZ20GDm+tcwVhEvePILFiwR3tzfTzbzS2NiXKoQwoQorbMbiR/a1z
  41.111 +GXL90+tag6K4QksOtJUrvrKa8lJUZffUZTmHfAyjlfVPgmLJb77HXfJqjXMXAIpX
  41.112 +EG8811iVswetlkfFXRN+I4nYQH5h3AQwpHAdXoN3ePltMSfWIqcJcIsbaG/Ppm74
  41.113 +SGlmZsB70kdOgTxdLWY7oX6plZXo1q7q5UcazAyYbEkgczaFQh31OGs3L8NdoUUk
  41.114 +AD8ZTc/5OWW7XIOI5SzMP7uwp6f+pcsRgMp0gBSGjQxFyROBa3atA5M4XbMBCVg/
  41.115 +3Kx1miy+4PDd8aVw3r1zYWy/eO4PXqO6MNAx2R1PMxYlUkp5W/b3V1f8FIfY4Cfj
  41.116 +3I0pBeVn5u8ZiL9LnbZEKCqqgdkX2J0U+UYFlwR38mWEWcU8+LmdZhTLOYRM8hiE
  41.117 +RwlX4pkUzjygNy4VgjTT6Z7WFYA6j7BgQkCGMWrOAPOJhZ2Cs66lehxbzpeleLJi
  41.118 +hlveRnUMzkfWg1dUj1xvud3eqM6S2kSv4PrHK7RZNruYJa6/Y0rAZi9zz8XVqu9Z
  41.119 +eIr0x/9hDjfPFnczsopXGUheNStoeVpSYH8Q5PesNgN1X3eVVUYTSCgI0hKNMQG4
  41.120 +n8kv0HVGPLKMH2LdYzZKpRar4f3Ekbj8BBOFjA40ShUw9ABsNOeM7GDlgNprKdwA
  41.121 +xtC7CltLwbhJORs53Cs2RXo3x67UyoWREbnMb+SpviejJ0tEqP66DjJTP65ywZqX
  41.122 +8VsDvpdu6PrMDHBnCpiQq8anN3+ofaWspM//fp0MewCQlsCAhHiGsCMAoCsePSM5
  41.123 +Tg8P0avZFaq1v4G1TgRDfPishz59E8idxQWruWkobWoM3WZ7geFKp+p4NmIGcxLi
  41.124 +NZ7kfhfTtA/wCWrweHwXQcrYSyPwZ4CJraZDqPg0f97XoLF+lVWuuYaU34go2/Kw
  41.125 +nN79sr7i2r4QSGH1whmaOOA4ZoNn/C/3yWKHcvSq1TTgyyJxrML6o+gqDwGWJXh5
  41.126 +Iae9hljnMUyNBpdDYXc8ackLHw0PsdaqBZDCogeDD9ZSjUZ0wp3ThmMaM0O4nrJW
  41.127 +b6+MQWMjOH04zLpXq3zqpa66ZYc5weVll715MfrOVzcRwm6AyHd3koc36Kmkb3Vv
  41.128 +bGyGkgXfHXj/rkBJUsDFJiHw/t/9KOmfWugbN/DV8rfDy2sH68SS+2QIlYeODTKn
  41.129 +qf7HSiCmeZgUIAjgWzD4BGUiGF6IjL3n3IT9DrvRibrjTw5d5NGGYhIZuXHbYx80
  41.130 +l6U9zh/Wplsi3+d1dTXwcI+rZLS48T0rVTQ+PkS+hdo=
  41.131 +=X2Iw
  41.132 +-----END PGP MESSAGE-----
  41.133 +
  41.134 +--2eb141f241b71efb79e2a9e37545e146--
    42.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.2 +++ b/test/test_mails/From_M1_0.eml	Wed Aug 07 14:08:11 2019 +0200
    42.3 @@ -0,0 +1,159 @@
    42.4 +X-Envelope-From: <SRS0=fIwmw7=WD=pep-project.org=pep-test-carol@srs.smtpin.rzone.de>
    42.5 +X-Envelope-To: <krista@darthmama.org>
    42.6 +X-Delivery-Time: 1565167147
    42.7 +X-UID: 1648
    42.8 +Return-Path: <SRS0=fIwmw7=WD=pep-project.org=pep-test-carol@srs.smtpin.rzone.de>
    42.9 +Authentication-Results: strato.com; dmarc=none header.from=pep-project.org
   42.10 +Authentication-Results: strato.com; arc=none
   42.11 +Authentication-Results: strato.com; dkim=none
   42.12 +Authentication-Results: strato.com; dkim-adsp=none header.from="pep-test-carol@pep-project.org"
   42.13 +Authentication-Results: strato.com; spf=pass smtp.mailfrom="SRS0=fIwmw7=WD=pep-project.org=pep-test-carol@srs.smtpin.rzone.de"
   42.14 +X-RZG-Expurgate: clean/normal
   42.15 +X-RZG-Expurgate-ID: 149500::1565167147-00003DDB-C7945173/0/0
   42.16 +X-RZG-CLASS-ID: mi00
   42.17 +Received-SPF: pass
   42.18 +	(strato.com: domain _spf.strato.com designates 2a01:238:20a:202:5100::3 as permitted sender)
   42.19 +	mechanism=ip6;
   42.20 +	client-ip=2a01:238:20a:202:5100::3;
   42.21 +	helo="mi6-p00-ob.smtp.rzone.de";
   42.22 +	envelope-from="SRS0=fIwmw7=WD=pep-project.org=pep-test-carol@srs.smtpin.rzone.de";
   42.23 +	receiver=smtpin.rzone.de;
   42.24 +	identity=mailfrom;
   42.25 +Received: from mi6-p00-ob.smtp.rzone.de ([IPv6:2a01:238:20a:202:5100::3])
   42.26 +	by smtpin.rzone.de (RZmta 44.24 OK)
   42.27 +	with ESMTPS id A06378v778d77Mx
   42.28 +	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits))
   42.29 +	(Client CN "*.smtp.rzone.de", Issuer "TeleSec ServerPass Class 2 CA" (verified OK (+EmiG)))
   42.30 +	(Client hostname verified OK)
   42.31 +	for <krista@darthmama.org>;
   42.32 +	Wed, 7 Aug 2019 10:39:07 +0200 (CEST)
   42.33 +X-RZG-FWD-BY: pep.test.alexander0@darthmama.org
   42.34 +Received: from mailin.rzone.de ([unix socket])
   42.35 +	by mailin.rzone.de (RZmta 44.24) with LMTPA;
   42.36 +	Wed, 7 Aug 2019 10:38:51 +0200 (CEST)
   42.37 +Authentication-Results: strato.com; dmarc=none header.from=pep-project.org
   42.38 +Authentication-Results: strato.com; arc=none
   42.39 +Authentication-Results: strato.com; dkim=none
   42.40 +Authentication-Results: strato.com; dkim-adsp=none header.from="pep-test-carol@pep-project.org"
   42.41 +Authentication-Results: strato.com; spf=none smtp.mailfrom="pep-test-carol@pep-project.org"
   42.42 +X-RZG-Expurgate: clean/normal
   42.43 +X-RZG-Expurgate-ID: 149500::1565167131-00003DDB-FC731615/0/0
   42.44 +X-Strato-MessageType: email
   42.45 +X-RZG-CLASS-ID: mi00
   42.46 +Received-SPF: none
   42.47 +	client-ip=94.231.81.244;
   42.48 +	helo="dragon.pibit.ch";
   42.49 +	envelope-from="pep-test-carol@pep-project.org";
   42.50 +	receiver=smtpin.rzone.de;
   42.51 +	identity=mailfrom;
   42.52 +Received: from dragon.pibit.ch ([94.231.81.244])
   42.53 +	by smtpin.rzone.de (RZmta 44.24 OK)
   42.54 +	with ESMTPS id m04b52v778cp8lj
   42.55 +	(using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256 bits))
   42.56 +	(Client did not present a certificate)
   42.57 +	for <pep.test.alexander0@darthmama.org>;
   42.58 +	Wed, 7 Aug 2019 10:38:51 +0200 (CEST)
   42.59 +Received: from localhost (localhost [127.0.0.1])
   42.60 +	by dragon.pibit.ch (Postfix) with ESMTP id 08F6A171C07C
   42.61 +	for <pep.test.alexander0@darthmama.org>; Wed,  7 Aug 2019 10:38:51 +0200 (CEST)
   42.62 +Received: from dragon.pibit.ch ([127.0.0.1])
   42.63 +	by localhost (dragon.pibit.ch [127.0.0.1]) (amavisd-new, port 10024)
   42.64 +	with ESMTP id OvZUPxZCJx_I for <pep.test.alexander0@darthmama.org>;
   42.65 +	Wed,  7 Aug 2019 10:38:50 +0200 (CEST)
   42.66 +Received: from [192.168.43.214] (ip-109-40-131-98.web.vodafone.de [109.40.131.98])
   42.67 +	by dragon.pibit.ch (Postfix) with ESMTPSA id AD2B8171C069
   42.68 +	for <pep.test.alexander0@darthmama.org>; Wed,  7 Aug 2019 10:38:50 +0200 (CEST)
   42.69 +To: pep.test.alexander0@darthmama.org
   42.70 +From: pep-test-carol@pep-project.org
   42.71 +Subject: 1.0 Test Msg
   42.72 +Openpgp: preference=signencrypt
   42.73 +Message-ID: <967793b1-8d03-537c-1fca-2c18e029f5a4@pep.foundation>
   42.74 +Date: Wed, 7 Aug 2019 10:38:49 +0200
   42.75 +User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:60.0)
   42.76 + Gecko/20100101 Thunderbird/60.8.0
   42.77 +MIME-Version: 1.0
   42.78 +Content-Type: multipart/encrypted;
   42.79 + protocol="application/pgp-encrypted";
   42.80 + boundary="FJo2kRnx54tqD8mPE6mgtnDKuVoGxrGwO"
   42.81 +
   42.82 +This is an OpenPGP/MIME encrypted message (RFC 4880 and 3156)
   42.83 +--FJo2kRnx54tqD8mPE6mgtnDKuVoGxrGwO
   42.84 +Content-Type: application/pgp-encrypted
   42.85 +Content-Description: PGP/MIME version identification
   42.86 +
   42.87 +Version: 1
   42.88 +
   42.89 +--FJo2kRnx54tqD8mPE6mgtnDKuVoGxrGwO
   42.90 +Content-Type: application/octet-stream; name="encrypted.asc"
   42.91 +Content-Description: OpenPGP encrypted message
   42.92 +Content-Disposition: inline; filename="encrypted.asc"
   42.93 +
   42.94 +-----BEGIN PGP MESSAGE-----
   42.95 +
   42.96 +hQGMAwjkZzJfiW8+AQwA4TFiILeKBTdW3UQi8PcQKOzJE6pxgQL+B1gpOzjCRUel
   42.97 +n3drMe02EwZkmQcGwCmoIP9vdYw/mlEgsWvTbuv85CXXUyw8lJ5gT/u52H0/zHrU
   42.98 +yaJQu2WyCOVYEZv2qlVGw9pWSSW14Xh39aTiLwOKr4gtOoa7O9lbbyZI4TKVqn7d
   42.99 +8hUbEO/dScFFnzPTcUBwKsWmO4NBkQd9kW0v9kw2RtZwy47gYA+V1SlWiZAqsIV1
  42.100 +j1xUK4ZkWFfQlbh3aYX8RX1F5lwV56nR5bk0Jcpeu/NLSTUBJwck8IcgIQ+LnYZA
  42.101 +a4Fag+m+neEw0rkgdkAaD0Vb2GrOqG61p8uA5xkpcaOy+3QQb7DeeK1QKh22DFaS
  42.102 +MHZZynlcqYsurS/6iO9i7+OB+QbslWtnfItXJpKtwc24mLZp9Xp20gfO3KXElTIx
  42.103 +rI1S/LRwG0054CUwChVeO4OVr3mwmR/zMvw4XqFj0K/Cjx6qwy1esyl/FQfQrbZC
  42.104 +c05QW+ojpC6rGMFa4aGchQEMA6jr/28pI+hCAQf/ZNhBOn8pOARAW2csYHWtc8Fy
  42.105 +N0Sknn2VFvDLCI43P+HqgqZfqeu53WlbADJ8zd8xzi9riB+3HSMRS4bpD2WKOzut
  42.106 +RQmjdEZxLceA82clvY02AH1mpjMb9Axl0/FZRlmoqZtJEVMYDEeKXJmONr6M6J5n
  42.107 +agAsPiSX9H7fHkRBRvna6K3GUTZpftLuptTdR54YvMr6HR6+1M6847f6IXrza0I+
  42.108 ++IckY5iEL0JCTnSNYehEDfXVoq7AubsiuVMrXK313uKtrOnxPbeDz7OXxusfa/u9
  42.109 +y2A4YR8L3lj1F5ZiHEojfFnKU+k+P2dt/ydQjRo0WihtMhFHNKcZaS9AUUkE1tLr
  42.110 +AQXNiMOM3IdciqVMFNX8uKlpVOxi8/0ak7vzaPsEpp/x+gnFHNsBykQ+rMDC1D6p
  42.111 +kkEz9ukEqZmq5PvwRX51AbZMwoFBxWoLTEZU0/g2d2eSCY7FJUaCsMVxkrBjRR2K
  42.112 +GnCQjHqBazOyfF/qlUtRycXa7sQsSWV4ywU1h76xW9qrc8py+zz2bOJhgRUdTP0s
  42.113 +s2CTyKihoEkR9ORBMwbCG3ScwVF/xOFgz8xZQovHbvJGEZNNjIgfxibaSCPg3Bng
  42.114 +UdA/hkozmN4nxbmPWRafXvf9Zbf7ZAnRhelz32DfcSGzVwEdEWzPnHrEWmMkk0wf
  42.115 +tzVwLShpDKU8uf0XwOf3kNzbFeCD2IjOYBq3ddhCpzxr1ZBNPxeX8FW+3LYXZkJK
  42.116 +W7jVLoeFFfZxaYtlhDJ8/ZwbhIUcpu5e+U9hUek83DffCIm/Wsea2wdOv48+gc+h
  42.117 +vbTQsnJzVA+bJzsXryMpY77rngVoyU8YjEcXt3JTDxYgym6i895rxOZ0ZS4+j81a
  42.118 +CKgCVWO2vFslqg/nBqeCIVO6vRgv3Gie7/u91b3N1s0J5eeCl+QkLP4re1S/s9TD
  42.119 +e7AUum+3qrPSMwMS8Yns9WTlyqF5OS80R0iPPW8HtGT+hNFHMHxGy1wMUdabeD/M
  42.120 +WRnxyivnpQICfAJeN0rNMaJkB0phbb/zmqIO7j6yb3MTDA9R/C03h72fRd46Elai
  42.121 +jfBYdLjYrsdx7r5/z5igKCsvFSqozW68HdtNgqktPaG7HWbzsx1aQDjKi5O5bVuu
  42.122 +kQL75tZ58knss5v35HPLRbn4A4K8HGcX/N8UaYPQQXoZ4RjIOaeSPaWRTRw1zuj8
  42.123 +C9N7uXiVCyv4PNOZ+12Y6Tq3Xj/zkKHH5YsMs/sc9Nfz0AGVHaYHCqau8t1w40ab
  42.124 +/3AESAn6LO6P+97fFgsIq/Ox40MOdtMcQ7PIdySCcO3zzx5pp1dtoyJKCa4poXbs
  42.125 +T/ZEEMuwAMRLXVwVbfKST+OSUCJGs8vBEP/25wavKEVcwiRFbFpevlr1vSai2lVp
  42.126 +2UxXH5IBCdA6nXrNYIPLs2z0KyRgPI/SRovlWSeLGmaBcQiG23AuQJgtoRfE2BPk
  42.127 +iL3rdge+g3vzyqLwRiGsTMakwN8oYHgC6C+PO38L+u77Yu2gIzc55X9Dk15uQn99
  42.128 +8Q5w+EXZFMLZciZj2n1e1fQguoaF/QrJS0LFmftC5FC8e1o5vDorg56an8s3KlOW
  42.129 +tZnWBPqCoIkqwQPIvMuDSJpF/xTaOqRBqHEXwo9j3imodo7i40FxtinYgsMAvrY8
  42.130 +RuzKSgrpAIg1ADG79f4rpo8MVHNYKgFGUkc3P9YwrBMUCWJB2YYOV6v12ODo0NTt
  42.131 +P9Aep0+StCb5LiKT6YbfbA+wKIfkRdDddHw5ZR0NKOZjwK7HG3sxGsyWnpRsEYEv
  42.132 +o1pA7NKQa3kgSjpTeyYIVIF3CPJ+w7AlTUN30J5k3z+IeRYiTagr64lPjTYChPgT
  42.133 +fqG4ZdbWE9Dh0wO+jMm9a73ppVNBaGsFY4dg3x611vH6VoK1f1/9LVqW5bMNpIZz
  42.134 +vKh70giOnVnh0UpuK1Bnc8BUm3OMfYyVq5qiVj/4bGCAaNQcVNdbnLW7sXp+mLci
  42.135 +QBKGmlOZHQegoSRSyLIg60Z8FR1KDrIEZ0E5CaRAUdUA5WlPxTriDAUQa3zmNaaW
  42.136 +fe/87+0RbNpoJWPsG63XHVVkxgWk8472qpH9/qzqVrvrbiSB+VplJfQZL2LSVc7D
  42.137 +nJsTmTLNu5/VGt9L8lJzcwbhpfs9wiSVuPSgoovYRv4l9vrNpBaZzxdeicM0gZsy
  42.138 +Gdj/TSPd92zT7IOD70K8hWf8EHY0Uw/JkzJiFUHWNtw77M5ksTzOcarLw26s28EQ
  42.139 +iAPHAMmu0pdoyHlHYQY3wrDlesRbKSeilUvsxICXRvTlzx+SvV99Zs2/RfEAVD7X
  42.140 +DJL8FaS9ZwQvhGzcgAKq3SVo4v4FyaAWinSWSlE3f4ri+Xl7o/qvKMZ/kgnZxo+5
  42.141 +DGJ9M6qs2SLL8ICP9FOqC3eK/BnCcAbomN1hvDKPWJnluSBW7i6LXEq8dzp2YWR7
  42.142 +wljAJKuM29IWmYVTl+WzGDBQqHHUNGpymzUip+mBXlJG3n/3kaN8Snhk1qwes8Hi
  42.143 ++KaILwL2I8kFDuEO0xhqtErpbeMHUephLmSckgh4SdL+UdEC8JWfmth/PwX2b7US
  42.144 +ZA6co8X2ysPbni1Z61Df9rejZDMPTG2gm1Jn4kGUhwTBQnNBUUigNDukZxmJnagC
  42.145 +XZaUphij9kOsLQe6qXUqNXTmRmDKowSjkSu4/VIBUgdYKkIHMkfoNyWTn7MO2NUm
  42.146 +YGMQJLPqSheKM2WBwjlCrMHe5vuDH4OO0zjQWfJ0oPGrK5htMlmwjWYKjLXhmMPy
  42.147 +RRKil/PfKMCpZamiLFDt1YP9M62qTHktEuwIzjad/KERI3DOPmWszZWV36+b6s2q
  42.148 +ieasWYWIZHJBcTCc2AetjHlVvJrPPnMlOI6vS0OMYJVTiL5nzR2Rk6GkH1PXizqw
  42.149 +co/+Q4zLeC0Zx7u1FOdhX7s8a+qsV/kLbqczSMBOEDiMpcuQUGfB39XeuloOGkby
  42.150 +I/muioTiZqVKH06U6iZiAXktqdmsWOBABydeknKiBftpVc88eFQ9s7GTmidayjTF
  42.151 +FAuYmA3OP4dNlVImzuuB81qui28uNYF8LIwfpAukNU6yQQpU7sZhW7OuUq/KHjTq
  42.152 +aAtQuaHDgL8RD5HeYHx6w/RY1Ug9NGPEpNKsws1QzOvAS73vYKH0eILUONWd/JbV
  42.153 +0OB8ZQ0njP8CLcxrA5QZIMrhnw+k05wuPevfeFP/kvcfRuQu1qMhpqMt60M8PSHx
  42.154 +g1a2lGYzZV3d4VKZVuD4CZWg6eduqEQTKRx/nj2Fkfzdw5UVK8KdMhm2dX1a9Nzr
  42.155 +NNOf7wM5ypgkNGWvh/oxUJYVgKJUewN+9GzGn7L86WFyzcwVVllpcRKXCzz/1kNU
  42.156 +B3/tDbNvKntbgbNvMQNgMgHvW7H2NuZdHPjDxvkZQPRaKpquAx/zOHNjl1MASkJc
  42.157 +w4pEHRH2mssVX37Zi7C4qRu0F43nt+BiCYSixcCVXsHF2BKsKkSAV9elmcJWfAHo
  42.158 +sUuYMxKH4stfkWDNRQ==
  42.159 +=4k3/
  42.160 +-----END PGP MESSAGE-----
  42.161 +
  42.162 +--FJo2kRnx54tqD8mPE6mgtnDKuVoGxrGwO--
    43.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.2 +++ b/test/test_mails/From_M2_1.eml	Wed Aug 07 14:08:11 2019 +0200
    43.3 @@ -0,0 +1,124 @@
    43.4 +Message-ID: <pEp.PVUYXR.0AZSSOYBYY6MW.CEB1AB30-47AC-4B4D-AC1B-C3CF8F02D49D@pep-project.org>
    43.5 +From: Alice Spivak Hyatt <pep.test.alice@pep-project.org>
    43.6 +To: Carol Burnett <pep-test-carol@pep-project.org>
    43.7 +Subject: =?utf-8?Q?p=E2=89=A1p?=
    43.8 +X-pEp-Version: 2.1
    43.9 +MIME-Version: 1.0
   43.10 +Content-Type: multipart/encrypted; boundary="2eb141f241b71efb79e2a9e37545e146"; 
   43.11 + protocol="application/pgp-encrypted"
   43.12 +
   43.13 +--2eb141f241b71efb79e2a9e37545e146
   43.14 +Content-Type: application/pgp-encrypted
   43.15 +
   43.16 +Version: 1
   43.17 +--2eb141f241b71efb79e2a9e37545e146
   43.18 +Content-Type: application/octet-stream
   43.19 +Content-Transfer-Encoding: 7bit
   43.20 +Content-Disposition: inline; filename="msg.asc"
   43.21 +
   43.22 +-----BEGIN PGP MESSAGE-----
   43.23 +
   43.24 +wcBMA1oCBdlzCD9NAQgAlTYeWEzZy4kP4gD5m6d/QpGWVBZ9UFu9YqOSmiX3i+g1
   43.25 +DJyKPtYc9n1X5IDFr2VutmB73PLFgIySh3gV4LV2Nw9DMCFLo4LuamACXSmTYgfX
   43.26 +LwEi6X/tUl9gfnGWfokFDn5og/8g9fIAu3Iju+IoCYTxse3CbRzen6K88A/Eze1O
   43.27 +XW7W6lmo01CiqgJ++fxkuh68qfHROHIoiCo5cACdj98HKvtMPMLFXa+VIqDxKrt1
   43.28 +8jKGZxlA244MFfjHW5ICO6G0k1wQaUgw0PKRSBSshX6okKytfH3ckEkFNJVQZtRT
   43.29 +72j5I6ssuNUs53ymSzsrV5IrQhK/EsnhmnKBJ+GsosHATAOo6/9vKSPoQgEH/1DK
   43.30 +FH2UPlmflD3+07vlFZyoCwCYlcgN9sWl77bT5CTSFV4PK19F9vkaYcOwEbGxcS1D
   43.31 +z7OnHTFNTe3kVuM9kzWZ+F87+phGV6FWoAfuGAOWF3luZSop0quIJLwu1n3EtX0D
   43.32 +Xl5OchfLitcWxzrCXZHcvM+P4VEsIWudnJFC4hHHWgbbOF65B4dVEs3dINyVoTF6
   43.33 +z+iQImCn3EDPhcB9SlMZOob8hGUvUSTZDJJETZPHAJeW76NGQZ95fF/x9nqr/3/N
   43.34 +alGQ7Lq7R9Inv9BYlnXmJXTEnhLwFlwlPVoMf7pQnj3D0CYKP9AldrDNP2mQHYWO
   43.35 +Yac/3uDXiN5/QrLCMg3Sz8YBY9rS1pWV8ZZt+ZzY5jEIpdOUSw89mfEUDeZTNDo0
   43.36 +VoDzJvKn42NlRVQk4/6TVfaezgJjw/eVs0xLjOCGdsgCJ/PojExY+dfuo071Asbq
   43.37 +dCpc9qgNzDNJoS2XftTFHb1cH1ttC8an1ySLQNBg/9vguFAUxr+kAomfO1lRxpv5
   43.38 +BT2F7UBQTqWHqO4CPffsWQ5e6vCIx2c2FO3aFR0+WY3uTmlIZyjjMz1mB9KjjuO8
   43.39 +BgERxWd75ahoB3w8Hveel0vTussKpkLxxcQChhstcozoFX8M2VqVwVYqn7uChP9q
   43.40 +TPbuRVUpLvAAwKyO10eM+GZaHNbar7//v9KlCG1SLVE5PR8v5/n7L5slJwVfkqwR
   43.41 +9lZGtrSy4dB0lSfeQRwCd3iduu3oMdo2GeWU5duBdqqbrEGXAtubctZqXwzew1Vb
   43.42 +kNYuyozstv5B9psFSBshEaRGTFRGHuKB952AUeh8ISPX9IbucxNSbXxBRCOx/9Wj
   43.43 +1E9bm8WYZTT9r9Qwj1v0z0XfFze9i1nYWh8OVMCcsokhClBn46vDbY427cwSaS/O
   43.44 +luuqSL2B3Jhg4uCHNWHMjYvZh9jS50R7Do6aljQVK+TPk77LidAaNtG9fm04nL7+
   43.45 ++6+tLlMLKJ914i8t0rR8kTWtSp9xfzE59My56HOFsNZ3VAxrOaY2Xzxn67m8rXt5
   43.46 +0wXGy6yEQ9imoiQakZnOHWilE1BOplzIvdTugi2q8ILfqToE3t8vlSi9K39vUUTV
   43.47 +uj/Fw9vbGjfoeHt06mxHHSN3ePDj1v78jm8W10m+c0Zwrz3KrKW4B2WMrpqz8D6N
   43.48 +/PY/qJIccfCpCBZcZMO+6Wa4SWeYUyNn/JhhMCES9cpyllnZyVGrTb8l0NHhNG/P
   43.49 +eOuRa+5z7c/CtCSQlMlX2gti23q6j4mdm3HdaBQrW8uKvqKuh72pLDXUaY3EoDN7
   43.50 +g3V9I127hxd6K8KTKG/S18nlfHoSc9gVho4YOys9WEYE9S/Gznf4aU1lnnrjaKLF
   43.51 +B9w/RmWryqdu7hEl92j0zhdvQt6RI3/2rE7RN4XW7TtcmlnyWh6nfiqBLnS9zvU7
   43.52 +4hzukfMKQ91M8UfqpocQdxnxLk8TCw/RKhQP7onu9jR3nnPhtH54Ag3ohPxz+xBq
   43.53 +9k5K8Uo3JQXYFxs9hBYUc6WOLACQxOEmzMTApAr4nHObLp4Q74gd8FJ2KOmaWS13
   43.54 +vLJTmHroCw0w69dNZSUWQaSrn/enmXZ8Y4IOoZ17B5el5Ms76heYinjHY+sofi0I
   43.55 +cg2QrHxM+t0u7f9qaU0hbHWVt33i6AmGChu+0M/HyjSiEWv/Q5jE2lG0b/6yVl+f
   43.56 +C/6QUMg6Fr/6eVKuCeEYjVgoTMKDmQdo/w1SUSjfpVAdB/o6WL1lcv26k8HRsNZa
   43.57 +gEAPQuC/xEY8Vrou62etOh6tDO2jZ7ytd96aTcHvRIecilORhSOS7ClrNrBD8JJG
   43.58 +WGak9E5zBjLXXl8hSo+WMw0DOKacA6ccie0VRNlkg7QrGZD3S+FqKX/6Pv/YI7Q0
   43.59 ++RgS5hoKnj3vNmyAijJi2Nzksl+wjFZa5UnVsReynCZfOkZC+l5SrLwx5dX+NbG2
   43.60 +vdzGiw6ldLK/GO4n9tEIkpT0NfOLUbh26huhl59GWsv1XMA5R48J0vyqZCKfd6bG
   43.61 +V6wjEiELo0D7JMyhVsEqYMsr8DwyXH6yJ1UsKWDc/gKk6dx55SxJc8cBcu+s6qqg
   43.62 +mlXUGMXWj3VNHE4YeSd8BNA7f/yZSUTP6sO2fJsy5wuf8QcYNVE04bv2Vo7rnuaJ
   43.63 +9HpPwqwEeSqI5mjsdxwXHd434H7F7CCVUSqbkZe9jzsLC+Lb0xQYwtjk62pUq1CX
   43.64 +hI9k8YU5RuTeRv2Pg6Gzm17uXNG1wCZAWX2lWC+CgLpv+A0+ihy9srDnBZZPh2A+
   43.65 +ii9PKO36HlAszm6K/El/OGKN9El2PkberPblfFhfzXmPYLB5jiyMyIA/Vn9E4mp0
   43.66 +FyU7oFEttC0np9WGcExLPJWbL5dxqlAOKBuL0Rn+0+lvQjjb0aHQTku/yXE+6qlA
   43.67 +VwjbTT+4C4t6Jg4enJpAUZkzDVsr9hfkqkN1ezkjiNAJKD2NXD3nnOjHV0NMwfjL
   43.68 +Lm4vtOLJAKl3uMRFhqH0VkSbt4WuVe3hyro8LR7zstIfY7csEtcpk2RGCIFBqJjv
   43.69 +q1VSYpfg2ig5u06A2bDGY82GYmNAwnk3tEf1sBIdvLHDSHwKAQcmnlUAiMWoQRDA
   43.70 ++z+axP1qIUb1A7Ph7fqRQBLDQwqL0cT6f0dSy6oPT3IRd/R5C23AJB6G1HsSiBTP
   43.71 +i+lVdk14iseZW2yQcfXKq1mQCDMxP9ic6r+AaI7U70bGyVT/LM2LQ0JK0n5a9e31
   43.72 +llhu3XWoVrePhrPYo/nChSxkCjE/cmopeD/znKOSGPFYuxa1EEEjCN2R5Vm37kT4
   43.73 +say+GspHnatm8SGRSSRsiANl9hWnM/TdbeGZGUYZPV8kBqEMmX7mMic7T6ny8RZE
   43.74 +IWjMPZN9y4OygFNTD2KHd/krPfpvQSl7hRtjZJaDakNKxkMsKoTZjhGFDOqMeqoP
   43.75 +dufoxsCIV/oUPTRrgpQy4BPXbRkRYAKWOhwTr5OgbfT43M0WA+eUmPyqYQJn6iS+
   43.76 +75vAUAwNjX/+L0ECYqnnDSb2PPPIdGVSv0wOk01CSLKwlPoq0BezFw4iYqGXcWVN
   43.77 +kKLYvm+o+y6izCOlwtyPZpWDkSb9+gnsRXkjhGAlhVYawYxDWrKJY+9Qk1l7HHFU
   43.78 +45IMaDsiRamgjsmBuSrR95TUsaxwx2+/BXPK/7UmHFSR3JTEhzbaOHiGSrS8JxXm
   43.79 +3dt95pfSnAM5OxcLge6m0tSPXil/2KN/MGoJLR45+hZq9Kh6P4mb4MOu/nrIjq1U
   43.80 +O/haaF7seh1N4CvhFK+0DQ32aMwrgyla/EinRq2uIcXGMXBqf6k3zL8KlAfPWdeR
   43.81 +8uhShYs6HdIN7bG91jy83QTrYfptDBWQUPQdcqaNDb1ByOBpzkbyjrGTszCdYou2
   43.82 +/WZlV3vRuadiK1OfvnWWQrEGX6A4ug3fy6H7rfJmCxqL7w06eac+leihCw1y8rZK
   43.83 +A+Er1smYn5k1A8Jc66QsKlXGWvpTF28nGmKkLHJeQquS2OK4TPKNObY3U1J7MpNj
   43.84 +asAvoiyrQppHKOEqSf9nls2EdywtN45sGaotPZVmNUzSU4xyA4WmJBLScDHysgf/
   43.85 +1ZwaHpexLCUNKd8dQ/dm1SXO0zG0+iB7sDpjPcYUTIzVRLP6ihB+xvQZpd29Z6mG
   43.86 +lM8AcJSaLhl9bFe5PPBKIygtuuj8nJojpY2MlU4jK23axeNvtIFgypZmU8E1gCSj
   43.87 +kxEXuL8cBhF090DJ/xeDtc5hlXi7QXL6p3WnDpSe5W0NT9mI36wg21vlqwVvJVn+
   43.88 ++WKkD4pkAQEaXxa5B7U5XAut43qdQQSWcZHBsfifsYFmwhyT63XkAhkkCg1pTKCI
   43.89 +Lm9W2GN6VBk9gp4fzKEzf29yUjs18xa1g8sYGi9iWMKJVvCpVSVbtl2f6UAkUFky
   43.90 +0H1e1U4sFiQtapTpvnJyyUg4jaOoU9lATID32ZMcxPeLFpPI0k2zFV1j3SqaC67K
   43.91 +MxPzhQhCepq+8T9cdp7fBee6u5DVKEOd6jpdgom7VYE68Hjc7HyWd2XsOyDmGemp
   43.92 +QbPloTJDoa/g1sMbG6AW5zuNNoKlrktAb04S6AQdE30KdivwKtAEg34/rmzOXeNf
   43.93 +Y6L4W7OIPNhrv7uvmiMiLnAKxFBTlru5rPuNzIVmjmuysJBisi+3dqtN+KuZYWAo
   43.94 +C5ssivN+OBuJrypoKOYmyDmmOgT5YRIn7Uhm0DTOez10aprg8jOyfcyCSZ10c633
   43.95 +ZeUNl7FQ2+Nt/yyY3mQH1HP2aU+orA/qpqAYW4kaq8wWH/00soUXrik5FkPg5s5H
   43.96 +Mrqtnz4QimqAMTixQg2BTGATVm+Kv2F9PVlTmiSVl4Uv93t7w5ipoCieuYaVmDjq
   43.97 +KSV8RNbasl/+qwtWK0szEeE/8Tl6ZlKT0/EfMYKMGGPbSKryzmjYrSzXK0rkv56S
   43.98 +b9JqdZ633m6EQIBLzImtZscd11kYuiZynJLmWUW5PbdPqo3OGCIcWuOcQ4aPHVqD
   43.99 +0XPna30bcjIY937Jo5+kWyg2/mLQ24aV99hUIhOc5aLlNi6P5n+22iA68t/sUIT9
  43.100 +v+UC3ScD8MmUQg6gRPt8bWk78DmMP6AmnZx8a0HwCYwPmSi4uZzh1AkREs4KsWHe
  43.101 +z2NqeolSvSH3O3gaWtjs08mPOfZ+JGtDLyfmAM2Ojttfz7gHb6a7ZtjVXgTpXqH7
  43.102 +xGvY3udeibO6THZ9Y9rymXH9OpCt2Qc69GuBAgfDpXZOVb8JMROWnDmgkObo27Kc
  43.103 +bdFSWnzbbWgXo2xVUlKDih3lSaBFdntthAxjKj0dckCJ8J31P+LYBoX9yEeiMZaJ
  43.104 +j1fhiRMk/Ae4hTUbzc0Fabut8A3p0Ah+YgH2Pf7DEr7LE9/GH5/J4hB5fEC+n4Dq
  43.105 +q+fjNkZyvx6seZrwr1h5APg96cmrZeuAELLRkJzqbBq5aaQQgYr/B9tiA+PIIn9p
  43.106 +6grNHm8YKwIzO/Tgk7MgLyEZIkg0CVvM74t6u7JLc+hXoDLe957BrgDuqgwRu8OP
  43.107 +kh2OfFKBAw/38qtDdILpZ4MI4L9OoQI0QNTScN2aB9eXRBir9DvUhAtmNfepQjxM
  43.108 +O/tWO2D+L27Yoofx2LIZ0trg4GcaOSE3jmsHr+VAz9axwVUdG9wQPbSshzbsCpZQ
  43.109 +YXY+o1ofi+RSm957ANUYqSnpRl7PYiypVbdu+wVK+iqacotFeoCDV+vmOtfUkarW
  43.110 +DRNLDCZeguG0zQ5MsGAn1jhxsFXizSoXFlqfHUP3B3qJpP5R4CiFZjdYzXHUwoxl
  43.111 +N0UdleUpq5gWJXpZd+0ELR2HvA7d2NVLjUEgJuyMnwx+lXnqd9v9jdk9SMkHxwje
  43.112 +ETGI+Vy4dpjAGwTQNTUTMD/R4krlJP8uJ4D2mrzK/aFL1+WilKKWIEUlH7llwRT0
  43.113 +IEQplQt/4tXd4sCuojqV6dqJtWEQV0Y51BKDgUL7bTzktCTKCS5LzhxRD/5EtC/R
  43.114 +vYNXyfEvU2j4MxG/ghQwBlFF/v8xrWCufL4Jqr2sx3OWQIkJY5Ol6F3ZjY7amUEt
  43.115 +CMvgkx0cL2YeYejCwLUcgMXKO1FaWfL/DDg0DvOjqhlXWgUXUslDst6lmDZFNiuc
  43.116 +MJJsNyMPCO9o+Y1YCSiXz8M801Md3YsAxv59+1Tlqq1oxkSXOhmpVtKkiQNTjRmH
  43.117 +L9bVjckIJ95ejynGKpjoEPZsXDPBVq1ty59+EXZTVO1ZqxkrcrHFzAtQqkwpHOur
  43.118 +9rd0D26W//PzOGDC30O3VNkhgxtB94bzlXkmg7PleiJBgOrThPM/ojTOQmW3BX4y
  43.119 +EqzSQGJUDErQwOtXBYCJW5K5ITorfi/ykYKaCuj2MfmHFyWTV0kBQh/zOKWXcH70
  43.120 +kfdjDo9Oh7D+RhOsSwrUj0v3t91+x4LcCMsL83vbKqtoYZ1+a7PJl7/zY81Rwuo4
  43.121 +lCx911ITGeHR5nxclHeZ5XRkNjdJVz0UNshRyPbaH7d8XnkJA0ZeKcTJnUEMtjwJ
  43.122 +t5HnJE5aUbilAxBm+3bhmHrmcExXW7OgtbX9Nb8R7Yg7CX6Bgc1t8cRTuGT+sfFC
  43.123 +7jOFijjxNApGQfKC4cuCTx5J6P62FSc=
  43.124 +=orc1
  43.125 +-----END PGP MESSAGE-----
  43.126 +
  43.127 +--2eb141f241b71efb79e2a9e37545e146--