Пример #1
0
    def create_command_channel(self, cmd):
        """
        Create an SSH channel over the existing connection and issue a command.
        `cmd` should already be encoded as a byte string.
        Return the `CommandProtocol` instance.
        """
        log = self.log
        if not self.connected_to_target:
            raise Exception(
                "Tried to open channel, but was not connected to the target host."
            )
        ssh_conn = self.ssh_conn
        endpoint = SSHCommandClientEndpoint.existingConnection(ssh_conn, cmd)
        proto = CommandProtocol()
        proto.log = self.log
        d = connectProtocol(endpoint, proto)

        def _on_timeout(result, timeout):
            self.disconnect_from_target()
            raise Exception(
                "Timed out while attempting to establish command channel.")

        d.addTimeout(self.cmd_timeout,
                     self.reactor,
                     onTimeoutCancel=_on_timeout)
        log.debug("Establishing channel ...")
        proto = yield d
        log.debug("Channel established.")
        returnValue(proto)
Пример #2
0
    def test_publicKeyAuthenticationFailure(self):
        """
        If the SSH server rejects the key pair presented during authentication,
        the L{Deferred} returned by L{SSHCommandClientEndpoint.connect} fires
        with a L{Failure} wrapping L{AuthenticationFailed}.
        """
        badKey = Key.fromString(privateRSA_openssh)
        self.setupKeyChecker(self.portal, {self.user: privateDSA_openssh})

        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor, b"/bin/ls -l", self.user,
            self.hostname, self.port, keys=[badKey],
            knownHosts=self.knownHosts, ui=FixedResponseUI(False))

        factory = Factory()
        factory.protocol = Protocol
        connected = endpoint.connect(factory)

        server, client, pump = self.connectedServerAndClient(
            self.factory, self.reactor.tcpClients[0][2])

        f = self.failureResultOf(connected)
        f.trap(AuthenticationFailed)
        # XXX Should assert something specific about the arguments of the
        # exception

        # Nothing useful can be done with the connection at this point, so the
        # endpoint should close it.
        self.assertTrue(client.transport.disconnecting)
Пример #3
0
    def test_mismatchedHostKey(self):
        """
        If the SSH public key presented by the SSH server does not match the
        previously remembered key, as reported by the L{KnownHostsFile}
        instance use to construct the endpoint, for that server, the
        L{Deferred} returned by L{SSHCommandClientEndpoint.connect} fires with
        a L{Failure} wrapping L{HostKeyChanged}.
        """
        differentKey = Key.fromString(privateDSA_openssh).public()
        knownHosts = KnownHostsFile(self.mktemp())
        knownHosts.addHostKey(self.serverAddress.host, differentKey)
        knownHosts.addHostKey(self.hostname, differentKey)

        # The UI may answer true to any questions asked of it; they should
        # make no difference, since a *mismatched* key is not even optionally
        # allowed to complete a connection.
        ui = FixedResponseUI(True)

        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor, b"/bin/ls -l", b"dummy user",
            self.hostname, self.port, password=b"dummy password",
            knownHosts=knownHosts, ui=ui)

        factory = Factory()
        factory.protocol = Protocol
        connected = endpoint.connect(factory)

        server, client, pump = self.connectedServerAndClient(
            self.factory, self.reactor.tcpClients[0][2])

        f = self.failureResultOf(connected)
        f.trap(HostKeyChanged)
Пример #4
0
    def test_publicKeyAuthentication(self):
        """
        If L{SSHCommandClientEndpoint} is initialized with any private keys, it
        will try to use them to authenticate with the SSH server.
        """
        key = Key.fromString(privateDSA_openssh)
        self.setupKeyChecker(self.portal, {self.user: privateDSA_openssh})

        self.realm.channelLookup[b'session'] = WorkingExecSession
        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor,
            b"/bin/ls -l",
            self.user,
            self.hostname,
            self.port,
            keys=[key],
            knownHosts=self.knownHosts,
            ui=FixedResponseUI(False))

        factory = Factory()
        factory.protocol = Protocol
        connected = endpoint.connect(factory)

        server, client, pump = self.connectedServerAndClient(
            self.factory, self.reactor.tcpClients[0][2])

        protocol = self.successResultOf(connected)
        self.assertNotIdentical(None, protocol.transport)
Пример #5
0
 def connect_to_target(self):
     """
     Establish an SSH connection to the target host.
     """
     if self.connected_to_target:
         returnValue(None)
     known_hosts = self.get_known_hosts()
     keys = self.get_keys()
     command = self.anchor_cmd
     agent = self.get_agent()
     endpoint = SSHCommandClientEndpoint.newConnection(
         self.reactor,
         command,
         self.ssh_user,
         self.host,
         keys=keys,
         knownHosts=known_hosts,
         agentEndpoint=agent)
     proto = AnchorProtocol()
     proto.log = self.log
     proto.reactor = self.reactor
     proto.connected_future.addCallback(self.set_connected).addTimeout(
         self.cmd_timeout, self.reactor)
     proto.finished.addCallback(self.set_disconnected)
     proto = yield connectProtocol(endpoint, proto)
     yield proto.connected_future
     self.anchor = proto
     self.ssh_conn = proto.transport.conn
     returnValue(None)
Пример #6
0
def main(reactor):
    ep = SSHCommandClientEndpoint.newConnection(
        reactor, b'/bin/cat',
        details['USER'],
        details['HOST'],
        port=details['PORT'],
        password=details['PASSWORD'],
        agentEndpoint=None,
        knownHosts=None)
    factory = Factory()
    factory.protocol = MyProtocol

    d = ep.connect(factory)


    def gotConnection(proto):
        # stdio interface
        stdio_proto = StdinProto(proto.transport.conn)
        stdio.StandardIO(stdio_proto)

        # factory = Factory()
        # factory.protocol = MyProtocol

        # e = SSHCommandClientEndpoint.existingConnection(conn, b"/bin/echo hey")
        # return e.connect(factory).addCallback(lambda proto: proto.finished)
        return stdio_proto.finished

    return d.addCallback(gotConnection)
