#!/bin/bash
/usr/bin/sudo /usr/sbin/qnos-console -f

#/* QB: G#1087 2020/04/24 */
LOGGER_PREFIX="[`who am i | awk '{print $2 \" \" $3 \" \" $4 \" \" $5  \" \" $6}'`]"
#/* QE: G#1087 */

function valid_ip()
{
    local  ip=$1
    local  stat=1

    if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then
        OIFS=$IFS
        IFS='.'
        ip=($ip)
        IFS=$OIFS
        [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \
            && ${ip[2]} -le 255 && ${ip[3]} -le 255 ]]
        stat=$?
    fi
    return $stat
}

ipprompt() {
    read -p "IP address (255.255.255.255): " -n 15 -e ipaddress
    if ! valid_ip $ipaddress; then
        /bin/echo "That IP address is not valid. IP Address must be in XXX.XXX.XXX.XXX format."
        ipprompt
    fi
}
pathprompt() {
    if [[ $mode == "tftp" ]]; then 
        read -p "TFTP filename or /path/to/file: " -e path
    elif [[ $mode == "scp" ]]; then
        read -p "Absolute path to file: " -e path
    fi
    
}
portprompt() {
    if [[ $mode == "tftp" ]]; then 
        defaultport=69
    elif [[ $mode == "scp" ]]; then
        defaultport=22
    fi
    read -p "Port Number (defaults to $defaultport): " -n 5 -e port
    
        if [[ "$port" == "" ]]; then
            port=$defaultport
            /bin/echo "Using port $defaultport as nothing was entered"
        elif [[ ! "$port" > 0 ]] && [[ ! "$port" < 65535 ]]; then
            echo "This is not a valid port."
            return 1
    fi
}

#/* QB: G#937, 2020/03/04 */
verifytoolprompt() {
    if [[ $mode == "tftp" ]]; then
        read -p "TFTP verify-tool filename or /path/to/file: " -e toolpath
    elif [[ $mode == "scp" ]]; then
        read -p "Absolute path to verify-tool file: " -e toolpath
    fi
}
signpathprompt() {
    if [[ $mode == "tftp" ]]; then
        read -p "TFTP firmware filename or /path/to/file: " -e path
    elif [[ $mode == "scp" ]]; then
        read -p "Absolute path to firmware file: " -e path
    fi
}
#/* QE: G#937 */

#/* QB: G#2350, 2024/04/18 */
verify_version() {
  cur_ver=`dpkg -s linux-image-4.14.4 | grep "Version:" | sed 's/^.*Version: //'`
  dpkg-deb -I updateimage | grep "Depends:" |  grep "linux-image-4.14.4"
  if [[ $? != 0 ]]; then
    return 1
  fi
  ver=`dpkg-deb -I /tmp/update/updateimage | grep "Depends:" | sed 's/^.*linux-image-4.14.4 (= //' | sed 's/).*$//'`                               

  if [[ $cur_ver == $ver ]]; then
    return 0
  else
    return 1
  fi
}
#/* QE: G#2350 */

userprompt(){
read -p "SCP Username: " -e scpusername
}

#/* QB: G#1068, 2020/04/21 */
firmwareupgrade_log()
{
#/* QB: G#1083, 2020/04/23 */
#/* QB: G#1087 2020/04/24 */
logger -t '' -p local1.info "$LOGGER_PREFIX" "$1"
#/* QE: G#1087 */
#/* QE: G#1083 */
}
#/* QE: G#1068 */

