Example #1
0
def regenerate_firewall(data, range=[]):
    """
    Flush and regenerate arkOS firewall chain.

    If ``range`` is not specified, network module will guess what they are.

    :param SecurityPolicy data: Security policies to enact
    :param list range: Range(s) of local network(s) ('192.168.0.0/24')
    """
    signals.emit("security", "pre_fw_regen")
    flush_chain("arkos-apps")
    default_range = range or network.get_active_ranges()
    # For each policy in the system, add a rule
    for x in data:
        range = getattr(x, "allowed_ranges", default_range)
        for port in x.ports:
            if x.policy == 2:
                add_rule("ACCEPT", port[0], port[1], ["anywhere"])
            elif x.policy == 1:
                add_rule("ACCEPT", port[0], port[1], range)
            else:
                add_rule("REJECT", port[0], port[1])
    shell("iptables -A arkos-apps -j RETURN")
    save_rules()
    signals.emit("security", "post_fw_regen")
Example #2
0
File: groups.py Project: ns408/core
 def add(self):
     """Add group."""
     shell("groupadd {0}".format(self.name))
     self.update()
     for x in grp.getgrall():
         if x.gr_name == self.name:
             self.gid = x.gr_gid
 def post_install(self, name, path, vars, dbinfo={}):
     # UPDATE: Config DB info and enable modules
     index_php = os.path.join(path, 'index.php')
     os.remove(index_php)
     with open(index_php, "w") as f:
         f.write(switching_index)  # see below
     shell('chown -R http ' + path)
Example #4
0
 def post_install(self, name, path, vars, dbinfo={}):
     # UPDATE: Config DB info and enable modules
     index_php = os.path.join(path, 'index.php')
     os.remove(index_php)
     with open(index_php, "w") as f:
         f.write(switching_index)  # see below
     shell('chown -R http ' + path)
Example #5
0
    def update_password(self, passwd):
        """
        Set password.

        :param str passwd: password to set
        """
        shell("passwd {0}".format(self.name),
              stdin="{0}\n{1}\n".format(passwd, passwd))
Example #6
0
def firstrun():
    data = request.get_json()
    resize_boards = [
        "Raspberry Pi", "Raspberry Pi 2", "Raspberry Pi 3", "Cubieboard2",
        "Cubietruck", "BeagleBone Black", "ODROID-U"
    ]
    if data.get("resize_sd_card", None)\
            and config.get("enviro", "board") in resize_boards:
        part = 1 if config.get("enviro", "board").startswith("Cubie") else 2
        p1str = 'd\nn\np\n1\n\n\nw\n'
        p2str = 'd\n2\nn\np\n2\n\n\nw\n'
        shell('fdisk /dev/mmcblk0', stdin=(p1str if part == 1 else p2str))
        if not os.path.exists('/etc/cron.d'):
            os.mkdir('/etc/cron.d')
        with open('/etc/cron.d/resize', 'w') as f:
            f.write('@reboot root e2fsck -fy /dev/mmcblk0p{0}\n'.format(part))
            f.write('@reboot root resize2fs /dev/mmcblk0p{0}\n'.format(part))
            f.write('@reboot root rm /etc/cron.d/resize\n')
            f.close()
    if data.get("use_gpu_mem", None) \
            and config.get("enviro", "board").startswith("Raspberry"):
        f = filesystems.get("mmcblk0p1")
        if not f.is_mounted:
            f.mountpoint = "/boot"
            f.mount()
        cfgdata = []
        if os.path.exists('/boot/config.txt'):
            with open("/boot/config.txt", "r") as f:
                for x in f.readlines():
                    if x.startswith("gpu_mem"):
                        x = "gpu_mem=16\n"
                    cfgdata.append(x)
                if "gpu_mem=16\n" not in cfgdata:
                    cfgdata.append("gpu_mem=16\n")
            with open("/boot/config.txt", "w") as f:
                f.writelines(cfgdata)
        else:
            with open("/boot/config.txt", "w") as f:
                f.write("gpu_mem=16\n")
    if data.get("cubie_mac", None) \
            and config.get("enviro", "board").startswith("Cubie"):
        if config.get("enviro", "board") == "Cubieboard2":
            with open('/boot/uEnv.txt', 'w') as f:
                opt_str = 'extraargs=mac_addr={0}\n'
                f.write(opt_str.format(data.get("cubie_mac")))
        elif config.get("enviro", "board") == "Cubietruck":
            with open('/etc/modprobe.d/gmac.conf', 'w') as f:
                opt_str = 'options sunxi_gmac mac_str="{0}"\n'
                f.write(opt_str.format(data.get("cubie_mac")))
    if data.get("install"):
        as_job(install, data["install"])
    rootpwd = ""
    if data.get("protectRoot"):
        rootpwd = random_string(16)
        shell("passwd root", stdin="{0}\n{0}\n".format(rootpwd))
    security.initialize_firewall()
    return jsonify(rootpwd=rootpwd)
Example #7
0
def update_gem(*gems, **kwargs):
    # Updates a set of presently-installed Ruby gems.
    verify_path()
    gemlist = shell("gem list")["stdout"].split("\n")
    for x in gems:
        if not any(x==s for s in gemlist) or force:
            d = shell("gem update -N --no-user-install %s" % x)
            if d["code"] != 0:
                logger.error("Gem update '%s' failed: %s"%(x,str(d["stderr"])))
                raise Exception("Gem update '%s' failed. See logs for more info"%x)
Example #8
0
File: php.py Project: kidaa/arkos
def composer_install(path):
    # Install a PHP application bundle via Composer.
    verify_composer()
    cwd = os.getcwd()
    os.chdir(path)
    shell("composer self-update")
    s = shell("composer install")
    os.chdir(cwd)
    if s["code"] != 0:
        raise Exception("Composer failed to install this app's bundle. Error: %s"%str(s["stderr"]))
