Commit 0049d9cb authored by Xueshan Feng's avatar Xueshan Feng
Browse files

hznssltool.sh (Marcello Golfieri)

parent 4bc70f7b
#!/usr/bin/env bash
# Marcello Golfieri
# Pieces here and there from zmcertmgr (addcacert, verifycrt)
# Some variables here (common ones)
TEMP=/tmp/sslcheck123152343joewgjj34
mkdir $TEMP > /dev/null 2>&1
TEMPCERT=$TEMP/_cert
TEMPCHAIN=$TEMP/_chain
TEMPFULLCHAIN=$TEMP/_fullchain
TEMPFULLCERTBUNDLE=$TEMP/_fullcertbundle
TEMPOUTPUT=$TEMP/_output
CONNSERVCACERTS=/usr/java/jre-vmware/lib/security/cacerts
ZIMBRACACERTS=/opt/zimbra/java/jre/lib/security/cacerts
CONNSERVkeytool=/usr/java/jre-vmware/bin/keytool
ZIMBRAkeytool=/opt/zimbra/java/jre/bin/keytool
ERROR_PREFIX='ERROR: '
openssl=`which openssl`
keypass=changeit
if [ -f ${CONNSERVkeytool} ]; then
keytool=${CONNSERVkeytool};
elif [ -f ${ZIMBRAkeytool} ]; then
keytool=${ZIMBRAkeytool};
else
keytool=`which keytool`
[[ $? != 0 ]] && { echo No keytool binary found, please run this script from either the service, connector or data-va.; exit 1 ; }
fi
if [ x`whoami` = "xsshuser" ]; then
echo "$0 can't be run as sshuser"
exit 1
fi
addCACERT() {
if [ -f "${1}" -a -f "${2}" ]; then
usage; exit 1;
fi
CACERTS=${1}
TEMPCERT=${2}
ALIAS=${3:-horizon-$(date +%F-%H%M)}
echo -n "** Importing certificate ${TEMPCERT} to $CACERTS as $ALIAS..."
tmpfile=`mktemp -t zmcertmgr.XXXXXX 2> /dev/null` || (echo "Failed to create tmpfile" && exit 1)
${keytool} -delete -alias ${ALIAS} -keystore ${CACERTS} -storepass ${keypass} > /dev/null 2>&1
${keytool} -import -noprompt -keystore ${CACERTS} -file ${TEMPCERT} -alias ${ALIAS} -storepass ${keypass} > ${TEMPOUTPUT} 2>&1
if [ $? != 0 ]; then
echo "failed."
echo "${ERROR_PREFIX} failed to import certficate."
echo
cat $TEMPOUTPUT
echo
rm -f $TEMPOUTPUT 2>/dev/null
exit 1
else
echo "done."
echo "** NOTE: services on the host must be restarted in order to use the imported certificate."
fi
rm -f $tmpfile 2>/dev/null
}
showcertinfo() {
if [ ! -f ${1} ]; then
echo No such file found: ${1}
usage; exit 1;
fi
${openssl} x509 -in $1 -text -noout
}
fetchPEMoutput() {
TARGETHOST=${1}
REDIRECT=${2}
TEMPFILE=${3}
OPENSSL_OPTS=${4}
if [ "x$REDIRECT" = "xTOFILE" ]; then
echo -n | ${openssl} s_client $OPENSSL_OPTS -connect $TARGETHOST > $TEMPOUTPUT 2>&1
cat $TEMPOUTPUT | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p' > $TEMPFILE
else
echo -n | ${openssl} s_client $OPENSSL_OPTS -connect $TARGETHOST > $TEMPOUTPUT 2>&1
cat $TEMPOUTPUT | sed -ne '/-BEGIN CERTIFICATE-/,/-END CERTIFICATE-/p'
fi
}
showhostcert() {
if [ x"${1}" = "x" ]; then
usage; exit 1;
fi
TARGETHOST=$1
REDIRECT=$2
fetchPEMoutput $TARGETHOST $REDIRECT $TEMPCERT
}
showhostcertfullchain() {
if [ x"${1}" = "x" ]; then
usage; exit 1;
fi
TARGETHOST=$1
REDIRECT=${2:-TOSTDOUT}
fetchPEMoutput $TARGETHOST $REDIRECT $TEMPFULLCHAIN "-showcerts"
}
showhostchain() {
if [ x"${1}" = "x" ]; then
usage; exit 1;
fi
TARGETHOST=$1
showhostcert $TARGETHOST TOFILE
showhostcertfullchain $TARGETHOST TOFILE
if [ x"${2}" = "xTOFILE" ]; then
diff --suppress-common-lines --unchanged-group-format="%L" $TEMPCERT $TEMPFULLCHAIN |sed 's/%L//' > $TEMPCHAIN
else
diff --suppress-common-lines --unchanged-group-format="%L" $TEMPCERT $TEMPFULLCHAIN |sed 's/%L//'
fi
}
showhostfullcertbundle() {
if [ x"${1}" = "x" ]; then
usage; exit 1;
fi
TARGETHOST=$1
showhostcert $TARGETHOST TOFILE
showhostchain $TARGETHOST TOFILE
if [ x"${2}" = "xTOFILE" ]; then
cat $TEMPCHAIN $TEMPCERT > $TEMPFULLCERTBUNDLE
else
cat $TEMPCHAIN $TEMPCERT
fi
}
verifycrt() {
if [ x"${1}" = "x" ]; then
usage
else
key=$1
ca_crt=$2
crt=$3
fi
verifycrtkey $key $crt
verifycrtchain $ca_crt $crt
}
verifycrtkey() {
if [ x"${1}" = "x" ]; then
usage
else
key=$1
crt=$2
fi
echo "** Verifying $crt against $key"
if [ ! -f $key ]; then
echo "${ERROR_PREFIX} Can't find private key ${key} "
exit 1
elif [ ! -f $crt ]; then
echo "${ERROR_PREFIX} Can't find certificate ${crt} "
exit 1
else
key_md5=`${openssl} rsa -noout -modulus -in ${key} | ${openssl} md5`
crt_md5=`${openssl} x509 -noout -modulus -in ${crt} | ${openssl} md5`
fi
if [ x"${key_md5}" != "x" -a x"${key_md5}" = x"${crt_md5}" ] ; then
echo "Certificate (${crt}) and private key (${key}) match."
else
echo "${ERROR_PREFIX} Unmatching certificate (${crt}) and private key (${key}) pair."
exit 1
fi
}
verifycrtchain () {
cafile=$1
crt=$2
result=`${openssl} verify -purpose sslserver -CAfile $cafile $crt`
if [ x"${result}" = x"${crt}: OK" ]; then
echo "Valid Certificate Chain: $result"
else
echo "${ERROR_PREFIX} Invalid Certificate Chain: $result"
exit 1
fi
}
ExplodeCACerts()
{
if [ ! -f "${1}" ]; then
if [ -f "$CONNSERVCACERTS" ]; then
echo ${1} not found. Maybe you meant "$CONNSERVCACERTS"?; exit 1;
elif [ -f "$ZIMBRACACERTS" ]; then
echo ${1} not found. Maybe you meant "$ZIMBRACACERTS"?; exit 1;
else
echo No such file or directory $1; exit 1;
fi
fi
CACERTS=$1
CACERTS_MD5=$(cat $CACERTS | ${openssl} md5)
echo "$CACERTS_MD5" | grep ' ' 2>&1
[[ $? = 0 ]] && { CACERTS_MD5=$(cat $CACERTS | ${openssl} md5 | awk '{print $2}'); }
CACERTS_EXPLODED_DIR=$TEMP/$CACERTS_MD5
echo castore MD5SUM: $CACERTS_MD5
mkdir $CACERTS_EXPLODED_DIR > /dev/null 2>&1
if [ x`echo "$?"` == "x0" ]; then
ALIAS_LIST=$(${keytool} -list -v -keystore $CACERTS -storepass changeit \
| grep 'Alias name'|awk '{print $3}')
echo 'No previous run with this keystore, now extracting PEMs. This might take some time (~1m), please wait...'
for ALIAS in $ALIAS_LIST; do
${keytool} -keystore $CACERTS -storepass changeit -export \
-alias $ALIAS -rfc -file $CACERTS_EXPLODED_DIR/$ALIAS.pem > /dev/null 2>&1
done
c_rehash $CACERTS_EXPLODED_DIR > /dev/null 2>&1
fi
echo Total CAs in the kestore: $(ls $CACERTS_EXPLODED_DIR|grep pem|wc -l)
}
verifypemformatting() {
if [ x"${1}" = "x" ] || [ ! -f $1 ]; then
usage; exit 1;
fi
CERTFILE=$1
_INCORRECT=0
egrep -v '^-----BEGIN PRIVATE KEY-----$|^-----END PRIVATE KEY-----$|^-----BEGIN CERTIFICATE-----$|^-----END CERTIFICATE-----$|^[A-Za-z0-9+=/]{0,66}$' $CERTFILE
if [ "x$?" = "x0" ]; then
_INCORRECT=1
fi
egrep '^\s*$' $CERTFILE > /dev/null
if [ "x$?" = "x0" ]; then
echo Certificate contains blank lines, please remove them
_INCORRECT=1
fi
if [ "x$_INCORRECT" = "x0" ]; then
echo Certificate/key is in correct PEM format
else
echo Certificate/key has formatting issues, please review it, see above lines for the troubled ones
fi
}
checkhost() {
if [ x"${1}" = "x" ]; then
usage; exit 1;
fi
TARGETHOST=$2
CACERTS=$1
ExplodeCACerts $CACERTS
echo 'Remote host check (WARNING: see script comment #NOTE01 for more info):'
#NOTE01
# The problem here is that the openssl shipped with the distros come with an hardcoded value set at compile time
# to fallback for the CApath, regardless of whether this is set or not in the command line.
# For example, in Ubuntu it fallbacks to /etc/ssl/certs and therefore it's not really verifying against
# the pure cacerts passed as argument. Working on this as we speak.
echo quit | ${openssl} s_client -connect $TARGETHOST -CApath $CACERTS_EXPLODED_DIR 2>&1 |grep "Verify return code"
[[ "x$?" != "x0" ]] && echo ${ERROR_PREFIX} $TARGETHOST is not responding
}
checkcert() {
if [ x"${1}" = "x" ] || [ ! -f $1 ]; then
usage; exit 1;
fi
CERTFILE=$2
CACERTS=$1
ExplodeCACerts $CACERTS
echo 'Local cert check (WARNING: see script comment #NOTE01 for more info):'
#NOTE01
# The problem here is that the openssl shipped with the distros come with an hardcoded value set at compile time
# to fallback for the CApath, regardless of whether this is set or not in the command line.
# For example, in Ubuntu it fallbacks to /etc/ssl/certs and therefore it's not really verifying against
# the pure cacerts passed as argument. Working on this as we speak.
openssl verify -CApath $CACERTS_EXPLODED_DIR $CERTFILE
}
########################
usage () {
echo "Usage: "
echo " $0 -help"
echo " $0 verifycrt <priv_key> <ca_file> <certfile>"
echo " $0 verifycrtkey <priv_key> <certfile>"
echo " $0 verifycrtchain <ca_file> <certfile>"
echo " $0 verifypemformatting <pem_file>"
echo " $0 checkcrtexpiration [-days 30] [service]"
echo " $0 checkcert <cacerts_store_file> <certfile>"
echo " $0 checkhost <cacerts_store_file> <hostname>:<port>"
echo " $0 showcertinfo <certfile>"
echo " $0 showhostcert <hostname>:<port>"
echo " $0 showhostfullcertbundle <hostname>:<port>"
echo " $0 showhostchain <hostname>:<port>"
echo " $0 addcacert <cacerts_store_file> <certfile> [<alias>]"
echo
exit 1;
}
if [ $# = 0 ]; then
usage
fi
ACTION=$1
shift
ACTION_ROOT_DIR=$TEMP
# check for valid usage
if [ x"$ACTION" = "xcheckhost" ]; then
checkhost $@
elif [ x"$ACTION" = "xcheckcert" ]; then
checkcert $@
elif [ x"$ACTION" = "xverifypemformatting" ]; then
verifypemformatting $@
elif [ x"$ACTION" = "xverifycrt" ]; then
verifycrt $@
elif [ x"$ACTION" = "xverifycrtkey" ]; then
verifycrtkey $@
elif [ x"$ACTION" = "xverifycrtchain" ]; then
verifycrtchain $@
elif [ x"$ACTION" = "xshowhostcertfullchain" ]; then
showhostcertfullchain $@
elif [ x"$ACTION" = "xshowhostcert" ]; then
showhostcert $@
elif [ x"$ACTION" = "xshowcertinfo" ]; then
showcertinfo $@
elif [ x"$ACTION" = "xshowhostfullcertbundle" ]; then
showhostfullcertbundle $@
elif [ x"$ACTION" = "xshowhostchain" ]; then
showhostchain $@
elif [ x"$ACTION" = "xcheckcrtexpiration" ]; then
checkCertExpiration $@
elif [ x"$ACTION" = "xaddcacert" ]; then
addCACERT $@
elif [ x"$ACTION" = "x-help" -o x"$ACTION" = "xhelp" -o x"$ACTION" = "x-h" -o x"$ACTION" = "x--help" ]; then
usage
else
usage
fi
exit 0
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment