1#!/bin/sh 2# 3# $OpenBSD: snmpd.sh,v 1.20 2024/02/08 17:09:51 martijn Exp $ 4#/* 5# * Copyright (c) Rob Pierce <rob@openbsd.org> 6# * 7# * Permission to use, copy, modify, and distribute this software for any 8# * purpose with or without fee is hereby granted, provided that the above 9# * copyright notice and this permission notice appear in all copies. 10# * 11# * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES 12# * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF 13# * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR 14# * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES 15# * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN 16# * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 17# * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 18# */ 19 20# Basic snmpd regression script. 21 22export OBJDIR 23 24FAILED=0 25SLEEP=1 26PF[0]="disabled" 27PF[1]="enabled" 28 29STARTSOCK="/tmp/agentx" 30 31# This file will be creatred by traphandler.c as user _snmpd 32TMPFILE=$(mktemp -q /tmp/_snmpd_traptest.XXXXXX) 33 34trap 'skip' INT 35 36if [ "$(pgrep snmpd)" ] 37then 38 echo "The snmpd daemon is already running." 39 echo SKIPPED 40 exit 0 41fi 42 43snmpdstart() { 44 rm "${STARTSOCK}" >/dev/null 2>&1 45 (cd ${OBJDIR} && nohup snmpd -dvf ./snmpd.conf > snmpd.log 2>&1) & 46 i=0 47 # wait max ~10s 48 while [ ! -S "$STARTSOCK" ]; do 49 i=$((i + 1)) 50 if [ $i -eq 100 ]; then 51 echo "Failed to start snmpd" >&2 52 snmpdstop 53 fail 54 fi 55 sleep 0.1 56 done 57} 58 59snmpdstop() { 60 pkill snmpd 61 wait 62 rm -f "${STARTSOCK}" >/dev/null 2>&1 63} 64 65cleanup() { 66 rm ${STARTSOCK} >/dev/null 2>&1 67 rm ${TMPFILE} >/dev/null 2>&1 68 rm ${OBJDIR}/nohup.out >/dev/null 2>&1 69 rm ${OBJDIR}/snmpd.log >/dev/null 2>&1 70 rm ${OBJDIR}/snmpd.conf >/dev/null 2>&1 71} 72 73fail() { 74 echo FAILED 75 cleanup 76 exit 1 77} 78 79skip() { 80 echo SKIPPED 81 cleanup 82 exit 0 83} 84 85# # # # # CONFIG ONE # # # # # 86 87echo "\nConfiguration: default community strings, trap receiver, trap handle\n" 88 89cat > ${OBJDIR}/snmpd.conf <<EOF 90# This is config template (1) for snmpd regression testing 91# Restrict daemon to listen on localhost only 92listen on 127.0.0.1 snmpv1 snmpv2c snmpv3 93listen on 127.0.0.1 snmpv2c notify 94listen on ::1 snmpv1 snmpv2c snmpv3 95listen on ::1 snmpv2c notify 96 97agentx path "${STARTSOCK}" 98 99# Specify communities 100read-only community public 101read-write community private 102trap community public 103 104trap handle 1.2.3.4 "/usr/bin/touch ${TMPFILE}" 105EOF 106 107snmpdstart 108 109# pf (also checks "oid all" which obtains privileged kernel data 110 111pf_enabled="$(pfctl -si | grep ^Status | awk '{ print $2 }' | tr [A-Z] [a-z])" 112snmp_command="snmp walk -Oq -v2c -cpublic localhost 1.3" 113echo ======= $snmp_command 114enabled="$(eval $snmp_command | grep -vi parameters | grep -i pfrunning | awk '{ print $2 }')" 115if [ "${PF[$enabled]}" != "${PF[enabled]}" ] 116then 117 if [ "${PF[$enabled]}" != "${PF[disabled]}" ] 118 then 119 echo "Retrieval of pf status failed." 120 FAILED=1 121 fi 122fi 123 124# hostname 125 126sys_name=$(hostname) 127snmp_command="snmp get -Oqv -v2c -cpublic localhost 1.3.6.1.2.1.1.5.0" 128echo ======= $snmp_command 129name="$(eval $snmp_command)" 130if [ "$name" != "$sys_name" ] 131then 132 echo "Retrieval of hostname failed." 133 FAILED=1 134fi 135 136# carp allow 137 138carp="$(sysctl net.inet.carp.allow | awk -F= '{ print $2 }')" 139snmp_command="snmp get -On -v2c -cpublic localhost 1.3.6.1.4.1.30155.6.1.1.0" 140echo ======= $snmp_command 141carp_allow="$(eval $snmp_command)" 142carp_allow="${carp_allow##.1.3.6.1.4.1.30155.6.1.1.0 = INTEGER: }" 143if [ "$carp" -ne "$carp_allow" ] 144then 145 echo "Retrieval of carp.allow failed." 146 FAILED=1 147fi 148 149# carp allow with default ro community string 150 151carp="$(sysctl net.inet.carp.allow | awk -F= '{ print $2 }')" 152snmp_command="snmp getnext -Onq -v2c -cpublic localhost 1.3.6.1.4.1.30155.6.1.1" 153echo ======= $snmp_command 154carp_allow="$(eval $snmp_command)" 155carp_allow="${carp_allow##.1.3.6.1.4.1.30155.6.1.1.0 }" 156if [ "$carp" -ne "$carp_allow" ] 157then 158 echo "Retrieval of carp.allow with default ro community string failed." 159 FAILED=1 160fi 161 162# trap handler with command execution 163 164rm -f ${TMPFILE} 165snmp_command="snmp trap -v2c -cpublic 127.0.0.1 '' 1.2.3.4" 166echo ======= $snmp_command 167eval $snmp_command 168sleep ${SLEEP} 169if [ ! -f "${TMPFILE}" ] 170then 171 echo "Trap handler test failed." 172 FAILED=1 173fi 174 175# system.sysContact set with default rw community string 176 177# Currently no set support in snmpd 178#puffy="puffy@openbsd.org" 179#snmp_command="snmp set -c private -v 1 localhost system.sysContact.0 s $puffy" 180#echo ======= $snmp_command 181#eval $snmp_command > /dev/null 2>&1 182#snmp_command="snmp get -v2c -cpublic localhost 1.3.6.1.2.1.1.4.0" 183#echo ======= $snmp_command 184#contact="$(eval $snmp_command)" 185#contact="${contact##sysContact.0 = STRING: }" 186#if [ "$contact" != "$puffy" ] 187#then 188# echo "Setting with default rw community string failed." 189# FAILED=1 190#fi 191 192snmpdstop 193 194# # # # # CONFIG TWO # # # # # 195echo "\nConfiguration: seclevel auth\n" 196 197cat > ${OBJDIR}/snmpd.conf <<EOF 198# This is config template (2) for snmpd regression testing 199# Restrict daemon to listen on localhost only 200listen on 127.0.0.1 201listen on ::1 202 203agentx path "${STARTSOCK}" 204 205seclevel auth 206 207user "hans" authkey "password123" auth hmac-sha1 208EOF 209 210snmpdstart 211 212# make sure we can't get an oid with deault community string 213 214snmp_command="snmp get -r2 -v2c -cpublic localhost 1.3.6.1.2.1.1.5.0" 215echo ======= $snmp_command 216eval $snmp_command > /dev/null 2>&1 217if [ $? -eq 0 ] 218then 219 echo "Non-defaut ro community string test failed." 220 FAILED=1 221fi 222 223# get with SHA authentication 224 225os="$(uname -s)" 226snmp_command="snmp get -v3 -Oq -l authNoPriv -u hans -a SHA -A password123 \ 227 localhost system.sysDescr.0" 228echo ======= $snmp_command 229system="$(eval $snmp_command | awk '{ print $2 }')" 230if [ "$system" != "$os" ] 231then 232 echo "Retrieval test with seclevel auth and SHA failed." 233 FAILED=1 234fi 235 236snmpdstop 237 238# # # # # CONFIG THREE # # # # # 239echo "\nConfiguration: seclevel enc\n" 240 241cat > ${OBJDIR}/snmpd.conf <<EOF 242# This is config template (3) for snmpd regression testing 243# Restrict daemon to listen on localhost only 244listen on 127.0.0.1 245listen on ::1 246 247agentx path "${STARTSOCK}" 248 249seclevel enc 250 251user "hans" authkey "password123" auth hmac-sha1 enc aes enckey "321drowssap" 252EOF 253 254snmpdstart 255 256# get with SHA authentication and AES encryption 257 258os="$(uname -s)" 259snmp_command="snmp get -v3 -Oq -l authPriv -u hans -a SHA -A password123 -x AES \ 260 -X 321drowssap localhost system.sysDescr.0" 261echo ======= $snmp_command 262system="$(eval $snmp_command | awk '{ print $2 }')" 263if [ "$system" != "$os" ] 264then 265 echo "seclevel auth with SHA failed" 266 FAILED=1 267fi 268 269snmpdstop 270 271# # # # # CONFIG FOUR # # # # # 272echo "\nConfiguration: non-default community strings, custom oids\n" 273 274replacement="$(printf '\357\277\275')" 275oe="$(printf '\303\266')" 276boe="$(printf '\303')" 277cat > ${OBJDIR}/snmpd.conf <<EOF 278# This is config template (4) for snmpd regression testing 279# Restrict daemon to listen on localhost only 280listen on 127.0.0.1 snmpv1 snmpv2c 281listen on ::1 snmpv1 snmpv2c 282 283agentx path "${STARTSOCK}" 284 285read-only community non-default-ro 286 287read-write community non-default-rw 288 289oid 1.3.6.1.4.1.30155.42.1 name myName read-only string "humppa" 290oid 1.3.6.1.4.1.30155.42.2 name myStatus read-only integer 1 291# No need to place a full index, we just need the object 292EOF 293 294snmpdstart 295 296# carp allow with non-default ro community string 297 298carp="$(sysctl net.inet.carp.allow | awk -F= '{ print $2 }')" 299snmp_command="snmp get -OfQ -v2c -c non-default-ro localhost \ 300 1.3.6.1.4.1.30155.6.1.1.0" 301echo ======= $snmp_command 302carp_allow="$(eval $snmp_command)" 303carp_allow="${carp_allow##.iso.org.dod.internet.private.enterprises.openBSD.carpMIBObjects.carpSysctl.carpAllow.0 = }" 304if [ "$carp" -ne "$carp_allow" ] 305then 306 echo "Retrieval test with default ro community string failed." 307 FAILED=1 308fi 309 310# system.sysContact set with non-default rw/ro community strings 311 312# Currently no set support in snmpd 313#puffy="puffy@openbsd.org" 314#snmp_command="snmp set -c non-default-rw -v 1 localhost system.sysContact.0 \ 315# s $puffy" 316#echo ======= $snmp_command 317#eval $snmp_command > /dev/null 2>&1 318#snmp_command="snmp get -Oqv -v2c -cnon-default-ro localhost 1.3.6.1.2.1.1.4.0" 319#echo ======= $snmp_command 320#contact="$(eval $snmp_command)" 321#if [ "$contact" != "$puffy" ] 322#then 323# echo "Setting with default rw community string failed." 324# FAILED=1 325#fi 326 327# custom oids, with a ro that we should not be able to set 328 329snmp_command="snmp get -Oqv -v2c -cnon-default-rw localhost \ 330 1.3.6.1.4.1.30155.42.1.0" 331echo ======= $snmp_command 332string="$(eval $snmp_command)" 333if [ "$string" != "humppa" ] 334then 335 echo "couldn't get customer oid string" 336 FAILED=1 337fi 338 339snmp_command="snmp get -Oqv -v2c -c non-default-rw localhost \ 340 1.3.6.1.4.1.30155.42.2.0" 341echo ======= $snmp_command 342integer="$(eval $snmp_command)" 343if [ $integer -ne 1 ] 344then 345 echo "Retrieval of customer oid integer failed." 346 FAILED=1 347fi 348 349# Currently no set support in snmpd 350#snmp_command="snmp set -c non-default-rw -v 1 localhost \ 351# 1.3.6.1.4.1.30155.42.1.0 s \"bula\"" 352#echo ======= $snmp_command 353#eval $snmp_command > /dev/null 2>&1 354#if [ $? -eq 0 ] 355#then 356# echo "Setting of a ro custom oid test unexpectedly succeeded." 357# FAILED=1 358#fi 359 360snmpdstop 361 362case $FAILED in 3630) echo 364 cleanup 365 exit 0 366 ;; 3671) fail 368 ;; 369esac 370