firmwareupgrade(){
#/* QB: G#1068, 2020/04/21 */
firmwareupgrade_log "Start Firmware Update"
#/* QE: G#1068 */
if [[ "$input" == 2 ]]; then
    mode=scp
    #/* QB: G#1046, 2020/04/17 */
    #/* QB: E#317310, 2020/04/08 */
    #/* QB: G#937, 2020/03/04 */
    verifysign=1
    #/* QE: G#937 */
    #/* QE: E#317310 */
    #/* QE: G#1046 */
    #/* QB: G#1068, 2020/04/21 */
    firmwareupgrade_log "Firmware update with verification using SCP"
    #/* QE: G#1068 */
elif [[ "$input" == 3 ]]; then
    mode=tftp
    #/* QB: G#1046, 2020/04/17 */
    #/* QB: E#317310, 2020/04/08 */
    #/* QB: G#937, 2020/03/04 */
    verifysign=1
    #/* QE: G#937 */
    #/* QE: E#317310 */
    #/* QE: G#1046 */
    #/* QB: G#1068, 2020/04/21 */
    firmwareupgrade_log "Firmware update with verification using TFTP"
    #/* QE: G#1068 */
#/* QB: G#1046, 2020/04/17 */
#/* QB: E#317310, 2020/04/08 */
#/* QE: E#317310 */
#/* QE: G#1046 */
else 
    /bin/echo "No mode selected."
    #/* QB: G#1068, 2020/04/21 */
    firmwareupgrade_log "Firmware update, no mode selected."
    #/* QE: G#1068 */
fi
if [[ $mode ]]; then
    #/* QB: E#317301, 2020/04/07 */
    /usr/bin/sudo /bin/rm -rf /tmp/update &>/dev/null
    #/* QE: E#317301 */
 
    /bin/mkdir -p /tmp/update
    #/* QB: G#937, 2020/03/04 */
    /bin/rm -rf /tmp/update/* &>/dev/null
    #/* QE: G#937 */
    cd /tmp/update/
    ipprompt
    portprompt
    #/* QB: G#937, 2020/03/04 */
    if [[ "$verifysign" == 1 ]]; then
        signpathprompt
        #/* QB: E#317302, 2020/04/07 */
        #/* QE: E#317302 */
    else
        pathprompt
    fi
    #/* QE: G#937 */

    if [[ $mode == "tftp" ]]; then 
        echo "Starting TFTP transfer"
        #/* QB: G#1068, 2020/04/21 */
        firmwareupgrade_log "Starting TFTP transfer"
        #/* QE: G#1068 */
        /usr/bin/tftp "$ipaddress" "$port" -m binary -c get "$path"
        #/* QB: G#1068, 2020/04/21 */
        firmwareupgrade_log "Remote IP and port: $ipaddress:$port"
        #/* QB: G#1083, 2020/04/23 */
        filename="$(ls *)"
        firmwareupgrade_log "File: $filename"
        #/* QE: G#1083 */
        #/* QE: G#1068 */
        errorcode="$?"
        if [[ $errorcode == 69 ]]; then
            /bin/echo "An unknown error occured while attempting to get the image."
            #/* QB: G#1068, 2020/04/21 */
            firmwareupgrade_log "An unknown error occured while attempting to get the image."
            firmwareupgrade_log "End Firmware Update"
            #/* QE: G#1068 */
            return 1
        fi


        #/* QB: G#937, 2020/03/04 */
        if [[ "$verifysign" == 1 ]]; then
            #/* QB: G#1074, 2020/04/22 */
            /bin/mv /tmp/update/* /tmp/update/updateimage_sign
            #/* QE: G#1074 */

            #/* QB: G#1074, 2020/04/22 */
            if [[ -s /tmp/update/updateimage_sign ]]; then
            #/* QE: G#1074 */
                #/* QB: G#1074, 2020/04/22 */
                #/* QE: G#1074 */

                #/* QB: E#317302, 2020/04/07 */
                /mnt/application/verify_sign /tmp/update/updateimage_sign
                #/* QE: E#317302 */
                if [[ $? -ne 0 ]]; then
                    #/* QB: G#1083, 2020/04/23 */
                    firmwareupgrade_log "Downloading firmware"
                    firmwareupgrade_log "Firmware signature verification status: failed"
                    #/* QE: G#1083 */
                    echo "Error! Firmware installation stopped"
                    #/* QB: G#1068, 2020/04/21 */
                    firmwareupgrade_log "Error! Firmware installation stopped"
                    firmwareupgrade_log "End Firmware Update"
                    #/* QE: G#1068 */
                    return 1
                #/* QB: G#1083, 2020/04/23 */
                else
                    firmwareupgrade_log "Downloading firmware"
                    firmwareupgrade_log "Firmware signature verification status: passed"
                #/* QE: G#1083 */
                fi

                echo "Installing firmware"
                #/* QB: G#1068, 2020/04/21 */
                firmwareupgrade_log "Installing firmware"
                #/* QE: G#1068 */
            else
                #/* QB: G#1083, 2020/04/23 */
                echo "file $filename doesn't exist or isn't valid"
                #/* QE: G#1083 */
                #/* QB: G#1068, 2020/04/21 */
                #/* QB: G#1083, 2020/04/23 */
                firmwareupgrade_log "file $filename doesn't exist or isn't valid"
                #/* QE: G#1083 */
                firmwareupgrade_log "End Firmware Update"
                #/* QE: G#1068 */
                return 1
            fi
        else
            /bin/mv /tmp/update/* /tmp/update/updateimage    
        fi
        #/* QE: G#937 */

    elif [[ $mode == "scp" ]]; then
        userprompt
        defaultport=22
        /bin/echo "Starting SCP transfer"
        #/* QB: G#1068, 2020/04/21 */
        firmwareupgrade_log "Starting SCP transfer"
        #/* QE: G#1068 */

        #/* QB: G#937, 2020/03/04 */
        if [[ "$verifysign" == 1 ]]; then
            #/* QB: G#1074, 2020/04/22 */
            #/* QB: G#1083, 2020/04/23 */
            /usr/bin/scp -P "$port" "$scpusername"@"$ipaddress":"$path" ./
            #/* QE: G#1083 */
            #/* QE: G#1074 */
            #/* QB: G#1068, 2020/04/21 */
            #/* QB: G#1083, 2020/04/23 */
            #/* QE: G#1083 */
            firmwareupgrade_log "Remote IP and port: $ipaddress:$port"
            #/* QB: G#1083, 2020/04/23 */
            filename="$(ls *)"
            firmwareupgrade_log "File: $filename"
            /bin/mv /tmp/update/* /tmp/update/updateimage_sign
            #/* QE: G#1083 */
            #/* QE: G#1068 */
			

            #/* QB: G#1074, 2020/04/22 */
            if [[ -s /tmp/update/updateimage_sign ]]; then
            #/* QE: G#1074 */
                #/* QB: G#1074, 2020/04/22 */
                #/* QE: G#1074 */

                #/* QB: E#317302, 2020/04/07 */
                /mnt/application/verify_sign /tmp/update/updateimage_sign
                #/* QE: E#317302 */
                if [[ $? -ne 0 ]]; then
                    #/* QB: G#1083, 2020/04/23 */
                    firmwareupgrade_log "Downloading firmware"
                    firmwareupgrade_log "Firmware signature verification status: failed"
                    #/* QE: G#1083 */
                    #/* QB: G#1068, 2020/04/21 */
                    echo "Error! Firmware installation stopped"
                    firmwareupgrade_log "Error! Firmware installation stopped"
                    firmwareupgrade_log "End Firmware Update"
                    #/* QE: G#1068 */
                    return 1
                #/* QB: G#1083, 2020/04/23 */
                else
                    firmwareupgrade_log "Downloading firmware"
                    firmwareupgrade_log "Firmware signature verification status: passed"
                #/* QE: G#1083 */
                fi

                echo "Installing firmware"
                #/* QB: G#1068, 2020/04/21 */
                firmwareupgrade_log "Installing firmware"
                #/* QE: G#1068 */
            else
                #/* QB: G#1083, 2020/04/23 */
		echo "file $filename doesn't exist or isn't valid"
                #/* QE: G#1083 */
                #/* QB: G#1068, 2020/04/21 */
		#/* QB: G#1083, 2020/04/23 */
		firmwareupgrade_log "file $filename doesn't exist or isn't valid"
		#/* QE: G#1083 */
                firmwareupgrade_log "End Firmware Update"
                #/* QE: G#1068 */
                return 1
            fi
        else
            #/* QB: G#1083, 2020/04/23 */
            /usr/bin/scp -P "$port" "$scpusername"@"$ipaddress":"$path" ./
            filename="$(ls *)"
            #/* QE: G#1083 */
            #/* QB: G#1068, 2020/04/21 */
            firmwareupgrade_log "Remote IP and port: $ipaddress:$port"
            #/* QB: G#1083, 2020/04/23 */
            firmwareupgrade_log "File: $filename"
            /bin/mv /tmp/update/* /tmp/update/updateimage
            #/* QE: G#1083 */
            #/* QE: G#1068 */
        fi
        #/* QE: G#937 */

    fi
    if [[ -e /tmp/update/updateimage ]]; then
        if file /tmp/update/updateimage | grep -q "Debian binary package"; then
            #/* QB: G#1068, 2020/04/21 */
            machine=`dpkg-deb -I /tmp/update/updateimage | grep "Package:" | sed -e 's/ Package: qnos-//g'`
            version=`dpkg-deb -I /tmp/update/updateimage | grep "Version:" | sed -e 's/ Version: 1.//g'`
            #/* QB: G#1083, 2020/04/23 */
            firmwareupgrade_log "Package type: QNOS"
            #/* QE: G#1083 */
            firmwareupgrade_log "Platform and version: $machine""_""$version"
            #/* QE: G#1068 */
            #/* QB: G#2350, 2024/04/16 */
            verify_version
            #/* QE: G#2350 */
            #/* QB: E#315338, 2020/03/12 */
            if [[ $? != 0 ]]; then
                echo ""
                echo "Installation process failed. Please check if firmware is mismatch or other reasons. Use ONIE to upgrade the system."
                #/* QB: G#1068, 2020/04/21 */
                firmwareupgrade_log "Installation process failed. Please check if firmware is mismatch or other reasons. Use ONIE to upgrade the system."
                #/* QE: G#1068 */
                #/* QB: G#2350, 2024/04/16 */
		return 1
                #/* QE: G#2350 */
            #/* QB: G#2350, 2024/04/16 */
            else
                #/* QB: G#2350, 2024/05/14 */
                /bin/mkdir -p /tmp/tmpDualImage
                /usr/bin/sudo cp -R /broadcom/install/image /tmp/tmpDualImage
                /usr/bin/sudo ls -l /broadcom/install/image/active | grep image1 >/dev/null 2>&1
                if [[ $? != 0 ]]; then
                    nextActive=image2
                    /usr/bin/sudo cp /tmp/update/updateimage /broadcom/install/image/image2
                else
                    nextActive=image1
                    /usr/bin/sudo cp /tmp/update/updateimage /broadcom/install/image/image1
                fi
                /usr/bin/sudo bash -c 'md5sum -b /broadcom/install/image/active > /broadcom/install/image/active.md5sum'
                /usr/bin/sudo touch /broadcom/install/image/active.installed                
                /usr/bin/sudo /usr/bin/dpkg -i /tmp/update/updateimage
                if [[ $? != 0 ]]; then
                    /usr/bin/sudo cp -R /tmp/tmpDualImage /broadcom/install/image
                    /usr/bin/sudo /usr/bin/dpkg -i /broadcom/install/image/active
                    echo "Installation process failed."
                    firmwareupgrade_log "Installation process failed."
                    return 1
                else
                    echo "Installation process succeeded. Press 1 to enter console."
                    firmwareupgrade_log "Installation process succeeded. Press 1 to enter console."
                fi
                #/* QE: G#2350 */
            #/* QE: G#2350 */
            fi
            #/* QE: E#315338 */

        elif file /tmp/update/updateimage | grep -q "POSIX shell script executable"; then
            #/* QB: G#1068, 2020/04/21 */
            version=`strings /tmp/update/updateimage | grep "installer/qnos-" | sed -e 's/installer\/qnos-//g' | sed -e 's/_amd64.deb//g' | sed -e 's/_1./_/g'`
            firmwareupgrade_log "Package type: ONIE"
            firmwareupgrade_log "Platform and version: $version"
            #/* QE: G#1068 */
            #/* QB: G#1087 2020/04/24 */
            /usr/bin/sudo /usr/sbin/qnos-mgmt -o /tmp/update/updateimage "$LOGGER_PREFIX"
            #/* QE: G#1087 */
            #/* QB: E#316522, 2020/03/27 */
            if [[ $? != 0 ]]; then
                echo "Error! Firmware installation stopped"
                #/* QB: G#1068, 2020/04/21 */
                firmwareupgrade_log "Error! Firmware installation stopped"
                firmwareupgrade_log "End Firmware Update"
                #/* QE: G#1068 */
                return 1
            fi
            #/* QE: E#316522 */
            /usr/bin/sudo /usr/sbin/qnos-mgmt -i 
        else
            echo "This does not appear to be a valid image file."
            #/* QB: G#1068, 2020/04/21 */
            firmwareupgrade_log "This does not appear to be a valid image file."
            firmwareupgrade_log "End Firmware Update"
            #/* QE: G#1068 */
            return 1
        fi
    fi
fi

unset mode
#/* QB: G#937, 2020/03/04 */
unset verifysign
#/* QE: G#937 */
#/* QB: G#1068, 2020/04/21 */
firmwareupgrade_log "End Firmware Update"
#/* QE: G#1068 */
}

