#!/bin/sh
#  Copyright (c) 2003, 2020, Oracle and/or its affiliates. All rights reserved.
#  This software code contains proprietary information
#  and should be treated as confidential.

. "common-env.sh"

export JAVA_HOME=${SGD_JAVA_HOME}

N=""
C=""
if echo -n | grep n > /dev/null
then
  C="\c"
else
  N="-n"
fi
case "$MACHINEARCH" in
i3li*|ppli*) N="$N -e" ;;
esac
_ss_headlines="--------------------------------------------------------------------------"

u="`LANG=C LC_ALL=C id | sed 's/.*uid=\([0-9][0-9]*\).*/\1/'`"
if [ "$u" = "0" ]
then
  : # all is okay
else
  echo "You must be root to run this program"
  exit 15
fi

if [ -f $TTAMSG/common -a -f $TTAMSG/tta_webserver ]; then
  . $TTAMSG/common
  . $TTAMSG/tta_webserver
else
  echo "Unable to open message file: $TTAMSG/tta_webserver"
  exit 1
fi

GetPrivUsrGrp()
{
    cat $TTAINSTDIR/var/serverconfig/global/array.properties 2>/dev/null | awk -F= \
	'BEGIN { u="ttasys"; wu="ttaserv"; g="ttaserv" }
	$1 == "tarantella.config.array.privilegeduser" { u = $2 }
	$1 == "tarantella.config.array.webserveruser" { wu = $2 }
	$1 == "tarantella.config.array.privilegedgroup" { g = $2 }
	END { print u " " wu " " g }'
}
_privusrgrp=`GetPrivUsrGrp`
privusr=`expr "$_privusrgrp" : '\([^ ]*\) .*'`
webservusr=`expr "$_privusrgrp" : '.* \([^ ]*\) .*'`
privgrp=`expr "$_privusrgrp" : '.* \([^ ]*\)$'`

