Пример #1
0
def parse_auth_line(line):
    ldata = line.split(b"|")
    log("found %s fields", len(ldata))
    assert len(ldata) >= 4, "not enough fields"
    #parse fields:
    username = ldata[0]
    password = ldata[1]

    def getsysid(s, get_default_value):
        if s:
            try:
                return int(s)
            except:
                pass
        return get_default_value()

    uid = getsysid(ldata[2], os.getuid)
    gid = getsysid(ldata[3], os.getgid)
    displays = ldata[4].split(b",")
    env_options = {}
    session_options = {}
    if len(ldata) >= 6:
        env_options = parse_simple_dict(ldata[5], ";")
    if len(ldata) >= 7:
        session_options = parse_simple_dict(ldata[6], ";")
    return username, password, uid, gid, displays, env_options, session_options
Пример #2
0
 def get_sessions(self):
     import sqlite3
     try:
         conn = sqlite3.connect(self.filename)
         conn.row_factory = sqlite3.Row
         cursor = conn.cursor()
         cursor.execute(self.sessions_query,
                        [self.username, self.password_used or ""])
         data = cursor.fetchone()
     except sqlite3.DatabaseError as e:
         log("get_sessions()", exc_info=True)
         log.error("Error: sqlauth database access problem:")
         log.error(" %s", e)
         return None
     try:
         uid = parse_uid(data["uid"])
         gid = parse_gid(data["gid"])
         displays = []
         env_options = {}
         session_options = {}
         if data["displays"]:
             displays = [x.strip() for x in str(data[2]).split(",")]
         if data["env_options"]:
             env_options = parse_simple_dict(str(data[3]), ";")
         if data["session_options"]:
             session_options = parse_simple_dict(str(data[4]), ";")
     except Exception as e:
         log("get_sessions() error on row %s", data, exc_info=True)
         log.error("Error: sqlauth database row parsing problem:")
         log.error(" %s", e)
         return None
     return uid, gid, displays, env_options, session_options
Пример #3
0
def get_sound_source_options(plugin, options_str, device, want_monitor_device, remote):
    """
        Given a plugin (short name), options string and remote info,
        return the options for the plugin given,
        using the dynamic defaults (which may use remote info)
        and applying the options string on top.
    """
    #ie: get_sound_source_options("audiotestsrc", "wave=4,freq=220", {remote_pulseaudio_server=XYZ}):
    #use the defaults as starting point:
    defaults_fn = DEFAULT_SRC_PLUGIN_OPTIONS.get(plugin)
    if defaults_fn:
        options = defaults_fn(device, want_monitor_device, remote)
        if options is None:
            #means failure
            return None
    else:
        options = {}
        #if we add support for choosing devices in the GUI,
        #this code will then get used:
        if device and plugin in SRC_HAS_DEVICE_NAME:
            #assume the user knows the "device-name"...
            #(since I have no idea where to get the "device" string)
            options["device-name"] = device
    options.update(parse_simple_dict(options_str))
    return options
Пример #4
0
def parse_bind_ip(bind_ip, default_port=DEFAULT_PORT):
    ip_sockets = {}
    if bind_ip:
        for spec in bind_ip:
            parts = spec.split(",", 1)
            ip_port = parts[0]
            if ":" not in spec:
                raise InitException("port must be specified as [HOST]:PORT")
            host, port = ip_port.rsplit(":", 1)
            if host == "":
                host = "127.0.0.1"
            if not port:
                iport = default_port
            elif port == "0":
                iport = 0
            else:
                try:
                    iport = int(port)
                    assert 0 < iport < 2**16
                except (TypeError, ValueError):
                    raise InitException("invalid port number: %s" %
                                        port) from None
            options = {}
            if len(parts) == 2:
                options = parse_simple_dict(parts[1])
            ip_sockets[(host, iport)] = options
    return ip_sockets
Пример #5
0
def get_sound_source_options(plugin, options_str, device, want_monitor_device, remote):
    """
        Given a plugin (short name), options string and remote info,
        return the options for the plugin given,
        using the dynamic defaults (which may use remote info)
        and applying the options string on top.
    """
    #ie: get_sound_source_options("audiotestsrc", "wave=4,freq=220", {remote_pulseaudio_server=XYZ}):
    #use the defaults as starting point:
    defaults_fn = DEFAULT_SRC_PLUGIN_OPTIONS.get(plugin)
    log("DEFAULT_SRC_PLUGIN_OPTIONS(%s)=%s", plugin, defaults_fn)
    if defaults_fn:
        options = defaults_fn(device, want_monitor_device, remote)
        log("%s%s=%s", defaults_fn, (device, want_monitor_device, remote), options)
        if options is None:
            #means failure
            return None
    else:
        options = {}
        #if we add support for choosing devices in the GUI,
        #this code will then get used:
        if device and plugin in SRC_HAS_DEVICE_NAME:
            #assume the user knows the "device-name"...
            #(since I have no idea where to get the "device" string)
            options["device-name"] = device
    options.update(parse_simple_dict(options_str))
    return options
Пример #6
0
def parse_auth_line(line):
    ldata = line.split(b"|")
    log("found %s fields", len(ldata))
    assert len(ldata)>=4, "not enough fields"
    #parse fields:
    username = ldata[0]
    password = ldata[1]
    uid = getuid(ldata[2])
    gid = getgid(ldata[3])
    displays = ldata[4].split(b",")
    env_options = {}
    session_options = {}
    if len(ldata)>=6:
        env_options = parse_simple_dict(ldata[5], ";")
    if len(ldata)>=7:
        session_options = parse_simple_dict(ldata[6], ";")
    return username, password, uid, gid, displays, env_options, session_options
Пример #7
0
def parse_auth_line(line):
    ldata = line.split(b"|")
    log("found %s fields", len(ldata))
    assert len(ldata) >= 4, "not enough fields"
    #parse fields:
    username = ldata[0]
    password = ldata[1]
    uid = getuid(ldata[2])
    gid = getgid(ldata[3])
    displays = ldata[4].split(b",")
    env_options = {}
    session_options = {}
    if len(ldata) >= 6:
        env_options = parse_simple_dict(ldata[5], ";")
    if len(ldata) >= 7:
        session_options = parse_simple_dict(ldata[6], ";")
    return username, password, uid, gid, displays, env_options, session_options
Пример #8
0
 def parse_session_data(self, data):
     try:
         uid = parse_uid(data["uid"])
         gid = parse_gid(data["gid"])
         displays = []
         env_options = {}
         session_options = {}
         if data["displays"]:
             displays = [x.strip() for x in str(data["displays"]).split(",")]
         if data["env_options"]:
             env_options = parse_simple_dict(str(data["env_options"]), ";")
         if data["session_options"]:
             session_options=parse_simple_dict(str(data["session_options"]), ";")
     except Exception as e:
         log("get_sessions() error on row %s", data, exc_info=True)
         log.error("Error: sqlauth database row parsing problem:")
         log.error(" %s", e)
         return None
     return uid, gid, displays, env_options, session_options
Пример #9
0
 def parse_session_data(self, data):
     try:
         uid = data[0]
         gid = data[1]
         displays = []
         env_options = {}
         session_options = {}
         if len(data)>2:
             displays = [x.strip() for x in str(data[2]).split(",")]
         if len(data)>3:
             env_options = parse_simple_dict(str(data[3]), ";")
         if len(data)>4:
             session_options = parse_simple_dict(str(data[4]), ";")
     except Exception as e:
         log("parse_session_data() error on row %s", data, exc_info=True)
         log.error("Error: sqlauth database row parsing problem:")
         log.error(" %s", e)
         return None
     return uid, gid, displays, env_options, session_options
Пример #10
0
 def get_auth_module(self, socket_type, auth_str, opts):
     authlog("get_auth_module(%s, %s, {..})", socket_type, auth_str)
     if not auth_str:
         return None
     #separate options from the auth module name
     parts = auth_str.split(":", 1)
     auth = parts[0]
     auth_options = {}
     if len(parts) > 1:
         auth_options = parse_simple_dict(parts[1])
     if auth == "sys":
         #resolve virtual "sys" auth:
         if sys.platform.startswith("win"):
             auth = "win32"
         else:
             auth = "pam"
         authlog("will try to use sys auth module '%s' for %s", auth,
                 sys.platform)
     from xpra.server.auth import fail_auth, reject_auth, allow_auth, none_auth, file_auth, multifile_auth, password_auth, env_auth
     AUTH_MODULES = {
         "fail": fail_auth,
         "reject": reject_auth,
         "allow": allow_auth,
         "none": none_auth,
         "env": env_auth,
         "password": password_auth,
         "multifile": multifile_auth,
         "file": file_auth,
     }
     try:
         from xpra.server.auth import pam_auth
         AUTH_MODULES["pam"] = pam_auth
     except Exception as e:
         authlog("cannot load pam auth: %s", e)
     if sys.platform.startswith("win"):
         try:
             from xpra.server.auth import win32_auth
             AUTH_MODULES["win32"] = win32_auth
         except Exception as e:
             authlog.error(
                 "Error: cannot load the MS Windows authentication module:")
             authlog.error(" %s", e)
     auth_module = AUTH_MODULES.get(auth)
     if not auth_module:
         raise InitException(
             "cannot find authentication module '%s' (supported: %s)" %
             (auth, csv(AUTH_MODULES.keys())))
     try:
         auth_module.init(opts)
         auth_class = getattr(auth_module, "Authenticator")
         auth_class.auth_name = auth.lower()
         return auth, auth_class, auth_options
     except Exception as e:
         raise InitException("Authenticator class not found in %s" %
                             auth_module)
