Esempio n. 1
0
    async def _getConnection(self, user, acceptTos=False):
        """
		Get a cached connection or establish one.

		Can throw TermsNotAccepted via BawwabSSHClient.
		"""
        async with self._locks[user]:
            c = self._conns.get(user, None)
            if c is None:
                conn = await asyncssh.connect(
                    client_factory=lambda: BawwabSSHClient(user, acceptTos),
                    host=self.host,
                    port=22,
                    username=user.name,
                    password=user.password,
                    options=asyncssh.SSHClientConnectionOptions(
                        known_hosts=self.knownHosts),
                )
                try:
                    stdin, stdout, stderr = await conn.open_session()
                except asyncssh.misc.ChannelOpenError:
                    raise Exception('channel_open')

                # get motd
                try:
                    conn.bclient.motd = await asyncio.wait_for(stdout.read(
                        64 * 1024),
                                                               timeout=0.5)
                except asyncio.TimeoutError:
                    pass

                c = self._conns[user] = conn
            return c
Esempio n. 2
0
    async def connect(self, options=None, **kwargs):
        """Open a connection to the test server"""

        options = asyncssh.SSHClientConnectionOptions(options, gss_host=None)

        return await asyncssh.connect(self._server_addr, self._server_port,
                                      options=options, **kwargs)
Esempio n. 3
0
    async def do_test(self, settings):
        vm_logger = logging.getLogger(self.name)

        logger.info("Waiting for SSH port to open...")
        await self.wait_for_ssh()

        logger.info("Connecting to VM...")
        client = await asyncssh.connect(
            host='localhost',
            port=5555,
            options=asyncssh.SSHClientConnectionOptions(username='******',
                                                        password='******',
                                                        known_hosts=None),
            loop=self.event_loop)
        try:
            sftp = await client.start_sftp_client()
            try:
                logger.info("Copy runtest.sh...")
                async with sftp.open('runtest.sh', 'w') as fp:
                    await fp.write(TEST_SCRIPT.format(settings=settings))
                await sftp.chmod('runtest.sh', 0o775)

                if settings.source == 'local':
                    logger.info("Copy local.tar.gz...")
                    proc = subprocess.Popen(
                        ['git', 'config', 'core.quotepath', 'off'],
                        cwd=ROOT_DIR)
                    proc.wait()
                    assert proc.returncode == 0

                    proc = subprocess.Popen([
                        'bash', '-c',
                        'tar -c -z -T<(git ls-tree --full-tree -r --name-only HEAD) -f-'
                    ],
                                            cwd=ROOT_DIR,
                                            stdout=subprocess.PIPE)
                    async with sftp.open('local.tar.gz', 'wb') as fp:
                        while True:
                            buf = proc.stdout.read(1 << 20)
                            if not buf:
                                break
                            await fp.write(buf)
                    proc.wait()
                    assert proc.returncode == 0

            finally:
                sftp.exit()

            proc = await client.create_process("./runtest.sh",
                                               stderr=subprocess.STDOUT)
            stdout_dumper = self.event_loop.create_task(
                log_dumper(proc.stdout, vm_logger.info))
            await proc.wait()
            await stdout_dumper
            assert proc.returncode == 0

        finally:
            client.close()
Esempio n. 4
0
    async def listen_reverse(cls, *, options=None, **kwargs):
        """Create a reverse SSH server for the tests to use"""

        options = asyncssh.SSHClientConnectionOptions(
            options=options, gss_host=None,
            known_hosts=(['skey.pub'], [], []))

        return await asyncssh.listen_reverse(port=0, family=socket.AF_INET,
                                             options=options, **kwargs)
Esempio n. 5
0
    def test_client_options(self):
        """Test client connection options"""

        with open('config', 'w') as f:
            f.write('User newuser\nServerAliveInterval 1')

        options = asyncssh.SSHClientConnectionOptions(username='******',
                                                      config='config')

        self.assertEqual(options.username, 'user')
        self.assertEqual(options.keepalive_interval, 1)

        with open('config', 'w') as f:
            f.write('ServerAliveInterval 2\nServerAliveCountMax 3\n')

        options = asyncssh.SSHClientConnectionOptions(options, config='config')

        self.assertEqual(options.keepalive_interval, 1)
        self.assertEqual(options.keepalive_count_max, 3)