Example #9
0
def install_gem(*gems, **kwargs):
    # Installs a set of Ruby gems to the system.
    verify_path()
    gemlist = shell("gem list")["stdout"].split("\n")
    for x in gems:
        if not any(x==s for s in gemlist) or force:
            d = shell("gem install -N --no-user-install %s" % x)
            if d["code"] != 0:
                logger.error("Gem install '%s' failed: %s"%(x,str(d["stderr"])))
                raise Exception("Gem install '%s' failed. See logs for more info"%x)
Example #10
0
    def post_install(self, extra_vars, dbpasswd=""):
        # Get around top-level zip restriction (FIXME 0.7.2)
        if "paperwork-master" in os.listdir(self.path):
            tmp_path = os.path.abspath(os.path.join(self.path, "../pwrk-tmp"))
            os.rename(os.path.join(self.path, "paperwork-master/frontend"),
                      tmp_path)
            os.rename(os.path.join(self.path, ".arkos"),
                      os.path.join(tmp_path, ".arkos"))
            shutil.rmtree(self.path)
            os.rename(tmp_path, self.path)

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('gd', 'opcache', 'mysql', 'pdo_mysql', 'mcrypt')
        php.enable_mod('apcu', config_file="/etc/php/conf.d/apcu.ini")

        dbstr = "mysql, localhost, 3389, {0}, {1}, {0}"\
            .format(self.id, dbpasswd)
        with open(os.path.join(self.path, 'app/storage/db_settings'),
                  'w') as f:
            f.write(dbstr)

        php.composer_install(self.path)
        nodejs.install("gulp", as_global=True)
        nodejs.install_from_package(self.path, stat=None)

        cwd = os.getcwd()
        os.chdir(self.path)
        s = shell("bower install --allow-root", stdin='y\n')
        if s["code"] != 0:
            raise Exception("Failed to run bower: {0}".format(s["stderr"]))
        s = shell("gulp")
        if s["code"] != 0:
            raise Exception("Failed to run gulp: {0}".format(s["stderr"]))
        s = shell("php artisan migrate --force")
        if s["code"] != 0:
            raise Exception("Failed to run artisan: {0}".format(s["stderr"]))
        os.chdir(cwd)

        # Make sure the webapps config points to the public directory.
        c = nginx.loadf(os.path.join('/etc/nginx/sites-available', self.id))
        for x in c.servers:
            if x.filter('Key', 'root'):
                x.filter('Key', 'root')[0].value = \
                    os.path.join(self.path, 'public')
        nginx.dumpf(c, os.path.join('/etc/nginx/sites-available', self.id))
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        for r, d, f in os.walk(os.path.join(self.path, 'app')):
            for x in d:
                os.chmod(os.path.join(r, x), 0o755)
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chmod(os.path.join(r, x), 0o644)
                os.chown(os.path.join(r, x), uid, gid)
        if os.path.exists(os.path.join(self.path, 'app/storage/setup')):
            os.unlink(os.path.join(self.path, 'app/storage/setup'))
 def update(self, pkg, ver):
     # General update procedure
     shell('unzip -o -d %s %s' % (self.path, pkg))
     uid = users.get_system("ghost").uid
     for r, d, f in os.walk(self.path):
         for x in d:
             os.chown(os.path.join(r, x), uid, -1)
         for x in f:
             os.chown(os.path.join(r, x), uid, -1)
     nodejs.install_from_package(self.path, 'production', {'sqlite': '/usr/bin/sqlite3', 'python': '/usr/bin/python2'})
     services.get(self.id).restart()
Example #12
0
 def remove_share(self):
     """Remove a share."""
     with open("/etc/exports", "r") as f:
         data = f.readlines()
     for i, x in enumerate(data):
         if x.startswith('#'):
             continue
         if shlex.split(x)[0] == self.path:
             data.pop(i)
     with open("/etc/exports", "w") as f:
         f.writelines(data)
     shell("exportfs -arv")
Example #13
0
    def post_install(self, vars, dbpasswd=""):
        # Get around top-level zip restriction (FIXME 0.7.2)
        if "paperwork-master" in os.listdir(self.path):
            tmp_path = os.path.abspath(os.path.join(self.path, "../pwrk-tmp"))
            os.rename(os.path.join(self.path, "paperwork-master/frontend"), tmp_path)
            os.rename(os.path.join(self.path, ".arkos"),
                      os.path.join(tmp_path, ".arkos"))
            shutil.rmtree(self.path)
            os.rename(tmp_path, self.path)

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('gd', 'opcache', 'mysql', 'pdo_mysql', 'mcrypt')
        php.enable_mod('apcu', config_file="/etc/php/conf.d/apcu.ini")

        dbstr = "mysql, localhost, 3389, {0}, {1}, {0}".format(self.id, dbpasswd)
        with open(os.path.join(self.path, 'app/storage/db_settings'), 'w') as f:
            f.write(dbstr)

        php.composer_install(self.path)
        nodejs.install("gulp", as_global=True)
        nodejs.install_from_package(self.path, stat=None)

        cwd = os.getcwd()
        os.chdir(self.path)
        s = shell("bower install --allow-root", stdin='y\n')
        if s["code"] != 0:
            raise Exception("Failed to run bower: %s" % s["stderr"])
        s = shell("gulp")
        if s["code"] != 0:
            raise Exception("Failed to run gulp: %s" % s["stderr"])
        s = shell("php artisan migrate --force")
        if s["code"] != 0:
            raise Exception("Failed to run artisan: %s" % s["stderr"])
        os.chdir(cwd)

        # Make sure the webapps config points to the public directory.
        c = nginx.loadf(os.path.join('/etc/nginx/sites-available', self.id))
        for x in c.servers:
            if x.filter('Key', 'root'):
                x.filter('Key', 'root')[0].value = os.path.join(self.path, 'public')
        nginx.dumpf(c, os.path.join('/etc/nginx/sites-available', self.id))
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        for r, d, f in os.walk(os.path.join(self.path, 'app')):
            for x in d:
                os.chmod(os.path.join(r, x), 0755)
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chmod(os.path.join(r, x), 0644)
                os.chown(os.path.join(r, x), uid, gid)
        if os.path.exists(os.path.join(self.path, 'app/storage/setup')):
            os.unlink(os.path.join(self.path, 'app/storage/setup'))
