From 5a45acd3486f4e7f830647953731353cda916d51 Mon Sep 17 00:00:00 2001 From: drebs Date: Tue, 24 Mar 2015 15:09:18 -0300 Subject: [feat] reject incoming mail if no pgp key found Implement a PGP key lookup in the postfix smtp recipient restriction and virtual alias mapping levels. If no PGP key is found, then the address is rejected with a temporary error. Closes: #6795 --- changes/bug_6795_reject-mail-if-no-pgp-key-found | 1 + src/leap/mx/alias_resolver.py | 45 +++++++++++------------- src/leap/mx/check_recipient_access.py | 5 ++- 3 files changed, 26 insertions(+), 25 deletions(-) create mode 100644 changes/bug_6795_reject-mail-if-no-pgp-key-found diff --git a/changes/bug_6795_reject-mail-if-no-pgp-key-found b/changes/bug_6795_reject-mail-if-no-pgp-key-found new file mode 100644 index 0000000..7b9ef1f --- /dev/null +++ b/changes/bug_6795_reject-mail-if-no-pgp-key-found @@ -0,0 +1 @@ + o Reject mail if no PGP key was found for a user. Closes #6795. diff --git a/src/leap/mx/alias_resolver.py b/src/leap/mx/alias_resolver.py index 45a3ed2..4247b57 100644 --- a/src/leap/mx/alias_resolver.py +++ b/src/leap/mx/alias_resolver.py @@ -28,10 +28,11 @@ TODO: try: # TODO: we should probably use the system alias somehow - # from twisted.mail import alias + # from twisted.mail import alias from twisted.protocols import postfix from twisted.python import log from twisted.internet import defer + from twisted.internet.protocol import ServerFactory except ImportError: print "This software requires Twisted. Please see the README file" print "for instructions on getting required dependencies." @@ -39,19 +40,20 @@ except ImportError: class LEAPPostFixTCPMapserver(postfix.PostfixTCPMapServer): def _cbGot(self, value): - if value is None: + uuid, pubkey = value + if uuid is None: self.sendCode(500, postfix.quote("NOT FOUND SRY")) + elif pubkey is None: + self.sendCode(400, postfix.quote("4.7.13 USER ACCOUNT DISABLED")) else: self.sendCode(200, postfix.quote(value)) -class AliasResolverFactory(postfix.PostfixTCPMapDeferringDictServerFactory): +class AliasResolverFactory(ServerFactory): protocol = LEAPPostFixTCPMapserver - def __init__(self, couchdb, *args, **kwargs): - postfix.PostfixTCPMapDeferringDictServerFactory.__init__( - self, *args, **kwargs) + def __init__(self, couchdb): self._cdb = couchdb def _to_str(self, result): @@ -64,14 +66,14 @@ class AliasResolverFactory(postfix.PostfixTCPMapDeferringDictServerFactory): log.msg("Result not found") return result - def spit_result(self, result): - """ - Formats the return codes in a postfix friendly format. - """ - if result is None: - return None - else: - return defer.succeed(result) + def _getPubKey(self, uuid): + if uuid is None: + return defer.succeed([None, None]) + d = defer.gatherResults([ + self._to_str(uuid), + self._cdb.getPubKey(uuid), + ]) + return d def get(self, key): """ @@ -79,13 +81,8 @@ class AliasResolverFactory(postfix.PostfixTCPMapDeferringDictServerFactory): At some point we will have to consider the domain part too. """ - try: - log.msg("Query key: %s" % (key,)) - d = self._cdb.queryByAddress(key) - - d.addCallback(self._to_str) - d.addCallback(self.spit_result) - d.addErrback(log.err) - return d - except Exception as e: - log.err('exception in get: %r' % e) + log.msg("Query key: %s" % (key,)) + d = self._cdb.queryByAddress(key) + d.addCallback(self._getPubKey) + d.addErrback(log.err) + return d diff --git a/src/leap/mx/check_recipient_access.py b/src/leap/mx/check_recipient_access.py index b80ccfd..d4ae339 100644 --- a/src/leap/mx/check_recipient_access.py +++ b/src/leap/mx/check_recipient_access.py @@ -32,8 +32,11 @@ class LEAPPostFixTCPMapserverAccess(postfix.PostfixTCPMapServer): # For more info, see: # http://www.postfix.org/tcp_table.5.html # http://www.postfix.org/access.5.html - if value is None: + uuid, pubkey = value + if uuid is None: self.sendCode(500, postfix.quote("REJECT")) + elif pubkey is None: + self.sendCode(400, postfix.quote("4.7.13 USER ACCOUNT DISABLED")) else: self.sendCode(200, postfix.quote("OK")) -- cgit v1.2.3