From d6aaa9f243b0c9f4a5fea2469f719752aa698018 Mon Sep 17 00:00:00 2001 From: Igor Rzegocki Date: Fri, 6 Sep 2013 21:57:49 +0200 Subject: [PATCH 1/9] Fixed #1 GnuPG2.x listed keys are now properly interpreted. --- GnuPG/__init__.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/GnuPG/__init__.py b/GnuPG/__init__.py index cde18a2..abe50e7 100644 --- a/GnuPG/__init__.py +++ b/GnuPG/__init__.py @@ -8,6 +8,8 @@ def public_keys( keyhome ): keys = list() for line in p.stdout.readlines(): if line[0:3] == 'uid' or line[0:3] == 'pub': + if ('<' not in line or '>' not in line): + continue key = line.split('<')[1].split('>')[0] if keys.count(key) == 0: keys.append(key) From f78652ac15860b283a0879436f5ad6d57b187fa2 Mon Sep 17 00:00:00 2001 From: perennate Date: Fri, 9 Aug 2013 14:41:06 +0800 Subject: [PATCH 2/9] Greatly improve recipient selection mechanism. This resolves many errors, such as forwarding loops arising from mailing lists. --- INSTALL | 4 ++-- gpg-mailgate.py | 15 +++++---------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/INSTALL b/INSTALL index e7bd421..350eba4 100644 --- a/INSTALL +++ b/INSTALL @@ -3,11 +3,11 @@ available in the GPG home directory you use in step 2 2) Configure /etc/gpg-mailgate.conf based on the provided sample config 3) Place gpg-mailgate.py in /usr/local/bin/ -4) Place the GnuPG directory in /usr/local/lib/python2.5/site-packages +4) Place the GnuPG directory in /usr/lib/python2.7/ (replace 2.7 with your Python version) 5) Add the following to the end of /etc/postfix/master.cf gpg-mailgate unix - n n - - pipe - flags= user=nobody argv=/usr/local/bin/gpg-mailgate.py + flags= user=nobody argv=/usr/local/bin/gpg-mailgate.py ${recipient} 127.0.0.1:10028 inet n - n - 10 smtpd -o content_filter= diff --git a/gpg-mailgate.py b/gpg-mailgate.py index b5372a4..656a213 100755 --- a/gpg-mailgate.py +++ b/gpg-mailgate.py @@ -22,16 +22,11 @@ for sect in _cfg.sections(): raw = sys.stdin.read() raw_message = email.message_from_string( raw ) from_addr = raw_message['From'] -to_addrs = list() +to_addrs = sys.argv[1:] + encrypted_to_addrs = list() -if raw_message.has_key('To'): - to_addrs.extend( [e[1] for e in email.utils.getaddresses([raw_message['To']])] ) -if raw_message.has_key('Cc'): - to_addrs.extend( [e[1] for e in email.utils.getaddresses([raw_message['Cc']])] ) -if raw_message.has_key('Bcc'): - to_addrs.extend( [e[1] for e in email.utils.getaddresses([raw_message['Bcc']])] ) if raw_message.has_key('X-GPG-Encrypt-Cc'): - encrypted_to_addrs.extend( [e[1] for e in email.utils.getaddresses([raw_message['X-GPG-Encrypt-Cc']])] ) + encrypted_to_addrs.extend( [e[1] for e in email.utils.getaddresses([raw_message['X-GPG-Encrypt-Cc']])] ) del raw_message['X-GPG-Encrypt-Cc'] def send_msg( message, recipients = None ): @@ -85,8 +80,8 @@ for enc in encrypted_to_addrs: if domain in cfg['default']['domains'].split(','): if enc in keys: gpg_to.append( (enc, enc) ) - elif cfg.has_key('keymap') and cfg['keymap'].has_key(enc): - gpg_to.append( (enc, cfg['keymap'][enc]) ) + elif cfg.has_key('keymap') and cfg['keymap'].has_key(enc): + gpg_to.append( (enc, cfg['keymap'][enc]) ) for to in to_addrs: domain = to.split('@')[1] From e7bd005430d475327b87f80538b4c248b3c57a45 Mon Sep 17 00:00:00 2001 From: Colin Moller Date: Mon, 17 Jun 2013 17:51:31 -0700 Subject: [PATCH 3/9] Patch GnuPG library to trust keys we've already got to avoid having to manually add them --- GnuPG/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GnuPG/__init__.py b/GnuPG/__init__.py index abe50e7..5fc089a 100644 --- a/GnuPG/__init__.py +++ b/GnuPG/__init__.py @@ -32,5 +32,5 @@ class GPGEncryptor: return encdata def _command(self): - cmd = "/usr/bin/gpg --homedir %s --batch --yes --pgp7 --no-secmem-warning -a -e -r %s" % (self._keyhome, ' -r '.join(self._recipients)) + cmd = "/usr/bin/gpg --trust-model always --homedir %s --batch --yes --pgp7 --no-secmem-warning -a -e -r %s" % (self._keyhome, ' -r '.join(self._recipients)) return cmd.split() From d03492a183061a7f2ec9dfbbb16986830b5c33ad Mon Sep 17 00:00:00 2001 From: Colin Moller Date: Tue, 18 Jun 2013 18:46:41 -0700 Subject: [PATCH 4/9] Rudimentary support for not re-encrypting already encrypted messages --- gpg-mailgate.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/gpg-mailgate.py b/gpg-mailgate.py index 656a213..6e82bb1 100755 --- a/gpg-mailgate.py +++ b/gpg-mailgate.py @@ -44,6 +44,8 @@ def encrypt_payload( payload, gpg_to_cmdline ): gpg = GnuPG.GPGEncryptor( cfg['gpg']['keyhome'], gpg_to_cmdline ) raw_payload = payload.get_payload(decode=True) gpg.update( raw_payload ) + if "-----BEGIN PGP MESSAGE-----" in raw_payload and "-----END PGP MESSAGE-----" in raw_payload: + return payload payload.set_payload( gpg.encrypt() ) if payload['Content-Disposition']: payload.replace_header( 'Content-Disposition', re.sub(r'filename="([^"]+)"', r'filename="\1.pgp"', payload['Content-Disposition']) ) From e4cf0d81a7172eadb9adad0eedd62847ecf72d77 Mon Sep 17 00:00:00 2001 From: Igor Rzegocki Date: Mon, 16 Sep 2013 19:26:45 +0200 Subject: [PATCH 5/9] Fixed encrypted messages check Moved it to the top of the method, to avoid unnecessary GnuPG class invocation. --- gpg-mailgate.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gpg-mailgate.py b/gpg-mailgate.py index 6e82bb1..35bafa7 100755 --- a/gpg-mailgate.py +++ b/gpg-mailgate.py @@ -41,11 +41,11 @@ def send_msg( message, recipients = None ): smtp.sendmail( from_addr, recipients, message.as_string() ) def encrypt_payload( payload, gpg_to_cmdline ): - gpg = GnuPG.GPGEncryptor( cfg['gpg']['keyhome'], gpg_to_cmdline ) raw_payload = payload.get_payload(decode=True) - gpg.update( raw_payload ) if "-----BEGIN PGP MESSAGE-----" in raw_payload and "-----END PGP MESSAGE-----" in raw_payload: return payload + gpg = GnuPG.GPGEncryptor( cfg['gpg']['keyhome'], gpg_to_cmdline ) + gpg.update( raw_payload ) payload.set_payload( gpg.encrypt() ) if payload['Content-Disposition']: payload.replace_header( 'Content-Disposition', re.sub(r'filename="([^"]+)"', r'filename="\1.pgp"', payload['Content-Disposition']) ) From 867905907991892b962393b5df420b06224bcecf Mon Sep 17 00:00:00 2001 From: perennate Date: Fri, 9 Aug 2013 14:35:57 +0800 Subject: [PATCH 6/9] Revert part of commit 43b3392162f5e3ed2411197232af21d6a66fa8aa, so that we still send if there are no PGP recipients. --- gpg-mailgate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gpg-mailgate.py b/gpg-mailgate.py index 35bafa7..ad10930 100755 --- a/gpg-mailgate.py +++ b/gpg-mailgate.py @@ -31,7 +31,7 @@ if raw_message.has_key('X-GPG-Encrypt-Cc'): def send_msg( message, recipients = None ): if recipients == None: - return + recipients = to_addrs if cfg.has_key('logging') and cfg['logging'].has_key('file'): log = open(cfg['logging']['file'], 'a') log.write("Sending email to: <%s>\n" % '> <'.join( recipients )) From 527f123391a0c3b273f4dd02a04eb0dd49620e9f Mon Sep 17 00:00:00 2001 From: perennate Date: Fri, 9 Aug 2013 14:43:56 +0800 Subject: [PATCH 7/9] Fix format errors, also do deliver email for domain that should be encrypted even if the recipient doesn't have a key. --- gpg-mailgate.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/gpg-mailgate.py b/gpg-mailgate.py index ad10930..eb1c8c7 100755 --- a/gpg-mailgate.py +++ b/gpg-mailgate.py @@ -84,6 +84,8 @@ for enc in encrypted_to_addrs: gpg_to.append( (enc, enc) ) elif cfg.has_key('keymap') and cfg['keymap'].has_key(enc): gpg_to.append( (enc, cfg['keymap'][enc]) ) + else: + ungpg_to.append(enc); for to in to_addrs: domain = to.split('@')[1] @@ -92,6 +94,8 @@ for to in to_addrs: gpg_to.append( (to, to) ) elif cfg.has_key('keymap') and cfg['keymap'].has_key(to): gpg_to.append( (to, cfg['keymap'][to]) ) + else: + ungpg_to.append(to); else: ungpg_to.append(to) From 72395a7e9f0d84494750589e5fade33fab6d02a8 Mon Sep 17 00:00:00 2001 From: perennate Date: Fri, 9 Aug 2013 16:08:29 +0800 Subject: [PATCH 8/9] Fix bug with text files (or html files) attachments. --- gpg-mailgate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gpg-mailgate.py b/gpg-mailgate.py index eb1c8c7..ade4320 100755 --- a/gpg-mailgate.py +++ b/gpg-mailgate.py @@ -51,7 +51,7 @@ def encrypt_payload( payload, gpg_to_cmdline ): payload.replace_header( 'Content-Disposition', re.sub(r'filename="([^"]+)"', r'filename="\1.pgp"', payload['Content-Disposition']) ) if payload['Content-Type']: payload.replace_header( 'Content-Type', re.sub(r'name="([^"]+)"', r'name="\1.pgp"', payload['Content-Type']) ) - if payload.get_content_type() != 'text/plain' and payload.get_content_type != 'text/html': + if 'name="' in payload['Content-Type']: payload.replace_header( 'Content-Type', re.sub(r'^[a-z/]+;', r'application/octet-stream;', payload['Content-Type']) ) payload.set_payload( "\n".join( filter( lambda x:re.search(r'^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$',x), payload.get_payload().split("\n") ) ) ) return payload From c04db9c35f847a53a1c9559aebec490ef988c786 Mon Sep 17 00:00:00 2001 From: perennate Date: Sun, 11 Aug 2013 20:35:48 +0800 Subject: [PATCH 9/9] Fix bug causing messages to have extra characters or failing to encode properly. --- GnuPG/__init__.py | 18 +++++++++++++++--- gpg-mailgate.py | 2 +- 2 files changed, 16 insertions(+), 4 deletions(-) diff --git a/GnuPG/__init__.py b/GnuPG/__init__.py index 5fc089a..7a358d5 100644 --- a/GnuPG/__init__.py +++ b/GnuPG/__init__.py @@ -16,10 +16,11 @@ def public_keys( keyhome ): return keys class GPGEncryptor: - def __init__(self, keyhome, recipients = None): + def __init__(self, keyhome, recipients = None, charset = None): self._keyhome = keyhome self._message = '' self._recipients = list() + self._charset = charset if recipients != None: self._recipients.extend(recipients) @@ -32,5 +33,16 @@ class GPGEncryptor: return encdata def _command(self): - cmd = "/usr/bin/gpg --trust-model always --homedir %s --batch --yes --pgp7 --no-secmem-warning -a -e -r %s" % (self._keyhome, ' -r '.join(self._recipients)) - return cmd.split() + cmd = ["/usr/bin/gpg", "--trust-model", "always", "--homedir", self._keyhome, "--batch", "--yes", "--pgp7", "--no-secmem-warning", "-a", "-e"] + + # add recipients + for recipient in self._recipients: + cmd.append("-r") + cmd.append(recipient) + + # add on the charset, if set + if self._charset: + cmd.append("--comment") + cmd.append('Charset: ' + self._charset) + + return cmd diff --git a/gpg-mailgate.py b/gpg-mailgate.py index ade4320..01765b1 100755 --- a/gpg-mailgate.py +++ b/gpg-mailgate.py @@ -44,7 +44,7 @@ def encrypt_payload( payload, gpg_to_cmdline ): raw_payload = payload.get_payload(decode=True) if "-----BEGIN PGP MESSAGE-----" in raw_payload and "-----END PGP MESSAGE-----" in raw_payload: return payload - gpg = GnuPG.GPGEncryptor( cfg['gpg']['keyhome'], gpg_to_cmdline ) + gpg = GnuPG.GPGEncryptor( cfg['gpg']['keyhome'], gpg_to_cmdline, payload.get_content_charset() ) gpg.update( raw_payload ) payload.set_payload( gpg.encrypt() ) if payload['Content-Disposition']: