Exemplo n.º 1
0
 def test_recv_raises_timeout_if_nothing_read(self, select, os_read, Popen):
     stdout = Popen.return_value.stdout
     select.return_value = [stdout], None, None
     fileno = stdout.fileno.return_value
     os_read.side_effect = socket.timeout
     proxy = ProxyCommand("hi")
     with raises(socket.timeout):
         proxy.recv(5)
     assert os_read.call_args[0] == (fileno, 5)
Exemplo n.º 2
0
 def test_recv_returns_buffer_on_timeout_if_any_read(
         self, select, os_read, Popen):
     stdout = Popen.return_value.stdout
     select.return_value = [stdout], None, None
     fileno = stdout.fileno.return_value
     os_read.side_effect = [b"was", socket.timeout]
     proxy = ProxyCommand("hi")
     data = proxy.recv(5)
     assert data == b"was"  # not b"waste"
     assert os_read.call_args[0] == (fileno, 2)
Exemplo n.º 3
0
 def test_recv_reads_from_process_stdout_returning_bytes(
         self, select, os_read, Popen):
     stdout = Popen.return_value.stdout
     select.return_value = [stdout], None, None
     fileno = stdout.fileno.return_value
     # Intentionally returning <5 at a time sometimes
     os_read.side_effect = [b"was", b"te", b"of ti", b"me"]
     proxy = ProxyCommand("hi")
     data = proxy.recv(5)
     assert data == b"waste"
     assert [x[0] for x in os_read.call_args_list] == [
         (fileno, 5),
         (fileno, 2),
     ]
Exemplo n.º 4
0
 def openconnection(self):
     if (self.grid_params["short_name"] == "hopper"
             or self.grid_params["short_name"] == "edison"):
         print "connecting ", self.grid_params["short_name"]
         self.client = SSHClient()
         self.client.set_missing_host_key_policy(client.AutoAddPolicy())
         self.client.load_system_host_keys()
         self.client.connect(self.grid_params["full_name"],
                             allow_agent=True)
         self.sftp = self.client.open_sftp()
     else:
         proxy_command = 'ssh %s nc %s %s' % (
             'aluf.technion.ac.il', self.grid_params["full_name"], 22)
         proxy = ProxyCommand(proxy_command)
         self.client = SSHClient()
         self.client.load_system_host_keys()
         self.client.connect(self.grid_params["short_name"],
                             sock=proxy,
                             allow_agent=True)
     self.sftp = self.client.open_sftp()
     stdin, stdout, stderr = self.client.exec_command("pwd")
     home = stdout.readlines()[0].rstrip()
     print home
     self.grid_params['home'] = home
     print "Connection Open"
Exemplo n.º 5
0
    def _configure(self):
        """ Configure the ssh parameters from the config file. """
        configfile = expanduser("~/.ssh/config")
        if not isfile(configfile):
            raise GerritError("ssh config file '%s' does not exist" %
                              configfile)

        config = SSHConfig()
        config.parse(open(configfile))
        data = config.lookup(self.hostname)
        if not data:
            raise GerritError("No ssh config for host %s" % self.hostname)
        if 'hostname' not in data or 'port' not in data or 'user' not in data:
            raise GerritError("Missing configuration data in %s" % configfile)
        self.hostname = data['hostname']
        self.username = data['user']
        if 'identityfile' in data:
            key_filename = abspath(expanduser(data['identityfile'][0]))
            if not isfile(key_filename):
                raise GerritError("Identity file '%s' does not exist" %
                                  key_filename)
            self.key_filename = key_filename
        try:
            self.port = int(data['port'])
        except ValueError:
            raise GerritError("Invalid port: %s" % data['port'])
        if 'proxycommand' in data:
            self.proxy = ProxyCommand(data['proxycommand'])
Exemplo n.º 6
0
    def _get_proxy_command(self, port=22):
        proxy_command = None

        # TO-DO: Add logic to scan ssh_* args to read ProxyCommand

        proxy_command = self.get_option("proxy_command")

        sock = None
        if proxy_command:
            if Version(NCCLIENT_VERSION) < "0.6.10":
                raise AnsibleError(
                    "Configuring jumphost settings through ProxyCommand is unsupported in ncclient version %s. "
                    "Please upgrade to ncclient 0.6.10 or newer." %
                    NCCLIENT_VERSION)

            replacers = {
                "%h": self._play_context.remote_addr,
                "%p": port,
                "%r": self._play_context.remote_user,
            }

            for find, replace in replacers.items():
                proxy_command = proxy_command.replace(find, str(replace))
            sock = ProxyCommand(proxy_command)

        return sock
