test/src/engine_tests/DeviceModelTests.cc
author Krista 'DarthMama' Bennett <krista@pep.foundation>
Tue, 26 Feb 2019 08:43:48 +0100
branchsync_test_refactor
changeset 3320 49df110e65d2
parent 3307 b3d26f9f0225
permissions -rw-r--r--
Changed device tests to account for sync mails (gee, when you try to make something work automatically, it works, uh, automativcally\!
     1 // This file is under GNU General Public License 3.0
     2 // see LICENSE.txt
     3 
     4 #include <stdlib.h>
     5 #include <string>
     6 #include <sys/stat.h>
     7 #include <errno.h>
     8 #include <unistd.h>
     9 #include <assert.h>
    10 #include <fstream>
    11 #include <iostream>
    12 #include <sys/types.h>
    13 
    14 #include "pEpEngine.h"
    15 #include "mime.h"
    16 
    17 #include "TestUtils.h"
    18 #include "EngineTestIndividualSuite.h"
    19 #include "DeviceModelTests.h"
    20 #include <cpptest.h>
    21 #include <cstring>
    22 
    23 using namespace std;
    24 
    25 static void remove_sync_mails(vector<message*> &mails) {
    26     for (vector<message*>::iterator it = mails.begin(); it != mails.end(); ) {
    27         stringpair_list_t* opt_fields = (*it)->opt_fields;
    28         bool erased = false;
    29         while (opt_fields && opt_fields->value && opt_fields->value->key && opt_fields->value->value) {
    30             if (strcmp(opt_fields->value->key, "pEp-auto-consume") == 0 &&
    31                 strcmp(opt_fields->value->value, "yes") == 0) {
    32                 it = mails.erase(it);
    33                 erased = true;
    34             }
    35             opt_fields = opt_fields->next;
    36         }
    37         if (!erased)
    38             it++;
    39     }
    40 }
    41 
    42 DeviceModelTests::DeviceModelTests(string suitename, string test_home_dir) :
    43     EngineTestIndividualSuite::EngineTestIndividualSuite(suitename, test_home_dir, false) {
    44     add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("DeviceModelTests::check_device_model"),
    45                                                                       static_cast<Func>(&DeviceModelTests::check_device_model)));
    46     add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("DeviceModelTests::check_two_device_model"),
    47                                                                       static_cast<Func>(&DeviceModelTests::check_two_device_model)));
    48     add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("DeviceModelTests::check_two_device_functionality"),
    49                                                                       static_cast<Func>(&DeviceModelTests::check_two_device_functionality)));
    50     add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("DeviceModelTests::check_mbox"),
    51                                                                       static_cast<Func>(&DeviceModelTests::check_mbox)));
    52     add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("DeviceModelTests::check_three_device_mbox_with_send"),
    53                                                                       static_cast<Func>(&DeviceModelTests::check_three_device_mbox_with_send)));
    54     add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("DeviceModelTests::check_switch_context"),
    55                                                                       static_cast<Func>(&DeviceModelTests::check_switch_context)));
    56 }
    57 
    58 void DeviceModelTests::setup() {
    59     EngineTestIndividualSuite::setup();
    60     pEpTestDevice::active = NULL;
    61 }
    62 
    63 void DeviceModelTests::tear_down() {
    64     for (vector<pEpTestDevice*>::iterator it = devices.begin();
    65                                          it != devices.end(); it++)
    66         delete(*it);                                         
    67     devices.clear();
    68     EngineTestIndividualSuite::tear_down();
    69 }
    70 
    71 void DeviceModelTests::check_device_model() {
    72     pEpTestDevice* single = new pEpTestDevice(temp_test_home, "SingleDevice");
    73     TEST_ASSERT_MSG(device == NULL, "EngineTestSuite created device when it should not have.");
    74     TEST_ASSERT_MSG(session == NULL, "EngineTestSuite has a default session - not cool.");    
    75     TEST_ASSERT_MSG(single->session, "Device has no session.");
    76 
    77     single->set_mailbox_dir(single->device_dir + "/mbox");
    78     const string mbox_dir = single->mbox_dir;
    79     struct stat dirchk;
    80     TEST_ASSERT_MSG(stat(mbox_dir.c_str(), &dirchk) == 0,
    81                     "Device mbox dir not created.");
    82     TEST_ASSERT_MSG(S_ISDIR(dirchk.st_mode), "Device mbox dir exists, but isn't a directory.");                
    83 
    84     const string device_dir = string(single->device_dir);
    85     delete(single);
    86     TEST_ASSERT_MSG(stat(device_dir.c_str(), &dirchk) != 0,
    87                          "Device dir not removed.");
    88 }
    89 
    90 void DeviceModelTests::check_two_device_model() {
    91     pEpTestDevice* first_device = new pEpTestDevice(temp_test_home, "First");
    92     devices.push_back(first_device);
    93     first_device->set_mailbox_dir(first_device->device_dir + "/mbox");
    94     string homedir = getenv("HOME");
    95     TEST_ASSERT_MSG(strcmp(homedir.c_str(), first_device->device_dir.c_str()) == 0, "First device didn't set $HOME correctly.");
    96     string gpgdir = getenv("GNUPGHOME");
    97     TEST_ASSERT_MSG(strcmp(gpgdir.c_str(), (first_device->device_dir + "/gnupg").c_str()) == 0, "First device didn't set $GNUPGHOME correctly.");    
    98 
    99     pEpTestDevice* second_device = new pEpTestDevice(temp_test_home, "Second");
   100     devices.push_back(second_device);
   101     homedir = getenv("HOME");
   102     TEST_ASSERT_MSG(strcmp(homedir.c_str(), second_device->device_dir.c_str()) == 0, "Second device didn't set $HOME correctly");
   103     gpgdir = getenv("GNUPGHOME");
   104     TEST_ASSERT_MSG(strcmp(gpgdir.c_str(), (second_device->device_dir + "/gnupg").c_str()) == 0, "Second device didn't set $GNUPGHOME correctly.");    
   105     second_device->set_mailbox_dir(first_device->device_dir + "/mbox");
   106     first_device->grab_context(second_device);
   107     homedir = getenv("HOME");
   108     TEST_ASSERT_MSG(strcmp(homedir.c_str(), first_device->device_dir.c_str()) == 0, "First device failed to grab context.");
   109     gpgdir = getenv("GNUPGHOME");
   110     TEST_ASSERT_MSG(strcmp(gpgdir.c_str(), (first_device->device_dir + "/gnupg").c_str()) == 0, "First device context switch didn't set $GNUPGHOME correctly.");    
   111     second_device->grab_context(first_device);
   112     homedir = getenv("HOME");
   113     TEST_ASSERT_MSG(strcmp(homedir.c_str(), second_device->device_dir.c_str()) == 0, "Second device failed to grab context.");
   114     gpgdir = getenv("GNUPGHOME");
   115     TEST_ASSERT_MSG(strcmp(gpgdir.c_str(), (second_device->device_dir + "/gnupg").c_str()) == 0, "Second device context switch didn't set $GNUPGHOME correctly.");        
   116 }
   117 
   118 void DeviceModelTests::check_two_device_functionality() {
   119     // Set up devices and shared mailbox
   120     pEpTestDevice* first_device = new pEpTestDevice(temp_test_home, "First");
   121     devices.push_back(first_device);    
   122     first_device->set_mailbox_dir(first_device->device_dir + "/mbox");
   123     
   124     pEpTestDevice* second_device = new pEpTestDevice(temp_test_home, "Second");
   125     devices.push_back(second_device);    
   126     second_device->set_mailbox_dir(first_device->device_dir + "/mbox");
   127 
   128     first_device->grab_context(second_device);
   129     TEST_ASSERT_MSG(first_device->mbox_dir.compare(second_device->mbox_dir) == 0,
   130                     "Shared mailbox is not really shared");
   131 
   132     string alice_email = "pep.test.alice@pep-project.org";
   133     string alice_fpr = "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97";
   134     
   135     // First device is Alice's established one with the current key
   136     TEST_ASSERT_MSG(slurp_and_import_key(first_device->session, "test_keys/pub/pep-test-alice-0x6FF00E97_pub.asc"),
   137                     "Alice's pubkey not imported for first device.");
   138     TEST_ASSERT_MSG(slurp_and_import_key(first_device->session, "test_keys/priv/pep-test-alice-0x6FF00E97_priv.asc"),
   139                     "Alice's privkey not imported for first device.");
   140 
   141     pEp_identity* alice_dev_1_ident = new_identity(alice_email.c_str(), alice_fpr.c_str(), "ALICE", "Alice From Mel's Diner");
   142     
   143     PEP_STATUS status = set_own_key(first_device->session, alice_dev_1_ident, alice_fpr.c_str());    
   144     TEST_ASSERT_MSG(status == PEP_STATUS_OK, 
   145         (string("Unable to set own key on first device. status is ") + tl_status_string(status)).c_str());
   146 
   147     free(alice_dev_1_ident->fpr);
   148     alice_dev_1_ident->fpr = NULL;
   149     status = myself(first_device->session, alice_dev_1_ident);
   150     TEST_ASSERT(alice_dev_1_ident->fpr);
   151     TEST_ASSERT_MSG(alice_fpr.compare(alice_dev_1_ident->fpr) == 0,
   152                     "set_own_key does not seem to have set alice's key for device 1.");
   153                 
   154     second_device->grab_context(first_device);
   155 
   156     pEp_identity* alice_dev_2_ident = new_identity(alice_email.c_str(), NULL, PEP_OWN_USERID, "Alice Miller");
   157     // Second device is one Alice is setting up (we'll use this model for keysync tests, so why not?)
   158 
   159     status = myself(second_device->session, alice_dev_2_ident);
   160 
   161     TEST_ASSERT_MSG(alice_dev_2_ident->fpr, "No fpr for alice on second device");
   162     TEST_ASSERT_MSG(alice_fpr.compare(alice_dev_2_ident->fpr) != 0,
   163                     "myself did not generate new key for alice on device 2; alice's old key was found.");
   164     
   165     const char* alice_2_fpr = alice_dev_2_ident->fpr;
   166     
   167     first_device->grab_context(second_device);
   168     
   169     stringlist_t* keylist = NULL;
   170     
   171     status = find_keys(first_device->session, alice_2_fpr, &keylist);
   172     
   173     TEST_ASSERT(!keylist);
   174     TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   175     free_stringlist(keylist);
   176     keylist = NULL;
   177 
   178     second_device->grab_context(first_device);
   179     
   180     char* alice_2_keydata = NULL;
   181     size_t alice_2_keydata_size = 0;
   182     
   183     status = export_key(second_device->session, alice_2_fpr, &alice_2_keydata, &alice_2_keydata_size);
   184 
   185     TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   186     TEST_ASSERT(alice_2_keydata);
   187     
   188     first_device->grab_context(second_device);
   189 
   190     status = import_key(first_device->session, alice_2_keydata, alice_2_keydata_size, NULL);
   191 
   192     free(alice_2_keydata);
   193     alice_2_keydata = NULL;
   194 
   195     status = find_keys(first_device->session, alice_2_fpr, &keylist);    
   196     TEST_ASSERT(keylist);
   197     TEST_ASSERT(status == PEP_STATUS_OK);
   198     free_stringlist(keylist);
   199     keylist = NULL;
   200 
   201     second_device->grab_context(first_device);
   202     TEST_ASSERT_MSG(slurp_and_import_key(second_device->session, "test_keys/pub/pep-test-alice-0x6FF00E97_pub.asc"),
   203                     "Alice's first pubkey not imported for second device.");
   204 
   205     // Ok, so, we're relatively certain we have all that set up. Now let's have both
   206     // import Bob's key, but only one of them trust it. Then we're sure we have 
   207     // different, functioning trust dbs, and we're done with this case and ready 
   208     // to move on to checking mboxes
   209     string bob_fpr = "BFCDB7F301DEEEBBF947F29659BFF488C9C2EE39";
   210     TEST_ASSERT_MSG(slurp_and_import_key(second_device->session, "test_keys/pub/pep-test-bob-0xC9C2EE39_pub.asc"), 
   211                     "Second device couldn't import Bob's pubkey");
   212     pEp_identity* bob_id = new_identity("pep.test.bob@pep-project.org", NULL, NULL, "Bob Barker");    
   213     status = update_identity(second_device->session, bob_id);
   214     TEST_ASSERT(status == PEP_STATUS_OK);
   215     TEST_ASSERT(bob_id->fpr);
   216     TEST_ASSERT(bob_fpr.compare(bob_id->fpr) == 0);
   217 
   218     status = trust_personal_key(second_device->session, bob_id);
   219     TEST_ASSERT(status == PEP_STATUS_OK);
   220     status = update_identity(second_device->session, bob_id);
   221     TEST_ASSERT(status == PEP_STATUS_OK);
   222     TEST_ASSERT(bob_id->comm_type == PEP_ct_OpenPGP);    
   223     
   224     first_device->grab_context(second_device);
   225     TEST_ASSERT_MSG(slurp_and_import_key(first_device->session, "test_keys/pub/pep-test-bob-0xC9C2EE39_pub.asc"), 
   226                     "First device couldn't import Bob's pubkey");
   227     pEp_identity* bob_id_2 = new_identity("pep.test.bob@pep-project.org", NULL, NULL, "Bob Barker");    
   228     status = update_identity(first_device->session, bob_id_2);
   229     TEST_ASSERT(status == PEP_STATUS_OK);
   230     TEST_ASSERT(bob_id_2->comm_type == PEP_ct_OpenPGP_unconfirmed);    
   231 
   232     free_identity(alice_dev_1_ident);                  
   233     free_identity(alice_dev_2_ident);
   234     free_identity(bob_id);
   235     free_identity(bob_id_2);              
   236 }
   237 
   238 void DeviceModelTests::check_mbox() {
   239     // Set up devices and shared mailbox
   240     pEpTestDevice* first_device = new pEpTestDevice(temp_test_home, "Device");
   241     devices.push_back(first_device);
   242     
   243     first_device->set_mailbox_dir(first_device->device_dir + "/mbox");
   244 
   245     string alice_email = "pep.test.alice@pep-project.org";
   246     string alice_fpr = "4ABE3AAF59AC32CFE4F86500A9411D176FF00E97";
   247     
   248     slurp_and_import_key(first_device->session, "test_keys/pub/pep-test-alice-0x6FF00E97_pub.asc");
   249     slurp_and_import_key(first_device->session, "test_keys/priv/pep-test-alice-0x6FF00E97_priv.asc");
   250     
   251     pEp_identity* alice_ident = new_identity(alice_email.c_str(), alice_fpr.c_str(), "ALICE", "Alice From Mel's Diner");    
   252     PEP_STATUS status = set_own_key(first_device->session, alice_ident, alice_fpr.c_str());    
   253     TEST_ASSERT_MSG(status == PEP_STATUS_OK, 
   254         (string("Unable to set own key. status is ") + tl_status_string(status)).c_str());
   255         
   256     message* new_msg = new_message(PEP_dir_outgoing);
   257     
   258     new_msg->from = alice_ident;
   259     new_msg->to = new_identity_list(identity_dup(alice_ident));
   260     new_msg->longmsg = strdup("Some dumb message.\nBlahblahblah.");
   261     new_msg->shortmsg = strdup("hello, world");
   262     new_msg->attachments = new_bloblist(NULL, 0, "application/octet-stream", NULL);
   263 
   264     message* enc_msg = NULL;
   265     
   266     status = encrypt_message(first_device->session, new_msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
   267 
   268     TEST_ASSERT(status == PEP_STATUS_OK);
   269     TEST_ASSERT(enc_msg);
   270     char* msg_text = NULL;
   271     mime_encode_message(enc_msg, false, &msg_text);
   272     TEST_ASSERT(msg_text);
   273     
   274     string filename = first_device->receive_mail(msg_text);
   275     TEST_ASSERT(!filename.empty());
   276 
   277     vector<string> curr_mail_received;
   278     first_device->check_mail(curr_mail_received);
   279     TEST_ASSERT_MSG(curr_mail_received.size() == 1, 
   280                     (string("Received ") + to_string(curr_mail_received.size()) + " emails, should have received 1.").c_str());
   281 
   282     first_device->receive_mail(msg_text);
   283     first_device->receive_mail(msg_text);
   284     first_device->receive_mail(msg_text);
   285     first_device->check_mail(curr_mail_received);
   286     TEST_ASSERT_MSG(curr_mail_received.size() == 3, 
   287                     (string("Received ") + to_string(curr_mail_received.size()) + " emails, should have received 3.").c_str());
   288     
   289     first_device->receive_mail(msg_text);
   290     first_device->receive_mail(msg_text);
   291     first_device->check_mail(curr_mail_received);
   292     TEST_ASSERT_MSG(curr_mail_received.size() == 2, 
   293                     (string("Received ") + to_string(curr_mail_received.size()) + " emails, should have received 2.").c_str());
   294 }
   295 
   296 void DeviceModelTests::check_three_device_mbox_with_send() {
   297     try {
   298         // Set up devices and shared mailbox
   299         pEpTestDevice* first_device = new pEpTestDevice(temp_test_home, "Alex");
   300         devices.push_back(first_device);    
   301         first_device->set_mailbox_dir(first_device->device_dir + "/mbox");
   302         string alex_email = "alex@darthmama.cool";
   303         pEp_identity* alex_identity = new_identity(alex_email.c_str(), NULL, "AlexID", "Alex Braithwaite");
   304         PEP_STATUS status = myself(first_device->session, alex_identity);
   305         
   306         pEpTestDevice* second_device = new pEpTestDevice(temp_test_home, "Bree");
   307         devices.push_back(second_device);    
   308         second_device->set_mailbox_dir(second_device->device_dir + "/mbox");
   309         string bree_email = "bree@cheese.melted";
   310         pEp_identity* bree_identity = new_identity(bree_email.c_str(), NULL, "BreeID", "Briana Cheeserton");
   311         status = myself(second_device->session, bree_identity);
   312         
   313         pEpTestDevice* third_device = new pEpTestDevice(temp_test_home, "Charmander");
   314         devices.push_back(third_device);    
   315         third_device->set_mailbox_dir(third_device->device_dir + "/mbox");
   316         string charm_email = "charmander@poke.mon";
   317         pEp_identity* charm_identity = new_identity(charm_email.c_str(), NULL, "CharmID", "Charmander T. Pokemon");
   318         status = myself(third_device->session, charm_identity);
   319         first_device->grab_context(third_device);
   320 
   321         map<string,string> address_maps = {
   322             {alex_email,first_device->mbox_dir},
   323             {bree_email,second_device->mbox_dir},
   324             {charm_email,third_device->mbox_dir},
   325         };
   326 
   327         // this just simulates the ability to address and deliver, so everyone has
   328         // the same maps.
   329         first_device->address_to_mbox_map = second_device->address_to_mbox_map =
   330             third_device->address_to_mbox_map = address_maps;
   331         // Note to self - I'll bet this is some C++ mem nightmare.
   332         
   333         message* msg = new_message(PEP_dir_outgoing);
   334         msg->from = identity_dup(alex_identity);
   335         msg->to = new_identity_list(new_identity(bree_email.c_str(), NULL, "ItsBree", "Bree Cheeserton"));
   336         msg->shortmsg = strdup("First test message!");
   337         msg->longmsg = strdup("Yo Bree! This is Alex! Hi!\nEr, hi!\n");
   338         msg->attachments = new_bloblist(NULL, 0, "application/octet-stream", NULL);
   339 
   340         // engine_passthrough
   341         message* enc_msg = NULL;
   342         status = encrypt_message(first_device->session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
   343         TEST_ASSERT(status == PEP_UNENCRYPTED);
   344         TEST_ASSERT(enc_msg == NULL);
   345 
   346         // when sent, msg is freed, so do NOT free it after this.
   347         first_device->add_message_to_send_queue(msg);
   348         second_device->grab_context(first_device);
   349         msg = NULL;
   350         
   351         vector<string> inbox_list;
   352         second_device->check_mail(inbox_list);
   353 
   354         vector<message*> inbox_mails;
   355         stringlist_t* keylist = NULL;
   356         PEP_rating rating;
   357         PEP_decrypt_flags_t flags;
   358         
   359         second_device->read_mail(inbox_list, inbox_mails);
   360         remove_sync_mails(inbox_mails);
   361         TEST_ASSERT(inbox_mails.size() == 1 && inbox_mails.at(0));
   362         
   363         // Get Alex's key
   364         status = decrypt_message(second_device->session,
   365                                  inbox_mails.at(0), &msg, &keylist,
   366                                  &rating, &flags);
   367         TEST_ASSERT(status == PEP_UNENCRYPTED);
   368         TEST_ASSERT(msg == NULL);
   369 
   370         inbox_list.clear();
   371         free(inbox_mails.at(0));
   372         inbox_mails.clear();
   373         
   374         third_device->grab_context(second_device);
   375             
   376         msg = new_message(PEP_dir_outgoing);
   377         msg->from = identity_dup(charm_identity);
   378         msg->to = new_identity_list(new_identity(bree_email.c_str(), NULL, "SuperBree", "Bree Cheeserton"));
   379         msg->shortmsg = strdup("First test message!");
   380         msg->longmsg = strdup("Yo Bree! This is Charmander! I'm a cool Pokemon! Hi!\nEr, hi!\n");
   381         msg->attachments = new_bloblist(NULL, 0, "application/octet-stream", NULL);
   382 
   383         // engine_passthrough
   384         enc_msg = NULL;
   385         status = encrypt_message(third_device->session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
   386         TEST_ASSERT(status == PEP_UNENCRYPTED);
   387         TEST_ASSERT(enc_msg == NULL);
   388 
   389         // when sent, msg is freed, so do NOT free it after this.
   390         third_device->add_message_to_send_queue(msg);
   391         second_device->grab_context(third_device);
   392         msg = NULL;
   393             
   394         second_device->check_mail(inbox_list);
   395             
   396         keylist = NULL;
   397         flags = 0;
   398         
   399         second_device->read_mail(inbox_list, inbox_mails);
   400         
   401         remove_sync_mails(inbox_mails);
   402         
   403         TEST_ASSERT(inbox_mails.size() == 1 && inbox_mails.at(0));
   404         
   405         // Get Charmander's key
   406         status = decrypt_message(second_device->session,
   407                                  inbox_mails.at(0), &msg, &keylist,
   408                                  &rating, &flags);
   409         TEST_ASSERT(status == PEP_UNENCRYPTED);
   410         TEST_ASSERT(msg == NULL);
   411 
   412         inbox_list.clear();
   413         free(inbox_mails.at(0));
   414         inbox_mails.clear();    
   415 
   416         // Ok, now, revenge of encrypting Bree
   417         msg = new_message(PEP_dir_outgoing);
   418         msg->from = identity_dup(bree_identity);
   419         msg->to = new_identity_list(new_identity(alex_email.c_str(), NULL, "Alexei", "Alex Braithwaite is a char in a bad novel"));
   420         identity_list_add(msg->to, new_identity(charm_email.c_str(), NULL, "Charming", "Charmanderpoke E. Mon is NOT a Pokemon"));
   421         msg->shortmsg = strdup("Last test message!");
   422         msg->longmsg = strdup("You guys are fools :)\n");
   423         msg->attachments = new_bloblist(NULL, 0, "application/octet-stream", NULL);
   424 
   425         enc_msg = NULL;
   426         status = encrypt_message(second_device->session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
   427         TEST_ASSERT(status == PEP_STATUS_OK);
   428         TEST_ASSERT(enc_msg);
   429          
   430         free_message(msg);
   431         msg = NULL;
   432         free_stringlist(keylist);
   433         flags = 0;
   434         keylist = NULL;
   435         
   436         // when sent, enc_msg is freed, so do NOT free it after this.
   437         second_device->add_message_to_send_queue(enc_msg);
   438         first_device->grab_context(second_device);
   439         enc_msg = NULL;
   440 
   441         first_device->check_mail(inbox_list);            
   442         first_device->read_mail(inbox_list, inbox_mails);
   443         remove_sync_mails(inbox_mails);
   444         TEST_ASSERT(inbox_mails.size() == 1 && inbox_mails.at(0));
   445         
   446         status = decrypt_message(first_device->session,
   447                                  inbox_mails.at(0), &msg, &keylist,
   448                                  &rating, &flags);
   449         TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   450         TEST_ASSERT_MSG(rating == PEP_rating_reliable, tl_rating_string(rating));
   451         TEST_ASSERT(msg);
   452 
   453         free_message(msg);
   454         inbox_list.clear();
   455         free(inbox_mails.at(0));
   456         inbox_mails.clear();    
   457 
   458         msg = NULL;
   459         free_stringlist(keylist);
   460         flags = 0;
   461         keylist = NULL;
   462         
   463         third_device->grab_context(first_device);
   464 
   465         third_device->check_mail(inbox_list);
   466             
   467         third_device->read_mail(inbox_list, inbox_mails);
   468         remove_sync_mails(inbox_mails);
   469 
   470         TEST_ASSERT(inbox_mails.size() == 1 && inbox_mails.at(0));
   471         
   472         status = decrypt_message(third_device->session,
   473                                  inbox_mails.at(0), &msg, &keylist,
   474                                  &rating, &flags);
   475         TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   476         TEST_ASSERT_MSG(rating == PEP_rating_reliable, tl_rating_string(rating));
   477         TEST_ASSERT(msg);
   478 
   479         free_message(msg);
   480         inbox_list.clear();
   481         free(inbox_mails.at(0));
   482         inbox_mails.clear();    
   483         free_stringlist(keylist);
   484     }
   485     catch (const runtime_error& error) {
   486         TEST_ASSERT_MSG(false, error.what());
   487     }
   488 }
   489 
   490 void DeviceModelTests::check_switch_context() {
   491     try {
   492         // Set up devices and shared mailbox
   493         pEpTestDevice* first_device = new pEpTestDevice(temp_test_home, "Alex");
   494         devices.push_back(first_device);    
   495         first_device->set_mailbox_dir(first_device->device_dir + "/mbox");
   496         string alex_email = "alex@darthmama.cool";
   497         pEp_identity* alex_identity = new_identity(alex_email.c_str(), NULL, "AlexID", "Alex Braithwaite");
   498         PEP_STATUS status = myself(first_device->session, alex_identity);
   499         
   500         pEpTestDevice* second_device = new pEpTestDevice(temp_test_home, "Bree");
   501         devices.push_back(second_device);    
   502         second_device->set_mailbox_dir(second_device->device_dir + "/mbox");
   503         string bree_email = "bree@cheese.melted";
   504         pEp_identity* bree_identity = new_identity(bree_email.c_str(), NULL, "BreeID", "Briana Cheeserton");
   505         status = myself(second_device->session, bree_identity);
   506         
   507         pEpTestDevice* third_device = new pEpTestDevice(temp_test_home, "Charmander");
   508         devices.push_back(third_device);    
   509         third_device->set_mailbox_dir(third_device->device_dir + "/mbox");
   510         string charm_email = "charmander@poke.mon";
   511         pEp_identity* charm_identity = new_identity(charm_email.c_str(), NULL, "CharmID", "Charmander T. Pokemon");
   512         status = myself(third_device->session, charm_identity);
   513         
   514         pEpTestDevice::switch_context(first_device);
   515 
   516         map<string,string> address_maps = {
   517             {alex_email,first_device->mbox_dir},
   518             {bree_email,second_device->mbox_dir},
   519             {charm_email,third_device->mbox_dir},
   520         };
   521 
   522         // this just simulates the ability to address and deliver, so everyone has
   523         // the same maps.
   524         first_device->address_to_mbox_map = second_device->address_to_mbox_map =
   525             third_device->address_to_mbox_map = address_maps;
   526         // Note to self - I'll bet this is some C++ mem nightmare.
   527         
   528         message* msg = new_message(PEP_dir_outgoing);
   529         msg->from = identity_dup(alex_identity);
   530         msg->to = new_identity_list(new_identity(bree_email.c_str(), NULL, "ItsBree", "Bree Cheeserton"));
   531         msg->shortmsg = strdup("First test message!");
   532         msg->longmsg = strdup("Yo Bree! This is Alex! Hi!\nEr, hi!\n");
   533         msg->attachments = new_bloblist(NULL, 0, "application/octet-stream", NULL);
   534 
   535         // engine_passthrough
   536         message* enc_msg = NULL;
   537         status = encrypt_message(pEpTestDevice::active->session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
   538         TEST_ASSERT(status == PEP_UNENCRYPTED);
   539         TEST_ASSERT(enc_msg == NULL);
   540 
   541         // when sent, msg is freed, so do NOT free it after this.
   542         pEpTestDevice::active->add_message_to_send_queue(msg);
   543         pEpTestDevice::switch_context(second_device);
   544 
   545         msg = NULL;
   546         
   547         vector<string> inbox_list;
   548         pEpTestDevice::active->check_mail(inbox_list);
   549 
   550         vector<message*> inbox_mails;
   551         stringlist_t* keylist = NULL;
   552         PEP_rating rating;
   553         PEP_decrypt_flags_t flags;
   554         pEpTestDevice::active->read_mail(inbox_list, inbox_mails);
   555         remove_sync_mails(inbox_mails);
   556 
   557         TEST_ASSERT(inbox_mails.size() == 1 && inbox_mails.at(0));
   558         
   559         // Get Alex's key
   560         status = decrypt_message(pEpTestDevice::active->session,
   561                                  inbox_mails.at(0), &msg, &keylist,
   562                                  &rating, &flags);
   563         TEST_ASSERT(status == PEP_UNENCRYPTED);
   564         TEST_ASSERT(msg == NULL);
   565 
   566         inbox_list.clear();
   567         free(inbox_mails.at(0));
   568         inbox_mails.clear();
   569         
   570         pEpTestDevice::switch_context(third_device);
   571             
   572         msg = new_message(PEP_dir_outgoing);
   573         msg->from = identity_dup(charm_identity);
   574         msg->to = new_identity_list(new_identity(bree_email.c_str(), NULL, "SuperBree", "Bree Cheeserton"));
   575         msg->shortmsg = strdup("First test message!");
   576         msg->longmsg = strdup("Yo Bree! This is Charmander! I'm a cool Pokemon! Hi!\nEr, hi!\n");
   577         msg->attachments = new_bloblist(NULL, 0, "application/octet-stream", NULL);
   578 
   579         // engine_passthrough
   580         enc_msg = NULL;
   581         status = encrypt_message(pEpTestDevice::active->session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
   582         TEST_ASSERT(status == PEP_UNENCRYPTED);
   583         TEST_ASSERT(enc_msg == NULL);
   584 
   585         // when sent, msg is freed, so do NOT free it after this.
   586         pEpTestDevice::active->add_message_to_send_queue(msg);
   587 
   588         pEpTestDevice::switch_context(second_device);
   589         msg = NULL;
   590             
   591         pEpTestDevice::active->check_mail(inbox_list);    
   592         keylist = NULL;
   593         flags = 0;
   594         pEpTestDevice::active->read_mail(inbox_list, inbox_mails);
   595         remove_sync_mails(inbox_mails);
   596 
   597         TEST_ASSERT(inbox_mails.size() == 1 && inbox_mails.at(0));
   598         
   599         // Get Charmander's key
   600         status = decrypt_message(pEpTestDevice::active->session,
   601                                  inbox_mails.at(0), &msg, &keylist,
   602                                  &rating, &flags);
   603         TEST_ASSERT(status == PEP_UNENCRYPTED);
   604         TEST_ASSERT(msg == NULL);
   605 
   606         inbox_list.clear();
   607         free(inbox_mails.at(0));
   608         inbox_mails.clear();    
   609 
   610         // Ok, now, revenge of encrypting Bree
   611         msg = new_message(PEP_dir_outgoing);
   612         msg->from = identity_dup(bree_identity);
   613         msg->to = new_identity_list(new_identity(alex_email.c_str(), NULL, "Alexei", "Alex Braithwaite is a char in a bad novel"));
   614         identity_list_add(msg->to, new_identity(charm_email.c_str(), NULL, "Charming", "Charmanderpoke E. Mon is NOT a Pokemon"));
   615         msg->shortmsg = strdup("Last test message!");
   616         msg->longmsg = strdup("You guys are fools :)\n");
   617         msg->attachments = new_bloblist(NULL, 0, "application/octet-stream", NULL);
   618 
   619         enc_msg = NULL;
   620         status = encrypt_message(pEpTestDevice::active->session, msg, NULL, &enc_msg, PEP_enc_PGP_MIME, 0);
   621         TEST_ASSERT(status == PEP_STATUS_OK);
   622         TEST_ASSERT(enc_msg);
   623          
   624         free_message(msg);
   625         msg = NULL;
   626         free_stringlist(keylist);
   627         flags = 0;
   628         keylist = NULL;
   629         
   630         // when sent, enc_msg is freed, so do NOT free it after this.
   631         pEpTestDevice::active->add_message_to_send_queue(enc_msg);
   632 
   633         pEpTestDevice::switch_context(first_device);
   634                 
   635         enc_msg = NULL;
   636 
   637         pEpTestDevice::active->check_mail(inbox_list);
   638             
   639         pEpTestDevice::active->read_mail(inbox_list, inbox_mails);
   640         remove_sync_mails(inbox_mails);
   641         TEST_ASSERT(inbox_mails.size() == 1 && inbox_mails.at(0));
   642         
   643         status = decrypt_message(pEpTestDevice::active->session,
   644                                  inbox_mails.at(0), &msg, &keylist,
   645                                  &rating, &flags);
   646         TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   647         TEST_ASSERT_MSG(rating == PEP_rating_reliable, tl_rating_string(rating));
   648         TEST_ASSERT(msg);
   649 
   650         free_message(msg);
   651         inbox_list.clear();
   652         free(inbox_mails.at(0));
   653         inbox_mails.clear();    
   654 
   655         msg = NULL;
   656         free_stringlist(keylist);
   657         flags = 0;
   658         keylist = NULL;
   659         
   660         pEpTestDevice::switch_context(third_device);
   661 
   662         pEpTestDevice::active->check_mail(inbox_list);
   663         pEpTestDevice::active->read_mail(inbox_list, inbox_mails);
   664         remove_sync_mails(inbox_mails);
   665         TEST_ASSERT(inbox_mails.size() == 1 && inbox_mails.at(0));
   666         
   667         status = decrypt_message(pEpTestDevice::active->session,
   668                                  inbox_mails.at(0), &msg, &keylist,
   669                                  &rating, &flags);
   670         TEST_ASSERT_MSG(status == PEP_STATUS_OK, tl_status_string(status));
   671         TEST_ASSERT_MSG(rating == PEP_rating_reliable, tl_rating_string(rating));
   672         TEST_ASSERT(msg);
   673 
   674         free_message(msg);
   675         inbox_list.clear();
   676         free(inbox_mails.at(0));
   677         inbox_mails.clear();    
   678         free_stringlist(keylist);
   679     }
   680     catch (const runtime_error& error) {
   681         TEST_ASSERT_MSG(false, error.what());
   682     }
   683 }