Esempio n. 1
0
 def init(self, opts, _extra_args=()):
     if self._init_done:
         #the gtk client classes can inherit this method
         #from multiple parents, skip initializing twice
         return
     self._init_done = True
     for c in XpraClientBase.__bases__:
         c.init(self, opts)
     self.compression_level = opts.compression_level
     self.display = opts.display
     self.username = opts.username
     self.password = opts.password
     self.password_file = opts.password_file
     self.encryption = opts.encryption or opts.tcp_encryption
     if self.encryption:
         crypto_backend_init()
     self.encryption_keyfile = opts.encryption_keyfile or opts.tcp_encryption_keyfile
     #register the authentication challenge handlers:
     ch = tuple(x.strip().lower() for x in (opts.challenge_handlers or "").split(","))
     for ch_name in ch:
         if ch_name=="all":
             self.challenge_handlers.update(self.default_challenge_methods)
             break
         method = self.default_challenge_methods.get(ch_name)
         if method:
             self.challenge_handlers[ch_name] = method
             continue
         log.warn("Warning: unknown challenge handler '%s'", ch_name)
     if DETECT_LEAKS:
         from xpra.util import detect_leaks
         print_leaks = detect_leaks()
         self.timeout_add(10*1000, print_leaks)
Esempio n. 2
0
    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
Esempio n. 3
0
    def init(self, opts):
        self.compression_level = opts.compression_level
        self.display = opts.display
        self.username = opts.username
        self.password = opts.password
        self.password_file = opts.password_file
        self.encryption = opts.encryption or opts.tcp_encryption
        if self.encryption:
            crypto_backend_init()
        self.encryption_keyfile = opts.encryption_keyfile or opts.tcp_encryption_keyfile
        self.quality = opts.quality
        self.min_quality = opts.min_quality
        self.speed = opts.speed
        self.min_speed = opts.min_speed
        # printing and file transfer:
        FileTransferHandler.init_opts(self, opts)

        if DETECT_LEAKS:
            from xpra.util import detect_leaks

            detailed = []
            # example: warning, uses ugly direct import:
            # try:
            #    from xpra.x11.bindings.ximage import XShmImageWrapper       #@UnresolvedImport
            #    detailed.append(XShmImageWrapper)
            # except:
            #    pass
            print_leaks = detect_leaks(log, detailed)
            self.timeout_add(10 * 1000, print_leaks)
Esempio n. 4
0
    def init(self, opts):
        self.compression_level = opts.compression_level
        self.display = opts.display
        self.username = opts.username
        self.password = opts.password
        self.password_file = opts.password_file
        self.encryption = opts.encryption or opts.tcp_encryption
        if self.encryption:
            crypto_backend_init()
        self.encryption_keyfile = opts.encryption_keyfile or opts.tcp_encryption_keyfile
        self.quality = opts.quality
        self.min_quality = opts.min_quality
        self.speed = opts.speed
        self.min_speed = opts.min_speed
        #printing and file transfer:
        FileTransferHandler.init_opts(self, opts)

        if DETECT_LEAKS:
            from xpra.util import detect_leaks
            detailed = []
            #example: warning, uses ugly direct import:
            #try:
            #    from xpra.x11.bindings.ximage import XShmImageWrapper       #@UnresolvedImport
            #    detailed.append(XShmImageWrapper)
            #except:
            #    pass
            print_leaks = detect_leaks(log, detailed)
            self.timeout_add(10 * 1000, print_leaks)
Esempio n. 5
0
 def process_server_packet(self, proto, packet):
     packet_type = packet[0]
     log("process_server_packet: %s", packet_type)
     if packet_type==Protocol.CONNECTION_LOST:
         self.stop("server connection lost", proto)
         return
     elif packet_type=="disconnect":
         log("got disconnect from server: %s", packet[1])
         if self.exit:
             self.server_protocol.close()
         else:
             self.stop("disconnect from server: %s" % packet[1])
     elif packet_type=="hello":
         c = typedict(packet[1])
         maxw, maxh = c.intpair("max_desktop_size", (4096, 4096))
         caps = self.filter_server_caps(c)
         #add new encryption caps:
         if self.cipher:
             from xpra.net.crypto import crypto_backend_init, new_cipher_caps, DEFAULT_PADDING
             crypto_backend_init()
             padding_options = self.caps.strlistget("cipher.padding.options", [DEFAULT_PADDING])
             auth_caps = new_cipher_caps(self.client_protocol, self.cipher, self.encryption_key, padding_options)
             caps.update(auth_caps)
         #may need to bump packet size:
         proto.max_packet_size = maxw*maxh*4*4
         file_transfer = self.caps.boolget("file-transfer") and c.boolget("file-transfer")
         file_size_limit = max(self.caps.intget("file-size-limit"), c.intget("file-size-limit"))
         file_max_packet_size = int(file_transfer) * (1024 + file_size_limit*1024*1024)
         self.client_protocol.max_packet_size = max(self.client_protocol.max_packet_size, file_max_packet_size)
         self.server_protocol.max_packet_size = max(self.server_protocol.max_packet_size, file_max_packet_size)
         packet = ("hello", caps)
     elif packet_type=="info-response":
         #adds proxy info:
         #note: this is only seen by the client application
         #"xpra info" is a new connection, which talks to the proxy server...
         info = packet[1]
         info.update(self.get_proxy_info(proto))
     elif packet_type=="lost-window":
         wid = packet[1]
         #mark it as lost so we can drop any current/pending frames
         self.lost_windows.add(wid)
         #queue it so it gets cleaned safely (for video encoders mostly):
         self.encode_queue.put(packet)
         #and fall through so tell the client immediately
     elif packet_type=="draw":
         #use encoder thread:
         self.encode_queue.put(packet)
         #which will queue the packet itself when done:
         return
     #we do want to reformat cursor packets...
     #as they will have been uncompressed by the network layer already:
     elif packet_type=="cursor":
         #packet = ["cursor", x, y, width, height, xhot, yhot, serial, pixels, name]
         #or:
         #packet = ["cursor", ""]
         self._packet_recompress(packet, 8, "cursor")
     elif packet_type=="window-icon":
         self._packet_recompress(packet, 5, "icon")
     self.queue_client_packet(packet)
