#!/bin/bash
#
# Copyright 2013 Aeneas Jaissle <aj@ajaissle.de>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; version 3 or, at your option, any later version
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Library General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin street, Fifth Floor, Boston, MA 02111-1301, USA.
#

echo "Checking for server certificate..."
CERTDIR=/etc/ssl/servercerts
CERTFILE=$CERTDIR/servercert.pem
CERTKEY=$CERTDIR/serverkey.pem

if [[ ! -f $CERTKEY ]]; then
  echo "  ERROR: No certificate key found at $CERTKEY"
  CERT_PRESENCE=no
elif [[ ! -s $CERTKEY ]]; then
  echo "  ERROR: Certificate key has a size of zero!"
  CERT_PRESENCE=no
fi
 
if [[ ! -f $CERTFILE ]]; then
  echo "  ERROR: No server certificate found at $CERTFILE"
  CERT_PRESENCE=no
elif [[ ! -s $CERTFILE ]]; then
  echo "  ERROR: Server certificate has a size of zero."
  CERT_PRESENCE=no
fi

if [[ "$CERT_PRESENCE" == "" ]]; then
  echo "Found server certificate and key"
else
  echo
  echo "Creating certificate authority... "
  mkdir -p /etc/ssl/private/
  mkdir -p /etc/ssl/servercerts/
  cd /etc/ssl/
  # create default passphrase
  DPASS=`head -c 200 /dev/urandom | tr -dc _A-Z-a-z-0-9 | head -c 15`
  read -p "  Supply a pass phrase for this CA: [$DPASS] " PASS
  if [[ "$PASS" == "" ]]; then
    PASS=$DPASS
  fi
  # create certificate authority
  [[ -f private/cakey ]] && mv private/cakey private/cakey.bkp
  openssl req -new -x509 -newkey rsa:2048 -keyout private/cakey.pem \
              -out cacert.pem -days 3650 -passout pass:$PASS
  chmod 600 private/cakey.pem
  echo
  echo "Creating server certificate..."
  # create server certificate key
  echo "  Generating certificate key..."
  openssl genrsa -out servercerts/serverkey.pem -aes256 2048 -days 3650
  # remove passphrase
  echo
  echo "  Removing key passphrase..."
  openssl rsa -in servercerts/serverkey.pem -out servercerts/serverkey.pem
  # create certificate signing request
  echo
  echo "  Generating certificate signing request..."
  openssl req -new -key servercerts/serverkey.pem -out csreq.pem -nodes

  # adjust openssl.cnf
  echo
  echo "  Adjusting openssl.conf..."
  sed -i '42s;= ./demoCA;= .;' openssl.cnf
  sed -i '48s;= $dir/newcerts;= $dir/servercerts;' openssl.cnf

  # create server certificate
  [[ ! -f /etc/ssl/index.html ]] && touch index.txt
  if [[ ! -f /etc/ssl/serial ]] || [[ ! -s /etc/ssl/serial ]]; then
    echo 01 > serial
  else
    mv serial serial.old
    if [[ `cat /etc/ssl/serial.old` < 10 ]] ; then
    echo 0$(( `cat /etc/ssl/serial.old` + 1 )) > serial
    else
    echo $(( `cat /etc/ssl/serial.old` + 1 )) > serial
    fi
  fi

  echo "  Signing generated certificate..."
  openssl ca -in csreq.pem -notext -out servercerts/servercert.pem -key $PASS

  echo "Setting cert paths in postfix main.cf..."
  MAINCF=/etc/postfix/main.cf
  for SETTING in 'smtp_use_tls = yes' \
                 'smtp_tls_CAfile = /etc/ssl/cacert.pem' \
                 'smtp_tls_CApath = /etc/ssl/' \
                 'smtp_tls_cert_file = /etc/ssl/servercerts/servercert.pem' \
                 'smtp_tls_key_file = /etc/ssl/servercerts/serverkey.pem' \
                 'smtpd_use_tls = yes' \
                 'smtpd_tls_CAfile = /etc/ssl/cacert.pem' \
                 'smtpd_tls_CApath = /etc/ssl/' \
                 'smtpd_tls_cert_file = /etc/ssl/servercerts/servercert.pem' \
                 'smtpd_tls_key_file = /etc/ssl/servercerts/serverkey.pem' \
                 'smtpd_tls_auth_only = yes'; do
    if [[ $(grep -c "^$SETTING$" $MAINCF) != 1 ]]; then
      SHORTSETTING=`echo $SETTING | head -c 14`
      sed -i "s/^$SHORTSETTING/#$SHORTSETTING/" $MAINCF
      echo "$SETTING" >> $MAINCF
      echo "  Set: $SETTING"
    fi
  done
fi