#!/bin/bash
#
# This is an sdm plugin for: dovecot-imap
#
# The plugin is called three times: for Phase 0, Phase 1, and post-install.
#

function loadparams() {
    source $SDMPT/etc/sdm/sdm-readparams
}

function dovecot_pline() {
    local line
    while read line
    do
        logtoboth "$line"
	#echo "$(thisdate) $line"
    done
}

# $1 is the phase: "0", "1", or "post-install"
# $2 is the argument list: arg1=val1|arg2=val2|arg3=val3| ...
#
# Main code for the Plugin
#
phase=$1
pfx="$(basename $0)"     #For messages
args="$2"
loadparams
vldargs="|email-address|common-name|org-name|"
rqdargs=""                   # |list|of|required|args|or|nullstring|
assetdir="$SDMPT/etc/sdm/assets/$pfx"

if [ "$phase" == "0" ]
then
    #
    # In Phase 0 all references to directories in the image must be preceded by $SDMPT
    #
    logtoboth "* Plugin $pfx: Start Phase 0"
    plugin_getargs $pfx "$args" "$vldargs" "$rqdargs" || exit
    plugin_printkeys
    mkdir -p $assetdir
    logtoboth "* Plugin $pfx: Complete Phase 0"
elif [ "$phase" == "1" ]
then
    #
    # Phase 1 (in nspawn)
    #
    logtoboth "* Plugin $pfx: Start Phase 1"
    plugin_getargs $pfx "$args" "$vldargs" "$rqdargs"
    #logfreespace "at start of Plugin $pfx Phase 1"
    logtoboth "> Plugin $pfx: Install dovecot-core and dovecot-imapd"
    installpkgsif "dovecot-core dovecot-imapd"
    #logfreespace "at end of $pfx Phase 1"
    logtoboth "* Plugin $pfx: Complete Phase 1"