Esempio n. 6
0
 def get_launcher_validation(self):
     crypto_backend_init()
     #TODO: since "mode" is not part of global options
     #this validation should be injected from the launcher instead
     def validate_in_list(x, options):
         if x in options:
             return None
         return "must be in %s" % (", ".join(options))
     modes = self.get_connection_modes()
     return {"mode"              : lambda x : validate_in_list(x, modes)}
Esempio n. 7
0
 def get_launcher_validation(self):
     crypto_backend_init()
     #TODO: since "mode" is not part of global options
     #this validation should be injected from the launcher instead
     def validate_in_list(x, options):
         if x in options:
             return None
         return "must be in %s" % (", ".join(options))
     modes = self.get_connection_modes()
     return {"mode"              : lambda x : validate_in_list(x, modes)}
Esempio n. 8
0
 def get_launcher_validation(self):
     crypto_backend_init()
     #TODO: since "mode" is not part of global options
     #this validation should be injected from the launcher instead
     MODES = ["tcp", "ssh"]
     if "AES" in ENCRYPTION_CIPHERS:
         MODES = ["tcp", "tcp + aes", "ssh"]
     def validate_in_list(x, options):
         if x in options:
             return None
         return "must be in %s" % (", ".join(options))
     return {"mode"              : lambda x : validate_in_list(x, MODES)}
Esempio n. 9
0
    def get_launcher_validation(self):
        crypto_backend_init()
        #TODO: since "mode" is not part of global options
        #this validation should be injected from the launcher instead
        MODES = ["tcp", "ssh"]
        if "AES" in ENCRYPTION_CIPHERS:
            MODES = ["tcp", "tcp + aes", "ssh"]

        def validate_in_list(x, options):
            if x in options:
                return None
            return "must be in %s" % (", ".join(options))

        return {"mode": lambda x: validate_in_list(x, MODES)}
Esempio n. 10
0
 def defaults_init(self):
     #skip warning when running the client
     from xpra import child_reaper
     child_reaper.POLL_WARNING = False
     getChildReaper()
     crypto_backend_init()
     log("XpraClientBase.defaults_init() os.environ:")
     for k,v in os.environ.items():
         log(" %s=%s", k, nonl(v))
     #client state:
     self.exit_code = None
     self.exit_on_signal = False
     #connection attributes:
     self.compression_level = 0
     self.display = None
     self.username = None
     self.password_file = None
     self.password_sent = False
     self.encryption = None
     self.encryption_keyfile = None
     self.server_padding_options = [DEFAULT_PADDING]
     self.quality = -1
     self.min_quality = 0
     self.speed = 0
     self.min_speed = -1
     self.printer_attributes = []
     self.send_printers_pending = False
     self.exported_printers = None
     #protocol stuff:
     self._protocol = None
     self._priority_packets = []
     self._ordinary_packets = []
     self._mouse_position = None
     self._aliases = {}
     self._reverse_aliases = {}
     #server state and caps:
     self.server_capabilities = None
     self._remote_machine_id = None
     self._remote_uuid = None
     self._remote_version = None
     self._remote_revision = None
     self._remote_platform = None
     self._remote_platform_release = None
     self._remote_platform_platform = None
     self._remote_platform_linux_distribution = None
     self.uuid = get_user_uuid()
     self.init_packet_handlers()
     sanity_checks()
Esempio n. 11
0
 def defaults_init(self):
     #skip warning when running the client
     from xpra import child_reaper
     child_reaper.POLL_WARNING = False
     getChildReaper()
     crypto_backend_init()
     log("XpraClientBase.defaults_init() os.environ:")
     for k, v in os.environ.items():
         log(" %s=%s", k, nonl(v))
     #client state:
     self.exit_code = None
     self.exit_on_signal = False
     #connection attributes:
     self.compression_level = 0
     self.display = None
     self.username = None
     self.password_file = None
     self.password_sent = False
     self.encryption = None
     self.encryption_keyfile = None
     self.server_padding_options = [DEFAULT_PADDING]
     self.quality = -1
     self.min_quality = 0
     self.speed = 0
     self.min_speed = -1
     self.printer_attributes = []
     self.send_printers_pending = False
     self.exported_printers = None
     #protocol stuff:
     self._protocol = None
     self._priority_packets = []
     self._ordinary_packets = []
     self._mouse_position = None
     self._aliases = {}
     self._reverse_aliases = {}
     #server state and caps:
     self.server_capabilities = None
     self._remote_machine_id = None
     self._remote_uuid = None
     self._remote_version = None
     self._remote_revision = None
     self._remote_platform = None
     self._remote_platform_release = None
     self._remote_platform_platform = None
     self._remote_platform_linux_distribution = None
     self.uuid = get_user_uuid()
     self.init_packet_handlers()
     sanity_checks()
Esempio n. 12
0
    def init(self, opts):
        if self._init_done:
            #the gtk client classes can inherit this method
            #from multiple parents, skip initializing twice
            return
        self._init_done = True
        for c in XpraClientBase.__bases__:
            c.init(self, opts)
        self.compression_level = opts.compression_level
        self.display = opts.display
        self.username = opts.username
        self.password = opts.password
        self.password_file = opts.password_file
        self.bandwidth_limit = parse_with_unit("bandwidth-limit",
                                               opts.bandwidth_limit)
        bandwidthlog("init bandwidth_limit=%s", self.bandwidth_limit)
        self.encryption = opts.encryption or opts.tcp_encryption
        if self.encryption:
            crypto_backend_init()
        self.encryption_keyfile = opts.encryption_keyfile or opts.tcp_encryption_keyfile
        #register the authentication challenge handlers:
        ch = tuple(x.strip().lower()
                   for x in (opts.challenge_handlers or "").split(","))

        def has_h(name):
            return "all" in ch or name in ch

        for ch_name in ch:
            if ch_name == "all":
                self.challenge_handlers.update(self.default_challenge_methods)
                break
            method = self.default_challenge_methods.get(ch_name)
            if method:
                self.challenge_handlers[ch_name] = method
                continue
            log.warn("Warning: unknown challenge handler '%s'", ch_name)
        if DETECT_LEAKS:
            from xpra.util import detect_leaks
            detailed = []
            #example: warning, uses ugly direct import:
            #try:
            #    from xpra.x11.bindings.ximage import XShmImageWrapper       #@UnresolvedImport
            #    detailed.append(XShmImageWrapper)
            #except:
            #    pass
            print_leaks = detect_leaks(log, detailed)
            self.timeout_add(10 * 1000, print_leaks)
