405.pkg-base-audit.in
1 #!/bin/sh -f 2 # 3 # Copyright (c) 2004 Oliver Eikemeier. All rights reserved. 4 # Copyright (c) 2014 Matthew Seaman <matthew@FreeBSD.org> 5 # Copyright (c) 2016 Miroslav Lachman <000.fbsd@quip.cz> 6 # 7 # Redistribution and use in source and binary forms, with or without 8 # modification, are permitted provided that the following conditions are 9 # met: 10 # 11 # 1. Redistributions of source code must retain the above copyright notice 12 # this list of conditions and the following disclaimer. 13 # 14 # 2. Redistributions in binary form must reproduce the above copyright 15 # notice, this list of conditions and the following disclaimer in the 16 # documentation and/or other materials provided with the distribution. 17 # 18 # 3. Neither the name of the author nor the names of its contributors may be 19 # used to endorse or promote products derived from this software without 20 # specific prior written permission. 21 # 22 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, 23 # INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY 24 # AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 25 # COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 26 # INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 27 # NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 # DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 # THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 31 # THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 # 33 # $FreeBSD$ 34 # 35 36 if [ -r /etc/defaults/periodic.conf ]; then 37 . /etc/defaults/periodic.conf 38 source_periodic_confs 39 fi 40 41 : ${security_status_baseaudit_enable:=YES} 42 : ${security_status_baseaudit_period:=daily} 43 : ${security_status_baseaudit_quiet:=NO} 44 : ${security_status_baseaudit_chroots=$pkg_chroots} 45 : ${security_status_baseaudit_jails=$pkg_jails} 46 : ${security_status_baseaudit_jails_ignore+=""} 47 : ${security_status_baseaudit_expiry:=2} 48 49 # Compute PKG_DBDIR from the config file. 50 pkgcmd=%prefix%/sbin/pkg 51 PKG_DBDIR=`${pkgcmd} config PKG_DBDIR` 52 auditfile="${PKG_DBDIR}/vuln.xml" 53 54 audit_base() { 55 local pkgargs="$1" 56 local basedir="$2" 57 local rc=0 58 local then 59 local now 60 local usrlv 61 local krnlv 62 local strlen 63 local chrootv 64 local jailv 65 local jid 66 67 # get version from chroot 68 if [ -n "`echo "$pkgargs" | egrep '^-c'`" ]; then 69 if [ -x "$basedir/bin/freebsd-version" ]; then 70 chrootv=$($basedir/bin/freebsd-version -u) 71 ## safety check - strlen 72 strlen=$(echo "$chrootv" | wc -c) 73 if [ $strlen -gt 17 -o $strlen -lt 11 ]; then 74 echo "Wrong version string, cannot run audit" 75 return 3 76 fi 77 usrlv=$(echo $chrootv | sed 's,^,FreeBSD-,;s,-RELEASE-p,_,;s,-RELEASE$,,') 78 else 79 echo "Cannot guess chroot version" 80 return 3 81 fi 82 # get version from jail 83 elif [ -n "`echo "$pkgargs" | egrep '^-j'`" ]; then 84 jid=$(echo "$pkgargs" | awk '$1 ~ /^-[j]/ { print $2 }') 85 jailv=$(jexec $jid freebsd-version -u) 86 ## safety check - strlen 87 strlen=$(echo "$jailv" | wc -c) 88 if [ $strlen -gt 17 -o $strlen -lt 11 ]; then 89 echo "Wrong version string, cannot run audit" 90 return 3 91 fi 92 usrlv=$(echo $jailv | sed 's,^,FreeBSD-,;s,-RELEASE-p,_,;s,-RELEASE$,,') 93 # get version from host 94 else 95 usrlv=$(freebsd-version -u | sed 's,^,FreeBSD-,;s,-RELEASE-p,_,;s,-RELEASE$,,') 96 fi 97 98 then=`stat -f '%m' "${basedir}${auditfile}" 2> /dev/null` || rc=3 99 now=`date +%s` || rc=3 100 # Add 10 minutes of padding since the check is in seconds. 101 if [ $rc -ne 0 -o \ 102 $(( 86400 \* "${security_status_baseaudit_expiry}" )) \ 103 -le $(( ${now} - ${then} + 600 )) ]; then 104 # When non-interactive, sleep to reduce congestion on mirrors 105 anticongestion 106 f="-F" 107 else 108 echo -n 'Database fetched: ' 109 date -r "${then}" -Iminutes || rc=3 110 fi 111 112 # Reset rc: the stat/date block above only informs the fetch 113 # decision; the actual return code should come from pkg audit. 114 rc=0 115 116 # cannot check kernel in jail or chroot 117 if [ -z "`echo "$pkgargs" | egrep '^-[cj]'`" -a `sysctl -n security.jail.jailed` = 0 ]; then 118 krnlv=$(freebsd-version -k | sed 's,^,FreeBSD-kernel-,;s,-RELEASE-p,_,;s,-RELEASE$,,') 119 ${pkgcmd} audit $f $q $krnlv || { rc=$?; [ $rc -lt 3 ] && rc=3; } 120 fi 121 122 ${pkgcmd} audit $f $q $usrlv || { rc=$?; [ $rc -lt 3 ] && rc=3; } 123 124 return $rc 125 } 126 127 # Use $pkg_chroots to provide a default list of chroots, and 128 # $pkg_jails to provide a default list of jails (or '*' for all jails) 129 # for all pkg periodic scripts, or set 130 # $security_status_baseaudit_chroots and 131 # $security_status_baseaudit_jails for this script only. 132 133 audit_base_all() { 134 local rc 135 local last_rc 136 local jails 137 138 # We always show audit results for the base system, but only print 139 # a banner line if we're also showing audit results for any 140 # chroots or jails. 141 142 if [ -n "${security_status_baseaudit_chroots}" -o \ 143 -n "${security_status_baseaudit_jails}" ]; then 144 echo "Host system:" 145 fi 146 147 audit_base '' '' 148 last_rc=$? 149 [ $last_rc -gt 1 ] && rc=$last_rc 150 151 for c in $security_status_baseaudit_chroots ; do 152 echo 153 echo "chroot: $c" 154 audit_base "-c $c" $c 155 last_rc=$? 156 [ $last_rc -gt 1 ] && rc=$last_rc 157 done 158 159 case $security_status_baseaudit_jails in 160 \*) 161 jails=$(jls -q -h name path | sed -e 1d -e 's/ /|/') 162 ;; 163 '') 164 jails= 165 ;; 166 *) 167 # Given the jail name or jid, find the jail path 168 jails= 169 for j in $security_status_baseaudit_jails ; do 170 p=$(jls -j $j -h name path | sed -e 1d -e 's/ /|/') 171 jails="${jails} ${p}" 172 done 173 ;; 174 esac 175 176 for j in ${jails} ; do 177 # ignore some jails 178 # we iterate to get exact matches because we want substring matches 179 # foo should not match foo.bar 180 for ignore in ${security_status_baseaudit_jails_ignore} ; do 181 if [ "${j%|*}" = "${ignore}" ]; then 182 echo 183 echo "ignoring jail: ${j%|*}" 184 # continue with the main loop 185 continue 2 186 fi 187 done 188 189 # ignore some jails 190 # we iterate to get prefix matches because we foo to match foo.bar 191 for ignore in ${security_status_baseaudit_jails_ignore_wild} ; do 192 if [ $(expr "${j%|*}" : "${ignore}") -ne 0 ] ; then 193 echo 194 echo "ignoring jail: ${j%|*}" 195 # continue with the main loop 196 continue 2 197 fi 198 done 199 200 echo 201 echo "jail: ${j%|*}" 202 audit_base "-j ${j%|*}" ${j##*|} 203 last_rc=$? 204 [ $last_rc -gt 1 ] && rc=$last_rc 205 done 206 207 return $rc 208 } 209 210 rc=0 211 212 if check_yesno_period security_status_baseaudit_enable 213 then 214 echo 215 echo 'Checking for security vulnerabilities in base (userland & kernel):' 216 217 if ! ${pkgcmd} -N >/dev/null 2>&1 ; then 218 echo 'pkg-audit is enabled but pkg is not used' 219 rc=2 220 else 221 case "${security_status_baseaudit_quiet}" in 222 [Yy][Ee][Ss]) 223 q='-q' 224 ;; 225 *) 226 q= 227 ;; 228 esac 229 230 audit_base_all ; rc=$? 231 fi 232 fi 233 234 exit "$rc"