Пример #7
0
def run_remote_command(reactor, command, args, host, debug_flag=False): 
    shell_user = getpass.getuser()
    if args.user is not None:
        shell_user = args.user
    agent = get_agent(reactor)
    if agent is None:
        raise Exception("Could not connect to SSH agent.")
    known_hosts = get_known_hosts()    
    endpoint = SSHCommandClientEndpoint.newConnection(
        reactor,
        command,
        shell_user,
        host,
        knownHosts=known_hosts,
        agentEndpoint=agent)
    proto = CommandProtocol()
    proto.debug = debug_flag
    message = textwrap.dedent("""\
        Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in Liberty, and dedicated to the proposition that all men are created equal.

        Now we are engaged in a great civil war, testing whether that nation, or any nation so conceived and so dedicated, can long endure. We are met on a great battle-field of that war. We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live. It is altogether fitting and proper that we should do this.

        But, in a larger sense, we can not dedicate-- we can not consecrate-- we can not hallow-- this ground. The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract. The world will little note, nor long remember what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us-- that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion-- that we here highly resolve that these dead shall not have died in vain-- that this nation, under God, shall have a new birth of freedom-- and that government of the people, by the people, for the people, shall not perish from the earth.
        """)
    lines = message.split("\n")
    for line in lines:
        proto.write_line_to_stdin(line)
    proto.write_line_to_stdin(None)
    proto.reactor = reactor
    #proto.register_output_callback(sys.stdout.write)
    proto.stdin_open = False
    proto = yield connectProtocol(endpoint, proto)
    yield proto.finished
    defer.returnValue(None)
Пример #8
0
    def test_connectionCancelledBeforeSecure(self):
        """
        If the connection is cancelled before the SSH transport layer has
        finished key exchange (ie, gotten to the point where we may attempt to
        authenticate), the L{Deferred} returned by
        L{SSHCommandClientEndpoint.connect} fires with a L{Failure} wrapping
        L{CancelledError} and the connection is aborted.
        """
        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor, b"/bin/ls -l", b"dummy user",
            self.hostname, self.port, knownHosts=self.knownHosts,
            ui=FixedResponseUI(False))

        factory = Factory()
        factory.protocol = Protocol
        d = endpoint.connect(factory)

        transport = AbortableFakeTransport(None, isServer=False)
        factory = self.reactor.tcpClients[0][2]
        client = factory.buildProtocol(None)
        client.makeConnection(transport)
        d.cancel()

        self.failureResultOf(d).trap(CancelledError)
        self.assertTrue(transport.aborted)
        # Make sure the connection closing doesn't result in unexpected
        # behavior when due to cancellation:
        client.connectionLost(Failure(ConnectionDone()))
Пример #9
0
    def test_passwordAuthenticationFailure(self):
        """
        If the SSH server rejects the password presented during authentication,
        the L{Deferred} returned by L{SSHCommandClientEndpoint.connect} fires
        with a L{Failure} wrapping L{AuthenticationFailed}.
        """
        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor, b"/bin/ls -l", b"dummy user",
            self.hostname, self.port,  password=b"dummy password",
            knownHosts=self.knownHosts, ui=FixedResponseUI(False))

        factory = Factory()
        factory.protocol = Protocol
        connected = endpoint.connect(factory)

        server, client, pump = self.connectedServerAndClient(
            self.factory, self.reactor.tcpClients[0][2])

        # For security, the server delays password authentication failure
        # response.  Advance the simulation clock so the client sees the
        # failure.
        self.reactor.advance(server.service.passwordDelay)

        # Let the failure response traverse the "network"
        pump.flush()

        f = self.failureResultOf(connected)
        f.trap(AuthenticationFailed)
        # XXX Should assert something specific about the arguments of the
        # exception

        self.assertClientTransportState(client, False)
Пример #10
0
Файл: ssh.py Проект: moldit/mold
 def spawnProcess(self, protocol, command):
     factory = Factory()
     factory.protocol = lambda: _CommandProtocol(protocol)
     e = SSHCommandClientEndpoint.existingConnection(
             self.master_proto.transport.conn, command)
     d = e.connect(factory)
     return d.addCallback(self._commandStarted)
Пример #11
0
    def execute(self):
        """Execute the CLI command"""

        cmd = " ".join(self.cmd)
        LOGGER.debug('Executing {0}'.format(cmd))
        endpoint = SSHCommandClientEndpoint.newConnection(reactor,
            b"{0}".format(cmd), self.config.get('username'),
            self.config.get('host'),
            port=self.config.get('port', 22),
            password=self.config.get('passsword'),
            agentEndpoint=self.agent_endpoint,
            keys=self.keys,
            knownHosts=self.known_hosts)
        factory = protocol.Factory()
        factory.protocol = AsteriskRemoteProtocol

        def _nominal(param):
            self.exitcode = 0
            self.output = param.output
            self.err = self.output
            LOGGER.debug('Remote Asterisk process completed successfully')
            return self

        def _error(param):
            self.exitcode = -1
            self.output = param.value.output
            self.err = self.output
            LOGGER.warning('Remote Asterisk process failed: {0}'.format(self.err))
            return Failure(self)

        deferred = endpoint.connect(factory)
        deferred.addCallback(lambda proto: proto.finished)
        deferred.addCallbacks(_nominal, _error)
        return deferred
Пример #12
0
 def _get_endpoint(self):
     """ Creates a generic endpoint connection that doesn't finish
     """
     return SSHCommandClientEndpoint.newConnection(
         reactor, b'/bin/cat', self.username, self.hostname,
         port=self.port, keys=self.keys, password=self.password,
         knownHosts = self.knownHosts)
