#!/bin/sh

ROOT=
PASSWD=
SSHKEYS=
MEC_PASSWORD=
VERBOSE=0
TEST=0
DRYRUN=0
FIREWALL=0

ARGS=$@
OPTS=`getopt -o r:p:tnvfh -l root:,passwd:,ssh-key:,mec-passwd:,test,dry-run,verbose,firewall,help -- "$@"`
[ $? = 0 ] || exit 1
eval set -- "$OPTS"

while true ; do
    case "$1" in
        -r|--root) ROOT=$2 ; shift 2 ;;
        -p|--passwd) PASSWD="$PASSWD $2" ; shift 2 ;;
        --ssh-key) SSHKEYS="$SSHKEYS $2" ; shift 2 ;;
        --mec-passwd) MEC_PASSWORD="$2" ; shift 2 ;;
        -f|--firewall) FIREWALL=1 ; shift ;;
        -t|--test) TEST=1 ; shift ;;
        -n|--dry-run) DRYRUN=1; shift ;;
        -v|--verbose) VERBOSE=1 ; shift ;;
        -h|--help)
            echo -e >&2 "Usage: $0 [options]\n" ;
            echo -e >&2 "Options:" ;
            echo -e >&2 " -r, --root=<rootfs>        Lockdown the target rootfs instead of current rootfs" ;
            echo -e >&2 " -p, --passwd=<user>:<pass> Change <user>'s password to <pass>" ;
            echo -e >&2 " --ssh-key=<user>[:<pass>]  Set ssh key-pair for <user> using <pass> as passphrase" ;
            echo -e >&2 "                            If no this option given, gwuser with no pass is used" ;
            echo -e >&2 " --mec-passwd=<pass>        Set McAfee MEC password to <pass>" ;
            echo -e >&2 " -f, --firewall             lockdown firewall" ;
            echo -e >&2 " -t, --test                 Test the system, and do not really run lockdown action" ;
            echo -e >&2 " -n, --dry-run              Perform a trial run with no changes made" ;
            echo -e >&2 " -v, --verbose              Print verbose messages" ;
            echo -e >&2 " -h, --help                 Print this usage message" ;
            exit 1 ;;
        --) shift ; break ;;
        *) echo "Error! Invalid option \"$1\"" ; exit 1 ;;
    esac
done

if [ "$DRYRUN" = 1 ]; then
	exit 0
fi

if [ "$TEST" != 1 ] && [ -z "$ROOT" ] && [ -z "$CHROOT_LOCKDOWN_ROOT" ]; then
	echo -e >&2 "Please set target rootfs while doing lockdown, using -r/--root option." ;
	exit 1
fi

if [ "$TEST" != 1 ] && [ -d "$ROOT" ]; then
	[ "$VERBOSE" = 1 ] && echo "* Generate and deploy ssh keys."
	[ -z "$SSHKEYS" ] && SSHKEYS=gwuser
	for i in $SSHKEYS ; do
		SSHUSER=`echo $i | awk -F: '{print $1}'`
		SSHPASS=`echo $i | awk -F: '{print $2}'`
		SSHUSER_GROUP=`id -gn $SSHUSER`
		SSHUSER_HOME=`cat /etc/passwd | grep "^$SSHUSER:" | cut -d: -f6`
		/lib/lockdown/sshkey.sh "$SSHUSER" "$SSHPASS" || exit 1
		if [ "`readlink -f $ROOT`" != "/" ]; then
			rm -rf $ROOT$SSHUSER_HOME/.ssh
			install -o $SSHUSER -g $SSHUSER_GROUP -m 700 -d $ROOT$SSHUSER_HOME/.ssh
			install -o $SSHUSER -g $SSHUSER_GROUP -m 600 $SSHUSER_HOME/.ssh/authorized_keys $ROOT$SSHUSER_HOME/.ssh
		fi
	done
fi