Esempio n. 6
0
    async def create_ssh_conn(self):
        key = "%s:%d" % (self._url.address)
        if key not in self.__class__.ssh_conns:
            loop = asyncio.get_event_loop()
            options = {
                "known_hosts": None,
                "host": self._url.host,
                "port": self._url.port,
            }
            private_key_path = self._url.params.get("private_key")
            if private_key_path:
                if not os.path.isfile(private_key_path):
                    utils.logger.error(
                        "[%s] Private key file %s not found" %
                        (self.__class__.__name__, private_key_path))
                    return None
                options["client_keys"] = [private_key_path]
            if self._url.auth:
                password = None
                if ":" in self._url.auth:
                    username, password = self._url.auth.split(":", 1)
                else:
                    username = self._url.auth
                options["username"] = username
                if password:
                    if private_key_path:
                        options["passphrase"] = password
                    else:
                        options["password"] = password
            try:
                options = asyncssh.SSHClientConnectionOptions(**options)
            except (asyncssh.KeyImportError, asyncssh.KeyEncryptionError) as e:
                utils.logger.error(
                    "[%s] Import private key %s failed: %s" %
                    (self.__class__.__name__, private_key_path, e))
                return None

            utils.logger.info(
                "[%s] Create connection to ssh server %s:%d" %
                (self.__class__.__name__, self._url.host, self._url.port))
            ssh_conn = asyncssh.SSHClientConnection(loop, options, wait="auth")
            transport = tunnel.TunnelTransport(self._tunnel, ssh_conn)
            ssh_conn.connection_made(transport)
            try:
                await ssh_conn.wait_established()
            except asyncssh.PermissionDenied as e:
                utils.logger.error(
                    "[%s] Connect ssh server %s:%d auth failed: %s" %
                    (self.__class__.__name__, self._url.host, self._url.port,
                     e))
                ssh_conn.abort()
                await ssh_conn.wait_closed()
                return None
            self.__class__.ssh_conns[key] = ssh_conn
        return self.__class__.ssh_conns[key]
Esempio n. 7
0
async def run_client(port, host, user, passw, debug):
    if debug == None:
        debug = False
    async with asyncssh.connect(host,
                                port=port,
                                options=asyncssh.SSHClientConnectionOptions(
                                    known_hosts=None,
                                    username=user,
                                    password=passw)) as mainconn:
        async with mainconn.create_session(mainsession) as initshell:
            initialize(mainconn, debug)
            await cossh.main_menu(mainconn, initshell, debug)
Esempio n. 8
0
 def connect(self):
     """ Connect to control SSH server """
     controlUrl = self.controlUrl
     # remove null arguments
     connectArgs = dict(
         filter(lambda x: x[1], [('host', controlUrl.host),
                                 ('port', controlUrl.port),
                                 ('username', controlUrl.username)]))
     knownHostsFile = '/etc/ssh/ssh_known_hosts'
     if os.path.exists(knownHostsFile):
         connectArgs['options'] = asyncssh.SSHClientConnectionOptions(
             known_hosts=knownHostsFile)
     return asyncssh.connect(**connectArgs)
Esempio n. 9
0
def ssh_options_from_args(args, known_hosts):
    kw = dict()
    kw['gss_host'] = None
    kw['known_hosts'] = known_hosts
    if args.login is not None:
        kw['username'] = args.login
    if args.client_version is not None:
        kw['client_version'] = args.client_version
    if args.identity is not None:
        kw['client_keys'] = list(args.identity)
    if args.password is not None:
        kw['password'] = args.password
    return asyncssh.SSHClientConnectionOptions(**kw)
Esempio n. 10
0
    def connect(self, loop=(), options=None, **kwargs):
        """Open a connection to the test server"""

        if loop == ():
            loop = self.loop

        options = asyncssh.SSHClientConnectionOptions(options, gss_host=None)

        return (yield from asyncssh.connect(self._server_addr,
                                            self._server_port,
                                            loop=loop,
                                            options=options,
                                            **kwargs))
Esempio n. 11
0
    def listen_reverse(cls, *, loop=(), options=None, **kwargs):
        """Create a reverse SSH server for the tests to use"""

        if loop == ():
            loop = cls.loop

        options = asyncssh.SSHClientConnectionOptions(
            options=options, gss_host=None, known_hosts=(['skey.pub'], [], []))

        return (yield from asyncssh.listen_reverse(port=0,
                                                   loop=loop,
                                                   family=socket.AF_INET,
                                                   options=options,
                                                   **kwargs))
Esempio n. 12
0
 async def test_invalid_password(self):
     await self.ensure_start_server()
     options = {
         "known_hosts": None,
     }
     options = asyncssh.SSHClientConnectionOptions(**options)
     with pytest.raises(asyncssh.PermissionDenied):
         await asyncssh.connect(
             "127.0.0.1",
             self.port,
             username=self.username,
             password="******",
             options=options,
         )
     self.ensure_stop_server()
Esempio n. 13
0
async def dispatch_ssh_key(host_port, logintype, username, password_key, public_key):
    host, port = host_port.split(":")
    options = None
    if logintype == "password":
        options = asyncssh.SSHClientConnectionOptions(
            known_hosts=None, username=username, password=password_key
        )
    elif logintype == "privatekey":
        options = asyncssh.SSHClientConnectionOptions(
            known_hosts=None,
            client_username=username,
            client_keys=[asyncssh.import_private_key(password_key)],
        )

    async with asyncssh.connect(host, int(port), options=options) as ssh_connection:
        async with ssh_connection.start_sftp_client() as sftp_connection:
            is_file_present = await sftp_connection.exists(".ssh/authorized_keys")
            file_pointer = None
            if is_file_present:
                file_pointer = await sftp_connection.open(".ssh/authorized_keys", "a")
            else:
                file_pointer = await sftp_connection.open(".ssh/authorized_keys", "w")
            await file_pointer.write(public_key)
            await file_pointer.close()
Esempio n. 14
0
    async def _remote_connection(
        self,
        host: str,
        addr: Optional[str] = None,
    ) -> "SSHClientConnection":
        if not self.cons.get(host):
            if not addr and host in self.mgr.inventory:
                addr = self.mgr.inventory.get_addr(host)

            if not addr:
                raise OrchestratorError("host address is empty")

            assert self.mgr.ssh_user
            n = self.mgr.ssh_user + '@' + addr
            logger.debug(
                "Opening connection to {} with ssh options '{}'".format(
                    n, self.mgr._ssh_options))

            asyncssh.set_log_level('DEBUG')
            asyncssh.set_debug_level(3)

            with self.redirect_log(host, addr):
                try:
                    ssh_options = asyncssh.SSHClientConnectionOptions(
                        keepalive_interval=7, keepalive_count_max=3)
                    conn = await asyncssh.connect(
                        addr,
                        username=self.mgr.ssh_user,
                        client_keys=[self.mgr.tkey.name],
                        known_hosts=None,
                        config=[self.mgr.ssh_config_fname],
                        preferred_auth=['publickey'],
                        options=ssh_options)
                except OSError:
                    raise
                except asyncssh.Error:
                    raise
                except Exception:
                    raise
            self.cons[host] = conn

        self.mgr.offline_hosts_remove(host)

        return self.cons[host]
