#!/bin/bash # # .---. . . # | | | # |--- .--. .-. .-. .-.| .-. .--.--. |.-. .-. .--. .-. # | | (.-' (.-' ( | ( )| | | | )( )| | (.-' # ' ' --' --' -' - -' ' ' -' -' -' ' - --' # # Freedom in the Cloud # # Email functions # # License # ======= # # Copyright (C) 2014-2016 Bob Mottram # # This program is free software: you can redistribute it and/or modify # it under the terms of the GNU Affero General Public License as published by # the Free Software Foundation, either version 3 of the License, 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 Affero General Public License for more details. # # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see . # the default email address MY_EMAIL_ADDRESS=$MY_USERNAME@$DEFAULT_DOMAIN_NAME # If you want to run a public mailing list specify its name here. # There should be no spaces in the name PUBLIC_MAILING_LIST= # Optional different domain name for the public mailing list PUBLIC_MAILING_LIST_DOMAIN_NAME= # Directory where the public mailing list data is stored PUBLIC_MAILING_LIST_DIRECTORY="/var/spool/mlmmj" # If you want to run an encrypted mailing list specify its name here. # There should be no spaces in the name PRIVATE_MAILING_LIST= GPG_KEYSERVER="hkp://keys.gnupg.net" # whether to encrypt all incoming email with your public key GPG_ENCRYPT_STORED_EMAIL="yes" # gets set to yes if gpg keys are imported from usb GPG_KEYS_IMPORTED="no" # optionally you can provide your exported GPG key pair here # Note that the private key file will be deleted after use # If these are unspecified then a new GPG key will be created MY_GPG_PUBLIC_KEY= MY_GPG_PRIVATE_KEY= # optionally specify your public key ID MY_GPG_PUBLIC_KEY_ID= EXIM_ONION_REPO="https://github.com/petterreinholdtsen/exim4-smtorp" # automatic archiving of email CLEANUP_MAILDIR_REPO="https://github.com/bashrc/cleanup-maildir" CLEANUP_MAILDIR_COMMIT='33241d2e3861f901ba17f5c77ada007e1ec06a86' # email encryption at rest GPGIT_REPO="https://gitlab.com/mikecardwell/gpgit" GPGIT_COMMIT='583dc76119f19420f8a33f606744faa7c8922738' # refresh gpg keys every few hours REFRESH_GPG_KEYS_HOURS=2 function email_create_template { if [ ! -d /etc/skel/log ]; then mkdir -m 700 /etc/skel/log fi if [ ! -d /etc/skel/Maildir ]; then mkdir -m 700 /etc/skel/.mutt mkdir -m 700 /etc/skel/Maildir mkdir -m 700 /etc/skel/Maildir/new mkdir -m 700 /etc/skel/Maildir/cur mkdir -m 700 /etc/skel/Maildir/Sent mkdir -m 700 /etc/skel/Maildir/Sent/tmp mkdir -m 700 /etc/skel/Maildir/Sent/cur mkdir -m 700 /etc/skel/Maildir/Sent/new mkdir -m 700 /etc/skel/Maildir/.learn-spam mkdir -m 700 /etc/skel/Maildir/.learn-spam/cur mkdir -m 700 /etc/skel/Maildir/.learn-spam/new mkdir -m 700 /etc/skel/Maildir/.learn-spam/tmp mkdir -m 700 /etc/skel/Maildir/.learn-ham mkdir -m 700 /etc/skel/Maildir/.learn-ham/cur mkdir -m 700 /etc/skel/Maildir/.learn-ham/new mkdir -m 700 /etc/skel/Maildir/.learn-ham/tmp ln -s /etc/skel/Maildir/.learn-spam /etc/skel/Maildir/spam ln -s /etc/skel/Maildir/.learn-ham /etc/skel/Maildir/ham fi if [ ! -d /home/$MY_USERNAME/Maildir ]; then mkdir -m 700 /home/$MY_USERNAME/.mutt mkdir -m 700 /home/$MY_USERNAME/Maildir mkdir -m 700 /home/$MY_USERNAME/Maildir/cur mkdir -m 700 /home/$MY_USERNAME/Maildir/tmp mkdir -m 700 /home/$MY_USERNAME/Maildir/new mkdir -m 700 /home/$MY_USERNAME/Maildir/Sent mkdir -m 700 /home/$MY_USERNAME/Maildir/Sent/cur mkdir -m 700 /home/$MY_USERNAME/Maildir/Sent/tmp mkdir -m 700 /home/$MY_USERNAME/Maildir/Sent/new mkdir -m 700 /home/$MY_USERNAME/Maildir/.learn-spam mkdir -m 700 /home/$MY_USERNAME/Maildir/.learn-spam/cur mkdir -m 700 /home/$MY_USERNAME/Maildir/.learn-spam/new mkdir -m 700 /home/$MY_USERNAME/Maildir/.learn-spam/tmp mkdir -m 700 /home/$MY_USERNAME/Maildir/.learn-ham mkdir -m 700 /home/$MY_USERNAME/Maildir/.learn-ham/cur mkdir -m 700 /home/$MY_USERNAME/Maildir/.learn-ham/new mkdir -m 700 /home/$MY_USERNAME/Maildir/.learn-ham/tmp ln -s /home/$MY_USERNAME/Maildir/.learn-spam /home/$MY_USERNAME/Maildir/spam ln -s /home/$MY_USERNAME/Maildir/.learn-ham /home/$MY_USERNAME/Maildir/ham chown -R $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/Maildir fi } function email_install_tls { # make a tls certificate for email if [ ! -f /etc/ssl/certs/exim.dhparam ]; then ${PROJECT_NAME}-addcert -h exim --dhkey $DH_KEYLENGTH check_certificates exim fi cp /etc/ssl/private/exim.key /etc/exim4 cp /etc/ssl/certs/exim.crt /etc/exim4 cp /etc/ssl/certs/exim.dhparam /etc/exim4 chown root:Debian-exim /etc/exim4/exim.key /etc/exim4/exim.crt /etc/exim4/exim.dhparam chmod 640 /etc/exim4/exim.key /etc/exim4/exim.crt /etc/exim4/exim.dhparam sed -i '/login_saslauthd_server/,/.endif/ s/# *//' /etc/exim4/exim4.conf.template if ! grep -q "MAIN_TLS_ENABLE = true" /etc/exim4/exim4.conf.template; then sed -i "/.ifdef MAIN_HARDCODE_PRIMARY_HOSTNAME/i\MAIN_HARDCODE_PRIMARY_HOSTNAME =\nMAIN_TLS_ENABLE = true" /etc/exim4/exim4.conf.template else sed -i "s|MAIN_HARDCODE_PRIMARY_HOSTNAME =.*|MAIN_HARDCODE_PRIMARY_HOSTNAME =|g" /etc/exim4/exim4.conf.template fi sed -i "s|SMTPLISTENEROPTIONS=''|SMTPLISTENEROPTIONS='-oX 465:25:587 -oP /var/run/exim4/exim.pid'|g" /etc/default/exim4 if ! grep -q "tls_on_connect_ports=465" /etc/exim4/exim4.conf.template; then sed -i '/SSL configuration for exim/i\tls_on_connect_ports=465' /etc/exim4/exim4.conf.template fi if ! grep -q "# don't send system passwords" /etc/exim4/exim4.conf.template; then sed -i "s|don't send system passwords.*|# don't send system passwords unencrypted|g" /etc/exim4/exim4.conf.template fi } function configure_email_onion { if [[ $(is_completed $FUNCNAME) == "1" ]]; then return fi if [[ $SYSTEM_TYPE == "mesh"* ]]; then return fi if ! grep -q "hidden_service_email" /etc/tor/torrc; then echo 'HiddenServiceDir /var/lib/tor/hidden_service_email/' >> /etc/tor/torrc echo 'HiddenServicePort 25 127.0.0.1:25' >> /etc/tor/torrc echo 'HiddenServicePort 587 127.0.0.1:587' >> /etc/tor/torrc echo 'HiddenServicePort 465 127.0.0.1:465' >> /etc/tor/torrc fi function_check onion_update onion_update function_check wait_for_onion_service wait_for_onion_service email if [ ! -f /var/lib/tor/hidden_service_email/hostname ]; then echo $"email onion site hostname not found" systemctl restart tor exit 782352 fi onion_address=$(cat /var/lib/tor/hidden_service_email/hostname) set_completion_param "email onion domain" "${onion_address}" add_email_hostname "$onion_address" mark_completed $FUNCNAME } function check_email_address_exists { read_config_param ONION_ONLY read_config_param MY_USERNAME read_config_param DEFAULT_DOMAIN_NAME read_config_param MY_EMAIL_ADDRESS read_config_param DH_KEYLENGTH if [ ! $MY_USERNAME ]; then echo $'No username for email installation' exit 73672 fi if [ ! $DEFAULT_DOMAIN_NAME ]; then echo $'No default domain name for email installation' exit 57634 fi my_email="$MY_EMAIL_ADDRESS" if [ ${#my_email} -lt 3 ]; then MY_EMAIL_ADDRESS=${MY_USERNAME}@${DEFAULT_DOMAIN_NAME} write_config_param "MY_EMAIL_ADDRESS" "$MY_EMAIL_ADDRESS" fi } function backup_email { echo '' } function configure_firewall_for_email { if [[ $INSTALLED_WITHIN_DOCKER == "yes" ]]; then # docker does its own firewalling return fi if [[ $ONION_ONLY != "no" ]]; then return fi firewall_add Email 25 tcp firewall_add Email 587 tcp firewall_add Email 465 tcp firewall_add Imap 993 tcp } function encrypt_incoming_email { # encrypts incoming mail using your GPG public key # so even if an attacker gains access to the data at rest they still need # to know your GPG key password to be able to read anything if [ ! -d /etc/exim4 ]; then return fi # update to the next commit function_check set_repo_commit set_repo_commit $INSTALL_DIR/gpgit "gpgit commit" "$GPGIT_COMMIT" $GPGIT_REPO if [[ $(is_completed $FUNCNAME) == "1" ]]; then return fi if [[ $GPG_ENCRYPT_STORED_EMAIL != "yes" ]]; then return fi if [ ! -f /usr/bin/gpgit.pl ]; then apt-get -yq install git libmail-gnupg-perl cd $INSTALL_DIR function_check git_clone git_clone $GPGIT_REPO $INSTALL_DIR/gpgit cd $INSTALL_DIR/gpgit git checkout $GPGIT_COMMIT -b $GPGIT_COMMIT set_completion_param "gpgit commit" "$GPGIT_COMMIT" cp gpgit.pl /usr/bin fi # add a procmail rule if ! grep -q "/usr/bin/gpgit.pl" /home/$MY_USERNAME/.procmailrc; then echo '' >> /home/$MY_USERNAME/.procmailrc echo ':0 f' >> /home/$MY_USERNAME/.procmailrc echo "| /usr/bin/gpgit.pl --encrypt-mode prefer-inline --inline-flatten $MY_EMAIL_ADDRESS" >> /home/$MY_USERNAME/.procmailrc chown $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/.procmailrc echo '' >> /etc/skel/.procmailrc echo ':0 f' >> /etc/skel/.procmailrc echo -n '| /usr/bin/gpgit.pl --encrypt-mode prefer-inline --inline-flatten $USER@' >> /etc/skel/.procmailrc echo "$DEFAULT_DOMAIN_NAME" >> /etc/skel/.procmailrc fi mark_completed $FUNCNAME } function encrypt_outgoing_email { # encrypts outgoing mail using your GPG public key # so even if an attacker gains access to the data at rest they still need # to know your GPG key password to be able to read sent mail if [ ! -d /etc/exim4 ]; then return fi if [[ $(is_completed $FUNCNAME) == "1" ]]; then return fi if [[ $GPG_ENCRYPT_STORED_EMAIL != "yes" ]]; then return fi if [ ! -d /home/$MY_USERNAME/.gnupg ]; then return fi if [ ! -f /home/$MY_USERNAME/.muttrc ]; then return fi # obtain your public key ID if [ ! $MY_GPG_PUBLIC_KEY_ID ]; then MY_GPG_PUBLIC_KEY_ID=$(gpg_pubkey_from_email "$MY_USERNAME" "$MY_EMAIL_ADDRESS") if [ ! "$MY_GPG_PUBLIC_KEY_ID" ]; then return fi if [ ${#MY_GPG_PUBLIC_KEY_ID} -lt 4 ]; then return fi fi if ! grep -q "pgp_encrypt_only_command" /home/$MY_USERNAME/.muttrc; then echo '' >> /home/$MY_USERNAME/.muttrc echo $'# Encrypt items in the Sent folder' >> /home/$MY_USERNAME/.muttrc echo "set pgp_encrypt_only_command=\"/usr/lib/mutt/pgpewrap gpg --batch --quiet --no-verbose --output - --encrypt --textmode --armor --trust-model always --encrypt-to $MY_GPG_PUBLIC_KEY_ID -- -r %r -- %f\"" >> /home/$MY_USERNAME/.muttrc else sed -i "s|set pgp_encrypt_only_command.*|set pgp_encrypt_only_command=\"/usr/lib/mutt/pgpewrap gpg --batch --quiet --no-verbose --output - --encrypt --textmode --armor --trust-model always --encrypt-to $MY_GPG_PUBLIC_KEY_ID -- -r %r -- %f\"|g" /home/$MY_USERNAME/.muttrc fi if ! grep -q "pgp_encrypt_sign_command" /home/$MY_USERNAME/.muttrc; then echo "set pgp_encrypt_sign_command=\"/usr/lib/mutt/pgpewrap gpg %?p?--passphrase-fd 0? --batch --quiet --no-verbose --textmode --output - --encrypt --sign %?a?-u %a? --armor --trust-model always --encrypt-to $MY_GPG_PUBLIC_KEY_ID -- -r %r -- %f\"" >> /home/$MY_USERNAME/.muttrc else sed -i "s|set pgp_encrypt_sign_command.*|set pgp_encrypt_sign_command=\"/usr/lib/mutt/pgpewrap gpg %?p?--passphrase-fd 0? --batch --quiet --no-verbose --textmode --output - --encrypt --sign %?a?-u %a? --armor --trust-model always --encrypt-to $MY_GPG_PUBLIC_KEY_ID -- -r %r -- %f\"|g" /home/$MY_USERNAME/.muttrc fi mark_completed $FUNCNAME } function encrypt_all_email { if [ ! -d /etc/exim4 ]; then return fi if [[ $GPG_ENCRYPT_STORED_EMAIL != "yes" ]]; then return fi if [ -f /usr/local/bin/${PROJECT_NAME}-encrypt-mail ]; then cp /usr/local/bin/${PROJECT_NAME}-encrypt-mail /usr/bin/encmaildir else cp /usr/bin/${PROJECT_NAME}-encrypt-mail /usr/bin/encmaildir fi chmod +x /usr/bin/encmaildir if [[ $(is_completed $FUNCNAME) == "1" ]]; then return fi if [ ! /home/$MY_USERNAME/README ]; then touch /home/$MY_USERNAME/README fi if ! grep -q $"If you have imported legacy email which is not encrypted" /home/$MY_USERNAME/README; then echo '' >> /home/$MY_USERNAME/README echo '' >> /home/$MY_USERNAME/README echo $'# Encrypting legacy email' >> /home/$MY_USERNAME/README echo $'If you have imported legacy email which is not encrypted' >> /home/$MY_USERNAME/README echo $'then it can be encrypted with the command:' >> /home/$MY_USERNAME/README echo '' >> /home/$MY_USERNAME/README echo ' encmaildir' >> /home/$MY_USERNAME/README echo '' >> /home/$MY_USERNAME/README echo $'But be warned that depending upon how much email you have' >> /home/$MY_USERNAME/README echo $'this could take a seriously LONG time on the Beaglebone' >> /home/$MY_USERNAME/README echo $'and may be better done on a faster machine.' >> /home/$MY_USERNAME/README chown $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/README chmod 600 /home/$MY_USERNAME/README fi mark_completed $FUNCNAME } function email_client { if [ ! -d /etc/exim4 ]; then return fi if [[ $(is_completed $FUNCNAME) == "1" ]]; then return fi apt-get -yq install lynx abook urlview mutt if [ ! -f /etc/Muttrc ]; then echo $"ERROR: Mutt does not appear to have installed. $CHECK_MESSAGE" exit 49 fi if [ ! -d /home/$MY_USERNAME/.mutt ]; then mkdir /home/$MY_USERNAME/.mutt fi echo "text/html; lynx -dump -width=78 -nolist %s | sed ‘s/^ //’; copiousoutput; needsterminal; nametemplate=%s.html" > /home/$MY_USERNAME/.mutt/mailcap cp /home/$MY_USERNAME/.mutt/mailcap /etc/skel/.mutt chown -R $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/.mutt chown -R root:root /etc/skel/.mutt echo 'set mbox_type=Maildir' >> /etc/Muttrc echo 'set folder="~/Maildir"' >> /etc/Muttrc echo 'set mask="!^\\.[^.]"' >> /etc/Muttrc echo 'set mbox="~/Maildir"' >> /etc/Muttrc echo 'set record="+Sent"' >> /etc/Muttrc echo 'set postponed="+Drafts"' >> /etc/Muttrc echo 'set trash="+Trash"' >> /etc/Muttrc echo 'set spoolfile="~/Maildir"' >> /etc/Muttrc echo 'auto_view text/x-vcard text/html text/enriched' >> /etc/Muttrc echo 'set header_cache="+.cache"' >> /etc/Muttrc echo 'set markers=no' >> /etc/Muttrc echo '' >> /etc/Muttrc echo '# ctrl-u to view long URLs' >> /etc/Muttrc echo 'macro pager \cu "urlview" "Follow links with urlview"' >> /etc/Muttrc echo '' >> /etc/Muttrc echo 'macro index S "=.learn-spam" "move to learn-spam"' >> /etc/Muttrc echo 'macro pager S "=.learn-spam" "move to learn-spam"' >> /etc/Muttrc echo 'macro index H "=.learn-ham" "copy to learn-ham"' >> /etc/Muttrc echo 'macro pager H "=.learn-ham" "copy to learn-ham"' >> /etc/Muttrc echo '' >> /etc/Muttrc echo '# set up the sidebar' >> /etc/Muttrc echo 'set sidebar_width=22' >> /etc/Muttrc echo 'set sidebar_visible=yes' >> /etc/Muttrc echo '' >> /etc/Muttrc echo 'set rfc2047_parameters' >> /etc/Muttrc echo '' >> /etc/Muttrc echo '# Show inbox and sent items' >> /etc/Muttrc echo 'mailboxes = =admin =Sent =maybe-spam =spam' >> /etc/Muttrc echo '' >> /etc/Muttrc echo '# Alter these colours as needed for maximum bling' >> /etc/Muttrc echo 'color sidebar_new yellow default' >> /etc/Muttrc echo 'color normal white default' >> /etc/Muttrc echo 'color hdrdefault brightcyan default' >> /etc/Muttrc echo 'color signature green default' >> /etc/Muttrc echo 'color attachment brightyellow default' >> /etc/Muttrc echo 'color quoted green default' >> /etc/Muttrc echo 'color quoted1 white default' >> /etc/Muttrc echo 'color tilde blue default' >> /etc/Muttrc echo '' >> /etc/Muttrc echo '# ctrl-n, ctrl-p to select next, prev folder' >> /etc/Muttrc echo '# ctrl-o to open selected folder' >> /etc/Muttrc echo 'bind index \Cp sidebar-prev' >> /etc/Muttrc echo 'bind index \Cn sidebar-next' >> /etc/Muttrc echo 'bind index \Co sidebar-open' >> /etc/Muttrc echo 'bind pager \Cp sidebar-prev' >> /etc/Muttrc echo 'bind pager \Cn sidebar-next' >> /etc/Muttrc echo 'bind pager \Co sidebar-open' >> /etc/Muttrc echo '' >> /etc/Muttrc echo '# ctrl-b toggles sidebar visibility' >> /etc/Muttrc echo "macro index,pager \Cb 'toggle sidebar_visible' 'toggle sidebar'" >> /etc/Muttrc echo '' >> /etc/Muttrc echo '# esc-m Mark new messages as read' >> /etc/Muttrc echo 'macro index m "T~N;WNT~O;WO\CT~T" "mark all messages read"' >> /etc/Muttrc echo '' >> /etc/Muttrc echo '# Collapsing threads' >> /etc/Muttrc echo 'macro index [ "" "collapse/uncollapse thread"' >> /etc/Muttrc echo 'macro index ] "" "collapse/uncollapse all threads"' >> /etc/Muttrc echo '' >> /etc/Muttrc echo '# threads containing new messages' >> /etc/Muttrc echo 'uncolor index "~(~N)"' >> /etc/Muttrc echo 'color index brightblue default "~(~N)"' >> /etc/Muttrc echo '' >> /etc/Muttrc echo '# new messages themselves' >> /etc/Muttrc echo 'uncolor index "~N"' >> /etc/Muttrc echo 'color index brightyellow default "~N"' >> /etc/Muttrc echo '' >> /etc/Muttrc echo '# GPG/PGP integration' >> /etc/Muttrc echo '# this set the number of seconds to keep in memory the passphrase used to encrypt/sign' >> /etc/Muttrc echo 'set pgp_timeout=1800' >> /etc/Muttrc echo '' >> /etc/Muttrc echo '# automatically sign and encrypt with PGP/MIME' >> /etc/Muttrc echo 'set pgp_autosign # autosign all outgoing mails' >> /etc/Muttrc echo 'set pgp_autoencrypt # Try to encrypt automatically' >> /etc/Muttrc echo 'set pgp_replyencrypt # autocrypt replies to crypted' >> /etc/Muttrc echo 'set pgp_replysign # autosign replies to signed' >> /etc/Muttrc echo 'set pgp_auto_decode=yes # decode attachments' >> /etc/Muttrc echo 'set fcc_clear=no # Keep encrypted copy of sent encrypted mail' >> /etc/Muttrc echo 'unset smime_is_default' >> /etc/Muttrc echo '' >> /etc/Muttrc echo 'set alias_file=~/.mutt-alias' >> /etc/Muttrc echo 'source ~/.mutt-alias' >> /etc/Muttrc echo 'set query_command= "abook --mutt-query \"%s\""' >> /etc/Muttrc echo 'macro index,pager A "abook --add-email-quiet" "add the sender address to abook"' >> /etc/Muttrc echo '' >> /etc/Muttrc echo '# Optional relay of SMTP via ISP' >> /etc/Muttrc echo '#set smtp_url="smtps://username:password@isp_mail_domain:465/"' >> /etc/Muttrc # For viewing long URLs echo 'REGEXP (((http|https|ftp|gopher)|mailto)[.:][^ >"\t]*|www\.[-a-z0-9.]+)[^ .,;\t>">\):]' > /home/$MY_USERNAME/.urlview echo 'COMMAND lynx -dump -width=78 -nolist %s' >> /home/$MY_USERNAME/.urlview cp -f /etc/Muttrc /home/$MY_USERNAME/.muttrc cp -f /etc/Muttrc /etc/skel/.muttrc cp -f /home/$MY_USERNAME/.urlview /etc/skel/.urlview touch /home/$MY_USERNAME/.mutt-alias cp /home/$MY_USERNAME/.mutt-alias /etc/skel/.mutt-alias chown $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/.muttrc chown $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/.mutt-alias # default user on generic images if [ -d /home/${GENERIC_IMAGE_USERNAME} ]; then cp -f /etc/Muttrc /home/${GENERIC_IMAGE_USERNAME}/.muttrc chown ${GENERIC_IMAGE_USERNAME}:${GENERIC_IMAGE_USERNAME} /home/${GENERIC_IMAGE_USERNAME}/.muttrc touch /home/${GENERIC_IMAGE_USERNAME}/.mutt-alias chown ${GENERIC_IMAGE_USERNAME}:${GENERIC_IMAGE_USERNAME} /home/${GENERIC_IMAGE_USERNAME}/.mutt-alias fi mark_completed $FUNCNAME } function email_archiving { if [ ! -d /etc/exim4 ]; then return fi # ensure that the mail archive script is up to date if [ -f /usr/local/bin/${PROJECT_NAME}-archive-mail ]; then cp /usr/local/bin/${PROJECT_NAME}-archive-mail /etc/cron.daily/archivemail else if [ -f /usr/bin/${PROJECT_NAME}-archive-mail ]; then cp /usr/bin/${PROJECT_NAME}-archive-mail /etc/cron.daily/archivemail else echo "/usr/bin/${PROJECT_NAME}-archive-mail was not found. ${PROJECT_NAME} might not have fully installed." exit 62379 fi fi chmod +x /etc/cron.daily/archivemail # update to the next commit function_check set_repo_commit set_repo_commit $INSTALL_DIR/cleanup-maildir "cleanup-maildir commit" "$CLEANUP_MAILDIR_COMMIT" $CLEANUP_MAILDIR_REPO if [[ $(is_completed $FUNCNAME) == "1" ]]; then return fi if [ ! -d $INSTALL_DIR ]; then mkdir $INSTALL_DIR fi cd $INSTALL_DIR function_check git_clone git_clone $CLEANUP_MAILDIR_REPO $INSTALL_DIR/cleanup-maildir cd $INSTALL_DIR/cleanup-maildir git checkout $CLEANUP_MAILDIR_COMMIT -b $CLEANUP_MAILDIR_COMMIT set_completion_param "cleanup-maildir commit" "$CLEANUP_MAILDIR_COMMIT" cp $INSTALL_DIR/cleanup-maildir/cleanup-maildir /usr/bin mark_completed $FUNCNAME } # Ensure that the from field is correct when sending email from Mutt function email_from_address { if [[ $(is_completed $FUNCNAME) == "1" ]]; then return fi if [ ! -f /home/$MY_USERNAME/.muttrc ]; then return fi if grep -q "set from=" /home/$MY_USERNAME/.muttrc; then sed -i "s|set from=.*|set from='$MY_NAME <$MY_EMAIL_ADDRESS>'|g" /home/$MY_USERNAME/.muttrc else echo "set from='$MY_NAME <$MY_EMAIL_ADDRESS>'" >> /home/$MY_USERNAME/.muttrc fi mark_completed $FUNCNAME } function create_public_mailing_list { if [ ! -d /etc/exim4 ]; then return fi if [[ $(is_completed $FUNCNAME) == "1" ]]; then return fi if [ ! $PUBLIC_MAILING_LIST ]; then return fi # does the mailing list have a separate domain name? if [ ! $PUBLIC_MAILING_LIST_DOMAIN_NAME ]; then PUBLIC_MAILING_LIST_DOMAIN_NAME=$DEFAULT_DOMAIN_NAME fi PUBLIC_MAILING_LIST_USER="mlmmj" apt-get -yq install mlmmj adduser --system $PUBLIC_MAILING_LIST_USER addgroup $PUBLIC_MAILING_LIST_USER adduser $PUBLIC_MAILING_LIST_USER $PUBLIC_MAILING_LIST_USER echo '' echo $"Creating the $PUBLIC_MAILING_LIST mailing list" echo '' # create the list mlmmj-make-ml -a -L "$PUBLIC_MAILING_LIST" -c $PUBLIC_MAILING_LIST_USER echo 'SYSTEM_ALIASES_PIPE_TRANSPORT = address_pipe' > /etc/exim4/conf.d/main/000_localmacros echo "SYSTEM_ALIASES_USER = $PUBLIC_MAILING_LIST_USER" >> /etc/exim4/conf.d/main/000_localmacros echo "SYSTEM_ALIASES_GROUP = $PUBLIC_MAILING_LIST_USER" >> /etc/exim4/conf.d/main/000_localmacros # router echo 'mlmmj_router:' > /etc/exim4/conf.d/router/750_exim4-config_mlmmj echo ' debug_print = "R: mlmmj_router for $local_part@$domain"' >> /etc/exim4/conf.d/router/750_exim4-config_mlmmj echo ' driver = accept' >> /etc/exim4/conf.d/router/750_exim4-config_mlmmj echo ' domains = +mlmmj_domains' >> /etc/exim4/conf.d/router/750_exim4-config_mlmmj echo ' #require_files = MLMMJ_HOME/${lc::$local_part}' >> /etc/exim4/conf.d/router/750_exim4-config_mlmmj echo ' # Use this instead, if you dont want to give Exim rx rights to mlmmj spool.' >> /etc/exim4/conf.d/router/750_exim4-config_mlmmj echo ' # Exim will then spawn a new process running under the UID of "mlmmj".' >> /etc/exim4/conf.d/router/750_exim4-config_mlmmj echo ' require_files = mlmmj:MLMMJ_HOME/${lc::$local_part}' >> /etc/exim4/conf.d/router/750_exim4-config_mlmmj echo ' local_part_suffix = +*' >> /etc/exim4/conf.d/router/750_exim4-config_mlmmj echo ' local_part_suffix_optional' >> /etc/exim4/conf.d/router/750_exim4-config_mlmmj echo ' headers_remove = Delivered-To' >> /etc/exim4/conf.d/router/750_exim4-config_mlmmj echo ' headers_add = Delivered-To: $local_part$local_part_suffix@$domain' >> /etc/exim4/conf.d/router/750_exim4-config_mlmmj echo ' transport = mlmmj_transport' >> /etc/exim4/conf.d/router/750_exim4-config_mlmmj # transport echo 'mlmmj_transport:' > /etc/exim4/conf.d/transport/40_exim4-config_mlmmj echo ' debug_print = "T: mlmmj_transport for $local_part@$domain"' >> /etc/exim4/conf.d/transport/40_exim4-config_mlmmj echo ' driver = pipe' >> /etc/exim4/conf.d/transport/40_exim4-config_mlmmj echo ' return_path_add' >> /etc/exim4/conf.d/transport/40_exim4-config_mlmmj echo ' user = mlmmj' >> /etc/exim4/conf.d/transport/40_exim4-config_mlmmj echo ' group = mlmmj' >> /etc/exim4/conf.d/transport/40_exim4-config_mlmmj echo ' home_directory = MLMMJ_HOME' >> /etc/exim4/conf.d/transport/40_exim4-config_mlmmj echo ' current_directory = MLMMJ_HOME' >> /etc/exim4/conf.d/transport/40_exim4-config_mlmmj echo ' command = /usr/bin/mlmmj-receive -F -L MLMMJ_HOME/${lc:$local_part}' >> /etc/exim4/conf.d/transport/40_exim4-config_mlmmj if ! grep -q "MLMMJ_HOME=/var/spool/mlmmj" /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs; then sed -i '/MAIN CONFIGURATION SETTINGS/a\MLMMJ_HOME=/var/spool/mlmmj' /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs fi if ! grep -q "domainlist mlmmj_domains =" /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs; then sed -i "/MLMMJ_HOME/a\domainlist mlmmj_domains = $PUBLIC_MAILING_LIST_DOMAIN_NAME" /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs fi if ! grep -q "delay_warning_condition =" /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs; then sed -i '/domainlist mlmmj_domains =/a\delay_warning_condition = ${if match_domain{$domain}{+mlmmj_domains}{no}{yes}}' /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs fi if ! grep -q ": +mlmmj_domains" /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs; then sed -i 's/domainlist relay_to_domains = MAIN_RELAY_TO_DOMAINS/domainlist relay_to_domains = MAIN_RELAY_TO_DOMAINS : +mlmmj_domains/g' /etc/exim4/conf.d/main/01_exim4-config_listmacrosdefs fi if ! grep -q "! +mlmmj_domains" /etc/exim4/conf.d/router/200_exim4-config_primary; then sed -i 's/domains = ! +local_domains/domains = ! +mlmmj_domains : ! +local_domains/g' /etc/exim4/conf.d/router/200_exim4-config_primary fi update-exim4.conf.template -r update-exim4.conf systemctl restart exim4 if ! grep -q $"$PUBLIC_MAILING_LIST mailing list" /home/$MY_USERNAME/README; then echo '' >> /home/$MY_USERNAME/README echo '' >> /home/$MY_USERNAME/README echo $"$PUBLIC_MAILING_LIST mailing list" >> /home/$MY_USERNAME/README echo '=================================' >> /home/$MY_USERNAME/README echo $"To subscribe to the $PUBLIC_MAILING_LIST mailing list send a" >> /home/$MY_USERNAME/README echo $"cleartext email to $PUBLIC_MAILING_LIST+subscribe@$DEFAULT_DOMAIN_NAME" >> /home/$MY_USERNAME/README chown $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/README chmod 600 /home/$MY_USERNAME/README fi ${PROJECT_NAME}-addlist -u $MY_USERNAME -l "$PUBLIC_MAILING_LIST" -s "$PUBLIC_MAILING_LIST" mark_completed $FUNCNAME } function create_private_mailing_list { if [ ! -d /etc/exim4 ]; then return fi if [[ $(is_completed $FUNCNAME) == "1" ]]; then return fi if [ ! $PRIVATE_MAILING_LIST ]; then return fi if [[ $PRIVATE_MAILING_LIST == $MY_USERNAME ]]; then echo $'The name of the private mailing list should not be the same as your username' exit 10 fi if [ ! $MY_GPG_PUBLIC_KEY ]; then echo $'To create a private mailing list you need to specify a file' echo $'containing your exported GPG key within MY_GPG_PUBLIC_KEY at' echo $'the top of the script' exit 11 fi apt-get -yq install ruby ruby-dev ruby-gpgme libgpgme11-dev libmagic-dev gem install schleuder schleuder-fix-gem-dependencies schleuder-init-setup --gem # NOTE: this is version number sensitive and so might need changing ln -s /var/lib/gems/2.1.0/gems/schleuder-2.2.4 /var/lib/schleuder sed -i 's/#smtp_port: 25/smtp_port: 465/g' /etc/schleuder/schleuder.conf sed -i 's/#superadminaddr: root@localhost/superadminaddr: root@localhost' /etc/schleuder/schleuder.conf schleuder-newlist $PRIVATE_MAILING_LIST@$DEFAULT_DOMAIN_NAME -realname "$PRIVATE_MAILING_LIST" -adminaddress $MY_EMAIL_ADDRESS -initmember $MY_EMAIL_ADDRESS -initmemberkey $MY_GPG_PUBLIC_KEY -nointeractive ${PROJECT_NAME}-addemail -u $MY_USERNAME -e $PRIVATE_MAILING_LIST@$DEFAULT_DOMAIN_NAME -l $PRIVATE_MAILING_LIST echo 'schleuder:' > /etc/exim4/conf.d/router/550_exim4-config_schleuder echo ' debug_print = "R: schleuder for $local_part@$domain"' >> /etc/exim4/conf.d/router/550_exim4-config_schleuder echo ' driver = accept' >> /etc/exim4/conf.d/router/550_exim4-config_schleuder echo ' local_part_suffix_optional' >> /etc/exim4/conf.d/router/550_exim4-config_schleuder echo ' local_part_suffix = +* : -bounce : -sendkey' >> /etc/exim4/conf.d/router/550_exim4-config_schleuder echo ' domains = +local_domains' >> /etc/exim4/conf.d/router/550_exim4-config_schleuder echo ' user = schleuder' >> /etc/exim4/conf.d/router/550_exim4-config_schleuder echo ' group = schleuder' >> /etc/exim4/conf.d/router/550_exim4-config_schleuder echo ' require_files = schleuder:+/var/lib/schleuder/$domain/${local_part}' >> /etc/exim4/conf.d/router/550_exim4-config_schleuder echo ' transport = schleuder_transport' >> /etc/exim4/conf.d/router/550_exim4-config_schleuder echo 'schleuder_transport:' > /etc/exim4/conf.d/transport/30_exim4-config_schleuder echo ' debug_print = "T: schleuder_transport for $local_part@$domain"' >> /etc/exim4/conf.d/transport/30_exim4-config_schleuder echo ' driver = pipe' >> /etc/exim4/conf.d/transport/30_exim4-config_schleuder echo ' home_directory = "/var/lib/schleuder/$domain/$local_part"' >> /etc/exim4/conf.d/transport/30_exim4-config_schleuder echo ' command = "/usr/bin/schleuder $local_part@$domain"' >> /etc/exim4/conf.d/transport/30_exim4-config_schleuder chown -R schleuder:schleuder /var/lib/schleuder update-exim4.conf.template -r update-exim4.conf systemctl restart exim4 chmod 600 /etc/shadow chmod 600 /etc/gshadow useradd -d /var/schleuderlists -s /bin/false schleuder adduser Debian-exim schleuder usermod -a -G mail schleuder chmod 0000 /etc/shadow chmod 0000 /etc/gshadow #exim -d -bt $PRIVATE_MAILING_LIST@$DEFAULT_DOMAIN_NAME mark_completed $FUNCNAME } function split_gpg_key_into_fragments { # split the gpg key into fragments if social key management is enabled if [[ $ENABLE_SOCIAL_KEY_MANAGEMENT == "yes" ]]; then if [ $IMAGE_PASSWORD_FILE ]; then if [ -f $IMAGE_PASSWORD_FILE ]; then ${PROJECT_NAME}-splitkey -u $MY_USERNAME -e $MY_EMAIL_ADDRESS --fullname "$MY_NAME" --passwordfile $IMAGE_PASSWORD_FILE return fi fi echo 'Splitting GPG key. You may need to enter your passphrase.' ${PROJECT_NAME}-splitkey -u $MY_USERNAME -e $MY_EMAIL_ADDRESS --fullname "$MY_NAME" if [ ! -d /home/$MY_USERNAME/.gnupg_fragments ]; then echo 'Yhe GPG key could not be split' exit 86548 fi fi } function import_email { if [ ! -d /etc/exim4 ]; then return fi EMAIL_COMPLETE_MSG=$" *** ${PROJECT_NAME} mailbox installation is complete *** Now on your internet router forward ports 25, 587, 465, 993 and 2222 to the ${PROJECT_NAME} " if [[ $(is_completed $FUNCNAME) == "1" ]]; then if [[ $SYSTEM_TYPE == "mail"* ]]; then function_check backup_to_friends_servers backup_to_friends_servers function_check install_tripwire install_tripwire function_check split_gpg_key_into_fragments split_gpg_key_into_fragments clear echo '' echo "$EMAIL_COMPLETE_MSG" if [ -d $USB_MOUNT ]; then umount $USB_MOUNT rm -rf $USB_MOUNT echo $' You can now remove the USB drive' fi exit 0 fi return fi mark_completed $FUNCNAME if [[ $SYSTEM_TYPE == "mail"* ]]; then function_check backup_to_friends_servers backup_to_friends_servers function_check install_tripwire install_tripwire function_check split_gpg_key_into_fragments split_gpg_key_into_fragments # unmount any attached usb drive clear echo '' echo "$EMAIL_COMPLETE_MSG" echo '' if [ -d $USB_MOUNT ]; then umount $USB_MOUNT rm -rf $USB_MOUNT echo $' You can now remove the USB drive' fi exit 0 fi } function remove_email { echo '' } function install_email_with_tor { apt-get -yq remove postfix apt-get -yq install exim4 sasl2-bin swaks libnet-ssleay-perl procmail xinetd if [ ! -d /etc/exim4 ]; then echo $"ERROR: Exim does not appear to have installed. $CHECK_MESSAGE" exit 48 fi onion_service_name='email' if [ ! -d /var/lib/tor ]; then echo $"No Tor installation found. ${onion_service_name} onion site cannot be configured." exit 877367 fi if ! grep -q "hidden_service_${onion_service_name}" /etc/tor/torrc; then echo "HiddenServiceDir /var/lib/tor/hidden_service_${onion_service_name}/" >> /etc/tor/torrc echo 'HiddenServicePort 25 127.0.0.1:25' >> /etc/tor/torrc echo 'HiddenServicePort 587 127.0.0.1:587' >> /etc/tor/torrc echo 'HiddenServicePort 465 127.0.0.1:465' >> /etc/tor/torrc echo 'HiddenServicePort 993 127.0.0.1:993' >> /etc/tor/torrc echo $"Added onion site for ${onion_service_name}" fi onion_update function_check wait_for_onion_service wait_for_onion_service ${onion_service_name} if [ ! -f /var/lib/tor/hidden_service_${onion_service_name}/hostname ]; then echo $"${onion_service_name} onion site hostname not found" exit 76362 fi EMAIL_ONION_HOSTNAME=$(cat /var/lib/tor/hidden_service_${onion_service_name}/hostname) if [[ $ONION_ONLY != "no" ]]; then function_check set_hostname set_hostname ${EMAIL_ONION_HOSTNAME} MY_EMAIL_ADDRESS=${MY_USERNAME}@${DEFAULT_DOMAIN_NAME} fi set_completion_param "email onion domain" "${EMAIL_ONION_HOSTNAME}" # see https://github.com/petterreinholdtsen/exim4-smtorp echo '# tor stuff first' > /etc/exim4/conf.d/router/100_exim4-smtorp echo '#' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo '# if were submitting mail *from* a .tor/.onion address,' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo '# make sure any header lines that may give us away is' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo '# stripped out, and add a new, cryptic Message-ID.' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo '# In address_data we store the name we should HELO as.' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo 'tor_to_any:' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo ' debug_print = "R: manualroute from .onion to $local_part@$domain"' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo ' driver = manualroute' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo ' domains = ! +local_domains' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo ' condition = ${if match {$sender_address_domain}{\N.*\.(onion|tor)$\N}}' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo ' address_data = $sender_address_domain' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo ' transport = remote_smtp_onion' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo ' self = send' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo ' route_list = * localhost' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo ' headers_remove = Received:Message-ID:X-Mailer:User-Agent' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo ' headers_add = Message-ID: <${lc:${sha1:$message_id}}@$sender_address_domain>' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo '' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo '# this catches the case where were submitting mail' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo '# from a regular email address where we dont need to' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo '# rewrite any headers' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo 'any_to_tor:' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo ' debug_print = "R: manualroute for $local_part@$domain"' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo ' driver = manualroute' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo ' domains = ! +local_domains' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo ' transport = remote_smtp_onion' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo ' self = send' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo ' route_list = *.onion localhost ; *.tor localhost' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo ' address_data = $smtp_active_hostname' >> /etc/exim4/conf.d/router/100_exim4-smtorp echo 'remote_smtp_onion:' > /etc/exim4/conf.d/transport/100_exim4-smtorp echo ' debug_print = "T: remote_smtp_onion for $local_part@$original_domain"' >> /etc/exim4/conf.d/transport/100_exim4-smtorp echo ' driver = smtp' >> /etc/exim4/conf.d/transport/100_exim4-smtorp echo '' >> /etc/exim4/conf.d/transport/100_exim4-smtorp echo ' # set helo_data to where we want to connect to,' >> /etc/exim4/conf.d/transport/100_exim4-smtorp echo ' # for the proxy program tor-smtp' >> /etc/exim4/conf.d/transport/100_exim4-smtorp echo ' helo_data = "$address_data $original_domain"' >> /etc/exim4/conf.d/transport/100_exim4-smtorp echo '' >> /etc/exim4/conf.d/transport/100_exim4-smtorp echo ' # wherever we configured our script at' >> /etc/exim4/conf.d/transport/100_exim4-smtorp echo ' port = 12668' >> /etc/exim4/conf.d/transport/100_exim4-smtorp echo '' >> /etc/exim4/conf.d/transport/100_exim4-smtorp echo ' # cannot use TLS otherwise it will EHLO again!!' >> /etc/exim4/conf.d/transport/100_exim4-smtorp echo ' hosts_avoid_tls = *' >> /etc/exim4/conf.d/transport/100_exim4-smtorp if [ ! -d $INSTALL_DIR ]; then mkdir -p $INSTALL_DIR fi cd $INSTALL_DIR function_check git_clone git_clone $EXIM_ONION_REPO $INSTALL_DIR/exim4-smtorp cd $INSTALL_DIR/exim4-smtorp/tor-smtp make if [ ! -f $INSTALL_DIR/exim4-smtorp/tor-smtp/tor-smtp ]; then echo $'Unable to make tor smtp transport' exit 52629 fi if [ ! -d /usr/lib/exim4-smtorp ]; then mkdir /usr/lib/exim4-smtorp fi cp $INSTALL_DIR/exim4-smtorp/tor-smtp/tor-smtp /usr/lib/exim4-smtorp/tor-smtp if [ ! -f /usr/lib/exim4-smtorp/tor-smtp ]; then echo $'Unable to copy tor-smtp' exit 83503 fi cp $INSTALL_DIR/exim4-smtorp/xinetd /etc/xinetd.d/tor-smtp if [ ! -f /etc/xinetd.d/tor-smtp ]; then echo $'Unable to copy to xinetd.d' exit 835954 fi systemctl restart xinetd # configure for Maildir format sed -i 's/MAIL_DIR/#MAIL_DIR/g' /etc/login.defs sed -i 's|#MAIL_FILE.*|MAIL_FILE Maildir/|g' /etc/login.defs if ! grep -q "export MAIL" /etc/profile; then echo 'export MAIL=~/Maildir' >> /etc/profile fi sed -i 's|pam_mail.so standard|pam_mail.so dir=~/Maildir standard|g' /etc/pam.d/login sed -i 's|pam_mail.so standard noenv|pam_mail.so dir=~/Maildir standard|g' /etc/pam.d/sshd sed -i 's|pam_mail.so nopen|pam_mail.so dir=~/Maildir nopen|g' /etc/pam.d/su echo "dc_eximconfig_configtype='internet'" > /etc/exim4/update-exim4.conf.conf if [[ $ONION_ONLY == "no" ]]; then # both ICANN and onion domains echo "dc_other_hostnames='${DEFAULT_DOMAIN_NAME};mail.${DEFAULT_DOMAIN_NAME};${EMAIL_ONION_HOSTNAME}'" >> /etc/exim4/update-exim4.conf.conf else echo "dc_other_hostnames='${EMAIL_ONION_HOSTNAME}'" >> /etc/exim4/update-exim4.conf.conf fi echo "dc_local_interfaces=''" >> /etc/exim4/update-exim4.conf.conf echo "dc_readhost=''" >> /etc/exim4/update-exim4.conf.conf echo "dc_relay_domains=''" >> /etc/exim4/update-exim4.conf.conf echo "dc_minimaldns='false'" >> /etc/exim4/update-exim4.conf.conf IPv4_address=$(get_ipv4_address) IPv4_address_base=$(echo "$IPv4_address" | awk -F '.' '{print $1"."$2"."$3}') RELAY_NETS="${IPv4_address_base}.0/24" if [ $LOCAL_NETWORK_STATIC_IP_ADDRESS ]; then RELAY_NETS=$(echo $LOCAL_NETWORK_STATIC_IP_ADDRESS | awk -F '.' '{print $1 "." $2 "." $3 ".0/24"}') fi echo "dc_relay_nets='$RELAY_NETS'" >> /etc/exim4/update-exim4.conf.conf echo "dc_smarthost=''" >> /etc/exim4/update-exim4.conf.conf echo "CFILEMODE='644'" >> /etc/exim4/update-exim4.conf.conf echo "dc_use_split_config='false'" >> /etc/exim4/update-exim4.conf.conf echo "dc_hide_mailname=''" >> /etc/exim4/update-exim4.conf.conf echo "dc_mailname_in_oh='true'" >> /etc/exim4/update-exim4.conf.conf echo "dc_localdelivery='maildir_home'" >> /etc/exim4/update-exim4.conf.conf echo "dc_main_log_selector=-all" >> /etc/exim4/update-exim4.conf.conf update-exim4.conf sed -i "s/START=no/START=yes/g" /etc/default/saslauthd systemctl start saslauthd email_install_tls adduser $MY_USERNAME sasl addgroup Debian-exim sasl systemctl restart exim4 email_create_template if [ -f /usr/sbin/exim ]; then chmod u+s /usr/sbin/exim fi if [ -f /usr/sbin/exim4 ]; then chmod u+s /usr/sbin/exim4 fi function_check configure_firewall_for_email configure_firewall_for_email dpkg-reconfigure --frontend noninteractive exim4-config } function install_email_basic { apt-get -yq remove postfix apt-get -yq install exim4 sasl2-bin swaks libnet-ssleay-perl procmail if [ ! -d /etc/exim4 ]; then echo $"ERROR: Exim does not appear to have installed. $CHECK_MESSAGE" exit 48 fi # configure for Maildir format sed -i 's/MAIL_DIR/#MAIL_DIR/g' /etc/login.defs sed -i 's|#MAIL_FILE.*|MAIL_FILE Maildir/|g' /etc/login.defs if ! grep -q "export MAIL" /etc/profile; then echo 'export MAIL=~/Maildir' >> /etc/profile fi sed -i 's|pam_mail.so standard|pam_mail.so dir=~/Maildir standard|g' /etc/pam.d/login sed -i 's|pam_mail.so standard noenv|pam_mail.so dir=~/Maildir standard|g' /etc/pam.d/sshd sed -i 's|pam_mail.so nopen|pam_mail.so dir=~/Maildir nopen|g' /etc/pam.d/su echo "dc_eximconfig_configtype='internet'" > /etc/exim4/update-exim4.conf.conf echo "dc_other_hostnames='${DEFAULT_DOMAIN_NAME};mail.${DEFAULT_DOMAIN_NAME}'" >> /etc/exim4/update-exim4.conf.conf echo "dc_local_interfaces=''" >> /etc/exim4/update-exim4.conf.conf echo "dc_readhost=''" >> /etc/exim4/update-exim4.conf.conf echo "dc_relay_domains=''" >> /etc/exim4/update-exim4.conf.conf echo "dc_minimaldns='false'" >> /etc/exim4/update-exim4.conf.conf IPv4_address=$(get_ipv4_address) IPv4_address_base=$(echo "$IPv4_address" | awk -F '.' '{print $1"."$2"."$3}') RELAY_NETS="${IPv4_address_base}.0/24" if [ $LOCAL_NETWORK_STATIC_IP_ADDRESS ]; then RELAY_NETS=$(echo $LOCAL_NETWORK_STATIC_IP_ADDRESS | awk -F '.' '{print $1 "." $2 "." $3 ".0/24"}') fi echo "dc_relay_nets='$RELAY_NETS'" >> /etc/exim4/update-exim4.conf.conf echo "dc_smarthost=''" >> /etc/exim4/update-exim4.conf.conf echo "CFILEMODE='644'" >> /etc/exim4/update-exim4.conf.conf echo "dc_use_split_config='false'" >> /etc/exim4/update-exim4.conf.conf echo "dc_hide_mailname=''" >> /etc/exim4/update-exim4.conf.conf echo "dc_mailname_in_oh='true'" >> /etc/exim4/update-exim4.conf.conf echo "dc_localdelivery='maildir_home'" >> /etc/exim4/update-exim4.conf.conf echo "dc_main_log_selector=-all" >> /etc/exim4/update-exim4.conf.conf update-exim4.conf sed -i "s/START=no/START=yes/g" /etc/default/saslauthd systemctl start saslauthd email_install_tls adduser $MY_USERNAME sasl addgroup Debian-exim sasl systemctl restart exim4 email_create_template if [ -f /usr/sbin/exim ]; then chmod u+s /usr/sbin/exim fi if [ -f /usr/sbin/exim4 ]; then chmod u+s /usr/sbin/exim4 fi function_check configure_firewall_for_email configure_firewall_for_email dpkg-reconfigure --frontend noninteractive exim4-config systemctl restart exim4 } function email_change_relay { curr_ip_address="$1" email_relay_base=$(echo "$curr_ip_address" | awk -F '.' '{print $1"."$2"."$3}') RELAY_NETS="${email_relay_base}.0/24" sed -i "s|dc_relay_nets=.*|dc_relay_nets='$RELAY_NETS'|g" /etc/exim4/update-exim4.conf.conf dpkg-reconfigure --frontend noninteractive exim4-config } function create_procmail { if [ ! -d /etc/exim4 ]; then return fi if [[ $(is_completed $FUNCNAME) == "1" ]]; then return fi if [ ! -f /home/$MY_USERNAME/.procmailrc ]; then echo 'MAILDIR=$HOME/Maildir' > /home/$MY_USERNAME/.procmailrc echo 'DEFAULT=$MAILDIR/' >> /home/$MY_USERNAME/.procmailrc echo 'LOGFILE=$HOME/log/procmail.log' >> /home/$MY_USERNAME/.procmailrc echo 'LOGABSTRACT=all' >> /home/$MY_USERNAME/.procmailrc echo '' >> /home/$MY_USERNAME/.procmailrc echo '# Test for an empty or missing subject line' >> /home/$MY_USERNAME/.procmailrc echo 'SUBJ_=$(formail -xSubject: \' >> /home/$MY_USERNAME/.procmailrc echo " | expand | sed -e 's/^[ ]*//g' -e 's/[ ]*\$//g')" >> /home/$MY_USERNAME/.procmailrc echo ':0' >> /home/$MY_USERNAME/.procmailrc echo ' * SUBJ_ ?? ^^^^' >> /home/$MY_USERNAME/.procmailrc echo '/dev/null' >> /home/$MY_USERNAME/.procmailrc echo '' >> /home/$MY_USERNAME/.procmailrc echo $"# Tripwire reports which have no violations don't need to be logged" >> /home/$MY_USERNAME/.procmailrc echo ':0 BD:' >> /home/$MY_USERNAME/.procmailrc TRIPWIRE_VIOLATIONS_STR=$'Total violations found: 0' echo " * .*$TRIPWIRE_VIOLATIONS_STR" >> /home/$MY_USERNAME/.procmailrc echo '/dev/null' >> /home/$MY_USERNAME/.procmailrc echo '' >> /home/$MY_USERNAME/.procmailrc chown $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/.procmailrc fi mkdir -p /home/$MY_USERNAME/Maildir/admin/new mkdir -p /home/$MY_USERNAME/Maildir/admin/cur chown -R $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/Maildir/admin if [ ! -f /etc/skel/.procmailrc ]; then cp /home/$MY_USERNAME/.procmailrc /etc/skel/.procmailrc chown root:root /etc/skel/.procmailrc fi if [ -f /usr/bin/procmail ]; then chmod 6755 /usr/bin/procmail fi mark_completed $FUNCNAME } function handle_admin_emails { # keep emails for root in a separate folder if [ -d /home/$MY_USERNAME/Maildir/admin ]; then return fi ${PROJECT_NAME}-addemail -u $MY_USERNAME -e "root@$DEFAULT_DOMAIN_NAME" -g admin --public no } function spam_filtering { if [ ! -d /etc/exim4 ]; then return fi if [[ $(is_completed $FUNCNAME) == "1" ]]; then return fi apt-get -yq install exim4-daemon-heavy apt-get -yq install spamassassin if [ ! -f /etc/default/spamassassin ]; then echo 'Spamassassin was not installed' exit 72570 fi sa-update -v sed -i 's/ENABLED=0/ENABLED=1/g' /etc/default/spamassassin sed -i 's/# spamd_address = 127.0.0.1 783/spamd_address = 127.0.0.1 783/g' /etc/exim4/exim4.conf.template # This configuration is based on https://wiki.debian.org/DebianSpamAssassin sed -i 's/local_parts = postmaster/local_parts = postmaster:abuse/g' /etc/exim4/conf.d/acl/30_exim4-config_check_rcpt sed -i '/domains = +local_domains : +relay_to_domains/a\ set acl_m0 = rfcnames' /etc/exim4/conf.d/acl/30_exim4-config_check_rcpt sed -i 's/accept/accept condition = ${if eq{$acl_m0}{rfcnames} {1}{0}}/g' /etc/exim4/conf.d/acl/40_exim4-config_check_data echo 'warn message = X-Spam-Score: $spam_score ($spam_bar)' >> /etc/exim4/conf.d/acl/40_exim4-config_check_data echo ' spam = nobody:true' >> /etc/exim4/conf.d/acl/40_exim4-config_check_data echo 'warn message = X-Spam-Flag: YES' >> /etc/exim4/conf.d/acl/40_exim4-config_check_data echo ' spam = nobody' >> /etc/exim4/conf.d/acl/40_exim4-config_check_data echo 'warn message = X-Spam-Report: $spam_report' >> /etc/exim4/conf.d/acl/40_exim4-config_check_data echo ' spam = nobody' >> /etc/exim4/conf.d/acl/40_exim4-config_check_data echo '# reject spam at high scores (> 12)' >> /etc/exim4/conf.d/acl/40_exim4-config_check_data echo 'deny message = This message scored $spam_score spam points.' >> /etc/exim4/conf.d/acl/40_exim4-config_check_data echo ' spam = nobody:true' >> /etc/exim4/conf.d/acl/40_exim4-config_check_data echo ' condition = ${if >{$spam_score_int}{120}{1}{0}}' >> /etc/exim4/conf.d/acl/40_exim4-config_check_data # procmail configuration echo '# get spamassassin to check emails' >> /home/$MY_USERNAME/.procmailrc echo ':0fw: .spamassassin.lock' >> /home/$MY_USERNAME/.procmailrc echo ' * < 256000' >> /home/$MY_USERNAME/.procmailrc echo '| spamc' >> /home/$MY_USERNAME/.procmailrc echo '# strong spam are discarded' >> /home/$MY_USERNAME/.procmailrc echo ':0' >> /home/$MY_USERNAME/.procmailrc echo ' * ^X-Spam-Level: \*\*\*\*\*\*' >> /home/$MY_USERNAME/.procmailrc echo '/dev/null' >> /home/$MY_USERNAME/.procmailrc echo '# weak spam are kept just in case - clear this out every now and then' >> /home/$MY_USERNAME/.procmailrc echo ':0' >> /home/$MY_USERNAME/.procmailrc echo ' * ^X-Spam-Level: \*\*\*\*\*' >> /home/$MY_USERNAME/.procmailrc echo 'maybe-spam/' >> /home/$MY_USERNAME/.procmailrc echo '# otherwise, marginal spam goes here for revision' >> /home/$MY_USERNAME/.procmailrc echo ':0' >> /home/$MY_USERNAME/.procmailrc echo ' * ^X-Spam-Level: \*\*' >> /home/$MY_USERNAME/.procmailrc echo 'spam/' >> /home/$MY_USERNAME/.procmailrc chown $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/.procmailrc echo '# get spamassassin to check emails' >> /etc/skel/.procmailrc echo ':0fw: .spamassassin.lock' >> /etc/skel/.procmailrc echo ' * < 256000' >> /etc/skel/.procmailrc echo '| spamc' >> /etc/skel/.procmailrc echo '# strong spam are discarded' >> /etc/skel/.procmailrc echo ':0' >> /etc/skel/.procmailrc echo ' * ^X-Spam-Level: \*\*\*\*\*\*' >> /etc/skel/.procmailrc echo '/dev/null' >> /etc/skel/.procmailrc echo '# weak spam are kept just in case - clear this out every now and then' >> /etc/skel/.procmailrc echo ':0' >> /etc/skel/.procmailrc echo ' * ^X-Spam-Level: \*\*\*\*\*' >> /etc/skel/.procmailrc echo 'maybe-spam/' >> /etc/skel/.procmailrc echo '# otherwise, marginal spam goes here for revision' >> /etc/skel/.procmailrc echo ':0' >> /etc/skel/.procmailrc echo ' * ^X-Spam-Level: \*\*' >> /etc/skel/.procmailrc echo 'spam/' >> /etc/skel/.procmailrc # filtering scripts echo '#!/bin/bash' > /usr/bin/filterspam echo 'for d in /home/*/ ; do' >> /usr/bin/filterspam echo ' USERNAME=$(echo "$d" | awk -F '"'"'/'"'"' '"'"'{print $3}'"'"')' >> /usr/bin/filterspam echo ' if [[ $USERNAME != "git" && $USERNAME != "go" && $USERNAME != "gogs" && $USERNAME != "mirrors" && $USERNAME != "sync" && $USERNAME != "tahoelafs" ]]; then' >> /usr/bin/filterspam echo ' MAILDIR=/home/$USERNAME/Maildir/.learn-spam' >> /usr/bin/filterspam echo ' if [ ! -d "$MAILDIR" ]; then' >> /usr/bin/filterspam echo ' exit' >> /usr/bin/filterspam echo ' fi' >> /usr/bin/filterspam echo ' for f in `ls $MAILDIR/cur`' >> /usr/bin/filterspam echo ' do' >> /usr/bin/filterspam echo ' spamc -L spam < "$MAILDIR/cur/$f" > /dev/null' >> /usr/bin/filterspam echo ' rm "$MAILDIR/cur/$f"' >> /usr/bin/filterspam echo ' done' >> /usr/bin/filterspam echo ' for f in `ls $MAILDIR/new`' >> /usr/bin/filterspam echo ' do' >> /usr/bin/filterspam echo ' spamc -L spam < "$MAILDIR/new/$f" > /dev/null' >> /usr/bin/filterspam echo ' rm "$MAILDIR/new/$f"' >> /usr/bin/filterspam echo ' done' >> /usr/bin/filterspam echo ' fi' >> /usr/bin/filterspam echo 'done' >> /usr/bin/filterspam echo 'exit 0' >> /usr/bin/filterspam echo '#!/bin/bash' > /usr/bin/filterham echo 'for d in /home/*/ ; do' >> /usr/bin/filterham echo ' USERNAME=$(echo "$d" | awk -F '"'"'/'"'"' '"'"'{print $3}'"'"')' >> /usr/bin/filterham echo ' if [[ $USERNAME != "git" && $USERNAME != "go" && $USERNAME != "gogs" && $USERNAME != "mirrors" && $USERNAME != "sync" && $USERNAME != "tahoelafs" ]]; then' >> /usr/bin/filterham echo ' MAILDIR=/home/$USERNAME/Maildir/.learn-ham' >> /usr/bin/filterham echo ' if [ ! -d "$MAILDIR" ]; then' >> /usr/bin/filterham echo ' exit' >> /usr/bin/filterham echo ' fi' >> /usr/bin/filterham echo ' for f in `ls $MAILDIR/cur`' >> /usr/bin/filterham echo ' do' >> /usr/bin/filterham echo ' spamc -L ham < "$MAILDIR/cur/$f" > /dev/null' >> /usr/bin/filterham echo ' rm "$MAILDIR/cur/$f"' >> /usr/bin/filterham echo ' done' >> /usr/bin/filterham echo ' for f in `ls $MAILDIR/new`' >> /usr/bin/filterham echo ' do' >> /usr/bin/filterham echo ' spamc -L ham < "$MAILDIR/new/$f" > /dev/null' >> /usr/bin/filterham echo ' rm "$MAILDIR/new/$f"' >> /usr/bin/filterham echo ' done' >> /usr/bin/filterham echo ' fi' >> /usr/bin/filterham echo 'done' >> /usr/bin/filterham echo 'exit 0' >> /usr/bin/filterham function_check cron_add_mins cron_add_mins 3 '/usr/bin/timeout 120 /usr/bin/filterspam' cron_add_mins 3 '/usr/bin/timeout 120 /usr/bin/filterham' chmod 655 /usr/bin/filterspam /usr/bin/filterham sed -i 's/# use_bayes 1/use_bayes 1/g' /etc/mail/spamassassin/local.cf sed -i 's/# bayes_auto_learn 1/bayes_auto_learn 1/g' /etc/mail/spamassassin/local.cf # user preferences if [ ! -d /home/$MY_USERNAME/.spamassassin ]; then mkdir /home/$MY_USERNAME/.spamassassin echo $'# How many points before a mail is considered spam.' > /home/$MY_USERNAME/.spamassassin/user_prefs echo '# required_score 5' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo '' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo $'# Whitelist and blacklist addresses are now file-glob-style patterns, so' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo $'# "friend@somewhere.com", "*@isp.com", or "*.domain.net" will all work.' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo '# whitelist_from someone@somewhere.com' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo '' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo $'# Add your own customised scores for some tests below. The default scores are' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo $'# read from the installed spamassassin rules files, but you can override them' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo $'# here. To see the list of tests and their default scores, go to' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo '# http://spamassassin.apache.org/tests.html .' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo '#' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo '# score SYMBOLIC_TEST_NAME n.nn' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo '' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo $'# Speakers of Asian languages, like Chinese, Japanese and Korean, will almost' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo $'# definitely want to uncomment the following lines. They will switch off some' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo $'# rules that detect 8-bit characters, which commonly trigger on mails using CJK' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo $'# character sets, or that assume a western-style charset is in use. ' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo '# ' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo '# score HTML_COMMENT_8BITS 0' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo '# score UPPERCASE_25_50 0' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo '# score UPPERCASE_50_75 0' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo '# score UPPERCASE_75_100 0' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo '# score OBSCURED_EMAIL 0' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo '' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo $'# Speakers of any language that uses non-English, accented characters may wish' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo $'# to uncomment the following lines. They turn off rules that fire on' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo $'# misformatted messages generated by common mail apps in contravention of the' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo $'# email RFCs.' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo '' >> /home/$MY_USERNAME/.spamassassin/user_prefs echo '# score SUBJ_ILLEGAL_CHARS 0' >> /home/$MY_USERNAME/.spamassassin/user_prefs fi # this must be accessible by root chown -R $MY_USERNAME:root /home/$MY_USERNAME/.spamassassin # script to keep spamassassin running # There is a systemd script from the debian package, but it doesn't restart on failure # and also doesn't ensure start after networking is up. If that is eventually fixed # then this script and the cron job which runs it can be removed. script_name=/usr/bin/run-spamassassin echo '#!/bin/bash' > $script_name echo 'current_state=$(systemctl status spamassassin)' >> $script_name echo 'if [[ "$current_state" != *"(running)"* ]]; then' >> $script_name echo ' systemctl restart spamassassin' >> $script_name echo 'fi' >> $script_name echo 'exit 0' >> $script_name chmod +x $script_name systemctl start spamassassin systemctl restart exim4 systemctl restart cron function_check cron_add_mins cron_add_mins 10 "$script_name 2> /dev/null" mark_completed $FUNCNAME } function configure_imap { if [ ! -d /etc/exim4 ]; then return fi if [[ $(is_completed $FUNCNAME) == "1" ]]; then return fi dpkg -P dovecot-imapd dpkg -P dovecot-core apt-get -yq install dovecot-imapd if [ ! -d /etc/dovecot ]; then echo $"ERROR: Dovecot does not appear to have installed. $CHECK_MESSAGE" exit 48 fi if [[ $ONION_ONLY == 'no' ]]; then # obtain a cert for the default domain if [[ "$(cert_exists ${DEFAULT_DOMAIN_NAME} pem)" == "0" ]]; then echo $'Obtaining certificate for the main domain' create_site_certificate ${DEFAULT_DOMAIN_NAME} 'yes' fi else ${PROJECT_NAME}-addcert -h dovecot --dhkey $DH_KEYLENGTH check_certificates dovecot fi if [[ "$(cert_exists ${DEFAULT_DOMAIN_NAME} pem)" == "0" ]]; then if [[ "$(cert_exists dovecot)" == "0" ]]; then ${PROJECT_NAME}-addcert -h dovecot --dhkey $DH_KEYLENGTH check_certificates dovecot fi fi chmod 600 /etc/shadow chmod 600 /etc/gshadow groupadd default usermod -g default dovecot chmod 0000 /etc/shadow chmod 0000 /etc/gshadow chown root:default /etc/ssl/certs/dovecot.* chown root:default /etc/ssl/private/dovecot.* chown root:default /etc/ssl/certs/${DEFAULT_DOMAIN_NAME}.* chown root:default /etc/ssl/private/${DEFAULT_DOMAIN_NAME}.* if [ ! -f /etc/dovecot/conf.d/10-ssl.conf ]; then echo $'Unable to find /etc/dovecot/conf.d/10-ssl.conf' exit 83629 fi sed -i 's|#ssl =.*|ssl = required|g' /etc/dovecot/conf.d/10-ssl.conf sed -i 's|ssl =.*|ssl = required|g' /etc/dovecot/conf.d/10-ssl.conf if [[ $ONION_ONLY == 'no' ]]; then if [[ "$(cert_exists ${DEFAULT_DOMAIN_NAME} pem)" == "1" ]]; then sed -i "s|#ssl_cert =.*|ssl_cert = > /etc/dovecot/conf.d/10-ssl.conf if [ ! -f /etc/dovecot/conf.d/10-master.conf ]; then echo $'Unable to find /etc/dovecot/conf.d/10-master.conf' exit 49259 fi sed -i 's/#process_limit =.*/process_limit = 100/g' /etc/dovecot/conf.d/10-master.conf if [ ! -f /etc/dovecot/conf.d/10-logging.conf ]; then echo $'Unable to find /etc/dovecot/conf.d/10-logging.conf' exit 48936 fi sed -i 's/#auth_verbose.*/auth_verbose = yes/g' /etc/dovecot/conf.d/10-logging.conf if [ ! -f /etc/dovecot/dovecot.conf ]; then echo $'Unable to find /etc/dovecot/dovecot.conf' exit 43890 fi sed -i 's/#listen =.*/listen = */g' /etc/dovecot/dovecot.conf if [ ! -f /etc/dovecot/conf.d/10-auth.conf ]; then echo $'Unable to find /etc/dovecot/conf.d/10-auth.conf' exit 843256 fi sed -i 's/#disable_plaintext_auth =.*/disable_plaintext_auth = no/g' /etc/dovecot/conf.d/10-auth.conf sed -i 's/auth_mechanisms =.*/auth_mechanisms = plain login/g' /etc/dovecot/conf.d/10-auth.conf if [ ! -f /etc/dovecot/conf.d/10-mail.conf ]; then echo $'Unable to find /etc/dovecot/conf.d/10-mail.conf' exit 42036 fi sed -i 's|mail_location =.*|mail_location = maildir:~/Maildir:LAYOUT=fs|g' /etc/dovecot/conf.d/10-mail.conf # This long notify interval makes the system more suited for use with # battery powered mobile devices sed -i 's|#imap_idle_notify_interval =.*|imap_idle_notify_interval = 29|g' /etc/dovecot/conf.d/20-imap.conf if [ -f /var/lib/dovecot/ssl-parameters.dat ]; then rm /var/lib/dovecot/ssl-parameters.dat fi if [ -f /etc/systemd/system/sockets.target.wants/dovecot.socket ]; then rm /etc/systemd/system/sockets.target.wants/dovecot.socket fi # Separate logging, otherwise syslog is used if ! grep "# logging" /etc/dovecot/dovecot.conf; then echo '' >> /etc/dovecot/dovecot.conf echo '# logging' >> /etc/dovecot/dovecot.conf echo 'log_path = /var/log/dovecot.log' >> /etc/dovecot/dovecot.conf echo 'info_log_path = /var/log/dovecot-info.log' >> /etc/dovecot/dovecot.conf echo 'debug_log_path = /var/log/dovecot-debug.log' >> /etc/dovecot/dovecot.conf fi systemctl restart dovecot mark_completed $FUNCNAME } function configure_imap_client_certs { if [ ! -d /etc/exim4 ]; then return fi if [[ $(is_completed $FUNCNAME) == "1" ]]; then return fi # http://strange.systems/certificate-based-auth-with-dovecot-sendmail/ sed -i 's|#default_process_limit =.*|default_process_limit = 100|g' /etc/dovecot/conf.d/10-master.conf sed -i 's/disable_plaintext_auth =.*/disable_plaintext_auth = yes/g' /etc/dovecot/conf.d/10-auth.conf sed -i 's|#auth_ssl_require_client_cert =.*|auth_ssl_require_client_cert = yes|g' /etc/dovecot/conf.d/10-auth.conf sed -i 's|#auth_ssl_username_from_cert =.*|auth_ssl_username_from_cert = yes|g' /etc/dovecot/conf.d/10-auth.conf sed -i "s|#ssl_ca =.*|ssl_ca = /etc/ssl/certs/ca-$DEFAULT_DOMAIN_NAME.crt|g" /etc/dovecot/conf.d/10-ssl.conf sed -i 's|#ssl_cert_username_field =.*|ssl_cert_username_field = commonName|g' /etc/dovecot/conf.d/10-ssl.conf sed -i 's|#ssl_verify_client_cert =.*|ssl_verify_client_cert = yes|g' /etc/dovecot/conf.d/10-ssl.conf if ! grep -q "passdb {" /etc/dovecot/conf.d/10-auth.conf; then echo '' >> /etc/dovecot/conf.d/10-auth.conf echo 'passdb {' >> /etc/dovecot/conf.d/10-auth.conf echo ' driver = passwd-file' >> /etc/dovecot/conf.d/10-auth.conf echo ' args = /etc/dovecot/passwd-file' >> /etc/dovecot/conf.d/10-auth.conf echo ' deny = no' >> /etc/dovecot/conf.d/10-auth.conf echo ' master = no' >> /etc/dovecot/conf.d/10-auth.conf echo ' pass = no' >> /etc/dovecot/conf.d/10-auth.conf echo '}' >> /etc/dovecot/conf.d/10-auth.conf fi if [[ $ONION_ONLY == "no" ]]; then # make a CA cert if [ ! -f /etc/ssl/private/ca-$DEFAULT_DOMAIN_NAME.key ]; then if [[ $LETSENCRYPT_ENABLED != "yes" ]]; then ${PROJECT_NAME}-addcert -h $DEFAULT_DOMAIN_NAME --ca "" --dhkey $DH_KEYLENGTH else ${PROJECT_NAME}-addcert -e $DEFAULT_DOMAIN_NAME -s $LETSENCRYPT_SERVER --ca "" --dhkey $DH_KEYLENGTH --email $MY_EMAIL_ADDRESS fi fi fi # CA configuration echo '[ ca ]' > /etc/ssl/dovecot-ca.cnf echo "default_ca = dovecot-ca" >> /etc/ssl/dovecot-ca.cnf echo '' >> /etc/ssl/dovecot-ca.cnf echo '[ crl_ext ]' >> /etc/ssl/dovecot-ca.cnf echo 'authorityKeyIdentifier=keyid:always' >> /etc/ssl/dovecot-ca.cnf echo '' >> /etc/ssl/dovecot-ca.cnf echo '[ dovecot-ca ]' >> /etc/ssl/dovecot-ca.cnf echo 'new_certs_dir = .' >> /etc/ssl/dovecot-ca.cnf echo 'unique_subject = no' >> /etc/ssl/dovecot-ca.cnf echo "certificate = /etc/ssl/certs/ca-$DEFAULT_DOMAIN_NAME.crt" >> /etc/ssl/dovecot-ca.cnf echo 'database = ssldb' >> /etc/ssl/dovecot-ca.cnf echo "private_key = /etc/ssl/private/ca-$DEFAULT_DOMAIN_NAME.key" >> /etc/ssl/dovecot-ca.cnf echo 'serial = sslserial' >> /etc/ssl/dovecot-ca.cnf echo 'default_days = 3650' >> /etc/ssl/dovecot-ca.cnf echo 'default_md = sha256' >> /etc/ssl/dovecot-ca.cnf echo 'default_bits = 4096' >> /etc/ssl/dovecot-ca.cnf echo 'policy = dovecot-ca_policy' >> /etc/ssl/dovecot-ca.cnf echo 'x509_extensions = dovecot-ca_extensions' >> /etc/ssl/dovecot-ca.cnf echo '' >> /etc/ssl/dovecot-ca.cnf echo '[ dovecot-ca_policy ]' >> /etc/ssl/dovecot-ca.cnf echo 'commonName = supplied' >> /etc/ssl/dovecot-ca.cnf echo 'stateOrProvinceName = supplied' >> /etc/ssl/dovecot-ca.cnf echo 'countryName = supplied' >> /etc/ssl/dovecot-ca.cnf echo 'emailAddress = optional' >> /etc/ssl/dovecot-ca.cnf echo 'organizationName = supplied' >> /etc/ssl/dovecot-ca.cnf echo 'organizationalUnitName = optional' >> /etc/ssl/dovecot-ca.cnf echo '' >> /etc/ssl/dovecot-ca.cnf echo '[ dovecot-ca_extensions ]' >> /etc/ssl/dovecot-ca.cnf echo 'basicConstraints = CA:false' >> /etc/ssl/dovecot-ca.cnf echo 'subjectKeyIdentifier = hash' >> /etc/ssl/dovecot-ca.cnf echo 'authorityKeyIdentifier = keyid:always' >> /etc/ssl/dovecot-ca.cnf echo 'keyUsage = digitalSignature,keyEncipherment' >> /etc/ssl/dovecot-ca.cnf echo 'extendedKeyUsage = clientAuth' >> /etc/ssl/dovecot-ca.cnf if [ -f /etc/ssl/ssldb ]; then rm /etc/ssl/ssldb fi if [ -f /etc/ssl/sslserial ]; then rm /etc/ssl/sslserial fi touch /etc/ssl/ssldb echo 0001 > /etc/ssl/sslserial #${PROJECT_NAME}-clientcert -u $MY_USERNAME systemctl restart dovecot mark_completed $FUNCNAME } function create_gpg_subkey { # Note: currently not used if [ ! -d /etc/exim4 ]; then return fi if [[ $(is_completed $FUNCNAME) == "1" ]]; then return fi apt-get -yq install gnupg GPG_KEY_USAGE=$1 if [[ $GPG_KEY_USAGE != "sign" && $GPG_KEY_USAGE != "auth" && $GPG_KEY_USAGE != "encrypt" ]]; then echo $"Unknown subkey usage: $GPG_KEY_USAGE" echo $'Available types: sign|auth|encrypt' exit 14783 fi KEYGRIP=$(gpg --fingerprint --fingerprint $MY_EMAIL_ADDRESS | grep fingerprint | tail -1 | cut -d= -f2 | sed -e 's/ //g') # Generate a GPG subkey # Here a 2048bit length is used to be compatible with yubikey echo 'Key-Type: 1' > /home/$MY_USERNAME/gpg-genkey.conf echo "Key-Grip: $KEYGRIP" > /home/$MY_USERNAME/gpg-genkey.conf echo 'Subkey-Type: 1' >> /home/$MY_USERNAME/gpg-genkey.conf echo 'Subkey-Length: 2048' >> /home/$MY_USERNAME/gpg-genkey.conf echo "subkey-Usage: $GPG_KEY_USAGE" > /home/$MY_USERNAME/gpg-genkey.conf echo "Name-Real: $MY_NAME" >> /home/$MY_USERNAME/gpg-genkey.conf echo "Name-Email: $MY_EMAIL_ADDRESS" >> /home/$MY_USERNAME/gpg-genkey.conf echo "Name-Comment: $GPG_KEY_USAGE" >> /home/$MY_USERNAME/gpg-genkey.conf echo 'Expire-Date: 0' >> /home/$MY_USERNAME/gpg-genkey.conf echo "Passphrase: $PROJECT_NAME" >> /home/$MY_USERNAME/gpg-genkey.conf chown $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/gpg-genkey.conf su -m root -c "gpg --homedir /home/$MY_USERNAME/.gnupg --batch --full-gen-key /home/$MY_USERNAME/gpg-genkey.conf" - $MY_USERNAME chown -R $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/.gnupg shred -zu /home/$MY_USERNAME/gpg-genkey.conf MY_GPG_SUBKEY_ID=$(gpg_pubkey_from_email "$MY_USERNAME" "$MY_EMAIL_ADDRESS") mark_completed $FUNCNAME } function gpg_key_exists { key_owner_username=$1 key_search_text=$2 if [[ $key_owner_username != "root" ]]; then KEY_EXISTS=$(su -c "gpg --list-keys \"${key_search_text}\"" - $key_owner_username) else KEY_EXISTS=$(gpg --list-keys "${key_search_text}") fi if [ ! "$KEY_EXISTS" ]; then echo "no" return fi if [ "$KEY_EXISTS" == *"error"* ]; then echo "no" return fi echo "yes" } function configure_gpg { if [ ! -d /etc/exim4 ]; then return fi if [[ $(is_completed $FUNCNAME) == "1" ]]; then return fi apt-get -yq install gnupg check_email_address_exists gpg_dir=/home/$MY_USERNAME/.gnupg # if gpg keys directory was previously imported from usb if [[ $GPG_KEYS_IMPORTED == "yes" && -d $gpg_dir ]]; then echo $'GPG keys were imported' sed -i "s|keyserver hkp://keys.gnupg.net|keyserver $GPG_KEYSERVER|g" $gpg_dir/gpg.conf MY_GPG_PUBLIC_KEY_ID=$(gpg_pubkey_from_email "$MY_USERNAME" "$MY_EMAIL_ADDRESS") if [ ${#MY_GPG_PUBLIC_KEY_ID} -lt 4 ]; then echo $'GPG public key ID could not be obtained' fi chown -R $MY_USERNAME:$MY_USERNAME $gpg_dir chmod 700 $gpg_dir chmod 600 $gpg_dir/* mark_completed $FUNCNAME return fi if [ ! -d $gpg_dir ]; then mkdir $gpg_dir echo "keyserver $GPG_KEYSERVER" >> $gpg_dir/gpg.conf echo 'keyserver-options auto-key-retrieve' >> $gpg_dir/gpg.conf fi sed -i "s|keyserver hkp://keys.gnupg.net|keyserver $GPG_KEYSERVER|g" $gpg_dir/gpg.conf if ! grep -q "# default preferences" $gpg_dir/gpg.conf; then echo '' >> $gpg_dir/gpg.conf echo '# default preferences' >> $gpg_dir/gpg.conf echo 'personal-digest-preferences SHA256' >> $gpg_dir/gpg.conf echo 'cert-digest-algo SHA256' >> $gpg_dir/gpg.conf echo 'default-preference-list SHA512 SHA384 SHA256 SHA224 AES256 AES192 AES CAST5 ZLIB BZIP2 ZIP Uncompressed' >> $gpg_dir/gpg.conf fi chown -R $MY_USERNAME:$MY_USERNAME $gpg_dir chmod 700 $gpg_dir chmod 600 $gpg_dir/* if [[ $MY_GPG_PUBLIC_KEY && $MY_GPG_PRIVATE_KEY ]]; then echo $'Importing GPG keys from file' echo $"Public key: $MY_GPG_PUBLIC_KEY" echo $"Private key: $MY_GPG_PRIVATE_KEY" # use your existing GPG keys which were exported if [ ! -f $MY_GPG_PUBLIC_KEY ]; then echo $"GPG public key file $MY_GPG_PUBLIC_KEY was not found" exit 2483 fi if [ ! -f $MY_GPG_PRIVATE_KEY ]; then echo $"GPG private key file $MY_GPG_PRIVATE_KEY was not found" exit 5383 fi su -c "gpg --import $MY_GPG_PUBLIC_KEY" - $MY_USERNAME su -c "gpg --allow-secret-key-import --import $MY_GPG_PRIVATE_KEY" - $MY_USERNAME KEY_EXISTS=$(gpg_key_exists "$MY_USERNAME" "$MY_EMAIL_ADDRESS") if [[ $KEY_EXISTS == "no" ]]; then echo $"The GPG key for $MY_EMAIL_ADDRESS could not be imported" exit 13821 fi # for security ensure that the private key file doesn't linger around shred -zu $MY_GPG_PRIVATE_KEY MY_GPG_PUBLIC_KEY_ID=$(gpg_pubkey_from_email "$MY_USERNAME" "$MY_EMAIL_ADDRESS") if [ ${#MY_GPG_PUBLIC_KEY_ID} -lt 4 ]; then echo $'GPG public key ID could not be obtained' fi else # Generate a GPG key echo 'Key-Type: 1' > /home/$MY_USERNAME/gpg-genkey.conf echo 'Key-Length: 4096' >> /home/$MY_USERNAME/gpg-genkey.conf echo 'Subkey-Type: 1' >> /home/$MY_USERNAME/gpg-genkey.conf echo 'Subkey-Length: 4096' >> /home/$MY_USERNAME/gpg-genkey.conf echo "Name-Real: $MY_NAME" >> /home/$MY_USERNAME/gpg-genkey.conf echo "Name-Email: $MY_EMAIL_ADDRESS" >> /home/$MY_USERNAME/gpg-genkey.conf echo 'Expire-Date: 0' >> /home/$MY_USERNAME/gpg-genkey.conf if [ -f $IMAGE_PASSWORD_FILE ]; then echo "Passphrase: $(printf `cat $IMAGE_PASSWORD_FILE`)" >> /home/$MY_USERNAME/gpg-genkey.conf else echo "Passphrase: $PROJECT_NAME" >> /home/$MY_USERNAME/gpg-genkey.conf fi chown $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/gpg-genkey.conf echo $'Generating a new GPG key' su -m root -c "gpg --homedir /home/$MY_USERNAME/.gnupg --batch --full-gen-key /home/$MY_USERNAME/gpg-genkey.conf" - $MY_USERNAME chown -R $MY_USERNAME:$MY_USERNAME /home/$MY_USERNAME/.gnupg KEY_EXISTS=$(gpg_key_exists "$MY_USERNAME" "$MY_EMAIL_ADDRESS") if [[ $KEY_EXISTS == "no" ]]; then echo $"A GPG key for $MY_EMAIL_ADDRESS could not be created" exit 6362 fi shred -zu /home/$MY_USERNAME/gpg-genkey.conf MY_GPG_PUBLIC_KEY_ID=$(gpg_pubkey_from_email "$MY_USERNAME" "$MY_EMAIL_ADDRESS") if [ ${#MY_GPG_PUBLIC_KEY_ID} -lt 4 ]; then echo $'GPG public key ID could not be obtained' fi MY_GPG_PUBLIC_KEY=/tmp/public_key.gpg su -m root -c "gpg --homedir /home/$MY_USERNAME/.gnupg --output $MY_GPG_PUBLIC_KEY --armor --export $MY_GPG_PUBLIC_KEY_ID" - $MY_USERNAME fi if [ ! -d /root/.gnupg ]; then cp -r /home/$MY_USERNAME/.gnupg /root/ fi gpg_agent_setup root gpg_agent_setup $MY_USERNAME mark_completed $FUNCNAME } function refresh_gpg_keys { REFRESH_GPG_KEYS_SCRIPT=/usr/bin/update-gpg-keys echo '#!/bin/bash' > $REFRESH_GPG_KEYS_SCRIPT echo "if [ -f /usr/local/bin/${PROJECT_NAME}-sec ]; then" >> $REFRESH_GPG_KEYS_SCRIPT echo " /usr/bin/timeout 600 /usr/local/bin/${PROJECT_NAME}-sec --refresh yes" >> $REFRESH_GPG_KEYS_SCRIPT echo 'else' >> $REFRESH_GPG_KEYS_SCRIPT echo " /usr/bin/timeout 600 /usr/bin/${PROJECT_NAME}-sec --refresh yes" >> $REFRESH_GPG_KEYS_SCRIPT echo 'fi' >> $REFRESH_GPG_KEYS_SCRIPT echo 'exit 0' >> $REFRESH_GPG_KEYS_SCRIPT chmod +x $REFRESH_GPG_KEYS_SCRIPT if grep -q "${PROJECT_NAME}-sec" /etc/crontab; then sed -i "/${PROJECT_NAME}-sec /d" /etc/crontab fi if ! grep -q "$REFRESH_GPG_KEYS_SCRIPT" /etc/crontab; then GPG_REFRESH_TIME=$(( RANDOM % 60 )) echo "$GPG_REFRESH_TIME */$REFRESH_GPG_KEYS_HOURS * * * root cronic $REFRESH_GPG_KEYS_SCRIPT" >> /etc/crontab systemctl restart cron else sed -i "s|root $REFRESH_GPG_KEYS_SCRIPT.*|root cronic $REFRESH_GPG_KEYS_SCRIPT|g" /etc/crontab fi } function install_email { if [[ $SYSTEM_TYPE == "mesh"* ]]; then return fi if [[ $(is_completed $FUNCNAME) == "1" ]]; then return fi check_email_address_exists install_email_basic configure_email_onion #install_email_with_tor mark_completed $FUNCNAME } # NOTE: deliberately no exit 0