if [ -d "$ROOT" ] && [ "`readlink -f $ROOT`" != "/" ]; then
	cd $ROOT
	mount -t proc proc proc
	mount -t sysfs sys sys
	mount -t devtmpfs devtmpfs dev

	chroot $ROOT /bin/systemd-tmpfiles --create --remove --boot 2>/dev/null

	export CHROOT_LOCKDOWN_ROOT="$ROOT"
	chroot $ROOT /sbin/lockdown $ARGS --root=""
	RET=$?

	chroot $ROOT /bin/systemd-tmpfiles --clean 2>/dev/null

	umount -l dev
	umount -l sys
	umount -l proc

	[ $RET = 0 ] || exit 1
	MEC_PASSWORD="$MEC_PASSWORD" /lib/lockdown/mec.sh $ROOT || RET=1
	exit $RET
fi

if [ "$TEST" = 1 ]; then
	cd /lib/lockdown/test
	for s in *.sh ; do
		awk -F'\t' -vf=$s '$1".sh"==f{print $1". "$3}' /lib/lockdown/checklist
		if [ $VERBOSE = 1 ]; then
			./$s && echo "> Pass." || echo "> Fail."
		else
			./$s >/dev/null 2>&1 && echo "> Pass." || echo "> Fail."
		fi
	done
	exit 0
fi

# Remove develop packages
[ "$VERBOSE" = 1 ] && echo "* Remove DevHub."
/lib/lockdown/devhub.sh
[ "$VERBOSE" = 1 ] && echo "* Remove Nodejs npm/red."
/lib/lockdown/nodejs.sh
[ "$VERBOSE" = 1 ] && echo "* Remove Develop Packages."
/lib/lockdown/toolchain.sh

# Run fix scripts in STIGs checklist
[ "$VERBOSE" = 1 ] && echo "* Harden system."
/lib/lockdown/home.sh
cd /lib/lockdown/scripts
for s in *.sh ; do
	if [ $VERBOSE = 1 ]; then
		awk -F'\t' -vf=$s '$1".sh"==f{print $1". "$3}' /lib/lockdown/checklist
		./$s || exit 1
	else
		./$s >/dev/null 2>&1 || { echo "Failed on "$s"." && exit 1 ; }
	fi
done

# Run other lockdown scripts
[ "$VERBOSE" = 1 ] && echo "* Harden EMS."
/lib/lockdown/ems.sh
[ "$VERBOSE" = 1 ] && echo "* Harden nginx."
/lib/lockdown/nginx.sh
[ "$VERBOSE" = 1 ] && echo "* Harden sshd."
/lib/lockdown/sshd.sh
if [ "$FIREWALL" = 1 ]; then
	[ "$VERBOSE" = 1 ] && echo "* Harden firewall."
	/lib/lockdown/firewall.sh
fi
[ "$VERBOSE" = 1 ] && echo "* Harden smart."
/lib/lockdown/smart.sh

# Clean update-rc.d save directory for services of uninstalled packages
if [ -d "/var/lib/update-rc.d" ]; then
	cd /var/lib/update-rc.d
	for i in * ; do
		[ -x /etc/init.d/$i ] || rm -rf /var/lib/update-rc.d/$i
	done
	# Remove update-rc.d save directory only if empty(no -f flag)
	rm -r /var/lib/update-rc.d 2>/dev/null
fi

if [ -z "$CHROOT_LOCKDOWN_ROOT" ]; then
	[ "$VERBOSE" = 1 ] && echo "* Enable MEC protection."
	MEC_PASSWORD="$MEC_PASSWORD" /lib/lockdown/mec.sh || exit 1
fi

# Change password for users
[ -n "$PASSWD" ] && [ "$VERBOSE" = 1 ] && echo "* Change password for users."
for i in $PASSWD ; do
	echo "$i" | chpasswd
        user=${i%%:*}
        pass=${i#*:}
        if [ "x$user" == "xgwuser" ]; then
            [ -x "/usr/sbin/nginx-pass" ] && {
                /usr/sbin/nginx-pass -u gwuser "$pass" > /dev/null 2>&1
            }
        fi
done

exit 0
