Author: jmg
Date: Sat Oct 19 18:51:06 2013
New Revision: 256773
URL: http://svnweb.freebsd.org/changeset/base/256773

Log:
  Enable the automatic creation of a certificate (if one does not exists)
  and enable the usage by sendmail if sendmail is enabled.  Include and
  document knobs to disable this feature and also set the Common Name of
  the certificate created.
  
  As the certificate is signed w/ a discarded key, it only helps prevent
  Eve, but not Malory from knowing the contents of the emails.
  
  This means that new installs (and people that use the updated freebsd.mc
  file) will automaticly have STARTTLS enabled allowing incoming email to
  be encrypted in most cases.
  
  Reviewed by:  gshapiro
  MFC after:    3 days
  Security:     Yes, please.

Modified:
  head/etc/defaults/rc.conf
  head/etc/rc.d/sendmail
  head/etc/sendmail/freebsd.mc
  head/share/man/man8/rc.sendmail.8

Modified: head/etc/defaults/rc.conf
==============================================================================
--- head/etc/defaults/rc.conf   Sat Oct 19 18:13:32 2013        (r256772)
+++ head/etc/defaults/rc.conf   Sat Oct 19 18:51:06 2013        (r256773)
@@ -573,6 +573,8 @@ sendmail_enable="NO"        # Run the sendmail 
 sendmail_pidfile="/var/run/sendmail.pid"       # sendmail pid file
 sendmail_procname="/usr/sbin/sendmail"         # sendmail process name
 sendmail_flags="-L sm-mta -bd -q30m" # Flags to sendmail (as a server)
+sendmail_cert_create="YES"     # Create a server certificate if none (YES/NO)
+#sendmail_cert_cn="CN"         # CN of the generate certificate
 sendmail_submit_enable="YES"   # Start a localhost-only MTA for mail submission
 sendmail_submit_flags="-L sm-mta -bd -q30m -ODaemonPortOptions=Addr=localhost"
                                # Flags for localhost-only MTA

Modified: head/etc/rc.d/sendmail
==============================================================================
--- head/etc/rc.d/sendmail      Sat Oct 19 18:13:32 2013        (r256772)
+++ head/etc/rc.d/sendmail      Sat Oct 19 18:51:06 2013        (r256773)
@@ -24,6 +24,8 @@ command=${sendmail_program:-/usr/sbin/${
 pidfile=${sendmail_pidfile:-/var/run/${name}.pid}
 procname=${sendmail_procname:-/usr/sbin/${name}}
 
+CERTDIR=/etc/mail/certs
+
 case ${sendmail_enable} in
 [Nn][Oo][Nn][Ee])
        sendmail_enable="NO"
@@ -44,6 +46,118 @@ if checkyesno sendmail_submit_enable; th
        sendmail_outbound_enable="NO"
 fi
 
+sendmail_cert_create()
+{
+       cnname="${sendmail_cert_cn:-`hostname`}"
+       cnname="${cnname:-amnesiac}"
+
+       # based upon:
+       # http://www.sendmail.org/~ca/email/other/cagreg.html
+       CAdir=`mktemp -d` &&
+       certpass=`(date; ps ax ; hostname) | md5 -q`
+
+       # make certificate authority
+       ( cd "$CAdir" &&
+       chmod 700 "$CAdir" &&
+       mkdir certs crl newcerts &&
+       echo "01" > serial &&
+       :> index.txt &&
+
+       cat <<-OPENSSL_CNF > openssl.cnf &&
+               RANDFILE        = $CAdir/.rnd
+               [ ca ]
+               default_ca      = CA_default
+               [ CA_default ]
+               dir             = .
+               certs           = \$dir/certs           # Where the issued 
certs are kept
+               crl_dir         = \$dir/crl             # Where the issued crl 
are kept
+               database        = \$dir/index.txt       # database index file.
+               new_certs_dir   = \$dir/newcerts        # default place for new 
certs.
+               certificate     = \$dir/cacert.pem      # The CA certificate
+               serial          = \$dir/serial          # The current serial 
number
+               crlnumber       = \$dir/crlnumber       # the current crl number
+               crl             = \$dir/crl.pem         # The current CRL
+               private_key     = \$dir/cakey.pem
+               x509_extensions = usr_cert              # The extentions to add 
to the cert
+               name_opt        = ca_default            # Subject Name options
+               cert_opt        = ca_default            # Certificate field 
options
+               default_days    = 365                   # how long to certify 
for
+               default_crl_days= 30                    # how long before next 
CRL
+               default_md      = default               # use public key 
default MD
+               preserve        = no                    # keep passed DN 
ordering
+               policy          = policy_anything
+               [ policy_anything ]
+               countryName             = optional
+               stateOrProvinceName     = optional
+               localityName            = optional
+               organizationName        = optional
+               organizationalUnitName  = optional
+               commonName              = supplied
+               emailAddress            = optional
+               [ req ]
+               default_bits            = 2048
+               default_keyfile         = privkey.pem
+               distinguished_name      = req_distinguished_name
+               attributes              = req_attributes
+               x509_extensions = v3_ca # The extentions to add to the self 
signed cert
+               string_mask = utf8only
+               prompt = no
+               [ req_distinguished_name ]
+               countryName                     = XX
+               stateOrProvinceName             = Some-state
+               localityName                    = Some-city
+               0.organizationName              = Some-org
+               CN                              = $cnname
+               [ req_attributes ]
+               challengePassword               = foobar
+               unstructuredName                = An optional company name
+               [ usr_cert ]
+               basicConstraints=CA:FALSE
+               nsComment                       = "OpenSSL Generated 
Certificate"
+               subjectKeyIdentifier=hash
+               authorityKeyIdentifier=keyid,issuer
+               [ v3_req ]
+               basicConstraints = CA:FALSE
+               keyUsage = nonRepudiation, digitalSignature, keyEncipherment
+               [ v3_ca ]
+               subjectKeyIdentifier=hash
+               authorityKeyIdentifier=keyid:always,issuer
+               basicConstraints = CA:true
+       OPENSSL_CNF
+
+       # though we use a password, the key is discarded and never used
+       openssl req -batch -passout pass:"$certpass" -new -x509 \
+           -keyout cakey.pem -out cacert.pem -days 3650 \
+           -config openssl.cnf -newkey rsa:2048 >/dev/null 2>&1 &&
+
+       # make new certificate
+       openssl req -batch -nodes -new -x509 -keyout newkey.pem \
+           -out newreq.pem -days 365 -config openssl.cnf \
+           -newkey rsa:2048 >/dev/null 2>&1 &&
+
+       # sign certificate
+       openssl x509 -x509toreq -in newreq.pem -signkey newkey.pem \
+           -out tmp.pem >/dev/null 2>&1 &&
+       openssl ca -notext -config openssl.cnf \
+           -out newcert.pem -keyfile cakey.pem -cert cacert.pem \
+           -key "$certpass" -batch -infiles tmp.pem >/dev/null 2>&1 &&
+
+       mkdir -p "$CERTDIR" &&
+       chmod 0755 "$CERTDIR" &&
+       chmod 644 newcert.pem cacert.pem &&
+       chmod 600 newkey.pem &&
+       cp -p newcert.pem "$CERTDIR"/host.cert &&
+       cp -p cacert.pem "$CERTDIR"/cacert.pem &&
+       cp -p newkey.pem "$CERTDIR"/host.key &&
+       ln -s cacert.pem "$CERTDIR"/`openssl x509 -hash -noout \
+           -in cacert.pem`.0)
+
+       retVal="$?"
+       rm -rf "$CAdir"
+
+       return "$retVal"
+}
+
 sendmail_precmd()
 {
        # Die if there's pre-8.10 custom configuration file.  This check is
@@ -71,6 +185,17 @@ sendmail_precmd()
                                /usr/bin/newaliases
                fi
        fi
+
+       if checkyesno sendmail_cert_create && [ ! \( \
+           -f "$CERTDIR/host.cert" -o -f "$CERTDIR/host.key" -o \
+           -f "$CERTDIR/cacert.pem" \) ]; then
+               if ! openssl version >/dev/null 2>&1; then
+                       warn "OpenSSL not available, but sendmail_cert_create 
is YES."
+               else
+                       info Creating certificate for sendmail.
+                       sendmail_cert_create
+               fi
+       fi
 }
 
 run_rc_command "$1"

Modified: head/etc/sendmail/freebsd.mc
==============================================================================
--- head/etc/sendmail/freebsd.mc        Sat Oct 19 18:13:32 2013        
(r256772)
+++ head/etc/sendmail/freebsd.mc        Sat Oct 19 18:51:06 2013        
(r256773)
@@ -42,6 +42,11 @@ divert(-1)
 #  /usr/share/sendmail/cf/README or
 #  /usr/src/contrib/sendmail/cf/README
 # 
+#
+#  NOTE: If you enable RunAsUser, make sure that you adjust the permissions
+#  and owner of the SSL certificates and keys in /etc/mail/certs to be usable
+#  by that user.
+#
 
 divert(0)
 VERSIONID(`$FreeBSD$')
@@ -54,6 +59,16 @@ FEATURE(local_lmtp)
 FEATURE(mailertable, `hash -o /etc/mail/mailertable')
 FEATURE(virtusertable, `hash -o /etc/mail/virtusertable')
 
+dnl Enable STARTTLS for receiving email.
+define(`CERT_DIR', `/etc/mail/certs')dnl
+define(`confSERVER_CERT', `CERT_DIR/host.cert')dnl
+define(`confSERVER_KEY', `CERT_DIR/host.key')dnl
+define(`confCLIENT_CERT', `CERT_DIR/host.cert')dnl
+define(`confCLIENT_KEY', `CERT_DIR/host.key')dnl
+define(`confCACERT', `CERT_DIR/cacert.pem')dnl
+define(`confCACERT_PATH', `CERT_DIR')dnl
+define(`confDH_PARAMETERS', `CERT_DIR/dh.param')dnl
+
 dnl Uncomment to allow relaying based on your MX records.
 dnl NOTE: This can allow sites to use your server as a backup MX without
 dnl       your permission.

Modified: head/share/man/man8/rc.sendmail.8
==============================================================================
--- head/share/man/man8/rc.sendmail.8   Sat Oct 19 18:13:32 2013        
(r256772)
+++ head/share/man/man8/rc.sendmail.8   Sat Oct 19 18:51:06 2013        
(r256773)
@@ -26,7 +26,7 @@
 .\"
 .\" $FreeBSD$
 .\"
-.Dd March 30, 2002
+.Dd October 19, 2013
 .Dt RC.SENDMAIL 8
 .Os
 .Sh NAME
@@ -119,6 +119,42 @@ The
 .Dq Li NONE
 option is deprecated and should not be used.
 It will be removed in a future release.
+.It Va sendmail_cert_create
+.Pq Vt str
+If
+.Va sendmail_enable
+is set to
+.Dq Li YES ,
+create a signed certificate
+.Pa /etc/mail/certs/host.cert
+representing
+.Pa /etc/mail/certs/host.key
+by the CA certificate in
+.Pa /etc/mail/certs/cacert.pem .
+This will enable connecting hosts to negotiate STARTTLS allowing incoming
+email to be encrypted in transit.
+.Xr sendmail 8
+needs to be configured to use these generated files.
+The default configuration in
+.Pa /etc/mail/freebsd.mc
+has the required options in it.
+.It Va sendmail_cert_cn
+.Pq Vt str
+If
+.Va sendmail_enable
+is set to
+.Dq Li YES
+and
+.Va sendmail_cert_create
+is set to
+.Dq Li YES ,
+this is the Common Name (CN) of the certificate that will be created.
+If
+.Va sendmail_cert_cn
+is not set, the system's hostname will be used.
+If there is no hostname set,
+.Dq Li amnesiac
+will be used.
 .It Va sendmail_flags
 .Pq Vt str
 If
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to