#!/bin/sh
#
#    Copyright (c) 2007-2008 Brocade Communications Systems, Inc.
#    All rights reserved.
#   
#    File name:   cipherutil
#    Module name: fabos/src/security/cipherutil.sh
#   
#    This script modifies the ssh cipher list and restarts the SSH deamon.
#   
    
export PATH=/fabos/sbin:/fabos/bin:/bin:/usr/bin:/sbin:/usr/sbin:/fabos/cliexec:/fabos/libexec:


#Absolute path for generic utilites 
ECHO=/bin/echo
GREP=/bin/grep
CUT=/usr/bin/cut
SED=/bin/sed
CAT=/bin/cat
RM=/bin/rm
PS=/bin/ps
CP=/bin/cp
TR=/usr/bin/tr
AWK=/bin/awk
SYS_CONFIG=/fabos/cliexec/config
KILL=/bin/kill
RSH=/usr/bin/rsh
PING=/bin/ping

# SSH Configuration Files 

SSHD_CONFIG=/etc/sshd_config
SSH_CONFIG=/etc/ssh_config

# Temporary config file used for validation 

TMP_SSHD_CONFIG=/etc/tmp_sshd_config

# SSH Daemon
SSHD=/usr/sbin/sshd

# Replacing SSH config 
SSH_KEX_REPLACE=replacekex
SSH_ENC_REPLACE=replaceenc
SSH_MAC_REPLACE=replacemac

# Verify - Used to verify if one set is subset of another
SSH_KEX_VERIFY=verifykex
SSH_ENC_VERIFY=verifyenc
SSH_MAC_VERIFY=verifymac

#Validate 
SSH_KEX_VALIDATE=validatekex
SSH_ENC_VALIDATE=validateenc
SSH_MAC_VALIDATE=validatemac

#restartSSH

SSH_RESTART=restartssh

#TLS 
WEB_RPC_KILL=webrpckill
CIPHER_VERIFICATION=validatetlscipher
CIPHER_VERIFY_SUBSET=verifytlscipher
HTTPD_PID_FILE=/tmp/webtools/httpd.pid.0
WEBDRESTART="/fabos/libexec/webdcfghandler http.restart:1"
OPENSSL_CIPHER_CMD="/usr/bin/openssl ciphers"
TMPFILE="/tmp/tmpfile"

#restartHTTPS

HTTPS_RESTART=restarthttps

# convert option to all lower case
cmd_option=`$ECHO $1 | $TR "[:upper:]" "[:lower:]"`


strstr() {
  [ "${1#*$2*}" = "$1" ] && return 1
  return 0
}
swbd() {
    /bin/sed -n -e 's/^.*\(SWBD[[:digit:]]\{1,\}\).\+$/\1/gp'
}
cpid() {
    sed -n -e 's/^Control.\+No: \([[:digit:]]\{1,\}\)$/\1/gp'
}
SWBD=$(/sbin/sin | swbd 2> /dev/null)
CPID=$(/sbin/sin | cpid 2> /dev/null)

otherhost(){
    case ${SWBD##SWBD} in
    '62')
        printf 127.1.1.$((8 - CPID % 2))
        ;;
    '77')
        printf 127.1.1.$((6 - CPID % 2))
        ;;
    '141')
        printf 127.1.$((17 - CPID % 2)).$((17 - CPID % 2))
        ;;
    '142')
        printf 127.1.$((15 - CPID % 2)).$((15 - CPID % 2))
        ;;
    '165' | '166')
        printf 127.3.1.$((2 - CPID % 2))
        ;;
    *)
        printf 10.0.0.$((6 - CPID % 2))
        ;;
    esac
}

