Пример #1
0
 def hello_oked(self, proto, packet, c, auth_caps):
     if ServerCore.hello_oked(self, proto, packet, c, auth_caps):
         #already handled in superclass
         return
     self.accept_client(proto, c)
     generic_request = c.strget("request")
     def is_req(mode):
         return generic_request==mode or c.boolget("%s_request" % mode)
     if any(is_req(x) for x in ("screenshot", "event", "print", "exit")):
         self.send_disconnect(proto, "invalid request")
         return
     if is_req("stop"):
         if not CAN_STOP_PROXY:
             self.send_disconnect(proto, "cannot stop proxy server")
             return
         self._requests.add(proto)
         #send a hello back and the client should then send its "shutdown-server" packet
         capabilities = self.make_hello()
         proto.send_now(("hello", capabilities))
         def force_exit_request_client():
             try:
                 self._requests.remove(proto)
             except:
                 pass
             if not proto._closed:
                 self.send_disconnect(proto, "timeout")
         self.timeout_add(10*1000, force_exit_request_client)
         return
     self.proxy_auth(proto, c, auth_caps)
Пример #2
0
    def hello_oked(self, proto, packet, c, auth_caps):
        if ServerCore.hello_oked(self, proto, packet, c, auth_caps):
            #already handled in superclass
            return
        self.accept_client(proto, c)
        if any(
                c.boolget("%s_request" % x)
                for x in ("screenshot", "event", "print", "exit")):
            self.send_disconnect(proto, "invalid request")
            return
        if c.boolget("stop_request"):
            self._requests.add(proto)
            #send a hello back and the client should then send its "shutdown-server" packet
            capabilities = self.make_hello()
            proto.send_now(("hello", capabilities))

            def force_exit_request_client():
                try:
                    self._requests.remove(proto)
                except:
                    pass
                if not proto._closed:
                    self.send_disconnect(proto, "timeout")

            self.timeout_add(10 * 1000, force_exit_request_client)
        else:
            self.start_proxy(proto, c, auth_caps)
Пример #3
0
    def hello_oked(self, proto, packet, c, auth_caps):
        if ServerCore.hello_oked(self, proto, packet, c, auth_caps):
            #already handled in superclass
            return
        self.accept_client(proto, c)
        generic_request = c.strget("request")

        def is_req(mode):
            return generic_request == mode or c.boolget("%s_request" % mode)

        if any(is_req(x) for x in ("screenshot", "event", "print", "exit")):
            self.send_disconnect(proto, "invalid request")
            return
        if is_req("stop"):
            #global kill switch:
            if not CAN_STOP_PROXY:
                msg = "cannot stop proxy server"
                log.warn("Warning: %s", msg)
                self.send_disconnect(proto, msg)
                return
            #verify socket type (only local connections by default):
            try:
                socktype = proto._conn.get_info().get("type", "unknown")
            except:
                socktype = "unknown"
            if socktype not in STOP_PROXY_SOCKET_TYPES:
                msg = "cannot stop proxy server from a '%s' connection" % socktype
                log.warn("Warning: %s", msg)
                log.warn(" only from: %s", csv(STOP_PROXY_SOCKET_TYPES))
                self.send_disconnect(proto, msg)
                return
            #connection must be authenticated:
            if not proto.authenticators:
                msg = "cannot stop proxy server from unauthenticated connections"
                log.warn("Warning: %s", msg)
                self.send_disconnect(proto, msg)
                return
            self._requests.add(proto)
            #send a hello back and the client should then send its "shutdown-server" packet
            capabilities = self.make_hello()
            proto.send_now(("hello", capabilities))

            def force_exit_request_client():
                try:
                    self._requests.remove(proto)
                except KeyError:
                    pass
                if not proto._closed:
                    self.send_disconnect(proto, "timeout")

            self.timeout_add(10 * 1000, force_exit_request_client)
            return
        self.proxy_auth(proto, c, auth_caps)
Пример #4
0
 def hello_oked(self, proto, packet, c, auth_caps):
     if ServerCore.hello_oked(self, proto, packet, c, auth_caps):
         #already handled in superclass
         return
     self.accept_client(proto, c)
     if any(c.boolget("%s_request" % x) for x in ("screenshot", "event", "print", "exit")):
         self.send_disconnect(proto, "invalid request")
         return
     if c.boolget("stop_request"):
         self._requests.add(proto)
         #send a hello back and the client should then send its "shutdown-server" packet
         capabilities = self.make_hello()
         proto.send_now(("hello", capabilities))
         def force_exit_request_client():
             try:
                 self._requests.remove(proto)
             except:
                 pass
             if not proto._closed:
                 self.send_disconnect(proto, "timeout")
         self.timeout_add(10*1000, force_exit_request_client)
     else:
         self.start_proxy(proto, c, auth_caps)