Exemplo n.º 7
0
 def test_closed_exposes_whether_subprocess_has_exited(self, Popen):
     proxy = ProxyCommand("hi")
     Popen.return_value.returncode = None
     assert proxy.closed is False
     assert proxy._closed is False
     Popen.return_value.returncode = 0
     assert proxy.closed is True
     assert proxy._closed is True
Exemplo n.º 8
0
 def test_recv_raises_ProxyCommandFailure_on_non_timeout_error(
         self, select, os_read, Popen):
     select.return_value = [Popen.return_value.stdout], None, None
     os_read.side_effect = IOError(0, "whoops")
     with raises(ProxyCommandFailure) as info:
         ProxyCommand("hi").recv(5)
     assert info.value.command == "hi"
     assert info.value.error == "whoops"
Exemplo n.º 9
0
 def test_init_takes_command_string(self, subprocess):
     ProxyCommand(command_line="do a thing")
     subprocess.Popen.assert_called_once_with(
         ["do", "a", "thing"],
         stdin=subprocess.PIPE,
         stdout=subprocess.PIPE,
         stderr=subprocess.PIPE,
         bufsize=0,
     )
Exemplo n.º 10
0
 def test_timeout_affects_whether_timeout_is_raised(self, select, os_read,
                                                    Popen, time):
     stdout = Popen.return_value.stdout
     select.return_value = [stdout], None, None
     # Base case: None timeout means no timing out
     os_read.return_value = b"meh"
     proxy = ProxyCommand("yello")
     assert proxy.timeout is None
     # Implicit 'no raise' check
     assert proxy.recv(3) == b"meh"
     # Use settimeout to set timeout, and it is honored
     time.side_effect = [0, 10]  # elapsed > 7
     proxy = ProxyCommand("ohnoz")
     proxy.settimeout(7)
     assert proxy.timeout == 7
     with raises(socket.timeout):
         proxy.recv(3)
Exemplo n.º 11
0
def ssh_connection(hostname):
    host = ssh_config(hostname)
    ssh_client = SSHClient()
    ssh_client.load_system_host_keys()

    try:
        ssh_client.connect(host['hostname'],
                           username=host['user'],
                           sock=ProxyCommand(host.get('proxycommand')))
        return ssh_client
    except:
        ssh_client.connect(host['hostname'], username=host['user'])
        return ssh_client
def scp_upload(src_blob='Preproc.tar.gz',
               dst_blob="~",
               options={
                   'hostname': 'lecun',
                   'username': '******'
               },
               progress=simple_callback):
    # from https://gist.github.com/acdha/6064215

    #--- Make the Paramiko SSH thing use my .ssh/config file (b/c I like ProxyCommand!)
    client = SSHClient()
    client.load_system_host_keys()
    client._policy = WarningPolicy()
    client.set_missing_host_key_policy(
        WarningPolicy())  # hmm. WarningPolicy? Most people use AutoAddPolicy.

    ssh_config = SSHConfig()
    user_config_file = os.path.expanduser("~/.ssh/config")
    if os.path.exists(user_config_file):
        with open(user_config_file) as f:
            ssh_config.parse(f)

    cfg = {'hostname': options['hostname'], 'username': options["username"]}

    user_config = ssh_config.lookup(cfg['hostname'])
    for k in ('hostname', 'username', 'port'):
        if k in user_config:
            cfg[k] = user_config[k]

    if 'proxycommand' in user_config:
        cfg['sock'] = ProxyCommand(user_config['proxycommand'])

    client.connect(**cfg)

    socket_timeout = None  # number of seconds for timeout. None = never timeout. TODO: None means program may hang. But timeouts are annoying!

    # SCPCLient takes a paramiko transport and progress callback as its arguments.
    scp = SCPClient(client.get_transport(),
                    progress=progress,
                    socket_timeout=socket_timeout)

    # NOW we can finally upload! (in a separate process)
    #scp.put(src_blob, dst_blob)   # now in scp_thread

    # we want this to be non-blocking so we stick it in a thread
    thread = threading.Thread(target=scp_thread,
                              args=(scp, src_blob, dst_blob))
    thread.start()
