#!/usr/pkg/bin/bash
# version 7
PATH=/usr/pkg/bin:/bin:/usr/bin:/usr/local/bin
shopt -q -s extglob
host="$1"
sender="$2"
# First, figure out who the sending domain is:
[[ -z "$sender" && "$DEFAULTDOMAIN" ]] && sender="@$DEFAULTDOMAIN"
[ -z "$sender" ] && sender=@`hostname -f`
DOMAIN="${sender##*@}"
# Convert to lower-case
if [ ${BASH_VERSION%%.*} -ge 4 ] ; then
    DOMAIN=${DOMAIN,,}
else
    DOMAIN=$(tr [A-Z] [a-z] <<<"$DOMAIN")
fi
# Sanity-check the sender
if [[ $DOMAIN == !(+([a-zA-Z0-9\!\#$%*/?|^{}\`~&\'+=_.-])) ]] ; then
	# ' fix vim quote logic
	echo "DSender address contains illegal characters."
	exit 0
fi
# Now, fill in the basic variables (if they don't exist already)
[ "$DKREMOTE" ] || DKREMOTE="/var/qmail/bin/qmail-remote"
[ "$DKSIGN" ]   || DKSIGN="/var/qmail/control/domainkeys/%/default"
# Now try and find the right subdomain, per RFC 4871
# (you can eliminate this loop if you don't want parent domains signing child
# domain's email)
if [ "$DOMAIN" ] ; then
	while [ ! -r "${DKSIGN//\%/$DOMAIN}" ] ; do
		# try parent domains, per RFC 4871, section 3.8
		DOMAIN=${DOMAIN#*.}
		DPARTS=( ${DOMAIN//./ } )
		[ ${#DPARTS[*]} -eq 1 ] && DOMAIN="${sender##*@}" && break
	done
fi
DKSIGN="${DKSIGN//\%/$DOMAIN}"
# Now that we have the correct DKSIGN value (i.e. the filename of the key to
# use to sign email), check to see if this file exists
if [ -r "$DKSIGN" ] ; then
	# The key does exist, so now use it to generate signatures!
	tmp=`mktemp -t dk.sign.XXXXXXXXXXXXXXXXXXX`
	tmp2=`mktemp -t dk2.sign.XXXXXXXXXXXXXXXXXXX`
	cat - >"$tmp"

    # compute the DomainKey signature (obsolete)
	#error=`(dktest -s "$DKSIGN" -c nofws -h <"$tmp" | \
	#	sed 's/; d=.*;/; d='"$DOMAIN"';/' > "$tmp2") 2>&1`
	#if [ "$error" ] ; then
	#	# Communicate the problem to qmail (that's why the 'Z')
	#	echo "ZDomainKey error: $error"
	#	rm "$tmp" "$tmp2"
	#	exit -1
	#fi

	# compute the DKIM signature
	error=`(dkimsign.pl --type=dkim --selector=default --domain="$DOMAIN" \
				--key="$DKSIGN" --method=relaxed <"$tmp" | \
			tr -d '\r' >> "$tmp2") 2>&1`
	if [ "$error" ] ; then
		# Communicate the problem to qmail (that's why the 'Z')
		echo "ZDKIM error: $error"
		rm "$tmp" "$tmp2"
		exit -2
	fi

	# feed the signatures and the original message to the real qmail-remote
	# I'm combining to a third temp file to allow the file to be "rewound",
	# since some folks like that ability
	tmp3=`mktemp -t dk3.sign.XXXXXXXXXXXXXXXXXXX`
	cat "$tmp2" "$tmp" > "$tmp3"
	rm "$tmp" "$tmp2"
	"$DKREMOTE" "$@" < "$tmp3"
	retval=$?
	rm "$tmp3"
	exit $retval
else
	# No signature added
	exec "$DKREMOTE" "$@"
fi