Пример #11
0
def parse_bind_vsock(bind_vsock):
    vsock_sockets = {}
    if bind_vsock:
        from xpra.scripts.parsing import parse_vsock  #pylint: disable=import-outside-toplevel
        for spec in bind_vsock:
            parts = spec.split(",", 1)
            cid, iport = parse_vsock(parts[0])
            options = {}
            if len(parts) == 2:
                options = parse_simple_dict(parts[1])
            vsock_sockets[(cid, iport)] = options
    return vsock_sockets
Пример #12
0
def parse_bind_vsock(bind_vsock):
    vsock_sockets = {}
    if bind_vsock:
        from xpra.scripts.main import parse_vsock
        for spec in bind_vsock:
            parts = spec.split(",", 1)
            cid, iport = parse_vsock(parts[0])
            options = {}
            if len(parts) == 2:
                options = parse_simple_dict(parts[1])
            vsock_sockets[(cid, iport)] = options
    return vsock_sockets
Пример #13
0
 def makeRootWindowModels(self):
     screenlog("makeRootWindowModels() root=%s, display_options=%s", self.root, self.display_options)
     self.capture = self.setup_capture()
     model_class = self.get_root_window_model_class()
     models = []
     display_name = prettify_plug_name(self.root.get_screen().get_display().get_name())
     monitors = self.get_shadow_monitors()
     match_str = None
     multi_window = MULTI_WINDOW
     geometries = None
     if "=" in self.display_options:
         #parse the display options as a dictionary:
         opt_dict = parse_simple_dict(self.display_options)
         windows = opt_dict.get("windows")
         if windows:
             self.window_matches = windows.split("/")
             return self.makeDynamicWindowModels()
         match_str = opt_dict.get("plug")
         multi_window = parse_bool("multi-window", opt_dict.get("multi-window", multi_window))
         geometries_str = opt_dict.get("geometry")
         if geometries_str:
             geometries = parse_geometries(geometries_str)
     else:
         try:
             geometries = parse_geometries(self.display_options)
         except Exception:
             match_str = self.display_options
     if not multi_window or geometries:
         for geometry in (geometries or (self.root.get_geometry()[:4],)):
             model = model_class(self.root, self.capture, display_name, geometry)
             models.append(model)
         return models
     found = []
     screenlog("capture inputs matching %r", match_str or "all")
     for i, monitor in enumerate(monitors):
         plug_name, x, y, width, height, scale_factor = monitor
         title = display_name
         if plug_name or i>1:
             title = plug_name or str(i)
         found.append(plug_name or title)
         if match_str and not(title in match_str or plug_name in match_str):
             screenlog.info(" skipped monitor %s", plug_name or title)
             continue
         geometry = (x, y, width, height)
         model = model_class(self.root, self.capture, title, geometry)
         models.append(model)
         screenlog("monitor %i: %10s geometry=%s, scale factor=%s", i, title, geometry, scale_factor)
     screenlog("makeRootWindowModels()=%s", models)
     if not models and match_str:
         screenlog.warn("Warning: no monitors found matching %r", match_str)
         screenlog.warn(" only found: %s", csv(found))
     return models
Пример #14
0
def parse_auth_line(line):
    ldata = line.split(b"|")
    assert len(ldata)>=2, "not enough fields: %i" % (len(ldata))
    log("found %s fields", len(ldata))
    #parse fields:
    username = ldata[0]
    password = ldata[1]
    if len(ldata)>=5:
        uid = parse_uid(bytestostr(ldata[2]))
        gid = parse_gid(bytestostr(ldata[3]))
        displays = bytestostr(ldata[4]).split(",")
    else:
        #this will use the default value, usually "nobody":
        uid = parse_uid(None)
        gid = parse_gid(None)
        displays = []
    env_options = {}
    session_options = {}
    if len(ldata)>=6:
        env_options = parse_simple_dict(ldata[5], b";")
    if len(ldata)>=7:
        session_options = parse_simple_dict(ldata[6], b";")
    return username, password, uid, gid, displays, env_options, session_options
