#!/bin/sh

# 
# Copyright 1999-2006 University of Chicago
# 
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
# 
# http://www.apache.org/licenses/LICENSE-2.0
# 
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# 

#
# globus-cert-info
#
# Easily extract information from a user's cert.
#

prefix="${GLOBUS_LOCATION-@prefix@}"
exec_prefix="@exec_prefix@"
bindir="@bindir@"
sbindir="@sbindir@"
sysconfdir="@sysconfdir@"

PATH=${bindir}:${sbindir}:${PATH}

PROGRAM_NAME=`echo $0 | sed 's|.*/||g'`

PROGRAM_VERSION="@VERSION@"

VERSION="@VERSION@"

PACKAGE="@PACKAGE@"

DIRT_TIMESTAMP="@DIRT_TIMESTAMP@"
DIRT_BRANCH_ID="@DIRT_BRANCH_ID@"

short_usage="$PROGRAM_NAME [-help] [-file certfile] [-all] [-subject] [...]"

long_usage () {
    cat >&2 <<EOF

${short_usage}

    Displays certificate information. Unless the optional -file
    argument is given, the default location of the file containing the
    certficate is assumed:

      -- The location pointed to by the X509_USER_CERT.
      -- If X509_USER_CERT not set, $HOME/.globus/usercert.pem.

    Several options can be given: The output of
        "grid-cert-info -subject -issuer"
    is equivalent to that of
        "grid-cert-info -subject ; grid-cert-info -issuer"

    Options
      -help, -usage                Display usage
      -version                     Display version
      -file certfile     |-f       Use 'certfile' at non-default location
      -rfc2253                     Print X.509 names in RFC-2253 form


    Options determining what to print from certificate

      -all                        Whole certificate
      -subject           |-s      Subject string of the cert
      -issuer            |-i      Issuer of the cert
      -issuerhash        |-ih     Hash of the issuer name 
      -startdate         |-sd     Validity of cert: start date
      -enddate           |-ed     Validity of cert: end date

EOF
}

# See http://www-unix.globus.org/toolkit/docs/4.0/admin/docbook/ch05.html#prewsaa-env-credentials
find_default_credential()
{
    if [ -n "$X509_USER_CERT" ]; then
        echo "$X509_USER_CERT"
    elif [ -r "${HOME}/.globus/usercert.pem" ]; then
        echo "${HOME}/.globus/usercert.pem"
    elif [ -r "${HOME}/.globus/usercred.p12" ]; then
        echo "${HOME}/.globus/usercred.p12"
    else
        echo ""
    fi
}

certificate_format()
{
    testfile="$1"
    _format=''

    if test "$testfile" = ""; then
        :
    elif echo "$certfile" | grep '\.p12$' > /dev/null 2>&1 ; then
        _format=pkcs12
    elif echo "$certfile" | grep '\.pem$' > /dev/null 2>&1 ; then
        _format=x509
    elif grep -- '-----BEGIN' "$testfile" > /dev/null 2>&1 ; then
        _format="x509"
    else
        :
    fi

    echo $_format
}


if ! openssl version > /dev/null 2> /dev/null; then
    echo "Unable to locate openssl binary in PATH" 1>&2
    exit 1
fi

# Default Generated Files
cert_format=x509
openssl_options=""
toprint=""

# set default location of certificate (may be overridden by --file)
#
certfile=`find_default_credential`

globus_args_short_usage()
{
    cat 1>&2 <<EOF

Syntax : ${short_usage}

Use -help to display full usage.

EOF
}

globus_args_option_error()
{
    cat 1>&2 <<EOF

ERROR: option $1 : $2
EOF
    globus_args_short_usage
    exit 1
}

globus_args_unrecognized_option()
{
    globus_args_option_error $1 "unrecognized option"
    exit 1
}

