File: //usr/share/sendmail/update_tls
#!/bin/sh -e
#-----------------------------------------------------------------------------
#
# $Sendmail: update_tls,v 8.15.2 2021-03-16 16:04:16 cowboy Exp $
#
# Sendmail support for TLS
#
# Copyright (c) 2000-2010 Richard Nelson. All Rights Reserved.
#
# Notes:
#
#-----------------------------------------------------------------------------
set -e;
#------------------------------------------------------------------------------
# Local variables
#---------------------------------------------------------------------------
HOSTNAME=`hostname -s`;
DOMAINNAME=`hostname -d`;
MAILNAME=`cat /etc/mailname 2> /dev/null || hostname -f`;
SSL_FQDN=`hostname -f`;
SSL_EMAIL="admin@${MAILNAME}";
export SSL_FQDN SSL_EMAIL;
PROGRAM='sendmail';
CERT_DIR="/etc/ssl/certs";
COM_PRM="/etc/mail/tls/$PROGRAM-common.prm";
COM_KEY="/etc/mail/tls/$PROGRAM-common.key";
MTA_CFG="/etc/mail/tls/$PROGRAM-server.cfg";
MTA_CSR="/etc/mail/tls/$PROGRAM-server.csr";
MTA_CRT="/etc/mail/tls/$PROGRAM-server.crt";
MSP_CFG="/etc/mail/tls/$PROGRAM-client.cfg";
MSP_CSR="/etc/mail/tls/$PROGRAM-client.csr";
MSP_CRT="/etc/mail/tls/$PROGRAM-client.crt";
NEW=0;
REFD=0;
# Path to other sendmail helpers
if [ -x ./update_sendmail ]; then
sm_path='.';
elif [ -x $(dirname $0)/update_sendmail ]; then
sm_path=$(dirname $0);
else
sm_path=/usr/share/sendmail;
fi;
# Bring in sendmail.conf for the network definitions
if [ ! -f /etc/mail/sendmail.conf ]; then
if [ -x $sm_path/update_conf ]; then
$sm_path/update_conf;
fi;
fi;
if [ -f /etc/mail/sendmail.conf ]; then
. /etc/mail/sendmail.conf;
fi;
if [ "$HANDS_OFF" != 'No' ]; then
exit 0;
fi;
#---------------------------------------------------------------------------
# create_config: Function to create openssl configuration file
#---------------------------------------------------------------------------
create_config () {
cat >$MTA_CFG <<EOT
[ ca ]
default_days = 3650
x509_extensions = X509v3
[ req ]
default_bits = 2048
distinguished_name = req_DN
[ req_DN ]
countryName = "1. Country Name (2 letter code)"
countryName_min = 2
countryName_max = 2
countryName_default =
stateOrProvinceName = "2. State or Province Name (full name) "
stateOrProvinceName_default =
localityName = "3. Locality Name (eg, city) "
localityName_default =
0.organizationName = "4. Organization Name (eg, company) "
0.organizationName_default = Sendmail
organizationalUnitName = "5. Organizational Unit Name (eg, section) "
organizationalUnitName_default = Sendmail Server
commonName = "6. Common Name (MUST==FQDN) "
commonName_max = 64
commonName_default = \$ENV::SSL_FQDN
emailAddress = "7. Email Address (eg, name@FQDN)"
emailAddress_max = 40
emailAddress_default = \$ENV::SSL_EMAIL
[ x509v3 ]
subjectAltName = email:copy
issuerAltName = issuer:copy
basicConstraints = CA:false
nsComment = "Sendmail generated custom certificate"
nsCertType = server
nsSslServerName = \$ENV::SSL_FQDN
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer:always
EOT
};
#---------------------------------------------------------------------------
# Check if OpenSSL is installed
if [ ! -d "$CERT_DIR" ]; then
cat <<-EOT
OpenSSL is not installed, will not configure sendmail support for it.
to install openssl, get openssl.
To enable sendmail TLS support at a later date, invoke "$0"
EOT
exit 0;
fi;
echo ' ';
echo 'Creating/Updating SSL(for TLS) information';
#---------------------------------------------------------------------------
# Process arguments
#---------------------------------------------------------------------------
case "$1" in
[Nn][Ee][Ww]* | \
[Rr][Ee][Nn][Ee][Ww]* | \
[Rr][Ee][Ss][Ii][Gg][Nn]*)
echo 'Removing any pre-existing sendmail certificates.';
if [ -x /usr/bin/openssl ]; then
if [ -f $MTA_CRT ]; then
LINK="$CERT_DIR/"$(openssl x509 -noout -hash < $MTA_CRT)".0";
rm -f $LINK 2>/dev/null;
fi;
if [ -f $MSP_CRT ]; then
LINK="$CERT_DIR/"$(openssl x509 -noout -hash < $MSP_CRT)".0";
rm -f $LINK 2>/dev/null;
fi;
fi;
rm -f $MTA_CSR $MTA_CRT 2>/dev/null;
rm -f $MSP_CSR $MSP_CRT 2>/dev/null;
rm -f $COM_PRM $COM_KEY 2>/dev/null;
;;
esac
#---------------------------------------------------------------------------
# Make sure sendmail.mc points to proper /etc/mail/tls/starttls.m4
if [ -f /etc/mail/sendmail.mc ]; then
if (grep -qEe "^[[:space:]]*include\(\`?/etc/mail/starttls.m4" \
/etc/mail/sendmail.mc); then
sed -e "s=^\([[:space:]]*\)\(\`\?\)include(\`\?/etc/mail/starttls.m4'\?)\(dnl\)\?=\1\2include(\`/etc/mail/tls/starttls.m4')dnl=g" \
/etc/mail/sendmail.mc > /etc/mail/sendmail.mc.new;
chown root:smmsp /etc/mail/sendmail.mc.new;
chmod 0644 /etc/mail/sendmail.mc.new;
mv /etc/mail/sendmail.mc.new /etc/mail/sendmail.mc;
fi;
fi;
if [ -f /etc/mail/submit.mc ]; then
if (grep -qEe "^[[:space:]]*include\(\`?/etc/mail/starttls.m4" \
/etc/mail/submit.mc); then
sed -e "s=^\([[:space:]]*\)\(\`\?\)include(\`\?/etc/mail/starttls.m4'\?)\(dnl\)\?=\1\2include(\`/etc/mail/tls/starttls.m4')dnl=g" \
/etc/mail/submit.mc > /etc/mail/submit.mc.new;
chown root:smmsp /etc/mail/submit.mc.new;
chmod 0644 /etc/mail/submit.mc.new;
mv /etc/mail/submit.mc.new /etc/mail/submit.mc;
fi;
fi;
#---------------------------------------------------------------------------
# check for references to starttls.m4 in sendmail.mc
if [ -f /etc/mail/sendmail.mc ]; then
if grep -qEe "^[[:space:]]*include\(\`?/etc/mail/tls/starttls.m4" \
/etc/mail/sendmail.mc; then
REFD=1;
fi;
fi;
#---------------------------------------------------------------------------
# Make sure prototype /etc/mail/tls/starttls.m4 exists
mkdir -p /etc/mail/tls 2>/dev/null;
chown smmta:smmsp /etc/mail/tls;
chmod 0755 /etc/mail/tls;
$sm_path/update_tlsm4 || true;
#---------------------------------------------------------------------------
# check for SSL
if [ -d "$CERT_DIR" ]; then
if [ -f $MTA_CRT ] && [ -f $MSP_CRT ]; then
echo 'You already have sendmail certificates';
echo ' ';
chown root:smmsp $COM_PRM;
chown root:smmsp $COM_KEY;
chown root:smmsp $MTA_CRT;
chown root:smmsp $MSP_CRT;
else
if [ -x /usr/bin/openssl ]; then
yn="Y";
else
cat <<-EOT
$PROGRAM needs openssl (not installed) to create a
certificate to validate users
If you don't need a certificate, say No
If you want a certificate, install openssl and say Yes
Do you wish to create a certificate?
EOT
read yn;
yn=$(echo -n "$yn" | sed -e "s/^\ *//" -e "s/^\t*//");
test -n "$yn" || yn="N";
fi;
# Create new (self-signed) certificate
case "$yn" in
[Yy]*)
echo "Creating SSL certificates for sendmail.";
# Create prompt file
if [ ! -f /etc/mail/tls/no_prompt ]; then
cat >/etc/mail/tls/no_prompt <<-EOT
EOT
fi;
# Create config files
if [ ! -f $MTA_CFG ]; then
create_config;
chmod 0600 $MTA_CFG;
fi;
if [ ! -f $MSP_CFG ]; then
sed -e "s/Sendmail Server/Sendmail Client/" \
$MTA_CFG > $MSP_CFG;
chmod 0600 $MSP_CFG;
fi;
# Create shared DSA/DH password parameters
if [ ! -s $COM_PRM ]; then
openssl dsaparam -out $COM_PRM 2048
openssl dhparam -dsaparam -in $COM_PRM >> $COM_PRM;
chown root:smmsp $COM_PRM;
chmod 0640 $COM_PRM;
fi;
# Create shared DSA/RSA key (RSA preferred for browser support)
if [ ! -f $COM_KEY ]; then
openssl genrsa -out $COM_KEY 2048;
#openssl gendsa -out $COM_KEY $COM_PRM;
chown root:smmsp $COM_KEY;
chmod 0640 $COM_KEY;
fi;
# sendmail requires that CN=fqdn
# Prompts: 1) Country Name (2 letter code)
# 2) State or Province Name
# 3) Locality Name (eg, city)
# 4) Organization Name (eg, company)
# 5) Organizational Unit Name (eg, section)
# 6) Common Name (eg, YOUR name)
# 7) Email Address
if [ ! -f $MTA_CRT ]; then
openssl req -new -config $MTA_CFG -key $COM_KEY \
-out $MTA_CSR \
</etc/mail/tls/no_prompt >/dev/null 2>&1;
chmod 0600 $MTA_CSR;
openssl x509 -req -extfile $MTA_CFG \
-signkey $COM_KEY -in $MTA_CSR \
-out $MTA_CRT -days 3650 \
>/dev/null 2>&1;
chown root:smmsp $MTA_CRT;
chmod 0644 $MTA_CRT;
fi;
if [ ! -f $MSP_CRT ]; then
openssl req -new -config $MSP_CFG -key $COM_KEY \
-out $MSP_CSR \
</etc/mail/tls/no_prompt >/dev/null 2>&1;
chmod 0600 $MSP_CSR;
openssl x509 -req -extfile $MSP_CFG \
-signkey $COM_KEY -in $MSP_CSR \
-out $MSP_CRT -days 3650 \
>/dev/null 2>&1;
chown root:smmsp $MSP_CRT;
chmod 0644 $MSP_CRT;
fi;
esac;
fi;
# Create hash link for new certificate (must do msp last!)
if [ -f $MTA_CRT ]; then
LINK="$CERT_DIR/"$(openssl x509 -noout -hash < $MTA_CRT)".0";
if [ ! -f $LINK ]; then
ln -sf $MTA_CRT $LINK;
fi;
fi;
if [ -f $MSP_CRT ]; then
LINK="$CERT_DIR/"$(openssl x509 -noout -hash < $MSP_CRT)".0";
if [ ! -f $LINK ]; then
ln -sf $MSP_CRT $LINK;
fi;
fi;
fi;
if [ $REFD -eq 0 ]; then
cat <<-EOT
*** *** *** WARNING *** WARNING *** WARNING *** WARNING *** *** ***
Everything you need to support STARTTLS (encrypted mail transmission
and user authentication via certificates) is installed and configured
but is *NOT* being used.
To enable sendmail to use STARTTLS, you need to:
1) Add this line to /etc/mail/sendmail.mc and optionally
to /etc/mail/submit.mc:
include(\`/etc/mail/tls/starttls.m4')dnl
2) Run sendmailconfig
3) Restart sendmail
EOT
fi;