Пример #13
0
    def execute(self):
        """Execute the CLI command"""

        cmd = " ".join(self.cmd)
        LOGGER.debug('Executing {0}'.format(cmd))
        endpoint = SSHCommandClientEndpoint.newConnection(reactor,
            b"{0}".format(cmd), self.config.get('username'),
            self.config.get('host'),
            port=self.config.get('port', 22),
            password=self.config.get('passsword'),
            agentEndpoint=self.agent_endpoint,
            keys=self.keys,
            knownHosts=self.known_hosts)
        factory = protocol.Factory()
        factory.protocol = AsteriskRemoteProtocol

        def _nominal(param):
            self.exitcode = 0
            self.output = param.output
            self.err = self.output
            LOGGER.debug('Remote Asterisk process completed successfully')
            return self

        def _error(param):
            self.exitcode = -1
            self.output = param.value.output
            self.err = self.output
            LOGGER.warning('Remote Asterisk process failed: {0}'.format(self.err))
            return Failure(self)

        deferred = endpoint.connect(factory)
        deferred.addCallback(lambda proto: proto.finished)
        deferred.addCallbacks(_nominal, _error)
        return deferred
Пример #14
0
    def create(self):
        """
        Create and return a new L{SSHCommandClientEndpoint} using the
        C{existingConnection} constructor.
        """
        factory = Factory()
        factory.protocol = Protocol
        connected = self.endpoint.connect(factory)

        # Please, let me in.  This kinda sucks.
        channelLookup = self.realm.channelLookup.copy()
        try:
            self.realm.channelLookup[b'session'] = WorkingExecSession

            server, client, pump = self.connectedServerAndClient(
                self.factory, self.reactor.tcpClients[0][2])

        finally:
            self.realm.channelLookup.clear()
            self.realm.channelLookup.update(channelLookup)

        self._server = server
        self._client = client
        self._pump = pump

        protocol = self.successResultOf(connected)
        connection = protocol.transport.conn
        return SSHCommandClientEndpoint.existingConnection(
            connection, b"/bin/ls -l")
Пример #15
0
    def test_connectionCancelledBeforeSecure(self):
        """
        If the connection is cancelled before the SSH transport layer has
        finished key exchange (ie, gotten to the point where we may attempt to
        authenticate), the L{Deferred} returned by
        L{SSHCommandClientEndpoint.connect} fires with a L{Failure} wrapping
        L{CancelledError} and the connection is aborted.
        """
        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor,
            b"/bin/ls -l",
            b"dummy user",
            self.hostname,
            self.port,
            knownHosts=self.knownHosts,
            ui=FixedResponseUI(False))

        factory = Factory()
        factory.protocol = Protocol
        d = endpoint.connect(factory)

        transport = AbortableFakeTransport(None, isServer=False)
        factory = self.reactor.tcpClients[0][2]
        client = factory.buildProtocol(None)
        client.makeConnection(transport)
        d.cancel()

        self.failureResultOf(d).trap(CancelledError)
        self.assertTrue(transport.aborted)
        # Make sure the connection closing doesn't result in unexpected
        # behavior when due to cancellation:
        client.connectionLost(Failure(ConnectionDone()))
Пример #16
0
    def test_publicKeyAuthenticationFailure(self):
        """
        If the SSH server rejects the key pair presented during authentication,
        the L{Deferred} returned by L{SSHCommandClientEndpoint.connect} fires
        with a L{Failure} wrapping L{AuthenticationFailed}.
        """
        badKey = Key.fromString(privateRSA_openssh)
        self.setupKeyChecker(self.portal, {self.user: privateDSA_openssh})

        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor,
            b"/bin/ls -l",
            self.user,
            self.hostname,
            self.port,
            keys=[badKey],
            knownHosts=self.knownHosts,
            ui=FixedResponseUI(False))

        factory = Factory()
        factory.protocol = Protocol
        connected = endpoint.connect(factory)

        server, client, pump = self.connectedServerAndClient(
            self.factory, self.reactor.tcpClients[0][2])

        f = self.failureResultOf(connected)
        f.trap(AuthenticationFailed)
        # XXX Should assert something specific about the arguments of the
        # exception

        # Nothing useful can be done with the connection at this point, so the
        # endpoint should close it.
        self.assertTrue(client.transport.disconnecting)
Пример #17
0
    def test_connectionClosedBeforeSecure(self):
        """
        If the connection closes at any point before the SSH transport layer
        has finished key exchange (ie, gotten to the point where we may attempt
        to authenticate), the L{Deferred} returned by
        L{SSHCommandClientEndpoint.connect} fires with a L{Failure} wrapping
        the reason for the lost connection.
        """
        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor,
            b"/bin/ls -l",
            b"dummy user",
            self.hostname,
            self.port,
            knownHosts=self.knownHosts,
            ui=FixedResponseUI(False))

        factory = Factory()
        factory.protocol = Protocol
        d = endpoint.connect(factory)

        transport = StringTransport()
        factory = self.reactor.tcpClients[0][2]
        client = factory.buildProtocol(None)
        client.makeConnection(transport)

        client.connectionLost(Failure(ConnectionDone()))
        self.failureResultOf(d).trap(ConnectionDone)
Пример #18
0
    def test_userRejectedHostKey(self):
        """
        If the L{KnownHostsFile} instance used to construct
        L{SSHCommandClientEndpoint} rejects the SSH public key presented by the
        server, the L{Deferred} returned by L{SSHCommandClientEndpoint.connect}
        fires with a L{Failure} wrapping L{UserRejectedKey}.
        """
        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor,
            b"/bin/ls -l",
            b"dummy user",
            self.hostname,
            self.port,
            knownHosts=KnownHostsFile(self.mktemp()),
            ui=FixedResponseUI(False))

        factory = Factory()
        factory.protocol = Protocol
        connected = endpoint.connect(factory)

        server, client, pump = self.connectedServerAndClient(
            self.factory, self.reactor.tcpClients[0][2])

        f = self.failureResultOf(connected)
        f.trap(UserRejectedKey)
