From 12870d71e5e6b05687c31840a49f577e6ec225dc Mon Sep 17 00:00:00 2001 From: Christoph Date: Thu, 6 Aug 2020 01:20:43 +0200 Subject: [PATCH] Redesign of script 'sent_userinfo_postfix.sh'. --- .gitignore | 2 +- ...l.sample => Heartbleed-Bug_userinfo.email} | 5 + conf/sent_userinfo_postfix.conf.sample | 20 +- files/sent_userinfo_postfix.message | 44 ++++ files/sent_userinfo_postfix.subject | 1 + sent_userinfo_postfix.sh | 242 +++++++++++++++--- 6 files changed, 273 insertions(+), 41 deletions(-) rename conf/{sent_userinfo_postfix.email.sample => Heartbleed-Bug_userinfo.email} (93%) create mode 100644 files/sent_userinfo_postfix.message create mode 100644 files/sent_userinfo_postfix.subject diff --git a/.gitignore b/.gitignore index 9d64a31..b37f0fc 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ *.swp *.log conf/*.conf -conf/*.email* +conf/*.message* conf/*.lst* log/* !conf/sent_userinfo_postfix.email.sample diff --git a/conf/sent_userinfo_postfix.email.sample b/conf/Heartbleed-Bug_userinfo.email similarity index 93% rename from conf/sent_userinfo_postfix.email.sample rename to conf/Heartbleed-Bug_userinfo.email index bf73497..9ca8d0c 100644 --- a/conf/sent_userinfo_postfix.email.sample +++ b/conf/Heartbleed-Bug_userinfo.email @@ -3,6 +3,11 @@ From: %email_from_org% <%email_from%> Subject: Heartbleed Bug und so36.net Content-type: text/plain; charset=UTF-8 +Leider ist unsere Rundmail von eben nur bruchstückhaft bei Euch angekommen. +Deshalb hier nochmals in voller Länge.. + +--- + Liebe so36-Nutzer_innen, Am Dienstag 08.04.2014 ist eine gravierende Sicherheitslücke in der diff --git a/conf/sent_userinfo_postfix.conf.sample b/conf/sent_userinfo_postfix.conf.sample index 79f40e2..9c90095 100644 --- a/conf/sent_userinfo_postfix.conf.sample +++ b/conf/sent_userinfo_postfix.conf.sample @@ -4,16 +4,17 @@ # --- # ---------------------------------------------------- -# - user_info_file +# - message_body_file # - -# - Full path to file containing the user info. If file is placed in this -# - configuration directory use '${conf_dir}/' # - # - See sent_userinfo_postfix.email.sample # - -# - Defaults to '${conf_dir}/conf/sent_userinfo_postfix.email' +# - Defaults to '${conf_dir}/sent_userinfo_postfix.email' # - -#user_info_file="${conf_dir}/conf/sent_userinfo_postfix.email" +#message_body_file="${conf_dir}/sent_userinfo_postfix.email" # - email_from @@ -68,15 +69,18 @@ email_from_org="" # - # - The owner of the mailbox directories and within the e-mails itself. # - -# - defaults to 'vmail' -#mail_user=vmail +# - defaults to mail_user="vmail" +# - +#mail_user="vmail" # - mail_group # - # - The group of the mailbox directories # - -#mail_group=vmail +# - defaults to mail_group="vmail" +# - +#mail_group="vmail" # - mail_basedir - No more needed! diff --git a/files/sent_userinfo_postfix.message b/files/sent_userinfo_postfix.message new file mode 100644 index 0000000..417d9a2 --- /dev/null +++ b/files/sent_userinfo_postfix.message @@ -0,0 +1,44 @@ +---------------------------------------------------------------------- +DE: so36.net löscht ab Dez. 2020 alte, ungenutzte Mail-Accounts +EN: so36.net will delete old, unused email-accounts starting Dec. 2020 +---------------------------------------------------------------------- + +- English version follows - + +Hallo, + +ab Dezember 2020 werden wir damit beginnen, alte, ungenutzte Mail-Accounts von unseren Servern zu löschen. Betroffen sind davon alle Accounts, bei denen sich seit über einem Jahr niemand mehr per Webmail, POP3 oder IMAP eingeloggt hat. + +Neben @mail36.net und @so36.net sind davon auch alle anderen Mail-Domains betroffen, die bei uns gehostet werden. + +Solltet Ihr Accounts nutzen, die auch ohne regelmäßiges Login funktionieren (zB Weiterleitungen, nur Versand), kontaktiert uns bitte, damit wir die entsprechenden Adressen auf eine "nicht-löschen"-Liste setzen können. + +Im Zeitalter der Terabyte-Festplatten ist unsere Motivation hinter der neuen Praxis nicht, Speicherplatz einzusparen. Uns geht es um den Datenschutz. Private Mails an verwaiste Adressen müssen nicht bis in alle Ewigkeit auf unseren Servern rumliegen. + +Gelöschte Adressen bleiben bis auf weiteres gesperrt. Sie werden also nach dem Löschen erst mal nicht wieder neu vergeben. + +Wenn Ihr Feedback habt, oder Accounts von der automatischen Löschung nach einem Jahr ausschließen wollt, meldet Euch gerne per Mail bei uns. support[ät]so36.net + +----------------------- +Grüße vom Team so36.net +----------------------- + + +Hi, + +starting December 2020 we will be deleting old, unused mail-accounts from our servers. All accounts whose owners have not logged in via webmail, POP3 or IMAP for more than one year are affected. + +This applies not only to @mail36.net and @so36.net accounts, but also to all other mail-domains hosted with us. + +If you are actively using an account without ever logging in (e.g. mail-forwarding, send-only), please contact us. We will put your account on our "do-not-delete"-list. + +In the age of terabyte-harddrives we do not change our policy to save storage space. For us it's about privacy. We don't want private mails to abandoned accounts lying around on our servers for years and years. + +Deleted accounts will stay locked until further notice. After deletion they will not become available for other users again. + +If you have any feedback or want to protect you account from automated deletion, please contact us via email. support[ät]so36.net + +------------- +All the best +Team so36.net +------------- diff --git a/files/sent_userinfo_postfix.subject b/files/sent_userinfo_postfix.subject new file mode 100644 index 0000000..49de4a4 --- /dev/null +++ b/files/sent_userinfo_postfix.subject @@ -0,0 +1 @@ +Löschung unbenutzer E-Mail Accounts / Delete unused e-mail accounts diff --git a/sent_userinfo_postfix.sh b/sent_userinfo_postfix.sh index 69ac737..eaaa30d 100755 --- a/sent_userinfo_postfix.sh +++ b/sent_userinfo_postfix.sh @@ -1,11 +1,15 @@ #!/usr/bin/env bash -script_dir="$(dirname $(realpath $0))" -conf_dir="${script_dir}/conf" -conf_file="${conf_dir}/sent_userinfo_postfix.conf" +script_name="$(basename $(realpath $0))" +working_dir="$(dirname $(realpath $0))" +file_dir="${working_dir}/files" +conf_dir="${working_dir}/conf" +log_dir="${working_dir}/log" -tmp_dir="$(mktemp -d)" -logfile="${script_dir}/log/sent_userinfo_postfix.$(date +%Y-%m-%d-%H%M).log" +conf_file="${conf_dir}/sent_userinfo_postfix.conf" +logfile="${working_dir}/log/sent_userinfo_postfix.$(date +%Y-%m-%d-%H%M).log" + +LOCK_DIR="/tmp/$(basename $0).$$.LOCK" #--------------------------------------- #----------------------------- @@ -13,12 +17,16 @@ logfile="${script_dir}/log/sent_userinfo_postfix.$(date +%Y-%m-%d-%H%M).log" #----------------------------- #--------------------------------------- -DEFAULT_user_info_file="${conf_dir}/sent_userinfo_postfix.email" +DEFAULT_message_body_file="${file_dir}/sent_userinfo_postfix.message" DEFAULT_db_type="pgsql" DEFAULT_db_name="postfix" DEFAULT_mail_user="vmail" DEFAULT_mail_group="vmail" +if [[ -f "${file_dir}/sent_userinfo_postfix.subject" ]]; then + DEFAULT_email_subject="$(cat "${file_dir}/sent_userinfo_postfix.subject" | head -1)" +fi + #--------------------------------------- #----------------------------- @@ -29,9 +37,10 @@ DEFAULT_mail_group="vmail" clean_up() { # Perform program exit housekeeping - rm -rf $tmp_dir + rm -rf $LOCK_DIR exit $1 } + echononl(){ echo X\\c > /tmp/shprompt$$ if [ `wc -c /tmp/shprompt$$ | awk '{print $1}'` -eq 1 ]; then @@ -59,6 +68,9 @@ fatal(){ echo_ok() { echo -e "\033[75G[ \033[32mok\033[m ]" } +echo_done() { + echo -e "\033[75G[ \033[32mdone\033[m ]" +} echo_failed() { echo -e "\033[75G[ \033[1;31mfailed\033[m ]" } @@ -66,12 +78,36 @@ echo_skipped() { echo -e "\033[75G[ \033[33m\033[1mskipped\033[m ]" } + +# ---------- +# - Jobhandling +# ---------- + +# - Run 'clean_up' for signals SIGHUP SIGINT SIGTERM +# - trap clean_up SIGHUP SIGINT SIGTERM +# - Create lock directory '$LOCK_DIR" +# +mkdir "$LOCK_DIR" + + +# ---------- +# - Main part of script +# ---------- + clear echo "" -echo -e "\033[32mRunning script \033[1m"$(basename $0)"\033[m .." echo "" +echo -e "\033[1m----------\033[m" +echo -e "\033[32m\033[1mRunning script \033[m\033[1m$script_name\033[32m .. \033[m" +echo -e "\033[1m----------\033[m" +echo "" + + +# ---------- +# - Read Configuration file +# ---------- echo "" echo "" @@ -87,15 +123,19 @@ else fi fi -if [[ -z "$email_from" ]] ; then - fatal "Missing Mail Sender Address (parameter 'email_from')." + + +if [[ -n "$email_from" ]] ; then + DEFAULT_email_from="$email_from" fi -if [[ -z "$email_from_org" ]] ; then - fatal "Missing Mail Sender Organisation (parameter 'email_from_org')." +if [[ -n "$email_from_org" ]] ; then + DEFAULT_email_from_org="$email_from_org" fi -[[ -n "$user_info_file" ]] || user_info_file="$DEFAULT_user_info_file" +if [[ -n "$message_body_file" ]] ; then + $DEFAULT_message_body_file="$message_body_file" +fi [[ -n "$db_type" ]] || db_type="$DEFAULT_db_type" if [[ "$db_type" != "pgsql" ]] && [[ "$db_type" != "mysql" ]]; then @@ -119,10 +159,6 @@ fi [[ -n "$mail_user" ]] || mail_user="$DEFAULT_mail_user" [[ -n "$mail_group" ]] || mail_group="$DEFAULT_mail_group" -if [[ ! -f $user_info_file ]];then - fatal "User Info-file to send '$user_info_file' does not exist !!" -fi - echo "" echo -e "\033[32m--\033[m" @@ -134,7 +170,7 @@ _TEST_RUN= while [ "$_TEST_RUN" != "yes" -o "$_TEST_RUN" != "no" ] ; do echononl "\033[1mTest run? [yes/no]:\033[m " read _TEST_RUN - ## - To lower case + # - To lower case _TEST_RUN=${_TEST_RUN,,} if [ "X$_TEST_RUN" = "X" ]; then echo -e "\n\t\033[33m\033[1mAn entry is required! Type 'yes' or 'no'\033[m.\n" @@ -171,12 +207,131 @@ if $TEST_RUN ; then done fi +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Give the Sender E-Mail for the user info." +echo "" +echo "" +email_from="" +if [[ -n "$DEFAULT_email_from" ]]; then + echononl "Sender E-Mail [$DEFAULT_email_from]: " + read email_from + # - To lower case + email_from=${email_from,,} + if [[ "X$email_from" = "X" ]] ; then + email_from="$DEFAULT_email_from" + fi +else + while [ "X$email_from" = "X" ]; do + echononl "Sender E-Mail: " + read email_from + # - To lower case + email_from=${email_from,,} + if [ "X$email_from" = "X" ]; then + echo "" + echo -e "\n\t\033[33m\033[1m'Sender E-Mail' is required!\033[m\n" + continue + fi + done +fi + +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Give the Sender Organisation or the Sender Name." +echo "" +echo "" +email_from_org="" +if [[ -n "$DEFAULT_email_from_org" ]]; then + echononl "Sender Organisation/Name [$DEFAULT_email_from_org]: " + read email_from_org + if [[ "X$email_from_org" = "X" ]] ; then + email_from_org="$DEFAULT_email_from_org" + fi +else + while [ "X$email_from_org" = "X" ]; do + echononl "Sender Organisation/Name: " + read email_from_org + if [ "X$email_from_org" = "X" ]; then + echo "" + echo -e "\n\t\033[33m\033[1m'Sender Organisation/Name' is required!\033[m\n" + continue + fi + done +fi + +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Give the Subject of the user info e-mail." +echo "" +echo "" +email_subject="" +if [[ -n "$DEFAULT_email_subject" ]]; then + echononl "Subject [$DEFAULT_email_subject]: " + read email_subject + if [[ "X$email_subject" = "X" ]] ; then + email_subject="$DEFAULT_email_subject" + fi +else + while [ "X$email_subject" = "X" ]; do + echononl "Subject: " + read email_subject + if [ "X$email_subject" = "X" ]; then + echo "" + echo -e "\n\t\033[33m\033[1m'Subject' is required!\033[m\n" + continue + fi + done +fi + +echo "" +echo -e "\033[32m--\033[m" +echo "" +echo "Give the path to the file containing message (body) of the info e-mail." +echo "" +echo "" +message_body_file="" +if [[ -n "$DEFAULT_message_body_file" ]]; then + echononl "Path to message file [$DEFAULT_message_body_file]: " + read message_body_file + if [[ "X$message_body_file" = "X" ]] ; then + message_body_file="$DEFAULT_message_body_file" + fi +else + while [ "X$message_body_file" = "X" ]; do + echononl "Path to message file: " + read message_body_file + if [ "X$message_body_file" = "X" ]; then + echo "" + echo -e "\n\t\033[33m\033[1m'Path to message file' is required!\033[m\n" + continue + fi + done +fi + + + +if [[ -z "$email_from" ]] ; then + fatal "Missing Mail Sender Address (parameter 'email_from')." +fi +if [[ -z "$email_from_org" ]] ; then + fatal "Missing Mail Sender Organisation (parameter 'email_from_org')." +fi +if [[ -z "$email_subject" ]] ; then + fatal "Missing Subject (parameter 'email_subject')." +fi +if [[ ! -f $message_body_file ]];then + fatal "User Info-file to send '$message_body_file' does not exist !!" +fi + echo "" echo "" echo -e "\033[32mSettings for script \033[37m\033[1msent_userinfo_postfix.sh\033[m" echo "" -echo " File containing the mail-body.........: $user_info_file" +echo " File containing the mail-body.........: $message_body_file" echo "" if [[ "$db_type" = "pgsql" ]] ; then echo " Type of postfix databae...............: PostgreSQL ($db_type)" @@ -189,6 +344,7 @@ fi echo "" echo " Mail Sender Address...................: $email_from" echo " Mail Sender Organisation..............: $email_from_org" +echo " Subject of the userinfo e-mail........: $email_subject" echo "" echo " Mail User.............................: $mail_user" echo " Mail Group............................: $mail_group" @@ -239,22 +395,38 @@ fi curdir=`pwd` -rc_done="\033[71G[ \033[32mdone\033[m ]" -rc_failed="\033[71G[ \033[31m\033[1mfailed\033[m ]" -if [ ! -f $user_info_file ]; then +if [ ! -f $message_body_file ]; then fatal "File containing User Info not found!" fi pwd=`pwd` cd /tmp +echo "" +echo -e "\n\t --- Prepare Info E-Mail --\n" | tee -a $logfile + +cp "$message_body_file" "${LOCK_DIR}/message_tmp.txt" +echo "$email_subject" > ${LOCK_DIR}/subject_tmp.txt + +# - Convert to UTF-8 +# - +iconv -t UTF8 -o "${LOCK_DIR}/message_tmp_UTF8.txt" "${LOCK_DIR}/message_tmp.txt" +iconv -t UTF8 -o "${LOCK_DIR}/subject_tmp_UTF8.txt" "${LOCK_DIR}/subject_tmp.txt" + +# - encode base64 +# -- +ENCODED_SUBJECT="=?utf-8?B?$(cat ${LOCK_DIR}/subject_tmp_UTF8.txt | base64 --wrap=0)?=" +ENCODED_MESSAGE="$(cat ${LOCK_DIR}/message_tmp_UTF8.txt | base64)" +content_type='Content-Type: text/plain;\n charset="utf-8"' +transfer_encoding='Content-Transfer-Encoding: base64' +content_disposition='Content-Disposition: inline' + + echo "" echo -e "\n\t --- Sending userinfo into all local virtual mailboxes --\n" | tee -a $logfile - - ## - list of local virtual domains ## - if $TEST_RUN ; then @@ -299,18 +471,24 @@ for domain in $domains ;do fi for local_part in $local_parts ; do - cp "$user_info_file" "$tmp_dir" - perl -i -n -p -e "s/%email_to%/$local_part\@$domain/" "${tmp_dir}/$(basename $user_info_file)" - perl -i -n -p -e "s/%email_from%/${email_from_regex}/" "${tmp_dir}/$(basename $user_info_file)" - perl -i -n -p -e "s/%email_from_org%/${email_from_org}/" "${tmp_dir}/$(basename $user_info_file)" + echononl "\tSend userinfo to $local_part@$domain.." - cat ${tmp_dir}/$(basename $user_info_file) | /usr/sbin/sendmail -F "$email_from_org" -f $email_from -t "$local_part@$domain" + echo -e "From: ${email_from_org} <${email_from}> +To: $local_part@$domain +Subject: ${ENCODED_SUBJECT} +${content_type} +${transfer_encoding} +${content_disposition} + +$ENCODED_MESSAGE +" | /usr/sbin/sendmail -F "$email_from_org" -f $email_from -t + if [ "$?" = "0" ]; then num_mbox=num_mbox+1 - echo -e "$rc_done" + echo_done echo " [ OK ]: Send userinfo to $local_part@$domain" >> $logfile else - echo -e "$rc_failed" + echo_failed echo " [ ERROR ]: Cannot sent userinfo to \"$local_part\@$domain\"!" >> $logfile num_mbox_failed=num_mbox_failed+1 fi @@ -319,7 +497,7 @@ for domain in $domains ;do done if ! $TEST_RUN ; then - mv "$user_info_file" "${user_info_file}.SENT.$(date +%Y-%m-%d)" + mv "$message_body_file" "${message_body_file}.SENT.$(date +%Y-%m-%d)" fi echo -e "\n\n----- Statistics -----\n\n\tSent mail to $num_mbox mailboxe(s) of $num_dom domain(s)" | tee -a $logfile