#!/bin/bash

PATH="/sbin:/usr/sbin:/bin:/usr/bin"
LOGDIR="/var/log/aide"
LOGFILE="aide.log"
CONFFILE="/var/lib/aide/aide.conf.autogenerated"
ERRORLOG="error.log"
ERRORTMP=$(tempfile --directory "/tmp" --prefix "$ERRORLOG")

[ -f /usr/bin/aide ] || exit 0

AIDEARGS="-V4"
FQDN="$(hostname -f)"
MAILSUBJ="Daily AIDE report for $FQDN"

if [ -f /etc/default/aide ]; then
	. /etc/default/aide
fi

DATABASE="$(grep "^database=file:/" $CONFFILE | head -1 | cut --delimiter=: --fields=2)"
DATABASE_OUT="$(grep "^database_out=file:/" $CONFFILE | head -1 | cut --delimiter=: --fields=2)"
DATE="$(date +"%Y-%m-%d %H:%M")"

# default values

MAILTO="${MAILTO:-root}"
eval MAILTO="$MAILTO"
DATABASE="${DATABASE:-/var/lib/aide/aide.db}"
LINES="${LINES:-1000}"
COMMAND="${COMMAND:-check}"
COPYNEWDB="${COPYNEWDB:-no}"
QUIETREPORTS="${QUIETREPORTS:-no}"

if [ ! -f $DATABASE ]; then
	(
	echo "Fatal error: The AIDE database does not exist!"
	echo "This may mean you haven't created it, or it may mean that someone has removed it."
	) | /usr/bin/mail -s "FAILED! $MAILSUBJ" $MAILTO
	rm -f "$ERRORTMP"
	exit 0
fi

BEGINTIME="$(date +%s)"

[ -f "$LOGDIR/$LOGFILE" ] && savelog -t -g adm -m 640 -u root -c 7 "$LOGDIR/$LOGFILE" > /dev/null
[ -f "$LOGDIR/$ERRORLOG" ] && savelog -t -g adm -m 640 -u root -c 7 "$LOGDIR/$ERRORLOG" > /dev/null

update-aide.conf
aide.wrapper $AIDEARGS --$COMMAND >"$LOGDIR/$LOGFILE" 2>"$ERRORTMP"
RETVAL=$?

COPYDB="0"
CHANGES="1"
if < $LOGDIR/$LOGFILE grep '^###' | head -n 1 | grep -q '### All files match AIDE database. Looks okay!' && \
   [ "$(< $LOGDIR/$LOGFILE wc -l)" -lt 20 ]; then
	CHANGES="0"
fi

if [ "$COPYNEWDB" = "ifnochange" ] && [ "$CHANGES" = "0" ]; then
	COPYDB="1"
fi

if [ "$COPYNEWDB" = "yes" ]; then
	COPYDB=1
fi

if [ "$COPYDB" = "1" ] && [ "$COMMAND" = "update" ]; then
	cp -f "$DATABASE_OUT" "$DATABASE"
	echo "output database $DATABASE_OUT was copied to $DATABASE as requested by cron job configuration" >> "$LOGDIR/$LOGFILE"
fi

echo "end timestamp $(date +"at %Y-%m-%d %H:%M"), run time $(( $(date +%s) - $BEGINTIME )) seconds" >> "$LOGDIR/$LOGFILE"

if [ "$QUIETREPORTS" = "yes" ] && [ "$CHANGES" = "0" ] && [ $(< $ERRORTMP wc -l) -eq 0 ]; then
	# Bail now because QUIETREPORTS set, no changes detected and no errors
	rm -f "$ERRORTMP"
	exit 0
fi

(cat << EOF;
This is an automated report generated by the Advanced Intrusion Detection
Environment on $FQDN at ${DATE}.

EOF

# include error log in daily report e-mail

if [ "$RETVAL" != "0" ]; then
	cat > "$LOGDIR/$ERRORLOG" << EOF;
	
*****************************************************************************
*                    aide returned a non-zero exit value                    *
*****************************************************************************

EOF
	echo "exit value is: $RETVAL" >> "$LOGDIR/$ERRORLOG"
else
	touch "$LOGDIR/$ERRORLOG"
fi
< "$ERRORTMP" cat >> "$LOGDIR/$ERRORLOG"
rm -f "$ERRORTMP"

if [ -s "$LOGDIR/$ERRORLOG" ]; then
	errorlines="$(wc -l "$LOGDIR/$ERRORLOG" | awk '{ print $1 }')"
	if [ ${errorlines:=0} -gt $LINES ]; then
		cat << EOF;

****************************************************************************
*                      aide has returned many errors.                      *
*           the error log output has been truncated in this mail           *
****************************************************************************

EOF
		echo "Error output is $errorlines lines, truncated to $LINES."
		head -$LINES "$LOGDIR/$ERRORLOG"
		echo "The full output can be found in $LOGDIR/$ERRORLOG."
	else
		echo "Errors produced  ($errorlines lines):"
		cat "$LOGDIR/$ERRORLOG"
	fi
else
	echo "AIDE produced no errors."
fi

# include de-noised log

if [ -n "$NOISE" ]; then
	NOISETMP="$(tempfile --directory "/tmp" --prefix "aidenoise")"
	NOISETMP2="$(tempfile --directory "/tmp" --prefix "aidenoise")"
	sed -n '1,/^Detailed information about changes:/p' "$LOGDIR/$LOGFILE" | \
	grep '^\(changed\|removed\|added\):' | \
	grep -v "^added: THERE WERE ALSO [0-9]\+ FILES ADDED UNDER THIS DIRECTORY" > $NOISETMP2
	
	if [ -n "$NOISE" ]; then
		< $NOISETMP2 grep -v "^\(changed\|removed\|added\):$NOISE" > $NOISETMP
		rm -f $NOISETMP2
		echo "De-Noised output removes everything matching $NOISE."
	else
		mv $NOISETMP2 $NOISETMP
		echo "No noise expression was given."
	fi
	
	if [ -s "$NOISETMP" ]; then
		loglines="$(< $NOISETMP wc -l | awk '{ print $1 }')"
		if [ ${loglines:=0} -gt $LINES ]; then
			cat << EOF;

****************************************************************************
*   aide has returned long output which has been truncated in this mail    *
****************************************************************************

EOF
			echo "De-Noised output is $loglines lines, truncated to $LINES."
			< $NOISETMP head -$LINES
			echo "The full output can be found in $LOGDIR/$LOGFILE."
		else
			echo "De-Noised output of the daily AIDE run ($loglines lines):"
			cat $NOISETMP
		fi
	else
		echo "AIDE detected no changes after removing noise."
	fi
	rm -f $NOISETMP
	echo "============================================================================"
fi

# include non-de-noised log

if [ -s "$LOGDIR/$LOGFILE" ]; then
	loglines="$(wc -l "$LOGDIR/$LOGFILE" | awk '{ print $1 }')"
	if [ ${loglines:=0} -gt $LINES ]; then
		cat << EOF;

****************************************************************************
*   aide has returned long output which has been truncated in this mail    *
****************************************************************************

EOF
		echo "Output is $loglines lines, truncated to $LINES."
		head -$LINES "$LOGDIR/$LOGFILE"
		echo "The full output can be found in $LOGDIR/$LOGFILE."
	else
		echo "Output of the daily AIDE run ($loglines lines):"
		cat "$LOGDIR/$LOGFILE"
	fi
else
	echo "AIDE detected no changes."
fi
) | /usr/bin/mail -s "$MAILSUBJ" $MAILTO