restart_SSH (){
        # Restart sshd.
        pizzabox=$(/fabos/cliexec/hashow | $GREP -c "Not supported on this platform")

        pid=`$PS -ef | $GREP "sshd" | $GREP -v "sshd:" | \
            $GREP -v "sshd_config" | $GREP -v grep|$AWK '{print $2}'`
        if [ -n "$pid" ]; then
            $KILL $pid
        fi
        $SSHD >/dev/null 2>&1

        pid=`$PS -ef | $GREP "sshd" | $GREP -v "sshd:" | \
            $GREP -v "sshd_config" | $GREP -v grep|$AWK '{print $2}'`
        if [ $pizzabox -eq 1 ]; then
            if [ -z "$pid" ]; then
                exit 1
            fi
        fi
        
        if [ $pizzabox -eq 0 ]; then
            # Restart ssh on standby cp only if standby cp is up
            if  $PING -c 2 $(otherhost) >/dev/null 2>&1; then
                pid=`$RSH -n $(otherhost)  $PS -ef 2> /dev/null | $GREP "sshd" | \
                    $GREP -v "sshd:" | $GREP -v "sshd_config" | $GREP -v grep \
                    | $AWK '{print $2}'`
                if [ -n "$pid" ]; then
                    $RSH -n $(otherhost) $KILL $pid 2> /dev/null
                fi
                $RSH -n $(otherhost) $SSHD >/dev/null 2>&1
                pid=`$RSH -n $(otherhost) $PS -ef 2> /dev/null | $GREP "sshd" | $GREP -v "sshd:" | \
                    $GREP -v "sshd_config" | $GREP -v grep|$AWK '{print $2}'`
                if [ -z "$pid" ]; then
                    exit 1
                fi
            fi
        fi
}

#Main processiong starts here. 

case "$cmd_option" in

################################################
#  SSH based options
################################################

#SSH replace options 

"$SSH_ENC_REPLACE" )
    # Verify  the no of input arguments before processing
    if [ $# -ne 3 ]
    then
        exit 1
    fi

    # Modify ssh server configuration
    # Finds out whether Cipher filed exists or not.
    cipher=`$CAT $SSHD_CONFIG|$GREP -ce "^#*Ciphers"`
    if [ "$cipher" -eq 0 ]; then
        $ECHO Ciphers $2 >> $SSHD_CONFIG
        $SYS_CONFIG save $SSHD_CONFIG
    else
        cipherlist=`$CAT $SSHD_CONFIG|$GREP -ie "^#*Ciphers" | \
                    cut -d" " -f2-`

        $SED "s/^#*Ciphers $cipherlist/Ciphers $2/" $SSHD_CONFIG > $TMPFILE
        $CAT $TMPFILE > $SSHD_CONFIG
        $RM $TMPFILE
        $SYS_CONFIG save $SSHD_CONFIG
    fi

    #Modify the ssh client configuration
    cipher=`$CAT $SSH_CONFIG|$GREP -ce "^#*Ciphers"`
    if [ "$cipher" -eq 0 ]; then
        $ECHO Ciphers $2 >> $SSH_CONFIG
        $SYS_CONFIG save $SSH_CONFIG
    else
        cipherlist=`$CAT $SSH_CONFIG|$GREP -ie "^#*Ciphers" | \
                    $CUT -d" " -f2-`

        $SED "s/^#*Ciphers $cipherlist/Ciphers $2/" $SSH_CONFIG > $TMPFILE
        $CAT $TMPFILE > $SSH_CONFIG
        $RM $TMPFILE
        $SYS_CONFIG save $SSH_CONFIG
    fi

    if [ $3 -eq 0 ]; then
        # Restart sshd.
    	restart_SSH
    fi
;;


"$SSH_RESTART" )
        # Restart sshd.
	restart_SSH
;;

