Files
packages/net/net-snmp/files/snmpd.init
Eric McDonald 93983e5b2a net-snmp: fix literal string test in snmpd_sink_add
The function snmpd_sink_add() has a guard clause that tests the literal
string "section", not the variable value "$section".

The test `[ -n "section" ]` always evaluates to true because the string
literal "section" is non-empty, making the check useless.

This function is only called internally with hardcoded arguments, so the
bug has no actual impact currently. For the same reason, this change
should not break existing configurations. However, I think it should be
fixed so future callers do not have a false sense of security.

Signed-off-by: Eric McDonald <librick-openwrt@proton.me>
2025-12-14 23:52:39 +02:00

474 lines
12 KiB
Bash

#!/bin/sh /etc/rc.common
# Copyright (C) 2008 OpenWrt.org
START=99
USE_PROCD=1
PROG="/usr/sbin/snmpd"
CONFIGFILE="/var/run/snmpd.conf"
snmpd_agent_add() {
local cfg="$1"
config_get agentaddress "$cfg" agentaddress
[ -n "$agentaddress" ] || return 0
echo "agentaddress $agentaddress" >> $CONFIGFILE
}
snmpd_agentx_add() {
local cfg="$1"
echo "master agentx" >> $CONFIGFILE
config_get agentxsocket "$cfg" agentxsocket
[ -n "$agentxsocket" ] && echo "agentXSocket $agentxsocket" >> $CONFIGFILE
}
snmpd_system_add() {
local cfg="$1"
local hostname
config_get syslocation "$cfg" sysLocation
[ -n "$syslocation" ] && echo "sysLocation $syslocation" >> $CONFIGFILE
config_get syscontact "$cfg" sysContact
[ -n "$syscontact" ] && echo "sysContact $syscontact" >> $CONFIGFILE
config_get sysname "$cfg" sysName
[ -n "$sysname" ] && echo "sysName $sysname" >> $CONFIGFILE
[ -z "$sysname" ] && hostname=$(uci_get system.@system[0].hostname) && echo "sysName $hostname" >> $CONFIGFILE
config_get sysservice "$cfg" sysService
[ -n "$sysservice" ] && echo "sysService $sysservice" >> $CONFIGFILE
config_get sysdescr "$cfg" sysDescr
[ -n "$sysdescr" ] && echo "sysDescr $sysdescr" >> $CONFIGFILE
config_get sysobjectid "$cfg" sysObjectID
[ -n "$sysobjectid" ] && echo "sysObjectID $sysobjectid" >> $CONFIGFILE
}
snmpd_com2sec_add() {
local cfg="$1"
config_get secname "$cfg" secname
[ -n "$secname" ] || return 0
config_get source "$cfg" source
[ -n "$source" ] || return 0
config_get community "$cfg" community
[ -n "$community" ] || return 0
echo "com2sec $secname $source $community" >> $CONFIGFILE
}
snmpd_com2sec6_add() {
local cfg="$1"
config_get secname "$cfg" secname
[ -n "$secname" ] || return 0
config_get source "$cfg" source
[ -n "$source" ] || return 0
config_get community "$cfg" community
[ -n "$community" ] || return 0
echo "com2sec6 $secname $source $community" >> $CONFIGFILE
}
snmpd_group_add() {
local cfg="$1"
config_get group "$cfg" group
[ -n "$group" ] || return 0
config_get version "$cfg" version
[ -n "$version" ] || return 0
config_get secname "$cfg" secname
[ -n "$secname" ] || return 0
echo "group $group $version $secname" >> $CONFIGFILE
}
snmpd_view_add() {
local cfg="$1"
config_get viewname "$cfg" viewname
[ -n "$viewname" ] || return 0
config_get type "$cfg" type
[ -n "$type" ] || return 0
config_get oid "$cfg" oid
[ -n "$oid" ] || return 0
# optional mask
config_get mask "$cfg" mask
echo "view $viewname $type $oid $mask" >> $CONFIGFILE
}
snmpd_access_add() {
local cfg="$1"
config_get group "$cfg" group
[ -n "$group" ] || return 0
config_get context "$cfg" context
[ -n $context ] || return 0
[ "$context" == "none" ] && context='""'
config_get version "$cfg" version
[ -n "$version" ] || return 0
config_get level "$cfg" level
[ -n "$level" ] || return 0
config_get prefix "$cfg" prefix
[ -n "$prefix" ] || return 0
config_get read "$cfg" read
[ -n "$read" ] || return 0
config_get write "$cfg" write
[ -n "$write" ] || return 0
config_get notify "$cfg" notify
[ -n "$notify" ] || return 0
echo "access $group $context $version $level $prefix $read $write $notify" >> $CONFIGFILE
}
snmpd_trap_hostname_add() {
local cfg="$1"
config_get hostname "$cfg" HostName
config_get port "$cfg" Port
config_get community "$cfg" Community
config_get type "$cfg" Type
echo "$type $hostname $community $port" >> $CONFIGFILE
}
snmpd_trap_ip_add() {
local cfg="$1"
config_get host_ip "$cfg" HostIP
config_get port "$cfg" Port
config_get community "$cfg" Community
config_get type "$cfg" Type
echo "$type $host_ip $community $port" >> $CONFIGFILE
}
snmpd_access_default_add() {
local cfg="$1"
config_get mode "$cfg" Mode
config_get community "$cfg" CommunityName
config_get oidrestrict "$cfg" RestrictOID
config_get oid "$cfg" RestrictedOID
echo -n "$mode $community default" >> $CONFIGFILE
[ "$oidrestrict" == "yes" ] && echo " $oid" >> $CONFIGFILE
[ "$oidrestrict" == "no" ] && echo "" >> $CONFIGFILE
}
snmpd_access_HostName_add() {
local cfg="$1"
config_get hostname "$cfg" HostName
config_get mode "$cfg" Mode
config_get community "$cfg" CommunityName
config_get oidrestrict "$cfg" RestrictOID
config_get oid "$cfg" RestrictedOID
echo -n "$mode $community $hostname" >> $CONFIGFILE
[ "$oidrestrict" == "yes" ] && echo " $oid" >> $CONFIGFILE
[ "$oidrestrict" == "no" ] && echo "" >> $CONFIGFILE
}
snmpd_access_HostIP_add() {
local cfg="$1"
config_get host_ip "$cfg" HostIP
config_get ip_mask "$cfg" IPMask
config_get mode "$cfg" Mode
config_get community "$cfg" CommunityName
config_get oidrestrict "$cfg" RestrictOID
config_get oid "$cfg" RestrictedOID
echo -n "$mode $community $host_ip/$ip_mask" >> $CONFIGFILE
[ "$oidrestrict" == "yes" ] && echo " $oid" >> $CONFIGFILE
[ "$oidrestrict" == "no" ] && echo "" >> $CONFIGFILE
}
snmpd_pass_add() {
local cfg="$1"
local pass='pass'
config_get miboid "$cfg" miboid
[ -n "$miboid" ] || return 0
config_get prog "$cfg" prog
[ -n "$prog" ] || return 0
config_get_bool persist "$cfg" persist 0
[ $persist -ne 0 ] && pass='pass_persist'
config_get priority "$cfg" priority
priority=${priority:+-p $priority}
echo "$pass $priority $miboid $prog" >> $CONFIGFILE
}
snmpd_exec_add() {
local cfg="$1"
config_get name "$cfg" name
[ -n "$name" ] || return 0
config_get prog "$cfg" prog
[ -n "$prog" ] || return 0
config_get args "$cfg" args
config_get miboid "$cfg" miboid
echo "exec $miboid $name $prog $args" >> $CONFIGFILE
}
snmpd_extend_add() {
local cfg="$1"
config_get name "$cfg" name
[ -n "$name" ] || return 0
config_get prog "$cfg" prog
[ -n "$prog" ] || return 0
config_get args "$cfg" args
config_get miboid "$cfg" miboid
echo "extend $miboid $name $prog $args" >> $CONFIGFILE
}
snmpd_disk_add() {
local cfg="$1"
local disk='disk'
config_get partition "$cfg" partition
[ -n "$partition" ] || return 0
config_get size "$cfg" size
[ -n "$size" ] || return 0
echo "$disk $partition $size" >> $CONFIGFILE
}
snmpd_engineid_add() {
local cfg="$1"
config_get engineid "$cfg" engineid
[ -n "$engineid" ] && echo "engineID $engineid" >> $CONFIGFILE
config_get engineidtype "$cfg" engineidtype
[ "$engineidtype" -ge 1 -a "$engineidtype" -le 3 ] && \
echo "engineIDType $engineidtype" >> $CONFIGFILE
config_get engineidnic "$cfg" engineidnic
[ -n "$engineidnic" ] && echo "engineIDNic $engineidnic" >> $CONFIGFILE
}
snmpd_sink_add() {
local cfg="$1"
local section="$2"
local community
local port
local host
config_get host "$cfg" host
[ -n "$section" -a -n "$host" ] || return 0
# optional community
config_get community "$cfg" community
# optional port
config_get port "$cfg" port
port=${port:+:$port}
echo "$section $host$port $community" >> $CONFIGFILE
}
snmpd_snmpv3_add() {
local cfg="$1"
local cfg2="$2"
local version
local username
local auth_type
local auth_pass
local privacy_type
local privacy_pass
local allow_write
local oid
config_get version "$cfg2" snmp_version
if [ "$version" != "v1/v2c/v3" ] && [ "$version" != "v3" ]; then
echo "skipping section '$cfg' wrong 'snmp_version=$version' configured"
return 0
fi
config_get username "$cfg" username
[ -n "$username" ] || {
echo "skipping section '$cfg' 'username' missing"
return 0
}
config_get auth_pass "$cfg" auth_pass
config_get oid "$cfg" RestrictedOID
config_get_bool allow_write "$cfg" allow_write 0
local useraccess="rouser"
[ "$allow_write" -eq 1 ] && useraccess="rwuser"
if [ -z "$auth_pass" ]; then
echo "createUser $username" >> "$CONFIGFILE"
echo "$useraccess $username noauth $oid" >> "$CONFIGFILE"
return
fi
[ "${#auth_pass}" -lt 8 ] && {
echo "skipping section '$cfg' 'auth_pass' requires a min length of 8"
return 0
}
config_get auth_type "$cfg" auth_type
[ -z "$auth_type" ] && {
echo "skipping section '$cfg' 'auth_type' missing"
return 0
}
config_get privacy_type "$cfg" privacy_type
config_get privacy_pass "$cfg" privacy_pass
if [ -n "$privacy_type" ] && [ -n "$privacy_pass" ]; then
[ "${#privacy_pass}" -lt 8 ] && {
echo "skipping section '$cfg' 'privacy_pass' requires a min length of 8"
return 0
}
echo "createUser $username $auth_type \"$auth_pass\" $privacy_type \"$privacy_pass\"" >> "$CONFIGFILE"
echo "$useraccess $username priv $oid" >> "$CONFIGFILE"
else
echo "createUser $username $auth_type \"$auth_pass\"" >> "$CONFIGFILE"
echo "$useraccess $username auth $oid" >> "$CONFIGFILE"
fi
}
append_parm() {
local section="$1"
local option="$2"
local switch="$3"
local _loctmp
config_get _loctmp "$section" "$option"
[ -z "$_loctmp" ] && return 0
echo "$switch $_loctmp" >> $CONFIGFILE
}
append_authtrapenable() {
local section="$1"
local option="$2"
local switch="$3"
local _loctmp
config_get_bool _loctmp "$section" "$option"
[ -z "$_loctmp" ] && return 0
[ "$_loctmp" -gt 0 ] && echo "$switch $_loctmp" >> $CONFIGFILE
}
snmpd_setup_fw_rules() {
local net="$1"
local zone
zone=$(fw3 -q network "$net" 2>/dev/null)
local handled_zone
for handled_zone in $HANDLED_SNMP_ZONES; do
[ "$handled_zone" = "$zone" ] && return
done
json_add_object ""
json_add_string type rule
json_add_string src "$zone"
json_add_string proto udp
json_add_string dest_port 161
json_add_string target ACCEPT
json_close_object
HANDLED_SNMP_ZONES="$HANDLED_SNMP_ZONES $zone"
}
snmpd_configure_logging() {
local cfg="$1"
local log_syslog
local log_syslog_facility
local log_file
local log_file_priority
config_get_bool log_syslog "$cfg" log_syslog 0
# d - LOG_DAEMON,
# u - LOG_USER,
# 0-7 - LOG_LOCAL0 through LOG_LOCAL7.
# 0 or ! - LOG_EMERG
# 1 or a - LOG_ALERT
# 2 or c - LOG_CRIT
# 3 or e - LOG_ERR
# 4 or w - LOG_WARN
# 5 or n - LOG_NOTICE
# 6 or i - LOG_INFO
# 7 or d - LOG_DEBUG
if [ $log_syslog -eq 1 ]; then
config_get log_syslog_facility "$cfg" log_syslog_facility "d"
procd_append_param command -Ls "${log_syslog_facility}"
fi
config_get log_file "$cfg" log_file
if [ -n "$log_file" ]; then
config_get log_file_priority "$cfg" log_file_priority "i"
mkdir -p "$(dirname "${log_file}")"
procd_append_param command -LF "${log_file_priority} ${log_file}"
fi
if [ "$log_syslog" -eq 0 ] && [ -z "$log_file" ]; then
procd_append_param command -Lf /dev/null
fi
}
start_service() {
[ -f "$CONFIGFILE" ] && rm -f "$CONFIGFILE"
config_load snmpd
config_get_bool snmp_enabled general enabled 1
[ "$snmp_enabled" -eq 0 ] && return
local pid_file="/var/run/snmpd.pid"
procd_open_instance
config_foreach snmpd_agent_add agent
config_foreach snmpd_agentx_add agentx
config_foreach snmpd_system_add system
config_foreach snmpd_com2sec_add com2sec
config_foreach snmpd_com2sec6_add com2sec6
config_foreach snmpd_group_add group
config_foreach snmpd_view_add view
config_foreach snmpd_access_add access
config_foreach snmpd_trap_hostname_add trap_HostName
config_foreach snmpd_trap_ip_add trap_HostIP
config_foreach snmpd_access_default_add access_default
config_foreach snmpd_access_HostName_add access_HostName
config_foreach snmpd_access_HostIP_add access_HostIP
config_foreach snmpd_pass_add pass
config_foreach snmpd_exec_add exec
config_foreach snmpd_extend_add extend
config_foreach snmpd_disk_add disk
config_foreach snmpd_engineid_add engineid
append_parm trapcommunity community trapcommunity
config_foreach snmpd_sink_add trapsink trapsink
config_foreach snmpd_sink_add trap2sink trap2sink
config_foreach snmpd_sink_add informsink informsink
append_authtrapenable authtrapenable enable authtrapenable
append_parm v1trapaddress host v1trapaddress
append_parm trapsess trapsess trapsess
config_foreach snmpd_snmpv3_add v3 general
procd_set_param command $PROG -f -r -p "$pid_file"
procd_append_param command -C -c "$CONFIGFILE"
config_foreach snmpd_configure_logging log
procd_set_param respawn
for iface in $(ls /sys/class/net 2>/dev/null); do
procd_append_param netdev "$iface"
done
procd_open_data
json_add_array firewall
config_list_foreach general network snmpd_setup_fw_rules
json_close_array
procd_close_data
procd_close_instance
}
service_stopped() {
[ -f "$CONFIGFILE" ] || return
rm -f "$CONFIGFILE"
procd_set_config_changed firewall
}
service_triggers(){
local script=$(readlink "$initscript")
local name=$(basename ${script:-$initscript})
procd_open_trigger
procd_add_raw_trigger "interface.*" 2000 /etc/init.d/$name reload
procd_close_trigger
procd_add_reload_trigger 'snmpd' 'system'
}
service_started() {
[ "$snmp_enabled" -eq 0 ] && return
procd_set_config_changed firewall
}