#!/bin/bash # _____ _ _ # | __|___ ___ ___ _| |___ _____| |_ ___ ___ ___ # | __| _| -_| -_| . | . | | . | . | | -_| # |__| |_| |___|___|___|___|_|_|_|___|___|_|_|___| # # Freedom in the Cloud # # Interactively creates a configuration file for use with the main # freedombone command # # License # ======= # # Copyright (C) 2015-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 . NO_OF_ARGS=$# PROJECT_NAME='freedombone' # username created by default within a debian image GENERIC_IMAGE_USERNAME='fbone' export TEXTDOMAIN=${PROJECT_NAME}-config export TEXTDOMAINDIR="/usr/share/locale" # Web site FREEDOMBONE_WEBSITE="https://freedombone.net or http://4fvfozz6g3zmvf76.onion" # Minimum number of characters in a password MINIMUM_PASSWORD_LENGTH=$(grep 'MINIMUM_PASSWORD_LENGTH=' "/usr/share/${PROJECT_NAME}/utils/${PROJECT_NAME}-utils-passwords" | head -n 1 | awk -F '=' '{print $2}') # file containing new password IMAGE_PASSWORD_FILE=/root/login.txt MY_USERNAME= DEFAULT_DOMAIN_NAME= DEFAULT_DOMAIN_CODE= MY_EMAIL_ADDRESS= SYSTEM_TYPE='full' INSTALLING_ON_BBB="no" DDNS_PROVIDER= DDNS_USERNAME= DDNS_PASSWORD= MY_NAME= LOCAL_NETWORK_STATIC_IP_ADDRESS= ROUTER_IP_ADDRESS= ENABLE_BATMAN= DEBIAN_REPO= NAMESERVER1= NAMESERVER2= DOKUWIKI_TITLE= DOKUWIKI_DOMAIN_NAME= DOKUWIKI_CODE= HTMLY_TITLE= HTMLY_DOMAIN_NAME= HTMLY_CODE= HUBZILLA_DOMAIN_NAME= HUBZILLA_CODE= GNUSOCIAL_DOMAIN_NAME= GNUSOCIAL_CODE= GNUSOCIAL_WELCOME_MESSAGE=$"

Welcome to \$GNUSOCIAL_DOMAIN_NAME a federated social network

Another $PROJECT_NAME site

