#!/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.
# 


printDirections ()
{
  printThis=0
  if [ -f $DIRECTIONS_FILE ] ; then
    while read line || test ! -z "${line}" ; do
      if test -n "`echo $line | grep \"END $1 TEXT\"`" ; then
        break
      fi
      if [ "$printThis" = "1" ]; then
        echo "`eval echo \"$line\"`"
      fi
      if test -n "`echo $line | grep \"BEGIN $1 TEXT\"`" ; then
        printThis=1
      fi
    done < $DIRECTIONS_FILE
  fi

  return $printThis
}

openssl="@OPENSSL@"
prefix="${GLOBUS_LOCATION-@prefix@}"
exec_prefix="@exec_prefix@"
bindir="@bindir@"
sbindir="@sbindir@"
datarootdir="@datarootdir@"
datadir="@datadir@"
sysconfdir="@sysconfdir@"

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

if [ ! -z "${GRID_SECURITY_DIR}" ] ; then
    if [ -r "${GRID_SECURITY_DIR}/globus-user-ssl.conf" ] && 
       [ -r "${GRID_SECURITY_DIR}/globus-host-ssl.conf" ] ; then
        secconfdir="${GRID_SECURITY_DIR}"
        if test ! -z "${X509_CERT_DIR}" ; then
            trusted_certs_dir="${X509_CERT_DIR}"
        elif test "X`echo ${GRID_SECURITY_DIR}| sed 's/\/\//\//'`" \
                = "X`echo ${sysconfdir}|sed 's/\/\//\//'`" ; then
            trusted_certs_dir="${datadir}/certificates"
        elif test -d "${secconfdir}/certificates"; then
            trusted_certs_dir="${secconfdir}/certificates"
        else
            echo "ERROR: Cannot determine trusted certificate directory. Please set X509_CERT_DIR" 1>&2
            exit 1
        fi
    fi
elif [ -r "/etc/grid-security/globus-user-ssl.conf" ] && 
     [ -r "/etc/grid-security/globus-host-ssl.conf" ] ; then
    secconfdir="/etc/grid-security"
    if test ! -z "${X509_CERT_DIR}" ; then
        trusted_certs_dir="${X509_CERT_DIR}"
    else
        trusted_certs_dir="${secconfdir}/certificates"
    fi
elif [ -r "${sysconfdir}/globus-user-ssl.conf" ] &&
     [ -r "${sysconfdir}/globus-host-ssl.conf" ] ; then
    secconfdir="${sysconfdir}"
    if test ! -z "${X509_CERT_DIR}" ; then
        trusted_certs_dir="${X509_CERT_DIR}"
    else
        trusted_certs_dir="${datadir}/certificates"
    fi
else
    secconfdir="/etc/grid-security"
    if test ! -z "${X509_CERT_DIR}" ; then
        trusted_certs_dir="${X509_CERT_DIR}"
    else
        trusted_certs_dir="${secconfdir}/certificates"
    fi

fi

#
# Sample script to generate a certificate request which can be sent 
# to the Globus CA, who will sign it. This script uses the 
# globus-ssl.conf file.
#
# When generating a certificate request and private key for a 
# globus gatekeeper daemon, use the -nopw option, so the
# key is not protected by pass phrase. 
#
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] [ options ...]"


###########################################################
# long_usage
#   Provide usage instructions to the end user
###########################################################

