Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 19 Dec 2001 23:43:04 -0500
From:      "Louis A. Mamakos" <louie@TransSys.COM>
To:        "Roger 'Rocky' Vetterberg" <listsub@rambo.simx.org>
Cc:        Leo Bicknell <bicknell@ufp.org>, freebsd-hackers@FreeBSD.ORG
Subject:   Re: sendmail + auth + ssl + freebsd 
Message-ID:  <200112200443.fBK4h4791394@whizzo.transsys.com>
In-Reply-To: Your message of "Thu, 20 Dec 2001 03:43:12 %2B0100." <3C215040.9080404@rambo.simx.org> 
References:  <20011220022654.GA78232@ussenterprise.ufp.org> <3C215040.9080404@rambo.simx.org> 

next in thread | previous in thread | raw e-mail | index | archive | help
This is a multipart MIME message.

--==_Exmh_14687768880
Content-Type: text/plain; charset=us-ascii

> Leo Bicknell wrote:
> 
> >After searching the archives and looking at the source, I find
> >myself more confused.  I've been asked to set up sendmail + ssl +
> >SMTP auth on a FreeBSD host.
> >
> >A quick "strings" on the sendmail binary shows a number of SSL
> >functions, so I'm thinking the SSL bits are in there, but I'm not
> >quite sure how to take advantage of them.  Issuing "AUTH" to a
> >stock -STABLE sendmail gets command unrecognized though, so I don't
> >think that is there.
> >
> >If no one else has figured this mess out, I'll do it and write a
> >page for the handbook. If someone else has, please clue me in, and
> >if necessary I'll still write that handbook page. :-)  It would be
> >very nice if it was simple to make FreeBSD sendmail SSL and 
> >authenticate against the password file.
> >
> I've managed to set it up to use AUTH, however I have not yet found the 
> time to make it use SSL.
> The only usefull documentation I have been able to find is this one: 
> http://www.sendmail.org/~ca/email/auth.html

You have to generate a public key certificate and have the private 
key available to the sendmail daemon before it will do the STARTTLS
thing.

I've got a shell script around there that signs a certificate with a
bogus CA which enable the use of STARTTLS.  You can't validate the
other end of the connection, but at least it negotiates an encrypted
session.

It's attached below, and it's a horrible blecherous hack and
provides very little security other than allowing the session to
be encrypted.  It's at least obviously not able to protect against
man-in-the-middle attacks since the CA signing the cert is completely
bogus.  It will make long distance phone calls when you're not
looking, eat your food, and make rude remarks about your spouse. 
Use at your own risk.

But it seems to do, er, something.  At least it makes passive traffic
sniffing less productive.

louie




--==_Exmh_14687768880
Content-Type: application/x-sh ; name="make-sendmail-cert.sh"
Content-Description: make-sendmail-cert.sh
Content-Disposition: attachment; filename="make-sendmail-cert.sh"

#!/bin/sh

###
###  cobbled together from scripts from Yeak Nai Siew, but hacked
###  horribly into this twisted, inappropriate mess.  
###

##
##  new-root-ca.sh - create the root CA
##  Copyright (c) 2000 Yeak Nai Siew, All Rights Reserved. 
##

trap 'rm -rf tmp*' 0 2 3 5

if [ "`openssl md5 < /dev/null`" != "d41d8cd98f00b204e9800998ecf8427e" ]; then
    echo "Can't find working openssl binary"
    exit 1
fi

if  echo help | /usr/sbin/sendmail -bs | grep STARTTLS >/dev/null ; then \
    echo sendmail is compiled with STARTTLS
else
    echo sendmail doesn\'t support STARTTLS
    exit 1
fi


RANDOM=/dev/random
ROOTCA=tmp-rootca
HOSTNAME=`hostname`

MAILDIR=${HOSTNAME}-etc-mail
MAILSSLDIR=${MAILDIR}/certs

rm -rf ${MAILDIR}
mkdir  ${MAILDIR} ${MAILSSLDIR}

# Create the master CA key. This should be done once.
if [ ! -f ${ROOTCA}.key ]; then
	echo "No Root CA key round. Generating one"
	openssl genrsa -out ${ROOTCA}.key -rand ${RANDOM} 1024
	echo ""
fi

echo  --------------------------------------------------------------------------

if [ ! -f ${ROOTCA}.crt ]; then
    # Self-sign it.
    CONFIG="tmp-root-${ROOTCA}.conf"

    cat >${CONFIG} << EOT
[ req ]
prompt                          = no
default_bits			= 1024
default_keyfile			= ${ROOTCA}.key
distinguished_name		= req_distinguished_name
x509_extensions			= v3_ca
string_mask			= nombstr
req_extensions			= v3_req
[ req_distinguished_name ]
countryName			= ZZ
stateOrProvinceName		= Atlantis
localityName			= The Village
0.organizationName		= Unsuitable for security at any keysize
organizationalUnitName		= Bogon Anonymous Certificate Authority
commonName			= ${HOSTNAME}
emailAddress			= postmaster@${HOSTNAME}

[ v3_ca ]
basicConstraints		= critical,CA:true
subjectKeyIdentifier		= hash
[ v3_req ]
nsCertType			= objsign,email,server
EOT

    echo "Self-sign the root CA..."
    openssl req -new -x509 -nodes -days 3650 -config ${CONFIG} \
	-rand ${RANDOM} -key ${ROOTCA}.key -out ${ROOTCA}.crt 
    
    rm -f ${CONFIG}
else
    echo "ROOT CA certificate/key already exists"
fi

install -c -m 444 ${ROOTCA}.crt ${MAILSSLDIR}/cacert.pem
install -c -m 400 ${ROOTCA}.key ${MAILSSLDIR}/cakey.pem

echo  --------------------------------------------------------------------------

##
##  new-server-cert.sh - create the server cert
##  Copyright (c) 2000 Yeak Nai Siew, All Rights Reserved. 
##

# Create the key. This should be done once per cert.
CERT=smtp-${HOSTNAME}

if [ ! -f ${CERT}.key ]; then
	echo "No ${CERT}.key found. Generating one"
	openssl genrsa -out ${CERT}.key 1024 -rand ${RANDOM}
	echo ""
fi

# Fill the necessary certificate data
CONFIG="tmp-server-cert.conf"
cat >${CONFIG} << EOT
[ req ]
prompt				= no
default_bits			= 1024
distinguished_name		= req_distinguished_name
string_mask			= nombstr
req_extensions			= v3_req
[ req_distinguished_name ]
countryName			= ZZ
stateOrProvinceName		= Confusion
localityName			= The Village
0.organizationName		= Number 6
organizationalUnitName		= Number 6\'s SMTP server
commonName			= ${HOSTNAME}
emailAddress			= postmaster@${HOSTNAME}

[ v3_req ]
nsCertType			= server
basicConstraints		= critical,CA:false
EOT

openssl req -new -config ${CONFIG} -rand ${RANDOM} \
	    -key ${CERT}.key   -out ${CERT}.csr

rm -f ${CONFIG}

echo  --------------------------------------------------------------------------

if [ ! -f ${CERT}.csr ]; then
        echo "No ${CERT}.csr found. You must create that first."
	exit 1
fi

#   make sure environment exists
if [ ! -d tmp-ca.db.certs ]; then
    mkdir tmp-ca.db.certs
fi
if [ ! -f tmp-ca.db.serial ]; then
    echo '01' >tmp-ca.db.serial
fi
if [ ! -f tmp-ca.db.index ]; then
    cp /dev/null tmp-ca.db.index
fi


# Check for root CA key
if [ ! -f ${ROOTCA}.key -o ! -f ${ROOTCA}.crt ]; then
	echo "You must have root CA key generated first."
	exit 1
fi

# Sign it with our CA key #

#  create the CA requirement to sign the cert

CONFIG='tmp-ca.config'

