1ccdcb388SKyle Evans#!/bin/sh 2ccdcb388SKyle Evans#- 34d846d26SWarner Losh# SPDX-License-Identifier: BSD-2-Clause 4ccdcb388SKyle Evans# 5ccdcb388SKyle Evans# Copyright 2018 Allan Jude <allanjude@freebsd.org> 6ccdcb388SKyle Evans# 7ccdcb388SKyle Evans# Redistribution and use in source and binary forms, with or without 8ccdcb388SKyle Evans# modification, are permitted providing that the following conditions 9ccdcb388SKyle Evans# are met: 10ccdcb388SKyle Evans# 1. Redistributions of source code must retain the above copyright 11ccdcb388SKyle Evans# notice, this list of conditions and the following disclaimer. 12ccdcb388SKyle Evans# 2. Redistributions in binary form must reproduce the above copyright 13ccdcb388SKyle Evans# notice, this list of conditions and the following disclaimer in the 14ccdcb388SKyle Evans# documentation and/or other materials provided with the distribution. 15ccdcb388SKyle Evans# 16ccdcb388SKyle Evans# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17ccdcb388SKyle Evans# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 18ccdcb388SKyle Evans# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19ccdcb388SKyle Evans# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 20ccdcb388SKyle Evans# DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21ccdcb388SKyle Evans# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22ccdcb388SKyle Evans# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23ccdcb388SKyle Evans# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 24ccdcb388SKyle Evans# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 25ccdcb388SKyle Evans# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 26ccdcb388SKyle Evans# POSSIBILITY OF SUCH DAMAGE. 27ccdcb388SKyle Evans# 28ccdcb388SKyle Evans 291525625cSDag-Erling Smørgravset -u 301525625cSDag-Erling Smørgrav 31ccdcb388SKyle Evans############################################################ CONFIGURATION 32ccdcb388SKyle Evans 33ccdcb388SKyle Evans: ${DESTDIR:=} 34232cf6beSJessica Clarke: ${DISTBASE:=} 35ccdcb388SKyle Evans 36ccdcb388SKyle Evans############################################################ GLOBALS 37ccdcb388SKyle Evans 38ccdcb388SKyle EvansSCRIPTNAME="${0##*/}" 39ccdcb388SKyle EvansERRORS=0 401525625cSDag-Erling SmørgravNOOP=false 411525625cSDag-Erling SmørgravUNPRIV=false 421525625cSDag-Erling SmørgravVERBOSE=false 43ccdcb388SKyle Evans 44ccdcb388SKyle Evans############################################################ FUNCTIONS 45ccdcb388SKyle Evans 461525625cSDag-Erling Smørgravinfo() 471525625cSDag-Erling Smørgrav{ 481525625cSDag-Erling Smørgrav echo "${0##*/}: $@" >&2 491525625cSDag-Erling Smørgrav} 501525625cSDag-Erling Smørgrav 511525625cSDag-Erling Smørgravverbose() 521525625cSDag-Erling Smørgrav{ 531525625cSDag-Erling Smørgrav if "${VERBOSE}" ; then 541525625cSDag-Erling Smørgrav info "$@" 551525625cSDag-Erling Smørgrav fi 561525625cSDag-Erling Smørgrav} 571525625cSDag-Erling Smørgrav 581525625cSDag-Erling Smørgravperform() 591525625cSDag-Erling Smørgrav{ 601525625cSDag-Erling Smørgrav if ! "${NOOP}" ; then 611525625cSDag-Erling Smørgrav "$@" 621525625cSDag-Erling Smørgrav fi 631525625cSDag-Erling Smørgrav} 641525625cSDag-Erling Smørgrav 65a401c8cbSDag-Erling Smørgravcert_files_in() 66a401c8cbSDag-Erling Smørgrav{ 67a401c8cbSDag-Erling Smørgrav find -L "$@" -type f \( \ 68a401c8cbSDag-Erling Smørgrav -name '*.pem' -or \ 69a401c8cbSDag-Erling Smørgrav -name '*.crt' -or \ 7087945a08SDag-Erling Smørgrav -name '*.cer' \ 71a401c8cbSDag-Erling Smørgrav \) 2>/dev/null 72a401c8cbSDag-Erling Smørgrav} 73a401c8cbSDag-Erling Smørgrav 74f7d16a62SDag-Erling Smørgraveolcvt() 75f7d16a62SDag-Erling Smørgrav{ 76f7d16a62SDag-Erling Smørgrav cat "$@" | tr -s '\r' '\n' 77f7d16a62SDag-Erling Smørgrav} 78f7d16a62SDag-Erling Smørgrav 79ccdcb388SKyle Evansdo_hash() 80ccdcb388SKyle Evans{ 81ccdcb388SKyle Evans local hash 82ccdcb388SKyle Evans 83ccdcb388SKyle Evans if hash=$(openssl x509 -noout -subject_hash -in "$1") ; then 84ccdcb388SKyle Evans echo "$hash" 85ccdcb388SKyle Evans return 0 86ccdcb388SKyle Evans else 871525625cSDag-Erling Smørgrav info "Error: $1" 881525625cSDag-Erling Smørgrav ERRORS=$((ERRORS + 1)) 89ccdcb388SKyle Evans return 1 90ccdcb388SKyle Evans fi 91ccdcb388SKyle Evans} 92ccdcb388SKyle Evans 9305a16147SKyle Evansget_decimal() 9405a16147SKyle Evans{ 9505a16147SKyle Evans local checkdir hash decimal 9605a16147SKyle Evans 9705a16147SKyle Evans checkdir=$1 9805a16147SKyle Evans hash=$2 9905a16147SKyle Evans decimal=0 10005a16147SKyle Evans 10105a16147SKyle Evans while [ -e "$checkdir/$hash.$decimal" ] ; do 10205a16147SKyle Evans decimal=$((decimal + 1)) 10305a16147SKyle Evans done 10405a16147SKyle Evans 10505a16147SKyle Evans echo ${decimal} 10605a16147SKyle Evans return 0 10705a16147SKyle Evans} 10805a16147SKyle Evans 109a401c8cbSDag-Erling Smørgravcreate_trusted() 110ccdcb388SKyle Evans{ 1111525625cSDag-Erling Smørgrav local hash certhash otherfile otherhash 11205a16147SKyle Evans local suffix 1133fed4f0dSMark Peek local link=${2:+-lrs} 114ccdcb388SKyle Evans 115ccdcb388SKyle Evans hash=$(do_hash "$1") || return 11605a16147SKyle Evans certhash=$(openssl x509 -sha1 -in "$1" -noout -fingerprint) 1171525625cSDag-Erling Smørgrav for otherfile in $(find $UNTRUSTDESTDIR -name "$hash.*") ; do 1181525625cSDag-Erling Smørgrav otherhash=$(openssl x509 -sha1 -in "$otherfile" -noout -fingerprint) 1191525625cSDag-Erling Smørgrav if [ "$certhash" = "$otherhash" ] ; then 120a401c8cbSDag-Erling Smørgrav info "Skipping untrusted certificate $hash ($otherfile)" 12187945a08SDag-Erling Smørgrav return 0 122ccdcb388SKyle Evans fi 12305a16147SKyle Evans done 124a401c8cbSDag-Erling Smørgrav for otherfile in $(find $CERTDESTDIR -name "$hash.*") ; do 125a401c8cbSDag-Erling Smørgrav otherhash=$(openssl x509 -sha1 -in "$otherfile" -noout -fingerprint) 126a401c8cbSDag-Erling Smørgrav if [ "$certhash" = "$otherhash" ] ; then 127a401c8cbSDag-Erling Smørgrav verbose "Skipping duplicate entry for certificate $hash" 128a401c8cbSDag-Erling Smørgrav return 0 129a401c8cbSDag-Erling Smørgrav fi 130a401c8cbSDag-Erling Smørgrav done 13105a16147SKyle Evans suffix=$(get_decimal "$CERTDESTDIR" "$hash") 1321525625cSDag-Erling Smørgrav verbose "Adding $hash.$suffix to trust store" 133a401c8cbSDag-Erling Smørgrav perform install ${INSTALLFLAGS} -m 0444 ${link} \ 134a401c8cbSDag-Erling Smørgrav "$(realpath "$1")" "$CERTDESTDIR/$hash.$suffix" 135ccdcb388SKyle Evans} 136ccdcb388SKyle Evans 1378c4094f3SKyle Evans# Accepts either dot-hash form from `certctl list` or a path to a valid cert. 1388c4094f3SKyle Evansresolve_certname() 139ccdcb388SKyle Evans{ 14094a5245cSKyle Evans local hash srcfile filename 14105a16147SKyle Evans local suffix 142ccdcb388SKyle Evans 14394a5245cSKyle Evans # If it exists as a file, we'll try that; otherwise, we'll scan 14494a5245cSKyle Evans if [ -e "$1" ] ; then 145ccdcb388SKyle Evans hash=$(do_hash "$1") || return 14694a5245cSKyle Evans srcfile=$(realpath "$1") 14764e6e1e4SCeri Davies suffix=$(get_decimal "$UNTRUSTDESTDIR" "$hash") 14805a16147SKyle Evans filename="$hash.$suffix" 1498c4094f3SKyle Evans echo "$srcfile" "$hash.$suffix" 15094a5245cSKyle Evans elif [ -e "${CERTDESTDIR}/$1" ] ; then 15194a5245cSKyle Evans srcfile=$(realpath "${CERTDESTDIR}/$1") 15205a16147SKyle Evans hash=$(echo "$1" | sed -Ee 's/\.([0-9])+$//') 15364e6e1e4SCeri Davies suffix=$(get_decimal "$UNTRUSTDESTDIR" "$hash") 15405a16147SKyle Evans filename="$hash.$suffix" 1558c4094f3SKyle Evans echo "$srcfile" "$hash.$suffix" 1568c4094f3SKyle Evans fi 1578c4094f3SKyle Evans} 1588c4094f3SKyle Evans 15964e6e1e4SCeri Daviescreate_untrusted() 1608c4094f3SKyle Evans{ 1618c4094f3SKyle Evans local srcfile filename 1623fed4f0dSMark Peek local link=${2:+-lrs} 1638c4094f3SKyle Evans 1648c4094f3SKyle Evans set -- $(resolve_certname "$1") 1658c4094f3SKyle Evans srcfile=$1 1668c4094f3SKyle Evans filename=$2 1678c4094f3SKyle Evans 1688c4094f3SKyle Evans if [ -z "$srcfile" -o -z "$filename" ] ; then 16994a5245cSKyle Evans return 17094a5245cSKyle Evans fi 1718c4094f3SKyle Evans 1721525625cSDag-Erling Smørgrav verbose "Adding $filename to untrusted list" 173a401c8cbSDag-Erling Smørgrav perform install ${INSTALLFLAGS} -m 0444 ${link} \ 174a401c8cbSDag-Erling Smørgrav "$srcfile" "$UNTRUSTDESTDIR/$filename" 175ccdcb388SKyle Evans} 176ccdcb388SKyle Evans 177ccdcb388SKyle Evansdo_scan() 178ccdcb388SKyle Evans{ 179a401c8cbSDag-Erling Smørgrav local CFUNC CSEARCH CPATH CFILE CERT SPLITDIR 180ccdcb388SKyle Evans local oldIFS="$IFS" 181ccdcb388SKyle Evans CFUNC="$1" 182ccdcb388SKyle Evans CSEARCH="$2" 183ccdcb388SKyle Evans 184ccdcb388SKyle Evans IFS=: 185ccdcb388SKyle Evans set -- $CSEARCH 186ccdcb388SKyle Evans IFS="$oldIFS" 187a401c8cbSDag-Erling Smørgrav for CFILE in $(cert_files_in "$@") ; do 1881525625cSDag-Erling Smørgrav verbose "Reading $CFILE" 189f7d16a62SDag-Erling Smørgrav case $(eolcvt "$CFILE" | egrep -c '^-+BEGIN CERTIFICATE-+$') in 190a401c8cbSDag-Erling Smørgrav 0) 191a401c8cbSDag-Erling Smørgrav ;; 192a401c8cbSDag-Erling Smørgrav 1) 193a401c8cbSDag-Erling Smørgrav "$CFUNC" "$CFILE" link 194a401c8cbSDag-Erling Smørgrav ;; 195a401c8cbSDag-Erling Smørgrav *) 196a401c8cbSDag-Erling Smørgrav verbose "Multiple certificates found, splitting..." 197a401c8cbSDag-Erling Smørgrav SPLITDIR=$(mktemp -d) 198f7d16a62SDag-Erling Smørgrav eolcvt "$CFILE" | egrep '^(---|[0-9A-Za-z/+=]+$)' | \ 19987945a08SDag-Erling Smørgrav split -p '^-+BEGIN CERTIFICATE-+$' - "$SPLITDIR/x" 200a401c8cbSDag-Erling Smørgrav for CERT in $(find "$SPLITDIR" -type f) ; do 201a401c8cbSDag-Erling Smørgrav "$CFUNC" "$CERT" 202ccdcb388SKyle Evans done 203a401c8cbSDag-Erling Smørgrav rm -rf "$SPLITDIR" 204a401c8cbSDag-Erling Smørgrav ;; 205a401c8cbSDag-Erling Smørgrav esac 206ccdcb388SKyle Evans done 207ccdcb388SKyle Evans} 208ccdcb388SKyle Evans 209ccdcb388SKyle Evansdo_list() 210ccdcb388SKyle Evans{ 211ccdcb388SKyle Evans local CFILE subject 212ccdcb388SKyle Evans 213a401c8cbSDag-Erling Smørgrav for CFILE in $(find "$@" \( -type f -or -type l \) -name '*.[0-9]') ; do 214ccdcb388SKyle Evans if [ ! -s "$CFILE" ] ; then 2151525625cSDag-Erling Smørgrav info "Unable to read $CFILE" 2161525625cSDag-Erling Smørgrav ERRORS=$((ERRORS + 1)) 217ccdcb388SKyle Evans continue 218ccdcb388SKyle Evans fi 219ccdcb388SKyle Evans subject= 220a401c8cbSDag-Erling Smørgrav if ! "$VERBOSE" ; then 221a401c8cbSDag-Erling Smørgrav subject=$(openssl x509 -noout -subject -nameopt multiline -in "$CFILE" | sed -n '/commonName/s/.*= //p') 222ccdcb388SKyle Evans fi 223a401c8cbSDag-Erling Smørgrav if [ -z "$subject" ] ; then 224ccdcb388SKyle Evans subject=$(openssl x509 -noout -subject -in "$CFILE") 225ccdcb388SKyle Evans fi 226a401c8cbSDag-Erling Smørgrav printf "%s\t%s\n" "${CFILE##*/}" "$subject" 227a401c8cbSDag-Erling Smørgrav done 228ccdcb388SKyle Evans} 229ccdcb388SKyle Evans 230ccdcb388SKyle Evanscmd_rehash() 231ccdcb388SKyle Evans{ 232ccdcb388SKyle Evans 2335e6c628eSKyle Evans if [ -e "$CERTDESTDIR" ] ; then 234a401c8cbSDag-Erling Smørgrav perform find "$CERTDESTDIR" \( -type f -or -type l \) -delete 2355e6c628eSKyle Evans else 2361525625cSDag-Erling Smørgrav perform install -d -m 0755 "$CERTDESTDIR" 2375e6c628eSKyle Evans fi 23864e6e1e4SCeri Davies if [ -e "$UNTRUSTDESTDIR" ] ; then 239a401c8cbSDag-Erling Smørgrav perform find "$UNTRUSTDESTDIR" \( -type f -or -type l \) -delete 2405e6c628eSKyle Evans else 2411525625cSDag-Erling Smørgrav perform install -d -m 0755 "$UNTRUSTDESTDIR" 2425e6c628eSKyle Evans fi 243ccdcb388SKyle Evans 24464e6e1e4SCeri Davies do_scan create_untrusted "$UNTRUSTPATH" 245a401c8cbSDag-Erling Smørgrav do_scan create_trusted "$TRUSTPATH" 246ccdcb388SKyle Evans} 247ccdcb388SKyle Evans 248ccdcb388SKyle Evanscmd_list() 249ccdcb388SKyle Evans{ 2501525625cSDag-Erling Smørgrav info "Listing Trusted Certificates:" 251ccdcb388SKyle Evans do_list "$CERTDESTDIR" 252ccdcb388SKyle Evans} 253ccdcb388SKyle Evans 25464e6e1e4SCeri Daviescmd_untrust() 255ccdcb388SKyle Evans{ 2561525625cSDag-Erling Smørgrav local UTFILE 257ccdcb388SKyle Evans 258ccdcb388SKyle Evans shift # verb 2591525625cSDag-Erling Smørgrav perform install -d -m 0755 "$UNTRUSTDESTDIR" 2601525625cSDag-Erling Smørgrav for UTFILE in "$@"; do 2611525625cSDag-Erling Smørgrav info "Adding $UTFILE to untrusted list" 2621525625cSDag-Erling Smørgrav create_untrusted "$UTFILE" 263ccdcb388SKyle Evans done 264ccdcb388SKyle Evans} 265ccdcb388SKyle Evans 26664e6e1e4SCeri Daviescmd_trust() 267ccdcb388SKyle Evans{ 2681525625cSDag-Erling Smørgrav local UTFILE untrustedhash certhash hash 269ccdcb388SKyle Evans 270ccdcb388SKyle Evans shift # verb 2711525625cSDag-Erling Smørgrav for UTFILE in "$@"; do 2721525625cSDag-Erling Smørgrav if [ -s "$UTFILE" ] ; then 2731525625cSDag-Erling Smørgrav hash=$(do_hash "$UTFILE") 2741525625cSDag-Erling Smørgrav certhash=$(openssl x509 -sha1 -in "$UTFILE" -noout -fingerprint) 2751525625cSDag-Erling Smørgrav for UNTRUSTEDFILE in $(find $UNTRUSTDESTDIR -name "$hash.*") ; do 2761525625cSDag-Erling Smørgrav untrustedhash=$(openssl x509 -sha1 -in "$UNTRUSTEDFILE" -noout -fingerprint) 2771525625cSDag-Erling Smørgrav if [ "$certhash" = "$untrustedhash" ] ; then 2781525625cSDag-Erling Smørgrav info "Removing $(basename "$UNTRUSTEDFILE") from untrusted list" 2791525625cSDag-Erling Smørgrav perform rm -f $UNTRUSTEDFILE 28005a16147SKyle Evans fi 28105a16147SKyle Evans done 2821525625cSDag-Erling Smørgrav elif [ -e "$UNTRUSTDESTDIR/$UTFILE" ] ; then 2831525625cSDag-Erling Smørgrav info "Removing $UTFILE from untrusted list" 2841525625cSDag-Erling Smørgrav perform rm -f "$UNTRUSTDESTDIR/$UTFILE" 285ccdcb388SKyle Evans else 2861525625cSDag-Erling Smørgrav info "Cannot find $UTFILE" 2871525625cSDag-Erling Smørgrav ERRORS=$((ERRORS + 1)) 288ccdcb388SKyle Evans fi 289ccdcb388SKyle Evans done 290ccdcb388SKyle Evans} 291ccdcb388SKyle Evans 29264e6e1e4SCeri Daviescmd_untrusted() 293ccdcb388SKyle Evans{ 2941525625cSDag-Erling Smørgrav info "Listing Untrusted Certificates:" 29564e6e1e4SCeri Davies do_list "$UNTRUSTDESTDIR" 296ccdcb388SKyle Evans} 297ccdcb388SKyle Evans 298ccdcb388SKyle Evansusage() 299ccdcb388SKyle Evans{ 300ccdcb388SKyle Evans exec >&2 301ccdcb388SKyle Evans echo "Manage the TLS trusted certificates on the system" 302ccdcb388SKyle Evans echo " $SCRIPTNAME [-v] list" 303ccdcb388SKyle Evans echo " List trusted certificates" 30464e6e1e4SCeri Davies echo " $SCRIPTNAME [-v] untrusted" 30564e6e1e4SCeri Davies echo " List untrusted certificates" 306232cf6beSJessica Clarke echo " $SCRIPTNAME [-nUv] [-D <destdir>] [-d <distbase>] [-M <metalog>] rehash" 307ccdcb388SKyle Evans echo " Generate hash links for all certificates" 30864e6e1e4SCeri Davies echo " $SCRIPTNAME [-nv] untrust <file>" 30964e6e1e4SCeri Davies echo " Add <file> to the list of untrusted certificates" 31064e6e1e4SCeri Davies echo " $SCRIPTNAME [-nv] trust <file>" 31164e6e1e4SCeri Davies echo " Remove <file> from the list of untrusted certificates" 312ccdcb388SKyle Evans exit 64 313ccdcb388SKyle Evans} 314ccdcb388SKyle Evans 315ccdcb388SKyle Evans############################################################ MAIN 316ccdcb388SKyle Evans 317232cf6beSJessica Clarkewhile getopts D:d:M:nUv flag; do 318ccdcb388SKyle Evans case "$flag" in 31948e9fb85SBrooks Davis D) DESTDIR=${OPTARG} ;; 320232cf6beSJessica Clarke d) DISTBASE=${OPTARG} ;; 32148e9fb85SBrooks Davis M) METALOG=${OPTARG} ;; 3221525625cSDag-Erling Smørgrav n) NOOP=true ;; 3231525625cSDag-Erling Smørgrav U) UNPRIV=true ;; 3241525625cSDag-Erling Smørgrav v) VERBOSE=true ;; 325ccdcb388SKyle Evans esac 326ccdcb388SKyle Evansdone 3271525625cSDag-Erling Smørgravshift $((OPTIND - 1)) 328ccdcb388SKyle Evans 32917720d0bSMarius van WitzenburgDESTDIR=${DESTDIR%/} 33017720d0bSMarius van Witzenburg 3311525625cSDag-Erling Smørgravif ! [ -z "${CERTCTL_VERBOSE:-}" ] ; then 3321525625cSDag-Erling Smørgrav VERBOSE=true 3331525625cSDag-Erling Smørgravfi 33448e9fb85SBrooks Davis: ${METALOG:=${DESTDIR}/METALOG} 33548e9fb85SBrooks DavisINSTALLFLAGS= 3361525625cSDag-Erling Smørgravif "$UNPRIV" ; then 337*4d15b583SPat Maddox INSTALLFLAGS="-U -M ${METALOG} -D ${DESTDIR} -o root -g wheel" 3381525625cSDag-Erling Smørgravfi 339b799d38aSKyle Evans: ${LOCALBASE:=$(sysctl -n user.localbase)} 340232cf6beSJessica Clarke: ${TRUSTPATH:=${DESTDIR}${DISTBASE}/usr/share/certs/trusted:${DESTDIR}${LOCALBASE}/share/certs:${DESTDIR}${LOCALBASE}/etc/ssl/certs} 341232cf6beSJessica Clarke: ${UNTRUSTPATH:=${DESTDIR}${DISTBASE}/usr/share/certs/untrusted:${DESTDIR}${LOCALBASE}/etc/ssl/untrusted:${DESTDIR}${LOCALBASE}/etc/ssl/blacklisted} 342232cf6beSJessica Clarke: ${CERTDESTDIR:=${DESTDIR}${DISTBASE}/etc/ssl/certs} 343232cf6beSJessica Clarke: ${UNTRUSTDESTDIR:=${DESTDIR}${DISTBASE}/etc/ssl/untrusted} 34448e9fb85SBrooks Davis 345ccdcb388SKyle Evans[ $# -gt 0 ] || usage 346ccdcb388SKyle Evanscase "$1" in 347ccdcb388SKyle Evanslist) cmd_list ;; 348ccdcb388SKyle Evansrehash) cmd_rehash ;; 34964e6e1e4SCeri Daviesblacklist) cmd_untrust "$@" ;; 35064e6e1e4SCeri Daviesuntrust) cmd_untrust "$@" ;; 35164e6e1e4SCeri Daviestrust) cmd_trust "$@" ;; 35264e6e1e4SCeri Daviesunblacklist) cmd_trust "$@" ;; 35364e6e1e4SCeri Daviesuntrusted) cmd_untrusted ;; 35464e6e1e4SCeri Daviesblacklisted) cmd_untrusted ;; 355ccdcb388SKyle Evans*) usage # NOTREACHED 356ccdcb388SKyle Evansesac 357ccdcb388SKyle Evans 358ccdcb388SKyle Evansretval=$? 3591525625cSDag-Erling Smørgravif [ $ERRORS -gt 0 ] ; then 3601525625cSDag-Erling Smørgrav info "Encountered $ERRORS errors" 3611525625cSDag-Erling Smørgravfi 362ccdcb388SKyle Evansexit $retval 363ccdcb388SKyle Evans 364ccdcb388SKyle Evans################################################################################ 365ccdcb388SKyle Evans# END 366ccdcb388SKyle Evans################################################################################ 367