mirror of
https://github.com/kernelkit/infix.git
synced 2026-08-07 07:53:18 +02:00
board/common: only apply explicitly requested DHCP options in client
Validate that DHCP options were requested in the parameter request list before applying them. This prevents malicious or misconfigured DHCP servers from forcing unwanted configuration changes. Validates: hostname (12), DNS (6), domain (15), search (119), router (3), static routes (121), and NTP (42). Fail-safe behavior: rejects options if config file unavailable. Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
@@ -50,6 +50,26 @@ wait_for_ipv6_default_route()
|
||||
err "Timed out waiting for IPv6 default route!"
|
||||
}
|
||||
|
||||
# Check if a DHCP option was requested in the parameter request list
|
||||
# Returns: 0 if requested, 1 if not requested or config unavailable
|
||||
was_option_requested()
|
||||
{
|
||||
local opt_num="$1"
|
||||
local config="/etc/finit.d/available/dhcp-client-${interface}.conf"
|
||||
|
||||
if [ ! -f "$config" ]; then
|
||||
dbg "config file not found: $config"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Extract udhcpc command line and check for -O <option_num>
|
||||
if grep -q -- "-O ${opt_num}\b" "$config"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
return 1
|
||||
}
|
||||
|
||||
# RFC3442: If the DHCP server returns both a Classless
|
||||
# Static Routes option and a Router option, the DHCP
|
||||
# client MUST ignore the Router option.
|
||||
@@ -57,17 +77,25 @@ set_dhcp_routes()
|
||||
{
|
||||
echo "! Generated by udhcpc" > "$NEXT"
|
||||
if [ -n "$staticroutes" ]; then
|
||||
# format: dest1/mask gw1 ... destn/mask gwn
|
||||
set -- $staticroutes
|
||||
while [ -n "$1" -a -n "$2" ]; do
|
||||
dbg "adding route $1 via $2 metric $metric tag 100"
|
||||
echo "ip route $1 $2 $metric tag 100" >> "$NEXT"
|
||||
shift 2
|
||||
done
|
||||
if was_option_requested 121; then
|
||||
# format: dest1/mask gw1 ... destn/mask gwn
|
||||
set -- $staticroutes
|
||||
while [ -n "$1" -a -n "$2" ]; do
|
||||
dbg "adding route $1 via $2 metric $metric tag 100"
|
||||
echo "ip route $1 $2 $metric tag 100" >> "$NEXT"
|
||||
shift 2
|
||||
done
|
||||
else
|
||||
log "ignoring unrequested staticroutes (option 121)"
|
||||
fi
|
||||
elif [ -n "$router" ] ; then
|
||||
for i in $router ; do
|
||||
echo "ip route 0.0.0.0/0 $i $metric tag 100" >> "$NEXT"
|
||||
done
|
||||
if was_option_requested 3; then
|
||||
for i in $router ; do
|
||||
echo "ip route 0.0.0.0/0 $i $metric tag 100" >> "$NEXT"
|
||||
done
|
||||
else
|
||||
log "ignoring unrequested router (option 3)"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Reduce changes needed by comparing with previous route(s)
|
||||
@@ -109,8 +137,9 @@ case "$ACTION" in
|
||||
rm -f "$RESOLV_CONF"
|
||||
rm -f "$NTPFILE"
|
||||
if [ -f "/etc/hostname.d/90-dhcp-${interface}" ]; then
|
||||
rm -f "/etc/hostname.d/90-dhcp-${interface}"
|
||||
/usr/libexec/infix/hostname dhcp
|
||||
log "removing /etc/hostname.d/90-dhcp-${interface}"
|
||||
rm -f "/etc/hostname.d/90-dhcp-${interface}"
|
||||
/usr/libexec/infix/hostname dhcp
|
||||
fi
|
||||
if [ -x /usr/sbin/avahi-autoipd ]; then
|
||||
/usr/sbin/avahi-autoipd -c $interface && /usr/sbin/avahi-autoipd -k $interface
|
||||
@@ -137,22 +166,35 @@ case "$ACTION" in
|
||||
|
||||
set_dhcp_routes
|
||||
|
||||
# set hostname if given
|
||||
# set hostname if given and requested
|
||||
if [ -n "$hostname" ]; then
|
||||
log "received DHCP hostname: $hostname"
|
||||
mkdir -p /etc/hostname.d
|
||||
echo "$hostname" > "/etc/hostname.d/90-dhcp-${interface}"
|
||||
/usr/libexec/infix/hostname dhcp
|
||||
if was_option_requested 12; then
|
||||
log "received DHCP hostname: $hostname"
|
||||
mkdir -p /etc/hostname.d
|
||||
echo "$hostname" > "/etc/hostname.d/90-dhcp-${interface}"
|
||||
/usr/libexec/infix/hostname dhcp
|
||||
else
|
||||
log "ignoring unrequested hostname (option 12): $hostname"
|
||||
fi
|
||||
fi
|
||||
|
||||
# drop info from this interface
|
||||
truncate -s 0 "$RESOLV_CONF"
|
||||
|
||||
# prefer rfc3397 domain search list (option 119) if available
|
||||
search_list=""
|
||||
if [ -n "$search" ]; then
|
||||
search_list=$search
|
||||
if was_option_requested 119; then
|
||||
search_list=$search
|
||||
else
|
||||
log "ignoring unrequested search (option 119): $search"
|
||||
fi
|
||||
elif [ -n "$domain" ]; then
|
||||
search_list=$domain
|
||||
if was_option_requested 15; then
|
||||
search_list=$domain
|
||||
else
|
||||
log "ignoring unrequested domain (option 15): $domain"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "$search_list" ]; then
|
||||
@@ -160,19 +202,29 @@ case "$ACTION" in
|
||||
echo "search $search_list # $interface" >> $RESOLV_CONF
|
||||
fi
|
||||
|
||||
for i in $dns ; do
|
||||
dbg "adding dns $i"
|
||||
echo "nameserver $i # $interface" >> $RESOLV_CONF
|
||||
resolvconf -u
|
||||
done
|
||||
if [ -n "$dns" ]; then
|
||||
if was_option_requested 6; then
|
||||
for i in $dns ; do
|
||||
dbg "adding dns $i"
|
||||
echo "nameserver $i # $interface" >> $RESOLV_CONF
|
||||
resolvconf -u
|
||||
done
|
||||
else
|
||||
log "ignoring unrequested dns (option 6): $dns"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -n "$ntpsrv" ]; then
|
||||
truncate -s 0 "$NTPFILE"
|
||||
for srv in $ntpsrv; do
|
||||
dbg "got NTP server $srv"
|
||||
echo "server $srv iburst" >> "$NTPFILE"
|
||||
done
|
||||
chronyc reload sources >/dev/null
|
||||
if was_option_requested 42; then
|
||||
truncate -s 0 "$NTPFILE"
|
||||
for srv in $ntpsrv; do
|
||||
dbg "got NTP server $srv"
|
||||
echo "server $srv iburst" >> "$NTPFILE"
|
||||
done
|
||||
chronyc reload sources >/dev/null
|
||||
else
|
||||
log "ignoring unrequested ntpsrv (option 42): $ntpsrv"
|
||||
fi
|
||||
fi
|
||||
esac
|
||||
|
||||
|
||||
Reference in New Issue
Block a user