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()
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()
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()
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()
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
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()