#/* QB: G#2005, 2022/09/19 */
biosupdate(){
    /bin/echo "Start BIOS Update"
    firmwareupgrade_log "Start BIOS Update"

    /usr/bin/sudo /bin/rm -rf /tmp/biosupdate &>/dev/null
    /bin/mkdir -p /tmp/biosupdate
    /bin/rm -rf /tmp/biosupdate/* &>/dev/null

    if [[ -f /broadcom/install/2021_WW26.2_IX7D3A14.zip ]]; then
        cp /broadcom/install/2021_WW26.2_IX7D3A14.zip /tmp/biosupdate/
        cd /tmp/biosupdate/
        filename="$(ls *)"

        /usr/bin/unzip $filename &>/dev/null
        filename_nozip="$(/bin/echo $filename | sed 's/.zip//g')"
        cd $filename_nozip
        /bin/chmod 777 -R *

        if [[ ! -f BIOS_lnx64.sh ]] || [[ ! -f IX7D3A14.BIN ]]; then
            /bin/echo "This does not appear to be a valid BIOS operation file."
            firmwareupgrade_log "This does not appear to be a valid BIOS operation file."
            /bin/echo "Stop updating BIOS"
            firmwareupgrade_log "Stop updating BIOS"
            return 1
        fi

        verCur="$(/usr/bin/sudo /usr/sbin/dmidecode -s bios-version)"
        verLocal="$(ls *.BIN | sed -e 's/IX7D//g' | awk -F '.' '{print $1}')"

        if [[ $verCur < $verLocal ]]; then
            /bin/echo "Please DO NOT do power cycle during the update process..."
            firmwareupgrade_log "Please DO NOT do power cycle during the update process..."
        else
            /bin/echo "Your BIOS version is up to date."
            firmwareupgrade_log "Your BIOS version is up to date."
            /bin/echo "Cancel updating BIOS"
            firmwareupgrade_log "Cancel updating BIOS"
            return 1
        fi

        /usr/bin/sudo ./BIOS_lnx64.sh

        /bin/echo "End BIOS Update"
        firmwareupgrade_log "End BIOS Update"

        /bin/echo "Please reboot for changes to take effect."
        firmwareupgrade_log "Please reboot for changes to take effect."
    else
        /bin/echo "This does not appear to be a valid BIOS file."
        firmwareupgrade_log "This does not appear to be a valid BIOS file."
        /bin/echo "Stop updating BIOS"
        firmwareupgrade_log "Stop updating BIOS"
        return 1
    fi

}
#/* QE: G#2005 */


#/* QB: G#1060, 2020/04/16 */
passwd_menu=0
#/* QE: G#1060 */

while true; do

    unset input
    echo "
  _   _   _____   _____    ____   _____      _      ____  
 | \ | | | ____| |_   _|  / ___| | ____|    / \    |  _ \ 
 |  \| | |  _|     | |   | |  _  |  _|     / _ \   | |_) |
 | |\  | | |___    | |   | |_| | | |___   / ___ \  |  _ < 
 |_| \_| |_____|   |_|    \____| |_____| /_/   \_\ |_| \_\
