-
Bob Mottram authoredBob Mottram authored
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
freedombone-installer 63.61 KiB
#!/bin/bash
# _____ _ _
# | __|___ ___ ___ _| |___ _____| |_ ___ ___ ___
# | __| _| -_| -_| . | . | | . | . | | -_|
# |__| |_| |___|___|___|___|_|_|_|___|___|_|_|___|
#
# Freedom in the Cloud
#
# Install daemon for the web admin system
# See also freedombone-utils-webadmin
#
# License
# =======
#
# Copyright (C) 2018 Bob Mottram <bob@freedombone.net>
#
# 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 <http://www.gnu.org/licenses/>.
PROJECT_NAME='freedombone'
export TEXTDOMAIN=${PROJECT_NAME}-installer
export TEXTDOMAINDIR="/usr/share/locale"
INSTALL_STATE_FIRST_BOOT=0
INSTALL_STATE_WEBADMIN_PASSWORD_CTEATED=1
INSTALL_STATE_RUNNING_COMMAND=2
INSTALL_STATE_COMMAND_FAIL=3
INSTALL_STATE_COMMAND_SUCCESS=4
install_state=$INSTALL_STATE_FIRST_BOOT
CONFIGURATION_FILE="/root/${PROJECT_NAME}.cfg"
COMPLETION_FILE="/root/${PROJECT_NAME}-completed.txt"
# file containing a list of removed apps
REMOVED_APPS_FILE=/root/removed
# contains the blocked users and domains
FIREWALL_DOMAINS=/root/${PROJECT_NAME}-firewall-domains.cfg
local_hostname=$(grep 'host-name' /etc/avahi/avahi-daemon.conf | awk -F '=' '{print $2}').local
webadmin_install_dir="/var/www/${local_hostname}/htdocs/admin"
language_file="$webadmin_install_dir/.language.txt"
system_monitor_file="$webadmin_install_dir/.system_monitor.txt"
dynamic_dns_file="$webadmin_install_dir/.dynamicdns.txt"
reset_file="$webadmin_install_dir/.reset.txt"
shutdown_file="$webadmin_install_dir/.shutdown.txt"
setup_file="$webadmin_install_dir/setup.txt"
domain_file="$webadmin_install_dir/.temp_domain.txt"
pending_removes="$webadmin_install_dir/pending_removes.txt"
pending_installs="$webadmin_install_dir/pending_installs.txt"
new_user_file="$webadmin_install_dir/.new_user.txt"
remove_user_file="$webadmin_install_dir/.remove_user.txt"
change_password_file="$webadmin_install_dir/changepassword.dat"
install_state_file="/root/.install_state.txt"
blocklist_file="$webadmin_install_dir/.blocklist.txt"
INSTALL_DIR=/root/build
webadmin_user='admin'
webadmin_temp_password_file=/root/.temp_webadmin_password
installer_script=/root/.fbone_installer.sh
# Used to initiate automatic backups
webadmin_prev_hour=99
# temporary backup and restore scripts
backup_script=/root/.webadmin_backup.sh
backup_keys_script=/root/.webadmin_backup_keys.sh
restore_script=/root/.webadmin_restore.sh
restore_keys_script=/root/.webadmin_restore_keys.sh
format_script=/root/.webadmin_format.sh
new_user_script=/root/.webadmin_new_user.sh
remove_user_script=/root/.webadmin_remove_user.sh
# Files used to initiate backup or restore manually from the web UI
backup_file="$webadmin_install_dir/.start_backup"
backup_keys_file="$webadmin_install_dir/.start_backup_keys"
restore_file="$webadmin_install_dir/.start_restore"
restore_keys_file="$webadmin_install_dir/.start_restore_keys"
format_file="$webadmin_install_dir/.start_format"
# These files contain the percentage progress
backup_progress_file=/root/.backup_progress.txt
restore_progress_file=/root/.backup_progress.txt
format_progress_file=/root/.format_progress.txt
function webadmin_update_version {
local_hostname=$(grep 'host-name' /etc/avahi/avahi-daemon.conf | awk -F '=' '{print $2}').local
webadmin_install_dir="/var/www/${local_hostname}/htdocs/admin"
if [ -f "$webadmin_install_dir/about.html" ]; then
VERSION=$(grep "VERSION=" "/usr/local/bin/${PROJECT_NAME}-vars" | grep -v DEBIAN | awk -F '"' '{print $2}')
sed -i "s|\"versiontext\".*|\"versiontext\">$VERSION</p>|g" "$webadmin_install_dir/about.html"
fi
}
function web_admin_onion_only {
# In onion only mode domain names or ddns codes
# don't need to be provided
if ! grep -q 'ONION_ONLY=' "$CONFIGURATION_FILE"; then
return
fi
ONION_ONLY=$(grep 'ONION_ONLY=' "$CONFIGURATION_FILE" | head -n 1 | awk -F '=' '{print $2}')
if [ ! "$ONION_ONLY" ]; then
ONION_ONLY='no'
fi
if [[ "$ONION_ONLY" == 'no' ]]; then
return
fi
# shellcheck disable=SC2154
sed -i '/freedns_code/d' "$webadmin_install_dir/app_add_template.html"
# shellcheck disable=SC2154
sed -i '/freedns_code/d' "$webadmin_install_dir/add_app_confirm_template.html"
sed -i '/install_domain/d' "$webadmin_install_dir/app_add_template.html"
sed -i '/install_domain/d' "$webadmin_install_dir/add_app_confirm_template.html"
sed -i 's|onion_only=false;|onion_only=true;|g' "$webadmin_install_dir/installapp.php"
sed -i 's|onion_only=false;|onion_only=true;|g' "$webadmin_install_dir/installappconfirm.php"
sed -i 's|setup_domain.html|setup_installing.html|g' "$webadmin_install_dir/setupconfirm.php"
}
function web_admin_create_add_apps {
if grep -q 'ONION_ONLY=' "$CONFIGURATION_FILE"; then
ONION_ONLY=$(grep 'ONION_ONLY=' "$CONFIGURATION_FILE" | head -n 1 | awk -F '=' '{print $2}')
else
ONION_ONLY='no'
fi
appslist_add_filename="$webadmin_install_dir/apps_add.html"
apps_add_template_filename="$webadmin_install_dir/apps_add_template.html"
pending_installs="$webadmin_install_dir/pending_installs.txt"
icons_dir="$webadmin_install_dir/icons"
app_add_template_filename="$webadmin_install_dir/app_add_template.html"
FILES="/usr/share/${PROJECT_NAME}/apps/${PROJECT_NAME}-app-*"
if [ ! -d "$icons_dir" ]; then
mkdir -p "$icons_dir"
fi
if [ ! -f "$apps_add_template_filename" ]; then
return
fi
cp "$apps_add_template_filename" "$appslist_add_filename"
sed -i '/<\/body>/d' "$appslist_add_filename"
sed -i '/<\/html>/d' "$appslist_add_filename"
available_apps_ctr=0
for filename in $FILES
do
app_name=$(echo "${filename}" | awk -F '-app-' '{print $2}')
app_is_installed=
# check if the app is pending installation
app_pending_install=
if [ -f "$pending_installs" ]; then
if grep -q "install_${app_name}" "$pending_installs"; then
app_is_installed=1
app_pending_install=1
fi
fi
if [ ! $app_is_installed ]; then
app_filename="/usr/share/${PROJECT_NAME}/apps/${PROJECT_NAME}-app-${app_name}"
if [ -f "$app_filename" ]; then
if grep -q "VARIANTS=''" "$app_filename"; then
continue
fi
if grep -q 'VARIANTS=""' "$app_filename"; then
continue
fi
# get the icon for the app
icon_filename="/usr/share/${PROJECT_NAME}/android-app/${app_name}.png"
if [ -f "$icon_filename" ]; then
cp "$icon_filename" "$webadmin_install_dir/icons/${app_name}.png"
else
continue
fi
app_name_upper=$(echo "$app_name" | awk '{print toupper($0)}')
DESCRIPTION=
if ! grep -q "${app_name_upper}_SHORT_DESCRIPTION=" "$app_filename"; then
continue
fi
if grep -q "#${app_name_upper}_SHORT_DESCRIPTION=" "$app_filename"; then
continue
fi
if grep -q "${app_name_upper}_DESCRIPTION=" "$app_filename"; then
DESCRIPTION="$(grep "${app_name_upper}_DESCRIPTION=" "$app_filename" | head -n 1 | sed 's|\$||g' | sed "s|'||g" | sed 's|\"||g' | awk -F '=' '{print $2}')"
fi
if [ $available_apps_ctr -eq 0 ]; then
echo ' <div class="row">' >> "$appslist_add_filename"
fi
filename="$webadmin_install_dir/app_${app_name}.html"
if [ -f "$filename" ]; then
rm "$filename"
fi
filename="$webadmin_install_dir/app_add_${app_name}.html"
if [ ! $app_pending_install ]; then
{ echo ' <div class="column">';
echo ' <div>';
echo " <a href=\"app_add_${app_name}.html\">";
echo " <img src=\"icons/${app_name}.png\" style=\"width:100%\">";
echo " <center>${app_name}</center>";
echo ' </a>';
echo ' </div>';
echo ' </div>'; } >> "$appslist_add_filename"
else
{ echo ' <div class="column">';
echo ' <div>';
echo " <img src=\"icons/${app_name}.png\" style=\"width:100%\">";
echo " <center class=\"installing\">${app_name}</center>";
echo ' </div>';
echo ' </div>'; } >> "$appslist_add_filename"
fi
cp "$app_add_template_filename" "$filename"
# Replace app variables
sed -i "s|HOSTNAME|$(hostname)|g" "$filename"
sed -i "s|APPNAME|${app_name}|g" "$filename"
sed -i "s|APPDESCRIPTION|${DESCRIPTION}|g" "$filename"
# remove domain if onion only
if [[ "$ONION_ONLY" != 'no' ]]; then
if grep -q 'install_domain' "$filename"; then
sed -i '/install_domain/d' "$filename"
fi
sed -i "/installappconfirm.php/a <input type=\"hidden\" name=\"install_domain\" value=\"${app_name}.$(hostname)\">" "$filename"
fi
if grep -q 'freedns_code' "$filename"; then
sed -i '/freedns_code/d' "$filename"
fi
available_apps_ctr=$((available_apps_ctr+1))
# four columns per row
if [ $available_apps_ctr -eq 4 ]; then
echo ' </div>' >> "$appslist_add_filename"
available_apps_ctr=0
fi
fi
fi
done
if [ ${available_apps_ctr} -gt 0 ]; then
# Complete the rest of the four column row
# shellcheck disable=SC2034
for i in $(seq ${available_apps_ctr} 3)
do
{ echo ' <div class="column">';
echo ' <div>';
echo ' </div>';
echo ' </div>'; } >> "$appslist_add_filename"
done
echo ' </div>' >> "$appslist_add_filename"
fi
{ echo ' <br><br>';
echo ' </body>';
echo '</html>'; } >> "$appslist_add_filename"
chown -R www-data:www-data "$webadmin_install_dir"
}
function web_admin_create_installed_apps {
appslist_filename="$webadmin_install_dir/apps.html"
appslist_template_filename="$webadmin_install_dir/apps_template.html"
icons_dir="$webadmin_install_dir/icons"
pending_removes="$webadmin_install_dir/pending_removes.txt"
if [ ! -d "$icons_dir" ]; then
mkdir -p "$icons_dir"
fi
if [ ! -f "$appslist_template_filename" ]; then
return
fi
cp "$appslist_template_filename" "$appslist_filename"
sed -i '/<\/body>/d' "$appslist_filename"
sed -i '/<\/html>/d' "$appslist_filename"
installed_apps_ctr=0
# Complete the rest of the four column row
# shellcheck disable=SC2034
for i in $(seq ${installed_apps_ctr} 3)
do
{ echo ' <div class="column">';
echo ' <div>';
echo ' </div>';
echo ' </div>'; } >> "$appslist_filename"
done
echo ' </body>' >> "$appslist_filename"
echo '</html>' >> "$appslist_filename"
chown -R www-data:www-data "$webadmin_install_dir"
}
function web_admin_create_users {
if [ ! -d "/home/$webadmin_user" ]; then
return
fi
users_file="$webadmin_install_dir/users.html"
cp "$webadmin_install_dir"/users_template.html "$users_file"
sed -i '/users list/,/end of users/d' "$users_file"
sed -i '/<\/body>/d' "$users_file"
sed -i '/<\/html>/d' "$users_file"
echo " <div class=\"row\">" >> "$users_file"
echo " <div class=\"column\">" >> "$users_file"
rm "$webadmin_install_dir/userprofile_"*
USERNAME="$webadmin_user"
userfile="$webadmin_install_dir/userprofile_${USERNAME}.html"
useremail=${USERNAME}@${HOSTNAME}
GPG_ID=$(su -c "gpg --list-keys '$useremail'" - "$USERNAME" | sed -n '2p' | sed 's/^[ \t]*//')
if [ -f "/home/$USERNAME/.gnupg/gpg.conf" ]; then
if grep -q "default-key" "/home/$USERNAME/.gnupg/gpg.conf"; then
default_gpg_key=$(grep "default-key" "/home/$USERNAME/.gnupg/gpg.conf")
if [[ "$default_gpg_key" != *'#'* ]]; then
default_gpg_key=$(grep "default-key" "/home/$USERNAME/.gnupg/gpg.conf" | awk -F ' ' '{print $2}')
if [ ${#default_gpg_key} -gt 3 ]; then
GPG_ID=$(su -c "gpg --list-keys '$default_gpg_key'" - "$USERNAME" | sed -n '2p' | sed 's/^[ \t]*//')
fi
fi
fi
fi
pubkey_qrcode="$webadmin_install_dir/images/userprofile_${USERNAME}.png"
su -c "gpg --armor --export \"$GPG_ID\"" - "$USERNAME" | qrencode -t PNG -o "$pubkey_qrcode"
{ echo ' <div class="chip">';
echo " <a href=\"userprofile_${USERNAME}.html\">";
echo ' <img src="images/admin_users.png" alt="Person" width="96" height="96">';
echo " $USERNAME";
echo ' </a>';
echo ' </div>'; } >> "$users_file"
cp "$webadmin_install_dir"/userprofile.html "$userfile"
sed -i "s|USERNAME|${USERNAME}|g" "$userfile"
if [[ "$USERNAME" == "$webadmin_user" ]]; then
sed -i "s|USERTYPE|Admin|g" "$userfile"
sed -i '/remove user button/,/end of remove/d' "$userfile"
else
sed -i "s|USERTYPE|User|g" "$userfile"
fi
sed -i "s|USEREMAIL|${useremail}|g" "$userfile"
sed -i "s|USERGPG|${GPG_ID}|g" "$userfile"
chown www-data:www-data "$userfile"
chown www-data:www-data "$pubkey_qrcode"
{ echo ' <div class="chip">';
echo " <a href=\"new_user.html\">";
echo ' <img src="images/admin_users.png" alt="Person" width="96" height="96">';
echo ' +';
echo ' </a>';
echo ' </div>';
echo ' </div>';
echo ' </div>';
echo ' </body>';
echo '</html>'; } >> "$users_file"
chown www-data:www-data "$users_file"
}
function wait_for_enough_entropy {
# Wait indefinitely until enough entropy is available to
# generate the webadmin login password
while true
do
ENTROPY=$(cat /proc/sys/kernel/random/entropy_avail)
# shellcheck disable=SC2086
if [ $ENTROPY -gt 500 ]; then
break
fi
sleep 2
done
}
function web_admin_create_user {
username="$1"
password="$2"
if [ ! "$username" ]; then
return
fi
if [ ! -d "/home/$username" ]; then
chmod 600 /etc/shadow
chmod 600 /etc/gshadow
useradd -m -p "$password" -s /bin/bash "$username"
groupadd "$username"
chmod 0000 /etc/shadow
chmod 0000 /etc/gshadow
else
echo "${username}:${password}"|chpasswd
fi
}
function web_admin_setup_login {
if [ $install_state -ne $INSTALL_STATE_FIRST_BOOT ]; then
return
fi
# if an nginx password file has not been created for web admin
if [ -f /etc/nginx/.webadminpasswd ]; then
return
fi
# this file indicates that the setup screen is active
# and gets removed by freedombone-installer
if [ ! -f "$webadmin_install_dir/.setupscreenactive" ]; then
touch "$webadmin_install_dir/.setupscreenactive"
fi
if [ ! -f $webadmin_temp_password_file ]; then
wait_for_enough_entropy
webadmin_password="$(openssl rand -base64 32 | tr -dc A-Za-z0-9 | head -c 10 ; echo -n '')"
echo -n "$webadmin_password" > $webadmin_temp_password_file
else
webadmin_password=$(cat $webadmin_temp_password_file)
fi
web_admin_create_user "$webadmin_user" "$webadmin_password"
# create a password for users
if [ ! -f /etc/nginx/.webadminpasswd ]; then
touch /etc/nginx/.webadminpasswd
fi
# create a password file used by nginx
echo -n "$webadmin_password" | htpasswd -i -s -c /etc/nginx/.webadminpasswd "$webadmin_user"
if ! grep -q "${webadmin_user}:" /etc/nginx/.webadminpasswd; then
echo $"/etc/nginx/.webadminpasswd password not created for $webadmin_user"
if [ -f /etc/nginx/.webadminpasswd ]; then
rm /etc/nginx/.webadminpasswd
fi
return
fi
# create a setup page with the initial password inserted
# and copy it to the index
cp "$webadmin_install_dir"/setup.html "$webadmin_install_dir"/setup.prev
cp "$webadmin_install_dir"/setup_confirm_template.html "$webadmin_install_dir"/setup_confirm.html
sed -i "s|WEBADMINPASSWORD|${webadmin_password}|g" "$webadmin_install_dir/setup.prev"
sed -i "s|WEBADMINPASSWORD|${webadmin_password}|g" "$webadmin_install_dir/setup_confirm.html"
cp "$webadmin_install_dir"/setup.prev "$webadmin_install_dir"/index.html
# if initial setup has not yet happened then create
# a password file
if ! grep -q 'install_final' "$COMPLETION_FILE"; then
echo -n "$webadmin_password" > /root/login.txt
fi
echo -n "$INSTALL_STATE_WEBADMIN_PASSWORD_CTEATED" > "$install_state_file"
install_state=$INSTALL_STATE_WEBADMIN_PASSWORD_CTEATED
}
function enable_webadmin_login {
# switch on nginx authentication for freedombone.local
if grep -q "#auth_basic" "/etc/nginx/sites-available/${local_hostname}"; then
sed -i 's|#auth_basic|auth_basic|g' "/etc/nginx/sites-available/${local_hostname}"
fi
}
function remove_initial_setup_page {
if [ -f "$webadmin_install_dir/index.prev" ]; then
curr_language=$(web_admin_get_language_subdir)
# Replace the installing screen with the main index page when done
# It should reload by itself
if [ -f "$webadmin_install_dir/setup_installing.html" ]; then
cp "$webadmin_install_dir/${curr_language}/index.html" "$webadmin_install_dir/setup_installing.html"
fi
# Replace the setup confirm screen with the main index
if [ -f "$webadmin_install_dir/setup_confirm.html" ]; then
cp "$webadmin_install_dir/${curr_language}/index.html" "$webadmin_install_dir/setup_confirm.html"
fi
# Replace the setup domain screen with the main index
if [ -f "$webadmin_install_dir/setup_domain.html" ]; then
cp "$webadmin_install_dir/${curr_language}/index.html" "$webadmin_install_dir/setup_domain.html"
fi
# Show the web admin index page (not the initial setup page)
cp "$webadmin_install_dir/${curr_language}/index.html" "$webadmin_install_dir/index.html"
rm "$webadmin_install_dir/index.prev"
fi
# Remove the initial setup page
if [ -f "$webadmin_install_dir/setup.prev" ]; then
rm "$webadmin_install_dir/setup.prev"
fi
}
function remove_temporary_setup_files {
# remove the file which indicates that the setup screen is active
if [ -f "$webadmin_install_dir/.setupscreenactive" ]; then
rm "$webadmin_install_dir/.setupscreenactive"
fi
# remove the setup file created by setup.php
if [ -f "$setup_file" ]; then
rm "$setup_file"
fi
# remove the file containing the domain name
if [ -f "$domain_file" ]; then
rm "$domain_file"
fi
}
function restore_webadmin_files {
# restore files which were removed for the initial setup
if [ -d "$INSTALL_DIR/tempwebadmin" ]; then
mv "$INSTALL_DIR/tempwebadmin"/* "$webadmin_install_dir"
rm -rf "$INSTALL_DIR/tempwebadmin"
fi
}
function set_webadmin_permissions {
# set permissions for web admin site at freedombone.local
chown www-data:www-data "$webadmin_install_dir/*.html"
}
function check_for_existing_processes {
script_name="$1"
{ echo '#!/bin/bash';
echo '';
echo 'function exit_if_process_is_running {';
echo " process_name=\"\$1\"";
echo " process_exists=\$(ps a | grep \"\$process_name\" | grep -v 'grep')";
echo " if [ \"\$process_exists\" ]; then";
echo " if [[ \"\$process_exists\" != *'grep'* ]]; then";
echo " process_id=\$(echo \"\$process_exists\" | awk -F ' ' '{print \$1}')";
echo " if [ \"\$process_id\" ]; then";
echo " exit 0";
echo ' fi';
echo ' fi';
echo ' fi';
echo '}';
echo '';
echo 'exit_if_process_is_running fbone_installer.sh';
echo 'exit_if_process_is_running webadmin_format.sh';
echo 'exit_if_process_is_running webadmin_backup.sh';
echo 'exit_if_process_is_running webadmin_backup_keys.sh';
echo 'exit_if_process_is_running webadmin_restore.sh';
echo 'exit_if_process_is_running webadmin_restore_keys.sh';
echo 'exit_if_process_is_running webadmin_new_user.sh';
echo 'exit_if_process_is_running webadmin_remove_user.sh';
echo ''; } > "$script_name"
}
function run_setup_command {
if [ $install_state -ne $INSTALL_STATE_WEBADMIN_PASSWORD_CTEATED ]; then
return
fi
check_for_existing_processes $installer_script
{ echo "echo \"Beginning install \$(date)\" > $webadmin_install_dir/log.txt";
echo "chown www-data:www-data $webadmin_install_dir/log.txt";
echo '';
echo "/usr/local/bin/freedombone -c \"$CONFIGURATION_FILE\" >> $webadmin_install_dir/log.txt;";
echo "if ! grep -q 'install_final' \"$COMPLETION_FILE\"; then";
echo " chown www-data:www-data $webadmin_install_dir/log.txt";
echo " echo '$INSTALL_STATE_COMMAND_FAIL' > $install_state_file";
echo ' exit 364873';
echo 'fi';
echo '';
echo "chown www-data:www-data $webadmin_install_dir/log.txt";
echo '';
echo "exit 0"; } >> $installer_script
chmod +x $installer_script
echo -n "$INSTALL_STATE_RUNNING_COMMAND" > "$install_state_file"
install_state=$INSTALL_STATE_RUNNING_COMMAND
# run in a separate process
./$installer_script &
}
function check_install_command_state {
if [ $install_state -ne $INSTALL_STATE_RUNNING_COMMAND ]; then
return
fi
reset_install_state=
if [ ! -f "$install_state_file" ]; then
reset_install_state=1
else
curr_state=$(cat "$install_state_file")
# shellcheck disable=SC2086
if [ $curr_state -eq $INSTALL_STATE_COMMAND_FAIL ]; then
reset_install_state=1
fi
install_has_finished=
# shellcheck disable=SC2086
if [ $curr_state -eq $INSTALL_STATE_COMMAND_SUCCESS ]; then
install_has_finished=1
else
# Also check the install log for a message
# indicating completion has happened
if [ -f "$webadmin_install_dir/log.txt" ]; then
end_of_log=$(tail -n 10 "$webadmin_install_dir/log.txt" | grep ${PROJECT_NAME})
end_of_log_message=$'installation is complete'
if [[ "$end_of_log" == *"$end_of_log_message"* ]]; then
install_has_finished=1
fi
fi
fi
if [ $install_has_finished ]; then
echo -n "$INSTALL_STATE_COMMAND_SUCCESS" > "$install_state_file"
install_state=$INSTALL_STATE_COMMAND_SUCCESS
restore_webadmin_files
fi
fi
if [ $reset_install_state ]; then
chown www-data:www-data "$webadmin_install_dir/log.txt"
# remove the setup file containing login details
if [ -f "$setup_file" ]; then
rm "$setup_file"
fi
# remove the webadmin password file
if [ -f /etc/nginx/.webadminpasswd ]; then
rm /etc/nginx/.webadminpasswd
fi
echo -n "$INSTALL_STATE_FIRST_BOOT" > "$install_state_file"
install_state=$INSTALL_STATE_FIRST_BOOT
fi
}
function web_admin_get_language_subdir {
if grep -q 'DEFAULT_LANGUAGE=' "$CONFIGURATION_FILE"; then
DEFAULT_LANGUAGE=$(grep 'DEFAULT_LANGUAGE=' "$CONFIGURATION_FILE" | head -n 1 | awk -F '=' '{print $2}')
fi
if [ ! "$DEFAULT_LANGUAGE" ]; then
echo 'EN'
return
fi
lang_lower="${DEFAULT_LANGUAGE:0:2}"
echo "$lang_lower" | awk '{print toupper($0)}'
}
function before_setup_runs {
if [ $install_state -ne $INSTALL_STATE_WEBADMIN_PASSWORD_CTEATED ]; then
return
fi
if [ ! -f /etc/nginx/.webadminpasswd ]; then
return
fi
if grep -q 'install_final' "$COMPLETION_FILE"; then
return
fi
curr_language=$(web_admin_get_language_subdir)
if [ ! -f "/usr/share/${PROJECT_NAME}/webadmin/${curr_language}/setup_installing.html" ]; then
return
fi
cp "/usr/share/${PROJECT_NAME}/webadmin/${curr_language}/setup_installing.html" "$webadmin_install_dir/index.html"
# get the username and domain from the .temp_setup.txt file
# created by setup.php
MY_USERNAME=$(cat "$setup_file")
if [ ! "$MY_USERNAME" ]; then
MY_USERNAME="$webadmin_user"
else
if [[ "$MY_USERNAME" != "$webadmin_user" ]]; then
temp_webadmin_password=$(cat $webadmin_temp_password_file)
web_admin_create_user "$webadmin_user" "$temp_webadmin_password"
webadmin_user="$MY_USERNAME"
fi
fi
DEFAULT_DOMAIN_NAME=${local_hostname}
if [ -f "$domain_file" ]; then
DEFAULT_DOMAIN_NAME=$(cat "$domain_file")
fi
# change the username in the config file
if grep -q 'MY_USERNAME=' "$CONFIGURATION_FILE"; then
if ! grep -Fxq "MY_USERNAME=$MY_USERNAME" "$CONFIGURATION_FILE"; then
sed -i "s|MY_USERNAME=.*|MY_USERNAME=$MY_USERNAME|g" "$CONFIGURATION_FILE"
fi
else
echo "MY_USERNAME=$MY_USERNAME" >> "$CONFIGURATION_FILE"
fi
# change the full name in the config file
if grep -q 'MY_NAME=' "$CONFIGURATION_FILE"; then
if ! grep -Fxq "MY_NAME=$MY_USERNAME" "$CONFIGURATION_FILE"; then
sed -i "s|MY_NAME=.*|MY_USERNAME=$MY_USERNAME|g" "$CONFIGURATION_FILE"
fi
else
echo "MY_NAME=$MY_USERNAME" >> "$CONFIGURATION_FILE"
fi
# change the default domain in the config file
if grep -q 'DEFAULT_DOMAIN_NAME=' "$CONFIGURATION_FILE"; then
if ! grep -Fxq "DEFAULT_DOMAIN_NAME=$DEFAULT_DOMAIN_NAME" "$CONFIGURATION_FILE"; then
sed -i "s|DEFAULT_DOMAIN_NAME=.*|DEFAULT_DOMAIN_NAME=$DEFAULT_DOMAIN_NAME|g" "$CONFIGURATION_FILE"
fi
else
echo "DEFAULT_DOMAIN_NAME=$DEFAULT_DOMAIN_NAME" >> "$CONFIGURATION_FILE"
fi
# ensure that minimal install is set
if grep -q 'MINIMAL_INSTALL=' "$CONFIGURATION_FILE"; then
if ! grep -Fxq "MINIMAL_INSTALL=yes" "$CONFIGURATION_FILE"; then
sed -i 's|MINIMAL_INSTALL=.*|MINIMAL_INSTALL=yes|g' "$CONFIGURATION_FILE"
fi
else
echo 'MINIMAL_INSTALL=yes' >> "$CONFIGURATION_FILE"
fi
# ensure that no DDNS provider is specified
if grep -q 'DDNS_PROVIDER=' "$CONFIGURATION_FILE"; then
if ! grep -Fxq "DDNS_PROVIDER=none" "$CONFIGURATION_FILE"; then
sed -i 's|DDNS_PROVIDER=.*|DDNS_PROVIDER=none|g' "$CONFIGURATION_FILE"
fi
else
echo 'DDNS_PROVIDER=none' >> "$CONFIGURATION_FILE"
fi
run_setup_command
}
function after_setup_has_finished {
if [ $install_state -ne $INSTALL_STATE_COMMAND_SUCCESS ]; then
return
fi
if [ -f /root/.initial_setup ]; then
rm /root/.initial_setup
fi
enable_webadmin_login
remove_initial_setup_page
set_webadmin_permissions
remove_temporary_setup_files
if [ -f $webadmin_temp_password_file ]; then
rm $webadmin_temp_password_file
fi
web_admin_onion_only
web_admin_create_users
web_admin_create_installed_apps
web_admin_create_add_apps
webadmin_update_version
# remove default user
if [ -d /home/fbone ]; then
userdel -r fbone
if [ -d /home/fbone ]; then
rm -rf /home/fbone
fi
fi
systemctl restart nginx
if [ -f $installer_script ]; then
rm $installer_script
fi
regenerate_blocklist
systemctl reboot -i
}
function install_apps_from_webadmin {
if [ -f "$pending_installs" ]; then
linestr=$(head -n 1 "$pending_installs")
if [[ "$linestr" == "install_"* ]]; then
app_name=$(echo "$linestr" | awk -F '_' '{print $2}' | awk -F ',' '{print $1}')
if [ -f "/usr/share/${PROJECT_NAME}/apps/${PROJECT_NAME}-app-${app_name}" ]; then
app_domain=$(echo "$linestr" | awk -F ',' '{print $2}')
if [ ! "$app_domain" ]; then
app_domain=${app_name}.local
fi
app_name_upper=$(echo "$app_name" | awk '{print toupper($0)}')
freedns_code=$(echo -n "$linestr" | awk -F ',' '{print $3}')
# indicate that we are installing
if [[ "$linestr" != *'_running'* ]]; then
sed -i "s|${app_name}|${app_name}_running|g" "$pending_installs"
fi
# Add domain name to the config
if ! grep -q "${app_name_upper}_DOMAIN_NAME=" $CONFIGURATION_FILE; then
echo "${app_name_upper}_DOMAIN_NAME=${app_domain}" >> $CONFIGURATION_FILE
else
sed -i "s|${app_name_upper}_DOMAIN_NAME=.*|${app_name_upper}_DOMAIN_NAME=${app_domain}|g" $CONFIGURATION_FILE
fi
if grep -q 'ONION_ONLY=no' $CONFIGURATION_FILE; then
# Add freedns code to the config
if [ "$freedns_code" ]; then
# shellcheck disable=SC2086
${app_name_upper}_CODE="${freedns_code}"
if ! grep -q "${app_name_upper}_CODE=" $CONFIGURATION_FILE; then
echo "${app_name_upper}_CODE=${freedns_code}" >> $CONFIGURATION_FILE
else
sed -i "s|${app_name_upper}_CODE=.*|${app_name_upper}_CODE=${freedns_code}|g" $CONFIGURATION_FILE
fi
fi
fi
# remove app from the removed file
if ! grep -Fxq "_${app_name}_" "$REMOVED_APPS_FILE"; then
sed -i "/_${app_name}_/d" "$REMOVED_APPS_FILE"
fi
if ! /usr/local/bin/${PROJECT_NAME}-addremove add "${app_name}" > "$webadmin_install_dir/applog.txt"; then
sed -i "/$linestr/d" "$pending_installs"
web_admin_create_add_apps
fi
chown www-data:www-data "$webadmin_install_dir/applog.txt"
fi
# remove the line
sed -i "/$linestr/d" "$pending_installs"
else
# if any unusual line is found then remove the file
rm "$pending_installs"
fi
fi
}
function remove_apps_from_webadmin {
if [ -f "$pending_removes" ]; then
linestr=$(head -n 1 "$pending_removes")
if [[ "$linestr" == "remove_"* ]]; then
app_name=$(echo "$linestr" | awk -F '_' '{print $2}')
if [ -f "/usr/share/${PROJECT_NAME}/apps/${PROJECT_NAME}-app-${app_name}" ]; then
# indicate that we are removing
if [[ "$linestr" != *'_running'* ]]; then
sed -i "s|${app_name}|${app_name}_running|g" "$pending_removes"
fi
/usr/local/bin/${PROJECT_NAME}-addremove remove "${app_name}" > "$webadmin_install_dir/applog.txt"
web_admin_create_add_apps
chown www-data:www-data "$webadmin_install_dir/applog.txt"
fi
# remove the line
sed -i "/$linestr/d" "$pending_removes"
else
# if any unusual line is found then remove the file
rm "$pending_removes"
fi
fi
}
function update_progress_bar {
# shellcheck disable=SC2086
if [ $install_state -ne $INSTALL_STATE_RUNNING_COMMAND ]; then
return
fi
if [ ! -f /root/.install_counter ]; then
echo -n '1' > /root/.install_counter
fi
max_counter=273
installing_page="$webadmin_install_dir/setup_installing.html"
progress_counter=$(cat /root/.install_counter)
progress_percent=$((progress_counter * 100 / max_counter))
if [ $progress_percent -gt 100 ]; then
progress_percent=100
fi
sed -i "s|<div class=\"w3-container.*|<div class=\"w3-container w3-blue w3-round-xlarge\" style=\"width:${progress_percent}%\">${progress_percent}%</div>|g" "$installing_page"
if ! grep -q 'w3-container w3-blue' "$webadmin_install_dir/index.html"; then
cp "$webadmin_install_dir/setup_installing.html" "$webadmin_install_dir/index.html"
fi
sed -i "s|<div class=\"w3-container.*|<div class=\"w3-container w3-blue w3-round-xlarge\" style=\"width:${progress_percent}%\">${progress_percent}%</div>|g" "$webadmin_install_dir/index.html"
}
function initiate_automatic_backup {
backup_hour=3
if grep -q "BACKUP_HOUR=" "$CONFIGURATION_FILE"; then
backup_hour=$(grep "BACKUP_HOUR=" "$CONFIGURATION_FILE" | awk -F '=' '{print $2}')
else
echo "BACKUP_HOUR=$backup_hour" >> "$CONFIGURATION_FILE"
fi
curr_hour=$(date +%H)
if [[ "$curr_hour" == "$backup_hour" ]]; then
if [[ "$webadmin_prev_hour" != "$backup_hour" ]]; then
touch "$backup_file"
fi
fi
webadmin_prev_hour=$curr_hour
}
function update_backup_progress_bar {
if [ ! -f "$backup_progress_file" ]; then
return
fi
backup_process_exists=
backup_process=$(pgrep 'webadmin_backup.sh' | grep -v 'grep')
if [ "$backup_process" ]; then
if [[ "$backup_process" != *'grep'* ]]; then
backup_pid=$(echo "$backup_process" | awk -F ' ' '{print $1}')
if [ "$backup_pid" ]; then
backup_process_exists=1
fi
fi
fi
if [ ! $backup_process_exists ]; then
return
fi
max_counter=203
progress_page="$webadmin_install_dir/backup_progress.html"
progress_counter=$(cat $backup_progress_file)
progress_percent=$((progress_counter * 100 / max_counter))
if [ $progress_percent -gt 100 ]; then
progress_percent=$((progress_percent - 100))
fi
sed -i "s|<div class=\"w3-container.*|<div class=\"w3-container w3-blue w3-round-xlarge\" style=\"width:${progress_percent}%\">${progress_percent}%</div>|g" "$progress_page"
}
function update_restore_progress_bar {
if [ ! -f "$restore_progress_file" ]; then
return
fi
restore_process_exists=
restore_process=$(pgrep 'webadmin_restore.sh' | grep -v 'grep')
if [ "$restore_process" ]; then
if [[ "$restore_process" != *'grep'* ]]; then
restore_pid=$(echo "$restore_process" | awk -F ' ' '{print $1}')
if [ "$restore_pid" ]; then
restore_process_exists=1
fi
fi
fi
if [ ! $restore_process_exists ]; then
return
fi
max_counter=203
progress_page="$webadmin_install_dir/restore_progress.html"
progress_counter=$(cat $restore_progress_file)
progress_percent=$((progress_counter * 100 / max_counter))
if [ $progress_percent -gt 100 ]; then
progress_percent=$((progress_percent - 100))
fi
sed -i "s|<div class=\"w3-container.*|<div class=\"w3-container w3-blue w3-round-xlarge\" style=\"width:${progress_percent}%\">${progress_percent}%</div>|g" "$progress_page"
}
function update_format_progress_bar {
if [ ! -f "$format_progress_file" ]; then
return
fi
format_process_exists=
format_process=$(pgrep 'webadmin_format.sh' | grep -v 'grep')
if [ "$format_process" ]; then
if [[ "$format_process" != *'grep'* ]]; then
format_pid=$(echo "$format_process" | awk -F ' ' '{print $1}')
if [ "$format_pid" ]; then
format_process_exists=1
fi
fi
fi
if [ ! $format_process_exists ]; then
return
fi
max_counter=5
progress_page="$webadmin_install_dir/format_progress.html"
progress_counter=$(cat $format_progress_file)
progress_percent=$((progress_counter * 100 / max_counter))
if [ $progress_percent -gt 100 ]; then
progress_percent=100
fi
sed -i "s|<div class=\"w3-container.*|<div class=\"w3-container w3-blue w3-round-xlarge\" style=\"width:${progress_percent}%\">${progress_percent}%</div>|g" "$progress_page"
}
function backup_and_restore {
update_backup_progress_bar
update_restore_progress_bar
update_format_progress_bar
initiate_automatic_backup
if [ -f "$restore_file" ]; then
rm "$restore_file"
restore_title=$'Restore status'
restore_failed_message=$"Restore failed. See http://${HOSTNAME}/admin/restore.txt for details"
restore_success_message=$"Restore succeeded"
check_for_existing_processes $restore_script
{ echo "echo \"Beginning webadmin restore \$(date)\" > $webadmin_install_dir/restore.txt";
echo "chown www-data:www-data $webadmin_install_dir/restore.txt";
echo '';
echo "cp $webadmin_install_dir/restore_progress_template.html $webadmin_install_dir/restore_progress.html";
echo "chown www-data:www-data $webadmin_install_dir/restore_progress.html";
echo '';
echo "if /usr/local/bin/${PROJECT_NAME}-restore-local simple >> $webadmin_install_dir/restore.txt; then";
echo " echo \"Completed \$(date)\" >> $webadmin_install_dir/restore.txt";
echo " cp $webadmin_install_dir/restore_complete.html $webadmin_install_dir/restore_progress.html";
echo " /usr/local/bin/${PROJECT_NAME}-notification -m \"$restore_success_message\" -s \"$restore_title\"";
echo 'else';
echo " cp $webadmin_install_dir/restore_failed.html $webadmin_install_dir/restore_progress.html";
echo " /usr/local/bin/${PROJECT_NAME}-notification -m \"$restore_failed_message\" -s \"$restore_title\"";
echo 'fi';
echo '';
echo "chown www-data:www-data $webadmin_install_dir/restore.txt";
echo "chown www-data:www-data $webadmin_install_dir/restore_progress.html";
echo '';
echo "rm $restore_progress_file";
echo '';
echo "exit 0"; } >> $restore_script
chmod +x $restore_script
# run in a separate process
./$restore_script &
else
if [ -f "$backup_file" ]; then
rm "$backup_file"
backup_title=$'Backup status'
backup_failed_message=$"Backup failed. See http://${HOSTNAME}/admin/backup.txt for details"
backup_success_message=$"Backup succeeded"
check_for_existing_processes $backup_script
{ echo "echo \"Beginning webadmin backup \$(date)\" > $webadmin_install_dir/backup.txt";
echo "chown www-data:www-data $webadmin_install_dir/backup.txt";
echo '';
echo "cp $webadmin_install_dir/backup_progress_template.html $webadmin_install_dir/backup_progress.html";
echo "chown www-data:www-data $webadmin_install_dir/backup_progress.html";
echo '';
echo "if /usr/local/bin/${PROJECT_NAME}-backup-local simple >> $webadmin_install_dir/backup.txt; then";
echo " echo \"Completed \$(date)\" >> $webadmin_install_dir/backup.txt";
echo " cp $webadmin_install_dir/backup_complete.html $webadmin_install_dir/backup_progress.html";
echo " /usr/local/bin/${PROJECT_NAME}-notification -m \"$backup_success_message\" -s \"$backup_title\"";
echo 'else';
echo " cp $webadmin_install_dir/backup_failed.html $webadmin_install_dir/backup_progress.html";
echo " /usr/local/bin/${PROJECT_NAME}-notification -m \"$backup_failed_message\" -s \"$backup_title\"";
echo 'fi';
echo '';
echo "chown www-data:www-data $webadmin_install_dir/backup.txt";
echo "chown www-data:www-data $webadmin_install_dir/backup_progress.html";
echo '';
echo "rm $backup_progress_file";
echo '';
echo "exit 0"; } >> $backup_script
chmod +x $backup_script
# run in a separate process
./$backup_script &
else
if [ -f "$format_file" ]; then
rm "$format_file"
format_title=$'USB format status'
format_failed_message=$"USB format failed. See http://${HOSTNAME}/admin/format.txt for details"
format_success_message=$"USB format succeeded"
check_for_existing_processes $format_script
{ echo "if /usr/local/bin/${PROJECT_NAME}-format simple > $webadmin_install_dir/format.txt; then";
echo " cp $webadmin_install_dir/format_complete.html $webadmin_install_dir/format_progress.html";
echo " /usr/local/bin/${PROJECT_NAME}-notification -m \"$format_success_message\" -s \"$format_title\"";
echo 'else';
echo " cp $webadmin_install_dir/format_failed.html $webadmin_install_dir/format_progress.html";
echo " /usr/local/bin/${PROJECT_NAME}-notification -m \"$format_failed_message\" -s \"$format_title\"";
echo 'fi';
echo "chown www-data:www-data $webadmin_install_dir/format_progress.html";
echo '';
echo "rm $format_progress_file";
echo '';
echo "exit 0"; } >> $format_script
chmod +x $format_script
# run in a separate process
./$format_script &
fi
fi
fi
}
function backup_and_restore_keys {
if [ -f "$restore_keys_file" ]; then
rm "$restore_keys_file"
admin_username=$(grep 'MY_USERNAME=' "$CONFIGURATION_FILE" | head -n 1 | awk -F '=' '{print $2}')
# check_for_existing_processes $restore_keys_script
{ echo "echo \"Beginning webadmin restore keys \$(date)\" > $webadmin_install_dir/restore.txt";
echo "chown www-data:www-data $webadmin_install_dir/restore.txt";
echo '';
echo "cp $webadmin_install_dir/restore_keys_progress_template.html $webadmin_install_dir/restore_keys_progress.html";
echo "chown www-data:www-data $webadmin_install_dir/restore_keys_progress.html";
echo '';
echo "if /usr/local/bin/${PROJECT_NAME}-recoverkey -u \"$admin_username\" -d \"simple\" >> $webadmin_install_dir/restore.txt; then";
echo " echo \"Completed \$(date)\" >> $webadmin_install_dir/restore.txt";
echo " cp $webadmin_install_dir/restore_keys_complete.html $webadmin_install_dir/restore_keys_progress.html";
echo 'else';
echo " cp $webadmin_install_dir/restore_keys_failed.html $webadmin_install_dir/restore_keys_progress.html";
echo 'fi';
echo '';
echo "chown www-data:www-data $webadmin_install_dir/restore.txt";
echo "chown www-data:www-data $webadmin_install_dir/restore_keys_progress.html";
echo '';
echo "exit 0"; } >> $restore_keys_script
chmod +x $restore_keys_script
# run in a separate process
./$restore_keys_script &
else
if [ -f "$backup_keys_file" ]; then
rm "$backup_keys_file"
admin_username=$(grep 'MY_USERNAME=' "$CONFIGURATION_FILE" | head -n 1 | awk -F '=' '{print $2}')
check_for_existing_processes $backup_keys_script
{ echo "echo \"Beginning webadmin backup keys \$(date)\" > $webadmin_install_dir/backup.txt";
echo "chown www-data:www-data $webadmin_install_dir/backup.txt";
echo '';
echo "cp $webadmin_install_dir/backup_keys_progress_template.html $webadmin_install_dir/backup_keys_progress.html";
echo "chown www-data:www-data $webadmin_install_dir/backup_keys_progress.html";
echo '';
echo "if /usr/local/bin/${PROJECT_NAME}-keydrive -u \"$admin_username\" --master 'yes' -d \"simple\" >> $webadmin_install_dir/backup.txt; then";
echo " echo \"Completed \$(date)\" >> $webadmin_install_dir/backup.txt";
echo " cp $webadmin_install_dir/backup_keys_complete.html $webadmin_install_dir/backup_keys_progress.html";
echo 'else';
echo " cp $webadmin_install_dir/backup_keys_failed.html $webadmin_install_dir/backup_keys_progress.html";
echo 'fi';
echo '';
echo "chown www-data:www-data $webadmin_install_dir/backup.txt";
echo "chown www-data:www-data $webadmin_install_dir/backup_keys_progress.html";
echo '';
echo "exit 0"; } >> $backup_keys_script
chmod +x $backup_keys_script
# run in a separate process
./$backup_keys_script &
fi
fi
}
function is_valid_user {
USRNAME="$1"
if [[ "$USRNAME" != "turtl" && "$USRNAME" != "znc" && "$USRNAME" != "pihole" && "$USRNAME" != "fbone" && "$USRNAME" != "go" && "$USRNAME" != "gogs" && "$USRNAME" != "git" && "$USRNAME" != "sync" && "$USRNAME" != "tahoelafs" ]]; then
echo "1"
else
echo "0"
fi
}
function valid_username_characters {
local re='^[[:lower:]_][[:lower:][:digit:]_-]{2,15}$'
(( ${#1} > 16 )) && return 1
[[ $1 =~ $re ]] # return value of this comparison is used for the function
}
function add_remove_users {
if [ -f "$new_user_file" ]; then
new_username=$(awk -F ',' '{print $1}' < "$new_user_file")
if [ ${#new_username} -ge 3 ]; then
if [ ${#new_username} -le 32 ]; then
if valid_username_characters "$new_username"; then
if [ ! -d "/home/$new_username" ]; then
if [[ $(is_valid_user "$new_username") == "1" ]]; then
new_password=$(awk -F ',' '{print $2}' < "$new_user_file")
check_for_existing_processes $new_user_script
{ echo "/usr/local/bin/${PROJECT_NAME}-adduser $new_username password=$new_password > $webadmin_install_dir/log.txt";
echo "exit 0"; } >> $new_user_script
chmod +x $new_user_script
# run in a separate process
./$new_user_script &
new_password=
fi
fi
fi
fi
fi
rm "$new_user_file"
fi
if [ -f "$remove_user_file" ]; then
remove_username=$(cat "$remove_user_file")
if [ ${#remove_username} -ge 3 ]; then
if [ ${#remove_username} -le 32 ]; then
if valid_username_characters "$remove_username"; then
if [ -d "/home/$remove_username" ]; then
if [[ $(is_valid_user "$remove_username") == "1" ]]; then
admin_username=$(grep 'MY_USERNAME=' "$CONFIGURATION_FILE" | head -n 1 | awk -F '=' '{print $2}')
if [[ "$remove_username" != "$admin_username" ]]; then
check_for_existing_processes $remove_user_script
{ echo "/usr/local/bin/${PROJECT_NAME}-rmuser $remove_username -f > $webadmin_install_dir/log.txt";
echo "exit 0"; } >> $remove_user_script
chmod +x $remove_user_script
# run in a separate process
./$remove_user_script &
fi
fi
fi
fi
fi
fi
rm "$remove_user_file"
fi
}
function webadmin_change_password {
if [ ! -f "$change_password_file" ]; then
return
fi
temp_password_file=$(cat "$change_password_file")
if [ -f "$temp_password_file" ]; then
curr_username=$(awk -F ',' '{print $1}' < "$temp_password_file")
if [ ${#curr_username} -ge 3 ]; then
if [[ $(is_valid_user "$curr_username") == "1" ]]; then
if [ -d "/home/$curr_username" ]; then
new_password=$(awk -F ',' '{print $2}' < "$temp_password_file")
admin_username=$(grep 'MY_USERNAME=' "$CONFIGURATION_FILE" | head -n 1 | awk -F '=' '{print $2}')
# change the webadmin login
if [[ "$curr_username" == "$admin_username" ]]; then
if [ -f /etc/nginx/.webadminpasswd ]; then
sed -i "/${curr_username}:/d" /etc/nginx/.webadminpasswd
fi
echo -n "$new_password" | htpasswd -i -s -c /etc/nginx/.webadminpasswd "$curr_username"
fi
# change the login for the user
echo "${curr_username}:${new_password}"|chpasswd
# change passwords for each installed app
/usr/local/bin/${PROJECT_NAME}-chpasswd "$curr_username" "$new_password"
new_password=
fi
fi
fi
rm "$temp_password_file"
fi
rm "$change_password_file"
}
function reset_shutdown {
if [ -f "$shutdown_file" ]; then
rm "$shutdown_file"
if [ -f "$reset_file" ]; then
rm "$reset_file"
fi
sleep 2
systemctl poweroff
fi
if [ -f "$reset_file" ]; then
rm "$reset_file"
if [ -f "$shutdown_file" ]; then
rm "$shutdown_file"
fi
sleep 2
systemctl reboot -i
fi
}
function regenerate_blocklist {
if [ ! -f "$FIREWALL_DOMAINS" ]; then
touch "$FIREWALL_DOMAINS"
fi
local_hostname=$(grep 'host-name' /etc/avahi/avahi-daemon.conf | awk -F '=' '{print $2}').local
webadmin_install_dir="/var/www/${local_hostname}/htdocs/admin"
if [ -f "$webadmin_install_dir/blocking_template.html" ]; then
cp "$webadmin_install_dir/blocking_template.html" "$webadmin_install_dir/blocking.html"
blockedlist=$(sed 's@[/\&]@\\&@g;s/$/\\/' "$FIREWALL_DOMAINS"; echo .)
blockedlist=${blockedlist%.}
sed -i "s|BLOCKEDLIST|$blockedlist|g" "$webadmin_install_dir/blocking.html"
chown www-data:www-data "$webadmin_install_dir/blocking.html"
fi
}
function regenerate_dynamic_dns {
ddns="$1"
ddns_username="$2"
ddns_password="$3"
local_hostname=$(grep 'host-name' /etc/avahi/avahi-daemon.conf | awk -F '=' '{print $2}').local
webadmin_install_dir="/var/www/${local_hostname}/htdocs/admin"
if [ -f "$webadmin_install_dir/dynamicdns_template.html" ]; then
cp "$webadmin_install_dir/dynamicdns_template.html" "$webadmin_install_dir/dynamicdns.html"
if [[ "$ddns" == 'default@freedns.afraid.org' ]]; then
ddns='freedns'
fi
if [[ "$ddns" == 'dyn.com' ]]; then
ddns='dyn'
fi
sed -i "s|\"$ddns\"|\"$ddns\" selected|g" "$webadmin_install_dir/dynamicdns.html"
sed -i "s|DDNS_USERNAME|$ddns_username|g" "$webadmin_install_dir/dynamicdns.html"
# Note: For security don't populate the password
#sed -i "s|DDNS_PASSWORD|$ddns_password|g" "$webadmin_install_dir/dynamicdns.html"
chown www-data:www-data "$webadmin_install_dir/dynamicdns.html"
fi
}
function update_blocklist {
if [ -f "$blocklist_file" ]; then
if [ -f "${FIREWALL_DOMAINS}.new" ]; then
rm "${FIREWALL_DOMAINS}.new"
fi
touch "${FIREWALL_DOMAINS}.new"
blocked_lines_ctr=0
while read -r line; do
if [ $blocked_lines_ctr -gt 1024 ]; then
# This prevents someone copy-pasting a giant amount of text
# into the blocklist. If you're legitimately blocking more
# than this number then you probably have other problems to
# think about and should consider whitelisting instead
break
fi
blocked_lines_ctr=$((blocked_lines_ctr + 1))
if [ "$line" ]; then
# remove leading and trailing spaces
newline="$(echo -e "${line}" | sed -e 's/^[[:space:]]*//' -e 's/[[:space:]]*$//')"
line="$newline"
if [[ "$line" == *'@'* ]]; then
# blocked user
# remove leading @
if [[ "$line" == '@'* ]]; then
newline=${line:1}
line="$newline"
fi
blocked_username=$(echo "$line" | awk -F '@' '{print $1}')
if valid_username_characters "$blocked_username"; then
blocked_domain=$(echo "$line" | awk -F '@' '{print $2}')
if [[ "$blocked_domain" == *'.'* ]]; then
if [ ${#blocked_domain} -gt 3 ]; then
test_domain=$(echo "$blocked_domain" | tr -dc a-z0-9.-)
if [[ "$blocked_domain" == "$test_domain" ]]; then
blocked_address="${blocked_username}@${blocked_domain}"
if ! grep -q "$blocked_address" "${FIREWALL_DOMAINS}.new"; then
echo "${blocked_username}@${blocked_domain}" >> "${FIREWALL_DOMAINS}.new"
fi
fi
fi
fi
fi
else
# blocked domain
if [[ "$line" == *'.'* ]]; then
blocked_domain="$line"
test_domain=$(echo "$blocked_domain" | tr -dc a-z0-9.-)
if [[ "$blocked_domain" == "$test_domain" ]]; then
if [ ${#blocked_domain} -gt 3 ]; then
if ! grep -q "$blocked_domain" "${FIREWALL_DOMAINS}.new"; then
echo "$blocked_domain" >> "${FIREWALL_DOMAINS}.new"
fi
fi
fi
fi
fi
fi
done < "$blocklist_file"
mv "${FIREWALL_DOMAINS}" "${FIREWALL_DOMAINS}.backup"
mv "${FIREWALL_DOMAINS}.new" "${FIREWALL_DOMAINS}"
rm "$blocklist_file"
regenerate_blocklist
fi
}
function update_dynamic_dns {
if [ -f "$dynamic_dns_file" ]; then
ddns=$(awk -F ',' '{print $1}' < "$dynamic_dns_file")
ddns_username=$(awk -F ',' '{print $2}' < "$dynamic_dns_file")
ddns_password=$(awk -F ',' '{print $3}' < "$dynamic_dns_file")
ddns_is_valid=
if [ "$ddns_username" ]; then
if [ "$ddns_password" ]; then
if [ ${#ddns_username} -gt 2 ]; then
if [ ${#ddns_username} -lt 512 ]; then
if [ ${#ddns_password} -gt 2 ]; then
if [ ${#ddns_password} -lt 512 ]; then
ddns_is_valid=1
fi
fi
fi
fi
fi
fi
if [ $ddns_is_valid ]; then
/usr/local/bin/${PROJECT_NAME}-ddns "$ddns" "$ddns_username" "$ddns_password"
regenerate_dynamic_dns "$ddns" "$ddns_username" "$ddns_password"
fi
rm "$dynamic_dns_file"
fi
}
function change_language {
if [ -f "$language_file" ]; then
language=$(cat "$language_file")
local_hostname=$(grep 'host-name' /etc/avahi/avahi-daemon.conf | awk -F '=' '{print $2}').local
webadmin_install_dir="/var/www/${local_hostname}/htdocs/admin"
if [ -f "$webadmin_install_dir/language_template.html" ]; then
if grep -q "\"$language\"" "$webadmin_install_dir/language_template.html"; then
cp "$webadmin_install_dir/language_template.html" "$webadmin_install_dir/language.html"
sed -i "s|\"$language\"|\"$language\" selected|g" "$webadmin_install_dir/language.html"
chown www-data:www-data "$webadmin_install_dir/language.html"
config_language=$(grep "DEFAULT_LANGUAGE=" "$CONFIGURATION_FILE" | awk -F '=' '{print $2}')
if [[ "$config_language" != "$language" ]]; then
curr_language=$(web_admin_get_language_subdir)
if [ -d "/usr/share/${PROJECT_NAME}/webadmin/${curr_language}" ]; then
# copy files for the new language
cp -r "/usr/share/${PROJECT_NAME}/webadmin/${curr_language}/*" "/usr/share/${PROJECT_NAME}/webadmin/"
# recreate some screens from templates
regenerate_blocklist
touch "$system_monitor_file"
update_system_monitor
webadmin_update_version
fi
chown -R www-data:www-data "$webadmin_install_dir/*"
sed -i "s|DEFAULT_LANGUAGE=.*|DEFAULT_LANGUAGE=$language|g" "$CONFIGURATION_FILE"
locale-gen "${language}"
update-locale LANG="${language}"
update-locale LANGUAGE="${language}"
update-locale LC_MESSAGES="${language}"
update-locale LC_ALL="${language}"
update-locale LC_CTYPE="${language}"
fi
fi
fi
rm "$language_file"
fi
}
function update_system_monitor {
if [ -f "$system_monitor_file" ]; then
rm "$system_monitor_file"
disk_use=$(df -h | grep /dev/sda1)
disk_use_percent=0
if [[ "$disk_use" == *'/dev/sda1'* ]]; then
disk_use_percent=$(df -h | grep /dev/sda1 | awk -F ' ' '{print $5}')
else
disk_use_percent=$(df -h | grep /dev/mmcblk0p1 | awk -F ' ' '{print $5}')
fi
used_memory=$(free -m | grep "Mem:" | awk -F ' ' '{print $3}')
total_memory=$(free -m | grep "Mem:" | awk -F ' ' '{print $2}')
used_memory_percent=$((used_memory * 100 / total_memory))
cpu_temperature=0
if [ -f /sys/class/thermal/thermal_zone0/temp ]; then
cpu_temp=$(cat /sys/class/thermal/thermal_zone*/temp | head -n 1)
if [ "$cpu_temp" ]; then
cpu_temperature=$((cpu_temp / 1000))
fi
fi
test_drive=/dev/sda1
if ! ls $test_drive; then
if ls /dev/mmcblk0p2; then
test_drive=/dev/mmcblk0p2
else
test_drive=
fi
fi
disk_io_speed=20
disk_io_speed_percent=10
if [ "$test_drive" ]; then
disk_io_speed=$(hdparm -t $test_drive | awk -F '= ' '{print $2}' | awk -F ' ' '{print $1}' | tail -n 1 | awk -F '.' '{print $1}')
if [ "$disk_io_speed" ]; then
disk_io_speed_percent=$((disk_io_speed * 100 / 500))
if [ $disk_io_speed_percent -gt 100 ]; then
disk_io_speed_percent=100
fi
fi
fi
local_hostname=$(grep 'host-name' /etc/avahi/avahi-daemon.conf | awk -F '=' '{print $2}').local
webadmin_install_dir="/var/www/${local_hostname}/htdocs/admin"
if [ -f "$webadmin_install_dir/system_monitor_template.html" ]; then
cp "$webadmin_install_dir/system_monitor_template.html" "$webadmin_install_dir/system_monitor.html"
if [[ "$disk_use_percent" == *'%'* ]]; then
sed -i "s|<div name=\"diskspace\" class=\"w3-container.*|<div name=\"diskspace\" class=\"w3-container w3-blue w3-round-xlarge\" style=\"width:$disk_use_percent\">$disk_use_percent</div>|g" "$webadmin_install_dir/system_monitor.html"
fi
sed -i "s|<div name=\"memory\" class=\"w3-container.*|<div name=\"memory\" class=\"w3-container w3-blue w3-round-xlarge\" style=\"width:${used_memory_percent}%\">${used_memory_percent}%</div>|g" "$webadmin_install_dir/system_monitor.html"
if [ $cpu_temperature -gt 0 ]; then
sed -i "s|<div name=\"cputemp\" class=\"w3-container.*|<div name=\"cputemp\" class=\"w3-container w3-blue w3-round-xlarge\" style=\"width:${cpu_temperature}%\">${cpu_temperature}C</div>|g" "$webadmin_install_dir/system_monitor.html"
else
sed -i "/\"cputemp\"/d" "$webadmin_install_dir/system_monitor.html"
sed -i '/titletextcputemp/d' "$webadmin_install_dir/system_monitor.html"
fi
sed -i "s|<div name=\"diskio\" class=\"w3-container.*|<div name=\"diskio\" class=\"w3-container w3-blue w3-round-xlarge\" style=\"width:${disk_io_speed_percent}%\">${disk_io_speed} MB/s</div>|g" "$webadmin_install_dir/system_monitor.html"
chown www-data:www-data "$webadmin_install_dir/system_monitor.html"
fi
fi
}
# If the freedombone command is already running then kill its process
#shellcheck disable=SC2009
install_process=$(ps a | grep '/usr/local/bin/freedombone -c' | grep -v 'grep')
if [ "$install_process" ]; then
if [[ "$install_process" != *'grep'* ]]; then
install_pid=$(echo "$install_process" | awk -F ' ' '{print $1}')
if [ "$install_pid" ]; then
pkill -9 "$install_pid"
fi
fi
fi
# get the current install state
if [ -f "$install_state_file" ]; then
install_state=$(cat "$install_state_file")
# shellcheck disable=SC2086
if [ $install_state -ne $INSTALL_STATE_COMMAND_SUCCESS ]; then
if grep -q 'install_final' "$COMPLETION_FILE"; then
install_state=$INSTALL_STATE_COMMAND_SUCCESS
else
chown www-data:www-data "$webadmin_install_dir/log.txt"
# remove the setup file containing login details
if [ -f "$setup_file" ]; then
rm "$setup_file"
fi
if [ -f /etc/nginx/.webadminpasswd ]; then
rm /etc/nginx/.webadminpasswd
fi
install_state=$INSTALL_STATE_FIRST_BOOT
fi
echo -n "$install_state" > "$install_state_file"
fi
else
if grep -q 'install_final' "$COMPLETION_FILE"; then
install_state=$INSTALL_STATE_COMMAND_SUCCESS
else
install_state=$INSTALL_STATE_FIRST_BOOT
fi
echo -n "$install_state" > "$install_state_file"
fi
while true
do
if [ -f /tmp/.upgrading ]; then
sleep 2
else
web_admin_setup_login
if [ -d "$webadmin_install_dir" ]; then
if [ -f "$setup_file" ]; then
update_progress_bar
before_setup_runs
check_install_command_state
after_setup_has_finished
sleep 1
else
if [ $install_state -eq $INSTALL_STATE_COMMAND_SUCCESS ]; then
reset_shutdown
webadmin_change_password
update_blocklist
update_dynamic_dns
update_system_monitor
change_language
backup_and_restore
backup_and_restore_keys
add_remove_users
install_apps_from_webadmin
sleep 1
remove_apps_from_webadmin
fi
fi
fi
sleep 1
fi
done
exit 0