#! /usr/bin/ksh
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
# ike720 src/bos/usr/sbin/isakmp/cmd/certmgr.sh 1.6.1.2 
#  
# Licensed Materials - Property of IBM 
#  
# Restricted Materials of IBM 
#  
# COPYRIGHT International Business Machines Corp. 2000,2011 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# @(#)61  1.6.1.2 src/bos/usr/sbin/isakmp/cmd/certmgr.sh, ike_cmds, ike720 7/15/11 05:07:51
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Kshell Scripts: certmgr
# Purpose: Wrapper script that allows the user to easily run the
#          IBM Key Management software (aka "gsk") without setting
#          the necessary environment variables.
#
#          This script will automatically identify the most current
#          version of gsk installed, ensure that a compatable version
#          of JAVA is installed, then configure the environment
#          appropriately for gsk/JAVA set found. At that point gsk
#          is automatically started for the user.
# 
#          Note that the user must have root privilege to execute
#          this script and perform the operations specified.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
trap INT Interupt
trap TERM Interupt
if [[ $* = -[Dd] ]]; then
    DEBUG=1
fi

export readonly INTERUPT=1
export readonly NOTROOT=2
export readonly GSKITNOTINSTALLED=3
export readonly BADPATH=4
export readonly EXECUTABLENOTFOUND=5
export readonly UNRECOGNIZEDVERSION=6
export readonly NOJAVA=7
export readonly GSKJAVAMISMATCH=8
export readonly NOCONFIGFILE=9
export readonly BADCONFIGFILE=10

export readonly RTE=0
export readonly VERSION=1
export readonly BINDIR=2
export readonly HOMEDIR=3
export readonly ENDINFO=4
export readonly ENDVERSIONINFO="MARKER"

export readonly ALLVERSIONS="4 5 6 7"
export readonly GSK5PATHINFO="/usr/java_dev2/jre/sh:usr/java_dev2/sh"
export readonly CONFIGVAL="DEFAULT_SUBJECT_ALTERNATIVE_NAME_SUPPORT="

export NUMGSKITS=0
export GSKITEXE=""
export GSKITDIR=""
export GSKITVER=0
export JAVA_HOME=""
export JAVAVERSION=0
export JAVABIN=""
export ERRORS=0
export GSKIT_HOME=""
export IKMCONFIGFILE=""

set -A javaInfo

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Function: CertMgr
# Purpose:  Main function for the CertMgr script
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function CertMgr {

    CheckIfRoot
    SetVersionMatchArray
    SetErrorMsgsArray

    GetGskitVersion
    GetJavaVersions
    CheckJavaVersion
    SetUpEnvironment

    StartGsk


    Done 
}

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Function: CheckIfRoot
# Purpose:  Checks to ensure the user is root. If not, we exit.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function CheckIfRoot {

    if [[ $USER != "root" ]]; then
	ERRORS=$NOTROOT
        Done
    fi

}

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Function: SetVersionMatchArray
# Purpose: This array defines the versions of JAVA that are compatable
#          with the version of gsk that was found. 
#
# Note: Note that the first entry in each "line" is the gsk version.
#       The following entries in the "line" are regular expressions
#       used to identify an accesptable version JAVA for the associated
#       version of gsk.
#
#       To extend the life of this script, simply append to the end
#       of the array. When adding JAVA version expressions, be sure
#       to put them in "preferred order", as the algorithm that looks
#       for a matching version accepts the first one it finds.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function SetVersionMatchArray {

    set -A gskToJava \
    "4" "^1.2" "^1.1" "$ENDVERSIONINFO" \
    "5" "^[2-9]" "^1.[3-9]" "$ENDVERSIONINFO" \
    "6" "^1.[3-9]" "$ENDVERSIONINFO" \
    "7" "^[2-9]" "^1.[3-9]" "$ENDVERSIONINFO"

}