Пример #15
0
 def get_auth_module(self, socket_type, auth_str, opts):
     authlog("get_auth_module(%s, %s, {..})", socket_type, auth_str)
     if not auth_str:
         return None
     #separate options from the auth module name
     parts = auth_str.split(":", 1)
     auth = parts[0]
     auth_options = {}
     if len(parts)>1:
         auth_options = parse_simple_dict(parts[1])
     if auth=="sys":
         #resolve virtual "sys" auth:
         if sys.platform.startswith("win"):
             auth = "win32"
         else:
             auth = "pam"
         authlog("will try to use sys auth module '%s' for %s", auth, sys.platform)
     from xpra.server.auth import fail_auth, reject_auth, allow_auth, none_auth, file_auth, multifile_auth, password_auth, env_auth
     AUTH_MODULES = {
                     "fail"      : fail_auth,
                     "reject"    : reject_auth,
                     "allow"     : allow_auth,
                     "none"      : none_auth,
                     "env"       : env_auth,
                     "password"  : password_auth,
                     "multifile" : multifile_auth,
                     "file"      : file_auth,
                     }
     try:
         from xpra.server.auth import pam_auth
         AUTH_MODULES["pam"] = pam_auth
     except Exception as e:
         authlog("cannot load pam auth: %s", e)
     if sys.platform.startswith("win"):
         try:
             from xpra.server.auth import win32_auth
             AUTH_MODULES["win32"] = win32_auth
         except Exception as e:
             authlog.error("Error: cannot load the MS Windows authentication module:")
             authlog.error(" %s", e)
     auth_module = AUTH_MODULES.get(auth)
     if not auth_module:
         raise InitException("cannot find authentication module '%s' (supported: %s)" % (auth, csv(AUTH_MODULES.keys())))
     try:
         auth_module.init(opts)
         auth_class = getattr(auth_module, "Authenticator")
         auth_class.auth_name = auth.lower()
         return auth, auth_class, auth_options
     except Exception as e:
         raise InitException("Authenticator class not found in %s" % auth_module)
Пример #16
0
def parse_auth_line(line):
    ldata = line.split(b"|")
    log("found %s fields", len(ldata))
    assert len(ldata)>=4, "not enough fields"
    #parse fields:
    username = ldata[0]
    password = ldata[1]
    def getsysid(s, get_default_value):
        if s:
            try:
                return int(s)
            except:
                pass
        return get_default_value()
    uid = getsysid(ldata[2], os.getuid)
    gid = getsysid(ldata[3], os.getgid)
    displays = ldata[4].split(b",")
    env_options = {}
    session_options = {}
    if len(ldata)>=6:
        env_options = parse_simple_dict(ldata[5], ";")
    if len(ldata)>=7:
        session_options = parse_simple_dict(ldata[6], ";")
    return username, password, uid, gid, displays, env_options, session_options
Пример #17
0
def get_auth_module(auth_str, cwd=os.getcwd(), **auth_options):
    log("get_auth_module(%s, {..})", auth_str)
    #separate options from the auth module name
    #either with ":" or "," as separator
    scpos = auth_str.find(":")
    cpos = auth_str.find(",")
    if cpos < 0 or scpos < cpos:
        parts = auth_str.split(":", 1)
    else:
        parts = auth_str.split(",", 1)
    auth = parts[0]
    if len(parts) > 1:
        auth_options.update(parse_simple_dict(parts[1]))
    auth_options["exec_cwd"] = cwd
    try:
        if auth == "sys":
            #resolve virtual "sys" auth:
            if WIN32:
                auth_modname = "win32_auth"
            else:
                auth_modname = "pam_auth"
            log("will try to use sys auth module '%s' for %s", auth,
                sys.platform)
        else:
            auth_modname = auth.replace("-", "_") + "_auth"
        auth_mod_name = "xpra.server.auth." + auth_modname
        log("auth module name for '%s': '%s'", auth, auth_mod_name)
        auth_module = __import__(auth_mod_name, {}, {}, ["Authenticator"])
    except ImportError as e:
        log("cannot load %s auth for %r", auth, auth_str, exc_info=True)
        raise InitException(
            "cannot load authentication module '%s' for %r: %s" %
            (auth, auth_str, e)) from None
    log("auth module for '%s': %s", auth, auth_module)
    try:
        auth_class = auth_module.Authenticator
        auth_class.auth_name = auth.lower()
        return auth, auth_module, auth_class, auth_options
    except Exception as e:
        log("cannot access authenticator class", exc_info=True)
        raise InitException("authentication setup error in %s: %s" %
                            (auth_module, e)) from None
