#!/bin/sh

# change version 1.5.8
# (c) 2005-2009 Jan ONDREJ (SAL) <ondrejj(at)salstar.sk>
# All rights reserved.

export MAILTO="system@salstar.sk"
export LANG=C
export LC_ALL=C
export MALLOC_CHECK_=0

if [ ! "$1" = "-q" ]; then
  export TEST_SUID_SGID=yes
  export TEST_WRITEABLE=yes
  export TEST_RPM_CHANGE=yes
  export TEST_RPM_CHECKSUM=yes
  export TEST_MD5_CHECKSUM=yes
fi

BACKUPDIR='/var/spool/change'
DIFFFORM='-u'

EXCLUDE='.*~$'
LINE='============================================================================='

include() {
  INCLUDE="$INCLUDE $@"
}

exclude() {
  for i in "$@"; do
    EXCLUDE="$EXCLUDE|$i"
  done
}

include /etc /var/named/chroot/var/named /var/named/chroot/etc /var/lib/tftpboot
exclude '/etc/selinux/.*/contexts/files/file_contexts'
exclude '/etc/selinux/.*/tmp.*'
exclude '/etc/selinux/targeted/contexts/files/file_contexts'
exclude '/etc/selinux/targeted/modules/active/.*'
exclude '/etc/selinux/targeted/policy/policy.*'
exclude /etc/prelink.cache
exclude /etc/readahead.d/
exclude /etc/shadow /etc/smbpasswd /etc/group- /etc/gshadow.\*
exclude '/etc/passwd\.OLD' /etc/passwd-
exclude /etc/ssh/ssh_random_seed
exclude /etc/ntp/drift /etc/adjtime
exclude /etc/aliases.db '/etc/mail/.*\.db' '/etc/postfix/.*\.db'
exclude /etc/mtab
exclude /etc/.aumixrc
exclude /etc/linuxconf/archive
exclude /etc/log.d/
exclude /etc/postfix/prng_exch
exclude /etc/samba/secrets.tdb
exclude /etc/gconf/
exclude '/etc/mail/spamassassin/bayes_.*'
exclude /etc/cups/certs/
exclude /etc/pimd.pid
exclude /boot/grub/stage2
exclude /etc/dcc/map
exclude /var/named/chroot/var/named/data/named.run
exclude /var/named/chroot/var/named/data/named_mem_stats.txt
exclude /var/named/chroot/var/named/slaves
exclude /var/named/chroot/var/named/w3sa
exclude /var/named/chroot/etc/w3sa.zones
exclude /var/named/chroot/etc/dns-slave.conf
exclude /var/named/chroot/etc/pki
exclude /var/named/chroot/etc/rndc.key
exclude /var/named/chroot/var/named/chroot
exclude /etc/dhcp/w3sa
exclude /etc/readahead.d
exclude '/etc/blkid/blkid.tab.*'
exclude '/etc/mrtg/chain.cfg.*'

# avoid loop problems
#for p in `mount | grep "r.,bind" | awk '{ print $3 }'`; do
#  exclude $p
#done

# Make date
export BDATE=`date +%Y%m%d-%H%M`

# BEGIN: install part
if [ -x /usr/bin/gpg2 ]; then
  GPG=gpg2
else
  GPG=gpg
fi
if [ ! -s /root/.gnupg/secring.gpg ]; then
# init gpg
echo "" | $GPG --batch 2>/dev/null || true
# make own secret key
export SYSNAME=`uname -n`
$GPG --batch --gen-key << EOF
%echo Generating a standard key
Key-Type: RSA
Key-Length: 2048
Name-Real: $SYSNAME
Expire-Date: 0
%commit
%echo done
EOF
$GPG --batch --import << EOF
-----BEGIN PGP PUBLIC KEY BLOCK-----
Version: GnuPG v1.0.6 (GNU/Linux)
Comment: For info see http://www.gnupg.org

