### Copyright 1999-2014. Parallels IP Holdings GmbH. All Rights Reserved.

import sys, os, urllib2, tempfile, tarfile, shutil
from contextlib import closing
from plesk_atomic import create_include_conf, pack_archive, comment_plesk_managed_directives, TORTIX_WAF_FILENAME

SUBSCRIPTION_PATH = "http://updates.atomicorp.com/channels/rules/subscription/"
ATOMIC_WAF_CONF_URL = "http://www.atomicorp.com/installer/tortix_waf.conf"

ASL_WHITELIST_PATH = "/etc/asl/whitelist"
ASL_CUSTOM_DOMAIN_BLOCKS = "/etc/asl/custom-domain-blocks"

exclude_confings = [
    "05_asl_scanner.conf",
    "11_asl_data_loss.conf",
    "15_asl_paranoid_rules.conf",
    "40_asl_apache2-rules.conf",
    "70_asl_csrf_experimental.conf",
    "98_asl_jitp.conf",
    "99_asl_a_redactor.conf",
    "99_asl_redactor.conf",
    "99_asl_redactor_post.conf",
    "99_asl_scanner.conf",
]

def make_opener(base_url, username, password):
    manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
    manager.add_password(realm=None,
            uri="%s/" % (base_url),
            user=username,
            passwd=password)
    auth_handler = urllib2.HTTPBasicAuthHandler(manager)
    return urllib2.build_opener(auth_handler)

def fetch_version(opener, base_url):
    f = opener.open("%s/VERSION" % (base_url))
    for line in f:
        (key, value) = line.strip().split("=")
        if key == "MODSEC_VERSION":
            return value

def fetch_archive(opener, base_url, version, tmp_file):
    f = opener.open("%s/modsec-%s.tar.gz" % (base_url, version))
    with open(tmp_file, 'w') as out:
        for line in f:
            out.write(line)

def fetch_tortix_waf_conf(path):
    with open(path, "w") as fout:
        with closing(urllib2.urlopen(ATOMIC_WAF_CONF_URL)) as fin:
            for line in fin:
                fout.write(line)

def unpack_archive(src_arch, dest_dir):
    arch = tarfile.open(src_arch)
    arch.extractall(dest_dir)

def disable_configs(path, confs):
    save_dir = os.getcwd()
    os.chdir(path)
    for f in confs:
        os.rename(f, f + ".disabled")
    os.chdir(save_dir)

def create_user_defined_lists():
    for path in [ASL_WHITELIST_PATH, ASL_CUSTOM_DOMAIN_BLOCKS]:
        if os.path.isfile(path):
            continue
        sys.stderr.write("Creating empty file: %s\n" % path)
        if not os.path.isdir(os.path.dirname(path)):
            os.makedirs(os.path.dirname(path), 0755)
        open(path, "a").close()

def main():
    temp_dir = None
    try:
        username = os.environ["MODSEC_VENDOR_LOGIN"]
        password = os.environ["MODSEC_VENDOR_PASS"]

        target_archive_path = sys.argv[1]

        temp_dir = tempfile.mkdtemp()
        vendor_archive_path = os.path.join(temp_dir, "atomic-vendor.tar.gz")
        include_conf_name = "plesk_init.conf.tpl"
        include_conf_path = os.path.join(temp_dir, include_conf_name)
        modsec = "modsec"
        modsec_dir = os.path.join(temp_dir, "modsec")
        tortix_waf_conf_path = os.path.join(modsec_dir, TORTIX_WAF_FILENAME)

        opener = make_opener(SUBSCRIPTION_PATH, username, password)
        atomic_version = fetch_version(opener, SUBSCRIPTION_PATH)
        fetch_archive(opener, SUBSCRIPTION_PATH, atomic_version, vendor_archive_path)
        unpack_archive(vendor_archive_path, temp_dir)
        fetch_tortix_waf_conf(tortix_waf_conf_path)
        comment_plesk_managed_directives(tortix_waf_conf_path)
        create_include_conf(include_conf_path)
        create_user_defined_lists()
        disable_configs(modsec_dir, exclude_confings)
        pack_archive(temp_dir, [modsec, include_conf_name], target_archive_path)
    except Exception as ex:
        sys.stderr.write("%s\n" % ex)
        sys.exit(1)
    finally:
        if temp_dir:
            shutil.rmtree(temp_dir, ignore_errors=True)

if __name__ == "__main__":
    main()

# vim: ts=4 sts=4 sw=4 et :
