#!/bin/bash
#
# Shellscript zum Start von TRIPWIRE als Cron-Job.
#

function info
{
  echo -e '
  SYNTAX: tw_check [-c ext] [-i select-flag1,select-flag2,...]

  -c  Wählt die Konfiguration "tw.config-ext" an.
  -i  Diese Signaturen werden beim Testlauf ausgeblendet.

  tw_check kennt das Schlüsselwort PRI. ( # [PRI(low|medium|high)] )\n'
}

source ${0%/*}/tw_conf

DATABASE=tw.db_$HOSTNAME
DBSIG=tw.db_sig

err_types=("Dateien wurden hinzugefügt!" "Dateien wurden gelöscht!" "Dateien wurden verändert!" \
           "Trojaner gefunden!" "Köder angetastet!" "Datenbank beschädigt!" "Laufzeitfehler!")
# Fehlertypen...
declare -ia err_pri=(0 0 0 1 1 2 2)
# ...und zug. Prioritäten.
declare -i maxpri=2
# Arbeitspunkt für PRI-Marker

function Notfallaktion
{
  # Einige Beispiele:
  # report | mail -s "Hilfe!" sherlock@investigations.com	# Nachricht an zust. Stelle
  # killproc -TERM /usr/sbin/inetd				# Netzwerkdienste einstellen
  # init S							# Single-User-Mode
  # rm -f /home/norma/.gnupg/secring.gpg			# PG-Schlüssel vernichten
  # $DESTDIR/tw_service -c etc -b				# Backup wichtiger Inhalte
  return
}

function cf_pri
{
  # Liefert PRI-Argument.
  case $(grep "^#.*PRI(" | sed 's/.*PRI(//g;s/).*//g') in
    low   ) n=1;;
    medium) n=2;;
    high  ) n=3;;
    *     ) n=0;;
  esac
  echo $n
} <$cf

function report
{
# Kurzinfo.
echo -e "--> $0: TRIPWIRE meldet Inkonsistenzen!\n"
declare -i mask=2 i=0 max=0 stat=$1 ; IFS=''
for mess in ${err_types[*]}; do
  if [ $((stat & mask)) != 0 ]; then
    echo "    - $mess"
    [ ${err_pri[$i]} -gt $max ] && max=${err_pri[$i]}
  fi
  mask=$((mask << 1)) ; let i+=1
done
IFS=' ' ; echo
cat << EOF
    Benutzer ......... $LOGNAME
    Zeit ............. $local_time
    Rechner .......... $HOSTNAME.$DOMAINNAME
    Kommandozeile .... ${0##*/} $com_opt
    Bericht .......... $REPORT
EOF
[ $((max + $(cf_pri))) -gt $maxpri ] && Notfallaktion
}

function add_mess
{
  echo -e "$1\n" >>$REPORT
}

# Optionen?
cf=$DESTDIR/tw.config ; db=$DATADIR/$DATABASE ; dbsig=$DBSIGDIR/$DBSIG ; com_opt=$*
while getopts "c:i:h" opt; do
  case $opt in
    c) ext="$OPTARG" ; cf="$cf-$ext" ; db="$db-$ext" ; dbsig="$dbsig-$ext"
       tw_opt_1="--cfgfile $cf --dbfile $db" ; see_opt="-c $OPTARG";;
    i) tw_opt_2="--ignore ${OPTARG//,/ --ignore }";;
    h) info ; exit 0;;
    *) exit 1;;
  esac
done

if ! [ -e $cf ] || ! [ -e $db ] || ! [ -e $dbsig ]; then
  echo "--> ${0##*/}: Keine gültige Konfiguration!" ; exit 1
fi

local_time=$(date '+%a, %-d. %b %Y %H:%M:%S')

{ echo "Folgende Veränderungen wurden von TRIPWIRE am $local_time erfasst:
---------------------------------------------------------------------------------"
} >>$REPORT ; chmod 600 $REPORT

# Datenbank integer?
if [ "$(< $dbsig)" != "$($DESTDIR/siggen -7 $db)" ]; then
  add_mess " - Datenbank ${db##*/} beschädigt - "
  report 64 ; exit 64
fi

# Dateisystem integer?
$DESTDIR/tripwire --quiet $tw_opt_1 $tw_opt_2 >$REPORT.new
if [ $? = 1 ]; then
  # Laufzeitfehler.
  rm -f $REPORT.new
  add_mess ' - Laufzeitfehler - '
  report 128 ; exit 1
fi
$DESTDIR/see $see_opt $REPORT.new >$REPORT.filt ; see_stat=$?
rm -f $REPORT.new
if [ $see_stat = 1 ]; then
  # Laufzeitfehler.
  rm -f $REPORT.filt
  add_mess ' - Laufzeitfehler - '
  report 128 ; exit 1
elif [ $((see_stat & 62)) = 0 ]; then
  # Test ohne Befund.
  rm -f $REPORT.filt
  add_mess " - Bereich ${ext:-<HARDCODED>} ok - "
  exit 0
else
  # Inkonsistenzen.
  { cat $REPORT.filt; echo; } >>$REPORT && rm -f $REPORT.filt
  report $see_stat ; exit $see_stat
fi

# Statusbit:	7	6	5	4	3	2	1	0
# Bedeutung:	-	datab.	touch.  detec.  chang.  delet.  added	-

