#!/bin/sh
# $Id: t-tls-rel-1.sh,v 1.19 2007/01/11 02:00:27 ca Exp $
# Copyright (c) 2004-2006 Sendmail, Inc. and its suppliers.
#	All rights reserved.
#
# By using this file, you agree to the terms and conditions set
# forth in the LICENSE file which can be found at the top level of
# the sendmail distribution.
#
# ----------------------------------------
# test relaying via TLS; check cert issuer/subject via access map
# creates two MTS (one in chkmts, one in qmgr) to use STARTTLS
# run smtpcnf.sh with different parameters
# ----------------------------------------
#
test -s stop && exit 1
#

SD=`dirname $0`
THISDIR=`pwd`
if test "${SD}" = "."
then
   SD=../chkmts
fi
. ${SD}/common.sh

I=""
ERRS=0
OUT="t-tls-rel-0.out"
PID2=pids2
SKIP=""

if test X"`uname`" != "XOSF1"
then
while getopts s:V FLAG
do
  case "${FLAG}" in
    s) SKIP="${SKIP} ${OPTARG}";;
    V) VERBOSE=true;;
  esac
done
shift `expr ${OPTIND} - 1`
# linux: killall kills qmgr/smar from first MTS, hence subsequent tests fail
if test X"`uname`" = "XLinux" -a X"${SKIP}" = "X"
then
    SKIP=" 2 3 4 "
fi
fi

if ../smtps/smtps -VVV | ${GREP} MTA_USE_TLS >/dev/null
then
  :
else
  echo "SKIPPED: $0: smtps not compiled with STARTTLS"
  exit 0
fi
if ../smtpc/smtpc -VVV | ${GREP} MTA_USE_TLS >/dev/null
then
  :
else
  echo "SKIPPED: $0: smtpc not compiled with STARTTLS"
  exit 0
fi

killit()
{
cd ${THISDIR}
if test -s ${PID2}
then
  # stop MTA components
  for i in `${CAT} ${PID2}`
  do
    kill ${i}
  done
fi
# ----------------
# thanks kids for not following the POSIX standard...
if test X"`uname`" = "XLinux"
then
  killall qmgr smar
fi
exit ${ERRS}
}

# cd to working directory for alias file!
cd ../qmgr || exit 1

# create aliases
${CAT} > ${ALI} <<EOF
abuse:	local:
postmaster:	local:
user:	local:
EOF
# create map
rm -f ${ALIMAP}
${MM} < ${ALI}

# create mailertable (save old version?)
${CAT} > ${MT} <<EOF
local.dom	lmtp:
other.dom	[127.1.2.3]
host.local	[127.0.0.1]
EOF

# get certs
for i in smcert.pem smkey.pem CAcert.pem
do
  cp ${SD}/${i} .
done

# ----------------------------------------
# need two SMTP servers:
# server1: chkmts, uses smx2.conf, started here "by hand"
# server2: qmgr, uses smx.conf, started by smtpcnf.sh
#
# test client [smtpcnf.sh] -> SMTP server 1 (SRVPORT)
# -> QMGR 1 -> SMTP client 1 (SNKPORT)
# -> SMTP server 2 [smtpcnf.sh] (SRVPORT2=SNKPORT)
# -> QMGR 2 [smtpcnf.sh] -> SMTP client 2 [smtpcnf.sh]
# -> lmtp sink [smtpcnf.sh]
# problem: test client in smtpcnf.sh will use SNKPORT (=SRVPORT2)
# hence the port must be passed explicitly via -F ${SRVPORT}
#
# relaying restrictions are imposed in smx.conf

cd ${THISDIR} || exit 1
# get certs
for i in smcert.pem smkey.pem CAcert.pem
do
  cp ${SD}/${i} .
done
# create mailertable (save old version?)
${CAT} > ${MT} <<EOF
local.dom	[127.0.0.1]
other.dom	[${MTA_LMTPIPV4D}]
EOF
# create aliases
${CAT} > ${ALI} <<EOF
abuse:	local:
postmaster:	local:
sender1:	local:
sender2:	local:
sender3:	local:
sender4:	local:
EOF
# create map
rm -f ${ALIMAP}
${MM} < ${ALI}


MTA_CDQMGRDIR=false
export MTA_CDQMGRDIR
. ${SD}/mta-setup.sh
MTA_CDQMGRDIR=true

