#!/bin/bash
# script to install spamdyke in a qmail-toaster
# Copyright (C) 2008-2010 Eric Shubert <ejs@shubes.net>
######################################################################
# 02/08/13 added "dynamic" to blacklist_keywords file
# 12/14/12 added rule to filter multiple From: addresses
# 6/06/12 changed greeting delay from 5 to 6 seconds
# 7/28/10 fixed problem where run.dist file would get clobbered
# 1/25/10 added installation of qtp-prune-graylist script
# 11/5/09 added tls-level parameter to have spamdyke to do tls
# 8/30/08 modified for v4
# 5/05/08 added localhost to whitelist (for squirrelmail)
# 4/12/08 written by Eric 'shubes' <ejs@shubes.net>
#
WEB_LOC=http://www.spamdyke.org/releases
SRC_DIR=/usr/src/spamdyke
CONF_LINK=/etc/spamdyke
VAR_LINK=/var/spamdyke
BASE_DIR=/opt/spamdyke
CONF_DIR=$BASE_DIR/etc
VAR_DIR=$BASE_DIR/var
CONF_FILE=$CONF_DIR/spamdyke.conf
QMAIL_SUPERVISE=/var/qmail/supervise
QMAIL_CONTROL=/var/qmail/control
RCPTHOSTFILES="rcpthosts morercpthosts"

######################################################################
# Figure out which version to get
#
a1_determine_version(){

# Make sure we're root
if [ "$UID" != "0" ]; then
  echo "Error: You are not logged in as root, please su -"
  exit 1
fi

echo "$me $myver - getting latest spamdyke version ..."

VERSION=$(wget -O - $WEB_LOC/CURRENT-4.x 2>/dev/null)
if [ "$?" != "0" ]; then
  echo "$me - unable to reach $WEB_LOC/CURRENT-4.x, pleas try again later."
  exit 1
fi

newver=${VERSION%%.*}
}

######################################################################
# Download and unpack the source tarball.
#
a2_get_package(){

echo "$me $myver - downloading spamdyke-$VERSION ..."

mkdir -p $SRC_DIR
cd $SRC_DIR
rm -rf spamdyke-$VERSION*
wget $WEB_LOC/spamdyke-$VERSION.tgz 2>/dev/null
tar -xzf spamdyke-$VERSION.tgz
}

######################################################################
# Compile the spamdyke program
# There should be no warning or error messages
#
a3_compile_package(){

echo "$me $myver - compiling spamdyke-$VERSION ..."

cd spamdyke-$VERSION/spamdyke
./configure
make
}

######################################################################
# determine which version is already installed
#
a4_check_installed_version(){

sdver=$(spamdyke -v 2>&1)
rc=$?

if [ "$rc" == "0" ]; then
  sdverstring=$(echo "$sdver" | sed -e 's/^spamdyke //')
  instver=${sdverstring%%.*}
else
  instver=0
fi
}

######################################################################
# Put the program in place (what "make install" might do).
#
a5_install_program(){

echo "$me $myver - installing spamdyke-$VERSION ..."
mkdir -p $BASE_DIR/bin
mv -f spamdyke $BASE_DIR/bin/.
ln -f -s ../../..$BASE_DIR/bin/spamdyke /usr/local/bin/.
}

######################################################################
# Put configuration files in place
#
a6_create_config_files(){

echo "$me $myver - configuring spamdyke-$VERSION ..."

b62_config_graylist

if [ -d $CONF_DIR ]; then
  mv $CONF_DIR $CONF_DIR.$(date +%Y%m%d-%H%M)
fi

mkdir -p $CONF_DIR
rm -f $CONF_LINK $VAR_LINK
ln -s ..$CONF_DIR $CONF_LINK
ln -s ..$VAR_DIR $VAR_LINK
touch $CONF_DIR/blacklist_ip \
      $CONF_DIR/blacklist_rdns \
      $CONF_DIR/blacklist_recipients \
      $CONF_DIR/blacklist_senders \
      $CONF_DIR/whitelist_keywords \
      $CONF_DIR/whitelist_rdns \
      $CONF_DIR/whitelist_recipients \
      $CONF_DIR/whitelist_senders

echo "127.0.0.1"  >$CONF_DIR/whitelist_ip

echo "# These are words which will reject the sender"
                  >$CONF_DIR/blacklist_keywords
echo "# when matched in an rDNS name along with an IP address."
                 >>$CONF_DIR/blacklist_keywords
echo "dynamic"   >>$CONF_DIR/blacklist_keywords

b65_create_conf_file
}