Exemplo n.º 13
0
    def parse_config(self, hostname):
        cfg = {'port': 22}
        forward_agent = False

        ssh_config = get_ssh_config()
        if not ssh_config:
            return hostname, cfg, forward_agent

        host_config = ssh_config.lookup(hostname)
        forward_agent = host_config.get('forwardagent') == 'yes'

        if 'hostname' in host_config:
            hostname = host_config['hostname']

        if 'user' in host_config:
            cfg['username'] = host_config['user']

        if 'identityfile' in host_config:
            cfg['key_filename'] = host_config['identityfile']

        if 'port' in host_config:
            cfg['port'] = int(host_config['port'])

        if 'proxycommand' in host_config:
            cfg['sock'] = ProxyCommand(host_config['proxycommand'])
        elif 'proxyjump' in host_config:
            hops = host_config['proxyjump'].split(',')
            sock = None
            for i, hop in enumerate(hops):
                hop_hostname, hop_config = self.derive_shorthand(hop)
                c = SSHClient()
                c.set_missing_host_key_policy(AutoAddPolicy())
                c.connect(hop_hostname, sock=sock, **hop_config)
                if i == len(hops) - 1:
                    target = hostname
                    target_config = {'port': cfg['port']}
                else:
                    target, target_config = self.derive_shorthand(hops[i + 1])
                sock = c.gateway(target, target_config['port'])
            cfg['sock'] = sock

        return hostname, cfg, forward_agent
Exemplo n.º 14
0
def update_database():
    if os.uname()[1] in ('workstation', ):
        print("Actualizando copia local de la base de datos...")
        host = 'ha-remote'
        ssh = SSHClient()
        ssh_config_file = os.path.expanduser("~/.ssh/config")
        if os.path.exists(ssh_config_file):
            conf = SSHConfig()
            with open(ssh_config_file) as f:
                conf.parse(f)
            host_config = conf.lookup(host)
        proxy = ProxyCommand("ssh {}@{} -p {} nc {} 22".format(
            "pi", "remote-ssh.proxy.host", 2222, 'homeassistant-host'))
        ssh.load_system_host_keys()
        ssh.set_missing_host_key_policy(AutoAddPolicy())
        #ssh.connect(host, username=user, pkey=pkey, sock=proxy)
        ssh.connect(host, username=host_config['user'], sock=proxy)
        with SCPClient(ssh.get_transport()) as scp:
            src = '/home/homeassistant/devel/hamlfeeder/database.sqlite'
            dst = '/home/roberto/devel/python/hamlfeeder/database.sqlite'
            scp.get(src, dst)
Exemplo n.º 15
0
    def parse_config(self, hostname):
        cfg = {
            'port': 22,
        }

        user_config_file = os.path.expanduser('~/.ssh/config')
        if os.path.exists(user_config_file):
            with open(user_config_file) as f:
                ssh_config = SSHConfig()
                ssh_config.parse(f)
                host_config = ssh_config.lookup(hostname)
                if 'hostname' in host_config:
                    hostname = host_config['hostname']
                if 'user' in host_config:
                    cfg['username'] = host_config['user']
                if 'identityfile' in host_config:
                    cfg['key_filename'] = host_config['identityfile']
                if 'port' in host_config:
                    cfg['port'] = int(host_config['port'])
                if 'proxycommand' in host_config:
                    cfg['sock'] = ProxyCommand(host_config['proxycommand'])
                elif 'proxyjump' in host_config:
                    hops = host_config['proxyjump'].split(',')
                    sock = None
                    for i, hop in enumerate(hops):
                        hop_hostname, hop_config = self.derive_shorthand(hop)
                        c = SSHClient()
                        c.set_missing_host_key_policy(AutoAddPolicy())
                        c.connect(hop_hostname, sock=sock, **hop_config)
                        if i == len(hops) - 1:
                            target = hostname
                            target_config = {'port': cfg['port']}
                        else:
                            target, target_config = self.derive_shorthand(
                                hops[i + 1])
                        sock = c.gateway(target, target_config['port'])
                    cfg['sock'] = sock
        return hostname, cfg
Exemplo n.º 16
0
    def connect(self):
        host_config = self.config.lookup(self.host)
        log.debug('ssh-config: %s' % host_config)

        forwardagent = host_config.get('forwardagent')
        if forwardagent is not None and forwardagent == 'yes':
            self.forward_agent = True
            log.debug('forwarding agent is enabled')

        param = {
            'sock': None,
            'timeout': 10.0,
        }

        proxy_command = host_config.get('proxycommand')
        if proxy_command is not None:
            param['sock'] = ProxyCommand(proxy_command)

        if self.credential is not None:
            param.update(self.credential.connect_param)

        self.client.connect(self.host, **param)
        log.info('connected: %s' % self.host)
