예제 #1
0
    def post_install(self, vars, dbpasswd=""):
        # Create Lychee automatic configuration file
        with open(os.path.join(self.path, 'data', 'config.php'), 'w') as f:
            f.write(
                '<?php\n'
                '   if(!defined(\'LYCHEE\')) exit(\'Error: Direct access is allowed!\');\n'
                '   $dbHost = \'localhost\';\n'
                '   $dbUser = \'' + self.db.id + '\';\n'
                '   $dbPassword = \'' + dbpasswd + '\';\n'
                '   $dbName = \'' + self.db.id + '\';\n'
                '   $dbTablePrefix = \'\';\n'
                '?>\n')

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('mysql', 'mysqli', 'gd', 'zip', 'exif', 'json',
                       'mbstring')

        # Rename lychee index.html to index.php to make it work with our default nginx config
        os.rename(os.path.join(self.path, "index.html"),
                  os.path.join(self.path, "index.php"))

        # Finally, make sure that permissions are set so that Lychee
        # can make adjustments and save plugins when need be.
        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.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
예제 #2
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)
예제 #3
0
    def post_install(self, vars, dbpasswd=""):
        # Create Lychee automatic configuration file
        with open(os.path.join(self.path, 'data', 'config.php'), 'w') as f:
            f.write(
                '<?php\n'
                '   if(!defined(\'LYCHEE\')) exit(\'Error: Direct access is allowed!\');\n'
                '   $dbHost = \'localhost\';\n'
                '   $dbUser = \'' + self.db.id + '\';\n'
                '   $dbPassword = \'' + dbpasswd + '\';\n'
                '   $dbName = \'' + self.db.id + '\';\n'
                '   $dbTablePrefix = \'\';\n'
                '?>\n'
            )

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('mysql', 'mysqli', 'gd', 'zip', 'exif', 'json', 'mbstring')

        # Rename lychee index.html to index.php to make it work with our default nginx config
        os.rename(os.path.join(self.path, "index.html"), os.path.join(self.path, "index.php"))

        # Finally, make sure that permissions are set so that Lychee
        # can make adjustments and save plugins when need be.
        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.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
예제 #4
0
    def post_install(self, extra_vars, dbpasswd=""):
        # Write a basic index file showing that we are here
        if extra_vars.get('php'):
            php.enable_mod('apcu', config_file="/etc/php/conf.d/apcu.ini")

        index_ext = 'php' if extra_vars.get('php') else 'html'
        index_path = os.path.join(self.path, 'index.{0}'.format(index_ext))
        addr = self.domain + (":" + str(self.port) if self.port != 80 else "")
        with open(index_path, 'w') as f:
            f.write(
                '<html>\n'
                '<body>\n'
                '<div style="text-align:center;margin-top:20%;font-family:sans-serif;">\n'
                '<img style="width: 300px;" src="https://cdn.citizenweb.io/static/img/arkos-2-01.png" />\n'
                '<h1>Custom Website</h1>\n'
                '<p>Your site is online at http://{0}, and stored at {0}</p>\n'
                '<p>Feel free to paste your site files there!</p>\n'
                '</div>\n'
                '</body>\n'
                '</html>\n'.format(addr, self.path))

        # Give access to httpd
        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.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
예제 #5
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)
예제 #6
0
    def post_install(self, extra_vars, dbpasswd=""):
        secret_key = random_string()

        # Use the WordPress key generators as first option
        # If connection fails, use the secret_key as fallback
        try:
            keysection = requests.get(
                'https://api.wordpress.org/secret-key/1.1/salt/').text
        except:
            keysection = ''
        if 'define(\'AUTH_KEY' not in keysection:
            keysection = (
                'define(\'AUTH_KEY\', \'{0}\');\n'
                'define(\'SECURE_AUTH_KEY\', \'{0}\');\n'
                'define(\'LOGGED_IN_KEY\', \'{0}\');\n'
                'define(\'NONCE_KEY\', \'{0}\');\n'.format(secret_key)
                )

        # Write a standard WordPress config file
        with open(os.path.join(self.path, 'wp-config.php'), 'w') as f:
            f.write('<?php\n'
                    'define(\'DB_NAME\', \'{0}\');\n'
                    'define(\'DB_USER\', \'{0}\');\n'
                    'define(\'DB_PASSWORD\', \'{1}\');\n'
                    'define(\'DB_HOST\', \'localhost\');\n'
                    'define(\'DB_CHARSET\', \'utf8\');\n'
                    'define(\'SECRET_KEY\', \'{2}\');\n'
                    '\n'
                    'define(\'WP_CACHE\', true);\n'
                    'define(\'FORCE_SSL_ADMIN\', false);\n'
                    '\n'
                    '{3}'
                    '\n'
                    '$table_prefix = \'wp_\';\n'
                    '\n'
                    '/** Absolute path to the WordPress directory. */\n'
                    'if ( !defined(\'ABSPATH\') )\n'
                    '   define(\'ABSPATH\', dirname(__FILE__) . \'/\');\n'
                    '\n'
                    '/** Sets up WordPress vars and included files. */\n'
                    'require_once(ABSPATH . \'wp-settings.php\');\n'
                    .format(self.db.id, dbpasswd, secret_key, keysection)
                    )

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

        # Finally, make sure that permissions are set so that Wordpress
        # can make adjustments and save plugins when need be.
        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.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
예제 #7
0
def add(id, user, type):
    uid, gid = users.get_system("radicale").uid, groups.get_system("radicale").gid
    try:
        os.makedirs('/home/radicale/.config/radicale/collections/%s' % user)
        os.chown('/home/radicale/.config/radicale/collections', uid, gid)
    except os.error:
        pass
    with open(os.path.join('/home/radicale/.config/radicale/collections', user, id+type), 'w') as f:
        f.write("")
    os.chown(os.path.join('/home/radicale/.config/radicale/collections', user, id+type), uid, gid)
