You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							210 lines
						
					
					
						
							4.1 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							210 lines
						
					
					
						
							4.1 KiB
						
					
					
				
								#!/bin/sh
							 | 
						|
								#
							 | 
						|
								# Ben Secrest <blsecres@gmail.com>
							 | 
						|
								#
							 | 
						|
								# sh c_rehash script, scan all files in a directory
							 | 
						|
								# and add symbolic links to their hash values.
							 | 
						|
								#
							 | 
						|
								# based on the c_rehash perl script distributed with openssl
							 | 
						|
								#
							 | 
						|
								# LICENSE: See OpenSSL license
							 | 
						|
								# ^^acceptable?^^
							 | 
						|
								#
							 | 
						|
								
							 | 
						|
								# default certificate location
							 | 
						|
								DIR=/etc/ssl
							 | 
						|
								
							 | 
						|
								# for filetype bitfield
							 | 
						|
								IS_CERT=$(( 1 << 0 ))
							 | 
						|
								IS_CRL=$(( 1 << 1 ))
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								# check to see if a file is a certificate file or a CRL file
							 | 
						|
								# arguments:
							 | 
						|
								#       1. the filename to be scanned
							 | 
						|
								# returns:
							 | 
						|
								#       bitfield of file type; uses ${IS_CERT} and ${IS_CRL}
							 | 
						|
								#
							 | 
						|
								check_file()
							 | 
						|
								{
							 | 
						|
								    local IS_TYPE=0
							 | 
						|
								
							 | 
						|
								    # make IFS a newline so we can process grep output line by line
							 | 
						|
								    local OLDIFS=${IFS}
							 | 
						|
								    IFS=$( printf "\n" )
							 | 
						|
								
							 | 
						|
								    # XXX: could be more efficient to have two 'grep -m' but is -m portable?
							 | 
						|
								    for LINE in $( grep '^-----BEGIN .*-----' ${1} )
							 | 
						|
								    do
							 | 
						|
									if echo ${LINE} \
							 | 
						|
									    | grep -q -E '^-----BEGIN (X509 |TRUSTED )?CERTIFICATE-----'
							 | 
						|
									then
							 | 
						|
									    IS_TYPE=$(( ${IS_TYPE} | ${IS_CERT} ))
							 | 
						|
								
							 | 
						|
									    if [ $(( ${IS_TYPE} & ${IS_CRL} )) -ne 0 ]
							 | 
						|
									    then
							 | 
						|
									    	break
							 | 
						|
									    fi
							 | 
						|
									elif echo ${LINE} | grep -q '^-----BEGIN X509 CRL-----'
							 | 
						|
									then
							 | 
						|
									    IS_TYPE=$(( ${IS_TYPE} | ${IS_CRL} ))
							 | 
						|
								
							 | 
						|
									    if [ $(( ${IS_TYPE} & ${IS_CERT} )) -ne 0 ]
							 | 
						|
									    then
							 | 
						|
									    	break
							 | 
						|
									    fi
							 | 
						|
									fi
							 | 
						|
								    done
							 | 
						|
								
							 | 
						|
								    # restore IFS
							 | 
						|
								    IFS=${OLDIFS}
							 | 
						|
								
							 | 
						|
								    return ${IS_TYPE}
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								#
							 | 
						|
								# use openssl to fingerprint a file
							 | 
						|
								#    arguments:
							 | 
						|
								#	1. the filename to fingerprint
							 | 
						|
								#	2. the method to use (x509, crl)
							 | 
						|
								#    returns:
							 | 
						|
								#	none
							 | 
						|
								#    assumptions:
							 | 
						|
								#	user will capture output from last stage of pipeline
							 | 
						|
								#
							 | 
						|
								fingerprint()
							 | 
						|
								{
							 | 
						|
								    ${SSL_CMD} ${2} -fingerprint -noout -in ${1} | sed 's/^.*=//' | tr -d ':'
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								#
							 | 
						|
								# link_hash - create links to certificate files
							 | 
						|
								#    arguments:
							 | 
						|
								#       1. the filename to create a link for
							 | 
						|
								#	2. the type of certificate being linked (x509, crl)
							 | 
						|
								#    returns:
							 | 
						|
								#	0 on success, 1 otherwise
							 | 
						|
								#
							 | 
						|
								link_hash()
							 | 
						|
								{
							 | 
						|
								    local FINGERPRINT=$( fingerprint ${1} ${2} )
							 | 
						|
								    local HASH=$( ${SSL_CMD} ${2} -hash -noout -in ${1} )
							 | 
						|
								    local SUFFIX=0
							 | 
						|
								    local LINKFILE=''
							 | 
						|
								    local TAG=''
							 | 
						|
								
							 | 
						|
								    if [ ${2} = "crl" ]
							 | 
						|
								    then
							 | 
						|
								    	TAG='r'
							 | 
						|
								    fi
							 | 
						|
								
							 | 
						|
								    LINKFILE=${HASH}.${TAG}${SUFFIX}
							 | 
						|
								
							 | 
						|
								    while [ -f ${LINKFILE} ]
							 | 
						|
								    do
							 | 
						|
									if [ ${FINGERPRINT} = $( fingerprint ${LINKFILE} ${2} ) ]
							 | 
						|
									then
							 | 
						|
									    echo "WARNING: Skipping duplicate file ${1}" >&2
							 | 
						|
									    return 1
							 | 
						|
									fi	
							 | 
						|
								
							 | 
						|
									SUFFIX=$(( ${SUFFIX} + 1 ))
							 | 
						|
									LINKFILE=${HASH}.${TAG}${SUFFIX}
							 | 
						|
								    done
							 | 
						|
								
							 | 
						|
								    echo "${1} => ${LINKFILE}"
							 | 
						|
								
							 | 
						|
								    # assume any system with a POSIX shell will either support symlinks or
							 | 
						|
								    # do something to handle this gracefully
							 | 
						|
								    ln -s ${1} ${LINKFILE}
							 | 
						|
								
							 | 
						|
								    return 0
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								# hash_dir create hash links in a given directory
							 | 
						|
								hash_dir()
							 | 
						|
								{
							 | 
						|
								    echo "Doing ${1}"
							 | 
						|
								
							 | 
						|
								    cd ${1}
							 | 
						|
								
							 | 
						|
								    ls -1 * 2>/dev/null | while read FILE
							 | 
						|
								    do
							 | 
						|
								        if echo ${FILE} | grep -q -E '^[[:xdigit:]]{8}\.r?[[:digit:]]+$' \
							 | 
						|
									    	&& [ -h "${FILE}" ]
							 | 
						|
								        then
							 | 
						|
								            rm ${FILE}
							 | 
						|
								        fi
							 | 
						|
								    done
							 | 
						|
								
							 | 
						|
								    ls -1 *.pem *.cer *.crt *.crl 2>/dev/null | while read FILE
							 | 
						|
								    do
							 | 
						|
									check_file ${FILE}
							 | 
						|
								        local FILE_TYPE=${?}
							 | 
						|
									local TYPE_STR=''
							 | 
						|
								
							 | 
						|
								        if [ $(( ${FILE_TYPE} & ${IS_CERT} )) -ne 0 ]
							 | 
						|
								        then
							 | 
						|
								            TYPE_STR='x509'
							 | 
						|
								        elif [ $(( ${FILE_TYPE} & ${IS_CRL} )) -ne 0 ]
							 | 
						|
								        then
							 | 
						|
								            TYPE_STR='crl'
							 | 
						|
								        else
							 | 
						|
								            echo "WARNING: ${FILE} does not contain a certificate or CRL: skipping" >&2
							 | 
						|
									    continue
							 | 
						|
								        fi
							 | 
						|
								
							 | 
						|
									link_hash ${FILE} ${TYPE_STR}
							 | 
						|
								    done
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								
							 | 
						|
								# choose the name of an ssl application
							 | 
						|
								if [ -n "${OPENSSL}" ]
							 | 
						|
								then
							 | 
						|
								    SSL_CMD=$(which ${OPENSSL} 2>/dev/null)
							 | 
						|
								else
							 | 
						|
								    SSL_CMD=/usr/bin/openssl
							 | 
						|
								    OPENSSL=${SSL_CMD}
							 | 
						|
								    export OPENSSL
							 | 
						|
								fi
							 | 
						|
								
							 | 
						|
								# fix paths
							 | 
						|
								PATH=${PATH}:${DIR}/bin
							 | 
						|
								export PATH
							 | 
						|
								
							 | 
						|
								# confirm existance/executability of ssl command
							 | 
						|
								if ! [ -x ${SSL_CMD} ]
							 | 
						|
								then
							 | 
						|
								    echo "${0}: rehashing skipped ('openssl' program not available)" >&2
							 | 
						|
								    exit 0
							 | 
						|
								fi
							 | 
						|
								
							 | 
						|
								# determine which directories to process
							 | 
						|
								old_IFS=$IFS
							 | 
						|
								if [ ${#} -gt 0 ]
							 | 
						|
								then
							 | 
						|
								    IFS=':'
							 | 
						|
								    DIRLIST=${*}
							 | 
						|
								elif [ -n "${SSL_CERT_DIR}" ]
							 | 
						|
								then
							 | 
						|
								    DIRLIST=$SSL_CERT_DIR
							 | 
						|
								else
							 | 
						|
								    DIRLIST=${DIR}/certs
							 | 
						|
								fi
							 | 
						|
								
							 | 
						|
								IFS=':'
							 | 
						|
								
							 | 
						|
								# process directories
							 | 
						|
								for CERT_DIR in ${DIRLIST}
							 | 
						|
								do
							 | 
						|
								    if [ -d ${CERT_DIR} -a -w ${CERT_DIR} ]
							 | 
						|
								    then
							 | 
						|
								        IFS=$old_IFS
							 | 
						|
								        hash_dir ${CERT_DIR}
							 | 
						|
								        IFS=':'
							 | 
						|
								    fi
							 | 
						|
								done
							 | 
						|
								
							 |