Exemplo n.º 17
0
    def parse_config(
        self,
        hostname,
        initial_cfg=None,
        ssh_config_file=None,
        strict_host_key_checking=None,
    ):
        cfg = {"port": 22}
        cfg.update(initial_cfg or {})

        forward_agent = False
        missing_host_key_policy = get_missing_host_key_policy(strict_host_key_checking)
        host_keys_file = path.expanduser("~/.ssh/known_hosts")  # OpenSSH default

        ssh_config = get_ssh_config(ssh_config_file)
        if not ssh_config:
            return hostname, cfg, forward_agent, missing_host_key_policy, host_keys_file

        host_config = ssh_config.lookup(hostname)
        forward_agent = host_config.get("forwardagent") == "yes"

        # If not overridden, apply any StrictHostKeyChecking
        if strict_host_key_checking is None and "stricthostkeychecking" in host_config:
            missing_host_key_policy = get_missing_host_key_policy(
                host_config["stricthostkeychecking"],
            )

        if "userknownhostsfile" in host_config:
            host_keys_file = path.expanduser(host_config["userknownhostsfile"])

        if "hostname" in host_config:
            hostname = host_config["hostname"]

        if "user" in host_config:
            cfg["username"] = host_config["user"]

        if "identityfile" in host_config:
            cfg["key_filename"] = host_config["identityfile"]

        if "port" in host_config:
            cfg["port"] = int(host_config["port"])

        if "proxycommand" in host_config:
            cfg["sock"] = ProxyCommand(host_config["proxycommand"])

        elif "proxyjump" in host_config:
            hops = host_config["proxyjump"].split(",")
            sock = None

            for i, hop in enumerate(hops):
                hop_hostname, hop_config = self.derive_shorthand(ssh_config, hop)
                logger.debug("SSH ProxyJump through %s:%s", hop_hostname, hop_config["port"])

                c = SSHClient()
                c.connect(
                    hop_hostname, _pyinfra_ssh_config_file=ssh_config_file, sock=sock, **hop_config
                )

                if i == len(hops) - 1:
                    target = hostname
                    target_config = {"port": cfg["port"]}
                else:
                    target, target_config = self.derive_shorthand(ssh_config, hops[i + 1])

                sock = c.gateway(hostname, cfg["port"], target, target_config["port"])
            cfg["sock"] = sock

        return hostname, cfg, forward_agent, missing_host_key_policy, host_keys_file
Exemplo n.º 18
0
 def test_send_raises_ProxyCommandFailure_on_error(self, Popen):
     Popen.return_value.stdin.write.side_effect = IOError(0, "whoops")
     with raises(ProxyCommandFailure) as info:
         ProxyCommand("hi").send("data")
     assert info.value.command == "hi"
     assert info.value.error == "whoops"
