def process_server_packet(self, proto, packet): packet_type = packet[0] debug("process_server_packet: %s", packet_type) if packet_type==Protocol.CONNECTION_LOST: self.stop("server connection lost", proto) return elif packet_type=="hello": c = typedict(packet[1]) maxw, maxh = c.intpair("max_desktop_size", (4096, 4096)) proto.max_packet_size = maxw*maxh*4 caps = self.filter_server_caps(c) #add new encryption caps: if self.cipher: auth_caps = new_cipher_caps(self.client_protocol, self.cipher, self.encryption_key) caps.update(auth_caps) 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(get_server_info("proxy.")) info.update(get_thread_info("proxy.", proto)) info.update(self.get_encoder_info()) 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=="cursor": #packet = ["cursor", x, y, width, height, xhot, yhot, serial, pixels, name] #or: #packet = ["cursor", ""] if len(packet)>=9: pixels = packet[8] if len(pixels)<64: packet[8] = str(pixels) else: packet[8] = compressed_wrapper("cursor", pixels) self.queue_client_packet(packet)
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 == "hello": c = typedict(packet[1]) maxw, maxh = c.intpair("max_desktop_size", (4096, 4096)) proto.max_packet_size = maxw * maxh * 4 * 4 caps = self.filter_server_caps(c) #add new encryption caps: if self.cipher: auth_caps = new_cipher_caps(self.client_protocol, self.cipher, self.encryption_key) caps.update(auth_caps) 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 elif packet_type == "cursor": #packet = ["cursor", x, y, width, height, xhot, yhot, serial, pixels, name] #or: #packet = ["cursor", ""] if len(packet) >= 9: pixels = packet[8] if len(pixels) < 512: packet[8] = str(pixels) else: packet[8] = compressed_wrapper("cursor", pixels) self.queue_client_packet(packet)
def process_server_packet(self, proto, packet): packet_type = packet[0] debug("process_server_packet: %s", packet_type) if packet_type==Protocol.CONNECTION_LOST: self.stop("server connection lost", proto) return elif packet_type=="hello": c = typedict(packet[1]) maxw, maxh = c.intpair("max_desktop_size", (4096, 4096)) proto.max_packet_size = maxw*maxh*4 caps = self.filter_server_caps(c) #add new encryption caps: if self.cipher: auth_caps = new_cipher_caps(self.client_protocol, self.cipher, self.encryption_key) caps.update(auth_caps) 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(get_server_info("proxy.")) info.update(get_thread_info("proxy.", proto)) info.update(self.get_encoder_info()) elif packet_type=="lost-window": wid = packet[1] ve = self.video_encoders.get(wid) if ve: ve.clean() del self.video_encoders[wid] elif packet_type=="draw": self.process_draw(packet) elif packet_type=="cursor": #packet = ["cursor", x, y, width, height, xhot, yhot, serial, pixels, name] #or: #packet = ["cursor", ""] if len(packet)>=9: pixels = packet[8] if len(pixels)<64: packet[8] = str(pixels) else: packet[8] = compressed_wrapper("cursor", pixels) self.queue_client_packet(packet)
def process_server_packet(self, proto, packet): packet_type = packet[0] debug("process_server_packet: %s", packet_type) if packet_type == Protocol.CONNECTION_LOST: self.stop("server connection lost", proto) return elif packet_type == "hello": c = typedict(packet[1]) maxw, maxh = c.intpair("max_desktop_size", (4096, 4096)) proto.max_packet_size = maxw * maxh * 4 caps = self.filter_server_caps(c) #add new encryption caps: if self.cipher: auth_caps = new_cipher_caps(self.client_protocol, self.cipher, self.encryption_key) caps.update(auth_caps) packet = ("hello", caps) elif packet_type == "info-response": #adds proxy info: info = packet[1] info.update(get_server_info("proxy.")) info.update(get_thread_info("proxy.", proto)) elif packet_type == "draw": #packet = ["draw", wid, x, y, outw, outh, coding, data, self._damage_packet_sequence, outstride, client_options] #ensure we don't try to re-compress the pixel data in the network layer: #(re-add the "compressed" marker that gets lost when we re-assemble packets) coding = packet[6] if coding != "mmap": data = packet[7] packet[7] = Compressed("%s pixels" % coding, data) elif packet_type == "cursor": #packet = ["cursor", x, y, width, height, xhot, yhot, serial, pixels, name] #or: #packet = ["cursor", ""] if len(packet) >= 9: pixels = packet[8] if len(pixels) < 64: packet[8] = str(pixels) else: packet[8] = compressed_wrapper("cursor", pixels) self.queue_client_packet(packet)
def process_server_packet(self, proto, packet): packet_type = packet[0] debug("process_server_packet: %s", packet_type) if packet_type==Protocol.CONNECTION_LOST: self.stop("server connection lost", proto) return elif packet_type=="hello": c = typedict(packet[1]) maxw, maxh = c.intpair("max_desktop_size", (4096, 4096)) proto.max_packet_size = maxw*maxh*4 caps = self.filter_server_caps(c) #add new encryption caps: if self.cipher: auth_caps = new_cipher_caps(self.client_protocol, self.cipher, self.encryption_key) caps.update(auth_caps) packet = ("hello", caps) elif packet_type=="info-response": #adds proxy info: info = packet[1] info.update(get_server_info("proxy.")) info.update(get_thread_info("proxy.", proto)) elif packet_type=="draw": #packet = ["draw", wid, x, y, outw, outh, coding, data, self._damage_packet_sequence, outstride, client_options] #ensure we don't try to re-compress the pixel data in the network layer: #(re-add the "compressed" marker that gets lost when we re-assemble packets) coding = packet[6] if coding!="mmap": data = packet[7] packet[7] = Compressed("%s pixels" % coding, data) elif packet_type=="cursor": #packet = ["cursor", x, y, width, height, xhot, yhot, serial, pixels, name] #or: #packet = ["cursor", ""] if len(packet)>=9: pixels = packet[8] if len(pixels)<64: packet[8] = str(pixels) else: packet[8] = compressed_wrapper("cursor", pixels) self.queue_client_packet(packet)
key_salt = c.strget("cipher.key_salt") iterations = c.intget("cipher.key_stretch_iterations") auth_caps = {} if cipher and cipher_iv: if cipher not in ENCRYPTION_CIPHERS: log.warn("unsupported cipher: %s", cipher) auth_failed("unsupported cipher") return False encryption_key = self.get_encryption_key(proto.authenticator) if encryption_key is None: auth_failed("encryption key is missing") return False proto.set_cipher_out(cipher, cipher_iv, encryption_key, key_salt, iterations) #use the same cipher as used by the client: auth_caps = new_cipher_caps(proto, cipher, encryption_key) log("server cipher=%s", auth_caps) else: auth_caps = None #verify authentication if required: if proto.authenticator and proto.authenticator.requires_challenge(): challenge_response = c.strget("challenge_response") client_salt = c.strget("challenge_client_salt") log( "processing authentication with %s, response=%s, client_salt=%s", proto.authenticator, challenge_response, binascii.hexlify(client_salt or "")) #send challenge if this is not a response: if not challenge_response: challenge = proto.authenticator.get_challenge()
cipher_iv = c.strget("cipher.iv") key_salt = c.strget("cipher.key_salt") iterations = c.intget("cipher.key_stretch_iterations") auth_caps = {} if cipher and cipher_iv: if cipher not in ENCRYPTION_CIPHERS: log.warn("unsupported cipher: %s", cipher) auth_failed("unsupported cipher") return False encryption_key = self.get_encryption_key(proto.authenticator) if encryption_key is None: auth_failed("encryption key is missing") return False proto.set_cipher_out(cipher, cipher_iv, encryption_key, key_salt, iterations) #use the same cipher as used by the client: auth_caps = new_cipher_caps(proto, cipher, encryption_key) log("server cipher=%s", auth_caps) else: auth_caps = None #verify authentication if required: if proto.authenticator: challenge_response = c.strget("challenge_response") client_salt = c.strget("challenge_client_salt") log("processing authentication with %s, response=%s, client_salt=%s", proto.authenticator, challenge_response, binascii.hexlify(client_salt or "")) #send challenge if this is not a response: if not challenge_response: challenge = proto.authenticator.get_challenge() if challenge is None: auth_failed("invalid authentication state: unexpected challenge response") return False