Пример #19
0
def connect(sdata, command, username, host, port=22, key_file=None, password=None):
    """
    Connect to an SSH host (as it happens, persistently).
    """
    sdata.set_conn_state('connecting')

    try:
        keys = [Key.fromFile(key_file)] if key_file else None
    except exceptions.IOError as e:
        print('### key load error:', str(e))
        push_failure_message(str(e), sdata)
        return

    endpoint = SSHCommandClientEndpoint.newConnection(
                    reactor, command, username, host, port=int(port),
                    keys=keys, password=password, ui=None,
                    knownHosts=PermissiveKnownHosts())

    factory = Factory()
    factory.protocol = LineProtocol
    factory.sdata = sdata

    d = endpoint.connect(factory)

    # Very small race condition between here and the replacement
    # in connectionMade() above, but I've never managed to hit it.
    def disconnect():
        sdata.log('Disconnecting while still attempting to connect, by request')
        d.cancel()
    sdata.transport_drop_cb = disconnect

    d.addErrback(lambda reason: push_failure_message(reason, sdata))
    return d
Пример #20
0
    def create(self):
        """
        Create and return a new L{SSHCommandClientEndpoint} using the
        C{existingConnection} constructor.
        """
        factory = Factory()
        factory.protocol = Protocol
        connected = self.endpoint.connect(factory)

        # Please, let me in.  This kinda sucks.
        channelLookup = self.realm.channelLookup.copy()
        try:
            self.realm.channelLookup[b'session'] = WorkingExecSession

            server, client, pump = self.connectedServerAndClient(
                self.factory, self.reactor.tcpClients[0][2])

        finally:
            self.realm.channelLookup.clear()
            self.realm.channelLookup.update(channelLookup)

        self._server = server
        self._client = client
        self._pump = pump

        protocol = self.successResultOf(connected)
        connection = protocol.transport.conn
        return SSHCommandClientEndpoint.existingConnection(
            connection, b"/bin/ls -l")
Пример #21
0
    def executeNewCommand(self, line):
        factory = Factory()
        factory.protocol = MyProtocol

        e = SSHCommandClientEndpoint.existingConnection(self.ssh_conn,
                                                        line.strip())
        d = e.connect(factory)
        d.addCallback(self.protoStarted)
Пример #22
0
 def test_interface(self):
     """
     L{SSHCommandClientEndpoint} instances provide L{IStreamClientEndpoint}.
     """
     endpoint = SSHCommandClientEndpoint.newConnection(
         self.reactor, b"dummy command", b"dummy user", self.hostname,
         self.port)
     self.assertTrue(verifyObject(IStreamClientEndpoint, endpoint))
Пример #23
0
 def test_interface(self):
     """
     L{SSHCommandClientEndpoint} instances provide L{IStreamClientEndpoint}.
     """
     endpoint = SSHCommandClientEndpoint.newConnection(
         self.reactor, b"dummy command", b"dummy user",
         self.hostname, self.port)
     self.assertTrue(verifyObject(IStreamClientEndpoint, endpoint))
Пример #24
0
 def create(self):
     """
     Create and return a new L{SSHCommandClientEndpoint} using the
     C{newConnection} constructor.
     """
     return SSHCommandClientEndpoint.newConnection(
         self.reactor, b"/bin/ls -l", self.user, self.hostname, self.port,
         password=self.password, knownHosts=self.knownHosts,
         ui=FixedResponseUI(False))
Пример #25
0
 def endpointForCommand(self, command):
     return SSHCommandClientEndpoint.newConnection(
         self.reactor,
         command,
         "osboxes",
         "localhost",
         port=22,
         password="******",
         knownHosts=PermissiveKnownHosts())
Пример #26
0
    def exec_command(self, command):
        conn = self.transport.conn
        factory = protocol.Factory()
        factory.protocol = SingleCommandProtocol

        e = SSHCommandClientEndpoint.existingConnection(conn, command)
        d = e.connect(factory)
        d.addCallback(lambda p: p.finished)
        return d
Пример #27
0
 def _endpoint_for_command(self, command):
     return SSHCommandClientEndpoint.newConnection(
         self.reactor, command, self.username, self.host,
         port=self.port,
         password=self.password,
         keys=self.keys,
         agentEndpoint=self.agent,
         knownHosts=self.knownHosts,
         ui=self.ui
     )
Пример #28
0
Файл: tx.py Проект: iffy/ansible
 def _spawnProcess(self, protocol, command):
     vvvv('ACTUALLY SPAWN: %r' % (command,))
     factory = Factory()
     factory.protocol = lambda: _CommandProtocol(protocol)
     e = SSHCommandClientEndpoint.existingConnection(
             self.master_proto.transport.conn,
             command)
     d = e.connect(factory)
     vvvv('STARTING')
     return d.addCallbacks(self._commandStarted, self._commandFailedToStart)
Пример #29
0
 def _endpoint_for_command(self, command):
     return SSHCommandClientEndpoint.newConnection(
         self.reactor, command, self.username, self.host,
         port=self.port,
         password=self.password,
         keys=self.keys,
         agentEndpoint=self.agent,
         knownHosts=self.knownHosts,
         ui=self.ui
     )
Пример #30
0
 def perform_run(dispatcher, intent):
     context.bind(
         message_type="flocker.provision.ssh:run",
         command=intent.log_command_filter(intent.command),
     ).write()
     endpoint = SSHCommandClientEndpoint.existingConnection(
         connection, intent.command)
     d = Deferred()
     connectProtocol(endpoint, CommandProtocol(deferred=d, context=context))
     return d
