#!/usr/bin/python3
#
# This script is run by a VM host (eg "west") to prepare itself for testing
# It should be passed a testname as its only argument

import os
import sys
import socket
import shutil
import distutils.dir_util
import subprocess
import pexpect
import glob
from pathlib import Path
import re

try:
    import argparse
except ImportError as e:
    module = str(e)[16:]
    sys.exit("we requires the python argparse module")

def path_touch(dst, mode=None):
    if mode: #it is seems unhappy with mode=None
        Path(dst).touch(mode)
    else:
        Path(dst).touch()

def rsync_ap(srs, dst, timer=20):

    cmd = "/usr/bin/rsync --delete -q -aP"
    cmd += " %s %s" % (src, dst)

    try:
        output = subprocess.check_output(cmd, shell=True, timeout=timer, stderr=subprocess.STDOUT)
    except subprocess.TimeoutExpired:
        print( "EXCEPTION TIMEOUT ? cmd %s , cwd %s" % (os.getcwd(), cmd))
    except subprocess.CalledProcessError as e:
         print ("EXCEPTION ? cwd %s , %s %s" % (os.getcwd(), cmd, e.output))

def mount_bind(src, dst, mode=None, touch_src_file=False, mkdir_src=False, wipe_old_dst=False):

    if touch_src_file and mkdir_src:
        print("conflicting options touch_src_file and mkdir_src");

    if mkdir_src and not os.path.isdir(src) and not touch_src_file:
        os.makedirs(src)

    if touch_src_file :
        path_touch(src, mode)

    if wipe_old_dst:
        wipe_old(dst)

    if os.path.isdir(src):
        if not os.path.isdir(dst) and not os.path.islink(dst):
            os.makedirs(dst)
    elif os.path.isfile(src):
        if not os.path.isfile(dst) and not os.path.islink(dst):
            path_touch(dst, mode)
    else:
        mode_str = ''
        if mode:
            mode_str = "mode 0o%o" % mode
        print("mount_bind unknown action src=%s dst=%s %s"
                 % (src, dst, mode_str))
        return True

    cmd = ['/usr/bin/mount', '--bind',  src, dst]

    o = subprocess.run(cmd, stderr=subprocess.PIPE, stdout=subprocess.PIPE,
                        encoding='utf-8')
    if o.returncode:
        print("mount_bind failed %s" % cmd)

    return o.returncode

def lsw_cp_file(src, dst, mode=None, nsbasepath=''):

    if args.namespace:
        ns_dst="%s/%s" %(nsbasepath, dst) #copy to local NS/hostname/<path> then mount
        shutil.copy(src, ns_dst)
        
        if mode:
            os.chmod(ns_dst, mode)
        mount_bind(ns_dst, dst)
    else:
        shutil.copy(src, dst)
        if mode:
            os.chmod(dst, mode)
    return

def umount(dst):
    if os.path.isdir(dst) or os.path.isfile(dst):
        subprocess.getoutput("/usr/bin/umount %s" % dst)
    else:
        if os.path.islink(dst):
            os.unlink(dst)

def wipe_old(dst):
    if args.namespace:
        umount(dst)
    else:
        if os.path.islink(dst) or os.path.isfile(dst):
            os.unlink(dst)
        elif os.path.isdir(dst):
            shutil.rmtree(dst)
        # else: #no existing file
        #   print("can not wipe unknown type %s" % dst)

def shell(command, out=False):
    """Run command as a sub-process and report failures"""
    if args.verbose:
        print(command)
    status, output = subprocess.getstatusoutput(command)
    if status:
        print(("command '%s' failed with status %d: %s" %
               (command, status, output)))
    elif (args.verbose or out) and output:
        print(output)
    return output

# prevent double installs from going unnoticed
if os.path.isfile("/usr/libexec/ipsec/pluto"):
    if os.path.isfile("/usr/local/libexec/ipsec/pluto"):
        sys.exit("\n\n---------------------------------------------------------------------\n"
                 "ABORT: found a swan userland in the base system as well as /usr/local\n"
                 "---------------------------------------------------------------------\n")

