#!/bin/bash ######################################################################## # Copyright (C) 2016 Max Mehl ######################################################################## # # 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 # . # ######################################################################## # # This script handles calls from submit.php. # It checks the validity of usernames, executes basic command # When password entries are required, it starts the respective python # scripts # ######################################################################## # Test if config.cfg exists and set needed variables if [ ! -e config.cfg ]; then echo "Missing config.cfg file. Edit and rename config.cfg.sample"; exit 1; fi source config.cfg ACTION=$1 # adduser, changepw, listusers, userdetail, deluser, sizeall, sizeuser, viewdata USER=$2 PASSFILE=$3 # $3 is a file containing the password PASS=$(cat $PASSFILE) PATH=$PATH:$HOME/bin ## FUNCTIONS function checkaction { REGEX="^adduser$|^changepw$|^listusers$|^userdetail$|^deluser$|^sizeall$|^sizeuser$|^viewdata$|^addalias$|^quota$|^installwp$|^uninstallwp$" if [[ $1 =~ $REGEX ]]; then echo "true" else echo "false" fi } function checkuser { REGEX="^[A-Za-z0-9._+-]+$" # Allowed symbols if [[ $1 =~ $REGEX ]]; then echo "true" else echo "false" fi } function checkpass { REGEX="[ '\\]" # Not allowed symbols if [[ $(grep -E "$REGEX" $1 ; echo $?) == 1 ]]; then echo "true" else echo "false" fi } function userexists { STATUS=$(listvdomain | cut -d" " -f 1 | sed '1d' | grep -q "^$1$" ; echo $?) if [ $STATUS == 0 ]; then echo "true" else echo "false" fi } function mailsend { TOEMAIL="$TOEMAIL"; FREMAIL="$FREMAIL"; SUBJECT="[$DOMAIN] $1"; MSGBODY1="$2" MSGBODY2="$3" printf '%s\n' "From: $FREMAIL To: $TOEMAIL Reply-To: $FREMAIL Subject: $SUBJECT $MSGBODY1 $MSGBODY2 " > $MAILTMP cat $MAILTMP | "$SENDMAILPATH" -t; rm $MAILTMP; } function mailsendenc { if [ ! -e $SSLKEY ]; then #echo "Encryption key \"$SSLKEY\" is not available. Aborting." #exit 1 openssl genrsa -out $SSLKEY 2048 fi TOEMAIL="$TOEMAIL"; FREMAIL="$FREMAIL"; SUBJECT="[$DOMAIN] $1"; MSGBODY1="$2" BOUNDARY="ZZafgwejwepfgkl.9453x1q" ATTACHMENT=$(echo $3 | openssl rsautl -inkey $SSLKEY -encrypt | base64) printf '%s\n' "From: $FREMAIL To: $TOEMAIL Reply-To: $FREMAIL Subject: $SUBJECT Mime-Version: 1.0 Content-Type: multipart/mixed; boundary=\"$BOUNDARY\" --${BOUNDARY} Content-Type: text/plain; charset=\"us-ascii\" Content-Transfer-Encoding: 7bit Content-Disposition: inline $MSGBODY1 Upload the attached encrypted file to your Account Administration Panel in order to see sensitive details. Please visit the section \"Decrypt system email\" for more details. --${BOUNDARY} Content-Type: text/plain Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename=\"message.txt.crypt\" $ATTACHMENT --${BOUNDARY} " > $MAILTMP cat $MAILTMP | "$SENDMAILPATH" -t; rm $MAILTMP; } function notesdelete { USER="$1" # Extract Mail part | exclude LEAD and TAIL | delete user sed -n "/$LEAD/,/$TAIL/ p" $NOTES | grep -v "$LEAD\|$TAIL" | sed "/User:[ \t]*$USER$/,+2d" > $NOTESTMP # Put edited part in between $LEAD and $TAIL again sed -i "/$LEAD/,/$TAIL/{ /$LEAD/{p; r $NOTESTMP }; /$TAIL/p; d }" $NOTES rm $NOTESTMP } function notesinsert { # Update datasheet (add new entry in Email section) USER=$1 PASSFILE=$2 # Create temporary file from $PASSFILE sed -E "s/(.*)/User: $USER\nPass: \1\n\n/" $PASSFILE > .$PASSFILE.tmp # Insert this edited file into the datasheet sed -i "/$TAIL/ { h r .$PASSFILE.tmp g N }" $NOTES rm .$PASSFILE.tmp } ## FIRST CHECKS if ! $(checkaction "$ACTION"); then echo "No valid action chosen" exit 1 fi # # # # # # ADDING USER # # # # # if [ "$ACTION" == "adduser" ]; then echo "Adding new Email user..." echo if ! $(checkuser "$USER"); then echo "Username \"$USER\" invalid" exit 1 fi if $(userexists "$USER"); then echo "User \"$USER\" does already exist!" exit 1 fi if ! $(checkpass "$PASSFILE"); then echo "Password \""$(cat $PASSFILE)"\" invalid" exit 1 fi python adduser.py "$USER" "$PASSFILE" if [ $? == 0 ]; then # Send infomail $MAILTYPE "New Email account created" \ "A new Email account has been created." \ "User: $USER" LEAD='## > EMAIL' TAIL='## < EMAIL' notesinsert "$USER" "$PASSFILE" fi fi # /adduser # # # # # # ADD ALIAS # # # # # if [ "$ACTION" == "addalias" ]; then echo "Extracting details of Email account..." echo DEST=$PASS if ! $(checkuser "$USER"); then echo "Username \"$USER\" invalid" exit 1 fi if $(userexists "$USER"); then echo "User \"$USER\" does already exist!" exit 1 fi if ! $(userexists "$DEST"); then echo "Destination account \"$DEST\" does not exist!" exit 1 fi vaddalias $USER $DEST fi # /addalias # # # # # # CHANGE PASSWORD # # # # # if [ "$ACTION" == "changepw" ]; then echo "Changing password of Email account..." echo if ! $(userexists "$USER"); then echo "User \"$USER\" does not exist!" exit 1 fi if ! $(checkpass "$PASSFILE"); then echo "Password \""$(cat $PASSFILE)"\" invalid" exit 1 fi python changepw.py "$USER" "$PASSFILE" if [ $? == 0 ]; then # Send infomail $MAILTYPE "Email password changed" \ "An Email account password has been changed." \ "User: $USER" # Update datasheet (delete entry in Email section and add a new one with the new password) # In fact a combination of deluser and adduser LEAD='## > EMAIL' TAIL='## < EMAIL' notesdelete "$USER" notesinsert "$USER" "$PASSFILE" fi fi # /changepw # # # # # # LIST USERS # # # # # if [ "$ACTION" == "listusers" ]; then echo "Listing all Email accounts..." echo listvdomain | column -s $' ' -t fi # /listusers # # # # # # SIZE ALL USERS # # # # # if [ "$ACTION" == "sizeall" ]; then echo "Calculate total size of all Email accounts..." echo du -sBM ~/users/* | sed -e "s:/home/$SYSUSER/users/::g" fi # /sizeall # # # # # # VIEW DATASHEET # # # # # if [ "$ACTION" == "viewdata" ]; then echo "Extracting data sheet..." echo cat $NOTES fi # /viewdata # # # # # # SIZE USER # # # # # if [ "$ACTION" == "sizeuser" ]; then echo "Calculate size of all folders of an Email account..." echo # Show size in MB, strip long paths, strip tmp and new folders, rename .INBOX cur-folder du -BM ~/users/"$USER" | sed -e "s:/home/$SYSUSER/users/$USER/::g" | grep -v "/cur$\|new$\|tmp$" | sed "s:cur$:.INBOX:" | grep -v "/home/$SYSUSER/users/$USER" | sort -nr fi # /sizeuser # # # # # # USER DETAIL # # # # # if [ "$ACTION" == "userdetail" ]; then echo "Extracting details of Email account..." echo if ! $(userexists "$USER"); then echo "User \"$USER\" does not exist!" exit 1 fi dumpvuser "$USER" | column -s $' ' -t fi # /userdetail # # # # # # QUOTA # # # # # if [ "$ACTION" == "quota" ]; then echo "Calculating account disk usage..." echo USAGE=$(cat quota | tail -n 1 | awk -F" " '{ print $2 }') QUOTA=$(cat quota | tail -n 1 | awk -F" " '{ print $3 }' | sed 's/[A-Za-z]//g') # If smaller than 1M, set usage to 1M to avoid miscalcuations if ! echo $USAGE | grep -q "[A-Za-z]$"; then USAGE="1" else USAGE=$(echo $USAGE | sed 's/[A-Za-z]//g') fi PERC=$(echo "scale=2; $USAGE/$QUOTA" | bc) PERC=$(echo "scale=2; $PERC*100" | bc) echo "$USAGE MB of $QUOTA MB are used ($PERC %)." PERC=$(echo "scale=2; 100 - $PERC" | bc) echo "You have "$(($QUOTA - $USAGE))" MB free ($PERC %)." fi # /quota # # # # # # DELETE USER # # # # # if [ "$ACTION" == "deluser" ]; then echo "Extracting details of Email account..." echo if ! $(userexists "$USER"); then echo "User \"$USER\" does not exist!" exit 1 fi vdeluser "$USER" if [ $? == 0 ]; then # Send infomail $MAILTYPE "Email account deleted" \ "An Email account has been deleted." \ "User: $USER" # Update datasheet (delete entry in Email section) LEAD='## > EMAIL' TAIL='## < EMAIL' notesdelete "$USER" fi fi # /deluser # # # # # # INSTALL WORDPRESS # # # # # if [ "$ACTION" == "installwp" ]; then echo "Installing WordPress..." echo # $USER: Username for Wordpress # $PASS: Email address for Wordpress user if ! $(checkuser "$USER"); then echo "Username \"$USER\" invalid" exit 1 fi WEBDIR=$HOME/html WPUSER=$USER WPPASS=$(apg -n 1 -M NCL -m 14) WPMAIL=$PASS WPDOMAIN=http://$DOMAIN # Get MySQL password LEAD='## > MYSQL' TAIL='## < MYSQL' MYSQLUSER=$SYSUSER MYSQLDB=${MYSQLUSER}_wp MYSQLPASS=$(sed -n "/$LEAD/,/$TAIL/ p" $NOTES | grep "^Pass:" | awk -F" " '{ print $2 }') # Check if ready for install: WEBDIR empty, Database available if [ $(ls -a $WEBDIR | wc -l) -gt 2 ]; then echo "The website directory \"$WEBDIR\" doesn't seem to be empty." exit 1 fi if [ $(mysql -e "SHOW DATABASES;" | tr -d "| " | grep -v Database | grep "^$$WPDB$" ; echo $?) = 0 ]; then echo "The default database \"${USER}_wp\" already exists." exit 1 fi # Downloading wordpress wget $WPDL unzip $(basename $WPDL) mv wordpress/* $WEBDIR rm -r wordpress $(basename $WPDL) # Downloading wp-cli curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar chmod +x wp-cli.phar mv wp-cli.phar $HOME/bin/wp-cli # Create database mysql -e "CREATE DATABASE $MYSQLDB;" # Use wp-cli to create config.php and install WP wp-cli core config --dbname=${MYSQLDB} --dbpass=${MYSQLPASS} --dbuser=${MYSQLUSER} --path=${WEBDIR} wp-cli core install --url="$WPDOMAIN" --title="CHANGE THIS TITLE" --admin_user=${WPUSER} --admin_password=${WPPASS} --admin_email=${WPMAIL} --path=${WEBDIR} # Update datasheet TAIL='## < WORDPRESS' sed -i "/$TAIL/i User: $WPUSER\nPass: $WPPASS\n" $NOTES echo echo "Wordpress successfully installed to $WPDOMAIN" echo "You can login on $WPDOMAIN/wp-login.php" echo "Please take a look into your data sheet for the login data." fi # /installwp # # # # # # REMOVE WORDPRESS # # # # # if [ "$ACTION" == "uninstallwp" ]; then echo "Uninstalling WordPress..." echo # $USER: Username for Wordpress # $PASS: Email address for Wordpress user WEBDIR=$HOME/html MYSQLUSER=$SYSUSER MYSQLDB=${MYSQLUSER}_wp # Delete database and content of ~/htmp mysql -e "DROP DATABASE ${MYSQLDB};" rm -rf $WEBDIR/* rm -rf $WEBDIR/.* # Update datasheet LEAD='## > WORDPRESS' TAIL='## < WORDPRESS' notesdelete ".*" echo echo "Wordpress successfully uninstalled." fi # /uninstallwp