Пример #5
0
    def hello_oked(self, proto, packet, c, auth_caps):
        if self._server_sources.get(proto):
            log.warn("Warning: received another 'hello' packet")
            log.warn(" from an existing connection: %s", proto)
            return
        if ServerCore.hello_oked(self, proto, packet, c, auth_caps):
            #has been handled
            return
        if not self.sanity_checks(proto, c):
            return
        if not c.boolget("steal", True) and self._server_sources:
            self.disconnect_client(proto, SESSION_BUSY,
                                   "this session is already active")
            return
        if c.boolget("screenshot_request"):
            self.send_screenshot(proto)
            return
        #added in 2.2:
        request = c.strget("request")

        def is_req(mode):
            return request == mode or c.boolget("%s_request" % mode, False)

        if not request:
            #"normal" connection, so log welcome message:
            log.info("Handshake complete; enabling connection")
        else:
            log("handling request %s", request)
        self.server_event("handshake-complete")

        # Things are okay, we accept this connection, and may disconnect previous one(s)
        # (but only if this is going to be a UI session - control sessions can co-exist)
        ui_client = c.boolget("ui_client", True)
        share = c.boolget("share")
        uuid = c.strget("uuid")
        detach_request = is_req("detach")
        accepted, share_count, disconnected = self.handle_sharing(
            proto, ui_client, detach_request, share, uuid)
        if not accepted:
            return

        if is_req("detach"):
            self.disconnect_client(
                proto, DONE,
                "%i other clients have been disconnected" % disconnected)
            return

        if not request and ui_client:
            #a bit of explanation:
            #normally these things are synchronized using xsettings, which we handle already
            #but non-posix clients have no such thing,
            #and we don't want to expose that as an interface
            #(it's not very nice and it is very X11 specific)
            #also, clients may want to override what is in their xsettings..
            #so if the client specifies what it wants to use, we patch the xsettings with it
            #(the actual xsettings part is done in update_all_server_settings in the X11 specific subclasses)
            if share_count > 0:
                log.info("sharing with %s other client(s)", share_count)
                self.dpi = 0
                self.xdpi = 0
                self.ydpi = 0
                self.double_click_time = -1
                self.double_click_distance = -1, -1
                self.antialias = {}
                self.cursor_size = 24
            else:
                self.dpi = c.intget("dpi", 0)
                self.xdpi = c.intget("dpi.x", 0)
                self.ydpi = c.intget("dpi.y", 0)
                self.double_click_time = c.intget("double_click.time", -1)
                self.double_click_distance = c.intpair("double_click.distance",
                                                       (-1, -1))
                self.antialias = c.dictget("antialias", {})
                self.cursor_size = c.intget("cursor.size", 0)
            #FIXME: this belongs in DisplayManager!
            screenlog(
                "dpi=%s, dpi.x=%s, dpi.y=%s, antialias=%s, cursor_size=%s",
                self.dpi, self.xdpi, self.ydpi, self.antialias,
                self.cursor_size)
            log("double-click time=%s, distance=%s", self.double_click_time,
                self.double_click_distance)
            #if we're not sharing, reset all the settings:
            reset = share_count == 0
            self.update_all_server_settings(reset)

        self.accept_client(proto, c)
        #use blocking sockets from now on:
        if not WIN32:
            set_socket_timeout(proto._conn, None)

        def drop_client(reason="unknown", *args):
            self.disconnect_client(proto, reason, *args)

        cc_class = self.get_client_connection_class(c)
        ss = cc_class(
            proto,
            drop_client,
            self.session_name,
            self,
            self.idle_add,
            self.timeout_add,
            self.source_remove,
            self.setting_changed,
            self._socket_dir,
            self.unix_socket_paths,
            not request,
            self.bandwidth_limit,
            self.bandwidth_detection,
        )
        log("process_hello clientconnection=%s", ss)
        try:
            ss.parse_hello(c)
        except:
            #close it already
            ss.close()
            raise
        self._server_sources[proto] = ss
        add_work_item(self.mdns_update)
        #process ui half in ui thread:
        send_ui = ui_client and not request
        self.idle_add(self._process_hello_ui, ss, c, auth_caps, send_ui,
                      share_count)
