예제 #1
0
 def test_manual(self):
     """
     Calling L{appdirs.getDataDirectory} with a C{moduleName} argument will
     make a data directory with that name instead.
     """
     res = _appdirs.getDataDirectory("foo.bar.baz")
     self.assertTrue(res.endswith("foo.bar.baz"))
예제 #2
0
 def test_manual(self):
     """
     Calling L{appdirs.getDataDirectory} with a C{moduleName} argument will
     make a data directory with that name instead.
     """
     res = _appdirs.getDataDirectory("foo.bar.baz")
     self.assertTrue(res.endswith("foo.bar.baz"))
예제 #3
0
 def test_moduleName(self):
     """
     Calling L{appdirs.getDataDirectory} will return a user data directory
     in the system convention, with the module of the caller as the
     subdirectory.
     """
     res = _appdirs.getDataDirectory()
     self.assertTrue(res.endswith("twisted.python.test.test_appdirs"))
예제 #4
0
 def test_moduleName(self):
     """
     Calling L{appdirs.getDataDirectory} will return a user data directory
     in the system convention, with the module of the caller as the
     subdirectory.
     """
     res = _appdirs.getDataDirectory()
     self.assertTrue(res.endswith("twisted.python.test.test_appdirs"))
예제 #5
0
def conch_helper(endpoint,
                 proto=None,
                 namespace=dict(),
                 keyDir=None,
                 keySize=4096):
    """
    Return a L{SSHKeyDirectory} based SSH service with the given parameters.

    Authorized keys are read as per L{SSHKeyDirectory} with ``baseDir`` being
    ``keyDir/users``.

    @param endpoint: endpoint for the SSH service
    @param namespace: the manhole namespace
    @param keyDir: directory that holds server/server.key file and
        users directory, which is used as ``baseDir`` in L{SSHKeyDirectory}
    @see: L{SSHKeyDirectory}
    """
    if keyDir is None:
        from twisted.python._appdirs import getDataDirectory

        keyDir = getDataDirectory()

    keyDir = filepath.FilePath(keyDir)
    keyDir.child("server").makedirs(True)
    keyDir.child("users").makedirs(True)

    checker = SSHPublicKeyChecker(SSHKeyDirectory(keyDir.child("users")))

    if proto is None:
        sshRealm = manhole_ssh.TerminalRealm()
        sshRealm.chainedProtocolFactory = chainedProtocolFactory(namespace)
    else:
        sshRealm = SSHSimpleRealm(proto)
    sshPortal = portal.Portal(sshRealm, [checker])

    sshKeyPath = keyDir.child("server").child("server.key")
    sshKey = keys._getPersistentRSAKey(sshKeyPath, keySize)

    sshFactory = manhole_ssh.ConchFactory(sshPortal)
    sshFactory.publicKeys[b"ssh-rsa"] = sshKey
    sshFactory.privateKeys[b"ssh-rsa"] = sshKey

    sshService = strports.service(endpoint, sshFactory)
    return sshService
