#!/bin/sh
#  $Id: security_customca.sh 109677 2015-03-31 12:24:31Z pc161604 $
#  Copyright (c) 2000, 2019, Oracle and/or its affiliates. All rights reserved.
#  This software code contains proprietary information 
#  and should be treated as confidential.
#
#  Author: Tim Moss
#
#  Generates a Custom CA Certificate for this host
#

. "common-env.sh"

[ "$trace" = x ] && set -x

# be paranoid about the current path
if [ -d /bin ]; then
  PATH=/bin:$PATH
fi
if [ -d /sbin ]; then
  PATH=/sbin:$PATH
fi
if [ -d /usr/bin ]; then
  PATH=/usr/bin:$PATH
fi
if [ -d /usr/sbin ]; then
  PATH=/usr/sbin:$PATH
fi
if [ -d /etc ]; then
  PATH=/etc:$PATH
fi
export PATH

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="--------------------------------------------------------------------------"

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

GetPrivUsrGrp()
{
    cat $TTADATADIR/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" : '.* \([^ ]*\)$'`

MkTtaDir()
{
    _newdirs="" _pflag=""
    case "$1" in
    -p) _pflag="-p"; shift
    esac
    for _d in "$@"; do
	while [ -n "$_d" ]; do
	    [ -d "$_d" ] && break
	    _newdirs="$_newdirs $_d"
	    _d=`dirname $_d`
	done
    done
    mkdir $_pflag "$@"
    [ -n "$_newdirs" ] && { chgrp $privgrp $_newdirs 2>/dev/null; chown $privusr $_newdirs 2>/dev/null; }
}


OPENSSL_BINARY=openssl
OPENSSL_HELPER=$TTABINDIR/scripts/openssl_lib.sh
TSPDIR=$TTADATADIR/tsp
CONFIG_FILE=$TTAINSTDIR/etc/data/openssl.cnf
PEM_FILE=$TSPDIR/ca.pem
DER_FILE=$TSPDIR/ca.der
SERVER_CERT=$TSPDIR/cert.pem

usage()
{
  echo "$lf_customca_usage"
}

#
# Does a "shift" only if there are some parameters left
#
SHIFT='if [ $# -ge 1 ]; then shift; else usage; exit 2; fi'

rootfile=""
#
# Parse command-line parameters
#
while [ -n "$1" ]; do
    case $1 in
        --rootfile ) rootfile=$2; eval "$SHIFT"; eval "$SHIFT";;
        --remove ) 

	# only attempt to remove the file if the PEM exists
	if [ ! -f $PEM_FILE ]; then
	    echo "$l_customca_notexist"
	    exit 1
	fi

    	rm -f $PEM_FILE $DER_FILE >/dev/null 2>&1

	if [ $? -eq 0 ]; then
	    echo "$l_customca_removed"
	    exit 0
	else
	    echo "$l_customca_notremoved"
	    exit 1
	fi
		    
	;;
	* ) usage ; exit 1;;
    esac
done

#
# See if TSP is installed.
#
if [ ! -x $TTABINDIR/bin/ttassl ]; then 
    echo "$lf_tspnotinstalled"
    exit 2
fi

#
# Create $TSPDIR if it doesn't exist
#
if [ ! -d $TSPDIR ]; then
    MkTtaDir $TSPDIR
    if [ $? != 0 ]; then
	echo "$l_cant_create_tspdir"
	exit 1
    fi
    chmod 751 $TSPDIR
fi


#
# Make the files only accessible by root.
#
umask 077

TMPFILE=$TSPDIR/cert.tmp
rm -f $TMPFILE
if [ -z "$rootfile" ]; then
#
# Read a certificate file from stdin
#
cat >$TMPFILE 2>/dev/null
else
    if [ ! -f "$rootfile" ]; then
        # Try in cwd
        newrootfile="$TTACWD/$rootfile"
        if [ ! -f $newrootfile ]; then
	    echo "$l_customca_norootfile1$rootfile$l_customca_norootfile2"
	    exit 2
        fi
        rootfile=$newrootfile
    fi
    cat $rootfile >$TMPFILE 2>/dev/null
fi

# See if we have a certificate installed
if [ -f $SERVER_CERT ]; then
  # Check to see if the ca cert if compatible with our server cert
  `${OPENSSL_HELPER} checkca --cacert=${TMPFILE} --cert=${SERVER_CERT}`
  if [ $? -ne 0 ]; then
    ca_ans=${s_no}
[ -z "${i18n_yes}" ] && i18n_yes="${a_yes}"
[ -z "${i18n_no}" ] && i18n_no="${a_no}"
[ -z "${i18n_case_yes}" ] && i18n_case_yes="${a_case_yes}"
[ -z "${i18n_case_no}" ] && i18n_case_no="${a_case_no}"
[ -z "${i18n_s_yes}" ] && i18n_s_yes="${s_yes}"
[ -z "${i18n_s_no}" ] && i18n_s_no="${s_no}"
[ "${l_customca_servercertincompatible}" != "NOPROMPT" ] && echo "${l_customca_servercertincompatible}"
echo # blank line between prompt and question
_valid=false
while [ $_valid = false ]
do
  echo $N "${q_customca_servercertincompatible_q} [$ca_ans] $C"
  read _answer
  if [ -z "$_answer" ]
  then
    _answer="$ca_ans"   # default
  fi
  case "$_answer" in
    [${i18n_case_yes}]* )
	    _answer=$i18n_s_yes
	    _valid=true
	    ;;
    [${i18n_case_no}]* )
	    _answer=$i18n_s_no
	    _valid=true
	    ;;
  esac