long_usage ()
{
    cat >&2 <<EOF

${short_usage}

  Example Usage:

    Creating a user certifcate:
      grid-cert-request

    Creating a host or gatekeeper certifcate:
      grid-cert-request -host [my.host.fqdn]

    Creating a LDAP server certificate:
      grid-cert-request -service ldap -host [my.host.fqdn]

  Options:
    
    -version           : Display version
    -?, -h, -help,     : Display usage
    -usage 
    -cn <name>,        : Common name of the user
    -commonname <name>
    -service <service> : Create certificate for a service. Requires
                         the -host option and implies that the generated 
                         key will not be password protected (ie implies -nopw).
    -host <FQDN>       : Create certificate for a host named <FQDN>
    -dns <FQDN>,...    : Create certificate with the dNSName extension
    -ip <IP-ADDRESS>,...
                       : Create certificate with the iPAddress extension
    -dir <dir_name>    : Changes the directory the private key and certificate 
                         request will be placed in. By default user 
                         certificates are placed in $HOME/.globus, host 
                         certificates are placed in /etc/grid-security and 
                         service certificates are place in 
                         /etc/grid-security/<service>.
    -prefix <prefix>   : Causes the generated files to be named 
                         <prefix>cert.pem, <prefix>key.pem and
                         <prefix>cert_request.pem
    -nopw,             : Create certificate without a passwd
    -nodes,
    -nopassphrase,
    -verbose           : Don't clear the screen
    -int[eractive]     : Prompt user for each component of the DN
    -force             : Overwrites preexisting certifictes
    -ca                : Will ask which CA is to be used (interactive)
    -ca <hash>         : Will use the CA with hash value <hash>
EOF
}

###########################################################
# set_non_default_ca
#   Change the CA used for generating the certificate
###########################################################