예제 #6
0
def makeService(options):
    """
    Create a manhole server service.

    @type options: C{dict}
    @param options: A mapping describing the configuration of
    the desired service.  Recognized key/value pairs are::

        "telnetPort": strports description of the address on which
                      to listen for telnet connections.  If None,
                      no telnet service will be started.

        "sshPort": strports description of the address on which to
                   listen for ssh connections.  If None, no ssh
                   service will be started.

        "namespace": dictionary containing desired initial locals
                     for manhole connections.  If None, an empty
                     dictionary will be used.

        "passwd": Name of a passwd(5)-format username/password file.

        "sshKeyDir": The folder that the SSH server key will be kept in.

        "sshKeyName": The filename of the key.

        "sshKeySize": The size of the key, in bits. Default is 4096.

    @rtype: L{twisted.application.service.IService}
    @return: A manhole service.
    """
    svc = service.MultiService()

    namespace = options['namespace']
    if namespace is None:
        namespace = {}

    checker = checkers.FilePasswordDB(options['passwd'])

    if options['telnetPort']:
        telnetRealm = _StupidRealm(telnet.TelnetBootstrapProtocol,
                                   insults.ServerProtocol,
                                   manhole.ColoredManhole, namespace)

        telnetPortal = portal.Portal(telnetRealm, [checker])

        telnetFactory = protocol.ServerFactory()
        telnetFactory.protocol = makeTelnetProtocol(telnetPortal)
        telnetService = strports.service(options['telnetPort'], telnetFactory)
        telnetService.setServiceParent(svc)

    if options['sshPort']:
        sshRealm = manhole_ssh.TerminalRealm()
        sshRealm.chainedProtocolFactory = chainedProtocolFactory(namespace)

        sshPortal = portal.Portal(sshRealm, [checker])
        sshFactory = manhole_ssh.ConchFactory(sshPortal)

        if options['sshKeyDir'] != "<USER DATA DIR>":
            keyDir = options['sshKeyDir']
        else:
            from twisted.python._appdirs import getDataDirectory
            keyDir = getDataDirectory()

        keyLocation = filepath.FilePath(keyDir).child(options['sshKeyName'])

        sshKey = keys._getPersistentRSAKey(keyLocation,
                                           int(options['sshKeySize']))
        sshFactory.publicKeys["ssh-rsa"] = sshKey
        sshFactory.privateKeys["ssh-rsa"] = sshKey

        sshService = strports.service(options['sshPort'], sshFactory)
        sshService.setServiceParent(svc)

    return svc
예제 #7
0
def makeService(options):
    """
    Create a manhole server service.

    @type options: C{dict}
    @param options: A mapping describing the configuration of
    the desired service.  Recognized key/value pairs are::

        "telnetPort": strports description of the address on which
                      to listen for telnet connections.  If None,
                      no telnet service will be started.

        "sshPort": strports description of the address on which to
                   listen for ssh connections.  If None, no ssh
                   service will be started.

        "namespace": dictionary containing desired initial locals
                     for manhole connections.  If None, an empty
                     dictionary will be used.

        "passwd": Name of a passwd(5)-format username/password file.

        "sshKeyDir": The folder that the SSH server key will be kept in.

        "sshKeyName": The filename of the key.

        "sshKeySize": The size of the key, in bits. Default is 4096.

    @rtype: L{twisted.application.service.IService}
    @return: A manhole service.
    """
    svc = service.MultiService()

    namespace = options['namespace']
    if namespace is None:
        namespace = {}

    checker = checkers.FilePasswordDB(options['passwd'])

    if options['telnetPort']:
        telnetRealm = _StupidRealm(telnet.TelnetBootstrapProtocol,
                                   insults.ServerProtocol,
                                   manhole.ColoredManhole,
                                   namespace)

        telnetPortal = portal.Portal(telnetRealm, [checker])

        telnetFactory = protocol.ServerFactory()
        telnetFactory.protocol = makeTelnetProtocol(telnetPortal)
        telnetService = strports.service(options['telnetPort'],
                                         telnetFactory)
        telnetService.setServiceParent(svc)

    if options['sshPort']:
        sshRealm = manhole_ssh.TerminalRealm()
        sshRealm.chainedProtocolFactory = chainedProtocolFactory(namespace)

        sshPortal = portal.Portal(sshRealm, [checker])
        sshFactory = manhole_ssh.ConchFactory(sshPortal)

        if options['sshKeyDir'] != "<USER DATA DIR>":
            keyDir = options['sshKeyDir']
        else:
            from twisted.python._appdirs import getDataDirectory
            keyDir = getDataDirectory()

        keyLocation = filepath.FilePath(keyDir).child(options['sshKeyName'])

        sshKey = keys._getPersistentRSAKey(keyLocation,
                                           int(options['sshKeySize']))
        sshFactory.publicKeys["ssh-rsa"] = sshKey
        sshFactory.privateKeys["ssh-rsa"] = sshKey

        sshService = strports.service(options['sshPort'], sshFactory)
        sshService.setServiceParent(svc)

    return svc
