Example #1
0
def send_server_information(ip, port, spread=True):
    # Validates the ip or domain (syntax only)
    if validators.domain(ip) is not True:
        if validators.ip_address.ipv4(ip) is not True:
            if validators.ip_address.ipv6(ip) is not True:
                print(
                    f"Failed to validate ip or domain: {ip}. Check for typing mistakes."
                )
                return False

    # Validates port number
    if validators.between(port, min=1, max=65535) is not True:
        print(f"Invalid port number: {port} is not between 1 and 65535")
        return False

    if not registry.exists(settings.ADDRESS_ID_REGISTRY):
        print(
            f"Address ID was not found in the registry! (Location: {settings.ADDRESS_ID_REGISTRY})"
        )
        return False
    if not registry.exists(settings.RSA_PRIVATE_REGISTRY):
        print(
            f"RSA Private Key was not found in the registry! (Location: {settings.RSA_PRIVATE_REGISTRY})"
        )
        return False
    address_id = registry.get_value(settings.ADDRESS_ID_REGISTRY)

    # Creates server message
    server_update_dict = dict(
        type=MessageType.SERVER_UPDATE,
        signature=0,
        address_id=address_id +
        1,  # Increases the address id, to indicate the information is new and up to date.
        address_size=len(ip),
        address=ip.encode("ascii"),
        port=port,
        spread=spread)

    # Calculate signature of message
    try:
        server_update_message = messages.SERVER_UPDATE_MESSAGE.build(
            server_update_dict)

        # Update signature
        server_update_dict["signature"] = messages.sign_message(
            server_update_message)
        server_update_message = messages.SERVER_UPDATE_MESSAGE.build(
            server_update_dict)
    except construct.ConstructError as e:
        # Should never occur
        print(f"Failed to build server update message: {e.args}")
        return False

    # Sends server information update (should also update local server information)
    updater.send_broadcast(server_update_message)
    print("Server information was sent to services!")
    return True
Example #2
0
def generate_rsa_keys(display_keys=True):
    key_pair = RSA.generate(bits=settings.RSA_KEY_SIZE)

    # Adds the keys to settings file
    rsa_settings = dict(
        RSA_MODULO=hex(key_pair.n),
        PUBLIC_KEY=hex(key_pair.e),
    )
    if not add_to_settings(rsa_settings):
        print(f"Failed to add rsa key to {DEFAULT_SETTINGS_PATH}")
        return False

    # Adds the keys to registry
    if not registry.exists(settings.REGISTRY_PATH):
        registry.create_key(settings.REGISTRY_PATH)
    registry.set_value(settings.RSA_MODULO_REGISTRY, hex(key_pair.n))
    registry.set_value(settings.RSA_PUBLIC_REGISTRY, hex(key_pair.e))
    registry.set_value(settings.RSA_PRIVATE_REGISTRY, hex(key_pair.d))

    # Displays the keys to the user
    print("RSA keys were generated!")
    print("")
    if display_keys:
        show_rsa_keys()
    return True
Example #3
0
def show_server_information():
    address_id = "Not available"
    if registry.exists(settings.ADDRESS_ID_REGISTRY):
        address_id = registry.get_value(settings.ADDRESS_ID_REGISTRY)

    ip = "Not available"
    if registry.exists(settings.UPDATING_SERVER_REGISTRY):
        ip = registry.get_value(settings.UPDATING_SERVER_REGISTRY)

    port = "Not available"
    if registry.exists(settings.PORT_REGISTRY):
        port = registry.get_value(settings.PORT_REGISTRY)

    print(f"Address ID: \t{address_id}")
    print(f"Domain (IP): \t{ip}")
    print(f"Port: \t\t{port}")
    return True
Example #4
0
def show_rsa_keys():
    print("RSA Modulo (n):")
    if registry.exists(settings.RSA_MODULO_REGISTRY):
        print(registry.get_value(settings.RSA_MODULO_REGISTRY))
    else:
        print("Not available.")
    print("")

    print("RSA Public Key (e):")
    if registry.exists(settings.RSA_PUBLIC_REGISTRY):
        print(registry.get_value(settings.RSA_PUBLIC_REGISTRY))
    else:
        print("Not available.")
    print("")

    print("RSA Private Key (d):")
    if registry.exists(settings.RSA_PRIVATE_REGISTRY):
        print(registry.get_value(settings.RSA_PRIVATE_REGISTRY))
    else:
        print("Not available.")
    return True