#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Function: ErrorMsgsArray
# Purpose:  This array defines all the error messages that are
#           associated with exit conditions that can be encountered.
#
# Note: As of the original release of this script, these messages
#       are only printed if the DEBUG option is submitted at script
#       invocation (-d on the command line). See the function "Done".
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function SetErrorMsgsArray {

    set -A ERRORMSGS "" \
    "Interupt detected" \
    "Must have root privilege to execute this script." \
    "GSKIT is not installed." \
    "Null path to gskit exectuable." \
    "GSKIT executable not found." \
    "Unrecognized version of GSKIT." \
    "Cannot find JAVA." \
    "GSK/JAVA version mismatch." \
    "Ike Manager configuration file not found." \
    "Unable to modify config file: $IKMCONFIGFILE"

}

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Function: GetGskitVersion
# Purpose:  Checks to see if GSKIT is loaded on the system, is actually
#           there, and if so - determines the version(s) installed. If
#           more than one version is present, then the most recent 
#           version (as in highest version number) is used.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function GetGskitVersion {

    if [[ $(/usr/bin/lslpp -L | /usr/bin/grep gsk ) != "" ]]; then
        NUMGSKITS=$(/usr/bin/lslpp -l | /usr/bin/grep gsk |  /usr/bin/grep -v "sdk" |/usr/bin/wc -l)
        NUMGSKITS=${NUMGSKITS##+( )}
        #Check to see if both version 4 and 5 are installed, if so use 5.
        if [[ $NUMGSKITS != 1 ]] ; then
           GSKRTE=$(/usr/bin/lslpp -l | /usr/bin/grep gsk | /usr/bin/grep -v "sdk" | /usr/bin/egrep "5|gskta" | /usr/bin/awk '{print $1}')
        else
           GSKRTE=$(/usr/bin/lslpp -l | /usr/bin/grep gsk | /usr/bin/grep -v "sdk" | /usr/bin/awk '{print $1}')
        fi
	GSKDIRNAME=$(print $GSKRTE | /usr/bin/cut -f1 -d.)
	GSKITDIR=$(/usr/bin/lslpp -f $GSKRTE | /usr/bin/grep "/$GSKDIRNAME/bin$" | /usr/bin/awk '{print $1}')
	# is the directory there?
	if [[ -a $GSKITDIR ]]; then
	    # is there an executable there?
	    if [[ $(/usr/bin/ls ${GSKITDIR}/gsk?ikm 2> /dev/null) != "" ]]; then
		# is there a recognizable version of gskit there?
		for gskExe in ${GSKITDIR}/gsk?ikm; do
		    for version in $ALLVERSIONS; do
			if [[ $gskExe = *gsk${version}ikm* ]]; then
			    if (( $version > $GSKITVER )); then
				GSKITVER=$version
				GSKITEXE=$gskExe
				if (( $DEBUG )); then
				   print "gskit version is: $GSKITVER"
				   print "gskit exe is: $GSKITEXE"
				fi
				break
			    fi
			fi
		    done
		done
		if [[ $GSKITVER = "0" ]]; then
		    ERRORS=$UNRECOGNIZEDVERSION
		fi
		if [[ $GSKITEXE = "" ]]; then
		    ERRORS=$BADPATH
		fi
	    else
		ERRORS=$EXECUTABLENOTFOUND		
	    fi
	else
	    ERRORS=$GSKITNOTINSTALLED
	fi
    else 
	ERRORS=$GSKITNOTINSTALLED
    fi

    if (( $GSKITVER < 6 )); then
      export GSKIT_HOME="/usr/opt/ibm/gskkm"
    else
      export GSKIT_HOME="/usr/opt/ibm/gskak"
    fi
   
    if (( $GSKITVER == 7 )); then
      export GSKIT_HOME="/usr/opt/ibm/gskta"
    fi
    export IKMCONFIGFILE="$GSKIT_HOME/classes/ikminit.properties"

    if (( $ERRORS )); then
	Done
    fi
}

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Function: GetJavaVersions
# Purpose:  Gets all the versions of Java installed on the system
#           (there could be more than one), and stores them in the
#           javaInfo array for later use.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function GetJavaVersions {

    versionIsNext=0; thisVer=0; i=0
    for jI in $(/usr/bin/lslpp -l | /usr/bin/grep Java); do
	if (( $versionIsNext )); then

	    # the if below synched up on the RTE name, so the next
            # item in the loop is the JAVA version.
	    javaInfo[$thisVer+$VERSION]=$jI

	    # Now get the rest of the version info...
	    JAVAPATH=$( /usr/bin/lslpp -f ${javaInfo[$thisVer+$RTE]} | /usr/bin/grep "bin/java$" )
	    if [[ $JAVAPATH = *"->"* ]]; then # symbolic link there?
		JAVAPATH=$(print $JAVAPATH | /usr/bin/awk '{print $4}')
	    else
		JAVAPATH=$(print $JAVAPATH | /usr/bin/awk '{print $1}')
	    fi
	    JAVABIN=${JAVAPATH%/java}

	    javaInfo[$thisVer+$BINDIR]=$JAVABIN
 	    javaInfo[$thisVer+$HOMEDIR]="/$(print $JAVABIN | /usr/bin/cut -f2 -d/)/$(print $JAVABIN | /usr/bin/cut -f3 -d/)"
	    javaInfo[$thisVer+$ENDINFO]=$ENDVERSIONINFO

	    let thisVer=$thisVer+$ENDINFO+1
	    versionIsNext=0

	fi
  if  [[ $(print $jI | /usr/bin/grep "Java.*.rte.bin") != "" ]] ||
    [[ $(print $jI | /usr/bin/grep "Java.*.sdk") != "" ]]; then
	    javaInfo[$thisVer+$RTE]=$jI
	    versionIsNext=1
	fi
    done

}

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Function: CheckJavaVersion
# Purpose:  Checks to see that there is a version of JAVA available
#           that is compatable with the version of gsk that is in use.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function CheckJavaVersion {

    # sync up on the version of gsk that was found.
    thisGsk=0; export gskVerIndex=0; gskVer=0
    while (( $thisGsk < ${#gskToJava[*]} )); do
	if [[ ${gskToJava[$thisGsk]} = $GSKITVER ]]; then
	    gskVerIndex=$thisGsk
	    gskVer=${gskToJava[$gskVerIndex]}
	    if (( $DEBUG )); then
		print "GSKIT version is: $gskVer"
	    fi
	    break
	fi

	# Wrong gsk version - go to the next one.
	while  [[ ${gskToJava[$thisGsk]} != $ENDVERSIONINFO ]]; do
	    let thisGsk=$thisGsk+1
	done
	let thisGsk=$thisGsk+1

    done

    # if we found the version of gsk in use.
    if (( $gskVer )); then
	acceptableJava=$gskVerIndex+1
	matched=0
	while [[ ${gskToJava[$acceptableJava]} != $ENDVERSIONINFO ]]; do
	    jIndex=0
	    if (( $DEBUG )); then
		print "Java Match Expression: \"${gskToJava[$acceptableJava]}\" Java Version Found:\c"
	    fi
	    while (( $jIndex != ${#javaInfo[*]} )); do
		if (( $DEBUG )); then
		    print " \"${javaInfo[$jIndex+$VERSION]}\"\c"
		fi
		if [[ $(print "${javaInfo[$jIndex+$VERSION]}" | /usr/bin/grep "${gskToJava[$acceptableJava]}") != "" ]]; then
		    export JAVABIN=${javaInfo[$jIndex+$BINDIR]}
		    export JAVA_HOME=${javaInfo[$jIndex+$HOMEDIR]}
		    export JAVAVERSION=${javaInfo[$jIndex+$VERSION]}
		    if (( $DEBUG )); then
			print "\nJAVA Version is: \"$JAVAVERSION\""
			print "JAVA bin is: \"$JAVABIN\""
			print "JAVA_HOME is: \"$JAVA_HOME\""
      print "GSKIT_HOME is: \"$GSKIT_HOME\""
      print "GSKITVER is: \"$GSKITVER\""
		    fi
		    matched=1
		    break
		fi
		let jIndex=$jIndex+$ENDINFO+1
	    done
	    if (( $matched )); then
		break
	    else
		if (( $DEBUG )); then
		    print
		fi
	    fi
	    let acceptableJava=$acceptableJava+1
	done
	if (( ! $matched )); then
	    ERRORS=$GSKJAVAMISMATCH
	fi
    else
	ERRORS=$UNRECOGNIZEDVERSION
    fi

    if (( $ERRORS )); then
	Done
    fi

}

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Function: SetUpEnvironment
# Purpose:  Does what ever is necessary to setup the environment
#           for the version of GSKIT that was found.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function SetUpEnvironment {

    if (( $GSKITVER == 4 )); then
	if [[ $JAVA_HOME = "" ]]; then
	    ERRORS=$CANTFINDJAVAHOME
	fi

    # Assumes environment is the same for all versions of gskit newer than 4 
    else
	if (( $DEBUG )); then
	    print "Unsetting JAVA_HOME"
	fi
	unset JAVA_HOME
	if [[ -a $IKMCONFIGFILE ]]; then
	    if [[ $(/usr/bin/egrep "$CONFIGVAL" $IKMCONFIGFILE) = "" ]]; then
		# No config line present, so append one to the end.
		print "${CONFIGVAL}true" >> $IKMCONFIGFILE
	    else
		# the config line is there - simply make sure it is correct.
		/usr/bin/sed "s/^#*.*${CONFIGVAL}.*$/${CONFIGVAL}true/g" $IKMCONFIGFILE > ${IKMCONFIGFILE}.new
		/usr/bin/rm -f $IKMCONFIGFILE
		/usr/bin/mv ${IKMCONFIGFILE}.new $IKMCONFIGFILE
	    fi
	    # Ok, now double check to ensure that the configuration setting is there.
	    if [[ $(/usr/bin/egrep "^${CONFIGVAL}[Tt][Rr][Uu][Ee]$" $IKMCONFIGFILE) != "" ]]; then
		export PATH="$GSK5PATHINFO:$PATH"
		if [[ $(whence java) = "" ]]; then
		    export PATH=$JAVABIN:$PATH
	        fi
	    else
		ERROR=$BADCONFIGFILE
	    fi
	else
	    ERRORS=$NOCONFIGFILE	    
	fi
    fi
      
    if (( $ERRORS )); then
	Done
    fi

}

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Function: StartGsk
# Purpose:  Starts gsk.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function StartGsk {

    if (( $DEBUG )); then
         print "Starting gsk: $GSKITEXE"
         print "JAVA_HOME: $JAVA_HOME"
    fi
    $GSKITEXE

}

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Function: Done
# Purpose:  The single exit point for this script.
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function Done {

    if (( $ERRORS )); then
	if (( $DEBUG )); then
	    print "${ERRORMSGS[$ERRORS]}"
	fi
	exit 1
    fi
    exit 0

}

#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Function: Interupt
# Purpose: Clean trap routine for SIGTERM and SIGINT 
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
function Interupt {
    ERRORS=$INTERUPT
    Done
}
CertMgr