Example #14
0
 def update(self, pkg, ver):
     # General update procedure
     shell('unzip -o -d {0} {1}'.format(self.path, pkg))
     uid = users.get_system("ghost").uid
     for r, d, f in os.walk(self.path):
         for x in d:
             os.chown(os.path.join(r, x), uid, -1)
         for x in f:
             os.chown(os.path.join(r, x), uid, -1)
     nodejs.install_from_package(self.path, 'production', {
         'sqlite': '/usr/bin/sqlite3',
         'python': '/usr/bin/python2'
     })
     services.get(self.id).restart()
Example #15
0
 def update_site(self, pkg, ver):
     cwd = os.getcwd()
     os.chdir(self.path)
     s = shell("bin/gpm selfupgrade -f")
     if s["code"] != 0:
         logger.error(
             "Webs", "Grav failed to run selfupgrade. Error: {0}".format(
                 s["stderr"].decode()))
     s = shell("bin/gpm update -f")
     if s["code"] != 0:
         logger.error(
             "Webs", "Grav failed to run plugin update. Error: {0}".format(
                 s["stderr"].decode()))
     os.chdir(cwd)
Example #16
0
def add_rule(opt, protocol, port, ranges=[]):
    # Add rule for this port
    # If range is not provided, assume "0.0.0.0"
    cmd = "iptables -I arkos-apps {src} -p {ptc} -m {ptc} --dport {prt} -j {opt}"
    src = ""
    for x in [r for r in ranges if r not in ["", "anywhere", "0.0.0.0"]]:
        src = "-s " if not src else (src + ",")
        ip, cidr = x.split("/")
        mask = cidr_to_netmask(int(cidr))
        src += ip + "/" + mask
    s = shell(cmd.format(src=src, ptc=protocol, prt=port, opt=opt))
    if s["code"] != 0 and "No chain/target/match by that name" in s["stderr"]:
        # Create chain if not exists
        shell("iptables -N arkos-apps")
        shell(cmd.format(src=src, ptc=protocol, prt=port, opt=opt))
Example #17
0
def make_json_error(err):
    """Prepare a standardized error report."""
    if hasattr(err, "description"):
        message = err.description
    else:
        message = str(err)
    if (isinstance(err, HTTPException) and err.code == 500)\
            or not isinstance(err, HTTPException):
        pyver = [str(x) for x in platform.python_version_tuple()]
        apps = arkos_storage.applications.values()
        apps = [x.id for x in apps if x.installed]
        stacktrace = traceback.format_exc()
        report = "arkOS {0} Crash Report\n".format(version)
        report += "--------------------\n\n"
        report += "Running in {0}\n".format(config.get("enviro", "run"))
        report += "System: {0}\n".format(shell("uname -a")["stdout"].decode())
        report += "Platform: {0} {1}\n".format(config.get("enviro", "arch"),
                                               config.get("enviro", "board"))
        report += "Python version {0}\n".format('.'.join(pyver))
        report += "Config path: {0}\n\n".format(config.filename)
        report += "Loaded applicatons: \n{0}\n\n".format("\n".join(apps))
        report += "Request: {0} {1}\n\n".format(request.method, request.path)
        report += stacktrace
        response = jsonify(errors={"msg": message, "stack": stacktrace,
                           "report": report, "version": version,
                           "arch": config.get("enviro", "arch")})
        logger.critical("Unknown", stacktrace)
    else:
        response = jsonify(errors={"msg": message})
    response.status_code = err.code if isinstance(err, HTTPException) else 500
    return add_cors_to_response(response)
Example #18
0
 def create(self, mount=False):
     vdisk_dir = config.get("filesystems", "vdisk_dir")
     if not os.path.exists(os.path.join(config.get("filesystems", "vdisk_dir"))):
         os.mkdir(os.path.join(config.get("filesystems", "vdisk_dir")))
     self.path = str(os.path.join(vdisk_dir, self.id+".img"))
     if os.path.exists(self.path):
         raise Exception("This virtual disk already exists")
     signals.emit("filesystems", "pre_add", self)
     # Create an empty file matching disk size
     with open(self.path, "wb") as f:
         written = 0
         with file("/dev/zero", "r") as zero:
             while self.size > written:
                 written += 1024
                 f.write(zero.read(1024))
     # Get a free loopback device and mount
     loop = losetup.find_unused_loop_device()
     loop.mount(str(self.path), offset=1048576)
     # Make a filesystem
     s = shell("mkfs.ext4 %s" % loop.device)
     if s["code"] != 0:
         raise Exception("Failed to format loop device: %s" % s["stderr"])
     loop.unmount()
     signals.emit("filesystems", "pre_add", self)
     if mount:
         self.mount()
Example #19
0
File: nodejs.py Project: ns408/core
def install(*mods, **kwargs):
    """
    Install a set of NPM packages.

    Include ``as_global`` in kwargs to install package as global.

    :param *mods: Packages to install
    :param **kwargs: Extra keyword arguments to pass to NPM
    """
    as_global = "-g " if kwargs.get("as_global") else ""
    mods = " ".join(x for x in mods)
    opt_str = ""
    if kwargs.get("opts"):
        opt_str += " --"
    for k, v in kwargs.get("opts", {}):
        opt_str += " --".join(k + v if v[0] == '=' else k + " " + v)
    cwd = os.getcwd()
    if "install_path" in kwargs:
        os.chdir(kwargs["install_path"])
    s = shell("npm install {0}{1}{2}".format(
        as_global,
        mods,
    ))
    os.chdir(cwd)
    if s["code"] != 0:
        errmsg = "NPM install of {0} failed.".format(mods)
        logmsg = "NPM install failure details:\n{0}"
        logger.error("NodeJS", logmsg.format(s["stderr"].decode()))
        raise errors.OperationFailedError(errmsg)
