#!/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'
}

. ${0%/*}/tw_conf ; . ${0%/*}/tw_lib

err_types=("Dateien wurden hinzugefügt!" "Dateien wurden gelöscht!" \
           "Dateien wurden verändert!" "Trojaner gefunden!" "Köder angetastet!" \
           "Datenbank manipuliert!" "Konfigurationsdateien fehlen!" "Laufzeitfehler!")
# Fehlertypen...
declare -ia err_pri=(0 0 0 1 1 2 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			# lokalen PG-Schlüssel vernichten
  # $DESTDIR/tw_service -c etc -b				# Backup wichtiger Inhalte
  # { who -i; tail -500 /var/log/messages; } >/root/tw.evidence	# Sichert Beweismittel
  return
}

function cf_pri
{
  # Liefert Priorität.
  local n
  set_entry PRI global <$cf
  case ${rem[0]} in
    low   ) n=1;;
    medium) n=2;;
    high  ) n=3;;
    *     ) n=0;;
  esac
  echo $n
}

function report
{
# Kurzinfo.
local h=$IFS mess emer_cond
echo -e "--> ${0##*/}: TRIPWIRE-shield 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=$h ; echo
[ -e $cf ] && [ $((max + $(cf_pri))) -gt $maxpri ] && emer_cond=gestartet
cat << EOF
    Benutzer .......... $LOGNAME
    Zeit .............. $local_time
    Rechner ........... $FQDN
    Kommandozeile ..... ${0##*/} $com_opt
    Bericht ........... $REPORT
    Notfallaktion ..... ${emer_cond:-nein}
EOF
[ "$emer_cond" ] && Notfallaktion
}

function log_mess
{
  echo -e " - ${ext:-$DEFDBNAME}: $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

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

# Konfiguration ok?
if ! [ -e $cf ] || ! [ -e $db ] || ! [ -e $dbsig ]; then
  log_mess 'Konfigurationsdateien fehlen' ; report 128
  exit 1
fi

# Datenbank integer?
if [ "$(< $dbsig)" != "$($DESTDIR/siggen -7 $db)" ]; then
  log_mess 'Datenbank manipuliert' ; report 64
  exit 64
fi

# Dateisystem integer?
$DESTDIR/tripwire --quiet $tw_opt_1 $tw_opt_2 >$REPORT.new 2>/dev/null
if [ $? = 1 ]; then
  # Laufzeitfehler.
  rm -f $REPORT.new
  log_mess 'Laufzeitfehler' ; report 256
  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
  log_mess 'Laufzeitfehler' ; report 256
  exit 1
elif [ $((see_stat & 62)) = 0 ]; then
  # Test ohne Befund.
  rm -f $REPORT.filt
  log_mess '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	-

