Exemple #1
0
 def mode_changed(self, *args):
     ssh = self.mode_combo.get_active_text() == "SSH"
     self.port_entry.set_text("")
     if ssh:
         self.ssh_port_entry.show()
         self.port_entry.set_tooltip_text("Display number (optional)")
         self.password_entry.set_tooltip_text("SSH Password")
         self.username_entry.show()
         self.username_label.show()
     else:
         self.ssh_port_entry.hide()
         self.port_entry.set_tooltip_text("port number")
         self.password_entry.set_tooltip_text("Session Password")
         self.username_entry.hide()
         self.username_label.hide()
         if self.config.port > 0:
             self.port_entry.set_text("%s" % self.config.port)
     can_use_password = not ssh
     if ssh:
         if sys.platform.startswith("win"):
             #plink can use password
             pass
         else:
             #can use password if sshpass is installed:
             from xpra.platform.paths import get_sshpass_command
             sshpass = get_sshpass_command()
             can_use_password = bool(sshpass)
     if can_use_password:
         self.password_label.show()
         self.password_entry.show()
     else:
         self.password_label.hide()
         self.password_entry.hide()
     self.validate()
Exemple #2
0
 def mode_changed(self, *_args):
     mode = self.mode_combo.get_active_text().lower()
     ssh = mode == "ssh"
     if ssh:
         self.port_entry.set_tooltip_text("Display number (optional)")
         self.port_entry.set_text("")
         self.ssh_port_entry.set_text("22")
         self.ssh_port_entry.show()
         self.password_entry.set_tooltip_text("SSH Password")
         self.username_entry.set_tooltip_text("SSH Username")
     else:
         self.ssh_port_entry.hide()
         self.ssh_port_entry.set_text("")
         port_str = self.port_entry.get_text()
         if not port_str:
             self.port_entry.set_text(
                 str(max(0, self.config.port) or DEFAULT_PORT))
         self.port_entry.set_tooltip_text("xpra server port number")
         self.password_entry.set_tooltip_text("Session Password (optional)")
         self.username_entry.set_tooltip_text("Session Username (optional)")
         if self.config.port > 0:
             self.port_entry.set_text("%s" % self.config.port)
     can_use_password = True
     if ssh:
         ssh_cmd = parse_ssh_string(self.config.ssh)[0].strip().lower()
         is_putty = ssh_cmd.endswith("plink") or ssh_cmd.endswith(
             "plink.exe")
         is_paramiko = ssh_cmd == "paramiko"
         if is_putty or is_paramiko:
             can_use_password = True
         else:
             #we can also use password if sshpass is installed:
             from xpra.platform.paths import get_sshpass_command
             sshpass = get_sshpass_command()
             can_use_password = bool(sshpass)
     if can_use_password:
         self.password_label.show()
         self.password_entry.show()
     else:
         self.password_label.hide()
         self.password_entry.hide()
     self.validate()
     if mode == "ssl" or (mode == "ssh" and not WIN32):
         self.nostrict_host_check.show()
     else:
         self.nostrict_host_check.hide()
Exemple #3
0
 def mode_changed(self, *args):
     mode = self.mode_combo.get_active_text().lower()
     ssh = mode == "ssh"
     if ssh:
         self.port_entry.set_tooltip_text("Display number (optional)")
         self.port_entry.set_text("")
         self.ssh_port_entry.set_text("22")
         self.ssh_port_entry.show()
         self.password_entry.set_tooltip_text("SSH Password")
         self.username_entry.set_tooltip_text("SSH Username")
     else:
         self.ssh_port_entry.hide()
         self.ssh_port_entry.set_text("")
         port_str = self.port_entry.get_text()
         if not port_str:
             self.port_entry.set_text(
                 str(max(0, self.config.port) or DEFAULT_PORT))
         self.port_entry.set_tooltip_text("xpra server port number")
         self.password_entry.set_tooltip_text("Session Password (optional)")
         self.username_entry.set_tooltip_text("Session Username (optional)")
         if self.config.port > 0:
             self.port_entry.set_text("%s" % self.config.port)
     can_use_password = not ssh
     if ssh:
         if sys.platform.startswith("win"):
             #plink can use password
             pass
         else:
             #can use password if sshpass is installed:
             from xpra.platform.paths import get_sshpass_command
             sshpass = get_sshpass_command()
             can_use_password = bool(sshpass)
     if can_use_password:
         self.password_label.show()
         self.password_entry.show()
     else:
         self.password_label.hide()
         self.password_entry.hide()
     self.validate()
     if mode == "ssl" or (mode == "ssh"
                          and not sys.platform.startswith("win")):
         self.nostrict_host_check.show()
     else:
         self.nostrict_host_check.hide()