Пример #18
0
 def get_challenge_handler(self, auth, import_error_logger):
     #the module may have attributes,
     #ie: file:filename=password.txt
     parts = auth.split(":", 1)
     mod_name = parts[0]
     kwargs = {}
     if len(parts)==2:
         kwargs = parse_simple_dict(parts[1])
     auth_mod_name = "xpra.client.auth.%s_handler" % mod_name
     authlog("auth module name for '%s': '%s'", auth, auth_mod_name)
     try:
         auth_module = __import__(auth_mod_name, {}, {}, ["Handler"])
         auth_class = auth_module.Handler
         instance = auth_class(self, **kwargs)
         return instance
     except ImportError as e:
         import_error_logger("Error: authentication handler %s not available", mod_name)
         import_error_logger(" %s", e)
     except Exception as e:
         authlog("get_challenge_handler(%s)", auth, exc_info=True)
         authlog.error("Error: cannot instantiate authentication handler")
         authlog.error(" '%s': %s", mod_name, e)
     return None
Пример #19
0
def run_sound(mode, error_cb, options, args):
    """ this function just parses command line arguments to feed into the sound subprocess class,
        which in turn just feeds them into the sound pipeline class (sink.py or src.py)
    """
    from xpra.gtk_common.gobject_compat import want_gtk3
    want_gtk3(True)
    gst = import_gst()
    if not gst:
        return 1
    info = mode.replace("_sound_", "")  #ie: "_sound_record" -> "record"
    from xpra.platform import program_context
    with program_context("Xpra-Audio-%s" % info, "Xpra Audio %s" % info):
        log("run_sound(%s, %s, %s, %s) gst=%s", mode, error_cb, options, args, gst)
        if mode=="_sound_record":
            subproc = sound_record
        elif mode=="_sound_play":
            subproc = sound_play
        elif mode=="_sound_query":
            plugins = get_all_plugin_names()
            sources = [x for x in get_source_plugins() if x in plugins]
            sinks = [x for x in get_sink_plugins() if x in plugins]
            from xpra.sound.gstreamer_util import gst_version, pygst_version
            import struct
            bits = struct.calcsize("P")*8
            d = {
                 "encoders"         : can_encode(),
                 "decoders"         : can_decode(),
                 "sources"          : sources,
                 "source.default"   : get_default_source() or "",
                 "sinks"            : sinks,
                 "sink.default"     : get_default_sink() or "",
                 "muxers"           : get_muxers(),
                 "demuxers"         : get_demuxers(),
                 "gst.version"      : [int(x) for x in gst_version],
                 "pygst.version"    : pygst_version,
                 "plugins"          : plugins,
                 "python.version"   : sys.version_info[:3],
                 "python.bits"      : bits,
                }
            if BUNDLE_METADATA:
                d["bundle-metadata"] = True
            for k,v in d.items():
                if type(v) in (list, tuple):
                    v = ",".join(str(x) for x in v)
                print("%s=%s" % (k, v))
            return 0
        else:
            log.error("unknown mode: %s" % mode)
            return 1
        assert len(args)>=6, "not enough arguments"

        #the plugin to use (ie: 'pulsesrc' for src.py or 'autoaudiosink' for sink.py)
        plugin = args[2]
        #plugin options (ie: "device=monitor_device,something=value")
        options = parse_simple_dict(args[3])
        #codecs:
        codecs = [x.strip() for x in args[4].split(",")]
        #codec options:
        codec_options = parse_simple_dict(args[5])
        #volume (optional):
        try:
            volume = int(args[6])
        except:
            volume = 1.0

        ss = None
        try:
            ss = subproc(plugin, options, codecs, codec_options, volume)
            ss.start()
            return 0
        except InitExit as e:
            log.error("%s: %s", info, e)
            return e.status
        except InitException as e:
            log.error("%s: %s", info, e)
            return 1
        except Exception:
            log.error("run_sound%s error", (mode, error_cb, options, args), exc_info=True)
            return 1
        finally:
            if ss:
                ss.stop()