Example #20
0
 def encrypt(self, passwd, cipher="", keysize=0, mount=False):
     cipher = cipher or config.get("filesystems", "cipher") or "aes-xts-plain64"
     keysize = keysize or config.get("filesystems", "keysize") or 256
     os.rename(self.path, os.path.join(config.get("filesystems", "vdisk_dir"), self.id+".crypt"))
     self.path = os.path.join(config.get("filesystems", "vdisk_dir"), self.id+".crypt")
     # Find an open loopback device and mount
     loop = losetup.find_unused_loop_device()
     loop.mount(str(self.path), offset=1048576)
     # Encrypt the file inside the loopback and mount
     s = crypto.luks_format(loop.device, passwd, cipher, int(keysize))
     if s != 0:
         loop.unmount()
         os.rename(self.path, os.path.join(config.get("filesystems", "vdisk_dir"), self.id+".img"))
         raise Exception("Failed to encrypt %s with errno %s"%(self.id, str(s)))
     s = crypto.luks_open(loop.device, self.id, passwd)
     if s != 0:
         loop.unmount()
         raise Exception("Failed to decrypt %s with errno %s"%(self.id, str(s)))
     # Create a filesystem inside the encrypted device
     s = shell("mkfs.ext4 /dev/mapper/%s" % self.id)
     crypto.luks_close(self.id)
     loop.unmount()
     if s["code"] != 0:
         raise Exception("Failed to format loop device: %s" % s["stderr"])
     self.crypt = True
     if mount:
         self.mount(passwd)
Example #21
0
def get_connections(id=None, iface=None):
    """
    Get list of network connections.

    :param str id: Filter by network connection name
    :param str iface: Filter by network interface name
    :returns: Connection(s)
    :rtype: Connection or list thereof
    """
    conns = []
    netctl = shell("netctl list")
    for line in netctl["stdout"].split(b"\n"):
        if not line.split():
            continue
        svc = "/etc/systemd/system/multi-user.target.wants/netctl@{0}.service"
        enabled = os.path.exists(svc.format(line[2:]))
        c = Connection(line[2:].decode(), line.startswith(b"*"), enabled)
        with open(os.path.join("/etc/netctl", c.id), "r") as f:
            data = f.readlines()
        for x in data:
            if x.startswith("#") or not x.strip():
                continue
            parse = x.split("=")
            to_trans = dict.fromkeys(map(ord, "()\"\"\n"), None)
            c.config[parse[0].lower()] = parse[1].translate(to_trans)
        if id == c.id:
            return c
        if not iface or c.config.get("interface") == iface:
            conns.append(c)
    return conns if not id else None
Example #22
0
def install_updates(message=DefaultMessage()):
    updates = storage.updates.get("updates")
    if not updates:
        return
    signals.emit("updates", "pre_install")
    amount = len(updates)
    responses, ids = [], []
    for z in enumerate(updates):
        message.update("info", "%s of %s..." % (z[0]+1, amount), head="Installing updates")
        for x in sorted(z[1]["tasks"], key=lambda y: y["step"]):
            getout = False
            if x["unit"] == "shell":
                s = shell(x["order"], stdin=x.get("data", None))
                if s["code"] != 0:
                    responses.append((x["step"], s["stderr"]))
                    getout = True
                    break
            elif x["unit"] == "fetch":
                try:
                    download(x["order"], x["data"], True)
                except Exception, e:
                    code = 1
                    if hasattr(e, "code"):
                        code = e.code
                    responses.append((x["step"], str(code)))
                    getout = True
                    break
        else:
            ids.append(z[1]["id"])
            config.set("updates", "current_update", z[1]["id"])
            config.save()
            continue
        message.complete("error", "Installation of update %s failed. See logs for details." % str(z[1]["id"]))
        print responses
        break
Example #23
0
 def get_log(self):
     if self.stype == "supervisor":
         supervisor_ping()
         s = conns.Supervisor.tailProcessStdoutLog(self.name)
     else:
         s = shell("systemctl --no-ask-password status {}.service".format(self.name))["stdout"]
     return s
Example #24
0
 def add_share(self):
     """Add a share."""
     with open("/etc/exports", "r") as f:
         data = f.readlines()
     if any([shlex.split(x)[0] == self.path for x in data]):
         raise errors.InvalidConfigError(
             "Share already present with this path"
         )
     if not os.path.exists(self.path):
         os.makedirs(self.path)
     sstr = '"' + self.path + '" '
     sstr += '*(' + ("ro" if self.readonly else "rw") + ',sync)'
     with open("/etc/exports", "w") as f:
         f.writelines(data)
         f.write(sstr + '\n')
     shell("exportfs -arv")
Example #25
0
def is_installed(name):
    # Returns a list of installed Python packages.
    s = shell("pip2 freeze")
    for x in s["stdout"].split("\n"):
        if name.lower() in x.split("==")[0].lower():
            return True
    return False
Example #26
0
    def post_install(self, extra_vars, dbpasswd=""):

        # Make sure the webapps config points to
        # the _site directory and generate it.
        c = nginx.loadf(os.path.join('/etc/nginx/sites-available', self.id))
        for x in c.servers:
            if x.filter('Key', 'root'):
                x.filter('Key', 'root')[0].value = \
                    os.path.join(self.path, '_site')
        nginx.dumpf(c, os.path.join('/etc/nginx/sites-available', self.id))
        s = shell('jekyll build --source {0} --destination {1}'.format(
            self.path, os.path.join(self.path, '_site')))
        if s["code"] != 0:
            raise errors.OperationFailedError(
                'Jekyll failed to build: {0}'.format(str(s["stderr"])))
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chmod(os.path.join(r, x), 0o755)
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chmod(os.path.join(r, x), 0o644)
                os.chown(os.path.join(r, x), uid, gid)

        # Return an explicatory message.
        return 'Jekyll has been setup, with a sample site at {0}. '\
            'Modify these files as you like. To learn how to use Jekyll, '\
            'visit http://jekyllrb.com/docs/usage. After making changes, '\
            'click the site icon to edit, then "Regenerate Site" '\
            'to bring your changes live.'.format(self.path)