Exemplo n.º 19
0
    def connect(self, username=None, password=None,
                accept_missing_host_key=True, tcp_timeout=30,
                auth_strategy=SSHAuthStrategy.PASSWORD,
                port=22, key=None, allow_agent=True, key_filename=None):
        """
        Attempts to connect to a remote server via SSH

        @param username: Username to be used for SSH connection
        @type username: string
        @param password: Password to be used for SSH connection
        @type password: string
        @param auth_strategy: Authentication strategy to use to connect
        @type auth_strategy: string
        @param port: Port to use for the SSH connection
        @type port: int
        @param key: Text of an SSH key to be used to connect
        @type key: string
        @param key_filename: Name of a file that contains a SSH key
        @type key_filename: string
        @param allow_agent: Set to False to disable connecting to
                            the SSH agent
        @type allow_agent: bool
        @param accept_missing_host_key: Sets if a SSH connection can
                                        be made to remote server if
                                        the server does not have a
                                        host key in the local system
        @type accept_missing_host_key: bool
        @return: None
        """

        ssh = ExtendedParamikoSSHClient()
        if accept_missing_host_key:
            ssh.set_missing_host_key_policy(AutoAddPolicy())

        connect_args = {'hostname': self.host, 'username': username,
                        'timeout': tcp_timeout, 'port': port,
                        'allow_agent': allow_agent}

        self._log.debug('Attempting to SSH connect to {host} '
                        'with user {user} and strategy {strategy}.'.format(
                            host=self.host, user=username,
                            strategy=auth_strategy))

        if auth_strategy == SSHAuthStrategy.PASSWORD:
            connect_args['password'] = password

        if auth_strategy == SSHAuthStrategy.LOCAL_KEY:
            connect_args['look_for_keys'] = True

        if auth_strategy == SSHAuthStrategy.KEY_STRING:
            key_file = io.StringIO(key)
            key = RSAKey.from_private_key(key_file)
            connect_args['pkey'] = key

        if auth_strategy == SSHAuthStrategy.KEY_FILE_LIST:
            connect_args['key_filename'] = key_filename

        # Add sock proxy if ssh tunnel through proxy/bastion is required
        if self.is_proxy_needed():
            self._log.info("Using a proxy: {proxy}".format(proxy=self.proxy))
            proxy_str = 'ssh -q -a -x {proxy} nc {host} {port}'
            proxy_cmd = proxy_str.format(proxy=self.proxy,
                                         host=self.host, port=port)
            connect_args['sock'] = ProxyCommand(proxy_cmd)

        try:
            ssh.connect(**connect_args)
        except (AuthenticationException, SSHException,
                socket.error, EOFError) as exception:
            # Log the failure
            self._log.error(exception.message)
        else:
            # Complete setup of the client
            ResourceManager.register(self, ssh.get_transport())
            self.ssh_connection = ssh