Пример #20
0
def run_sound(mode, error_cb, options, args):
    """ this function just parses command line arguments to feed into the sound subprocess class,
        which in turn just feeds them into the sound pipeline class (sink.py or src.py)
    """
    #we have to import gstreamer before init() on OSX,
    #because init will end up import gobject,
    #which means choosing between gi and gtk2 bindings
    from xpra.sound.gstreamer_util import import_gst, get_pygst_version
    gst = import_gst()
    from xpra.gtk_common.gobject_compat import want_gtk3
    want_gtk3(get_pygst_version()[0]>0)
    from xpra.platform import program_context
    with program_context("Xpra"):
        log("run_sound(%s, %s, %s, %s) gst=%s", mode, error_cb, options, args, gst)
        if not gst:
            return 1
        if mode=="_sound_record":
            subproc = sound_record
            info = "record"
        elif mode=="_sound_play":
            subproc = sound_play
            info = "play"
        elif mode=="_sound_query":
            plugins = get_all_plugin_names()
            sources = [x for x in get_source_plugins() if x in plugins]
            from xpra.sound.gstreamer_util import gst_version, pygst_version
            d = {"encoders"         : can_encode(),
                 "decoders"         : can_decode(),
                 "sources"          : sources,
                 "muxers"           : get_muxers(),
                 "demuxers"         : get_demuxers(),
                 "gst.version"      : gst_version,
                 "pygst.version"    : pygst_version,
                 "plugins"          : plugins,
                 "python.version"   : sys.version_info[:3],
                }
            for k,v in d.items():
                print("%s=%s" % (k, ",".join(str(x) for x in v)))
            return 0
        else:
            log.error("unknown mode: %s" % mode)
            return 1
        assert len(args)>=6, "not enough arguments"

        #the plugin to use (ie: 'pulsesrc' for src.py or 'autoaudiosink' for sink.py)
        plugin = args[2]
        #plugin options (ie: "device=monitor_device,something=value")
        options = parse_simple_dict(args[3])
        #codecs:
        codecs = [x.strip() for x in args[4].split(",")]
        #codec options:
        codec_options = parse_simple_dict(args[5])
        #volume (optional):
        try:
            volume = int(args[6])
        except:
            volume = 1.0

        ss = None
        try:
            ss = subproc(plugin, options, codecs, codec_options, volume)
            ss.start()
            return 0
        except InitExit as e:
            log.error("%s: %s", info, e)
            return e.status
        except InitException as e:
            log.error("%s: %s", info, e)
            return 1
        except Exception:
            log.error("run_sound%s error", (mode, error_cb, options, args), exc_info=True)
            return 1
        finally:
            if ss:
                ss.stop()
Пример #21
0
    PRINTER_PREFIX, ADD_LOCAL_PRINTERS)
log("pycups settings: FORWARDER_TMPDIR=%s", FORWARDER_TMPDIR)
log("pycups settings: SKIPPED_PRINTERS=%s", SKIPPED_PRINTERS)

MIMETYPE_TO_PRINTER = {
    "application/postscript"    : "Generic PostScript Printer",
    "application/pdf"           : "Generic PDF Printer",
    }
MIMETYPE_TO_PPD = {
    "application/postscript"    : "CUPS-PDF.ppd",
    "application/pdf"           : "Generic-PDF_Printer-PDF.ppd",
    }


dco = os.environ.get("XPRA_DEFAULT_CUPS_OPTIONS", "fit-to-page=True")
DEFAULT_CUPS_OPTIONS = parse_simple_dict(dco)
log("DEFAULT_CUPS_OPTIONS=%s", DEFAULT_CUPS_OPTIONS)


#allows us to inject the lpadmin and lpinfo commands from the config file
def set_lpadmin_command(lpadmin):
    global LPADMIN
    LPADMIN = lpadmin

def set_add_printer_options(options):
    global ADD_OPTIONS
    ADD_OPTIONS = options

def set_lpinfo_command(lpinfo):
    global LPINFO
    LPINFO = lpinfo