Example #27
0
 def disable(self):
     """Disable connection on boot."""
     s = shell("netctl disable {0}".format(self.id))
     if s["code"] == 0:
         self.enabled = False
     else:
         raise errors.OperationFailedError("Network disable failed")
Example #28
0
    def post_install(self, extra_vars, dbpasswd=""):
        secret_key = random_string()
        dbengine = 'mysql' \
            if self.app.selected_dbengine == 'db-mariadb' \
            else 'sqlite'

        # Write a standard Wallabag config file
        config_file = os.path.join(self.path, 'app/config/parameters.yml')
        with open(config_file + ".dist", 'r') as f:
            ic = f.readlines()
        with open(config_file, 'w') as f:
            for l in ic:
                if "database_driver: " in l:
                    pdo = "pdo_mysql" if dbengine == "mysql" else "pdo_sqlite"
                    l = "    database_driver: {0}\n".format(pdo)
                elif "database_path: " in l and dbengine == 'sqlite':
                    l = "    database_path: {0}\n".format(self.db.path)
                elif "database_name: " in l and dbengine == 'mysql':
                    l = "    database_name: {0}\n".format(self.db.id)
                elif "database_user: "******"    database_user: {0}\n".format(self.db.id)
                elif "database_password: "******"{0}"\n'.format(dbpasswd)
                elif "secret: " in l:
                    l = "    secret: {0}\n".format(secret_key)
                f.write(l)

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('sqlite3', 'bcmath',
                       'pdo_mysql' if dbengine == 'mysql' else 'pdo_sqlite',
                       'zip', 'tidy')
        php.open_basedir('add', '/usr/bin/php')

        uid, gid = users.get_system("http").uid, groups.get_system("http").gid

        # Set up the database then delete the install folder
        if dbengine == 'sqlite3':
            php.open_basedir('add', '/var/lib/sqlite3')

        cwd = os.getcwd()
        os.chdir(self.path)
        s = shell("php bin/console wallabag:install --env=prod -n")
        if s["code"] != 0:
            logger.error("Websites", s["stderr"].decode())
            raise errors.OperationFailedError(
                "Failed to populate database. See logs for more info")
        os.chdir(cwd)

        if dbengine == 'sqlite3':
            os.chown("/var/lib/sqlite3/{0}.db".format(self.db.id), -1, gid)
            os.chmod("/var/lib/sqlite3/{0}.db".format(self.db.id), 0o660)

        # Finally, make sure that permissions are set so that Wallabag
        # can make adjustments and save plugins when need be.
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
Example #29
0
 def disconnect(self):
     signals.emit("networks", "pre_disconnect", self)
     s = shell("netctl stop %s" % self.id)
     if s["code"] == 0:
         self.connected = False
         signals.emit("networks", "post_disconnect", self)
     else:
         raise Exception("Network disconnection failed")
Example #30
0
 def _init_samba_for_ldap(self):
     shell("smbpasswd -w {0}".format(secrets.get("ldap")))
     config = configparser.ConfigParser()
     config.read(["/etc/samba/smb.conf"])
     config.set("global", "passdb backend", 'ldapsam:"ldap://localhost/"')
     config.set("global", "ldap ssl", "off")
     config.set("global", "ldap passwd sync", "no")
     config.set("global", "ldap suffix", "dc=arkos-servers,dc=org")
     config.set("global", "ldap user suffix", "ou=users")
     config.set("global", "ldap group suffix", "ou=groups")
     config.set(
         "global", "ldap admin dn", "cn=admin,dc=arkos-servers,dc=org"
     )
     if config.has_section("homes"):
         config.remove_section("homes")
     with open("/etc/samba/smb.conf", "w") as f:
         config.write(f)
Example #31
0
def nslcd():
    """Initialize distribution PAM integration of OpenLDAP."""
    patchfiles = [
        ("/etc/pam.d/system-auth", "001-add-ldap-to-system-auth.patch"),
        ("/etc/pam.d/su", "002-add-ldap-to-su.patch"),
        ("/etc/pam.d/su-l", "003-add-ldap-to-su-l.patch"),
        ("/etc/pam.d/passwd", "004-add-ldap-to-passwd.patch"),
        ("/etc/pam.d/system-login", "005-add-ldap-to-system-login.patch"),
        ("/etc/nsswitch.conf", "006-add-ldap-to-nsswitch.patch"),
        ("/etc/nslcd.conf", "007-add-ldap-to-nslcd.patch")
    ]
    for x in patchfiles:
        if not os.path.exists(os.path.join("/usr/share/arkos/nslcd", x[1])):
            raise CLIException(
                "Patch files could not be found. Your installation may "
                "be corrupted. Please reinstall the `arkos-configs` package.")

    logger.debug('ctl:init:nslcd', 'Stopping daemon: nslcd')
    s = shell("systemctl stop nslcd")
    if s["code"] != 0:
        raise click.ClickException(s["stderr"].decode())

    logger.info('ctl:init:nslcd', 'Patching system files')
    for x in patchfiles:
        shell("patch -N {0} {1}".format(
            x[0], os.path.join("/usr/share/arkos/nslcd", x[1])))

    logger.debug('ctl:init:nslcd', 'Starting daemon: nslcd')
    shell("systemctl enable nslcd")
    shell("systemctl start nslcd")
    logger.success('ctl:init:nslcd', 'Complete')
Example #32
0
 def get_log(self):
     """Get supervisor service logs."""
     if self.stype == "supervisor":
         supervisor_ping()
         s = conns.Supervisor.tailProcessStdoutLog(self.name)
     else:
         s = shell("systemctl --no-ask-password status {0}".format(
             self.sfname))["stdout"]
     return s
Example #33
0
 def disconnect(self):
     """Disconnect from network."""
     signals.emit("networks", "pre_disconnect", self)
     s = shell("netctl stop {0}".format(self.id))
     if s["code"] == 0:
         self.connected = False
         signals.emit("networks", "post_disconnect", self)
     else:
         raise errors.OperationFailedError("Network disconnection failed")