Example #5
0
def load_settings():
    global __values__
    if "SETTINGS_REGISTRY" in __values__ and registry.exists(
            __values__["SETTINGS_REGISTRY"]):
        settings_path = registry.get_value(__values__["SETTINGS_REGISTRY"])
    else:
        settings_path = __values__[
            "SETTINGS_PATH"] if "SETTINGS_PATH" in __values__ else INITIAL_SETTINGS_PATH

    try:
        with open(settings_path, "r") as settings_file:
            data = settings_file.read()
            __values__.update(json.loads(data))
    except FileNotFoundError:
        # If settings file is not found, use default settings
        pass
Example #6
0
def save_settings():
    global __values__
    if "SETTINGS_REGISTRY" in __values__ and registry.exists(
            __values__["SETTINGS_REGISTRY"]):
        settings_path = registry.get_value(__values__["SETTINGS_REGISTRY"])
    else:
        settings_path = __values__[
            "SETTINGS_PATH"] if "SETTINGS_PATH" in __values__ else INITIAL_SETTINGS_PATH

    try:
        with open(settings_path, "w") as settings_file:
            data = json.dumps(__values__)
            settings_file.write(data)
    except PermissionError:
        logging.critical(
            f"Failed to write settings file due to PermissionError: {__values__['SETTINGS_PATH']}",
            exc_info=True)
Example #7
0
def init_settings(save=True, load=True):
    global __values__

    # Default settings that are needed before load
    __values__.setdefault(
        "REGISTRY_PATH",
        rf"Software\{__values__['SOFTWARE_NAME']}\{__values__['UPDATER_NAME']}"
    )
    __values__.setdefault("SETTINGS_REGISTRY",
                          rf"{__values__['REGISTRY_PATH']}\settings")

    if registry.exists(__values__['SETTINGS_REGISTRY']):
        settings_path = registry.get_value(__values__['SETTINGS_REGISTRY'])
        software_path = os.path.dirname(os.path.dirname(settings_path))
        __values__['SOFTWARE_PATH'] = software_path

    # Load existing settings
    if load:
        load_settings()

    # Setting default settings values, if they don't appear in the settings.json file already

    __values__.setdefault(
        "SOFTWARE_PATH",
        rf"{PROGRAM_FILES}{os.path.sep}{__values__['SOFTWARE_NAME']}")
    __values__.setdefault(
        "UPDATER_PATH",
        rf"{__values__['SOFTWARE_PATH']}{os.path.sep}{__values__['UPDATER_NAME']}"
    )
    __values__.setdefault(
        "PROGRAM_PATH",
        rf"{__values__['SOFTWARE_PATH']}{os.path.sep}{__values__['SOFTWARE_NAME']}"
    )
    __values__.setdefault(
        "LAUNCHER_PATH",
        rf"{__values__['SOFTWARE_PATH']}{os.path.sep}{__values__['LAUNCHER_NAME']}"
    )
    __values__.setdefault(
        "SETTINGS_PATH",
        rf"{__values__['UPDATER_PATH']}{os.path.sep}settings.json")
    __values__.setdefault(
        "LOGGER_PATH", rf"{__values__['UPDATER_PATH']}{os.path.sep}log.txt")
    __values__.setdefault(
        "UPDATE_PATH", rf"{__values__['UPDATER_PATH']}{os.path.sep}update.zip")
    __values__.setdefault("AUTO_INSTALLATIONS_REGISTRY",
                          rf"{__values__['REGISTRY_PATH']}\auto_update")
    __values__.setdefault("UPDATING_SERVER_REGISTRY",
                          rf"{__values__['REGISTRY_PATH']}\update_server")
    __values__.setdefault("PORT_REGISTRY",
                          rf"{__values__['REGISTRY_PATH']}\port")
    __values__.setdefault("RSA_MODULO_REGISTRY",
                          rf"{__values__['REGISTRY_PATH']}\rsa_modulo")
    __values__.setdefault("RSA_PUBLIC_REGISTRY",
                          rf"{__values__['REGISTRY_PATH']}\rsa_public")
    __values__.setdefault("RSA_PRIVATE_REGISTRY",
                          rf"{__values__['REGISTRY_PATH']}\rsa_private")
    __values__.setdefault("UPDATE_MAJOR_REGISTRY",
                          rf"{__values__['REGISTRY_PATH']}\update_major")
    __values__.setdefault("UPDATE_MINOR_REGISTRY",
                          rf"{__values__['REGISTRY_PATH']}\update_minor")
    __values__.setdefault("VERSION_MAJOR_REGISTRY",
                          rf"{__values__['REGISTRY_PATH']}\version_major")
    __values__.setdefault("VERSION_MINOR_REGISTRY",
                          rf"{__values__['REGISTRY_PATH']}\version_minor")
    __values__.setdefault("ADDRESS_ID_REGISTRY",
                          rf"{__values__['REGISTRY_PATH']}\address_id")
    __values__.setdefault("UPDATE_REGISTRY_FORMAT",
                          rf"{__values__['REGISTRY_PATH']}\Update_{{}}")

    # Saves the settings, if they should be saved
    if save:
        save_settings()