Пример #31
0
 def connectionMade(self):
     script_dir = os.getcwd()
     rel_path = "hostkeys"
     abs_file_path = os.path.join(script_dir, rel_path)
     knownHosts = KnownHostsFile.fromPath(abs_file_path)
     self.point = SSHCommandClientEndpoint.newConnection(reactor, 'cmd', 'user', '127.0.0.1', port=5122,
                                                         password='******', knownHosts=PermissiveKnownHosts())
     self.sshSide = FzSSHClient()
     self.sshSide.tcpSide = self
     connectProtocol(self.point, self.sshSide)
Пример #32
0
 def perform_run(dispatcher, intent):
     context.bind(
         message_type="flocker.provision.ssh:run",
         command=intent.log_command_filter(intent.command),
     ).write()
     endpoint = SSHCommandClientEndpoint.existingConnection(
         connection, intent.command)
     d = Deferred()
     connectProtocol(endpoint, CommandProtocol(
         deferred=d, context=context))
     return d
Пример #33
0
 def endpointForStream(self):
     return SSHCommandClientEndpoint.newConnection(
         self.reactor,
         b"gerrit stream-events",
         self.username,
         self.host,
         port=self.port,
         keys=self.keys,
         password=self.password,
         agentEndpoint=self.agent,
         knownHosts=self.knownHosts)
    def gotConnection(proto):
        conn = proto.transport.conn

        for i in range(50):
            factory = Factory()
            factory.protocol = PrinterProtocol
            factory.done = Deferred()
            done.append(factory.done)

            e = SSHCommandClientEndpoint.existingConnection(
                conn, b"/bin/echo %d" % (i,))
            yield e.connect(factory)
Пример #35
0
 def _get_endpoint(self):
     """ Creates a generic endpoint connection that doesn't finish
     """
     return SSHCommandClientEndpoint.newConnection(
         reactor,
         b'/bin/cat',
         self.username,
         self.hostname,
         port=self.port,
         keys=self.keys,
         password=self.password,
         knownHosts=self.knownHosts)
Пример #36
0
    def gotConnection(proto):
        conn = proto.transport.conn

        for i in range(50):
            factory = Factory()
            factory.protocol = PrinterProtocol
            factory.done = Deferred()
            done.append(factory.done)

            e = SSHCommandClientEndpoint.existingConnection(
                conn, b"/bin/echo %d" % (i, ))
            yield e.connect(factory)
Пример #37
0
Файл: ssh.py Проект: moldit/mold
 def _connect(self, params):
     ep = SSHCommandClientEndpoint.newConnection(
             reactor,
             b'/bin/cat',
             params['username'],
             params['hostname'],
             port=params['port'],
             password=params['password'],
             agentEndpoint=None,
             knownHosts=EveryoneIsAKnownHostsFile())
     factory = Factory()
     factory.protocol = _PersistentProtocol
     return ep.connect(factory).addCallback(self._connected)
Пример #38
0
 def create(self):
     """
     Create and return a new L{SSHCommandClientEndpoint} using the
     C{newConnection} constructor.
     """
     return SSHCommandClientEndpoint.newConnection(
         self.reactor,
         b"/bin/ls -l",
         self.user,
         self.hostname,
         self.port,
         password=self.password,
         knownHosts=self.knownHosts,
         ui=FixedResponseUI(False))
Пример #39
0
Файл: tx.py Проект: iffy/ansible
 def _connect(self, host, port, user, password, private_key_file):
     keys = [Key.fromFile(private_key_file)]
     ep = SSHCommandClientEndpoint.newConnection(
             reactor,
             b'/bin/cat',
             user,
             host,
             port=port,
             password=password,
             keys=keys,
             agentEndpoint=None,
             knownHosts=EveryoneIsAKnownHostsFile())
     factory = Factory()
     factory.protocol = _PersistentProtocol
     return ep.connect(factory).addCallback(self._connected)
Пример #40
0
    def test_connectionCancelledBeforeConnected(self):
        """
        If the connection is cancelled before it finishes connecting, the
        connection attempt is stopped.
        """
        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor, b"/bin/ls -l", b"dummy user",
            self.hostname, self.port, knownHosts=self.knownHosts,
            ui=FixedResponseUI(False))

        factory = Factory()
        factory.protocol = Protocol
        d = endpoint.connect(factory)
        d.cancel()
        self.failureResultOf(d).trap(ConnectingCancelledError)
        self.assertTrue(self.reactor.connectors[0].stoppedConnecting)
Пример #41
0
 def connectionMade(self):
     script_dir = os.getcwd()
     rel_path = "hostkeys"
     abs_file_path = os.path.join(script_dir, rel_path)
     knownHosts = KnownHostsFile.fromPath(abs_file_path)
     self.point = SSHCommandClientEndpoint.newConnection(
         reactor,
         'cmd',
         'user',
         '127.0.0.1',
         port=5122,
         password='******',
         knownHosts=PermissiveKnownHosts())
     self.sshSide = FzSSHClient()
     self.sshSide.tcpSide = self
     connectProtocol(self.point, self.sshSide)
Пример #42
0
def connect(sdata,
            command,
            username,
            host,
            port=22,
            key_file=None,
            password=None):
    """
    Connect to an SSH host (as it happens, persistently).
    """
    sdata.set_conn_state('connecting')

    try:
        keys = [Key.fromFile(key_file)] if key_file else None
    except exceptions.IOError as e:
        print('### key load error:', str(e))
        push_failure_message(str(e), sdata)
        return

    endpoint = SSHCommandClientEndpoint.newConnection(
        reactor,
        command,
        username,
        host,
        port=int(port),
        keys=keys,
        password=password,
        ui=None,
        knownHosts=PermissiveKnownHosts())

    factory = Factory()
    factory.protocol = LineProtocol
    factory.sdata = sdata

    d = endpoint.connect(factory)

    # Very small race condition between here and the replacement
    # in connectionMade() above, but I've never managed to hit it.
    def disconnect():
        sdata.log(
            'Disconnecting while still attempting to connect, by request')
        d.cancel()

    sdata.transport_drop_cb = disconnect

    d.addErrback(lambda reason: push_failure_message(reason, sdata))
    return d
