Пример #1
0
def initialize_upnp(svcs):
    """
    Initialize uPnP port forwarding with the IGD.

    :param SecurityPolicy svcs: SecurityPolicies to open
    """
    upnpc = _upnp_igd_connect()
    if not upnpc:
        return
    for svc in svcs:
        if svc.policy != 2:
            continue
        for protocol, port in svc.ports:
            if upnpc.getspecificportmapping(port, protocol.upper()):
                try:
                    upnpc.deleteportmapping(port, protocol.upper())
                except:
                    pass
            try:
                pf = 'arkOS Port Forwarding: {0}'
                upnpc.addportmapping(port, protocol.upper(), upnpc.lanaddr,
                                     port, pf.format(port), '')
            except Exception as e:
                msg = "Failed to register {0} with uPnP IGD: {1}"\
                    .format(port, str(e))
                logger.warning("TrSv", msg)
Пример #2
0
def create_token(user):
    """
    Create a JSON Web Token (JWT) for the specified user.

    :param User user: an arkOS user
    :returns: JSON Web Token (JWT)
    :rtype: str
    """
    iat = systemtime.get_unix_time()
    try:
        offset = systemtime.get_offset()
        if offset < -3600 or offset > 3600:
            systemtime.set_datetime()
            iat = systemtime.get_unix_time()
    except:
        twarn = ("System time is not accurate or could not be verified."
                 " Access tokens will not expire.")
        logger.warning("System", twarn)
        iat = None
    payload = {
        "uid": user.name,
        "ufn": user.first_name,
        "uln": user.last_name,
    }
    if iat:
        payload["iat"] = iat
        payload["exp"] = iat + config.get("genesis", "token_valid_for", 3600)
    tjwss = TimedJSONWebSignatureSerializer(
        secret_key=current_app.config["SECRET_KEY"],
        expires_in=config.get("genesis", "token_valid_for", 3600),
        algorithm_name="HS256")
    return tjwss.dumps(payload).decode("utf-8")
Пример #3
0
def _upnp_igd_connect():
    logger.debug("TrSv", "Attempting to connect to uPnP IGD")
    upnpc = miniupnpc.UPnP()
    upnpc.discoverdelay = 3000
    devs = upnpc.discover()
    if devs == 0:
        msg = "Failed to connect to uPnP IGD: no devices found"
        logger.warning("TrSv", msg)
        return
    try:
        upnpc.selectigd()
    except Exception as e:
        msg = "Failed to connect to uPnP IGD: {0}"
        logger.warning("TrSv", msg.format(str(e)))
    return upnpc
Пример #4
0
def scan_shares():
    """
    Retrieve a list of all file shares registered with arkOS.

    :return: Share(s)
    :rtype: Share or list thereof
    """
    storage.shares.clear()
    for x in get_sharers():
        try:
            for y in x.get_shares():
                storage.shares[y.id] = y
        except Exception as e:
            logger.warning("Sharers",
                           "Could not get shares for {0}".format(x.name))
            logger.debug("Sharers", str(e))
    return storage.shares
Пример #5
0
def _install(id, load=True, cry=True):
    """
    Utility function to download and install arkOS app packages.

    :param str id: ID of arkOS app to install
    :param bool load: Load the app after install?
    :param bool cry: Raise exception on dependency install failure?
    """
    app_dir = config.get("apps", "app_dir")
    # Download and extract the app source package
    api_url = "https://{0}/api/v1/apps/{1}"
    data = api(api_url.format(config.get("general", "repo_server"), id),
               returns="raw", crit=True)
    path = os.path.join(app_dir, "{0}.tar.gz".format(id))
    with open(path, "wb") as f:
        f.write(data)
    with tarfile.open(path, "r:gz") as t:
        t.extractall(app_dir)
    os.unlink(path)
    # Read the app's metadata and create an object
    with open(os.path.join(app_dir, id, "manifest.json")) as f:
        data = json.loads(f.read())
    app = get(id)
    for x in data:
        setattr(app, x, data[x])
    app.upgradable = ""
    app.installed = True
    for x in app.services:
        if x.get("type") == "system" and x.get("binary") \
                and not x.get("ignore_on_install"):
            s = services.get(x["binary"])
            if s:
                s.enable()
                if s.state != "running":
                    try:
                        s.start()
                    except services.ActionError as e:
                        logger.warning(
                            "Apps", "{0} could not be automatically started."
                            .format(s.name))
    if load:
        app.load(cry=cry)