set_non_default_ca() 
{
    if [ "${nondefaultca}" = "true" ]; then

        INSTALLED_CERTS="`echo ${trusted_certs_dir}/*.0`"

        if [ -z "${INSTALLED_CERTS}" ]; then
            echo "No CA's have been installed on this host!"
            echo "To run grid-cert-request, a CA must first"
            echo "be installed"
            exit 1;
        else
            echo
            echo "The available CA configurations installed on this host are:"
            echo
        fi
    
        index=1
        
        for cert in ${trusted_certs_dir}/*.0; do
            if test -r "${cert}" ; then
                eval "CA${index}=${cert}"
                TEMP_SUBJECT=`"$openssl" x509 -in ${cert} -noout -subject -nameopt sep_multiline | sed -e '/^subject=/d' -e 's!^\s*!/!' | tr -d '\n'`
                eval "CA_SUBJECT${index}=\"${TEMP_SUBJECT}\""
                eval "CA_HASH${index}=`"$openssl" x509 -in ${cert} -noout -hash`"
                eval "echo \"$index)  \${CA_HASH${index}} - \${CA_SUBJECT${index}}\""
                index=`expr $index + 1`
            fi
        done
    
        echo
        echo -n "Enter the index number of the CA you want to sign your cert request: "
        read CA_CHOSEN_INDEX
    
        if [ 0 -ge ${CA_CHOSEN_INDEX:-0} ] || [ $index -le ${CA_CHOSEN_INDEX:-0} ] ; then
            echo "${CA_CHOSEN_INDEX} is not a valid index!"
            exit 1
        fi
    
        eval "CA_SUBJECT=\${CA_SUBJECT${CA_CHOSEN_INDEX}}"
        eval "CA_HASH=\${CA_HASH${CA_CHOSEN_INDEX}}"

    elif [ ! -z "${nondefaultca}" ] ; then
        CA_HASH=${nondefaultca}
        if test ! -r "${trusted_certs_dir}/${CA_HASH}.0" ; then
            echo
            echo "Cannot find a CA with hash ${CA_HASH}."
            echo "Use grid-cert-request -ca to pick a CA interactively."
            echo 
            exit 1
        fi
        TEMP_SUBJECT=`"$openssl" x509 -in ${trusted_certs_dir}/${CA_HASH}.0 -noout -subject -nameopt sep_multiline | sed -e '/^subject=/d' -e 's!^\s*!/!' | tr -d '\n'`
        eval "CA_SUBJECT=\"${TEMP_SUBJECT}\""
    fi

    echo
    echo "Using CA: ${CA_HASH} - ${CA_SUBJECT}"
    echo

    SSL_CONFIG=${trusted_certs_dir}/globus-user-ssl.conf.${CA_HASH}
    SSL_USER_CONFIG=${trusted_certs_dir}/globus-user-ssl.conf.${CA_HASH}
    SSL_HOST_CONFIG=${trusted_certs_dir}/globus-host-ssl.conf.${CA_HASH}
    DIRECTIONS_FILE=${trusted_certs_dir}/directions.${CA_HASH}
    security_conf=${trusted_certs_dir}/grid-security.conf.${CA_HASH}
}


###########################################################
# abort_cleanup
#   Remove temp files generated by this script
###########################################################

abort_cleanup () 
{
    rm -f ${CERT_FILE} ${KEY_FILE} \
                          ${REQUEST_FILE} ${RAND_TEMP} \
                          ${REQ_HEAD} ${REQ_INPUT} ${REQ_OUTPUT} ${REQ_CONF}
}


###########################################################
# absolute_path
#    Make these absolute file names if they are not
###########################################################

absolute_path () 
{
   _file_name="$1"

   case $_file_name in
      /*)
        echo ${_file_name}
        ;;
      *)
        echo ${PWD}/${_file_name}
    esac
}


###########################################################
# read_command_line
#   Command line parsing
###########################################################
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
}

read_command_line () 
{
    # Expects $* from the shell invocation

    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;
                ;;
            -cn | -commonname | --commonname)
                COMMON_NAME="$2"
                shift ; shift
                ;;
            -host | --host)
                SERVICE_HOST="$2"
                SERVICE_HOST=`echo ${SERVICE_HOST}|tr 'A-Z' 'a-z'`
                if echo ${SERVICE_HOST}|grep "localhost" >/dev/null || \
                   echo ${SERVICE_HOST}|grep "localdomain" >/dev/null; then
                    globus_args_option_error "$1" "$2 may not contain localhost or localdomain"
                fi
                NO_DES="-nodes"
                shift ; shift
                ;;
            -dns | --dns)
                DNS_NAME_EXTENSIONS="$2"
                shift; shift;
                ;;
            -ip | --ip)
                IP_ADDRESS_EXTENSIONS="$2"
                shift; shift;
                ;;
            -service | --service)
                SERVICE="$2"
                SERVICE=`echo ${SERVICE}|tr 'A-Z' 'a-z'`
                shift ; shift
                ;;
            -dir | --dir)
                TARGET_DIR="$2"
                TARGET_DIR="`absolute_path ${TARGET_DIR}`"
                shift ; shift
                ;;
            -prefix | --prefix)
                PREFIX="$2"
                shift ; shift
                ;;
            -nopw|-nodes|-nopassphrase | --nopw | --nodes | --nopassphrase)
                NO_DES="-nodes"
                shift
                ;;
            -verbose | --verbose)
                VERBOSE="yes"
                shift
                ;;
            -int|-interactive | --int | --interactive)
                INTERACTIVE="TRUE"
                shift
                ;;
            -force | --force)
                FORCE="TRUE"
                shift
                ;;
            -ca | --ca)
                if [ ! -z "$2" ] && \
                   [ -z "`echo $2 | sed -e \"s|[^-]*||g\"`" ]
                then
                    nondefaultca=$2
                    shift
                else
                    echo "nondefaultca=true"
                    nondefaultca="true"
                fi
                set_non_default_ca
                shift
                ;;
            *)
                globus_args_unrecognized_option "$1"
                ;;
        esac
    done

    if test -z "${SERVICE}"; then 
        if test -z "${SERVICE_HOST}"; then
            SERVICE="user"
        else
            SERVICE="host"
        fi
    else
        if test -z "${SERVICE_HOST}"; then
            globus_args_option_error "-service" "Requires thes -host option"
        fi
    fi

    if test -z "${TARGET_DIR}"; then
        case ${SERVICE} in
            user)
                TARGET_DIR="$HOME/.globus"
                ;;
            host)
                TARGET_DIR="${secconfdir}"
                ;;
            *)
                TARGET_DIR="${secconfdir}/${SERVICE}"
                ;;
        esac
    fi

    if test -z "${PREFIX}"; then
        REQUEST_FILE="${TARGET_DIR}/${SERVICE}cert_request.pem"
        CERT_FILE="${TARGET_DIR}/${SERVICE}cert.pem"
        KEY_FILE="${TARGET_DIR}/${SERVICE}key.pem"
    else
        REQUEST_FILE="${TARGET_DIR}/${PREFIX}cert_request.pem"
        CERT_FILE="${TARGET_DIR}/${PREFIX}cert.pem"
        KEY_FILE="${TARGET_DIR}/${PREFIX}key.pem"
    fi
}



###########################################################
# create_input_file
#   Generate a inputfile to be given to SSL that fully 
#   specifies the DN of the user
#   files
###########################################################

create_input_file () 
{
    _common_name="$1"
    _config_file="$2"

    # Parse the ssleay configuration file, to determine the
    # correct default parameters

    awk  < $_config_file '
 
  /^\[ req_distinguished_name \]/ {
     start_parsing=1;
     next;
  }

  /^\[ .*/ {
     start_parsing=0;
     next;
  }

  /^[a-zA-Z0-9\.]*_default[ \t]*=/ && start_parsing==1 {
     split($0, a, "=");
     # default value is in a[2], but we should strip of leading ws
     for(i=1;substr(a[2],i,1) == " " || substr(a[2],i,1) == "\t"; i++);
     print substr(a[2], i);
     next;
}
'

    echo ${_common_name}
}


