#!/bin/bash

. ${TOOLKIT}-functions.sh

# CONTENT FILTER
use_content_filter=$(getconfirm srv-mail.use_content_filter && echo true || echo false)


# assemble master.cf file
#
master_cf=master.cf.tmp

:> $master_cf	|| exit 1

parts="base dovecot"
$use_content_filter && parts="$parts content-filter"
parts="$parts local"

for part in $parts
do
	file=$(filepath "master.cf-$part") && {
		echo "  (master.cf) adding $file"
		echo >>$master_cf
		echo "#[ku] file: $file" >>$master_cf
		echo >>$master_cf
		cat "$file" >>$master_cf
		echo >>$master_cf
		echo "#[ku] end-file: $file" >>$master_cf
	}
done


# assemble main.cf file
#
# 2020.06.11 lc
# - at some point postfix introduced smtpd_relay_restrictions parm, that
#   changes to check stages sequence, so we must use the proper template
#
if postconf -d smtpd_relay_restrictions 2>&1 | grep -q "unknown param"
then
	part1=$(filepath main.cf-part1) || exit $?
else
	part1=$(filepath main.cf-part1-with-relay) || exit $?
fi
part2=$(filepath main.cf-part2) || exit $?
main_cf=main.cf.tmp

cp "$part1" $main_cf	|| exit $?

# RBL list
#
for rbl in $(jtconf postfix.rbl_url_list 2>/dev/null || :)
do
	echo "  ($main_cf) adding RBL $rbl"
	echo "	reject_rbl_client $rbl," >>$main_cf
done

cat "$part2" >>$main_cf




# CONTENT FILTER

$use_content_filter || exit 0


echo "  ($main_cf) activating content filter"
file=$(filepath main.cf_content_filters) || exit $?
cat "$file" >> $main_cf



# spamassassin, local rules
#
file="sa-auto-rules"
out="$file.tmp"
cp $file $out

echo "
# WHITELIST rules
" >>$out

for entry in $(jtconf --list nospam.)
do
	header=$(jtconf $entry.header 2>/dev/nulll)	|| continue	# this entry can be a no-op default

	fields=$(jtconf $entry.fields)	|| exit_missing_define $entry.fields

	header_and=$(jtconf $entry.header_and 2>/dev/null) || :
	header_or=$(jtconf $entry.header_or 2>/dev/null) || :
	name="KU_$(echo $entry | sed -e 's/^nospam\./WL_/' -e 's/\./_/g' | tr '[a-z]' '[A-Z]')"
	tagnum=0
	buf=""

	[ "x$header_and" != "x" -a "x$header_or" != "x" ] && {
		echo " error on rule $entry:"
		echo "    you can use both 'header_and' and 'header_or' in the same rule"
		exit 1
	}

	echo "  spam whitelist rule: $entry"

	for field in $fields
	do
		tag="${name}_$tagnum"
		tagnum=$(expr $tagnum + 1)
		buf="header		__${tag}_A	$field $header"

		[ "x$header_and" != "x" ] && {
			buf="$buf\nheader		__${tag}_B	$field $header_and"
			buf="$buf\nmeta		D_${tag}	__${tag}_A && __${tag}_B"
		}
		[ "x$header_or" != "x" ] && {
			buf="$buf\nheader		__${tag}_B	$field $header_or"
			buf="$buf\nmeta		D_${tag}	__${tag}_A || __${tag}_B"
		}
		[ "x$header_and" == "x" -a "x$header_or" == "x" ] && {
			buf="$buf\nmeta		D_${tag}	__${tag}_A"
		}

		buf="$buf\nscore		D_${tag}	-5.0"
		buf="$buf\ndescribe	D_${tag}	kusa rule $entry"
		buf="$buf\n"

		echo -e "$buf" >>$out
	done
done

echo "
# BLACKLIST rules
" >>$out

