#!/bin/sh
#
#    Copyright (c) 2009-10 Brocade Communications Systems, Inc.
#    All rights reserved.
#
#    File name:   ssh_handler
#    Module name: fabos/src/security/ssh_handler.sh
#
#    1. This script will be triggered from PDM to enable PermitUserEnvironment variable in sshd_config file.
#    2. This will be triggered for authorized_keys and authorizedKeys.tar
#
	
export PATH=/fabos/sbin:/fabos/bin:/bin:/usr/bin:/sbin:/usr/sbin:/fabos/cliexec:/fabos/libexec:

SSHD_CONFIG=/etc/sshd_config
SSH_CONFIG=/etc/ssh_config
MNT_FILE=/mnt/etc/sshd_config
MNT_FILE2=/mnt/etc/ssh_config

FROM_MAJOR=`echo $2 |cut -d '.' -f 1`
FROM_MINOR=`echo $2 |cut -d '.' -f 2`
FROM_PATCH=`echo $2 |cut -d '.' -f 3`
TO_MAJOR=`echo $3 |cut -d '.' -f 1`
TO_MINOR=`echo $3 |cut -d '.' -f 2`
TO_PATCH=`echo $3 |cut -d '.' -f 3`

INPUT_FILE=$1

SSHD=/usr/sbin/sshd
CIPHERS="Ciphers=3des-cbc,aes128-cbc,aes192-cbc,aes256-cbc"
MACS="Macs=hmac-sha1"

#Check for FIPS mode
checkFipsMode() {
    	# "config get" for fips mode returns value only if called from
   	# default VF. So, temporarily set FABOS_SWITCHNO to 0 and then
    	# revert it back to its original value after "config get"
    	FABOS_SWITCHNO_TEMP=$FABOS_SWITCHNO
    	FABOS_SWITCHNO=0
    	retVal1=`/fabos/cliexec/config get fips.mode 2`
    	retVal2=`/fabos/cliexec/config get fips.simulate 2`
    	FABOS_SWITCHNO=$FABOS_SWITCHNO_TEMP
	retVal=0

	if [ $retVal1 -eq 1 ]; then
		return $retVal1
	elif [ $retVal2 -eq 1 ];  then
		return $retVal2
	else 
		return $retVal
	fi

}

sshd_restart() {
	pid=`ps -ef | grep -w "sshd" | grep -v "sshd:" | grep -v grep | grep -iv "sshdconfigupdate" | awk '{print $2}'`
	if [ -n "$pid" ]; then
		kill $pid
	fi
    	$SSHD >/dev/null 2>&1
	pid=`ps -ef | grep -w "sshd" | grep -v "sshd:" | grep -v grep | grep -iv "sshdconfigupdate" | awk '{print $2}'`
    	if [ -z "$pid" ]; then
    		exit 1
	fi
}

sshd_reload() {
	pid=`/bin/ps -ef | /bin/grep -w "sshd" | /bin/grep -v "sshd:" | /bin/grep -v grep | /bin/grep -iv "sshdconfigupdate" | /usr/bin/awk '{print $2}'`
	if [ -n "$pid" ]; then
		/bin/kill -s HUP $pid 2> /dev/null
		if [ $? != 0 ]; then
			exit 1
		fi
	fi
}

#For FIPS 2014 compliance additional ssh parameters to be supported from v7.2.1
fips_upgrade() {
	# "config get" for fips mode returns value only if called from
	# default VF. So, temporarily set FABOS_SWITCHNO to 0 and then
	# revert it back to its original value after "config get"
	checkFipsMode
	retVal=$?
	if [ $retVal -eq 1 ]; then
		if [ $FROM_MAJOR -eq 7 -a $FROM_MINOR -eq 2 -a $FROM_PATCH -eq 1 ] && [ $TO_MAJOR -eq 7 -a $TO_MINOR -eq 2 -a $TO_PATCH -eq 1 ]; then
			if [ $INPUT_FILE = $SSHD_CONFIG ] || [ $INPUT_FILE = $MNT_FILE ]; then
				sshd_restart
			fi
		fi
		if [ $FROM_MAJOR -eq 7 -a $FROM_MINOR -eq 2 -a $FROM_PATCH -eq 0 ] && [ $TO_MAJOR -eq 7 -a $TO_MINOR -eq 2 -a $TO_PATCH -eq 1 ]; then
        		/fabos/cliexec/sshdconfigupdate ServerHostKeySize 1
			/fabos/cliexec/sshdconfigupdate MinPrime 1
        		/fabos/cliexec/sshdconfigupdate ShaValue 1
			if [ $INPUT_FILE = $SSHD_CONFIG ] || [ $INPUT_FILE = $MNT_FILE ] ; then
				cp $SSHD_CONFIG $MNT_FILE
			elif [ $INPUT_FILE = $SSH_CONFIG ] || [ $INPUT_FILE = $MNT_FILE2 ]; then
				cp $SSH_CONFIG $MNT_FILE2
			fi
		elif [ $FROM_MAJOR -eq 7 -a $FROM_MINOR -eq 2 -a $FROM_PATCH -eq 1 ] && [ $TO_MAJOR -eq 7 -a $TO_MINOR -eq 2 -a $TO_PATCH -eq 0 ]; then
			if [ $INPUT_FILE = $SSHD_CONFIG ] || [ $INPUT_FILE = $MNT_FILE ]; then
				/bin/grep -v "MinPrime" $SSHD_CONFIG > temp && mv temp $SSHD_CONFIG
				/bin/grep -v "ShaValue" $SSHD_CONFIG > temp && mv temp $SSHD_CONFIG
				/bin/grep -v "KexAlgorithms diffie-hellman-group-exchange-sha256" $SSHD_CONFIG > temp && mv temp $SSHD_CONFIG
    				/bin/grep -v "MinPrime" $MNT_FILE > temp && mv temp $MNT_FILE
				/bin/grep -v "ShaValue" $MNT_FILE > temp && mv temp $MNT_FILE
				/bin/grep -v "KexAlgorithms diffie-hellman-group-exchange-sha256" $MNT_FILE > temp && mv temp $MNT_FILE
			elif [ $INPUT_FILE = $SSH_CONFIG ] || [ $INPUT_FILE = $MNT_FILE2 ]; then
       				/bin/grep -v "MinPrime" $SSH_CONFIG > temp && mv temp $SSH_CONFIG
				/bin/grep -v "ServerHostKeySize" $SSH_CONFIG > temp && mv temp $SSH_CONFIG
       				/bin/grep -v "ShaValue" $SSH_CONFIG > temp && mv temp $SSH_CONFIG
       				/bin/grep -v "KexAlgorithms diffie-hellman-group-exchange-sha256" $SSH_CONFIG > temp && mv temp $SSH_CONFIG
				/bin/grep -v "MinPrime" $MNT_FILE2 > temp && mv temp $MNT_FILE2
				/bin/grep -v "ServerHostKeySize" $MNT_FILE2 > temp && mv temp $MNT_FILE2
				/bin/grep -v "ShaValue" $MNT_FILE2 > temp && mv temp $MNT_FILE2
				/bin/grep -v "KexAlgorithms diffie-hellman-group-exchange-sha256" $MNT_FILE2 > temp && mv temp $MNT_FILE2
			fi
			if [ $INPUT_FILE = $SSHD_CONFIG ] || [ $INPUT_FILE = $MNT_FILE ]; then
				sshd_restart
			fi
		fi
	fi
}
rekey_conversion() {
	TMP_SSHD=/tmp/sshd_tmp
	if [ $FROM_MAJOR -le 8 ] && [ $TO_MAJOR -ge 9 ]; then
		ret1=$(grep -c "RekeyInterval" $MNT_FILE)
		if [ $ret1 -gt 0 ]; then
			/bin/sed "s/RekeyInterval/RekeyLimit default/" $MNT_FILE > $TMP_SSHD
			/bin/mv $TMP_SSHD $MNT_FILE
			cp $MNT_FILE $SSHD_CONFIG
		fi
	fi
}