Example #8
0
 def init_registry():
     if not registry.exists(settings.REGISTRY_PATH):
         registry.create_key(settings.REGISTRY_PATH)
     if not registry.exists(settings.AUTO_INSTALLATIONS_REGISTRY):
         registry.set_value(settings.AUTO_INSTALLATIONS_REGISTRY,
                            settings.AUTO_INSTALLATIONS)
     if not registry.exists(settings.UPDATING_SERVER_REGISTRY):
         registry.set_value(settings.UPDATING_SERVER_REGISTRY,
                            settings.UPDATING_SERVER)
     if not registry.exists(settings.PORT_REGISTRY):
         registry.set_value(settings.PORT_REGISTRY, settings.PORT)
     if not registry.exists(settings.RSA_MODULO_REGISTRY):
         registry.set_value(settings.RSA_MODULO_REGISTRY,
                            settings.RSA_MODULO)
     if not registry.exists(settings.RSA_PUBLIC_REGISTRY):
         registry.set_value(settings.RSA_PUBLIC_REGISTRY,
                            settings.PUBLIC_KEY)
     if not registry.exists(settings.UPDATE_MAJOR_REGISTRY):
         registry.set_value(settings.UPDATE_MAJOR_REGISTRY,
                            settings.UPDATE_MAJOR)
     if not registry.exists(settings.UPDATE_MINOR_REGISTRY):
         registry.set_value(settings.UPDATE_MINOR_REGISTRY,
                            settings.UPDATE_MINOR)
     if not registry.exists(settings.VERSION_MAJOR_REGISTRY):
         registry.set_value(settings.VERSION_MAJOR_REGISTRY,
                            settings.VERSION_MAJOR)
     if not registry.exists(settings.VERSION_MINOR_REGISTRY):
         registry.set_value(settings.VERSION_MINOR_REGISTRY,
                            settings.VERSION_MINOR)
     if not registry.exists(settings.ADDRESS_ID_REGISTRY):
         registry.set_value(settings.ADDRESS_ID_REGISTRY,
                            settings.ADDRESS_ID)
     if not registry.exists(settings.SETTINGS_REGISTRY):
         registry.set_value(settings.SETTINGS_REGISTRY,
                            settings.SETTINGS_PATH)
Example #9
0
    def send_version_update(message, requester):
        if len(message) != messages.REQUEST_VERSION_MESSAGE.sizeof():
            # The message has an incorrect size...
            logging.warning(f"Incorrect message size: {len(message)}")
            return

        # Parse the message
        try:
            message = messages.REQUEST_VERSION_MESSAGE.parse(message)
        except construct.ConstructError:
            # Should never occur
            logging.critical(
                f"Failed to parse request update message: {message.hex()}",
                exc_info=True)
            return

        # Check if the version file exists
        requested_version = Version(message.major, message.minor)
        version_registry = requested_version.get_update_registry_path()
        if not registry.exists(version_registry):
            # Version not exists... abort
            logging.info(
                f"Version {requested_version} was requested but wasn't found in the registry"
            )
            return

        # Retrieve the update filepath
        version_filepath = registry.get_value(version_registry)
        try:
            update_file = open(version_filepath, "rb")
        except OSError:
            logging.error(f"Unable to open version file: {version_filepath}",
                          exc_info=True)
            return

        logging.info(f"Sending update of version {requested_version}")
        sender = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        try:
            # Connect to the TCP server of the receiver
            sender.settimeout(settings.CONNECTION_TIMEOUT)
            sender.connect((requester[0], message.listening_port))

            # Send the update file
            with update_file:
                chunk = update_file.read(settings.VERSION_CHUNK_SIZE)
                while len(chunk) != 0:
                    sender.send(chunk)
                    chunk = update_file.read(settings.VERSION_CHUNK_SIZE)

            logging.info(
                f"Finished sending update of version {requested_version}")

        except socket.timeout:
            # Connection was timed-out, too bad... abort
            logging.info("Connection timed out")
        except socket.error:
            # Socket error
            logging.info("Socket error has occurred")
        finally:
            sender.shutdown(socket.SHUT_WR)
            sender.close()
Example #10
0
 def is_server():
     # The updater can be run as an official updates server
     # An update server is distinguished from a normal client only by the
     # fact that it knows the private RSA key
     return registry.exists(settings.RSA_PRIVATE_REGISTRY)