#!/bin/sh -fu

PLYMOUTH_BIN="/bin/plymouth"
REPORT_LOG_BASE=/var/log/lastosec

## Add other profiles here
KNOWN_BASE_PROFILES='container vm'

## Add a profile-specific things for pipe.conf here
customize_profile() {
    case "$1" in
	vm)
            cat <<EOF
IGNORE_FIELDS=inode
EOF
	    ;;
    esac
}


### Main

show_usage() {
    echo "Usage: ${0##*/} [$(echo "$KNOWN_BASE_PROFILES" | tr ' ' '|')] [fix]" >&2
}

if [ $# -eq 0 ]; then
    BASE_PROFILE='integalert'
elif [ "$1" = 'fix' -a $# -eq 1 ]; then
    BASE_PROFILE='integalert'
    PROFILE='integalert_fix'
elif echo "$KNOWN_BASE_PROFILES" | grep -qFw -- "$1"; then
    BASE_PROFILE="integalert_$1"
else
    echo "Error! Unknown profile: $1" >&2
    show_usage
    exit 1
fi

if [ -n "${2:-}" ]; then
    case "$2" in
	fix)
	    PROFILE="${BASE_PROFILE}_fix"
	    ;;
	*)
	    echo "Error! Unknown mode: $2" >&2
	    show_usage
	    exit 1
	    ;;
    esac
else
    PROFILE="${PROFILE:-$BASE_PROFILE}"
fi

if [ -z "$BASE_PROFILE" -o -z "$PROFILE" ]; then
    echo "BUG!: Empty profile!" >&2
    exit 2
fi

if [ ! -d /etc/osec/$BASE_PROFILE ]; then
    echo "Create osec profile \"$BASE_PROFILE\"" >&2
    mkdir -p /etc/osec/$BASE_PROFILE
fi
if [ ! -d /etc/osec/$PROFILE ]; then
    echo "Create osec profile \"$PROFILE\"" >&2
    mkdir -p /etc/osec/$PROFILE
fi

if [ ! -e /etc/osec/$BASE_PROFILE/dirs.conf ]; then
    case "$BASE_PROFILE" in
	integalert)
	    echo "Warning! Initializing /etc/osec/$BASE_PROFILE/dirs.conf with /etc/osec/dirs.conf" >&2
	    cat /etc/osec/dirs.conf >/etc/osec/$BASE_PROFILE/dirs.conf
	    ;;
	*)
	    touch "/etc/osec/$BASE_PROFILE/dirs.conf"
	    ;;
    esac
fi

if [ ! -s /etc/osec/$BASE_PROFILE/dirs.conf ]; then
    echo "Warning! /etc/osec/$BASE_PROFILE/dirs.conf is empty! Please, fill it with a directory list corresponding to your setup." >&2
    exit 0
fi

if [ ! -e /etc/osec/$BASE_PROFILE/exclude.conf ]; then
    case "$BASE_PROFILE" in
	integalert)
	    if [ -e /etc/osec/exclude.conf ]; then
		echo "Warning! Initializing /etc/osec/$BASE_PROFILE/exclude.conf with /etc/osec/exclude.conf" >&2
		cat /etc/osec/exclude.conf >/etc/osec/$BASE_PROFILE/exclude.conf
	    else
		touch /etc/osec/$BASE_PROFILE/exclude.conf
	    fi
	    ;;
	*)
	    touch /etc/osec/$BASE_PROFILE/exclude.conf
	    ;;
    esac
fi

case "$BASE_PROFILE" in
    integalert)
	REPORT_LOG="$REPORT_LOG_BASE"
	mode_clause=
	;;
    *)
	REPORT_LOG="${REPORT_LOG_BASE}_$BASE_PROFILE"
	mode_clause=", ${BASE_PROFILE#integalert_} mode"
	;;
esac

if [ ! -e /etc/osec/$PROFILE/pipe.conf ]; then
    case "$PROFILE" in
	*_fix)
	    fix_clause='update'
	    cat >/etc/osec/$PROFILE/pipe.conf <<EOF
IMMUTABLE_DATABASE=no
EOF
	    ;;
	*)
	    fix_clause='check'
	    cat >/etc/osec/$PROFILE/pipe.conf <<EOF
IMMUTABLE_DATABASE=yes
EOF
	    ;;
    esac

    cat >>/etc/osec/$PROFILE/pipe.conf <<EOF
DIRS_FILE=/etc/osec/$BASE_PROFILE/dirs.conf
EXCLUDE_FILE=/etc/osec/$BASE_PROFILE/exclude.conf
REPORT_LOG='$REPORT_LOG'
JOURNAL_PIPE='systemd-cat -t integalert; echo "System integrity $fix_clause$mode_clause (\$STAT) -- \$HOSTNAME" | tee "\$REPORT_LOG" | systemd-cat -t integalert'
SEND_PIPE="\$JOURNAL_PIPE"
EOF

    customize_profile "${BASE_PROFILE#integalert_}" >>/etc/osec/$PROFILE/pipe.conf
fi

/usr/share/osec/osec.cron $PROFILE
ret=$?

case "$BASE_PROFILE" in
    integalert)
	for_clause=
	;;
    *)
	for_clause=" for '$BASE_PROFILE'"
	;;
esac

mkdir -p "${REPORT_LOG}_logs"
cat "$REPORT_LOG" >"${REPORT_LOG}_logs/lastosec_$(date --iso-8601)"

case "$PROFILE" in
    *_fix)
	if [ $ret -eq 0 ]; then
            echo "Integrity database$for_clause updated." >&2
        else
            echo "Error updating integrity database$for_clause!" >&2
        fi

        exit $ret
        ;;
esac

if grep -q "(chg=0,add=0,del=0)" "$REPORT_LOG"; then
    echo "Integrity check$for_clause OK." >&2
else
    [ ! -x "$PLYMOUTH_BIN" ] || $PLYMOUTH_BIN quit

    echo "" >/dev/tty1
    echo -e "\r**************************\r" >/dev/tty1
    echo -e "**************************\r" >/dev/tty1
    echo -e "**************************\r" >/dev/tty1
    echo -e "**************************\r" >/dev/tty1
    echo -e "Integrity check failure$for_clause! Возможное нарушение целостности! Проверьте логи в однопользовательском режиме!\r" >/dev/tty1
    echo -e "**************************\r" >/dev/tty1
    echo -e "**************************\r" >/dev/tty1
    echo -e "**************************\r" >/dev/tty1
    echo -e "**************************\r" >/dev/tty1
    echo -e "**************************\r" >/dev/tty1
    echo "" >/dev/tty1

    echo -e "\n**************\n" >&2
    echo "Integrity check failure$for_clause! Возможное нарушение целостности! Проверьте логи в однопользовательском режиме!" >&2
    echo -e "\n**************\n" >&2

    exit 1
fi