for entry in $(jtconf --list spam.)
do
	header=$(jtconf $entry.header 2>/dev/null)	|| continue	# this entry can be a no-op default

	score=$(jtconf $entry.score)	|| exit_missing_define $entry.score
	fields=$(jtconf $entry.fields)	|| exit_missing_define $entry.fields

	header_and=$(jtconf $entry.header_and 2>/dev/null) || :
	header_or=$(jtconf $entry.header_or 2>/dev/null) || :
	name="KU_$(echo $entry | sed -e 's/^spam\./BL_/' -e 's/\./_/g' | tr '[a-z]' '[A-Z]')"
	tagnum=0
	buf="\n"

	[ "x$header_and" != "x" -a "x$header_or" != "x" ] && {
		echo " error on rule $entry:"
		echo "    you can use both 'header_and' and 'header_or' in the same rule"
		exit 1
	}

	echo "  spam blacklist rule: $entry"

	for field in $fields
	do
		tag="${name}_$tagnum"
		tagnum=$(expr $tagnum + 1)

		buf="header		__${tag}_A	$field $header"

		[ "x$header_and" != "x" ] && {
			buf="$buf\nheader		__${tag}_B	$field $header_and"
			buf="$buf\nmeta		D_${tag}	__${tag}_A && __${tag}_B"
		}
		[ "x$header_or" != "x" ] && {
			buf="$buf\nheader		__${tag}_B	$field $header_or"
			buf="$buf\nmeta		D_${tag}	__${tag}_A || __${tag}_B"
		}
		[ "x$header_and" == "x" -a "x$header_or" == "x" ] && {
			buf="$buf\nmeta		D_${tag}	__${tag}_A"
		}

		buf="$buf\nscore		D_${tag}	$score"
		buf="$buf\ndescribe	D_${tag}	kusa rule $entry"
		buf="$buf\n"

		echo -e "$buf" >>$out
	done
done


# 2019.04.11
#
# global whitelists/blacklists
#
for list in whitelist_from whitelist_from_rcvd blacklist_from blacklist_from_rvcd
do
	echo -e "\n# GLOBAL $list\n" >>$out
	for entry in $(jtconf spamassassin.$list 2>/dev/null || :)
	do
		echo " adding $list $entry"
		echo "$list $entry" >>$out
	done
done

echo -e "\n# End-of-file" >>$out


# cope with postinst amavis, complaining if amavis user exists with no homedir
#
getent passwd amavis >/dev/null && {
	create_dir /var/lib/amavis amavis:amavis 700		|| exit $?
}


# dovecot ssl, needs chain certificate or not?
#
# (using temp local db to pass extra definitions to install/parse process)
#
ca_file=$(jtconf dovecot.ssl_ca_file 2>/dev/null) || :
[ "X$ca_file" != "X" ] && {
    (
	echo "[dovecot]"
	echo "  tmp_ssl_ca_define	ssl_ca = <$ca_file"
	echo
    ) >>$MODLOCALDB
}

# DKIM

getconfirm srv-mail.use_dkim && {

	# if we are using unix sockets we need to accomodate for differences
	# from opendkim and postfix
	#
	socket=$(jtconf dkim.socket)

	# opendkim uses 'local:' for unix sockets
	#
	opendkim_socket=$(echo "$socket" | sed -e 's/unix:/local:/')

	# postfix uses 'unix:' for unix sockets, that's ok, just make sure to convert
	# if opendkim notation is used; also if the unix socket is under the postfix
	# spool dir, this means that postfix is running chrooted, so we must remove
	# the spool dir from the path
	#
	postfix_socket=$(echo "$socket" | sed -e 's/local:/unix:/' -e 's#/var/spool/postfix##')

	# (using temp local db to pass extra definitions to install/parse process)
	#
	echo "[dkim]" >>$MODLOCALDB
	echo "  tmp_postfix_socket	$postfix_socket" >>$MODLOCALDB
	echo "  tmp_opendkim_socket	$opendkim_socket" >>$MODLOCALDB


	echo "  ($main_cf) activating DKIM"
	file=$(filepath main.cf_dkim) || exit $?
	echo >>$main_cf
	cat "$file" >> $main_cf
}

exit 0