mQGiBDtSrLcRBADvGirfFuQq6cBZ820MLgkSrbrmdB9155pUtd/8mBYUXIHmsMZE
2SIcr1576rVCTyAViO0eZg1we0wzT4XLLACEhn9gGxX8+WPUL1HvBaIuTUN8P9ST
4P8UVRHELMNyMpaELL+z6XtjTW3LRyMPrc+uZsQ+cXoUnhDq+olSKNqZSwCg1PrO
mKDPhMiS2Kx1y+yDeStUL/MEAMki75D9cfEKRkjpQSf740BpEevAWpz9tdMRsFB9
JUrmM4uyjU8S3e/zu6rStj0p3xr6iPqvn4FTnMp3o9XM3Uld9gkvcaIL44k2lv+s
apkN/7AqLNT+BDABcxcU1wjNznKDlocNiyYdQHnSSdX1xYOp330eruo3S65AEic9
YobgA/9B9rFkX35MsD9Oyb/JNpDrgRNdjeYRLv1rwPerF0UF+IV1FFeKh7JEtgWU
EcXGi/HaCOKWi1kIgP1dqPkW4aYWeIsGgOF2c74QQDX3+lxWIlYwg/kEZEAybrUz
49/AIeKNUU3aDfByfWPaf03K0DywEn0QzSaBnUx8NA7q0w3DlbQgU3lzdGVtIChz
eXMpIDxzeXN0ZW1Ac2Fsc3Rhci5zaz6IVwQTEQIAFwUCO1KstwULBwoDBAMVAwID
FgIBAheAAAoJEJRyY/gkNdzoW14An2vF41tCqDccMBP1pfXPYp+GeZaGAKDEVnsk
iIB/mFvHUjkQ8iS2ay081YhGBBARAgAGBQI7Uq69AAoJEF3h3Lq97Rsq8aAAoJXF
uNCcvVlfRNu8mrzaHh0nGwzEAKCTU2ZRdHH9dRWguQNmlH6TLN3wDbkBDQQ7UqzH
EAQA30gGOPxx85f9bS0rwXjy/CeJFUHuPeLjr2PCIXNL1njukPdV+QIqdRZjhT/l
v7Be9JUf0gDIJL6B8Qz18GyMqxKxbLFZCHZSUYSBLXBssv82evu0AVhli2Wx0Zol
FGLfJ64NVBQret1OllG1uqYec/L+wRo0iUvccKl9YnA/WW8AAwUD/118IHabEzyn
97ahtXmWUC0S+fN27W4KVt4LiRZAB2GuYfpztngJC52KL9/20yInG40pZ0rIGLLy
MkH0Ay/AwOzERmSKMgOglddsgBd9S7Aa9/kQQq55DNaPkjW6LMJgTvKsNhZfBL8O
7UppY+SeVUYJILBQXJ2X9aZc5lOHlkxBiEYEGBECAAYFAjtSrMcACgkQlHJj+CQ1
3OiBDACgsIEiEmPzjEGe/kDeAZtHQWTgPgwAn0k2JEbXEfgDjAb84pE8S5EkxXuG
=TceP
-----END PGP PUBLIC KEY BLOCK-----
EOF
# User have to press "y<enter>" after this command,
# unable to add --yes or yes| .
$GPG --sign-key system
fi # gpg already initialized
# END: install part

# Store old filelist
mv $BACKUPDIR/filelist $BACKUPDIR/filelist.backup

# Make new filelist
for i in $INCLUDE; do
  if [ -d $i ]; then
    find $i -type f 2>/dev/null
  fi
done | egrep -v "^($EXCLUDE)" | sort > $BACKUPDIR/filelist

# Basic functions
sdiff() {
  diff $DIFFFORM $@ | grep -v -e '^---' -e '^+++' -e '^ ' -e '^@@'
}

