Exemple #1
0
def get_icc_info():
    try:
        data = _get_X11_root_property("_ICC_PROFILE", "CARDINAL")
        if data:
            screenlog("_ICC_PROFILE=%s (%s)", type(data), len(data))
            version = _get_X11_root_property("_ICC_PROFILE_IN_X_VERSION",
                                             "CARDINAL")
            screenlog(
                "get_icc_info() found _ICC_PROFILE_IN_X_VERSION=%s, _ICC_PROFILE=%s",
                hexstr(version or ""), hexstr(data))
            icc = {
                "source": "_ICC_PROFILE",
                "data": data,
            }
            if version:
                try:
                    version = ord(version)
                except:
                    pass
                icc["version"] = version
            return icc
    except Exception as e:
        screenlog.error(
            "Error: cannot access _ICC_PROFILE X11 window property")
        screenlog.error(" %s", e)
        screenlog("get_icc_info()", exc_info=True)
    return {}
Exemple #2
0
 def _parse_security_handshake(self, packet):
     log("parse_security_handshake(%s)", hexstr(packet))
     n = struct.unpack(b"B", packet[:1])[0]
     if n == 0:
         self._internal_error("cannot parse security handshake '%s'" %
                              hexstr(packet))
         return 0
     security_types = struct.unpack(b"B" * n, packet[1:])
     st = []
     for v in security_types:
         try:
             v = RFBAuth(v)
         except ValueError:
             pass
         st.append(v)
     log("parse_security_handshake(%s) security_types=%s", hexstr(packet),
         [AUTH_STR.get(v, v) for v in st])
     if not st or RFBAuth.NONE in st:
         auth_type = RFBAuth.NONE
         #go straight to the result:
         self._packet_parser = self._parse_security_result
     elif RFBAuth.VNC in st:
         auth_type = RFBAuth.VNC
         self._packet_parser = self._parse_vnc_security_challenge
     else:
         self._internal_error("no supported security types in %r" %
                              csv(AUTH_STR.get(v, v) for v in st))
         return 0
     self.send_struct(b"B", auth_type)
     return 1 + n
Exemple #3
0
 def _parse_challenge(self, response):
     authlog("parse_challenge(%s)", hexstr(response))
     if len(response) < 16:
         return 0
     assert self._authenticator
     try:
         assert len(response) == 16
         hex_response = hexstr(response)
         #log("padded password=%s", password)
         caps = typedict({
             "challenge_response": hex_response,
         })
         if self._authenticator.authenticate(caps):
             authlog("challenge authentication succeeded")
             self.send(struct.pack(b"!I", 0))
             self._packet_parser = self._parse_security_result
             return 16
         authlog.warn("Warning: authentication challenge response failure")
         authlog.warn(" password does not match")
     except Exception as e:
         authlog("parse_challenge(%s)", hexstr(response), exc_info=True)
         authlog.error("Error: authentication challenge failure:")
         authlog.error(" %s", e)
     self.timeout_add(1000, self.send_fail_challenge)
     return len(response)
Exemple #4
0
def get_icc_info():
    if not is_Wayland():
        try:
            data = _get_X11_root_property("_ICC_PROFILE", "CARDINAL")
            if data:
                screenlog("_ICC_PROFILE=%s (%s)", type(data), len(data))
                version = _get_X11_root_property("_ICC_PROFILE_IN_X_VERSION",
                                                 "CARDINAL")
                screenlog(
                    "get_icc_info() found _ICC_PROFILE_IN_X_VERSION=%s, _ICC_PROFILE=%s",
                    hexstr(version or ""), hexstr(data))
                icc = {
                    "source": "_ICC_PROFILE",
                    "data": data,
                }
                if version:
                    try:
                        version = ord(version)
                    except TypeError:
                        pass
                    icc["version"] = version
                screenlog("get_icc_info()=%s", icc)
                return icc
        except Exception as e:
            screenlog.error(
                "Error: cannot access _ICC_PROFILE X11 window property")
            screenlog.error(" %s", e)
            screenlog("get_icc_info()", exc_info=True)
    from xpra.platform.gui import default_get_icc_info
    return default_get_icc_info()
Exemple #5
0
 def _parse_security_handshake(self, packet):
     log("parse_security_handshake(%s)", hexstr(packet))
     try:
         auth = struct.unpack(b"B", packet)[0]
     except:
         self._internal_error(
             packet, "cannot parse security handshake response '%s'" %
             hexstr(packet))
         return 0
     auth_str = RFBAuth.AUTH_STR.get(auth, auth)
     if auth == RFBAuth.VNC:
         #send challenge:
         self._packet_parser = self._parse_challenge
         assert self._authenticator
         challenge, digest = self._authenticator.get_challenge("des")
         assert digest == "des"
         self._challenge = challenge[:16]
         log("sending RFB challenge value: %s", hexstr(self._challenge))
         self.send(self._challenge)
         return 1
     if self._authenticator and self._authenticator.requires_challenge():
         self._invalid_header(
             packet,
             "invalid security handshake response, authentication is required"
         )
         return 0
     log("parse_security_handshake: auth=%s, sending SecurityResult",
         auth_str)
     #Security Handshake, send SecurityResult Handshake
     self._packet_parser = self._parse_security_result
     self.send(struct.pack(b"!I", 0))
     return 1
Exemple #6
0
    def send_challenge_reply(self, packet, password):
        if not password:
            if self.password_file:
                self.auth_error(
                    EXIT_PASSWORD_FILE_ERROR,
                    "failed to load password from file%s %s" %
                    (engs(self.password_file), csv(self.password_file)),
                    "no password available")
            else:
                self.auth_error(
                    EXIT_PASSWORD_REQUIRED,
                    "this server requires authentication and no password is available"
                )
            return
        if self.encryption:
            assert len(
                packet
            ) >= 3, "challenge does not contain encryption details to use for the response"
            server_cipher = typedict(packet[2])
            key = self.get_encryption_key()
            if key is None:
                self.auth_error(EXIT_ENCRYPTION,
                                "the server does not use any encryption",
                                "client requires encryption")
                return
            if not self.set_server_encryption(server_cipher, key):
                return
        #all server versions support a client salt,
        #they also tell us which digest to use:
        server_salt = bytestostr(packet[1])
        digest = bytestostr(packet[3])
        actual_digest = digest.split(":", 1)[0]
        l = len(server_salt)
        salt_digest = "xor"
        if len(packet) >= 5:
            salt_digest = bytestostr(packet[4])
        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)
        authlog("combined %s salt(%s, %s)=%s", salt_digest,
                hexstr(server_salt), hexstr(client_salt), hexstr(salt))

        challenge_response = gendigest(actual_digest, password, salt)
        if not challenge_response:
            log("invalid digest module '%s': %s", actual_digest)
            self.auth_error(
                EXIT_UNSUPPORTED,
                "server requested '%s' digest but it is not supported" %
                actual_digest, "invalid digest")
            return
        authlog("%s(%s, %s)=%s", actual_digest, repr(password), repr(salt),
                repr(challenge_response))
        self.do_send_challenge_reply(challenge_response, client_salt)
