#!/bin/bash
# Author: Steven Shiau <steven _at_ nchc org tw>
# License: GPL

# Load DRBL setting and functions
. /opt/drbl/sbin/drbl-conf-functions

# slat for SHA1, better to leave it empty, let the program pick a random one.
salt=""

#
usage() {
    echo "Usage:"
    echo "To set the pxelinux password for clients:"
    echo "`basename $0` [OPTION]"
    echo " Options:"
    echo " --stdin PASSWORD     set the root's password for clients as PASSWORD"
    echo " -h, --host IP_ADDRESS:  set only for the host with IP_ADDRESS instead of all DRBL clients"
    echo " -d, --disable        disable the menu password"
    echo " -e, --enaable        enable the menu password"
    echo " -v, --verbose        prints out verbose information"
}

#
check_if_root

# main
unalias ls 2>/dev/null

specified_host=''
# Parse command-line options
while [ $# -gt 0 ]; do
  case "$1" in
    --stdin)  
            shift;
            if [ -z "$(echo $1 |grep ^-.)" ]; then
              # skip the -xx option, in case 
	      pxelinux_passwd="$1"
            fi
            shift;;
    -h|--host)
            shift; specified_host="$specified_host $1"
            shift;;
    -d|--disable)
            shift; mode="disable"
	    ;;
    -e|--enable)
            shift; mode="enable"
	    ;;
    -v|--verbose)
            shift; VERBOSE="on"
            ;;
    -*)     echo "${0}: ${1}: invalid option" >&2
            usage >& 2
            exit 2 ;;
    *)      break ;;
  esac
done

if [ -z "$mode" ]; then
  usage
  exit 1
fi

#
input_new_passwd() {
  # interactive
  echo "New password: (It will not be echoed in the screen)"
  read -s pass1
  echo "Retype new password: (It will not be echoed in the screen)"
  read -s pass2
  while [ "$pass1" != "$pass2" ]; do
    echo "Sorry, passwords do not match"
    echo "New password: (It will not be echoed in the screen)"
    read -s pass1
    echo "Retype new password: (It will not be echoed in the screen)"
    read -s pass2
  done
  #
  [ -z "$pass1" ] && echo "Password can NOT be empty!!! Program terminated" && exit 1
  # set the matched password
  new_passwd="$pass1"
}

get_pxelinux_master_sha1passwd() {
  local CONFILE="$1"
  sha1_passwd="$(grep -i "^[[:space:]]*[#]*[[:space:]]*MENU MASTER PASSWD.*" $PXELINUX_DIR/$CONFILE | sed -e "s/^[[:space:]]*[#]*[[:space:]]*MENU MASTER PASSWD[[:space:]]*//g")"
}

get_new_passwd_or_old_sha1_passwd() {
  local CONFILE="$1"
  get_pxelinux_master_sha1passwd $CONFILE
  if [ -z "$pxelinux_passwd" ]; then
     if [ -z "$sha1_passwd" ]; then
       # ask user the input
       input_new_passwd
     else
       # confirm since old sha1_passwd exists
       echo "Previous password for pxelinux exists! Do you want to overwrite ?"
       echo "[y/N] "
       read overwrite_pxelinux_passwd
       case "$overwrite_pxelinux_passwd" in
          y|Y|[yY][eE][sS])
             input_new_passwd
             ;;
          *)
             echo "We will use the old password."
             ;;
       esac
     fi
  else
     # enter from stdin
     new_passwd="$pxelinux_passwd"
  fi
}

disable_pxepasswd_in_config() {
  local CONFILE="$1"
  perl -pi -e 's/^[[:space:]]*[#]*[[:space:]]*(timeout .*)/$1/gi' $PXELINUX_DIR/$CONFILE
  perl -pi -e 's/^[[:space:]]*[#]*[[:space:]]*(MENU MASTER PASSWD.*)/# $1/gi' $PXELINUX_DIR/$CONFILE
  perl -pi -e 's/^[[:space:]]*[#]*[[:space:]]*(MENU PASSWD.*)/  # $1/gi' $PXELINUX_DIR/$CONFILE
}

