Add E2E case: a user with a key and PGP/MIME configured
- Add a new test input message for a new test identity, test scenario configuration and a test key. - While retrieving message payload, determine charset based on the Content-Type header. When missing, default to UTF-8. - Use more comprehensible variables names. - Adjust logging levels.
This commit is contained in:
parent
707fc96234
commit
3bcc1151e5
6 changed files with 47 additions and 32 deletions
|
@ -35,20 +35,6 @@ def build_command(key_home, *args, **kwargs):
|
|||
cmd = ["gpg", '--homedir', key_home] + list(args)
|
||||
return cmd
|
||||
|
||||
def private_keys( keyhome ):
|
||||
cmd = build_command(keyhome, '--list-secret-keys', '--with-colons')
|
||||
p = subprocess.Popen( cmd, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
|
||||
p.wait()
|
||||
keys = dict()
|
||||
for line in p.stdout.readlines():
|
||||
if line[0:3] == 'uid' or line[0:3] == 'sec':
|
||||
if ('<' not in line or '>' not in line):
|
||||
continue
|
||||
email = line.split('<')[1].split('>')[0]
|
||||
fingerprint = line.split(':')[4]
|
||||
keys[fingerprint] = email
|
||||
return keys
|
||||
|
||||
def public_keys( keyhome ):
|
||||
cmd = build_command(keyhome, '--list-keys', '--with-colons')
|
||||
p = subprocess.Popen( cmd, stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
|
||||
|
@ -58,7 +44,7 @@ def public_keys( keyhome ):
|
|||
fingerprint = None
|
||||
email = None
|
||||
for line in p.stdout.readlines():
|
||||
line = line.decode('utf-8')
|
||||
line = line.decode(sys.getdefaultencoding())
|
||||
if line[0:3] == LINE_FINGERPRINT:
|
||||
fingerprint = line.split(':')[POS_FINGERPRINT]
|
||||
if line[0:3] == LINE_USER_ID:
|
||||
|
|
|
@ -113,7 +113,7 @@ def gpg_encrypt( raw_message, recipients ):
|
|||
else:
|
||||
# Log message only if an unknown style is defined
|
||||
if conf.config_item_set('pgp_style', rcpt[0]):
|
||||
LOG.info("Style %s for recipient %s is not known. Use default as fallback." % (conf.get_item("pgp_style", rcpt[0]), rcpt[0]))
|
||||
LOG.debug("Style %s for recipient %s is not known. Use default as fallback." % (conf.get_item("pgp_style", rcpt[0]), rcpt[0]))
|
||||
|
||||
# If no style is in settings defined for recipient, use default from settings
|
||||
if conf.config_item_equals('default', 'mime_conversion', 'yes'):
|
||||
|
@ -177,17 +177,17 @@ def encrypt_all_payloads_inline( message, gpg_to_cmdline ):
|
|||
def encrypt_all_payloads_mime( message, gpg_to_cmdline ):
|
||||
|
||||
# Convert a plain text email into PGP/MIME attachment style. Modeled after enigmail.
|
||||
submsg1 = email.message.Message()
|
||||
submsg1.set_payload("Version: 1\n")
|
||||
submsg1.set_type("application/pgp-encrypted")
|
||||
submsg1.set_param('PGP/MIME version identification', "", 'Content-Description' )
|
||||
pgp_ver_part = email.message.Message()
|
||||
pgp_ver_part.set_payload("Version: 1\n")
|
||||
pgp_ver_part.set_type("application/pgp-encrypted")
|
||||
pgp_ver_part.set_param('PGP/MIME version identification', "", 'Content-Description' )
|
||||
|
||||
submsg2 = email.message.Message()
|
||||
submsg2.set_type("application/octet-stream")
|
||||
submsg2.set_param('name', "encrypted.asc")
|
||||
submsg2.set_param('OpenPGP encrypted message', "", 'Content-Description' )
|
||||
submsg2.set_param('inline', "", 'Content-Disposition' )
|
||||
submsg2.set_param('filename', "encrypted.asc", 'Content-Disposition' )
|
||||
encrypted_part = email.message.Message()
|
||||
encrypted_part.set_type("application/octet-stream")
|
||||
encrypted_part.set_param('name', "encrypted.asc")
|
||||
encrypted_part.set_param('OpenPGP encrypted message', "", 'Content-Description' )
|
||||
encrypted_part.set_param('inline', "", 'Content-Disposition' )
|
||||
encrypted_part.set_param('filename', "encrypted.asc", 'Content-Disposition' )
|
||||
|
||||
if isinstance(message.get_payload(), str):
|
||||
# WTF! It seems to swallow the first line. Not sure why. Perhaps
|
||||
|
@ -195,13 +195,16 @@ def encrypt_all_payloads_mime( message, gpg_to_cmdline ):
|
|||
# Workaround it here by prepending a blank line.
|
||||
# This happens only on text only messages.
|
||||
additionalSubHeader=""
|
||||
encoding = sys.getdefaultencoding()
|
||||
if 'Content-Type' in message and not message['Content-Type'].startswith('multipart'):
|
||||
additionalSubHeader="Content-Type: "+message['Content-Type']+"\n"
|
||||
submsg2.set_payload(additionalSubHeader+"\n" +message.get_payload(decode=True))
|
||||
(base, encoding) = parse_content_type(message['Content-Type'])
|
||||
LOG.debug(f"Identified encoding as {encoding}")
|
||||
encrypted_part.set_payload(additionalSubHeader+"\n" +message.get_payload(decode=True).decode(encoding))
|
||||
check_nested = True
|
||||
else:
|
||||
processed_payloads = generate_message_from_payloads(message)
|
||||
submsg2.set_payload(processed_payloads.as_string())
|
||||
encrypted_part.set_payload(processed_payloads.as_string())
|
||||
check_nested = False
|
||||
|
||||
message.preamble = "This is an OpenPGP/MIME encrypted message (RFC 2440 and 3156)"
|
||||
|
@ -217,7 +220,15 @@ def encrypt_all_payloads_mime( message, gpg_to_cmdline ):
|
|||
else:
|
||||
message['Content-Type'] = "multipart/encrypted; protocol=\"application/pgp-encrypted\";\nboundary=\"%s\"\n" % boundary
|
||||
|
||||
return [ submsg1, encrypt_payload(submsg2, gpg_to_cmdline, check_nested) ]
|
||||
return [ pgp_ver_part, encrypt_payload(encrypted_part, gpg_to_cmdline, check_nested) ]
|
||||
|
||||
def parse_content_type(content_type):
|
||||
split_at = content_type.index(';')
|
||||
second_part = content_type[split_at+1 : ].strip()
|
||||
if second_part.startswith('charset'):
|
||||
return (content_type[0 : split_at], second_part[second_part.index('=') + 1 : ].strip())
|
||||
else:
|
||||
return (content_type[0 : split_at], sys.getdefaultencoding())
|
||||
|
||||
def encrypt_payload( payload, gpg_to_cmdline, check_nested = True ):
|
||||
global LOG
|
||||
|
@ -297,11 +308,11 @@ def smime_encrypt( raw_message, recipients ):
|
|||
|
||||
s.write(out, p7)
|
||||
|
||||
LOG.debug("Sending message from " + from_addr + " to " + str(smime_to))
|
||||
LOG.debug(f"Sending message from {from_addr} to {smime_to}")
|
||||
|
||||
send_msg(out.read(), smime_to)
|
||||
if unsmime_to:
|
||||
LOG.debug("Unable to find valid S/MIME certificates for " + str(unsmime_to))
|
||||
LOG.debug(f"Unable to find valid S/MIME certificates for {unsmime_to}")
|
||||
|
||||
return unsmime_to
|
||||
|
||||
|
|
|
@ -30,7 +30,7 @@ certs: test/certs
|
|||
|
||||
[tests]
|
||||
# Number of "test-*" sections in this file, describing test cases.
|
||||
cases: 6
|
||||
cases: 7
|
||||
e2e_log: test/logs/e2e.log
|
||||
e2e_log_format: %(asctime)s %(pathname)s:%(lineno)d %(levelname)s [%(funcName)s] %(message)s
|
||||
e2e_log_datefmt: %Y-%m-%d %H:%M:%S
|
||||
|
@ -72,3 +72,9 @@ descr: Multipart encrypted message to a user with an Ed25519 key.
|
|||
to: bob@disposlab
|
||||
in: test/msgin/multipart2rsa.msg
|
||||
out: -----BEGIN PGP MESSAGE-----
|
||||
|
||||
[case-7]
|
||||
descr: Clear text message to a user with an RSA key and PGP/MIME enabled in configuration
|
||||
to: evan@disposlab
|
||||
in: test/msgin/clear2rsa2.msg
|
||||
out: -----BEGIN PGP MESSAGE-----
|
||||
|
|
|
@ -51,6 +51,12 @@ def build_config(config):
|
|||
cp.add_section("enc_keymap")
|
||||
cp.set("enc_keymap", "alice@disposlab", "1CD245308F0963D038E88357973CF4D9387C44D7")
|
||||
cp.set("enc_keymap", "bob@disposlab", "19CF4B47ECC9C47AFA84D4BD96F39FDA0E31BB67")
|
||||
cp.set("enc_keymap", "evan@disposlab", "530B1BB2D0CC7971648198BBA4774E507D3AF5BC")
|
||||
|
||||
cp.add_section("pgp_style")
|
||||
# Default style is PGP/Inline, so to cover more branches, one test identity
|
||||
# uses PGP/MIME.
|
||||
cp.set("pgp_style", "evan@disposlab", "mime")
|
||||
|
||||
logging.debug(f"Created config with keyhome={config['gpg_keyhome']}, cert_path={config['smime_certpath']} and relay at port {config['port']}")
|
||||
return cp
|
||||
|
|
Binary file not shown.
6
test/msgin/clear2rsa2.msg
Normal file
6
test/msgin/clear2rsa2.msg
Normal file
|
@ -0,0 +1,6 @@
|
|||
From: Dave <dave@disposlab
|
||||
To: Evan <evan@disposlab>
|
||||
Subject: Test
|
||||
Content-Type: text/plain; charset="utf-8"
|
||||
|
||||
Body of the message.
|
Loading…
Reference in a new issue