예제 #1
0
def add_simulated_widgets(app):
    local_machine = app.server
    for entry in TEST_REMOTES:
        display_name, name, user_name, hostname, ip, port, status, num_ops = entry
        machine = remote.RemoteMachine(name, hostname, hostname, ip, port,
                                       local_machine.service_ident)

        local_machine.remote_machines[name] = machine
        machine.connect("ops-changed", local_machine.remote_ops_changed)
        app.window.add_remote_button(machine, simulated=True)

        if status == RemoteStatus.ONLINE:
            machine.display_name = display_name
            machine.user_name = user_name
            machine.emit("machine-info-changed")
            machine.set_remote_status(RemoteStatus.ONLINE)

            if name == "test2":
                add_ops(machine)

        elif status == RemoteStatus.OFFLINE:
            machine.display_name = display_name
            machine.user_name = user_name
            machine.emit("machine-info-changed")
            machine.set_remote_status(RemoteStatus.OFFLINE)
        elif status == RemoteStatus.UNREACHABLE:
            machine.display_name = display_name
            machine.user_name = user_name
            machine.emit("machine-info-changed")
            machine.set_remote_status(RemoteStatus.UNREACHABLE)
        elif status == RemoteStatus.INIT_CONNECTING:
            machine.set_remote_status(RemoteStatus.INIT_CONNECTING)
            machine.emit("machine-info-changed")
        elif status == "new_op":
            machine.display_name = display_name
            machine.user_name = user_name
            machine.set_remote_status(RemoteStatus.ONLINE)
            machine.emit("machine-info-changed")
            for i in range(num_ops):
                op = ops.ReceiveOp(name)
                op.receiver_name = GLib.get_real_name()
예제 #2
0
    def add_service(self, zeroconf, _type, name):
        info = zeroconf.get_service_info(_type, name)

        if info:
            ident = name.partition(".")[0]

            try:
                remote_hostname = info.properties[b"hostname"].decode()
            except KeyError:
                logging.critical(
                    ">>> Discovery: no hostname in service info properties.  Is this an old version?"
                )
                return

            remote_ip = socket.inet_ntoa(
                info.addresses[0] if wrappers.zc_new_api else info.address)

            if not util.same_subnet(remote_ip):
                if remote_ip != self.ip_address:
                    logging.debug(
                        ">>> Discovery: service is not on this subnet, ignoring: %s (%s)"
                        % (remote_hostname, remote_ip))
                return

            try:
                # Check if this is a flush registration to reset the remote servier's presence.
                if info.properties[b"type"].decode() == "flush":
                    logging.debug(
                        ">>> Discovery: received flush service info (ignoring): %s (%s:%d)"
                        % (remote_hostname, remote_ip, info.port))
                    return
            except KeyError:
                logging.warning(
                    "No type in service info properties, assuming this is a real connect attempt"
                )

            if ident == self.service_ident:
                return

            def check_cert():
                # This will block if the remote's warp udp port is closed, until either the port is unblocked
                # or we tell the auth object to shutdown, in which case the request timer will cancel and return
                # here immediately (with None)
                got_cert = auth.get_singleton().retrieve_remote_cert(
                    ident, remote_hostname, remote_ip, info.port)

                if not got_cert:
                    logging.critical(
                        ">>> Discovery: unable to authenticate with %s (%s:%d)"
                        % (remote_hostname, remote_ip, info.port))
                    return False
                return True

            try:
                machine = self.remote_machines[ident]
                machine.has_zc_presence = True
                logging.debug(">>> Discovery: existing remote: %s (%s:%d)" %
                              (machine.display_hostname, remote_ip, info.port))

                # If the remote truly is the same one (our service info just dropped out
                # momentarily), this will end up just retrieving the current cert again.
                # If this was a real disconnect we didn't notice, we'll have the new cert
                # which we'll need when our supposedly existing connection tries to continue
                # pinging. It will fail out and restart the connection loop, and will need
                # this updated one.
                if not check_cert():
                    return

                if machine.status == RemoteStatus.ONLINE:
                    logging.debug(
                        ">>> Discovery: rejoining existing connect with %s (%s:%d)"
                        % (machine.display_hostname, remote_ip, info.port))
                    return

                # Update our connect info if it changed.
                machine.hostname = remote_hostname
                machine.ip_address = remote_ip
                machine.port = info.port
            except KeyError:
                if not check_cert():
                    return

                display_hostname = remote_hostname
                i = 1

                while True:
                    found = False

                    for key in self.remote_machines.keys():
                        remote_machine = self.remote_machines[key]

                        if remote_machine.display_hostname == display_hostname:
                            display_hostname = "%s[%d]" % (remote_hostname, i)
                            found = True
                            break

                    i += 1

                    if not found:
                        break

                logging.debug(">>> Discovery: new remote: %s (%s:%d)" %
                              (display_hostname, remote_ip, info.port))

                machine = remote.RemoteMachine(ident, remote_hostname,
                                               display_hostname, remote_ip,
                                               info.port, self.service_ident)

                self.remote_machines[ident] = machine
                machine.connect("ops-changed", self.remote_ops_changed)
                machine.connect("remote-status-changed",
                                self.remote_status_changed)
                self.idle_emit("remote-machine-added", machine)

            machine.has_zc_presence = True

            logging.debug(
                ">>> Discovery: closing previous connection for %s (%s:%d)" %
                (machine.display_hostname, remote_ip, info.port))
            machine.shutdown(
            )  # This does nothing if run more than once.  It's here to make sure
            # the previous start thread is complete before starting a new one.
            # This is needed in the corner case where the remote has gone offline,
            # and returns before our Ping loop times out and closes the thread
            # itself.

            machine.start_remote_thread()
