merged in default ENGINE-214
authorKrista Bennett <krista@pep-project.org>
Tue, 19 Sep 2017 12:38:55 +0200
branchENGINE-214
changeset 2077d6ea1827e4e3
parent 2056 416d7d4e26b1
parent 2067 d9b52129daef
child 2078 12571364b016
merged in default
     1.1 --- a/build-config/common.conf	Wed Sep 13 08:38:48 2017 +0200
     1.2 +++ b/build-config/common.conf	Tue Sep 19 12:38:55 2017 +0200
     1.3 @@ -62,10 +62,7 @@
     1.4  
     1.5  ######### OpenPGP #########
     1.6  # Path of GPG binary
     1.7 -GPG_CMD=gpg
     1.8 -ifneq ($(shell which gpg2),)
     1.9 -    GPG_CMD=gpg2
    1.10 -endif
    1.11 +GPG_CMD:=$(shell gpgconf --list-components | awk -F: '/^gpg:/ { print $$3; exit 0; }')
    1.12  # Selects OpenPGP implementation. must be either `GPG` or `NETPGP`
    1.13  OPENPGP=GPG
    1.14  # Path of libGPGME binary
     2.1 --- a/src/blacklist.h	Wed Sep 13 08:38:48 2017 +0200
     2.2 +++ b/src/blacklist.h	Tue Sep 19 12:38:55 2017 +0200
     2.3 @@ -22,12 +22,12 @@
     2.4  //
     2.5  //  parameters:
     2.6  //      session (in)        session to use
     2.7 -//      fpr (in)            fingerprint of key to blacklist
     2.8 +//      fpr (in)            fingerprint of key to be removed from blacklist
     2.9  
    2.10  DYNAMIC_API PEP_STATUS blacklist_delete(PEP_SESSION session, const char *fpr);
    2.11  
    2.12  
    2.13 -// blacklist_is_listed() - is_listed from blacklist
    2.14 +// blacklist_is_listed() - is_listed in blacklist
    2.15  //
    2.16  //  parameters:
    2.17  //      session (in)        session to use
     3.1 --- a/src/keymanagement.h	Wed Sep 13 08:38:48 2017 +0200
     3.2 +++ b/src/keymanagement.h	Tue Sep 19 12:38:55 2017 +0200
     3.3 @@ -169,7 +169,7 @@
     3.4  //  parameters:
     3.5  //      session (in)        session to use
     3.6  //      fpr (in)            fingerprint of key to test
     3.7 -//      bool (out)          flags if key is own
     3.8 +//      listed (out)        flags if key is own
     3.9  
    3.10  DYNAMIC_API PEP_STATUS own_key_is_listed(
    3.11          PEP_SESSION session,
     4.1 --- a/src/pgp_gpg.c	Wed Sep 13 08:38:48 2017 +0200
     4.2 +++ b/src/pgp_gpg.c	Tue Sep 19 12:38:55 2017 +0200
     4.3 @@ -97,6 +97,82 @@
     4.4      return true;
     4.5  }
     4.6  
     4.7 +char* _undot_address(const char* address) {
     4.8 +    if (!address)
     4.9 +        return NULL;
    4.10 +    
    4.11 +    int addr_len = strlen(address);
    4.12 +    const char* at = strstr(address, "@");
    4.13 +    
    4.14 +    if (!at)
    4.15 +        at = address + addr_len;
    4.16 +        
    4.17 +    char* retval = calloc(1, addr_len + 1);
    4.18 +
    4.19 +    const char* addr_curr = address;
    4.20 +    char* retval_curr = retval;
    4.21 +    
    4.22 +    while (addr_curr < at) {
    4.23 +        if (*addr_curr == '.') {
    4.24 +            addr_curr++;
    4.25 +            continue;
    4.26 +        }
    4.27 +        *retval_curr = *addr_curr;
    4.28 +        retval_curr++;
    4.29 +        addr_curr++;
    4.30 +    }
    4.31 +    if (*addr_curr == '@')
    4.32 +        strcat(retval_curr, addr_curr);
    4.33 +    
    4.34 +    return retval;
    4.35 +}
    4.36 +
    4.37 +static bool _email_heuristic_match(const char* str1, const char* str2) {
    4.38 +    if (!str1 || !str2)
    4.39 +        return false;
    4.40 +        
    4.41 +    if (strcasecmp(str1, str2) == 0)
    4.42 +        return true;
    4.43 +    
    4.44 +    int len1 = strlen(str1);
    4.45 +    int len2 = strlen(str2);
    4.46 +    
    4.47 +    // otherwise, we work against dotted usernames
    4.48 +    const char* at1 = strstr(str1, "@");
    4.49 +    const char* at2 = strstr(str2, "@");
    4.50 +    
    4.51 +    if (!at1)
    4.52 +        at1 = str1 + len1;
    4.53 +    
    4.54 +    if (!at2)
    4.55 +        at2 = str2 + len2;
    4.56 +        
    4.57 +    // This sucks. And is expensive. Here we go.
    4.58 +    const char* str1_curr = str1;
    4.59 +    const char* str2_curr = str2;
    4.60 +    
    4.61 +    while (str1_curr > at1 && str2_curr > at2) {
    4.62 +        if (*str1_curr == '.') {
    4.63 +            str1_curr++;
    4.64 +            continue;
    4.65 +        }
    4.66 +
    4.67 +        if (*str2_curr == '.') {
    4.68 +            str2_curr++;
    4.69 +            continue;
    4.70 +        }
    4.71 +        
    4.72 +        if (tolower(*str1_curr) != tolower(*str2_curr))
    4.73 +            return false;
    4.74 +        
    4.75 +        str1_curr++;
    4.76 +        str2_curr++;
    4.77 +    }
    4.78 +    if (str1_curr == at1 && str2_curr == at2)
    4.79 +        return true;
    4.80 +    
    4.81 +    return false;
    4.82 +}
    4.83  
    4.84  PEP_STATUS pgp_init(PEP_SESSION session, bool in_first)
    4.85  {
    4.86 @@ -284,7 +360,7 @@
    4.87              = (gpgme_get_key_t) (intptr_t) dlsym(gpgme, "gpgme_get_key");
    4.88          assert(gpg.gpgme_get_key);
    4.89          
    4.90 -        #ifdef GPGME_VERSION_NUMBER 
    4.91 +        #ifdef GPGME_VERSION_NUMBER
    4.92          #if (GPGME_VERSION_NUMBER >= 0x010700)
    4.93                  gpg.gpgme_op_createkey
    4.94                      = (gpgme_op_createkey_t) (intptr_t) dlsym(gpgme,
    4.95 @@ -581,7 +657,7 @@
    4.96                      gpgme_verify_result =
    4.97                          gpg.gpgme_op_verify_result(session->ctx);
    4.98                              assert(gpgme_verify_result);
    4.99 -                    gpgme_signature = gpgme_verify_result->signatures;                    
   4.100 +                    gpgme_signature = gpgme_verify_result->signatures;
   4.101                  }
   4.102  
   4.103                  if (gpgme_signature) {
   4.104 @@ -689,7 +765,7 @@
   4.105                      *keylist = _keylist;
   4.106                      if (recipient_keylist) {
   4.107                          if (!_keylist)
   4.108 -                            *keylist = new_stringlist(""); // no sig 
   4.109 +                            *keylist = new_stringlist(""); // no sig
   4.110                          if (!(*keylist)) {
   4.111                              free_stringlist(_keylist);
   4.112                              if (recipient_keylist)
   4.113 @@ -698,7 +774,7 @@
   4.114                              gpg.gpgme_data_release(cipher);
   4.115                              free(_buffer);
   4.116                              return PEP_OUT_OF_MEMORY;
   4.117 -                        }    
   4.118 +                        }
   4.119                          stringlist_append(*keylist, recipient_keylist);
   4.120                      }
   4.121                  }
   4.122 @@ -909,7 +985,7 @@
   4.123      PEP_SESSION session, const stringlist_t *keylist, const char *ptext,
   4.124      size_t psize, char **ctext, size_t *csize, bool sign
   4.125  )
   4.126 -{    
   4.127 +{
   4.128      PEP_STATUS result;
   4.129      gpgme_error_t gpgme_error;
   4.130      gpgme_data_t plain, cipher;
   4.131 @@ -1120,7 +1196,7 @@
   4.132  static PEP_STATUS _pgp_createkey(PEP_SESSION session, pEp_identity *identity) {
   4.133      PEP_STATUS status = PEP_VERSION_MISMATCH;
   4.134  
   4.135 -    if (identity && identity->address) {    
   4.136 +    if (identity && identity->address) {
   4.137  #ifdef GPGME_VERSION_NUMBER 
   4.138  #if (GPGME_VERSION_NUMBER >= 0x010700)
   4.139          gpgme_error_t gpgme_error;
   4.140 @@ -1139,7 +1215,7 @@
   4.141          if (gpgme_error != GPG_ERR_NOT_SUPPORTED) {
   4.142              switch (gpgme_error) {
   4.143                  case GPG_ERR_NO_ERROR:
   4.144 -                    break;		    
   4.145 +                    break;
   4.146                  case GPG_ERR_INV_VALUE:
   4.147                      return PEP_ILLEGAL_VALUE;
   4.148                  case GPG_ERR_GENERAL:
   4.149 @@ -1147,7 +1223,7 @@
   4.150                  default:
   4.151                      assert(0);
   4.152                      return PEP_UNKNOWN_ERROR;
   4.153 -            }        
   4.154 +            }
   4.155  
   4.156              /* This is the same regardless of whether we got it from genkey or createkey */
   4.157              gpgme_genkey_result_t gpgme_genkey_result = gpg.gpgme_op_genkey_result(session->ctx);
   4.158 @@ -1159,7 +1235,7 @@
   4.159              PEP_STATUS key_status = find_single_key(session, fpr, &key);
   4.160              if (!key || key_status != PEP_STATUS_OK)
   4.161                  return PEP_CANNOT_CREATE_KEY;
   4.162 -                                
   4.163 +            
   4.164              gpgme_error = gpg.gpgme_op_createsubkey(session->ctx, key, 
   4.165                                                      "RSA", 0, 
   4.166                                                      31536000, GPGME_CREATE_NOPASSWD 
   4.167 @@ -1167,7 +1243,7 @@
   4.168  
   4.169              switch (gpgme_error) {
   4.170                  case GPG_ERR_NO_ERROR:
   4.171 -                    break;		    
   4.172 +                    break;
   4.173                  case GPG_ERR_INV_VALUE:
   4.174                      return PEP_ILLEGAL_VALUE;
   4.175                  case GPG_ERR_GENERAL:
   4.176 @@ -1175,7 +1251,7 @@
   4.177                  default:
   4.178                      assert(0);
   4.179                      return PEP_UNKNOWN_ERROR;
   4.180 -            }        
   4.181 +            }
   4.182              
   4.183              free(identity->fpr);
   4.184              identity->fpr = fpr;
   4.185 @@ -1185,7 +1261,7 @@
   4.186  //            gpg.gpgme_key_unref(key);
   4.187              
   4.188              status = pgp_replace_only_uid(session, fpr,
   4.189 -                        identity->username, identity->address);                       
   4.190 +                        identity->username, identity->address);
   4.191          }
   4.192  #endif
   4.193  #endif
   4.194 @@ -1726,9 +1802,10 @@
   4.195                      break;
   4.196                  assert(key->uids);
   4.197                  gpgme_user_id_t kuid = key->uids;
   4.198 -                // check that at least one uid's email matches pattern exactly
   4.199 +                // check that at least one uid's email matches pattern exactly,
   4.200 +                // modulo the email-diff heuristic
   4.201                  while(kuid) {
   4.202 -                    if((pattern && kuid->email && strcmp(kuid->email, pattern) == 0) ||
   4.203 +                    if((pattern && kuid->email && _email_heuristic_match(kuid->email, pattern)) ||
   4.204                         pattern == NULL /* match all */ )
   4.205                      { 
   4.206                          char *fpr = key->subkeys->fpr;
   4.207 @@ -1759,7 +1836,23 @@
   4.208      if (_keylist->value == NULL) {
   4.209          free_stringlist(_keylist);
   4.210          _keylist = NULL;
   4.211 -    }
   4.212 +        
   4.213 +        // If match failed, check to see if we've got a dotted address in the pattern.
   4.214 +        // (last chance of the heuristic, really)
   4.215 +        // If so, try again without any dots.
   4.216 +        const char* dotpos = strstr(pattern, ".");
   4.217 +        const char* atpos = strstr(pattern, "@");
   4.218 +        if (dotpos && atpos && (dotpos < atpos)) {
   4.219 +            char* undotted = _undot_address(pattern);
   4.220 +            if (undotted) {
   4.221 +                PEP_STATUS status = _pgp_search_keys(session, undotted,
   4.222 +                                                     keylist, private_only);
   4.223 +                free(undotted);
   4.224 +                return status;
   4.225 +            }
   4.226 +        }
   4.227 +    }    
   4.228 +    
   4.229      *keylist = _keylist;
   4.230      return PEP_STATUS_OK;
   4.231  }
   4.232 @@ -1964,7 +2057,7 @@
   4.233                      return GPG_ERR_ENOMEM;
   4.234                  }
   4.235                  strlcpy(realname, handle->realname, realname_strlen + 1);
   4.236 -                realname[realname_strlen] = '\n'; 
   4.237 +                realname[realname_strlen] = '\n';
   4.238                  gpg.gpgme_io_write(fd, realname, realname_strlen + 1);
   4.239                  handle->state = replace_uid_email;
   4.240                  free(realname);
   4.241 @@ -1986,7 +2079,7 @@
   4.242                      return GPG_ERR_ENOMEM;
   4.243                  }
   4.244                  strlcpy(email, handle->email, email_strlen + 1);
   4.245 -                email[email_strlen] = '\n'; 
   4.246 +                email[email_strlen] = '\n';
   4.247                  gpg.gpgme_io_write(fd, email, email_strlen + 1);
   4.248                  handle->state = replace_uid_comment;
   4.249                  free(email);
   4.250 @@ -2134,7 +2227,7 @@
   4.251              return GPG_ERR_GENERAL;
   4.252              
   4.253          default:
   4.254 -            break;                
   4.255 +            break;
   4.256      }
   4.257      return GPG_ERR_NO_ERROR;
   4.258  }
     5.1 --- a/test/Makefile	Wed Sep 13 08:38:48 2017 +0200
     5.2 +++ b/test/Makefile	Tue Sep 19 12:38:55 2017 +0200
     5.3 @@ -57,6 +57,12 @@
     5.4  UNIT_TESTS=$(subst .cc,,$(UNIT_TESTS_SOURCE))
     5.5  UNIT_TESTS_RUN=$(subst .cc,_run,$(UNIT_TESTS_SOURCE))
     5.6  
     5.7 +ifneq ($(MAKECMDGOALS),clean)
     5.8 +    ifneq (,$(findstring -DNDEBUG,$(CFLAGS)))
     5.9 +        $(error The macro NDEBUG must not be defined for test compilation.)
    5.10 +    endif
    5.11 +endif
    5.12 +
    5.13  .PHONY: all
    5.14  all: $(TARGET) $(UNIT_TESTS)
    5.15  
     6.1 --- a/test/pEp_subject_received_test.cc	Wed Sep 13 08:38:48 2017 +0200
     6.2 +++ b/test/pEp_subject_received_test.cc	Tue Sep 19 12:38:55 2017 +0200
     6.3 @@ -36,7 +36,7 @@
     6.4      pEp_identity * me = new_identity("pep.test.recip@kgrothoff.org", "93D19F24AD6F4C4BA9134AAF84D9217908DB0AEE", PEP_OWN_USERID, "pEp Test Recipient");    
     6.5      PEP_STATUS status = myself(session, me);
     6.6      
     6.7 -    pEp_identity * you = new_identity("pep.test.apple@pep-project.org", NULL, "TOFU_pep.test.apple@pep-project.org", "pEp Test Recipient");    
     6.8 +    pEp_identity * you = new_identity("pep.test.alice@pep-project.org", NULL, "TOFU_pep.test.alice@pep-project.org", "Alice Test");    
     6.9      
    6.10      status = update_identity(session, you);
    6.11      trust_personal_key(session, you);