create_subjectAltName()
{
    _dns_extensions=""
    _ip_extensions=""

    if [ -n "$DNS_NAME_EXTENSIONS" ]; then
        _dns_extensions="`echo \"$DNS_NAME_EXTENSIONS\" | sed -e 's/^/DNS:/' -e 's/,/,DNS:/g'`"
    fi
    if [ -n "$IP_ADDRESS_EXTENSIONS" ]; then
        _ip_extensions="`echo \"$IP_ADDRESS_EXTENSIONS\" | sed -e 's/^/IP:/' -e 's/,/,IP:/g'`"
    fi

    if [ -n "$_dns_extensions" -a -n "$_ip_extensions" ]; then
        echo "subjectAltName=$_dns_extensions,$_ip_extensions"
    elif [ -n "$_dns_extensions" ]; then
        echo "subjectAltName=$_dns_extensions"
    else
        echo "subjectAltName=$_ip_extensions"
    fi
}

create_conf_file ()
{
    _config_file="$1"

    # Add $DNS_NAME_EXTENSIONS and $IP_ADDRESS_EXTENSIONS to the v3_req section
    while read line; do
        echo "$line"

        if echo "$line" | grep '\[ v3_req \]' > /dev/null 2>&1 ; then
            create_subjectAltName
        fi
    done < $_config_file
}

###########################################################
# create_request_header
###########################################################

create_request_header () 
{
  if printDirections "REQUEST HEADER" ; then
    cat <<EOF
This is a Certificate Request file:

It should be mailed to ${GSI_CA_EMAIL_ADDR}


=========================================================================
Certificate Subject:

    ${SUBJECT}

The above string is known as your ${SERVICE} certificate subject, and it
uniquely identifies this ${SERVICE}.

To install this ${SERVICE} certificate, please save this e-mail message
into the following file.


${CERT_FILE}


      You need not edit this message in any way. Simply
      save this e-mail message to the file.



If you have any questions about the certificate contact
the ${GSI_CA_NAME} at ${GSI_CA_EMAIL_ADDR}

EOF
  fi
}

###########################################################
# check4certs:  
#   Ensure that the user does not overwrite their
#   security files.
###########################################################
check4certs () 
{
    _exists="FALSE"

    if [ -r ${REQUEST_FILE} ] ; then
        printf "\n    ${REQUEST_FILE} already exists" 1>&2
        chmod u+w ${REQUEST_FILE}
        _exists=TRUE
    fi
    
    if [ -r ${CERT_FILE} ] ; then
        printf "\n    ${CERT_FILE} already exists" 1>&2
        chmod u+w ${CERT_FILE}
        _exists=TRUE
    fi
    
    if [ -r ${KEY_FILE} ] ; then
        printf "\n    ${KEY_FILE} already exists" 1>&2
        chmod u+w ${KEY_FILE}
        _exists=TRUE
    fi

  
    if [ "X$_exists" = "XTRUE" ] ; then
        if [ "X$FORCE" = "XTRUE" ] ; then
            rm -f ${CERT_FILE} ${KEY_FILE} ${REQUEST_FILE}
            echo
            echo
        else 
            printf "\n\nIf you wish to overwrite, run the script again with -force.\n" 1>&2
            exit 1
        fi
    fi
}