Пример #22
0
def setup_local_sockets(bind,
                        socket_dir,
                        socket_dirs,
                        display_name,
                        clobber,
                        mmap_group="auto",
                        socket_permissions="600",
                        username="",
                        uid=0,
                        gid=0):
    log = get_network_logger()
    log("setup_local_sockets%s",
        (bind, socket_dir, socket_dirs, display_name, clobber, mmap_group,
         socket_permissions, username, uid, gid))
    if not bind:
        return {}
    if not socket_dir and (not socket_dirs or
                           (len(socket_dirs) == 1 and not socket_dirs[0])):
        if WIN32:
            socket_dirs = [""]
        else:
            raise InitExit(
                EXIT_SOCKET_CREATION_ERROR,
                "at least one socket directory must be set to use unix domain sockets"
            )
    from xpra.platform.dotxpra import DotXpra, norm_makepath
    dotxpra = DotXpra(socket_dir or socket_dirs[0], socket_dirs, username, uid,
                      gid)
    if display_name is not None and not WIN32:
        display_name = normalize_local_display_name(display_name)
    defs = {}
    try:
        sockpaths = {}
        log("setup_local_sockets: bind=%s, dotxpra=%s", bind, dotxpra)
        for b in bind:
            if b in ("none", ""):
                continue
            parts = b.split(",")
            sockpath = parts[0]
            options = {}
            if len(parts) == 2:
                options = parse_simple_dict(parts[1])
            if sockpath == "auto":
                assert display_name is not None
                for sockpath in dotxpra.norm_socket_paths(display_name):
                    sockpaths[sockpath] = options
                log("sockpaths(%s)=%s (uid=%i, gid=%i)", display_name,
                    sockpaths, uid, gid)
            else:
                sockpath = dotxpra.osexpand(sockpath)
                if os.path.isabs(sockpath):
                    pass
                elif sockpath.endswith("/") or (os.path.exists(sockpath)
                                                and os.path.isdir(sockpath)):
                    assert display_name is not None
                    sockpath = os.path.abspath(sockpath)
                    if not os.path.exists(sockpath):
                        os.makedirs(sockpath)
                    sockpath = norm_makepath(sockpath, display_name)
                else:
                    sockpath = dotxpra.socket_path(sockpath)
                sockpaths[sockpath] = options
            assert sockpaths, "no socket paths to try for %s" % b
        #expand and remove duplicate paths:
        tmp = {}
        for tsp, options in sockpaths.items():
            sockpath = dotxpra.osexpand(tsp)
            if sockpath in tmp:
                log.warn("Warning: skipping duplicate bind path %s", sockpath)
                continue
            tmp[sockpath] = options
        sockpaths = tmp
        log("sockpaths=%s", sockpaths)
        #create listeners:
        if WIN32:
            from xpra.platform.win32.namedpipes.listener import NamedPipeListener
            from xpra.platform.win32.dotxpra import PIPE_PATH
            for sockpath, options in sockpaths.items():
                npl = NamedPipeListener(sockpath)
                ppath = sockpath
                if ppath.startswith(PIPE_PATH):
                    ppath = ppath[len(PIPE_PATH):]
                log.info("created named pipe '%s'", ppath)
                defs[("named-pipe", npl, sockpath, npl.stop)] = options
        else:

            def checkstate(sockpath, state):
                if state not in (DotXpra.DEAD, DotXpra.UNKNOWN):
                    if state == DotXpra.INACCESSIBLE:
                        raise InitException(
                            "An xpra server is already running at %s\n" %
                            (sockpath, ))
                    raise InitExit(
                        EXIT_SERVER_ALREADY_EXISTS,
                        "You already have an xpra server running at %s\n"
                        "  (did you want 'xpra upgrade'?)" % (sockpath, ))

            #remove exisiting sockets if clobber is set,
            #otherwise verify there isn't a server already running
            #and create the directories for the sockets:
            unknown = []
            for sockpath in sockpaths:
                if clobber and os.path.exists(sockpath):
                    os.unlink(sockpath)
                else:
                    state = dotxpra.get_server_state(sockpath, 1)
                    log("state(%s)=%s", sockpath, state)
                    checkstate(sockpath, state)
                    if state == dotxpra.UNKNOWN:
                        unknown.append(sockpath)
                d = os.path.dirname(sockpath)
                try:
                    kwargs = {}
                    if d in ("/var/run/xpra", "/run/xpra"):
                        #this is normally done by tmpfiles.d,
                        #but we may need to do it ourselves in some cases:
                        kwargs["mode"] = SOCKET_DIR_MODE
                        xpra_gid = get_group_id(SOCKET_DIR_GROUP)
                        if xpra_gid > 0:
                            kwargs["gid"] = xpra_gid
                    log("creating sockdir=%s, kwargs=%s" % (d, kwargs))
                    dotxpra.mksockdir(d, **kwargs)
                    log("%s permission mask: %s", d, oct(os.stat(d).st_mode))
                except Exception as e:
                    log.warn("Warning: failed to create socket directory '%s'",
                             d)
                    log.warn(" %s", e)
                    del e
            #wait for all the unknown ones:
            log("sockets in unknown state: %s", unknown)
            if unknown:
                #re-probe them using threads so we can do them in parallel:
                threads = []

                def timeout_probe(sockpath):
                    #we need a loop because "DEAD" sockets may return immediately
                    #(ie: when the server is starting up)
                    start = monotonic_time()
                    while monotonic_time() - start < WAIT_PROBE_TIMEOUT:
                        state = dotxpra.get_server_state(
                            sockpath, WAIT_PROBE_TIMEOUT)
                        log("timeout_probe() get_server_state(%s)=%s",
                            sockpath, state)
                        if state not in (DotXpra.UNKNOWN, DotXpra.DEAD):
                            break
                        sleep(1)

                log.warn(
                    "Warning: some of the sockets are in an unknown state:")
                for sockpath in unknown:
                    log.warn(" %s", sockpath)
                    t = start_thread(timeout_probe,
                                     "probe-%s" % sockpath,
                                     daemon=True,
                                     args=(sockpath, ))
                    threads.append(t)
                log.warn(
                    " please wait as we allow the socket probing to timeout")
                #wait for all the threads to do their job:
                for t in threads:
                    t.join(WAIT_PROBE_TIMEOUT + 1)
            if sockpaths:
                #now we can re-check quickly:
                #(they should all be DEAD or UNKNOWN):
                for sockpath in sockpaths:
                    state = dotxpra.get_server_state(sockpath, 1)
                    log("state(%s)=%s", sockpath, state)
                    checkstate(sockpath, state)
                    try:
                        if os.path.exists(sockpath):
                            os.unlink(sockpath)
                    except OSError:
                        pass
                #socket permissions:
                if mmap_group.lower() in TRUE_OPTIONS:
                    #when using the mmap group option, use '660'
                    sperms = 0o660
                else:
                    #parse octal mode given as config option:
                    try:
                        if isinstance(socket_permissions, int):
                            sperms = socket_permissions
                        else:
                            #assume octal string:
                            sperms = int(socket_permissions, 8)
                        assert 0 <= sperms <= 0o777, "invalid socket permission value %s" % oct(
                            sperms)
                    except ValueError:
                        raise ValueError("invalid socket permissions " +
                                         "(must be an octal number): '%s'" %
                                         socket_permissions) from None
                #now try to create all the sockets:
                for sockpath, options in sockpaths.items():
                    #create it:
                    try:
                        sock, cleanup_socket = create_unix_domain_socket(
                            sockpath, sperms)
                        log.info("created unix domain socket '%s'", sockpath)
                        defs[("unix-domain", sock, sockpath,
                              cleanup_socket)] = options
                    except Exception as e:
                        handle_socket_error(sockpath, sperms, e)
                        del e
    except Exception:
        for sock, cleanup_socket in defs.items():
            try:
                cleanup_socket()
            except Exception as e:
                log.error("Error cleaning up socket %s:", sock)
                log.error(" %s", e)
                del e
        raise
    return defs