ipv = 0
ipv6 = 0
parser = argparse.ArgumentParser(description='swan-prep arguments')
parser.add_argument('--testpath', '-t', action='store',
                    default=os.getcwd(), help="Test directory full path %s " % os.getcwd())
parser.add_argument('--hostname', '-H', action='store',
                    default='', help='The name of the host to prepare as')
# we should get this from the testparams.sh file?
parser.add_argument('--userland', '-u', action='store',
                    default='libreswan', help='which userland to prepare')
parser.add_argument('--x509', '-x', action='store_true',
                    help='create X509 NSS file by importing test certs')
parser.add_argument('--dnssec', '-d', action='store_true',
                    help='start nsd and unbound for DNSSEC - meant only for nic')
parser.add_argument('--nsd', action='store_true',
                    help='start nsd only for DNSSEC')
parser.add_argument('--x509name', '-X', action='store', default="",
                    help='create X509 NSS file by importing test certs')
parser.add_argument('--fips', '-f', action='store_true',
                    help='prepare /etc/ipsec.d for running in FIPS mode')
parser.add_argument('--revoked', '-r', action='store_true',
                    help='load a revoked certificate')
parser.add_argument('--signedbyother', '-o', action='store_true',
                    help='load the signedbyother certificate')
parser.add_argument('--eccert', '-e', action='store_true',
                    help='enable an EC cert for this host')
parser.add_argument('--nsspw', action='store_true',
                    help='set the security password (on the NSS DB)')
parser.add_argument('--certchain', '-c', action='store_true',
                    help='import the ca-chain test certs')
parser.add_argument('--46', '--64', action='store_true',
                    help='Do not disable IPv6. Default is disable IPv6 ', dest='ipv', default=False)
parser.add_argument('--6', action='store_true',
                    help='Enable IPv6 and run - /etc/init.d/network restart', dest='ipv6', default=False)
parser.add_argument('--verbose', '-v', action='store_true',
                    help='more verbose')
parser.add_argument('--nokeys', action='store_true',
                    help='do not provide any keys')
parser.add_argument('--namespace', action='store_true',
        default='', help='Running inside name sapace')
args = parser.parse_args()

if args.hostname:
    hostname = args.hostname
else:
    hostname = socket.gethostname()

if "." in hostname:
    hostname = hostname.split(".")[0]

# Validate this is sane?
testpath = args.testpath
if not os.path.isdir(testpath):
    sys.exit("Unknown or bad testpath '%s'" % args.testname)

testname = os.path.basename(testpath)

namespace = ''

#this does not work:)
if not args.namespace:
    namespace = os.getenv('SWAN_TEST_NS')
    if namespace:
        args.namespace = True

o = subprocess.run(['ip' , '-o', 'link' , 'show', 'dev', 'eth0'], stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="ascii")
ifname = o.stdout.split(' ')[1]
if o.returncode:
    print("can not find eht0? where are we %s\n%s" % i (o.output, o.stderr))
    sys.exit(1)
if re.match(r'eth0@if\d+', ifname):
    args.namespace = True

if args.namespace:
    nsbasepath="%s/NS/%s" % (testpath, hostname) #will create testpath/NS/hostname/*
    if not os.path.isdir(nsbasepath):
        os.makedirs(nsbasepath)
else:
    nsbasepath = ''

# Setup pluto.log softlink and bindmount in namespace
if hostname != "nic":
    subprocess.run(["ipsec", "stop"], stdout=subprocess.PIPE, stderr=subprocess.PIPE, encoding="ascii") # gentle try before wiping files and killall

    outputdir = "%s/OUTPUT/" % testpath
    if not os.path.isdir(outputdir):
        os.mkdir(outputdir)
        os.chmod(outputdir, 0o777)

    if args.userland in ("libreswan", "openswan"):
        dname = "pluto"
    elif args.userland == "strongswan":
        dname = "charon"
    else:
        dname = "iked"

    daemonlogfile = "%s/%s.%s.log" % (outputdir, hostname, dname)
    tmplink = "/tmp/%s.log" % dname 
    wipe_old(tmplink)

    Path(daemonlogfile).touch(mode=0o777)

    if args.namespace :
        mount_bind(daemonlogfile, tmplink, touch_src_file=True)
    else :
        os.symlink(daemonlogfile, tmplink)
   