예제 #8
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'))
예제 #9
0
 def put(self, path):
     data = json.loads(request.data)["file"]
     if not os.path.exists(data["path"]):
         abort(404)
     if data["operation"] == "copy":
         if os.path.exists(os.path.join(data["newdir"], data["name"])):
             data["name"] = data["name"]+"-copy"
         if os.path.isdir(data["path"]):
             shutil.copytree(data["path"], os.path.join(data["newdir"], data["name"]))
         else:
             shutil.copy2(data["path"], os.path.join(data["newdir"], data["name"]))
         return jsonify(file=as_dict(os.path.join(data["newdir"], data["name"])))
     elif data["operation"] == "rename":
         shutil.move(data["path"], os.path.join(os.path.split(join(data["path"]))[0], data["name"]))
     elif data["operation"] == "edit":
         with open(data["path"], "w") as f:
             f.write(data["data"])
         return jsonify(file=as_dict(data["path"]))
     elif data["operation"] == "props":
         orig = as_dict(data["path"])
         if data["user"] != orig["user"] or data["group"] != orig["group"]:
             uid, gid = None, None
             u, g = users.get_system(data["user"]), groups.get_system(data["group"])
             if data["user"] == "root":
                 uid = 0
             if data["group"] == "root":
                 gid = 0
             if u and g:
                 uid, gid = u.uid, g.gid
             if uid == None or gid == None:
                 resp = jsonify(message="Invalid user/group specification")
                 resp.status_code = 422
                 return resp
             if data["folder"]:
                 os.chown(data["path"], uid, gid)
                 for r, d, f in os.walk(data["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)
             else:
                 os.chown(data["path"], u.uid, g.gid)
         if data["perms"]["oct"] != orig["perms"]["oct"]:
             if data["folder"]:
                 os.chmod(data["path"], int(data["perms"]["oct"][1:], 8))
                 for r, d, f in os.walk(data["path"]):
                     for x in d:
                         os.chmod(os.path.join(r, x), int(data["perms"]["oct"][1:], 8))
                     for x in f:
                         os.chmod(os.path.join(r, x), int(data["perms"]["oct"][1:], 8))
             else:
                 os.chmod(data["path"], int(data["perms"]["oct"][1:], 8))
         return jsonify(file=as_dict(data["path"]))
     else:
         abort(422)
예제 #10
0
    def post_install(self, vars, dbpasswd=""):
        secret_key = random_string()

        # Use the WordPress key generators as first option
        # If connection fails, use the secret_key as fallback
        try:
            keysection = urllib.urlopen('https://api.wordpress.org/secret-key/1.1/salt/').read()
        except:
            keysection = ''
        if not 'define(\'AUTH_KEY' in keysection:
            keysection = (
                'define(\'AUTH_KEY\', \''+secret_key+'\');\n'
                'define(\'SECURE_AUTH_KEY\', \''+secret_key+'\');\n'
                'define(\'LOGGED_IN_KEY\', \''+secret_key+'\');\n'
                'define(\'NONCE_KEY\', \''+secret_key+'\');\n'
                )

        # Write a standard WordPress config file
        with open(os.path.join(self.path, 'wp-config.php'), 'w') as f:
            f.write('<?php\n'
                'define(\'DB_NAME\', \''+self.db.id+'\');\n'
                'define(\'DB_USER\', \''+self.db.id+'\');\n'
                'define(\'DB_PASSWORD\', \''+dbpasswd+'\');\n'
                'define(\'DB_HOST\', \'localhost\');\n'
                'define(\'DB_CHARSET\', \'utf8\');\n'
                'define(\'SECRET_KEY\', \''+secret_key+'\');\n'
                '\n'
                'define(\'WP_CACHE\', true);\n'
                'define(\'FORCE_SSL_ADMIN\', false);\n'
                '\n'
                +keysection+
                '\n'
                '$table_prefix = \'wp_\';\n'
                '\n'
                '/** Absolute path to the WordPress directory. */\n'
                'if ( !defined(\'ABSPATH\') )\n'
                '   define(\'ABSPATH\', dirname(__FILE__) . \'/\');\n'
                '\n'
                '/** Sets up WordPress vars and included files. */\n'
                'require_once(ABSPATH . \'wp-settings.php\');\n'
            )

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

        # Finally, make sure that permissions are set so that Wordpress
        # can make adjustments and save plugins when need be.
        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.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
예제 #11
0
 def chkpath(self):
     # Make sure the db dir exists and that it has the right perms
     g = groups.get_system("sqlite3")
     if not g:
         g = groups.SystemGroup("sqlite3", users=["http"])
         g.add()
     if not os.path.isdir('/var/lib/sqlite3'):
         os.makedirs('/var/lib/sqlite3')
     if oct(stat.S_IMODE(os.stat('/var/lib/sqlite3').st_mode)) != 0775:
         os.chmod('/var/lib/sqlite3', 0775)
     if int(os.stat('/var/lib/sqlite3').st_gid) != g.gid:
         os.chown('/var/lib/sqlite3', -1, g.gid)
예제 #12
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'))
예제 #13
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)
예제 #14
0
def add(id, user, type):
    uid, gid = users.get_system("radicale").uid, groups.get_system(
        "radicale").gid
    try:
        os.makedirs('/home/radicale/.config/radicale/collections/%s' % user)
        os.chown('/home/radicale/.config/radicale/collections', uid, gid)
    except os.error:
        pass
    with open(
            os.path.join('/home/radicale/.config/radicale/collections', user,
                         id + type), 'w') as f:
        f.write("")
    os.chown(
        os.path.join('/home/radicale/.config/radicale/collections', user,
                     id + type), uid, gid)
예제 #15
0
 def regenerate(self):
     path = self.path
     if not path.endswith("_site"):
         path = os.path.join(self.path, "_site")
     s = shell('jekyll build --source {0} --destination {1}'.format(
         self.path.split('/_site')[0], path))
     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)
예제 #16
0
    def post_install(self, vars, dbpasswd=""):
        # Write a standard CMS.js config file
        with open(os.path.join(self.path, 'js/config.js'), 'r') as f:
            d = f.read()
        d = d.replace("siteName: 'My Site'", "siteName: 'CMS.js on arkOS'")
        d = d.replace("siteTagline: 'Your site tagline'", "siteTagline: 'Configure js/config.js to your liking'")
        d = d.replace("mode: 'Github'", "mode: 'Server'")

        with open(os.path.join(self.path, 'js/config.js'), 'w') as f:
            f.write(d)

        # Give access to httpd
        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.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
예제 #17
0
    def post_install(self, vars, dbpasswd=""):
        # Write a standard Wikitten config file
        shutil.copy(os.path.join(self.path, 'config.php.example'),
            os.path.join(self.path, 'config.php'))
        with open(os.path.join(self.path, 'config.php'), 'r') as f:
            d = f.read()
        d = d.replace("'My Wiki'", "'%s'" % self.id)

        with open(os.path.join(self.path, 'config.php'), 'w') as f:
            f.write(d)

        # Give access to httpd
        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.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
예제 #18
0
    def post_install(self, extra_vars, dbpasswd=""):
        # Write a standard CMS.js config file
        with open(os.path.join(self.path, 'js/config.js'), 'r') as f:
            d = f.read()
        d = d.replace("siteName: 'My Site'", "siteName: 'CMS.js on arkOS'")
        d = d.replace("siteTagline: 'Your site tagline'",
                      "siteTagline: 'Configure js/config.js to your liking'")
        d = d.replace("mode: 'Github'", "mode: 'Server'")

        with open(os.path.join(self.path, 'js/config.js'), 'w') as f:
            f.write(d)

        # Give access to httpd
        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.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
예제 #19
0
    def post_install(self, vars, dbpasswd=""):
        secret_key = random_string()
        php.open_basedir('add', '/dev')

        # If there is a custom path for the data directory, add to open_basedir
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        os.makedirs(os.path.join(self.path, "data"))
        os.chown(os.path.join(self.path, "data"), uid, gid)
        if self.data_path == self.path:
            self.data_path = os.path.join(self.path, "data")
        else:
            try:
                os.makedirs(os.path.join(self.data_path))
            except OSError, e:
                if e[0] == 17:
                    pass
                else:
                    raise
            os.chown(os.path.join(self.data_path), uid, gid)
            php.open_basedir('add', self.data_path)
