Index: third_party/twisted_8_1/twisted/mail/scripts/mailmail.py |
diff --git a/third_party/twisted_8_1/twisted/mail/scripts/mailmail.py b/third_party/twisted_8_1/twisted/mail/scripts/mailmail.py |
deleted file mode 100644 |
index 1f138e454efb02b22dff0c689ccf555b57276948..0000000000000000000000000000000000000000 |
--- a/third_party/twisted_8_1/twisted/mail/scripts/mailmail.py |
+++ /dev/null |
@@ -1,363 +0,0 @@ |
- |
-# Copyright (c) 2001-2004 Twisted Matrix Laboratories. |
-# See LICENSE for details. |
- |
-# |
- |
-""" |
-Implementation module for the `newtexaco` command. |
- |
-The name is preliminary and subject to change. |
-""" |
- |
-import os |
-import sys |
-import rfc822 |
-import socket |
-import getpass |
-from ConfigParser import ConfigParser |
- |
-try: |
- import cStringIO as StringIO |
-except: |
- import StringIO |
- |
-from twisted.internet import reactor |
-from twisted.mail import bounce, smtp |
- |
-GLOBAL_CFG = "/etc/mailmail" |
-LOCAL_CFG = os.path.expanduser("~/.twisted/mailmail") |
-SMARTHOST = '127.0.0.1' |
- |
-ERROR_FMT = """\ |
-Subject: Failed Message Delivery |
- |
- Message delivery failed. The following occurred: |
- |
- %s |
--- |
-The Twisted sendmail application. |
-""" |
- |
-def log(message, *args): |
- sys.stderr.write(str(message) % args + '\n') |
- |
-class Options: |
- """ |
- @type to: C{list} of C{str} |
- @ivar to: The addresses to which to deliver this message. |
- |
- @type sender: C{str} |
- @ivar sender: The address from which this message is being sent. |
- |
- @type body: C{file} |
- @ivar body: The object from which the message is to be read. |
- """ |
- |
-def getlogin(): |
- try: |
- return os.getlogin() |
- except: |
- return getpass.getuser() |
- |
- |
-def parseOptions(argv): |
- o = Options() |
- o.to = [e for e in argv if not e.startswith('-')] |
- o.sender = getlogin() |
- |
- # Just be very stupid |
- |
- # Skip -bm -- it is the default |
- |
- # -bp lists queue information. Screw that. |
- if '-bp' in argv: |
- raise ValueError, "Unsupported option" |
- |
- # -bs makes sendmail use stdin/stdout as its transport. Screw that. |
- if '-bs' in argv: |
- raise ValueError, "Unsupported option" |
- |
- # -F sets who the mail is from, but is overridable by the From header |
- if '-F' in argv: |
- o.sender = argv[argv.index('-F') + 1] |
- o.to.remove(o.sender) |
- |
- # -i and -oi makes us ignore lone "." |
- if ('-i' in argv) or ('-oi' in argv): |
- raise ValueError, "Unsupported option" |
- |
- # -odb is background delivery |
- if '-odb' in argv: |
- o.background = True |
- else: |
- o.background = False |
- |
- # -odf is foreground delivery |
- if '-odf' in argv: |
- o.background = False |
- else: |
- o.background = True |
- |
- # -oem and -em cause errors to be mailed back to the sender. |
- # It is also the default. |
- |
- # -oep and -ep cause errors to be printed to stderr |
- if ('-oep' in argv) or ('-ep' in argv): |
- o.printErrors = True |
- else: |
- o.printErrors = False |
- |
- # -om causes a copy of the message to be sent to the sender if the sender |
- # appears in an alias expansion. We do not support aliases. |
- if '-om' in argv: |
- raise ValueError, "Unsupported option" |
- |
- # -t causes us to pick the recipients of the message from the To, Cc, and Bcc |
- # headers, and to remove the Bcc header if present. |
- if '-t' in argv: |
- o.recipientsFromHeaders = True |
- o.excludeAddresses = o.to |
- o.to = [] |
- else: |
- o.recipientsFromHeaders = False |
- o.exludeAddresses = [] |
- |
- requiredHeaders = { |
- 'from': [], |
- 'to': [], |
- 'cc': [], |
- 'bcc': [], |
- 'date': [], |
- } |
- |
- headers = [] |
- buffer = StringIO.StringIO() |
- while 1: |
- write = 1 |
- line = sys.stdin.readline() |
- if not line.strip(): |
- break |
- |
- hdrs = line.split(': ', 1) |
- |
- hdr = hdrs[0].lower() |
- if o.recipientsFromHeaders and hdr in ('to', 'cc', 'bcc'): |
- o.to.extend([ |
- a[1] for a in rfc822.AddressList(hdrs[1]).addresslist |
- ]) |
- if hdr == 'bcc': |
- write = 0 |
- elif hdr == 'from': |
- o.sender = rfc822.parseaddr(hdrs[1])[1] |
- |
- if hdr in requiredHeaders: |
- requiredHeaders[hdr].append(hdrs[1]) |
- |
- if write: |
- buffer.write(line) |
- |
- if not requiredHeaders['from']: |
- buffer.write('From: %s\r\n' % (o.sender,)) |
- if not requiredHeaders['to']: |
- if not o.to: |
- raise ValueError, "No recipients specified" |
- buffer.write('To: %s\r\n' % (', '.join(o.to),)) |
- if not requiredHeaders['date']: |
- buffer.write('Date: %s\r\n' % (smtp.rfc822date(),)) |
- |
- buffer.write(line) |
- |
- if o.recipientsFromHeaders: |
- for a in o.excludeAddresses: |
- try: |
- o.to.remove(a) |
- except: |
- pass |
- |
- buffer.seek(0, 0) |
- o.body = StringIO.StringIO(buffer.getvalue() + sys.stdin.read()) |
- return o |
- |
-class Configuration: |
- """ |
- @ivar allowUIDs: A list of UIDs which are allowed to send mail. |
- @ivar allowGIDs: A list of GIDs which are allowed to send mail. |
- @ivar denyUIDs: A list of UIDs which are not allowed to send mail. |
- @ivar denyGIDs: A list of GIDs which are not allowed to send mail. |
- |
- @type defaultAccess: C{bool} |
- @ivar defaultAccess: C{True} if access will be allowed when no other access |
- control rule matches or C{False} if it will be denied in that case. |
- |
- @ivar useraccess: Either C{'allow'} to check C{allowUID} first |
- or C{'deny'} to check C{denyUID} first. |
- |
- @ivar groupaccess: Either C{'allow'} to check C{allowGID} first or |
- C{'deny'} to check C{denyGID} first. |
- |
- @ivar identities: A C{dict} mapping hostnames to credentials to use when |
- sending mail to that host. |
- |
- @ivar smarthost: C{None} or a hostname through which all outgoing mail will |
- be sent. |
- |
- @ivar domain: C{None} or the hostname with which to identify ourselves when |
- connecting to an MTA. |
- """ |
- def __init__(self): |
- self.allowUIDs = [] |
- self.denyUIDs = [] |
- self.allowGIDs = [] |
- self.denyGIDs = [] |
- self.useraccess = 'deny' |
- self.groupaccess= 'deny' |
- |
- self.identities = {} |
- self.smarthost = None |
- self.domain = None |
- |
- self.defaultAccess = True |
- |
- |
-def loadConfig(path): |
- # [useraccess] |
- # allow=uid1,uid2,... |
- # deny=uid1,uid2,... |
- # order=allow,deny |
- # [groupaccess] |
- # allow=gid1,gid2,... |
- # deny=gid1,gid2,... |
- # order=deny,allow |
- # [identity] |
- # host1=username:password |
- # host2=username:password |
- # [addresses] |
- # smarthost=a.b.c.d |
- # default_domain=x.y.z |
- |
- c = Configuration() |
- |
- if not os.access(path, os.R_OK): |
- return c |
- |
- p = ConfigParser() |
- p.read(path) |
- |
- au = c.allowUIDs |
- du = c.denyUIDs |
- ag = c.allowGIDs |
- dg = c.denyGIDs |
- for (section, a, d) in (('useraccess', au, du), ('groupaccess', ag, dg)): |
- if p.has_section(section): |
- for (mode, L) in (('allow', a), ('deny', d)): |
- if p.has_option(section, mode) and p.get(section, mode): |
- for id in p.get(section, mode).split(','): |
- try: |
- id = int(id) |
- except ValueError: |
- log("Illegal %sID in [%s] section: %s", section[0].upper(), section, id) |
- else: |
- L.append(id) |
- order = p.get(section, 'order') |
- order = map(str.split, map(str.lower, order.split(','))) |
- if order[0] == 'allow': |
- setattr(c, section, 'allow') |
- else: |
- setattr(c, section, 'deny') |
- |
- if p.has_section('identity'): |
- for (host, up) in p.items('identity'): |
- parts = up.split(':', 1) |
- if len(parts) != 2: |
- log("Illegal entry in [identity] section: %s", up) |
- continue |
- p.identities[host] = parts |
- |
- if p.has_section('addresses'): |
- if p.has_option('addresses', 'smarthost'): |
- c.smarthost = p.get('addresses', 'smarthost') |
- if p.has_option('addresses', 'default_domain'): |
- c.domain = p.get('addresses', 'default_domain') |
- |
- return c |
- |
-def success(result): |
- reactor.stop() |
- |
-failed = None |
-def failure(f): |
- global failed |
- reactor.stop() |
- failed = f |
- |
-def sendmail(host, options, ident): |
- d = smtp.sendmail(host, options.sender, options.to, options.body) |
- d.addCallbacks(success, failure) |
- reactor.run() |
- |
-def senderror(failure, options): |
- recipient = [options.sender] |
- sender = '"Internally Generated Message (%s)"<postmaster@%s>' % (sys.argv[0], smtp.DNSNAME) |
- error = StringIO.StringIO() |
- failure.printTraceback(file=error) |
- body = StringIO.StringIO(ERROR_FMT % error.getvalue()) |
- |
- d = smtp.sendmail('localhost', sender, recipient, body) |
- d.addBoth(lambda _: reactor.stop()) |
- |
-def deny(conf): |
- uid = os.getuid() |
- gid = os.getgid() |
- |
- if conf.useraccess == 'deny': |
- if uid in conf.denyUIDs: |
- return True |
- if uid in conf.allowUIDs: |
- return False |
- else: |
- if uid in conf.allowUIDs: |
- return False |
- if uid in conf.denyUIDs: |
- return True |
- |
- if conf.groupaccess == 'deny': |
- if gid in conf.denyGIDs: |
- return True |
- if gid in conf.allowGIDs: |
- return False |
- else: |
- if gid in conf.allowGIDs: |
- return False |
- if gid in conf.denyGIDs: |
- return True |
- |
- return not conf.defaultAccess |
- |
-def run(): |
- o = parseOptions(sys.argv[1:]) |
- gConf = loadConfig(GLOBAL_CFG) |
- lConf = loadConfig(LOCAL_CFG) |
- |
- if deny(gConf) or deny(lConf): |
- log("Permission denied") |
- return |
- |
- host = lConf.smarthost or gConf.smarthost or SMARTHOST |
- |
- ident = gConf.identities.copy() |
- ident.update(lConf.identities) |
- |
- if lConf.domain: |
- smtp.DNSNAME = lConf.domain |
- elif gConf.domain: |
- smtp.DNSNAME = gConf.domain |
- |
- sendmail(host, o, ident) |
- |
- if failed: |
- if o.printErrors: |
- failed.printTraceback(file=sys.stderr) |
- raise SystemExit(1) |
- else: |
- senderror(failed, o) |