ENGINE-289: oops - combined merging in of default and adding pref for update_identity to select an own_identity from the DB when it has a choice and the input only has an address. ENGINE-289
authorKrista Bennett <krista@pep-project.org>
Tue, 16 Jan 2018 23:31:06 +0100
branchENGINE-289
changeset 23952b7294a57041
parent 2394 88b9027db1bf
parent 2393 d40873a44181
child 2396 f9015ee2527c
ENGINE-289: oops - combined merging in of default and adding pref for update_identity to select an own_identity from the DB when it has a choice and the input only has an address.
src/keymanagement.c
src/message_api.c
src/pEp_internal.h
test/message_2.0_test.cc
     1.1 --- a/src/bloblist.c	Tue Jan 16 14:14:01 2018 +0100
     1.2 +++ b/src/bloblist.c	Tue Jan 16 23:31:06 2018 +0100
     1.3 @@ -1,17 +1,17 @@
     1.4  // This file is under GNU General Public License 3.0
     1.5  // see LICENSE.txt
     1.6  
     1.7 -#include "pEp_internal.h"
     1.8 -
     1.9 +#include <stdbool.h>
    1.10  #include <stdlib.h>
    1.11  #include <assert.h>
    1.12  #include <string.h>
    1.13  
    1.14 +#include "platform.h"
    1.15  #include "bloblist.h"
    1.16  
    1.17  static bool set_blob_data(bloblist_t* bloblist, char* blob, size_t size, const char* mime_type,
    1.18 -                          const char* filename) {
    1.19 -    
    1.20 +        const char* filename)
    1.21 +{
    1.22      if (!bloblist)
    1.23          return false;
    1.24          
    1.25 @@ -30,9 +30,8 @@
    1.26         }
    1.27         /* Default behaviour, can be overwritten post-allocation with
    1.28            set_blob_content_disposition */
    1.29 -       if (strstr(filename, "cid://") == filename)
    1.30 +       if (strncmp(filename, "cid://", 6) == 0)
    1.31             bloblist->disposition = PEP_CONTENT_DISP_INLINE;
    1.32 -                        
    1.33      }               
    1.34      
    1.35      if (blob) {
    1.36 @@ -65,7 +64,10 @@
    1.37  
    1.38      while (curr) {
    1.39          bloblist_t *next = curr->next;
    1.40 -        free(curr->value);
    1.41 +        if (curr->release_value)
    1.42 +            curr->release_value(curr->value);
    1.43 +        else
    1.44 +            free(curr->value);
    1.45          free(curr->mime_type);
    1.46          free(curr->filename);
    1.47          free(curr);
    1.48 @@ -126,14 +128,15 @@
    1.49          const char *mime_type, const char *filename)
    1.50  {
    1.51      assert(blob);
    1.52 -    if (blob == NULL)
    1.53 +    if (!blob)
    1.54          return NULL;
    1.55  
    1.56 -    if (bloblist == NULL)
    1.57 +    if (!bloblist)
    1.58          return new_bloblist(blob, size, mime_type, filename);
    1.59  
    1.60 -    if (bloblist->value == NULL) { // empty list
    1.61 -        if (bloblist->next != NULL)
    1.62 +    if (!bloblist->value) { // empty list
    1.63 +        assert(!bloblist->next);
    1.64 +        if (bloblist->next)
    1.65              return NULL; // invalid list
    1.66              
    1.67          if (!set_blob_data(bloblist, blob, size, mime_type, filename)) {
    1.68 @@ -145,18 +148,19 @@
    1.69      }
    1.70  
    1.71      bloblist_t* list_curr = bloblist;
    1.72 +    void (*release_value)(char *) = list_curr->release_value;
    1.73  
    1.74      while (list_curr->next)
    1.75          list_curr = list_curr->next;
    1.76  
    1.77      list_curr->next = new_bloblist(blob, size, mime_type, filename);
    1.78 +    list_curr->release_value = release_value;
    1.79  
    1.80      assert(list_curr->next);
    1.81 -    if (list_curr->next == NULL)
    1.82 +    if (!list_curr->next)
    1.83          return NULL;
    1.84  
    1.85      return list_curr->next;
    1.86 -
    1.87  }
    1.88  
    1.89  DYNAMIC_API int bloblist_length(const bloblist_t *bloblist)
    1.90 @@ -170,7 +174,8 @@
    1.91  }
    1.92  
    1.93  DYNAMIC_API void set_blob_disposition(bloblist_t* blob, 
    1.94 -                                      content_disposition_type disposition) {
    1.95 +        content_disposition_type disposition)
    1.96 +{
    1.97      if (blob)                                    
    1.98          blob->disposition = disposition;
    1.99  }
     2.1 --- a/src/bloblist.h	Tue Jan 16 14:14:01 2018 +0100
     2.2 +++ b/src/bloblist.h	Tue Jan 16 23:31:06 2018 +0100
     2.3 @@ -17,15 +17,18 @@
     2.4  } content_disposition_type;
     2.5  
     2.6  typedef struct _bloblist_t {
     2.7 -    char *value;                    // blob
     2.8 -    size_t size;                    // size of blob
     2.9 -    char *mime_type;                // UTF-8 string of MIME type of blob or
    2.10 -                                    // NULL if unknown
    2.11 -    char *filename;                // UTF-8 string of file name of blob or
    2.12 -                                    // NULL if unknown
    2.13 -    content_disposition_type disposition; // default is attachment when allocated
    2.14 -                                          // (see mime.h and RFC2183)
    2.15 -    struct _bloblist_t *next;
    2.16 +    char *value;                        // blob
    2.17 +    size_t size;                        // size of blob
    2.18 +    char *mime_type;                    // UTF-8 string of MIME type of blob or
    2.19 +                                        // NULL if unknown
    2.20 +    char *filename;                     // UTF-8 string of file name of blob or
    2.21 +                                        // NULL if unknown
    2.22 +    content_disposition_type disposition;
    2.23 +                                        // default is attachment when allocated
    2.24 +                                        // (see mime.h and RFC2183)
    2.25 +    struct _bloblist_t *next;           // this is a single linked list
    2.26 +    void (*release_value)(char *);      // pointer to release function;
    2.27 +                                        // pEp_free() if not set
    2.28  } bloblist_t;
    2.29  
    2.30  
    2.31 @@ -43,6 +46,10 @@
    2.32  //  caveat:
    2.33  //      the ownership of the blob goes to the bloblist; mime_type and filename
    2.34  //      are being copied, the originals remain in the ownership of the caller
    2.35 +//
    2.36 +//      if blob is on a different heap then after the call release_value has to
    2.37 +//      be set by the adapter; this is relevant on operating systems with
    2.38 +//      multiple heaps like Microsoft Windows
    2.39  
    2.40  DYNAMIC_API bloblist_t *new_bloblist(char *blob, size_t size, const char *mime_type,
    2.41          const char *filename);
    2.42 @@ -69,6 +76,7 @@
    2.43  
    2.44  DYNAMIC_API bloblist_t *bloblist_dup(const bloblist_t *src);
    2.45  
    2.46 +
    2.47  // bloblist_add() - add reference to a blob to bloblist
    2.48  //
    2.49  //  parameters:
    2.50 @@ -87,6 +95,9 @@
    2.51  //      are being copied, the originals remain in the ownership of the caller.
    2.52  //      bloblist input parameter equal to NULL or with value == NULL is a valid
    2.53  //      empty input list.
    2.54 +//
    2.55 +//      If there is release_value set in bloblist it is copied to the added
    2.56 +//      leaf
    2.57  
    2.58  DYNAMIC_API bloblist_t *bloblist_add(bloblist_t *bloblist, char *blob, size_t size,
    2.59          const char *mime_type, const char *filename);
    2.60 @@ -102,6 +113,7 @@
    2.61  
    2.62  DYNAMIC_API int bloblist_length(const bloblist_t *bloblist);
    2.63  
    2.64 +
    2.65  // set_blob_content_disposition() - set blob content disposition and parameters
    2.66  //                                  when necessary
    2.67  //
    2.68 @@ -110,9 +122,7 @@
    2.69  //      disposition (in)        disposition type (see enum)
    2.70  
    2.71  DYNAMIC_API void set_blob_disposition(bloblist_t* blob, 
    2.72 -                                              content_disposition_type disposition);
    2.73 -
    2.74 -
    2.75 +        content_disposition_type disposition);
    2.76  
    2.77  
    2.78  #ifdef __cplusplus
     3.1 --- a/src/keymanagement.c	Tue Jan 16 14:14:01 2018 +0100
     3.2 +++ b/src/keymanagement.c	Tue Jan 16 23:31:06 2018 +0100
     3.3 @@ -548,40 +548,52 @@
     3.4           * Temporary identity information with username supplied
     3.5              * Input: address, username (no others)
     3.6           */
     3.7 -        identity_list* id_list = NULL;
     3.8 -        status = get_identities_by_address(session, identity->address, &id_list);
     3.9 +         
    3.10 +        //  * See if there is an own identity that uses this address. If so, we'll
    3.11 +        //    prefer that
    3.12 +        stored_ident = NULL;
    3.13 +        
    3.14 +        if (default_own_id) {
    3.15 +            status = get_identity(session, 
    3.16 +                                  default_own_id, 
    3.17 +                                  identity->address, 
    3.18 +                                  &stored_ident);
    3.19 +        }
    3.20 +        // If there isn't an own identity, search for a non-temp stored ident
    3.21 +        // with this address.                      
    3.22 +        if (status == PEP_CANNOT_FIND_IDENTITY || !stored_ident) { 
    3.23 + 
    3.24 +            identity_list* id_list = NULL;
    3.25 +            status = get_identities_by_address(session, identity->address, &id_list);
    3.26  
    3.27 -        //  * Search for an identity with non-temporary user_id with that mapping
    3.28 -        if (id_list) {
    3.29 -            identity_list* id_curr = id_list;
    3.30 -            while (id_curr) {
    3.31 -                pEp_identity* this_id = id_curr->ident;
    3.32 -                if (this_id) {
    3.33 -                    char* this_uid = this_id->user_id;
    3.34 -                    if (this_uid && (strstr(this_uid, "TOFU_") != this_uid)) {
    3.35 -                        // FIXME: should we also be fixing pEp_own_userId in this
    3.36 -                        // function here?
    3.37 -                        
    3.38 -                        // if usernames match, we replace the userid.
    3.39 -                        if (identity->username && 
    3.40 -                            strcasecmp(identity->username, 
    3.41 -                                       this_id->username) == 0) {
    3.42 -                            
    3.43 -                            // Ok, we have a real ID. Copy it!
    3.44 -                            identity->user_id = strdup(this_uid);
    3.45 -                            
    3.46 -                            if (!identity->user_id)
    3.47 -                                status = PEP_OUT_OF_MEMORY;
    3.48 -                            stored_ident = this_id;
    3.49 -                            
    3.50 -                            break;                                
    3.51 -                        }                            
    3.52 -                    } 
    3.53 +            if (id_list) {
    3.54 +                identity_list* id_curr = id_list;
    3.55 +                while (id_curr) {
    3.56 +                    pEp_identity* this_id = id_curr->ident;
    3.57 +                    if (this_id) {
    3.58 +                        char* this_uid = this_id->user_id;
    3.59 +                        if (this_uid && (strstr(this_uid, "TOFU_") != this_uid)) {
    3.60 +                            // if usernames match, we replace the userid.
    3.61 +                            if (identity->username && 
    3.62 +                                strcasecmp(identity->username, 
    3.63 +                                           this_id->username) == 0) {
    3.64 +                                
    3.65 +                                // Ok, we have a real ID. Copy it!
    3.66 +                                identity->user_id = strdup(this_uid);
    3.67 +                                
    3.68 +                                if (!identity->user_id)
    3.69 +                                    status = PEP_OUT_OF_MEMORY;
    3.70 +                                stored_ident = this_id;
    3.71 +                                
    3.72 +                                break;                                
    3.73 +                            }                            
    3.74 +                        } 
    3.75 +                    }
    3.76 +                    id_curr = id_curr->next;
    3.77                  }
    3.78 -                id_curr = id_curr->next;
    3.79              }
    3.80          }
    3.81 -
    3.82 +        
    3.83          if (stored_ident) {
    3.84              status = prepare_updated_identity(session,
    3.85                                                identity,
    3.86 @@ -616,22 +628,35 @@
    3.87           * Temporary identity information without username suplied
    3.88              * Input: address (no others)
    3.89           */
    3.90 -        identity_list* id_list = NULL;
    3.91 -        status = get_identities_by_address(session, identity->address, &id_list);
    3.92 +         
    3.93 +        //  * Again, see if there is an own identity that uses this address. If so, we'll
    3.94 +        //    prefer that
    3.95 +        stored_ident = NULL;
    3.96 +         
    3.97 +        if (default_own_id) {
    3.98 +            status = get_identity(session, 
    3.99 +                                  default_own_id, 
   3.100 +                                  identity->address, 
   3.101 +                                  &stored_ident);
   3.102 +        }
   3.103 +        // If there isn't an own identity, search for a non-temp stored ident
   3.104 +        // with this address.                      
   3.105 +        if (status == PEP_CANNOT_FIND_IDENTITY || !stored_ident) { 
   3.106 + 
   3.107 +            identity_list* id_list = NULL;
   3.108 +            status = get_identities_by_address(session, identity->address, &id_list);
   3.109  
   3.110 -        //    * Search for identity with this address
   3.111 -        if (id_list && !(id_list->next)) { // exactly one            
   3.112 -            //    * If exactly one found
   3.113 -            //      * elect valid key for identity (see below)
   3.114 -            //      * Return this identity
   3.115 -            stored_ident = id_list->ident;
   3.116 -            
   3.117 -            if (stored_ident)
   3.118 -                status = prepare_updated_identity(session, identity,
   3.119 -                                                  stored_ident, false);
   3.120 -            else
   3.121 -                status = PEP_CANNOT_FIND_IDENTITY;
   3.122 +            //    * Search for identity with this address
   3.123 +            if (id_list && !(id_list->next)) { // exactly one            
   3.124 +                //    * If exactly one found
   3.125 +                //      * elect valid key for identity (see below)
   3.126 +                //      * Return this identity
   3.127 +                stored_ident = id_list->ident;
   3.128 +            }
   3.129          }
   3.130 +        if (stored_ident)
   3.131 +            status = prepare_updated_identity(session, identity,
   3.132 +                                              stored_ident, false);
   3.133          else // too little info
   3.134              status = PEP_CANNOT_FIND_IDENTITY; 
   3.135      }
     4.1 --- a/src/message_api.c	Tue Jan 16 14:14:01 2018 +0100
     4.2 +++ b/src/message_api.c	Tue Jan 16 23:31:06 2018 +0100
     4.3 @@ -3282,6 +3282,7 @@
     4.4      if (tmp_msg->from) {
     4.5          char* own_id = NULL;
     4.6          status = get_default_own_userid(session, &own_id);
     4.7 +        free(tmp_msg->from->user_id);
     4.8          
     4.9          if (status != PEP_STATUS_OK || !own_id) {
    4.10              tmp_msg->from->user_id = strdup(PEP_OWN_USERID);
     5.1 --- a/src/pEp_internal.h	Tue Jan 16 14:14:01 2018 +0100
     5.2 +++ b/src/pEp_internal.h	Tue Jan 16 23:31:06 2018 +0100
     5.3 @@ -82,7 +82,6 @@
     5.4  #include "sqlite3.h"
     5.5  #endif
     5.6  
     5.7 -#define _EXPORT_PEP_ENGINE_DLL
     5.8  #include "pEpEngine.h"
     5.9  
    5.10  // If not specified, build for GPG
     6.1 --- a/src/platform_windows.h	Tue Jan 16 14:14:01 2018 +0100
     6.2 +++ b/src/platform_windows.h	Tue Jan 16 23:31:06 2018 +0100
     6.3 @@ -5,15 +5,16 @@
     6.4  
     6.5  // Windows platform specifica
     6.6  
     6.7 +#define _EXPORT_PEP_ENGINE_DLL
     6.8  #pragma warning(disable : 4996)
     6.9  
    6.10 -// We need to make sure winsock2 is included before windows.h, or we will get redefinitions of symbols
    6.11 -// as windows.h includes winsock1.h, so we will have duplicate symbols if windows.h is included first.
    6.12 -// It seems some of our code includes sync.h before including winsock.h, leading to the failure.
    6.13 -// Including winsock2.h here fixes the problem for now...
    6.14 -#ifdef WIN32 
    6.15 -#include <winsock2.h>
    6.16 -#endif // WIN32 
    6.17 +// We need to make sure winsock2 is included before windows.h, or we will get redefinitions of symbols
    6.18 +// as windows.h includes winsock1.h, so we will have duplicate symbols if windows.h is included first.
    6.19 +// It seems some of our code includes sync.h before including winsock.h, leading to the failure.
    6.20 +// Including winsock2.h here fixes the problem for now...
    6.21 +#ifdef WIN32 
    6.22 +#include <winsock2.h>
    6.23 +#endif // WIN32 
    6.24  
    6.25  #include <Rpc.h>
    6.26  #include <string.h>
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/test/message_2.0_test.cc	Tue Jan 16 23:31:06 2018 +0100
     7.3 @@ -0,0 +1,168 @@
     7.4 +// This file is under GNU General Public License 3.0
     7.5 +// see LICENSE.txt
     7.6 +
     7.7 +#include <stdlib.h>
     7.8 +#include <string.h>
     7.9 +#include "platform.h"
    7.10 +#include <iostream>
    7.11 +#include <fstream>
    7.12 +#include <assert.h>
    7.13 +#include "mime.h"
    7.14 +#include "message_api.h"
    7.15 +#include "keymanagement.h"
    7.16 +#include "test_util.h"
    7.17 +
    7.18 +using namespace std;
    7.19 +
    7.20 +int main() {
    7.21 +    cout << "\n*** message_2.0_test ***\n\n";
    7.22 +
    7.23 +    PEP_SESSION session;
    7.24 +    
    7.25 +    cout << "calling init()\n";
    7.26 +    PEP_STATUS status1 = init(&session);
    7.27 +    assert(status1 == PEP_STATUS_OK);
    7.28 +    assert(session);
    7.29 +    cout << "init() completed.\n";
    7.30 +
    7.31 +    PEP_comm_type carol_comm_type = PEP_ct_OpenPGP_unconfirmed;
    7.32 +
    7.33 +    // message_api test code
    7.34 +
    7.35 +    const string alice_pub_key = slurp("test_keys/pub/pep-test-alice-0x6FF00E97_pub.asc");
    7.36 +    const string alice_priv_key = slurp("test_keys/priv/pep-test-alice-0x6FF00E97_priv.asc");
    7.37 +    const string carol_pub_key = slurp("test_keys/pub/pep-test-carol-0x42A85A42_pub.asc");
    7.38 +    const string carol_priv_key = slurp("test_keys/priv/pep-test-carol-0x42A85A42_priv.asc");
    7.39 +
    7.40 +    PEP_STATUS statuspub = import_key(session, alice_pub_key.c_str(), alice_pub_key.length(), NULL);
    7.41 +    PEP_STATUS statuspriv = import_key(session, alice_priv_key.c_str(), alice_priv_key.length(), NULL);
    7.42 +    assert(statuspub == PEP_STATUS_OK);
    7.43 +    assert(statuspriv == PEP_STATUS_OK);
    7.44 +    statuspub = import_key(session, carol_pub_key.c_str(), carol_pub_key.length(), NULL);
    7.45 +    statuspriv = import_key(session, carol_priv_key.c_str(), carol_priv_key.length(), NULL);
    7.46 +    assert(statuspub == PEP_STATUS_OK);
    7.47 +    assert(statuspriv == PEP_STATUS_OK);
    7.48 +
    7.49 +    cout << "creating message…\n";
    7.50 +    pEp_identity* alice = new_identity("pep.test.alice@pep-project.org", "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97", PEP_OWN_USERID, "Alice Test");
    7.51 +    pEp_identity* carol = new_identity("pep-test-carol@pep-project.org", NULL, "TOFU_pep-test-carol@pep-project.org", "Carol Test");
    7.52 +
    7.53 +    PEP_STATUS alice_status = update_identity(session, alice);
    7.54 +    PEP_STATUS carol_status = update_identity(session, carol);
    7.55 +
    7.56 +    PEP_STATUS status = update_trust_for_fpr(session, alice->fpr, PEP_ct_pEp);
    7.57 +    status = update_trust_for_fpr(session, carol->fpr, carol_comm_type);
    7.58 +    
    7.59 +    PEP_STATUS mystatus = myself(session, alice);
    7.60 +    assert(mystatus == PEP_STATUS_OK);
    7.61 +    alice_status = update_identity(session, alice);
    7.62 +    alice_status = update_identity(session, carol);
    7.63 +    assert(alice->comm_type == PEP_ct_pEp);
    7.64 +    assert(carol->comm_type == carol_comm_type);
    7.65 +    
    7.66 +    identity_list* to_list = new_identity_list(carol); // to carol
    7.67 +    message* outgoing_message = new_message(PEP_dir_outgoing);
    7.68 +    assert(outgoing_message);
    7.69 +    outgoing_message->from = alice;
    7.70 +    outgoing_message->to = to_list;
    7.71 +    outgoing_message->shortmsg = strdup("Greetings, humans!");
    7.72 +    outgoing_message->longmsg = strdup("This is a test of the emergency message system. This is only a test. BEEP.");
    7.73 +    outgoing_message->attachments = new_bloblist(NULL, 0, "application/octet-stream", NULL);
    7.74 +//    outgoing_message->id = strdup("blahblahyourmama@pep-project.org");
    7.75 +    outgoing_message->references = new_stringlist("one-839274982347239847@pep-project.org");
    7.76 +    stringlist_add(outgoing_message->references, "two-dfddffd839274982347239847@pep-project.org");
    7.77 +    stringlist_add(outgoing_message->references, "three-OMGWTFBBQ.edfddffd839274982347239847@pep-project.org");
    7.78 +    
    7.79 +    cout << "message created.\n";
    7.80 +
    7.81 +    char* encoded_text = nullptr;
    7.82 +    status = mime_encode_message(outgoing_message, false, &encoded_text);
    7.83 +    assert(status == PEP_STATUS_OK);
    7.84 +    assert(encoded_text);
    7.85 +
    7.86 +    cout << "unencrypted:\n\n";
    7.87 +    cout << encoded_text << "\n";
    7.88 +
    7.89 +    free(encoded_text);
    7.90 +
    7.91 +    cout << "encrypting message as MIME multipart…\n";
    7.92 +    message* encrypted_msg = nullptr;
    7.93 +    cout << "calling encrypt_message\n";
    7.94 +    status = encrypt_message(session, outgoing_message, NULL, 
    7.95 +        &encrypted_msg, PEP_enc_PGP_MIME, 0);
    7.96 +    cout << "encrypt_message() returns " << std::hex << status << '.' << endl;
    7.97 +    assert(status == PEP_STATUS_OK);
    7.98 +    assert(encrypted_msg);
    7.99 +    cout << "message encrypted.\n";
   7.100 +    
   7.101 +    encrypted_msg->enc_format = PEP_enc_none;
   7.102 +    status = mime_encode_message(encrypted_msg, false, &encoded_text);
   7.103 +    assert(status == PEP_STATUS_OK);
   7.104 +    assert(encoded_text);
   7.105 +     
   7.106 +    cout << "encrypted:\n\n";
   7.107 +    cout << encoded_text << "\n";
   7.108 +     
   7.109 +    char* decrypted_text;
   7.110 +    
   7.111 +    message* decrypted_msg = nullptr;
   7.112 +    stringlist_t* keylist_used = nullptr;
   7.113 +    
   7.114 +    PEP_rating rating;
   7.115 +    PEP_decrypt_flags_t flags;
   7.116 +     
   7.117 +//    MIME_decrypt_message(session, encoded_text, strlen(encoded_text), &decrypted_text, &keylist_used, &rating, &flags);
   7.118 +    
   7.119 +//    cout << "HEY!" << endl;
   7.120 +//    cout << decrypted_text << endl;
   7.121 +    
   7.122 +    message* decoded_msg = nullptr;
   7.123 +    status = mime_decode_message(encoded_text, strlen(encoded_text), &decoded_msg);
   7.124 +    assert(status == PEP_STATUS_OK);
   7.125 +    const string string3 = encoded_text;
   7.126 +      
   7.127 +    unlink("msg_2.0.asc");
   7.128 +    ofstream outFile3("msg_2.0.asc");
   7.129 +    outFile3.write(string3.c_str(), string3.size());
   7.130 +    outFile3.close();
   7.131 +    
   7.132 +    // message* decrypted_msg = nullptr;
   7.133 +    // stringlist_t* keylist_used = nullptr;
   7.134 +    // 
   7.135 +    // PEP_rating rating;
   7.136 +    // PEP_decrypt_flags_t flags;
   7.137 +    // 
   7.138 +    stringpair_t* autoconsume = new_stringpair("pEp-auto-consume", "yes");
   7.139 +    stringpair_list_add(encrypted_msg->opt_fields, autoconsume);
   7.140 +    status = decrypt_message(session, encrypted_msg, &decrypted_msg, &keylist_used, &rating, &flags);
   7.141 +    assert(decrypted_msg);
   7.142 +    assert(keylist_used);
   7.143 +    assert(rating);
   7.144 +    //assert(status == PEP_STATUS_OK && rating == PEP_rating_reliable);
   7.145 +    //PEP_comm_type ct = encrypted_msg->from->comm_type;
   7.146 +    //assert(ct == PEP_ct_pEp);
   7.147 +    
   7.148 +    cout << "keys used:\n";
   7.149 +    
   7.150 +    for (stringlist_t* kl4 = keylist_used; kl4 && kl4->value; kl4 = kl4->next)
   7.151 +    {
   7.152 +       cout << "\t " << kl4->value << endl;
   7.153 +    }
   7.154 +     
   7.155 +    decrypted_msg->enc_format = PEP_enc_none; 
   7.156 +    status = _mime_encode_message_internal(decrypted_msg, false, &encoded_text, false);
   7.157 +    assert(status == PEP_STATUS_OK);
   7.158 +    assert(encoded_text);
   7.159 +    cout << "Decrypted message: " << endl;
   7.160 +    cout << encoded_text << endl;
   7.161 +     
   7.162 +    cout << "freeing messages…\n";
   7.163 +    free_message(encrypted_msg);
   7.164 +    free_message(decrypted_msg);
   7.165 +    free_message(outgoing_message);
   7.166 +    cout << "done.\n";
   7.167 +    
   7.168 +    cout << "calling release()\n";
   7.169 +    release(session);
   7.170 +    return 0;
   7.171 +}