#!/bin/sh
#
# service-qmail-smtpd-run (formerly "run.smtp" and "run.smtp.sslserver")
# John Simpson <jms1@jms1.net> 2003-07-05 to 2008-03-24
#
# Generic daemontools "run" script for qmail "smtp" or "smtpssl" service.
#
# Documentation: http://qmail.jms1.net/scripts/service-qmail-smtpd-run.shtml
#
###############################################################################
#
# Copyright (C) 2003-2007 John Simpson.
#
# 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
# or visit http://www.gnu.org/licenses/gpl.txt
#
###############################################################################

exec 2>&1
VQ="/var/qmail"
PATH="$VQ/bin:/usr/local/bin:/usr/bin:/bin"
QUSER=vpopmail
LOCAL=`head -1 $VQ/control/me`

###############################################################################
#
# options for tcpserver/sslserver

IP=0
PORT=465
SSL=1
SSL_CERT="$VQ/control/servercert.pem"
SMTP_CDB="/etc/tcp.smtp.cdb"
MAX=30

# these require the "tcpserver limits" patch for ucspi-tcp, available here:
# http://linux.voyager.hr/ucspi-tcp/

#MAXLOAD=750
#MAXCONNIP=2
#MAXCONNC=5
#DIEMSG="421 $LOCAL Service temporarily unavailable"

# my newer version of the tcpserver limits patch allows you to specify
# individual DIEMSG values for each policy.
# http://qmail.jms1.net/ucspi-tcp/

#DIEMSG_MAXLOAD="421 $LOCAL Server busy, try again later."
#DIEMSG_MAXCONNIP="421 $LOCAL Too many connections from your IP."
#DIEMSG_MAXCONNC="421 $LOCAL Too many connections from your network."

###############################################################################
#
# options for programs which run before qmail-smtpd

#RBLSMTPD_PROG="rblsmtpd"
#RBL_GOOD=""
#RBL_BAD="zen.spamhaus.org dnsbl.sorbs.net bl.spamcop.net"

#GREYLIST="jgreylist"

#JGREYLIST_DIR="$VQ/jgreylist"
#JGREYLIST_NOREV=1
#JGREYLIST_BY_IP=0
#JGREYLIST_HOLDTIME=120
#JGREYLIST_LOG=1
#JGREYLIST_LOG_PID=1
#JGREYLIST_LOG_SMTP=0
#JGREYLIST_TIMEOUT=60
#JGREYLIST_LIMIT=0

#RECORDIO="recordio"

###############################################################################
#
# options for qmail-smtpd itself

SMTPD="qmail-smtpd"
#SMTPGREETING="$LOCAL NO UCE"
#GREETDELAY=30
#DROP_PRE_GREET=1
FORCE_TLS=0
DENY_TLS=0
MFCHECK=3
#MAXRCPT=100
#RELAYREJ=1
QMAILSMTPD_LOG_MAIL=1
QMAILSMTPD_LOG_RCPT=1
#QMAILSMTPD_HELP_VERSION=1

###############################################################################
#
# options pertaining to the AUTH command.

AUTH=1
REQUIRE_AUTH=1
ALLOW_INSECURE_AUTH=0

# if using the AUTH_CDB method
#AUTH_CDB="$VQ/control/auth.cdb"

# if using the CHECKPW method
CHECKPW=~vpopmail/bin/vchkpw
TRUE=`which true`

# to change the environment whenever somebody authenticates
#AUTH_SET_MFCHECK=0
#AUTH_SET_MAXRCPT=0
#AUTH_SET_DATABYTES=0
#AUTH_SET_SPFBEHAVIOR=1
#AUTH_SET_VALIDRCPTTO_LIMIT=10
#AUTH_SET_VALIDRCPTTO_LOG=1
#AUTH_SET_SPF_LOG=1
#AUTH_SET_RELAYREJ=0
#AUTH_SET_VALIDRCPTTO_CDB=""
#AUTH_SET_QMAILSMTPD_LOG_MAIL=1
#AUTH_SET_QMAILSMTPD_LOG_RCPT=1
#AUTH_SET_QMAILSMTPD_HELP_VERSION=1

###############################################################################
#
# options pertaining to the "validrcptto.cdb" mechanism.
# see http://qmail.jms1.net/patches/validrcptto.cdb.shtml for details.

#VALIDRCPTTO_CDB="$VQ/control/validrcptto.cdb"
#VALIDRCPTTO_LIMIT=10
#VALIDRCPTTO_LOG=2

