Ejemplo n.º 1
0
 def test_warnOpenFailed(self):
     """
     L{ConsoleUI.warn} should log a traceback if the output can't be opened.
     """
     def raiseIt():
         1 / 0
     ui = ConsoleUI(raiseIt)
     ui.warn("This message never makes it.")
     self.assertEqual(len(self.flushLoggedErrors(ZeroDivisionError)), 1)
Ejemplo n.º 2
0
 def test_promptOpenFailed(self):
     """
     If the C{opener} passed to L{ConsoleUI} raises an exception, that
     exception will fail the L{Deferred} returned from L{ConsoleUI.prompt}.
     """
     def raiseIt():
         raise IOError()
     ui = ConsoleUI(raiseIt)
     d = ui.prompt("This is a test.")
     return self.assertFailure(d, IOError)
Ejemplo n.º 3
0
 def test_promptOpenFailed(self):
     """
     If the C{opener} passed to L{ConsoleUI} raises an exception, that
     exception will fail the L{Deferred} returned from L{ConsoleUI.prompt}.
     """
     def raiseIt():
         raise IOError()
     ui = ConsoleUI(raiseIt)
     l = []
     ui.prompt("This is a test.").addErrback(l.append)
     l[0].trap(IOError)
Ejemplo n.º 4
0
    def test_promptOpenFailed(self):
        """
        If the C{opener} passed to L{ConsoleUI} raises an exception, that
        exception will fail the L{Deferred} returned from L{ConsoleUI.prompt}.
        """
        def raiseIt():
            raise IOError()

        ui = ConsoleUI(raiseIt)
        l = []
        ui.prompt("This is a test.").addErrback(l.append)
        l[0].trap(IOError)
Ejemplo n.º 5
0
    def __init__(self,
                 reactor,
                 hostname,
                 port,
                 username,
                 keys,
                 password,
                 agentEndpoint,
                 knownHosts,
                 ui,
                 tty=FilePath(b"/dev/tty")):
        """
        @param tty: The path of the tty device to use in case C{ui} is L{None}.
        @type tty: L{FilePath}

        @see: L{SSHCommandClientEndpoint.newConnection}
        """
        self.reactor = reactor
        self.hostname = hostname
        if port is not None:
            self.port = port
        self.username = username
        self.keys = keys
        self.password = password
        self.agentEndpoint = agentEndpoint
        if knownHosts is None:
            knownHosts = self._knownHosts()
        self.knownHosts = knownHosts

        if ui is None:
            ui = ConsoleUI(self._opener)
        self.ui = ui
        self.tty = tty
Ejemplo n.º 6
0
    def fromCommandLine(cls, reactor, argv):
        config = EchoOptions()
        config.parseOptions(argv)

        ui = ConsoleUI(lambda: open("/dev/tty", "r+"))

        keys = []
        if config["identity"]:
            keyPath = os.path.expanduser(config["identity"])
            if os.path.exists(keyPath):
                keys.append(readKey(keyPath))

        knownHostsPath = FilePath(os.path.expanduser(config["knownhosts"]))
        if knownHostsPath.exists():
            knownHosts = KnownHostsFile.fromPath(knownHostsPath)
        else:
            knownHosts = None

        if config["no-agent"] or "SSH_AUTH_SOCK" not in os.environ:
            agentEndpoint = None
        else:
            agentEndpoint = UNIXClientEndpoint(reactor,
                                               os.environ["SSH_AUTH_SOCK"])

        return cls(reactor, ui, config["host"], config["port"],
                   config["username"], config["password"], keys, knownHosts,
                   agentEndpoint)
Ejemplo n.º 7
0
def verifyHostKey(transport, host, pubKey, fingerprint):
    """
    Verify a host's key.

    This function is a gross vestige of some bad factoring in the client
    internals.  The actual implementation, and a better signature of this logic
    is in L{KnownHostsFile.verifyHostKey}.  This function is not deprecated yet
    because the callers have not yet been rehabilitated, but they should
    eventually be changed to call that method instead.

    However, this function does perform two functions not implemented by
    L{KnownHostsFile.verifyHostKey}.  It determines the path to the user's
    known_hosts file based on the options (which should really be the options
    object's job), and it provides an opener to L{ConsoleUI} which opens
    '/dev/tty' so that the user will be prompted on the tty of the process even
    if the input and output of the process has been redirected.  This latter
    part is, somewhat obviously, not portable, but I don't know of a portable
    equivalent that could be used.

    @param host: Due to a bug in L{SSHClientTransport.verifyHostKey}, this is
    always the dotted-quad IP address of the host being connected to.
    @type host: L{str}

    @param transport: the client transport which is attempting to connect to
    the given host.
    @type transport: L{SSHClientTransport}

    @param fingerprint: the fingerprint of the given public key, in
    xx:xx:xx:... format.  This is ignored in favor of getting the fingerprint
    from the key itself.
    @type fingerprint: L{str}

    @param pubKey: The public key of the server being connected to.
    @type pubKey: L{str}

    @return: a L{Deferred} which fires with C{1} if the key was successfully
    verified, or fails if the key could not be successfully verified.  Failure
    types may include L{HostKeyChanged}, L{UserRejectedKey}, L{IOError} or
    L{KeyboardInterrupt}.
    """
    actualHost = transport.factory.options['host']
    actualKey = keys.Key.fromString(pubKey)
    kh = KnownHostsFile.fromPath(FilePath(
            transport.factory.options['known-hosts']
            or os.path.expanduser(_KNOWN_HOSTS)
            ))
    ui = ConsoleUI(lambda : _open("/dev/tty", "r+b", buffering=0))
    return kh.verifyHostKey(ui, actualHost, host, actualKey)
Ejemplo n.º 8
0
 def setUp(self):
     """
     Create a L{ConsoleUI} pointed at a L{FakeFile}.
     """
     self.fakeFile = FakeFile()
     self.ui = ConsoleUI(self.openFile)
Ejemplo n.º 9
0
class ConsoleUITests(TestCase):
    """
    Test cases for L{ConsoleUI}.
    """
    def setUp(self):
        """
        Create a L{ConsoleUI} pointed at a L{FakeFile}.
        """
        self.fakeFile = FakeFile()
        self.ui = ConsoleUI(self.openFile)

    def openFile(self):
        """
        Return the current fake file.
        """
        return self.fakeFile

    def newFile(self, lines):
        """
        Create a new fake file (the next file that self.ui will open) with the
        given list of lines to be returned from readline().
        """
        self.fakeFile = FakeFile()
        self.fakeFile.inlines = lines

    def test_promptYes(self):
        """
        L{ConsoleUI.prompt} writes a message to the console, then reads a line.
        If that line is 'yes', then it returns a L{Deferred} that fires with
        True.
        """
        for okYes in ['yes', 'Yes', 'yes\n']:
            self.newFile([okYes])
            l = []
            self.ui.prompt("Hello, world!").addCallback(l.append)
            self.assertEqual(["Hello, world!"], self.fakeFile.outchunks)
            self.assertEqual([True], l)
            self.assertEqual(True, self.fakeFile.closed)

    def test_promptNo(self):
        """
        L{ConsoleUI.prompt} writes a message to the console, then reads a line.
        If that line is 'no', then it returns a L{Deferred} that fires with
        False.
        """
        for okNo in ['no', 'No', 'no\n']:
            self.newFile([okNo])
            l = []
            self.ui.prompt("Goodbye, world!").addCallback(l.append)
            self.assertEqual(["Goodbye, world!"], self.fakeFile.outchunks)
            self.assertEqual([False], l)
            self.assertEqual(True, self.fakeFile.closed)

    def test_promptRepeatedly(self):
        """
        L{ConsoleUI.prompt} writes a message to the console, then reads a line.
        If that line is neither 'yes' nor 'no', then it says "Please enter
        'yes' or 'no'" until it gets a 'yes' or a 'no', at which point it
        returns a Deferred that answers either True or False.
        """
        self.newFile(['what', 'uh', 'okay', 'yes'])
        l = []
        self.ui.prompt("Please say something useful.").addCallback(l.append)
        self.assertEqual([True], l)
        self.assertEqual(self.fakeFile.outchunks,
                         ["Please say something useful."] +
                         ["Please type 'yes' or 'no': "] * 3)
        self.assertEqual(True, self.fakeFile.closed)
        self.newFile(['blah', 'stuff', 'feh', 'no'])
        l = []
        self.ui.prompt("Please say something negative.").addCallback(l.append)
        self.assertEqual([False], l)
        self.assertEqual(self.fakeFile.outchunks,
                         ["Please say something negative."] +
                         ["Please type 'yes' or 'no': "] * 3)
        self.assertEqual(True, self.fakeFile.closed)

    def test_promptOpenFailed(self):
        """
        If the C{opener} passed to L{ConsoleUI} raises an exception, that
        exception will fail the L{Deferred} returned from L{ConsoleUI.prompt}.
        """
        def raiseIt():
            raise IOError()

        ui = ConsoleUI(raiseIt)
        d = ui.prompt("This is a test.")
        return self.assertFailure(d, IOError)

    def test_warn(self):
        """
        L{ConsoleUI.warn} should output a message to the console object.
        """
        self.ui.warn("Test message.")
        self.assertEqual(["Test message."], self.fakeFile.outchunks)
        self.assertEqual(True, self.fakeFile.closed)

    def test_warnOpenFailed(self):
        """
        L{ConsoleUI.warn} should log a traceback if the output can't be opened.
        """
        def raiseIt():
            1 / 0

        ui = ConsoleUI(raiseIt)
        ui.warn("This message never makes it.")
        self.assertEqual(len(self.flushLoggedErrors(ZeroDivisionError)), 1)
Ejemplo n.º 10
0
 def setUp(self):
     """
     Create a L{ConsoleUI} pointed at a L{FakeFile}.
     """
     self.fakeFile = FakeFile()
     self.ui = ConsoleUI(self.openFile)
Ejemplo n.º 11
0
class ConsoleUITests(TestCase):
    """
    Test cases for L{ConsoleUI}.
    """

    def setUp(self):
        """
        Create a L{ConsoleUI} pointed at a L{FakeFile}.
        """
        self.fakeFile = FakeFile()
        self.ui = ConsoleUI(self.openFile)


    def openFile(self):
        """
        Return the current fake file.
        """
        return self.fakeFile


    def newFile(self, lines):
        """
        Create a new fake file (the next file that self.ui will open) with the
        given list of lines to be returned from readline().
        """
        self.fakeFile = FakeFile()
        self.fakeFile.inlines = lines


    def test_promptYes(self):
        """
        L{ConsoleUI.prompt} writes a message to the console, then reads a line.
        If that line is 'yes', then it returns a L{Deferred} that fires with
        True.
        """
        for okYes in ['yes', 'Yes', 'yes\n']:
            self.newFile([okYes])
            l = []
            self.ui.prompt("Hello, world!").addCallback(l.append)
            self.assertEqual(["Hello, world!"], self.fakeFile.outchunks)
            self.assertEqual([True], l)
            self.assertEqual(True, self.fakeFile.closed)


    def test_promptNo(self):
        """
        L{ConsoleUI.prompt} writes a message to the console, then reads a line.
        If that line is 'no', then it returns a L{Deferred} that fires with
        False.
        """
        for okNo in ['no', 'No', 'no\n']:
            self.newFile([okNo])
            l = []
            self.ui.prompt("Goodbye, world!").addCallback(l.append)
            self.assertEqual(["Goodbye, world!"], self.fakeFile.outchunks)
            self.assertEqual([False], l)
            self.assertEqual(True, self.fakeFile.closed)


    def test_promptRepeatedly(self):
        """
        L{ConsoleUI.prompt} writes a message to the console, then reads a line.
        If that line is neither 'yes' nor 'no', then it says "Please enter
        'yes' or 'no'" until it gets a 'yes' or a 'no', at which point it
        returns a Deferred that answers either True or False.
        """
        self.newFile(['what', 'uh', 'okay', 'yes'])
        l = []
        self.ui.prompt("Please say something useful.").addCallback(l.append)
        self.assertEqual([True], l)
        self.assertEqual(self.fakeFile.outchunks,
                         ["Please say something useful."] +
                         ["Please type 'yes' or 'no': "] * 3)
        self.assertEqual(True, self.fakeFile.closed)
        self.newFile(['blah', 'stuff', 'feh', 'no'])
        l = []
        self.ui.prompt("Please say something negative.").addCallback(l.append)
        self.assertEqual([False], l)
        self.assertEqual(self.fakeFile.outchunks,
                         ["Please say something negative."] +
                         ["Please type 'yes' or 'no': "] * 3)
        self.assertEqual(True, self.fakeFile.closed)


    def test_promptOpenFailed(self):
        """
        If the C{opener} passed to L{ConsoleUI} raises an exception, that
        exception will fail the L{Deferred} returned from L{ConsoleUI.prompt}.
        """
        def raiseIt():
            raise IOError()
        ui = ConsoleUI(raiseIt)
        d = ui.prompt("This is a test.")
        return self.assertFailure(d, IOError)


    def test_warn(self):
        """
        L{ConsoleUI.warn} should output a message to the console object.
        """
        self.ui.warn("Test message.")
        self.assertEqual(["Test message."], self.fakeFile.outchunks)
        self.assertEqual(True, self.fakeFile.closed)


    def test_warnOpenFailed(self):
        """
        L{ConsoleUI.warn} should log a traceback if the output can't be opened.
        """
        def raiseIt():
            1 / 0
        ui = ConsoleUI(raiseIt)
        ui.warn("This message never makes it.")
        self.assertEqual(len(self.flushLoggedErrors(ZeroDivisionError)), 1)
Ejemplo n.º 12
0
 def __init__(self, hostname, port):
     self.hostname = hostname
     self.port = port
     self.ui = ConsoleUI(lambda: open("/dev/tty", "r+b"))