#!/bin/bash # # .---. . . # | | | # |--- .--. .-. .-. .-.| .-. .--.--. |.-. .-. .--. .-. # | | (.-' (.-' ( | ( )| | | | )( )| | (.-' # ' ' --' --' -' - -' ' ' -' -' -' ' - --' # # Freedom in the Cloud # # Administrator control panel for the Freedombone system # # License # ======= # # Copyright (C) 2015-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 . PROJECT_NAME='freedombone' export TEXTDOMAIN=${PROJECT_NAME}-controlpanel export TEXTDOMAINDIR="/usr/share/locale" UTILS_FILES=/usr/share/${PROJECT_NAME}/utils/${PROJECT_NAME}-utils-* for f in $UTILS_FILES do source $f done APP_FILES=/usr/share/${PROJECT_NAME}/apps/${PROJECT_NAME}-app-* for f in $APP_FILES do source $f done COMPLETION_FILE=$HOME/${PROJECT_NAME}-completed.txt SELECTED_USERNAME= SIP_CONFIGURATION_FILE=/etc/sipwitch.conf ADMIN_USER= UPGRADE_SCRIPT_NAME="${PROJECT_NAME}-upgrade" UPDATE_DATE_SCRIPT=/usr/bin/updatedate # Minimum number of characters in a password MINIMUM_PASSWORD_LENGTH=$(cat /usr/share/${PROJECT_NAME}/utils/${PROJECT_NAME}-utils-passwords | grep 'MINIMUM_PASSWORD_LENGTH=' | head -n 1 | awk -F '=' '{print $2}') # voip VOIP_PORT=64738 VOIP_ONION_PORT=8095 SSH_PORT=2222 IRC_PORT=6697 IRC_ONION_PORT=8093 # outgoing SMTP proxy SMTP_PROXY_ENABLE=$'no' SMTP_PROXY_PROTOCOL='smtps' SMTP_PROXY_SERVER='mail.myispdomain' SMTP_PROXY_PORT=465 SMTP_PROXY_USERNAME='' SMTP_PROXY_PASSWORD='' WIFI_INTERFACE=wlan0 WIFI_SSID= WIFI_TYPE='wpa2-psk' WIFI_PASSPHRASE= WIFI_HOTSPOT='no' WIFI_NETWORKS_FILE=~/${PROJECT_NAME}-wifi.cfg USB_DRIVE=sdb # get default USB from config file CONFIGURATION_FILE=/root/${PROJECT_NAME}.cfg if [ -f $CONFIGURATION_FILE ]; then if grep -q "WIFI_HOTSPOT=" $CONFIGURATION_FILE; then WIFI_HOTSPOT=$(cat $CONFIGURATION_FILE | grep "WIFI_HOTSPOT=" | awk -F '=' '{print $2}') fi if grep -q "WIFI_INTERFACE=" $CONFIGURATION_FILE; then WIFI_INTERFACE=$(cat $CONFIGURATION_FILE | grep "WIFI_INTERFACE=" | awk -F '=' '{print $2}') fi if grep -q "WIFI_TYPE=" $CONFIGURATION_FILE; then WIFI_TYPE=$(cat $CONFIGURATION_FILE | grep "WIFI_TYPE=" | awk -F '=' '{print $2}') fi if grep -q "WIFI_SSID=" $CONFIGURATION_FILE; then WIFI_SSID=$(cat $CONFIGURATION_FILE | grep "WIFI_SSID=" | awk -F '=' '{print $2}') fi if grep -q "WIFI_PASSPHRASE=" $CONFIGURATION_FILE; then WIFI_PASSPHRASE=$(cat $CONFIGURATION_FILE | grep "WIFI_PASSPHRASE=" | awk -F '=' '{print $2}') fi if grep -q "USB_DRIVE=" $CONFIGURATION_FILE; then USB_DRIVE=$(cat $CONFIGURATION_FILE | grep "USB_DRIVE=" | awk -F '=' '{print $2}') if [[ $USB_DRIVE == *"dev"* ]]; then USB_DRIVE=$(echo ${USB_DRIVE} | awk -F '/' '{print $3}' | sed 's|1||g' | sed 's|2||g') fi fi if grep -q "SSH_PORT=" $CONFIGURATION_FILE; then SSH_PORT=$(cat $CONFIGURATION_FILE | grep "SSH_PORT=" | awk -F '=' '{print $2}') fi if grep -q "IRC_PORT=" $CONFIGURATION_FILE; then IRC_PORT=$(cat $CONFIGURATION_FILE | grep "IRC_PORT=" | awk -F '=' '{print $2}') fi if grep -q "SMTP_PROXY_ENABLE=" $CONFIGURATION_FILE; then SMTP_PROXY_ENABLE=$(cat $CONFIGURATION_FILE | grep "SMTP_PROXY_ENABLE=" | awk -F '=' '{print $2}') fi if grep -q "SMTP_PROXY_PROTOCOL=" $CONFIGURATION_FILE; then SMTP_PROXY_PROTOCOL=$(cat $CONFIGURATION_FILE | grep "SMTP_PROXY_PROTOCOL=" | awk -F '=' '{print $2}') fi if grep -q "SMTP_PROXY_SERVER=" $CONFIGURATION_FILE; then SMTP_PROXY_SERVER=$(cat $CONFIGURATION_FILE | grep "SMTP_PROXY_SERVER=" | awk -F '=' '{print $2}') fi if grep -q "SMTP_PROXY_PORT=" $CONFIGURATION_FILE; then SMTP_PROXY_PORT=$(cat $CONFIGURATION_FILE | grep "SMTP_PROXY_PORT=" | awk -F '=' '{print $2}') fi if grep -q "SMTP_PROXY_USERNAME=" $CONFIGURATION_FILE; then SMTP_PROXY_USERNAME=$(cat $CONFIGURATION_FILE | grep "SMTP_PROXY_USERNAME=" | awk -F '=' '{print $2}') fi if grep -q "SMTP_PROXY_PASSWORD=" $CONFIGURATION_FILE; then SMTP_PROXY_PASSWORD=$(cat $CONFIGURATION_FILE | grep "SMTP_PROXY_PASSWORD=" | awk -F '=' '{print $2}') fi fi # Mirrors settings FRIENDS_MIRRORS_SERVER= FRIENDS_MIRRORS_SSH_PORT=2222 FRIENDS_MIRRORS_PASSWORD= MY_MIRRORS_PASSWORD= function any_key { echo ' ' read -n1 -r -p $"Press any key to continue..." key } function check_for_updates { if [ ! -f /etc/cron.weekly/$UPGRADE_SCRIPT_NAME ]; then dialog --title $"Check for updates" \ --msgbox $"Upgrade script was not found" 6 40 return fi clear . /etc/cron.weekly/$UPGRADE_SCRIPT_NAME any_key } function read_repo_servers { if [ -f $CONFIGURATION_FILE ]; then if grep -q "FRIENDS_MIRRORS_SERVER" $CONFIGURATION_FILE; then FRIENDS_MIRRORS_SERVER=$(grep "FRIENDS_MIRRORS_SERVER" $CONFIGURATION_FILE | awk -F '=' '{print $2}') fi if grep -q "FRIENDS_MIRRORS_SSH_PORT" $CONFIGURATION_FILE; then FRIENDS_MIRRORS_SSH_PORT=$(grep "FRIENDS_MIRRORS_SSH_PORT" $CONFIGURATION_FILE | awk -F '=' '{print $2}') fi if grep -q "MY_MIRRORS_PASSWORD" $CONFIGURATION_FILE; then MY_MIRRORS_PASSWORD=$(grep "MY_MIRRORS_PASSWORD" $CONFIGURATION_FILE | awk -F '=' '{print $2}') fi if grep -q "FRIENDS_MIRRORS_PASSWORD" $CONFIGURATION_FILE; then FRIENDS_MIRRORS_PASSWORD=$(grep "FRIENDS_MIRRORS_PASSWORD" $CONFIGURATION_FILE | awk -F '=' '{print $2}') fi fi if [ ! $FRIENDS_MIRRORS_SERVER ]; then return fi if [ ${#FRIENDS_MIRRORS_SERVER} -lt 2 ]; then return fi MAIN_COMMAND=/usr/local/bin/${PROJECT_NAME} if [ ! -f $MAIN_COMMAND ]; then MAIN_COMMAND=/usr/bin/${PROJECT_NAME} fi REPOS=($(cat ${MAIN_COMMAND} | grep "_REPO=\"" | uniq -u | sed 's|${PROJECT_NAME}|'"${PROJECT_NAME}"'|g')) for line in "${REPOS[@]}" do repo_name=$(echo "$line" | awk -F '=' '{print $1}') mirrors_name=$(echo "$repo_name" | sed "s|_REPO||g" | awk '{print tolower($0)}') friends_repo_url="ssh://mirrors@${FRIENDS_MIRRORS_SERVER}:${FRIENDS_MIRRORS_SSH_PORT}/home/mirrors/${mirrors_name}" ${repo_name}="${friends_repo_url}" done } function set_main_repo { data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --backtitle $"Freedombone Control Panel" \ --title $"Main Repository (Mirrors)" \ --form $"If you do not wish to use the default repositories they can be obtained from mirrors on another ${PROJECT_NAME} server." 14 60 3 \ $"URL:" 1 1 "$FRIENDS_MIRRORS_SERVER" 1 14 40 15 \ $"SSH Port:" 2 1 "$FRIENDS_MIRRORS_SSH_PORT" 2 14 40 10000 \ $"Password:" 3 1 "$FRIENDS_MIRRORS_PASSWORD" 3 14 40 10000 \ 2> $data sel=$? case $sel in 1) return;; 255) return;; esac new_mirrors_url=$(cat $data | sed -n 1p) new_mirrors_ssh_port=$(cat $data | sed -n 2p) new_mirrors_password=$(cat $data | sed -n 3p) if [ ${#new_mirrors_url} -lt 2 ]; then return fi if [ ${#new_mirrors_ssh_port} -lt 1 ]; then return fi if [ ${#new_mirrors_password} -lt 10 ]; then dialog --title $"Main Repository" \ --msgbox $'Mirrors password was too short. Should be at least 10 characters.' 6 40 return fi if [[ $new_mirrors_url == *"."* ]]; then FRIENDS_MIRRORS_SERVER=$new_mirrors_url FRIENDS_MIRRORS_SSH_PORT=$new_mirrors_ssh_port FRIENDS_MIRRORS_PASSWORD=$new_mirrors_password if ! grep -q "FRIENDS_MIRRORS_SERVER" $CONFIGURATION_FILE; then echo "FRIENDS_MIRRORS_SERVER=$FRIENDS_MIRRORS_SERVER" >> $CONFIGURATION_FILE else sed -i "s|FRIENDS_MIRRORS_SERVER=.*|FRIENDS_MIRRORS_SERVER=$FRIENDS_MIRRORS_SERVER|g" $CONFIGURATION_FILE fi if ! grep -q "FRIENDS_MIRRORS_SSH_PORT" $CONFIGURATION_FILE; then echo "FRIENDS_MIRRORS_SSH_PORT=$FRIENDS_MIRRORS_SSH_PORT" >> $CONFIGURATION_FILE else sed -i "s|FRIENDS_MIRRORS_SSH_PORT=.*|FRIENDS_MIRRORS_SSH_PORT=$FRIENDS_MIRRORS_SSH_PORT|g" $CONFIGURATION_FILE fi if ! grep -q "FRIENDS_MIRRORS_PASSWORD" $CONFIGURATION_FILE; then echo "FRIENDS_MIRRORS_PASSWORD=$FRIENDS_MIRRORS_PASSWORD" >> $CONFIGURATION_FILE else sed -i "s|FRIENDS_MIRRORS_PASSWORD=.*|FRIENDS_MIRRORS_PASSWORD=$FRIENDS_MIRRORS_PASSWORD|g" $CONFIGURATION_FILE fi # re-read the repos read_repo_servers dialog --title $"Main Repository" \ --msgbox $"Main repository set to $FRIENDS_MIRRORS_SERVER" 6 60 fi } function add_user { data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --backtitle $"Freedombone Control Panel" \ --title $"Add new user" \ --form "\n" 8 60 3 \ $"Username:" 1 1 "" 1 28 16 15 \ $"ssh public key (optional):" 2 1 "" 2 28 40 10000 \ 2> $data sel=$? case $sel in 1) return;; 255) return;; esac new_user_username=$(cat $data | sed -n 1p) new_user_ssh_public_key=$(cat $data | sed -n 2p) if [ ${#new_user_username} -lt 2 ]; then dialog --title $"New username" \ --msgbox $"No username was given" 6 40 return fi if [[ "$new_user_username" == *" "* ]]; then dialog --title $"Invalid username" \ --msgbox $"The username should not contain any spaces" 6 40 return fi if [ ${#new_user_ssh_public_key} -lt 20 ]; then clear ${PROJECT_NAME}-adduser "$new_user_username" any_key else if [[ "$new_user_ssh_public_key" == "ssh-"* ]]; then clear ${PROJECT_NAME}-adduser "$new_user_username" "$new_user_ssh_public_key" any_key else dialog --title $"ssh public key" \ --msgbox $"This does not look like an ssh public key" 6 40 fi fi } function pad_string { echo -n -e "$1" | sed -e :a -e 's/^.\{1,25\}$/& /;ta' } function show_domains { DEFAULT_DOMAIN_NAME=$(cat $CONFIGURATION_FILE | grep "DEFAULT_DOMAIN_NAME=" | awk -F '=' '{print $2}') echo 'Domains' echo '=======' echo '' echo -n -e "$(pad_string 'Name')" echo -n -e "$(pad_string 'ICANN')" echo -n -e "$(pad_string 'Tor')" echo '' echo '--------------------------------------------------------------------------' if grep -q "ssh onion domain" $COMPLETION_FILE; then echo -n -e "$(pad_string 'ssh')" echo -n -e "$(pad_string ${DEFAULT_DOMAIN_NAME})" echo "$(cat ${COMPLETION_FILE} | grep 'ssh onion domain' | awk -F ':' '{print $2}')" fi if grep -q "Email onion domain" $COMPLETION_FILE; then echo -n -e "$(pad_string 'Email')" echo -n -e "$(pad_string ${DEFAULT_DOMAIN_NAME})" echo "$(cat ${COMPLETION_FILE} | grep 'Email onion domain' | awk -F ':' '{print $2}')" fi if grep -q "XMPP onion domain" $COMPLETION_FILE; then echo -n -e "$(pad_string 'XMPP')" echo -n -e "$(pad_string ${DEFAULT_DOMAIN_NAME})" echo "$(cat ${COMPLETION_FILE} | grep 'XMPP onion domain' | awk -F ':' '{print $2}')" fi if grep -q "VoIP onion domain" $COMPLETION_FILE; then echo -n -e "$(pad_string 'VoIP/Mumble')" echo -n -e "$(pad_string ${DEFAULT_DOMAIN_NAME})" echo "$(cat ${COMPLETION_FILE} | grep 'VoIP onion domain' | awk -F ':' '{print $2}')" fi if grep -q "SIP onion domain" $COMPLETION_FILE; then echo -n -e "$(pad_string 'SIP')" echo -n -e "$(pad_string ${DEFAULT_DOMAIN_NAME})" echo "$(cat ${COMPLETION_FILE} | grep 'SIP onion domain' | awk -F ':' '{print $2}')" fi if grep -q "IRC onion domain" $COMPLETION_FILE; then echo -n -e "$(pad_string 'IRC')" echo -n -e "$(pad_string ${DEFAULT_DOMAIN_NAME})" echo "$(cat ${COMPLETION_FILE} | grep 'IRC onion domain' | awk -F ':' '{print $2}')" fi if grep -q "tox onion domain" $COMPLETION_FILE; then echo -n -e "$(pad_string 'Tox Bootstrap')" echo -n -e "$(pad_string ${DEFAULT_DOMAIN_NAME})" echo "$(cat ${COMPLETION_FILE} | grep 'tox onion domain' | awk -F ':' '{print $2}')" fi if grep -q "Wiki domain" $COMPLETION_FILE; then echo -n -e "$(pad_string 'Wiki')" WIKIDOM=$(cat ${COMPLETION_FILE} | grep 'Wiki domain' | awk -F ':' '{print $2}') echo -n -e "$(pad_string ${WIKIDOM})" if [ -d /var/lib/tor/hidden_service_wiki ]; then echo -n "$(cat /var/lib/tor/hidden_service_wiki/hostname)" fi echo '' fi if grep -q "Hubzilla domain" $COMPLETION_FILE; then echo -n -e "$(pad_string 'Hubzilla')" HUBZILLADOM=$(cat ${COMPLETION_FILE} | grep 'Hubzilla domain' | awk -F ':' '{print $2}') echo -n -e "$(pad_string ${HUBZILLADOM})" if [ -d /var/lib/tor/hidden_service_hubzilla ]; then echo -n "$(cat /var/lib/tor/hidden_service_hubzilla/hostname)" fi echo '' fi if grep -q "Blog domain" $COMPLETION_FILE; then echo -n -e "$(pad_string 'Blog')" BLOGDOM=$(cat ${COMPLETION_FILE} | grep 'Blog domain' | awk -F ':' '{print $2}') echo -n -e "$(pad_string ${BLOGDOM})" if [ -d /var/lib/tor/hidden_service_blog ]; then echo -n "$(cat /var/lib/tor/hidden_service_blog/hostname)" fi echo '' fi if grep -q "GNU Social domain" $COMPLETION_FILE; then echo -n -e "$(pad_string 'GNU Social')" GNUSOCIALDOM=$(cat ${COMPLETION_FILE} | grep 'GNU Social domain' | awk -F ':' '{print $2}') echo -n -e "$(pad_string ${GNUSOCIALDOM})" if [ -d /var/lib/tor/hidden_service_microblog ]; then echo -n "$(cat /var/lib/tor/hidden_service_microblog/hostname)" fi echo '' fi if grep -q "Gogs domain" $COMPLETION_FILE; then echo -n -e "$(pad_string 'Gogs')" GOGSDOM=$(cat ${COMPLETION_FILE} | grep 'Gogs domain' | awk -F ':' '{print $2}') echo -n -e "$(pad_string ${GOGSDOM})" if [ -d /var/lib/tor/hidden_service_gogs ]; then echo -n "$(cat /var/lib/tor/hidden_service_gogs/hostname)" fi echo '' fi if grep -q "RSS reader domain" $COMPLETION_FILE; then if [ -d /var/lib/tor/hidden_service_ttrss ]; then echo -n -e "$(pad_string 'RSS reader')" RSSDOM='-' echo -n -e "$(pad_string ${RSSDOM})" echo -n "$(cat /var/lib/tor/hidden_service_ttrss/hostname)" echo '' fi if [ -d /var/lib/tor/hidden_service_ttrss_mobile ]; then echo -n -e "$(pad_string 'RSS mobile')" RSSMOBILEDOM='-' echo -n -e "$(pad_string ${RSSMOBILEDOM})" echo -n "$(cat /var/lib/tor/hidden_service_ttrss_mobile/hostname)" echo '' fi fi if grep -q "Webmail onion domain" $COMPLETION_FILE; then echo -n -e "$(pad_string 'Webmail')" WEBMAILDOM='-' echo -n -e "$(pad_string ${WEBMAILDOM})" if [ -d /var/lib/tor/hidden_service_webmail ]; then echo -n "$(cat /var/lib/tor/hidden_service_webmail/hostname)" fi echo '' fi if grep -q "Search engine onion domain" $COMPLETION_FILE; then echo -n -e "$(pad_string 'Search engine')" SEARCHDOM='-' echo -n -e "$(pad_string ${SEARCHDOM})" if [ -d /var/lib/tor/hidden_service_searx ]; then echo -n "$(cat /var/lib/tor/hidden_service_searx/hostname)" fi echo '' fi if grep -q "Mediagoblin domain" $COMPLETION_FILE; then echo -n -e "$(pad_string 'Mediagoblin')" MEDIADOM=$(cat ${COMPLETION_FILE} | grep 'Mediagoblin domain' | awk -F ':' '{print $2}') echo -n -e "$(pad_string ${MEDIADOM})" if [ -d /var/lib/tor/hidden_service_mediagoblin ]; then echo -n "$(cat /var/lib/tor/hidden_service_mediagoblin/hostname)" fi echo '' fi if grep -q "Media server domain" $COMPLETION_FILE; then echo -n -e "$(pad_string 'Media server')" MEDIADOM=$(cat ${COMPLETION_FILE} | grep 'Media server domain' | awk -F ':' '{print $2}') echo -n -e "$(pad_string ${MEDIADOM})" if [ -d /var/lib/tor/hidden_service_mediadrop ]; then echo -n "$(cat /var/lib/tor/hidden_service_mediadrop/hostname)" fi echo '' fi echo '' } function show_users { echo 'Users' echo '=====' echo '' echo -n -e "$(pad_string 'Name')" echo -n -e "$(pad_string 'SIP ext')" echo -n -e "$(pad_string 'Data')" echo '' echo '--------------------------------------------------------------------------' for d in /home/*/ ; do USRNAME=$(echo "$d" | awk -F '/' '{print $3}') if [[ $USRNAME != "git" && $USRNAME != "mirrors" && $USRNAME != "sync" && $USERNAME != "tahoelafs" ]]; then echo -n -e "$(pad_string ${USRNAME})" # get the SIP extension SIPEXT= while read ext; do if [[ $ext == *"user id"* ]]; then CURR_UID=$(echo "$ext" | awk -F '"' '{print $2}' | awk -F '"' '{print $1}') fi if [[ $ext == *"extension"* ]]; then if [[ $CURR_UID == $USRNAME ]]; then SIPEXT=$(echo "$ext" | awk -F '>' '{print $2}' | awk -F '<' '{print $1}') fi fi done < $SIP_CONFIGURATION_FILE if [ $SIPEXT ]; then echo -n -e "$(pad_string SIP:${SIPEXT})" else echo -n -e "$(pad_string '')" fi # size of the home directory echo "$(du -s -h /home/${USRNAME} | awk -F ' ' '{print $1}')" fi done echo '' } function show_mirrors_password { if [ ! /home/mirrors ]; then return fi if grep -q "MY_MIRRORS_PASSWORD" $CONFIGURATION_FILE; then MY_MIRRORS_PASSWORD=$(grep "MY_MIRRORS_PASSWORD" $CONFIGURATION_FILE | awk -F '=' '{print $2}') fi echo 'Local Mirrors' echo '=============' echo '' echo -n "URL: " echo "$(cat ${COMPLETION_FILE} | grep 'ssh onion domain' | awk -F ':' '{print $2}')" echo "SSH Port: $SSH_PORT" echo "Password: $MY_MIRRORS_PASSWORD" echo '' } function show_tahoe_introducer { if [ ! -f /home/tahoelafs/.tahoe-introducer/private/introducer.furl ]; then return fi echo 'Tahoe-LAFS' echo '==========' echo '' cat /home/tahoelafs/.tahoe-introducer/private/introducer.furl echo '' } function show_about { clear show_domains show_mirrors_password show_tahoe_introducer show_users any_key } function select_user { SELECTED_USERNAME= users_array=($(ls /home)) delete=(mirrors git) for del in ${delete[@]} do users_array=(${users_array[@]/$del}) done i=0 W=() name=() for u in ${users_array[@]} do i=$((i+1)) W+=($i "$u") name+=("$u") done user_index=$(dialog --backtitle $"Freedombone Control Panel" --title $"Select User" --menu $"Select one of the following:" 24 40 17 "${W[@]}" 3>&2 2>&1 1>&3) if [ $? -eq 0 ]; then SELECTED_USERNAME="${name[$((user_index-1))]}" fi } function smtp_proxy { MUTTRC_FILE=/home/$ADMIN_USER/.muttrc if [ ! -f $MUTTRC_FILE ]; then return fi data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --backtitle $"Freedombone Control Panel" \ --title $"SMTP Proxy for $ADMIN_USER" \ --form $"You may need to proxy outgoing email via your ISP's mail server. If so enter the details below." 14 75 6 \ $"Enable proxy:" 1 1 "$SMTP_PROXY_ENABLE" 1 24 5 5 \ $"Protocol (smtp/smtps):" 2 1 "$SMTP_PROXY_PROTOCOL" 2 24 5 5 \ $"ISP mail server:" 3 1 "$SMTP_PROXY_SERVER" 3 24 40 10000 \ $"Port:" 4 1 "$SMTP_PROXY_PORT" 4 24 5 5 \ $"Username:" 5 1 "$SMTP_PROXY_USERNAME" 5 24 40 10000 \ $"Password:" 6 1 "$SMTP_PROXY_PASSWORD" 6 24 40 10000 \ 2> $data sel=$? case $sel in 1) return;; 255) return;; esac SMTP_PROXY_ENABLE=$(cat $data | sed -n 1p) SMTP_PROXY_PROTOCOL=$(cat $data | sed -n 2p) SMTP_PROXY_SERVER=$(cat $data | sed -n 3p) SMTP_PROXY_PORT=$(cat $data | sed -n 4p) SMTP_PROXY_USERNAME=$(cat $data | sed -n 5p) SMTP_PROXY_PASSWORD=$(cat $data | sed -n 6p) # change muttrc if [ $SMTP_PROXY_ENABLE != $'no' ]; then if ! grep "set smtp_url" $MUTTRC_FILE; then echo "set smtp_url=\"${SMTP_PROXY_PROTOCOL}://${SMTP_PROXY_USERNAME}:${SMTP_PROXY_PASSWORD}@${SMTP_PROXY_SERVER}:${SMTP_PROXY_PORT}/\"" >> $MUTTRC_FILE else sed -i "s|set smtp_url=.*|set smtp_url=\"${SMTP_PROXY_PROTOCOL}://${SMTP_PROXY_USERNAME}:${SMTP_PROXY_PASSWORD}@${SMTP_PROXY_SERVER}:${SMTP_PROXY_PORT}/\"|g" $MUTTRC_FILE fi sed -i 's|#set smtp_url|set smtp_url|g' $MUTTRC_FILE else if grep "set smtp_url" $MUTTRC_FILE; then sed -i 's|set smtp_url|#set smtp_url|g' $MUTTRC_FILE fi fi # save settings within the main configuration file if ! grep -q "SMTP_PROXY_ENABLE=" $CONFIGURATION_FILE; then echo "SMTP_PROXY_ENABLE=$SMTP_PROXY_ENABLE" >> $CONFIGURATION_FILE else sed -i "s|SMTP_PROXY_ENABLE=.*|SMTP_PROXY_ENABLE=$SMTP_PROXY_ENABLE|g" $CONFIGURATION_FILE fi if ! grep -q "SMTP_PROXY_PROTOCOL=" $CONFIGURATION_FILE; then echo "SMTP_PROXY_PROTOCOL=$SMTP_PROXY_PROTOCOL" >> $CONFIGURATION_FILE else sed -i "s|SMTP_PROXY_PROTOCOL=.*|SMTP_PROXY_PROTOCOL=$SMTP_PROXY_PROTOCOL|g" $CONFIGURATION_FILE fi if ! grep -q "SMTP_PROXY_SERVER=" $CONFIGURATION_FILE; then echo "SMTP_PROXY_SERVER=$SMTP_PROXY_SERVER" >> $CONFIGURATION_FILE else sed -i "s|SMTP_PROXY_SERVER=.*|SMTP_PROXY_SERVER=$SMTP_PROXY_SERVER|g" $CONFIGURATION_FILE fi if ! grep -q "SMTP_PROXY_PORT=" $CONFIGURATION_FILE; then echo "SMTP_PROXY_PORT=$SMTP_PROXY_PORT" >> $CONFIGURATION_FILE else sed -i "s|SMTP_PROXY_PORT=.*|SMTP_PROXY_PORT=$SMTP_PROXY_PORT|g" $CONFIGURATION_FILE fi if ! grep -q "SMTP_PROXY_USERNAME=" $CONFIGURATION_FILE; then echo "SMTP_PROXY_USERNAME=$SMTP_PROXY_USERNAME" >> $CONFIGURATION_FILE else sed -i "s|SMTP_PROXY_USERNAME=.*|SMTP_PROXY_USERNAME=$SMTP_PROXY_USERNAME|g" $CONFIGURATION_FILE fi if ! grep -q "SMTP_PROXY_PASSWORD=" $CONFIGURATION_FILE; then echo "SMTP_PROXY_PASSWORD=$SMTP_PROXY_PASSWORD" >> $CONFIGURATION_FILE else sed -i "s|SMTP_PROXY_PASSWORD=.*|SMTP_PROXY_PASSWORD=$SMTP_PROXY_PASSWORD|g" $CONFIGURATION_FILE fi } function delete_user { select_user if [ ! $SELECTED_USERNAME ]; then return fi if grep -Fxq "Admin user:$SELECTED_USERNAME" $COMPLETION_FILE; then dialog --title $"Administrator user" \ --msgbox $"You can't delete the administrator user" 6 40 return fi clear ${PROJECT_NAME}-rmuser $SELECTED_USERNAME any_key } function configure_remote_backups { if ! grep -Fxq "Admin user:$ADMIN_USER" $COMPLETION_FILE; then dialog --title $"Administrator user" \ --msgbox $"No Administrator user found. Check $COMPLETION_FILE" 6 40 return fi if [ ${#ADMIN_USER} -lt 2 ]; then dialog --title $"Administrator user" \ --msgbox $"Username not found" 6 40 return fi if [ ! -d /home/$ADMIN_USER ]; then dialog --title $"Administrator user" \ --msgbox $"Home directory not found" 6 40 return fi ${PROJECT_NAME}-remote -u $ADMIN_USER if [ ! "$?" = "0" ]; then any_key fi } function change_password { select_user if [ ! $SELECTED_USERNAME ]; then return fi dialog --title $"Change password" \ --passwordbox $"New password for user $SELECTED_USERNAME" 8 40 2> $data newpassword=$(<$data) if [ ${#newpassword} -lt ${MINIMUM_PASSWORD_LENGTH} ]; then dialog --title $"Change password" \ --msgbox $"The password should be ${MINIMUM_PASSWORD_LENGTH} or more characters" 6 40 return fi echo "$SELECTED_USERNAME:$newpassword"|chpasswd dialog --title $"Change password" \ --msgbox $"Password for $SELECTED_USERNAME was changed" 6 40 } function change_ssh_public_key { select_user if [ ! $SELECTED_USERNAME ]; then return fi if grep -Fxq "Admin user:$SELECTED_USERNAME" $COMPLETION_FILE; then dialog --title $"Change ssh public key" \ --backtitle $"Freedombone Control Panel" \ --defaultno \ --yesno $"\nThis is the administrator user.\n\nAre you sure you want to change the ssh public key for the administrator?" 10 60 sel=$? case $sel in 1) return;; 255) return;; esac fi data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --title $"Change ssh public key for $SELECTED_USERNAME" \ --backtitle $"Freedombone Control Panel" \ --inputbox $"Paste the ssh public key below" 8 60 2>$data sel=$? case $sel in 0) SSH_PUBLIC_KEY=$(<$data) if [ "$SSH_PUBLIC_KEY" ]; then if [ ${#SSH_PUBLIC_KEY} -gt 5 ]; then if [ -f "$SSH_PUBLIC_KEY" ]; then if [ ! -d /home/$SELECTED_USERNAME/.ssh ]; then mkdir /home/$SELECTED_USERNAME/.ssh fi cp $SSH_PUBLIC_KEY \ /home/$SELECTED_USERNAME/.ssh/authorized_keys chown -R $SELECTED_USERNAME:$SELECTED_USERNAME \ /home/$SELECTED_USERNAME/.ssh dialog --title $"Change ssh public key" \ --msgbox $"ssh public key was installed" 6 40 else if [[ "$SSH_PUBLIC_KEY" == "ssh-"* ]]; then if [ ! -d /home/$SELECTED_USERNAME/.ssh ]; then mkdir /home/$SELECTED_USERNAME/.ssh fi echo "$SSH_PUBLIC_KEY" > \ /home/$SELECTED_USERNAME/.ssh/authorized_keys chown -R $SELECTED_USERNAME:$SELECTED_USERNAME \ /home/$SELECTED_USERNAME/.ssh dialog --title $"Change ssh public key" \ --msgbox $"ssh public key was installed" 6 40 fi fi fi fi ;; esac } function remove_user_from_mailing_list { select_user if [ ! $SELECTED_USERNAME ]; then return fi USER_MAILING_LISTS=$(cat "/home/$SELECTED_USERNAME/.procmailrc" | grep '\[' | grep '\]' | awk -F '\[' '{print $2}' | awk -F '\\' '{print $1}') i=0 W=() list_name=() while read -r listname; do i=$((i+1)) W+=($i "$listname") list_name+=("$listname") echo $listname done <<< "$USER_MAILING_LISTS" i=$((i+1)) W+=($i $"Exit back to user mainenance") list_selected=$(dialog --default-item "$i" --backtitle $"Freedombone Control Panel" --title $"Remove a mailing list for $SELECTED_USERNAME" --menu $"Select one of the following:" 24 50 17 "${W[@]}" 3>&2 2>&1 1>&3) if [ $? -eq 0 ]; then # Exit with OK if [ ${list_selected} -ne ${i} ]; then remove_list_name="${list_name[$((list_selected-1))]}" # find the line number where the list is defined line_number=0 i=0 while read -r line do if [[ "$line" == *"\[${remove_list_name}\\]"* ]]; then line_number=${i} fi i=$((i+1)) done < "/home/$SELECTED_USERNAME/.procmailrc" if [ ${line_number} -eq 0 ]; then # no match was found return fi # recreate the file if [ -f /home/${SELECTED_USERNAME}/.procmailrc_new ]; then rm /home/${SELECTED_USERNAME}/.procmailrc_new fi i=0 clip=0 while read -r line do i=$((i+1)) if [ ${i} -gt $((line_number-1)) ]; then if [ ${clip} -eq 0 ]; then clip=1 fi if [ ${clip} -eq 1 ]; then if [ ${i} -lt $((line_number+2)) ]; then continue else if [ ${#line} -lt 1 ]; then clip=2 continue fi if [[ "$line" == ":"* || "$line" == "#"* ]]; then clip=2 else continue fi fi fi fi echo "$line" >> /home/${SELECTED_USERNAME}/.procmailrc_new if [[ "$line" == *"\[${remove_list_name}\\]"* ]]; then line_number=${i} fi done < "/home/$SELECTED_USERNAME/.procmailrc" cp /home/${SELECTED_USERNAME}/.procmailrc_new /home/${SELECTED_USERNAME}/.procmailrc rm /home/${SELECTED_USERNAME}/.procmailrc_new chown ${SELECTED_USERNAME}:${SELECTED_USERNAME} /home/${SELECTED_USERNAME}/.procmailrc dialog --title $"Remove user from mailing list" \ --msgbox $"${SELECTED_USERNAME} has been removed from ${remove_list_name}" 6 50 fi fi } function add_to_mailing_list { select_user if [ ! $SELECTED_USERNAME ]; then return fi data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --backtitle $"Freedombone Control Panel" \ --title $"Subscribe $SELECTED_USERNAME to a mailing list" \ --form $"You can either enter a subject or an email address\n" 11 68 4 \ $"List folder name:" 1 1 "" 1 35 26 25 \ $"Name between [] on subject line:" 2 1 "" 2 35 26 25 \ $"List email address:" 3 1 "" 3 35 26 25 \ $"Public:" 4 1 $"yes" 4 35 4 25 \ 2> $data sel=$? case $sel in 1) return;; 255) return;; esac LIST_NAME=$(cat $data | sed -n 1p) LIST_SUBJECT=$(cat $data | sed -n 2p) LIST_EMAIL=$(cat $data | sed -n 3p) LIST_PUBLIC=$(cat $data | sed -n 4p) if [ ${#LIST_PUBLIC} -lt 1 ]; then LIST_PUBLIC='no' fi if [[ $LIST_PUBLIC == $'y' || $LIST_PUBLIC == $'Y' || $LIST_PUBLIC == $'true' || $LIST_PUBLIC == $'True' || $LIST_PUBLIC == $'yes' || $LIST_PUBLIC == $'Yes' || $LIST_PUBLIC == $'YES' ]]; then LIST_PUBLIC='yes' else LIST_PUBLIC='no' fi if [ ${#LIST_NAME} -lt 2 ]; then dialog --title $"Add mailing list" \ --msgbox $"No mailing list name was given" 6 40 return fi if [ ${#LIST_SUBJECT} -lt 2 ]; then if [ ${#LIST_EMAIL} -lt 2 ]; then dialog --title $"Add mailing list" \ --msgbox $"No mailing list subject or address was given" 6 40 return fi fi if [ ${#LIST_SUBJECT} -gt 1 ]; then ${PROJECT_NAME}-addlist -u $SELECTED_USERNAME -l "$LIST_NAME" \ -s "$LIST_SUBJECT" --public $LIST_PUBLIC else if [[ "$LIST_EMAIL" != *"@"* || "$LIST_EMAIL" != *"."* ]]; then dialog --title $"Add mailing list" \ --msgbox $"Unrecognised email address" 6 40 return else ${PROJECT_NAME}-addlist -u $SELECTED_USERNAME -l "$LIST_NAME" \ -e "$LIST_EMAIL" --public $LIST_PUBLIC fi fi dialog --title $"Add mailing list" \ --msgbox $"$LIST_NAME list was added" 6 40 } function email_rule { select_user if [ ! $SELECTED_USERNAME ]; then return fi data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --backtitle $"Freedombone Control Panel" \ --title $"Email rule for user $SELECTED_USERNAME" \ --form "\n" 9 65 4 \ $"When email arrives from address:" 1 1 "" 1 35 24 28 \ $"Move to folder:" 2 1 "" 2 35 24 28 \ $"Public:" 3 1 $"no" 3 35 4 25 \ 2> $data sel=$? case $sel in 1) return;; 255) return;; esac RULE_EMAIL=$(cat $data | sed -n 1p) RULE_FOLDER=$(cat $data | sed -n 2p) RULE_PUBLIC=$(cat $data | sed -n 3p) if [ ${#RULE_PUBLIC} -lt 1 ]; then RULE_PUBLIC='no' fi if [[ $RULE_PUBLIC == $'y' || $RULE_PUBLIC == $'Y' || $RULE_PUBLIC == $'true' || $RULE_PUBLIC == $'True' || $RULE_PUBLIC == $'yes' || $RULE_PUBLIC == $'Yes' || $RULE_PUBLIC == $'YES' ]]; then RULE_PUBLIC='yes' else RULE_PUBLIC='no' fi if [ ${#RULE_EMAIL} -lt 2 ]; then dialog --title $"Add email rule" \ --msgbox $"No email address was given" 6 40 return fi if [ ${#RULE_FOLDER} -lt 2 ]; then dialog --title $"Add email rule" \ --msgbox $"No folder name was given" 6 40 return fi if [[ "$RULE_EMAIL" != *"@"* || "$RULE_EMAIL" != *"."* ]]; then dialog --title $"Add email rule" \ --msgbox $"Unrecognised email address" 6 40 return fi ${PROJECT_NAME}-addemail -u $SELECTED_USERNAME -e "$RULE_EMAIL" \ -g "$RULE_FOLDER" --public $RULE_PUBLIC dialog --title $"Add email rule" \ --msgbox $"Email rule for $RULE_EMAIL was added" 6 40 } function block_unblock_email { select_user if [ ! $SELECTED_USERNAME ]; then return fi blockstr=$"Block/Unblock email going to" data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --backtitle $"Freedombone Control Panel" \ --title "$blockstr $SELECTED_USERNAME" \ --form "\n" 8 65 3 \ $"When email arrives from address:" 1 1 "" 1 35 24 100 \ $"Block it:" 2 1 "yes" 2 35 4 4 \ 2> $data sel=$? case $sel in 1) return;; 255) return;; esac BLOCK_EMAIL=$(cat $data | sed -n 1p) BLOCK=$(cat $data | sed -n 2p) if [ ${#BLOCK_EMAIL} -lt 2 ]; then dialog --title $"Block/Unblock an email" \ --msgbox $"No email address was given" 6 40 return fi if [[ "$BLOCK_EMAIL" != *"@"* || "$BLOCK_EMAIL" != *"."* ]]; then dialog --title $"Block/Unblock an email" \ --msgbox $"Unrecognised email address" 6 40 return fi if [[ $BLOCK == "y"* || $BLOCK == "Y"* ]]; then ${PROJECT_NAME}-ignore -u $SELECTED_USERNAME -e "$BLOCK_EMAIL" dialog --title $"Block an email" \ --msgbox "Email from $BLOCK_EMAIL to $SELECTED_USERNAME blocked" 6 75 else ${PROJECT_NAME}-unignore -u $SELECTED_USERNAME -e "$BLOCK_EMAIL" dialog --title $"Unblock an email" \ --msgbox "Email from $BLOCK_EMAIL to $SELECTED_USERNAME unblocked" 6 75 fi } function block_unblock_subject { select_user if [ ! $SELECTED_USERNAME ]; then return fi blockstr=$"Block/Unblock email going to" data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --backtitle $"Freedombone Control Panel" \ --title "$blockstr $SELECTED_USERNAME" \ --form "\n" 8 70 3 \ $"When email arrives with subject text:" 1 1 "" 1 40 24 28 \ $"Block it:" 2 1 "yes" 2 40 4 4 \ 2> $data sel=$? case $sel in 1) return;; 255) return;; esac BLOCK_SUBJECT=$(cat $data | sed -n 1p) BLOCK=$(cat $data | sed -n 2p) if [ ${#BLOCK_SUBJECT} -lt 2 ]; then dialog --title $"Block/Unblock an email" \ --msgbox $"No subject was given" 6 40 return fi if [[ $BLOCK == "y"* || $BLOCK == "Y"* ]]; then ${PROJECT_NAME}-ignore -u $SELECTED_USERNAME -t "$BLOCK_SUBJECT" dialog --title $"Block an email" \ --msgbox "Email with subject $BLOCK_SUBJECT to $SELECTED_USERNAME blocked" 6 40 else ${PROJECT_NAME}-unignore -u $SELECTED_USERNAME -t "$BLOCK_SUBJECT" dialog --title $"Unblock an email" \ --msgbox "Email with subject $BLOCK_SUBJECT to $SELECTED_USERNAME unblocked" 6 40 fi } function create_keydrive_master { select_user if [ ! $SELECTED_USERNAME ]; then return fi dialog --title $"USB Master Keydrive" \ --msgbox $"Plug in a LUKS encrypted USB drive" 6 40 clear ${PROJECT_NAME}-keydrive -u $SELECTED_USERNAME --master 'yes' any_key } function create_keydrive_fragment { select_user if [ ! $SELECTED_USERNAME ]; then return fi dialog --title $"USB Fragment Keydrive" \ --msgbox $"Plug in a LUKS encrypted USB drive" 6 40 clear ${PROJECT_NAME}-keydrive -u $SELECTED_USERNAME any_key } function backup_data { dialog --title $"Backup data to USB" \ --msgbox $"Plug in a LUKS encrypted USB drive" 6 40 clear echo ' ' echo $'Enter the passphrase for your LUKS encrypted backup drive:' ${PROJECT_NAME}-backup-local any_key } function restore_from_usb { detect_apps applist="all" n=1 app_index=0 for a in "${APPS_INSTALLED_NAMES[@]}" do applist="$applist $n $a off" n=$[n+1] app_index=$[app_index+1] done choices=$(dialog --stdout --backtitle $"Freedombone" \ --title $"Restore apps" \ --checklist $'Choose:' \ 80 40 20 $applist) if [ $? -eq 0 ]; then clear ctr=0 for choice in $choices do app_index = $[choice-1] app_name=${APPS_INSTALLED_NAMES[app_index]} if [[ "${app_name}" == 'all' ]]; then ${PROJECT_NAME}-restore-local $USB_DRIVE else ${PROJECT_NAME}-restore-local $USB_DRIVE "${app_name}" fi if [ ! "$?" = "0" ]; then dialog --title $"Restore apps from USB" \ --msgbox $"Restore of ${app_name} failed with code $?" 6 40 return fi ctr=$((ctr + 1)) done if [ $ctr -gt 0 ]; then dialog --title $"Restore apps from USB" \ --msgbox $"Restore complete" 6 40 fi fi } function restore_from_remote { remote_domain_name=$1 while true do data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --backtitle $"Freedombone Control Panel" \ --title $"Restore from ${remote_domain_name}" \ --radiolist $"Choose an application to restore:" 31 70 28 \ 1 $"Everything" off \ 2 $"Return to the backup and restore menu" on \ 3 $"Configuration files" off \ 4 $"MariaDB settings" off \ 5 $"Let's Encrypt account" off \ 6 $"Mutt email client settings" off \ 7 $"GPG keys" off \ 8 $"Email processing rules" off \ 9 $"Spam filtering rules" off \ 10 $"Administrator's README file" off \ 11 $"IPFS" off \ 12 $"SSH keys" off \ 13 $"User configuration files" off \ 14 $"User local files" off \ 15 $"User fin files" off \ 16 $"SSL/TLS certificates" off \ 17 $"Personal settings" off \ 18 $"Mailing List" off \ 19 $"XMPP chat" off \ 20 $"GNU Social" off \ 21 $"Hubzilla" off \ 22 $"Syncthing" off \ 23 $"Gogs" off \ 24 $"Wiki" off \ 25 $"Blog" off \ 26 $"CJDNS" off \ 27 $"Email" off \ 28 $"DLNA" off \ 29 $"VoIP" off \ 30 $"RSS reader" off \ 31 $"Tox" off 2> $data sel=$? case $sel in 1) break;; 255) break;; esac if [ $(cat $data) -ne 2 ]; then clear fi case $(cat $data) in 1) ${PROJECT_NAME}-restore-remote $remote_domain_name;; 2) return;; 3) ${PROJECT_NAME}-restore-remote $remote_domain_name configuration;; 4) ${PROJECT_NAME}-restore-remote $remote_domain_name mariadb;; 5) ${PROJECT_NAME}-restore-remote $remote_domain_name letsencrypt;; 6) ${PROJECT_NAME}-restore-remote $remote_domain_name mutt;; 7) ${PROJECT_NAME}-restore-remote $remote_domain_name gpg;; 8) ${PROJECT_NAME}-restore-remote $remote_domain_name procmail;; 9) ${PROJECT_NAME}-restore-remote $remote_domain_name spamassassin;; 10) ${PROJECT_NAME}-restore-remote $remote_domain_name readme;; 11) ${PROJECT_NAME}-restore-remote $remote_domain_name ipfs;; 12) ${PROJECT_NAME}-restore-remote $remote_domain_name ssh;; 13) ${PROJECT_NAME}-restore-remote $remote_domain_name userconfig;; 14) ${PROJECT_NAME}-restore-remote $remote_domain_name userlocal;; 15) ${PROJECT_NAME}-restore-remote $remote_domain_name userfin;; 16) ${PROJECT_NAME}-restore-remote $remote_domain_name certs;; 17) ${PROJECT_NAME}-restore-remote $remote_domain_name personal;; 18) ${PROJECT_NAME}-restore-remote $remote_domain_name mailinglist;; 19) ${PROJECT_NAME}-restore-remote $remote_domain_name xmpp;; 20) ${PROJECT_NAME}-restore-remote $remote_domain_name gnusocial;; 21) ${PROJECT_NAME}-restore-remote $remote_domain_name hubzilla;; 22) ${PROJECT_NAME}-restore-remote $remote_domain_name syncthing;; 23) ${PROJECT_NAME}-restore-remote $remote_domain_name gogs;; 24) ${PROJECT_NAME}-restore-remote $remote_domain_name wiki;; 25) ${PROJECT_NAME}-restore-remote $remote_domain_name blog;; 26) ${PROJECT_NAME}-restore-remote $remote_domain_name cjdns;; 27) ${PROJECT_NAME}-restore-remote $remote_domain_name email;; 28) ${PROJECT_NAME}-restore-remote $remote_domain_name dlna;; 29) ${PROJECT_NAME}-restore-remote $remote_domain_name voip;; 30) ${PROJECT_NAME}-restore-remote $remote_domain_name ttrss;; 31) ${PROJECT_NAME}-restore-remote $remote_domain_name tox;; esac done any_key } function restore_data { dialog --title $"Restore data from USB" \ --msgbox $"Plug in your backup USB drive" 6 40 clear echo ' ' echo $'Enter the passphrase for your LUKS encrypted backup drive:' restore_from_usb } function restore_data_remote { if [ ! $ADMIN_USER ]; then dialog --title $"Restore data from remote server" \ --msgbox $"Unknown admin user" 6 40 return fi data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --title $"Restore from remote server" \ --backtitle $"Freedombone Control Panel" \ --inputbox $"Enter the domain name of the server from which you wish to restore" 8 60 2>$data sel=$? case $sel in 0) friend_server_domain_name=$(<$data) if [ ${#friend_server_domain_name} -lt 2 ]; then return fi if [[ $friend_server_domain_name != *"."* ]]; then dialog --title $"Remote server domain name" \ --msgbox $"Invalid domain name" 6 40 return fi restore_from_remote $friend_server_domain_name ;; esac } function ping_enable_disable { ping_str=$"\nDo you want to enable other systems to ping this machine?\n\nPing may be useful for diagnostic purposes, but for added security you may not want to enable it." enable_ping="no" dialog --title $"Enable Ping / ICMP" \ --backtitle $"Freedombone Control Panel" \ --defaultno \ --yesno "$ping_str" 10 60 sel=$? case $sel in 0) enable_ping="yes";; 255) return;; esac if [[ $enable_ping == "yes" ]]; then iptables -A INPUT -p icmp --icmp-type echo-request -j ACCEPT iptables -A OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT echo "0" > /proc/sys/net/ipv4/icmp_echo_ignore_all else iptables -D INPUT -p icmp --icmp-type echo-request -j ACCEPT iptables -D OUTPUT -p icmp --icmp-type echo-reply -j ACCEPT echo "1" > /proc/sys/net/ipv4/icmp_echo_ignore_all fi } function logging_on_off { logging="no" dialog --title $"Logging" \ --backtitle $"Freedombone Control Panel" \ --yesno $"\nDo you want to turn logging on?" 7 60 sel=$? case $sel in 0) logging="yes";; 255) return;; esac clear echo '' echo $'This may take a few seconds. Please wait...' if [[ $logging == "no" ]]; then ${PROJECT_NAME}-logging off else ${PROJECT_NAME}-logging on fi } function restore_gpg_key { select_user if [ ! $SELECTED_USERNAME ]; then return fi restorestr=$"Restore GPG key for user" dialog --title "$restorestr $SELECTED_USERNAME" \ --msgbox $"Plug in your USB keydrive" 6 40 clear ${PROJECT_NAME}-recoverkey -u $SELECTED_USERNAME any_key } function security_settings { ${PROJECT_NAME}-sec any_key } function reset_tripwire { if [ ! -f /usr/bin/reset-tripwire ]; then return fi clear echo $'Resetting the Tripwire...' echo ' ' echo ' ' | reset-tripwire any_key } function format_drive { drive= data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --backtitle $"Freedombone Control Panel" \ --title $"Format a USB drive (LUKS encrypted)" \ --radiolist $"Choose a drive:" 12 70 5 \ 1 $"sda (Beaglebone Black)" off \ 2 $"sdb" off \ 3 $"sdc" off \ 4 $"sdd" off \ 5 $"Back to Backup and Restore menu" on 2> $data sel=$? case $sel in 1) return;; 255) return;; esac case $(cat $data) in 1) drive='sda';; 2) drive='sdb';; 3) drive='sdc';; 4) drive='sdd';; 5) return;; esac dialog --title $"Format USB drive" \ --backtitle $"Freedombone Control Panel" \ --defaultno \ --yesno $"\nPlease confirm that you wish to format drive\n\n ${drive}\n\nAll current data on the drive will be lost, and you will be prompted to give a password used to encrypt the drive.\n\nDANGER: If you screw up here and format the wrong drive it's your own fault!" 16 60 sel=$? case $sel in 1) return;; 255) return;; esac clear ${PROJECT_NAME}-format $drive any_key } function remove_backups { drive= data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --backtitle $"Freedombone Control Panel" \ --title $"Remove backups from a USB drive" \ --radiolist $"Choose a drive:" 12 70 5 \ 1 $"sda (Beaglebone Black)" off \ 2 $"sdb" off \ 3 $"sdc" off \ 4 $"sdd" off \ 5 $"Back to Backup and Restore menu" on 2> $data sel=$? case $sel in 1) return;; 255) return;; esac case $(cat $data) in 1) drive='sda';; 2) drive='sdb';; 3) drive='sdc';; 4) drive='sdd';; 5) return;; esac dialog --title $"Remove backups from a USB drive" \ --backtitle $"Freedombone Control Panel" \ --defaultno \ --yesno $"\nPlease confirm that you wish to remove backups from this drive\n\n ${drive}\n\nYou will not be able to recover them afterwards." 12 60 sel=$? case $sel in 1) return;; 255) return;; esac clear ${PROJECT_NAME}-backup-local $drive remove any_key } function shut_down_system { dialog --title $"Power off the system" \ --backtitle $"Freedombone Control Panel" \ --defaultno \ --yesno $"\nPlease confirm that you wish to power off the system.\n\nWARNING: to power on again you will need to have physical access to the hardware." 10 60 sel=$? case $sel in 1) return;; 255) return;; esac shutdown now } function restart_system { dialog --title $"Restart the system" \ --backtitle $"Freedombone Control Panel" \ --defaultno \ --yesno $"\nPlease confirm that you wish to restart the system.\n\nWARNING: If you are using full disk encryption then you will need physical access to the hardware to type in the password" 10 60 sel=$? case $sel in 1) return;; 255) return;; esac reboot } function change_system_name { data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --title $"Change the name of this system" \ --backtitle $"Freedombone Control Panel" \ --inputbox $'Enter a new name for this system on your local network\n\nIt will appear as newname.local' 10 60 2>$data sel=$? case $sel in 0) NEW_SYSTEM_NAME=$(<$data) if [ "$NEW_SYSTEM_NAME" ]; then if [ ${#NEW_SYSTEM_NAME} -gt 1 ]; then sed -i "s|host-name=.*|host-name=$NEW_SYSTEM_NAME|g" /etc/avahi/avahi-daemon.conf systemctl restart avahi-daemon if grep -q "host-name=$NEW_SYSTEM_NAME" /etc/avahi/avahi-daemon.conf; then dialog --title $"New local network name" \ --msgbox $"The name of this system on your local network was changed successfully" 6 70 fi fi fi ;; esac } function set_tls_time_source { TLS_DATE_SOURCE=$(cat /usr/bin/updatedate | grep "TIMESOURCE='" | awk -F '=' '{print $2}' | awk -F "'" '{print $2}') data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --title $"Set the TLS date/time source" \ --backtitle $"Freedombone Control Panel" \ --inputbox $"Enter a domain name to use as a TLS time source.\n\nFactors to consider when choosing a source are whether you wish that site to know that your system is 'alive' and also what might happen if an adversary were to try to mess with the date/time from that domain (i.e. how much blowback would there be)." 14 60 "$TLS_DATE_SOURCE" 2>$data sel=$? case $sel in 0) NEW_TLS_DATE_SOURCE=$(<$data) if [[ $NEW_TLS_DATE_SOURCE == *"."* && $NEW_TLS_DATE_SOURCE != *'/'* ]]; then if [[ $NEW_TLS_DATE_SOURCE != "http"* ]]; then sed -i "s|TIMESOURCE='.*|TIMESOURCE='${NEW_TLS_DATE_SOURCE}'|g" $UPDATE_DATE_SCRIPT else dialog --title $"Invalid domain name" \ --msgbox $"Don't include the 'https'" 6 70 fi else dialog --title $"Invalid domain name" \ --msgbox $"That doesn't look like a domain name" 6 70 fi ;; esac } function set_static_IP { STATIC_IP='192.168.1.60' STATIC_GATEWAY='192.168.1.1' NEW_STATIC_IP= NEW_STATIC_GATEWAY= if grep -q 'iface eth0 inet static' /etc/network/interfaces; then STATIC_IP=$(cat /etc/network/interfaces | grep "address " | awk -F ' ' '{print $2}' | head -n 1) STATIC_GATEWAY=$(cat /etc/network/interfaces | grep "gateway " | awk -F ' ' '{print $2}' | head -n 1) fi # get the IP for the box data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --title $"Set a static local IP address" \ --backtitle $"Freedombone Control Panel" \ --inputbox $"In order to forward incoming internet traffic to this system most internet routers need to know a static local IP address to send the data to.\n\n Enter a static local IP address for this system.\n\nIt will typically be 192.168.1.x" 15 60 "$STATIC_IP" 2>$data sel=$? case $sel in 0) NEW_STATIC_IP=$(<$data) if [[ "$NEW_STATIC_IP" != *"."* ]]; then return fi if grep -q 'iface eth0 inet static' /etc/network/interfaces; then if [[ "$NEW_STATIC_IP" != "$STATIC_IP" ]]; then sed -i "s|${STATIC_IP}|${NEW_STATIC_IP}|g" /etc/network/interfaces fi fi ;; esac # get the gateway data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --title $"Set the IP address of your internet router/modem" \ --backtitle $"Freedombone Control Panel" \ --inputbox $"Set the local IP address for your internet router or ADSL modem.\n\nIt will typically be 192.168.1.1, 192.168.1.254, or similar" 12 60 "$STATIC_GATEWAY" 2>$data sel=$? case $sel in 0) NEW_STATIC_GATEWAY=$(<$data) if [[ "$NEW_STATIC_GATEWAY" != *"."* ]]; then return fi if grep -q 'iface eth0 inet static' /etc/network/interfaces; then if [[ "$NEW_STATIC_GATEWAY" != "$STATIC_GATEWAY" ]]; then sed -i "s|${STATIC_GATEWAY}|${NEW_STATIC_GATEWAY}|g" /etc/network/interfaces fi return fi ;; esac if ! grep -q 'iface eth0 inet static' /etc/network/interfaces; then if [ "$NEW_STATIC_GATEWAY" && "$NEW_STATIC_IP" ]; then echo '# This file describes the network interfaces available on your system' > /etc/network/interfaces echo '# and how to activate them. For more information, see interfaces(5).' >> /etc/network/interfaces echo '' >> /etc/network/interfaces echo '# The loopback network interface' >> /etc/network/interfaces echo 'auto lo' >> /etc/network/interfaces echo 'iface lo inet loopback' >> /etc/network/interfaces echo '' >> /etc/network/interfaces echo '# The primary network interface' >> /etc/network/interfaces echo 'auto eth0' >> /etc/network/interfaces echo 'iface eth0 inet static' >> /etc/network/interfaces echo " address ${NEW_STATIC_IP}" >> /etc/network/interfaces echo ' netmask 255.255.255.0' >> /etc/network/interfaces echo " gateway ${NEW_STATIC_GATEWAY}" >> /etc/network/interfaces echo " dns-nameservers 213.73.91.35 85.214.20.141" >> /etc/network/interfaces echo '# Example to keep MAC address between reboots' >> /etc/network/interfaces echo '#hwaddress ether DE:AD:BE:EF:CA:FE' >> /etc/network/interfaces echo '' >> /etc/network/interfaces echo '# The secondary network interface' >> /etc/network/interfaces echo '#auto eth1' >> /etc/network/interfaces echo '#iface eth1 inet dhcp' >> /etc/network/interfaces echo '' >> /etc/network/interfaces echo '# WiFi Example' >> /etc/network/interfaces echo "#auto $WIFI_INTERFACE" >> /etc/network/interfaces echo "#iface $WIFI_INTERFACE inet dhcp" >> /etc/network/interfaces echo '# wpa-ssid "essid"' >> /etc/network/interfaces echo '# wpa-psk "password"' >> /etc/network/interfaces echo '' >> /etc/network/interfaces echo '# Ethernet/RNDIS gadget (g_ether)' >> /etc/network/interfaces echo '# ... or on host side, usbnet and random hwaddr' >> /etc/network/interfaces echo '# Note on some boards, usb0 is automaticly setup with an init script' >> /etc/network/interfaces echo '#iface usb0 inet static' >> /etc/network/interfaces echo '# address 192.168.7.2' >> /etc/network/interfaces echo '# netmask 255.255.255.0' >> /etc/network/interfaces echo '# network 192.168.7.0' >> /etc/network/interfaces echo '# gateway 192.168.7.1' >> /etc/network/interfaces fi fi } function wifi_settings { if [ -f /etc/hostapd/hostapd.conf ]; then return fi TEMP_WIFI_NETWORKS_FILE=~/.temp-${PROJECT_NAME}-wifi.cfg ${PROJECT_NAME}-wifi --networksinteractive $TEMP_WIFI_NETWORKS_FILE if [ -f $TEMP_WIFI_NETWORKS_FILE ]; then cp $TEMP_WIFI_NETWORKS_FILE $WIFI_NETWORKS_FILE rm $TEMP_WIFI_NETWORKS_FILE ${PROJECT_NAME}-wifi --networks $WIFI_NETWORKS_FILE dialog --title $"Wifi Settings" \ --msgbox $"Wifi settings were changed" 6 40 fi } function wifi_edit_networks { if [ -f /etc/hostapd/hostapd.conf ]; then return fi if [ ! -f $WIFI_NETWORKS_FILE ]; then echo $'# Add wifi networks as follows:' > $WIFI_NETWORKS_FILE echo '#' >> $WIFI_NETWORKS_FILE echo $'# MySSID' >> $WIFI_NETWORKS_FILE echo $'# wpa2-psk' >> $WIFI_NETWORKS_FILE echo $'# myWifiPassphrase' >> $WIFI_NETWORKS_FILE echo '#' >> $WIFI_NETWORKS_FILE echo $'# AnotherSSID' >> $WIFI_NETWORKS_FILE echo $'# none' >> $WIFI_NETWORKS_FILE echo '#' >> $WIFI_NETWORKS_FILE fi editor $WIFI_NETWORKS_FILE ${PROJECT_NAME}-wifi --networks $WIFI_NETWORKS_FILE } function hotspot_settings { data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --backtitle $"Freedombone Control Panel" \ --title $"Hotspot Settings" \ --form $"" 10 60 4 \ $"Enabled (yes/no):" 1 1 "$WIFI_HOTSPOT" 1 24 5 5 \ $"SSID:" 2 1 "$WIFI_SSID" 2 24 256 256 \ $"Type (wpa2-psk/none):" 3 1 "$WIFI_TYPE" 3 24 10 10 \ $"Passphrase:" 4 1 "$WIFI_PASSPHRASE" 4 24 256 256 \ 2> $data sel=$? case $sel in 1) return;; 255) return;; esac TEMP_WIFI_HOTSPOT=$(cat $data | sed -n 1p) TEMP_WIFI_SSID=$(cat $data | sed -n 2p) TEMP_WIFI_TYPE=$(cat $data | sed -n 3p) TEMP_WIFI_PASSPHRASE=$(cat $data | sed -n 4p) if [ ${#TEMP_WIFI_SSID} -lt 2 ]; then return fi if [ ${#TEMP_WIFI_TYPE} -lt 2 ]; then return fi WIFI_EXTRA='' if [[ $TEMP_WIFI_HOTSPOT == $'yes' || $TEMP_WIFI_HOTSPOT == $'y' || $TEMP_WIFI_HOTSPOT == $'on' ]]; then TEMP_WIFI_HOTSPOT='yes' else TEMP_WIFI_HOTSPOT='no' if [ -f $WIFI_NETWORKS_FILE ]; then WIFI_EXTRA='--networks $WIFI_NETWORKS_FILE' fi fi if [[ $TEMP_WIFI_TYPE != $'none' ]]; then if [ ! $TEMP_WIFI_PASSPHRASE ]; then dialog --title $"Wifi Settings" \ --msgbox $"No wifi hotspot passphrase was given" 6 40 return fi if [ ${#TEMP_WIFI_PASSPHRASE} -lt 2 ]; then dialog --title $"Wifi Settings" \ --msgbox $"Wifi hotspot passphrase was too short" 6 40 return fi WIFI_HOTSPOT=$TEMP_WIFI_HOTSPOT WIFI_SSID=$TEMP_WIFI_SSID WIFI_TYPE=$TEMP_WIFI_TYPE WIFI_PASSPHRASE=$TEMP_WIFI_PASSPHRASE ${PROJECT_NAME}-wifi -i $WIFI_INTERFACE -s $WIFI_SSID -t $WIFI_TYPE -p $WIFI_PASSPHRASE --hotspot $WIFI_HOTSPOT $WIFI_EXTRA else WIFI_HOTSPOT=$TEMP_WIFI_HOTSPOT WIFI_SSID=$TEMP_WIFI_SSID WIFI_TYPE=$TEMP_WIFI_TYPE WIFI_PASSPHRASE=$TEMP_WIFI_PASSPHRASE ${PROJECT_NAME}-wifi -i $WIFI_INTERFACE -s $WIFI_SSID -t $WIFI_TYPE --hotspot $WIFI_HOTSPOT $WIFI_EXTRA fi # store any changes if ! grep -q "WIFI_HOTSPOT" $CONFIGURATION_FILE; then echo "WIFI_HOTSPOT=$WIFI_HOTSPOT" >> $CONFIGURATION_FILE else sed -i "s|WIFI_HOTSPOT=.*|WIFI_HOTSPOT=$WIFI_HOTSPOT|g" $CONFIGURATION_FILE fi if ! grep -q "WIFI_SSID" $CONFIGURATION_FILE; then echo "WIFI_SSID=$WIFI_SSID" >> $CONFIGURATION_FILE else sed -i "s|WIFI_SSID=.*|WIFI_SSID=$WIFI_SSID|g" $CONFIGURATION_FILE fi if ! grep -q "WIFI_TYPE" $CONFIGURATION_FILE; then echo "WIFI_TYPE=$WIFI_TYPE" >> $CONFIGURATION_FILE else sed -i "s|WIFI_TYPE=.*|WIFI_SSID=$WIFI_TYPE|g" $CONFIGURATION_FILE fi if ! grep -q "WIFI_PASSPHRASE" $CONFIGURATION_FILE; then echo "WIFI_PASSPHRASE=$WIFI_PASSPHRASE" >> $CONFIGURATION_FILE else sed -i "s|WIFI_PASSPHRASE=.*|WIFI_PASSPHRASE=$WIFI_PASSPHRASE|g" $CONFIGURATION_FILE fi dialog --title $"Wifi Settings" \ --msgbox $"Hotspot settings were changed" 6 40 } function reinstall_mariadb { dialog --title $"Reinstall MariaDB" \ --backtitle $"Freedombone Control Panel" \ --defaultno \ --yesno $"\nThis should be a LAST RESORT, if the mysql daemon won't start. You will lose ALL databases and will then need to restore them from backup.\n\nAre you sure that you wish to continue?" 12 60 sel=$? case $sel in 1) return;; 255) return;; esac clear database_reinstall dialog --title $"Reinstall MariaDB" \ --msgbox $"MariaDB has been reinstalled" 6 40 } function menu_backup_restore { while true do data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --backtitle $"Freedombone Control Panel" \ --title $"Backup and Restore" \ --radiolist $"Choose an operation:" 19 70 12 \ 1 $"Backup data to USB drive" off \ 2 $"Restore GPG key from USB keydrive" off \ 3 $"Restore data from USB drive" off \ 4 $"Reinstall mariadb" off \ 5 $"Configure remote backups" off \ 6 $"Restore from remote backup" off \ 7 $"Backup GPG key to USB (master keydrive)" off \ 8 $"Backup GPG key to USB (fragment keydrive)" off \ 9 $"Format a USB drive (LUKS encrypted)" off \ 10 $"Remove backups from a USB drive" off \ 11 $"Back to main menu" on 2> $data sel=$? case $sel in 1) break;; 255) break;; esac case $(cat $data) in 1) backup_data;; 2) restore_gpg_key;; 3) restore_data;; 4) reinstall_mariadb;; 5) configure_remote_backups;; 6) restore_data_remote;; 7) create_keydrive_master;; 8) create_keydrive_fragment;; 9) format_drive;; 10) remove_backups;; 11) break;; esac done } function menu_email { while true do data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --backtitle $"Freedombone Control Panel" \ --title $"Email Filtering Rules" \ --radiolist $"Choose an operation:" 13 70 6 \ 1 $"Add a user to a mailing list" off \ 2 $"Remove a user from a mailing list" off \ 3 $"Add an email rule" off \ 4 $"Block/Unblock an email address" off \ 5 $"Block/Unblock email with subject text" off \ 6 $"Back to main menu" on 2> $data sel=$? case $sel in 1) break;; 255) break;; esac case $(cat $data) in 1) add_to_mailing_list;; 2) remove_user_from_mailing_list;; 3) email_rule;; 4) block_unblock_email;; 5) block_unblock_subject;; 6) break;; esac done } function menu_users { while true do data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --backtitle $"Freedombone Control Panel" \ --title $"Manage Users" \ --radiolist $"Choose an operation:" 12 70 5 \ 1 $"Add a user" off \ 2 $"Delete a user" off \ 3 $"Change user password" off \ 4 $"Change user ssh public key" off \ 5 $"Back to main menu" on 2> $data sel=$? case $sel in 1) break;; 255) break;; esac case $(cat $data) in 1) add_user;; 2) delete_user;; 3) change_password;; 4) change_ssh_public_key;; 5) break;; esac done } function wifi_enable { disable_wifi='yes' dialog --title $"Enable Wifi" \ --backtitle $"Freedombone Control Panel" \ --defaultno \ --yesno $"\nDo you wish to enable wifi?" 10 50 sel=$? case $sel in 0) disable_wifi='no';; 1) disable_wifi='yes';; 255) return;; esac ${PROJECT_NAME}-wifi --disable $disable_wifi } function menu_wifi { while true do status_str=$'Wifi OFF' if [ -f /etc/hostapd/hostapd.conf ]; then status_str=$'Hotspot ON' else if grep -q "# wifi enabled" /etc/network/interfaces; then status_str=$'Wifi ON' fi fi data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --backtitle $"Freedombone Control Panel" \ --title $"Wifi Menu" \ --radiolist $"${status_str}\n\nChoose an operation:" 14 70 6 \ 1 $"Enable or disable Wifi" off \ 2 $"Configure wifi networks" off \ 3 $"Manually edit wifi networks file" off \ 4 $"Hotspot settings" off \ 5 $"Exit" on 2> $data sel=$? case $sel in 1) break;; 255) break;; esac case $(cat $data) in 1) wifi_enable;; 2) wifi_settings;; 3) wifi_edit_networks;; 4) hotspot_settings;; 5) break;; esac done } function app_settings { detect_installable_apps applist="" appnames=() n=1 app_index=0 for a in "${APPS_AVAILABLE[@]}" do if [[ ${APPS_INSTALLED[$app_index]} != "0" ]]; then if [[ $(function_exists configure_interactive_${a}) == "1" ]]; then applist="$applist $n $a off" n=$[n+1] appnames+=("$a") fi fi app_index=$[app_index+1] done backstr=$'Exit' applist="$applist $n $backstr on" appnames+=("Exit") choice=$(dialog --stdout --backtitle $"Freedombone" \ --title $"Change Settings for an App" \ --radiolist $'Choose:' \ 27 40 20 $applist) if [ $? -eq 0 ]; then app_index=$[choice-1] chosen_app=${appnames[$app_index]} if [[ $chosen_app != "Exit" ]]; then configure_interactive_${chosen_app} fi fi } function menu_top_level { while true do data=$(tempfile 2>/dev/null) trap "rm -f $data" 0 1 2 5 15 dialog --backtitle $"Freedombone Control Panel" \ --title $"Control Panel" \ --radiolist $"Choose an operation:" 29 70 22 \ 1 $"About this system" off \ 2 $"Backup and Restore" off \ 3 $"Reset Tripwire" off \ 4 $"App Settings" off \ 5 $"Logging on/off" off \ 6 $"Ping enable/disable" off \ 7 $"Manage Users" off \ 8 $"Email Filtering Rules" off \ 9 $"Outgoing Email Proxy" off \ 10 $"Security Settings" off \ 11 $"Set the main repository (repo mirrors)" off \ 12 $"Change the name of this system" off \ 13 $"Set the TLS date/time source" off \ 14 $"Set a static local IP address" off \ 15 $"Wifi menu" off \ 16 $"Check for updates" off \ 17 $"Power off the system" off \ 18 $"Restart the system" off \ 19 $"Exit" on 2> $data sel=$? case $sel in 1) exit 1;; 255) exit 1;; esac case $(cat $data) in 1) show_about;; 2) menu_backup_restore;; 3) reset_tripwire;; 4) app_settings;; 5) logging_on_off;; 6) ping_enable_disable;; 7) menu_users;; 8) menu_email;; 9) smtp_proxy;; 10) security_settings;; 11) set_main_repo;; 12) change_system_name;; 13) set_tls_time_source;; 14) set_static_IP;; 15) menu_wifi;; 16) check_for_updates;; 17) shut_down_system;; 18) restart_system;; 19) break;; esac done } if [[ $USER != 'root' ]]; then # show the user version of the control panel ${PROJECT_NAME}-controlpanel-user exit 0 fi if [ ! -f $COMPLETION_FILE ]; then echo $'This command should only be run on an installed Freedombone system' exit 1 fi ADMIN_USER=$(cat $COMPLETION_FILE | grep "Admin user" | awk -F ':' '{print $2}') read_repo_servers menu_top_level clear cat /etc/motd exit 0