Merge pull request 'Handle addresses with delimiters' (#89) from 87-handle-delimiters into master
Reviewed-on: #89
This commit is contained in:
commit
8a366f2f17
|
@ -59,9 +59,15 @@ def gpg_encrypt( raw_message, recipients ):
|
||||||
for fingerprint in keys:
|
for fingerprint in keys:
|
||||||
keys[fingerprint] = sanitize_case_sense(keys[fingerprint])
|
keys[fingerprint] = sanitize_case_sense(keys[fingerprint])
|
||||||
|
|
||||||
|
# This list will be filled with pairs (M, N), where M is the destination
|
||||||
|
# address we're going to deliver the message to and N is the identity we're
|
||||||
|
# going to encrypt it for.
|
||||||
gpg_to = list()
|
gpg_to = list()
|
||||||
|
|
||||||
ungpg_to = list()
|
ungpg_to = list()
|
||||||
|
|
||||||
|
enc_keymap_only = conf.config_item_equals('default', 'enc_keymap_only', 'yes')
|
||||||
|
|
||||||
for to in recipients:
|
for to in recipients:
|
||||||
|
|
||||||
# Check if recipient is in keymap
|
# Check if recipient is in keymap
|
||||||
|
@ -75,16 +81,23 @@ def gpg_encrypt( raw_message, recipients ):
|
||||||
LOG.info("Key '%s' in encrypt keymap not found in keyring for email address '%s'." % (conf.get_item('enc_keymap', to), to))
|
LOG.info("Key '%s' in encrypt keymap not found in keyring for email address '%s'." % (conf.get_item('enc_keymap', to), to))
|
||||||
|
|
||||||
# Check if key in keychain is present
|
# Check if key in keychain is present
|
||||||
if to in keys.values() and not conf.config_item_equals('default', 'enc_keymap_only', 'yes'):
|
if not enc_keymap_only:
|
||||||
gpg_to.append( (to, to) )
|
if to in keys.values():
|
||||||
continue
|
gpg_to.append( (to, to) )
|
||||||
|
continue
|
||||||
|
|
||||||
|
# If this is an address with a delimiter (i.e. "foo+bar@example.com"),
|
||||||
|
# then strip whatever is found after the delimiter and try this address.
|
||||||
|
(newto, topic) = text.parse_delimiter(to)
|
||||||
|
if newto in keys.values():
|
||||||
|
gpg_to.append((to, newto))
|
||||||
|
|
||||||
# Check if there is a default key for the domain
|
# Check if there is a default key for the domain
|
||||||
splitted_to = to.split('@')
|
splitted_to = to.split('@')
|
||||||
if len(splitted_to) > 1:
|
if len(splitted_to) > 1:
|
||||||
domain = splitted_to[1]
|
domain = splitted_to[1]
|
||||||
if conf.config_item_set('enc_domain_keymap', domain):
|
if conf.config_item_set('enc_domain_keymap', domain):
|
||||||
LOG.info("Encrypt domain keymap has key '%s'" % conf.get_item('enc_dec_keymap', domain) )
|
LOG.info("Encrypt domain keymap has key '%s'" % conf.get_item('enc_domain_keymap', domain) )
|
||||||
# Check we've got a matching key!
|
# Check we've got a matching key!
|
||||||
if conf.get_item('enc_domain_keymap', domain) in keys:
|
if conf.get_item('enc_domain_keymap', domain) in keys:
|
||||||
LOG.info("Using default domain key for recipient '%s'" % to)
|
LOG.info("Using default domain key for recipient '%s'" % to)
|
||||||
|
@ -315,26 +328,29 @@ def smime_encrypt( raw_message, recipients ):
|
||||||
def get_cert_for_email( to_addr, cert_path ):
|
def get_cert_for_email( to_addr, cert_path ):
|
||||||
global LOG
|
global LOG
|
||||||
|
|
||||||
|
insensitive = conf.config_item_equals('default', 'mail_case_insensitive', 'yes')
|
||||||
|
|
||||||
files_in_directory = os.listdir(cert_path)
|
files_in_directory = os.listdir(cert_path)
|
||||||
for filename in files_in_directory:
|
for filename in files_in_directory:
|
||||||
file_path = os.path.join(cert_path, filename)
|
file_path = os.path.join(cert_path, filename)
|
||||||
if not os.path.isfile(file_path):
|
if not os.path.isfile(file_path):
|
||||||
continue
|
continue
|
||||||
|
|
||||||
if conf.config_item_equals('default', 'mail_case_insensitive', 'yes'):
|
if insensitive:
|
||||||
if filename.lower() == to_addr:
|
if filename.casefold() == to_addr:
|
||||||
return (file_path, to_addr)
|
return (file_path, to_addr)
|
||||||
else:
|
else:
|
||||||
if filename == to_addr:
|
if filename == to_addr:
|
||||||
return (file_path, to_addr)
|
return (file_path, to_addr)
|
||||||
# support foo+ignore@bar.com -> foo@bar.com
|
|
||||||
multi_email = re.match('^([^\+]+)\+([^@]+)@(.*)$', to_addr)
|
|
||||||
if multi_email:
|
|
||||||
fixed_up_email = "%s@%s" % (multi_email.group(1), multi_email.group(3))
|
|
||||||
LOG.debug("Multi-email %s converted to %s" % (to_addr, fixed_up_email))
|
|
||||||
return get_cert_for_email(fixed_up_email)
|
|
||||||
|
|
||||||
return None
|
# support foo+ignore@bar.com -> foo@bar.com
|
||||||
|
(fixed_up_email, topic) = text.parse_delimiter(to_addr)
|
||||||
|
if topic is None:
|
||||||
|
# delimiter not used
|
||||||
|
return None
|
||||||
|
else:
|
||||||
|
LOG.debug(f"Looking up certificate for {fixed_up_email} after parsing {to_addr}")
|
||||||
|
return get_cert_for_email(fixed_up_email, cert_path)
|
||||||
|
|
||||||
def sanitize_case_sense( address ):
|
def sanitize_case_sense( address ):
|
||||||
if conf.config_item_equals('default', 'mail_case_insensitive', 'yes'):
|
if conf.config_item_equals('default', 'mail_case_insensitive', 'yes'):
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
import sys
|
import sys
|
||||||
|
import re
|
||||||
|
|
||||||
# The standard way to encode line-ending in email:
|
# The standard way to encode line-ending in email:
|
||||||
EOL = "\r\n"
|
EOL = "\r\n"
|
||||||
|
@ -22,6 +23,13 @@ def parse_content_type(content_type):
|
||||||
else:
|
else:
|
||||||
return (ctype, sys.getdefaultencoding())
|
return (ctype, sys.getdefaultencoding())
|
||||||
|
|
||||||
|
def parse_delimiter(address):
|
||||||
|
withdelim = re.match('^([^\+]+)\+([^@]+)@(.*)$', address)
|
||||||
|
if withdelim:
|
||||||
|
return (withdelim.group(1) + '@' + withdelim.group(3), withdelim.group(2))
|
||||||
|
else:
|
||||||
|
return (address, None)
|
||||||
|
|
||||||
def is_pgp_inline(payload):
|
def is_pgp_inline(payload):
|
||||||
"""Finds out if the payload (bytes) contains PGP/INLINE markers."""
|
"""Finds out if the payload (bytes) contains PGP/INLINE markers."""
|
||||||
return PGP_INLINE_BEGIN in payload and PGP_INLINE_END in payload
|
return PGP_INLINE_BEGIN in payload and PGP_INLINE_END in payload
|
||||||
|
|
|
@ -30,7 +30,7 @@ certs: test/certs
|
||||||
|
|
||||||
[tests]
|
[tests]
|
||||||
# Number of "test-*" sections in this file, describing test cases.
|
# Number of "test-*" sections in this file, describing test cases.
|
||||||
cases: 7
|
cases: 8
|
||||||
e2e_log: test/logs/e2e.log
|
e2e_log: test/logs/e2e.log
|
||||||
e2e_log_format: %(asctime)s %(pathname)s:%(lineno)d %(levelname)s [%(funcName)s] %(message)s
|
e2e_log_format: %(asctime)s %(pathname)s:%(lineno)d %(levelname)s [%(funcName)s] %(message)s
|
||||||
e2e_log_datefmt: %Y-%m-%d %H:%M:%S
|
e2e_log_datefmt: %Y-%m-%d %H:%M:%S
|
||||||
|
@ -78,3 +78,9 @@ descr: Clear text message to a user with an RSA key and PGP/MIME enabled in conf
|
||||||
to: evan@disposlab
|
to: evan@disposlab
|
||||||
in: test/msgin/clear2rsa2.msg
|
in: test/msgin/clear2rsa2.msg
|
||||||
out: -----BEGIN PGP MESSAGE-----
|
out: -----BEGIN PGP MESSAGE-----
|
||||||
|
|
||||||
|
[case-8]
|
||||||
|
descr: Clear text message to address with delimiter and a user with an Ed25519 key.
|
||||||
|
to: bob@disposlab
|
||||||
|
in: test/msgin/clear2ed-delim.msg
|
||||||
|
out: -----BEGIN PGP MESSAGE-----
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
From: Dave <dave@localhost>
|
||||||
|
To: Bob <bob+foobar@localhost>
|
||||||
|
Subject: Test
|
||||||
|
|
||||||
|
Body of the message.
|
|
@ -23,3 +23,15 @@ class LacreTextTest(unittest.TestCase):
|
||||||
(mtype, mcharset) = lacre.text.parse_content_type('text/plain; charset="UTF-8"; some-param="Some Value"')
|
(mtype, mcharset) = lacre.text.parse_content_type('text/plain; charset="UTF-8"; some-param="Some Value"')
|
||||||
self.assertEqual(mtype, 'text/plain')
|
self.assertEqual(mtype, 'text/plain')
|
||||||
self.assertEqual(mcharset, '"UTF-8"')
|
self.assertEqual(mcharset, '"UTF-8"')
|
||||||
|
|
||||||
|
def test_parse_email_without_delimiter(self):
|
||||||
|
addr = "Some.Name@example.com"
|
||||||
|
(addr2, topic) = lacre.text.parse_delimiter(addr)
|
||||||
|
self.assertEqual(addr2, "Some.Name@example.com")
|
||||||
|
self.assertEqual(topic, None)
|
||||||
|
|
||||||
|
def test_parse_email_with_delimiter(self):
|
||||||
|
addr = "Some.Name+some-topic@example.com"
|
||||||
|
(addr2, topic) = lacre.text.parse_delimiter(addr)
|
||||||
|
self.assertEqual(addr2, "Some.Name@example.com")
|
||||||
|
self.assertEqual(topic, "some-topic")
|
||||||
|
|
Loading…
Reference in New Issue