-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtxgreylistd.py
65 lines (49 loc) · 2.18 KB
/
txgreylistd.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
from twisted.protocols.basic import LineOnlyReceiver
from twisted.internet.defer import Deferred
from twisted.internet.address import IPv6Address, IPv4Address
from twisted.python.components import proxyForInterface
from twisted.mail.smtp import IMessageDelivery, SMTPServerError
from twisted.internet.endpoints import connectProtocol, clientFromString
from twisted.python import log
class _GreylistProtocol(LineOnlyReceiver, object):
delimiter = '\n'
def __init__(self, deferred, command):
self.deferred = deferred
self.command = command
def connectionMade(self):
self.sendLine(self.command)
def lineReceived(self, line):
d, self.deferred = self.deferred, None
d.deferred.callback(line)
self.transport.loseConnection()
def greylistCommand(command, port='unix:/var/run/greylistd/socket', reactor=None):
if not reactor:
from twisted.internet import reactor
deferred = Deferred()
d = connectProtocol(clientFromString(reactor, port), _GreylistProtocol(deferred, command))
d.addErrback(deferred.errback)
return deferred
class GreylistDeliveryWrapper(
proxyForInterface(IMessageDelivery, '_delivery'), object):
def validateTo(self, user):
peer = user.protocol.transport.getPeer()
if not (isinstance(peer, IPv4Address)
or isinstance(peer, IPv6Address)):
# Not connected over TCP, so don't try greylisting
return self._delivery.validateTo(user)
command = ("IS_DEFERRED %(senderHost)s "
"%(senderAddress)s %(localAddress)s\n" % {
'senderHost': peer.host,
'senderAddress': str(user.orig),
'localAddress': str(user.destination)
})
d = greylistCommand(command)
def cbGreylist(line):
if line == 'yes':
raise SMTPServerError(450, "Greylisted")
return self._delivery.validateTo(user)
def ebGreylist(res):
log.err(res, "Error connecting to greylist, deferring.")
raise SMTPServerError(450, "Greylisted")
d.addCallbacks(cbGreylist, ebGreylist)
return d