Exemple #7
0
 def _test_YUV420P(self,
                   encoding,
                   encoder_module,
                   decoder_module,
                   yuvdata,
                   width=16,
                   height=16):
     in_csc = "YUV420P"
     if in_csc not in encoder_module.get_input_colorspaces(encoding):
         raise Exception("%s does not support %s as input" %
                         (encoder_module, in_csc))
     if in_csc != decoder_module.get_output_colorspace(encoding, in_csc):
         raise Exception("%s does not support %s as output for %s" %
                         (decoder_module, in_csc, in_csc))
     encoder = encoder_module.Encoder()
     options = typedict({"max-delayed": 0})
     encoder.init_context(encoding, width, height, in_csc, options)
     in_image = make_test_image(in_csc, width, height)
     yuv = []
     rowstrides = []
     divs = get_subsampling_divs(in_csc)
     for i, bvalue in enumerate(yuvdata):
         xdiv, ydiv = divs[i]
         rowstride = width // xdiv
         rowstrides.append(rowstride)
         size = rowstride * height // ydiv
         yuv.append(chr(bvalue).encode("latin1") * size)
     in_image.set_pixels(yuv)
     in_image.set_rowstride(rowstrides)
     cdata, client_options = encoder.compress_image(in_image)
     assert cdata
     #decode it:
     decoder = decoder_module.Decoder()
     decoder.init_context(encoding, width, height, in_csc)
     out_image = decoder.decompress_image(cdata, typedict(client_options))
     #print("%s %s : %s" % (encoding, decoder_module, out_image))
     in_planes = in_image.get_pixels()
     out_planes = out_image.get_pixels()
     for i, plane in enumerate(("Y", "U", "V")):
         in_pdata = in_planes[i]
         out_pdata = out_planes[i]
         xdiv, ydiv = divs[i]
         in_stride = in_image.get_rowstride()[i]
         out_stride = out_image.get_rowstride()[i]
         #compare lines at a time since the rowstride may be different:
         for y in range(height // ydiv):
             in_rowdata = in_pdata[in_stride * y:in_stride * y +
                                   width // xdiv]
             out_rowdata = out_pdata[out_stride * y:out_stride * y +
                                     width // xdiv]
             if not cmpp(in_rowdata, out_rowdata):
                 raise Exception(
                     "expected %s but got %s for row %i of plane %s with %s"
                     % (hexstr(in_rowdata), hexstr(out_rowdata), y, plane,
                        encoding))
Exemple #8
0
 def get_response_salt(self, client_salt=None):
     server_salt = self.salt
     #make sure it does not get re-used:
     self.salt = None
     if client_salt is None:
         return server_salt
     salt = gendigest(self.salt_digest, client_salt, server_salt)
     if salt in SysAuthenticator.USED_SALT:
         raise Exception("danger: an attempt was made to re-use the same computed salt")
     log("combined salt(%s, %s)=%s", hexstr(server_salt), hexstr(client_salt), hexstr(salt))
     SysAuthenticator.USED_SALT.append(salt)
     return salt
Exemple #9
0
    def do_test_backend(self,
                        message=b"some message1234",
                        encrypt_count=1,
                        decrypt_count=1):
        def mustequ(l):
            if not l:
                return
            v = l[0]
            size = len(l)
            for i in range(size):
                assert l[i] == v

        password = "******"
        key_salt = DEFAULT_SALT
        key_hash = DEFAULT_KEY_HASH
        iterations = DEFAULT_ITERATIONS
        block_size = DEFAULT_KEYSIZE
        #test key stretching:
        args = password, key_salt, key_hash, block_size, iterations
        secret = self.backend.get_key(*args)
        log("%s%s=%s" % (self.backend.get_key, args, hexstr(secret)))
        assert secret is not None
        #test creation of encryptors and decryptors:
        iv = DEFAULT_IV
        args = secret, iv
        enc = self.backend.get_encryptor(*args)
        log("%s%s=%s" % (self.backend.get_encryptor, args, enc))
        assert enc is not None
        dec = self.backend.get_decryptor(*args)
        log("%s%s=%s" % (self.backend.get_decryptor, args, dec))
        assert dec is not None
        #print("init took %ims", (monotonic()-start)//1000)
        #test encoding of a message:
        encrypted = []
        for i in range(encrypt_count):
            v = enc.encrypt(message)
            #print("%s%s=%s" % (enc.encrypt, (message,), hexstr(v)))
            assert v is not None
            if i == 0:
                encrypted.append(v)
        mustequ(encrypted)
        #test decoding of the message:
        decrypted = []
        for i in range(decrypt_count):
            v = dec.decrypt(encrypted[0])
            log("%s%s=%s" % (dec.decrypt, (encrypted[0], ), hexstr(v)))
            assert v is not None
            if i == 0:
                decrypted.append(v)
        mustequ(decrypted)
        if decrypted:
            mustequ([decrypted[0], message])
Exemple #10
0
 def send(self, packet):
     if self._closed:
         log("connection is closed already, not sending packet")
         return
     if log.is_debug_enabled():
         if len(packet)<=16:
             log("send(%i bytes: %s)", len(packet), hexstr(packet))
         else:
             from xpra.simple_stats import std_unit
             log("send(%sBytes: %s..)", std_unit(len(packet)), hexstr(packet[:16]))
     if self._write_thread is None:
         self.start_write_thread()
     self._write_queue.put(packet)
Exemple #11
0
 def got_contents(dtype, dformat, data):
     log("got_contents(%s, %s, %s:%s) data=0x%s..", dtype, dformat,
         type(data), len(data or ""), hexstr((data or "")[:200]))
     if dtype is None or data is None or (dformat == 0 and not data):
         no_contents()
         return
     log("perform clipboard limit checking - datasize - %d, %d",
         len(data), self.max_clipboard_send_size)
     truncated = 0
     if self.max_clipboard_send_size > 0:
         max_send_datalen = self.max_clipboard_send_size * 8 // get_format_size(
             dformat)
         if len(data) > max_send_datalen:
             truncated = len(data) - max_send_datalen
             data = data[:max_send_datalen]
     munged = self._munge_raw_selection_to_wire(target, dtype, dformat,
                                                data)
     wire_encoding, wire_data = munged
     log("clipboard raw -> wire: %r -> %r", (dtype, dformat, data),
         munged)
     if wire_encoding is None:
         no_contents()
         return
     wire_data = self._may_compress(dtype, dformat, wire_data)
     if wire_data is not None:
         packet = [
             "clipboard-contents", request_id, selection, dtype,
             dformat, wire_encoding, wire_data
         ]
         if self.clipboard_contents_slice_fix:
             #sending the extra argument requires the fix
             packet.append(truncated)
         self.send(*packet)
Exemple #12
0
    def set_icc_profile(self):
        ui_clients = [s for s in self._server_sources.values() if s.ui_client]
        if len(ui_clients) != 1:
            screenlog("%i UI clients, resetting ICC profile to default",
                      len(ui_clients))
            self.reset_icc_profile()
            return
        icc = ui_clients[0].icc
        data = None
        for x in ("data", "icc-data", "icc-profile"):
            if x in icc:
                data = icc.get(x)
                break
        if not data:
            screenlog("no icc data found in %s", icc)
            self.reset_icc_profile()
            return
        screenlog("set_icc_profile() icc data for %s: %s (%i bytes)",
                  ui_clients[0], hexstr(data or ""), len(data or ""))
        from xpra.x11.gtk_x11.prop import prop_set

        #each CARD32 contains just one 8-bit value - don't ask me why
        def o(x):
            try:
                return ord(x)
            except:
                return x

        prop_set(self.root_window, "_ICC_PROFILE", ["u32"],
                 [o(x) for x in data])
        prop_set(self.root_window, "_ICC_PROFILE_IN_X_VERSION", "u32",
                 0 * 100 + 4)  #0.4 -> 0*100+4*1
Exemple #13
0
def gendigest(digest, password, salt):
    assert password and salt
    salt = memoryview_to_bytes(salt)
    password = strtobytes(password)
    if digest=="des":
        from xpra.net.d3des import generate_response  #pylint: disable=import-outside-toplevel
        password = password.ljust(8, b"\x00")[:8]
        salt = salt.ljust(16, b"\x00")[:16]
        v = generate_response(password, salt)
        return hexstr(v)
    if digest in ("xor", "kerberos", "gss"):
        #kerberos and gss use xor because we need to use the actual token
        #at the other end
        salt = salt.ljust(len(password), b"\x00")[:len(password)]
        from xpra.buffers.cyxor import xor_str           #@UnresolvedImport pylint: disable=import-outside-toplevel
        v = xor_str(password, salt)
        return memoryview_to_bytes(v)
    digestmod = get_digest_module(digest)
    if not digestmod:
        log("invalid digest module '%s'", digest)
        return None
        #warn_server_and_exit(EXIT_UNSUPPORTED,
        #    "server requested digest '%s' but it is not supported" % digest, "invalid digest")
    v = hmac.HMAC(password, salt, digestmod=digestmod).hexdigest()
    return v
Exemple #14
0
def open_only(data, types=("png", "jpeg", "webp")):
    itype = get_image_type(data)
    if itype not in types:
        raise Exception("invalid data: %s, not recognized as %s, header: %s" %
                        ((itype or "unknown"), csv(types), hexstr(data[:64])))
    buf = BytesIO(data)
    return Image.open(buf)
Exemple #15
0
 def _copy_loop(self, log_name, from_conn, to_conn):
     #log("XpraProxy._copy_loop(%s, %s, %s)", log_name, from_conn, to_conn)
     try:
         while not self._closed:
             log("%s: waiting for data", log_name)
             buf = untilConcludes(self.is_active, noretry, from_conn.read,
                                  PROXY_BUFFER_SIZE)
             if not buf:
                 log("%s: connection lost", log_name)
                 return
             if SHOW_DATA:
                 log("%s: %s bytes: %s", log_name, len(buf),
                     repr_ellipsized(buf))
                 log("%s:           %s", log_name,
                     repr_ellipsized(hexstr(buf)))
             while buf and not self._closed:
                 log("%s: writing %s bytes", log_name, len(buf))
                 written = untilConcludes(self.is_active, noretry,
                                          to_conn.write, buf)
                 buf = buf[written:]
                 log("%s: written %s bytes", log_name, written)
         log("%s copy loop ended", log_name)
     except Exception as e:
         log("%s: %s", log_name, e)
     finally:
         self.quit()
Exemple #16
0
 def proxy_got_contents(self, request_id, selection, target, dtype, dformat, data):
     def no_contents():
         self.send("clipboard-contents-none", request_id, selection)
     dtype = bytestostr(dtype)
     if is_debug_enabled("clipboard"):
         log("proxy_got_contents(%s, %s, %s, %s, %s, %s:%s) data=0x%s..",
               request_id, selection, target,
               dtype, dformat, type(data), len(data or ""), hexstr((data or "")[:200]))
     if dtype is None or data is None or (dformat==0 and not data):
         no_contents()
         return
     truncated = 0
     if self.max_clipboard_send_size > 0:
         log("perform clipboard limit checking - datasize - %d, %d", len(data), self.max_clipboard_send_size)
         max_send_datalen = self.max_clipboard_send_size * 8 // get_format_size(dformat)
         if len(data) > max_send_datalen:
             truncated = len(data) - max_send_datalen
             data = data[:max_send_datalen]
     munged = self._munge_raw_selection_to_wire(target, dtype, dformat, data)
     if is_debug_enabled("clipboard"):
         log("clipboard raw -> wire: %r -> %r",
             (dtype, dformat, ellipsizer(data)), ellipsizer(munged))
     wire_encoding, wire_data = munged
     if wire_encoding is None:
         no_contents()
         return
     wire_data = self._may_compress(dtype, dformat, wire_data)
     if wire_data is not None:
         packet = ["clipboard-contents", request_id, selection,
                 dtype, dformat, wire_encoding, wire_data, truncated]
         self.send(*packet)
Exemple #17
0
def peek_connection(conn, timeout=PEEK_TIMEOUT_MS, size=PEEK_SIZE):
    log = get_network_logger()
    log("peek_connection(%s, %i)", conn, timeout)
    peek_data = b""
    start = monotonic_time()
    elapsed = 0
    set_socket_timeout(conn, PEEK_TIMEOUT_MS * 1000)
    while elapsed <= timeout:
        try:
            peek_data = conn.peek(size)
            if peek_data:
                break
        except OSError:
            log("peek_connection(%s, %i) failed", conn, timeout, exc_info=True)
        except ValueError:
            log("peek_connection(%s, %i) failed", conn, timeout, exc_info=True)
            break
        sleep(timeout / 4000.0)
        elapsed = int(1000 * (monotonic_time() - start))
        log("peek: elapsed=%s, timeout=%s", elapsed, timeout)
    line1 = b""
    log("socket %s peek: got %i bytes", conn, len(peek_data))
    if peek_data:
        line1 = peek_data.splitlines()[0]
        log("socket peek=%s", ellipsizer(peek_data, limit=512))
        log("socket peek hex=%s", hexstr(peek_data[:128]))
        log("socket peek line1=%s", ellipsizer(line1))
    return peek_data, line1
Exemple #18
0
 def _test_csc(self, mod,
              width=16, height=16,
              in_csc="BGRX", out_csc="YUV420P",
              pixel="00000000", expected=()):
     csc_mod = loader.load_codec(mod)
     if not csc_mod:
         print("%s not found" % mod)
         return
     if in_csc not in csc_mod.get_input_colorspaces():
         raise Exception("%s does not support %s as input" % (mod, in_csc))
     if out_csc not in csc_mod.get_output_colorspaces(in_csc):
         raise Exception("%s does not support %s as output for %s" % (mod, out_csc, in_csc))
     csc = csc_mod.ColorspaceConverter()
     csc.init_context(width, height, in_csc,
                      width, height, out_csc)
     image = make_test_image(in_csc, width, height)
     size = image.get_rowstride()//4*image.get_height()
     bgrx = h2b(pixel)*size
     image.set_pixels(bgrx)
     out_image = csc.convert_image(image)
     csc.clean()
     assert out_image.get_planes()>=len(expected)
     #now verify the value for each plane specified:
     for i, v_str in enumerate(expected):
         plane = out_image.get_pixels()[i]
         #plane_stride = out_image.get_rowstride()[i]
         #assert len(plane)>=plane_stride*out_image.get_height()
         plane_bytes = memoryview_to_bytes(plane)
         v = h2b(v_str)
         if not cmpp(plane_bytes, v):
             raise Exception("%s: plane %s, expected %s but got %s" % (
                 mod, out_csc[i], v_str, hexstr(plane_bytes[:len(v)])))
Exemple #19
0
 def authenticate_hmac(self, challenge_response, client_salt=None):
     log("authenticate_hmac(%r, %r)", challenge_response, client_salt)
     self.sessions = None
     if not self.salt:
         log.error(
             "Error: illegal challenge response received - salt cleared or unset"
         )
         return None
     #ensure this salt does not get re-used:
     salt = self.get_response_salt(client_salt)
     entry = self.get_auth_info()
     if entry is None:
         log.warn("Warning: authentication failed")
         log.warn(" no password for '%s' in '%s'", self.username,
                  self.password_filename)
         return None
     log("authenticate: auth-info(%s)=%s", self.username, entry)
     fpassword, uid, gid, displays, env_options, session_options = entry
     log("multifile authenticate_hmac password='******', hex(salt)=%s",
         fpassword, hexstr(salt))
     if not verify_digest(self.digest, fpassword, salt, challenge_response):
         log.warn("Warning: %s challenge for '%s' does not match",
                  self.digest, self.username)
         return False
     self.sessions = uid, gid, displays, env_options, session_options
     return True
Exemple #20
0
 def send_hello(self, challenge_response=None, client_salt=None):
     if not self._protocol:
         log("send_hello(..) skipped, no protocol (listen mode?)")
         return
     try:
         hello = self.make_hello_base()
         if self.has_password() and not challenge_response:
             #avoid sending the full hello: tell the server we want
             #a packet challenge first
             hello["challenge"] = True
         else:
             hello.update(self.make_hello())
     except InitExit as e:
         log.error("error preparing connection:")
         log.error(" %s", e)
         self.quit(EXIT_INTERNAL_ERROR)
         return
     except Exception as e:
         log.error("error preparing connection: %s", e, exc_info=True)
         self.quit(EXIT_INTERNAL_ERROR)
         return
     if challenge_response:
         hello["challenge_response"] = challenge_response
         #make it harder for a passive attacker to guess the password length
         #by observing packet sizes (only relevant for wss and ssl)
         hello["challenge_padding"] = get_salt(
             max(32, 512 - len(challenge_response)))
         if client_salt:
             hello["challenge_client_salt"] = client_salt
     log("send_hello(%s) packet=%s", hexstr(challenge_response or ""),
         hello)
     self.send("hello", hello)
Exemple #21
0
 def invalid_header(self, _proto, data, msg="invalid packet header"):
     self._packet_parser = self._parse_invalid
     err = "%s: '%s'" % (msg, hexstr(data[:8]))
     if len(data) > 1:
         err += " read buffer=%s (%i bytes)" % (repr_ellipsized(data),
                                                len(data))
     self.invalid(err, data)
Exemple #22
0
def peek_connection(conn, timeout=PEEK_TIMEOUT_MS):
    log = get_network_logger()
    log("peek_connection(%s, %i)", conn, timeout)
    PEEK_SIZE = 8192
    start = monotonic_time()
    peek_data = b""
    while not peek_data and int(1000*(monotonic_time()-start))<timeout:
        try:
            peek_data = conn.peek(PEEK_SIZE)
        except (OSError, IOError):
            pass
        except ValueError:
            log("peek_connection(%s, %i) failed", conn, timeout, exc_info=True)
            break
        if not peek_data:
            sleep(timeout/4000.0)
    line1 = b""
    log("socket %s peek: got %i bytes", conn, len(peek_data))
    set_socket_timeout(conn, PEEK_TIMEOUT_MS*1000)
    if peek_data:
        line1 = peek_data.splitlines()[0]
        log("socket peek=%s", repr_ellipsized(peek_data, limit=512))
        log("socket peek hex=%s", hexstr(peek_data[:128]))
        log("socket peek line1=%s", repr_ellipsized(bytestostr(line1)))
    return peek_data, line1
Exemple #23
0
def get_workarea():
    if not is_Wayland():
        try:
            d = get_current_desktop()
            if d < 0:
                return None
            workarea = _get_X11_root_property("_NET_WORKAREA", "CARDINAL")
            if not workarea:
                return None
            screenlog("get_workarea() _NET_WORKAREA=%s (%s), len=%s",
                      ellipsizer(workarea), type(workarea), len(workarea))
            #workarea comes as a list of 4 CARDINAL dimensions (x,y,w,h), one for each desktop
            sizeof_long = struct.calcsize(b"@L")
            if len(workarea) < (d + 1) * 4 * sizeof_long:
                screenlog.warn("get_workarea() invalid _NET_WORKAREA value")
            else:
                cur_workarea = workarea[d * 4 * sizeof_long:(d + 1) * 4 *
                                        sizeof_long]
                v = struct.unpack(b"@LLLL", cur_workarea)
                screenlog("get_workarea() %s=%s", hexstr(cur_workarea), v)
                return v
        except Exception as e:
            screenlog("get_workarea()", exc_info=True)
            screenlog.warn("Warning: failed to query workarea: %s", e)
    return None
Exemple #24
0
def selftest(full=False):
    global ENCODINGS
    from xpra.os_util import hexstr
    from xpra.codecs.codec_checks import make_test_image
    img = make_test_image("BGRA", 32, 32)
    if full:
        vrange = (0, 50, 100)
    else:
        vrange = (50, )
    for encoding in tuple(ENCODINGS):
        try:
            for q in vrange:
                for s in vrange:
                    for alpha in (True, False):
                        v = encode(encoding, img, q, s, False, alpha)
                        assert v, "encode output was empty!"
                        cdata = v[1].data
                        log("encode(%s)=%s", (encoding, img, q, s, alpha),
                            hexstr(cdata))
        except Exception as e:  # pragma: no cover
            l = log.warn
            l("Pillow error saving %s with quality=%s, speed=%s, alpha=%s",
              encoding, q, s, alpha)
            l(" %s", e, exc_info=True)
            ENCODINGS.remove(encoding)
Exemple #25
0
 def __init__(self, _disp, data):
     #some applications use the wrong size (ie: blender uses 16) so pad it:
     sizeof_long = struct.calcsize(b"@L")
     pdata = _force_length("_MOTIF_WM_HINTS", data, sizeof_long*5, sizeof_long*4)
     self.flags, self.functions, self.decorations, self.input_mode, self.status = \
         struct.unpack(b"@LLLlL", pdata)
     log("MotifWMHints(%s)=%s", hexstr(data), self)
Exemple #26
0
 def set_icc_profile(self):
     if not SYNC_ICC:
         return
     ui_clients = [s for s in self._server_sources.values() if s.ui_client]
     if len(ui_clients) != 1:
         screenlog("%i UI clients, resetting ICC profile to default",
                   len(ui_clients))
         self.reset_icc_profile()
         return
     icc = typedict(ui_clients[0].icc)
     data = None
     for x in ("data", "icc-data", "icc-profile"):
         data = icc.strget(x)
         if data:
             break
     if not data:
         screenlog("no icc data found in %s", icc)
         self.reset_icc_profile()
         return
     screenlog("set_icc_profile() icc data for %s: %s (%i bytes)",
               ui_clients[0], hexstr(data or ""), len(data or ""))
     self.icc_profile = data
     from xpra.x11.gtk_x11.prop import prop_set
     prop_set(self.root_window, "_ICC_PROFILE", ["u32"],
              [ord(x) for x in data])
     prop_set(self.root_window, "_ICC_PROFILE_IN_X_VERSION", "u32",
              0 * 100 + 4)  #0.4 -> 0*100+4*1
Exemple #27
0
 def get_icc_info(self) -> dict:
     icc_info = {
         "sync": SYNC_ICC,
     }
     if SYNC_ICC:
         icc_info["profile"] = hexstr(self.icc_profile)
     return icc_info
Exemple #28
0
def get_settings(d):
    global XSETTINGS_CACHE
    DEBUG_XSETTINGS = envbool("XPRA_XSETTINGS_DEBUG", False)
    #parse xsettings according to
    #http://standards.freedesktop.org/xsettings-spec/xsettings-spec-0.5.html
    assert len(d)>=12, "_XSETTINGS_SETTINGS property is too small: %s" % len(d)
    if DEBUG_XSETTINGS:
        log("get_settings(%s)", tuple(d))
    byte_order, _, _, _, serial, n_settings = struct.unpack(b"=BBBBII", d[:12])
    cache = XSETTINGS_CACHE
    log("get_settings(..) found byte_order=%s (local is %s), serial=%s, n_settings=%s, cache=%s",
        byte_order, get_local_byteorder(), serial, n_settings, cache)
    if cache and cache[0]==serial:
        log("get_settings(..) returning value from cache")
        return cache
    settings = []
    pos = 12
    while n_settings>len(settings):
        log("get_settings(..) pos=%i (len=%i), data=%s", pos, len(d), hexstr(d[pos:]))
        istart = pos
        #parse header:
        setting_type, _, name_len = struct.unpack(b"=BBH", d[pos:pos+4])
        pos += 4
        #extract property name:
        prop_name = d[pos:pos+name_len]
        pos += (name_len + 0x3) & ~0x3
        #serial:
        assert len(d)>=pos+4, "not enough data (%s bytes) to extract serial (4 bytes needed)" % (len(d)-pos)
        last_change_serial = struct.unpack(b"=I", d[pos:pos+4])[0]
        pos += 4
        if DEBUG_XSETTINGS:
            log("get_settings(..) found property %s of type %s, serial=%s",
                prop_name, XSettingsNames.get(setting_type, "INVALID!"), last_change_serial)
        #extract value:
        if setting_type==XSettingsTypeInteger:
            assert len(d)>=pos+4, "not enough data (%s bytes) to extract int (4 bytes needed)" % (len(d)-pos)
            value = int(struct.unpack(b"=I", d[pos:pos+4])[0])
            pos += 4
        elif setting_type==XSettingsTypeString:
            assert len(d)>=pos+4, "not enough data (%s bytes) to extract string length (4 bytes needed)" % (len(d)-pos)
            value_len = struct.unpack(b"=I", d[pos:pos+4])[0]
            assert len(d)>=pos+4+value_len, "not enough data (%s bytes) to extract string (%s bytes needed)" % (len(d)-pos-4, value_len)
            value = d[pos+4:pos+4+value_len]
            pos += 4 + ((value_len + 0x3) & ~0x3)
        elif setting_type==XSettingsTypeColor:
            assert len(d)>=pos+8, "not enough data (%s bytes) to extract color (8 bytes needed)" % (len(d)-pos)
            red, blue, green, alpha = struct.unpack(b"=HHHH", d[pos:pos+8])
            value = (red, blue, green, alpha)
            pos += 8
        else:
            log.error("invalid setting type: %s, cannot continue parsing XSETTINGS!", setting_type)
            break
        setting = setting_type, prop_name, value, last_change_serial
        if DEBUG_XSETTINGS:
            log("get_settings(..) %s -> %s", tuple(d[istart:pos]), setting)
        settings.append(setting)
    log("get_settings(..) settings=%s", settings)
    XSETTINGS_CACHE = (serial, settings)
    return  serial, settings
Exemple #29
0
 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
Exemple #30
0
 def send(self, packet):
     log("send(%i bytes: %s..)", len(packet), hexstr(packet[:16]))
     if self._closed:
         log("connection is closed already, not sending packet")
         return
     if self._write_thread is None:
         self.start_write_thread()
     self._write_queue.put(packet)