###############################################################################
#
# options pertaining to the SPF mechanism.

SPFBEHAVIOR=3
SPF_LOG=1
SPF_BLOCK_PLUS_ALL=1

###############################################################################
#
# options pertaining to the Domainkeys mechanism.
# this requires an add-on patch.

#DOMAINKEYS=0
#DKVERIFY=DEfGhIJK
#AUTH_SET_DKSIGN=/etc/domainkeys/%/default

###############################################################################
#
# options for programs which run after qmail-smtpd

# if you are using simscan...

#QMAILQUEUE="$VQ/bin/simscan"
NOP0FCHECK=1
#SIMSCAN_DEBUG=0
#SIMSCAN_DEBUG_FILES=0

# if you are using qmail-scanner, un-comment ONE of these lines.

#QMAILQUEUE="$VQ/bin/qmail-scanner-queue"
#QMAILQUEUE="$VQ/bin/qmail-scanner-queue.pl"

# if you're using some other qmail-queue replacement, add your own line here
# with the correct value.


###############################################################################
###############################################################################
###############################################################################
#
# THERE SHOULD BE NO NEED TO CHANGE ANYTHING BELOW THIS LINE. of course, the
# script is on your system and you're free to edit it however you want, but
# changing things below this point may cause strange things to happen. make
# sure you understand what you're doing if you change anything below...

QDUID=`id -u $QUSER`
QDGID=`id -g $QUSER`

if [ -z "$IP" -o "$IP" = "unset" ]
then
	echo "The IP variable is not set in the run script. Cannot start."
	sleep 5
	exit 1
fi

if [ -z "$QDUID" -o -z "$QDGID" -o -z "$MAX" -o -z "$LOCAL" \
	-o -z "$SSL" -o -z "$AUTH" ]
then
	echo "One of the variables QDUID, QDGID, MAX, LOCAL, SSL, or AUTH"
	echo "is not set in the run script. Cannot start."
	sleep 5
	exit 1
fi

if [ ! -f $VQ/control/rcpthosts ]
then
	echo Creating emtpy $VQ/control/rcpthosts file to prevent open relay.
	touch $VQ/control/rcpthosts
	chmod 644 $VQ/control/rcpthosts
fi

if [ "$SSL" = "1" ]
then
	if ! which sslserver > /dev/null 2>&1
	then
		echo ERROR: sslserver not found in PATH [$PATH]
		exit 1
	fi

	if [ ! -f $SSL_CERT ]
	then
		echo ERROR: $SSL_CERT does not exist
		exit 1
	fi

	export CERTFILE=${SSL_CERT}
	export KEYFILE=""
	export DHFILE=""

	SCMD="sslserver -e"
else
	if [ -n "$SSL_CERT" ]
	then
		export TLS_SERVER_CERT=${SSL_CERT}
	fi

	SCMD="tcpserver"
fi

if [ "$IP" = "127.0.0.1" ]
then
	export RELAYCLIENT=""
	RBLSMTPD_PROG=""
	ACMD=""
elif [ -z "${SMTP_CDB:-}" ]
then
	ACMD=""
else
	if [ ! -f "$SMTP_CDB" ]
	then
		echo ERROR: $SMTP_CDB does not exist
		exit 1
	fi

	ACMD="-x $SMTP_CDB"
fi

if [ "$AUTH" = "1" ]
then
	if [ -n "$AUTH_CDB" ]
	then
		if [ ! -f $AUTH_CDB ]
		then
			echo ERROR: AUTH_CDB file [$AUTH_CDB] does not exist
			exit 1
		fi

		export AUTH_CDB
		ARGS=""
	elif [ -n "$CHECKPW" ]
	then
		if [ ! -f $CHECKPW ]
		then
			echo ERROR: $CHECKPW [$CHECKPW] program does not exist
			exit 1
		fi

		if [ -z "$LOCAL" ]
		then
			echo ERROR: LOCAL is not set in the run script
			exit 1
		elif [ -z "$TRUE" ]
		then
			echo ERROR: TRUE is not set in the run script
			exit 1
		elif [ ! -e $TRUE ]
		then
			echo ERROR: $TRUE [$TRUE] is not an executable
			exit 1
		fi

		ARGS=" $LOCAL $CHECKPW $TRUE"
	else
		echo ERROR: AUTH=1 but no AUTH_CDB or CHECKPW
		exit 1
	fi
else
	ARGS=""
	AUTH_CDB=""
fi

########################################
# make RBL command (if needed)

RBLCMD=""