######################################################################
# Create graylist configuration for all domains
#
b62_config_graylist(){

rm -rf $VAR_DIR/graylist
mkdir -p $VAR_DIR/graylist

for rcpthostsfile in $RCPTHOSTFILES; do
  if [ -f $QMAIL_CONTROL/$rcpthostsfile ]; then
    for domain in $(cat $QMAIL_CONTROL/$rcpthostsfile); do
      mkdir -p $VAR_DIR/graylist/$domain
    done
  fi
done

chown -R vpopmail:vchkpw $VAR_DIR
}

######################################################################
# Create main configuration file
#
b65_create_conf_file(){

echo "#dns-blacklist-entry=zombie.dnsbl.sorbs.net"               >$CONF_FILE
echo "#dns-blacklist-entry=dul.dnsbl.sorbs.net"                 >>$CONF_FILE
echo "#dns-blacklist-entry=bogons.cymru.com"                    >>$CONF_FILE
echo "dns-blacklist-entry=zen.spamhaus.org"                     >>$CONF_FILE
echo "dns-blacklist-entry=bl.spamcop.net"                       >>$CONF_FILE
echo "graylist-dir=$VAR_LINK/graylist"                          >>$CONF_FILE
echo "graylist-level=always"                                    >>$CONF_FILE
echo "graylist-max-secs=2678400"                                >>$CONF_FILE
echo "graylist-min-secs=180"                                    >>$CONF_FILE
echo "greeting-delay-secs=6"                                    >>$CONF_FILE
echo "header-blacklist-entry=From:*>,*<*"                       >>$CONF_FILE
echo "idle-timeout-secs=60"                                     >>$CONF_FILE
echo "ip-blacklist-file=$CONF_LINK/blacklist_ip"                >>$CONF_FILE
echo "ip-in-rdns-keyword-blacklist-file=$CONF_LINK/blacklist_keywords" \
                                                                >>$CONF_FILE
echo "ip-in-rdns-keyword-whitelist-file=$CONF_LINK/whitelist_keywords" \
                                                                >>$CONF_FILE
echo "ip-whitelist-file=$CONF_LINK/whitelist_ip"                >>$CONF_FILE

for rcpthostsfile in $RCPTHOSTFILES; do
  if [ -f $QMAIL_CONTROL/$rcpthostsfile ]; then
    echo "local-domains-file=$QMAIL_CONTROL/$rcpthostsfile"     >>$CONF_FILE
  fi
done

echo "log-level=info"                                           >>$CONF_FILE
echo "log-target=stderr"                                        >>$CONF_FILE
echo "max-recipients=50"                                        >>$CONF_FILE
echo "#policy-url=http://my.policy.explanation.url/"            >>$CONF_FILE
echo "rdns-blacklist-file=$CONF_LINK/blacklist_rdns"            >>$CONF_FILE
echo "rdns-whitelist-file=$CONF_LINK/whitelist_rdns"            >>$CONF_FILE
echo "recipient-blacklist-file=$CONF_LINK/blacklist_recipients" >>$CONF_FILE
echo "recipient-whitelist-file=$CONF_LINK/whitelist_recipients" >>$CONF_FILE
echo "reject-empty-rdns"                                        >>$CONF_FILE
echo "#reject-ip-in-cc-rdns"                                    >>$CONF_FILE
echo "reject-missing-sender-mx"                                 >>$CONF_FILE
echo "reject-unresolvable-rdns"                                 >>$CONF_FILE
echo "sender-blacklist-file=$CONF_LINK/blacklist_senders"       >>$CONF_FILE
echo "sender-whitelist-file=$CONF_LINK/whitelist_senders"       >>$CONF_FILE
echo "tls-certificate-file=$QMAIL_CONTROL/servercert.pem"       >>$CONF_FILE
echo "tls-level=smtp"                                           >>$CONF_FILE
}