if args.userland:
    if not args.userland in ("libreswan", "strongswan", "openswan"):
        sys.exit("swan-prep: unknown userland type '%s'" % args.userland)
    userland = args.userland
else:
    userland = "libreswan"

# print "swan-prep running on %s for test %s with userland
# %s"%(hostname,testname,userland)

# wipe any old configs in /etc/ipsec.*
wipe_old("/etc/ipsec.conf")
wipe_old("/etc/ipsec.secrets")
wipe_old("/etc/ipsec.d")

# if using systemd, ensure we don't restart pluto on crash
if os.path.isfile("/lib/systemd/system/ipsec.service") and not args.namespace:
    service = "".join(open("/lib/systemd/system/ipsec.service").readlines())
    if "Restart=always" in service:
        fp = open("/lib/systemd/system/ipsec.service", "w")
        fp.write("".join(service).replace("Restart=always", "Restart=no"))
    # always reload to avoid "service is masked" errors
    subprocess.getoutput("/usr/bin/systemctl daemon-reload")

# AA_201902 what happens to audit log namespace
# we have to cleanup the audit log or we could get entries from previous test
if os.path.isfile("/var/log/audit/audit.log"):
    fp = open("/var/log/audit/audit.log", "w")
    fp.close()
    if os.path.isfile("/lib/systemd/system/auditd.service"):
        subprocess.getoutput("/usr/bin/systemctl restart auditd.service")

# disable some daemons that could cause noise packets getting encrypted
if not args.namespace :
    subprocess.getoutput("/usr/bin/systemctl stop chronyd")
    subprocess.getoutput("/usr/bin/systemctl stop sssd")

# ensure cores are just dropped, not sent to aobrt-hook-ccpp or systemd.
# setting /proc/sys/kernel/core_pattern to "core" or a pattern does not
# work. And you cannot use shell redirection ">". So we hack it with "tee"
pattern = "|/usr/bin/tee /tmp/core.%h.%e.%p"
fp = open("/proc/sys/kernel/core_pattern", "w")
fp.write(pattern)
fp.close()

if userland == "libreswan" or userland == "openswan" or userland == "strongswan":
    # copy in base configs
    prefix = ""

