~justin-fathomdb/nova/justinsb-openstack-api-volumes

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/twisted/mail/tap.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- test-case-name: twisted.mail.test.test_options -*-
 
2
# Copyright (c) 2001-2004 Twisted Matrix Laboratories.
 
3
# See LICENSE for details.
 
4
 
 
5
 
 
6
"""I am the support module for creating mail servers with twistd
 
7
"""
 
8
 
 
9
import os
 
10
import sys
 
11
 
 
12
from twisted.mail import mail
 
13
from twisted.mail import maildir
 
14
from twisted.mail import relay
 
15
from twisted.mail import relaymanager
 
16
from twisted.mail import alias
 
17
 
 
18
from twisted.python import usage
 
19
 
 
20
from twisted.cred import checkers
 
21
from twisted.application import internet
 
22
 
 
23
 
 
24
class Options(usage.Options):
 
25
    synopsis = "[options]"
 
26
 
 
27
    optParameters = [
 
28
        ["pop3", "p", 8110, "Port to start the POP3 server on (0 to disable).", usage.portCoerce],
 
29
        ["pop3s", "S", 0, "Port to start the POP3-over-SSL server on (0 to disable).", usage.portCoerce],
 
30
        ["smtp", "s", 8025, "Port to start the SMTP server on (0 to disable).", usage.portCoerce],
 
31
        ["certificate", "c", None, "Certificate file to use for SSL connections"],
 
32
        ["relay", "R", None,
 
33
            "Relay messages according to their envelope 'To', using the given"
 
34
            "path as a queue directory."],
 
35
        ["hostname", "H", None, "The hostname by which to identify this server."],
 
36
    ]
 
37
 
 
38
    optFlags = [
 
39
        ["esmtp", "E", "Use RFC 1425/1869 SMTP extensions"],
 
40
        ["disable-anonymous", None, "Disallow non-authenticated SMTP connections"],
 
41
    ]
 
42
    zsh_actions = {"hostname" : "_hosts"}
 
43
 
 
44
    longdesc = "This creates a mail.tap file that can be used by twistd."
 
45
 
 
46
    def __init__(self):
 
47
        usage.Options.__init__(self)
 
48
        self.service = mail.MailService()
 
49
        self.last_domain = None
 
50
 
 
51
    def opt_passwordfile(self, filename):
 
52
        """Specify a file containing username:password login info for authenticated ESMTP connections."""
 
53
        ch = checkers.OnDiskUsernamePasswordDatabase(filename)
 
54
        self.service.smtpPortal.registerChecker(ch)
 
55
    opt_P = opt_passwordfile
 
56
 
 
57
    def opt_default(self):
 
58
        """Make the most recently specified domain the default domain."""
 
59
        if self.last_domain:
 
60
            self.service.addDomain('', self.last_domain)
 
61
        else:
 
62
            raise usage.UsageError("Specify a domain before specifying using --default")
 
63
    opt_D = opt_default
 
64
 
 
65
    def opt_maildirdbmdomain(self, domain):
 
66
        """generate an SMTP/POP3 virtual domain which saves to \"path\"
 
67
        """
 
68
        try:
 
69
            name, path = domain.split('=')
 
70
        except ValueError:
 
71
            raise usage.UsageError("Argument to --maildirdbmdomain must be of the form 'name=path'")
 
72
 
 
73
        self.last_domain = maildir.MaildirDirdbmDomain(self.service, os.path.abspath(path))
 
74
        self.service.addDomain(name, self.last_domain)
 
75
    opt_d = opt_maildirdbmdomain
 
76
 
 
77
    def opt_user(self, user_pass):
 
78
        """add a user/password to the last specified domains
 
79
        """
 
80
        try:
 
81
            user, password = user_pass.split('=', 1)
 
82
        except ValueError:
 
83
            raise usage.UsageError("Argument to --user must be of the form 'user=password'")
 
84
        if self.last_domain:
 
85
            self.last_domain.addUser(user, password)
 
86
        else:
 
87
            raise usage.UsageError("Specify a domain before specifying users")
 
88
    opt_u = opt_user
 
89
 
 
90
    def opt_bounce_to_postmaster(self):
 
91
        """undelivered mails are sent to the postmaster
 
92
        """
 