(

# Check for new files
if [ "`diff -q $BACKUPDIR/filelist $BACKUPDIR/filelist.backup`" ]; then
  echo "Added/removed files:"
  echo "$LINE"
  comm -3 $BACKUPDIR/filelist.backup $BACKUPDIR/filelist \
    | sed -e 's/^\//-\//g' -e 's/^	*\//+\//g'
  echo "$LINE"
fi
CHNGD=`comm -13 $BACKUPDIR/filelist.backup $BACKUPDIR/filelist`
RMVD=`comm -23 $BACKUPDIR/filelist.backup $BACKUPDIR/filelist`

# Compare files
for i in `comm -12 $BACKUPDIR/filelist $BACKUPDIR/filelist.backup`; do
  if [ -f "$BACKUPDIR$i" ]; then
    if [ "`diff -q $i $BACKUPDIR$i`" ]; then
      CHNGD="$CHNGD $i"
      echo ""
      echo "File: $i"
      echo "$LINE"
        diff $DIFFFORM "$BACKUPDIR$i" "$i"
      echo "$LINE"
    fi
  else
    echo "ERROR, FILE $i NOT FOUND!"
    CHNGD="$CHNGD $i"
  fi
done

# Remove backup and old files
rm -f $BACKUPDIR/filelist.backup
if [ "$RMVD" ]; then
  echo "Removing files:"
  for i in $RMVD; do
    echo "$i"
    rm -f "$BACKUPDIR$i"
  done
fi

# Copy current file to backup
for i in $CHNGD; do
  D="`echo $i | sed 's/\/[^/]*$//g'`"
  if [ ! -d $BACKUPDIR$D ]; then
    echo "Making directory $D"
    mkdir -p "$BACKUPDIR$D"
  fi
  echo "Copying file $i"
  cp -f "$i" "$BACKUPDIR$D"
done

if [ "$TEST_SUID_SGID" ]; then
  DIRS=`mount | grep -v -e nosuid -e noexec -e ^[^/] -e /proc -e fuse\\. | cut -d" " -f3`
  mv -f $BACKUPDIR/suid-changes $BACKUPDIR/suid-changes.backup
  find $DIRS \
    -mount -ignore_readdir_race \
    -perm +6000 \
    -type f \
    -exec ls -dils --full-time {} \; 2>/dev/null > $BACKUPDIR/suid-changes
  if [ "`diff -q $BACKUPDIR/suid-changes.backup $BACKUPDIR/suid-changes`" ]; then
    echo $LINE
    echo 'Setuid and setgid changes...'
    echo $LINE
    sdiff $BACKUPDIR/suid-changes.backup $BACKUPDIR/suid-changes
  fi
fi

if [ "$TEST_WRITEABLE" ]; then
  mv -f $BACKUPDIR/writeable $BACKUPDIR/writeable.backup
  find /bin /boot /etc /lib /root /sbin /usr \
    -mount \
    -perm +0002 \
    \( -type f -or -type d \) \
    -exec ls -dils --full-time {} \; 2>/dev/null > $BACKUPDIR/writeable
  if [ "`diff -q $BACKUPDIR/writeable.backup $BACKUPDIR/writeable`" ]; then
    echo $LINE
    echo 'World writeable files and directory changes...'
    echo $LINE
    sdiff $BACKUPDIR/writeable.backup $BACKUPDIR/writeable
  fi
fi

if [ "$TEST_RPM_CHANGE" ]; then
  mv -f $BACKUPDIR/rpm-qf $BACKUPDIR/rpm-qf.backup
  rpm -qa --queryformat \
    '%11{SIZE} %11{BUILDTIME} %11{INSTALLTIME} %{NAME}-%{VERSION}-%{RELEASE}\n' \
    | sort -k 3 -n > $BACKUPDIR/rpm-qf
  if [ -s $BACKUPDIR/rpm-qf ]; then
    if [ "`diff -q $BACKUPDIR/rpm-qf.backup $BACKUPDIR/rpm-qf`" ]; then
      echo $LINE
      echo 'RPM package changes ...'
      echo $LINE
      sdiff $BACKUPDIR/rpm-qf.backup $BACKUPDIR/rpm-qf
    fi
  else
    echo 'RPM package check FAILED!'
    cp -af $BACKUPDIR/rpm-qf.backup $BACKUPDIR/rpm-qf
  fi
fi

if [ "$TEST_RPM_CHECKSUM" ]; then
  mv -f $BACKUPDIR/rpm-Va $BACKUPDIR/rpm-Va.backup
  rpm -Va 2>/dev/null | grep -e '^..5' | grep -v \
    -e '^........ c ' \
    -e '^........   /usr/src/' \
    -e '\.[chS]$' \
    | sort -k 2 > $BACKUPDIR/rpm-Va
  if [ "`diff -q $BACKUPDIR/rpm-Va.backup $BACKUPDIR/rpm-Va`" ]; then
    echo $LINE
    echo 'RPM verification ...'
    echo $LINE
    sdiff $BACKUPDIR/rpm-Va.backup $BACKUPDIR/rpm-Va
  fi
fi

if [ "$TEST_MD5_CHECKSUM" ]; then
  mv -f $BACKUPDIR/md5sum $BACKUPDIR/md5sum.backup
  find /boot /lib/modules -type f -exec md5sum {} \; 2>/dev/null \
    | grep -v /boot/grub/stage2 > $BACKUPDIR/md5sum
  if [ "`diff -q $BACKUPDIR/md5sum.backup $BACKUPDIR/md5sum`" ]; then
    echo $LINE
    echo 'MD5SUM verification ...'
    echo $LINE
    sdiff $BACKUPDIR/md5sum.backup $BACKUPDIR/md5sum
  fi
fi

) > $BACKUPDIR/log/$BDATE

wc -c $BACKUPDIR/log/$BDATE | awk '{ if ($1!=0) exit 1 }' \
  && rm -f $BACKUPDIR/log/$BDATE || \
  for em in $MAILTO; do
  (
    echo "From: \"`hostname`\" <root@`hostname`>"
    echo "To: $em"
    echo "Subject: change"
    echo "Content-Type: application/pgp; format=text; x-action=encryptsign"
    echo ""
    cat $BACKUPDIR/log/$BDATE | \
      $GPG --homedir /root/.gnupg -e -a -r $em --batch --always-trust \
        2> /dev/null
  ) | sendmail -t
  done
#gzip $BACKUPDIR/log/$BDATE

exit 0