_setsid=''
for _dir in `echo "$PATH" | tr : ' '`; do
    case "${_dir}" in
    /*) [ -x "${_dir}/setsid" ] && { _setsid="${_dir}/setsid"; break; }
    esac
done

GetSecurity()
{
   FILE=$1

   SECURITY=`tr '>' '\012' < ${FILE}  | tr '<' ' '  | grep security`
   VALUE=`echo ${SECURITY} | grep "Value"`
   if [ -z "${VALUE}" ]; then
      LINE=`grep -n security ${FILE} | awk '{print $1}' | tr ':' ' '`
      NEXT=`expr ${LINE} + 1`
      SECURITY=`head -${NEXT} ${FILE} | tail -1`
   fi

   echo ${SECURITY} | tr '"' ' ' |
   awk '{ for (i=1; i<NF; i++)
   {
       if ($i == "Value=")
       {
          n=(i+1)
          print $n
          break
       }
   } }'
}

GetWebGateConfig()
{
   CONFIG=$1

   # Try local first
   LOCAL_CONFIG="--tarantella-config-sso-server-${CONFIG}"
   CONF=`${TTAINSTDIR}/bin/tarantella config list ${LOCAL_CONFIG} | awk '{print $2}' | tr -d '\"'`
   if [ -z "${CONF}" ]; then
      GLOBAL_CONFIG="--tarantella-config-sso-${CONFIG}"
      CONF=`${TTAINSTDIR}/bin/tarantella config list ${GLOBAL_CONFIG} | awk '{print $2}' | tr -d '\"'`
   fi

   echo "${CONF}"
}


isnumeric()
{
   stripped=`echo "$1" | tr -cd '[0-9]'`
   [ -n "$1" -a "$1" = "${stripped}" ] && return 0 || return 1
}

notnumeric()
{
   isnumeric "$1" && return 1 || return 0
}

LISTEN_HTTP=${TMPDIR:-/tmp}/listen0_$$
LISTEN_HTTPS=${TMPDIR:-/tmp}/listen1_$$

rm -rf "${LISTEN_HTTP}" "${LISTEN_HTTPS}" 2>/dev/null

# extract "Listen" directives from an Apache httpd.conf file and
# check they are available to use.
# Return 0 - HTTP Ports available to use
# Return 1 - Problem with the HTTP ports and log the error
CheckHTTPListenDirectives()
{
    conffile="$1"
    awk '$1=="<IfDefine" && $2=="SSL>" {
      state = 1
    }
    $1=="</IfDefine>" {
      state = 0
    }
    state==0 && $1=="Listen" && bGotListenHttp==0 {
      print >"'"${LISTEN_HTTP}"'"; bGotListenHttp = 1
    }
    state==1 && $1=="Listen" && bGotListenHttps==0 {
      print >"'"${LISTEN_HTTPS}"'"; bGotListenHttps = 1
    }' "${conffile}"

    ############################################################
    # Check HTTP port value is valid number then check for inuse
    a_httpport=`awk '{print $2}' <${LISTEN_HTTP}`
    notnumeric "${a_httpport}" && {
      # maybe it was (eg) 127.0.0.1:80
      case "${a_httpport}" in
        *:*) a_httpport=`expr "${a_httpport}" : '.*:\([^:]*\)'` ;;
        esac
    }
    notnumeric "${a_httpport}" && {
      # try getting the port number from the Port directive instead of the Listen directive
      a_httpport=`awk '$1=="Port"{print $2}' "${APACHE_CONF}"`
    }
    # Have we a valid port to check
    httpinuse="y"
    isnumeric "${a_httpport}" && {
       httpinuse=`$TTAINSTDIR/bin/bin/ttahostprobe localhost:$a_httpport`
    }

    #############################################################
    # Check HTTPS port value is valid number then check for inuse
    a_httpsport=`awk '{print $2}' <${LISTEN_HTTPS}`
    notnumeric "${a_httpsport}" && {
      # maybe it was (eg) 127.0.0.1:443
      case "${a_httpsport}" in
        *:*) a_httpsport=`expr "${a_httpsport}" : '.*:\([^:]*\)'` ;;
        esac
    }
    notnumeric "${a_httpsport}" && {
      # try getting the port number from the Port directive instead of the Listen directive
      a_httpsport=`awk '$1=="Port"{print $2}' "${APACHE_CONF}"`
    }
    # Have we a valid port to check
    httpsinuse="y"
    isnumeric "${a_httpsport}" && {
      httpsinuse=`$TTAINSTDIR/bin/bin/ttahostprobe localhost:$a_httpsport`
    }

    if [ "$httpinuse" = "y" ]; then
        printf "${l_apache_httpportinuse}" "${a_httpport}" >> ${TTAINSTDIR}/var/log/stderrout.log 2>&1
    fi

    if [ "$httpsinuse" = "y" ]; then
        printf "${l_apache_httpsportinuse}" "${a_httpsport}" >> ${TTAINSTDIR}/var/log/stderrout.log 2>&1
    fi

    if [ "$httpinuse" = "y" ] || [ "$httpsinuse" = "y" ]; then
        printf "${l_apache_httpports}" >> ${TTAINSTDIR}/var/log/stderrout.log 2>&1
        return 1
    else
        return 0
    fi
}

CheckWebGate()
{
   #  If SSO is not enabled return immediately 
   SSO_ENABLED=`grep "sso.enabled=1" $TTAINSTDIR/var/serverconfig/global/sso.properties`
   if [ -z "${SSO_ENABLED}" ]; then
      return
   fi

   # Check the WebGate binaries exist
   WEBGATE_INSTALL=`GetWebGateConfig webgateinstall`
   if [ ! -s "${WEBGATE_INSTALL}/lib/webgate.so" -o ! -s "${WEBGATE_INSTALL}/lib/webgatessl.so" ]; then
      echo "${l_webgateconfig_error} ${l_missingbinaries}"
      echo "${l_webgate_notstarted}"
      return
   fi 

   # Check webgate.conf is available
   if [ ! -s "${apachepath}/conf/webgate.conf" ]; then
      echo "${l_webgateconfig_error} ${l_missingconf}"
      echo "${l_webgate_notstarted}"
      return
   fi
 
   # Check webgate configuration files are available
   WEBGATE_INSTANCE=`GetWebGateConfig webgateinstance`
   if [ -z "${WEBGATE_INSTANCE}" ]; then
      echo "${l_webgateconfig_error} ${l_webgate_missinginstance}"
      echo "${l_webgate_notstarted}"
      return
   fi
   OAMCFGDIR="${WEBGATE_INSTANCE}/webgate/config" 
   if [ ! -s "${OAMCFGDIR}/ObAccessClient.xml" ]; then
      echo "${l_webgateconfig_error} ${l_webgate_missingobclient}"
      echo "${l_webgate_notstarted}"
      return
   fi
 
   if [ ! -s "${OAMCFGDIR}/cwallet.sso" ]; then
      echo "${l_webgateconfig_error} ${l_webgate_missingcwallet}"
      echo "${l_webgate_notstarted}"
      return
   fi
   SECURITY_LEVEL=`GetSecurity ${OAMCFGDIR}/ObAccessClient.xml`
   case "${SECURITY_LEVEL}" in
      "simple")
          if [ ! -s "${OAMCFGDIR}/password.xml" ]; then
             echo "${l_webgateconfig_error} ${l_webgate_missingpassword}"
             echo "${l_webgate_notstarted}"
             return
          fi
          if [ ! -s "${OAMCFGDIR}/simple/aaa_key.pem" ]; then
             echo "${l_webgateconfig_error} ${l_webgate_missingkey}"
             echo "${l_webgate_notstarted}"
             return
          fi 
          if [ ! -s "${OAMCFGDIR}/simple/aaa_cert.pem" ]; then
             echo "${l_webgateconfig_error} ${l_webgate_missingcert}"
             echo "${l_webgate_notstarted}"
             return
          fi  
          ;;             
      "cert")
          if [ ! -s "${OAMCFGDIR}/password.xml" ]; then
             echo "${l_webgateconfig_error} ${l_webgate_missingpassword}"
             echo "${l_webgate_notstarted}"
             return
          fi
          if [ ! -s "${OAMCFGDIR}/simple/aaa_key.pem" ]; then
             echo "${l_webgateconfig_error} ${l_webgate_missingkey}"
             echo "${l_webgate_notstarted}"
             return
          fi 
          if [ ! -s "${OAMCFGDIR}/simple/aaa_cert.pem" ]; then
             echo "${l_webgateconfig_error} ${l_webgate_missingcert}"
             echo "${l_webgate_notstarted}"
             return
          fi  
          if [ ! -s "${OAMCFGDIR}/simple/aaa_chain.pem" ]; then
             echo "${l_webgateconfig_error} ${l_webgate_missingchain}"
             echo "${l_webgate_notstarted}"
             return
          fi  
          ;;
   esac

   # All requirements are met 
   echo "${WEBGATE_INSTALL}/lib"
}

GetRESTPort()
{
    port=`${TTAINSTDIR}/bin/tarantella config list --tarantella-config-rest-apiport | grep "apiport" | awk '{print $2}'`

    # If config list doesn't return a value, try getting the
    # value from the config file directly
    notnumeric "${port}" && {
        port=`grep "tarantella.config.rest.apiport" ${TTAINSTDIR}/var/serverconfig/local/rest.properties 2>/dev/null | cut -d'=' -f2`
    }

    echo "${port}"
}

# We need this on SuSE SLES 9 (and it doesn't do any harm on other platforms)
CATALINA_OPTS=""
export CATALINA_OPTS

case "$trace" in x|X) set -x;; esac

action="" target="" secure="" quiet=""

# Where are they?
webdir=$TTAINSTDIR/webserver
apachedir=$webdir/apache
tomcatdir=$webdir/tomcat

A_VER=`cat "${TTAINSTDIR}/var/info/apacheversion"`
T_VER=`cat "${TTAINSTDIR}/var/info/tomcatversion"`

secfile=$webdir/.TWS_secure

SSO_STATUS="${TTAINSTDIR}/var/info/sso.status"

apachepath="${apachedir}/${A_VER}"
apachebin=$apachepath/bin/apachectl
apacheconf=$apachepath/conf/httpd.conf

tomcatpath="${tomcatdir}/${T_VER}"
tomcatbin=$tomcatpath/bin/catalina.sh

envvars=${apachepath}/bin/envvars

##Source the appropriate environment for httpd installation.
if [ -f "${envvars}" ]; then 
    #source envvars
    . ${envvars}
    export LD_LIBRARY_PATH
fi

suAttr="login-thirdparty-superusers"
tpAttr="login-thirdparty"

if [ -z "$1" -o "$1" = "--help" ]; then
    echo "$lf_webserver_usage"
    exit 0
fi

tomcat_fn () {
CATALINA_PID="${tomcatpath}/logs/catalina_pid" export CATALINA_PID
case $1 in
    stop)
        echo "$l_tomcat_stop"
        $tomcatbin stop -force 2>&1 |
	awk '/ConnectException/ {
	    suppress = 1; next
	}
        /^[^ 	]/ {
	    suppress = 0
	}
	suppress == 0 {
	    print
	}' > ${tomcatpath}/logs/stderrout.log 2>&1
        res=$?
	;;
    start)
        echo "$l_tomcat_start"
        trap "" 1
	logfile=$tomcatpath/logs/catalina.out
	cat $logfile >>$logfile.sav 2>/dev/null
	:>$logfile
	chown $webservusr $logfile
	chgrp $privgrp $logfile
        su $webservusr -c "${_setsid} $tomcatbin start" > ${tomcatpath}/logs/stderrout.log 2>&1
        res=$?
	;;
esac
case $res in
    0) echo "$l_ok";;
    *) echo "$l_failed";;
esac
}

apache_kill() {
    for sig in 15 9; do
	procs=`ps -ef | grep ":[0-9][0-9]  *${apachedir}/" | grep -v 'grep ' | awk '{printf "%d ", $2}'`
	case "${procs}" in
	*[0-9]*)
	    kill -${sig} ${procs} 2>/dev/null
	esac
    done
    rm -f "${apachepath}/logs/httpd.pid" 2>/dev/null
}

apache_fn () {
case $1 in
    stop)
        echo "$l_apache_stop"
        REST_PORT=`GetRESTPort`
        notnumeric "${REST_PORT}" && {
            # REST port must be set to avoid an Apache error
            # but the value is not used, so default to "" if
            # no valid value is found 
            REST_PORT=""
        }
        export REST_PORT
        $apachebin -d $apachepath -k stop
	apache_kill
	# Delete the SSO status file
        rm -f ${SSO_STATUS}
	echo "$l_ok"
	return
	;;
    start)
	start_cmd="-k start"
	# Have a look to see if we appear to have a valid certificate/key
	CERTFILE=`grep '^SSLCertificateFile[ 	]' "${apacheconf}" 2>/dev/null|tail -1|awk '{print $2}'`
	KEYFILE=`grep '^SSLCertificateKeyFile[ 	]' "${apacheconf}" 2>/dev/null|tail -1|awk '{print $2}'`
	if [ "${secure}" = "f" ]; then
	    echo "${l_apache_start_http}"
	elif [ "${secure}" = "t" -o -f $secfile ]; then
	    #apache 2.4.x needs to have the mutex dir ready.
	    mutexfile="${apachepath}/logs/ssl_mutex/" 
	    mkdir -p $mutexfile 2>/dev/null
	    chown $webservusr $mutexfile
        chgrp $privgrp $mutexfile
	    start_cmd="-D SSL -k start"
	    echo "${l_apache_start_https}"
	elif [ -n "${CERTFILE}" -a -n "${KEYFILE}" ] && \
	     [ -n "`egrep -e '-----BEGIN .*CERTIFICATE-----' ${CERTFILE} 2>/dev/null`" -a \
	       -n "`egrep -e '-----END .*CERTIFICATE-----'   ${CERTFILE} 2>/dev/null`" -a \
	       -n "`egrep -e '-----BEGIN .*KEY-----' ${KEYFILE} 2>/dev/null`" -a \
	       -n "`egrep -e '-----END .*KEY-----'   ${KEYFILE} 2>/dev/null`" ]; then
	    start_cmd="-D SSL -k start"
	    echo "${l_apache_start_https}"
	else
	    echo "${l_apache_start_http}"
	fi

        # Check whether single sign-on with OAM is enabled
        OAM_ALLOWED=`CheckWebGate`
        case "${OAM_ALLOWED}" in
           /*)
              LD_LIBRARY_PATH="${LD_LIBRARY_PATH}:${OAM_ALLOWED}"
              export LD_LIBRARY_PATH
              OAM="-D OAM"
              # Write file which status can check
	      echo "OAM is active" > ${SSO_STATUS}
              echo "${l_sso_available}"
              ;;
           ${l_webgateconfig_error}*|"")
              if [ -n "${OAM_ALLOWED}" ]; then
                 echo ${OAM_ALLOWED} 
              fi
              ;;
        esac 

        CheckHTTPListenDirectives "${apacheconf}"
        REST_PORT=`GetRESTPort`
        notnumeric "${REST_PORT}" && {
            echo "${l_apache_restportmissing}"
            echo "$l_failed"
            return
        }
        export REST_PORT
        if [ $? = 0 ]; then
            ${_setsid} $apachebin -d $apachepath $OAM $start_cmd
        else
            echo "$l_failed"
            return
        fi
	;;
    restart)
        echo "$l_apache_restart"
        [ -f $secfile ] && start_cmd="-D SSL -k restart" || start_cmd="-k restart"
        CheckHTTPListenDirectives "${apacheconf}"
        REST_PORT=`GetRESTPort`
        notnumeric "${REST_PORT}" && {
            echo "${l_apache_restportmissing}"
            echo "$l_failed"
            return
        }
        export REST_PORT
        if [ $? = 0 ]; then
            ${_setsid} $apachebin -d $apachepath $start_cmd
        else
            echo "$l_failed"
            return;
        fi
	;;
esac
case $? in
    0) echo "$l_ok";;
    *) echo "$l_failed";;
esac
}

get_config()
{
    oldtrace="$trace"
    unset trace
    ${TTAINSTDIR}/bin/tarantella config list --${tpAttr} --${suAttr} 2>/dev/null |
    awk 'BEGIN {
	tpla="'"${tpAttr}"': 0"
	su="'"${suAttr}"': \"\""
    }
    /^'"${tpAttr}"':/ {
	tpla = $0
    }
    /^'"${suAttr}"':/ {
	su = $0
    }
    END {
	print tpla "\n" su
    }'
    [ -n "$oldtrace" ] && trace="$oldtrace"
    return 0
}

add_trusted_user()
{
    case "$1" in
    ''|help|--help) echo "${l_add_trusted_user_usage}"; return 1
    esac
    [ $# -ne 1 ] && { echo "${l_add_trusted_user_usage}"; return 1; }
    trustedUsername="$1"
    config=`get_config`
    superusers=`echo "${config}" | sed "1d;s/.*: *//"`
    case "${superusers}" in
    ${trustedUsername} | ${trustedUsername},* | *,${trustedUsername},* | *,${trustedUsername})
	echo "${trustedUsername}${l_already_trusted}" >&2
	return 1
	;;
    esac
    gotpasswd=""
    while [ -z "${gotpasswd}" ]; do
	echo $N "${l_password1}${trustedUsername}${l_password2}" $C
	stty -echo; read trustedPassword; stty echo
	case "${trustedPassword}" in
	??????*)
	    echo $N "${l_password_again}" $C
	    stty -echo; read try2; stty echo
	    if [ "${trustedPassword}" != "${try2}" ]; then
		echo "${l_password_nonmatch}" >&2
	    else
		echo
		gotpasswd=t
	    fi
	    ;;
	*)  echo "${l_password_too_short}" >&2
	esac
    done
    ${TTAINSTDIR}/bin/tarantella config edit --${suAttr} `echo "${superusers}" | tr ',' ' '` ${trustedUsername}
    t=${TMPDIR:-/tmp}/ttatomcat$$
    trap 'rm -f $t; exit' 1 2 3 15
    rm -f $t >/dev/null 2>&1

    tomcatDir="${TTAINSTDIR}/webserver/tomcat/default"
    digestedPassword="$(${tomcatDir}/bin/digest.sh -a SHA-256 "${trustedPassword}" | sed -n "s/${trustedPassword}://p")"

    tomcatUsers="${tomcatpath}/conf/tomcat-users.xml"
    awk '/^ *<role rolename="SGDExternalAuth"/ {
	print
	print "  <user username=\"'"${trustedUsername}"'\" password=\"'"${digestedPassword}"'\" roles=\"SGDExternalAuth\" />"
	next
    }
    {
	print
    }' "${tomcatUsers}" >$t 2>/dev/null
    [ `wc -c <$t` -gt 0 ] && cp $t "${tomcatUsers}"
    rm -f $t >/dev/null 2>&1
    echo "${l_todo1}"
    [ "`echo \"${config}\" | sed -n '1s/.*: *//p'`" = "0" ] && echo "${l_todo2}${tpAttr}${l_todo3}"
    return 0
}