Exemplo n.º 20
0
def ssh_paramiko_connect_to(display_desc):
    #plain socket attributes:
    dtype = display_desc["type"]
    host = display_desc["host"]
    port = display_desc.get("ssh-port", 22)
    #ssh and command attributes:
    username = display_desc.get("username") or get_username()
    if "proxy_host" in display_desc:
        display_desc.setdefault("proxy_username", get_username())
    password = display_desc.get("password")
    remote_xpra = display_desc["remote_xpra"]
    proxy_command = display_desc["proxy_command"]       #ie: "_proxy_start"
    socket_dir = display_desc.get("socket_dir")
    display = display_desc.get("display")
    display_as_args = display_desc["display_as_args"]   #ie: "--start=xterm :10"
    paramiko_config = display_desc.copy()
    paramiko_config.update(display_desc.get("paramiko-config", {}))
    socket_info = {
            "host"  : host,
            "port"  : port,
            }
    def get_keyfiles(host_config, config_name="key"):
        keyfiles = (host_config or {}).get("identityfile") or get_default_keyfiles()
        keyfile = paramiko_config.get(config_name)
        if keyfile:
            keyfiles.insert(0, keyfile)
        return keyfiles

    with nogssapi_context():
        from paramiko import SSHConfig, ProxyCommand
        ssh_config = SSHConfig()
        user_config_file = os.path.expanduser("~/.ssh/config")
        sock = None
        host_config = None
        if os.path.exists(user_config_file):
            with open(user_config_file) as f:
                ssh_config.parse(f)
            log("parsed user config '%s': %i hosts found", user_config_file, len(ssh_config.get_hostnames()))
            host_config = ssh_config.lookup(host)
            if host_config:
                log("got host config for '%s': %s", host, host_config)
                chost = host_config.get("hostname", host)
                cusername = host_config.get("user", username)
                cport = host_config.get("port", port)
                try:
                    port = int(cport)
                except (TypeError, ValueError):
                    raise InitExit(EXIT_SSH_FAILURE, "invalid ssh port specified: '%s'" % cport) from None
                proxycommand = host_config.get("proxycommand")
                if proxycommand:
                    log("found proxycommand='%s' for host '%s'", proxycommand, chost)
                    sock = ProxyCommand(proxycommand)
                    log("ProxyCommand(%s)=%s", proxycommand, sock)
                    from xpra.child_reaper import getChildReaper
                    cmd = getattr(sock, "cmd", [])
                    def proxycommand_ended(proc):
                        log("proxycommand_ended(%s) exit code=%s", proc, proc.poll())
                    getChildReaper().add_process(sock.process, "paramiko-ssh-client", cmd, True, True,
                                                 callback=proxycommand_ended)
                    proxy_keys = get_keyfiles(host_config, "proxy_key")
                    log("proxy keys=%s", proxy_keys)
                    from paramiko.client import SSHClient
                    ssh_client = SSHClient()
                    ssh_client.load_system_host_keys()
                    log("ssh proxy command connect to %s", (chost, cport, sock))
                    ssh_client.connect(chost, cport, sock=sock)
                    transport = ssh_client.get_transport()
                    do_ssh_paramiko_connect_to(transport, chost,
                                               cusername, password,
                                               host_config or ssh_config.lookup("*"),
                                               proxy_keys,
                                               paramiko_config)
                    chan = paramiko_run_remote_xpra(transport, proxy_command, remote_xpra, socket_dir, display_as_args)
                    peername = (chost, cport)
                    conn = SSHProxyCommandConnection(chan, peername, peername, socket_info)
                    conn.target = host_target_string("ssh", cusername, chost, port, display)
                    conn.timeout = SOCKET_TIMEOUT
                    conn.start_stderr_reader()
                    conn.process = (sock.process, "ssh", cmd)
                    from xpra.net import bytestreams
                    from paramiko.ssh_exception import ProxyCommandFailure
                    bytestreams.CLOSED_EXCEPTIONS = tuple(list(bytestreams.CLOSED_EXCEPTIONS)+[ProxyCommandFailure])
                    return conn

        keys = get_keyfiles(host_config)
        from xpra.scripts.main import socket_connect
        from paramiko.transport import Transport
        from paramiko import SSHException
        if "proxy_host" in display_desc:
            proxy_host = display_desc["proxy_host"]
            proxy_port = display_desc.get("proxy_port", 22)
            proxy_username = display_desc.get("proxy_username", username)
            proxy_password = display_desc.get("proxy_password", password)
            proxy_keys = get_keyfiles(host_config, "proxy_key")
            sock = socket_connect(dtype, proxy_host, proxy_port)
            middle_transport = Transport(sock)
            middle_transport.use_compression(False)
            try:
                middle_transport.start_client()
            except SSHException as e:
                log("start_client()", exc_info=True)
                raise InitExit(EXIT_SSH_FAILURE, "SSH negotiation failed: %s" % e) from None
            proxy_host_config = ssh_config.lookup(host)
            do_ssh_paramiko_connect_to(middle_transport, proxy_host,
                                       proxy_username, proxy_password,
                                       proxy_host_config or ssh_config.lookup("*"),
                                       proxy_keys,
                                       paramiko_config)
            log("Opening proxy channel")
            chan_to_middle = middle_transport.open_channel("direct-tcpip", (host, port), ('localhost', 0))

            transport = Transport(chan_to_middle)
            transport.use_compression(False)
            try:
                transport.start_client()
            except SSHException as e:
                log("start_client()", exc_info=True)
                raise InitExit(EXIT_SSH_FAILURE, "SSH negotiation failed: %s" % e)
            do_ssh_paramiko_connect_to(transport, host,
                                       username, password,
                                       host_config or ssh_config.lookup("*"),
                                       keys,
                                       paramiko_config)
            chan = paramiko_run_remote_xpra(transport, proxy_command, remote_xpra, socket_dir, display_as_args)
            peername = (host, port)
            conn = SSHProxyCommandConnection(chan, peername, peername, socket_info)
            conn.target = "%s via %s" % (
                host_target_string("ssh", username, host, port, display),
                host_target_string("ssh", proxy_username, proxy_host, proxy_port, None),
                )
            conn.timeout = SOCKET_TIMEOUT
            conn.start_stderr_reader()
            return conn

        #plain TCP connection to the server,
        #we open it then give the socket to paramiko:
        sock = socket_connect(dtype, host, port)
        sockname = sock.getsockname()
        peername = sock.getpeername()
        log("paramiko socket_connect: sockname=%s, peername=%s", sockname, peername)
        transport = Transport(sock)
        transport.use_compression(False)
        try:
            transport.start_client()
        except SSHException as e:
            log("start_client()", exc_info=True)
            raise InitExit(EXIT_SSH_FAILURE, "SSH negotiation failed: %s" % e) from None
        do_ssh_paramiko_connect_to(transport, host, username, password,
                                   host_config or ssh_config.lookup("*"),
                                   keys,
                                   paramiko_config)
        chan = paramiko_run_remote_xpra(transport, proxy_command, remote_xpra, socket_dir, display_as_args)
        conn = SSHSocketConnection(chan, sock, sockname, peername, (host, port), socket_info)
        conn.target = host_target_string("ssh", username, host, port, display)
        conn.timeout = SOCKET_TIMEOUT
        conn.start_stderr_reader()
        return conn