예제 #8
0
def getManholeFactory(namespace, user, secret, keydir=None):
    """
    Get an administrative manhole into the application.

    :param namespace: the namespace to show in the manhole
    :type namespace: dict
    :param user: the user to authenticate into the administrative shell.
    :type user: str
    :param secret: pass for this manhole
    :type secret: str
    """
    import string

    from twisted.cred import portal
    from twisted.conch import manhole, manhole_ssh
    from twisted.conch import recvline
    from twisted.conch.insults import insults
    from twisted.conch.ssh import keys
    from twisted.cred.checkers import (InMemoryUsernamePasswordDatabaseDontUse
                                       as MemoryDB)
    from twisted.python import filepath

    try:
        from IPython.core.completer import Completer
    except ImportError:
        from rlcompleter import Completer

    class EnhancedColoredManhole(manhole.ColoredManhole):
        """
        A nicer Manhole with some autocomplete support.

        See the patch in https://twistedmatrix.com/trac/ticket/6863
        Since you're reading this, it'd be good if *you* can help getting that
        patch into twisted :)
        """

        completion = True

        def handle_TAB(self):
            """
            If tab completion is available and enabled then perform some tab
            completion.
            """
            if not self.completion:
                recvline.HistoricRecvLine.handle_TAB(self)
                return
            # If we only have whitespace characters on this line we pass
            # through the tab
            if set(self.lineBuffer).issubset(string.whitespace):
                recvline.HistoricRecvLine.handle_TAB(self)
                return
            cp = Completer(namespace=self.namespace)
            cp.limit_to__all__ = False
            lineLeft, lineRight = self.currentLineBuffer()

            # Extract all the matches
            matches = []
            n = 0
            while True:
                match = cp.complete(lineLeft, n)
                if match is None:
                    break
                n += 1
                matches.append(match)

            if not matches:
                return

            if len(matches) == 1:
                # Found the match so replace the line. This is apparently how
                # we replace a line
                self.handle_HOME()
                self.terminal.eraseToLineEnd()

                self.lineBuffer = []
                self._deliverBuffer(matches[0] + lineRight)
            else:
                # Must have more than one match, display them
                matches.sort()
                self.terminal.write("\n")
                self.terminal.write("   ".join(matches))
                self.terminal.write("\n\n")
                self.drawInputLine()

        def keystrokeReceived(self, keyID, modifier):
            """
            Act upon any keystroke received.
            """
            self.keyHandlers.update({'\b': self.handle_BACKSPACE})
            m = self.keyHandlers.get(keyID)
            if m is not None:
                m()
            elif keyID in string.printable:
                self.characterReceived(keyID, False)

    class chainedProtocolFactory:
        def __init__(self, namespace):
            self.namespace = namespace

        def __call__(self):
            return insults.ServerProtocol(EnhancedColoredManhole,
                                          self.namespace)

    sshRealm = manhole_ssh.TerminalRealm()
    sshRealm.chainedProtocolFactory = chainedProtocolFactory(namespace)

    checker = MemoryDB(**{user: secret})
    sshPortal = portal.Portal(sshRealm, [checker])
    sshFactory = manhole_ssh.ConchFactory(sshPortal)

    if not keydir:
        from twisted.python._appdirs import getDataDirectory
        keydir = getDataDirectory()

    keyLocation = filepath.FilePath(keydir).child('id_rsa')
    sshKey = keys._getPersistentRSAKey(keyLocation, 4096)
    sshFactory.publicKeys[b"ssh-rsa"] = sshKey
    sshFactory.privateKeys[b"ssh-rsa"] = sshKey
    return sshFactory