Esempio n. 15
0
        async def async_wd():
            options = asyncssh.SSHClientConnectionOptions(
                client_keys=self.key if self.key is not None else None,
                password=self.password if self.key is None else None)
            provider = asyncssh.connect
            if self.jump:
                self._tunnel = await asyncssh.connect(self.jump_host,
                                                      port=self.jump_port,
                                                      username=self.jump_user,
                                                      options=options)
                provider = self._tunnel.connect_ssh

            async with provider(self.host,
                                port=self.port,
                                keepalive_interval=60,
                                keepalive_count_max=9,
                                options=options) as conn:
                async with conn.create_process(
                        'python3 -u /tmp/iris_wd.py',
                        input='\n'.join(
                            [self.path, self.pattern, self.ignore_pattern]),
                        stderr=asyncssh.STDOUT) as process:
                    self.process = process
                    line = False
                    while True:
                        try:
                            line = (await process.stdout.readline()).split('%')
                            path, isdir, change, mtime = line
                            log.debug(
                                f'Remote WD event: {path} {isdir} {change} {mtime}'
                            )
                            if change != 'D':
                                mtime = None
                            self.tasks.put(
                                File(path, mtime, self.holder, change))
                        except Exception as e:
                            # TODO: Probably here the conn and tunnel should be closed?
                            while line:
                                log.debug(line)
                                log.debug(e)
                                line = await process.stdout.readline()
                            break
Esempio n. 16
0
 async def test_exec_command(self):
     if sys.platform == "win32":
         # Ignore on windows currently
         return
     await self.ensure_start_server()
     options = {
         "known_hosts": None,
     }
     options = asyncssh.SSHClientConnectionOptions(**options)
     async with asyncssh.connect(
             "127.0.0.1",
             self.port,
             username=self.username,
             password=self.password,
             options=options,
     ) as conn:
         message = "Hello ssh!"
         result = await conn.run('echo "%s"' % message)  # , check=True
         # assert result.stdout.strip() == message
     self.ensure_stop_server()
Esempio n. 17
0
 async def ssh_connect(self):
     options = asyncssh.SSHClientConnectionOptions(
         client_keys=self.key if self.key is not None else None,
         password=self.password if self.key is None else None)
     if self.jump:
         self._tunnel = await asyncssh.connect(self.jump_host,
                                               port=self.jump_port,
                                               username=self.jump_user,
                                               options=options)
         self._conn = await self._tunnel.connect_ssh(self.host,
                                                     port=self.port,
                                                     username=self.user,
                                                     options=options)
     else:
         self._conn = await asyncssh.connect(self.host,
                                             port=self.port,
                                             username=self.user,
                                             options=options)
     # self._conn.connection_lost = self.connection_lost
     return self._conn
Esempio n. 18
0
 async def connect(self):
     utils.logger.info(
         "[%s] Connect SSH server %s:%d..."
         % (self.__class__.__name__, self._host, self._port)
     )
     options = {
         "known_hosts": None,
         "host": self._host,
         "port": self._port,
         "username": self._username,
     }
     options = asyncssh.SSHClientConnectionOptions(**options)
     ssh_conn = await asyncssh.connect(
         self._host, self._port, known_hosts=None, username=self._username
     )
     self._channel_writer, self._channel_reader, _ = await ssh_conn.open_session(
         subsystem="tmate", env=(), send_env=(), encoding=None
     )
     ssh_conn.set_keepalive(300, 3)
     return True
Esempio n. 19
0
 async def test_tcp_forward(self):
     await self.ensure_start_server()
     server = DemoTCPServer()
     port = get_random_port()
     server.listen(port)
     options = {
         "known_hosts": None,
     }
     options = asyncssh.SSHClientConnectionOptions(**options)
     async with asyncssh.connect(
             "127.0.0.1",
             self.port,
             username=self.username,
             password=self.password,
             options=options,
     ) as conn:
         message = b"Hello ssh!"
         reader, writer = await conn.open_connection("127.0.0.1", port)
         writer.write(message + b"\n")
         buffer = await reader.read(4096)
         assert buffer.strip() == message
     self.ensure_stop_server()
 def get_ssh_conn_options(self):
     return asyncssh.SSHClientConnectionOptions(
         username=self.sftp_username,
         password=self.sftp_password,
         known_hosts=None,
         x509_trusted_certs=None)