"$SSH_KEX_REPLACE" )
    # Verify  the no of input arguments before processing
    if [ $# -ne 3 ]
    then
        exit 1
    fi

    # Finds out whether Cipher filed exists or not.
    kex=`$CAT $SSHD_CONFIG|$GREP -ce "^#*KexAlgorithms"`
        if [ "$kex" -eq 0 ]; then
        $ECHO KexAlgorithms $2 >> $SSHD_CONFIG
        $SYS_CONFIG save $SSHD_CONFIG
    else
        kexlist=`$CAT $SSHD_CONFIG|$GREP -ie "^#*KexAlgorithms" | \
                    $CUT -d" " -f2-`
        $SED "s/^#*KexAlgorithms $kexlist/KexAlgorithms $2/" $SSHD_CONFIG > $TMPFILE
        $CAT $TMPFILE > $SSHD_CONFIG
        $RM $TMPFILE
        $SYS_CONFIG save $SSHD_CONFIG
    fi
    #Modify the SSH client configuration
    kex=`$CAT $SSH_CONFIG|$GREP -ce "^#*KexAlgorithms"`
    if [ "$kex" -eq 0 ]; then
        $ECHO KexAlgorithms $2 >> $SSH_CONFIG
        $SYS_CONFIG save $SSH_CONFIG
    else
        kexlist=`$CAT $SSH_CONFIG|$GREP -ie "^#*KexAlgorithms" | \
                    $CUT -d" " -f2-`
        $SED "s/^#*KexAlgorithms $kexlist/KexAlgorithms $2/" $SSH_CONFIG > $TMPFILE
        $CAT $TMPFILE > $SSH_CONFIG
        $RM $TMPFILE
        $SYS_CONFIG save $SSH_CONFIG
    fi

    if [ $3 -eq 0 ]; then
        # Restart sshd.
	restart_SSH
    fi

;;

"$SSH_MAC_REPLACE" )
    # Verify  the no of input arguments before processing
    if [ $# -ne 3 ]
    then
        exit 1
    fi

    # Finds out whether Cipher filed exists or not.
    mac1=`$CAT $SSHD_CONFIG|$GREP -ce "^#*MACs"`
    mac2=`$CAT $SSHD_CONFIG|$GREP -ce "^#*Macs"`
    if [ "$mac1" -eq 0 ]; then
        if [ "$mac2" -eq 0 ]; then
            $ECHO MACs $2 >> $SSHD_CONFIG
            $SYS_CONFIG save $SSHD_CONFIG
        fi
    else
        if [ "$mac1" -eq 1 ] && [ "$mac2" -eq 1 ]; then

            maclist=`$CAT $SSHD_CONFIG|$GREP -e "^#*MACs" | \
                         $CUT -d" " -f2-`
            $SED "s/^#*MACs $maclist/MACs $2/" $SSHD_CONFIG > $TMPFILE

            $CAT $TMPFILE > $SSHD_CONFIG
            $RM $TMPFILE
            $SYS_CONFIG save $SSHD_CONFIG

            maclist=`$CAT $SSHD_CONFIG|$GREP -e "^#*Macs" | \
                         $CUT -d" " -f2-`
            $SED "s/^#*Macs $maclist/Macs $2/" $SSHD_CONFIG > $TMPFILE
        elif [ "$mac1" -eq 1 ]; then
            maclist=`$CAT $SSHD_CONFIG|$GREP -e "^#*MACs" | \
                         $CUT -d" " -f2-`
            $SED "s/^#*MACs $maclist/MACs $2/" $SSHD_CONFIG > $TMPFILE

        else
            maclist=`$CAT $SSHD_CONFIG|$GREP -e "^#*Macs" | \
                         $CUT -d" " -f2-`
            $SED "s/^#*Macs $maclist/Macs $2/" $SSHD_CONFIG > $TMPFILE

        fi

        $CAT $TMPFILE > $SSHD_CONFIG
        $RM $TMPFILE
        $SYS_CONFIG save $SSHD_CONFIG
    fi

    #Modify the SSH client configuration
    mac1=`$CAT $SSH_CONFIG|$GREP -ce "^#*MACs"`
    mac2=`$CAT $SSH_CONFIG|$GREP -ce "^#*Macs"`
    if [ "$mac1" -eq 0 ]; then
        if [ "$mac2" -eq 0 ]; then
            $ECHO MACs $2 >> $SSH_CONFIG
            $SYS_CONFIG save $SSH_CONFIG
        fi
    else
        if [ "$mac1" -eq 1 ] && [ "$mac2" -eq 1 ]; then
            maclist=`$CAT $SSH_CONFIG|$GREP -e "^#*MACs" | \
                         $CUT -d" " -f2-`
            $SED "s/^#*MACs $maclist/MACs $2/" $SSH_CONFIG > $TMPFILE

            $CAT $TMPFILE > $SSH_CONFIG
            $RM $TMPFILE
            $SYS_CONFIG save $SSH_CONFIG

            maclist=`$CAT $SSH_CONFIG|$GREP -e "^#*Macs" | \
                         $CUT -d" " -f2-`
            $SED "s/^#*Macs $maclist/Macs $2/" $SSH_CONFIG > $TMPFILE
        elif [ "$mac1" -eq 1 ]; then
            maclist=`$CAT $SSH_CONFIG|$GREP -e "^#*MACs" | \
                         $CUT -d" " -f2-`
            $SED "s/^#*MACs $maclist/MACs $2/" $SSH_CONFIG > $TMPFILE

        else
            maclist=`$CAT $SSH_CONFIG|$GREP -e "^#*Macs" | \
                         $CUT -d" " -f2-`
            $SED "s/^#*Macs $maclist/Macs $2/" $SSH_CONFIG > $TMPFILE

        fi

        $CAT $TMPFILE > $SSH_CONFIG
        $RM $TMPFILE
        $SYS_CONFIG save $SSH_CONFIG
    fi

    if [ $3 -eq 0 ]; then
        # Restart sshd.
	restart_SSH
    fi

;;

# SSH validate options 

"$SSH_KEX_VALIDATE" )
	if [ -z "$2" ]; then
		exit 1
	fi
	$CP $SSHD_CONFIG $TMP_SSHD_CONFIG
	$ECHO KexAlgorithms $2 >> $TMP_SSHD_CONFIG
	$SSHD -T -f $TMP_SSHD_CONFIG  >/dev/null 2>&1

	if [ $? != 0 ]; then
		$RM $TMP_SSHD_CONFIG
		exit 1
	fi
	$RM $TMP_SSHD_CONFIG