if hostname != "nic":

    ipsec_d_dir = "strongswan/" if userland == "strongswan" else "ipsec.d"

    src = "%s/etc/%s" % (nsbasepath, ipsec_d_dir)
    dst = "/etc/%s" % (ipsec_d_dir)
    if args.namespace :
        if mount_bind(src, dst, mkdir_src=True,  wipe_old_dst=True):
            sys.exit(1)

    if args.userland in ("libreswan", "openswan"):
        dst = "/run/pluto"
    elif args.userland in ("strongswan"):
        dst="/run/strongswan"
    src = "%s%s" % (nsbasepath, dst)
    if args.namespace :
        if mount_bind(src, dst, mkdir_src=True, wipe_old_dst=False):
            sys.exit(1)

    if args.userland in ("libreswan", "openswan"):
        # this brings in the nss *.db files that are path-specific -
        # they have pathnames hardcoded inside the file
        # shutil.copytree("/testing/baseconfigs/%s/etc/ipsec.d"%hostname,
        # "/etc/").  This default database contains a default key-pair
        # for basic testing.
        distutils.dir_util.copy_tree("/testing/baseconfigs/%s/etc/ipsec.d" % hostname, "/etc/ipsec.d/")
        # fill in any missing dirs
    elif args.userland in ("strongswan"):
        prefix = "strongswan/"
        dst = "/etc/strongswan/ipsec.d"
        if not os.path.isdir(dst):
            os.mkdir(dst)

    for dir in ("/etc/%sipsec.d" % prefix, "/etc/%sipsec.d/policies" % prefix, "/etc/%sipsec.d/cacerts" % prefix, "/etc/%sipsec.d/crls" % prefix, "/etc/%sipsec.d/certs" % prefix, "/etc/%sipsec.d/private" % prefix):
        if not os.path.isdir(dir):
            os.mkdir(dir)
            if "private" in dir:
                os.chmod(dir, 0o700)
        else:
            oldfiles = glob.glob("%s/*.der"%dir) + glob.glob("%s/*.crt"%dir) + glob.glob("%s/*.pem"%dir) + glob.glob("%s/*.key"%dir)
            for oldfile in oldfiles:
                os.unlink(oldfile)

        # test specific files
        ipsecconf = "%s/ipsec.conf" % (testpath)
        ipsecsecrets = "%s/ipsec.secrets" % (testpath)
        h_ipsecconf = "%s/%s.conf" % (testpath, hostname)
        h_ipsecsecrets = "%s/%s.secrets" % (testpath, hostname)
        xl2tpdconf = "%s/%s.xl2tpd.conf" % (testpath, hostname)
        pppoptions = "%s/%s.ppp-options.xl2tpd" % (testpath, hostname)
        chapfile = "%s/chap-secrets" % testpath

        if os.path.isfile(h_ipsecconf):
            if os.path.isfile(ipsecconf):
                print("conflicting files %s %s" % (ipsecconf, h_ipsecconf))
            else:
                ipsecconf = h_ipsecconf
        elif not os.path.isfile(ipsecconf) and args.userland in ("libreswan", "openswan") :
            ipsecconf = "/testing/baseconfigs/%s/etc/ipsec.conf" % hostname

        if os.path.isfile(h_ipsecsecrets):
            if os.path.isfile(ipsecsecrets):
               print("conflicting files %s %s" % (ipsecsecrets, h_ipsecsecrets))
            else:
                ipsecsecrets = h_ipsecsecrets
        elif not os.path.isfile(ipsecsecrets):
            ipsecsecrets = "/testing/baseconfigs/%s/etc/ipsec.secrets" % hostname

        if args.userland == "strongswan":
            # check version and fail early
            output = subprocess.getoutput("strongswan version")
            if not "U5.8.2" in output:
                sys.exit("strongswan 5.8.2 must be installed")
            # required to write log file in /tmp
            subprocess.getoutput("setenforce 0")
            strongswanconf = "%s/%sstrongswan.conf" % (testpath, hostname)
            shutil.copy(strongswanconf, "/etc/strongswan/strongswan.conf")
            for dir in ("/etc/strongswan/ipsec.d/aacerts", "/etc/strongswan/ipsec.d/ocspcerts"):
                if not os.path.isdir(dir):
                    os.mkdir(dir)

        dstconf = "/etc/%sipsec.conf" % (prefix)
        dstsecrets = "/etc/%sipsec.secrets" % (prefix)

        lsw_cp_file(ipsecconf, dstconf, nsbasepath=nsbasepath)
        lsw_cp_file(ipsecsecrets, dstsecrets, mode=0o666, nsbasepath=nsbasepath)

        if os.path.isfile(xl2tpdconf):
            lsw_cp_file(xl2tpdconf, "/etc/xl2tpd/xl2tpd.conf", nsbasepath=nsbasepath)
        if os.path.isfile(pppoptions):
           lsw_cp_file(pppoptions, "/etc/ppp/options.xl2tpd", nsbasepath=nsbasepath)
        if os.path.isfile(chapfile):
            lsw_cp_file(chapfile, "/etc/ppp/chap-secrets", nsbasepath=nsbasepath)

        if not args.namespace:
            dbfiles = glob.glob("/etc/ipsec.d/*db")
            for dbfile in dbfiles:
                os.chown(dbfile, 0, 0)

    # restore /etc/hosts to original - some tests make changes
    lsw_cp_file("/testing/baseconfigs/all/etc/hosts", "/etc/hosts", nsbasepath=nsbasepath)
    resolv = "/testing/baseconfigs/all/etc/resolv.conf"
    if os.path.isfile("/testing/baseconfigs/%s/etc/resolv.conf" % hostname):
        resolv = "/testing/baseconfigs/%s/etc/resolv.conf" % hostname
    else:
        resolv = "/testing/baseconfigs/all/etc/resolv.conf"
    dst = "/etc/resolv.conf"
    if not args.namespace and os.path.islink(dst): # on fedora 22 it is link frist remove the link
        os.unlink(dst)
    lsw_cp_file(resolv, "/etc/resolv.conf", nsbasepath=nsbasepath)