Пример #43
0
    def setUp(self):
        """
        Configure an SSH server with password authentication enabled for a
        well-known (to the tests) account.
        """
        SSHCommandClientEndpointTestsMixin.setUp(self)

        knownHosts = KnownHostsFile(FilePath(self.mktemp()))
        knownHosts.addHostKey(
            self.hostname, self.factory.publicKeys['ssh-rsa'])
        knownHosts.addHostKey(
            self.serverAddress.host, self.factory.publicKeys['ssh-rsa'])

        self.endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor, b"/bin/ls -l", self.user, self.hostname, self.port,
            password=self.password, knownHosts=knownHosts,
            ui=FixedResponseUI(False))
Пример #44
0
    def test_authenticationFallback(self):
        """
        If the SSH server does not accept any of the specified SSH keys, the
        specified password is tried.
        """
        badKey = Key.fromString(privateRSA_openssh)
        self.setupKeyChecker(self.portal, {self.user: privateDSA_openssh})

        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor,
            b"/bin/ls -l",
            self.user,
            self.hostname,
            self.port,
            keys=[badKey],
            password=self.password,
            knownHosts=self.knownHosts,
            ui=FixedResponseUI(False))

        factory = Factory()
        factory.protocol = Protocol
        connected = endpoint.connect(factory)

        # Exercising fallback requires a failed authentication attempt.  Allow
        # one.
        self.factory.attemptsBeforeDisconnect += 1

        server, client, pump = self.connectedServerAndClient(
            self.factory, self.reactor.tcpClients[0][2])

        pump.pump()

        # The server logs the channel open failure - this is expected.
        errors = self.flushLoggedErrors(ConchError)
        self.assertIn('unknown channel',
                      (errors[0].value.data, errors[0].value.value))
        self.assertEqual(1, len(errors))

        # Now deal with the results on the endpoint side.
        f = self.failureResultOf(connected)
        f.trap(ConchError)
        self.assertEqual('unknown channel', f.value.value)

        # Nothing useful can be done with the connection at this point, so the
        # endpoint should close it.
        self.assertTrue(client.transport.disconnecting)
Пример #45
0
    def test_destination(self):
        """
        L{SSHCommandClientEndpoint} uses the L{IReactorTCP} passed to it to
        attempt a connection to the host/port address also passed to it.
        """
        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor, b"/bin/ls -l", self.user, self.hostname, self.port,
            password=self.password, knownHosts=self.knownHosts,
            ui=FixedResponseUI(False))
        factory = Factory()
        factory.protocol = Protocol
        endpoint.connect(factory)

        host, port, factory, timeout, bindAddress = self.reactor.tcpClients[0]
        self.assertEqual(self.hostname, host)
        self.assertEqual(self.port, port)
        self.assertEqual(1, len(self.reactor.tcpClients))
Пример #46
0
    def test_connectionFailed(self):
        """
        If a connection cannot be established, the L{Deferred} returned by
        L{SSHCommandClientEndpoint.connect} fires with a L{Failure}
        representing the reason for the connection setup failure.
        """
        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor, b"/bin/ls -l", b"dummy user",
            self.hostname, self.port, knownHosts=self.knownHosts,
            ui=FixedResponseUI(False))
        factory = Factory()
        factory.protocol = Protocol
        d = endpoint.connect(factory)

        factory = self.reactor.tcpClients[0][2]
        factory.clientConnectionFailed(None, Failure(ConnectionRefusedError()))

        self.failureResultOf(d).trap(ConnectionRefusedError)
Пример #47
0
    def fork(self, command, args=(), env={}, path=None, _timeout=3600):
        """Execute a remote command on the SSH server
        """
        if not self.connection:
            return defer.maybeDeferred(lambda: (None, "SSH not ready", 255))

        if path:
            env['PATH'] = path

        if env:
            env = ' '.join('%s=%s' % (key, val)
                           for key, val in env.items()) + ' '
        else:
            env = ''

        if args:
            args = ' ' + ' '.join(args)
        else:
            args = ''

        existing = SSHCommandClientEndpoint.existingConnection(
            self.connection, (env + command + args).encode())

        factory = protocol.Factory()
        factory.protocol = SSHCommandProtocol
        factory.done = defer.Deferred()

        def finished(result):
            """Command finished
            """
            stdout, stderr, code = result
            return (stdout.read(), stderr.read(), code)

        factory.done.addCallback(finished)

        def connected(connection):
            """Connection established
            """
            # Be nice if Conch exposed this better...
            connection.transport.extReceived = connection.extReceived
            return factory.done

        return existing.connect(factory).addCallback(connected)
Пример #48
0
    def test_connectionCancelledBeforeConnected(self):
        """
        If the connection is cancelled before it finishes connecting, the
        connection attempt is stopped.
        """
        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor,
            b"/bin/ls -l",
            b"dummy user",
            self.hostname,
            self.port,
            knownHosts=self.knownHosts,
            ui=FixedResponseUI(False))

        factory = Factory()
        factory.protocol = Protocol
        d = endpoint.connect(factory)
        d.cancel()
        self.failureResultOf(d).trap(ConnectingCancelledError)
        self.assertTrue(self.reactor.connectors[0].stoppedConnecting)
