Drop arguement config_counterpart from append_config_option(). append_config_option took an additional argument named config_counterpart which represents the configuration name in configfile.This is needed for configuration variable names isn't the same as in uci. Nodogsplash ignores the case of configuration variables and makes this feature optional. Introduce new func append_config_option_map() which does the old behaviour.
396 lines
11 KiB
Bash
Executable file
396 lines
11 KiB
Bash
Executable file
#!/bin/sh /etc/rc.common
|
|
#
|
|
# description: Startup/shutdown script for nodogsplash captive portal
|
|
#
|
|
# Alexander Couzens <lynxis@fe80.eu> 2014
|
|
# P. Kube 2007
|
|
#
|
|
# (Based on wifidog startup script
|
|
# Date : 2004-08-25
|
|
# Version : 1.0
|
|
# Comment by that author: Could be better, but it's working as expected)
|
|
#
|
|
|
|
START=95
|
|
STOP=95
|
|
|
|
USE_PROCD=1
|
|
|
|
IPT=/usr/sbin/iptables
|
|
WD_DIR=/usr/bin
|
|
# -s -d 5 runs in background, with level 5 (not so verbose) messages to syslog
|
|
# -f -d 7 runs in foreground, with level 7 (verbose) debug messages to terminal
|
|
OPTIONS="-s -f -d 5"
|
|
CONFIGFILE="/tmp/invalid_nodogsplash.conf"
|
|
|
|
# nolog(loglevel message ...)
|
|
nolog() {
|
|
local level=$1
|
|
shift
|
|
logger -s -t nodogsplash -p daemon.$level $@
|
|
}
|
|
|
|
# append_config_option_map <cfgfile> <uci_cfg_obj> <option_name> <config_counterpart> [<optional default>]
|
|
# append "$config_counterpart $value" to cfgfile if option_name exists
|
|
# e.g. append_config_option "$CONFIGFILE" "$cfg" bind_address BindAddress 0.0.0.0
|
|
# will append "BindAddress 192.168.1.1" if uci bind_address is '192.168.1.1'
|
|
append_config_option_map() {
|
|
local val=""
|
|
local config_file="$1"
|
|
local cfg="$2"
|
|
local option_name="$3"
|
|
local config_counterpart="$4"
|
|
local default="$5"
|
|
config_get val "$cfg" "$option_name" "$default"
|
|
[ -n "$val" ] && echo "$config_counterpart $val" >> $config_file
|
|
}
|
|
|
|
# append_config_option <cfgfile> <uci_cfg_obj> <option_name> [<optional default>]
|
|
# append "$option_name $value" to cfgfile if option_name exists
|
|
# e.g. append_config_option "$CONFIGFILE" "$cfg" bind_address 0.0.0.0
|
|
# will append "bind_address 192.168.1.1" if uci bind_address is '192.168.1.1'
|
|
# if uci bind_address is unset append "bind_address 0.0.0.0"
|
|
append_config_option() {
|
|
local val=""
|
|
local config_file="$1"
|
|
local cfg="$2"
|
|
local option_name="$3"
|
|
local default="$4"
|
|
config_get val "$cfg" "$option_name" "$default"
|
|
[ -n "$val" ] && echo "$option_name $val" >> $config_file
|
|
}
|
|
|
|
setup_user_authentication() {
|
|
local cfg="$1"
|
|
local val
|
|
|
|
config_get_bool val "$cfg" authenticate_immediately 0
|
|
[ $val -gt 0 ] && echo "AuthenticateImmediately yes" >> $CONFIGFILE
|
|
|
|
config_get val "$cfg" username
|
|
if [ -n "$val" ] ; then
|
|
echo "UsernameAuthentication" >> $CONFIGFILE
|
|
echo "Username $val" >> $CONFIGFILE
|
|
fi
|
|
|
|
config_get val "$cfg" password
|
|
if [ -n "$val" ] ; then
|
|
echo "PasswordAuthentication" >> $CONFIGFILE
|
|
echo "Password $val" >> $CONFIGFILE
|
|
fi
|
|
}
|
|
|
|
setup_mac_lists() {
|
|
local cfg="$1"
|
|
local MAC=""
|
|
local val
|
|
|
|
append_mac() {
|
|
append MAC "$1" ","
|
|
}
|
|
|
|
config_get val "$cfg" macmechanism
|
|
if [ -z "$val" ] ; then
|
|
# check if we have AllowedMACList or BlockedMACList defined they will be ignored
|
|
config_get val "$cfg" allowedmac
|
|
if [ -n "$val" ] ; then
|
|
echo "Ignoring allowedmac - macmechanism not \"allow\"" >&2
|
|
fi
|
|
|
|
config_get val "$cfg" blockedmac
|
|
if [ -n "$val" ] ; then
|
|
echo "Ignoring blockedmac - macmechanism not \"block\"" >&2
|
|
fi
|
|
elif [ "$val" == "allow" ] ; then
|
|
MAC=""
|
|
config_list_foreach "$cfg" allowedmac append_mac
|
|
echo "AllowedMACList $MAC" >> $CONFIGFILE
|
|
elif [ "$val" == "block" ] ; then
|
|
MAC=""
|
|
config_list_foreach "$cfg" blockedmac append_mac
|
|
echo "BlockedMACList $MAC" >> $CONFIGFILE
|
|
else
|
|
nolog error "$cfg Invalid macmechanism '$val' - allow or block are valid."
|
|
return 1
|
|
fi
|
|
MAC=""
|
|
config_list_foreach "$cfg" trustedmac append_mac
|
|
[ -n "$MAC" ] && echo "TrustedMACList $MAC" >> $CONFIGFILE
|
|
}
|
|
|
|
setup_firewall() {
|
|
local cfg="$1"
|
|
local uciname
|
|
local val
|
|
|
|
append_firewall() {
|
|
echo " FirewallRule $1" >> $CONFIGFILE
|
|
}
|
|
|
|
for rule in $(echo authenticated-users preauthenticated-users users-to-router trusted-users trusted-users-to-router)
|
|
do
|
|
uci_name=${rule//-/_}
|
|
# uci does not allow - dashes
|
|
echo "FirewallRuleSet $rule {" >> $CONFIGFILE
|
|
config_list_foreach "$cfg" ${uci_name} append_firewall
|
|
echo "}" >> $CONFIGFILE
|
|
config_get val "$cfg" policy_${uci_name}
|
|
[ -n "$val" ] && echo "EmptyRuleSetPolicy $rule $val" >> $CONFIGFILE
|
|
done
|
|
}
|
|
|
|
generate_uci_config() {
|
|
local cfg="$1"
|
|
local val
|
|
local ifname
|
|
local download
|
|
local upload
|
|
|
|
CONFIGFILE="/tmp/etc/nodogsplash_$cfg.conf"
|
|
|
|
echo "# auto-generated config file from /etc/config/nodogsplash" > $CONFIGFILE
|
|
|
|
config_get val "$cfg" config
|
|
if [ -n "$val" ] ; then
|
|
if [ -f "$val" ] ; then
|
|
nolog error "Configuration file '$file' doesn't exist"
|
|
return 0
|
|
fi
|
|
cat $val > CONFIGFILE
|
|
fi
|
|
|
|
config_get val "$cfg" network
|
|
if [ -n "$val" ] ; then
|
|
if ! network_get_device ifname "$val" ; then
|
|
nolog error "$cfg can not find ifname for network '$val'"
|
|
return 1
|
|
fi
|
|
fi
|
|
|
|
config_get val "$cfg" gatewayinterface
|
|
if [ -n "$val" ] ; then
|
|
if [ -n "$ifname" ] ; then
|
|
nolog error "$cfg cannot use both option network and gatewayinterface"
|
|
return 1
|
|
fi
|
|
ifname="$val"
|
|
fi
|
|
|
|
if [ -z "$ifname" ] ; then
|
|
nolog error "$cfg option network or gatewayinterface missing"
|
|
return 1
|
|
fi
|
|
|
|
echo "GatewayInterface $ifname" >> $CONFIGFILE
|
|
|
|
append_config_option "$CONFIGFILE" "$cfg" gatewayname
|
|
append_config_option "$CONFIGFILE" "$cfg" gatewayaddress
|
|
append_config_option "$CONFIGFILE" "$cfg" gatewayport
|
|
append_config_option "$CONFIGFILE" "$cfg" maxclients
|
|
append_config_option "$CONFIGFILE" "$cfg" webroot
|
|
append_config_option "$CONFIGFILE" "$cfg" debuglevel
|
|
append_config_option "$CONFIGFILE" "$cfg" splashpage
|
|
append_config_option "$CONFIGFILE" "$cfg" pagesdir
|
|
append_config_option "$CONFIGFILE" "$cfg" checkinterval
|
|
append_config_option "$CONFIGFILE" "$cfg" syslogfacility
|
|
append_config_option "$CONFIGFILE" "$cfg" gatewayiprange
|
|
append_config_option "$CONFIGFILE" "$cfg" imagedir
|
|
append_config_option "$CONFIGFILE" "$cfg" redirecturl
|
|
append_config_option "$CONFIGFILE" "$cfg" clientidletimeout
|
|
append_config_option "$CONFIGFILE" "$cfg" clientforcetimeout
|
|
append_config_option "$CONFIGFILE" "$cfg" gatewayiprange
|
|
append_config_option "$CONFIGFILE" "$cfg" passwordattempts
|
|
append_config_option "$CONFIGFILE" "$cfg" macmechanism
|
|
append_config_option "$CONFIGFILE" "$cfg" uploadlimit
|
|
append_config_option "$CONFIGFILE" "$cfg" downloadlimit
|
|
append_config_option "$CONFIGFILE" "$cfg" remoteauthenticatoraction
|
|
append_config_option "$CONFIGFILE" "$cfg" enablepreauth
|
|
append_config_option "$CONFIGFILE" "$cfg" binvoucher
|
|
append_config_option "$CONFIGFILE" "$cfg" forcevoucher
|
|
append_config_option "$CONFIGFILE" "$cfg" passwordauthentication
|
|
append_config_option "$CONFIGFILE" "$cfg" usernameauthentication
|
|
append_config_option "$CONFIGFILE" "$cfg" passwordattempts
|
|
append_config_option "$CONFIGFILE" "$cfg" username
|
|
append_config_option "$CONFIGFILE" "$cfg" password
|
|
append_config_option "$CONFIGFILE" "$cfg" authenticateimmediately
|
|
append_config_option "$CONFIGFILE" "$cfg" decongesthttpdthreads
|
|
append_config_option "$CONFIGFILE" "$cfg" httpdthreadthreshold
|
|
append_config_option "$CONFIGFILE" "$cfg" httpdthreaddelayms
|
|
append_config_option "$CONFIGFILE" "$cfg" fw_mark_authenticated
|
|
append_config_option "$CONFIGFILE" "$cfg" fw_mark_trusted
|
|
append_config_option "$CONFIGFILE" "$cfg" fw_mark_blocked
|
|
|
|
config_get download "$cfg" downloadlimit
|
|
config_get upload "$cfg" uploadlimit
|
|
[ -n "$upload" -o -n "$download" ] && echo "TrafficControl yes" >> $CONFIGFILE
|
|
|
|
setup_mac_lists "$cfg"
|
|
setup_user_authentication "$cfg"
|
|
setup_firewall "$cfg"
|
|
}
|
|
|
|
# setup configuration and start instance
|
|
create_instance() {
|
|
local cfg="$1"
|
|
local manual_config
|
|
local val
|
|
|
|
config_get_bool val "$cfg" enabled 0
|
|
[ $val -gt 0 ] || return 0
|
|
|
|
generate_uci_config "$cfg"
|
|
|
|
if ! test_module ; then
|
|
logger -s -t nodogsplash -p daemon.error "nodogsplash is missing some kernel modules"
|
|
fi
|
|
|
|
procd_open_instance $cfg
|
|
procd_set_param command /usr/bin/nodogsplash -c $CONFIGFILE $OPTIONS
|
|
procd_set_param respawn
|
|
procd_set_param file $CONFIGFILE
|
|
procd_close_instance
|
|
}
|
|
|
|
start_service() {
|
|
include /lib/functions
|
|
|
|
mkdir -p /tmp/etc/
|
|
config_load nodogsplash
|
|
|
|
config_foreach create_instance instance
|
|
}
|
|
|
|
stop_service() {
|
|
# nodogsplash doesn't exit fast enought, when procd terminates it.
|
|
# otherwise procd will restart nodogsplash twice. first time starting nodogsplash fails, second time it succeeds
|
|
sleep 1
|
|
}
|
|
|
|
status() {
|
|
$WD_DIR/ndsctl status
|
|
}
|
|
|
|
# Test if we got all modules loaded
|
|
test_module() {
|
|
### Test ipt_mark with iptables
|
|
test_ipt_mark () {
|
|
($IPT -A FORWARD -m mark --mark 2 -j ACCEPT 2>&1) > /dev/null
|
|
IPTABLES_OK=$?
|
|
if [ "$IPTABLES_OK" -eq 0 ]; then
|
|
($IPT -D FORWARD -m mark --mark 2 -j ACCEPT 2>&1) > /dev/null
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
### Test ipt_mac with iptables
|
|
test_ipt_mac () {
|
|
($IPT -A INPUT -m mac --mac-source 00:00:00:00:00:00 -j ACCEPT 2>&1) > /dev/null
|
|
IPTABLES_OK=$?
|
|
if [ "$IPTABLES_OK" -eq 0 ]; then
|
|
($IPT -D INPUT -m mac --mac-source 00:00:00:00:00:00 -j ACCEPT 2>&1) > /dev/null
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
### Test ipt_IMQ with iptables
|
|
test_ipt_IMQ () {
|
|
($IPT -t mangle -A PREROUTING -j IMQ --todev 0 2>&1) > /dev/null
|
|
IPTABLES_OK=$?
|
|
if [ "$IPTABLES_OK" -eq 0 ]; then
|
|
($IPT -t mangle -D PREROUTING -j IMQ --todev 0 2>&1) > /dev/null
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
### Test imq with ip
|
|
test_imq () {
|
|
(ip link set imq0 up 2>&1) > /dev/null
|
|
IMQ0_OK=$?
|
|
(ip link set imq1 up 2>&1) > /dev/null
|
|
IMQ1_OK=$?
|
|
if [ "$IMQ0_OK" -eq 0 -a "$IMQ1_OK" -eq 0 ]; then
|
|
(ip link set imq0 down 2>&1) > /dev/null
|
|
(ip link set imq1 down 2>&1) > /dev/null
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
### Test sch_htb with tc; requires imq0
|
|
test_sch_htb () {
|
|
(tc qdisc del dev imq0 root 2>&1) > /dev/null
|
|
(tc qdisc add dev imq0 root htb 2>&1) > /dev/null
|
|
TC_OK=$?
|
|
if [ "$TC_OK" -eq 0 ]; then
|
|
(tc qdisc del dev imq0 root 2>&1) > /dev/null
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
### Find a module on disk
|
|
module_exists () {
|
|
EXIST=$(find /lib/modules/`uname -r` -name $1.*o 2> /dev/null)
|
|
if [ -n "$EXIST" ]; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
### Test if a module is in memory
|
|
module_in_memory () {
|
|
MODULE=$(lsmod | grep $1 | awk '{print $1}')
|
|
if [ "$MODULE" = "$1" ]; then
|
|
return 0
|
|
else
|
|
return 1
|
|
fi
|
|
}
|
|
|
|
### Test functionality of a module; load if necessary
|
|
do_module_tests () {
|
|
echo " Testing module $1 $2"
|
|
"test_$1"
|
|
if [ $? -ne 0 ]; then
|
|
echo " Module $1 $2 needed"
|
|
echo " Scanning disk for $1 module"
|
|
module_exists $1
|
|
if [ $? -ne 0 ]; then
|
|
echo " $1 module missing: please install it"
|
|
exit 1
|
|
else
|
|
echo " $1 exists, trying to load"
|
|
insmod $1 $2 > /dev/null
|
|
if [ $? -ne 0 ]; then
|
|
echo " Error: insmod $1 $2 failed"
|
|
exit 1
|
|
else
|
|
echo " $1 $2 loaded successfully"
|
|
fi
|
|
fi
|
|
else
|
|
echo " $1 is working"
|
|
fi
|
|
}
|
|
|
|
echo " Testing required modules"
|
|
|
|
do_module_tests "ipt_mac"
|
|
do_module_tests "ipt_mark"
|
|
|
|
# test for imq modules, only if TrafficControl is enabled in conf
|
|
if ( grep -q -E '^[[:space:]]*TrafficControl[[:space:]]+(yes|true|1)' "$CONFIGFILE" ) ; then
|
|
do_module_tests "imq" "numdevs=2"
|
|
do_module_tests "ipt_IMQ"
|
|
do_module_tests "sch_htb"
|
|
fi
|
|
}
|