#!/bin/bash # _____ _ _ # | __|___ ___ ___ _| |___ _____| |_ ___ ___ ___ # | __| _| -_| -_| . | . | | . | . | | -_| # |__| |_| |___|___|___|___|_|_|_|___|___|_|_|___| # # Freedom in the Cloud # # Brain Dead Simple Mail Server for i2p # # License # ======= # # Copyright (C) 2018 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 . VARIANTS='full full-vim' IN_DEFAULT_INSTALL=0 SHOW_ON_ABOUT=1 BDSMAIL_REPO="https://github.com/majestrate/bdsmail" BDSMAIL_COMMIT='6fae61365306ad3c1966a107aa06310ea65fb239' BDSMAIL_DIR=/etc/bdsmail I2P_SAM_PORT=7656 I2P_SMTP_PORT=2525 I2P_WEB_PORT=8489 I2P_POP3_PORT=1110 bdsmail=(MY_USERNAME) function bdsmail_configure_users { for d in /home/*/ ; do USERNAME=$(echo "$d" | awk -F '/' '{print $3}') if [[ $(is_valid_user "$USERNAME") == "1" ]]; then # Add the user to the i2p group usermod -a -G i2psvc "$USERNAME" if [ -f "/home/$USERNAME/.muttrc" ]; then # Create a mutt i2p folder if ! grep -q ' =i2p' "/home/$USERNAME/.muttrc"; then MUTT_MAILBOXES=$(grep "mailboxes =" "/home/$USERNAME/.muttrc") sed -i "s|$MUTT_MAILBOXES|$MUTT_MAILBOXES =i2p|g" "/home/$USERNAME/.muttrc" fi # Create a mutt folder hook to the i2p config if ! grep -q 'folder-hook !i2p' "/home/$USERNAME/.muttrc"; then echo 'folder-hook !i2p/* source ~/.muttrc' >> "/home/$USERNAME/.muttrc" fi if ! grep -q 'folder-hook i2p' "/home/$USERNAME/.muttrc"; then echo 'folder-hook i2p/* source ~/.mutt/bdsmail' >> "/home/$USERNAME/.muttrc" fi fi # Create a directory where i2p mail will be stored if [ ! -d "/home/$USERNAME/Maildir/i2p/new" ]; then mkdir -p "/home/$USERNAME/Maildir/i2p/cur" mkdir -p "/home/$USERNAME/Maildir/i2p/new" chown -R "$USERNAME":"$USERNAME" "/home/$USERNAME/Maildir/i2p" fi fi done } function logging_on_bdsmail { echo -n '' } function logging_off_bdsmail { echo -n '' } function remove_user_bdsmail { remove_username="$1" } function add_user_bdsmail { new_username="$1" new_user_password="$2" if [ ! -d "/home/$new_username/.mutt" ]; then mkdir "/home/$new_username/.mutt" cp /etc/skel/.mutt/bdsmail "/home/$new_username/.mutt" fi read_config_param MY_USERNAME BDSMAIL_PASSWORD=$("${PROJECT_NAME}-pass" -u "$MY_USERNAME" -a bdsmail) sed -i "s|username|$new_username|g" "/home/$new_username/.mutt/bdsmail" sed -i "s|password|$BDSMAIL_PASSWORD|g" "/home/$new_username/.mutt/bdsmail" bdsmail_configure_users cd $BDSMAIL_DIR || exit 57247684234 $BDSMAIL_DIR/bin/mailtool $BDSMAIL_DIR/config.ini "$new_username" "/home/$new_username/Maildir/i2p" "$BDSMAIL_PASSWORD" chown -R "$new_username":"$new_username" "/home/$new_username/.mutt" echo '0' } function install_interactive_bdsmail { echo -n '' APP_INSTALLED=1 } function change_password_bdsmail { curr_username="$1" new_user_password="$2" "${PROJECT_NAME}-pass" -u "$MY_USERNAME" -a bdsmail -p "$new_user_password" for d in /home/*/ ; do USERNAME=$(echo "$d" | awk -F '/' '{print $3}') if [[ $(is_valid_user "$USERNAME") == "1" ]]; then sed -i "s|set smtp_url=.*|set smtp_url=smtp://${curr_username}:${new_user_password}@127.0.0.1:$I2P_SMTP_PORT/" "/home/${USERNAME}/.mutt/bdsmail" sed -i "s|set from=.*|set from=${USERNAME}@$(bdsmail_domain)|g" "/home/${USERNAME}/.mutt/bdsmail" chown "${USERNAME}":"${USERNAME}" "/home/${USERNAME}/.mutt/bdsmail" cd $BDSMAIL_DIR || exit 2468246 $BDSMAIL_DIR/bin/mailtool $BDSMAIL_DIR/config.ini "$curr_username" "/home/$curr_username/Maildir/i2p" "$new_user_password" fi done } function bdsmail_update_domain { sed -i "s|set from=.*|set from=username@$(bdsmail_domain)|g" /etc/skel/.mutt/bdsmail for d in /home/*/ ; do USERNAME=$(echo "$d" | awk -F '/' '{print $3}') if [[ $(is_valid_user "$USERNAME") == "1" ]]; then cp /etc/skel/.mutt/bdsmail "/home/${USERNAME}/.mutt/bdsmail" sed -i "s|set from=.*|set from=${USERNAME}@$(bdsmail_domain)|g" "/home/${USERNAME}/.mutt/bdsmail" chown "${USERNAME}":"${USERNAME}" "/home/${USERNAME}/.mutt/bdsmail" fi done } function bdsmail_wait_for_key_generation { # wait for domain to be generated by the daemon # This can take a while, probably because i2p is connecting bds_domain= sleep_ctr=0 while [ ! $bds_domain ]; do echo $"Waiting for i2p domain to be generated ${sleep_ctr}/100" systemctl restart bdsmail sleep 30 bds_domain=$(bdsmail_domain) sleep_ctr=$((sleep_ctr + 1)) if [ "$sleep_ctr" -gt 100 ]; then break fi done } function reconfigure_bdsmail { systemctl stop bdsmail rm $BDSMAIL_DIR/*.dat rm $BDSMAIL_DIR/*.pem bdsmail_wait_for_key_generation if [ ! -f $BDSMAIL_DIR/bdsmail-privkey.dat ]; then return fi bdsmail_update_domain } function upgrade_bdsmail { CURR_BDSMAIL_COMMIT=$(get_completion_param "bdsmail commit") if [[ "$CURR_BDSMAIL_COMMIT" == "$BDSMAIL_COMMIT" ]]; then return fi # update to the next commit set_repo_commit $BDSMAIL_DIR "bdsmail commit" "$BDSMAIL_COMMIT" "$BDSMAIL_REPO" cd $BDSMAIL_DIR || exit 2457245 make GOROOT="/home/go/go${GO_VERSION}" chown -R i2psvc:i2psvc $BDSMAIL_DIR systemctl restart bdsmail if ! grep -q "$(bdsmail_domain)" /etc/skel/.mutt/bdsmail; then bdsmail_update_domain fi } function backup_local_bdsmail { systemctl stop bdsmail source_directory=$BDSMAIL_DIR function_check backup_directory_to_usb dest_directory=bdsmail backup_directory_to_usb $source_directory $dest_directory systemctl start bdsmail } function restore_local_bdsmail { systemctl stop bdsmail temp_restore_dir=/root/tempbdsmail bdsmail_dir=$BDSMAIL_DIR function_check restore_directory_from_usb restore_directory_from_usb $temp_restore_dir bdsmail if [ -d $temp_restore_dir ]; then if [ -d $temp_restore_dir$bdsmail_dir ]; then cp -rp $temp_restore_dir$bdsmail_dir $bdsmail_dir/ else if [ ! -d $bdsmail_dir ]; then mkdir $bdsmail_dir fi cp -rp $temp_restore_dir/* $bdsmail_dir fi chown -R i2psvc:i2psvc $bdsmail_dir rm -rf $temp_restore_dir fi systemctl start bdsmail } function backup_remote_bdsmail { systemctl stop bdsmail source_directory=$BDSMAIL_DIR function_check backup_directory_to_friend dest_directory=bdsmail backup_directory_to_friend $source_directory $dest_directory systemctl start bdsmail } function restore_remote_bdsmail { systemctl stop bdsmail temp_restore_dir=/root/tempbdsmail bdsmail_dir=$BDSMAIL_DIR function_check restore_directory_from_friend restore_directory_from_friend $temp_restore_dir bdsmail if [ -d $temp_restore_dir ]; then if [ -d $temp_restore_dir$bdsmail_dir ]; then cp -rp $temp_restore_dir$bdsmail_dir $bdsmail_dir/ else if [ ! -d $bdsmail_dir ]; then mkdir $bdsmail_dir fi cp -rp $temp_restore_dir/* $bdsmail_dir fi chown -R i2psvc:i2psvc $bdsmail_dir rm -rf $temp_restore_dir fi systemctl start bdsmail } function remove_bdsmail { if [ -f /etc/systemd/system/bdsmail.service ]; then systemctl stop bdsmail systemctl disable bdsmail rm /etc/systemd/system/bdsmail.service fi for d in /home/*/ ; do USERNAME=$(echo "$d" | awk -F '/' '{print $3}') if [[ $(is_valid_user "$USERNAME") == "1" ]]; then # remove the user from the i2p group deluser "$USERNAME" i2psvc # Remove mutt folder hook to the i2p config if [ -f "/home/$USERNAME/.muttrc" ]; then if grep -q 'folder-hook !i2p' "/home/$USERNAME/.muttrc"; then sed -i '/folder-hook !i2p/d' "/home/$USERNAME/.muttrc" fi if grep -q 'folder-hook i2p' "/home/$USERNAME/.muttrc"; then sed -i '/folder-hook i2p/d' "/home/$USERNAME/.muttrc" fi fi # Remove folder if grep -q ' =i2p' "/home/$USERNAME/.muttrc"; then sed -i 's| =i2p||g' "/home/$USERNAME/.muttrc" fi # NOTE: leave Maildir/i2p/cur. We might want to archive that # or just be reinstalling the system without losing mail rm -rf "/home/$USERNAME/Maildir/i2p/new" fi done remove_i2p remove_app bdsmail remove_completion_param install_bdsmail sed -i '/bdsmail/d' "$COMPLETION_FILE" rm -rf /etc/skel/.mutt if [ -d $BDSMAIL_DIR ]; then rm -rf $BDSMAIL_DIR fi rm /usr/bin/bdsmail_domain sed -i '/bdsmail_distribute/d' /etc/crontab rm /usr/bin/bdsmail_distribute if [ -f /etc/skel/.mutt/bdsmail ]; then rm /etc/skel/.mutt/bdsmail fi } function install_bdsmail { if [ -d $BDSMAIL_DIR ]; then remove_bdsmail fi if [ -d /repos/bdsmail ]; then mkdir $BDSMAIL_DIR cp -r -p /repos/bdsmail/. $BDSMAIL_DIR cd $BDSMAIL_DIR || exit 24687246 git pull else git_clone "$BDSMAIL_REPO" "$BDSMAIL_DIR" fi if [ ! -d $BDSMAIL_DIR ]; then echo $'Unable to clone bdsmail repo' exit 5735735 fi cd $BDSMAIL_DIR || exit 2468246 git checkout "$BDSMAIL_COMMIT" -b "$BDSMAIL_COMMIT" set_completion_param "bdsmail commit" "$BDSMAIL_COMMIT" mkdir -p $BDSMAIL_DIR/Maildir/i2p chmod -R 700 $BDSMAIL_DIR/Maildir make GOROOT="/home/go/go${GO_VERSION}" if [ ! -f $BDSMAIL_DIR/bin/bdsconfig ]; then echo $'Unable to make bdsmail' exit 87923567842 fi install_i2p i2p_enable_sam # create configuration file #$BDSMAIL_DIR/bin/bdsconfig > $BDSMAIL_DIR/config.ini { echo '[maild]': echo "i2paddr = 127.0.0.1:$I2P_SAM_PORT"; echo 'i2pkeyfile = bdsmail-privkey.dat'; echo "bindmail = 127.0.0.1:$I2P_SMTP_PORT"; echo "bindweb = 127.0.0.1:$I2P_WEB_PORT"; echo "bindpop3 = 127.0.0.1:$I2P_POP3_PORT"; echo 'domain = localhost'; echo 'maildir = Maildir/i2p'; echo 'database = localhost.sqlite'; echo 'assets = contrib/assets/web'; } > $BDSMAIL_DIR/config.ini { echo '[Unit]'; echo 'Description=bdsmail'; echo 'After=syslog.target'; echo 'After=network.target'; echo ''; echo '[Service]'; echo 'Type=simple'; echo 'User=i2psvc'; echo 'Group=i2psvc'; echo "WorkingDirectory=$BDSMAIL_DIR"; echo "ExecStart=$BDSMAIL_DIR/bin/maild $BDSMAIL_DIR/config.ini"; echo 'Restart=always'; echo 'Environment="USER=i2psvc"'; echo ''; echo '[Install]'; echo 'WantedBy=multi-user.target'; } > /etc/systemd/system/bdsmail.service { echo '#!/usr/bin/env python2'; echo 'import base64, hashlib, sys'; echo 'with open(sys.argv[1]) as f:'; echo " print(base64.b32encode(hashlib.sha256(base64.b64decode(f.read(516), '-~')).digest()).strip('=')+\".b32.i2p\")"; } > $BDSMAIL_DIR/get_address chmod +x $BDSMAIL_DIR/get_address chown -R i2psvc:i2psvc $BDSMAIL_DIR systemctl enable bdsmail systemctl start bdsmail { echo '#!/bin/bash'; echo "BDSMAIL_DIR=$BDSMAIL_DIR"; echo "MAIL_DIR=\$BDSMAIL_DIR/\$(cat \$BDSMAIL_DIR/config.ini | grep 'maildir =' | awk -F ' ' '{print \$3}')"; echo "if [ ! -d \$MAIL_DIR/postmaster/new ]; then"; echo ' exit 0'; echo 'fi'; echo "for filename in \$MAIL_DIR/postmaster/new/*; do"; echo " to_line=\$(cat \$filename | grep \"To: \" | head -n 1)"; echo " to_username=\$(echo \"\$to_line\" | awk -F ' ' '{print \$2}' | awk -F '@' '{print \$1}')"; echo " if [ -d /home/\$to_username/Maildir/i2p/new ]; then"; echo " chown \$to_username:\$to_username \$filename"; echo " chmod 600 \$filename"; echo " mv \$filename /home/\$to_username/Maildir/i2p/new"; echo ' fi'; echo 'done'; } > /usr/bin/bdsmail_distribute chmod +x /usr/bin/bdsmail_distribute if ! grep -q 'bdsmail_distribute' /etc/crontab; then cron_add_mins 1 '/usr/bin/bdsmail_distribute 2> /dev/null' fi { echo '#!/bin/bash'; echo "cd $BDSMAIL_DIR"; echo 'if [ ! -f bdsmail-privkey.dat ]; then'; echo ' exit 1'; echo 'fi'; echo "python2 get_address bdsmail-privkey.dat | tr '[:upper:]' '[:lower:]'"; } > /usr/bin/bdsmail_domain chmod +x /usr/bin/bdsmail_domain echo '' echo $'Now we will wait for i2p to connect and a private key to be generated' echo $'This may take a while.' echo '' bdsmail_wait_for_key_generation if [ ! "$bds_domain" ]; then systemctl stop bdsmail systemctl disable bdsmail remove_i2p echo $'Failed to get the bdsmail domain' exit 8934638 fi BDSMAIL_PASSWORD="$(create_password "${MINIMUM_PASSWORD_LENGTH}")" "${PROJECT_NAME}-pass" -u "$MY_USERNAME" -a bdsmail -p "$BDSMAIL_PASSWORD" cd $BDSMAIL_DIR || exit 2346872427 $BDSMAIL_DIR/bin/mailtool $BDSMAIL_DIR/config.ini admin $BDSMAIL_DIR/Maildir/i2p/admin "$BDSMAIL_PASSWORD" # Create mutt configuration if [ ! -d /etc/skel/.mutt ]; then mkdir /etc/skel/.mutt fi { echo 'set mbox_type=Maildir'; echo "set smtp_url=smtp://username:password@127.0.0.1:$I2P_SMTP_PORT/"; echo 'set use_from=yes'; echo "set from=username@${bds_domain}"; echo "set spoolfile=~/Maildir/i2p"; echo 'set pgp_autoencrypt=no'; echo 'set pgp_replyencrypt=no'; echo 'set pgp_autosign=no'; echo 'set pgp_replysign=no'; } > /etc/skel/.mutt/bdsmail # mutt configuration for the admin user if [ ! -d "/home/$MY_USERNAME/.mutt" ]; then mkdir "/home/$MY_USERNAME/.mutt" fi cp /etc/skel/.mutt/bdsmail "/home/$MY_USERNAME/.mutt" sed -i "s|username|$MY_USERNAME|g" "/home/$MY_USERNAME/.mutt/bdsmail" sed -i "s|password|$BDSMAIL_PASSWORD|g" "/home/$MY_USERNAME/.mutt/bdsmail" chown -R "$MY_USERNAME":"$MY_USERNAME" "/home/$MY_USERNAME/.mutt" bdsmail_configure_users cd $BDSMAIL_DIR || exit 2457245 $BDSMAIL_DIR/bin/mailtool $BDSMAIL_DIR/config.ini "$MY_USERNAME" "/home/$MY_USERNAME/Maildir/i2p" "$BDSMAIL_PASSWORD" APP_INSTALLED=1 } # NOTE: deliberately there is no "exit 0"