SNKPORT=8753
SRVPORT=1579
MTA_SNKPORT=8752
MTA_SRVPORT=${SNKPORT}
SNKPORT2=${MTA_SNKPORT}
SRVPORT2=${MTA_SRVPORT}

# ----------------------------------------
# start first MTS (chkmts)
#
CONF2=smx2.conf
${CAT} > ${CONF2} <<EOF
qmgr { Log_Level = 12; wait_for_server=4; wait_for_client=4;
}
smar { Log_Level = 12;
}
smtpc { Log_Level = 12; remote_port=${SNKPORT}; wait_for_server=4;
  flags = talk_to_myself; # don't check "talking to myself"
}
smtps {
Log_Level = 12;
daemon_address = localhost:${SRVPORT};
wait_for_server=4;
}
EOF

# version of output files
V=1
# path to programs
P=..
rm -f ${PID2}
trap killit EXIT 2 15
# go for it
${P}/smar/smar -f ${CONF2} > a${V}.log 2>&1 &
echo $! >> ${PID2}
${P}/qmgr/qmgr -f ${CONF2} > q${V}.log 2>&1 &
echo $! >> ${PID2}
${P}/smtpc/smtpc -f ${CONF2} > c${V}.log 2>&1 &
echo $! >> ${PID2}
${P}/smtps/smtps -f ${CONF2} > s${V}.log 2>&1 &
echo $! >> ${PID2}

# check that the MTA is running
export P
${CHKD}/mta-running.sh ${SRVPORT} || killit

export MTA_SNKPORT MTA_SRVPORT

cd ../qmgr
${CAT} > ${SMXCNF} <<EOF
qmgr { Log_Level = 12; wait_for_server=4; wait_for_client=4; }
smar { Log_Level = 12; nameserver = ${NS}; }
smtpc { Log_Level = 12; remote_port=${SNKPORT}; wait_for_server=4; }
smtps {
Log_Level = 12;
daemon_address = localhost:${SRVPORT2};
flags = {access, lmtp_does_not_imply_relaying };
tls { flags = { check_access_map_for_relaying} };
relay_from = "No.host.";
relay_to = "No.host.";
wait_for_server=4;
}
EOF

# ----------------------------------------
# test: send mail to sink, relaying not allowed

TEST=1
if echo " ${SKIP} X" | ${GREP} -v " ${TEST} " > /dev/null
then
ERR=false

${CAT} > ${ACC} <<EOF
certissuer:/C=US/ST=California/L=Emeryville/O=Example+20Org/OU=MTA/CN=CA/emailAddress=CA@example.org	CONT
certissuer:/C=US/ST=California/L=Emeryville/O=Example+20Org/OU=MTA/CN=CA/Email=CA@example.org	CONT
EOF
rm -f ${ACCMAP}
${MM} -t'	' -F ${ACCMAP} < ${ACC}

if ${SHELL} ${SD}/smtpcnf.sh -F ${SRVPORT} -3 lmtpsock -Ssender${TEST}@other.dom -Ruser@local.dom -E 0 -X 0 -A 1
then
  if test -s ${B1}
  then
    ERR=true
  fi
else
  ERR=true
fi
if ${ERR}
then
   echo "$0: test ${TEST} failed"
   ERRS=`expr ${ERRS} + 1 `
   test X"${MTA_STOPONERROR}" != X && exit 1
fi
rm -f ${B1}
else
  ${VERBOSE} && echo "$0: test ${TEST} SKIPPED"
fi


# ----------------------------------------
# test: send mail to sink, allow relaying due to access map (certissuer)

TEST=2
if echo " ${SKIP} X" | ${GREP} -v " ${TEST} " > /dev/null
then
ERR=false

${CAT} > ${ACC} <<EOF
certissuer:/C=US/ST=California/L=Emeryville/O=Example+20Org/OU=MTA/CN=CA/emailAddress=CA@example.org	RELAY
certissuer:/C=US/ST=California/L=Emeryville/O=Example+20Org/OU=MTA/CN=CA/Email=CA@example.org	RELAY
EOF
rm -f ${ACCMAP}
${MM} -t'	' -F ${ACCMAP} < ${ACC}

if ${SHELL} ${SD}/smtpcnf.sh -F ${SRVPORT} -3 lmtpsock -Ssender${TEST}@other.dom -Ruser@local.dom -E 0 -X 0 -A 1
then
  if test -s ${B1}
  then
    if ${GREP} 'TLS' ${B1} >/dev/null
    then
      :
    else
      ERR=true
    fi
  else
    ERR=true
  fi