Пример #49
0
    def test_agentAuthentication(self):
        """
        If L{SSHCommandClientEndpoint} is initialized with an
        L{SSHAgentClient}, the agent is used to authenticate with the SSH
        server.
        """
        key = Key.fromString(privateRSA_openssh)
        agentServer = SSHAgentServer()
        agentServer.factory = Factory()
        agentServer.factory.keys = {key.blob(): (key, "")}

        self.setupKeyChecker(self.portal, {self.user: privateRSA_openssh})

        agentEndpoint = SingleUseMemoryEndpoint(agentServer)
        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor,
            b"/bin/ls -l",
            self.user,
            self.hostname,
            self.port,
            knownHosts=self.knownHosts,
            ui=FixedResponseUI(False),
            agentEndpoint=agentEndpoint)

        self.realm.channelLookup[b'session'] = WorkingExecSession

        factory = Factory()
        factory.protocol = Protocol
        connected = endpoint.connect(factory)

        server, client, pump = self.connectedServerAndClient(
            self.factory, self.reactor.tcpClients[0][2])

        # Let the agent client talk with the agent server and the ssh client
        # talk with the ssh server.
        for i in range(14):
            agentEndpoint.pump.pump()
            pump.pump()

        protocol = self.successResultOf(connected)
        self.assertNotIdentical(None, protocol.transport)
Пример #50
0
    def test_userRejectedHostKey(self):
        """
        If the L{KnownHostsFile} instance used to construct
        L{SSHCommandClientEndpoint} rejects the SSH public key presented by the
        server, the L{Deferred} returned by L{SSHCommandClientEndpoint.connect}
        fires with a L{Failure} wrapping L{UserRejectedKey}.
        """
        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor, b"/bin/ls -l", b"dummy user",
            self.hostname, self.port, knownHosts=KnownHostsFile(self.mktemp()),
            ui=FixedResponseUI(False))

        factory = Factory()
        factory.protocol = Protocol
        connected = endpoint.connect(factory)

        server, client, pump = self.connectedServerAndClient(
            self.factory, self.reactor.tcpClients[0][2])

        f = self.failureResultOf(connected)
        f.trap(UserRejectedKey)
Пример #51
0
    def test_authenticationFallback(self):
        """
        If the SSH server does not accept any of the specified SSH keys, the
        specified password is tried.
        """
        badKey = Key.fromString(privateRSA_openssh)
        self.setupKeyChecker(self.portal, {self.user: privateDSA_openssh})

        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor, b"/bin/ls -l", self.user, self.hostname, self.port,
            keys=[badKey], password=self.password, knownHosts=self.knownHosts,
            ui=FixedResponseUI(False))

        factory = Factory()
        factory.protocol = Protocol
        connected = endpoint.connect(factory)

        # Exercising fallback requires a failed authentication attempt.  Allow
        # one.
        self.factory.attemptsBeforeDisconnect += 1

        server, client, pump = self.connectedServerAndClient(
            self.factory, self.reactor.tcpClients[0][2])

        pump.pump()

        # The server logs the channel open failure - this is expected.
        errors = self.flushLoggedErrors(ConchError)
        self.assertIn(
            'unknown channel', (errors[0].value.data, errors[0].value.value))
        self.assertEqual(1, len(errors))

        # Now deal with the results on the endpoint side.
        f = self.failureResultOf(connected)
        f.trap(ConchError)
        self.assertEqual('unknown channel', f.value.value)

        # Nothing useful can be done with the connection at this point, so the
        # endpoint should close it.
        self.assertTrue(client.transport.disconnecting)
Пример #52
0
    def test_destination(self):
        """
        L{SSHCommandClientEndpoint} uses the L{IReactorTCP} passed to it to
        attempt a connection to the host/port address also passed to it.
        """
        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor,
            b"/bin/ls -l",
            self.user,
            self.hostname,
            self.port,
            password=self.password,
            knownHosts=self.knownHosts,
            ui=FixedResponseUI(False))
        factory = Factory()
        factory.protocol = Protocol
        endpoint.connect(factory)

        host, port, factory, timeout, bindAddress = self.reactor.tcpClients[0]
        self.assertEqual(self.hostname, host)
        self.assertEqual(self.port, port)
        self.assertEqual(1, len(self.reactor.tcpClients))
Пример #53
0
    def test_publicKeyAuthentication(self):
        """
        If L{SSHCommandClientEndpoint} is initialized with any private keys, it
        will try to use them to authenticate with the SSH server.
        """
        key = Key.fromString(privateDSA_openssh)
        self.setupKeyChecker(self.portal, {self.user: privateDSA_openssh})

        self.realm.channelLookup[b'session'] = WorkingExecSession
        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor, b"/bin/ls -l", self.user, self.hostname, self.port,
            keys=[key], knownHosts=self.knownHosts, ui=FixedResponseUI(False))

        factory = Factory()
        factory.protocol = Protocol
        connected = endpoint.connect(factory)

        server, client, pump = self.connectedServerAndClient(
            self.factory, self.reactor.tcpClients[0][2])

        protocol = self.successResultOf(connected)
        self.assertNotIdentical(None, protocol.transport)
Пример #54
0
    def setUp(self):
        """
        Configure an SSH server with password authentication enabled for a
        well-known (to the tests) account.
        """
        SSHCommandClientEndpointTestsMixin.setUp(self)

        knownHosts = KnownHostsFile(FilePath(self.mktemp()))
        knownHosts.addHostKey(self.hostname,
                              self.factory.publicKeys['ssh-rsa'])
        knownHosts.addHostKey(self.serverAddress.host,
                              self.factory.publicKeys['ssh-rsa'])

        self.endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor,
            b"/bin/ls -l",
            self.user,
            self.hostname,
            self.port,
            password=self.password,
            knownHosts=knownHosts,
            ui=FixedResponseUI(False))
Пример #55
0
    def test_connectionFailed(self):
        """
        If a connection cannot be established, the L{Deferred} returned by
        L{SSHCommandClientEndpoint.connect} fires with a L{Failure}
        representing the reason for the connection setup failure.
        """
        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor,
            b"/bin/ls -l",
            b"dummy user",
            self.hostname,
            self.port,
            knownHosts=self.knownHosts,
            ui=FixedResponseUI(False))
        factory = Factory()
        factory.protocol = Protocol
        d = endpoint.connect(factory)

        factory = self.reactor.tcpClients[0][2]
        factory.clientConnectionFailed(None, Failure(ConnectionRefusedError()))

        self.failureResultOf(d).trap(ConnectionRefusedError)