Пример #6
0
    def hello_oked(self, proto, packet, c, auth_caps):
        if ServerCore.hello_oked(self, proto, packet, c, auth_caps):
            #has been handled
            return
        if not c.boolget("steal", True) and self._server_sources:
            self.disconnect_client(proto, SESSION_BUSY, "this session is already active")
            return
        if c.boolget("screenshot_request"):
            self.send_screenshot(proto)
            return
        #added in 2.2:
        generic_request = c.strget("request")
        def is_req(mode):
            return generic_request==mode or c.boolget("%s_request" % mode, False)
        detach_request  = is_req("detach")
        stop_request    = is_req("stop_request")
        exit_request    = is_req("exit_request")
        event_request   = is_req("event_request")
        print_request   = is_req("print_request")
        is_request = detach_request or stop_request or exit_request or event_request or print_request
        if not is_request:
            #"normal" connection, so log welcome message:
            log.info("Handshake complete; enabling connection")
        else:
            log("handling request %s", generic_request)
        self.server_event("handshake-complete")

        # Things are okay, we accept this connection, and may disconnect previous one(s)
        # (but only if this is going to be a UI session - control sessions can co-exist)
        ui_client = c.boolget("ui_client", True)
        share = c.boolget("share")
        uuid = c.strget("uuid")
        accepted, share_count, disconnected = self.handle_sharing(proto, ui_client, detach_request, share, uuid)
        if not accepted:
            return

        if detach_request:
            self.disconnect_client(proto, DONE, "%i other clients have been disconnected" % disconnected)
            return

        if not is_request and ui_client:
            #a bit of explanation:
            #normally these things are synchronized using xsettings, which we handle already
            #but non-posix clients have no such thing,
            #and we don't want to expose that as an interface
            #(it's not very nice and it is very X11 specific)
            #also, clients may want to override what is in their xsettings..
            #so if the client specifies what it wants to use, we patch the xsettings with it
            #(the actual xsettings part is done in update_all_server_settings in the X11 specific subclasses)
            if share_count>0:
                log.info("sharing with %s other client(s)", share_count)
                self.dpi = 0
                self.xdpi = 0
                self.ydpi = 0
                self.double_click_time = -1
                self.double_click_distance = -1, -1
                self.antialias = {}
                self.cursor_size = 24
            else:
                self.dpi = c.intget("dpi", 0)
                self.xdpi = c.intget("dpi.x", 0)
                self.ydpi = c.intget("dpi.y", 0)
                self.double_click_time = c.intget("double_click.time", -1)
                self.double_click_distance = c.intpair("double_click.distance", (-1, -1))
                self.antialias = c.dictget("antialias")
                self.cursor_size = c.intget("cursor.size", 0)
            #FIXME: this belongs in DisplayManager!
            log("dpi=%s, dpi.x=%s, dpi.y=%s, double_click_time=%s, double_click_distance=%s, antialias=%s, cursor_size=%s", self.dpi, self.xdpi, self.ydpi, self.double_click_time, self.double_click_distance, self.antialias, self.cursor_size)
            #if we're not sharing, reset all the settings:
            reset = share_count==0
            self.update_all_server_settings(reset)

        self.accept_client(proto, c)
        #use blocking sockets from now on:
        if not (PYTHON3 and WIN32):
            set_socket_timeout(proto._conn, None)

        def drop_client(reason="unknown", *args):
            self.disconnect_client(proto, reason, *args)
        get_window_id = self._window_to_id.get
        bandwidth_limit = self.get_client_bandwidth_limit(proto)
        ClientConnectionClass = self.get_server_source_class()
        ss = ClientConnectionClass(proto, drop_client,
                          self.session_name,
                          self.idle_add, self.timeout_add, self.source_remove, self.setting_changed,
                          self.idle_timeout,
                          self._socket_dir, self.unix_socket_paths, not is_request, self.dbus_control,
                          self.get_transient_for, self.get_focus, self.get_cursor_data,
                          get_window_id,
                          self.window_filters,
                          self.file_transfer,
                          self.supports_mmap, self.mmap_filename, self.min_mmap_size,
                          bandwidth_limit,
                          self.av_sync,
                          self.core_encodings, self.encodings, self.default_encoding, self.scaling_control,
                          self.webcam_enabled, self.webcam_device, self.webcam_encodings,
                          self.sound_properties,
                          self.sound_source_plugin,
                          self.supports_speaker, self.supports_microphone,
                          self.speaker_codecs, self.microphone_codecs,
                          self.default_quality, self.default_min_quality,
                          self.default_speed, self.default_min_speed)
        log("process_hello clientconnection=%s", ss)
        try:
            ss.parse_hello(c)
        except:
            #close it already
            ss.close()
            raise
        try:
            self.notify_new_user(ss)
        except Exception as e:
            notifylog("%s(%s)", self.notify_new_user, ss, exc_info=True)
            notifylog.error("Error: failed to show notification of user login:"******" %s", e)
        self._server_sources[proto] = ss
        #process ui half in ui thread:
        send_ui = ui_client and not is_request
        self.idle_add(self.parse_hello_ui, ss, c, auth_caps, send_ui, share_count)