if [ -n "$RBLSMTPD_PROG" ]
then
	if [ -n "$RBL_GOOD" ]
	then
		for name in $RBL_GOOD
		do
			RBLCMD="$RBLCMD -a $name"
		done
	fi

	if [ -n "$RBL_BAD" ]
	then
		for name in $RBL_BAD
		do
			RBLCMD="$RBLCMD -r $name"
		done
	fi

	if [ -n "$RBLCMD" ]
	then
		RBLCMD="$RBLSMTPD_PROG -t0 $RBLCMD"
	fi
fi

########################################
# make domainkeys command (if needed)

if [ "$DOMAINKEYS" = "1" ]
then
	if [ -f "$VQ/bin/qmail-dk" ]
	then
		if [ -n "$QMAILQUEUE" ]
		then
			export DKQUEUE="$QMAILQUEUE"
		fi
		export AUTH_UNSET_DKVERIFY=1
		export QMAILQUEUE="$VQ/bin/qmail-dk"

		if [ -n "$DKVERIFY" ] ; then export DKVERIFY ; fi
		if [ -n "$DKSIGN"   ] ; then export DKSIGN   ; fi
	else
		echo ERROR: $VQ/bin/qmail-dk not found, cannot use domainkeys
	fi
fi

########################################
# handle variables which may not have been set, but need to exist even
# if they contain blank values

if [ -z "$RECORDIO" ]
then
	RECORDIO=""
fi

if [ -z "$GREYLIST" ]
then
	GREYLIST=""
fi

########################################
# do the deed

for n in SSL					\
	MAXLOAD					\
	MAXCONNIP				\
	MAXCONNC				\
	DIEMSG					\
	DIEMSG_MAXLOAD				\
	DIEMSG_MAXCONNIP			\
	DIEMSG_MAXCONNC				\
	JGREYLIST_DIR				\
	JGREYLIST_NOREV				\
	JGREYLIST_BY_IP				\
	JGREYLIST_HOLDTIME			\
	JGREYLIST_LOG				\
	JGREYLIST_LOG_PID			\
	JGREYLIST_LOG_SMTP			\
	JGREYLIST_TIMEOUT			\
	JGREYLIST_LIMIT				\
	SMTPGREETING				\
	GREETDELAY				\
	DROP_PRE_GREET				\
	FORCE_TLS				\
	DENY_TLS				\
	MFCHECK					\
	MAXRCPT					\
	RELAYREJ				\
	QMAILSMTPD_LOG_MAIL			\
	QMAILSMTPD_LOG_RCPT			\
	QMAILSMTPD_HELP_VERSION			\
	REQUIRE_AUTH				\
	ALLOW_INSECURE_AUTH			\
	AUTH_CDB				\
	AUTH_SET_MFCHECK			\
	AUTH_SET_MAXRCPT			\
	AUTH_SET_DATABYTES			\
	AUTH_SET_SPFBEHAVIOR			\
	AUTH_SET_VALIDRCPTTO_LIMIT		\
	AUTH_SET_VALIDRCPTTO_LOG		\
	AUTH_SET_SPF_LOG			\
	AUTH_SET_RELAYREJ			\
	AUTH_SET_VALIDRCPTTO_CDB		\
	AUTH_SET_QMAILSMTPD_LOG_MAIL		\
	AUTH_SET_QMAILSMTPD_LOG_RCPT		\
	AUTH_SET_QMAILSMTPD_HELP_VERSION	\
	VALIDRCPTTO_CDB				\
	VALIDRCPTTO_LIMIT			\
	VALIDRCPTTO_LOG				\
	SPFBEHAVIOR				\
	SPF_LOG					\
	SPF_BLOCK_PLUS_ALL			\
	DKVERIFY				\
	AUTH_SET_DKSIGN				\
	QMAILQUEUE				\
	NOP0FCHECK				\
	SIMSCAN_DEBUG				\
	SIMSCAN_DEBUG_FILES
do
	# note: not 100% sure "eval" works under old-school /bin/sh
	eval "if [ -n \"\$$n\" ];then echo \"$n=\\\"\$$n\\\"\";export $n;fi"
done

CMD="$SCMD -vR -l $LOCAL -c $MAX -u $QDUID -g $QDGID $ACMD $IP $PORT"
CMD="$CMD $RBLCMD $GREYLIST $RECORDIO $SMTPD $ARGS"

echo "command-line: exec $CMD 2>&1"
exec $CMD 2>&1

########################################
# this will only be reached if the exec fails

echo ERROR: command did not run correctly
exit 1
