#!/bin/sh # $Name: v1_6_1 $ # $Id: edg-fetch-crl.in,v 1.7 2003/04/11 08:10:39 fabio Exp $ ############################################################################### # File: edg-fetch-crl # # # # Version: 1.7 # # # # Description: this script is useful to download and install a set of # # certificate revocation lists (CRL) published by the # # Certification Authorities supported by the DataGRID project. # # Each CRL file is downloaded, appropiately named and copied to # # the specified directory so that Globus can find it. # # # # Usage: edg-fetch-crl [-h|--help] # # edg-fetch-crl [-l|--loc locationDirectory] # # [-o|--out outputDirectory] [-q|--quiet] # # # # Author: Fabio Hernandez # # fabio@in2p3.fr # # IN2P3 Computer Center # # http://www.in2p3.fr/CC # # Lyon (FRANCE) # # # # Date: Aug 2001 # # Dec 2002 - fix problem with openssl # # Apr 2003 - add support for EDG v2.0-style config files # # # ############################################################################### #-----------------------------------------------------------------------------# # I N I T I A L I Z A T I O N # #-----------------------------------------------------------------------------# # # Needed commands: it is useful to specify the full path of the needed commands here # in order to be able to run this script within te context of a user whitout the # PATH environment varible initialized (e.g. cron, root, ...) # openssl=/usr/bin/openssl lynx=/usr/bin/lynx wget=/usr/bin/wget basename=/bin/basename getopt=/usr/bin/getopt awk=/bin/awk cat=/bin/cat cp=/bin/cp chmod=/bin/chmod chown=/bin/chown chgrp=/bin/chgrp mv=/bin/mv rm=/bin/rm id=/usr/bin/id ls=/bin/ls date=/bin/date sed=/bin/sed grep=/bin/grep # # Global variables # programName=`${basename} $0` tempDir="/tmp" # temporary directory verboseMode=1 # enable message display outputDirectory=`pwd` # default output directory is current directory crlLocationFileSuffix="crl_url" # this script will look for files with this extension #-----------------------------------------------------------------------------# # R O U T I N E S # #-----------------------------------------------------------------------------# # # RetrieveFileByURL - downloads a file given a URL and writes its contents to the # file pointed to by the ${tempFile} variable. You can use # replace the call to lynx by wget if you prefer. # Returns 0 if the specified URL can be donwloaded and stored # in a file # RetrieveFileByURL() { url=$1 destinationFile=$2 # # If you don't have 'wget' installed on your machine or you prefer use 'lynx' instead, # uncomment next line and comment the following one. # # ${lynx} -source ${url} > ${destinationFile} # ${wget} -q -t 3 -T 30 -O ${destinationFile} ${url} return $? } # # ShowUsage - show this program usage # ShowUsage() { echo echo "Usage:" ${programName} "[-h|--help]" echo " " ${programName} "[-l|--loc ]" echo " [-o|--out ] [-q|--quiet]" echo echo " Options:" echo echo " -h|--help show this help" echo echo " -l|--loc " echo " The script will search this directory for files with the" echo " suffix '.${crlLocationFileSuffix}'. It is supposed that each one of these" echo " files contains the URL of a Certificate Revocation List (CRL)" echo " for a Certification Authority. This URL is of the form " echo " http://www.myhost.com/myCRL." echo " Note: the CRL files to download must be in either PEM or" echo " DER format." echo " For validity checking of the CA certificates, this script" echo " assumes that the certificates of the CAs are found also" echo " in this directory." echo " Default: output directory (see below)" echo echo " -o|--out " echo " directory where to put the downloaded and processed CRLs." echo " The directory to be used as argument for this option" echo " is typically /etc/grid-security/certificates" echo " Default: current working directory" echo echo " -q|--quiet" echo " Quiet mode (do not print information messages)" echo } # # Print information message # PrintMessage() { if [ ${verboseMode} -eq 0 ]; then return fi timeStamp=`${date} +%Y/%m/%d-%H:%M:%S` echo ${programName}": ["${timeStamp}"]" $* } # # Print error message # PrintError() { timeStamp=`${date} +%Y/%m/%d-%H:%M:%S` echo ${programName}": ["${timeStamp}"]" $* 1>&2 } # # ProcessCRLFile # ProcessCRLFile() { downloadedFile=$1 # # Compute hash value to build the CRL file name # pemFile=${tempDir}/$$.pem conversionSucceeded="no" supportedFormats="PEM DER" for format in ${supportedFormats}; do crlHashValue=`${openssl} crl -hash -inform ${format} -in ${downloadedFile} \ -out ${pemFile} -text 2>/dev/null | ${awk} '{print $1}'` if [ "X"${crlHashValue} != "X" ]; then conversionSucceeded="yes" break fi done ${rm} -f ${downloadedFile} 2>/dev/null if [ ${conversionSucceeded} = "no" ]; then return 1 fi # # Rename the converted CRL file # result=${tempDir}/${crlHashValue}.r0.tmp ${mv} ${pemFile} ${result} # # We are done # return 0 } #-----------------------------------------------------------------------------# # M A I N # #-----------------------------------------------------------------------------# # # Parse the command line # getoptResult=`${getopt} -o hl:o:q -a -l help,loc:,out:,quiet -n ${programName} -- "$@"` if [ $? != 0 ] ; then ShowUsage exit 1 fi eval set -- "${getoptResult}" while true ; do case "$1" in -h|--help) helpRequested="true" ; shift ;; -l|--loc) locationDirectory=$2; shift 2 ;; -o|--out) outputDirectory=$2; shift 2 ;; -q|--quiet) verboseMode=0; shift ;; --) shift; break;; *) echo ${programName}": internal error!" ; exit 1 ;; esac done # # Are there extra arguments? # if [ $1 ]; then echo ${programName}": unexpected argument '"$1"'" ShowUsage exit 1 fi # # Did the user request help? # if [ "X${helpRequested}" = "Xtrue" ]; then ShowUsage exit 0 fi # # Make sure that we can write to the specified output directory # if [ ! -d ${outputDirectory} -o ! -w ${outputDirectory} ]; then PrintError "'"${outputDirectory}"' is not a directory or cannot be written" exit 1 fi # # Look for the Globus configuration file and extract the root of the Globus installation and the # path of the configuration file # globusSysconfigFile="/etc/sysconfig/globus" if [ -r ${globusSysconfigFile} ]; then globusLocation=`${grep} -i "^[[:space:]]*GLOBUS_LOCATION" ${globusSysconfigFile} | ${sed} "s/^[[:space:]]*//g" | ${awk} -F'=' '{print $2}' | ${sed} "s/[[:space:]]*//g"` if [ "X${globusLocation}" != "X" ]; then GLOBUS_LOCATION=${globusLocation} fi globusConfigurationFile=`${grep} -i "^[[:space:]]*GLOBUS_CONFIG" ${globusSysconfigFile} | ${sed} "s/^[[:space:]]*//g" | ${awk} -F'=' '{print $2}' | ${sed} "s/[[:space:]]*//g"` fi # # Make sure the location directory exists # if [ "X${locationDirectory}" = "X" ]; then # # Location directory is not supplied. Let's try to find where it may be. # Look into the Globus configuration file for extracting the directory where # the certificates are located. # if [ "X${globusConfigurationFile}" = "X" ]; then globusConfigurationFile="/etc/globus.conf" fi if [ -r ${globusConfigurationFile} ]; then certDir=`${grep} "^[ ]*X509_CERT_DIR" ${globusConfigurationFile} | ${sed} "s/^[[:space:]]*//g" | ${awk} -F'=' '{print $2}' | ${sed} "s/[[:space:]]*//g"` if [ "X${certDir}" != "X" ]; then if [ -d ${certDir} ]; then locationDirectory=${certDir} fi fi fi fi if [ "X${locationDirectory}" = "X" ]; then locationDirectory=${outputDirectory} fi if [ ! -d ${locationDirectory} ]; then PrintError "'"${locationDirectory}"' is not a directory or cannot be read" exit 1 fi # # This script needs "openssl", which can be installed within the Globus # hierarchy or elsewhere. Let's try to find it. # if [ ! -z "${GLOBUS_LOCATION}" ]; then if [ -x ${GLOBUS_LOCATION}/bin/openssl ]; then openssl=${GLOBUS_LOCATION}/bin/openssl fi fi if [ ! -x "${openssl}" ]; then PrintError "openssl not found - define GLOBUS_LOCATION or create '${globusConfigFile}'" exit 1 fi # # Initialize the group name for the 'globus' user # # # Look for CRL location files with the expected suffix # locationFiles=`${ls} ${locationDirectory}/*.${crlLocationFileSuffix} 2>/dev/null` if [ "X${locationFiles}" = "X" ]; then PrintError "no files with suffix '."${crlLocationFileSuffix}"' found in '"${locationDirectory}"'" exit 1 fi # # Process each one of the CRL location files # for nextLocationFile in ${locationFiles}; do PrintMessage "processing location file '"${nextLocationFile}"'" ${cat} ${nextLocationFile} | while true ; do # # Extract the next URL from this CRL location file # read nextLine if [ $? != 0 ]; then break fi nextURL=`echo ${nextLine} | ${awk} -F'#' '{print $1}'` if [ -z ${nextURL} ]; then # This is a comment or a blank line, skip it continue fi # # Download this CRL # tempFile=${tempDir}/crl-dg.$$ RetrieveFileByURL ${nextURL} ${tempFile} if [ $? != 0 ]; then PrintError "could not download a valid file from '"${nextURL}"'" ${rm} -f ${tempFile} continue fi # # Process and rename the downloaded file # ProcessCRLFile ${tempFile} if [ $? != 0 ]; then continue fi crlFile=${result} # # Verify this CRL # issuer=`${openssl} crl -inform "PEM" -in ${crlFile} -issuer -noout | ${awk} '{print $2}'` verifyResult=`${openssl} crl -CApath ${locationDirectory} -in ${crlFile} -noout 2>&1` if [ "X${verifyResult}" != "Xverify OK" ]; then PrintError "verify failed for CRL issued by '"${issuer}"' (${verifyResult})" ${rm} -f ${crlFile} 2>/dev/null continue fi # # Move the temporary file to the output directory and set the appropriate file # permissions and ownership # PrintMessage "updating CRL issued by '"${issuer}"'" ${chmod} 0644 ${crlFile} finalCrlFileName=`${basename} ${crlFile} ".tmp"` ${mv} ${crlFile} ${outputDirectory}/${finalCrlFileName} > /dev/null 2>&1 # # Check the validity of the CA certificate # caCertificate=`${basename} ${finalCrlFileName} ".r0"`".0" verifyResult=`${openssl} verify -CApath ${locationDirectory} ${locationDirectory}/${caCertificate} 2>&1 | ${awk} '{print $2}'` if [ "X${verifyResult}" != "XOK" ]; then PrintError "verify failed for CA certificate issued by '"${issuer}"' (${verifyResult})" fi done # while done # for # # Done # exit 0