GPG Mailgate 0.1
This commit is contained in:
commit
782cda3639
4 changed files with 161 additions and 0 deletions
43
GnuPG/__init__.py
Normal file
43
GnuPG/__init__.py
Normal file
|
@ -0,0 +1,43 @@
|
|||
import os
|
||||
import subprocess
|
||||
|
||||
def public_keys( keyhome ):
|
||||
cmd = '/usr/bin/gpg --homedir %s --list-keys --with-colons' % keyhome
|
||||
p = subprocess.Popen( cmd.split(' '), stdin=None, stdout=subprocess.PIPE, stderr=subprocess.PIPE )
|
||||
p.wait()
|
||||
keys = list()
|
||||
for line in p.stdout.readlines():
|
||||
if line[0:3] == 'uid' or line[0:3] == 'pub':
|
||||
key = line.split('<')[1].split('>')[0]
|
||||
if keys.count(key) == 0:
|
||||
keys.append(key)
|
||||
return keys
|
||||
|
||||
class GPGEncryptor:
|
||||
def __init__(self, keyhome, recipients = None):
|
||||
self._keyhome = keyhome
|
||||
self._message = ''
|
||||
self._recipients = list()
|
||||
if recipients != None:
|
||||
self._recipients.extend(recipients)
|
||||
|
||||
def update(self, message):
|
||||
self._message += message
|
||||
|
||||
def encrypt(self):
|
||||
p = subprocess.Popen( self._command(), stdin=subprocess.PIPE, stdout=subprocess.PIPE,stderr=subprocess.PIPE )
|
||||
(stdin, stdout, stderr) = (p.stdin, p.stdout, p.stderr)
|
||||
|
||||
# Write the data
|
||||
stdin.write(self._message)
|
||||
stdin.close()
|
||||
|
||||
# Read the encrypted data
|
||||
p.wait()
|
||||
encdata = stdout.read()
|
||||
|
||||
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))
|
||||
return cmd.split()
|
26
INSTALL
Normal file
26
INSTALL
Normal file
|
@ -0,0 +1,26 @@
|
|||
1) Ensure that GPG is installed and configured.
|
||||
a) Make sure public keys for all of your potential recipients are
|
||||
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
|
||||
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
|
||||
|
||||
127.0.0.1:10028 inet n - n - 10 smtpd
|
||||
-o content_filter=
|
||||
-o receive_override_options=no_unknown_recipient_checks,no_header_body_checks
|
||||
-o smtpd_helo_restrictions=
|
||||
-o smtpd_client_restrictions=
|
||||
-o smtpd_sender_restrictions=
|
||||
-o smtpd_recipient_restrictions=permit_mynetworks,reject
|
||||
-o mynetworks=127.0.0.0/8
|
||||
-o smtpd_authorized_xforward_hosts=127.0.0.0/8
|
||||
|
||||
6) Add the following to /etc/postfix/main.cf
|
||||
|
||||
content_filter = gpg-mailgate
|
||||
|
||||
7) Restart postfix.
|
23
gpg-mailgate.conf.sample
Normal file
23
gpg-mailgate.conf.sample
Normal file
|
@ -0,0 +1,23 @@
|
|||
[default]
|
||||
add_header = yes
|
||||
domains = example.com,corp.org
|
||||
|
||||
[gpg]
|
||||
keyhome = /var/gpg/.gnupg
|
||||
|
||||
[logging]
|
||||
file = /tmp/gpg-mailgate.log
|
||||
|
||||
[relay]
|
||||
host = 127.0.0.1
|
||||
port = 10028
|
||||
|
||||
[keymap]
|
||||
# You can find these by running the following command:
|
||||
# gpg --list-keys --keyid-format long user@example.com
|
||||
# Which will return output similar to:
|
||||
# pub 1024D/AAAAAAAAAAAAAAAA 2007-10-22
|
||||
# uid Joe User <user@example.com>
|
||||
# sub 2048g/BBBBBBBBBBBBBBBB 2007-10-22
|
||||
# You want the AAAAAAAAAAAAAAAA not BBBBBBBBBBBBBBBB.
|
||||
#user@example.com <gpg key id>
|
69
gpg-mailgate.py
Executable file
69
gpg-mailgate.py
Executable file
|
@ -0,0 +1,69 @@
|
|||
#!/usr/bin/python
|
||||
|
||||
from ConfigParser import RawConfigParser
|
||||
import email
|
||||
import GnuPG
|
||||
import smtplib
|
||||
import sys
|
||||
|
||||
# Read configuration from /etc/gpg-mailgate.conf
|
||||
_cfg = RawConfigParser()
|
||||
_cfg.read('/etc/gpg-mailgate.conf')
|
||||
cfg = dict()
|
||||
for sect in _cfg.sections():
|
||||
cfg[sect] = dict()
|
||||
for (name, value) in _cfg.items(sect):
|
||||
cfg[sect][name] = value
|
||||
|
||||
# Read e-mail from stdin
|
||||
raw = sys.stdin.read()
|
||||
raw_message = email.message_from_string( raw )
|
||||
from_addr = raw_message['From']
|
||||
to_addrs = map(lambda x: x.strip(), raw_message['To'].split(','))
|
||||
if raw_message.has_key('Cc'):
|
||||
to_addrs.extend( map(lambda x: x.strip(), raw_message['Cc'].split(',')))
|
||||
if raw_message.has_key('Bcc'):
|
||||
to_addrs.extend( map(lambda x: x.strip(), raw_message['Bcc'].split(',')))
|
||||
|
||||
def send_msg( message, recipients = None ):
|
||||
if recipients == None:
|
||||
recipients = to_addrs
|
||||
relay = (cfg['relay']['host'], int(cfg['relay']['port']))
|
||||
smtp = smtplib.SMTP(relay[0], relay[1])
|
||||
smtp.sendmail( from_addr, recipients, message.as_string() )
|
||||
sys.exit(0)
|
||||
|
||||
gpg_to = list()
|
||||
keys = GnuPG.public_keys( cfg['gpg']['keyhome'] )
|
||||
for to in to_addrs:
|
||||
domain = to.split('@')[1]
|
||||
if domain in cfg['default']['domains'].split(','):
|
||||
if to in keys:
|
||||
gpg_to.append( (to, to) )
|
||||
elif cfg.has_key('keymap') and cfg['keymap'].has_key(to):
|
||||
gpg_to.append( (to, cfg['keymap'][to]) )
|
||||
|
||||
if gpg_to == list():
|
||||
if cfg['default'].has_key('add_header') and cfg['default']['add_header'] == 'yes':
|
||||
raw_message['X-GPG-Mailgate'] = 'Not encrypted, public key not found'
|
||||
send_msg( raw_message )
|
||||
|
||||
if raw_message.is_multipart():
|
||||
payload = list()
|
||||
for part in raw_message.get_payload():
|
||||
if part.get_content_type() == "text/plain":
|
||||
payload.append(part)
|
||||
raw_message.set_payload( payload )
|
||||
|
||||
if cfg.has_key('logging') and cfg['logging'].has_key('file'):
|
||||
log = open(cfg['logging']['file'], 'a')
|
||||
log.write("Encrypting email to: %s\n" % ' '.join( map(lambda x: x[0], gpg_to) ))
|
||||
log.close()
|
||||
|
||||
if cfg['default'].has_key('add_header') and cfg['default']['add_header'] == 'yes':
|
||||
raw_message['X-GPG-Mailgate'] = 'Encrypted by GPG Mailgate 0.1'
|
||||
|
||||
gpg = GnuPG.GPGEncryptor( cfg['gpg']['keyhome'], map(lambda x: x[1], gpg_to) )
|
||||
gpg.update( raw_message.get_payload() )
|
||||
raw_message.set_payload( gpg.encrypt() )
|
||||
send_msg( raw_message, map(lambda x: x[0], gpg_to) )
|
Loading…
Reference in a new issue