Пример #6
0
def run_daemon(environment, config_file, secrets_file,
               policies_file, debug):
    """Run the Kraken server daemon."""
    app.debug = debug or environment in ["dev", "vagrant"]
    app.config["SECRET_KEY"] = random_string()

    # Open and load configuraton
    config = arkos.init(config_file, secrets_file, policies_file,
                        app.debug, environment in ["dev", "vagrant"],
                        app.logger)
    storage.connect()

    if environment not in ["dev", "vagrant"]:
        filehdlr = RotatingFileHandler(
            '/var/log/kraken.log', maxBytes=2097152, backupCount=5
        )
        st = "{asctime} [{cls}] [{levelname}] {comp}: {message}"
        filehdlr.setLevel(logging.DEBUG if app.debug else logging.INFO)
        filehdlr.setFormatter(FileFormatter(st))
        logger.logger.addHandler(filehdlr)

    apihdlr = APIHandler()
    apihdlr.setLevel(logging.DEBUG if app.debug else logging.INFO)
    apihdlr.addFilter(NotificationFilter())
    logger.logger.addHandler(apihdlr)

    logger.info("Init", "arkOS Kraken {0}".format(arkos.version))
    if environment in ["dev", "vagrant"]:
        logger.debug("Init", "*** TEST MODE ***")
    logger.info("Init", "Using config file at {0}".format(config.filename))
    app.conf = config

    arch = config.get("enviro", "arch", "Unknown")
    board = config.get("enviro", "board", "Unknown")
    platform = detect_platform()
    hwstr = "Detected architecture/hardware: {0}, {1}"
    logger.info("Init", hwstr.format(arch, board))
    logger.info("Init", "Detected platform: {0}".format(platform))
    logger.info("Init", "Environment: {0}".format(environment))
    config.set("enviro", "run", environment)

    for code in list(default_exceptions.keys()):
        app.register_error_handler(code, make_json_error)

    app.register_blueprint(auth.backend)

    logger.info("Init", "Loading applications and scanning system...")
    arkos.initial_scans()

    # Load framework blueprints
    logger.info("Init", "Loading frameworks...")
    register_frameworks(app)

    logger.info("Init", "Initializing Genesis (if present)...")
    app.register_blueprint(genesis.backend)
    hasgen = genesis.verify_genesis()
    if not hasgen:
        errmsg = ("A compiled distribution of Genesis was not found. "
                  "Kraken will finish loading but you may not be able to "
                  "access the Web interface.")
        logger.warning("Init", errmsg)

    app.after_request(add_cors_to_response)
    logger.info("Init", "Server is up and ready")
    try:
        import eventlet
        pubsub = storage.redis.pubsub(ignore_subscribe_messages=True)
        pubsub.subscribe(["arkos:notifications", "arkos:records:push",
                          "arkos:records:purge"])
        eventlet.spawn(handle_pubsub, pubsub, socketio)
        eventlet_socket = eventlet.listen(
            (config.get("genesis", "host"), config.get("genesis", "port"))
        )
        if config.get("genesis", "ssl", False):
            eventlet_socket = eventlet.wrap_ssl(
                eventlet_socket, certfile=config.get("genesis", "cert_file"),
                keyfile=config.get("genesis", "cert_key"),
                ssl_version=ssl.PROTOCOL_TLSv1_2, server_side=True)
        eventlet.wsgi.server(
            eventlet_socket, app, log=WSGILogWrapper(),
            log_format=('%(client_ip)s - "%(request_line)s" %(status_code)s '
                        '%(body_length)s %(wall_seconds).6f'))
    except KeyboardInterrupt:
        logger.info("Init", "Received interrupt")
        raise
Пример #7
0
def scan(verify=True, cry=True):
    """
    Search app directory for applications, load them and store metadata.

    Also contacts arkOS repo servers to obtain current list of available
    apps, and merges in any updates as necessary.

    :param bool verify: Verify app dependencies as the apps are scanned
    :param bool cry: Raise exception on dependency install failure?
    :return: list of Application objects
    :rtype: list
    """
    signals.emit("apps", "pre_scan")
    logger.debug("Apps", "Scanning for applications")
    app_dir = config.get("apps", "app_dir")
    if not os.path.exists(app_dir):
        os.makedirs(app_dir)

    pacman.refresh()
    logger.debug("Apps", "Getting system/python/ruby installed list")
    inst_list = {
        "sys": pacman.get_installed(),
        "py": python.get_installed(),
        "py2": python.get_installed(py2=True),
        "rb": ruby.get_installed()
    }

    # Get paths for installed apps, metadata for available ones
    installed_apps = [x for x in os.listdir(app_dir) if not x.startswith(".")]
    api_url = ("https://{0}/api/v1/apps"
               .format(config.get("general", "repo_server")))
    logger.debug("Apps", "Fetching available apps: {0}".format(api_url))
    try:
        available_apps = api(api_url)
    except Exception as e:
        available_apps = []
        logger.error("Apps", "Could not get available apps from GRM.")
        logger.error("Apps", str(e))
    if available_apps:
        available_apps = available_apps["applications"]
    else:
        available_apps = []

    # Create objects for installed apps with appropriate metadata
    for x in installed_apps:
        try:
            with open(os.path.join(app_dir, x, "manifest.json"), "r") as f:
                data = json.loads(f.read())
        except ValueError:
            warn_str = "Failed to load {0} due to a JSON parsing error"
            logger.warning("Apps", warn_str.format(x))
            continue
        except IOError:
            warn_str = "Failed to load {0}: manifest file inaccessible "\
                       "or not present"
            logger.warning("Apps", warn_str.format(x))
            continue
        logger.debug("Apps", " *** Loading {0}".format(data["id"]))
        app = App(**data)
        app.installed = True
        for y in enumerate(available_apps):
            if app.id == y[1]["id"] and app.version != y[1]["version"]:
                app.upgradable = y[1]["version"]
            if app.id == y[1]["id"]:
                app.assets = y[1]["assets"]
                available_apps[y[0]]["installed"] = True
        app.load(verify=verify, cry=cry, installed=inst_list)
        storage.applications[app.id] = app

    # Convert available apps payload to objects
    for x in available_apps:
        if not x.get("installed"):
            app = App(**x)
            app.installed = False
            storage.applications[app.id] = app

    if verify:
        verify_app_dependencies()
    signals.emit("apps", "post_scan")
    return storage.applications