Esempio n. 1
0
    def test_hostnames(self):
        """
        CompleteHostnames produces zsh shell-code that completes hostnames.
        """
        c = usage.CompleteHostnames()
        out = c._shellCode('some-option', usage._ZSH)
        self.assertEqual(out, ':some-option:_hosts')

        c = usage.CompleteHostnames(descr='some action', repeat=True)
        out = c._shellCode('some-option', usage._ZSH)
        self.assertEqual(out, '*:some action:_hosts')
Esempio n. 2
0
class Options(usage.Options):
    synopsis = "[options]"
    longdesc = "Port Forwarder."
    optParameters = [
        ["port", "p", "6666", "Set the port number."],
        ["host", "h", "localhost", "Set the host."],
        ["dest_port", "d", 6665, "Set the destination port."],
    ]

    compData = usage.Completions(optActions={"host": usage.CompleteHostnames()})
Esempio n. 3
0
class MyOptions(usage.Options):
    optParameters = [("user", "u", "guest", "username"),
                     ("password", "w", "guest"),
                     ("service", "s", "twisted.manhole", "PB Service"),
                     ("host", "h", "localhost"), ("port", "p", str(pbportno)),
                     ("perspective", "P", "", "PB Perspective to ask for "
                      "(if different than username)")]

    compData = usage.Completions(optActions={
        "host": usage.CompleteHostnames(),
        "user": usage.CompleteUsernames()
    })
Esempio n. 4
0
class Options(usage.Options):
    synopsis = "[options]"
    longdesc = 'Fix Client.'
    optParameters = [
        ["hostname", "h", "localhost", "Set the host to connect to."],
        ["port", "p", 8443, "Set the destination port."],
        ['spec', 's', None, 'Fix xml spec file'],
        ['heartbeat_int', 'H', 30, 'Heartbeat Interval'],
        ['target_comp_id', 'T', None, 'TargetCompId'],
        ['sender_comp_id', 'S', None, 'SenderCompID'],
        ['password', 'P', None, 'Password'],
        ['instrument_id', 'i', None, 'Instrument/security id'],
        ['market_depth', 'd', 1, 'Market depth'],
        ['metrics_interval', 'm', 5, 'Interval to record metrics (sec)'],
        ['statsdir', 'o',
         os.getcwd(), 'irectory to stora stats output'],
    ]
    compData = usage.Completions(
        optActions={"hostname": usage.CompleteHostnames()})
Esempio n. 5
0
class Options(usage.Options):
    synopsis = "[options]"

    groups = None
    servers = None
    subscriptions = None

    optParameters = [["port", "p", "119", "Listen port"],
                     ["interface", "i", "", "Interface to which to bind"],
                     ["datadir", "d", "news.db", "Root data storage path"],
                     [
                         "mailhost", "m", "localhost",
                         "Host of SMTP server to use"
                     ]]
    compData = usage.Completions(
        optActions={
            "datadir": usage.CompleteDirs(),
            "mailhost": usage.CompleteHostnames(),
            "interface": usage.CompleteNetInterfaces()
        })

    def __init__(self):
        usage.Options.__init__(self)
        self.groups = []
        self.servers = []
        self.subscriptions = []

    def opt_group(self, group):
        """The name of a newsgroup to carry."""
        self.groups.append([group, None])

    def opt_moderator(self, moderator):
        """The email of the moderator for the most recently passed group."""
        self.groups[-1][1] = moderator

    def opt_subscription(self, group):
        """A newsgroup to list as a recommended subscription."""
        self.subscriptions.append(group)

    def opt_server(self, server):
        """The address of a Usenet server to pass messages to and receive messages from."""
        self.servers.append(server)