Exemple #4
0
    def mode_changed(self, *args):
        mode = self.mode_combo.get_active_text().lower()
        ssh = mode == "ssh"
        if ssh:
            self.port_entry.set_tooltip_text("Display number (optional)")
            self.port_entry.set_text("")
            self.ssh_port_entry.set_text("22")
            self.ssh_port_entry.show()
            self.password_entry.set_tooltip_text("SSH Password")
            self.username_entry.set_tooltip_text("SSH Username")
        else:
            self.ssh_port_entry.hide()
            self.ssh_port_entry.set_text("")
            port_str = self.port_entry.get_text()
            if not port_str:
                self.port_entry.set_text(str(max(0, self.config.port) or DEFAULT_PORT))
            self.port_entry.set_tooltip_text("xpra server port number")
            self.password_entry.set_tooltip_text("Session Password (optional)")
            self.username_entry.set_tooltip_text("Session Username (optional)")
            if self.config.port > 0:
                self.port_entry.set_text("%s" % self.config.port)
        can_use_password = not ssh
        if ssh:
            if WIN32:
                # plink can use password
                pass
            else:
                # can use password if sshpass is installed:
                from xpra.platform.paths import get_sshpass_command

                sshpass = get_sshpass_command()
                can_use_password = bool(sshpass)
        if can_use_password:
            self.password_label.show()
            self.password_entry.show()
        else:
            self.password_label.hide()
            self.password_entry.hide()
        self.validate()
        if mode == "ssl" or (mode == "ssh" and not WIN32):
            self.nostrict_host_check.show()
        else:
            self.nostrict_host_check.hide()