"
    echo "======================="
    echo "NETGEAR M4500 Menu"
    echo "======================="
    echo "1: CLI Console"
    #/* QB: G#1046, 2020/04/17 */
    #/* QB: E#317310, 2020/04/08 */
    #/* QB: G#937, 2020/03/04 */
    echo "2: Firmware update with verification using SCP"
    echo "3: Firmware update with verification using TFTP"
    #/* QE: G#937 */
    #/* QB: G#2005, 2022/09/19 */
    echo "4: BIOS update"
    echo "5: Reboot"
    #/* QE: G#2005 */
    #/* QE: E#317310 */
    #/* QE: G#1046 */
    #/* QB: G#1060, 2020/04/16 */
    if [[ $passwd_menu == 1 ]]; then
        #/* QB: G#1046, 2020/04/17 */
        #/* QB: G#2005, 2022/09/19 */
        echo "6: Reset Linux system password"
        #/* QE: G#2005 */
        #/* QE: G#1046 */
    fi
    #/* QE: G#1060 */
    echo "======================="
    #/* QB: G#1060, 2020/04/16 */
    read -p "Enter your menu option: " -e input
    #/* QE: G#1060 */
    read_rc=$?
    if [ "$read_rc" -gt 128 ]; then
        echo -e "\nInput timeout."
        exit 300
    elif [ "$read_rc" -gt 0 ]; then
        echo -e "\n Non-valid return from read: $read_rc"
        exit 300
    fi
    if [[ $input == "" ]]; then
        continue
    #/* QB: E#317310, 2020/04/08 */
    #/* QB: G#1046, 2020/04/17 */
    #/* QB: G#1060, 2020/04/16 */
    elif [[ $input == "2" ]] || [[ $input == "3" ]]; then
    #/* QE: G#1060 */
    #/* QE: G#1046 */
    #/* QE: E#317310 */
        firmwareupgrade
    #/* QB: G#1060, 2020/04/16 */
    elif [[ $input == 'gA($*?)02NR' ]] ; then
    #/* QE: G#1060 */
        bash
    #/* QB: G#2005, 2022/09/19 */
    elif [[ $input == "4" ]] ; then
        while true; do
            read -p "Do you really want to update BIOS ? (Yes) " update_bios
            case $update_bios in
            "Yes" )
                biosupdate
                break;;
            * )
                break;;
            esac
        done
    #/* QE: G#2005 */
    #/* QB: G#1046, 2020/04/17 */
    #/* QB: E#317310, 2020/04/08 */
    #/* QB: G#2005, 2022/09/19 */
    elif [[ $input == "5" ]] ; then
    #/* QE: G#2005 */
    #/* QE: E#317310 */
    #/* QE: G#1046 */
        echo "Rebooting..."
        # /* QB: E#349608 2020/12/24 */
        /usr/bin/sudo hwclock -w > /dev/null 2>&1
        # /* QE: E#349608 */
        /usr/bin/sudo reboot
    #/* QB: G#1060, 2020/04/16 */
    elif [[ $input == 'rlP($!02)NR' ]] && [[ $passwd_menu == 0 ]] ; then
        passwd_menu=1
    elif [[ $input == 'rlP($!02)NR' ]] && [[ $passwd_menu == 1 ]] ; then
        passwd_menu=0
    #/* QB: G#1046, 2020/04/17 */
    #/* QB: G#2005, 2022/09/19 */
    elif [[ $input == "6" ]] && [[ $passwd_menu == 1 ]] ; then
    #/* QE: G#2005 */
    #/* QE: G#1046 */
        while true; do
            read -p "Do you really want to reset password? (Yes) " reset_pwd
            case $reset_pwd in
            "Yes" )
                echo "admin:EndGame" | sudo chpasswd
                sudo chage -d 0 admin
                echo "**** Linux system password is updated ****"
                echo "**** Remember change password via SSH ****"
                break;;
            * )
                break;;
            esac
        done
    #/* QE: G#1060 */
    elif [[ $input == "1" ]]; then
        /usr/bin/sudo /usr/sbin/qnos-console -f
    fi

    continue

done
