From 6cc3953119d0a46c9d8156dc7f958b6fb089c871 Mon Sep 17 00:00:00 2001 From: Isis Lovecruft Date: Tue, 15 Jan 2013 09:06:31 +0000 Subject: Added /leap/mx/alias_resolver.py, which contains classes for creating a server to resolve Postfix aliases. --- leap/mx/alias_resolver.py | 118 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 leap/mx/alias_resolver.py (limited to 'leap') diff --git a/leap/mx/alias_resolver.py b/leap/mx/alias_resolver.py new file mode 100644 index 0000000..2263de5 --- /dev/null +++ b/leap/mx/alias_resolver.py @@ -0,0 +1,118 @@ +#!/usr/bin/env python +# -*- encoding: utf-8 -*- +''' +alias_resolver.py +================= +Classes for resolving postfix aliases. + +@authors: Isis Agora Lovecruft +@version: 0.0.1-beta +@license: WTFPL see included LICENSE file +@copyright: copyright 2013 Isis Agora Lovecruft +''' + +import os + +from twisted.internet import address +from twisted.mail import maildir +from twisted.protocols import postfix + +from leap.mx import net, log + + +def checkIPaddress(addr): + """ + Check that a given string is a valid IPv4 or IPv6 address. + + @param addr: + Any string defining an IP address, i.e. '0.0.0.0', '::1', or '1.2.3.4'. + @returns: + True if :param:`addr` defines a valid IPAddress, False otherwise. + """ + import ipaddr + + try: + check = ipaddr.IPAddress(addr) + except ValueError, ve: + log.warn(ve.message) + return False + else: + return True + +class PostfixAliasResolver(postfix.PostfixTCPMapServer): + """ + Resolve postfix aliases, similarly to using "$ postmap -q ". + + This class starts a simple LineReceiver server which listens for a string + specifying an alias to look up, :param:`key`, and which will be used to + query the local Postfix server. You can test it with: + + $ ./alias_resolver.py & + $ /usr/bin/postmap -q tcp:localhost:4242 + + """ + def __init__(self, *args, **kwargs): + """ + Create a local LineReceiver server which listens for Postfix aliases + to resolve. + """ + super(postfix.PostfixTCPMapServer, self).__init__(*args, **kwargs) + +class PostfixAliasResolverFactory(postfix.PostfixTCPMapDeferringDictServerFactory): + """ + A Factory for creating PostfixAliasResolver servers, which handles inputs + and outputs, and keeps an in-memory mapping of Postfix aliases in the form + of a dict. + + xxx fill me in + + """ + protocol = PostfixAliasResolver + + def __init__(self, addr='127.0.0.1', port=4242, timeout=120, data=None): + """ + Create a Factory which returns :class:`PostfixAliasResolver` servers. + + @param addr: + (optional) A string giving the IP address of the Postfix server. + Default: '127.0.0.1' + @param port: + (optional) An integer that specifies the port number of the + Postfix server. Default: 4242 + @param timeout: + (optional) An integer specifying the number of seconds to wait + until we should time out. Default: 120 + @param data: + (optional) A dict to use to initialise or update the alias + mapping. + """ + super(postfix.PostfixTCPMapDeferringDictServerFactory, + self).__init__(data=data) + self.timeout = timeout + self.noisy = False ## xxx get config value + + try: + assert isinstance(port, int), "Port number must be an integer" + assert isinstance(timeout, int), "Timeout must be an integer" + except AssertionError, ae: + raise SystemExit(ae.message) + + if checkIPaddress(addr): + self.addr = address._IPAddress('TCP', addr, int(port)) + else: + log.debug("Using default address for Postfix: 127.0.0.1:%s" % port) + self.addr = address._IPAddress('TCP', '127.0.0.1', int(port)) + + def buildProtocol(self): + """ + Create an instance of the :class:`PostfixAliasResolver` server. + """ + proto = self.protocol() + proto.timeout = self.timeout + proto.factory = self + return proto + + +if __name__ == "__main__": + + print "To test alias_resolver.py, please use /test/test_alias_resolver.py" -- cgit v1.2.3