Esempio n. 1
0
    def test_dirs(self):
        """
        CompleteDirs produces zsh shell-code that completes directory names.
        """
        c = usage.CompleteDirs()
        got = c._shellCode('some-option', usage._ZSH)
        self.assertEqual(got, ':some-option:_directories')

        c = usage.CompleteDirs(descr="some action", repeat=True)
        got = c._shellCode('some-option', usage._ZSH)
        self.assertEqual(got, '*:some action:_directories')
Esempio n. 2
0
class Options(usage.Options, strcred.AuthOptionMixin):
    synopsis = "[-i <interface>] [-p <port>] [-d <dir>] "
    longdesc = (
        "Makes a Conch SSH server.  If no authentication methods are "
        "specified, the default authentication methods are UNIX passwords, "
        "SSH public keys, and PAM if it is available.  If --auth options are "
        "passed, only the measures specified will be used.")
    optParameters = [
        ["interface", "i", "", "local interface to which we listen"],
        ["port", "p", "tcp:22", "Port on which to listen"],
        ["data", "d", "/etc", "directory to look for host keys in"],
        [
            "moduli", "", None, "directory to look for moduli in "
            "(if different from --data)"
        ]
    ]
    compData = usage.Completions(
        optActions={
            "data": usage.CompleteDirs(descr="data directory"),
            "moduli": usage.CompleteDirs(descr="moduli directory"),
            "interface": usage.CompleteNetInterfaces()
        })

    def __init__(self, *a, **kw):
        usage.Options.__init__(self, *a, **kw)

        # call the default addCheckers (for backwards compatibility) that will
        # be used if no --auth option is provided - note that conch's
        # UNIXPasswordDatabase is used, instead of twisted.plugins.cred_unix's
        # checker
        super(Options, self).addChecker(conch_checkers.UNIXPasswordDatabase())
        super(Options, self).addChecker(
            conch_checkers.SSHPublicKeyChecker(
                conch_checkers.UNIXAuthorizedKeysFiles()))
        if pamauth is not None:
            super(Options, self).addChecker(
                checkers.PluggableAuthenticationModulesChecker())
        self._usingDefaultAuth = True

    def addChecker(self, checker):
        """
        Add the checker specified.  If any checkers are added, the default
        checkers are automatically cleared and the only checkers will be the
        specified one(s).
        """
        if self._usingDefaultAuth:
            self['credCheckers'] = []
            self['credInterfaces'] = {}
            self._usingDefaultAuth = False
        super(Options, self).addChecker(checker)
Esempio n. 3
0
class Options(usage.Options, strcred.AuthOptionMixin):
    synopsis = """[options].
    WARNING: This FTP server is probably INSECURE do not use it.
    """
    optParameters = [
        ["port", "p", "2121", "set the port number"],
        ["root", "r", "/usr/local/ftp", "define the root of the ftp-site."],
        ["userAnonymous", "", "anonymous", "Name of the anonymous user."],
    ]

    compData = usage.Completions(
        optActions={"root": usage.CompleteDirs(descr="root of the ftp site")})

    longdesc = ""

    def __init__(self, *a, **kw):
        usage.Options.__init__(self, *a, **kw)
        self.addChecker(checkers.AllowAnonymousAccess())

    def opt_password_file(self, filename):
        """
        Specify a file containing username:password login info for
        authenticated connections. (DEPRECATED; see --help-auth instead)
        """
        self["password-file"] = filename
        msg = deprecate.getDeprecationWarningString(
            self.opt_password_file, versions.Version("Twisted", 11, 1, 0))
        warnings.warn(msg, category=DeprecationWarning, stacklevel=2)
        self.addChecker(checkers.FilePasswordDB(filename, cache=True))
Esempio n. 4
0
class BasedirMixin:

    """SubcommandOptions Mixin to handle subcommands that take a basedir
    argument"""

    # on tab completion, suggest directories as first argument
    if hasattr(usage, 'Completions'):
        # only set completion suggestion if running with
        # twisted version (>=11.1.0) that supports it
        compData = usage.Completions(
            extraActions=[usage.CompleteDirs(descr="buildbot base directory")])

    def parseArgs(self, *args):
        if args:
            self['basedir'] = args[0]
        else:
            # Use the current directory if no basedir was specified.
            self['basedir'] = os.getcwd()
        if len(args) > 1:
            raise usage.UsageError("I wasn't expecting so many arguments")

    def postOptions(self):
        # get an unambiguous, expanded basedir, including expanding '~', which
        # may be useful in a .buildbot/config file
        self['basedir'] = os.path.abspath(os.path.expanduser(self['basedir']))