Пример #23
0
    def makeRootWindowModels(self):
        screenlog("makeRootWindowModels() root=%s, display_options=%s",
                  self.root, self.display_options)
        self.capture = self.setup_capture()
        model_class = self.get_root_window_model_class()
        models = []
        display_name = prettify_plug_name(
            self.root.get_screen().get_display().get_name())
        monitors = self.get_shadow_monitors()
        match_str = None
        multi_window = MULTI_WINDOW
        geometries = None

        def parse_geometry(s):
            try:
                parts = s.split("@")
                if len(parts) == 1:
                    x = y = 0
                else:
                    x, y = [int(v.strip(" ")) for v in parts[1].split("x")]
                w, h = [int(v.strip(" ")) for v in parts[0].split("x")]
                geometry = [x, y, w, h]
                screenlog("capture geometry: %s", geometry)
                return geometry
            except ValueError:
                screenlog("failed to parse geometry %r", s, exc_info=True)
                screenlog.error(
                    "Error: invalid display geometry specified: %r", s)
                screenlog.error(" use the format: WIDTHxHEIGHT@x,y")
                raise

        def parse_geometries(s):
            g = []
            for geometry_str in s.split("/"):
                if geometry_str:
                    g.append(parse_geometry(geometry_str))
            return g

        if "=" in self.display_options:
            #parse the display options as a dictionary:
            opt_dict = parse_simple_dict(self.display_options)
            match_str = opt_dict.get("plug")
            multi_window = parse_bool(
                "multi-window", opt_dict.get("multi-window", multi_window))
            geometries_str = opt_dict.get("geometry")
            if geometries_str:
                geometries = parse_geometries(geometries_str)
        else:
            try:
                geometries = parse_geometries(self.display_options)
            except:
                match_str = self.display_options
        if not multi_window or geometries:
            for geometry in (geometries or (None, )):
                model = model_class(self.root, self.capture)
                model.title = display_name
                if geometry:
                    model.geometry = geometry
                models.append(model)
            return models
        found = []
        screenlog("capture inputs matching %r", match_str or "all")
        for i, monitor in enumerate(monitors):
            plug_name, x, y, width, height, scale_factor = monitor
            title = display_name
            if plug_name or i > 1:
                title = plug_name or str(i)
            found.append(plug_name or title)
            if match_str and not (title in match_str
                                  or plug_name in match_str):
                screenlog.info(" skipped monitor %s", plug_name or title)
                continue
            model = model_class(self.root, self.capture)
            model.title = title
            model.geometry = (x, y, width, height)
            models.append(model)
            screenlog("monitor %i: %10s geometry=%s, scale factor=%s", i,
                      title, model.geometry, scale_factor)
        screenlog("makeRootWindowModels()=%s", models)
        if not models and match_str:
            screenlog.warn("Warning: no monitors found matching %r", match_str)
            screenlog.warn(" only found: %s", csv(found))
        return models