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() if encryption: crypto_backend_init() assert encryption in ENCRYPTION_CIPHERS, "invalid encryption '%s', options: %s" % ( encryption, csv(ENCRYPTION_CIPHERS)) iv = get_iv() key_salt = get_salt() iterations = get_iterations() padding = choose_padding(self.server_padding_options) up( "cipher", { "": encryption, "iv": iv, "key_salt": key_salt, "key_stretch_iterations": iterations, "padding": padding, "padding.options": PADDING_OPTIONS, }) key = self.get_encryption_key() self._protocol.set_cipher_in(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_hello(self, source): capabilities = super().make_hello(source) for c in SERVER_BASES: if c != ServerCore: merge_dicts(capabilities, c.get_caps(self, source)) capabilities["server_type"] = "base" if source.wants_display: capabilities.update({ "max_desktop_size": self.get_max_screen_size(), "display": os.environ.get("DISPLAY", "Main"), }) if source.wants_features: capabilities.update({ "client-shutdown": self.client_shutdown, "sharing": self.sharing is not False, "sharing-toggle": self.sharing is None, "lock": self.lock is not False, "lock-toggle": self.lock is None, "windows": server_features.windows, "keyboard": server_features.input_devices, "pointer": server_features.input_devices, }) capabilities.update(flatten_dict(self.get_server_features(source))) capabilities[ "configure.pointer"] = True #v4 clients assume this is enabled return capabilities
def make_hello(self, source): capabilities = ServerCore.make_hello(self, source) for c in SERVER_BASES: if c != ServerCore: merge_dicts(capabilities, c.get_caps(self, source)) capabilities["server_type"] = "base" if source.wants_display: capabilities.update({ "max_desktop_size": self.get_max_screen_size(), }) if source.wants_features: capabilities.update({ "client-shutdown": self.client_shutdown, "sharing": self.sharing is not False, "sharing-toggle": self.sharing is None, "lock": self.lock is not False, "lock-toggle": self.lock is None, "windows": server_features.windows, "keyboard": server_features.input_devices, "pointer": server_features.input_devices, }) capabilities.update(flatten_dict(self.get_server_features(source))) #this is a feature, but we would need the hello request #to know if it is really needed.. so always include it: capabilities["exit_server"] = True return capabilities
def make_hello(self, source): capabilities = ServerCore.make_hello(self, source) for c in ServerBase.__bases__: if c!=ServerCore: merge_dicts(capabilities, c.get_caps(self)) capabilities["server_type"] = "base" if source.wants_display: capabilities.update({ "max_desktop_size" : self.get_max_screen_size(), }) if source.wants_features: capabilities.update({ "bell" : self.bell, "cursors" : self.cursors, "av-sync.enabled" : self.av_sync, "client-shutdown" : self.client_shutdown, "sharing" : self.sharing is not False, "sharing-toggle" : self.sharing is None, "lock" : self.lock is not False, "lock-toggle" : self.lock is None, }) capabilities.update(flatten_dict(self.get_server_features(source))) #this is a feature, but we would need the hello request #to know if it is really needed.. so always include it: capabilities["exit_server"] = True return capabilities
def do_command(self): if self.server_capabilities: if FLATTEN_INFO<2: #compatibility mode: c = flatten_dict(self.server_capabilities) for k in sorted_nicely(c.keys()): v = c.get(k) if PYTHON3: #FIXME: this is a nasty and horrible python3 workaround (yet again) #we want to print bytes as strings without the ugly 'b' prefix.. #it assumes that all the strings are raw or in (possibly nested) lists or tuples only #we assume that all strings we get are utf-8, #and fallback to the bytestostr hack if that fails def fixvalue(w): if type(w)==bytes: try: return w.decode("utf-8") except: return bytestostr(w) elif type(w) in (tuple,list): return type(w)([fixvalue(x) for x in w]) return w v = fixvalue(v) k = fixvalue(k) log.info("%s=%s", k, nonl(v)) else: print_nested_dict(self.server_capabilities) self.quit(EXIT_OK)
def do_command(self, caps : typedict): def print_fn(s): sys.stdout.write("%s\n" % (s,)) if not caps: self.quit(EXIT_NO_DATA) return exit_code = EXIT_OK try: if FLATTEN_INFO<2: #compatibility mode: c = flatten_dict(caps) for k in sorted_nicely(c.keys()): v = c.get(k) #FIXME: this is a nasty and horrible python3 workaround (yet again) #we want to print bytes as strings without the ugly 'b' prefix.. #it assumes that all the strings are raw or in (possibly nested) lists or tuples only #we assume that all strings we get are utf-8, #and fallback to the bytestostr hack if that fails def fixvalue(w): if isinstance(w, bytes): if k.endswith(".data"): return hexstr(w) return u(w) elif isinstance(w, (tuple,list)): return type(w)([fixvalue(x) for x in w]) return w v = fixvalue(v) k = fixvalue(k) print_fn("%s=%s" % (k, nonl(v))) else: print_nested_dict(caps, print_fn=print_fn) except OSError: exit_code = EXIT_IO_ERROR self.quit(exit_code)
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_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 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_hello(self, source): capabilities = ServerBase.make_hello(self, source) if source.wants_display: display = gtk.gdk.display_get_default() capabilities.update({ "display" : display.get_name(), "cursor.default_size" : display.get_default_cursor_size(), "cursor.max_size" : display.get_maximal_cursor_size()}) if source.wants_versions: capabilities.update(flatten_dict(get_gtk_version_info())) return capabilities
def make_hello_base(self): capabilities = flatten_dict(get_network_caps()) #add "kerberos" and "gss" if enabled: default_on = "all" in self.challenge_handlers or "auto" in self.challenge_handlers for auth in ("kerberos", "gss", "u2f"): if default_on or auth in self.challenge_handlers: capabilities["digest"].append(auth) capabilities.update(FilePrintMixin.get_caps(self)) capabilities.update({ "version" : XPRA_VERSION, "encoding.generic" : True, "namespace" : True, "websocket.multi-packet": 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 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 get_caps(self) -> dict: if not self.wants_sound or not self.sound_properties: return {} sound_props = self.sound_properties.copy() sound_props.update({ "codec-full-names" : True, "encoders" : self.speaker_codecs, "decoders" : self.microphone_codecs, "send" : self.supports_speaker and len(self.speaker_codecs)>0, "receive" : self.supports_microphone and len(self.microphone_codecs)>0, }) return flatten_dict({"sound" : sound_props})
def make_hello(self, source): capabilities = super().make_hello(source) if source.wants_display: display = Gdk.Display.get_default() max_size = tuple(display.get_maximal_cursor_size()) capabilities.update({ "display" : display.get_name(), "cursor.default_size" : display.get_default_cursor_size(), "cursor.max_size" : max_size, }) if source.wants_versions: capabilities.update(flatten_dict(get_gtk_version_info())) return capabilities
def make_hello(self, source): now = time.time() capabilities = flatten_dict(get_network_caps()) if source.wants_versions: capabilities.update(flatten_dict(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", "server.mode" : self.get_server_mode(), }) 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 = flatten_dict(get_network_caps()) if source.wants_versions: capabilities.update(flatten_dict(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", "server.mode": self.get_server_mode(), }) 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 get_caps(self): caps = flatten_dict({ "clipboard": { "notifications": self.client_supports_clipboard, "selections": CLIPBOARDS, #buggy osx clipboards: "want_targets": CLIPBOARD_WANT_TARGETS, #buggy osx and win32 clipboards: "greedy": CLIPBOARD_GREEDY, "set_enabled": True, }, }) caps["clipboard"] = self.client_supports_clipboard return caps
def get_caps(self): caps = { "randr_notify": True, "show-desktop": True, } wm_name = get_wm_name() if wm_name: caps["wm_name"] = wm_name self._last_screen_settings = self.get_screen_settings() root_w, root_h, sss, ndesktops, desktop_names, u_root_w, u_root_h, _, _ = self._last_screen_settings if u_root_w and u_root_h: caps["desktop_size"] = self.cp(u_root_w, u_root_h) if ndesktops: caps["desktops"] = ndesktops caps["desktop.names"] = desktop_names ss = self.get_screen_sizes() self._current_screen_sizes = ss log.info(" desktop size is %sx%s with %s screen%s:", u_root_w, u_root_h, len(ss), engs(ss)) log_screen_sizes(u_root_w, u_root_h, ss) if self.xscale != 1 or self.yscale != 1: caps["screen_sizes.unscaled"] = ss caps["desktop_size.unscaled"] = u_root_w, u_root_h root_w, root_h = self.cp(u_root_w, u_root_h) if fequ(self.xscale, self.yscale): sinfo = "%i%%" % iround(self.xscale * 100) else: sinfo = "%i%% x %i%%" % (iround( self.xscale * 100), iround(self.yscale * 100)) log.info(" %sscaled by %s, virtual screen size: %ix%i", ["down", "up"][int(u_root_w > root_w or u_root_h > root_h)], sinfo, root_w, root_h) log_screen_sizes(root_w, root_h, sss) else: root_w, root_h = u_root_w, u_root_h sss = ss caps["screen_sizes"] = sss caps.update(self.get_screen_caps()) caps.update( flatten_dict({ "dpi": self.get_dpi_caps(), "screen-scaling": self.get_scaling_caps(), })) return caps
def get_caps(self) -> dict: caps = { "randr_notify": True, "show-desktop": True, "vrefresh": self.get_vrefresh(), } wm_name = get_wm_name() if wm_name: caps["wm_name"] = wm_name self._last_screen_settings = self.get_screen_settings() root_w, root_h, sss, ndesktops, desktop_names, u_root_w, u_root_h = self._last_screen_settings[: 7] if u_root_w and u_root_h: caps["desktop_size"] = self.cp(u_root_w, u_root_h) if ndesktops: caps["desktops"] = ndesktops caps["desktop.names"] = tuple(desktop_names) ss = self.get_screen_sizes() self._current_screen_sizes = ss log.info(" desktop size is %sx%s:", u_root_w, u_root_h) log_screen_sizes(u_root_w, u_root_h, ss) if self.xscale != 1 or self.yscale != 1: caps["screen_sizes.unscaled"] = ss caps["desktop_size.unscaled"] = u_root_w, u_root_h root_w, root_h = self.cp(u_root_w, u_root_h) if fequ(self.xscale, self.yscale): sinfo = "%i%%" % iround(self.xscale * 100) else: sinfo = "%i%% x %i%%" % (iround( self.xscale * 100), iround(self.yscale * 100)) scaled_up = u_root_w > root_w or u_root_h > root_h log.info(" %sscaled to %s, virtual screen size: %ix%i", "up" if scaled_up else "down", sinfo, root_w, root_h) log_screen_sizes(root_w, root_h, sss) else: root_w, root_h = u_root_w, u_root_h sss = ss caps["screen_sizes"] = sss caps.update(self.get_screen_caps()) caps.update( flatten_dict({ "dpi": self.get_dpi_caps(), "screen-scaling": self.get_scaling_caps(), })) return caps
def get_caps(self): if not self.client_supports_clipboard: return {} caps = flatten_dict({ "clipboard" : { "" : True, "notifications" : True, "selections" : CLIPBOARDS, #buggy osx clipboards: "want_targets" : CLIPBOARD_WANT_TARGETS, #buggy osx and win32 clipboards: "greedy" : CLIPBOARD_GREEDY, "set_enabled" : True, "contents-slice-fix" : True, }, }) return caps
def filter_caps(self, caps, prefixes): #removes caps that the proxy overrides / does not use: pcaps = {} removed = [] for k in caps.keys(): if any(e for e in prefixes if bytestostr(k).startswith(e)): removed.append(k) else: pcaps[k] = caps[k] log("filtered out %s matching %s", removed, prefixes) #replace the network caps with the proxy's own: pcaps.update(flatten_dict(get_network_caps())) #then add the proxy info: updict(pcaps, "proxy", get_server_info(), flatten_dicts=True) pcaps["proxy"] = True pcaps["proxy.hostname"] = socket.gethostname() return pcaps
def get_caps(self) -> dict: if not self.client_supports_clipboard: return {} caps = flatten_dict({ "clipboard" : { "" : True, "notifications" : True, "selections" : CLIPBOARDS, #buggy osx clipboards: "want_targets" : CLIPBOARD_WANT_TARGETS, #buggy osx and win32 clipboards: "greedy" : CLIPBOARD_GREEDY, "preferred-targets" : CLIPBOARD_PREFERRED_TARGETS, "set_enabled" : True, #v4 servers no longer use or show this flag "contents-slice-fix" : True, #fixed in v2.4, removed check in v4.3 }, }) return caps
def main(): from xpra.util import nonl, pver, flatten_dict, print_nested_dict def print_version_dict(d, vformat=pver): for k in sorted(d.keys()): v = d[k] print("* %-48s : %s" % (str(k).replace(".version", "").ljust(12), nonl(vformat(v)))) from xpra.platform import program_context with program_context("GTK-Version-Info", "GTK Version Info"): from xpra.platform.gui import init as gui_init, ready gui_init() ready() from xpra.gtk_common import gtk_util if "-v" in sys.argv or "--verbose" in sys.argv: gtk_util.SHOW_ALL_VISUALS = True print("GTK Version:") print_version_dict(flatten_dict(gtk_util.get_gtk_version_info())) print("Display:") print_nested_dict(gtk_util.get_display_info(), vformat=str)
def filter_caps(self, caps, prefixes): #removes caps that the proxy overrides / does not use: #(not very pythonic!) pcaps = {} removed = [] for k in caps.keys(): skip = len([e for e in prefixes if k.startswith(e)]) if skip==0: pcaps[k] = caps[k] else: removed.append(k) log("filtered out %s matching %s", removed, prefixes) #replace the network caps with the proxy's own: pcaps.update(flatten_dict(get_network_caps())) #then add the proxy info: updict(pcaps, "proxy", get_server_info(), flatten_dicts=True) pcaps["proxy"] = True pcaps["proxy.hostname"] = socket.gethostname() return pcaps
def make_hello(self): capabilities = UIXpraClient.make_hello(self) capabilities["named_cursors"] = len(cursor_types) > 0 capabilities.update(flatten_dict(get_gtk_version_info())) #tell the server which icons GTK can use #so it knows when it should supply one as fallback it = icon_theme_get_default() #this would add our bundled icon directory #to the search path, but I don't think we have #any extra icons that matter in there: #from xpra.platform.paths import get_icon_dir #d = get_icon_dir() #if d not in it.get_search_path(): # it.append_search_path(d) # it.rescan_if_needed() log("default icon theme: %s", it) log("icon search path: %s", it.get_search_path()) log("contexts: %s", it.list_contexts()) icons = [] for context in it.list_contexts(): icons += it.list_icons(context) log("icons: %s", icons) capabilities["theme.default.icons"] = list(set(icons)) if METADATA_SUPPORTED: ms = [x.strip() for x in METADATA_SUPPORTED.split(",")] else: #this is currently unused, and slightly redundant because of metadata.supported below: capabilities["window.states"] = [ "fullscreen", "maximized", "sticky", "above", "below", "shaded", "iconified", "skip-taskbar", "skip-pager" ] ms = list(DEFAULT_METADATA_SUPPORTED) #added in 0.15: ms += [ "command", "workspace", "above", "below", "sticky", "set-initial-position" ] #0.17 if os.name == "posix": #this is only really supported on X11, but posix is easier to check for.. #"strut" and maybe even "fullscreen-monitors" could also be supported on other platforms I guess ms += [ "shaded", "bypass-compositor", "strut", "fullscreen-monitors" ] if HAS_X11_BINDINGS: ms += ["shape"] if self._set_window_menu: ms += ["menu"] #figure out if we can handle the "global menu" stuff: if os.name == "posix" and not sys.platform.startswith("darwin"): try: from xpra.dbus.helper import DBusHelper assert DBusHelper except: pass log("metadata.supported: %s", ms) capabilities["metadata.supported"] = ms #we need the bindings to support initiate-moveresize (posix only for now): updict( capabilities, "window", { "initiate-moveresize": HAS_X11_BINDINGS, "configure.pointer": True, "frame_sizes": self.get_window_frame_sizes() }) from xpra.client.window_backing_base import DELTA_BUCKETS updict( capabilities, "encoding", { "icons.greedy": True, #we don't set a default window icon any more "icons.size": (64, 64), #size we want "icons.max_size": (128, 128), #limit "delta_buckets": DELTA_BUCKETS, }) return capabilities
def do_send_info(self, proto, info, flatten): if flatten: info = flatten_dict(info) else: info = notypedict(info) proto.send_now(("hello", info))
def send_info_response(self, info): if self.info_namespace: v = notypedict(info) else: v = flatten_dict(info) self.send_async("info-response", v)
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
def make_hello(self): capabilities = UIXpraClient.make_hello(self) capabilities["named_cursors"] = len(cursor_types)>0 capabilities.update(flatten_dict(get_gtk_version_info())) #tell the server which icons GTK can use #so it knows when it should supply one as fallback it = icon_theme_get_default() #this would add our bundled icon directory #to the search path, but I don't think we have #any extra icons that matter in there: #from xpra.platform.paths import get_icon_dir #d = get_icon_dir() #if d not in it.get_search_path(): # it.append_search_path(d) # it.rescan_if_needed() log("default icon theme: %s", it) log("icon search path: %s", it.get_search_path()) log("contexts: %s", it.list_contexts()) icons = [] for context in it.list_contexts(): icons += it.list_icons(context) log("icons: %s", icons) capabilities["theme.default.icons"] = list(set(icons)) if METADATA_SUPPORTED: ms = [x.strip() for x in METADATA_SUPPORTED.split(",")] else: #this is currently unused, and slightly redundant because of metadata.supported below: capabilities["window.states"] = ["fullscreen", "maximized", "sticky", "above", "below", "shaded", "iconified", "skip-taskbar", "skip-pager"] ms = list(DEFAULT_METADATA_SUPPORTED) #added in 0.15: ms += ["command", "workspace", "above", "below", "sticky", "set-initial-position"] #0.17 if os.name=="posix": #this is only really supported on X11, but posix is easier to check for.. #"strut" and maybe even "fullscreen-monitors" could also be supported on other platforms I guess ms += ["shaded", "bypass-compositor", "strut", "fullscreen-monitors"] if HAS_X11_BINDINGS: ms += ["shape"] if self._set_window_menu: ms += ["menu"] #figure out if we can handle the "global menu" stuff: if os.name=="posix" and not sys.platform.startswith("darwin"): try: from xpra.dbus.helper import DBusHelper assert DBusHelper except: pass log("metadata.supported: %s", ms) capabilities["metadata.supported"] = ms #we need the bindings to support initiate-moveresize (posix only for now): updict(capabilities, "window", { "initiate-moveresize" : HAS_X11_BINDINGS, "configure.pointer" : True, "frame_sizes" : self.get_window_frame_sizes() }) from xpra.client.window_backing_base import DELTA_BUCKETS updict(capabilities, "encoding", { "icons.greedy" : True, #we don't set a default window icon any more "icons.size" : (64, 64), #size we want "icons.max_size" : (128, 128), #limit "delta_buckets" : DELTA_BUCKETS, }) 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 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