delete_trusted_user()
{
    case "$1" in
    ''|help|--help) echo "${l_delete_trusted_user_usage}"; return 1
    esac
    [ $# -ne 1 ] && { echo "${l_delete_trusted_user_usage}"; return 1; }
    trustedUsername="$1"
    config=`get_config`
    superusers=`echo "${config}" | sed "1d;s/.*: *//"`
    case "${superusers}" in
    ${trustedUsername})
	${TTAINSTDIR}/bin/tarantella config edit --${suAttr}
	;;
    ${trustedUsername},* | *,${trustedUsername},* | *,${trustedUsername})
	${TTAINSTDIR}/bin/tarantella config edit --${suAttr} `echo "${superusers}" | tr ',' ' ' | sed "s/^${trustedUsername} //;s/ ${trustedUsername} / /g;s/ ${trustedUsername}\$//"`
	;;
    *)  echo "${trustedUsername}${l_not_trusted}" >&2
	return 1
    esac
    t=${TMPDIR:-/tmp}/ttatomcat$$
    trap 'rm -f $t; exit' 1 2 3 15
    rm -f $t >/dev/null 2>&1
    tomcatUsers="${tomcatpath}/conf/tomcat-users.xml"
    grep -v "^ *< *user *username=\"${trustedUsername}\".*roles=\"SGDExternalAuth\"" "${tomcatUsers}" >$t 2>/dev/null
    [ `wc -c <$t` -gt 0 ] && cp $t "${tomcatUsers}"
    rm -f $t >/dev/null 2>&1
    return 0
}

