routing/nodogsplash/files/nodogsplash.init
Alexander Couzens 7a233607af nodogsplash: simplify append_config_option
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.
2015-03-05 18:01:05 +01:00

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
}