elif [ "$phase" == "post-install" ]
then
    #
    # Plugin Post-install edits
    #
    logtoboth "* Plugin $pfx: Start Phase post-install"
    plugin_getargs $pfx "$args" "$vldargs" "$rqdargs"
    #logfreespace "at start of Plugin $pfx Phase post-install"

    [ -d /etc/postfix ] || logtobothex "? Plugin $pfx: Postfix is required but does not appear to be installed"
    logtoboth "> Plugin $pfx: Configure dovecot for imap"
    maildirmake.dovecot /etc/skel/Mail
    maildirmake.dovecot /etc/skel/Mail/.Drafts
    maildirmake.dovecot /etc/skel/Mail/.Sent
    maildirmake.dovecot /etc/skel/Mail/.Spam
    maildirmake.dovecot /etc/skel/Mail/.Trash
    maildirmake.dovecot /etc/skel/Mail/.Templates

    cp /etc/dovecot/dovecot.conf /etc/dovecot/.sdm.dovecot.conf
    # insert after existing #listen 
    sed -i '/#listen/a listen=*' /etc/dovecot/dovecot.conf

    cp /etc/dovecot/conf.d/10-mail.conf /etc/dovecot/conf.d/.sdm.10-mail.conf
    sed -i 's|^mail_location = .*$|mail_location = maildir:~/Mail|'  /etc/dovecot/conf.d/10-mail.conf

    cp /etc/dovecot/conf.d/10-master.conf /etc/dovecot/conf.d/.sdm.10-master.conf
    sed -i '/\# Postfix smtp-auth/, /\#\}/ {/\#\}/ s/.*/\
  unix_listener \/var\/spool\/postfix\/private\/auth \{\
    mode = 0660 \
    user = postfix \
    group = postfix \
  \}/; t; d}' /etc/dovecot/conf.d/10-master.conf
    sed -i '0,/#port = 143/s//port = 143/' /etc/dovecot/conf.d/10-master.conf    # Only does first occurrence
    sed -i '0,/#port = 993/s//port = 993/' /etc/dovecot/conf.d/10-master.conf    # Ditto
    sed -i '0,/#ssl = yes/s//ssl = yes/' /etc/dovecot/conf.d/10-master.conf      # ...

    cp /etc/dovecot/conf.d/10-auth.conf /etc/dovecot/conf.d/.sdm.10-auth.conf
    sed -i '/#disable_plaintext_auth/a disable_plaintext_auth =  no' /etc/dovecot/conf.d/10-auth.conf
    # comment out existing and add new line following
    sed -i 's/auth_mechanisms = plain/#auth_mechanisms = plain/' /etc/dovecot/conf.d/10-auth.conf
    sed -i '/#auth_mechanisms/a auth_mechanisms = plain login' /etc/dovecot/conf.d/10-auth.conf

    cp /usr/share/dovecot/dovecot-openssl.cnf /usr/share/dovecot/.sdm.dovecot-openssl.cnf
    # Prevent using /dev/urandom which errors out
    sed -i 's/RANDFILE/#RANDFILE/' /usr/share/dovecot/dovecot-openssl.cnf
    [ "$email__address" == "" ] || sed -i "s/@emailAddress@/$email__address/" /usr/share/dovecot/dovecot-openssl.cnf
    [ "$common__name" == "" ] || sed -i "s/@commonName@/$common__name/" /usr/share/dovecot/dovecot-openssl.cnf
    [ "$org__name" == "" ] || sed -i "s/ Dovecot mail server/ $org__name/" /usr/share/dovecot/dovecot-openssl.cnf

    logtoboth "> Plugin $pfx: Generate dovecot public/private keys"
    mv /etc/dovecot/private/dovecot.pem /etc/dovecot/private/.sdm.dovecot.pem
    mv /etc/dovecot/private/dovecot.key /etc/dovecot/private/.sdm.dovecot.key
    openssl req -new -x509 -nodes -config /usr/share/dovecot/dovecot-openssl.cnf \
	    -out    /etc/dovecot/private/dovecot.pem \
	    -keyout /etc/dovecot/private/dovecot.key -days 3650 >/dev/null 2>&1
    sts=$?
    [ $sts -ne 0 ] && logtobothex "? Plugin $pfx: 'openssl req' returned error '$sts'"

    logtoboth "> Plugin $pfx: Updating /etc/postfix/main.cf..."
    sed -i 's/inet_protocols = all/inet_protocols = ipv4/' /etc/postfix/main.cf
    sed -i 's/inet_interfaces = loopback-only/#inet_interfaces = loopback-only/' /etc/postfix/main.cf

    logtoboth "> Plugin $pfx: Enable submission (port 587) for postfix"
    sed -i 's/#submission /submission /' /etc/postfix/master.cf

    cat >> /etc/postfix/main.cf <<EOF
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_helo_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_invalid_helo_hostname, reject_non_fqdn_helo_hostname, reject_unknown_helo_hostname
#, check_helo_access = hash:/etc/postfix/helo_access

# For incoming mail
#
home_mailbox = Mail/
mailbox_command =
EOF

    #logfreespace "at end of $pfx Custom Phase post-install"
    plugin_addnote "*** dovecot-imap service notes"
    plugin_addnote ""
    plugin_addnote "This configuration enables imap Client Authentication modes (Thunderbird terminology):"
    plugin_addnote "* Port 143: Connection Security: None; Password transmitted insecurely"
    plugin_addnote "* Port 993: Connection Security: None; Password transmitted insecurely"
    plugin_addnote ""
    plugin_addnote "SMTP outgoing mail Client Authentication modes via sdm 'postfix' plugin"
    plugin_addnote "* Port 25:  Connection Security: None; Password transmitted insecurely"
    plugin_addnote "* Port 587: Connection Security: None; Password transmitted insecurely"
    plugin_addnote ""
    plugin_addnote "This configuration is only safe for LAN use"
    plugin_addnote "* NOT suitable as is for use with internet-exposed imap or smtp ports"
    plugin_addnote ""
    plugin_addnote "If actual certs are used (e.g., LetsEncrypt) STARTTLS should work"
    plugin_addnote "although this has not been tested/verified"
    plugin_addnote ""
    plugin_addnote ""
    logtoboth "* Plugin $pfx: Complete Phase post-install"
fi