list_trusted_users()
{
    case "$1" in
    help|--help) echo "${l_list_trusted_users_usage}"; return 1
    esac
    [ $# -ne 0 ] && { echo "${l_list_trusted_users_usage}"; return 1; }
    get_config
    return $?
}

while [ ! -z "$1" ]; do
    case $1 in
    .stop|.start|.restart)
	[ -z "$action" ] && action=`expr $1 : '.\(.*\)'` || { echo "$lf_webserver_usage"; exit 0; }
	shift
	;;
    add_trusted_user)
	shift; add_trusted_user "$@"
	exit $?
	;;
    delete_trusted_user)
	shift; delete_trusted_user "$@"
	exit $?
	;;
    list_trusted_users)
	shift; list_trusted_users "$@"
	exit $?
	;;
    --servlet|--http)
	[ -z "$target" ] && target="$1" || target="both"
	shift
	;;
    --quiet)
	quiet=t
	shift
	;;
    --ssl)
	secure=t
	shift
	;;
    --nossl)
	secure=f
	shift
	;;
    *help )
	[ -z "$action" ] && echo "$lf_webserver_usage" || eval echo "\"\$l_${action}_usage\""
	exit 0
	;;
    *)  echo "$lf_badarg $1"
	[ -z "$action" ] && echo "$lf_webserver_usage" || eval echo "\"\$l_${action}_shortusage\""
	exit 1
    esac
done
[ -z "$target" ] && target="both"

case $target in
*http|both)
    case $action in
    *start)
	if [ "$secure" = "t" ]; then
	    touch $secfile
	elif [ "$secure" = "f" ]; then
	    rm -f $secfile
	fi
	;;
    esac
    ;;
esac

case $action in
restart)
    case $target in
    both)
	tomcat_fn stop
	apache_fn stop
	tomcat_fn start
	apache_fn start
	;;
     --http)
	apache_fn restart
        ;;
     --servlet)
	tomcat_fn stop
	tomcat_fn start
        ;;
    esac
    ;;

start)
    case $target in
    both)
	tomcat_fn start
	apache_fn start
        ;;
     --http)
	apache_fn start
        ;;
     --servlet)
	tomcat_fn start
        ;;
    esac
    ;;

stop)
    case $target in
    both)
	tomcat_fn stop
	apache_fn stop
        ;;
     --http)
	apache_fn stop
        ;;
     --servlet)
	tomcat_fn stop
        ;;
    esac
    ;;
esac

exit 0
