vanhofen
4 years ago
3 changed files with 412 additions and 0 deletions
@ -0,0 +1,210 @@ |
|||||
|
#!/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 |
@ -0,0 +1,15 @@ |
|||||
|
#!/bin/sh |
||||
|
|
||||
|
CERTSCONF=/etc/ca-certificates.conf |
||||
|
CERTSDIR=/usr/share/ca-certificates |
||||
|
|
||||
|
rm -f $CERTSCONF |
||||
|
|
||||
|
subdirs="$(ls -1 $CERTSDIR)" |
||||
|
for subdir in $subdirs; do |
||||
|
certs="$(ls -1 $CERTSDIR/$subdir)" |
||||
|
for cert in $certs; do |
||||
|
echo "add $subdir/$cert" |
||||
|
echo "$subdir/$cert" >> $CERTSCONF |
||||
|
done |
||||
|
done |
@ -0,0 +1,187 @@ |
|||||
|
#!/bin/sh -e |
||||
|
# |
||||
|
# update-ca-certificates |
||||
|
# |
||||
|
# Copyright (c) 2003 Fumitoshi UKAI <ukai@debian.or.jp> |
||||
|
# Copyright (c) 2009 Philipp Kern <pkern@debian.org> |
||||
|
# |
||||
|
# This program is free software; you can redistribute it and/or modify |
||||
|
# it under the terms of the GNU General Public License as published by |
||||
|
# the Free Software Foundation; either version 2 of the License, or |
||||
|
# (at your option) any later version. |
||||
|
# |
||||
|
# This program is distributed in the hope that it will be useful, |
||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
||||
|
# GNU General Public License for more details. |
||||
|
# |
||||
|
# You should have received a copy of the GNU General Public License |
||||
|
# along with this program; if not, write to the Free Software |
||||
|
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02111-1301, |
||||
|
# USA. |
||||
|
# |
||||
|
|
||||
|
verbose=0 |
||||
|
fresh=0 |
||||
|
default=0 |
||||
|
CERTSCONF=/etc/ca-certificates.conf |
||||
|
CERTSDIR=/usr/share/ca-certificates |
||||
|
LOCALCERTSDIR=/var/share/ca-certificates |
||||
|
CERTBUNDLE=ca-certificates.crt |
||||
|
ETCCERTSDIR=/etc/ssl/certs |
||||
|
|
||||
|
while [ $# -gt 0 ]; |
||||
|
do |
||||
|
case $1 in |
||||
|
--verbose|-v) |
||||
|
verbose=1;; |
||||
|
--fresh|-f) |
||||
|
fresh=1;; |
||||
|
--default|-d) |
||||
|
default=1 |
||||
|
fresh=1;; |
||||
|
--certsconf) |
||||
|
shift |
||||
|
CERTSCONF="$1";; |
||||
|
--certsdir) |
||||
|
shift |
||||
|
CERTSDIR="$1";; |
||||
|
--localcertsdir) |
||||
|
shift |
||||
|
LOCALCERTSDIR="$1";; |
||||
|
--certbundle) |
||||
|
shift |
||||
|
CERTBUNDLE="$1";; |
||||
|
--etccertsdir) |
||||
|
shift |
||||
|
ETCCERTSDIR="$1";; |
||||
|
--help|-h|*) |
||||
|
echo "$0: [--verbose] [--fresh]" |
||||
|
exit;; |
||||
|
esac |
||||
|
shift |
||||
|
done |
||||
|
|
||||
|
if [ ! -s "$CERTSCONF" ] |
||||
|
then |
||||
|
fresh=1 |
||||
|
fi |
||||
|
|
||||
|
cleanup() { |
||||
|
rm -f "$TEMPBUNDLE" |
||||
|
rm -f "$ADDED" |
||||
|
rm -f "$REMOVED" |
||||
|
} |
||||
|
trap cleanup 0 |
||||
|
|
||||
|
# Helper files. (Some of them are not simple arrays because we spawn |
||||
|
# subshells later on.) |
||||
|
TEMPBUNDLE="$(mktemp -t "${CERTBUNDLE}.tmp.XXXXXX")" |
||||
|
ADDED="$(mktemp -t "ca-certificates.tmp.XXXXXX")" |
||||
|
REMOVED="$(mktemp -t "ca-certificates.tmp.XXXXXX")" |
||||
|
|
||||
|
# Adds a certificate to the list of trusted ones. This includes a symlink |
||||
|
# in /etc/ssl/certs to the certificate file and its inclusion into the |
||||
|
# bundle. |
||||
|
add() { |
||||
|
CERT="$1" |
||||
|
PEM="$ETCCERTSDIR/$(basename "$CERT" .crt | sed -e 's/ /_/g' \ |
||||
|
-e 's/[()]/=/g' \ |
||||
|
-e 's/,/_/g').pem" |
||||
|
if ! test -e "$PEM" || [ "$(readlink "$PEM")" != "$CERT" ] |
||||
|
then |
||||
|
ln -sf "$CERT" "$PEM" |
||||
|
echo "+$PEM" >> "$ADDED" |
||||
|
fi |
||||
|
# Add trailing newline to certificate, if it is missing (#635570) |
||||
|
sed -e '$a\' "$CERT" >> "$TEMPBUNDLE" |
||||
|
} |
||||
|
|
||||
|
remove() { |
||||
|
CERT="$1" |
||||
|
PEM="$ETCCERTSDIR/$(basename "$CERT" .crt).pem" |
||||
|
if test -L "$PEM" |
||||
|
then |
||||
|
rm -f "$PEM" |
||||
|
echo "-$PEM" >> "$REMOVED" |
||||
|
fi |
||||
|
} |
||||
|
|
||||
|
mkdir -p "$ETCCERTSDIR" |
||||
|
cd "$ETCCERTSDIR" |
||||
|
if [ "$fresh" = 1 ]; then |
||||
|
echo "Clearing symlinks in $ETCCERTSDIR..." |
||||
|
find . -type l -print | while read symlink |
||||
|
do |
||||
|
case $(readlink "$symlink") in |
||||
|
$CERTSDIR*|$LOCALCERTSDIR*) rm -f $symlink;; |
||||
|
esac |
||||
|
done |
||||
|
find . -type l -print | while read symlink |
||||
|
do |
||||
|
test -f "$symlink" || rm -f "$symlink" |
||||
|
done |
||||
|
echo "done." |
||||
|
fi |
||||
|
|
||||
|
echo "Updating certificates in $ETCCERTSDIR..." |
||||
|
|
||||
|
# Add default certificate authorities if requested |
||||
|
if [ "$default" = 1 ]; then |
||||
|
find -L "$CERTSDIR" -type f -name '*.crt' | sort | while read crt |
||||
|
do |
||||
|
add "$crt" |
||||
|
done |
||||
|
fi |
||||
|
|
||||
|
# Handle certificates that should be removed. This is an explicit act |
||||
|
# by prefixing lines in the configuration files with exclamation marks (!). |
||||
|
sed -n -e '/^$/d' -e 's/^!//p' "$CERTSCONF" | while read crt |
||||
|
do |
||||
|
remove "$CERTSDIR/$crt" |
||||
|
done |
||||
|
|
||||
|
sed -e '/^$/d' -e '/^#/d' -e '/^!/d' "$CERTSCONF" | while read crt |
||||
|
do |
||||
|
if ! test -f "$CERTSDIR/$crt" |
||||
|
then |
||||
|
echo "W: $CERTSDIR/$crt not found, but listed in $CERTSCONF." >&2 |
||||
|
continue |
||||
|
fi |
||||
|
add "$CERTSDIR/$crt" |
||||
|
done |
||||
|
|
||||
|
# Now process certificate authorities installed by the local system |
||||
|
# administrator. |
||||
|
if [ -d "$LOCALCERTSDIR" ] |
||||
|
then |
||||
|
find -L "$LOCALCERTSDIR" -type f -name '*.crt' | sort | while read crt |
||||
|
do |
||||
|
add "$crt" |
||||
|
done |
||||
|
fi |
||||
|
|
||||
|
rm -f "$CERTBUNDLE" |
||||
|
|
||||
|
ADDED_CNT=$(wc -l < "$ADDED") |
||||
|
REMOVED_CNT=$(wc -l < "$REMOVED") |
||||
|
|
||||
|
if [ "$ADDED_CNT" -gt 0 ] || [ "$REMOVED_CNT" -gt 0 ] |
||||
|
then |
||||
|
# only run if set of files has changed |
||||
|
if [ "$verbose" = 0 ] |
||||
|
then |
||||
|
c_rehash . > /dev/null |
||||
|
else |
||||
|
c_rehash . |
||||
|
fi |
||||
|
fi |
||||
|
|
||||
|
chmod 0644 "$TEMPBUNDLE" |
||||
|
mv -f "$TEMPBUNDLE" "$CERTBUNDLE" |
||||
|
# Restore proper SELinux label after moving the file |
||||
|
[ -x /usr/sbin/restorecon ] && /usr/sbin/restorecon "$CERTBUNDLE" >/dev/null 2>&1 |
||||
|
|
||||
|
echo "$ADDED_CNT added, $REMOVED_CNT removed; done." |
||||
|
|
||||
|
# vim:set et sw=2: |
Loading…
Reference in new issue