Esempio n. 21
0
    async def _init_ssh(self, init_boot_time=True) -> None:
        await self.ssh_ready.wait()
        if not self._conn:
            self.ssh_ready.clear()
            if self.ignore_known_hosts:
                options = asyncssh.SSHClientConnectionOptions(
                    client_keys=self.pvtkey if self.pvtkey else None,
                    login_timeout=self.cmd_timeout,
                    password=self.password if not self.pvtkey else None,
                    known_hosts=None,
                    config=self.ssh_config_file)
            else:
                options = asyncssh.SSHClientConnectionOptions(
                    client_keys=self.pvtkey if self.pvtkey else None,
                    login_timeout=self.cmd_timeout,
                    password=self.password if not self.pvtkey else None,
                    config=self.ssh_config_file,
                )

            try:
                if self.jump_host:
                    self.logger.info(
                        'Using jump host: {}, with username: {}, and port: {}'.
                        format(self.jump_host, self.jump_user, self.jump_port))
                    self._tunnel = await asyncssh.connect(
                        self.jump_host,
                        port=self.jump_port,
                        options=options,
                        username=self.jump_user)
                    self.logger.info(
                        f'Connection to jump host {self.jump_host} succeeded')

            except Exception as e:
                if self.sigend:
                    self._terminate()
                    return
                self.logger.error(
                    f"ERROR: Cannot connect to jump host: {self.jump_host}, "
                    f" {str(e)}")
                self.last_exception = e
                self._conn = None
                self._tunnel = None
                self.ssh_ready.set()
                return

            try:
                self._conn = await asyncssh.connect(self.address,
                                                    tunnel=self._tunnel,
                                                    username=self.username,
                                                    port=self.port,
                                                    options=options)

                self.logger.info(
                    f"Connected to {self.address} at {time.time()}")
                self.ssh_ready.set()
                if init_boot_time:
                    await self.init_boot_time()
            except Exception as e:
                if self.sigend:
                    self._terminate()
                    return
                self.logger.error(f"ERROR: Unable to connect, {str(e)}")
                self.last_exception = e
                self._conn = None
                self._tunnel = None
                self.ssh_ready.set()
        return
Esempio n. 22
0
ecr_repo = '812345574397.dkr.ecr.us-west-2.amazonaws.com'
s3_bucket = 'aft-experiment-logs'

cmd_template = (
   '{{ /home/ubuntu/miniconda3/bin/python -m awscli ecr get-login-password --region us-west-2 ' +
   '| docker login --username AWS --password-stdin {ecr_repo} ; }} && ' +
   'docker pull {ecr_repo}/aft_exp:latest && ' +
   'docker run --rm -it {ecr_repo}/aft_exp:latest --dataset {dataset} ' +
   '--distribution {distribution} --test_fold_id {test_fold_id} --seed 1 --sampler {sampler} ' +
   '--nthread {nthread} --ntrial {ntrial} --s3_bucket {s3_bucket}'
)

opts = asyncssh.SSHClientConnectionOptions(
    client_keys='./bench.pem',
    username='******',
    password=None,  #  Do not permit password authentication
    known_hosts=None
)

async def run_client(hostname, cmd, max_tries, logfile):
    sleep_time = 5
    with open(logfile, 'w') as f:
        print('', file=f, end='')
    for _ in range(max_tries):
        try:
            async with asyncssh.connect(hostname, options=opts) as conn:
                print(f'[{hostname}] Conneciton successful')
                async with conn.create_process(cmd, term_type='xterm-color',
                                               stderr=asyncssh.STDOUT) as process:
                    async for line in process.stdout:
                        with open(logfile, 'a') as f:
