merged in parent ENGINE-559
authorKrista 'DarthMama' Bennett <krista@pep.foundation>
Tue, 09 Jul 2019 11:24:36 +0200
branchENGINE-559
changeset 3915c3fa76972af5
parent 3884 49d25cfc873c
parent 3914 eec042946bec
child 3916 54f53e338f86
merged in parent
src/keymanagement.c
src/message_api.c
src/pEpEngine.c
src/pEpEngine.h
src/pEp_internal.h
test/src/SuiteMaker.cc
     1.1 --- a/build-mac/pEpEngine.xcodeproj/project.pbxproj	Thu Jun 27 12:40:43 2019 +0200
     1.2 +++ b/build-mac/pEpEngine.xcodeproj/project.pbxproj	Tue Jul 09 11:24:36 2019 +0200
     1.3 @@ -1155,7 +1155,7 @@
     1.4  				ONLY_ACTIVE_ARCH = YES;
     1.5  				OTHER_CFLAGS = "-DSQLITE3_FROM_OS";
     1.6  				SDKROOT = iphoneos;
     1.7 -				VALID_ARCHS = "arm64 armv7s armv7";
     1.8 +				VALID_ARCHS = "$(VALID_ARCHS) x86_64";
     1.9  			};
    1.10  			name = Debug;
    1.11  		};
    1.12 @@ -1214,7 +1214,7 @@
    1.13  				OTHER_CFLAGS = "-DSQLITE3_FROM_OS";
    1.14  				SDKROOT = iphoneos;
    1.15  				VALIDATE_PRODUCT = YES;
    1.16 -				VALID_ARCHS = "arm64 armv7s armv7";
    1.17 +				VALID_ARCHS = "$(VALID_ARCHS) x86_64";
    1.18  			};
    1.19  			name = Release;
    1.20  		};
     2.1 --- a/src/identity_list.c	Thu Jun 27 12:40:43 2019 +0200
     2.2 +++ b/src/identity_list.c	Tue Jul 09 11:24:36 2019 +0200
     2.3 @@ -108,6 +108,23 @@
     2.4      return list_curr->next;
     2.5  }
     2.6  
     2.7 +// returns *head* of list
     2.8 +DYNAMIC_API identity_list* identity_list_join(identity_list *first_list, identity_list *second_list) {
     2.9 +    if (!first_list) {
    2.10 +        if (!second_list)
    2.11 +            return NULL;
    2.12 +        return second_list;
    2.13 +    }
    2.14 +    if (second_list) {
    2.15 +        identity_list* list_curr = first_list;
    2.16 +        while (list_curr->next)
    2.17 +            list_curr = list_curr->next;    
    2.18 +            
    2.19 +        list_curr->next = second_list;
    2.20 +    }        
    2.21 +    return first_list;    
    2.22 +}
    2.23 +
    2.24  DYNAMIC_API int identity_list_length(const identity_list *id_list)
    2.25  {
    2.26      int len = 0;
     3.1 --- a/src/identity_list.h	Thu Jun 27 12:40:43 2019 +0200
     3.2 +++ b/src/identity_list.h	Tue Jul 09 11:24:36 2019 +0200
     3.3 @@ -63,6 +63,16 @@
     3.4  
     3.5  DYNAMIC_API identity_list *identity_list_add(identity_list *id_list, pEp_identity *ident);
     3.6  
     3.7 +// identity_list_add - join second identity_list to the first.
     3.8 +//
     3.9 +//  parameters:
    3.10 +//      first_list (in)             identity_list to add to
    3.11 +//      second_list (in)            identity list to add
    3.12 +//
    3.13 +//  return value:
    3.14 +//      pointer to the HEAD of the new list, or NULL if both lists are empty.
    3.15 +//
    3.16 +DYNAMIC_API identity_list *identity_list_join(identity_list *first_list, identity_list* second_list);
    3.17  
    3.18  // identity_list_length() - get length of identity_list
    3.19  //
    3.20 @@ -73,9 +83,7 @@
    3.21  //      length of identity_list in number of elements
    3.22  
    3.23  DYNAMIC_API int identity_list_length(const identity_list *id_list);
    3.24 -
    3.25 -
    3.26 +    
    3.27  #ifdef __cplusplus
    3.28  }
    3.29  #endif
    3.30 -
     4.1 --- a/src/keymanagement.c	Thu Jun 27 12:40:43 2019 +0200
     4.2 +++ b/src/keymanagement.c	Tue Jul 09 11:24:36 2019 +0200
     4.3 @@ -474,6 +474,8 @@
     4.4      PEP_STATUS status;
     4.5      
     4.6      bool is_identity_default, is_user_default, is_address_default;
     4.7 +    bool no_stored_default = EMPTYSTR(stored_ident->fpr);
     4.8 +    
     4.9      status = get_valid_pubkey(session, stored_ident,
    4.10                                  &is_identity_default,
    4.11                                  &is_user_default,
    4.12 @@ -492,7 +494,12 @@
    4.13              stored_ident->comm_type = ct;
    4.14          }
    4.15      }
    4.16 -    else {
    4.17 +    else if (status != PEP_STATUS_OK) {
    4.18 +        free(stored_ident->fpr);
    4.19 +        stored_ident->fpr = NULL;
    4.20 +        stored_ident->comm_type = PEP_ct_key_not_found;        
    4.21 +    }
    4.22 +    else { // no key returned, but status ok?
    4.23          if (stored_ident->comm_type == PEP_ct_unknown)
    4.24              stored_ident->comm_type = PEP_ct_key_not_found;
    4.25      }
    4.26 @@ -543,8 +550,17 @@
    4.27           // or identity AND is valid for this address, set in DB
    4.28           // as default
    4.29           status = set_identity(session, return_id);
    4.30 +    } 
    4.31 +    else if (no_stored_default && !EMPTYSTR(return_id->fpr) 
    4.32 +             && return_id->comm_type != PEP_ct_key_revoked
    4.33 +             && return_id->comm_type != PEP_ct_key_expired
    4.34 +             && return_id->comm_type != PEP_ct_key_expired_but_confirmed
    4.35 +             && return_id->comm_type != PEP_ct_mistrusted 
    4.36 +             && return_id->comm_type != PEP_ct_key_b0rken) { 
    4.37 +        // We would have stored this anyway for a first-time elected key. We just have an ident w/ no default already.
    4.38 +        status = set_identity(session, return_id);
    4.39      }
    4.40 -    else {
    4.41 +    else { // this is a key other than the default, but there IS a default (FIXME: fdik, do we really want behaviour below?)
    4.42          // Store without default fpr/ct, but return the fpr and ct 
    4.43          // for current use
    4.44          char* save_fpr = return_id->fpr;
     5.1 --- a/src/message_api.c	Thu Jun 27 12:40:43 2019 +0200
     5.2 +++ b/src/message_api.c	Tue Jul 09 11:24:36 2019 +0200
     5.3 @@ -3145,7 +3145,6 @@
     5.4  }
     5.5  
     5.6  static PEP_STATUS reconcile_sent_and_recv_info(message* src, message* inner_message) {
     5.7 -    PEP_STATUS status = PEP_STATUS_OK;
     5.8      if (!src || !inner_message)
     5.9          return PEP_ILLEGAL_VALUE;
    5.10          
     6.1 --- a/src/pEpEngine.h	Thu Jun 27 12:40:43 2019 +0200
     6.2 +++ b/src/pEpEngine.h	Tue Jul 09 11:24:36 2019 +0200
     6.3 @@ -60,6 +60,7 @@
     6.4      PEP_KEY_IMPORTED                                = 0x0220,
     6.5      PEP_NO_KEY_IMPORTED                             = 0x0221,
     6.6      PEP_KEY_IMPORT_STATUS_UNKNOWN                   = 0x0222,
     6.7 +    PEP_SOME_KEYS_IMPORTED                          = 0x0223,
     6.8      
     6.9      PEP_CANNOT_FIND_IDENTITY                        = 0x0301,
    6.10      PEP_CANNOT_SET_PERSON                           = 0x0381,
     7.1 --- a/src/pgp_sequoia.c	Thu Jun 27 12:40:43 2019 +0200
     7.2 +++ b/src/pgp_sequoia.c	Tue Jul 09 11:24:36 2019 +0200
     7.3 @@ -1447,6 +1447,33 @@
     7.4      if (size == 0 || sig_size == 0)
     7.5          return PEP_DECRYPT_WRONG_FORMAT;
     7.6  
     7.7 +#if TRACING > 0
     7.8 +    {
     7.9 +        int cr = 0;
    7.10 +        int crlf = 0;
    7.11 +        int lf = 0;
    7.12 +
    7.13 +        for (int i = 0; i < size; i ++) {
    7.14 +            // CR
    7.15 +            if (text[i] == '\r') {
    7.16 +                cr ++;
    7.17 +            }
    7.18 +            // LF
    7.19 +            if (text[i] == '\n') {
    7.20 +                if (i > 0 && text[i - 1] == '\r') {
    7.21 +                    cr --;
    7.22 +                    crlf ++;
    7.23 +                } else {
    7.24 +                    lf ++;
    7.25 +                }
    7.26 +            }
    7.27 +        }
    7.28 +
    7.29 +        T("Text to verify: %zd bytes with %d crlfs, %d bare crs and %d bare lfs",
    7.30 +          size, crlf, cr, lf);
    7.31 +    }
    7.32 +#endif
    7.33 +
    7.34      cookie.recipient_keylist = new_stringlist(NULL);
    7.35      if (!cookie.recipient_keylist)
    7.36          ERROR_OUT(NULL, PEP_OUT_OF_MEMORY, "out of memory");
    7.37 @@ -1854,7 +1881,27 @@
    7.38      return status;
    7.39  }
    7.40  
    7.41 -PEP_STATUS pgp_import_keydata(PEP_SESSION session, const char *key_data,
    7.42 +static unsigned int count_keydata_parts(const char* key_data, size_t size) {
    7.43 +    unsigned int retval = 0;
    7.44 +    
    7.45 +    const char* pgp_begin = "-----BEGIN PGP";
    7.46 +    size_t prefix_len = strlen(pgp_begin);
    7.47 +    size_t size_remaining = size;
    7.48 +    
    7.49 +    while (key_data) {
    7.50 +        if (size_remaining <= prefix_len || key_data[0] == '\0')
    7.51 +            break;
    7.52 +        key_data = strnstr(key_data, pgp_begin, size_remaining);
    7.53 +        if (key_data) {
    7.54 +            retval++;
    7.55 +            key_data += prefix_len;
    7.56 +            size_remaining -= prefix_len;
    7.57 +        }
    7.58 +    }
    7.59 +    return retval;
    7.60 + }
    7.61 +
    7.62 +PEP_STATUS _pgp_import_keydata(PEP_SESSION session, const char *key_data,
    7.63                                size_t size, identity_list **private_idents)
    7.64  {
    7.65      PEP_STATUS status = PEP_NO_KEY_IMPORTED;
    7.66 @@ -1986,6 +2033,78 @@
    7.67      return status;
    7.68  }
    7.69  
    7.70 +PEP_STATUS pgp_import_keydata(PEP_SESSION session, const char *key_data,
    7.71 +                              size_t size, identity_list **private_idents)
    7.72 +{
    7.73 +    unsigned int keycount = count_keydata_parts(key_data, size);
    7.74 +    if (keycount < 2)
    7.75 +        return(_pgp_import_keydata(session, key_data, size, private_idents));
    7.76 +
    7.77 +    const char* pgp_begin = "-----BEGIN PGP";
    7.78 +    size_t prefix_len = strlen(pgp_begin);
    7.79 +        
    7.80 +    unsigned int i;
    7.81 +    const char* curr_begin;
    7.82 +    size_t curr_size;
    7.83 +    
    7.84 +    identity_list* collected_idents = NULL;        
    7.85 +    
    7.86 +    PEP_STATUS retval = PEP_KEY_IMPORTED;
    7.87 +    
    7.88 +    for (i = 0, curr_begin = key_data; i < keycount; i++) {
    7.89 +        const char* next_begin = NULL;
    7.90 +
    7.91 +        // This is assured to be OK because the count function above 
    7.92 +        // made sure that THIS round contains at least prefix_len chars
    7.93 +        // We used strnstr to count, so we know that strstr will be ok.
    7.94 +        if (strlen(curr_begin + prefix_len) > prefix_len)
    7.95 +            next_begin = strstr(curr_begin + prefix_len, pgp_begin);
    7.96 +
    7.97 +        if (next_begin)
    7.98 +            curr_size = next_begin - curr_begin;
    7.99 +        else
   7.100 +            curr_size = (key_data + size) - curr_begin;
   7.101 +        
   7.102 +        PEP_STATUS curr_status = _pgp_import_keydata(session, curr_begin, curr_size, private_idents);
   7.103 +        if (private_idents && *private_idents) {
   7.104 +            if (!collected_idents)
   7.105 +                collected_idents = *private_idents;
   7.106 +            else 
   7.107 +                identity_list_join(collected_idents, *private_idents);
   7.108 +            *private_idents = NULL;    
   7.109 +        }
   7.110 +        
   7.111 +        if (curr_status != retval) {
   7.112 +            switch (curr_status) {
   7.113 +                case PEP_NO_KEY_IMPORTED:
   7.114 +                case PEP_KEY_NOT_FOUND:
   7.115 +                case PEP_UNKNOWN_ERROR:
   7.116 +                    switch (retval) {
   7.117 +                        case PEP_KEY_IMPORTED:
   7.118 +                            retval = PEP_SOME_KEYS_IMPORTED;
   7.119 +                            break;
   7.120 +                        case PEP_UNKNOWN_ERROR:
   7.121 +                            retval = curr_status;
   7.122 +                            break;
   7.123 +                        default:
   7.124 +                            break;
   7.125 +                    }
   7.126 +                    break;
   7.127 +                case PEP_KEY_IMPORTED:
   7.128 +                    retval = PEP_SOME_KEYS_IMPORTED;
   7.129 +                default:
   7.130 +                    break;
   7.131 +            }        
   7.132 +        }        
   7.133 +        curr_begin = next_begin;     
   7.134 +    }
   7.135 +    
   7.136 +    if (private_idents)
   7.137 +        *private_idents = collected_idents;
   7.138 +    
   7.139 +    return retval;    
   7.140 +}
   7.141 +
   7.142  PEP_STATUS pgp_export_keydata(
   7.143          PEP_SESSION session, const char *fpr, char **key_data, size_t *size,
   7.144          bool secret)
   7.145 @@ -2498,6 +2617,22 @@
   7.146  
   7.147      // Is the TPK live?
   7.148      *expired = !pgp_tpk_alive_at(tpk, when);
   7.149 +#ifdef TRACING
   7.150 +    {
   7.151 +        char buffer[26];
   7.152 +        time_t now = time(NULL);
   7.153 +
   7.154 +        if (when == now || when == now - 1) {
   7.155 +            sprintf(buffer, "now");
   7.156 +        } else {
   7.157 +            struct tm tm;
   7.158 +            gmtime_r(&when, &tm);
   7.159 +            strftime(buffer, sizeof(buffer), "%Y-%m-%d %H:%M:%S", &tm);
   7.160 +        }
   7.161 +
   7.162 +        T("TPK is %slive as of %s", *expired ? "not " : "", buffer);
   7.163 +    }
   7.164 +#endif
   7.165      if (*expired)
   7.166          goto out;
   7.167  
   7.168 @@ -2528,9 +2663,15 @@
   7.169  
   7.170      *expired = !(can_encrypt && can_sign && can_certify);
   7.171  
   7.172 +    T("Key can%s encrypt, can%s sign, can%s certify => %sexpired",
   7.173 +      can_encrypt ? "" : "not",
   7.174 +      can_sign ? "" : "not",
   7.175 +      can_certify ? "" : "not",
   7.176 +      *expired ? "" : "not ");
   7.177 +
   7.178   out:
   7.179      pgp_tpk_free(tpk);
   7.180 -    T("(%s) -> %s", fpr, pEp_status_to_string(status));
   7.181 +    T("(%s) -> %s (expired: %d)", fpr, pEp_status_to_string(status), *expired);
   7.182      return status;
   7.183  }
   7.184  
     8.1 --- a/src/platform_unix.c	Thu Jun 27 12:40:43 2019 +0200
     8.2 +++ b/src/platform_unix.c	Tue Jul 09 11:24:36 2019 +0200
     8.3 @@ -198,6 +198,43 @@
     8.4      return retval;
     8.5  }
     8.6  
     8.7 +char *strnstr(const char *big, const char *little, size_t len) {
     8.8 +    if (big == NULL || little == NULL)
     8.9 +        return NULL;
    8.10 +        
    8.11 +    if (*little == '\0')
    8.12 +        return (char*)big;
    8.13 +        
    8.14 +    const char* curr_big = big;
    8.15 +    
    8.16 +    size_t little_len = strlen(little);
    8.17 +    size_t remaining = len;
    8.18 +
    8.19 +    const char* retval = NULL;
    8.20 +    
    8.21 +    for (remaining = len; remaining >= little_len && *curr_big != '\0'; remaining--, curr_big++) {
    8.22 +        // find first-char match
    8.23 +        if (*curr_big != *little) {
    8.24 +            continue;
    8.25 +        }
    8.26 +        retval = curr_big;
    8.27 +
    8.28 +        const char* inner_big = retval + 1;
    8.29 +        const char* curr_little = little + 1;
    8.30 +        int j;
    8.31 +        for (j = 1; j < little_len; j++, inner_big++, curr_little++) {
    8.32 +            if (*inner_big != *curr_little) {
    8.33 +                retval = NULL;
    8.34 +                break;
    8.35 +            }    
    8.36 +        }
    8.37 +        if (retval)
    8.38 +            break;
    8.39 +    }
    8.40 +    return (char*)retval;
    8.41 +}
    8.42 +
    8.43 +
    8.44  #ifdef USE_NETPGP
    8.45  // FIXME: This may cause problems - this is a quick compatibility fix for netpgp code
    8.46  int regnexec(const regex_t* preg, const char* string,
    8.47 @@ -449,4 +486,3 @@
    8.48      return NULL;
    8.49  }
    8.50  #endif
    8.51 -
     9.1 --- a/src/platform_unix.h	Thu Jun 27 12:40:43 2019 +0200
     9.2 +++ b/src/platform_unix.h	Tue Jul 09 11:24:36 2019 +0200
     9.3 @@ -67,6 +67,7 @@
     9.4  #if !defined(BSD) && !defined(__APPLE__)
     9.5  size_t strlcpy(char* dst, const	char* src, size_t size);
     9.6  size_t strlcat(char* dst, const	char* src, size_t size);
     9.7 +char *strnstr(const char *big, const char *little, size_t len);
     9.8  
     9.9  // N.B. This is ifdef'd out because NDK users sometimes have trouble finding regex functions in
    9.10  //      the library in spite of the inclusion of regex.h - this is a FIXME, but since iOS is
    10.1 --- a/src/platform_windows.cpp	Thu Jun 27 12:40:43 2019 +0200
    10.2 +++ b/src/platform_windows.cpp	Tue Jul 09 11:24:36 2019 +0200
    10.3 @@ -283,6 +283,41 @@
    10.4      dst[start_len + size_to_copy] = '\0';
    10.5      return retval;
    10.6  }
    10.7 +char *strnstr(const char *big, const char *little, size_t len) {
    10.8 +    if (big == NULL || little == NULL)
    10.9 +        return NULL;
   10.10 +        
   10.11 +    if (*little == '\0')
   10.12 +        return (char*)big;
   10.13 +        
   10.14 +    const char* curr_big = big;
   10.15 +    
   10.16 +    size_t little_len = strlen(little);
   10.17 +    size_t remaining = len;
   10.18 +
   10.19 +    const char* retval = NULL;
   10.20 +    
   10.21 +    for (remaining = len; remaining >= little_len && *curr_big != '\0'; remaining--, curr_big++) {
   10.22 +        // find first-char match
   10.23 +        if (*curr_big != *little) {
   10.24 +            continue;
   10.25 +        }
   10.26 +        retval = curr_big;
   10.27 +
   10.28 +        const char* inner_big = retval + 1;
   10.29 +        const char* curr_little = little + 1;
   10.30 +        int j;
   10.31 +        for (j = 1; j < little_len; j++, inner_big++, curr_little++) {
   10.32 +            if (*inner_big != *curr_little) {
   10.33 +                retval = NULL;
   10.34 +                break;
   10.35 +            }    
   10.36 +        }
   10.37 +        if (retval)
   10.38 +            break;
   10.39 +    }
   10.40 +    return (char*)retval;
   10.41 +}
   10.42  
   10.43  int mkstemp(char *templ)
   10.44  {
    11.1 --- a/src/platform_windows.h	Thu Jun 27 12:40:43 2019 +0200
    11.2 +++ b/src/platform_windows.h	Tue Jul 09 11:24:36 2019 +0200
    11.3 @@ -74,6 +74,8 @@
    11.4  
    11.5  size_t strlcpy(char* dst, const	char* src, size_t size);
    11.6  size_t strlcat(char* dst, const	char* src, size_t size);
    11.7 +char *strnstr(const char *big, const char *little, size_t len);
    11.8 +
    11.9  
   11.10  const char *windoze_local_db(void);
   11.11  const char *windoze_system_db(void);
    12.1 --- a/src/status_to_string.h	Thu Jun 27 12:40:43 2019 +0200
    12.2 +++ b/src/status_to_string.h	Tue Jul 09 11:24:36 2019 +0200
    12.3 @@ -35,6 +35,7 @@
    12.4      case PEP_KEY_IMPORTED: return "PEP_KEY_IMPORTED";
    12.5      case PEP_NO_KEY_IMPORTED: return "PEP_NO_KEY_IMPORTED";
    12.6      case PEP_KEY_IMPORT_STATUS_UNKNOWN: return "PEP_KEY_IMPORT_STATUS_UNKNOWN";
    12.7 +    case PEP_SOME_KEYS_IMPORTED: return "PEP_SOME_KEYS_IMPORTED";
    12.8      
    12.9      case PEP_CANNOT_FIND_IDENTITY: return "PEP_CANNOT_FIND_IDENTITY";
   12.10      case PEP_CANNOT_SET_PERSON: return "PEP_CANNOT_SET_PERSON";
    13.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.2 +++ b/test/include/StrnstrTests.h	Tue Jul 09 11:24:36 2019 +0200
    13.3 @@ -0,0 +1,35 @@
    13.4 +// This file is under GNU General Public License 3.0
    13.5 +// see LICENSE.txt
    13.6 +
    13.7 +#ifndef STRNSTR_H
    13.8 +#define STRNSTR_H
    13.9 +
   13.10 +#include <string>
   13.11 +#include "EngineTestIndividualSuite.h"
   13.12 +
   13.13 +using namespace std;
   13.14 +
   13.15 +class StrnstrTests : public EngineTestIndividualSuite {
   13.16 +    public:
   13.17 +        StrnstrTests(string test_suite, string test_home_dir);
   13.18 +    private:
   13.19 +        void check_strnstr_equal();
   13.20 +        void check_strnstr_first_null();
   13.21 +        void check_strnstr_second_null();
   13.22 +        void check_strnstr_both_null();
   13.23 +        void check_strnstr_first_empty();
   13.24 +        void check_strnstr_second_empty();
   13.25 +        void check_strnstr_both_empty();
   13.26 +        void check_strnstr_first_letter_only();
   13.27 +        void check_strnstr_first_two_only();
   13.28 +        void check_strnstr_all_but_last();
   13.29 +        void check_strnstr_same_len_all_but_last();
   13.30 +        void check_strnstr_same_len_none();
   13.31 +        void check_strnstr_same_big_smaller();
   13.32 +        void check_strnstr_shift_one_no_match();
   13.33 +        void check_strnstr_shift_to_end();
   13.34 +        void check_strnstr_match_after_end();
   13.35 +        void check_strnstr_equal_but_size_too_small();
   13.36 +};
   13.37 +
   13.38 +#endif
    14.1 --- a/test/src/SuiteMaker.cc	Thu Jun 27 12:40:43 2019 +0200
    14.2 +++ b/test/src/SuiteMaker.cc	Tue Jul 09 11:24:36 2019 +0200
    14.3 @@ -71,6 +71,7 @@
    14.4  #include "KeyAttachmentTests.h"
    14.5  #include "OwnKeysRetrieveTests.h"
    14.6  #include "TrustManipulationTests.h"
    14.7 +#include "StrnstrTests.h"
    14.8  #include "SyncTests.h"
    14.9  #include "SenderFPRTests.h"
   14.10  #include "RevocationTests.h"
   14.11 @@ -137,6 +138,7 @@
   14.12      "KeyAttachmentTests",
   14.13      "OwnKeysRetrieveTests",
   14.14      "TrustManipulationTests",
   14.15 +    "StrnstrTests",
   14.16      "SyncTests",
   14.17      "SenderFPRTests",
   14.18      "RevocationTests",
   14.19 @@ -265,6 +267,8 @@
   14.20          *test_suite = new OwnKeysRetrieveTests(test_class_name, test_home);
   14.21      else if (strcmp(test_class_name, "TrustManipulationTests") == 0)
   14.22          *test_suite = new TrustManipulationTests(test_class_name, test_home);
   14.23 +    else if (strcmp(test_class_name, "StrnstrTests") == 0)
   14.24 +        *test_suite = new StrnstrTests(test_class_name, test_home);
   14.25      else if (strcmp(test_class_name, "SyncTests") == 0)
   14.26          *test_suite = new SyncTests(test_class_name, test_home);
   14.27      else if (strcmp(test_class_name, "SenderFPRTests") == 0)
    15.1 --- a/test/src/engine_tests/CheckRenewedExpiredKeyTrustStatusTests.cc	Thu Jun 27 12:40:43 2019 +0200
    15.2 +++ b/test/src/engine_tests/CheckRenewedExpiredKeyTrustStatusTests.cc	Tue Jul 09 11:24:36 2019 +0200
    15.3 @@ -108,6 +108,13 @@
    15.4      status = update_identity(session, expired_inquisitor);
    15.5      TEST_ASSERT_MSG((status == PEP_KEY_UNSUITABLE), tl_status_string(status));
    15.6      PEP_comm_type ct = expired_inquisitor->comm_type;    
    15.7 +    TEST_ASSERT_MSG(ct == PEP_ct_key_not_found, tl_ct_string(ct));
    15.8 +    TEST_ASSERT(!expired_inquisitor->fpr);
    15.9 +    
   15.10 +    expired_inquisitor->fpr = strdup(inquisitor_fpr);
   15.11 +    status = get_trust(session, expired_inquisitor);
   15.12 +    ct = expired_inquisitor->comm_type;    
   15.13 +    TEST_ASSERT(status == PEP_STATUS_OK);
   15.14      TEST_ASSERT_MSG(ct == PEP_ct_key_expired_but_confirmed, tl_ct_string(ct));
   15.15      
   15.16      // Ok, so I want to make sure we make an entry, so I'll try to decrypt the message WITH
   15.17 @@ -250,6 +257,13 @@
   15.18      status = update_identity(session, expired_inquisitor);
   15.19      TEST_ASSERT_MSG((status == PEP_KEY_UNSUITABLE), tl_status_string(status));
   15.20      PEP_comm_type ct = expired_inquisitor->comm_type;    
   15.21 +    TEST_ASSERT_MSG(ct == PEP_ct_key_not_found, tl_ct_string(ct));
   15.22 +    TEST_ASSERT(!expired_inquisitor->fpr);
   15.23 +    
   15.24 +    expired_inquisitor->fpr = strdup(inquisitor_fpr);
   15.25 +    status = get_trust(session, expired_inquisitor);
   15.26 +    ct = expired_inquisitor->comm_type;    
   15.27 +    TEST_ASSERT(status == PEP_STATUS_OK);
   15.28      TEST_ASSERT_MSG(ct == PEP_ct_key_expired_but_confirmed, tl_ct_string(ct));
   15.29      
   15.30      // Ok, so I want to make sure we make an entry, so I'll try to decrypt the message WITH
    16.1 --- a/test/src/engine_tests/ExternalRevokeTests.cc	Thu Jun 27 12:40:43 2019 +0200
    16.2 +++ b/test/src/engine_tests/ExternalRevokeTests.cc	Tue Jul 09 11:24:36 2019 +0200
    16.3 @@ -255,8 +255,9 @@
    16.4      
    16.5      status = get_trust(session, recip1);
    16.6  
    16.7 -    cout << "Recip's trust DB comm_type (should be unknown, as we're using a keyring-only key, not in DB) = "  << tl_ct_string(recip1->comm_type) << endl;
    16.8 -    TEST_ASSERT_MSG((recip1->comm_type != PEP_ct_OpenPGP_unconfirmed), "recip1->comm_type != PEP_ct_OpenPGP_unconfirmed");
    16.9 +//    cout << "Recip's trust DB comm_type (should be unknown, as we're using a keyring-only key, not in DB) = "  << tl_ct_string(recip1->comm_type) << endl;
   16.10 +    cout << "Recip's trust DB comm_type (should PEP_ct_OpenPGP_unconfirmed), as we now record this when using update_identity on no-default idents = "  << tl_ct_string(recip1->comm_type) << endl;
   16.11 +    TEST_ASSERT_MSG((recip1->comm_type == PEP_ct_OpenPGP_unconfirmed), tl_ct_string(recip1->comm_type));
   16.12  
   16.13      // decrypt message
   16.14  //    free_message(outgoing_msg);
   16.15 @@ -285,8 +286,9 @@
   16.16      
   16.17      status = get_trust(session, recip1);
   16.18      
   16.19 -    cout << "Recip's trust DB comm_type (should be unknown - there's nothing in the DB) = "  << tl_ct_string(recip1->comm_type) << endl;
   16.20 -    TEST_ASSERT_MSG((recip1->comm_type == PEP_ct_unknown), "recip1->comm_type == PEP_ct_unknown");
   16.21 +//    cout << "Recip's trust DB comm_type (should be unknown - there's nothing in the DB) = "  << tl_ct_string(recip1->comm_type) << endl;
   16.22 +    cout << "Recip's trust DB comm_type (should be PEP_ct_OpenPGP_unconfirmed, as we now store it.) = "  << tl_ct_string(recip1->comm_type) << endl;
   16.23 +    TEST_ASSERT_MSG((recip1->comm_type == PEP_ct_OpenPGP_unconfirmed), tl_ct_string(recip1->comm_type));
   16.24  
   16.25      free_message(encrypted_outgoing_msg);
   16.26      free_message(decrypted_msg);
    17.1 --- a/test/src/engine_tests/IOS1664Tests.cc	Thu Jun 27 12:40:43 2019 +0200
    17.2 +++ b/test/src/engine_tests/IOS1664Tests.cc	Tue Jul 09 11:24:36 2019 +0200
    17.3 @@ -48,12 +48,23 @@
    17.4      
    17.5      pEp_identity* you = new_identity("superxat@gmail.com", NULL, NULL, NULL);
    17.6      
    17.7 +    // N.B. while obviously it would be better to write the test expecting us to 
    17.8 +    // accept the key, I'm actually testing that we don't get the wrong status
    17.9 +    // based on the presumption of rejection
   17.10 +    
   17.11      message* out_msg = new_message(PEP_dir_outgoing);
   17.12      out_msg->from = me;
   17.13      out_msg->to = new_identity_list(you);
   17.14      out_msg->shortmsg = strdup("Hussidente 2020!");
   17.15      out_msg->longmsg = strdup("A Huss in every office!");
   17.16      
   17.17 +    status = identity_rating(session, out_msg->from, &rating);
   17.18 +    TEST_ASSERT(status == PEP_STATUS_OK);
   17.19 +    TEST_ASSERT_MSG(rating == PEP_rating_trusted_and_anonymized, tl_rating_string(rating));
   17.20 +    status = identity_rating(session, out_msg->to->ident, &rating);
   17.21 +    TEST_ASSERT_MSG(status == PEP_KEY_NOT_FOUND, tl_status_string(status));
   17.22 +    TEST_ASSERT_MSG(rating == PEP_rating_undefined, tl_rating_string(rating));
   17.23 +
   17.24      status = outgoing_message_rating(session, out_msg, &rating);
   17.25      TEST_ASSERT(rating == PEP_rating_unencrypted);
   17.26      
    18.1 --- a/test/src/engine_tests/NewUpdateIdAndMyselfTests.cc	Thu Jun 27 12:40:43 2019 +0200
    18.2 +++ b/test/src/engine_tests/NewUpdateIdAndMyselfTests.cc	Tue Jul 09 11:24:36 2019 +0200
    18.3 @@ -500,10 +500,10 @@
    18.4      TEST_ASSERT_MSG((bernd->user_id), "bernd->user_id");
    18.5      TEST_ASSERT_MSG((strcmp(bernd->user_id, bernd_userid) == 0), "strcmp(bernd->user_id, bernd_userid) == 0"); // ???
    18.6      TEST_ASSERT_MSG((!bernd->me), "!bernd->me"); 
    18.7 -    TEST_ASSERT_MSG((bernd->comm_type == PEP_ct_key_expired), "bernd->comm_type == PEP_ct_key_expired");
    18.8 +    TEST_ASSERT_MSG((bernd->comm_type == PEP_ct_key_not_found), tl_ct_string(bernd->comm_type));
    18.9      TEST_ASSERT_MSG((strcmp(bernd->address, bernd_address) == 0), "strcmp(bernd->address, bernd_address) == 0");
   18.10  
   18.11 -    cout << "PASS: update_identity() correctly rejected expired key with PEP_KEY_UNSUITABLE and PEP_ct_key_expired" << endl << endl;
   18.12 +    cout << "PASS: update_identity() correctly rejected expired key with PEP_KEY_UNSUITABLE and PEP_ct_key_not_found" << endl << endl;
   18.13      free_identity(bernd);
   18.14      
   18.15  }
    19.1 --- a/test/src/engine_tests/RevocationTests.cc	Thu Jun 27 12:40:43 2019 +0200
    19.2 +++ b/test/src/engine_tests/RevocationTests.cc	Tue Jul 09 11:24:36 2019 +0200
    19.3 @@ -52,8 +52,24 @@
    19.4      TEST_ASSERT_MSG((status == PEP_TEST_KEY_IMPORT_SUCCESS), "status == PEP_STATUS_OK");
    19.5  
    19.6      pEp_identity* post = new_identity("linda@example.org", NULL, NULL, NULL);
    19.7 +    
    19.8 +//    string save_fpr = post->fpr;
    19.9 +
   19.10 +    stringlist_t* keylist = NULL;
   19.11 +    
   19.12 +    status = find_keys(session, "linda@example.org", &keylist);
   19.13 +    TEST_ASSERT(status == PEP_STATUS_OK);
   19.14 +    
   19.15      status = update_identity(session, post);
   19.16      // PEP_KEY_UNSUITABLE => revoked (or something similar).
   19.17      TEST_ASSERT_MSG((status == PEP_KEY_UNSUITABLE), tl_status_string(status));
   19.18 +    TEST_ASSERT_MSG((post->comm_type == PEP_ct_key_not_found), tl_ct_string(post->comm_type));
   19.19 +    free(post->fpr);
   19.20 +    post->fpr = strdup(keylist->value);
   19.21 +    status = get_trust(session, post);
   19.22 +    TEST_ASSERT(status == PEP_STATUS_OK);
   19.23      TEST_ASSERT_MSG((post->comm_type == PEP_ct_key_revoked), tl_ct_string(post->comm_type));
   19.24 +    free_identity(pre);
   19.25 +    free_identity(post);
   19.26 +    free_stringlist(keylist);    
   19.27  }
    20.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.2 +++ b/test/src/engine_tests/StrnstrTests.cc	Tue Jul 09 11:24:36 2019 +0200
    20.3 @@ -0,0 +1,154 @@
    20.4 +// This file is under GNU General Public License 3.0
    20.5 +// see LICENSE.txt
    20.6 +
    20.7 +#include <stdlib.h>
    20.8 +#include <cstring>
    20.9 +#include <string>
   20.10 +
   20.11 +#include <cpptest.h>
   20.12 +#include "test_util.h"
   20.13 +
   20.14 +#include "pEpEngine.h"
   20.15 +#include "platform_unix.h"
   20.16 +
   20.17 +#include "EngineTestIndividualSuite.h"
   20.18 +#include "StrnstrTests.h"
   20.19 +
   20.20 +using namespace std;
   20.21 +
   20.22 +StrnstrTests::StrnstrTests(string suitename, string test_home_dir) :
   20.23 +    EngineTestIndividualSuite::EngineTestIndividualSuite(suitename, test_home_dir) {
   20.24 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_equal"),
   20.25 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_equal)));
   20.26 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_first_empty"),
   20.27 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_first_empty)));
   20.28 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_second_empty"),
   20.29 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_second_empty)));
   20.30 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_both_empty"),
   20.31 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_both_empty)));
   20.32 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_first_letter_only"),
   20.33 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_first_letter_only)));
   20.34 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_first_two_only"),
   20.35 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_first_two_only)));
   20.36 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_all_but_last"),
   20.37 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_all_but_last)));
   20.38 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_same_len_all_but_last"),
   20.39 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_same_len_all_but_last)));
   20.40 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_same_len_none"),
   20.41 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_same_len_none)));
   20.42 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_same_big_smaller"),
   20.43 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_same_big_smaller)));
   20.44 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_shift_one_no_match"),
   20.45 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_shift_one_no_match)));
   20.46 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_shift_to_end"),
   20.47 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_shift_to_end)));
   20.48 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_match_after_end"),
   20.49 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_match_after_end)));
   20.50 +    add_test_to_suite(std::pair<std::string, void (Test::Suite::*)()>(string("StrnstrTests::check_strnstr_equal_but_size_too_small"),
   20.51 +                                                                      static_cast<Func>(&StrnstrTests::check_strnstr_equal_but_size_too_small)));
   20.52 +}
   20.53 +
   20.54 +void StrnstrTests::check_strnstr_equal() {
   20.55 +    const char* big = "Bob123";
   20.56 +    const char* little = "Bob123";
   20.57 +    size_t size = strlen(big);
   20.58 +    const char* result = strnstr(big, little, size);
   20.59 +    TEST_ASSERT_MSG(result == big, result);
   20.60 +}
   20.61 +
   20.62 +void StrnstrTests::check_strnstr_first_empty() {
   20.63 +    const char* big = "";
   20.64 +    const char* little = "Bob123";
   20.65 +    size_t size = strlen(big);
   20.66 +    const char* result = strnstr(big, little, size);
   20.67 +    TEST_ASSERT_MSG(result == NULL, result);
   20.68 +}
   20.69 +void StrnstrTests::check_strnstr_second_empty() {
   20.70 +    const char* big = "YerMama";
   20.71 +    const char* little = "";
   20.72 +    size_t size = strlen(big);
   20.73 +    const char* result = strnstr(big, little, size);
   20.74 +    TEST_ASSERT_MSG(result == big, result);
   20.75 +    TEST_ASSERT(true);
   20.76 +}
   20.77 +
   20.78 +void StrnstrTests::check_strnstr_both_empty() {
   20.79 +    const char* big = "";
   20.80 +    const char* little = "";
   20.81 +    size_t size = strlen(big);
   20.82 +    const char* result = strnstr(big, little, size);
   20.83 +    TEST_ASSERT_MSG(result == big, result);
   20.84 +    TEST_ASSERT(true);
   20.85 +}
   20.86 +
   20.87 +void StrnstrTests::check_strnstr_first_letter_only() {
   20.88 +    const char* big = "Bob123";
   20.89 +    const char* little = "Beef";
   20.90 +    size_t size = strlen(big);
   20.91 +    const char* result = strnstr(big, little, size);
   20.92 +    TEST_ASSERT_MSG(result == NULL, result);    
   20.93 +}
   20.94 +void StrnstrTests::check_strnstr_first_two_only() {
   20.95 +    const char* big = "Bob123";
   20.96 +    const char* little = "Boof";
   20.97 +    size_t size = strlen(big);
   20.98 +    const char* result = strnstr(big, little, size);
   20.99 +    TEST_ASSERT_MSG(result == NULL, result);    
  20.100 +}
  20.101 +void StrnstrTests::check_strnstr_all_but_last() {
  20.102 +    const char* big = "BeesBeesBees";
  20.103 +    const char* little = "Beef";
  20.104 +    size_t size = strlen(big);
  20.105 +    const char* result = strnstr(big, little, size);
  20.106 +    TEST_ASSERT_MSG(result == NULL, result);    
  20.107 +}
  20.108 +void StrnstrTests::check_strnstr_same_len_all_but_last() {
  20.109 +    const char* big = "Bees";
  20.110 +    const char* little = "Beef";
  20.111 +    size_t size = strlen(big);
  20.112 +    const char* result = strnstr(big, little, size);
  20.113 +    TEST_ASSERT_MSG(result == NULL, result);    
  20.114 +}
  20.115 +void StrnstrTests::check_strnstr_same_len_none() {
  20.116 +    const char* big = "1234";
  20.117 +    const char* little = "Beef";
  20.118 +    size_t size = strlen(big);
  20.119 +    const char* result = strnstr(big, little, size);
  20.120 +    TEST_ASSERT_MSG(result == NULL, result);    
  20.121 +}
  20.122 +void StrnstrTests::check_strnstr_same_big_smaller() {
  20.123 +    const char* big = "Bee";
  20.124 +    const char* little = "Bees";
  20.125 +    size_t size = strlen(big);
  20.126 +    const char* result = strnstr(big, little, size);
  20.127 +    TEST_ASSERT_MSG(result == NULL, result);    
  20.128 +}
  20.129 +void StrnstrTests::check_strnstr_shift_one_no_match() {
  20.130 +    const char* big = "1Bee";
  20.131 +    const char* little = "Bees";
  20.132 +    size_t size = strlen(big);
  20.133 +    const char* result = strnstr(big, little, size);
  20.134 +    TEST_ASSERT_MSG(result == NULL, result);    
  20.135 +}
  20.136 +void StrnstrTests::check_strnstr_shift_to_end() {
  20.137 +    const char* big = "BigBeeWithExtraBeef";
  20.138 +    const char* little = "Beef";
  20.139 +    size_t size = strlen(big);
  20.140 +    const char* result = strnstr(big, little, size);
  20.141 +    TEST_ASSERT_MSG(result == big + 15, result);    
  20.142 +    TEST_ASSERT(true);
  20.143 +}
  20.144 +void StrnstrTests::check_strnstr_match_after_end() {
  20.145 +    const char* big = "EatMoreBeef";
  20.146 +    const char* little = "Beef";
  20.147 +    size_t size = strlen(big);
  20.148 +    const char* result = strnstr(big, little, size - 1);
  20.149 +    TEST_ASSERT_MSG(result == NULL, result);
  20.150 +}
  20.151 +void StrnstrTests::check_strnstr_equal_but_size_too_small() {
  20.152 +    const char* big = "Bob123";
  20.153 +    const char* little = "Bob123";
  20.154 +    size_t size = strlen(big);
  20.155 +    const char* result = strnstr(big, little, size - 1);
  20.156 +    TEST_ASSERT_MSG(result == NULL, result);
  20.157 +}