sysconfigd = "%s/etc/sysconfig" % (nsbasepath)
if not os.path.isdir(sysconfigd):
    os.makedirs(sysconfigd)

if args.userland in ("libreswan", "openswan") and hostname != "nic":
    if args.fips and args.userland in ("libreswan", "openswan"):
        # the test also requires using a modutil cmd which we cannot run here
        shutil.copyfile("/testing/baseconfigs/all/etc/sysconfig/pluto.fips", "/etc/sysconfig/pluto")
    else:
        lsw_cp_file("/testing/baseconfigs/all/etc/sysconfig/pluto", "/etc/sysconfig/pluto",
                nsbasepath=nsbasepath)
    if os.path.isfile("/etc/system-fips"):
        wipe_old("/etc/system-fips") # would work? would remove file from real system? AA_201902

# Set up NSS DB
if userland in ("libreswan", "openswan"):

    # Set password options.
    if args.nsspw or args.fips:
        dbpassword = "s3cret"
        util_pw = " -f /run/pluto/nsspw"
        p12cmd_pw = " -k /run/pluto/nsspw"
        with open("/run/pluto/nsspw", "w") as f:
            f.write(dbpassword)
            f.write("\n")
        with open("/etc/ipsec.d/nsspassword", "w") as f:
            if args.nsspw:
                f.write("NSS Certificate DB:" + dbpassword + "\n")
            if args.fips:
                f.write("NSS FIPS 140-2 Certificate DB:" + dbpassword + "\n")
    else:
        util_pw = ""
        p12cmd_pw = " -K ''"

    if args.x509 or args.nokeys:
        # Delete any existing db files, and start fresh.
        if args.x509:
            print("Preparing X.509 files")
        else:
            print("Creating empty NSS database")
        oldfiles = glob.glob("/etc/ipsec.d/*db")
        for oldfile in oldfiles:
            os.unlink(oldfile)
        shell("/usr/bin/certutil -N --empty-password -d sql:/etc/ipsec.d")

    # If needed set a password (this will upgrade any existing
    # database database)
    if args.nsspw or args.fips:
        with open("/tmp/pw", "w") as f:
            f.write("\n")
        shell("/usr/bin/certutil -W -f /tmp/pw -@ /run/pluto/nsspw -d sql:/etc/ipsec.d", out=True)

    # Switch on fips in the NSS db
    if args.fips:
        shell("/usr/bin/modutil -dbdir sql:/etc/ipsec.d -fips true -force", out=True)

    # this section is getting rough. could use a nice refactoring
    if args.x509:
        if userland == "strongswan":
            shutil.rmtree("/etc/strongswan/ipsec.d/cacerts/")
            os.mkdir("/etc/strongswan/ipsec.d/cacerts/")

        if not os.path.isfile("/testing/x509/keys/mainca.key"):
            print("\n\n---------------------------------------------------------------------\n"
                  "WARNING: no mainca.key file, did you run testing/x509/dist_certs.py?\n"
                  "---------------------------------------------------------------------\n")

        if args.eccert:
            p12 = hostname + "-ec"
            ca = "curveca"
            pw = "-W \"\""
        else:
            if args.x509name:
                p12 = args.x509name
            else:
                p12 = hostname
            ca = "mainca"
            pw = "-w /testing/x509/nss-pw"

        if args.certchain:
            icanum = 2
            pw = "-w /testing/x509/nss-pw"
            root = "mainca"
            ica_p = hostname + "_chain_int_"
            ee = hostname + "_chain_endcert"

            # a note about DB trusts
            # 'CT,,' is our root's trust. T is important!! it is for verifying "SSLClient" x509 KU
            # ',,' is an intermediate's trust
            # 'P,,' (trusted peer) is nic's for OCSP
            # 'u,u,u' will be end cert trusts that are p12 imported (with privkey)

            # mainca and nic import
            shell("/usr/bin/certutil -A -n %s -t 'CT,,' -d sql:/etc/ipsec.d/ -a -i /testing/x509/cacerts/%s.crt%s" %
                  (root, root, util_pw))
            shell("/usr/bin/certutil -A -n nic -t 'P,,' -d sql:/etc/ipsec.d/ -a -i /testing/x509/certs/nic.crt%s" % util_pw)

            # install ee
            shell("/usr/bin/pk12util -i /testing/x509/pkcs12/%s.p12 -d sql:/etc/ipsec.d %s%s" %
                  (ee, pw, p12cmd_pw))

            # install intermediates
            for i in range(1, icanum + 1):
                acrt = ica_p + str(i)
                shell("/usr/bin/certutil -A -n %s -t ',,' -d sql:/etc/ipsec.d/ -a -i /testing/x509/certs/%s.crt%s" %
                      (acrt, acrt, util_pw))
            if args.revoked:
                shell("/usr/bin/pk12util -i /testing/x509/pkcs12/%s_revoked.p12 -d /etc/ipsec.d %s%s" %
                      (hostname + "_chain", pw, p12cmd_pw))

        else:
            shell("/usr/bin/pk12util -i /testing/x509/pkcs12/%s/%s.p12 -d sql:/etc/ipsec.d %s%s" %
                  (ca, p12, pw, p12cmd_pw))
            # install all other public certs
            # libreswanhost = os.getenv("LIBRESWANHOSTS") #kvmsetu.sh is not
            # sourced

            if args.revoked:
                shell(
                    "/usr/bin/pk12util -i /testing/x509/pkcs12/mainca/revoked.p12 -d sql:/etc/ipsec.d %s%s" % (pw, p12cmd_pw))

            if args.signedbyother:
                shell(
                    "/usr/bin/pk12util -i /testing/x509/pkcs12/otherca/signedbyother.p12 -d sql:/etc/ipsec.d %s%s" % (pw, p12cmd_pw))

            # fix trust import from p12
            # is pw needed?
            shell("/usr/bin/certutil -M -n 'Libreswan test CA for mainca - Libreswan' -d sql:/etc/ipsec.d/ -t 'CT,,'%s" % (util_pw))

            for certname in ("west", "east", "road", "north", "hashsha1", "west-ec", "east-ec", "nic"):
                if not hostname in certname:
                    shell("/usr/bin/certutil -A -n %s -t 'P,,' -d sql:/etc/ipsec.d -a -i /testing/x509/certs/%s.crt%s" %
                          (certname, certname, util_pw))

