Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/bash
- #
- # fetch-sanesecurity-sigs
- # by Malcolm Scott, Retrosnub Internet Services
- # <malcolm at retrosnub dot co dot uk>
- #
- # http://www.retrosnub.co.uk/sanesecurity
- # svn://svn.sanesecurity.retrosnub.co.uk/
- #
- # $Revision$
- # $Date$
- #
- # -----------------------------------------------------------------------------
- # Copyright (C) 2009 Malcolm Scott
- #
- # This program is free software; you can redistribute it and/or modify it under
- # the terms of the GNU General Public License version 2 as published by the
- # Free Software Foundation.
- #
- # 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.
- #
- # You should have received a copy of the GNU General Public License along with
- # this program; if not, write to the Free Software Foundation, Inc., 59 Temple
- # Place, Suite 330, Boston, MA 02111-1307 USA
- # -----------------------------------------------------------------------------
- #
- # INSTALLATION AND USAGE:
- #
- # * Ensure that you have wget, gpg and rsync installed (in addition to a
- # standard set of UNIX tools).
- # * Configure this script by editing the configuration variables below.
- # * Set up cron to run this script periodically, at a randomly-selected time
- # (i.e. not just on the hour unless unavoidable), not more often than once
- # per hour. The script should be run either as root or as the user clamd
- # runs as. For example, add the following line to /etc/crontab or a file
- # in /etc/cron.d:
- # 42 * * * * root /path/to/fetch-sanesecurity-sigs >/dev/null
- # (Redirection of the output to /dev/null is recommended when running from
- # cron as the script is verbose in normal operation. This will not hide
- # errors, however.)
- #
- # Note that this script is tailored to the Sanesecurity setup (as of January
- # 2009). It should replace scripts using the pre-2009 setup (HTTP). It is
- # not intended to download non-Sanesecurity signatures; use another script
- # for that purpose.
- ### Configuration ###
- # ClamAV database location
- clamd_dbdir="/var/lib/clamav"
- # ClamAV daemon process ID file
- # (If this is commented out, the daemon will not be reloaded automatically)
- clamd_pidfile="/var/run/clamav/clamd.pid"
- # Directory in which this script will keep its persistent data
- data_dir="/var/lib/sanesecurity"
- # Directory in which this script will keep its cache
- # (This should not be the same as data_dir. Any unexpected files in this
- # directory will be deleted!)
- cache_dir="/var/cache/sanesecurity"
- # Mirror to use, in a form accepted by rsync
- # (Leave set to the round robin address unless you know what you are doing:
- # forcing the use of one particular mirror will cause excess load for that
- # mirror)
- mirror="rsync://rsync.sanesecurity.net/sanesecurity"
- # Extra options for rsync
- # The default, --contimeout=30, makes for faster recovery if a mirror is
- # blocking your connection (e.g. if you connect too frequently). However
- # this is not available in older versions of rsync so you may need to
- # remove it.
- # Additionally, if you have a slow link you may want to add -z here to
- # enable compression.
- rsync_extra_opts="--contimeout=30"
- # Minimum interval between updates, in minutes
- # (Note that the download servers may be configured to drop connections made
- # at too great a rate)
- min_interval="30"
- # Randomly sleep before downloading if running noninteractively?
- # (Please leave this enabled, as it reduces peak load on the mirrors)
- random_sleep=1
- # URL of the Sanesecurity GnuPG public key
- gpg_key_url="http://www.sanesecurity.net/publickey.gpg"
- # Location of GnuPG home directory
- # (If you change this, be sure that you understand the security implications:
- # signatures by *any* key in your public keyring will be accepted)
- gpg_homedir="$data_dir/gnupg"
- # Extra options for GnuPG, if required
- gpg_extra_opts=""
- # Exclude logical signatures (*.ldb)?
- # These are not supported by versions of ClamAV prior to 0.94.
- # If you use an old version of ClamAV, you should enable this option.
- #exclude_ldb=1
- ### End of configuration ###
- umask 0022
- # Check the configuration looks sane
- if [ ! -d "$clamd_dbdir" ]
- then
- echo "clamd_dbdir ($clamd_dbdir) does not exist; aborting" >&2
- echo "(check your configuration)" >&2
- exit 1
- fi
- mkdir -p "$data_dir" "$cache_dir"
- # Set up GnuPG, if necessary
- if [ ! -d "$gpg_homedir" ]
- then
- echo "GnuPG homedir is nonexistant; initialising" >&2
- echo "(This should only occur once)" >&2
- mkdir -p "$gpg_homedir"
- chmod 0700 "$gpg_homedir"
- gpg_tmp="$(mktemp -t fetch-sanesecurity-sigs.XXXXXXXXXX)"
- if ! wget -O "$gpg_tmp" "$gpg_key_url"
- then
- echo "ERROR: could not fetch GnuPG public key; aborting" >&2
- rm -f "$gpg_tmp"
- exit 4
- fi
- if ! gpg --homedir "$gpg_homedir" $gpg_extra_opts --import "$gpg_tmp"
- then
- echo "ERROR: could not import GnuPG public key; aborting" >&2
- rm -f "$gpg_tmp"
- exit 4
- fi
- rm -f "$gpg_tmp"
- fi
- # This appears to be the most portable way to find the current timestamp
- # (suggestions on how to avoid calling perl are very welcome)
- time_now="$(perl -le print+time)"
- if [ ! "$time_now" -gt 1 ]
- then
- echo "Could not find current timestamp -- is perl installed?" >&2
- exit 5
- fi
- # Check that min_interval seconds have elapsed since last run
- if [ -s "$data_dir/update-stamp" ]
- then
- time_then="$(cat "$data_dir/update-stamp")"
- minutes_elapsed=$(( (time_now - time_then) / 60 ))
- if [ "$minutes_elapsed" -lt "$min_interval" ]
- then
- echo "Must wait at least $min_interval minutes between updates; aborting" >&2
- exit 2
- fi
- fi
- # Random sleep (see comment in configuration section)
- if [ "$random_sleep" = "1" ]
- then
- # Are we running noninteractively, i.e. without a tty on stdin?
- if ! tty -s
- then
- # $RANDOM is between 0 and 32767.
- # Use this to generate a time between 30 and 32767/200+30 = 193 seconds.
- sleep_time=$((RANDOM/200+30))
- echo "Sleeping for $sleep_time seconds."
- sleep $sleep_time
- fi
- fi
- # Update the cache
- if [ "$exclude_ldb" = "1" ]
- then
- rsync_extra_opts="$rsync_extra_opts --exclude=*.ldb"
- rm -f "$cache_dir"/*.ldb
- fi
- if ! rsync --progress --delete -rt $rsync_extra_opts "$mirror/." "$cache_dir/"
- then
- echo "rsync failed; aborting." >&2
- exit 3
- fi
- echo "$time_now" > "$data_dir/update-stamp"
- chmod 0644 "$cache_dir"/*
- echo
- # Iterate through the databases in the cache
- installed=0
- for db in "$cache_dir"/*.?db "$cache_dir"/*.ftm
- do
- db_name=$(basename "$db")
- db_live="$clamd_dbdir/sanesecurity-$db_name"
- # Only pay any attention to this database if it's newer than the installed version
- if [ -e "$db_live" -a ! "$db" -nt "$db_live" ]
- then
- echo "$db_name is already up-to-date; skipping"
- continue
- fi
- # Zero-length databases have no value and confuse the test below
- if [ ! -s "$db" ]
- then
- echo "$db_name is zero-length; discarding"
- continue
- fi
- # Check that the GnuPG signature is present and correct
- if ! gpg_out=$(gpg --homedir "$gpg_homedir" $gpg_extra_opts --verify "$db.sig" "$db" 2>&1)
- then
- echo "SECURITY ERROR: $db_name has a bad GnuPG signature; discarding:" >&2
- echo "$gpg_out" >&2
- continue
- fi
- # Test the database by asking ClamAV to check something with it
- if ! clamscan --quiet --tempdir="${TMPDIR:-/tmp}" --database="$db" - < /dev/null
- then
- echo "ERROR: $db_name fails a simple test; discarding" >&2
- continue
- fi
- # Now we can actually install this database
- echo "Installing $db_name into $db_live"
- if rsync -p "$db" "$db_live"
- then
- installed=$((installed+1))
- # Clean up stuff left behind by old scripts
- rm -f "$clamd_dbdir/$db_name"*
- fi
- done
- # Finished; display summary and perhaps reload clamd
- echo
- if [ "$installed" -gt 0 ]
- then
- if [ "$installed" -eq 1 ]
- then
- s=""
- else
- s="s"
- fi
- echo "Installed $installed database$s"
- # Is clamd running?
- if [ "$clamd_pidfile" -a -f "$clamd_pidfile" ]
- then
- echo "Reloading ClamAV daemon"
- clamdscan --reload
- fi
- else
- echo "No databases installed."
- fi
- exit 0
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement