コード例 #1
0
 def create_control_socket(self):
     assert self.socket_dir
     username = get_username_for_uid(self.uid)
     dotxpra = DotXpra(self.socket_dir, actual_username=username, uid=self.uid, gid=self.gid)
     sockpath = dotxpra.socket_path(":proxy-%s" % os.getpid())
     state = dotxpra.get_server_state(sockpath)
     log("create_control_socket: socket path='%s', uid=%i, gid=%i, state=%s", sockpath, getuid(), getgid(), state)
     if state in (DotXpra.LIVE, DotXpra.UNKNOWN):
         log.error("Error: you already have a proxy server running at '%s'", sockpath)
         log.error(" the control socket will not be created")
         return False
     d = os.path.dirname(sockpath)
     try:
         dotxpra.mksockdir(d)
     except Exception as e:
         log.warn("Warning: failed to create socket directory '%s'", d)
         log.warn(" %s", e)
     try:
         sock, self.control_socket_cleanup = create_unix_domain_socket(sockpath, None, 0o600)
         sock.listen(5)
     except Exception as e:
         log("create_unix_domain_socket failed for '%s'", sockpath, exc_info=True)
         log.error("Error: failed to setup control socket '%s':", sockpath)
         log.error(" %s", e)
         return False
     self.control_socket = sock
     self.control_socket_path = sockpath
     log.info("proxy instance now also available using unix domain socket:")
     log.info(" %s", self.control_socket_path)
     return True
コード例 #2
0
    def create_control_socket(self):
        assert self.socket_dir

        def stop(msg):
            self.stop(None, "cannot create the proxy control socket: %s" % msg)

        username = get_username_for_uid(self.uid)
        dotxpra = DotXpra(self.socket_dir,
                          actual_username=username,
                          uid=self.uid,
                          gid=self.gid)
        sockname = ":proxy-%s" % os.getpid()
        sockpath = dotxpra.socket_path(sockname)
        log("%s.socket_path(%s)=%s", dotxpra, sockname, sockpath)
        state = dotxpra.get_server_state(sockpath)
        log(
            "create_control_socket: socket path='%s', uid=%i, gid=%i, state=%s",
            sockpath, getuid(), getgid(), state)
        if state in (DotXpra.LIVE, DotXpra.UNKNOWN, DotXpra.INACCESSIBLE):
            log.error("Error: you already have a proxy server running at '%s'",
                      sockpath)
            log.error(" the control socket will not be created")
            stop("socket already exists")
            return False
        d = os.path.dirname(sockpath)
        try:
            dotxpra.mksockdir(d, SOCKET_DIR_MODE)
        except Exception as e:
            log.warn("Warning: failed to create socket directory '%s'", d)
            log.warn(" %s", e)
        try:
            sock, self.control_socket_cleanup = create_unix_domain_socket(
                sockpath, 0o600)
            sock.listen(5)
        except Exception as e:
            log("create_unix_domain_socket failed for '%s'",
                sockpath,
                exc_info=True)
            log.error("Error: failed to setup control socket '%s':", sockpath)
            handle_socket_error(sockpath, 0o600, e)
            stop(e)
            return False
        self.control_socket = sock
        self.control_socket_path = sockpath
        log.info("proxy instance now also available using unix domain socket:")
        log.info(" %s", self.control_socket_path)
        return True
コード例 #3
0
ファイル: socket_util.py プロジェクト: rudresh2319/Xpra
def setup_local_sockets(bind,
                        socket_dir,
                        socket_dirs,
                        display_name,
                        clobber,
                        mmap_group=False,
                        socket_permissions="600",
                        username="",
                        uid=0,
                        gid=0):
    if not bind:
        return []
    if not socket_dir and (not socket_dirs or
                           (len(socket_dirs) == 1 and not socket_dirs[0])):
        raise InitException(
            "at least one socket directory must be set to use unix domain sockets"
        )
    dotxpra = DotXpra(socket_dir or socket_dirs[0], socket_dirs, username, uid,
                      gid)
    display_name = normalize_local_display_name(display_name)
    log = get_network_logger()
    defs = []
    try:
        sockpaths = []
        log("setup_local_sockets: bind=%s", bind)
        for b in bind:
            sockpath = b
            if b == "none" or b == "":
                continue
            elif b == "auto":
                sockpaths += dotxpra.norm_socket_paths(display_name)
                log("sockpaths(%s)=%s (uid=%i, gid=%i)", display_name,
                    sockpaths, uid, gid)
            else:
                sockpath = dotxpra.osexpand(b)
                if b.endswith("/") or (os.path.exists(sockpath)
                                       and os.path.isdir(sockpath)):
                    sockpath = os.path.abspath(sockpath)
                    if not os.path.exists(sockpath):
                        os.makedirs(sockpath)
                    sockpath = norm_makepath(sockpath, display_name)
                elif os.path.isabs(b):
                    sockpath = b
                else:
                    sockpath = dotxpra.socket_path(b)
                sockpaths += [sockpath]
            assert sockpaths, "no socket paths to try for %s" % b
        #expand and remove duplicate paths:
        tmp = []
        for tsp in sockpaths:
            sockpath = dotxpra.osexpand(tsp)
            if sockpath in tmp:
                log.warn("Warning: skipping duplicate bind path %s", sockpath)
                continue
            tmp.append(sockpath)
        sockpaths = tmp
        #create listeners:
        if WIN32:
            from xpra.platform.win32.namedpipes.listener import NamedPipeListener
            for sockpath in sockpaths:
                npl = NamedPipeListener(sockpath)
                log.info("created named pipe: %s", sockpath)
                defs.append((("named-pipe", npl, sockpath), npl.stop))
        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 InitException(
                        "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:
                    dotxpra.mksockdir(d)
                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:
                from time import sleep
                from xpra.make_thread import start_thread
                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)
            #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:
                    pass
            #now try to create all the sockets:
            for sockpath in sockpaths:
                #create it:
                try:
                    sock, cleanup_socket = create_unix_domain_socket(
                        sockpath, mmap_group, socket_permissions)
                    log.info("created unix domain socket: %s", sockpath)
                    defs.append(
                        (("unix-domain", sock, sockpath), cleanup_socket))
                except Exception as e:
                    handle_socket_error(sockpath, e)
                    del e
    except:
        for sock, cleanup_socket in defs:
            try:
                cleanup_socket()
            except Exception as e:
                log.error("Error cleaning up socket %s:", sock)
                log.error(" %s", e)
                del e
        defs = []
        raise
    return defs
コード例 #4
0
ファイル: socket_util.py プロジェクト: sincere32/xpra
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