Example #34
0
def install_from_package(path, stat="production", opts={}):
    # Installs a set of NPM package dependencies from an NPM package.json.
    cwd = os.getcwd()
    os.chdir(path)
    s = shell("npm install %s%s" % (" --"+stat if stat else "", " --"+" --".join(x+"="+opts[x] for x in opts) if opts else ""))
    os.chdir(cwd)
    if s["code"] != 0:
        logger.error("NPM install of %s failed; log output follows:\n%s"%(path,s["stderr"]))
        raise Exception("NPM install failed, check logs for info")
Example #35
0
File: system.py Project: ns408/core
def show_version():
    """Show version and diagnostic details"""
    click.echo(shell("uname -a")["stdout"].decode().rstrip("\n"))
    click.echo(
        click.style(" * arkOS server version: ", fg="yellow") +
        config.get("enviro", "version", "Unknown"))
    click.echo(
        click.style(" * Arch / Board: ", fg="yellow") +
        config.get("enviro", "arch", "Unknown") + " / " +
        config.get("enviro", "board", "Unknown"))
Example #36
0
 def add_db(self):
     if re.search('\.|-|`|\\\\|\/|[ ]', self.id):
         raise errors.InvalidConfigError(
             'Name must not contain spaces, dots, dashes or other '
             'special characters')
     self.manager.chkpath()
     status = shell("sqlite3 {0} \"ATTACH '{1}' AS {2};\"".format(
         self.path, self.path, self.id))
     if status["code"] >= 1:
         raise errors.OperationFailedError(status["stderr"])
Example #37
0
 def connect(self):
     signals.emit("networks", "pre_connect", self)
     for x in get_connections(iface=self.config.get("interface")):
         x.disconnect()
     s = shell("netctl start %s" % self.id)
     if s["code"] == 0:
         self.connected = True
         signals.emit("networks", "post_connect", self)
     else:
         raise Exception("Network connection failed")
Example #38
0
def regenerate_firewall(data, range=[]):
    # Regenerate our chain.
    # If local ranges are not provided, get them.
    signals.emit("security", "pre_fw_regen")
    flush_chain("arkos-apps")
    default_range = range or network.get_active_ranges()
    # For each policy in the system, add a rule
    for x in data:
        range = getattr(x, "allowed_ranges", default_range)
        for port in x.ports:
            if x.policy == 2:
                add_rule("ACCEPT", port[0], port[1], ["anywhere"])
            elif x.policy == 1:
                add_rule("ACCEPT", port[0], port[1], range)
            else:
                add_rule("REJECT", port[0], port[1])
    shell("iptables -A arkos-apps -j RETURN")
    save_rules()
    signals.emit("security", "post_fw_regen")
Example #39
0
 def connect(self, user='******', passwd='', db=None):
     passwd = passwd or secrets.get("mysql")
     if not os.path.exists("/var/lib/mysql/mysql"):
         shell("mysql_install_db --user=mysql --basedir=/usr --datadir=/var/lib/mysql")
     try:
         conns.MariaDB.ping()
         self.state = True
         return
     except:
         pass
     try:
         if not passwd:
             passwd = self.change_admin_passwd()
         conns.MariaDB = MySQLdb.connect('localhost', user, passwd, db or "")
         self.state = True
         self.connection = conns.MariaDB
     except:
         self.state = False
         raise ConnectionError("MariaDB")
Example #40
0
File: backup.py Project: ns408/core
 def pre_backup(self):
     """Reimplement."""
     s = shell("slapcat -n 1")
     if s["code"] != 0:
         emsg = ("Could not backup LDAP database. "
                 "Please check logs for errors.")
         logger.error("Backup", s["stderr"].decode())
         raise errors.OperationFailedError(emsg)
     with open("/tmp/ldap.ldif", "wb") as f:
         f.write(s["stdout"])
Example #41
0
 def add_db(self):
     if re.search('\.|-|`|\\\\|\/|[ ]', self.id):
         raise Exception(
             'Name must not contain spaces, dots, dashes or other special characters'
         )
     self.manager.chkpath()
     path = '/var/lib/sqlite3/%s.db' % self.id
     status = shell('sqlite3 %s "ATTACH \'%s\' AS %s;"' %
                    (path, path, self.id))
     if status["code"] >= 1:
         raise Exception(status["stderr"])
Example #42
0
File: nodejs.py Project: ns408/core
def is_installed(name, as_global=True):
    """
    Return whether an NPM package is installed.

    :param str name: NPM package name
    :param bool as_global: Check global NPM instead of local
    """
    s = shell("npm list -p {0}{1}".format("-g " if as_global else "", name))
    if name in s['stdout']:
        return True
    return False
Example #43
0
def install(*mods, **kwargs):
    # Installs a set of NPM packages.
    as_global = kwargs.get("as_global", False)
    cwd = os.getcwd()
    if "install_path" in kwargs:
        os.chdir(kwargs["install_path"])
    s = shell("npm install %s%s%s" % ("-g " if as_global else "", " ".join(x for x in mods), (" --"+" --".join(k+v if v[0]=='=' else k+" "+v for k,v in kwargs["opts"].items()) if kwargs.has_key("opts") else "")))
    os.chdir(cwd)
    if s["code"] != 0:
        logger.error("NPM install of %s failed; log output follows:\n%s"%(" ".join(x for x in mods),s["stderr"]))
        raise Exception("NPM install failed, check logs for info")
Example #44
0
 def post_restore(self):
     if not os.path.exists("/tmp/ldap.ldif"):
         raise Exception("Could not restore LDAP database. Please check logs for errors.")
     with open("/tmp/ldap.ldif", "r") as f:
         ldif = f.read()
     s = shell('ldapadd -D "cn=admin,dc=arkos-servers,dc=org" -w %s' % secrets.get("ldap"),
         stdin=ldif)
     if os.path.exists("/tmp/ldap.ldif"):
         os.unlink("/tmp/ldap.ldif")
     if s["code"] != 0:
         raise Exception("Could not restore LDAP database. Please check logs for errors.")