async def _get_server_host_key(host,
                               port=(),
                               *,
                               tunnel=(),
                               family=(),
                               flags=0,
                               local_addr=None,
                               client_version=(),
                               kex_algs=(),
                               server_host_key_algs=(),
                               config=(),
                               options=None):
    """Retrieve an SSH server's host key

       This is a coroutine which can be run to connect to an SSH server and
       return the server host key presented during the SSH handshake.

       A list of server host key algorithms can be provided to specify
       which host key types the server is allowed to choose from. If the
       key exchange is successful, the server host key sent during the
       handshake is returned.

           .. note:: Not all key exchange methods involve the server
                     presenting a host key. If something like GSS key
                     exchange is used without a server host key, this
                     method may return `None` even when the handshake
                     completes.

       :param host:
           The hostname or address to connect to
       :param port: (optional)
           The port number to connect to. If not specified, the default
           SSH port is used.
       :param tunnel: (optional)
           An existing SSH client connection that this new connection should
           be tunneled over. If set, a direct TCP/IP tunnel will be opened
           over this connection to the requested host and port rather than
           connecting directly via TCP. A string of the form
           [user@]host[:port] may also be specified, in which case a
           connection will first be made to that host and it will then be
           used as a tunnel.
       :param family: (optional)
           The address family to use when creating the socket. By default,
           the address family is automatically selected based on the host.
       :param flags: (optional)
           The flags to pass to getaddrinfo() when looking up the host address
       :param local_addr: (optional)
           The host and port to bind the socket to before connecting
       :param client_version: (optional)
           An ASCII string to advertise to the SSH server as the version of
           this client, defaulting to `'AsyncSSH'` and its version number.
       :param kex_algs: (optional)
           A list of allowed key exchange algorithms in the SSH handshake,
           taken from :ref:`key exchange algorithms <KexAlgs>`
       :param server_host_key_algs: (optional)
           A list of server host key algorithms to allow during the SSH
           handshake, taken from :ref:`server host key algorithms
           <PublicKeyAlgs>`.
       :param config: (optional)
           Paths to OpenSSH client configuration files to load. This
           configuration will be used as a fallback to override the
           defaults for settings which are not explcitly specified using
           AsyncSSH's configuration options. If no paths are specified,
           an attempt will be made to load the configuration from the file
           :file:`.ssh/config`. If this argument is explicitly set to
           `None`, no OpenSSH configuration files will be loaded. See
           :ref:`SupportedClientConfigOptions` for details on what
           configuration options are currently supported.
       :param options: (optional)
           Options to use when establishing the SSH client connection used
           to retrieve the server host key. These options can be specified
           either through this parameter or as direct keyword arguments to
           this function.
       :type host: `str`
       :type port: `int`
       :type tunnel: :class:`SSHClientConnection` or `str`
       :type family: `socket.AF_UNSPEC`, `socket.AF_INET`, or `socket.AF_INET6`
       :type flags: flags to pass to :meth:`getaddrinfo() <socket.getaddrinfo>`
       :type local_addr: tuple of `str` and `int`
       :type client_version: `str`
       :type kex_algs: `str` or `list` of `str`
       :type server_host_key_algs: `str` or `list` of `str`
       :type config: `list` of `str`
       :type options: :class:`SSHClientConnectionOptions`

       :returns: An :class:`SSHKey` public key or `None`

    """
    def conn_factory():
        """Return an SSH client connection factory"""

        return asyncssh.SSHClientConnection(loop, options, wait='kex')

    loop = asyncio.get_event_loop()

    options = asyncssh.SSHClientConnectionOptions(
        options,
        config=config,
        host=host,
        port=port,
        tunnel=tunnel,
        family=family,
        local_addr=local_addr,
        known_hosts=None,
        server_host_key_algs=server_host_key_algs,
        x509_trusted_certs=None,
        x509_trusted_cert_paths=None,
        x509_purposes='any',
        gss_host=None,
        kex_algs=kex_algs,
        client_version=client_version)

    conn = await asyncssh.connection._connect(options.host, options.port, loop,
                                              options.tunnel, options.family,
                                              flags, options.local_addr,
                                              conn_factory,
                                              'Fetching server host key from')

    server_host_key = conn.get_server_host_key()
    try:
        server_version = conn.get_extra_info('server_version')
    except:
        server_version = ''
    conn.abort()

    await conn.wait_closed()
    return server_version, server_host_key