Esempio n. 13
0
    def __init__(self):
        crypto_backend_init()
        log("ServerCore.__init__()")
        self.start_time = time.time()
        self.auth_class = None
        self.tcp_auth_class = None
        self.vsock_auth_class = None
        self._when_ready = []
        self.child_reaper = None
        self.original_desktop_display = None

        self._closing = False
        self._upgrading = False
        #networking bits:
        self._socket_info = []
        self._potential_protocols = []
        self._tcp_proxy_clients = []
        self._tcp_proxy = ""
        self._aliases = {}
        self._reverse_aliases = {}
        self.socket_types = {}
        self._max_connections = MAX_CONCURRENT_CONNECTIONS
        self._socket_timeout = 0.1
        self._socket_dir = None
        self.unix_socket_paths = []

        self.session_name = ""

        #Features:
        self.digest_modes = ("hmac", )
        self.encryption = None
        self.encryption_keyfile = None
        self.tcp_encryption = None
        self.tcp_encryption_keyfile = None
        self.password_file = None
        self.compression_level = 1
        self.exit_with_client = False
        self.server_idle_timeout = 0
        self.server_idle_timer = None

        self.init_control_commands()
        self.init_packet_handlers()
        self.init_aliases()
        sanity_checks()
Esempio n. 14
0
    def __init__(self):
        crypto_backend_init()
        log("ServerCore.__init__()")
        self.start_time = time.time()
        self.auth_class = None
        self.tcp_auth_class = None
        self.vsock_auth_class = None
        self._when_ready = []
        self.child_reaper = None
        self.original_desktop_display = None

        self._closing = False
        self._upgrading = False
        #networking bits:
        self._socket_info = []
        self._potential_protocols = []
        self._tcp_proxy_clients = []
        self._tcp_proxy = ""
        self._aliases = {}
        self._reverse_aliases = {}
        self.socket_types = {}
        self._max_connections = MAX_CONCURRENT_CONNECTIONS
        self._socket_timeout = 0.1
        self._socket_dir = None
        self.unix_socket_paths = []

        self.session_name = ""

        #Features:
        self.digest_modes = ("hmac", )
        self.encryption = None
        self.encryption_keyfile = None
        self.tcp_encryption = None
        self.tcp_encryption_keyfile = None
        self.password_file = None
        self.compression_level = 1
        self.exit_with_client = False
        self.server_idle_timeout = 0
        self.server_idle_timer = None

        self.init_control_commands()
        self.init_packet_handlers()
        self.init_aliases()
        sanity_checks()
Esempio n. 15
0
 def init(self, opts, _extra_args=()):
     if self._init_done:
         #the gtk client classes can inherit this method
         #from multiple parents, skip initializing twice
         return
     self._init_done = True
     for c in XpraClientBase.__bases__:
         c.init(self, opts)
     self.compression_level = opts.compression_level
     self.display = opts.display
     self.username = opts.username
     self.password = opts.password
     self.password_file = opts.password_file
     self.encryption = opts.encryption or opts.tcp_encryption
     if self.encryption:
         crypto_backend_init()
     self.encryption_keyfile = opts.encryption_keyfile or opts.tcp_encryption_keyfile
     self.init_challenge_handlers(opts.challenge_handlers)
     self.init_aliases()
Esempio n. 16
0
 def process_server_packet(self, proto, packet):
     packet_type = packet[0]
     log("process_server_packet: %s", packet_type)
     if packet_type == Protocol.CONNECTION_LOST:
         self.stop("server connection lost", proto)
         return
     elif packet_type == "disconnect":
         log("got disconnect from server: %s", packet[1])
         if self.exit:
             self.server_protocol.close()
         else:
             self.stop("disconnect from server: %s" % packet[1])
     elif packet_type == "hello":
         c = typedict(packet[1])
         maxw, maxh = c.intpair("max_desktop_size", (4096, 4096))
         caps = self.filter_server_caps(c)
         #add new encryption caps:
         if self.cipher:
             from xpra.net.crypto import crypto_backend_init, new_cipher_caps, DEFAULT_PADDING
             crypto_backend_init()
             padding_options = self.caps.strlistget(
                 "cipher.padding.options", [DEFAULT_PADDING])
             auth_caps = new_cipher_caps(self.client_protocol, self.cipher,
                                         self.encryption_key,
                                         padding_options)
             caps.update(auth_caps)
         #may need to bump packet size:
         proto.max_packet_size = maxw * maxh * 4 * 4
         file_transfer = self.caps.boolget("file-transfer") and c.boolget(
             "file-transfer")
         file_size_limit = max(self.caps.intget("file-size-limit"),
                               c.intget("file-size-limit"))
         file_max_packet_size = int(file_transfer) * (
             1024 + file_size_limit * 1024 * 1024)
         self.client_protocol.max_packet_size = max(
             self.client_protocol.max_packet_size, file_max_packet_size)
         self.server_protocol.max_packet_size = max(
             self.server_protocol.max_packet_size, file_max_packet_size)
         packet = ("hello", caps)
     elif packet_type == "info-response":
         #adds proxy info:
         #note: this is only seen by the client application
         #"xpra info" is a new connection, which talks to the proxy server...
         info = packet[1]
         info.update(self.get_proxy_info(proto))
     elif packet_type == "lost-window":
         wid = packet[1]
         #mark it as lost so we can drop any current/pending frames
         self.lost_windows.add(wid)
         #queue it so it gets cleaned safely (for video encoders mostly):
         self.encode_queue.put(packet)
         #and fall through so tell the client immediately
     elif packet_type == "draw":
         #use encoder thread:
         self.encode_queue.put(packet)
         #which will queue the packet itself when done:
         return
     #we do want to reformat cursor packets...
     #as they will have been uncompressed by the network layer already:
     elif packet_type == "cursor":
         #packet = ["cursor", x, y, width, height, xhot, yhot, serial, pixels, name]
         #or:
         #packet = ["cursor", "png", x, y, width, height, xhot, yhot, serial, pixels, name]
         #or:
         #packet = ["cursor", ""]
         if len(packet) >= 8:
             #hard to distinguish png cursors from normal cursors...
             try:
                 int(packet[1])
                 self._packet_recompress(packet, 8, "cursor")
             except:
                 self._packet_recompress(packet, 9, "cursor")
     elif packet_type == "window-icon":
         self._packet_recompress(packet, 5, "icon")
     self.queue_client_packet(packet)
Esempio n. 17
0
 def process_server_packet(self, proto, packet):
     packet_type = packet[0]
     log("process_server_packet: %s", packet_type)
     if packet_type==Protocol.CONNECTION_LOST:
         self.stop("server connection lost", proto)
         return
     elif packet_type=="disconnect":
         log("got disconnect from server: %s", packet[1])
         if self.exit:
             self.server_protocol.close()
         else:
             self.stop("disconnect from server: %s" % packet[1])
     elif packet_type=="hello":
         c = typedict(packet[1])
         maxw, maxh = c.intpair("max_desktop_size", (4096, 4096))
         caps = self.filter_server_caps(c)
         #add new encryption caps:
         if self.cipher:
             from xpra.net.crypto import crypto_backend_init, new_cipher_caps, DEFAULT_PADDING
             crypto_backend_init()
             padding_options = self.caps.strlistget("cipher.padding.options", [DEFAULT_PADDING])
             auth_caps = new_cipher_caps(self.client_protocol, self.cipher, self.encryption_key, padding_options)
             caps.update(auth_caps)
         #may need to bump packet size:
         proto.max_packet_size = maxw*maxh*4*4
         file_transfer = self.caps.boolget("file-transfer") and c.boolget("file-transfer")
         file_size_limit = max(self.caps.intget("file-size-limit"), c.intget("file-size-limit"))
         file_max_packet_size = int(file_transfer) * (1024 + file_size_limit*1024*1024)
         self.client_protocol.max_packet_size = max(self.client_protocol.max_packet_size, file_max_packet_size)
         self.server_protocol.max_packet_size = max(self.server_protocol.max_packet_size, file_max_packet_size)
         packet = ("hello", caps)
     elif packet_type=="info-response":
         #adds proxy info:
         #note: this is only seen by the client application
         #"xpra info" is a new connection, which talks to the proxy server...
         info = packet[1]
         info.update(self.get_proxy_info(proto))
     elif packet_type=="lost-window":
         wid = packet[1]
         #mark it as lost so we can drop any current/pending frames
         self.lost_windows.add(wid)
         #queue it so it gets cleaned safely (for video encoders mostly):
         self.encode_queue.put(packet)
         #and fall through so tell the client immediately
     elif packet_type=="draw":
         #use encoder thread:
         self.encode_queue.put(packet)
         #which will queue the packet itself when done:
         return
     #we do want to reformat cursor packets...
     #as they will have been uncompressed by the network layer already:
     elif packet_type=="cursor":
         #packet = ["cursor", x, y, width, height, xhot, yhot, serial, pixels, name]
         #or:
         #packet = ["cursor", "png", x, y, width, height, xhot, yhot, serial, pixels, name]
         #or:
         #packet = ["cursor", ""]
         if len(packet)>=8:
             #hard to distinguish png cursors from normal cursors...
             try:
                 int(packet[1])
                 self._packet_recompress(packet, 8, "cursor")
             except:
                 self._packet_recompress(packet, 9, "cursor")
     elif packet_type=="window-icon":
         self._packet_recompress(packet, 5, "icon")
     elif packet_type=="send-file":
         if packet[6]:
             packet[6] = Compressed("file-data", packet[6])
     elif packet_type=="send-file-chunk":
         if packet[3]:
             packet[3] = Compressed("file-chunk-data", packet[3])
     elif packet_type=="challenge":
         from xpra.net.crypto import get_salt
         #client may have already responded to the challenge,
         #so we have to handle authentication from this end
         salt = packet[1]
         digest = packet[3]
         client_salt = get_salt(len(salt))
         salt = xor_str(salt, client_salt)
         if digest!=b"hmac":
             self.stop("digest mode '%s' not supported", std(digest))
             return
         password = self.disp_desc.get("password", self.session_options.get("password"))
         log("password from %s / %s = %s", self.disp_desc, self.session_options, password)
         if not password:
             self.stop("authentication requested by the server, but no password available for this session")
             return
         import hmac, hashlib
         password = strtobytes(password)
         salt = strtobytes(salt)
         challenge_response = hmac.HMAC(password, salt, digestmod=hashlib.md5).hexdigest()
         log.info("sending %s challenge response", digest)
         self.send_hello(challenge_response, client_salt)
         return
     self.queue_client_packet(packet)
Esempio n. 18
0
def main():
	from xpra.util import print_nested_dict
	from xpra.platform import program_context
	from xpra.log import enable_color
	with program_context("Network-Info", "Network Info"):
		enable_color()
		verbose = "-v" in sys.argv or "--verbose" in sys.argv
		if verbose:
			log.enable_debug()

		print("Network interfaces found:")
		for iface in get_interfaces():
			if if_nametoindex:
				print("* %s (index=%s)" % (iface.ljust(20), if_nametoindex(iface)))
			else:
				print("* %s" % iface)

		def pver(v):
			if type(v) in (tuple, list):
				s = ""
				for i in range(len(v)):
					if i>0:
						#dot seperated numbers
						if type(v[i-1])==int:
							s += "."
						else:
							s += ", "
					s += str(v[i])
				return s
			if type(v)==bytes:
				from xpra.os_util import bytestostr
				v = bytestostr(v)
			if type(v)==str and v.startswith("v"):
				return v[1:]
			return str(v)

		print("Gateways found:")
		print_nested_dict(get_gateways())

		print("")
		print("Protocol Capabilities:")
		from xpra.net.protocol import get_network_caps
		netcaps = get_network_caps()
		netif = {""	: has_netifaces}
		if netifaces_version:
			netif["version"] = netifaces_version
		netcaps["netifaces"] = netif
		print_nested_dict(netcaps)

		print("")
		print("Network Config:")
		print_nested_dict(get_net_config())

		net_sys = get_net_sys_config()
		if net_sys:
			print("")
			print("Network System Config:")
			print_nested_dict(net_sys)

		print("")
		print("SSL:")
		print_nested_dict(get_ssl_info())

		try:
			from xpra.net.crypto import crypto_backend_init, get_crypto_caps
			crypto_backend_init()
			ccaps = get_crypto_caps()
			if ccaps:
				print("")
				print("Crypto Capabilities:")
				print_nested_dict(ccaps)
		except Exception as e:
			print("No Crypto:")
			print(" %s" % e)
Esempio n. 19
0
def main():
    from xpra.util import print_nested_dict, csv
    from xpra.platform import program_context
    from xpra.platform.netdev_query import get_interface_speed
    from xpra.log import enable_color, add_debug_category, enable_debug_for
    with program_context("Network-Info", "Network Info"):
        enable_color()
        verbose = "-v" in sys.argv or "--verbose" in sys.argv
        if verbose:
            enable_debug_for("network")
            add_debug_category("network")
            log.enable_debug()

        print("Network interfaces found:")
        for iface in get_interfaces():
            if if_nametoindex:
                s = "* %s (index=%s)" % (iface.ljust(20),
                                         if_nametoindex(iface))
            else:
                s = "* %s" % iface
            speed = get_interface_speed(0, iface)
            if speed > 0:
                from xpra.simple_stats import std_unit
                s += " (speed=%sbps)" % std_unit(speed)
            print(s)

        def pver(v):
            if type(v) in (tuple, list):
                s = ""
                for i in range(len(v)):
                    if i > 0:
                        #dot seperated numbers
                        if type(v[i - 1]) == int:
                            s += "."
                        else:
                            s += ", "
                    s += str(v[i])
                return s
            if type(v) == bytes:
                from xpra.os_util import bytestostr
                v = bytestostr(v)
            if type(v) == str and v.startswith("v"):
                return v[1:]
            return str(v)

        print("Gateways found:")
        for gt, idefs in get_gateways().items():
            print("* %s" % gt)  #ie: "INET"
            for i, idef in enumerate(idefs):
                try:
                    if isinstance(idef, (list, tuple)):
                        print(" [%i]           %s" % (i, csv(idef)))
                        continue
                except:
                    print(" [%i]           %s" % (i, idef))

        print("")
        print("Protocol Capabilities:")
        netcaps = get_network_caps()
        netif = {"": has_netifaces}
        if netifaces_version:
            netif["version"] = netifaces_version
        netcaps["netifaces"] = netif
        print_nested_dict(netcaps)

        print("")
        print("Network Config:")
        print_nested_dict(get_net_config())

        net_sys = get_net_sys_config()
        if net_sys:
            print("")
            print("Network System Config:")
            print_nested_dict(net_sys)

        print("")
        print("SSL:")
        print_nested_dict(get_ssl_info())

        try:
            from xpra.net.crypto import crypto_backend_init, get_crypto_caps
            crypto_backend_init()
            ccaps = get_crypto_caps()
            if ccaps:
                print("")
                print("Crypto Capabilities:")
                print_nested_dict(ccaps)
        except Exception as e:
            print("No Crypto:")
            print(" %s" % e)
Esempio n. 20
0
def main():
    from xpra.util import print_nested_dict
    from xpra.platform import program_context
    from xpra.log import enable_color
    with program_context("Network-Info", "Network Info"):
        enable_color()
        verbose = "-v" in sys.argv or "--verbose" in sys.argv
        if verbose:
            log.enable_debug()

        print("Network interfaces found:")
        for iface in get_interfaces():
            if if_nametoindex:
                print("* %s (index=%s)" %
                      (iface.ljust(20), if_nametoindex(iface)))
            else:
                print("* %s" % iface)

        def pver(v):
            if type(v) in (tuple, list):
                s = ""
                for i in range(len(v)):
                    if i > 0:
                        #dot seperated numbers
                        if type(v[i - 1]) == int:
                            s += "."
                        else:
                            s += ", "
                    s += str(v[i])
                return s
            if type(v) == bytes:
                from xpra.os_util import bytestostr
                v = bytestostr(v)
            if type(v) == str and v.startswith("v"):
                return v[1:]
            return str(v)

        print("Gateways found:")
        print_nested_dict(get_gateways())

        print("")
        print("Protocol Capabilities:")
        from xpra.net.protocol import get_network_caps
        netcaps = get_network_caps()
        netif = {"": has_netifaces}
        if netifaces_version:
            netif["version"] = netifaces_version
        netcaps["netifaces"] = netif
        print_nested_dict(netcaps)

        print("")
        print("Network Config:")
        print_nested_dict(get_net_config())

        net_sys = get_net_sys_config()
        if net_sys:
            print("")
            print("Network System Config:")
            print_nested_dict(net_sys)

        print("")
        print("SSL:")
        print_nested_dict(get_ssl_info())

        from xpra.net.crypto import crypto_backend_init, get_crypto_caps
        crypto_backend_init()
        ccaps = get_crypto_caps()
        if ccaps:
            print("")
            print("Crypto Capabilities:")
            print_nested_dict(ccaps)
Esempio n. 21
0
def main():  # pragma: no cover
    from xpra.os_util import POSIX
    from xpra.util import print_nested_dict, csv
    from xpra.platform import program_context
    from xpra.platform.netdev_query import get_interface_info
    from xpra.log import enable_color, add_debug_category, enable_debug_for
    with program_context("Network-Info", "Network Info"):
        enable_color()
        verbose = "-v" in sys.argv or "--verbose" in sys.argv
        if verbose:
            enable_debug_for("network")
            add_debug_category("network")
            log.enable_debug()

        print("Network interfaces found:")
        netifaces = import_netifaces()
        for iface in get_interfaces():
            if if_nametoindex:
                print("* %s (index=%s)" %
                      (iface.ljust(20), if_nametoindex(iface)))
            else:
                print("* %s" % iface)
            addresses = netifaces.ifaddresses(iface)  #@UndefinedVariable pylint: disable=no-member
            for addr, defs in addresses.items():
                if addr in (socket.AF_INET, socket.AF_INET6):
                    for d in defs:
                        ip = d.get("addr")
                        if ip:
                            stype = {
                                socket.AF_INET: "IPv4",
                                socket.AF_INET6: "IPv6",
                            }[addr]
                            print(" * %s:     %s" % (stype, ip))
                            if POSIX:
                                from xpra.net.socket_util import create_tcp_socket
                                try:
                                    sock = create_tcp_socket(ip, 0)
                                    sockfd = sock.fileno()
                                    info = get_interface_info(sockfd, iface)
                                    if info:
                                        print("  %s" % info)
                                finally:
                                    sock.close()
            if not POSIX:
                info = get_interface_info(0, iface)
                if info:
                    print("  %s" % info)

        from xpra.os_util import bytestostr

        def pver(v):
            if isinstance(v, (tuple, list)):
                s = ""
                lastx = None
                for x in v:
                    if lastx is not None:
                        #dot seperated numbers
                        if isinstance(lastx, int):
                            s += "."
                        else:
                            s += ", "
                    s += bytestostr(x)
                    lastx = x
                return s
            if isinstance(v, bytes):
                v = bytestostr(v)
            if isinstance(v, str) and v.startswith("v"):
                return v[1:]
            return str(v)

        print("Gateways found:")
        for gt, idefs in get_gateways().items():
            print("* %s" % gt)  #ie: "INET"
            for i, idef in enumerate(idefs):
                if isinstance(idef, (list, tuple)):
                    print(" [%i]           %s" % (i, csv(idef)))
                    continue

        print("")
        print("Protocol Capabilities:")
        netcaps = get_network_caps()
        netif = {"": bool(netifaces)}
        if netifaces_version:
            netif["version"] = netifaces_version
        netcaps["netifaces"] = netif
        print_nested_dict(netcaps, vformat=pver)

        print("")
        print("Network Config:")
        print_nested_dict(get_net_config())

        net_sys = get_net_sys_config()
        if net_sys:
            print("")
            print("Network System Config:")
            print_nested_dict(net_sys)

        print("")
        print("SSL:")
        print_nested_dict(get_ssl_info(True))

        try:
            from xpra.net.crypto import crypto_backend_init, get_crypto_caps
            crypto_backend_init()
            ccaps = get_crypto_caps()
            if ccaps:
                print("")
                print("Crypto Capabilities:")
                print_nested_dict(ccaps)
        except Exception as e:
            print("No Crypto:")
            print(" %s" % e)
    return 0
Esempio n. 22
0
 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
Esempio n. 23
0
 def process_server_packet(self, proto, packet):
     packet_type = packet[0]
     log("process_server_packet: %s", packet_type)
     if packet_type==Protocol.CONNECTION_LOST:
         self.stop("server connection lost", proto)
         return
     elif packet_type=="disconnect":
         log("got disconnect from server: %s", packet[1])
         if self.exit:
             self.server_protocol.close()
         else:
             self.stop("disconnect from server: %s" % packet[1])
     elif packet_type=="hello":
         c = typedict(packet[1])
         maxw, maxh = c.intpair("max_desktop_size", (4096, 4096))
         caps = self.filter_server_caps(c)
         #add new encryption caps:
         if self.cipher:
             from xpra.net.crypto import crypto_backend_init, new_cipher_caps, DEFAULT_PADDING
             crypto_backend_init()
             padding_options = self.caps.strlistget("cipher.padding.options", [DEFAULT_PADDING])
             auth_caps = new_cipher_caps(self.client_protocol, self.cipher, self.encryption_key, padding_options)
             caps.update(auth_caps)
         #may need to bump packet size:
         proto.max_packet_size = maxw*maxh*4*4
         file_transfer = self.caps.boolget("file-transfer") and c.boolget("file-transfer")
         file_size_limit = max(self.caps.intget("file-size-limit"), c.intget("file-size-limit"))
         file_max_packet_size = int(file_transfer) * (1024 + file_size_limit*1024*1024)
         self.client_protocol.max_packet_size = max(self.client_protocol.max_packet_size, file_max_packet_size)
         self.server_protocol.max_packet_size = max(self.server_protocol.max_packet_size, file_max_packet_size)
         packet = ("hello", caps)
     elif packet_type=="info-response":
         #adds proxy info:
         #note: this is only seen by the client application
         #"xpra info" is a new connection, which talks to the proxy server...
         info = packet[1]
         info.update(self.get_proxy_info(proto))
     elif packet_type=="lost-window":
         wid = packet[1]
         #mark it as lost so we can drop any current/pending frames
         self.lost_windows.add(wid)
         #queue it so it gets cleaned safely (for video encoders mostly):
         self.encode_queue.put(packet)
         #and fall through so tell the client immediately
     elif packet_type=="draw":
         #use encoder thread:
         self.encode_queue.put(packet)
         #which will queue the packet itself when done:
         return
     #we do want to reformat cursor packets...
     #as they will have been uncompressed by the network layer already:
     elif packet_type=="cursor":
         #packet = ["cursor", x, y, width, height, xhot, yhot, serial, pixels, name]
         #or:
         #packet = ["cursor", "png", x, y, width, height, xhot, yhot, serial, pixels, name]
         #or:
         #packet = ["cursor", ""]
         if len(packet)>=8:
             #hard to distinguish png cursors from normal cursors...
             try:
                 int(packet[1])
                 self._packet_recompress(packet, 8, "cursor")
             except:
                 self._packet_recompress(packet, 9, "cursor")
     elif packet_type=="window-icon":
         self._packet_recompress(packet, 5, "icon")
     elif packet_type=="send-file":
         if packet[6]:
             packet[6] = Compressed("file-data", packet[6])
     elif packet_type=="send-file-chunk":
         if packet[3]:
             packet[3] = Compressed("file-chunk-data", packet[3])
     elif packet_type=="challenge":
         from xpra.net.crypto import get_salt
         #client may have already responded to the challenge,
         #so we have to handle authentication from this end
         salt = packet[1]
         digest = packet[3]
         client_salt = get_salt(len(salt))
         salt = xor_str(salt, client_salt)
         if digest!=b"hmac":
             self.stop("digest mode '%s' not supported", std(digest))
             return
         password = self.session_options.get("password")
         if not password:
             self.stop("authentication requested by the server, but no password available for this session")
             return
         import hmac, hashlib
         password = strtobytes(password)
         salt = strtobytes(salt)
         challenge_response = hmac.HMAC(password, salt, digestmod=hashlib.md5).hexdigest()
         log.info("sending %s challenge response", digest)
         self.send_hello(challenge_response, client_salt)
         return
     self.queue_client_packet(packet)