sshd_config_handling() {
	TMP_SSHD=/tmp/sshd_tmp
	TMP_SSHD_COPY=/tmp/sshd_tmp_copy
	TMP_SSHD_COPY2=/tmp/sshd_tmp_copy2
	TMP_SSHD_NEW=/tmp/sshd_tmp_new
	# Remove PrintLastLog and UsePrivilegeSeparation in fw_versions>=9.0
	if [ $FROM_MAJOR -le 8 ] && [ $TO_MAJOR -ge 9 ]; then
		/bin/sed '/PrintLastLog/d' $MNT_FILE > $TMP_SSHD
		/bin/sed '/ServerKeyBits/d' $TMP_SSHD > $TMP_SSHD_NEW
		/bin/sed '/UsePrivilegeSeparation/d' $TMP_SSHD_NEW > $TMP_SSHD_COPY
		/bin/sed '/MinPrime/d' $TMP_SSHD_COPY > $TMP_SSHD_COPY2
		/bin/mv $TMP_SSHD_COPY2 $MNT_FILE
		cp $MNT_FILE $SSHD_CONFIG
		rm -rf $TMP_SSHD
		rm -rf $TMP_SSHD_NEW
		rm -rf $TMP_SSHD_COPY
		rm -rf $TMP_SSHD_COPY2
	fi

	## Set PermitUserEnvironment to "no" in fw_version >= v8.2.1
	if [  $FROM_MAJOR -eq 8 -a $FROM_MINOR -lt 2 ] || [ $FROM_MAJOR -eq 8 -a $FROM_MINOR -eq 2 -a $FROM_PATCH -lt 1 ]; then
        	if [ $TO_MAJOR -gt 8 ] || [ $TO_MAJOR -eq 8 -a $TO_MINOR -gt 2 ] || [ $TO_MAJOR -eq 8 -a $TO_MINOR -eq 2 -a $TO_PATCH -ge 1 ]; then
			permituser="no"
			permituser_config=`/bin/cat $MNT_FILE | /bin/grep "PermitUserEnvironment" | /bin/awk '{ print $2 }'`
			/bin/sed '/PermitUserEnvironment/ s/'$permituser_config'/'$permituser'/' $MNT_FILE > $TMP_SSHD
			/bin/mv $TMP_SSHD $MNT_FILE
			cp $MNT_FILE $SSHD_CONFIG
		fi
	fi
}

ssh_config_handling() {
	TMP_SSH_COPY=/tmp/ssh_tmp_copy
	TMP_SSH_COPY2=/tmp/ssh_tmp_copy2
	# Remove MinPrime and ServerHostKeySize in fw_versions>=9.0
	if [ $FROM_MAJOR -le 8 ] && [ $TO_MAJOR -ge 9 ]; then
		/bin/sed '/MinPrime/d' $MNT_FILE2 > $TMP_SSH_COPY
		/bin/sed '/ServerHostKeySize/d' $TMP_SSH_COPY > $TMP_SSH_COPY2
		/bin/mv $TMP_SSH_COPY2 $MNT_FILE2
		cp $MNT_FILE2 $SSH_CONFIG
		rm -rf $TMP_SSH_COPY
		rm -rf $TMP_SSH_COPY2
	fi
}

if [ $1 == $SSHD_CONFIG ] || [ $1 == $SSH_CONFIG ]; then
	fips_upgrade
elif [ $1 == $MNT_FILE ]; then
	fips_upgrade
	if [ $TO_MAJOR -eq 7 -a $TO_MINOR -ge 3 ]; then
		/bin/grep "HostKey /etc/ssh_host_ecdsa_key" $MNT_FILE > /dev/null 2>&1
		ret=`echo $?`
		if [ $ret -ne 0 ]; then
			echo "HostKey /etc/ssh_host_ecdsa_key" >> $MNT_FILE
		fi
	elif [ $TO_MAJOR -eq 7 -a $TO_MINOR -lt 3 ]; then
		/bin/grep -v "HostKey /etc/ssh_host_ecdsa_key" $MNT_FILE > temp && mv temp $MNT_FILE
		/bin/chmod 600 $MNT_FILE
	fi

	## Handle PermitUserEnvironment, PrintLastlog and UsePrivilegeSeparation
	sshd_config_handling

	# The following step enable the UsePAM disable the ChallengeResponseAuthentication in sshd_config file
	sed "s/#UsePAM no/UsePAM yes/" $MNT_FILE > /tmp/tmp
	cat /tmp/tmp > $MNT_FILE
	sed "s/#ChallengeResponseAuthentication yes/ChallengeResponseAuthentication no/" $MNT_FILE > /tmp/tmp
	cat /tmp/tmp > $MNT_FILE
	rm /tmp/tmp
	cp $MNT_FILE $SSHD_CONFIG
	rekey_conversion
	sshd_reload 