예제 #20
0
    def post_install(self, extra_vars, dbpasswd=""):
        # Write a standard Wikitten config file
        shutil.copy(os.path.join(
                        self.path,
                        'config.php.example'),
                    os.path.join(self.path, 'config.php'))
        with open(os.path.join(self.path, 'config.php'), 'r') as f:
            d = f.read()
        d = d.replace("'My Wiki'", "'{0}'".format(self.id))

        with open(os.path.join(self.path, 'config.php'), 'w') as f:
            f.write(d)

        # Give access to httpd
        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.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
예제 #21
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.'
예제 #22
0
    def post_install(self, vars, dbpasswd=""):
        # Write a basic index file showing that we are here
        if vars.get('php'):
            php.enable_mod('xcache')

        with open(os.path.join(self.path, 'index.'+('php' if vars.get('php') else 'html')), 'w') as f:
            f.write(
                '<html>\n'
                '<body>\n'
                '<h1>Genesis - Custom Site</h1>\n'
                '<p>Your site is online and available at '+self.path+'</p>\n'
                '<p>Feel free to paste your site files here</p>\n'
                '</body>\n'
                '</html>\n'
                )

        # Give access to httpd
        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.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
예제 #23
0
 def update(self, pkg, ver):
     # General update procedure
     if semver.Version.coerce(ver) > semver.Version('2.0.0'):
         raise Exception(
             "Cannot automatically update from 1.x to 2.x. Please see "
             "Wallabag documentation for more information.")
     os.rename(os.path.join(self.path, 'app/config/parameters.yml'),
               '/tmp/_wb_parameters.yml')
     shell('tar xzf {0} -C {1} --strip 1'.format(pkg, self.path))
     os.rename('/tmp/_wb_parameters.yml',
               os.path.join(self.path, 'app/config/parameters.yml'))
     cachepath = os.path.join(self.path, 'var/cache')
     for x in os.listdir(cachepath):
         fpath = os.path.join(cachepath, x)
         if os.path.isdir(fpath):
             shutil.rmtree(fpath)
         else:
             os.unlink(fpath)
     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.chown(os.path.join(r, x), uid, gid)
         for x in f:
             os.chown(os.path.join(r, x), uid, gid)