Esempio n. 5
0
class MakerBase(usage.Options):
    optFlags = [
        ['help', 'h', "Display this message"],
        ["quiet", "q", "Do not emit the commands being run"],
    ]

    longdesc = textwrap.dedent("""
    Operates upon the specified <basedir> (or the current directory, if not
    specified).
    """)

    # on tab completion, suggest directories as first argument
    if hasattr(usage, 'Completions'):
        # only set completion suggestion if running with
        # twisted version (>=11.1.0) that supports it
        compData = usage.Completions(
            extraActions=[usage.CompleteDirs(descr="worker base directory")])

    opt_h = usage.Options.opt_help

    def parseArgs(self, *args):
        if args:
            self['basedir'] = args[0]
        else:
            # Use the current directory if no basedir was specified.
            self['basedir'] = os.getcwd()
        if len(args) > 1:
            raise usage.UsageError("I wasn't expecting so many arguments")

    def postOptions(self):
        self['basedir'] = os.path.abspath(self['basedir'])
Esempio n. 6
0
class ServerOptions(app.ServerOptions):
    synopsis = "Usage: twistd [options]"

    optFlags = [
        ["nodaemon", "n", "don't daemonize, don't use default umask of 0077"],
        ["originalname", None, "Don't try to change the process name"],
        ["syslog", None, "Log to syslog, not to file"],
        [
            "euid",
            "",
            "Set only effective user-id rather than real user-id. "
            "(This option has no effect unless the server is running as "
            "root, in which case it means not to shed all privileges "
            "after binding ports, retaining the option to regain "
            "privileges in cases such as spawning processes. "
            "Use with caution.)",
        ],
    ]

    optParameters = [
        ["prefix", None, "twisted", "use the given prefix when syslogging"],
        ["pidfile", "", "twistd.pid", "Name of the pidfile"],
        ["chroot", None, None, "Chroot to a supplied directory before running"],
        ["uid", "u", None, "The uid to run as.", uidFromString],
        [
            "gid",
            "g",
            None,
            "The gid to run as.  If not specified, the default gid "
            "associated with the specified --uid is used.",
            gidFromString,
        ],
        ["umask", None, None, "The (octal) file creation mask to apply.", _umask],
    ]

    compData = usage.Completions(
        optActions={
            "pidfile": usage.CompleteFiles("*.pid"),
            "chroot": usage.CompleteDirs(descr="chroot directory"),
            "gid": usage.CompleteGroups(descr="gid to run as"),
            "uid": usage.CompleteUsernames(descr="uid to run as"),
            "prefix": usage.Completer(descr="syslog prefix"),
        },
    )

    def opt_version(self):
        """
        Print version information and exit.
        """
        print(
            "twistd (the Twisted daemon) {}".format(copyright.version), file=self.stdout
        )
        print(copyright.copyright, file=self.stdout)
        sys.exit()

    def postOptions(self):
        app.ServerOptions.postOptions(self)
        if self["pidfile"]:
            self["pidfile"] = os.path.abspath(self["pidfile"])
Esempio n. 7
0
class Options(usage.Options):
    synopsis = "[-i <interface>] [-p <port>] [-d <dir>] "
    longdesc = "Makes a Conch SSH server."
    optParameters = [
        ["interface", "i", "", "local interface to which we listen"],
        ["port", "p", "tcp:22", "Port on which to listen"],
        ["data", "d", "/etc", "directory to look for host keys in"],
        [
            "moduli", "", None, "directory to look for moduli in "
            "(if different from --data)"
        ]
    ]
    compData = usage.Completions(
        optActions={
            "data": usage.CompleteDirs(descr="data directory"),
            "moduli": usage.CompleteDirs(descr="moduli directory"),
            "interface": usage.CompleteNetInterfaces()
        })
Esempio n. 8
0
class ServerOptions(app.ServerOptions):
    synopsis = "Usage: twistd [options]"

    optFlags = [
        ['nodaemon', 'n', "don't daemonize, don't use default umask of 0077"],
        ['originalname', None, "Don't try to change the process name"],
        ['syslog', None, "Log to syslog, not to file"],
        [
            'euid', '', "Set only effective user-id rather than real user-id. "
            "(This option has no effect unless the server is running as "
            "root, in which case it means not to shed all privileges "
            "after binding ports, retaining the option to regain "
            "privileges in cases such as spawning processes. "
            "Use with caution.)"
        ],
    ]

    optParameters = [
        ['prefix', None, 'twisted', "use the given prefix when syslogging"],
        ['pidfile', '', 'twistd.pid', "Name of the pidfile"],
        [
            'chroot', None, None,
            'Chroot to a supplied directory before running'
        ],
        ['uid', 'u', None, "The uid to run as.", uidFromString],
        ['gid', 'g', None, "The gid to run as.", gidFromString],
        [
            'umask', None, None, "The (octal) file creation mask to apply.",
            _umask
        ],
    ]

    compData = usage.Completions(optActions={
        "pidfile":
        usage.CompleteFiles("*.pid"),
        "chroot":
        usage.CompleteDirs(descr="chroot directory"),
        "gid":
        usage.CompleteGroups(descr="gid to run as"),
        "uid":
        usage.CompleteUsernames(descr="uid to run as"),
        "prefix":
        usage.Completer(descr="syslog prefix"),
    }, )

    def opt_version(self):
        """Print version information and exit.
        """
        print 'twistd (the Twisted daemon) %s' % copyright.version
        print copyright.copyright
        sys.exit()

    def postOptions(self):
        app.ServerOptions.postOptions(self)
        if self['pidfile']:
            self['pidfile'] = os.path.abspath(self['pidfile'])
