/usr/lib/python2.7/dist-packages/twisted/mail/relay.py is in python-twisted-mail 13.2.0-1ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
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 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 | # -*- test-case-name: twisted.mail.test.test_mail -*-
# Copyright (c) Twisted Matrix Laboratories.
# See LICENSE for details.
"""
Support for relaying mail for L{twisted.mail}.
"""
from twisted.mail import smtp
from twisted.python import log
from twisted.internet.address import UNIXAddress
import os
try:
import cPickle as pickle
except ImportError:
import pickle
class DomainQueuer:
"""
An SMTP domain which add messages to a queue intended for relaying.
"""
def __init__(self, service, authenticated=False):
self.service = service
self.authed = authenticated
def exists(self, user):
"""
Check whether we will relay.
Calls overridable L{willRelay} method.
@raise smtp.SMTPBadRcpt: Raised if the given C{user} will not relay.
"""
if self.willRelay(user.dest, user.protocol):
# The most cursor form of verification of the addresses
orig = filter(None, str(user.orig).split('@', 1))
dest = filter(None, str(user.dest).split('@', 1))
if len(orig) == 2 and len(dest) == 2:
return lambda: self.startMessage(user)
raise smtp.SMTPBadRcpt(user)
def willRelay(self, address, protocol):
"""
Check whether we agree to relay.
The default is to relay for all connections over UNIX
sockets and all connections from localhost.
"""
peer = protocol.transport.getPeer()
return (self.authed or isinstance(peer, UNIXAddress) or
peer.host == '127.0.0.1')
def startMessage(self, user):
"""
Add envelope to queue and returns an SMTP message.
"""
queue = self.service.queue
envelopeFile, smtpMessage = queue.createNewMessage()
try:
log.msg('Queueing mail %r -> %r' % (str(user.orig),
str(user.dest)))
pickle.dump([str(user.orig), str(user.dest)], envelopeFile)
finally:
envelopeFile.close()
return smtpMessage
class RelayerMixin:
# XXX - This is -totally- bogus
# It opens about a -hundred- -billion- files
# and -leaves- them open!
def loadMessages(self, messagePaths):
self.messages = []
self.names = []
for message in messagePaths:
fp = open(message+'-H')
try:
messageContents = pickle.load(fp)
finally:
fp.close()
fp = open(message+'-D')
messageContents.append(fp)
self.messages.append(messageContents)
self.names.append(message)
def getMailFrom(self):
if not self.messages:
return None
return self.messages[0][0]
def getMailTo(self):
if not self.messages:
return None
return [self.messages[0][1]]
def getMailData(self):
if not self.messages:
return None
return self.messages[0][2]
def sentMail(self, code, resp, numOk, addresses, log):
"""Since we only use one recipient per envelope, this
will be called with 0 or 1 addresses. We probably want
to do something with the error message if we failed.
"""
if code in smtp.SUCCESS:
# At least one, i.e. all, recipients successfully delivered
os.remove(self.names[0]+'-D')
os.remove(self.names[0]+'-H')
del self.messages[0]
del self.names[0]
class SMTPRelayer(RelayerMixin, smtp.SMTPClient):
def __init__(self, messagePaths, *args, **kw):
smtp.SMTPClient.__init__(self, *args, **kw)
self.loadMessages(messagePaths)
class ESMTPRelayer(RelayerMixin, smtp.ESMTPClient):
def __init__(self, messagePaths, *args, **kw):
smtp.ESMTPClient.__init__(self, *args, **kw)
self.loadMessages(messagePaths)
|