done
ca_ans="$_answer"

    case "$ca_ans" in
      ${s_yes})
        useca="yes"
        ;;
      *) echo "${l_customca_notinstalled}"
         exit 1
    esac
  fi
fi

# Does the PEM file contain at least one 'BEGIN CERTIFICATE|END CERTIFICATE' pair?
containsCert() {
    b="`egrep -c 'BEGIN CERTIFICATE' $1 2>/dev/null`"
    e="`egrep -c 'END CERTIFICATE' $1 2>/dev/null`"
    [ -z "$b" -o -z "$e" ] && return 1
    [ "$b" -lt 1 -o "$e" -lt 1 ] && return 1
    return 0
}

# Import a certificate into the SGD cacerts file
importCert() {
    IMPORTCERT="$1" n="$2"
    KEYTOOL="${SGD_JAVA_DIR}/keytool"
    # Add to our own certificate keystore
    # Note this actually creates the SGD keystore
    CACERTS="${TTADIR}/var/info/certs/cacerts"
    read KEYSTOREPASS < "${TTADIR}/var/info/sgdstorepass"
    chmod 640 "${CACERTS}" > /dev/null 2>&1
    LC_ALL=C LANG=C ${KEYTOOL} -delete -keystore "${CACERTS}" \
				-storepass "${KEYSTOREPASS}" -alias sunsgdcacert${n} >/dev/null 2>&1
    LC_ALL=C LANG=C ${KEYTOOL} -importcert -noprompt -keystore "${CACERTS}" \
				-storepass "${KEYSTOREPASS}" -file ${IMPORTCERT} -alias sunsgdcacert${n}
    chmod 640 "${CACERTS}"
}

# Import a certificate chain into the JVM cacerts file
importCertChain() {
    CHAIN="${TMPDIR:-/tmp}/customca0_$$"
    THIS="${TMPDIR:-/tmp}/customca1_$$"
    OTHERS="${TMPDIR:-/tmp}/customca2_$$"
    rm -rf ${CHAIN} ${THIS} ${OTHERS} 2>/dev/null
    cp $1 ${CHAIN}
    n=0
    while containsCert ${CHAIN}; do
	cp /dev/null ${THIS}; cp /dev/null ${OTHERS}
	awk '/^-----BEGIN CERTIFICATE-----/ {
	    if (pretail) tail = 1
	}
	/^-----END CERTIFICATE-----/ {
	    pretail = 1
	}
	tail == 0 {
	    print >>"'"${THIS}"'"
	}
	tail == 1 {
	    print >>"'"${OTHERS}"'"
	}' ${CHAIN}
	containsCert ${THIS} && { n=`expr $n + 1`; importCert ${THIS} ${n}; }
	mv ${OTHERS} ${CHAIN}
    done
    rm -rf ${CHAIN} ${THIS} ${OTHERS} 2>/dev/null
}

if [ -f "$TMPFILE" ]
then
    #
    # Generate a x509 command
    #
    $OPENSSL_BINARY x509 -in $TMPFILE -out $PEM_FILE -outform PEM >/dev/null 2>/dev/null    
    if [ $? != 0 ]; then
	echo "$l_customca_error"
	exit 2
    fi
    cat $TMPFILE > $PEM_FILE 2>/dev/null
    chmod 640 $PEM_FILE >/dev/null 2>&1
    $OPENSSL_BINARY x509 -in $TMPFILE -out $DER_FILE -outform DER >/dev/null 2>/dev/null    
    if [ $? != 0 ]; then
	echo "$l_customca_error"
	exit 2
    fi
    chmod 640 $DER_FILE >/dev/null 2>&1
    rm -f $TMPFILE

    # Add cert (or cert chain) to SGD cacerts file
    importCertChain $PEM_FILE

    # print a summary of the CA cert 
echo $_ss_headlines
echo "$h_CA_summary"
echo $_ss_headlines

    echo "$l_customca_installed"
    echo "$l_CA_summary"
    ${OPENSSL_HELPER} textsummary --cert=${PEM_FILE}
    echo ""

else
    rm -f $TMPFILE
    echo "$l_customca_notinstalled"
    exit 2
fi

# If ca different to cert create link so it is included in mobile profile
cmp -s "${PEM_FILE}" "${SERVER_CERT}" || {
    sgd_cert_dir="${TSPDIR}/certs/array"
    HOSTNAME=`${TTADIR}/bin/bin/ttahostname 2>/dev/null`
    hostname_with_dashes="`echo ${HOSTNAME} | sed 's|\.|-|g'`"
    if [ -f "${PEM_FILE}" ]; then
        [ -f "${sgd_cert_dir}/CA-${hostname_with_dashes}.pem" ] && {
            rm -f ${sgd_cert_dir}/CA-${hostname_with_dashes}.pem
        }
        # create directory if not already present
        if [ ! -d "${sgd_cert_dir}" ]; then
            mkdir -p ${sgd_cert_dir}
        fi
        ln -s ${PEM_FILE} ${sgd_cert_dir}/CA-${hostname_with_dashes}.pem
    fi
}

# Set file owners
chown -R $privusr $TSPDIR
chgrp -R $privgrp $TSPDIR

#Make sure the certificates in the host file are up to date
$TTABINDIR/tarantella security setrootcerts

exit 0