###########################################################
# setup_target_dir:  
#   Create a directory in the HOME directory of the user
#   to store globus related stuff.
###########################################################

setup_target_dir () 
{
    if test ! -d ${TARGET_DIR} ; then
        mkdir ${TARGET_DIR}
        if [ $? -ne 0 ] ; then
            printf "\n\nUnable to create ${TARGET_DIR}. Please make sure that you have the right to create this directory before running this script.\n" 1>&2
            exit $?
        fi 
    fi

    if test ! -w ${TARGET_DIR} ; then
        printf "\n\nUnable to access ${TARGET_DIR}. Please make sure that you have the right to create files in this directory before running this script.\n" 1>&2
        exit 1
    fi
}


###########################################################
# get_user_CN
#   Determine the name of the user
###########################################################
get_user_CN () 
{
    _common_name="${COMMON_NAME}"

    # 1. Command line argument
    # 2. Query the system
    # 3. Prompt the user

    if [ -z "${_common_name}" ] ; then 
        finger -lm ${USERID}  >/dev/null 2>&1
        if [ $? -eq 0 ] ; then 
            _common_name="`finger -lm ${USERID}      |\
                           grep ${USERID}              |\
                           awk -F: '{ print $3; exit }' |\
                           cut -c2- `"
        fi
    fi

   if [ -z "${_common_name}" ] || [ "${_common_name}" = "(null)" ];  then
      printf "Enter your name, e.g., John Smith: " 1>&2
      read _common_name
   fi

   echo ${_common_name}
}



###########################################################
# get_host_CN
#   Determine the name of the host for a host certificate
###########################################################

get_host_CN () 
{
   _common_name="${COMMON_NAME}"

   # 1. Command line -cn argument
   # 2. Create from -host argument

   if [ -z "${_common_name}" ] ; then 
        # Check SERVICE_HOST and make sure it looks like a FQDN
        echo ${SERVICE_HOST} | \
            grep "\." >/dev/null 2>&1
        if [ $? -eq 1 ] ; then
            echo "The hostname ${SERVICE_HOST} does not appear to be fully qualified." 1>&2
            printf "Do you wish to continue? [n] " 1>&2
            read _response

            case X${_response} in
                Xy|XY|Xyes|XYES|XYes)
                    ;;

                *)
                    echo "Aborting" 1>&2
                    return 1
                    ;;
            esac
        fi
      
        _common_name="${SERVICE}/${SERVICE_HOST}"
    fi

    echo ${_common_name}
    return 0
}



###########################################################
# create_certs
#   Create the certificate, key, and certificate request
#   files
###########################################################
create_certs () {
  
    if [ -z "${NO_DES}" ] ; then
        echo "A certificate request and private key is being created."
        echo "You will be asked to enter a PEM pass phrase."
        echo "This pass phrase is akin to your account password, "
        echo "and is used to protect your key file."
        echo "If you forget your pass phrase, you will need to"
        echo "obtain a new certificate."
        echo
    fi

    #------------------------
    # Create the Certificate File
    umask 022
    touch ${CERT_FILE}


    #------------------------
    # Create some semi random data for key generation 
    umask 066
    touch ${RAND_TEMP}
    if [ -r /dev/urandom ] ; then
        head -1000 /dev/urandom >> ${RAND_TEMP} 2>&1
    fi
    date >> ${RAND_TEMP} 2>&1
    netstat -in >> ${RAND_TEMP} 2>&1
    ps -ef >> ${RAND_TEMP} 2>&1
    ls -ln ${HOME} >> ${RAND_TEMP} 2>&1
    ls -ln /tmp >> ${RAND_TEMP} 2>&1

    umask 266
    #------------------------
    # Create the Key and Request Files

    if test "${SERVICE}" = "user" ; then
        used_config="${SSL_USER_CONFIG}"
    elif [ -z "$DNS_NAME_EXTENSIONS" -a -z "$IP_ADDRESS_EXTENSIONS" ]; then
        used_config="${SSL_HOST_CONFIG}"
    else
        used_config="${REQ_CONF}"
        create_conf_file "${SSL_HOST_CONFIG}" > "${REQ_CONF}"
    fi

    if test ! -z "${INTERACTIVE}" ; then
        "$openssl" req -new -keyout ${KEY_FILE} -out ${REQ_OUTPUT} \
            -rand ${RAND_TEMP}:/var/adm/wtmp:/var/log/messages \
            -config ${used_config} ${NO_DES}
        RET=$?
        rm -f ${RAND_TEMP}
    else
        create_input_file "${COMMON_NAME}" "${used_config}" > ${REQ_INPUT}

        "$openssl" req -new -keyout ${KEY_FILE} \
              -rand ${RAND_TEMP}:/var/adm/wtmp:/var/log/messages \
              -out ${REQ_OUTPUT} -config ${used_config} \
              ${NO_DES} < ${REQ_INPUT} 
        RET=$?

        rm -f ${RAND_TEMP}
        rm -f ${REQ_INPUT}

        # You can't separate the SSL output, it all goes to stderr
        # including the prompts.
        # Don't remove ssleay output on error as it may be useful
        
        if test ${RET} -eq 0 -a -z "${VERBOSE}" ; then
            clear
        fi
    fi

    if [ ${RET} -ne 0 ] ; then
        echo "Error number ${RET} was returned by " 1>&2
        echo "   $openssl"                    1>&2
        exit ${RET}
    fi

    umask 022
    
    #------------------------
    # Insert instructions into the request file

    SUBJECT=`"$openssl" req -in ${REQ_OUTPUT} -noout -subject -nameopt sep_multiline | sed -e '/^subject=/d' -e 's!^\s*!/!' | tr -d '\n'`

    create_request_header >${REQ_HEAD}

    # Finalize the Request file.
    cat ${REQ_HEAD} ${REQ_OUTPUT} >${REQUEST_FILE}
    rm -f ${REQ_HEAD} ${REQ_OUTPUT} ${REQ_CONF}
}

###########################################################
# emit_directions
#   Provide instructions to the end user
###########################################################
emit_directions () {

  if test "${SERVICE}" = "user" ; then
    if printDirections "USER INSTRUCTIONS" ; then
      echo 
      echo "A private key and a certificate request has been generated with the subject:" 
 
      echo 
      echo "${SUBJECT}"
      echo
      echo "If the CN=${COMMON_NAME} is not appropriate, rerun this"
      echo "script with the -force -cn \"Common Name\" options."
      echo
      echo "Your private key is stored in ${KEY_FILE}"
      echo "Your request is stored in ${REQUEST_FILE}"
      echo
      echo "Please e-mail the request to the ${GSI_CA_NAME} ${GSI_CA_EMAIL_ADDR}"
      echo "You may use a command similar to the following:" 
      echo
      echo "  cat ${REQUEST_FILE} | mail ${GSI_CA_EMAIL_ADDR}"
      echo
      echo "Only use the above if this machine can send AND receive e-mail. if not, please"
      echo "mail using some other method."
      echo
      echo "Your certificate will be mailed to you within two working days."
      echo "If you receive no response, contact ${GSI_CA_NAME} at ${GSI_CA_EMAIL_ADDR}"
    fi

  else 
    if printDirections "NONUSER INSTRUCTIONS" ; then
      echo 
      echo "A private ${SERVICE} key and a certificate request has been generated"
      echo "with the subject:" 
      echo 
      echo "${SUBJECT}"
      echo
      echo "----------------------------------------------------------"
      echo
      echo "The private key is stored in ${KEY_FILE}"
      echo "The request is stored in ${REQUEST_FILE}"
      echo
      echo "Please e-mail the request to the ${GSI_CA_NAME} ${GSI_CA_EMAIL_ADDR}"
      echo "You may use a command similar to the following:"
      echo
      echo " cat ${REQUEST_FILE} | mail ${GSI_CA_EMAIL_ADDR}"
      echo
      echo "Only use the above if this machine can send AND receive e-mail. if not, please"
      echo "mail using some other method."
      echo
      echo "Your certificate will be mailed to you within two working days."
      echo "If you receive no response, contact ${GSI_CA_NAME} at ${GSI_CA_EMAIL_ADDR}"
    fi
  fi

}


###########################################################
# MAIN
###########################################################


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

SSL_CONFIG="${secconfdir}/globus-user-ssl.conf"
SSL_USER_CONFIG="${secconfdir}/globus-user-ssl.conf"
SSL_HOST_CONFIG="${secconfdir}/globus-host-ssl.conf"
DIRECTIONS_FILE="${secconfdir}/directions"
security_conf="${secconfdir}/grid-security.conf"

# Info sent with the certificate
SUBJECT=
USERID="`whoami`"
if command -v globus-hostname > /dev/null; then
    HOST="`globus-hostname`"
elif command -v hostname > /dev/null; then
    HOST=`hostname`
elif command -v uname > /dev/null; then
    HOST=`uname -n`
else
    HOST=""
fi

SERVICE=
SERVICE_HOST=
INTERACTIVE=
NO_DES=
TARGET_DIR=
CERT_FILE=
KEY_FILE=
REQUEST_FILE=

CERTREQ="grid-cert-request"

# Parse the command line

read_command_line "$@"

if test -z "$trusted_certs_dir"; then
    if test -n "$GRID_SECURITY_DIR"; then
        echo "Can't find valid CA config files in " \
             "GRID_SECURITY_DIR \"${GRID_SECURITY_DIR}\"." 
        echo "Please make sure that you have installed and " \
             "setup a CA setup package."
    else
        echo "Error reading"
        echo "    /etc/grid-security/globus-user-ssl.conf"
        echo "    /etc/grid-security/globus-host-ssl.conf"
        echo "    ${sysconfdir}/globus-user-ssl.conf"
        echo "    ${sysconfdir}/globus-host-ssl.conf"
        echo ""
        echo "Can't find valid CA config files."
        echo "Not all CAs use this tool to generate certificate requests."
        echo "If your CA is using this tool, make sure that you have installed"
        echo "your CA's setup package."
        echo "If your CA is not using this tool, consult the CA documentation"
        echo "to find the right way to request a certificate."
    fi

    echo ""
    exit 1   
fi

# set temporary files
REQ_HEAD=${TARGET_DIR}/$PROGRAM_NAME.$$.head
REQ_INPUT=${TARGET_DIR}/$PROGRAM_NAME.$$.input
REQ_OUTPUT=${TARGET_DIR}/$PROGRAM_NAME.$$.output
RAND_TEMP=${TARGET_DIR}/$PROGRAM_NAME.$$.random
REQ_CONF="${TARGET_DIR}/$PROGRAM_NAME.$$.conf"

# Source the security.conf file
. ${security_conf}

# Check the target directory
setup_target_dir

# Check for preexisting credential files
check4certs

# Derive the Common Name
if test "${SERVICE}" = "user"; then
    COMMON_NAME="`get_user_CN`"
else
    COMMON_NAME="`get_host_CN`"
    if [ $? -ne 0 ]; then
        exit 1
    fi
fi

# do clean up on abort

trap abort_cleanup 1 2 3 6 9 13 15

# create the certificate request and private key
create_certs

RET=$?

COMMON_NAME="`echo ${SUBJECT} | sed -e 's|^.*/CN=||'`"

# print directions to screen
emit_directions ${SERVICE}

exit ${RET}