Esempio n. 24
0
 def process_server_packet(self, proto, packet):
     packet_type = packet[0]
     log("process_server_packet: %s", packet_type)
     if packet_type == Protocol.CONNECTION_LOST:
         self.stop("server connection lost", proto)
         return
     elif packet_type == "disconnect":
         log("got disconnect from server: %s", packet[1])
         if self.exit:
             self.server_protocol.close()
         else:
             self.stop("disconnect from server: %s" % packet[1])
     elif packet_type == "hello":
         c = typedict(packet[1])
         maxw, maxh = c.intpair("max_desktop_size", (4096, 4096))
         caps = self.filter_server_caps(c)
         #add new encryption caps:
         if self.cipher:
             from xpra.net.crypto import crypto_backend_init, new_cipher_caps, DEFAULT_PADDING
             crypto_backend_init()
             padding_options = self.caps.strlistget(
                 "cipher.padding.options", [DEFAULT_PADDING])
             auth_caps = new_cipher_caps(self.client_protocol, self.cipher,
                                         self.encryption_key,
                                         padding_options)
             caps.update(auth_caps)
         #may need to bump packet size:
         proto.max_packet_size = maxw * maxh * 4 * 4
         file_transfer = self.caps.boolget("file-transfer") and c.boolget(
             "file-transfer")
         file_size_limit = max(self.caps.intget("file-size-limit"),
                               c.intget("file-size-limit"))
         file_max_packet_size = int(file_transfer) * (
             1024 + file_size_limit * 1024 * 1024)
         self.client_protocol.max_packet_size = max(
             self.client_protocol.max_packet_size, file_max_packet_size)
         self.server_protocol.max_packet_size = max(
             self.server_protocol.max_packet_size, file_max_packet_size)
         packet = ("hello", caps)
     elif packet_type == "info-response":
         #adds proxy info:
         #note: this is only seen by the client application
         #"xpra info" is a new connection, which talks to the proxy server...
         info = packet[1]
         info.update(self.get_proxy_info(proto))
     elif packet_type == "lost-window":
         wid = packet[1]
         #mark it as lost so we can drop any current/pending frames
         self.lost_windows.add(wid)
         #queue it so it gets cleaned safely (for video encoders mostly):
         self.encode_queue.put(packet)
         #and fall through so tell the client immediately
     elif packet_type == "draw":
         #use encoder thread:
         self.encode_queue.put(packet)
         #which will queue the packet itself when done:
         return
     #we do want to reformat cursor packets...
     #as they will have been uncompressed by the network layer already:
     elif packet_type == "cursor":
         #packet = ["cursor", x, y, width, height, xhot, yhot, serial, pixels, name]
         #or:
         #packet = ["cursor", "png", x, y, width, height, xhot, yhot, serial, pixels, name]
         #or:
         #packet = ["cursor", ""]
         if len(packet) >= 8:
             #hard to distinguish png cursors from normal cursors...
             try:
                 int(packet[1])
                 self._packet_recompress(packet, 8, "cursor")
             except:
                 self._packet_recompress(packet, 9, "cursor")
     elif packet_type == "window-icon":
         self._packet_recompress(packet, 5, "icon")
     elif packet_type == "send-file":
         if packet[6]:
             packet[6] = Compressed("file-data", packet[6])
     elif packet_type == "send-file-chunk":
         if packet[3]:
             packet[3] = Compressed("file-chunk-data", packet[3])
     elif packet_type == "challenge":
         password = self.session_options.get("password")
         if not password:
             self.stop(
                 "authentication requested by the server, but no password available for this session"
             )
             return
         from xpra.net.crypto import get_salt, gendigest
         #client may have already responded to the challenge,
         #so we have to handle authentication from this end
         server_salt = bytestostr(packet[1])
         l = len(server_salt)
         digest = bytestostr(packet[3])
         salt_digest = "xor"
         if len(packet) >= 5:
             salt_digest = bytestostr(packet[4])
         if salt_digest in ("xor", "des"):
             if not LEGACY_SALT_DIGEST:
                 self.stop("server uses legacy salt digest '%s'" %
                           salt_digest)
                 return
             log.warn(
                 "Warning: server using legacy support for '%s' salt digest",
                 salt_digest)
         if salt_digest == "xor":
             #with xor, we have to match the size
             assert l >= 16, "server salt is too short: only %i bytes, minimum is 16" % l
             assert l <= 256, "server salt is too long: %i bytes, maximum is 256" % l
         else:
             #other digest, 32 random bytes is enough:
             l = 32
         client_salt = get_salt(l)
         salt = gendigest(salt_digest, client_salt, server_salt)
         challenge_response = gendigest(digest, password, salt)
         if not challenge_response:
             log("invalid digest module '%s': %s", digest)
             self.stop(
                 "server requested '%s' digest but it is not supported" %
                 digest)
             return
         log.info("sending %s challenge response", digest)
         self.send_hello(challenge_response, client_salt)
         return
     self.queue_client_packet(packet)