cat > ${CONFIG}  << EOT
[ ca ]
default_ca              = default_CA
[ default_CA ]
prompt                  = no
dir                     = .
certs                   = \$dir/
new_certs_dir           = \$dir/tmp-ca.db.certs
database                = \$dir/tmp-ca.db.index
serial                  = \$dir/tmp-ca.db.serial
RANDFILE                = ${RANDOM}
certificate             = \$dir/${ROOTCA}.crt
private_key             = \$dir/${ROOTCA}.key
default_days            = 3650
default_crl_days        = 30
default_md              = md5
preserve                = no
x509_extensions		= server_cert
policy                  = policy_anything
[ policy_anything ]
countryName             = optional
stateOrProvinceName     = optional
localityName            = optional
organizationName        = optional
organizationalUnitName  = optional
commonName              = supplied
emailAddress            = optional
[ server_cert ]
#subjectKeyIdentifier	= hash
authorityKeyIdentifier	= keyid:always
extendedKeyUsage	= serverAuth,clientAuth,msSGC,nsSGC
basicConstraints	= critical,CA:false
EOT

#  sign the certificate
echo "CA signing: ${CERT}.csr -> ${CERT}.crt:"
openssl ca -batch -config ${CONFIG} -out ${CERT}.crt -infiles ${CERT}.csr

echo "CA verifying: ${CERT}.crt <-> CA cert"
openssl verify -CAfile ${ROOTCA}.crt ${CERT}.crt

install -c -m 400 ${CERT}.key ${MAILSSLDIR}/key.pem
install -c -m 444 ${CERT}.crt ${MAILSSLDIR}/cert.pem

hash=`openssl x509 -hash -noout -in ${MAILSSLDIR}/cert.pem`
ln -s cert.pem ${MAILSSLDIR}/$hash.0

#  cleanup after SSLeay 
rm -f ${CONFIG}
rm -f ${CERT}.csr tmp-ca.db.serial.old tmp-ca.db.index.old

if [ -f /etc/mail/freebsd.mc ]; then
    echo "Generating modified freebsd.mc file"
    cat > tmp.sed <<'EOF'
/^DOMAIN(/a\
\
dnl ---------------------------------------------\
dnl Stuff to TLS\
define(`CERT_DIR', `MAIL_SETTINGS_DIR`'certs')dnl\
define(`confCACERT_PATH', `CERT_DIR')dnl\
define(`confCACERT', `CERT_DIR/cacert.pem')dnl\
define(`confSERVER_CERT', `CERT_DIR/cert.pem')dnl\
define(`confSERVER_KEY', `CERT_DIR/key.pem')dnl\
define(`confCLIENT_CERT', `CERT_DIR/cert.pem')dnl\
define(`confCLIENT_KEY', `CERT_DIR/key.pem')dnl\
dnl ---------------------------------------------
EOF

    sed -f tmp.sed < /etc/mail/freebsd.mc > ${MAILDIR}/tls.mc
    rm tmp.sed
    echo "Generating modified freebsd.cf sendmail configuration file"
    (cd ${MAILDIR}; make -f /etc/mail/Makefile tls.cf)

    echo  --------------------------------------------------------------------------
fi

cat <<EOF
            DANGER!  WARNING!  BOGUS CRYPTO AHEAD!

This script has created a dummy root certificate authority, which has
signed a dummy key to create a dummy certificate suitable for use
by the ${HOSTNAME} machine.  It will allow that machine to 
negotiatean SSL/TLS session with other consenting and capable SMTP
servers by using the STARTTLS command.

Since this certificate was generated with no real trust, authority or
identity, it's not suitable for use to authenticate one host to
another, or to authorize SMTP relay.  It's sole purpose is to enable
the transport of mail over an encrypted SSL/TLS session.  It provides
no protection against man-in-the-middle attacks, either.

You should create a directory, /etc/mail/certs and copy the contents
of ${MAILSSLDIR} into that directory.  For more information, see
http://www.sendmail.org/~ca/email/starttls.html
 
EOF

ls -l ${MAILSSLDIR}/*

if [ -f "${MAILDIR}/tls.cf" ]; then
    cat <<EOF

There is a modified version of the freebsd.mc sendmail configuration
file (usually found as /etc/mail/freebsd.mc), as well as a sendmail
configuration file (usually found as /etc/mail/freebsd.cf and
/etc/mail/sendmail.cf) in ${MAILDIR}.  
You should either make the same changes or replace your sendmail
configuration file with the one in ${MAILDIR}/tls.cf

EOF
fi

rm -f ${CERT}.key ${CERT}.crt ${ROOTCA}.crt ${ROOTCA}.key


--==_Exmh_14687768880--


To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-hackers" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200112200443.fBK4h4791394>