Exemplo n.º 21
0
 def test_raises_subprocess_ImportErrors_at_runtime(self):
     # Not an ideal test, but I don't know of a non-bad way to fake out
     # module-time ImportErrors. So we mock the symptoms. Meh!
     with raises(ImportError) as info:
         ProxyCommand("hi!!!")
     assert str(info.value) == "meh"
Exemplo n.º 22
0
 def test_close_kills_subprocess(self, os_kill, Popen):
     proxy = ProxyCommand("hi")
     proxy.close()
     os_kill.assert_called_once_with(Popen.return_value.pid, signal.SIGTERM)
Exemplo n.º 23
0
def ssh(host,
        forward_agent=False,
        sudoable=False,
        max_attempts=1,
        max_timeout=5,
        ssh_password=None):
    """Manages a SSH connection to the desired host.
       Will leverage your ssh config at ~/.ssh/config if available

    :param host: the server to connect to
    :type host: str
    :param forward_agent: forward the local agents
    :type forward_agent: bool
    :param sudoable: allow sudo commands
    :type sudoable: bool
    :param max_attempts: the maximum attempts to connect to the desired host
    :type max_attempts: int
    :param max_timeout: the maximum timeout in seconds to sleep between attempts
    :type max_timeout: int
    :param ssh_password: SSH password to use if needed
    :type ssh_password: str
    :returns a SSH connection to the desired host
    :rtype: Connection

    :raises MaxConnectionAttemptsError: Exceeded the maximum attempts
    to establish the SSH connection.
    """
    with closing(SSHClient()) as client:
        client.set_missing_host_key_policy(AutoAddPolicy())

        cfg = {
            "hostname": host,
            "timeout": max_timeout,
        }
        if ssh_password:
            cfg['password'] = ssh_password

        ssh_config = SSHConfig()
        user_config_file = os.path.expanduser("~/.ssh/config")
        if os.path.exists(user_config_file):
            with open(user_config_file) as f:
                ssh_config.parse(f)
                host_config = ssh_config.lookup(host)
                if "user" in host_config:
                    cfg["username"] = host_config["user"]

                if "proxycommand" in host_config:
                    cfg["sock"] = ProxyCommand(host_config["proxycommand"])

                if "identityfile" in host_config:
                    cfg['key_filename'] = host_config['identityfile']

                if "port" in host_config:
                    cfg["port"] = int(host_config["port"])

        attempts = 0
        while attempts < max_attempts:
            try:
                attempts += 1
                client.connect(**cfg)
                break
            except socket.error as e:
                if attempts < max_attempts:
                    print("SSH to host {0} failed, retrying...".format(host))
                    time.sleep(max_timeout)
                else:
                    print("SSH Exception: {0}".format(e))

        else:
            raise MaxConnectionAttemptsError(
                "Exceeded max attempts to connect to host {0} after {1} retries"
                .format(host, max_attempts))

        yield Connection(client, forward_agent, sudoable)