Exemple #5
0
def ssh_exec_connect_to(display_desc, opts=None, debug_cb=None, ssh_fail_cb=ssh_connect_failed):
    if not ssh_fail_cb:
        ssh_fail_cb = ssh_connect_failed
    sshpass_command = None
    try:
        cmd = list(display_desc["full_ssh"])
        kwargs = {}
        env = display_desc.get("env")
        kwargs["stderr"] = sys.stderr
        if WIN32:
            from subprocess import CREATE_NEW_PROCESS_GROUP, CREATE_NEW_CONSOLE, STARTUPINFO, STARTF_USESHOWWINDOW
            startupinfo = STARTUPINFO()
            startupinfo.dwFlags |= STARTF_USESHOWWINDOW
            startupinfo.wShowWindow = 0     #aka win32.con.SW_HIDE
            flags = CREATE_NEW_PROCESS_GROUP | CREATE_NEW_CONSOLE
            kwargs.update({
                "startupinfo"   : startupinfo,
                "creationflags" : flags,
                "stderr"        : PIPE,
                })
        elif not display_desc.get("exit_ssh", False) and not OSX:
            kwargs["start_new_session"] = True
        remote_xpra = display_desc["remote_xpra"]
        assert remote_xpra
        socket_dir = display_desc.get("socket_dir")
        proxy_command = display_desc["proxy_command"]       #ie: "_proxy_start"
        display_as_args = display_desc["display_as_args"]   #ie: "--start=xterm :10"
        remote_cmd = ""
        for x in remote_xpra:
            if not remote_cmd:
                check = "if"
            else:
                check = "elif"
            if x=="xpra":
                #no absolute path, so use "which" to check that the command exists:
                pc = ['%s which "%s" > /dev/null 2>&1; then' % (check, x)]
            else:
                pc = ['%s [ -x %s ]; then' % (check, x)]
            pc += [x] + proxy_command + [shellquote(x) for x in display_as_args]
            if socket_dir:
                pc.append("--socket-dir=%s" % socket_dir)
            remote_cmd += " ".join(pc)+";"
        remote_cmd += "else echo \"no run-xpra command found\"; exit 1; fi"
        if INITENV_COMMAND:
            remote_cmd = INITENV_COMMAND + ";" + remote_cmd
        #how many times we need to escape the remote command string
        #depends on how many times the ssh command is parsed
        nssh = sum(int(x=="ssh") for x in cmd)
        if nssh>=2 and MAGIC_QUOTES:
            for _ in range(nssh):
                remote_cmd = shlex.quote(remote_cmd)
        else:
            remote_cmd = "'%s'" % remote_cmd
        cmd.append("sh -c %s" % remote_cmd)
        if debug_cb:
            debug_cb("starting %s tunnel" % str(cmd[0]))
        #non-string arguments can make Popen choke,
        #instead of lazily converting everything to a string, we validate the command:
        for x in cmd:
            if not isinstance(x, str):
                raise InitException("argument is not a string: %s (%s), found in command: %s" % (x, type(x), cmd))
        password = display_desc.get("password")
        if password and not display_desc.get("is_putty", False):
            from xpra.platform.paths import get_sshpass_command
            sshpass_command = get_sshpass_command()
            if sshpass_command:
                #sshpass -e ssh ...
                cmd.insert(0, sshpass_command)
                cmd.insert(1, "-e")
                if env is None:
                    env = os.environ.copy()
                env["SSHPASS"] = password
                #the password will be used by ssh via sshpass,
                #don't try to authenticate again over the ssh-proxy connection,
                #which would trigger warnings if the server does not require
                #authentication over unix-domain-sockets:
                opts.password = None
                del display_desc["password"]
        if env:
            kwargs["env"] = env
        if is_debug_enabled("ssh"):
            log.info("executing ssh command: %s" % (" ".join("\"%s\"" % x for x in cmd)))
        child = Popen(cmd, stdin=PIPE, stdout=PIPE, **kwargs)
    except OSError as e:
        raise InitExit(EXIT_SSH_FAILURE,
                       "Error running ssh command '%s': %s" % (" ".join("\"%s\"" % x for x in cmd), e))
    def abort_test(action):
        """ if ssh dies, we don't need to try to read/write from its sockets """
        e = child.poll()
        if e is not None:
            had_connected = conn.input_bytecount>0 or conn.output_bytecount>0
            if had_connected:
                error_message = "cannot %s using SSH" % action
            else:
                error_message = "SSH connection failure"
            sshpass_error = None
            if sshpass_command:
                sshpass_error = {
                                 1  : "Invalid command line argument",
                                 2  : "Conflicting arguments given",
                                 3  : "General runtime error",
                                 4  : "Unrecognized response from ssh (parse error)",
                                 5  : "Invalid/incorrect password",
                                 6  : "Host public key is unknown. sshpass exits without confirming the new key.",
                                 }.get(e)
                if sshpass_error:
                    error_message += ": %s" % sshpass_error
            if debug_cb:
                debug_cb(error_message)
            if ssh_fail_cb:
                ssh_fail_cb(error_message)
            if "ssh_abort" not in display_desc:
                display_desc["ssh_abort"] = True
                if not had_connected:
                    log.error("Error: SSH connection to the xpra server failed")
                    if sshpass_error:
                        log.error(" %s", sshpass_error)
                    else:
                        log.error(" check your username, hostname, display number, firewall, etc")
                    display_name = display_desc["display_name"]
                    log.error(" for server: %s", display_name)
                else:
                    log.error("The SSH process has terminated with exit code %s", e)
                cmd_info = " ".join(display_desc["full_ssh"])
                log.error(" the command line used was:")
                log.error(" %s", cmd_info)
            raise ConnectionClosedException(error_message) from None
    def stop_tunnel():
        if POSIX:
            #on posix, the tunnel may be shared with other processes
            #so don't kill it... which may leave it behind after use.
            #but at least make sure we close all the pipes:
            for name,fd in {
                            "stdin" : child.stdin,
                            "stdout" : child.stdout,
                            "stderr" : child.stderr,
                            }.items():
                try:
                    if fd:
                        fd.close()
                except Exception as e:
                    print("error closing ssh tunnel %s: %s" % (name, e))
            if not display_desc.get("exit_ssh", False):
                #leave it running
                return
        try:
            if child.poll() is None:
                child.terminate()
        except Exception as e:
            print("error trying to stop ssh tunnel process: %s" % e)
    host = display_desc["host"]
    port = display_desc.get("ssh-port", 22)
    username = display_desc.get("username")
    display = display_desc.get("display")
    info = {
        "host"  : host,
        "port"  : port,
        }
    from xpra.net.bytestreams import TwoFileConnection
    conn = TwoFileConnection(child.stdin, child.stdout,
                             abort_test, target=(host, port),
                             socktype="ssh", close_cb=stop_tunnel, info=info)
    conn.endpoint = host_target_string("ssh", username, host, port, display)
    conn.timeout = 0            #taken care of by abort_test
    conn.process = (child, "ssh", cmd)
    if kwargs.get("stderr")==PIPE:
        def stderr_reader():
            errs = []
            while child.poll() is None:
                try:
                    v = child.stderr.readline()
                except OSError:
                    log("stderr_reader()", exc_info=True)
                    break
                if not v:
                    log("SSH EOF on stderr of %s", cmd)
                    break
                s = bytestostr(v.rstrip(b"\n\r"))
                if s:
                    errs.append(s)
            if errs:
                log.warn("remote SSH stderr:")
                for e in errs:
                    log.warn(" %s", e)
        start_thread(stderr_reader, "ssh-stderr-reader", daemon=True)
    return conn