Example #45
0
 def connect(self):
     """Connect to network."""
     signals.emit("networks", "pre_connect", self)
     for x in get_connections(iface=self.config.get("interface")):
         x.disconnect()
     s = shell("netctl start {0}".format(self.id))
     if s["code"] == 0:
         self.connected = True
         signals.emit("networks", "post_connect", self)
     else:
         raise errors.OperationFailedError("Network connection failed")
Example #46
0
def nginx():
    """Initialize default nginx configuration."""
    if not os.path.exists("/usr/share/arkos/nginx.conf"):
        raise CLIException(
            "Template files could not be found. Your installation may "
            "be corrupted. Please reinstall the `arkos-configs` package.")

    logger.info('ctl:init:nginx', 'Copying files')
    if not os.path.exists("/srv/http/webapps"):
        os.makedirs("/srv/http/webapps")
    if not os.path.exists("/etc/nginx/sites-available"):
        os.makedirs("/etc/nginx/sites-available")
    if not os.path.exists("/etc/nginx/sites-enabled"):
        os.makedirs("/etc/nginx/sites-enabled")

    shutil.copy("/usr/share/arkos/nginx.conf", "/etc/nginx/nginx.conf")

    logger.debug('ctl:init:nginx', 'Restarting daemon: nginx')
    shell("systemctl enable nginx")
    shell("systemctl restart nginx")
    logger.success('ctl:init:nginx', 'Completed')
Example #47
0
 def connect(self, user='******', passwd='', db=None):
     passwd = passwd or secrets.get("mysql")
     if not os.path.exists("/var/lib/mysql/mysql"):
         shell("mysql_install_db --user=mysql --basedir=/usr "
               "--datadir=/var/lib/mysql")
     try:
         conns.MariaDB.ping()
         self.state = True
         return
     except:
         pass
     try:
         if not passwd:
             passwd = self.change_admin_passwd()
         conns.MariaDB = MySQLdb.connect('localhost', user, passwd, db
                                         or "")
         self.state = True
         self.connection = conns.MariaDB
     except:
         self.state = False
         raise errors.ConnectionError("MariaDB")
Example #48
0
File: python.py Project: ns408/core
def remove(*mods):
    """
    Remove a set of Python packages from the system.

    :param *mods: packages to remove
    """
    s = shell("pip uninstall {0}".format(mods))
    if s["code"] != 0:
        errmsg = "PyPI uninstall of {0} failed.".format(mods)
        logmsg = "PyPI uninstall failure details:\n{0}"
        logger.error("Python", logmsg.format(s["stderr"].decode()))
        raise errors.OperationFailedError(errmsg)
Example #49
0
File: python.py Project: ns408/core
def get_installed(py2=False):
    """
    Get all installed Python packages.

    Returns in format `{"id": "package_name", "version": "1.0.0"}`.

    :param bool py2: Check Python 2.x packages instead of 3.x
    """
    s = shell("pip{0} freeze".format("2" if py2 else ""))
    return [{
        "id": x.split(b"==")[0].decode(),
        "version": x.split(b"==")[1].decode()
    } for x in s["stdout"].split(b"\n") if x.split() and b"==" in x]
Example #50
0
def generate_certificate(
        id, domain, country, state="", locale="", email="", keytype="RSA",
        keylength=2048, message=DefaultMessage()):
    signals.emit("certificates", "pre_add", id)

    # Check to see that we have a CA ready; if not, generate one
    basehost = ".".join(domain.split(".")[-2:])
    ca = get_authorities(id=basehost)
    if not ca:
        message.update("info", "Generating certificate authority...")
        ca = generate_authority(basehost)
    with open(ca.cert_path, "r") as f:
        ca_cert = OpenSSL.crypto.load_certificate(OpenSSL.crypto.FILETYPE_PEM, f.read())
    with open(ca.key_path, "r") as f:
        ca_key = OpenSSL.crypto.load_privatekey(OpenSSL.crypto.FILETYPE_PEM, f.read())

    # Check to see that we have DH params, if not then do that too
    if not os.path.exists("/etc/arkos/ssl/dh_params.pem"):
        message.update("info", "Generating Diffie-Hellman parameters...")
        s = shell("openssl dhparam 2048 -out /etc/arkos/ssl/dh_params.pem")
        if s["code"] != 0:
            raise Exception("Failed to generate Diffie-Hellman parameters")
        os.chown("/etc/arkos/ssl/dh_params.pem", -1, gid)
        os.chmod("/etc/arkos/ssl/dh_params.pem", 0750)

    # Generate private key and create X509 certificate, then set options
    message.update("info", "Generating certificate...")
    kt = OpenSSL.crypto.TYPE_DSA if keytype == "DSA" else OpenSSL.crypto.TYPE_RSA
    try:
        key = OpenSSL.crypto.PKey()
        key.generate_key(kt, keylength)
        crt = OpenSSL.crypto.X509()
        crt.set_version(3)
        crt.get_subject().C = country
        crt.get_subject().CN = domain
        if state:
            crt.get_subject().ST = state
        if locale:
            crt.get_subject().L = locale
        if email:
            crt.get_subject().emailAddress = email
        crt.get_subject().O = "arkOS Servers"
        crt.set_serial_number(int(systemtime.get_serial_time()))
        crt.gmtime_adj_notBefore(0)
        crt.gmtime_adj_notAfter(2*365*24*60*60)
        crt.set_issuer(ca_cert.get_subject())
        crt.set_pubkey(key)
        crt.sign(ca_key, "sha256")
    except Exception, e:
        raise Exception("Error generating self-signed certificate: "+str(e))
Example #51
0
File: php.py Project: kidaa/arkos
def install_composer():
    # Installs Composer to the system.
    cwd = os.getcwd()
    os.chdir("/root")
    os.environ["COMPOSER_HOME"] = "/root"
    enable_mod("phar")
    open_basedir("add", "/root")
    installer = urllib2.urlopen("https://getcomposer.org/installer").read()
    s = shell("php", stdin=installer)
    os.chdir(cwd)
    if s["code"] != 0:
        raise Exception("Composer download/config failed. Error: %s"%str(s["stderr"]))
    os.rename("/root/composer.phar", "/usr/local/bin/composer")
    os.chmod("/usr/local/bin/composer", 755)
    open_basedir("add", "/usr/local/bin")