# Don't enable FIPS mode until after NSS DBS are created.  See:
# https://bugzilla.mozilla.org/show_bug.cgi?id=1531267
if args.fips:
    fp = open("/etc/system-fips", "w")
    fp.close()
    shell("/testing/guestbin/fipson")

# Strong swan has simple files.
if userland == "strongswan" and args.x509:
    if args.eccert:
        ca = "curveca"
        key = hostname + "-ec"
    else:
        ca = "mainca"
        key = hostname

    shutil.copy("/testing/x509/cacerts/%s.crt" %
                ca, "/etc/strongswan/ipsec.d/cacerts/")
    shutil.copy("/testing/x509/keys/%s.key" %
                key, "/etc/strongswan/ipsec.d/private/")

    for certname in ("west", "east", "road", "north", "hashsha1", "west-ec", "east-ec"):
        shutil.copy("/testing/x509/certs/%s.crt" %
                    certname, "/etc/strongswan/ipsec.d/certs/")

if hostname != "nic" and not args.ipv:
    subprocess.getoutput("sysctl net.ipv6.conf.all.disable_ipv6=1")
    subprocess.getoutput("sysctl net.ipv6.conf.default.disable_ipv6=1")

if args.ipv6:
    subprocess.getoutput("sysctl net.ipv6.conf.all.disable_ipv6=0")
    subprocess.getoutput("sysctl net.ipv6.conf.default.disable_ipv6=0")
 
    if not args.namespace: # AA_201902 check if this works inside ns
        if os.path.isfile("/usr/bin/systemctl"):
            subprocess.getoutput("systemctl restart systemd-networkd")
        else:
            subprocess.getoutput("service network restart")