elif  [ $1 = $MNT_FILE2 ]; then
	fips_upgrade

	## Handle MinPrime, ServerHostKeySize
	ssh_config_handling

	SWBD=`sin | sed -n -e 's/^.\+\(SWBD[[:digit:]]\{1,\}\).\+$/\1/gp' 2> /dev/null`
	if [ $SWBD == "SWBD117" ]; then
		if [ -s /etc/ssh_config.default.pharos ]; then
			SIZE=`ls -l /etc/ssh_config | awk '{ print $5}' 2> /dev/null`
			SIZE_FIPS=`ls -l /etc/ssh_config.fips | awk '{ print $5}' 2> /dev/null`
			if [ $SIZE = $SIZE_FIPS ]; then
				cp /etc/ssh_config.fips.pharos /etc/ssh_config 2> /dev/null
			else
				cp /etc/ssh_config.default.pharos /etc/ssh_config 2> /dev/null
			fi
			cp /etc/ssh_config.default.pharos /etc/ssh_config.default 2> /dev/null
			cp /etc/ssh_config.fips.pharos /etc/ssh_config.fips 2> /dev/null
			> /etc/ssh_config.default.pharos
			> /etc/ssh_config.fips.pharos
		fi
	fi
	cp $MNT_FILE2 $SSH_CONFIG
else
	#    If trigger is invoked for /fabos/users/admin/.ssh/authorizedKeys.tar file,
	#    it will remove all the /fabos/users/admin/.ssh/authorized_keys.* files
	#    and then untar /fabos/users/admin/.ssh/authorizedKeys.tar.
	#    If the trigger is invoked for /fabos/users/admin/.ssh/authorized_keys,
	#    the file is simply copied if active is on version >=7. If active is running
	#    on version before 7.0, the file then gets copied and also another copy is
	#    created as /fabos/users/admin/.ssh/authorized_keys.username where username 
	#    is as configured via "sshutil allowuser" command otherwise admin.
	#    /fabos/users/admin/.ssh/authorizedKeys.tar gets updated on standby.	
	#
	VER_7_0="7.0"
	SSH_AUTH_DIR=/fabos/users/admin/.ssh/
	MNT_SSH_AUTH_DIR=/mnt/fabos/users/admin/.ssh/
	SSH_AUTH_FILE_PREFIX=authorized_keys
	allowlogin=`cat $SSHD_CONFIG|grep -i "AllowedLogin" |\
		 grep -v "#" |cut -d" " -f2`

	if [ $# -lt 3 ]; then
		exit
	fi

	AUTH_FILE_NAME=$1
	echo $AUTH_FILE_NAME | grep -q "authorized_keys"
	unnamed_auth_conf=$?
	echo $AUTH_FILE_NAME | grep -q "authorizedKeys.tar"
	named_auth_conf=$?

	fver=$2
	tver=$3

	# Sync for authorized_keys
	if [ $unnamed_auth_conf -eq 0 ]; then
		if [ $fver \< $VER_7_0 ]; then
			cd $MNT_SSH_AUTH_DIR
			cp $SSH_AUTH_FILE_PREFIX $SSH_AUTH_FILE_PREFIX.$allowlogin
			tar -cf authorizedKeys.tar $SSH_AUTH_FILE_PREFIX.*
			cp authorizedKeys.tar $SSH_AUTH_DIR
			cd -

			cd $SSH_AUTH_DIR
			tar -xf authorizedKeys.tar
			/bin/chmod 600 authorized_keys*
			cd -
		fi
		cp $MNT_SSH_AUTH_DIR/$SSH_AUTH_FILE_PREFIX $SSH_AUTH_DIR
		/bin/chmod 600 $SSH_AUTH_DIR/$SSH_AUTH_FILE_PREFIX
	fi

	# Sync for authorizedKeys.tar
	if [ $named_auth_conf -eq 0 ]; then
		cd $MNT_SSH_AUTH_DIR
		for authfile in `ls $SSH_AUTH_FILE_PREFIX.* 2> /dev/null` ; do
			cat /dev/null > $authfile
			rm -f $authfile
		done
		if [ -f authorizedKeys.tar ]; then
			cp authorizedKeys.tar $SSH_AUTH_DIR
			tar -xf authorizedKeys.tar
			/bin/chmod 600 authorized_keys*
		fi
		cd -
		cd $SSH_AUTH_DIR
		for authfile in `ls $SSH_AUTH_FILE_PREFIX.* 2> /dev/null` ; do
			cat /dev/null > $authfile
			rm -f $authfile
		done
		if [ -f authorizedKeys.tar ]; then
			tar -xf authorizedKeys.tar
			/bin/chmod 600 authorized_keys*
		fi
		cd -
	fi
fi