else
  ERR=true
fi
if ${ERR}
then
   echo "$0: test ${TEST} failed"
   ERRS=`expr ${ERRS} + 1 `
   test X"${MTA_STOPONERROR}" != X && exit 1
fi
rm -f ${B1}
else
  ${VERBOSE} && echo "$0: test ${TEST} SKIPPED"
fi

# ----------------------------------------
# test: send mail to sink, allow relaying due to access map (certsubject)

TEST=3
if echo " ${SKIP} X" | ${GREP} -v " ${TEST} " > /dev/null
then
ERR=false

${CAT} > ${ACC} <<EOF
certissuer:/C=US/ST=California/L=Emeryville/O=Example+20Org/OU=MTA/CN=CA/emailAddress=CA@example.org	CONT
certsubject:/C=US/ST=California/L=Emeryville/O=Example+20Org/OU=MTA/CN=host.example.org/emailAddress=cert@example.org	RELAY
certissuer:/C=US/ST=California/L=Emeryville/O=Example+20Org/OU=MTA/CN=CA/Email=CA@example.org	CONT
certsubject:/C=US/ST=California/L=Emeryville/O=Example+20Org/OU=MTA/CN=host.example.org/Email=cert@example.org	RELAY
EOF
rm -f ${ACCMAP}
${MM} -t'	' -F ${ACCMAP} < ${ACC}

if ${SHELL} ${SD}/smtpcnf.sh -F ${SRVPORT} -3 lmtpsock -Ssender${TEST}@other.dom -Ruser@local.dom -E 0 -X 0 -A 1
then
  if test -s ${B1}
  then
    if ${GREP} 'TLS' ${B1} >/dev/null
    then
      :
    else
      ERR=true
    fi
  else
    ERR=true
  fi
else
  ERR=true
fi
if ${ERR}
then
   echo "$0: test ${TEST} failed"
   ERRS=`expr ${ERRS} + 1 `
   test X"${MTA_STOPONERROR}" != X && exit 1
fi
rm -f ${B1}
else
  ${VERBOSE} && echo "$0: test ${TEST} SKIPPED"
fi


# ----------------------------------------
# test: send mail to sink, relaying not allowed

TEST=4
if echo " ${SKIP} X" | ${GREP} -v " ${TEST} " > /dev/null
then
ERR=false

${CAT} > ${ACC} <<EOF
certissuer:/C=US/ST=California/L=Emeryville/O=Example+20Org/OU=MTA/CN=CA/emailAddress=CA@example.org	CONT
certsubject:/C=US/ST=California/L=Emeryville/O=Example+20Org/OU=MTA/CN=host.example.org/emailAddress=cert@example.org	CONT
certissuer:/C=US/ST=California/L=Emeryville/O=Example+20Org/OU=MTA/CN=CA/Email=CA@example.org	CONT
certsubject:/C=US/ST=California/L=Emeryville/O=Example+20Org/OU=MTA/CN=host.example.org/Email=cert@example.org	CONT
EOF
rm -f ${ACCMAP}
${MM} -t'	' -F ${ACCMAP} < ${ACC}

if ${SHELL} ${SD}/smtpcnf.sh -F ${SRVPORT} -3 lmtpsock -Ssender${TEST}@other.dom -Ruser@local.dom -E 0 -X 0 -A 1
then
  if test -s ${B1}
  then
    ERR=true
  fi
else
  ERR=true
fi
if ${ERR}
then
   echo "$0: test ${TEST} failed"
   ERRS=`expr ${ERRS} + 1 `
   test X"${MTA_STOPONERROR}" != X && exit 1
fi
rm -f ${B1}
else
  ${VERBOSE} && echo "$0: test ${TEST} SKIPPED"
fi



# ----------------------------------------
cd ${THISDIR}
rm -f ${MTMAP} ${ALIMAP} ${ACCMAP}
cd ../qmgr
rm -f ${MTMAP} ${ALIMAP} ${ACCMAP}

# ----------------------------------------
# end
if test "${ERRS}" = "0"
then
  exit 0
else
  echo "${ERRS} error(s)"
  exit 1
fi


syntax highlighted by Code2HTML, v. 0.9.1