if args.dnssec and not args.namespace:
        subprocess.getoutput("systemctl nsd start")
        subprocess.getoutput("systemctl unbound start")

if args.nsd or args.dnssec:
    if args.namespace:
        dst = "/etc/nsd"
        src = "%s%s" % (nsbasepath, dst)

        if mount_bind(src, dst, mkdir_src=True, wipe_old_dst=True):
            sys.exit(1)

        dst ="/run/nsd"
        src = "%s%s" % (nsbasepath, dst)
        if mount_bind(src, dst, mkdir_src=True, wipe_old_dst=True):
            sys.exit(1)

        if mount_bind(src, dst, mkdir_src=True, wipe_old_dst=True):
            print("failed to mount_bind src=%s dst %s" % (src, dst))
            sys.exit(1)

        src = '/testing/baseconfigs/nic/etc/nsd'
        dst = '/etc'
        rsync_ap(src, dst);
        cmd = "../../pluto/bin/nsd-start.sh --restart"
        output = subprocess.check_output(cmd, shell=True, timeout=20, stderr=subprocess.STDOUT)
    else:
        subprocess.getoutput("systemctl nsd start")


if not os.path.isfile("/root/.gdbinit"):
    fp = open("/root/.gdbinit", "w")
    fp.write("set auto-load safe-path /")
    fp.close()

subprocess.getoutput("iptables -F");
subprocess.getoutput("iptables -X");

# Create LOGDROP (used to be done in swan-transmogrify but we want it here
# for docker)
for ipt in ("iptables", "ip6tables"):
    subprocess.getoutput("%s -N LOGDROP " % ipt)
    subprocess.getoutput("%s -A LOGDROP -j LOG" % ipt)
    subprocess.getoutput("%s -A LOGDROP -j DROP" % ipt)

if not args.namespace and hostname != "nic": # inside namespace this would kill pluto from other ns
    # shouldn't happen early on? now wiped run time files pid etc.
    # this is probably a last resort? may be a more gentle attempt at the begining.
    #
    # final prep - this kills any running userland
    subprocess.call(["systemctl", "stop", "ipsec"])
    # for some reason this fails to stop strongswan?
    subprocess.call(["systemctl", "stop", "strongswan"])
    # python has no pidof - just outsource to the shell, thanks python!
    for dname in ( "pluto", "charon", "starter", "iked" ):
        try:
            if args.verbose:
                print ("INFO found daemon runing stop it %s" % dname)
            subprocess.check_output(["killall", "-9", dname], stderr=subprocess.STDOUT)
        except:
            pass

    if os.path.isfile("/usr/sbin/getenforce"):
        selinux = subprocess.getoutput("/usr/sbin/getenforce")
        if os.path.isfile("/usr/sbin/restorecon") and selinux == 'Enforcing':
            subprocess.getoutput("restorecon -Rv /etc/ipsec.* /var/lib/ipsec /usr/local/libexec/ipsec /usr/local/sbin/ipsec")

for pidfile in ("/var/run/pluto/pluto.pid", "/var/run/strongswan/charon.pid", "/var/run/charon.pid", "/var/run/spmd.pid", "/var/run/starter.charon.pid"):
    if os.path.isfile(pidfile):
        os.unlink(pidfile)

if not args.namespace:
    # remove stacks so test can start the stack it needs.
    subprocess.getoutput("ipsec _stackmanager stop")