Exemplo n.º 24
0
def ssh_paramiko_connect_to(display_desc):
    #plain socket attributes:
    dtype = display_desc["type"]
    host = display_desc["host"]
    port = display_desc.get("ssh-port", 22)
    #ssh and command attributes:
    username = display_desc.get("username") or get_username()
    if "proxy_host" in display_desc:
        display_desc.setdefault("proxy_username", get_username())
    password = display_desc.get("password")
    target = ssh_target_string(display_desc)
    remote_xpra = display_desc["remote_xpra"]
    proxy_command = display_desc["proxy_command"]  #ie: "_proxy_start"
    socket_dir = display_desc.get("socket_dir")
    display_as_args = display_desc["display_as_args"]  #ie: "--start=xterm :10"
    socket_info = {
        "host": host,
        "port": port,
    }
    with nogssapi_context():
        from paramiko import SSHConfig, ProxyCommand
        ssh_config = SSHConfig()
        user_config_file = os.path.expanduser("~/.ssh/config")
        sock = None
        host_config = None
        if os.path.exists(user_config_file):
            with open(user_config_file) as f:
                ssh_config.parse(f)
            host_config = ssh_config.lookup(host)
            if host_config:
                host = host_config.get("hostname", host)
                username = host_config.get("username", username)
                port = host_config.get("port", port)
                proxycommand = host_config.get("proxycommand")
                if proxycommand:
                    sock = ProxyCommand(proxycommand)
                    from xpra.child_reaper import getChildReaper
                    cmd = getattr(sock, "cmd", [])
                    getChildReaper().add_process(sock.process,
                                                 "paramiko-ssh-client", cmd,
                                                 True, True)
                    log("found proxycommand='%s' for host '%s'", proxycommand,
                        host)
                    from paramiko.client import SSHClient
                    ssh_client = SSHClient()
                    ssh_client.load_system_host_keys()
                    ssh_client.connect(host, port, sock=sock)
                    transport = ssh_client.get_transport()
                    do_ssh_paramiko_connect_to(
                        transport, host, username, password, host_config
                        or ssh_config.lookup("*"))
                    chan = paramiko_run_remote_xpra(transport, proxy_command,
                                                    remote_xpra, socket_dir,
                                                    display_as_args)
                    peername = (host, port)
                    conn = SSHProxyCommandConnection(chan, peername, target,
                                                     socket_info)
                    conn.timeout = SOCKET_TIMEOUT
                    conn.start_stderr_reader()
                    conn.process = (sock.process, "ssh", cmd)
                    from xpra.net import bytestreams
                    from paramiko.ssh_exception import ProxyCommandFailure
                    bytestreams.CLOSED_EXCEPTIONS = tuple(
                        list(bytestreams.CLOSED_EXCEPTIONS) +
                        [ProxyCommandFailure])
                    return conn
        from xpra.scripts.main import socket_connect
        from paramiko.transport import Transport
        from paramiko import SSHException
        if "proxy_host" in display_desc:
            proxy_host = display_desc["proxy_host"]
            proxy_port = display_desc.get("proxy_port", 22)
            proxy_username = display_desc.get("proxy_username", username)
            proxy_password = display_desc.get("proxy_password", password)
            sock = socket_connect(dtype, proxy_host, proxy_port)
            middle_transport = Transport(sock)
            middle_transport.use_compression(False)
            try:
                middle_transport.start_client()
            except SSHException as e:
                log("start_client()", exc_info=True)
                raise InitException("SSH negotiation failed: %s" % e)
            proxy_host_config = ssh_config.lookup(host)
            do_ssh_paramiko_connect_to(
                middle_transport, proxy_host, proxy_username, proxy_password,
                proxy_host_config or ssh_config.lookup("*"))
            log("Opening proxy channel")
            chan_to_middle = middle_transport.open_channel(
                "direct-tcpip", (host, port), ('localhost', 0))

            transport = Transport(chan_to_middle)
            transport.use_compression(False)
            try:
                transport.start_client()
            except SSHException as e:
                log("start_client()", exc_info=True)
                raise InitException("SSH negotiation failed: %s" % e)
            do_ssh_paramiko_connect_to(transport, host, username, password,
                                       host_config or ssh_config.lookup("*"))
            chan = paramiko_run_remote_xpra(transport, proxy_command,
                                            remote_xpra, socket_dir,
                                            display_as_args)

            peername = (host, port)
            conn = SSHProxyCommandConnection(chan, peername, target,
                                             socket_info)
            conn.timeout = SOCKET_TIMEOUT
            conn.start_stderr_reader()
            return conn

        #plain TCP connection to the server,
        #we open it then give the socket to paramiko:
        sock = socket_connect(dtype, host, port)
        sockname = sock.getsockname()
        peername = sock.getpeername()
        log("paramiko socket_connect: sockname=%s, peername=%s", sockname,
            peername)
        transport = Transport(sock)
        transport.use_compression(False)
        try:
            transport.start_client()
        except SSHException as e:
            log("start_client()", exc_info=True)
            raise InitException("SSH negotiation failed: %s" % e)
        do_ssh_paramiko_connect_to(transport, host, username, password,
                                   host_config or ssh_config.lookup("*"))
        chan = paramiko_run_remote_xpra(transport, proxy_command, remote_xpra,
                                        socket_dir, display_as_args)
        conn = SSHSocketConnection(chan, sock, sockname, peername, target,
                                   socket_info)
        conn.timeout = SOCKET_TIMEOUT
        conn.start_stderr_reader()
        return conn
Exemplo n.º 25
0
 def test_send_writes_to_process_stdin_returning_length(self, Popen):
     proxy = ProxyCommand("hi")
     written = proxy.send(b"data")
     Popen.return_value.stdin.write.assert_called_once_with(b"data")
     assert written == len(b"data")