예제 #3
0
    def add_service(self, zeroconf, _type, name):
        info = zeroconf.get_service_info(_type, name)

        if info:
            ident = name.partition(".")[0]

            try:
                remote_hostname = info.properties[b"hostname"].decode()
            except KeyError:
                logging.critical(
                    ">>> Discovery: no hostname in service info properties.  Is this an old version?"
                )
                return

            remote_ips = util.IPAddresses.new_from_binary_list(info.addresses)

            try:
                # Check if this is a flush registration to reset the remote server's presence.
                if info.properties[b"type"].decode() == "flush":
                    logging.debug(
                        ">>> Discovery: received flush service info (ignoring): %s (%s:%d)"
                        % (remote_hostname, remote_ips, info.port))
                    return
            except KeyError:
                logging.warning(
                    "No type in service info properties, assuming this is a real connect attempt"
                )

            if ident == self.service_ident:
                return

            try:
                api_version = info.properties[b"api-version"].decode()
                auth_port = int(info.properties[b"auth-port"].decode())
            except KeyError:
                api_version = "1"
                auth_port = 0

            # FIXME: I'm not sure why we still get discovered by other networks in some cases -
            # The Zeroconf object has a specific ip it is set to, what more do I need to do?
            if not self.netmon.same_subnet(remote_ips):
                if remote_ips != self.ips:
                    logging.debug(
                        ">>> Discovery: service is not on this subnet, ignoring: %s (%s)"
                        % (remote_hostname, remote_ips))
                return

            try:
                machine = self.remote_machines[ident]
                machine.has_zc_presence = True
                logging.debug(
                    ">>> Discovery: existing remote: %s (%s:%d)" %
                    (machine.display_hostname, remote_ips, info.port))

                # If the remote truly is the same one (our service info just dropped out
                # momentarily), this will end up just retrieving the current cert again.
                # If this was a real disconnect we didn't notice, we'll have the new cert
                # which we'll need when our supposedly existing connection tries to continue
                # pinging. It will fail out and restart the connection loop, and will need
                # this updated one.
                if not self.remote_registrar.register(
                        ident, remote_hostname, remote_ips, info.port,
                        auth_port,
                        api_version) or self.server_thread_keepalive.is_set():
                    logging.warning(
                        "Register failed, or the server was shutting down during registration, ignoring remote %s (%s:%d) auth port: %d"
                        % (remote_hostname, remote_ips, info.port, auth_port))
                    return

                if machine.status == RemoteStatus.ONLINE:
                    logging.debug(
                        ">>> Discovery: rejoining existing connect with %s (%s:%d)"
                        % (machine.display_hostname, remote_ips, info.port))
                    return

                # Update our connect info if it changed.
                machine.hostname = remote_hostname
                machine.ips = remote_ips
                machine.port = info.port
                machine.api_version = api_version
            except KeyError:
                display_hostname = remote_hostname
                i = 1

                while True:
                    found = False

                    for key in self.remote_machines.keys():
                        remote_machine = self.remote_machines[key]

                        if remote_machine.display_hostname == display_hostname:
                            display_hostname = "%s[%d]" % (remote_hostname, i)
                            found = True
                            break

                    i += 1

                    if not found:
                        break

                logging.debug(">>> Discovery: new remote: %s (%s:%d)" %
                              (display_hostname, remote_ips, info.port))

                machine = remote.RemoteMachine(ident, remote_hostname,
                                               display_hostname, remote_ips,
                                               info.port, self.service_ident,
                                               api_version)

                if not self.remote_registrar.register(
                        ident, remote_hostname, remote_ips, info.port,
                        auth_port,
                        api_version) or self.server_thread_keepalive.is_set():
                    logging.warning(
                        "Register failed, or the server was shutting down during registration, ignoring remote %s (%s:%d) auth port: %d"
                        % (remote_hostname, remote_ips, info.port, auth_port))
                    return

                self.remote_machines[ident] = machine
                machine.connect("ops-changed", self.remote_ops_changed)
                machine.connect("remote-status-changed",
                                self.remote_status_changed)
                self.idle_emit("remote-machine-added", machine)

            machine.has_zc_presence = True

            machine.shutdown(
            )  # This does nothing if run more than once.  It's here to make sure
            # the previous start thread is complete before starting a new one.
            # This is needed in the corner case where the remote has gone offline,
            # and returns before our Ping loop times out and closes the thread
            # itself.

            machine.start_remote_thread()