;;

"$SSH_MAC_VALIDATE" )
	if [ -z "$2" ]; then
		exit 1
	fi
	$CP $SSHD_CONFIG $TMP_SSHD_CONFIG
	$ECHO Macs $2 >> $TMP_SSHD_CONFIG
	$SSHD -T -f $TMP_SSHD_CONFIG  >/dev/null 2>&1

	if [ $? != 0 ]; then
		$RM $TMP_SSHD_CONFIG
		exit 1
	fi
	$RM $TMP_SSHD_CONFIG
;;

"$SSH_ENC_VALIDATE" )
	if [ -z "$2" ]; then
		exit 1
	fi

	$CP $SSHD_CONFIG $TMP_SSHD_CONFIG
	$ECHO Ciphers $2 >> $TMP_SSHD_CONFIG
	$SSHD -T -f $TMP_SSHD_CONFIG  >/dev/null 2>&1

	if [ $? != 0 ]; then
		$RM $TMP_SSHD_CONFIG
		exit 1
	fi
	$RM $TMP_SSHD_CONFIG
;;


################################################
#  TLS based options
################################################

"$CIPHER_VERIFICATION" )
	if [ -z "$2" ]; then
		exit 1
	fi
	$OPENSSL_CIPHER_CMD $2 >/dev/null 2>&1
	if [ $? != 0 ]; then
		exit 1
	fi
;;

"$CIPHER_VERIFY_SUBSET" )
	if [ -z "$3" ]; then
		exit 1
	fi


	# -v required to get one cipher at a time. 
	conf_ciph=`$OPENSSL_CIPHER_CMD -v $2 | $CUT -f 1 -d ' '`
	rcvd_ciph=`$OPENSSL_CIPHER_CMD -v $3 | $CUT -f 1 -d ' '`

    for cip in $rcvd_ciph
    do
		issubbset=0
        for sys_cip in $conf_ciph
        do
            if [ $cip == $sys_cip ]; then
				issubbset=1
				break
			fi
        done
		
		if [ $issubbset -eq 0 ]; then
			exit 1
		fi
    done
;;

"$WEB_RPC_KILL" )
    # Restart webd.
	$WEBDRESTART
	if [ ! -f $HTTPD_PID_FILE ]; then
		echo "Invalid cipher. Web server failed to restart."
		exit 1
	fi

        pizzabox=$(/fabos/cliexec/hashow | $GREP -c "Not supported on this platform")


        if [ $pizzabox -eq 0 ]; then
            `$RSH -n $(otherhost)  $WEBDRESTART`

            file=`$RSH -n $(otherhost) "ls -l  $HTTPD_PID_FILE | wc -l"`

            if [ $file -eq 0 ]; then
		echo "Invalid cipher. Web server failed to restart on Standby."
                exit 1
            fi
        fi


;;  

"$HTTPS_RESTART" )
        # Restart https after 7 seconds, a time given for REST response to reach the initiator
	sleep 7
	$WEBDRESTART
	echo "HTTPS restarted from REST "$?
;;


#Default option
* )
exit 1 
;;      
    
esac

#Script Exit 
exit 0
