def make_hello_base(self): capabilities = flatten_dict(get_network_caps()) import struct bits = struct.calcsize("P") * 8 capabilities.update( { "version": local_version, "encoding.generic": True, "namespace": True, "hostname": socket.gethostname(), "uuid": self.uuid, "username": self.username, "name": get_name(), "client_type": self.client_type(), "python.version": sys.version_info[:3], "python.bits": bits, "compression_level": self.compression_level, "argv": sys.argv, } ) capabilities.update(self.get_file_transfer_features()) if self.display: capabilities["display"] = self.display def up(prefix, d): updict(capabilities, prefix, d) up("build", self.get_version_info()) mid = get_machine_id() if mid: capabilities["machine_id"] = mid if self.encryption: assert self.encryption in ENCRYPTION_CIPHERS iv = get_iv() key_salt = get_salt() iterations = get_iterations() padding = choose_padding(self.server_padding_options) up( "cipher", { "": self.encryption, "iv": iv, "key_salt": key_salt, "key_stretch_iterations": iterations, "padding": padding, "padding.options": PADDING_OPTIONS, }, ) key = self.get_encryption_key() if key is None: self.warn_and_quit(EXIT_ENCRYPTION, "encryption key is missing") return self._protocol.set_cipher_in(self.encryption, iv, key, key_salt, iterations, padding) netlog( "encryption capabilities: %s", dict((k, v) for k, v in capabilities.items() if k.startswith("cipher")) ) capabilities.update(self.hello_extra) return capabilities
def make_uuid(self): try: import hashlib u = hashlib.sha1() except: #try python2.4 variant: import sha u = sha.new() def uupdate(ustr): u.update(ustr.encode("utf-8")) uupdate(get_machine_id()) if os.name=="posix": uupdate(u"/") uupdate(str(os.getuid())) uupdate(u"/") uupdate(str(os.getgid())) self.uuid = u.hexdigest()
def make_hello_base(self): capabilities = get_network_caps() capabilities.update({ "version" : local_version, "encoding.generic" : True, "namespace" : True, "file-transfer" : self.file_transfer, "file-size-limit" : self.file_size_limit, "printing" : self.printing, "hostname" : socket.gethostname(), "uuid" : self.uuid, "username" : self.username, "name" : get_name(), "client_type" : self.client_type(), "python.version" : sys.version_info[:3], "compression_level" : self.compression_level, }) if self.display: capabilities["display"] = self.display def up(prefix, d): updict(capabilities, prefix, d) up("platform", get_platform_info()) up("build", get_version_info()) mid = get_machine_id() if mid: capabilities["machine_id"] = mid if self.encryption: assert self.encryption in ENCRYPTION_CIPHERS iv = get_hex_uuid()[:16] key_salt = get_hex_uuid()+get_hex_uuid() iterations = 1000 capabilities.update({ "cipher" : self.encryption, "cipher.iv" : iv, "cipher.key_salt" : key_salt, "cipher.key_stretch_iterations": iterations, }) key = self.get_encryption_key() if key is None: self.warn_and_quit(EXIT_ENCRYPTION, "encryption key is missing") return self._protocol.set_cipher_in(self.encryption, iv, key, key_salt, iterations) log("encryption capabilities: %s", [(k,v) for k,v in capabilities.items() if k.startswith("cipher")]) return capabilities
def audio_loop_check(self, mode="speaker"): log("audio_loop_check(%s)", mode) from xpra.sound.gstreamer_util import ALLOW_SOUND_LOOP, loop_warning_messages if ALLOW_SOUND_LOOP: return True machine_id = get_machine_id() uuid = get_user_uuid() log( "audio_loop_check(%s) machine_id=%s client machine_id=%s, uuid=%s, client uuid=%s", mode, machine_id, self.machine_id, uuid, self.uuid) if self.machine_id: if self.machine_id != machine_id: #not the same machine, so OK return True if self.uuid != uuid: #different user, assume different pulseaudio server return True #check pulseaudio id if we have it pulseaudio_id = self.sound_properties.get("pulseaudio", {}).get("id") pulseaudio_cookie_hash = self.sound_properties.get( "pulseaudio", {}).get("cookie-hash") log( "audio_loop_check(%s) pulseaudio id=%s, client pulseaudio id=%s, pulseaudio cookie hash=%s, client pulseaudio cookie hash=%s", mode, pulseaudio_id, self.pulseaudio_id, pulseaudio_cookie_hash, self.pulseaudio_cookie_hash) if pulseaudio_id and self.pulseaudio_id: if self.pulseaudio_id != pulseaudio_id: return True elif pulseaudio_cookie_hash and self.pulseaudio_cookie_hash: if self.pulseaudio_cookie_hash != pulseaudio_cookie_hash: return True else: #no cookie or id, so probably not a pulseaudio setup, #hope for the best: return True msgs = loop_warning_messages(mode) summary = msgs[0] body = "\n".join(msgs[1:]) nid = XPRA_AUDIO_NOTIFICATION_ID self.may_notify(nid, summary, body, icon_name=mode) log.warn("Warning: %s", summary) for x in msgs[1:]: log.warn(" %s", x) return False
def make_hello_base(self): capabilities = get_network_caps() capabilities.update({ "version": local_version, "encoding.generic": True, "namespace": True, "hostname": socket.gethostname(), "uuid": self.uuid, "username": self.username, "name": get_name(), "client_type": self.client_type(), "python.version": sys.version_info[:3], "compression_level": self.compression_level, }) if self.display: capabilities["display"] = self.display capabilities.update(get_platform_info("platform")) capabilities.update(get_version_info("build")) mid = get_machine_id() if mid: capabilities["machine_id"] = mid if self.encryption: assert self.encryption in ENCRYPTION_CIPHERS iv = get_hex_uuid()[:16] key_salt = get_hex_uuid() + get_hex_uuid() iterations = 1000 capabilities.update({ "cipher": self.encryption, "cipher.iv": iv, "cipher.key_salt": key_salt, "cipher.key_stretch_iterations": iterations, }) key = self.get_encryption_key() if key is None: self.warn_and_quit(EXIT_ENCRYPTION, "encryption key is missing") return self._protocol.set_cipher_in(self.encryption, iv, key, key_salt, iterations) log("encryption capabilities: %s", [(k, v) for k, v in capabilities.items() if k.startswith("cipher")]) return capabilities
def make_uuid(self): try: import hashlib u = hashlib.sha1() except: #try python2.4 variant: import sha u = sha.new() def uupdate(ustr): u.update(ustr.encode("utf-8")) uupdate(get_machine_id()) if os.name == "posix": uupdate(u"/") uupdate(str(os.getuid())) uupdate(u"/") uupdate(str(os.getgid())) self.uuid = u.hexdigest()
def make_hello(self): now = time.time() capabilities = get_network_caps() capabilities.update(get_server_info()) capabilities.update({ "start_time": int(self.start_time), "current_time": int(now), "elapsed_time": int(now - self.start_time), "server_type": "core", "info-request": True, "uuid": get_user_uuid(), }) mid = get_machine_id() if mid: capabilities["machine_id"] = mid if self.session_name: capabilities["session_name"] = self.session_name if self._reverse_aliases: capabilities["aliases"] = self._reverse_aliases add_version_info(capabilities) return capabilities
def make_hello(self): now = time.time() capabilities = get_network_caps() capabilities.update(get_server_info()) capabilities.update({ "start_time" : int(self.start_time), "current_time" : int(now), "elapsed_time" : int(now - self.start_time), "server_type" : "core", "info-request" : True, "uuid" : get_user_uuid(), }) mid = get_machine_id() if mid: capabilities["machine_id"] = mid if self.session_name: capabilities["session_name"] = self.session_name if self._reverse_aliases: capabilities["aliases"] = self._reverse_aliases add_version_info(capabilities) return capabilities
def make_hello(self, source): now = time.time() capabilities = get_network_caps() if source.wants_versions: capabilities.update(get_server_info()) capabilities.update({ "version": xpra.__version__, "start_time": int(self.start_time), "current_time": int(now), "elapsed_time": int(now - self.start_time), "server_type": "core", }) if source.wants_features: capabilities["info-request"] = True if source.wants_versions: capabilities["uuid"] = get_user_uuid() mid = get_machine_id() if mid: capabilities["machine_id"] = mid if self.session_name: capabilities["session_name"] = self.session_name return capabilities
def make_hello(self, source): now = time.time() capabilities = get_network_caps() if source.wants_versions: capabilities.update(get_server_info()) capabilities.update({ "version" : xpra.__version__, "start_time" : int(self.start_time), "current_time" : int(now), "elapsed_time" : int(now - self.start_time), "server_type" : "core", }) if source.wants_features: capabilities["info-request"] = True if source.wants_versions: capabilities["uuid"] = get_user_uuid() mid = get_machine_id() if mid: capabilities["machine_id"] = mid if self.session_name: capabilities["session_name"] = self.session_name return capabilities
def make_hello_base(self): capabilities = flatten_dict(get_network_caps()) #add "kerberos", "gss" and "u2f" digests if enabled: for handler in self.challenge_handlers: digest = handler.get_digest() if digest: capabilities["digest"].append(digest) capabilities.update(FilePrintMixin.get_caps(self)) capabilities.update({ "version": XPRA_VERSION, "websocket.multi-packet": True, "hostname": socket.gethostname(), "uuid": self.uuid, "session-id": self.session_id, "username": self.username, "name": get_name(), "client_type": self.client_type(), "python.version": sys.version_info[:3], "python.bits": BITS, "compression_level": self.compression_level, "argv": sys.argv, }) capabilities.update(self.get_file_transfer_features()) if self.display: capabilities["display"] = self.display def up(prefix, d): updict(capabilities, prefix, d) up("build", self.get_version_info()) mid = get_machine_id() if mid: capabilities["machine_id"] = mid if self.encryption: assert self.encryption in ENCRYPTION_CIPHERS iv = get_iv() key_salt = get_salt() iterations = get_iterations() padding = choose_padding(self.server_padding_options) up( "cipher", { "": self.encryption, "iv": iv, "key_salt": key_salt, "key_stretch_iterations": iterations, "padding": padding, "padding.options": PADDING_OPTIONS, }) key = self.get_encryption_key() if key is None: self.warn_and_quit(EXIT_ENCRYPTION, "encryption key is missing") return None self._protocol.set_cipher_in(self.encryption, iv, key, key_salt, iterations, padding) netlog( "encryption capabilities: %s", dict((k, v) for k, v in capabilities.items() if k.startswith("cipher"))) capabilities.update(self.hello_extra) return capabilities
def do_update_screen(self): self.log("do_update_screen()") #c = self.stdscr.getch() #if c==curses.KEY_RESIZE: height, width = self.stdscr.getmaxyx() #log.info("update_screen() %ix%i", height, width) title = get_title() sli = self.server_last_info def _addstr(pad, y, x, s, *args): if len(s) + x >= width - pad: s = s[:max(0, width - x - 2 - pad)] + ".." self.stdscr.addstr(y, x, s, *args) def addstr_main(y, x, s, *args): _addstr(0, y, x, s, *args) def addstr_box(y, x, s, *args): _addstr(2, y, x, s, *args) try: x = max(0, width // 2 - len(title) // 2) addstr_main(0, x, title, curses.A_BOLD) if height <= 1: return server_info = self.slidictget("server") build = self.slidictget("server", "build") vstr = caps_to_version(build) mode = server_info.strget("mode", "server") python_info = typedict(server_info.dictget("python", {})) bits = python_info.intget("bits", 32) server_str = "Xpra %s server version %s %i-bit" % (mode, vstr, bits) proxy_info = self.slidictget("proxy") if proxy_info: proxy_platform_info = typedict( proxy_info.dictget("platform", {})) proxy_platform = proxy_platform_info.strget("") proxy_release = proxy_platform_info.strget("release") proxy_build_info = typedict(proxy_info.dictget("build", {})) proxy_version = proxy_build_info.strget("version") proxy_distro = proxy_info.strget("linux_distribution") server_str += " via: %s proxy version %s" % (platform_name( proxy_platform, proxy_distro or proxy_release), std(proxy_version or "unknown")) addstr_main(1, 0, server_str) if height <= 2: return #load and uptime: now = datetime.now() uptime = "" elapsed_time = server_info.intget("elapsed_time") if elapsed_time: td = timedelta(seconds=elapsed_time) uptime = " up %s" % str(td).lstrip("0:") clients_info = self.slidictget("clients") nclients = clients_info.intget("") load_average = "" load = sli.inttupleget("load") if load and len(load) == 3: float_load = tuple(v / 1000.0 for v in load) load_average = ", load average: %1.2f, %1.2f, %1.2f" % float_load addstr_main( 2, 0, "xpra top - %s%s, %2i users%s" % (now.strftime("%H:%M:%S"), uptime, nclients, load_average)) if height <= 3: return thread_info = self.slidictget("threads") rinfo = "%i threads" % thread_info.intget("count") server_pid = server_info.intget("pid", 0) if server_pid: rinfo += ", pid %i" % server_pid machine_id = server_info.get("machine-id") if machine_id is None or machine_id == get_machine_id(): try: process = self.psprocess.get(server_pid) if not process: import psutil process = psutil.Process(server_pid) self.psprocess[server_pid] = process else: cpu = process.cpu_percent() rinfo += ", %i%% CPU" % (cpu) except Exception: pass cpuinfo = self.slidictget("cpuinfo") if cpuinfo: rinfo += ", %s" % cpuinfo.strget("hz_actual") elapsed = monotonic_time() - self.server_last_info_time color = WHITE if self.server_last_info_time == 0: rinfo += " - no server data" elif elapsed > 2: rinfo += " - last updated %i seconds ago" % elapsed color = RED addstr_main(3, 0, rinfo, curses.color_pair(color)) if height <= 4: return #display: dinfo = [] server = self.slidictget("server") rws = server.intpair("root_window_size", None) if rws: sinfo = "%ix%i display" % (rws[0], rws[1]) mds = server.intpair("max_desktop_size") if mds: sinfo += " (max %ix%i)" % (mds[0], mds[1]) dinfo.append(sinfo) cursor_info = self.slidictget("cursor") if cursor_info: cx, cy = cursor_info.inttupleget("position", (0, 0)) dinfo.append("cursor at %ix%i" % (cx, cy)) display_info = self.slidictget("display") pid = display_info.intget("pid") if pid: dinfo.append("pid %i" % pid) addstr_main(4, 0, csv(dinfo)) if height <= 5: return hpos = 5 gl_info = self.get_gl_info(display_info.dictget("opengl")) if gl_info: addstr_main(5, 0, gl_info) hpos += 1 if hpos < height - 3: hpos += 1 if nclients == 0: addstr_main(hpos, 0, "no clients connected") else: addstr_main( hpos, 0, "%i client%s connected:" % (nclients, engs(nclients))) hpos += 1 client_info = self.slidictget("client") client_no = 0 while True: ci = client_info.dictget(client_no) if not ci: break client_no += 1 ci = typedict(ci) session_id = ci.strget("session-id") if session_id: #don't show ourselves: if session_id == self.session_id: continue elif not ci.boolget("windows", True): #for older servers, hide any client that doesn't display windows: continue ci = self.get_client_info(ci) l = len(ci) if hpos + 2 + l > height: if hpos < height: more = nclients - client_no addstr_box( hpos, 0, "%i client%s not shown" % (more, engs(more)), curses.A_BOLD) break self.box(1, hpos, width - 2, 2 + l) for i, info in enumerate(ci): info_text, color = info cpair = curses.color_pair(color) addstr_box(hpos + i + 1, 2, info_text, cpair) hpos += 2 + l windows = self.slidictget("windows") if hpos < height - 3: hpos += 1 addstr_main(hpos, 0, "%i window%s:" % (len(windows), engs(windows))) hpos += 1 wins = tuple(windows.values()) nwindows = len(wins) for win_no, win in enumerate(wins): wi = self.get_window_info(typedict(win)) l = len(wi) if hpos + 2 + l > height: if hpos < height: more = nwindows - win_no addstr_main(hpos, 0, "terminal window is too small: %i window%s not shown" % \ (more, engs(more)), curses.A_BOLD) break self.box(1, hpos, width - 2, 2 + l) for i, info in enumerate(wi): info_text, color = info cpair = curses.color_pair(color) addstr_box(hpos + i + 1, 2, info_text, cpair) hpos += 2 + l except Exception as e: self.err(e)
def set_printers(self, printers, password_file, auth, encryption, encryption_keyfile): log("set_printers(%s, %s, %s, %s, %s) for %s", printers, password_file, auth, encryption, encryption_keyfile, self) if self.machine_id == get_machine_id() and not ADD_LOCAL_PRINTERS: self.printers = printers log("local client with identical machine id,") log(" not configuring local printers") return if not self.uuid: log.warn("Warning: client did not supply a UUID,") log.warn(" printer forwarding cannot be enabled") return #remove the printers no longer defined #or those whose definition has changed (and we will re-add them): for k in tuple(self.printers.keys()): cpd = self.printers.get(k) npd = printers.get(k) if cpd == npd: #unchanged: make sure we don't try adding it again: try: del printers[k] except KeyError: pass continue if npd is None: log("printer %s no longer exists", k) else: log("printer %s has been modified:", k) log(" was %s", cpd) log(" now %s", npd) #remove it: try: del self.printers[k] except KeyError: pass self.remove_printer(k) #expand it here so the xpraforwarder doesn't need to import anything xpra: attributes = { "display": os.environ.get("DISPLAY"), "source": self.uuid } def makeabs(filename): #convert to an absolute path since the backend may run as a different user: return os.path.abspath(os.path.expanduser(filename)) if auth: auth_password_file = None try: name, authclass, authoptions = auth auth_password_file = authoptions.get("file") log("file for %s / %s: '%s'", name, authclass, password_file) except Exception as e: log.error( "Error: cannot forward authentication attributes to printer backend:" ) log.error(" %s", e) if auth_password_file or password_file: attributes["password-file"] = makeabs(auth_password_file or password_file) if encryption: if not encryption_keyfile: log.error("Error: no encryption keyfile found for printing") else: attributes["encryption"] = encryption attributes["encryption-keyfile"] = makeabs(encryption_keyfile) #if we can, tell it exactly where to connect: if self.unix_socket_paths: #prefer sockets in public paths: spath = self.unix_socket_paths[0] for x in self.unix_socket_paths: if x.startswith("/tmp") or x.startswith( "/var") or x.startswith("/run"): spath = x attributes["socket-path"] = spath log("printer attributes: %s", attributes) for k, props in printers.items(): if k not in self.printers: self.setup_printer(k, props, attributes)
def remove_printers(self): if self.machine_id == get_machine_id() and not ADD_LOCAL_PRINTERS: return self.printers = {} for k in tuple(self.printers_added): self.remove_printer(k)
def make_hello_base(self): capabilities = flatten_dict(get_network_caps()) #add "kerberos", "gss" and "u2f" digests if enabled: for handler in self.challenge_handlers: digest = handler.get_digest() if digest: capabilities["digest"].append(digest) capabilities.update(FilePrintMixin.get_caps(self)) capabilities.update({ "version" : XPRA_VERSION, "websocket.multi-packet": True, "hostname" : socket.gethostname(), "uuid" : self.uuid, "session-id" : self.session_id, "username" : self.username, "name" : get_name(), "client_type" : self.client_type(), "python.version" : sys.version_info[:3], "python.bits" : BITS, "compression_level" : self.compression_level, "argv" : sys.argv, }) capabilities.update(self.get_file_transfer_features()) if self.display: capabilities["display"] = self.display def up(prefix, d): updict(capabilities, prefix, d) up("build", self.get_version_info()) mid = get_machine_id() if mid: capabilities["machine_id"] = mid encryption = self.get_encryption() cryptolog("encryption=%s", encryption) if encryption: crypto_backend_init() enc, mode = (encryption+"-").split("-")[:2] if not mode: mode = DEFAULT_MODE assert enc in ENCRYPTION_CIPHERS, "invalid encryption '%s', options: %s" % (enc, csv(ENCRYPTION_CIPHERS)) assert mode in MODES, "invalid encryption mode '%s', options: %s" % (mode, csv(MODES)) iv = get_iv() key_salt = get_salt() iterations = get_iterations() padding = choose_padding(self.server_padding_options) cipher_caps = { "" : enc, "mode" : mode, "iv" : iv, "key_salt" : key_salt, "key_size" : DEFAULT_KEYSIZE, "key_hash" : DEFAULT_KEY_HASH, "key_stretch" : "PBKDF2", "key_stretch_iterations": iterations, "padding" : padding, "padding.options" : PADDING_OPTIONS, } cryptolog("cipher_caps=%s", cipher_caps) up("cipher", cipher_caps) key = self.get_encryption_key() self._protocol.set_cipher_in(encryption, iv, key, key_salt, DEFAULT_KEY_HASH, DEFAULT_KEYSIZE, iterations, padding) capabilities.update(self.hello_extra) return capabilities
def make_hello_base(self): capabilities = flatten_dict(get_network_caps()) import struct bits = struct.calcsize("P") * 8 capabilities.update({ "version" : XPRA_VERSION, "encoding.generic" : True, "namespace" : True, "hostname" : socket.gethostname(), "uuid" : self.uuid, "username" : self.username, "name" : get_name(), "client_type" : self.client_type(), "python.version" : sys.version_info[:3], "python.bits" : bits, "compression_level" : self.compression_level, "argv" : sys.argv, }) capabilities.update(self.get_file_transfer_features()) if self.display: capabilities["display"] = self.display def up(prefix, d): updict(capabilities, prefix, d) up("build", self.get_version_info()) mid = get_machine_id() if mid: capabilities["machine_id"] = mid #get socket speed if we have it: pinfo = self._protocol.get_info() netlog("protocol info=%s", pinfo) socket_speed = pinfo.get("socket", {}).get("speed") if socket_speed: capabilities["connection-data"] = {"speed" : socket_speed} bandwidth_limit = self.bandwidth_limit log("bandwidth-limit=%s, socket-speed=%s", self.bandwidth_limit, socket_speed) if bandwidth_limit is None: if socket_speed: #auto: use 80% of socket speed if we have it: bandwidth_limit = socket_speed*AUTO_BANDWIDTH_PCT//100 or 0 else: bandwidth_limit = 0 if bandwidth_limit>0: capabilities["bandwidth-limit"] = bandwidth_limit if self.encryption: assert self.encryption in ENCRYPTION_CIPHERS iv = get_iv() key_salt = get_salt() iterations = get_iterations() padding = choose_padding(self.server_padding_options) up("cipher", { "" : self.encryption, "iv" : iv, "key_salt" : key_salt, "key_stretch_iterations": iterations, "padding" : padding, "padding.options" : PADDING_OPTIONS, }) key = self.get_encryption_key() if key is None: self.warn_and_quit(EXIT_ENCRYPTION, "encryption key is missing") return self._protocol.set_cipher_in(self.encryption, iv, key, key_salt, iterations, padding) netlog("encryption capabilities: %s", dict((k,v) for k,v in capabilities.items() if k.startswith("cipher"))) capabilities.update(self.hello_extra) return capabilities