Exemple #6
0
 def mode_changed(self, *_args):
     mode = self.mode_combo.get_active_text().lower()
     ssh = mode == MODE_SSH
     sshtossh = mode == MODE_NESTED_SSH
     if ssh or sshtossh:
         self.port_entry.set_tooltip_text("Display number (optional)")
         self.port_entry.set_text("")
         self.ssh_port_entry.show()
         self.password_entry.set_tooltip_text("SSH Password")
         self.username_entry.set_tooltip_text("SSH Username")
         if ssh:
             self.proxy_vbox.hide()
             self.password_scb.hide()
             self.password_entry.set_sensitive(True)
             self.username_entry.set_sensitive(True)
         if sshtossh:
             self.proxy_vbox.show()
             self.password_scb.show()
     else:
         self.password_entry.set_sensitive(True)
         self.username_entry.set_sensitive(True)
         self.proxy_vbox.hide()
         self.ssh_port_entry.hide()
         self.ssh_port_entry.set_text("")
         port_str = self.port_entry.get_text()
         if not port_str:
             self.port_entry.set_text(
                 str(max(0, self.config.port) or DEFAULT_PORT))
         self.port_entry.set_tooltip_text("xpra server port number")
         self.password_entry.set_tooltip_text("Session Password (optional)")
         self.username_entry.set_tooltip_text("Session Username (optional)")
         if self.config.port > 0:
             self.port_entry.set_text("%s" % self.config.port)
     can_use_password = True
     sshpass = False
     if ssh or sshtossh:
         if not self.is_putty:
             self.proxy_key_entry.set_text("OpenSSH/Paramiko use ~/.ssh")
             self.proxy_key_entry.set_editable(False)
             self.proxy_key_entry.set_sensitive(False)
             self.proxy_key_browse.hide()
         if self.is_paramiko or self.is_putty:
             can_use_password = True
         else:
             #we can also use password if sshpass is installed:
             from xpra.platform.paths import get_sshpass_command
             sshpass = get_sshpass_command()
             can_use_password = bool(sshpass)
             sshpass = bool(sshpass)
     if can_use_password:
         self.password_hbox.show()
         if sshtossh:
             self.proxy_password_hbox.show()
             # sshpass cannot do different username/passwords for proxy and destination
             if not sshpass:
                 self.check_boxes_hbox.show()
                 p = self.password_entry.get_text()
                 pp = self.proxy_password_entry.get_text()
                 u = self.username_entry.get_text()
                 pu = self.proxy_username_entry.get_text()
             else:
                 self.check_boxes_hbox.hide()
                 p = pp = None
                 u = pu = None
             self.password_scb.set_active(p == pp)
             self.username_scb.set_active(u == pu)
     else:
         self.password_hbox.hide()
         if sshtossh:
             self.check_boxes_hbox.hide()
             self.proxy_password_hbox.hide()
     self.validate()
     if mode in (MODE_SSL, MODE_WSS) or (mode == MODE_SSH and not WIN32):
         self.nostrict_host_check.show()
     else:
         self.nostrict_host_check.hide()