merged in default ENGINE-633
authorKrista 'DarthMama' Bennett <krista@pep.foundation>
Mon, 13 Jul 2020 11:44:38 +0200
branchENGINE-633
changeset 48455feb6ee6b3e8
parent 4844 b63f3919f279
parent 4843 d5122e1d7ace
child 4848 e58bce005c91
merged in default
src/baseprotocol.c
src/message_api.c
src/pEpEngine.h
     1.1 --- a/.hgtags	Fri Jul 10 15:07:38 2020 +0200
     1.2 +++ b/.hgtags	Mon Jul 13 11:44:38 2020 +0200
     1.3 @@ -48,3 +48,8 @@
     1.4  a046dab8883fbc25a5ca4940e252ce6f0a862002 Release_2.1.0-RC8
     1.5  f783fb44981d96e46f9454977cec34eb027f9ab2 Release_2.1.0-RC9
     1.6  3b2ea2c1f5a1c033c1fcc1ee6e7d7ac35778597e Release_2.1.0-RC10
     1.7 +47231c726a380bf53411436a6a21091b6c59f283 Release_2.1.0-RC11
     1.8 +d0150fa70a3df2eeb5b96f68917a910ebcaa4597 Release_2.1.0-RC12
     1.9 +89e31ecdc61b25533eb7d00d09f1d44afcddf7e4 Release_2.1.0-RC13
    1.10 +64797b875a00d3167a4a53c6c80298141ed37376 Release_2.1.0-RC14
    1.11 +2c94359b432679702352ecd8705f4321eca3328a Release_2.1.0-RC15
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/release_rc.py	Mon Jul 13 11:44:38 2020 +0200
     2.3 @@ -0,0 +1,218 @@
     2.4 +import subprocess
     2.5 +import re
     2.6 +import sys
     2.7 +import argparse
     2.8 +
     2.9 +parser = argparse.ArgumentParser(description='Automate the RC release process as sanely as possible.')
    2.10 +parser.add_argument('-r','--rev',nargs=1, help="revision number or changeset to tag as next RC")
    2.11 +group = parser.add_mutually_exclusive_group(required=False)
    2.12 +group.add_argument('-v','--version',nargs=4, type=int, help="force this version - bypasses version inference. Format: major minor patch RC")
    2.13 +group.add_argument('--rc', type=int, help="force this RC number on the inferred version")
    2.14 +args = parser.parse_args()
    2.15 +
    2.16 +# Note: we could get this from the macros, but since folks seem to be actually upgrading 
    2.17 +# the release tag manually correctly and not the macro, let's just check both
    2.18 +cmd = ["hg", "log", "-r", ".", "--template", "\"{latesttag(r're:Release_[0-9]+\.[0-9]+\.[0-9]+-RC[0-9]+')}\""]
    2.19 +result = subprocess.run(cmd, capture_output=True)
    2.20 +release_string = result.stdout.decode("utf-8").replace('"','')
    2.21 +#print(release_string)
    2.22 +
    2.23 +changeset = args.rev # can be None :)
    2.24 +
    2.25 +major = -1
    2.26 +minor = -1
    2.27 +patch = -1
    2.28 +rc = -1
    2.29 +
    2.30 +if args.version:
    2.31 +    major = args.version[0]
    2.32 +    minor = args.version[1]
    2.33 +    patch = args.version[2]
    2.34 +    rc = args.version[3]
    2.35 +    #print(rc)
    2.36 +    if (major < 0) or (minor < 0) or (patch < 0) or (rc < 0):
    2.37 +        raise Exception("Version numbers must all be positive values.")
    2.38 +elif args.rc:
    2.39 +    rc = args.rc
    2.40 +    if (rc < 0):
    2.41 +        raise Exception("RC numbers must all be positive values.")
    2.42 +
    2.43 +#define PEP_ENGINE_VERSION_MAJOR 2
    2.44 +#define PEP_ENGINE_VERSION_MINOR 1
    2.45 +#define PEP_ENGINE_VERSION_PATCH 0
    2.46 +#define PEP_ENGINE_VERSION_RC    13
    2.47 +
    2.48 +# Amateur hour. Biteme.
    2.49 +cmd = ["grep", "-E", "#define PEP_ENGINE_VERSION_[A-Z]+[ \t]+[0-9]+", "src/pEpEngine.h"]
    2.50 +result = subprocess.run(cmd, capture_output=True)
    2.51 +grep_output = result.stdout.decode("utf-8")
    2.52 +#print(grep_output)
    2.53 +
    2.54 +if not args.version:
    2.55 +    src_nums = []
    2.56 +    src_nums = re.findall(r'([0-9]+)', grep_output)
    2.57 +        
    2.58 +    if not src_nums:
    2.59 +        raise Exception("Somehow, the source values for the engine versions were not found in src/pEpEngine.h. Aborting.")
    2.60 +    if len(src_nums) != 4:
    2.61 +        raise Exception("Somehow, we could not extract all version numbers from the header file src/pEpEngine.h. Aborting.")
    2.62 +            
    2.63 +    tag_nums = []
    2.64 +    if release_string.startswith("Release_"):
    2.65 +        tag_nums = re.findall(r'([0-9]+)', release_string)
    2.66 +    #    for num in tagnums:
    2.67 +    #        print (num)
    2.68 +
    2.69 +    if not tag_nums or len(tag_nums) != 4:
    2.70 +        if not tag_nums:
    2.71 +            print("Wow... there is no extant release tag. What did you do, wipe the repository?")
    2.72 +        else:
    2.73 +            print("Somehow, there was an error with the numbering of the tag \"" + release_string + "\"")
    2.74 +        print("Do you want to continue? We'll make a tag from the source RC info. (Y/N)[enter]")
    2.75 +        a = input().lower()
    2.76 +        if not (a.startswith("y") or a.startswith("Y")):
    2.77 +            sys.exit()
    2.78 +            
    2.79 +    force = False
    2.80 +
    2.81 +    if len(tag_nums) == 4 and src_nums:
    2.82 +        major_tag = int(tag_nums[0])
    2.83 +        major_src = int(src_nums[0])
    2.84 +        minor_tag = int(tag_nums[1])
    2.85 +        minor_src = int(src_nums[1])
    2.86 +        patch_tag = int(tag_nums[2])
    2.87 +        patch_src = int(src_nums[2])
    2.88 +        rc_tag = int(tag_nums[3])
    2.89 +        rc_src = int(src_nums[3])
    2.90 +
    2.91 +        print("Inferring current/next version info for automatic upgrade:")
    2.92 +        print("Tagged (should show current):                    " + str(major_tag) + "." + str(minor_tag) + "." + str(patch_tag) + "." + str(rc_tag))
    2.93 +        print("Source (should show *next* (i.e. this upgrade)): " + str(major_src) + "." + str(minor_src) + "." + str(patch_src) + "." + str(rc_src))            
    2.94 +            
    2.95 +        if (major_tag == major_src):
    2.96 +            major = major_tag
    2.97 +            if (minor_tag == minor_src):
    2.98 +                minor = minor_tag
    2.99 +                if (patch_tag == patch_src):
   2.100 +                    patch = patch_tag
   2.101 +                    # Hoorah, we're just changing the RC number.
   2.102 +                    if (rc < 0):
   2.103 +                        if (rc_tag == (rc_src - 1)):
   2.104 +                            # Best case!
   2.105 +                            rc = rc_src
   2.106 +                        elif (rc_tag == rc_src):
   2.107 +                            print("Someone was naughty and didn't bump the RC number in the src, or you made a mistake you want to fix.")
   2.108 +                            print("Current tagged version is " + str(major) + "." + str(minor) + "." + str(patch) + " RC" + rc_tag + ".")
   2.109 +                            print("(I)ncrement,(F)orce same version,(A)bort? [enter]")
   2.110 +                            a = input().lower()
   2.111 +                            a = lower(a)
   2.112 +                            if (a.startswith(i)):
   2.113 +                                rc = rc_tag + 1
   2.114 +                            elif (a.startswith(f)):
   2.115 +                                rc = rc_tag
   2.116 +                                force = True 
   2.117 +                            else:
   2.118 +                                print("Aborting...")
   2.119 +                                sys.exit()
   2.120 +                        else:
   2.121 +                            print("RC numbers are messed up. The last tagged version is " + str(rc_tag) + ", while the last source version is " + str(rc_src) + ".")
   2.122 +                            print("Please enter the RC version you want to use, followed by enter:")
   2.123 +                            a = input().lower()
   2.124 +                            rc = int(a) # Will raise value error if not a number. User deserves it, frankly.
   2.125 +                    
   2.126 +                    #Ok, we now have a value. Good.
   2.127 +                    
   2.128 +        # This feels extremely suboptimal, but I'm tired and don't care            
   2.129 +        if (rc < 0):
   2.130 +            if (major < 0):
   2.131 +                if (major_src == major_tag + 1) and (minor_src == 0) and (patch_src == 0):
   2.132 +                    major = major_src
   2.133 +                    minor = 0
   2.134 +                    patch = 0
   2.135 +                else:
   2.136 +                    print("Tagged release major version and source versions are too different for automatic deduction. Please do this manually.")
   2.137 +                    sys.exit()
   2.138 +            elif (minor < 0):
   2.139 +                if (minor_src == minor_tag + 1) and (patch_src == 0):
   2.140 +                    minor = minor_src
   2.141 +                    patch = 0
   2.142 +                else:
   2.143 +                    print("Tagged release major version and source versions are too different for automatic deduction. Please do this manually.")
   2.144 +                    sys.exit()
   2.145 +            elif (patch_src == patch_tag + 1):
   2.146 +                patch = patch_src
   2.147 +            else:
   2.148 +                print("Tagged release major version and source versions are too different for automatic deduction. Please do this manually.")
   2.149 +                sys.exit()    
   2.150 +            # if we got this far, it was a version upgrade.
   2.151 +
   2.152 +            if (rc_src > 0):
   2.153 +                print("We detected a version upgrade, but the source indicates the next RC is RC " + str(rc_src))
   2.154 +                print("(K)eep,(R)eset to 0,(A)bort? [enter]")
   2.155 +                a = input().lower()
   2.156 +                
   2.157 +                if a.startswith("k"):
   2.158 +                    rc = rc_src
   2.159 +                elif a.startswith("r"):
   2.160 +                    rc = 0
   2.161 +                else:
   2.162 +                    print("Aborting...")       
   2.163 +            else:
   2.164 +                rc = 0
   2.165 +
   2.166 +# Ok, so now, after all that, we should have the right version numbers.
   2.167 +
   2.168 +# If there's no changeset to tag, we take the latest local default
   2.169 +if not changeset:
   2.170 +    cmd = ["hg", "id", "-i", "-r", "default"]
   2.171 +    result = subprocess.run(cmd, capture_output=True)
   2.172 +    changeset = result.stdout.decode("utf-8").replace('"','').replace('\n','')
   2.173 +    if not changeset:
   2.174 +        raise Exception("Unable to determine latest default changeset. Aborting.")
   2.175 +
   2.176 +        
   2.177 +rev_tag = "Release_" + str(major) + "." + str(minor) + "." + str(patch) + "-RC" + str(rc)
   2.178 +
   2.179 +print("Preparing to tag changeset " + changeset + " with tag " + rev_tag + ".\n\nProceed? (Y/N) [enter]")
   2.180 +a = input().lower()
   2.181 +if not (a.startswith("y")):
   2.182 +    sys.exit()
   2.183 +
   2.184 +cmd = ["hg", "tag", "-r", changeset, rev_tag]  
   2.185 +subprocess.run(cmd, check=True, capture_output=False)
   2.186 +
   2.187 +if not grep_output:
   2.188 +    print("Information: Not writing version/RC info to src/pEpEngine.h")
   2.189 +    sys.exit()
   2.190 +
   2.191 +# If successful, then bump the RC
   2.192 +with open('src/pEpEngine.h', 'r') as file :
   2.193 +  filedata = file.read()
   2.194 +
   2.195 +grep_strs = grep_output.split("\n")
   2.196 +
   2.197 +cmd = ["grep", "-E", "#define PEP_ENGINE_VERSION[ \t]+\"[0-9]+.[0-9]+.[0-9]+\"", "src/pEpEngine.h"]
   2.198 +result = subprocess.run(cmd, capture_output=True)
   2.199 +grep_output = result.stdout.decode("utf-8")
   2.200 +
   2.201 +#define PEP_ENGINE_VERSION "2.1.0"
   2.202 +version_str = str(major) + "." + str(minor) + "." + str(patch)
   2.203 +
   2.204 +filedata = filedata.replace(grep_output, "#define PEP_ENGINE_VERSION \"" + version_str + "\"")
   2.205 +filedata = filedata.replace(grep_strs[0], "#define PEP_ENGINE_VERSION_MAJOR " + str(major))
   2.206 +filedata = filedata.replace(grep_strs[1], "#define PEP_ENGINE_VERSION_MINOR " + str(minor))
   2.207 +filedata = filedata.replace(grep_strs[2], "#define PEP_ENGINE_VERSION_PATCH " + str(patch))
   2.208 +filedata = filedata.replace(grep_strs[3], "#define PEP_ENGINE_VERSION_RC    " + str(rc + 1))
   2.209 +
   2.210 +# Write the file out again
   2.211 +with open('src/pEpEngine.h', 'w') as file:
   2.212 +    file.write(filedata)     
   2.213 +
   2.214 +comment = "Automatically bumped RC in source for future release. Next RC after this one will be " + version_str + "-RC" + str(rc + 1) + " **if released**."
   2.215 +#print("about to run with this comment:")
   2.216 +print(comment) 
   2.217 +cmd = ["hg", "commit", "-m", comment]  
   2.218 +subprocess.run(cmd, capture_output=False)
   2.219 +
   2.220 +print("New engine release: " + rev_tag + " Changeset: " + changeset)
   2.221 +                                     
     3.1 --- a/src/baseprotocol.c	Fri Jul 10 15:07:38 2020 +0200
     3.2 +++ b/src/baseprotocol.c	Mon Jul 13 11:44:38 2020 +0200
     3.3 @@ -244,34 +244,40 @@
     3.4  
     3.5      // https://dev.pep.foundation/Engine/MessageToSendPassphrase
     3.6  
     3.7 -    if (session->curr_passphrase) {
     3.8 -        // first try with empty passphrase
     3.9 -        char *passphrase = session->curr_passphrase;
    3.10 -        session->curr_passphrase = NULL;
    3.11 +    // first try with empty passphrase
    3.12 +    char *passphrase = session->curr_passphrase;
    3.13 +    session->curr_passphrase = NULL;
    3.14 +    status = base_prepare_message(session, me, partner, type, payload, size, fpr, result);
    3.15 +    session->curr_passphrase = passphrase;
    3.16 +    if (!(status == PEP_PASSPHRASE_REQUIRED || status == PEP_WRONG_PASSPHRASE))
    3.17 +        return status;
    3.18 +
    3.19 +    if (!EMPTYSTR(session->curr_passphrase)) {
    3.20 +        // try configured passphrase
    3.21          status = base_prepare_message(session, me, partner, type, payload, size, fpr, result);
    3.22 -        session->curr_passphrase = passphrase;
    3.23          if (!(status == PEP_PASSPHRASE_REQUIRED || status == PEP_WRONG_PASSPHRASE))
    3.24              return status;
    3.25      }
    3.26  
    3.27      do {
    3.28 -        // then try passphrases
    3.29 -        status = base_prepare_message(session, me, partner, type, payload, size, fpr, result);
    3.30 +        // then try passphrases from the cache
    3.31 +        status = session->messageToSend(NULL);
    3.32 +
    3.33 +        // if there will be no passphrase then exit
    3.34 +        if (status == PEP_SYNC_NO_CHANNEL)
    3.35 +            break;
    3.36 +
    3.37 +        // if a passphrase is needed ask the app
    3.38          if (status == PEP_PASSPHRASE_REQUIRED || status == PEP_WRONG_PASSPHRASE) {
    3.39 -            status = session->messageToSend(NULL);
    3.40 -            if (status == PEP_PASSPHRASE_REQUIRED || status == PEP_WRONG_PASSPHRASE) {
    3.41 -                pEp_identity *_me = identity_dup(me);
    3.42 -                if (!_me)
    3.43 -                    return PEP_OUT_OF_MEMORY;
    3.44 -                session->notifyHandshake(_me, NULL, SYNC_PASSPHRASE_REQUIRED);
    3.45 -                break;
    3.46 -            }
    3.47 +            pEp_identity* _me = identity_dup(me);
    3.48 +            if (!_me)
    3.49 +                return PEP_OUT_OF_MEMORY;
    3.50 +            session->notifyHandshake(_me, NULL, SYNC_PASSPHRASE_REQUIRED);
    3.51          }
    3.52 -        else {
    3.53 -            break;
    3.54 +        else if (status == PEP_STATUS_OK) {
    3.55 +            status = base_prepare_message(session, me, partner, type, payload, size, fpr, result);
    3.56          }
    3.57 -    } while (!status);
    3.58 +    } while (status == PEP_PASSPHRASE_REQUIRED || status == PEP_WRONG_PASSPHRASE);
    3.59  
    3.60      return status;
    3.61  }
    3.62 -
     4.1 --- a/src/message_api.c	Fri Jul 10 15:07:38 2020 +0200
     4.2 +++ b/src/message_api.c	Mon Jul 13 11:44:38 2020 +0200
     4.3 @@ -299,8 +299,18 @@
     4.4      assert(shortmsg);
     4.5      
     4.6      unsigned char pEpstr[] = PEP_SUBJ_STRING;
     4.7 -    assert(strcmp(shortmsg, "pEp") != 0 && _unsigned_signed_strcmp(pEpstr, shortmsg, PEP_SUBJ_BYTELEN) != 0); 
     4.8 +
     4.9 +    // assert(strcmp(shortmsg, "pEp") != 0 && _unsigned_signed_strcmp(pEpstr, shortmsg, PEP_SUBJ_BYTELEN) != 0); 
    4.10 +    // in case encrypt_message() is called twice with a different passphrase this was done already
    4.11      
    4.12 +    if (strcmp(shortmsg, "pEp") == 0 || _unsigned_signed_strcmp(pEpstr, shortmsg, PEP_SUBJ_BYTELEN) == 0) {
    4.13 +        char *ptext = strdup(longmsg);
    4.14 +        assert(ptext);
    4.15 +        if (!ptext)
    4.16 +            return NULL;
    4.17 +        return ptext;
    4.18 +    }
    4.19 +
    4.20      if (!shortmsg || strcmp(shortmsg, "pEp") == 0 || 
    4.21                       _unsigned_signed_strcmp(pEpstr, shortmsg, PEP_SUBJ_BYTELEN) == 0) {
    4.22          if (!longmsg) {
    4.23 @@ -1766,6 +1776,38 @@
    4.24      }
    4.25  }
    4.26  
    4.27 +PEP_STATUS probe_encrypt(PEP_SESSION session, const char *fpr)
    4.28 +{
    4.29 +    assert(session);
    4.30 +    if (!session)
    4.31 +        return PEP_ILLEGAL_VALUE;
    4.32 +
    4.33 +    if (EMPTYSTR(fpr))
    4.34 +        return PEP_KEY_NOT_FOUND;
    4.35 +
    4.36 +    stringlist_t *keylist = new_stringlist(fpr);
    4.37 +    if (!keylist)
    4.38 +        return PEP_OUT_OF_MEMORY;
    4.39 +
    4.40 +    char *ctext = NULL;
    4.41 +    size_t csize = 0;
    4.42 +    PEP_STATUS status = encrypt_and_sign(session, keylist, "pEp", 4, &ctext, &csize);
    4.43 +    free(ctext);
    4.44 +
    4.45 +    return status;
    4.46 +}
    4.47 +
    4.48 +static bool failed_test(PEP_STATUS status)
    4.49 +{
    4.50 +    if (status == PEP_OUT_OF_MEMORY ||
    4.51 +            status == PEP_PASSPHRASE_REQUIRED ||
    4.52 +            status == PEP_WRONG_PASSPHRASE  ||
    4.53 +            status == PEP_PASSPHRASE_FOR_NEW_KEYS_REQUIRED)
    4.54 +        return true;
    4.55 +
    4.56 +    return false;
    4.57 +}
    4.58 +
    4.59  DYNAMIC_API PEP_STATUS encrypt_message(
    4.60          PEP_SESSION session,
    4.61          message *src,
    4.62 @@ -1814,6 +1856,11 @@
    4.63      if (status != PEP_STATUS_OK)
    4.64          goto pEp_error;
    4.65  
    4.66 +    // is a passphrase needed?
    4.67 +    status = probe_encrypt(session, src->from->fpr);
    4.68 +    if (failed_test(status))
    4.69 +        return status;
    4.70 +
    4.71      char* send_fpr = strdup(src->from->fpr ? src->from->fpr : "");
    4.72      src->_sender_fpr = send_fpr;
    4.73      
    4.74 @@ -2223,6 +2270,11 @@
    4.75      if (status != PEP_STATUS_OK)
    4.76          goto pEp_free;
    4.77  
    4.78 +    // is a passphrase needed?
    4.79 +    status = probe_encrypt(session, own_identity->fpr);
    4.80 +    if (failed_test(status))
    4.81 +        goto pEp_free;
    4.82 +
    4.83      // Ok, now we know the address is an own address. All good. Then...
    4.84      own_private_fpr = own_identity->fpr;
    4.85      own_identity->fpr = strdup(to_fpr);
    4.86 @@ -2405,6 +2457,11 @@
    4.87      if (!target_fpr)
    4.88          return PEP_KEY_NOT_FOUND; // FIXME: Error condition
    4.89   
    4.90 +    // is a passphrase needed?
    4.91 +    status = probe_encrypt(session, target_fpr);
    4.92 +    if (failed_test(status))
    4.93 +        return status;
    4.94 +
    4.95      keys = new_stringlist(target_fpr);
    4.96      
    4.97      stringlist_t *_k = keys;
    4.98 @@ -3807,6 +3864,11 @@
    4.99          if (changed_public_keys)
   4.100              *changed_public_keys = _changed_keys;
   4.101          
   4.102 +        if (imported_key_fprs)
   4.103 +            *imported_key_fprs = _imported_key_list;
   4.104 +        if (changed_public_keys)
   4.105 +            *changed_public_keys = _changed_keys;
   4.106 +        
   4.107          return PEP_UNENCRYPTED;
   4.108      }
   4.109  
   4.110 @@ -5454,33 +5516,40 @@
   4.111  
   4.112      // https://dev.pep.foundation/Engine/MessageToSendPassphrase
   4.113  
   4.114 -    if (session->curr_passphrase) {
   4.115 -        // first try with empty passphrase
   4.116 -        char *passphrase = session->curr_passphrase;
   4.117 -        session->curr_passphrase = NULL;
   4.118 +    // first try with empty passphrase
   4.119 +    char* passphrase = session->curr_passphrase;
   4.120 +    session->curr_passphrase = NULL;
   4.121 +    status = encrypt_message(session, src, extra, dst, enc_format, flags);
   4.122 +    session->curr_passphrase = passphrase;
   4.123 +    if (!(status == PEP_PASSPHRASE_REQUIRED || status == PEP_WRONG_PASSPHRASE))
   4.124 +        return status;
   4.125 +
   4.126 +    if (!EMPTYSTR(session->curr_passphrase)) {
   4.127 +        // try configured passphrase
   4.128          status = encrypt_message(session, src, extra, dst, enc_format, flags);
   4.129 -        session->curr_passphrase = passphrase;
   4.130          if (!(status == PEP_PASSPHRASE_REQUIRED || status == PEP_WRONG_PASSPHRASE))
   4.131              return status;
   4.132      }
   4.133  
   4.134      do {
   4.135 -        // then try passphrases
   4.136 -        status = encrypt_message(session, src, extra, dst, enc_format, flags);
   4.137 +        // then try passphrases from the cache
   4.138 +        status = session->messageToSend(NULL);
   4.139 +
   4.140 +        // if there will be no passphrase then exit
   4.141 +        if (status == PEP_SYNC_NO_CHANNEL)
   4.142 +            break;
   4.143 +
   4.144 +        // if a passphrase is needed ask the app
   4.145          if (status == PEP_PASSPHRASE_REQUIRED || status == PEP_WRONG_PASSPHRASE) {
   4.146 -            status = session->messageToSend(NULL);
   4.147 -            if (status == PEP_PASSPHRASE_REQUIRED || status == PEP_WRONG_PASSPHRASE) {
   4.148 -                pEp_identity *me = identity_dup(src->from);
   4.149 -                if (!me)
   4.150 -                    return PEP_OUT_OF_MEMORY;
   4.151 -                session->notifyHandshake(me, NULL, SYNC_PASSPHRASE_REQUIRED);
   4.152 -                break;
   4.153 -            }
   4.154 +            pEp_identity* _me = identity_dup(src->from);
   4.155 +            if (!_me)
   4.156 +                return PEP_OUT_OF_MEMORY;
   4.157 +            session->notifyHandshake(_me, NULL, SYNC_PASSPHRASE_REQUIRED);
   4.158          }
   4.159 -        else {
   4.160 -            break;
   4.161 +        else if (status == PEP_STATUS_OK) {
   4.162 +            status = encrypt_message(session, src, extra, dst, enc_format, flags);
   4.163          }
   4.164 -    } while (!status);
   4.165 +    } while (status == PEP_PASSPHRASE_REQUIRED || status == PEP_WRONG_PASSPHRASE);
   4.166  
   4.167      return status;
   4.168  }
     5.1 --- a/src/pEpEngine.h	Fri Jul 10 15:07:38 2020 +0200
     5.2 +++ b/src/pEpEngine.h	Mon Jul 13 11:44:38 2020 +0200
     5.3 @@ -21,13 +21,10 @@
     5.4  
     5.5  // RELEASE version this targets
     5.6  // (string: major.minor.patch)
     5.7 -#define PEP_ENGINE_VERSION "2.1.0"
     5.8 -
     5.9 -// Numeric values of above:
    5.10 -#define PEP_ENGINE_VERSION_MAJOR 2
    5.11 +#define PEP_ENGINE_VERSION "2.1.0"#define PEP_ENGINE_VERSION_MAJOR 2
    5.12  #define PEP_ENGINE_VERSION_MINOR 1
    5.13  #define PEP_ENGINE_VERSION_PATCH 0
    5.14 -#define PEP_ENGINE_VERSION_RC    11
    5.15 +#define PEP_ENGINE_VERSION_RC    16
    5.16  
    5.17  
    5.18  #define PEP_OWN_USERID "pEp_own_userId"
     6.1 --- a/test/src/ImportKeyTest.cc	Fri Jul 10 15:07:38 2020 +0200
     6.2 +++ b/test/src/ImportKeyTest.cc	Mon Jul 13 11:44:38 2020 +0200
     6.3 @@ -326,3 +326,31 @@
     6.4      ASSERT_EQ(changes, 0xEABFF); // (938 << 10 | 1023) -> 11101010101111111111 = 0xEABFF
     6.5      free_stringlist(keylist);    
     6.6  }
     6.7 +
     6.8 +TEST_F(ImportKeyTest, check_770_import_priv_asc) {
     6.9 +    PEP_STATUS status = PEP_STATUS_OK;
    6.10 +
    6.11 +    string pubkey = slurp("test_keys/770_priv.asc");
    6.12 +    stringlist_t* keylist = NULL;
    6.13 +    status = _import_key_with_fpr_return(session, pubkey.c_str(), pubkey.size(), NULL, &keylist, NULL);
    6.14 +    ASSERT_EQ(status, PEP_KEY_IMPORTED);
    6.15 +    ASSERT_NE(keylist, nullptr);
    6.16 +    ASSERT_STREQ(keylist->value, "0521111E12084FDEA58A38E880D9FB378DCC789D");
    6.17 +    ASSERT_EQ(keylist->next, nullptr);
    6.18 +
    6.19 +    // FIXME, check key is actually imported
    6.20 +}
    6.21 +
    6.22 +TEST_F(ImportKeyTest, check_770_import_priv_pgp) {
    6.23 +    PEP_STATUS status = PEP_STATUS_OK;
    6.24 +
    6.25 +    string pubkey = slurp("test_keys/770_priv.pgp");
    6.26 +    stringlist_t* keylist = NULL;
    6.27 +    status = _import_key_with_fpr_return(session, pubkey.c_str(), pubkey.size(), NULL, &keylist, NULL);
    6.28 +    ASSERT_EQ(status, PEP_KEY_IMPORTED);
    6.29 +    ASSERT_NE(keylist, nullptr);
    6.30 +    ASSERT_STREQ(keylist->value, "0521111E12084FDEA58A38E880D9FB378DCC789D");
    6.31 +    ASSERT_EQ(keylist->next, nullptr);
    6.32 +
    6.33 +    // FIXME, check key is actually imported
    6.34 +}
     7.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.2 +++ b/test/test_keys/770_priv.asc	Mon Jul 13 11:44:38 2020 +0200
     7.3 @@ -0,0 +1,60 @@
     7.4 +-----BEGIN PGP PRIVATE KEY BLOCK-----
     7.5 +
     7.6 +lQPGBF8BfrABCACkJOcCxWjVk/ouBCz6RnSF7sZLZ8PAZTMQT9vJtboL6N2xR+7B
     7.7 +/SAzfTMcv+oU5A3Kd/k9dGA/p4wS3gXxkKaaUza1tjpWTDl92hVpxwOp7ZYczg1O
     7.8 +rB6EWhG1dcANrh/hy6wt/AWK39L0GANHsRweqC54EXJ+xCTLUT5CODFaelrGKE4b
     7.9 +TFRlk7NSTuRoqHRsS5Ax34L+RDC8orl/SAoqRFVe3UP+HLw5ODwIebgKKzzSTFHc
    7.10 +e7q5d/mJKsA2SPOoHi23numleBFknBKtfp6As0/07GRFFCb/W3xS8mSy6lBbgcly
    7.11 +k8ovPvm82PBBLiEDjdIB6FRLayBLnAr89i45ABEBAAH+BwMCcE+AMYzTIEDrgL5s
    7.12 +HZGhl2O4EDEs1Aq2FfYL4TYXS/PpHVOUnIYZYTIHKiR/O9prH8fn6M0TH1yAVgyD
    7.13 +BjQC9c0dnq4QkaHldhqZARWajC3O/bPJ2KU80KRdoFGS3qoc9JXY4hgPQVPAoWkY
    7.14 +zFJgJvU47W19tYU9M4WNjbxB8w14VjRVhSA3HiOiMM5uNCn0yrhs9bWInPKQB4IQ
    7.15 +x8Lvx/HDUYHS2QWh1LXiDy+Pbe8Vvji10LcqTTQaHvUKVM1Et/oDCUm9gLSdc+nE
    7.16 +uGYj7QmD+RhCny/vwhfZhM5DCEQm/wd1q8QGrRvTv0LEOoOVc2kwc7ro7YXBvIq2
    7.17 +cDK6bxMKdWq9maMk1FGD5iT3J2KuEYmvnl0zRQqTq/rk2gGmMULhbHs/UgE80c9U
    7.18 +4gnzI75rrlewpf0MBVXj6QnAy0sBxJQ65b3F3dYvBb0DmnoQIZCV2Zf3UY0E1HtB
    7.19 +4I+H/8rjNtD2fW/O2EoCbXMkbw0xxhMRsm//2Kfu4G0oOIsvAcgFDhQSvPjauht7
    7.20 +H6e3DQHuVTyathbmlqEeS8GkjKWgx2/RtdfH1D9yILDrx+YGuCyWlW+9ruZVNe54
    7.21 +WVtx5IZ0s5n6N9eLUzjfd4tdQorwznlAy93/f/LQ3VPyBPzIkE9fmhnMWVSIjRkd
    7.22 +cyhoD7GxDLQFaNGCrjhLkiur8w9WTDa1VgrIfIeGwhI/e0Q1+xalDV7bYFDa5Qda
    7.23 +3i6mTQLM1bn6t/Hkhs1Rn8xV3Ox/etVw78hdTulUDyMLunDIgBI0iHYEwcIwMXsD
    7.24 +VPec10R8MJUMETS/gC24wpTjHd/CITvutX4UNhfDH88iYHsssioDLpiQAcaw98Yg
    7.25 +pr+9ToKQ/GS5Ff1oT8/NakjlBDouEahtOEEwgbN1EFm4PxqSApcjory6NydNcNSg
    7.26 +mJq0KqBpkUxUtCtUaHVuZGVyIEJpcmQgVGVzdGluZ2VyIDx0YnRlc3RAZGluZ2Vu
    7.27 +cy5vcmc+iQFUBBMBCAA+FiEEBSERHhIIT96lijjogNn7N43MeJ0FAl8BfrACGwMF
    7.28 +CQPCZwAFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AACgkQgNn7N43MeJ1kmgf9FB3O
    7.29 +ELJhGgrzR7b/io1QWoWQclnKBmn3gK2YJvHFJWVfMg4R+QBQgwPu32E84s/A0al2
    7.30 +5FEwajM++uaaGjZ6x6rSGnOrmDPi3IFpuwefgTwKXqwHJoZjdDivfI5Fy46qL4hU
    7.31 +jhwiDtbKgZ+qw5gb4teUbkdlB5INj1kgSJC/Hxr6WuygsGl/QhdiXNpSxZxnmkwB
    7.32 +Wi7Aymd1x7ur++UEOVxEEp/N2rFHGsbEgh7hwL4cxEfhZLcxJv8p8i3EwfEvChjE
    7.33 +5yL3/j3gmlD/Q00/XE++kuHKJWASDf7wOA/WZovoeM+cBKUmvOKgME6eHpS/fLHS
    7.34 +ABrxdDzsLpUPFaTozJ0DxgRfAX6wAQgAtX0xtABFtHNSnt1mKZiKngnb6lMVDtDQ
    7.35 +kZA3MYG1SCjkezry6dJYVGip8Px4XvLT4jj7qmjN0eQYEqK4P8ufw3zGFk4R4E43
    7.36 +qa9aroW2X9A43Wv+D4nM9SDzURdJW4mX0WnC+hu7V4BF8esxagnHMlfVVt1jFwW5
    7.37 +6HgSDS+aAznFNRfhhO1zB8R8bJEDgmdJFnegSFMJlD0VqdWRCz5rBqKHddbMOppm
    7.38 +XnXwOTiGZuxg7KYByjMsp9XmFIs8+BFXUg141m0laUw2ezpdBRlLQaio6UvTRV8v
    7.39 +CSmYNbm8bk/qKM9SXrr4HYgrPdZ8V3tKfGGbLjlo/Ih1sag5T2qlJwARAQAB/gcD
    7.40 +ArhphXys3eD760Yf4PslFNwJSlWiuO4mao5Vg1x+/a8nqb2Qr+J+/6m43yYMZnSm
    7.41 +MIUqCbm+LBdAmbF+z8cAe1KWl3srx5UljFmlit9w7pdFXS8P8gPj+VsXpZT2kafq
    7.42 +DC5LzPvQALY6umHUAPUP3lMlB0P02GW1bS3nzAw6yPydYQ+OVHowZd/Tkf9l17YD
    7.43 +RArp7GM2itARq74jThj3QmujisTBgx7r/IxLB018rqjnpYw8G5eOezGX75a9WmUD
    7.44 +z8M9H6rKxZONQQf/I4Udn6pZfaPVeLNqFrIRsNxwcxEfrA4IthV0wggPbCGH2lzr
    7.45 +Qfy4yz5LJmdM6wpZvcV7xiSo67WI1qteUNxgY0LtY2fXN40C2scyb/XloUGzQap9
    7.46 +B35wuAzwPOenQlPOlEQZf/kb54714BsO198dzNGuwEzDsQbtNC4iiFAU3R6PVd8G
    7.47 +COQjKhGiGwwjtjaNCHLoPwABkj1jjGCin1wfIp9zDFEzh9hImQPcIAEgv25U1Ppt
    7.48 +cuhVsE15qpnVk3l1IKgy7/f8XHFA+aKPG9ltXMyGZ8FbyqloW4kUYIaChadKo1JZ
    7.49 ++PXhrme4DhDxMOJVIwUiIIzccUcphtGGYv0Ci5CA65ewkA+6HpgwcntvTJ41SMR1
    7.50 +PdXmI5AH33nmvHUPRyRjGAOWGAWGuQCfmSXvaOY1RG6OIZLFkwcHLeSDd7eqGyZU
    7.51 +mYR27OdaG9WfoK4rWsq+rLKnmrnSR5YoIVLO2wr5hZATjIQGazF3JQzHB8YI0Vk9
    7.52 +i/nbIseVO1+TS1SdB5dn4GA9Xlo2brxNkncXtWBR6raW1EFsEf3r8HLXvhNBT8Sh
    7.53 +nNBWXPiwUYMK+ZH0FufDk33o6jXI8Z3KxDp+rVoSDR5kK6rdQk3Q6u9v6aCN3J+X
    7.54 +QNgFrHmaHZRzC8AZQXS39ZAjUrZMPYkBPAQYAQgAJhYhBAUhER4SCE/epYo46IDZ
    7.55 ++zeNzHidBQJfAX6wAhsMBQkDwmcAAAoJEIDZ+zeNzHidlO4H/1Krf9bHbccbNyCq
    7.56 +13o6HE0TmgP7cibaOF+lP7qUIDlttdj+tIuduqaNkZAW07WSiL86wMiSgvxspC8h
    7.57 +Nmdp1QywC9cdM/1rzbZNI7klLi7lhQAgK+YOs9kY3Un85M0xrup453X1FDfWHlCg
    7.58 +JZz/wqqV8TCkX6gJ1/qm4+7prRJvYlI/4zo87s7WzCyOzHB6JR5Tg2+mY6PwrbJI
    7.59 +d+deP0TEcRZZj52PJYV7/E7Nf83Evk66Kb021WSq5uvJGdoRysGlQY0cg9owIZEU
    7.60 +ApVsG4gY1V3lPqTLOQfoJIEHLAHqtia3Al+tVx0iCRgxvX632j3PLvKvu5uEB3xH
    7.61 +OfvivGE=
    7.62 +=uvnV
    7.63 +-----END PGP PRIVATE KEY BLOCK-----
     8.1 Binary file test/test_keys/770_priv.pgp has changed