#! /bin/bash
#
# server_switcher       script to switch server on/off
#
# Edited by Jiri Brejcha <jirka@jiribrejcha.net> based on Nigel Bowden's <wifinigel@gmail.com> mode switcher
#
# History:
#
set -e

NAME=server_switcher
DESC="Script to switch server mode on/off"
STATUS_FILE="/etc/wlanpi-state"
SERVER_CONF_FILE="/etc/wlanpi-server/conf/hostapd.conf"

if [[ $EUID -ne 0 ]]; then
   echo "This script must be run as root"
   exit 1
fi

###############################################################################
#
# Activate server mode:
#
# 1. Backup various existing files to allow restoration when server
#    deactivated
# 2. Remove a number of existing files that need to be replaced
# 3. Create links from deleted file locations to server config files
# 4. Create status file to indicate server is active
# 5. Reboot the WLAN Pi to ensure clean activation
#
###############################################################################

server_on () {

  echo "Starting switch from Classic mode to Server mode"

  # check what state the WLAN Pi is in classic mode
  PI_STATUS=`cat $STATUS_FILE | grep 'classic'` || true
  if  [ -z "$PI_STATUS" ]; then
     echo "Failed: WLAN Pi is not in Classic mode"
     exit 1
  fi

  # Check if we are using the factory shipped SSID, rename if we are
  echo "Checking for factory default SSID name ..."
  if grep -q -E "^?ssid=wlanpi_server" $SERVER_CONF_FILE; then
    echo "Creating a unique SSID ..."
    # Get the last 3 chars of eth0 MAC address
    LAST_3_CHARS_MAC=$(sed s/://g /sys/class/net/eth0/address | grep -o '...$')
    # Check if we got 3 chars
    if [ ${#LAST_3_CHARS_MAC} -ne 3 ]; then
      echo "Failed parsing eth0 MAC address during unique SSID creation"
      exit 1
    fi
    # Configure the unique SSID
    if grep -q -E "^?ssid=" $SERVER_CONF_FILE; then
     sed -i "s/^#\?ssid=.*/ssid=WLAN Pi Server $LAST_3_CHARS_MAC/" $SERVER_CONF_FILE
    else
      echo "ssid=WLAN Pi Server $LAST_3_CHARS_MAC" >> $SERVER_CONF_FILE
    fi
  fi

  # Generate a random passphrase if the user has not configured their own one
  if grep -q -E "^?wpa_passphrase=wifipros" $SERVER_CONF_FILE; then
    echo "Generating a new random WPA2 passphrase ..."
    PASSPHRASE=$(tr -dc 'A-Ha-h2-9J-Kj-k2-9M-Nm-n2-9P-Zp-z2-9' </dev/urandom | head -c 12  ; echo)
    sed -i "s/^#\?wpa_passphrase=.*/wpa_passphrase=$PASSPHRASE/" $SERVER_CONF_FILE
  fi

  echo "Enabling server mode ..."
  # Backup existing config files
  echo "Backing up existing config files ..."
  cp /etc/default/isc-dhcp-server /etc/default/isc-dhcp-server.serv
  cp /etc/dhcp/dhcpd.conf /etc/dhcp/dhcpd.conf.serv
  cp /etc/network/interfaces /etc/network/interfaces.serv
  cp /etc/sysctl.conf /etc/sysctl.conf.serv
  cp /etc/default/ufw /etc/default/ufw.serv
  cp /etc/ufw/before.rules /etc/ufw/before.rules.serv
  # This file may or may not exist
  if [ -e /etc/hostapd/hostapd.conf ]; then
    cp /etc/hostapd/hostapd.conf /etc/hostapd/hostapd.conf.serv
  fi
  if [ -e /etc/ser2net.conf ]; then
    cp /etc/ser2net.conf /etc/ser2net.conf.serv
  fi
  # Remove existing config files
  echo "Removing existing config files ..."
  rm /etc/default/isc-dhcp-server
  rm /etc/dhcp/dhcpd.conf
  rm /etc/network/interfaces
  rm /etc/sysctl.conf
  rm /etc/default/ufw
  rm /etc/ufw/before.rules
  # This file may or may not exist
  if [ -e /etc/hostapd/hostapd.conf ]; then
    rm /etc/hostapd/hostapd.conf
  fi
  if [ -e /etc/ser2net.conf ]; then
    rm /etc/ser2net.conf
  fi

  # Create directory if it doesn't exist
  if [ ! -d "/etc/hostapd" ]; then
      echo "Directory /etc/hostapd does not exist. Creating it..."
      mkdir -p "/etc/hostapd"
  fi

  # Link to server config files
  echo "Creating links to config files..."
  ln -s /etc/wlanpi-server/default/isc-dhcp-server /etc/default/isc-dhcp-server
  ln -s /etc/wlanpi-server/dhcp/dhcpd.conf /etc/dhcp/dhcpd.conf
  ln -s /etc/wlanpi-server/network/interfaces /etc/network/interfaces
  ln -s /etc/wlanpi-server/conf/hostapd.conf /etc/hostapd/hostapd.conf
  ln -s /etc/wlanpi-server/sysctl/sysctl.conf /etc/sysctl.conf
  ln -s /etc/wlanpi-server/default/ufw /etc/default/ufw
  ln -s /etc/wlanpi-server/ufw/before.rules /etc/ufw/before.rules
  # Intentionally using wconsole config file
  ln -s /etc/wlanpi-wconsole/conf/ser2net.conf /etc/ser2net.conf

  # Open up console ports on FW
  ufw allow 2400:2408/tcp
  ufw allow 4800:4808/tcp
  ufw allow 9600:9608/tcp
  ufw allow 19200:19208/tcp
  ufw allow 38400:38408/tcp
  ufw allow 11520:11528/tcp
  ufw allow 2000:2008/tcp

  # Enable services to start after reboot
  systemctl enable hostapd ser2net isc-dhcp-server

  # Signal that we want to stay in Server mode after reboot
  touch "/etc/wlanpi-stay-in-server-mode"

  # Signal that Server mode is active
  echo "server" > $STATUS_FILE
  echo "WLAN Pi will now reboot"
  sleep 1
  sync
  reboot
}

###############################################################################
#
# Deactivate server:
#
# 1. Remove links created during activation
# 2. Restore config files backed up during activation
# 3. Remove firewall rules added during activation
# 4. Remove status file to indicate server no longer active
# 5. Reboot wlanpi to provide clean restoration of services
#
###############################################################################

server_off () {

  # Check what state the WLAN Pi is in
  PI_STATUS=`cat $STATUS_FILE | grep 'server'` || true
  if  [ -z "$PI_STATUS" ]; then
     echo "Failed - WLAN Pi is not in server mode."
     exit 1
  fi

  echo "Starting switch from server mode to classic mode"

  # Remove links to config files
  echo "Removing links to config files ..."
  unlink /etc/default/isc-dhcp-server
  unlink /etc/dhcp/dhcpd.conf
  unlink /etc/network/interfaces
  unlink /etc/hostapd/hostapd.conf
  unlink /etc/sysctl.conf
  unlink /etc/default/ufw
  unlink /etc/ufw/before.rules
  unlink /etc/ser2net.conf

  # Restore original config files
  echo "Restoring original config files ..."
  cp /etc/default/isc-dhcp-server.serv /etc/default/isc-dhcp-server
  cp /etc/dhcp/dhcpd.conf.serv /etc/dhcp/dhcpd.conf
  cp /etc/network/interfaces.serv /etc/network/interfaces
  cp /etc/sysctl.conf.serv /etc/sysctl.conf
  cp /etc/default/ufw.serv /etc/default/ufw
  cp /etc/ufw/before.rules.serv /etc/ufw/before.rules
  # This file may or may not exist
  if [ -e /etc/hostapd/hostapd.conf.serv ]; then
    cp /etc/hostapd/hostapd.conf.serv /etc/hostapd/hostapd.conf
  fi
  if [ -e /etc/ser2net.conf.serv ]; then
    cp /etc/ser2net.conf.serv /etc/ser2net.conf
  fi
  
  # Close ports on FW
  ufw delete allow 2400:2408/tcp
  ufw delete allow 4800:4808/tcp
  ufw delete allow 9600:9608/tcp
  ufw delete allow 19200:19208/tcp
  ufw delete allow 38400:38408/tcp
  ufw delete allow 2000:2008/tcp
  ufw delete allow 11520:11528/tcp
  
  # Disable services to start after reboot
  systemctl disable hostapd ser2net isc-dhcp-server

  echo "WLAN Pi will now reboot"
  echo "classic" > $STATUS_FILE
  sleep 1
  sync
  reboot
}

status () {
  PI_STATUS=`cat $STATUS_FILE | grep 'server'` || true
  if  [ -z "$PI_STATUS" ]; then
    echo "server is currently disabled"
    exit 0
  else
    echo "server is currently enabled"
    exit 0
  fi

}

version () {
  VERSION=$(apt list --installed wlanpi-server 2>/dev/null | grep wlanpi-server | awk '{print $2}')
  echo "Version: $VERSION" >&2
  exit 0
}

case "$1" in
  on)
        server_on
        ;;
  off)
        server_off
        ;;
  status)
        status
        ;;
  install)
        install
        ;;
  version)
        version;;
  *)
        N=/etc/wlanpi-server/$NAME
        echo "Usage: $N {on|off|status|version}" >&2
        exit 1
        ;;
esac

exit 0