예제 #24
0
    def post_install(self, vars, dbpasswd=""):
        secret_key = random_string()
        dbengine = 'mysql' if self.meta.selected_dbengine == 'db-mariadb' else 'sqlite'

        username = vars.get("wb-username")
        passwd = vars.get("wb-passwd") + username + secret_key
        passwd = hashlib.sha1(passwd).hexdigest()

        # Write a standard Wallabag config file
        shutil.copy(
            os.path.join(self.path, 'inc/poche/config.inc.default.php'),
            os.path.join(self.path, 'inc/poche/config.inc.php'))
        with open(os.path.join(self.path, 'inc/poche/config.inc.php'),
                  'r') as f:
            ic = f.readlines()
        oc = []
        for l in ic:
            if 'define (\'SALT\'' in l:
                l = '@define (\'SALT\', \'' + secret_key + '\');\n'
                oc.append(l)
            elif 'define (\'STORAGE\'' in l:
                l = '@define (\'STORAGE\', \'' + dbengine + '\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_SQLITE\'' in l and dbengine == 'sqlite':
                l = '@define (\'STORAGE_SQLITE\', \'/var/lib/sqlite3/' + self.db.id + '.db\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_DB\'' in l and dbengine == 'mysql':
                l = '@define (\'STORAGE_DB\', \'' + self.db.id + '\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_USER\'' in l and dbengine == 'mysql':
                l = '@define (\'STORAGE_USER\', \'' + self.db.id + '\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_PASSWORD\'' in l and dbengine == 'mysql':
                l = '@define (\'STORAGE_PASSWORD\', \'' + dbpasswd + '\');\n'
                oc.append(l)
            else:
                oc.append(l)
        with open(os.path.join(self.path, 'inc/poche/config.inc.php'),
                  'w') as f:
            f.writelines(oc)

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('mysql' if dbengine == 'mysql' else 'sqlite3',
                       'pdo_mysql' if dbengine == 'mysql' else 'pdo_sqlite',
                       'zip', 'tidy', 'xcache', 'openssl')

        # Set up Composer and install the proper modules
        php.composer_install(self.path)

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

        # Set up the database then delete the install folder
        if dbengine == 'mysql':
            with open(os.path.join(self.path, 'install/mysql.sql')) as f:
                self.db.execute(f.read())
            self.db.execute(
                "INSERT INTO users (username, password, name, email) VALUES ('%s', '%s', '%s', '');"
                % (username, passwd, username),
                commit=True)
            lid = int(self.db.manager.connection.insert_id())
            self.db.execute(
                "INSERT INTO users_config (user_id, name, value) VALUES (%s, 'pager', '10');"
                % lid,
                commit=True)
            self.db.execute(
                "INSERT INTO users_config (user_id, name, value) VALUES (%s, 'language', 'en_EN.UTF8');"
                % lid,
                commit=True)
        else:
            shutil.copy(os.path.join(self.path, 'install/poche.sqlite'),
                        '/var/lib/sqlite3/%s.db' % self.db.id)
            php.open_basedir('add', '/var/lib/sqlite3')
            os.chown("/var/lib/sqlite3/%s.db" % self.db.id, -1, gid)
            os.chmod("/var/lib/sqlite3/%s.db", 0664)
            self.db.execute(
                "INSERT INTO users (username, password, name, email) VALUES ('%s', '%s', '%s', '');"
                % (username, passwd, username))
            self.db.execute(
                "INSERT INTO users_config (user_id, name, value) VALUES (1, 'pager', '10');"
            )
            self.db.execute(
                "INSERT INTO users_config (user_id, name, value) VALUES (1, 'language', 'en_EN.UTF8');"
            )
        shutil.rmtree(os.path.join(self.path, 'install'))

        # 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:
                if d in ["assets", "cache", "db"]:
                    os.chmod(os.path.join(r, d), 0755)
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
예제 #25
0
 def put(self, path):
     data = request.get_json()["file"]
     if not os.path.exists(data["path"]):
         abort(404)
     orig = as_dict(data["path"])
     if data["operation"] == "copy":
         if os.path.exists(os.path.join(data["newdir"], data["name"])):
             data["name"] = data["name"] + "-copy"
         if os.path.isdir(data["path"]):
             shutil.copytree(data["path"],
                             os.path.join(data["newdir"], data["name"]))
         else:
             shutil.copy2(data["path"],
                          os.path.join(data["newdir"], data["name"]))
         return jsonify(
             file=as_dict(os.path.join(data["newdir"], data["name"])))
     elif data["operation"] == "rename":
         shutil.move(
             data["path"],
             os.path.join(
                 os.path.split(join(data["path"]))[0], data["name"]))
     elif data["operation"] == "edit":
         with open(data["path"], "w") as f:
             f.write(data["data"])
         return jsonify(file=as_dict(data["path"]))
     elif data["operation"] == "extract":
         if not orig["type"] == "archive":
             return jsonify(errors={"msg": "Not an archive"}), 422
         extract(data["path"], os.path.dirname(data["path"]))
         return jsonify(file=as_dict(data["path"]))
     elif data["operation"] == "props":
         if data["user"] != orig["user"] or data["group"] != orig["group"]:
             uid, gid = None, None
             u, g = users.get_system(data["user"]), groups.get_system(
                 data["group"])
             if data["user"] == "root":
                 uid = 0
             if data["group"] == "root":
                 gid = 0
             if u and g:
                 uid = u.uid if u.uid is not None else -1
                 gid = g.gid if g.gid is not None else -1
             if data["folder"]:
                 os.chown(data["path"], uid, gid)
                 for r, d, f in os.walk(data["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)
             else:
                 os.chown(data["path"], uid, gid)
         if data["perms"]["oct"] != orig["perms"]["oct"]:
             if data["folder"]:
                 os.chmod(data["path"], int(data["perms"]["oct"], 8))
                 for r, d, f in os.walk(data["path"]):
                     for x in d:
                         os.chmod(os.path.join(r, x),
                                  int(data["perms"]["oct"], 8))
                     for x in f:
                         os.chmod(os.path.join(r, x),
                                  int(data["perms"]["oct"], 8))
             else:
                 os.chmod(data["path"], int(data["perms"]["oct"], 8))
         return jsonify(file=as_dict(data["path"]))
     else:
         abort(422)
예제 #26
0
    def _install(self, extra_vars, enable, nthread):
        nthread.title = "Installing website"

        msg = Notification("info", "Webs", "Preparing to install...")
        nthread.update(msg)

        # Make sure the chosen port is indeed open
        if not tracked_services.is_open_port(self.port, self.domain):
            cname = "({0})".format(self.app.id)
            raise errors.InvalidConfigError(cname, nthread)\
                from tracked_services.PortConflictError(self.port, self.domain)

        # Set some metadata values
        specialmsg, dbpasswd = "", ""
        site_dir = config.get("websites", "site_dir")
        path = (self.path or os.path.join(site_dir, self.id))
        self.path = path
        self.php = extra_vars.get("php") or self.php \
            or self.app.uses_php or False
        self.version = self.app.version.rsplit("-", 1)[0] \
            if self.app.website_updates else None

        # Classify the source package type
        if not self.app.download_url:
            ending = ""
        elif self.app.download_url.endswith(".tar.gz"):
            ending = ".tar.gz"
        elif self.app.download_url.endswith(".tgz"):
            ending = ".tgz"
        elif self.app.download_url.endswith(".tar.bz2"):
            ending = ".tar.bz2"
        elif self.app.download_url.endswith(".zip"):
            ending = ".zip"
        elif self.app.download_url.endswith(".git"):
            ending = ".git"
        else:
            raise errors.InvalidConfigError(
                "Invalid source archive format in {0}".format(self.app.id))

        msg = "Running pre-installation..."
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        nthread.update(Notification("info", "Webs", msg))

        # Call website type's pre-install hook
        self.pre_install(extra_vars)

        # If needs DB and user didn't select an engine, choose one for them
        if len(self.app.database_engines) > 1 \
                and extra_vars.get("dbengine", None):
            self.app.selected_dbengine = extra_vars.get("dbengine")
        if not getattr(self.app, "selected_dbengine", None)\
                and self.app.database_engines:
            self.app.selected_dbengine = self.app.database_engines[0]

        # Create DB and/or DB user as necessary
        if getattr(self.app, "selected_dbengine", None):
            msg = "Creating database..."
            nthread.update(Notification("info", "Webs", msg))
            mgr = databases.get_managers(self.app.selected_dbengine)
            if not mgr:
                estr = "No manager found for {0}"
                raise errors.InvalidConfigError(
                    estr.format(self.app.selected_dbengine))
            # Make sure DB daemon is running if it has one
            if not mgr.state:
                svc = services.get(mgr.meta.database_service)
                svc.restart()
            self.db = mgr.add_db(self.id)
            if hasattr(self.db, "path"):
                os.chmod(self.db.path, 0o660)
                os.chown(self.db.path, -1, gid)
            # If multiuser DB type, create user
            if mgr.meta.database_multiuser:
                dbpasswd = random_string(16)
                db_user = mgr.add_user(self.id, dbpasswd)
                db_user.chperm("grant", self.db)

        # Make sure the target directory exists, but is empty
        pkg_path = os.path.join("/tmp", self.id + ending)
        if os.path.isdir(self.path):
            shutil.rmtree(self.path)
        os.makedirs(self.path)

        # Download and extract the source repo / package
        msg = "Downloading website source..."
        nthread.update(Notification("info", "Webs", msg))
        if self.app.download_url and ending == ".git":
            g = git.Repo.clone_from(self.app.download_url, self.path)
            if hasattr(self.app, "download_at_tag"):
                g = git.Git(self.path)
                g.checkout(self.app.download_git_tag)
        elif self.app.download_url:
            download(self.app.download_url, file=pkg_path, crit=True)

            # Format extraction command according to type
            msg = "Extracting source..."
            nthread.update(Notification("info", "Webs", msg))
            if ending in [".tar.gz", ".tgz", ".tar.bz2"]:
                arch = tarfile.open(pkg_path, "r:gz")
                r = (x for x in arch.getnames() if re.match("^[^/]*$", x))
                toplvl = next(r, None)
                if not toplvl:
                    raise errors.OperationFailedError(
                        "Malformed source archive")
                arch.extractall(site_dir)
                os.rename(os.path.join(site_dir, toplvl), self.path)
            else:
                arch = zipfile.ZipFile(pkg_path)
                r = (x for x in arch.namelist() if re.match("^[^/]*/$", x))
                toplvl = next(r, None)
                if not toplvl:
                    raise errors.OperationFailedError(
                        "Malformed source archive")
                arch.extractall(site_dir)
                os.rename(os.path.join(site_dir, toplvl.rstrip("/")),
                          self.path)
            os.remove(pkg_path)

        # Set proper starting permissions on source directory
        os.chmod(self.path, 0o755)
        os.chown(self.path, uid, 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)

        # If there is a custom path for the data directory, set it up
        if getattr(self.app, "website_datapaths", None) \
                and extra_vars.get("datadir"):
            self.data_path = extra_vars["datadir"]
            if not os.path.exists(self.data_path):
                os.makedirs(self.data_path)
            os.chmod(self.data_path, 0o755)
            os.chown(self.data_path, uid, gid)
        elif hasattr(self, "website_default_data_subdir"):
            self.data_path = os.path.join(self.path,
                                          self.website_default_data_subdir)
        else:
            self.data_path = self.path

        # Create the nginx serverblock
        addtoblock = self.addtoblock or []
        if extra_vars.get("addtoblock"):
            addtoblock += nginx.loads(extra_vars.get("addtoblock"), False)
        default_index = "index." + ("php" if self.php else "html")
        if hasattr(self.app, "website_root"):
            webroot = os.path.join(self.path, self.app.website_root)
        else:
            webroot = self.path
        block = nginx.Conf()
        server = nginx.Server(
            nginx.Key("listen", str(self.port)),
            nginx.Key("listen", "[::]:" + str(self.port)),
            nginx.Key("server_name", self.domain), nginx.Key("root", webroot),
            nginx.Key(
                "index",
                getattr(self.app, "website_index", None) or default_index),
            nginx.Location("/.well-known/acme-challenge/",
                           nginx.Key("root", self.path)))
        if addtoblock:
            server.add(*[x for x in addtoblock])
        block.add(server)
        nginx.dumpf(block, os.path.join("/etc/nginx/sites-available", self.id))
        challenge_dir = os.path.join(self.path, ".well-known/acme-challenge/")
        if not os.path.exists(challenge_dir):
            os.makedirs(challenge_dir)

        # Create arkOS metadata file
        meta = configparser.SafeConfigParser()
        meta.add_section("website")
        meta.set("website", "id", self.id)
        meta.set("website", "app", self.app.id)
        meta.set("website", "ssl",
                 self.cert.id if getattr(self, "cert", None) else "None")
        meta.set("website", "version", self.version or "None")
        if getattr(self.app, "website_datapaths", None) \
                and self.data_path:
            meta.set("website", "data_path", self.data_path)
        meta.set("website", "dbengine", "")
        meta.set("website", "dbengine",
                 getattr(self.app, "selected_dbengine", ""))
        with open(os.path.join(self.path, ".arkos"), "w") as f:
            meta.write(f)

        # Call site type's post-installation hook
        msg = "Running post-installation. This may take a few minutes..."
        nthread.update(Notification("info", "Webs", msg))
        specialmsg = self.post_install(extra_vars, dbpasswd)

        # Cleanup and reload daemons
        msg = "Finishing..."
        nthread.update(Notification("info", "Webs", msg))
        self.installed = True
        storage.websites[self.id] = self
        if self.port == 80:
            cleanup_acme_dummy(self.domain)
        signals.emit("websites", "site_installed", self)
        if enable:
            self.nginx_enable()
        if enable and self.php:
            php.open_basedir("add", "/srv/http/")
            php_reload()

        msg = "{0} site installed successfully".format(self.app.name)
        nthread.complete(Notification("success", "Webs", msg))
        if specialmsg:
            return specialmsg
예제 #27
0
파일: certificates.py 프로젝트: ns408/core
def _request_acme_certificate(domain, webroot, nthread):
    nthread.title = "Requesting ACME certificate"
    signals.emit("certificates", "pre_add", id)
    domains = [domain]

    uid = users.get_system("http").uid
    gid = groups.get_system("ssl-cert").gid

    if webroot:
        webroot = os.path.join(webroot, ".well-known", "acme-challenge")

    acme_dir = config.get("certificates", "acme_dir")
    cert_dir = os.path.join(acme_dir, "certs", domain)
    cert_path = os.path.join(cert_dir, "cert.pem")
    key_path = os.path.join(cert_dir, "privkey.pem")

    if not os.path.exists(cert_dir):
        os.makedirs(cert_dir)

    if not webroot:
        sites = websites.get()
        for x in sites:
            if x.port in [80, 443] and x.domain == domain:
                webroot = x.add_acme_challenge()
                break
        else:
            webroot = websites.create_acme_dummy(domain)

    smsg = "Requesting certificate from Let's Encrypt CA..."
    nthread.update(Notification("info", "Certificates", smsg))
    agree_to_tos = None
    has_written_files = False
    while True:
        try:
            leclient.issue_certificate(
                domains,
                acme_dir,
                acme_server=config.get("certificates", "acme_server"),
                certificate_file=cert_path,
                private_key_file=key_path,
                agree_to_tos_url=agree_to_tos)
            break
        except leclient.NeedToAgreeToTOS as e:
            agree_to_tos = e.url
            continue
        except leclient.NeedToTakeAction as e:
            if not has_written_files:
                if not os.path.exists(webroot):
                    os.makedirs(webroot)
                os.chown(webroot, uid, gid)
                for x in e.actions:
                    fn = os.path.join(webroot, x.file_name)
                    with open(fn, 'w') as f:
                        f.write(x.contents)
                    os.chown(fn, uid, gid)
                has_written_files = True
                continue
            else:
                raise errors.InvalidConfigError(
                    "Requesting a certificate failed - it doesn't appear your "
                    "requested domain's DNS is pointing to your server, or "
                    "there was a port problem. Please check these things and "
                    "try again.")
        except leclient.WaitABit as e:
            while e.until_when > datetime.datetime.now():
                until = e.until_when - datetime.datetime.now()
                until_secs = int(round(until.total_seconds())) + 1
                if until_secs > 300:
                    raise errors.InvalidConfigError(
                        "Requesting a certificate failed - LE rate limiting "
                        "detected, for a period of more than five minutes. "
                        "Please try again later."
                    )
                nthread.update(
                    Notification(
                        "warning", "Certificates", "LE rate limiting detected."
                        " Will reattempt in {0} seconds".format(until_secs))
                    )
                time.sleep(until_secs)
            continue
        except leclient.InvalidDomainName:
            raise errors.InvalidConfigError(
                "Requesting a certificate failed - invalid domain name"
            )
        except leclient.RateLimited:
            raise errors.InvalidConfigError(
                "Requesting a certificate failed - LE is refusing to issue "
                "more certificates to you for this domain. Please choose "
                "another domain or try again another time."
            )

    os.chown(cert_path, -1, gid)
    os.chown(key_path, -1, gid)
    os.chmod(cert_path, 0o750)
    os.chmod(key_path, 0o750)

    with open(cert_path, "rb") as f:
        cert = x509.load_pem_x509_certificate(f.read(), default_backend())
    with open(key_path, "rb") as f:
        key = serialization.load_pem_private_key(
            f.read(), password=None, backend=default_backend()
        )
    sha1 = binascii.hexlify(cert.fingerprint(hashes.SHA1())).decode()
    md5 = binascii.hexlify(cert.fingerprint(hashes.MD5())).decode()
    sha1 = ":".join([sha1[i:i+2].upper() for i in range(0, len(sha1), 2)])
    md5 = ":".join([md5[i:i+2].upper() for i in range(0, len(md5), 2)])
    if isinstance(key.public_key(), rsa.RSAPublicKey):
        ktype = "RSA"
    elif isinstance(key.public_key(), dsa.DSAPublicKey):
        ktype = "DSA"
    elif isinstance(key.public_key(), ec.EllipticCurvePublicKey):
        ktype = "EC"
    else:
        ktype = "Unknown"
    ksize = key.key_size
    c = Certificate(domain, domain, cert_path, key_path, ktype, ksize,
                    [], cert.not_valid_after, sha1, md5, is_acme=True)
    storage.certificates[c.id] = c

    with open("/etc/cron.d/arkos-acme-renew", "a") as f:
        f.write("0 4 * * * systemctl reload nginx\n")
        fln = ("30 3 * * * free_tls_certificate {0} {1} {2} {3} {4} "
               ">> /var/log/acme-renew.log\n")
        f.write(fln.format(
            " ".join(domains), key_path, cert_path,
            webroot.split("/.well-known/acme-challenge")[0], acme_dir
        ))

    signals.emit("certificates", "post_add", c)
    msg = "Certificate issued successfully"
    nthread.complete(Notification("success", "Certificates", msg))
    return c
예제 #28
0
파일: certificates.py 프로젝트: ns408/core
from cryptography.hazmat.backends import default_backend
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import dsa, rsa, ec
import datetime
from free_tls_certificates import client as leclient
import glob
import os
import time

from arkos import config, signals, storage, websites, applications, logger
from arkos.messages import Notification, NotificationThread
from arkos.system import users, groups
from arkos.utilities import errors, shell


if not groups.get_system("ssl-cert"):
    groups.SystemGroup("ssl-cert").add()
gid = groups.get_system("ssl-cert").gid


class Certificate:
    """
    Represents a TLS certificate managed by arkOS.

    Certificates can be generated (self-signed), generated from Let's Encrypt
    CA, or installed from external sources. When certificates are self-signed,
    they are accompanied by generated certificate authorities allowing client
    trust for the root domain in question.

    ``Assign`` objects that are sent to/from this class look like this:
예제 #29
0
    def post_install(self, vars, dbpasswd=""):
        secret_key = random_string()
        
        # If there is a custom path for the data directory, add to open_basedir
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        if not self.data_path.startswith(self.path):
            os.makedirs(os.path.join(self.path, "data"))
            os.chown(os.path.join(self.path, "data"), uid, gid)
            php.open_basedir('add', self.data_path)

        # Create ownCloud automatic configuration file
        with open(os.path.join(self.path, 'config', 'autoconfig.php'), 'w') as f:
            f.write(
                '<?php\n'
                '   $AUTOCONFIG = array(\n'
                '   "adminlogin" => "admin",\n'
                '   "adminpass" => "'+dbpasswd+'",\n'
                '   "dbtype" => "mysql",\n'
                '   "dbname" => "'+self.db.id+'",\n'
                '   "dbuser" => "'+self.db.id+'",\n'
                '   "dbpass" => "'+dbpasswd+'",\n'
                '   "dbhost" => "localhost",\n'
                '   "dbtableprefix" => "",\n'
                '   "directory" => "'+self.data_path+'",\n'
                '   );\n'
                '?>\n'
                )
        os.chown(os.path.join(self.path, 'config', 'autoconfig.php'), uid, gid)

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('mysql', 'pdo_mysql', 'zip', 'gd', 'ldap',
            'iconv', 'openssl', 'xcache', 'posix')
        
        # Make sure xcache has the correct settings, otherwise ownCloud breaks
        with open('/etc/php/conf.d/xcache.ini', 'w') as f:
            f.writelines(['extension=xcache.so\n',
                'xcache.size=64M\n',
                'xcache.var_size=64M\n',
                'xcache.admin.enable_auth = Off\n',
                'xcache.admin.user = "******"\n',
                'xcache.admin.pass = "******"\n'])
        
        php.change_setting("always_populate_raw_post_data", "-1")
        mydir = os.getcwd()
        os.chdir(self.path)
        s = shell("sudo -u http php index.php")
        if s["code"] != 0:
            raise Exception("ownCloud database population failed")
        s = shell("sudo -u http php occ app:enable user_ldap")
        if s["code"] != 0:
            raise Exception("ownCloud LDAP configuration failed")
        os.chdir(mydir)
        
        ldap_sql = ("REPLACE INTO appconfig (appid, configkey, configvalue) VALUES"
            "('user_ldap', 'ldap_uuid_attribute', 'auto'),"
            "('user_ldap', 'ldap_host', 'localhost'),"
            "('user_ldap', 'ldap_port', '389'),"
            "('user_ldap', 'ldap_base', 'dc=arkos-servers,dc=org'),"
            "('user_ldap', 'ldap_base_users', 'dc=arkos-servers,dc=org'),"
            "('user_ldap', 'ldap_base_groups', 'dc=arkos-servers,dc=org'),"
            "('user_ldap', 'ldap_tls', '0'),"
            "('user_ldap', 'ldap_display_name', 'cn'),"
            "('user_ldap', 'ldap_userlist_filter', 'objectClass=mailAccount'),"
            "('user_ldap', 'ldap_group_filter', 'objectClass=posixGroup'),"
            "('user_ldap', 'ldap_group_display_name', 'cn'),"
            "('user_ldap', 'ldap_group_member_assoc_attribute', 'uniqueMember'),"
            "('user_ldap', 'ldap_login_filter', '(&(|(objectclass=posixAccount))(|(uid=%uid)))'),"
            "('user_ldap', 'ldap_quota_attr', 'mailQuota'),"
            "('user_ldap', 'ldap_quota_def', ''),"
            "('user_ldap', 'ldap_email_attr', 'mail'),"
            "('user_ldap', 'ldap_cache_ttl', '600'),"
            "('user_ldap', 'ldap_configuration_active', '1'),"
            "('user_ldap', 'home_folder_naming_rule', ''),"
            "('user_ldap', 'ldap_backup_host', ''),"
            "('user_ldap', 'ldap_dn', ''),"
            "('user_ldap', 'ldap_agent_password', ''),"
            "('user_ldap', 'ldap_backup_port', ''),"
            "('user_ldap', 'ldap_nocase', ''),"
            "('user_ldap', 'ldap_turn_off_cert_check', ''),"
            "('user_ldap', 'ldap_override_main_server', ''),"
            "('user_ldap', 'ldap_attributes_for_user_search', ''),"
            "('user_ldap', 'ldap_attributes_for_group_search', ''),"
            "('user_ldap', 'ldap_expert_username_attr', 'uid'),"
            "('user_ldap', 'ldap_expert_uuid_attr', '');"
        )
        self.db.execute(ldap_sql, commit=True)
        # TODO set authed user name
        self.db.execute("INSERT INTO group_user VALUES ('admin','testuser');", commit=True)
예제 #30
0
    def post_install(self, vars, dbpasswd=""):
        secret_key = random_string()
        dbengine = 'mysql' if self.meta.selected_dbengine == 'db-mariadb' else 'sqlite'

        username = vars.get("wb-username")
        passwd = vars.get("wb-passwd") + username + secret_key
        passwd = hashlib.sha1(passwd).hexdigest()

        # Write a standard Wallabag config file
        shutil.copy(os.path.join(self.path, 'inc/poche/config.inc.default.php'),
            os.path.join(self.path, 'inc/poche/config.inc.php'))
        with open(os.path.join(self.path, 'inc/poche/config.inc.php'), 'r') as f:
            ic = f.readlines()
        oc = []
        for l in ic:
            if 'define (\'SALT\'' in l:
                l = '@define (\'SALT\', \''+secret_key+'\');\n'
                oc.append(l)
            elif 'define (\'STORAGE\'' in l:
                l = '@define (\'STORAGE\', \''+dbengine+'\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_SQLITE\'' in l and dbengine == 'sqlite':
                l = '@define (\'STORAGE_SQLITE\', \'/var/lib/sqlite3/'+self.db.id+'.db\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_DB\'' in l and dbengine == 'mysql':
                l = '@define (\'STORAGE_DB\', \''+self.db.id+'\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_USER\'' in l and dbengine == 'mysql':
                l = '@define (\'STORAGE_USER\', \''+self.db.id+'\');\n'
                oc.append(l)
            elif 'define (\'STORAGE_PASSWORD\'' in l and dbengine == 'mysql':
                l = '@define (\'STORAGE_PASSWORD\', \''+dbpasswd+'\');\n'
                oc.append(l)
            else:
                oc.append(l)
        with open(os.path.join(self.path, 'inc/poche/config.inc.php'), 'w') as f:
            f.writelines(oc)

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('mysql' if dbengine == 'mysql' else 'sqlite3', 
            'pdo_mysql' if dbengine == 'mysql' else 'pdo_sqlite', 
            'zip', 'tidy', 'xcache', 'openssl')

        # Set up Composer and install the proper modules
        php.composer_install(self.path)
        
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid

        # Set up the database then delete the install folder
        if dbengine == 'mysql':
            with open(os.path.join(self.path, 'install/mysql.sql')) as f:
                self.db.execute(f.read())
            self.db.execute(
                "INSERT INTO users (username, password, name, email) VALUES ('%s', '%s', '%s', '');" % (username, passwd, username),
                commit=True)
            lid = int(self.db.manager.connection.insert_id())
            self.db.execute(
                "INSERT INTO users_config (user_id, name, value) VALUES (%s, 'pager', '10');" % lid,
                commit=True)
            self.db.execute(
                "INSERT INTO users_config (user_id, name, value) VALUES (%s, 'language', 'en_EN.UTF8');" % lid,
                commit=True)
        else:
            shutil.copy(os.path.join(self.path, 'install/poche.sqlite'), '/var/lib/sqlite3/%s.db' % self.db.id)
            php.open_basedir('add', '/var/lib/sqlite3')
            os.chown("/var/lib/sqlite3/%s.db" % self.db.id, -1, gid)
            os.chmod("/var/lib/sqlite3/%s.db", 0664)
            self.db.execute(
                "INSERT INTO users (username, password, name, email) VALUES ('%s', '%s', '%s', '');" % (username, passwd, username))
            self.db.execute(
                "INSERT INTO users_config (user_id, name, value) VALUES (1, 'pager', '10');")
            self.db.execute(
                "INSERT INTO users_config (user_id, name, value) VALUES (1, 'language', 'en_EN.UTF8');")
        shutil.rmtree(os.path.join(self.path, 'install'))

        # 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:
                if d in ["assets", "cache", "db"]:
                    os.chmod(os.path.join(r, d), 0755)
                os.chown(os.path.join(r, x), uid, gid)
            for x in f:
                os.chown(os.path.join(r, x), uid, gid)
예제 #31
0
            # Format extraction command according to type
            message.update("info", "Extracting source...", head="Installing website")
            if ending in [".tar.gz", ".tgz", ".tar.bz2"]:
                extract_cmd = "tar "
                extract_cmd += "xzf" if ending in [".tar.gz", ".tgz"] else "xjf"
                extract_cmd += " /tmp/%s -C %s --strip 1" % (self.id+ending, self.path)
            else:
                extract_cmd = "unzip -d %s /tmp/%s" % (self.path, self.id+ending)
            status = shell(extract_cmd)
            if status["code"] >= 1:
                raise Exception(status["stderr"])
            os.remove(pkg_path)

        # Set proper starting permissions on source directory
        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)

        # If there is a custom path for the data directory, set it up
        if hasattr(self.meta, "website_datapaths") and self.meta.website_datapaths \
                and extra_vars.get("datadir"):
            self.data_path = extra_vars["datadir"]
            if not os.path.exists(self.data_path):
                os.makedirs(self.data_path)
            os.chmod(self.data_path, 0755)
예제 #32
0
    def post_install(self, extra_vars, dbpasswd=""):
        php.open_basedir('add', '/dev')

        # If there is a custom path for the data directory, add to open_basedir
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        os.makedirs(os.path.join(self.path, "data"))
        os.chown(os.path.join(self.path, "data"), uid, gid)
        if self.data_path == self.path:
            self.data_path = os.path.join(self.path, "data")
        else:
            try:
                os.makedirs(os.path.join(self.data_path))
            except OSError as e:
                if e[0] == 17:
                    pass
                else:
                    raise
            os.chown(os.path.join(self.data_path), uid, gid)
            php.open_basedir('add', self.data_path)

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('opcache', 'mysql', 'pdo_mysql', 'zip', 'gd', 'ldap',
                       'iconv', 'openssl', 'posix')
        php.enable_mod('apcu', 'apc', config_file="/etc/php/conf.d/apcu.ini")
        php.change_setting('apc.enable_cli',
                           '1',
                           config_file="/etc/php/conf.d/apcu.ini")

        # Make sure php-fpm has the correct settings,
        # otherwise Nextcloud breaks
        with open("/etc/php/php-fpm.conf", "r") as f:
            lines = f.readlines()
        with open("/etc/php/php-fpm.conf", "w") as f:
            for line in lines:
                if ";clear_env = " in line:
                    line = "clear_env = no\n"
                f.write(line)

        php.change_setting("always_populate_raw_post_data", "-1")
        mydir = os.getcwd()
        os.chdir(self.path)
        s = shell(('php occ maintenance:install '
                   '--database "mysql" --database-name "{}" '
                   '--database-user "{}" --database-pass "{}" '
                   '--admin-pass "{}" --data-dir "{}"').format(
                       self.db.id, self.db.id, dbpasswd, dbpasswd,
                       self.data_path))
        if s["code"] != 0:
            logger.critical("Nextcloud", s["stderr"])
            raise Exception("Nextcloud database population failed")
        s = shell("php occ app:enable user_ldap")
        if s["code"] != 0:
            logger.critical("Nextcloud", s["stderr"])
            raise Exception("Nextcloud LDAP configuration failed")
        os.chdir(mydir)
        os.chown(os.path.join(self.path, "config/config.php"), uid, gid)

        ldap_sql = ("REPLACE INTO oc_appconfig "
                    "(appid, configkey, configvalue) VALUES"
                    "('core', 'backgroundjobs_mode', 'cron'),"
                    "('user_ldap', 'ldap_uuid_attribute', 'auto'),"
                    "('user_ldap', 'ldap_host', 'localhost'),"
                    "('user_ldap', 'ldap_port', '389'),"
                    "('user_ldap', 'ldap_base', 'dc=arkos-servers,dc=org'),"
                    "('user_ldap', 'ldap_base_users', "
                    "'dc=arkos-servers,dc=org'),"
                    "('user_ldap', 'ldap_base_groups', "
                    "'dc=arkos-servers,dc=org'),"
                    "('user_ldap', 'ldap_tls', '0'),"
                    "('user_ldap', 'ldap_display_name', 'cn'),"
                    "('user_ldap', 'ldap_userlist_filter', "
                    "'objectClass=mailAccount'),"
                    "('user_ldap', 'ldap_group_filter', "
                    "'objectClass=posixGroup'),"
                    "('user_ldap', 'ldap_group_display_name', 'cn'),"
                    "('user_ldap', 'ldap_group_member_assoc_attribute', "
                    "'uniqueMember'),"
                    "('user_ldap', 'ldap_login_filter', "
                    "'(&(|(objectclass=posixAccount))(|(uid=%uid)))'),"
                    "('user_ldap', 'ldap_quota_attr', 'mailQuota'),"
                    "('user_ldap', 'ldap_quota_def', ''),"
                    "('user_ldap', 'ldap_email_attr', 'mail'),"
                    "('user_ldap', 'ldap_cache_ttl', '600'),"
                    "('user_ldap', 'ldap_configuration_active', '1'),"
                    "('user_ldap', 'home_folder_naming_rule', ''),"
                    "('user_ldap', 'ldap_backup_host', ''),"
                    "('user_ldap', 'ldap_dn', ''),"
                    "('user_ldap', 'ldap_agent_password', ''),"
                    "('user_ldap', 'ldap_backup_port', ''),"
                    "('user_ldap', 'ldap_nocase', ''),"
                    "('user_ldap', 'ldap_turn_off_cert_check', ''),"
                    "('user_ldap', 'ldap_override_main_server', ''),"
                    "('user_ldap', 'ldap_attributes_for_user_search', ''),"
                    "('user_ldap', 'ldap_attributes_for_group_search', ''),"
                    "('user_ldap', 'ldap_expert_username_attr', 'uid'),"
                    "('user_ldap', 'ldap_expert_uuid_attr', '');")
        self.db.execute(ldap_sql, commit=True)
        self.db.execute("DELETE FROM oc_group_user;", commit=True)
        self.db.execute(
            "INSERT INTO oc_group_user VALUES ('admin','{0}');".format(
                extra_vars.get("nc-admin", "admin")),
            commit=True)

        if not os.path.exists("/etc/cron.d"):
            os.mkdir("/etc/cron.d")
        with open("/etc/cron.d/nc-{0}".format(self.id), "w") as f:
            f.write("*/15 * * * * http php -f {0} > /dev/null 2>&1".format(
                os.path.join(self.path, "cron.php")))

        with open(os.path.join(self.path, "config", "config.php"), "r") as f:
            data = f.read()
        while re.search("\n(\s*('|\")memcache.local.*?\n)", data, re.DOTALL):
            data = data.replace(
                re.search("\n(\s*('|\")memcache.local.*?\n)", data,
                          re.DOTALL).group(1), "")
        data = data.split("\n")
        with open(os.path.join(self.path, "config", "config.php"), "w") as f:
            for x in data:
                if not x.endswith("\n"):
                    x += "\n"
                if x.startswith(");"):
                    f.write("  'memcache.local' => '\OC\Memcache\APCu',\n")
                f.write(x)

        rootcerts = os.path.join(self.data_path,
                                 'data/files_external/rootcerts.crt')
        if os.path.exists(rootcerts):
            os.chown(os.path.join(rootcerts), uid, gid)

        self.site_edited()
예제 #33
0
    def post_install(self, vars, dbpasswd=""):
        secret_key = random_string()

        # If there is a custom path for the data directory, add to open_basedir
        uid, gid = users.get_system("http").uid, groups.get_system("http").gid
        if not self.data_path.startswith(self.path):
            os.makedirs(os.path.join(self.path, "data"))
            os.chown(os.path.join(self.path, "data"), uid, gid)
            php.open_basedir('add', self.data_path)

        # Create ownCloud automatic configuration file
        with open(os.path.join(self.path, 'config', 'autoconfig.php'),
                  'w') as f:
            f.write('<?php\n'
                    '   $AUTOCONFIG = array(\n'
                    '   "adminlogin" => "admin",\n'
                    '   "adminpass" => "' + dbpasswd + '",\n'
                    '   "dbtype" => "mysql",\n'
                    '   "dbname" => "' + self.db.id + '",\n'
                    '   "dbuser" => "' + self.db.id + '",\n'
                    '   "dbpass" => "' + dbpasswd + '",\n'
                    '   "dbhost" => "localhost",\n'
                    '   "dbtableprefix" => "",\n'
                    '   "directory" => "' + self.data_path + '",\n'
                    '   );\n'
                    '?>\n')
        os.chown(os.path.join(self.path, 'config', 'autoconfig.php'), uid, gid)

        # Make sure that the correct PHP settings are enabled
        php.enable_mod('mysql', 'pdo_mysql', 'zip', 'gd', 'ldap', 'iconv',
                       'openssl', 'xcache', 'posix')

        # Make sure xcache has the correct settings, otherwise ownCloud breaks
        with open('/etc/php/conf.d/xcache.ini', 'w') as f:
            f.writelines([
                'extension=xcache.so\n', 'xcache.size=64M\n',
                'xcache.var_size=64M\n', 'xcache.admin.enable_auth = Off\n',
                'xcache.admin.user = "******"\n',
                'xcache.admin.pass = "******"\n'
            ])

        php.change_setting("always_populate_raw_post_data", "-1")
        mydir = os.getcwd()
        os.chdir(self.path)
        s = shell("sudo -u http php index.php")
        if s["code"] != 0:
            raise Exception("ownCloud database population failed")
        s = shell("sudo -u http php occ app:enable user_ldap")
        if s["code"] != 0:
            raise Exception("ownCloud LDAP configuration failed")
        os.chdir(mydir)

        ldap_sql = (
            "REPLACE INTO appconfig (appid, configkey, configvalue) VALUES"
            "('user_ldap', 'ldap_uuid_attribute', 'auto'),"
            "('user_ldap', 'ldap_host', 'localhost'),"
            "('user_ldap', 'ldap_port', '389'),"
            "('user_ldap', 'ldap_base', 'dc=arkos-servers,dc=org'),"
            "('user_ldap', 'ldap_base_users', 'dc=arkos-servers,dc=org'),"
            "('user_ldap', 'ldap_base_groups', 'dc=arkos-servers,dc=org'),"
            "('user_ldap', 'ldap_tls', '0'),"
            "('user_ldap', 'ldap_display_name', 'cn'),"
            "('user_ldap', 'ldap_userlist_filter', 'objectClass=mailAccount'),"
            "('user_ldap', 'ldap_group_filter', 'objectClass=posixGroup'),"
            "('user_ldap', 'ldap_group_display_name', 'cn'),"
            "('user_ldap', 'ldap_group_member_assoc_attribute', 'uniqueMember'),"
            "('user_ldap', 'ldap_login_filter', '(&(|(objectclass=posixAccount))(|(uid=%uid)))'),"
            "('user_ldap', 'ldap_quota_attr', 'mailQuota'),"
            "('user_ldap', 'ldap_quota_def', ''),"
            "('user_ldap', 'ldap_email_attr', 'mail'),"
            "('user_ldap', 'ldap_cache_ttl', '600'),"
            "('user_ldap', 'ldap_configuration_active', '1'),"
            "('user_ldap', 'home_folder_naming_rule', ''),"
            "('user_ldap', 'ldap_backup_host', ''),"
            "('user_ldap', 'ldap_dn', ''),"
            "('user_ldap', 'ldap_agent_password', ''),"
            "('user_ldap', 'ldap_backup_port', ''),"
            "('user_ldap', 'ldap_nocase', ''),"
            "('user_ldap', 'ldap_turn_off_cert_check', ''),"
            "('user_ldap', 'ldap_override_main_server', ''),"
            "('user_ldap', 'ldap_attributes_for_user_search', ''),"
            "('user_ldap', 'ldap_attributes_for_group_search', ''),"
            "('user_ldap', 'ldap_expert_username_attr', 'uid'),"
            "('user_ldap', 'ldap_expert_uuid_attr', '');")
        self.db.execute(ldap_sql, commit=True)
        # TODO set authed user name
        self.db.execute("INSERT INTO group_user VALUES ('admin','testuser');",
                        commit=True)