Esempio n. 25
0
 def process_server_packet(self, proto, packet):
     packet_type = bytestostr(packet[0])
     log("process_server_packet: %s", packet_type)
     if packet_type == CONNECTION_LOST:
         self.stop(proto, "server connection lost")
         return
     if packet_type == "disconnect":
         reason = bytestostr(packet[1])
         log("got disconnect from server: %s", reason)
         if self.exit:
             self.server_protocol.close()
         else:
             self.stop(None, "disconnect from server", reason)
     elif packet_type == "hello":
         c = typedict(packet[1])
         if c.boolget("ping-echo-sourceid"):
             self.schedule_server_ping()
         maxw, maxh = c.intpair("max_desktop_size", (4096, 4096))
         caps = self.filter_server_caps(c)
         #add new encryption caps:
         if self.cipher:
             from xpra.net.crypto import crypto_backend_init, new_cipher_caps, DEFAULT_PADDING
             crypto_backend_init()
             padding_options = self.caps.strtupleget(
                 "cipher.padding.options", [DEFAULT_PADDING])
             auth_caps = new_cipher_caps(self.client_protocol, self.cipher,
                                         self.cipher_mode,
                                         self.encryption_key,
                                         padding_options)
             caps.update(auth_caps)
         #may need to bump packet size:
         proto.max_packet_size = max(MAX_PACKET_SIZE, maxw * maxh * 4 * 4)
         packet = ("hello", caps)
     elif packet_type == "ping_echo" and self.server_ping_timer and len(
             packet) >= 7 and strtobytes(packet[6]) == strtobytes(
                 self.uuid):
         #this is one of our ping packets:
         self.server_last_ping_echo = packet[1]
         self.server_last_ping_latency = 1000 * monotonic(
         ) - self.server_last_ping_echo
         log("ping-echo: server latency=%.1fms",
             self.server_last_ping_latency)
         return
     elif packet_type == "info-response":
         #adds proxy info:
         #note: this is only seen by the client application
         #"xpra info" is a new connection, which talks to the proxy server...
         info = packet[1]
         info.update(self.get_proxy_info(proto))
     elif packet_type == "lost-window":
         wid = packet[1]
         #mark it as lost so we can drop any current/pending frames
         self.lost_windows.add(wid)
         #queue it so it gets cleaned safely (for video encoders mostly):
         self.encode_queue.put(packet)
         #and fall through so tell the client immediately
     elif packet_type == "draw":
         #use encoder thread:
         self.encode_queue.put(packet)
         #which will queue the packet itself when done:
         return
     elif packet_type == "sound-data":
         sound_data = packet[2]
         if sound_data:
             #best if we use raw packets for the actual sound-data chunk:
             packet[2] = Compressed("sound-data", sound_data)
     #we do want to reformat cursor packets...
     #as they will have been uncompressed by the network layer already:
     elif packet_type == "cursor":
         #packet = ["cursor", "png", x, y, width, height, xhot, yhot, serial, pixels, name]
         #or:
         #packet = ["cursor", ""]
         if len(packet) >= 8:
             self._packet_recompress(packet, 9, "cursor")
     elif packet_type == "window-icon":
         self._packet_recompress(packet, 5, "icon")
     elif packet_type == "send-file":
         if packet[6]:
             packet[6] = Compressed("file-data", packet[6])
     elif packet_type == "send-file-chunk":
         if packet[3]:
             packet[3] = Compressed("file-chunk-data", packet[3])
     elif packet_type == "challenge":
         password = self.disp_desc.get("password",
                                       self.session_options.get("password"))
         log("password from %s / %s = %s", self.disp_desc,
             self.session_options, password)
         if not password:
             if not PASSTHROUGH_AUTH:
                 self.stop(None, "authentication requested by the server,",
                           "but no password is available for this session")
             #otherwise, just forward it to the client
             self.client_challenge_packet = packet
         else:
             #client may have already responded to the challenge,
             #so we have to handle authentication from this end
             server_salt = bytestostr(packet[1])
             l = len(server_salt)
             digest = bytestostr(packet[3])
             salt_digest = "xor"
             if len(packet) >= 5:
                 salt_digest = bytestostr(packet[4])
             if salt_digest in ("xor", "des"):
                 if not LEGACY_SALT_DIGEST:
                     self.stop(
                         None, "server uses legacy salt digest '%s'" %
                         salt_digest)
                     return
                 log.warn(
                     "Warning: server using legacy support for '%s' salt digest",
                     salt_digest)
             if salt_digest == "xor":
                 #with xor, we have to match the size
                 assert l >= 16, "server salt is too short: only %i bytes, minimum is 16" % l
                 assert l <= 256, "server salt is too long: %i bytes, maximum is 256" % l
             else:
                 #other digest, 32 random bytes is enough:
                 l = 32
             client_salt = get_salt(l)
             salt = gendigest(salt_digest, client_salt, server_salt)
             challenge_response = gendigest(digest, password, salt)
             if not challenge_response:
                 log("invalid digest module '%s': %s", digest)
                 self.stop(
                     None,
                     "server requested '%s' digest but it is not supported"
                     % digest)
                 return
             log.info("sending %s challenge response", digest)
             self.send_hello(challenge_response, client_salt)
             return
     self.queue_client_packet(packet)