93
        self.last_domain.postmaster = 1
 
94
    opt_b = opt_bounce_to_postmaster
 
95
 
 
96
    def opt_aliases(self, filename):
 
97
        """Specify an aliases(5) file to use for this domain"""
 
98
        if self.last_domain is not None:
 
99
            if mail.IAliasableDomain.providedBy(self.last_domain):
 
100
                aliases = alias.loadAliasFile(self.service.domains, filename)
 
101
                self.last_domain.setAliasGroup(aliases)
 
102
                self.service.monitor.monitorFile(
 
103
                    filename,
 
104
                    AliasUpdater(self.service.domains, self.last_domain)
 
105
                )
 
106
            else:
 
107
                raise usage.UsageError(
 
108
                    "%s does not support alias files" % (
 
109
                        self.last_domain.__class__.__name__,
 
110
                    )
 
111
                )
 
112
        else:
 
113
            raise usage.UsageError("Specify a domain before specifying aliases")
 
114
    opt_A = opt_aliases
 
115
 
 
116
    def postOptions(self):
 
117
        if self['pop3s']:
 
118
            if not self['certificate']:
 
119
                raise usage.UsageError("Cannot specify --pop3s without "
 
120
                                       "--certificate")
 
121
            elif not os.path.exists(self['certificate']):
 
122
                raise usage.UsageError("Certificate file %r does not exist."
 
123
                                       % self['certificate'])
 
124
 
 
125
        if not self['disable-anonymous']:
 
126
            self.service.smtpPortal.registerChecker(checkers.AllowAnonymousAccess())
 
127
 
 
128
        if not (self['pop3'] or self['smtp'] or self['pop3s']):
 
129
            raise usage.UsageError("You cannot disable all protocols")
 
130
 
 
131
class AliasUpdater:
 
132
    def __init__(self, domains, domain):
 
133
        self.domains = domains
 
134
        self.domain = domain
 
135
    def __call__(self, new):
 
136
        self.domain.setAliasGroup(alias.loadAliasFile(self.domains, new))
 
137
 
 
138
def makeService(config):
 
139
    if config['esmtp']:
 
140
        rmType = relaymanager.SmartHostESMTPRelayingManager
 
141
        smtpFactory = config.service.getESMTPFactory
 
142
    else:
 
143
        rmType = relaymanager.SmartHostSMTPRelayingManager
 
144
        smtpFactory = config.service.getSMTPFactory
 
145
 
 
146
    if config['relay']:
 
147
        dir = config['relay']
 
148
        if not os.path.isdir(dir):
 
149
            os.mkdir(dir)
 
150
 
 
151
        config.service.setQueue(relaymanager.Queue(dir))
 
152
        default = relay.DomainQueuer(config.service)
 
153
 
 
154
        manager = rmType(config.service.queue)
 
155
        if config['esmtp']:
 
156
            manager.fArgs += (None, None)
 
157
        manager.fArgs += (config['hostname'],)
 
158
 
 
159
        helper = relaymanager.RelayStateHelper(manager, 1)
 
160
        helper.setServiceParent(config.service)
 
161
        config.service.domains.setDefaultDomain(default)
 
162
 
 
163
    ctx = None
 
164
    if config['certificate']:
 
165
        from twisted.mail.protocols import SSLContextFactory
 
166
        ctx = SSLContextFactory(config['certificate'])
 
167
 
 
168
    if config['pop3']:
 
169
        s = internet.TCPServer(config['pop3'], config.service.getPOP3Factory())
 
170
        s.setServiceParent(config.service)
 
171
    if config['pop3s']:
 
172
        s = internet.SSLServer(config['pop3s'],
 
173
                               config.service.getPOP3Factory(), ctx)
 
174
        s.setServiceParent(config.service)
 
175
    if config['smtp']:
 
176
        f = smtpFactory()
 
177
        f.context = ctx
 
178
        if config['hostname']:
 
179
            f.domain = config['hostname']
 
180
            f.fArgs = (f.domain,)
 
181
        if config['esmtp']:
 
182
            f.fArgs = (None, None) + f.fArgs
 
183
        s = internet.TCPServer(config['smtp'], f)
 
184
        s.setServiceParent(config.service)
 
185
    return config.service