#!/bin/sh
#
#     tiger - A UN*X security checking system
#     Copyright (C) 1993 Douglas Lee Schales, David K. Hess, David R. Safford
#
#    This program is free software; you can redistribute it and/or modify
#    it under the terms of the GNU General Public License as published by
#    the Free Software Foundation; either version 1, or (at your option)
#    any later version.
#
#    This program is distributed in the hope that it will be useful,
#    but WITHOUT ANY WARRANTY; without even the implied warranty of
#    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
#    GNU General Public License for more details.
#
#     Please see the file `COPYING' for the complete copyright notice.
#
# tigercron - 06/13/93
#
# 04/12/2008 jfs Include patch from Chris Lamb that fixes bashism in the script
#                (Debian bug #468700)
# 08/15/2003 jfs Now uses run_script instead of SCRIPTDIR/LSCRIPTDIR which
#                permits tigercron to execute the most relevant script given
#                the $OS/$REL/$ARCH
#                Safer creation of the temporary file which includes the
#                scripts' results.
# 04/23/2003 jfs Sanity check for the existance of ctrfile, use TigerConfigDir
#               instead of CONFIGDIR
# 10/28/2002 jfs Added check of non-comments in output (only available if
#                egrep is installed)
# 07/25/2002 jfs Changed TigerInstallDir to .
# 12/26/2001 jfs Modified to provide new ways to compare against previous
#                runs: per policy (template) or per run.
# 12/02/2001 jfs Fixed script to properly send out mails with valid
#                headers and content
#
#-----------------------------------------------------------------------------
# TODO:
# - Study wether or not GPG can be used to automatically sign messages
#   sent (using a passwordless key)
# - Make it work with syslog to send the reports (in much the same way 
#   that sendtologger is used by Tiger when a '-l @syslogserver' is used)
#   (Note: This would also help since having it log locally instead of
#   could help users running logcheck, at least in Debian)
# - Consider if running checks by absolute filename reference is permitted
#   or not
#-----------------------------------------------------------------------------
#
TigerInstallDir="/usr/share/tiger"

[ "$1" != "" ] && {
  case "$1" in
    -*);;
    *) ctrlfile=$1; shift;;
  esac
}

#
# Set default base directory.
# Order or preference:
#      -B option
#      TIGERHOMEDIR environment variable
#      TigerInstallDir installed location
#
basedir=${TIGERHOMEDIR:=$TigerInstallDir}

for parm
do
   case $parm in
   -B) basedir=$2; break;;
   esac
done

#
# Verify that a config file exists there, and if it does
# source it.
#
[ ! -r "$basedir/config" ] && {
  echo "--ERROR-- [init002e] No 'config' file in \`$basedir'."
  exit 1
}

. $basedir/config
TEMPLATEDIR="$TigerConfigDir/templates"

. $BASEDIR/initdefs

#
# If run in test mode (-t) this will verify that all required
# elements are set.
#
[ "$Tiger_TESTMODE" = 'Y' ] && {
  haveallcmds DATE SED EXPR DIFF MAILER GREP BASENAME || exit 1
  haveallfiles BASEDIR SCRIPTDIR WORKDIR LOGDIR || exit 1
  
  echo "--CONFIG-- [init003c] $0: Configuration ok..."
  exit 0
}

#------------------------------------------------------------------------
haveallcmds DATE SED EXPR DIFF MAILER GREP BASENAME || exit 1
haveallfiles BASEDIR SCRIPTDIR WORKDIR LOGDIR || exit 1

umask 077

[ -n "$Tiger_CRON_Output_Width" ] && {
  Tiger_Output_Width="$Tiger_CRON_Output_Width"
}

[ ! -n "$ctrlfile" ] && ctrlfile=$TigerConfigDir/cronrc
[ ! -r "$ctrlfile" ]  &&  {
	    message ERROR tigxxxx "" "Cannot read \`$ctrlfile', tigercron cannot proceed."
	    exit 1
}

set X `$DATE`
dow=$2
dom=$4
time=$5
IFS=:
set X $time
IFS=$saveifs
hour=$2
min=$3

# now some sanity checks
# WARN: Since the cronjob does not send err output we proceed but
# this should really be fixed in order to provide proper err messages
# (otherwise this might lead to a 'false sense of security' since the
# same checks are done over and over again, or none at all, depends
# on cronrc configuration)
[ -z "$hour" ] && hour=0
[ -z "$min" ] && min=0
[ -z "$dow" ] && dow=1
[ -z "$dom" ] && dom=1

[ $min -gt 50 ] && {
  if [ $hour -eq 23 ]; then
    hour=0
  else
    hour=`$EXPR $hour + 1`
  fi
}