Esempio n. 9
0
class Options(usage.Options, strcred.AuthOptionMixin):
    synopsis = "[options]"
    longdesc = (
        "Makes an EssFTP essftp.  If --root is not passed as a "
        "parameter, uses the current working directory.  If no auth service "
        "is specified, it will allow anyone in.")
    optParameters = [["root", "r", './', "Root directory, as seen by clients"],
                     ["port", "p", "8888", "Port on which to listen"],
                     [
                         "keyDirectory", "k", None,
                         "Directory to look for host keys in.  "
                         "If this is not provided, fake keys will be used."
                     ],
                     [
                         "moduli", "", None, "Directory to look for moduli in "
                         "(if different from --keyDirectory)"
                     ]]
    compData = usage.Completions(
        optActions={
            "root": usage.CompleteDirs(descr="root directory"),
            "keyDirectory": usage.CompleteDirs(descr="key directory"),
            "moduli": usage.CompleteDirs(descr="moduli directory")
        })
Esempio n. 10
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. 11
0
class ServerOptions(usage.Options, ReactorSelectionMixin):

    longdesc = ("twistd reads a twisted.application.service.Application out "
                "of a file and runs it.")

    optFlags = [[
        'savestats', None,
        "save the Stats object rather than the text output of "
        "the profiler."
    ], ['no_save', 'o', "do not save state on shutdown"],
                ['encrypted', 'e', "The specified tap/aos file is encrypted."]]

    optParameters = [
        ['logfile', 'l', None, "log to a specified file, - for stdout"],
        [
            'logger', None, None,
            "A fully-qualified name to a log observer factory to use "
            "for the initial log observer.  Takes precedence over "
            "--logfile and --syslog (when available)."
        ],
        [
            'profile', 'p', None,
            "Run in profile mode, dumping results to specified file"
        ],
        [
            'profiler', None, "hotshot",
            "Name of the profiler to use (%s)." %
            ", ".join(AppProfiler.profilers)
        ], ['file', 'f', 'twistd.tap', "read the given .tap file"],
        [
            'python', 'y', None,
            "read an application from within a Python file "
            "(implies -o)"
        ],
        [
            'source', 's', None,
            "Read an application from a .tas file (AOT format)."
        ],
        ['rundir', 'd', '.', 'Change to a supplied directory before running']
    ]

    compData = usage.Completions(mutuallyExclusive=[("file", "python",
                                                     "source")],
                                 optActions={
                                     "file": usage.CompleteFiles("*.tap"),
                                     "python":
                                     usage.CompleteFiles("*.(tac|py)"),
                                     "source": usage.CompleteFiles("*.tas"),
                                     "rundir": usage.CompleteDirs()
                                 })

    _getPlugins = staticmethod(plugin.getPlugins)

    def __init__(self, *a, **kw):
        self['debug'] = False
        usage.Options.__init__(self, *a, **kw)

    def opt_debug(self):
        """
        Run the application in the Python Debugger (implies nodaemon),
        sending SIGUSR2 will drop into debugger
        """
        defer.setDebugging(True)
        failure.startDebugMode()
        self['debug'] = True

    opt_b = opt_debug

    def opt_spew(self):
        """
        Print an insanely verbose log of everything that happens.
        Useful when debugging freezes or locks in complex code."""
        sys.settrace(util.spewer)
        try:
            import threading
        except ImportError:
            return
        threading.settrace(util.spewer)

    def parseOptions(self, options=None):
        if options is None:
            options = sys.argv[1:] or ["--help"]
        usage.Options.parseOptions(self, options)

    def postOptions(self):
        if self.subCommand or self['python']:
            self['no_save'] = True
        if self['logger'] is not None:
            try:
                self['logger'] = namedAny(self['logger'])
            except Exception as e:
                raise usage.UsageError(
                    "Logger '%s' could not be imported: %s" %
                    (self['logger'], e))

    def subCommands(self):
        plugins = self._getPlugins(service.IServiceMaker)
        self.loadedPlugins = {}
        for plug in sorted(plugins, key=attrgetter('tapname')):
            self.loadedPlugins[plug.tapname] = plug
            yield (
                plug.tapname,
                None,
                # Avoid resolving the options attribute right away, in case
                # it's a property with a non-trivial getter (eg, one which
                # imports modules).
                lambda plug=plug: plug.options(),
                plug.description)

    subCommands = property(subCommands)