#!/usr/bin/env bash mumbleConfigFile="/etc/mumble/mumble-server.ini" mumbleWelcomeFile="/etc/mumble/welcomefile.html" mumbleDefaultPort="64738" mumble_installed() { pacman -Q mumble-server &> /dev/null } ufw_installed() { pacman -Q ufw &> /dev/null } valid_port() { local portValue="$1" [[ "$portValue" =~ ^[0-9]+$ ]] && (( portValue >= 1 && portValue <= 65535 )) } install_mumble_server() { if mumble_installed; then return 0 fi if ! install_package mumble-server; then msgbox "Failed to install mumble-server." return 1 fi return 0 } set_mumble_config_value() { local keyName="$1" local keyValue="$2" local tempFile="" tempFile="$(mktemp)" # `sudoFlags` is initialized by the main launcher before sourcing this file. # shellcheck disable=SC2024,SC2154 if ! sudo "${sudoFlags[@]}" awk -v keyName="$keyName" -v keyValue="$keyValue" ' BEGIN { updated = 0 } $0 ~ "^[;#]?[[:space:]]*" keyName "[[:space:]]*=" { print keyName "=" keyValue updated = 1 next } { print } END { if (!updated) { print keyName "=" keyValue } } ' "$mumbleConfigFile" > "$tempFile"; then rm -f "$tempFile" msgbox "Failed to update ${keyName} in ${mumbleConfigFile}." return 1 fi if ! sudo "${sudoFlags[@]}" install -m 640 "$tempFile" "$mumbleConfigFile"; then rm -f "$tempFile" msgbox "Failed to save ${mumbleConfigFile}." return 1 fi rm -f "$tempFile" return 0 } clear_mumble_config_value() { local keyName="$1" set_mumble_config_value "$keyName" "" } read_mumble_port() { local configuredPort="" # `sudoFlags` is initialized by the main launcher before sourcing this file. # shellcheck disable=SC2154 if sudo "${sudoFlags[@]}" test -r "$mumbleConfigFile"; then configuredPort="$(sudo "${sudoFlags[@]}" awk -F '=' ' BEGIN { IGNORECASE = 1 } /^[[:space:]]*port[[:space:]]*=/ { value = $2 sub(/[[:space:]]*#.*$/, "", value) gsub(/^[[:space:]]+|[[:space:]]+$/, "", value) port = value } END { if (port != "") { print port } } ' "$mumbleConfigFile")" fi if valid_port "$configuredPort"; then printf '%s\n' "$configuredPort" else printf '%s\n' "$mumbleDefaultPort" fi } capture_welcome_message() { local tempFile="" local messageSize=0 if [[ "$(yesno "Would you like to create a welcome message now?")" != "Yes" ]]; then return 1 fi tempFile="$(mktemp)" clear cat <<'EOF' Enter the Mumble welcome message below. HTML is supported. Press Ctrl+D on a new line when you are finished. Leave it blank and press Ctrl+D to skip it. EOF cat > "$tempFile" messageSize="$(wc -c < "$tempFile")" if [[ "$messageSize" -eq 0 ]]; then rm -f "$tempFile" return 1 fi printf '%s\n' "$tempFile" return 0 } install_welcome_message() { local messageFile="$1" # `sudoFlags` is initialized by the main launcher before sourcing this file. # shellcheck disable=SC2154 if ! sudo "${sudoFlags[@]}" install -m 644 "$messageFile" "$mumbleWelcomeFile"; then msgbox "Failed to write ${mumbleWelcomeFile}." return 1 fi set_mumble_config_value "welcometextfile" "$mumbleWelcomeFile" } set_mumble_superuser_password() { local superuserPassword="$1" if [[ -z "$superuserPassword" ]]; then msgbox "The SuperUser password cannot be blank." return 1 fi # `sudoFlags` is initialized by the main launcher before sourcing this file. # shellcheck disable=SC2154 if ! printf '%s\n' "$superuserPassword" | sudo "${sudoFlags[@]}" mumble-server -ini "$mumbleConfigFile" -readsupw; then msgbox "Failed to set the Mumble SuperUser password." return 1 fi return 0 } enable_mumble_service() { # `sudoFlags` is initialized by the main launcher before sourcing this file. # shellcheck disable=SC2154 if ! sudo "${sudoFlags[@]}" systemctl enable --now mumble-server; then msgbox "Mumble was configured, but the service failed to enable or start." return 1 fi return 0 } configure_mumble_firewall() { local mumblePort="" if ! ufw_installed; then return 0 fi if [[ "$(yesno "ufw is installed. Open the default Mumble port now?")" != "Yes" ]]; then return 0 fi mumblePort="$(read_mumble_port)" # `sudoFlags` is initialized by the main launcher before sourcing this file. # shellcheck disable=SC2154 if ! sudo "${sudoFlags[@]}" ufw allow "${mumblePort}/tcp"; then msgbox "Failed to allow ${mumblePort}/tcp for Mumble." return 1 fi # shellcheck disable=SC2154 if ! sudo "${sudoFlags[@]}" ufw allow "${mumblePort}/udp"; then msgbox "Failed to allow ${mumblePort}/udp for Mumble." return 1 fi msgbox "The default Mumble firewall rules were added." return 0 } install_mumble_server || return 1 superuserPassword="$(passwordbox "Enter the Mumble SuperUser password.")" || return 1 serverPassword="$(passwordbox "Enter a server password, or leave blank for no server password.")" || return 1 allowRecordingChoice="$(yesno "Allow users to record audio on this server?")" welcomeMessageFile="" welcomeMessageFile="$(capture_welcome_message || true)" reset set_mumble_superuser_password "$superuserPassword" || return 1 if [[ -n "$serverPassword" ]]; then set_mumble_config_value "serverpassword" "$serverPassword" || return 1 else clear_mumble_config_value "serverpassword" || return 1 fi if [[ "$allowRecordingChoice" == "Yes" ]]; then set_mumble_config_value "allowRecording" "true" || return 1 else set_mumble_config_value "allowRecording" "false" || return 1 fi if [[ -n "$welcomeMessageFile" ]]; then install_welcome_message "$welcomeMessageFile" || { rm -f "$welcomeMessageFile" return 1 } rm -f "$welcomeMessageFile" else clear_mumble_config_value "welcometextfile" || return 1 fi enable_mumble_service || return 1 configure_mumble_firewall || return 1 msgbox "Basic Mumble configuration is complete. To fine tune your setup, edit ${mumbleConfigFile} as root."