Go to most recent revision | Blame | Last modification | View Log | Download | RSS feed
#!/bin/bash
#
################################################################
#
# Virus Scanner GUI for
#
# - f-prot
# - uvscan (McAfee)
# - clamscan
#
################################################################
#
# Urs Beyerle, PSI
#
# (some parts taken from f-prot_gui.sh by Fabian Franz)
#
################################################################
#
MyVersion=0.3
#
################################################################
clean_exit()
{
rm -rf /tmp/psi-scanvirus.$$
}
trap "clean_exit" EXIT
### ------------------------------------------------------------
### definitions
### ------------------------------------------------------------
### scan engine list
ENGINE_LIST=""
### fprot
FPROT=$(which f-prot)
if [ $FPROT ]; then
FPROT_NAME="F-Prot"
FPROT_OPT="-all -ai -archive -dumb -packed -list"
FPROT_CHECKUPDATES=/usr/local/f-prot/tools/check-updates.pl
FPROT_ON="1"
ENGINE_LIST="$ENGINE_LIST $FPROT_NAME $FPROT On"
fi
### uvscan (McAfee)
UVSCAN=$(which uvscan)
if [ $UVSCAN ]; then
UVSCAN_NAME="McAfee"
UVSCAN_OPT="--secure -v -r --summary"
UVSCAN_CHECKUPDATES=/usr/local/uvscan/update-dat
UVSCAN_ON="1"
ENGINE_LIST="$ENGINE_LIST $UVSCAN_NAME $UVSCAN On"
fi
### clamscan (Clam)
CLAM=$(which clamscan)
if [ $CLAM ]; then
CLAM_NAME="Clam"
CLAM_OPT="-r"
if [ -x /usr/bin/psi-freshclam ]; then
CLAM_CHECKUPDATES=/usr/bin/psi-freshclam
else
CLAM_CHECKUPDATES=/usr/bin/freshclam
fi
CLAM_ON="1"
ENGINE_LIST="$ENGINE_LIST $CLAM_NAME $CLAM On"
# Starting Clam AntiVirus Daemon
/etc/init.d/clamd start >/dev/null
fi
### tmpdir
TMPDIR=/tmp/psi-scanvirus.$$
TMP=$TMPDIR/dialog
mkdir -p $TMPDIR
### report dir
REPORT_DIR="/var/log/psi-scanvirus"
mkdir -p /var/log/psi-scanvirus
### dialog or xdialog?
DIALOG="dialog"
XDIALOG_HIGH_DIALOG_COMPAT=1
export XDIALOG_HIGH_DIALOG_COMPAT
[ -n "$DISPLAY" ] && [ -x /usr/bin/Xdialog ] && DIALOG="Xdialog"; XDIALOG="yes"
### title
TITLE="PSI Virus Scanner v$MyVersion"
MENU_TITLE="PSI Virus Scanner v$MyVersion"
### need root rights to run!
### ------------------------------------------------------------
if [ "$UID" -ne "0" ]; then
MESSAGE0="To use this program, you need to be root"
$DIALOG --title "$TITLE" --msgbox "$MESSAGE0" 0 0
exit 1
fi
### ------------------------------------------------------------
### functions
### ------------------------------------------------------------
psi-freshclam()
### ------------------------------------------------------------
{
echo
echo "***************************************"
echo "* Clam Antivirus Updater *"
echo "***************************************"
echo
echo "Run /usr/bin/freshclam:"
/usr/bin/freshclam
echo
}
### ------------------------------------------------------------
welcome_message()
{
WELCOME_MESSAGE=$( cat <<EOF
--------------------------------------------\n
Welcome to PSI Virus Scanner v$MyVersion\n
--------------------------------------------\n
PLEASE NOTE: No files will be delete.\n
\n
Press OK to continue\n
EOF)
[ $XDIALOG ] && echo $TITLE
$DIALOG --title "$TITLE" --infobox "$WELCOME_MESSAGE" 0 0 8
[ $? -ne 0 ] && exit
}
### ------------------------------------------------------------
find_partitions()
{
PART_ALL=$(LC_ALL=C fdisk -l | sed 's/*//g' | egrep -v "swap|Extended|Ext." | awk '{ print $1 }' | grep "/dev/")
PART_LIST=$(LC_ALL=C fdisk -l | sed 's/*//g' | egrep -v "swap|Extended|Ext." | awk '{ printf("%s %s-Partition off\n",$1,$6 $7 $8 $9) }' | grep "/dev/")
# add "Select all"
PART_LIST="$PART_LIST Select All off"
}
### ------------------------------------------------------------
choose_parts()
{
MESSAGE2="Found partitions"
$DIALOG --title "$TITLE" --checklist "$MESSAGE2" 0 0 0 $PART_LIST 2>$TMP
PARTS=$(sed 's,",,g;s,//, /,g' $TMP)
# all selected ?
grep -q "Select" $TMP
if [ "$?" = "0" ]; then
PARTS=$PART_ALL
fi
[ $XDIALOG ] && echo "Partition(s) selected:"
[ $XDIALOG ] && echo $PARTS
[ -n "$PARTS" ] && FILES=""
}
### ------------------------------------------------------------
choose_dirfile()
{
$DIALOG --title $TITLE --fselect "$(pwd)/" 0 0 2>$TMP
FILES=$(cat $TMP)
[ -n "$FILES" ] && PARTS=""
}
### ------------------------------------------------------------
choose_engine()
{
MESSAGE_ENGINE="Available Virus Scan Engine(s)"
$DIALOG --title "$TITLE" --checklist "$MESSAGE_ENGINE" 0 0 4 $ENGINE_LIST 2>$TMP
# create new engine list
ENGINE_LIST=""
# deselect f-prot ?
grep -q $FPROT_NAME $TMP
if [ "$?" = "0" ]; then
ENGINE_LIST="$ENGINE_LIST $FPROT_NAME $FPROT On"; FPROT_ON="1"
else
ENGINE_LIST="$ENGINE_LIST $FPROT_NAME $FPROT Off"; FPROT_ON=""
fi
# deselect uvscan ?
grep -q $UVSCAN_NAME $TMP
if [ "$?" = "0" ]; then
ENGINE_LIST="$ENGINE_LIST $UVSCAN_NAME $UVSCAN On"; UVSCAN_ON="1"
else
ENGINE_LIST="$ENGINE_LIST $UVSCAN_NAME $UVSCAN Off"; UVSCAN_ON=""
fi
# deselect clamscan ?
grep -q $CLAM_NAME $TMP
if [ "$?" = "0" ]; then
ENGINE_LIST="$ENGINE_LIST $CLAM_NAME $CLAM On"; CLAM_ON="1"
else
ENGINE_LIST="$ENGINE_LIST $CLAM_NAME $CLAM Off"; CLAM_ON=""
fi
}
### ------------------------------------------------------------
define_report()
{
DATE=$(date +"%Y-%m-%d")
DIVIDER="------------------------------------------------------------------------------------------"
DOTS=".........\n.........\n........."
### where to report
REPORT_TMP=$REPORT_DIR/report.tmp
rm -rf $REPORT_TMP
touch $REPORT_TMP
NR=$(ls $REPORT_DIR/$PREFIX* 2>/dev/null | wc -l | tr -d " ")
if [ $FPROT_ON ]; then
FPROT_REPORT="$REPORT_DIR/report_fprot-$DATE-$NR.txt"
FPROT_REPORT_MIN="$REPORT_DIR/report_fprot-$DATE-$NR.min.txt"
echo $DIVIDER > $FPROT_REPORT
echo "F-Prot Report:" >> $FPROT_REPORT
cat $FPROT_REPORT > $FPROT_REPORT_MIN
fi
if [ $UVSCAN_ON ]; then
UVSCAN_REPORT="$REPORT_DIR/report_mcafee-$DATE-$NR.txt"
UVSCAN_REPORT_MIN="$REPORT_DIR/report_mcafee-$DATE-$NR.min.txt"
echo $DIVIDER > $UVSCAN_REPORT
echo "McAfee Report:" >> $UVSCAN_REPORT
echo $DIVIDER >> $UVSCAN_REPORT
$UVSCAN --version >> $UVSCAN_REPORT
cat $UVSCAN_REPORT > $UVSCAN_REPORT_MIN
fi
if [ $CLAM_ON ]; then
CLAM_REPORT="$REPORT_DIR/report_clam-$DATE-$NR.txt"
CLAM_REPORT_MIN="$REPORT_DIR/report_clam-$DATE-$NR.min.txt"
echo $DIVIDER > $CLAM_REPORT
echo "Clam Report:" >> $CLAM_REPORT
echo $DIVIDER >> $CLAM_REPORT
$CLAM --version >> $CLAM_REPORT
cat $CLAM_REPORT > $CLAM_REPORT_MIN
fi
}
### ------------------------------------------------------------
report_fprot()
{
[ $XDIALOG ] && echo -n "Creating F-Prot report... "
# create report (normal and min)
# normal report
echo $DIVIDER >> $FPROT_REPORT
echo $PART_TOSCAN >> $FPROT_REPORT
echo $DIVIDER >> $FPROT_REPORT
cat $REPORT_TMP >> $FPROT_REPORT
echo $DIVIDER >> $FPROT_REPORT
echo >> $FPROT_REPORT
# min report
echo $DIVIDER >> $FPROT_REPORT_MIN
echo $PART_TOSCAN >> $FPROT_REPORT_MIN
echo $DIVIDER >> $FPROT_REPORT_MIN
head -n 25 $REPORT_TMP >> $FPROT_REPORT_MIN
echo -e $DOTS >> $FPROT_REPORT_MIN
tail -n 20 $REPORT_TMP >> $FPROT_REPORT_MIN
echo $DIVIDER >> $FPROT_REPORT_MIN
grep " Infection: " $REPORT_TMP >> $FPROT_REPORT_MIN
grep " Infection: " $REPORT_TMP
if [ "$?" = "0" ]; then
echo "VIRUS INFECTION FOUND !!!" >> $FPROT_REPORT_MIN
[ $XDIALOG ] && echo "VIRUS INFECTION FOUND !!!"
echo $DIVIDER >> $FPROT_REPORT_MIN
fi
echo >> $FPROT_REPORT_MIN
rm -f $REPORT_TMP
touch $REPORT_TMP
[ $XDIALOG ] && echo " done."
}
### ------------------------------------------------------------
report_uvscan()
{
[ $XDIALOG ] && echo -n "Creating McAfee report... "
# create report (normal and min)
# normal report
echo $DIVIDER >> $UVSCAN_REPORT
echo $PART_TOSCAN >> $UVSCAN_REPORT
echo $DIVIDER >> $UVSCAN_REPORT
cat $REPORT_TMP >> $UVSCAN_REPORT
echo $DIVIDER >> $UVSCAN_REPORT
echo >> $UVSCAN_REPORT
# min report
echo $DIVIDER >> $UVSCAN_REPORT_MIN
echo $PART_TOSCAN >> $UVSCAN_REPORT_MIN
echo $DIVIDER >> $UVSCAN_REPORT_MIN
head -n 10 $REPORT_TMP >> $UVSCAN_REPORT_MIN
echo -e $DOTS >> $UVSCAN_REPORT_MIN
tail -n 12 $REPORT_TMP >> $UVSCAN_REPORT_MIN
echo $DIVIDER >> $UVSCAN_REPORT_MIN
grep " Found: " $REPORT_TMP >> $UVSCAN_REPORT_MIN
grep " Found: " $REPORT_TMP
if [ "$?" = "0" ]; then
echo "VIRUS INFECTION FOUND !!!" >> $UVSCAN_REPORT_MIN
[ $XDIALOG ] && echo "VIRUS INFECTION FOUND !!!"
echo $DIVIDER >> $UVSCAN_REPORT_MIN
fi
echo >> $UVSCAN_REPORT_MIN
rm -f $REPORT_TMP
touch $REPORT_TMP
[ $XDIALOG ] && echo " done."
}
### ------------------------------------------------------------
report_clam()
{
[ $XDIALOG ] && echo -n "Creating Clam report... "
# create report (normal and min)
# normal report
echo $DIVIDER >> $CLAM_REPORT
echo $PART_TOSCAN >> $CLAM_REPORT
echo $DIVIDER >> $CLAM_REPORT
cat $REPORT_TMP >> $CLAM_REPORT
echo $DIVIDER >> $CLAM_REPORT
echo >> $CLAM_REPORT
# min report
echo $DIVIDER >> $CLAM_REPORT_MIN
echo $PART_TOSCAN >> $CLAM_REPORT_MIN
echo $DIVIDER >> $CLAM_REPORT_MIN
head -n 5 $REPORT_TMP >> $CLAM_REPORT_MIN
echo -e $DOTS >> $CLAM_REPORT_MIN
tail -n 15 $REPORT_TMP >> $CLAM_REPORT_MIN
echo $DIVIDER >> $CLAM_REPORT_MIN
grep " FOUND$" $REPORT_TMP >> $CLAM_REPORT_MIN
grep " FOUND$" $REPORT_TMP
if [ "$?" = "0" ]; then
echo "VIRUS INFECTION FOUND !!!" >> $CLAM_REPORT_MIN
[ $XDIALOG ] && echo "VIRUS INFECTION FOUND !!!"
echo $DIVIDER >> $CLAM_REPORT_MIN
fi
echo >> $CLAM_REPORT_MIN
rm -f $REPORT_TMP
touch $REPORT_TMP
[ $XDIALOG ] && echo " done."
}
### ------------------------------------------------------------
show_reports()
{
### show report
[ $FPROT_ON ] && $DIALOG --title "$TITLE: F-Prot Small Report" \
--textbox $FPROT_REPORT_MIN 0 0
[ $UVSCAN_ON ] && $DIALOG --title "$TITLE: McAfee Small Report" \
--textbox $UVSCAN_REPORT_MIN 0 0
[ $CLAM_ON ] && $DIALOG --title "$TITLE: Clam Small Report" \
--textbox $CLAM_REPORT_MIN 0 0
### info about report files
REPORT_MESSAGE="\nVirus Scan Reports can be found in $REPORT_DIR\n"
$DIALOG --title "$TITLE" --no-close --infobox "$REPORT_MESSAGE" 0 0 5
[ $XDIALOG ] && echo -e "$REPORT_MESSAGE"
}
### ------------------------------------------------------------
scan()
{
if [ -z "$PARTS" -a -z "$FILES" ]; then
MESSAGE3="Please select partition(s) or directory/file first."
$DIALOG --title "$TITLE" --msgbox "$MESSAGE3" 0 0
return
fi
if [ -z "$SCAN_WITH" ]; then
MESSAGE_SORRY="Sorry, either no scan engine selected or available."
$DIALOG --title "$TITLE" --msgbox "$MESSAGE_SORRY" 0 0
return
fi
### mount partitions
TOSCAN=""
for i in $PARTS; do
mkdir -p /mnt/${i/\/dev\//}
# first umount
umount $i 2>/dev/null
mount -o "ro" $i /mnt/${i/\/dev\//}
if [ "$?" != "0" ]; then
MESSAGE_UMOUNT="Partiton $i could not be mounted."
$DIALOG --title "$TITLE" --msgbox "$MESSAGE_UMOUNT" 0 0
fi
TOSCAN="$TOSCAN /mnt/${i/\/dev\//}"
done
TOSCAN="$TOSCAN $FILES"
MESSAGE4="Scanning files on"
MESSAGE5="Searching for files, that will be scanned ..."
### define where to report
define_report
### watch $REPORT_TMP
if [ $XDIALOG ]; then
xterm -sb -title "tail -F $REPORT_TMP" -e tail -F $REPORT_TMP &
fi
### scan each partition
for PART_TOSCAN in $TOSCAN; do
[ $XDIALOG ] && echo "Scanning $PART_TOSCAN... "
### scan with FPROT
if [ $FPROT_ON ]; then
{ max=$(find $PART_TOSCAN -type f | wc -l )
echo -e "XXX\nF-Prot: $MESSAGE4: $PART_TOSCAN\nXXX"
$FPROT $FPROT_OPT -report=$REPORT_TMP $PART_TOSCAN | grep "^$PART_TOSCAN" | sed 's/->.*//g' | uniq | while read a; do count=$[count+1]; echo $[count*100/max]; done
} | $DIALOG --title "$TITLE" --gauge "$MESSAGE5 $PART_TOSCAN" 10 40
report_fprot
fi
### scan with UVSCAN (McAfee)
if [ $UVSCAN_ON ]; then
{ max=$(find $PART_TOSCAN | wc -l )
echo -e "XXX\nMcAfee: $MESSAGE4: $PART_TOSCAN\nXXX"
$UVSCAN $UVSCAN_OPT $PART_TOSCAN 2>/dev/null | tee $REPORT_TMP 2>/dev/null | grep "^Scanning" | grep -v "\.zip" | grep -v "\.tar" | grep -v ".\tgz" | while read a; do count=$[count+1]; echo $[count*100/max]; done
} | $DIALOG --title "$TITLE" --gauge "$MESSAGE5 $PART_TOSCAN" 10 40
report_uvscan
fi
### scan clamscan (Clam)
if [ $CLAM_ON ]; then
{ max=$(find $PART_TOSCAN -type f | wc -l )
echo -e "XXX\nClam: $MESSAGE4: $PART_TOSCAN\nXXX"
$CLAM $CLAM_OPT $PART_TOSCAN 2>/dev/null | tee $REPORT_TMP 2>/dev/null | grep "^$PART_TOSCAN" | while read a; do count=$[count+1]; echo $[count*100/max]; done
} | $DIALOG --title "$TITLE" --gauge "$MESSAGE5 $PART_TOSCAN" 10 40
report_clam
fi
done
### unmount partitions
for i in $PARTS; do
umount /mnt/${i/\/dev\//}
done
### show reports
show_reports
}
shutdown ()
{
$DIALOG --title "$TITLE" --radiolist "Reboot or shutdown the PC?" 0 0 3 poweroff "" on reboot "" off 2>$TMP
ACTION=$(cat $TMP)
if [ $ACTION ]; then
$ACTION
exit 1
fi
}
online_update ()
{
# remove old temporary dir
rm -rf /var/tmp/f-prot
if [ -n "$DISPLAY" ]; then
xterm -sb -e "$FPROT_CHECKUPDATES; $UVSCAN_CHECKUPDATES; $CLAM_CHECKUPDATES; echo 'Press a key to continue ...'; read -n1"
else
$FPROT_CHECKUPDATES; $UVSCAN_CHECKUPDATES; $CLAM_CHECKUPDATES; echo 'Press a key to continue ...'; read -n1
fi
rm -rf /var/tmp/f-prot
}
### ------------------------------------------------------------
### Main Program
### ------------------------------------------------------------
### find partitons
find_partitions
### print welcome message
welcome_message
### menu
### ------------------------------------------------------------
MENU_1="Select partition(s)"
MENU_2="(or: Select a directory/file)"
MENU_3="Choose Scan Engine(s)"
MENU_4="Start Scanning"
MENU_5="Do Online-Update"
MENU_6="Reboot/Shutdown"
MENU_7="Quit"
while true; do
SCAN_WITH=""
[ $FPROT_ON ] && SCAN_WITH=" $FPROT_NAME"
[ $UVSCAN_ON ] && SCAN_WITH="$SCAN_WITH $UVSCAN_NAME"
[ $CLAM_ON ] && SCAN_WITH="$SCAN_WITH $CLAM_NAME"
$DIALOG --title "$TITLE" \
--menu "$MENU_TITLE" 0 0 7\
1 "$MENU_1"\
2 "$MENU_2"\
3 "$MENU_3" \
4 "$MENU_4 (with$SCAN_WITH)" \
5 "$MENU_5" \
6 "$MENU_6" \
7 "$MENU_7" \
2> $TMP
[ $? -ne 0 ] && break
CHOICE=$(cat $TMP)
case "$CHOICE" in
1)
choose_parts
;;
2)
choose_dirfile
;;
3)
choose_engine
;;
4)
scan
;;
5)
online_update
;;
6)
shutdown || break
;;
7)
break
;;
esac
done