Adjust E2E tests to work with all scenarios

Since it's not so easy to encrypt a message exactly the same way twice, we
only verify if the message has been encrypted or not.

Introduce minor changes to the library itself, because it doesn't work very
well with modern GnuPG.

Also, include GnuPG directory (pointed at by --homedir option).
This commit is contained in:
Piotr F. Mieszkowski 2022-01-06 16:23:10 +01:00
parent f41adc0d53
commit f1a799d864
10 changed files with 62 additions and 24 deletions

View File

@ -23,6 +23,13 @@ import subprocess
import shutil
import random
import string
import sys
LINE_FINGERPRINT = 'fpr'
LINE_USER_ID = 'uid'
POS_FINGERPRINT = 9
def private_keys( keyhome ):
cmd = ['/usr/bin/gpg', '--homedir', keyhome, '--list-secret-keys', '--with-colons']
@ -42,14 +49,21 @@ def public_keys( keyhome ):
cmd = ['/usr/bin/gpg', '--homedir', keyhome, '--list-keys', '--with-colons']
p = subprocess.Popen( cmd, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
p.wait()
keys = dict()
fingerprint = None
email = None
for line in p.stdout.readlines():
if line[0:3] == 'uid' or line[0:3] == 'pub':
if line[0:3] == LINE_FINGERPRINT:
fingerprint = line.split(':')[POS_FINGERPRINT]
if line[0:3] == LINE_USER_ID:
if ('<' not in line or '>' not in line):
continue
email = line.split('<')[1].split('>')[0]
fingerprint = line.split(':')[4]
if not (fingerprint is None or email is None):
keys[fingerprint] = email
fingerprint = None
email = None
return keys
# confirms a key has a given email address

View File

@ -7,6 +7,7 @@ test: test/tmp test/logs pre-clean
pre-clean:
rm -fv test/gpg-mailgate.conf
rm -f test/logs/*.log
test/tmp:
mkdir test/tmp

View File

@ -8,16 +8,16 @@ cases = 3
descr = Clear text message to a user without a key
to = carlos@disposlab
in = test/msgin/clear2clear.msg
out = test/msgout/clear2clear.msg
out = Body of the message.
[case-2]
descr = Clear text message to a user with an RSA key
to = alice@disposlab
in = test/msgin/clear2rsa.msg
out = test/msgout/clear2rsa.msg
out = -----BEGIN PGP MESSAGE-----
[case-3]
descr = Clear text message to a user with an Ed25519 key
to = bob@disposlab
in = test/msgin/clear2ed.msg
out = test/msgout/clear2ed.msg
out = -----BEGIN PGP MESSAGE-----

View File

@ -36,6 +36,10 @@ def build_config(config):
cp.set("relay", "host", "localhost")
cp.set("relay", "port", config["port"])
cp.add_section("enc_keymap")
cp.set("enc_keymap", "alice@disposlab", "1CD245308F0963D038E88357973CF4D9387C44D7")
cp.set("enc_keymap", "bob@disposlab", "19CF4B47ECC9C47AFA84D4BD96F39FDA0E31BB67")
logging.debug("Created config with keyhome=%s, cert_path=%s and relay at port %d" %
(config["gpg_keyhome"], config["smime_certpath"], config["port"]))
return cp
@ -68,18 +72,27 @@ def compare(result, expected):
fromfile='expected',
tofile='output')
def report_result(message_file, expected_file, test_output):
expected = load_file(expected_file)
diff = compare(test_output, expected)
if len(list(diff)) > 0:
print "Output and the expected message (%s) don't match:" % (expected_file)
def report_result(message_file, expected, test_output):
status = None
if expected in test_output:
status = "Success"
else:
print "Message %s processed properly" % (message_file)
for diff_line in diff:
print diff_line
status = "Failure"
def execute_e2e_test(message_file, expected_file, **kwargs):
test_command = "GPG_MAILGATE_CONFIG=%s %s gpg-mailgate.py %s < %s" % (kwargs["config_path"], PYTHON_BIN, kwargs["to_addr"], message_file)
print "%s %s" % (message_file.ljust(30, '.'), status)
def frozen_time_expr(timestamp):
if timestamp is None:
return ""
else:
return "GPG_FROZEN_TIME=%s" % (timestamp)
def execute_e2e_test(message_file, expected, **kwargs):
test_command = "GPG_MAILGATE_CONFIG=%s %s gpg-mailgate.py %s < %s" % (
kwargs["config_path"],
PYTHON_BIN,
kwargs["to_addr"],
message_file)
result_command = "%s %s %d" % (PYTHON_BIN, RELAY_SCRIPT, kwargs["port"])
logging.debug("Spawning: '%s'" % (result_command))
@ -95,16 +108,16 @@ def execute_e2e_test(message_file, expected_file, **kwargs):
logging.debug("Read %d characters of test output: '%s'" % (len(testout), testout))
report_result(message_file, expected_file, testout)
report_result(message_file, expected, testout)
def load_config():
def load_test_config():
cp = ConfigParser.ConfigParser()
cp.read("test/e2e.ini")
return cp
config = load_config()
config = load_test_config()
logging.basicConfig(filename = "test/logs/e2e.log",
format = "%(asctime)s %(pathname)s:%(lineno)d %(levelname)s [%(funcName)s] %(message)s",
@ -123,9 +136,10 @@ for case_no in range(1, config.getint("tests", "cases")+1):
case_name = "case-%d" % (case_no)
print "Executing: %s" % (config.get(case_name, "descr"))
execute_e2e_test(config.get(case_name, "in"), config.get(case_name, "out"),
config_path = config_path,
to_addr = config.get(case_name, "to"),
port = config.getint("relay", "port"))
execute_e2e_test(config.get(case_name, "in"),
config.get(case_name, "out"),
config_path = config_path,
to_addr = config.get(case_name, "to"),
port = config.getint("relay", "port"))
sleep(DELAY)
# sleep(DELAY)

View File

@ -0,0 +1 @@
v:1:

BIN
test/keyhome/pubring.kbx Normal file

Binary file not shown.

BIN
test/keyhome/random_seed Normal file

Binary file not shown.

BIN
test/keyhome/tofu.db Normal file

Binary file not shown.

BIN
test/keyhome/trustdb.gpg Normal file

Binary file not shown.

View File

@ -25,6 +25,9 @@ def welcome(msg):
def ok(msg = "OK"):
return "250 %s\r\n" % (msg)
def bye():
return "251 Bye"
def provide_message():
return "354 Enter a message, ending it with a '.' on a line by itself\r\n"
@ -57,6 +60,11 @@ def serve(port):
message += conn.recv(BUFFER_SIZE)
conn.sendall(ok("OK, id=test"))
conn.recv(BUFFER_SIZE)
conn.sendall(bye())
conn.close()
# Trim EOM marker as we're only interested in the message body.
return message[:-len(EOM)]