xref: /openbsd-src/regress/usr.sbin/snmpd/snmpd.sh (revision b00180234d84f197e5597c02aa033eeb104c024d)
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