while [ "X$1" != "X" ]; do
    case $1 in
    -help | -h | --help | -usage | --usage)
        long_usage
        exit 0
        ;;
    -version|--version)
        if [ "X${PROGRAM_NAME}" != "X" -a \
              "X${PROGRAM_VERSION}" != "X" ]; then
            echo "${PROGRAM_NAME}: ${PROGRAM_VERSION}"
        elif [ "X${PACKAGE}" != "X" -a \
               "X${VERSION}" != "X" ]; then
            echo "${PACKAGE}: ${VERSION}"
        else
            echo "No version information available."
        fi
        exit 0
        ;;
    -versions|--versions)
        __AT=@
        if [ -n "${PACKAGE}" -a -n "${VERSION}" -a \
             -n "${DIRT_TIMESTAMP}" -a -n "${DIRT_BRANCH_ID}" -a \
             "X${DIRT_TIMESTAMP}" != "X${__AT}DIRT_TIMESTAMP${__AT}" -a \
             "X${DIRT_BRANCH_ID}" != "X${__AT}DIRT_BRANCH_ID${__AT}" ];
        then
            echo "${PACKAGE}: ${VERSION} (${DIRT_TIMESTAMP}-${DIRT_BRANCH_ID})"
        else
            echo "No DiRT information available."
        fi
        exit 0;
        ;;
    -file| -f | --file)
        if [ -n "$2" -a -f "$2" -a -r "$2" ]; then
            certfile=$2
        else
            if [ -n "$2" ]; then 
                globus_args_option_error "$1" "\"$2\" is not a valid filename"
            else
                globus_args_option_error "$1" "needs a file name argument"
            fi
        fi
        shift
        ;;
    -all | -all)
	toprint="$toprint -text"
	;;
    -subject|-s | --subject)
	toprint="$toprint SUBJECT"
	;;
    -issuerhash|-ih | --issuerhash)
	toprint="$toprint -issuer_hash"
	;;
    -issuer|-i | --issuer)
	toprint="$toprint -issuer"
	;;
    -startdate|-sd|--startdate)
	toprint="$toprint -startdate"
	;;
    -enddate|-ed|--enddate)
	toprint="$toprint -enddate"
	;;
    -rfc2253|--rfc2253)
        openssl_options='-nameopt rfc2253'
        ;;
    *)
	globus_args_unrecognized_option "$1"
	;;
    esac
    shift
done

cert_format=`certificate_format "$certfile"`
if test "$cert_format" = ""; then
    echo "Error: Cannot locate certificate" 1>&2
    exit 1;
fi

if [ "X$toprint" = "X" ]; then
    toprint="-text"
fi

if [ ! \( -f "${certfile}" -a -r "${certfile}" \) ]; then
    echo "ERROR: Cannot read certificate file ${certfile}" >&2
    exit 1
fi
 
if [ "$cert_format" = pkcs12 ]; then
    echo "Credentials are in pkcs12 format, OpenSSL will prompt for p12 password"
    cert_data="`openssl pkcs12 -nokeys -clcerts -nomacver -in ${certfile}`"
    command_stub="openssl x509 -noout $openssl_options"
else
    command_stub="openssl x509 -noout -in ${certfile} $openssl_options"
fi


# Will probably need this...
if [ "$cert_format" = pkcs12 ]; then
    subject=`echo "$cert_data" | eval ${command_stub} -subject`
else
    subject=`eval ${command_stub} -subject`
fi

if test $? -ne 0 ; then
    exit 1
fi

subject=`echo ${subject} | sed 's%^subject=\ *%%'`

eval set -- "$toprint"
for i in "$@"; do
    case "$i" in
    -*)
	echo "$cert_data" | eval "{ ${command_stub} $i || exit $?; } | sed 's/^[a-zA-Z]*=[ ]*//'"
	;;
    SUBJECT)
	# Do not show the proxy levels
	echo "${subject}" | sed -e 's%/CN=proxy%%g' -e 's%/CN=limited proxy%%g'
	;;
    esac
done