Esempio n. 6
0
class Options(usage.Options, strcred.AuthOptionMixin):
    """
    An options list parser for twistd mail.

    @type synopsis: L{bytes}
    @ivar synopsis: A description of options for use in the usage message.

    @type optParameters: L{list} of L{list} of (0) L{bytes}, (1) L{bytes},
        (2) L{object}, (3) L{bytes}, (4) L{None} or
        callable which takes L{bytes} and returns L{object}
    @ivar optParameters: Information about supported parameters.  See
        L{Options <twisted.python.usage.Options>} for details.

    @type optFlags: L{list} of L{list} of (0) L{bytes}, (1) L{bytes} or
        L{None}, (2) L{bytes}
    @ivar optFlags: Information about supported flags.  See
        L{Options <twisted.python.usage.Options>} for details.

    @type _protoDefaults: L{dict} mapping L{bytes} to L{int}
    @ivar _protoDefaults: A mapping of default service to port.

    @type compData: L{Completions <usage.Completions>}
    @ivar compData: Metadata for the shell tab completion system.

    @type longdesc: L{bytes}
    @ivar longdesc: A long description of the plugin for use in the usage
        message.

    @type service: L{MailService}
    @ivar service: The email service.

    @type last_domain: L{IDomain} provider or L{None}
    @ivar last_domain: The most recently specified domain.
    """
    synopsis = "[options]"

    optParameters = [
        [
            "relay", "R", None,
            "Relay messages according to their envelope 'To', using "
            "the given path as a queue directory."
        ],
        [
            "hostname", "H", None,
            "The hostname by which to identify this server."
        ],
    ]

    optFlags = [
        ["esmtp", "E", "Use RFC 1425/1869 SMTP extensions"],
        [
            "disable-anonymous", None,
            "Disallow non-authenticated SMTP connections"
        ],
        ["no-pop3", None, "Disable the default POP3 server."],
        ["no-smtp", None, "Disable the default SMTP server."],
    ]

    _protoDefaults = {
        "pop3": 8110,
        "smtp": 8025,
    }

    compData = usage.Completions(
        optActions={"hostname": usage.CompleteHostnames()})

    longdesc = """
    An SMTP / POP3 email server plugin for twistd.

    Examples:

    1. SMTP and POP server

    twistd mail --maildirdbmdomain=example.com=/tmp/example.com
    --user=joe=password

    Starts an SMTP server that only accepts emails to [email protected] and saves
    them to /tmp/example.com.

    Also starts a POP mail server which will allow a client to log in using
    username: [email protected] and password: password and collect any email that
    has been saved in /tmp/example.com.

    2. SMTP relay

    twistd mail --relay=/tmp/mail_queue

    Starts an SMTP server that accepts emails to any email address and relays
    them to an appropriate remote SMTP server. Queued emails will be
    temporarily stored in /tmp/mail_queue.
    """

    def __init__(self):
        """
        Parse options and create a mail service.
        """
        usage.Options.__init__(self)
        self.service = mail.MailService()
        self.last_domain = None
        for service in self._protoDefaults:
            self[service] = []

    def addEndpoint(self, service, description):
        """
        Add an endpoint to a service.

        @type service: L{bytes}
        @param service: A service, either C{b'smtp'} or C{b'pop3'}.

        @type description: L{bytes}
        @param description: An endpoint description string or a TCP port
            number.
        """
        from twisted.internet import reactor
        self[service].append(endpoints.serverFromString(reactor, description))

    def opt_pop3(self, description):
        """
        Add a POP3 port listener on the specified endpoint.

        You can listen on multiple ports by specifying multiple --pop3 options.
        """
        self.addEndpoint('pop3', description)

    opt_p = opt_pop3

    def opt_smtp(self, description):
        """
        Add an SMTP port listener on the specified endpoint.

        You can listen on multiple ports by specifying multiple --smtp options.
        """
        self.addEndpoint('smtp', description)

    opt_s = opt_smtp

    def opt_default(self):
        """
        Make the most recently specified domain the default domain.
        """
        if self.last_domain:
            self.service.addDomain('', self.last_domain)
        else:
            raise usage.UsageError(
                "Specify a domain before specifying using --default")

    opt_D = opt_default

    def opt_maildirdbmdomain(self, domain):
        """
        Generate an SMTP/POP3 virtual domain.

        This option requires an argument of the form 'NAME=PATH' where NAME is
        the DNS domain name for which email will be accepted and where PATH is
        a the filesystem path to a Maildir folder.
        [Example: 'example.com=/tmp/example.com']
        """
        try:
            name, path = domain.split('=')
        except ValueError:
            raise usage.UsageError(
                "Argument to --maildirdbmdomain must be of the form 'name=path'"
            )

        self.last_domain = maildir.MaildirDirdbmDomain(self.service,
                                                       os.path.abspath(path))
        self.service.addDomain(name, self.last_domain)

    opt_d = opt_maildirdbmdomain

    def opt_user(self, user_pass):
        """
        Add a user and password to the last specified domain.
        """
        try:
            user, password = user_pass.split('=', 1)
        except ValueError:
            raise usage.UsageError(
                "Argument to --user must be of the form 'user=password'")
        if self.last_domain:
            self.last_domain.addUser(user, password)
        else:
            raise usage.UsageError("Specify a domain before specifying users")

    opt_u = opt_user

    def opt_bounce_to_postmaster(self):
        """
        Send undeliverable messages to the postmaster.
        """
        self.last_domain.postmaster = 1

    opt_b = opt_bounce_to_postmaster

    def opt_aliases(self, filename):
        """
        Specify an aliases(5) file to use for the last specified domain.
        """
        if self.last_domain is not None:
            if mail.IAliasableDomain.providedBy(self.last_domain):
                aliases = alias.loadAliasFile(self.service.domains, filename)
                self.last_domain.setAliasGroup(aliases)
                self.service.monitor.monitorFile(
                    filename,
                    AliasUpdater(self.service.domains, self.last_domain))
            else:
                raise usage.UsageError("%s does not support alias files" %
                                       (self.last_domain.__class__.__name__, ))
        else:
            raise usage.UsageError(
                "Specify a domain before specifying aliases")

    opt_A = opt_aliases

    def _getEndpoints(self, reactor, service):
        """
        Return a list of endpoints for the specified service, constructing
        defaults if necessary.

        If no endpoints were configured for the service and the protocol
        was not explicitly disabled with a I{--no-*} option, a default
        endpoint for the service is created.

        @type reactor: L{IReactorTCP <twisted.internet.interfaces.IReactorTCP>}
            provider
        @param reactor: If any endpoints are created, the reactor with
            which they are created.

        @type service: L{bytes}
        @param service: The type of service for which to retrieve endpoints,
            either C{b'pop3'} or C{b'smtp'}.

        @rtype: L{list} of L{IStreamServerEndpoint
            <twisted.internet.interfaces.IStreamServerEndpoint>} provider
        @return: The endpoints for the specified service as configured by the
            command line parameters.
        """
        if self[service]:
            # If there are any services set up, just return those.
            return self[service]
        elif self['no-' + service]:
            # If there are no services, but the service was explicitly disabled,
            # return nothing.
            return []
        else:
            # Otherwise, return the old default service.
            return [
                endpoints.TCP4ServerEndpoint(reactor,
                                             self._protoDefaults[service])
            ]

    def postOptions(self):
        """
        Check the validity of the specified set of options and
        configure authentication.

        @raise UsageError: When the set of options is invalid.
        """
        from twisted.internet import reactor

        if self['esmtp'] and self['hostname'] is None:
            raise usage.UsageError("--esmtp requires --hostname")

        # If the --auth option was passed, this will be present -- otherwise,
        # it won't be, which is also a perfectly valid state.
        if 'credCheckers' in self:
            for ch in self['credCheckers']:
                self.service.smtpPortal.registerChecker(ch)

        if not self['disable-anonymous']:
            self.service.smtpPortal.registerChecker(
                checkers.AllowAnonymousAccess())

        anything = False
        for service in self._protoDefaults:
            self[service] = self._getEndpoints(reactor, service)
            if self[service]:
                anything = True

        if not anything:
            raise usage.UsageError("You cannot disable all protocols")
Esempio n. 7
0
class Options(usage.Options, strcred.AuthOptionMixin):
    synopsis = "[options]"

    optParameters = [
        [
            "pop3s", "S", 0,
            "Port to start the POP3-over-SSL server on (0 to disable). "
            "DEPRECATED: use "
            "'--pop3 ssl:port:privateKey=pkey.pem:certKey=cert.pem'"
        ],
        [
            "certificate", "c", None,
            "Certificate file to use for SSL connections. "
            "DEPRECATED: use "
            "'--pop3 ssl:port:privateKey=pkey.pem:certKey=cert.pem'"
        ],
        [
            "relay", "R", None,
            "Relay messages according to their envelope 'To', using "
            "the given path as a queue directory."
        ],
        [
            "hostname", "H", None,
            "The hostname by which to identify this server."
        ],
    ]

    optFlags = [
        ["esmtp", "E", "Use RFC 1425/1869 SMTP extensions"],
        [
            "disable-anonymous", None,
            "Disallow non-authenticated SMTP connections"
        ],
        ["no-pop3", None, "Disable the default POP3 server."],
        ["no-smtp", None, "Disable the default SMTP server."],
    ]

    _protoDefaults = {
        "pop3": 8110,
        "smtp": 8025,
    }

    compData = usage.Completions(
        optActions={
            "hostname": usage.CompleteHostnames(),
            "certificate": usage.CompleteFiles("*.pem")
        })

    longdesc = "This creates a mail.tap file that can be used by twistd."

    def __init__(self):
        usage.Options.__init__(self)
        self.service = mail.MailService()
        self.last_domain = None
        for service in self._protoDefaults:
            self[service] = []

    def addEndpoint(self, service, description, certificate=None):
        """
        Given a 'service' (pop3 or smtp), add an endpoint.
        """
        self[service].append(_toEndpoint(description, certificate=certificate))

    def opt_pop3(self, description):
        """
        Add a pop3 port listener on the specified endpoint.  You can listen on
        multiple ports by specifying multiple --pop3 options.  For backwards
        compatibility, a bare TCP port number can be specified, but this is
        deprecated. [SSL Example: ssl:8995:privateKey=mycert.pem] [default:
        tcp:8110]
        """
        self.addEndpoint('pop3', description)

    opt_p = opt_pop3

    def opt_smtp(self, description):
        """
        Add an smtp port listener on the specified endpoint.  You can listen on
        multiple ports by specifying multiple --smtp options For backwards
        compatibility, a bare TCP port number can be specified, but this is
        deprecated.  [SSL Example: ssl:8465:privateKey=mycert.pem] [default:
        tcp:8025]
        """
        self.addEndpoint('smtp', description)

    opt_s = opt_smtp

    def opt_passwordfile(self, filename):
        """
        Specify a file containing username:password login info for authenticated
        ESMTP connections. (DEPRECATED; see --help-auth instead)
        """
        ch = checkers.OnDiskUsernamePasswordDatabase(filename)
        self.service.smtpPortal.registerChecker(ch)
        msg = deprecate.getDeprecationWarningString(
            self.opt_passwordfile, versions.Version('twisted.mail', 11, 0, 0))
        warnings.warn(msg, category=DeprecationWarning, stacklevel=2)

    opt_P = opt_passwordfile

    def opt_default(self):
        """Make the most recently specified domain the default domain."""
        if self.last_domain:
            self.service.addDomain('', self.last_domain)
        else:
            raise usage.UsageError(
                "Specify a domain before specifying using --default")

    opt_D = opt_default

    def opt_maildirdbmdomain(self, domain):
        """generate an SMTP/POP3 virtual domain which saves to \"path\"
        """
        try:
            name, path = domain.split('=')
        except ValueError:
            raise usage.UsageError(
                "Argument to --maildirdbmdomain must be of the form 'name=path'"
            )

        self.last_domain = maildir.MaildirDirdbmDomain(self.service,
                                                       os.path.abspath(path))
        self.service.addDomain(name, self.last_domain)

    opt_d = opt_maildirdbmdomain

    def opt_user(self, user_pass):
        """add a user/password to the last specified domains
        """
        try:
            user, password = user_pass.split('=', 1)
        except ValueError:
            raise usage.UsageError(
                "Argument to --user must be of the form 'user=password'")
        if self.last_domain:
            self.last_domain.addUser(user, password)
        else:
            raise usage.UsageError("Specify a domain before specifying users")

    opt_u = opt_user

    def opt_bounce_to_postmaster(self):
        """undelivered mails are sent to the postmaster
        """
        self.last_domain.postmaster = 1

    opt_b = opt_bounce_to_postmaster

    def opt_aliases(self, filename):
        """Specify an aliases(5) file to use for this domain"""
        if self.last_domain is not None:
            if mail.IAliasableDomain.providedBy(self.last_domain):
                aliases = alias.loadAliasFile(self.service.domains, filename)
                self.last_domain.setAliasGroup(aliases)
                self.service.monitor.monitorFile(
                    filename,
                    AliasUpdater(self.service.domains, self.last_domain))
            else:
                raise usage.UsageError("%s does not support alias files" %
                                       (self.last_domain.__class__.__name__, ))
        else:
            raise usage.UsageError(
                "Specify a domain before specifying aliases")

    opt_A = opt_aliases

    def _getEndpoints(self, reactor, service):
        """
        Return a list of endpoints for the specified service, constructing
        defaults if necessary.

        @param reactor: If any endpoints are created, this is the reactor with
            which they are created.

        @param service: A key into self indicating the type of service to
            retrieve endpoints for.  This is either C{"pop3"} or C{"smtp"}.

        @return: A C{list} of C{IServerStreamEndpoint} providers corresponding
            to the command line parameters that were specified for C{service}.
            If none were and the protocol was not explicitly disabled with a
            I{--no-*} option, a default endpoint for the service is created
            using C{self._protoDefaults}.
        """
        if service == 'pop3' and self['pop3s'] and len(self[service]) == 1:
            # The single endpoint here is the POP3S service we added in
            # postOptions.  Include the default endpoint alongside it.
            return self[service] + [
                endpoints.TCP4ServerEndpoint(reactor,
                                             self._protoDefaults[service])
            ]
        elif self[service]:
            # For any non-POP3S case, if there are any services set up, just
            # return those.
            return self[service]
        elif self['no-' + service]:
            # If there are no services, but the service was explicitly disabled,
            # return nothing.
            return []
        else:
            # Otherwise, return the old default service.
            return [
                endpoints.TCP4ServerEndpoint(reactor,
                                             self._protoDefaults[service])
            ]

    def postOptions(self):
        from twisted.internet import reactor

        if self['pop3s']:
            if not self['certificate']:
                raise usage.UsageError("Cannot specify --pop3s without "
                                       "--certificate")
            elif not os.path.exists(self['certificate']):
                raise usage.UsageError("Certificate file %r does not exist." %
                                       self['certificate'])
            else:
                self.addEndpoint('pop3',
                                 self['pop3s'],
                                 certificate=self['certificate'])

        if self['esmtp'] and self['hostname'] is None:
            raise usage.UsageError("--esmtp requires --hostname")

        # If the --auth option was passed, this will be present -- otherwise,
        # it won't be, which is also a perfectly valid state.
        if 'credCheckers' in self:
            for ch in self['credCheckers']:
                self.service.smtpPortal.registerChecker(ch)

        if not self['disable-anonymous']:
            self.service.smtpPortal.registerChecker(
                checkers.AllowAnonymousAccess())

        anything = False
        for service in self._protoDefaults:
            self[service] = self._getEndpoints(reactor, service)
            if self[service]:
                anything = True

        if not anything:
            raise usage.UsageError("You cannot disable all protocols")