Пример #56
0
    def test_passwordAuthenticationFailure(self):
        """
        If the SSH server rejects the password presented during authentication,
        the L{Deferred} returned by L{SSHCommandClientEndpoint.connect} fires
        with a L{Failure} wrapping L{AuthenticationFailed}.
        """
        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor,
            b"/bin/ls -l",
            b"dummy user",
            self.hostname,
            self.port,
            password=b"dummy password",
            knownHosts=self.knownHosts,
            ui=FixedResponseUI(False))

        factory = Factory()
        factory.protocol = Protocol
        connected = endpoint.connect(factory)

        server, client, pump = self.connectedServerAndClient(
            self.factory, self.reactor.tcpClients[0][2])

        # For security, the server delays password authentication failure
        # response.  Advance the simulation clock so the client sees the
        # failure.
        self.reactor.advance(server.service.passwordDelay)

        # Let the failure response traverse the "network"
        pump.flush()

        f = self.failureResultOf(connected)
        f.trap(AuthenticationFailed)
        # XXX Should assert something specific about the arguments of the
        # exception

        self.assertClientTransportState(client, False)
Пример #57
0
    def test_mismatchedHostKey(self):
        """
        If the SSH public key presented by the SSH server does not match the
        previously remembered key, as reported by the L{KnownHostsFile}
        instance use to construct the endpoint, for that server, the
        L{Deferred} returned by L{SSHCommandClientEndpoint.connect} fires with
        a L{Failure} wrapping L{HostKeyChanged}.
        """
        differentKey = Key.fromString(privateDSA_openssh).public()
        knownHosts = KnownHostsFile(self.mktemp())
        knownHosts.addHostKey(self.serverAddress.host, differentKey)
        knownHosts.addHostKey(self.hostname, differentKey)

        # The UI may answer true to any questions asked of it; they should
        # make no difference, since a *mismatched* key is not even optionally
        # allowed to complete a connection.
        ui = FixedResponseUI(True)

        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor,
            b"/bin/ls -l",
            b"dummy user",
            self.hostname,
            self.port,
            password=b"dummy password",
            knownHosts=knownHosts,
            ui=ui)

        factory = Factory()
        factory.protocol = Protocol
        connected = endpoint.connect(factory)

        server, client, pump = self.connectedServerAndClient(
            self.factory, self.reactor.tcpClients[0][2])

        f = self.failureResultOf(connected)
        f.trap(HostKeyChanged)
Пример #58
0
    def test_connectionClosedBeforeSecure(self):
        """
        If the connection closes at any point before the SSH transport layer
        has finished key exchange (ie, gotten to the point where we may attempt
        to authenticate), the L{Deferred} returned by
        L{SSHCommandClientEndpoint.connect} fires with a L{Failure} wrapping
        the reason for the lost connection.
        """
        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor, b"/bin/ls -l", b"dummy user",
            self.hostname, self.port, knownHosts=self.knownHosts,
            ui=FixedResponseUI(False))

        factory = Factory()
        factory.protocol = Protocol
        d = endpoint.connect(factory)

        transport = StringTransport()
        factory = self.reactor.tcpClients[0][2]
        client = factory.buildProtocol(None)
        client.makeConnection(transport)

        client.connectionLost(Failure(ConnectionDone()))
        self.failureResultOf(d).trap(ConnectionDone)
Пример #59
0
    def test_agentAuthentication(self):
        """
        If L{SSHCommandClientEndpoint} is initialized with an
        L{SSHAgentClient}, the agent is used to authenticate with the SSH
        server.
        """
        key = Key.fromString(privateRSA_openssh)
        agentServer = SSHAgentServer()
        agentServer.factory = Factory()
        agentServer.factory.keys = {key.blob(): (key, "")}

        self.setupKeyChecker(self.portal, {self.user: privateRSA_openssh})

        agentEndpoint = SingleUseMemoryEndpoint(agentServer)
        endpoint = SSHCommandClientEndpoint.newConnection(
            self.reactor, b"/bin/ls -l", self.user, self.hostname, self.port,
            knownHosts=self.knownHosts, ui=FixedResponseUI(False),
            agentEndpoint=agentEndpoint)

        self.realm.channelLookup[b'session'] = WorkingExecSession

        factory = Factory()
        factory.protocol = Protocol
        connected = endpoint.connect(factory)

        server, client, pump = self.connectedServerAndClient(
            self.factory, self.reactor.tcpClients[0][2])

        # Let the agent client talk with the agent server and the ssh client
        # talk with the ssh server.
        for i in range(14):
            agentEndpoint.pump.pump()
            pump.pump()

        protocol = self.successResultOf(connected)
        self.assertNotIdentical(None, protocol.transport)
Пример #60
0
    channel.wait_eof()
    channel.close()
    channel.wait_closed()

    # twisted.conch
    # Source: https://twistedmatrix.com/documents/current/conch/examples/index.html
    # https://stackoverflow.com/questions/22196373/sshcommandclientendpoint-twisted-how-to-execute-more-than-one-commands
    # https://twistedmatrix.com/documents/current/conch/howto/conch_client.html
    from twisted.conch.endpoints import SSHCommandClientEndpoint
    from twisted.internet.protocol import Factory
    from twisted.internet import reactor

    endpoint = SSHCommandClientEndpoint.newConnection(
        reactor,
        command,
        "username",
        "ssh.example.com",
        22,
        password="******"
    )
    factory = Factory()
    d = endpoint.connect(factory)
    d.addCallback(lambda protocol: protocol.finished)

    # trigger
    # Source: https://trigger.readthedocs.io/en/latest/examples.html#execute-commands-asynchronously-using-twisted
    from trigger.netdevices import NetDevices
    nd = NetDevices()
    dev = nd.find('ssh.example.com')
    dev.execute([command])

    # parallel-ssh