######################################################################
# set up smtp run file as symlink, then create new smtp run file
#
a7_create_run_file(){

echo "$me $myver - creating smtp run file ..."

if [ ! -f $QMAIL_SUPERVISE/smtp/run.dist ]; then
  mv $QMAIL_SUPERVISE/smtp/run $QMAIL_SUPERVISE/smtp/run.dist
fi

ln -f -s run.dist $QMAIL_SUPERVISE/smtp/run

cat $QMAIL_SUPERVISE/smtp/run.dist | sed  \
      -e "/^BLACKLIST/d; /^RBLSMTPD/d; s|\$RBLSMTPD \$BLACKLIST ||" \
      -e "/^MAXSMTPD/a\SPAMDYKE=\"/usr/local/bin/spamdyke\"" \
      -e "/^MAXSMTPD/a\SPAMDYKE_CONF=\"$CONF_LINK/spamdyke.conf\"" \
      -e "/0 smtp/a\     \$SPAMDYKE --config-file \$SPAMDYKE_CONF \\\\" \
      > $QMAIL_SUPERVISE/smtp/run.spamdyke

chown qmaill:qmail $QMAIL_SUPERVISE/smtp/run.spamdyke
chmod 751          $QMAIL_SUPERVISE/smtp/run.spamdyke
}

######################################################################
# run configuration test
#
a8_run_config_test(){

echo ""
echo "$me $myver - running spamdyke config test ..."
echo ""

# set variables for qmail-smtpd using harmless test values,
# so we don't get warnings about qmail-smtpd
export PROTO=TCP
export TCPLOCALHOST=$(hostname --fqdn)
export TCPLOCALIP=127.0.0.1
export TCPLOCALPORT=25025

/usr/local/bin/spamdyke \
      --config-file $CONF_LINK/spamdyke.conf \
      --config-test \
      --run-as-user vpopmail:vchkpw \
      /var/qmail/bin/qmail-smtpd \
      /home/vpopmail/bin/vchkpw /bin/true \
      2>&1

return $?
}

######################################################################
# main routine begins here
#
me=${0##*/}
myver=v0.3.6

a1_determine_version
a2_get_package
a3_compile_package
a4_check_installed_version

if [ "$instver" != "$newver" ] \
      && [ "$instver" != "0" ]; then
  echo "qmail must be stopped briefly to upgrade from spamdyke $instver to $newver"
  echo -n "would you like to proceed? [y]/n: "
  read REPLY
  case $REPLY in
    "n" | "no" | "N" )
      echo "ok. Please rerun $me when qmail can be stopped."
      exit 1
      ;;
  esac
  qmailctl stop
  sleep 3
fi

a5_install_program

if [ "$instver" != "$newver" ]; then
  a6_create_config_files
fi

if [ ! -f $QMAIL_SUPERVISE/smtp/run.spamdyke ]; then
  a7_create_run_file
fi

a8_run_config_test
rc=$?
echo ""

if [ "$rc" == "0" ]; then
  ln -f -s run.spamdyke $QMAIL_SUPERVISE/smtp/run
  cronjob=/etc/cron.daily/qtp-prune-graylist
  if [ -f "/opt/qmailtoaster-plus/$cronjob" ]; then
    cp /opt/qmailtoaster-plus/$cronjob $cronjob
    chmod +x $cronjob
  fi
  echo "$me $myver - Installation of spamdyke-$VERSION is complete."
  if [ "$instver" == "0" ]; then
    echo "$me $myver - spamdyke will be active once you start (or restart) qmail."
  else
    if [ "$instver" == "$newver" ]; then
      echo "$me $myver - upgraded spamdyke is automatically active."
    else
      qmailctl start
      echo "$me $myver - qmail has been started, and the upgraded spamdyke is active."
    fi
  fi
else
  echo "$me $myver - spamdyke configuration problem(s) detected."
  echo "$me $myver - please fix problem(s), then try again."
  if [ "$instver" != "$newver" ] \
        && [ "$instver" != "0" ]; then
    qmailctl start
    echo "$me $myver - qmail has been restarted."
  fi
fi

exit $rc