예제 #4
0
    def add_service(self, zeroconf, _type, name):
        info = zeroconf.get_service_info(_type, name)

        if info:
            ident = name.partition(".")[0]

            try:
                remote_hostname = info.properties[b"hostname"].decode()
            except KeyError:
                print(
                    "No hostname in service info properties.  Is this an old version?"
                )
                return

            remote_ip = socket.inet_ntoa(info.address)

            if ident == self.service_ident:
                return

            got_cert = auth.get_singleton().retrieve_remote_cert(
                remote_hostname, remote_ip, info.port)

            if not got_cert:
                print("Unable to authenticate with %s (%s)" %
                      (remote_hostname, remote_ip))
                return

            # print("Client %s added at %s" % (name, remote_ip))

            try:
                machine = self.remote_machines[ident]
                # Update our connect info if it changed.
                machine.hostname = remote_hostname
                machine.ip_address = remote_ip
                machine.port = info.port
            except KeyError:
                display_hostname = remote_hostname
                i = 1

                while True:
                    found = False

                    for key in self.remote_machines.keys():
                        remote_machine = self.remote_machines[key]

                        if remote_machine.display_hostname == display_hostname:
                            display_hostname = "%s[%d]" % (remote_hostname, i)
                            found = True
                            break

                    i += 1

                    if not found:
                        break

                machine = remote.RemoteMachine(ident, remote_hostname,
                                               display_hostname, remote_ip,
                                               info.port, self.service_ident)

                self.remote_machines[ident] = machine
                machine.connect("ops-changed", self.remote_ops_changed)
                self.emit_remote_machine_added(machine)

            machine.start()