Example #52
0
 def regenerate(self):
     path = self.path
     if not path.endswith("_site"):
         path = os.path.join(self.path, "_site")
     s = shell('jekyll build --source '+self.path.split('/_site')[0]+' --destination '+path)
     if s["code"] != 0:
         raise Exception('Jekyll failed to build: %s'%str(s["stderr"]))
     uid, gid = users.get_system("http").uid, groups.get_system("http").gid
     for r, d, f in os.walk(self.path):
         for x in d:
             os.chmod(os.path.join(r, x), 0755)
             os.chown(os.path.join(r, x), uid, gid)
         for x in f:
             os.chmod(os.path.join(r, x), 0644)
             os.chown(os.path.join(r, x), uid, gid)
 def update(self, pkg, ver):
     # General update procedure
     shell('tar xzf %s -C %s --strip 1' % (pkg, self.path))
     for x in os.listdir(os.path.join(self.path, 'cache')):
         if os.path.isdir(os.path.join(self.path, 'cache', x)):
             shutil.rmtree(os.path.join(self.path, 'cache', x))
         else:
             os.unlink(os.path.join(self.path, 'cache', x))
     shutil.rmtree(os.path.join(self.path, 'install'))
     shell('chmod -R 755 '+os.path.join(self.path, 'assets/')+' '
         +os.path.join(self.path, 'cache/')+' '
         +os.path.join(self.path, 'db/'))
     shell('chown -R http:http '+self.path)
Example #54
0
def get_connections(id=None, iface=None):
    conns = []
    netctl = shell("netctl list")
    for line in netctl["stdout"].split("\n"):
        if not line.split():
            continue
        enabled = os.path.exists("/etc/systemd/system/multi-user.target.wants/netctl@%s.service" % line[2:])
        c = Connection(id=line[2:], connected=line.startswith("*"), enabled=enabled)
        with open(os.path.join("/etc/netctl", c.id), "r") as f:
            data = f.readlines()
        for x in data:
            if x.startswith("#") or not x.strip():
                continue
            parse = x.split("=")
            c.config[parse[0].lower()] = parse[1].translate(None, "()\"\"\n")
        if id == c.id:
            return c
        if not iface or c.config.get("interface") == iface:
            conns.append(c)
    return conns if not id else None
Example #55
0
    def post_install(self, vars, dbpasswd=""):
        # Make sure the webapps config points to the _site directory and generate it.
        c = nginx.loadf(os.path.join('/etc/nginx/sites-available', self.id))
        for x in c.servers:
            if x.filter('Key', 'root'):
                x.filter('Key', 'root')[0].value = os.path.join(self.path, '_site')
        nginx.dumpf(c, os.path.join('/etc/nginx/sites-available', self.id))
        s = shell('jekyll build --source '+self.path+' --destination '+os.path.join(self.path, '_site'))
        if s["code"] != 0:
            raise Exception('Jekyll failed to build: %s'%str(s["stderr"]))
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        for r, d, f in os.walk(self.path):
            for x in d:
                os.chmod(os.path.join(r, x), 0755)
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chmod(os.path.join(r, x), 0644)
                os.chown(os.path.join(r, x), uid, gid)

        # Return an explicatory message.
        return 'Jekyll has been setup, with a sample site at '+self.path+'. Modify these files as you like. To learn how to use Jekyll, visit http://jekyllrb.com/docs/usage. After making changes, click the Edit button for the site, then "Regenerate Site" to bring your changes live.'
Example #56
0
def genesis_init(state):
    path = ""
    apps = applications.get()
    if config.get("enviro", "run") == "vagrant":
        path = '/home/vagrant/genesis'
    elif config.get("enviro", "run") == "dev":
        sdir = os.path.dirname(os.path.realpath(__file__))
        path = os.path.abspath(os.path.join(sdir, '../../genesis'))
    elif os.path.exists('/var/lib/arkos/genesis'):
        path = '/var/lib/arkos/genesis'
    if not os.path.exists(path):
        return
    backend.add_url_rule('/', defaults={'path': None}, view_func=genesis, 
        methods=['GET',])
    backend.add_url_rule('/<path:path>', view_func=genesis, methods=['GET',])
    for x in os.listdir(os.path.join(path, 'lib')):
        if os.path.islink(os.path.join(path, 'lib', x)):
            os.unlink(os.path.join(path, 'lib', x))
    libpaths = []
    for x in apps:
        genpath = "/var/lib/arkos/applications/%s/genesis" % x.id
        if os.path.exists(genpath):
            libpaths.append("lib/%s"%x.id)
            os.symlink(genpath, os.path.join(path, 'lib', x.id))
    if libpaths:
        with open(os.path.join(path, 'package.json'), 'r') as f:
            data = json.loads(f.read())
        data["ember-addon"] = {"paths": libpaths}
        with open(os.path.join(path, 'package.json'), 'w') as f:
            f.write(json.dumps(data, sort_keys=True, 
                indent=2, separators=(',', ': ')))
    mydir = os.getcwd()
    os.chdir(path)
    s = shell("ember build")
    os.chdir(mydir)
    if s["code"] != 0:
        raise Exception("Genesis rebuild process failed")
Example #57
0
 def disable(self):
     s = shell("netctl disable %s" % self.id)
     if s["code"] == 0:
         self.enabled = False
     else:
         raise Exception("Network disable failed")
Example #58
0
 def enable(self):
     s = shell("netctl enable %s" % self.id)
     if s["code"] == 0:
         self.enabled = True
     else:
         raise Exception("Network enable failed")
Example #59
0
 def disable(self):
     shell("systemctl disable netctl-auto@%s.service" % self.id)
Example #60
0
 def bring_down(self):
     shell("ip link set dev %s down" % self.id)