$SED -e 's/#.*$//' -e '/^$/d' $ctrlfile |
while read times doms days scripts
do
  
  hourok=0

  if [ "$times" != '*' ]; then
    IFS=,
    set X $times
    IFS=$saveifs
    shift
    for t
    do
      [ "$t" -eq "$hour" ] && {
	hourok=1
	break;
      }
    done
  else
    hourok=1
  fi

  domok=0
  [ $hourok -eq 1 ] && {
    if [ "$doms" != '*' ]; then
      IFS=,
      set X $doms
      IFS=$saveifs
      shift
      
      for d
      do
	[ "$d" = "$dom" ] && {
	  domok=1
	  break
	}
      done
    else
      domok=1
    fi
  }

  [ $hourok -eq 1 -a $domok -eq 1 ] && {
    dayok=0

    if [ "$days" != '*' ]; then
      IFS=,
      set X $days
      IFS=$saveifs
      shift

      for d
      do
	[ "$d" = "$dow" ] && {
	  dayok=1
	  break;
	}
      done
    else
      dayok=1
    fi
    
    [ $dayok -eq 1 ] && {
      for script in $scripts
      do
	outprefix="$LOGDIR/`$BASENAME $script`.out"
	safe_temp $outprefix.$$.tmp
	suffix=${TigerCron_Log_Keep_Max:=10}
	{
	  run_script $script
# TODO: Consider if including absolute references is considered
# validif [ -f $_SCRIPTDIR/$script ]; then
#	  elif [ -f $script ]; then
#	    $script
#	  else
#	    message ERROR tigxxxx "" "Not found (and cannot run) $script as requested in tigercron file, `$ctrlfile'."
#	  fi
	} > $outprefix.$$.tmp
	if [ -s $outprefix.$$.tmp ]; then
	  next=`$EXPR $suffix - 1`
	  while [ "$next" -ge 1 ]
	  do
	    [ -f "$outprefix.$next" ] && {
	      $MV $outprefix.$next $outprefix.$suffix
	    }
	    suffix=$next
	    next=`$EXPR $next - 1`
	  done
	  $MV $outprefix.$$.tmp $outprefix.1
	  echo $outprefix
	fi
      done
    }
  }
done |
while read filename
do
  newfile=$filename.1
  previousfile=$filename.2
  templatefile=$filename.template
#  etctemplatefile=`echo $templatefile | $SED 's/\/var\/log\/tiger\///'`
  etctemplatefile=`$BASENAME $templatefile`

  if [ "$Tiger_Cron_Template" = "Y" -a -s "$TEMPLATEDIR/$etctemplatefile" ]; then 
    $BASEDIR/util/difflogs $TEMPLATEDIR/$etctemplatefile $newfile
  elif [ "$Tiger_Cron_Template" = "Y" -a -s "$templatefile" ]; then 
    $BASEDIR/util/difflogs $templatefile $newfile
  elif [ "$Tiger_Cron_CheckPrev" = "Y" -a -s "$previousfile" ]; then 
    $BASEDIR/util/difflogs $previousfile $newfile
  else
    $CAT $newfile
  fi
done >> $WORKDIR/tigcron.diff.$$

[ ! -n "$Tiger_Mail_RCPT" ] && Tiger_Mail_RCPT="root"
[ ! -n "$Tiger_Mail_FROM" ] && Tiger_Mail_FROM="root@$(hostname)"
  
length=1
if [ ! -n "$EGREP" ] ; then
# this is useful (if egrep is available) to remove cruft
	length=`$EGREP -v "^\s*$|^\s*#" $WORKDIR/tigcron.diff.$$|$AWK 'END {print NR}'`
fi
[ -s "$WORKDIR/tigcron.diff.$$" -a $length -gt 0 ] && {
  send="Y"
  [ "$Tiger_Cron_SendOKReports" = "N" ] &&
  [ -z "`grep ERR $WORKDIR/tigcron.diff.$$`" ] &&
  [ -z "`grep WARN $WORKDIR/tigcron.diff.$$`" ] && { 
  	send="N"
  }
  haveallcmds MAILER && [ "$send" = "Y" ] &&  {
	# Mail header (so it does not just say it's root
	echo "From: \"Tiger automatic auditor at $(hostname)\" <$Tiger_Mail_FROM>"
	echo "To: $Tiger_Mail_RCPT"
	echo "Subject: Tiger Auditing Report for $(hostname)"
	echo 
	cat  $WORKDIR/tigcron.diff.$$ 
    } | $MAILER $Tiger_Mail_RCPT 
    # Note1: This could also be 
    # } | $MAILER -s "TIGER Output" $Tiger_Mail_RCPT < $WORKDIR/tigcron.diff.$$
    # Alas, it's not completely portable (no -s option on some mailers)
    # Note2: It could even be
    # } | $GPG -e -a | $MAILER -s "TIGER Output" $Tiger_Mail_RCPT < $WORKDIR/tigcron.diff.$$
    # But it should then use passwordless keys for GPG

}

delete $WORKDIR/tigcron.diff.$$