enable_pxepasswd_in_config() {
  local CONFILE="$1"
  local PASSWD_STR="$2"
     perl -pi -e 's/^[[:space:]]*(timeout .*)/# $1/gi' $PXELINUX_DIR/$CONFILE
     perl -pi -e "s/^[[:space:]]*[#]*[[:space:]]*MENU MASTER PASSWD.*/MENU MASTER PASSWD $PASSWD_STR/gi" $PXELINUX_DIR/$CONFILE
     perl -pi -e 's/^[[:space:]]*[#]*[[:space:]]*MENU PASSWD.*/  MENU PASSWD/gi' $PXELINUX_DIR/$CONFILE
}

enable_pxe_passwd() {
#
if [ -n "$specified_host" ]; then
  PXE_CONF="$PXELINUX_DIR/default_skeleton"
  cp -f $PXELINUX_DIR/default $PXE_CONF
  # check every hosts
  for ip in $specified_host; do
    if [ ! -d "$drblroot/$ip" ]; then
       [ "$BOOTUP" = "color" ] && $SETCOLOR_WARNING
       echo "Warning! Can NOT find DRBL client $ip (i.e. no $drblroot/$ip)! Program terminated!"
       [ "$BOOTUP" = "color" ] && $SETCOLOR_NORMAL
    fi
  done
 [ -n "$verbose" ] && echo "specified_host: $specified_host"
fi

# set the host to be processed
# host_list is the IP address of client, like 192.168.1.1...
if [ -n "$specified_host" ]; then
   # set the host path
   for ip in $specified_host; do
     hex_ip="$($DRBL_SCRIPT_PATH/bin/gethostip.pl $ip)"
     echo "Creating the pxelinux simple menu for DRBL client $ip..."
     cp -f $PXE_CONF $PXELINUX_DIR/$hex_ip
     get_new_passwd_or_old_sha1_passwd $hex_ip
     if [ -n "$new_passwd" ]; then
       sha1_passwd="$($DRBL_SCRIPT_PATH/bin/sha1pass $new_passwd $salt)"
     fi
     sha1_passwd_escape="$(echo "$sha1_passwd" | sed -e 's|\$|\\\$|g' -e 's|/|\\/|g')"
     # comment the timeout
     enable_pxepasswd_in_config $hex_ip $sha1_passwd_escape
     echo "done!"
   done
else
   # withoud specified_host, it must be all clients, create the default
   echo "Creating the default pxelinux simple menu for all DRBL clients..."
   get_new_passwd_or_old_sha1_passwd default
   if [ -n "$new_passwd" ]; then
     sha1_passwd="$($DRBL_SCRIPT_PATH/bin/sha1pass $new_passwd $salt)"
   fi
   sha1_passwd_escape="$(echo "$sha1_passwd" | sed -e 's|\$|\\\$|g' -e 's|/|\\/|g')"
   # comment the timeout
   enable_pxepasswd_in_config default $sha1_passwd_escape
   echo "done!"
fi
}

#
disable_pxe_passwd() {
# set the host to be processed
# host_list is the IP address of client, like 192.168.1.1...
if [ -n "$specified_host" ]; then
   # set the host path
   for ip in $specified_host; do
     hex_ip="$($DRBL_SCRIPT_PATH/bin/gethostip.pl $ip)"
     echo -n "Disabling the password in gxelinux simple menu for client $ip... "
     cp -f $PXE_CONF $PXELINUX_DIR/$hex_ip
     # comment the timeout
     disable_pxepasswd_in_config $hex_ip
     echo "done!"
   done
else
   # withoud specified_host, it must be all clients, create the default
   echo -n "Disable the password in pxelinux simple menu for all clients... "
   # comment the timeout
   disable_pxepasswd_in_config default
   # TODO: clean all hexip and mac config ?
   if [ -n "$PXELINUX_DIR" ]; then
     find $PXELINUX_DIR/ -maxdepth 1 ! -name "default" -type f -exec rm -f {} \;
   fi
   echo "done!"
fi
}

case "$mode" in
   "disable")
         disable_pxe_passwd
         ;;
   "enable")
         enable_pxe_passwd
         ;;
esac