" GNUSOCIAL_BACKGROUND_IMAGE_URL= GIT_DOMAIN_NAME= GIT_CODE= USB_DRIVE=/dev/sdb1 HWRNG_TYPE= ENABLE_SOCIAL_KEY_MANAGEMENT= WIFI_INTERFACE=wlan0 WIFI_TYPE='wpa2-psk' WIFI_SSID= WIFI_PASSPHRASE= WIFI_HOTSPOT= WIFI_NETWORKS_FILE=~/${PROJECT_NAME}-wifi.cfg BATMAN_CELLID='any' WIFI_CHANNEL= CONFIGURATION_FILE= DH_KEYLENGTH= MINIMAL_INSTALL="yes" DEFAULT_LANGUAGE='en_GB.UTF-8' ONION_ONLY="no" SELECTED_USERNAME= SOCIALINSTANCE= VALID_CODE= PROJECT_INSTALL_DIR=/usr/local/bin if [ -f /usr/bin/${PROJECT_NAME} ]; then PROJECT_INSTALL_DIR=/usr/bin fi function please_wait { local str width height length width=$(tput cols) height=$(tput lines) str=$"Please wait" length=${#str} clear tput cup $((height / 2)) $(((width / 2) - (length / 2))) echo "$str" tput cup $((height * 3 / 5)) $(((width / 2))) echo -n '' } source "$PROJECT_INSTALL_DIR/${PROJECT_NAME}-vars" 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 function show_help { echo '' echo $"${PROJECT_NAME}-config -f [config filename] -m [min password length]" echo '' echo $'Creates an inventory of remote backup locations' echo '' echo '' echo $' -h --help Show help' echo $" -f --filename Configuration file (usually ${PROJECT_NAME}.cfg)" echo $' -m --min Minimum password length (characters)' echo $' -w --www Freedombone web site' echo $' -o --onion [yes|no] Whether to only create .onion sites' echo $' --minimal [yes|no] For minimalistic "consumer grade" installs' echo $' --social [gnusocial|postactiv] Create gnusocial/postactiv instance' echo '' exit 0 } function choose_email_address { if [[ $ONION_ONLY != "no" ]]; then EMAIL_ADDRESS=$MY_USERNAME@$DEFAULT_DOMAIN_NAME else while [ ${#MY_EMAIL_ADDRESS} -lt 5 ] do EMAIL_ADDRESS=$(grep 'MY_EMAIL_ADDRESS' temp.cfg | awk -F '=' '{print $2}') if [ ! "$EMAIL_ADDRESS" ]; then EMAIL_ADDRESS=$MY_USERNAME@$DEFAULT_DOMAIN_NAME fi if [ ${#MY_EMAIL_ADDRESS} -lt 5 ]; then EMAIL_ADDRESS=$MY_USERNAME@$DEFAULT_DOMAIN_NAME fi data=$(mktemp 2>/dev/null) dialog --backtitle $"Freedombone Configuration" \ --inputbox $"Your email address" 10 30 "$EMAIL_ADDRESS" 2> "$data" sel=$? case $sel in 0) MY_EMAIL_ADDRESS=$(cat "$data");; 1) rm -f "$data" exit 1;; 255) rm -f "$data" exit 1;; esac rm -f "$data" done fi save_configuration_values } function choose_social_instance_domain_name { DEFAULT_DOMAIN_DETAILS_COMPLETE= while [ ! $DEFAULT_DOMAIN_DETAILS_COMPLETE ] do data=$(mktemp 2>/dev/null) if [[ "$DDNS_PROVIDER" == "default@freedns.afraid.org" ]]; then dialog --backtitle $"Freedombone Configuration" \ --title $"Instance domain" \ --form $"\\nEnter your instance domain name and its FreeDNS code:" 11 55 3 \ $"Domain:" 1 1 "$(grep 'DEFAULT_DOMAIN_NAME' temp.cfg | awk -F '=' '{print $2}')" 1 24 33 40 \ $"Code:" 2 1 "$(grep 'DEFAULT_DOMAIN_CODE' temp.cfg | awk -F '=' '{print $2}')" 2 24 33 255 \ 2> "$data" sel=$? case $sel in 1) rm -f "$data" exit 1;; 255) rm -f "$data" exit 1;; esac DEFAULT_DOMAIN_NAME=$(sed -n 1p < "$data") DEFAULT_DOMAIN_CODE=$(sed -n 2p < "$data") if [ "$DEFAULT_DOMAIN_NAME" ]; then validate_freedns_code "$DEFAULT_DOMAIN_CODE" if [ ! $VALID_CODE ]; then DEFAULT_DOMAIN_NAME= fi fi else dialog --backtitle $"Freedombone Configuration" \ --inputbox $"Enter your instance domain name:" 10 45 \ "$(grep 'DEFAULT_DOMAIN_NAME' temp.cfg | awk -F '=' '{print $2}')" 2> "$data" sel=$? case $sel in 0) DEFAULT_DOMAIN_NAME=$(cat "$data");; 1) rm -f "$data" exit 1;; 255) rm -f "$data" exit 1;; esac fi if [ "$DEFAULT_DOMAIN_NAME" ]; then TEST_DOMAIN_NAME=$DEFAULT_DOMAIN_NAME validate_domain_name if [[ "$TEST_DOMAIN_NAME" != "$DEFAULT_DOMAIN_NAME" ]]; then DEFAULT_DOMAIN_NAME= dialog --title $"Domain name validation" --msgbox "$TEST_DOMAIN_NAME" 15 50 else DEFAULT_DOMAIN_DETAILS_COMPLETE="yes" fi fi rm -f "$data" done save_configuration_values } function choose_default_domain_name { if [ $SOCIALINSTANCE ]; then choose_social_instance_domain_name return fi if [[ $ONION_ONLY != "no" ]]; then DEFAULT_DOMAIN_NAME="${LOCAL_NAME}.local" else DEFAULT_DOMAIN_DETAILS_COMPLETE= while [ ! $DEFAULT_DOMAIN_DETAILS_COMPLETE ] do data=$(mktemp 2>/dev/null) if [[ "$DDNS_PROVIDER" == "default@freedns.afraid.org" ]]; then dialog --backtitle $"Freedombone Configuration" \ --title $"Your main domain name" \ --form $"\nWhich domain name should your email/XMPP/IRC/Mumble be associated with?" 13 55 5 \ $"Domain:" 1 1 "$(grep 'DEFAULT_DOMAIN_NAME' temp.cfg | awk -F '=' '{print $2}')" 1 24 33 40 \ $"Code:" 2 1 "$(grep 'DEFAULT_DOMAIN_CODE' temp.cfg | awk -F '=' '{print $2}')" 2 24 33 255 \ $"mail subdomain Code:" 3 1 "$(grep 'EMAIL_DOMAIN_CODE' temp.cfg | awk -F '=' '{print $2}')" 3 24 33 255 \ $"XMPP subdomain Code:" 4 1 "$(grep 'XMPP_DOMAIN_CODE' temp.cfg | awk -F '=' '{print $2}')" 4 24 33 255 \ 2> "$data" sel=$? case $sel in 1) rm -f "$data" exit 1;; 255) rm -f "$data" exit 1;; esac DEFAULT_DOMAIN_NAME=$(sed -n 1p < "$data") DEFAULT_DOMAIN_CODE=$(sed -n 2p < "$data") EMAIL_DOMAIN_CODE=$(sed -n 3p < "$data") XMPP_DOMAIN_CODE=$(sed -n 4p < "$data") rm -f "$data" if [ "$DEFAULT_DOMAIN_NAME" ]; then validate_freedns_code "$DEFAULT_DOMAIN_CODE" if [ ! $VALID_CODE ]; then DEFAULT_DOMAIN_NAME= fi fi if [ "$EMAIL_DOMAIN_CODE" ]; then validate_freedns_code "$EMAIL_DOMAIN_CODE" if [ ! $VALID_CODE ]; then DEFAULT_DOMAIN_NAME= EMAIL_DOMAIN_CODE= else write_config_param "EMAIL_DOMAIN_CODE" "$EMAIL_DOMAIN_CODE" fi fi if [ "$XMPP_DOMAIN_CODE" ]; then validate_freedns_code "$XMPP_DOMAIN_CODE" if [ ! $VALID_CODE ]; then DEFAULT_DOMAIN_NAME= XMPP_DOMAIN_CODE= else write_config_param "XMPP_DOMAIN_CODE" "$XMPP_DOMAIN_CODE" fi fi else dialog --backtitle $"Freedombone Configuration" \ --inputbox $"Which domain name should your email/XMPP/IRC/Mumble be associated with?" 10 45 \ "$(grep 'DEFAULT_DOMAIN_NAME' temp.cfg | awk -F '=' '{print $2}')" 2> "$data" sel=$? case $sel in 0) DEFAULT_DOMAIN_NAME=$(cat "$data");; 1) rm -f "$data" exit 1;; 255) rm -f "$data" exit 1;; esac fi if [ "$DEFAULT_DOMAIN_NAME" ]; then TEST_DOMAIN_NAME=$DEFAULT_DOMAIN_NAME validate_domain_name if [[ "$TEST_DOMAIN_NAME" != "$DEFAULT_DOMAIN_NAME" ]]; then DEFAULT_DOMAIN_NAME= dialog --title $"Domain name validation" --msgbox "$TEST_DOMAIN_NAME" 15 50 else DEFAULT_DOMAIN_DETAILS_COMPLETE="yes" fi fi done fi save_configuration_values } function dynamic_dns_setup { W=(1 freedns.afraid.org 2 dyn.com 3 zoneedit.com 4 no-ip.com 5 easydns.com 6 dnsomatic.com 7 dns.he.net 8 tunnelbroker.net 9 sitelutions.com 10 dnsexit.com 11 changeip.com 12 zerigo.com 13 dhis.org 14 nsupdate.info 15 loopia.com 16 namecheap.com 17 ovh.com 18 dtdns.com 19 giradns.com 20 duiadns.net 21 ddnss.de 22 dynv6.com 23 ipv4.dynv6.com 24 spdyn.de 25 freemyip.com 26 cloudxns.net) # shellcheck disable=SC2068 selection=$(dialog --backtitle $"Freedombone Configuration" --title $"Dynamic DNS" --menu $"Choose Dynamic DNS provider, or ESC for none:" 24 60 32 "${W[@]}" 3>&2 2>&1 1>&3) if [ ! "$selection" ]; then if [ -f /etc/systemd/system/inadyn.service ]; then systemctl stop inadyn systemctl disable inadyn fi return fi case $selection in 1) DDNS_PROVIDER="default@freedns.afraid.org";; 2) DDNS_PROVIDER="default@www.dyn.com";; 3) DDNS_PROVIDER="default@www.zoneedit.com";; 4) DDNS_PROVIDER="default@www.no-ip.com";; 5) DDNS_PROVIDER="default@www.easydns.com";; 6) DDNS_PROVIDER="default@www.dnsomatic.com";; 7) DDNS_PROVIDER="default@dns.he.net";; 8) DDNS_PROVIDER="default@www.tunnelbroker.net";; 9) DDNS_PROVIDER="default@www.sitelutions.com";; 10) DDNS_PROVIDER="default@www.dnsexit.com";; 11) DDNS_PROVIDER="default@www.changeip.com";; 12) DDNS_PROVIDER="default@www.zerigo.com";; 13) DDNS_PROVIDER="default@www.dhis.org";; 14) DDNS_PROVIDER="default@nsupdate.info";; 15) DDNS_PROVIDER="default@www.loopia.com";; 16) DDNS_PROVIDER="default@www.namecheap.com";; 17) DDNS_PROVIDER="default@www.ovh.com";; 18) DDNS_PROVIDER="default@www.dtdns.com";; 19) DDNS_PROVIDER="default@giradns.com";; 20) DDNS_PROVIDER="default@www.duiadns.net";; 21) DDNS_PROVIDER="default@ddnss.de";; 22) DDNS_PROVIDER="default@dynv6.com";; 23) DDNS_PROVIDER="default@ipv4.dynv6.com";; 24) DDNS_PROVIDER="default@spdyn.de";; 25) DDNS_PROVIDER="default@freemyip.com";; 26) DDNS_PROVIDER="default@www.cloudxns.net";; esac save_configuration_values valid_ddns_username= valid_ddns_password= if [[ "$DDNS_PROVIDER" == "none" ]]; then if [ -f /etc/systemd/system/inadyn.service ]; then systemctl stop inadyn systemctl disable inadyn fi else while [ ! $valid_ddns_username ] do data=$(mktemp 2>/dev/null) dialog --backtitle $"Freedombone Configuration" \ --inputbox $"Dynamic DNS provider username" 10 30 "$(grep 'DDNS_USERNAME' temp.cfg | awk -F '=' '{print $2}')" 2> "$data" sel=$? case $sel in 0) possible_username=$(cat "$data") if [ "$possible_username" ]; then if [ ${#possible_username} -gt 1 ]; then valid_ddns_username=$(cat "$data") # shellcheck disable=SC2034 DDNS_USERNAME="$valid_ddns_username" rm -f "$data" break; fi fi ;; 1) rm -f "$data" exit 1;; 255) rm -f "$data" exit 1;; esac rm -f "$data" done save_configuration_values while [ ! $valid_ddns_password ] do data=$(mktemp 2>/dev/null) dialog --backtitle $"Freedombone Configuration" \ --clear \ --insecure \ --passwordbox $"Dynamic DNS provider password" 10 30 "$(grep 'DDNS_PASSWORD' temp.cfg | awk -F '=' '{print $2}')" 2> "$data" sel=$? case $sel in 0) possible_password=$(cat "$data") if [ "$possible_password" ]; then if [ ${#possible_password} -gt 1 ]; then valid_ddns_password=$(cat "$data") DDNS_PASSWORD=$valid_ddns_password break; fi fi ;; 1) rm -f "$data" exit 1;; 255) rm -f "$data" exit 1;; esac rm -f "$data" if [ ${#DDNS_PASSWORD} -lt "$MINIMUM_PASSWORD_LENGTH" ]; then dialog --title $"Password quality check" --msgbox $"The password given was too short. It must be at least $MINIMUM_PASSWORD_LENGTH characters. You may need to change your password on the dynamic DNS provider's web site." 10 40 DDNS_PASSWORD="" fi done save_configuration_values fi } function choose_dynamic_dns { DDNS_PROVIDER="none" if [[ "$SYSTEM_TYPE" != "mesh"* && "$ONION_ONLY" == "no" ]]; then dialog --title $"Dynamic DNS" \ --backtitle $"Freedombone Configuration" \ --yesno $"\\nConfigure a dynamic DNS service?\\n\\nIf it is already handled by your internet router then select 'no'." 10 50 sel=$? case $sel in 0) dynamic_dns_setup;; 255) exit 1;; esac fi save_configuration_values } function choose_debian_repo { if [[ "$MINIMAL_INSTALL" == "no" ]]; then W=(1 $"United Kingdom" 2 $"United States" 3 $"Australia" 4 $"Austria" 5 $"Belarus" 6 $"Belgium" 7 $"Bosnia and Herzegovina" 8 $"Brazil" 9 $"Bulgaria" 10 $"Canada" 11 $"Chile" 12 $"China" 13 $"Croatia" 14 $"Czech Republic" 15 $"Denmark" 16 $"El Salvador" 17 $"Estonia" 18 $"Finland" 19 $"France 1" 20 $"France 2" 21 $"Germany 1" 22 $"Germany 2" 23 $"Greece" 24 $"Hungary" 25 $"Iceland" 26 $"Iran" 27 $"Ireland" 28 $"Italy" 29 $"Japan" 30 $"Korea" 31 $"Lithuania" 32 $"Mexico" 33 $"Netherlands" 34 $"New Caledonia" 35 $"New Zealand" 36 $"Norway" 37 $"Poland" 38 $"Portugal" 39 $"Romania" 40 $"Russia" 41 $"Slovakia" 42 $"Slovenia" 43 $"Spain" 44 $"Sweden" 45 $"Switzerland" 46 $"Taiwan" 47 $"Thailand" 48 $"Turkey" 49 $"Ukraine") # shellcheck disable=SC2068 selection=$(dialog --backtitle $"Freedombone Configuration" --title $"Debian Repo" --menu $"Where to download Debian packages from:" 24 60 49 "${W[@]}" 3>&2 2>&1 1>&3) if [ ! "$selection" ]; then selection='1' fi case $selection in 1) DEBIAN_REPO='ftp.uk.debian.org';; 2) DEBIAN_REPO='ftp.us.debian.org';; 3) DEBIAN_REPO='ftp.au.debian.org';; 4) DEBIAN_REPO='ftp.at.debian.org';; 5) DEBIAN_REPO='ftp.by.debian.org';; 6) DEBIAN_REPO='ftp.be.debian.org';; 7) DEBIAN_REPO='ftp.ba.debian.org';; 8) DEBIAN_REPO='ftp.br.debian.org';; 9) DEBIAN_REPO='ftp.bg.debian.org';; 10) DEBIAN_REPO='ftp.ca.debian.org';; 11) DEBIAN_REPO='ftp.cl.debian.org';; 12) DEBIAN_REPO='ftp.cn.debian.org';; 13) DEBIAN_REPO='ftp.hr.debian.org';; 14) DEBIAN_REPO='ftp.cz.debian.org';; 15) DEBIAN_REPO='ftp.dk.debian.org';; 16) DEBIAN_REPO='ftp.sv.debian.org';; 17) DEBIAN_REPO='ftp.ee.debian.org';; 18) DEBIAN_REPO='ftp.fi.debian.org';; 19) DEBIAN_REPO='ftp2.fr.debian.org';; 20) DEBIAN_REPO='ftp.fr.debian.org';; 21) DEBIAN_REPO='ftp2.de.debian.org';; 22) DEBIAN_REPO='ftp.de.debian.org';; 23) DEBIAN_REPO='ftp.gr.debian.org';; 24) DEBIAN_REPO='ftp.hu.debian.org';; 25) DEBIAN_REPO='ftp.is.debian.org';; 26) DEBIAN_REPO='ftp.ir.debian.org';; 27) DEBIAN_REPO='ftp.ie.debian.org';; 28) DEBIAN_REPO='ftp.it.debian.org';; 29) DEBIAN_REPO='ftp.jp.debian.org';; 30) DEBIAN_REPO='ftp.kr.debian.org';; 31) DEBIAN_REPO='ftp.lt.debian.org';; 32) DEBIAN_REPO='ftp.mx.debian.org';; 33) DEBIAN_REPO='ftp.nl.debian.org';; 34) DEBIAN_REPO='ftp.nc.debian.org';; 35) DEBIAN_REPO='ftp.nz.debian.org';; 36) DEBIAN_REPO='ftp.no.debian.org';; 37) DEBIAN_REPO='ftp.pl.debian.org';; 38) DEBIAN_REPO='ftp.pt.debian.org';; 39) DEBIAN_REPO='ftp.ro.debian.org';; 40) DEBIAN_REPO='ftp.ru.debian.org';; 41) DEBIAN_REPO='ftp.sk.debian.org';; 42) DEBIAN_REPO='ftp.si.debian.org';; 43) DEBIAN_REPO='ftp.es.debian.org';; 44) DEBIAN_REPO='ftp.se.debian.org';; 45) DEBIAN_REPO='ftp.ch.debian.org';; 46) DEBIAN_REPO='ftp.tw.debian.org';; 47) DEBIAN_REPO='ftp.th.debian.org';; 48) DEBIAN_REPO='ftp.tr.debian.org';; 49) DEBIAN_REPO='ftp.ua.debian.org';; esac save_configuration_values else # shellcheck disable=SC2034 DEBIAN_REPO='ftp.de.debian.org' fi } function choose_rng { if [[ $MINIMAL_INSTALL == "no" ]]; then data=$(mktemp 2>/dev/null) if [[ "$INSTALLING_ON_BBB" != "yes" ]]; then dialog --backtitle $"Freedombone Configuration" \ --radiolist $"Type of Random Number Generator:" 10 40 2 \ 1 Haveged on \ 2 OneRNG off 2> "$data" sel=$? case $sel in 1) rm -f "$data" exit 1;; 255) rm -f "$data" exit 1;; esac case $(cat "$data") in 2) HWRNG_TYPE="onerng" dialog --title $"OneRNG Device" \ --msgbox $"Please ensure that the OneRNG device is disconnected. You can reconnect it later during the installation" 8 60 ;; 255) rm -f "$data" exit 1;; esac else # shellcheck disable=SC2034 HWRNG_TYPE="beaglebone" fi rm -f "$data" save_configuration_values fi } function choose_social_key_management { if [[ $MINIMAL_INSTALL == "no" ]]; then interactive_gpg SOCIAL_KEY_STR=$"\\nDo you wish to enable social key management, otherwise known as \"the unforgettable key\"?\\n\\nThis means that fragments of your GPG key will be included with any remote backups so that if you later lose your key then it can be reconstructed from your friends servers. If you select \"no\" then you can still do social key management, but offline using physical USB thumb drives, which is more secure but less convenient." if [[ $(grep "ENABLE_SOCIAL_KEY_MANAGEMENT" temp.cfg | awk -F '=' '{print $2}') == "yes" ]]; then dialog --title $"Social Key Management" \ --backtitle $"Freedombone Configuration" \ --yesno "$SOCIAL_KEY_STR" 15 60 else dialog --title $"Social Key Management" \ --backtitle $"Freedombone Configuration" \ --defaultno \ --yesno "$SOCIAL_KEY_STR" 15 60 fi sel=$? case $sel in 0) ENABLE_SOCIAL_KEY_MANAGEMENT="yes";; 255) exit 1;; esac save_configuration_values else # enable for the minimal case # shellcheck disable=SC2034 ENABLE_SOCIAL_KEY_MANAGEMENT="yes" fi } function choose_username { if [ -d /home/$GENERIC_IMAGE_USERNAME ]; then if [ ! -f $IMAGE_PASSWORD_FILE ]; then echo 'Cannot find the password file for the admin user' exit 62753 fi # when installing from an image which comes with a known default user account SELECTED_USERNAME= while [ ! $SELECTED_USERNAME ] do if [ ! $SELECTED_USERNAME ]; then SELECTED_USERNAME=$(grep 'MY_USERNAME' temp.cfg | awk -F '=' '{print $2}') fi data=$(mktemp 2>/dev/null) dialog --backtitle $"Freedombone Configuration" \ --title $"Username" \ --inputbox $"Set your username for the system\\n\\nYour username should not contain any spaces" 12 60 "$SELECTED_USERNAME" 2> "$data" sel=$? case $sel in 0) possible_username=$(cat "$data") SELECTED_USERNAME= if [[ "$possible_username" != *' '* && "$possible_username" != *'/'* && "$possible_username" != *'*'* ]]; then if [ "$possible_username" ]; then if [ ${#possible_username} -gt 1 ]; then if [[ "$possible_username" != "$GENERIC_IMAGE_USERNAME" ]]; then MY_USERNAME=$(cat "$data") please_wait echo '' echo $'Creating user account' chmod 600 /etc/shadow chmod 600 /etc/gshadow useradd -m -s /bin/bash "$MY_USERNAME" chmod 0000 /etc/shadow chmod 0000 /etc/gshadow if [ -d "/home/$MY_USERNAME" ]; then echo "${MY_USERNAME}:$(printf "%s" "$(cat "$IMAGE_PASSWORD_FILE")")" | chpasswd # Add the user as a sudoer - they will be the new admin user if ! grep -q "$MY_USERNAME ALL=(ALL) ALL" /etc/sudoers; then echo "$MY_USERNAME ALL=(ALL) ALL" >> /etc/sudoers # remove the generic image admin user from sudoers sed -i "s|${GENERIC_IMAGE_USERNAME}.*||g" /etc/sudoers fi rm -f "$data" break fi fi fi fi fi ;; 1) rm -f "$data" exit 1;; 255) rm -f "$data" exit 1;; esac rm -f "$data" done else no_of_users=$(find /home/* -maxdepth 0 -type d | wc -l) if [ "$no_of_users" -eq 1 ]; then # only a single user on the system MY_USERNAME=$(ls /home) else # select one from a number of users select_user if [ ! $SELECTED_USERNAME ]; then echo $'No username selected' exit 72589 fi MY_USERNAME="$SELECTED_USERNAME" fi fi if [ ! $MY_USERNAME ]; then echo $'No user account was selected' exit 64398 fi if [[ $MY_USERNAME == '-f' ]]; then echo $'No user account was selected' exit 8347 fi if [[ $MY_USERNAME == 'debian' || $MY_USERNAME == 'fbone' ]]; then echo $"Don't use the default user account" exit 9341 fi if [ ! -d /home/$MY_USERNAME ]; then echo $"The directory /home/$MY_USERNAME does not exist" exit 6437 fi save_configuration_values please_wait echo '' } function choose_full_name { valid_name= while [ ! $valid_name ] do data=$(mktemp 2>/dev/null) dialog --backtitle $"Freedombone Configuration" \ --inputbox $"Your full name (or nick)" 10 50 "$(grep 'MY_NAME' temp.cfg | awk -F '=' '{print $2}')" 2> "$data" sel=$? case $sel in 0) possible_name=$(cat "$data") if [ "$possible_name" ]; then if [ ${#possible_name} -gt 1 ]; then valid_name="$possible_name" # shellcheck disable=SC2034 MY_NAME="$possible_name" break; fi fi ;; 1) rm -f "$data" exit 1;; 255) rm -f "$data" exit 1;; esac rm -f "$data" done save_configuration_values please_wait echo '' } function choose_system_variant { available_variants_list=() available_system_variants varslist="" n=1 # shellcheck disable=SC2068 for a in ${available_variants_list[@]} do varstate='off' if [[ "$a" == $'full' || "$a" == $'Full' ]]; then varstate='on' fi varslist="$varslist $n $a $varstate" n=$((n+1)) done # shellcheck disable=SC2086 variant_choice=$(dialog --stdout --backtitle $"Freedombone Configuration" \ --title $"Type of Installation" \ --radiolist $'Choose:' \ 27 40 20 $varslist) # shellcheck disable=SC2181 if [ $? -eq 0 ]; then variant_choice=$((variant_choice-1)) SYSTEM_TYPE=${available_variants_list[$variant_choice]} save_configuration_values fi } function validate_freedns_code { freedns_code="$1" FREEDNS_MESSAGE=$"Please enter the FreeDNS code for this domain.\\n\\nThe code can be found by going to https://freedns.afraid.org, selecting 'Dynamic DNS' and then opening 'Wget example'. The code will consist of letters and numbers and be between the ? and = characters." if [[ "$freedns_code" == *"."* || "$freedns_code" == "http"* || "$freedns_code" == *"wget "* || "$freedns_code" == *" "* ]]; then dialog --title $"Invalid FreeDNS Code" --msgbox "$FREEDNS_MESSAGE" 10 70 VALID_CODE= fi if [ ${#freedns_code} -lt 30 ]; then dialog --title $"Invalid FreeDNS Code" --msgbox $'FreeDNS code is too short. Did you enter the entire code?' 6 70 VALID_CODE= fi VALID_CODE='yes' } # Get the commandline options while [ $# -gt 1 ] do key="$1" case $key in -h|--help) show_help ;; # Configuration filename -f|--filename) shift CONFIGURATION_FILE="$1" ;; # Minimum password length -m|--min) shift MINIMUM_PASSWORD_LENGTH="$1" ;; # Freedombone website -w|--www) shift FREEDOMBONE_WEBSITE="$1" ;; --social) shift if [[ "$1" == 'gnusocial' || "$1" == 'postactiv' ]]; then SOCIALINSTANCE="$1" fi ;; --minimal) shift MINIMAL_INSTALL="$1" ;; -o|--onion) shift ONION_ONLY="$1" ;; *) # unknown option ;; esac shift done function interactive_select_language { W=(1 $"English" 2 $"Afrikaans" 3 $"Albanian" 4 $"Arabic" 5 $"Basque" 6 $"Belarusian" 7 $"Bosnian" 8 $"Bulgarian" 9 $"Catalan" 10 $"Croatian" 11 $"Chinese (Simplified)" 12 $"Chinese (Traditional)" 13 $"Czech" 14 $"Danish" 15 $"Dutch" 16 $"English (US)" 17 $"Estonian" 18 $"Farsi" 19 $"Filipino" 20 $"Finnish" 21 $"French" 22 $"French (Canada)" 23 $"Gaelic" 24 $"Gallego" 25 $"Georgian" 26 $"German" 27 $"German (Personal)" 28 $"Greek" 29 $"Gujarati" 30 $"Hebrew" 31 $"Hindi" 32 $"Hungarian" 33 $"Icelandic" 34 $"Indonesian" 35 $"Italian" 36 $"Japanese" 37 $"Kannada" 38 $"Khmer" 39 $"Korean" 40 $"Lao" 41 $"Lithuanian" 42 $"Latvian" 43 $"Malayalam" 44 $"Malaysian" 45 $"Maori (Ngai Tahu)" 46 $"Maori (Waikoto Uni)" 47 $"Mongolian" 48 $"Norwegian" 49 $"Norwegian (Primary)" 50 $"Nynorsk" 51 $"Polish" 52 $"Portuguese" 53 $"Portuguese (Brazil)" 54 $"Romanian" 55 $"Russian" 56 $"Samoan" 57 $"Serbian" 58 $"Slovak" 59 $"Slovenian" 60 $"Somali" 61 $"Spanish (International)" 62 $"Swedish" 63 $"Tagalog" 64 $"Tamil" 65 $"Thai" 66 $"Turkish" 67 $"Ukrainian" 68 $"Vietnamese") # shellcheck disable=SC2068 selection=$(dialog --backtitle $"Freedombone Configuration" --title $"Language" --menu $"Select your language:" 24 60 68 "${W[@]}" 3>&2 2>&1 1>&3) if [ ! "$selection" ]; then selection='1' fi case $selection in 1) DEFAULT_LANGUAGE='en_GB.UTF-8';; 2) DEFAULT_LANGUAGE='af_ZA.UTF-8';; 3) DEFAULT_LANGUAGE='sq_AL.UTF-8';; 4) DEFAULT_LANGUAGE='ar_SA.UTF-8';; 5) DEFAULT_LANGUAGE='eu_ES.UTF-8';; 6) DEFAULT_LANGUAGE='be_BY.UTF-8';; 7) DEFAULT_LANGUAGE='bs_BA.UTF-8';; 8) DEFAULT_LANGUAGE='bg_BG.UTF-8';; 9) DEFAULT_LANGUAGE='ca_ES.UTF-8';; 10) DEFAULT_LANGUAGE='hr_HR.UTF-8';; 11) DEFAULT_LANGUAGE='zh_CN.UTF-8';; 12) DEFAULT_LANGUAGE='zh_TW.UTF-8';; 13) DEFAULT_LANGUAGE='cs_CZ.UTF-8';; 14) DEFAULT_LANGUAGE='da_DK.UTF-8';; 15) DEFAULT_LANGUAGE='nl_NL.UTF-8';; 16) DEFAULT_LANGUAGE='en_US.UTF-8';; 17) DEFAULT_LANGUAGE='et_EE.UTF-8';; 18) DEFAULT_LANGUAGE='fa_IR.UTF-8';; 19) DEFAULT_LANGUAGE='ph_PH.UTF-8';; 20) DEFAULT_LANGUAGE='fi_FI.UTF-8';; 21) DEFAULT_LANGUAGE='fr_FR.UTF-8';; 22) DEFAULT_LANGUAGE='fr_CA.UTF-8';; 23) DEFAULT_LANGUAGE='ga.UTF-8';; 24) DEFAULT_LANGUAGE='l_ES.UTF-8';; 25) DEFAULT_LANGUAGE='ka_GE.UTF-8';; 26) DEFAULT_LANGUAGE='de_DE.UTF-8';; 27) DEFAULT_LANGUAGE='de_DE.UTF-8';; 28) DEFAULT_LANGUAGE='el_GR.UTF-8';; 29) DEFAULT_LANGUAGE='gu.UTF-8';; 30) DEFAULT_LANGUAGE='he_IL.utf8';; 31) DEFAULT_LANGUAGE='hi_IN.UTF-8';; 32) DEFAULT_LANGUAGE='hu.UTF-8';; 33) DEFAULT_LANGUAGE='is_IS.UTF-8';; 34) DEFAULT_LANGUAGE='id_ID.UTF-8';; 35) DEFAULT_LANGUAGE='it_IT.UTF-8';; 36) DEFAULT_LANGUAGE='ja_JP.UTF-8';; 37) DEFAULT_LANGUAGE='kn_IN.UTF-8';; 38) DEFAULT_LANGUAGE='km_KH.UTF-8';; 39) DEFAULT_LANGUAGE='ko_KR.UTF-8';; 40) DEFAULT_LANGUAGE='lo_LA.UTF-8';; 41) DEFAULT_LANGUAGE='lt_LT.UTF-8';; 42) DEFAULT_LANGUAGE='lat.UTF-8';; 43) DEFAULT_LANGUAGE='ml_IN.UTF-8';; 44) DEFAULT_LANGUAGE='ms_MY.UTF-8';; 45) DEFAULT_LANGUAGE='mi_NZ.UTF-8';; 46) DEFAULT_LANGUAGE='mi_NZ.UTF-8';; 47) DEFAULT_LANGUAGE='mn.UTF-8';; 48) DEFAULT_LANGUAGE='no_NO.UTF-8';; 49) DEFAULT_LANGUAGE='no_NO.UTF-8';; 50) DEFAULT_LANGUAGE='nn_NO.UTF-8';; 51) DEFAULT_LANGUAGE='pl.UTF-8';; 52) DEFAULT_LANGUAGE='pt_PT.UTF-8';; 53) DEFAULT_LANGUAGE='pt_BR.UTF-8';; 54) DEFAULT_LANGUAGE='ro_RO.UTF-8';; 55) DEFAULT_LANGUAGE='ru_RU.UTF-8';; 56) DEFAULT_LANGUAGE='mi_NZ.UTF-8';; 57) DEFAULT_LANGUAGE='sr_CS.UTF-8';; 58) DEFAULT_LANGUAGE='sk_SK.UTF-8';; 59) DEFAULT_LANGUAGE='sl_SI.UTF-8';; 60) DEFAULT_LANGUAGE='so_SO.UTF-8';; 61) DEFAULT_LANGUAGE='es_ES.UTF-8';; 62) DEFAULT_LANGUAGE='sv_SE.UTF-8';; 63) DEFAULT_LANGUAGE='tl.UTF-8';; 64) DEFAULT_LANGUAGE='ta_IN.UTF-8';; 65) DEFAULT_LANGUAGE='th_TH.UTF-8';; 66) DEFAULT_LANGUAGE='tr_TR.UTF-8';; 67) DEFAULT_LANGUAGE='uk_UA.UTF-8';; 68) DEFAULT_LANGUAGE='vi_VN.UTF-8';; esac save_configuration_values please_wait echo '' echo 'Setting locale' locale-gen "${DEFAULT_LANGUAGE}" update-locale LANG=${DEFAULT_LANGUAGE} update-locale LANGUAGE=${DEFAULT_LANGUAGE} update-locale LC_MESSAGES=${DEFAULT_LANGUAGE} update-locale LC_ALL=${DEFAULT_LANGUAGE} update-locale LC_CTYPE=${DEFAULT_LANGUAGE} please_wait echo '' } function select_user { SELECTED_USERNAME= homedirs=$(ls /home) # shellcheck disable=SC2206 users_array=($homedirs) delete=(git) # shellcheck disable=SC2068 for del in ${delete[@]} do # shellcheck disable=SC2206 users_array=(${users_array[@]/$del}) done i=0 W=() name=() # shellcheck disable=SC2068 for u in ${users_array[@]} do if [[ $(is_valid_user "$u") == "1" ]]; then i=$((i+1)) W+=("$i" "$u") name+=("$u") fi done if [ $i -eq 1 ]; then SELECTED_USERNAME="${name[0]}" else # shellcheck disable=SC2068 user_index=$(dialog --backtitle $"Freedombone Configuration" --title $"Select User" --menu $"Select one of the following:" 24 40 17 ${W[@]} 3>&2 2>&1 1>&3) # shellcheck disable=SC2181 if [ $? -eq 0 ]; then SELECTED_USERNAME="${name[$((user_index-1))]}" fi fi } function interactive_config { # create a temporary copy of the configuration file # which can be used to pre-populate selections if [ -f "$CONFIGURATION_FILE" ]; then cp "$CONFIGURATION_FILE" temp.cfg fi interactive_select_language if [ "$SOCIALINSTANCE" ]; then INITIAL_MESSAGE=$"Welcome to your Freedombone $SOCIALINSTANCE instance.\\n\\nEnsure that you have your domain and dynamic DNS settings ready.\\n\\nFor more information please visit ${FREEDOMBONE_WEBSITE}/socialinstance.html." else if [[ "$ONION_ONLY" == "no" ]]; then INITIAL_MESSAGE=$"Welcome to the Freedombone interactive installer. Communications freedom is only a short time away.\\n\\nEnsure that you have your domain and dynamic DNS settings ready.\\n\\nFor more information please visit $FREEDOMBONE_WEBSITE." else INITIAL_MESSAGE=$"Welcome to the Freedombone interactive installer. Communications freedom is only a short time away.\\n\\nWeb sites created will only be viewable within a Tor browser.\\n\\nFor more information please visit $FREEDOMBONE_WEBSITE." fi fi dialog --title $"Freedombone" --msgbox "$INITIAL_MESSAGE" 15 50 #choose_system_variant choose_username choose_full_name choose_social_key_management choose_rng choose_debian_repo "${PROJECT_NAME}-wifi" --networksinteractive "$WIFI_NETWORKS_FILE" choose_dynamic_dns choose_default_domain_name choose_email_address interactive_key_recovery if [[ "$SOCIALINSTANCE" == 'gnusocial' ]]; then GNUSOCIAL_DOMAIN_NAME=$DEFAULT_DOMAIN_NAME GNUSOCIAL_CODE=$DEFAULT_DOMAIN_CODE write_config_param "GNUSOCIAL_DOMAIN_NAME" "$GNUSOCIAL_DOMAIN_NAME" write_config_param "GNUSOCIAL_CODE" "$GNUSOCIAL_CODE" write_config_param "SOCIALINSTANCE" "$SOCIALINSTANCE" install_gnusocial fi if [[ "$SOCIALINSTANCE" == 'postactiv' ]]; then POSTACTIV_DOMAIN_NAME=$DEFAULT_DOMAIN_NAME POSTACTIV_CODE=$DEFAULT_DOMAIN_CODE write_config_param "POSTACTIV_DOMAIN_NAME" "$POSTACTIV_DOMAIN_NAME" write_config_param "POSTACTIV_CODE" "$POSTACTIV_CODE" write_config_param "SOCIALINSTANCE" "$SOCIALINSTANCE" install_postactiv fi if [[ "$SOCIALINSTANCE" == 'pleroma' ]]; then PLEROMA_DOMAIN_NAME=$DEFAULT_DOMAIN_NAME PLEROMA_CODE=$DEFAULT_DOMAIN_CODE write_config_param "PLEROMA_DOMAIN_NAME" "$PLEROMA_DOMAIN_NAME" write_config_param "PLEROMA_CODE" "$PLEROMA_CODE" write_config_param "SOCIALINSTANCE" "$SOCIALINSTANCE" install_pleroma fi # delete the temporary configuration file if [ -f temp.cfg ]; then shred -zu temp.cfg fi # This file indicates that the configuration happened successfully touch "$HOME/.${PROJECT_NAME}-interactive" } function show_result { #clear echo '' echo -n $"Configuration filename:" echo " $CONFIGURATION_FILE" echo '' echo $'Contents:' echo '' cat "$CONFIGURATION_FILE" echo '' } if [ ! "$CONFIGURATION_FILE" ]; then CONFIGURATION_FILE=$HOME/${PROJECT_NAME}.cfg fi read_configuration_values interactive_config #show_result exit 0