Merge pull request #76 from Noltari/bird-next
[feed/routing.git] / nodogsplash / files / nodogsplash.init
1 #!/bin/sh /etc/rc.common
2 #
3 # description: Startup/shutdown script for nodogsplash captive portal
4 #
5 # Alexander Couzens <lynxis@fe80.eu> 2014
6 # P. Kube 2007
7 #
8 # (Based on wifidog startup script
9 # Date : 2004-08-25
10 # Version : 1.0
11 # Comment by that author: Could be better, but it's working as expected)
12 #
13
14 START=95
15 STOP=95
16
17 USE_PROCD=1
18
19 IPT=/usr/sbin/iptables
20 WD_DIR=/usr/bin
21 # -s -d 5 runs in background, with level 5 (not so verbose) messages to syslog
22 # -f -d 7 runs in foreground, with level 7 (verbose) debug messages to terminal
23 OPTIONS="-s -f -d 5"
24 CONFIGFILE="/tmp/invalid_nodogsplash.conf"
25
26 # nolog(loglevel message ...)
27 nolog() {
28 local level=$1
29 shift
30 logger -s -t nodogsplash -p daemon.$level $@
31 }
32
33 # append_config_option <cfgfile> <uci_cfg_obj> <option_name> <config_counterpart> [<optional default>]
34 # append "$config_counterpart $value" to cfgfile if option_name exists
35 # e.g. append_config_option "$CONFIGFILE" "$cfg" bind_address BindAddress 0.0.0.0
36 # will append "BindAddress 192.168.1.1" if uci bind_address is '192.168.1.1'
37 append_config_option() {
38 local val=""
39 local cfg="$1"
40 local config_file="$2"
41 local option_name="$3"
42 local config_counterpart="$4"
43 local default="$5"
44 config_get val "$cfg" "$option_name" "$default"
45 [ -n "$val" ] && echo "" >> $config_file
46 }
47
48 setup_user_authentication() {
49 local cfg="$1"
50 local val
51
52 config_get_bool val "$cfg" authenticate_immediately 0
53 [ $val -gt 0 ] && echo "AuthenticateImmediately yes" >> $CONFIGFILE
54
55 config_get val "$cfg" username
56 if [ -n "$val" ] ; then
57 echo "UsernameAuthentication" >> $CONFIGFILE
58 echo "Username $val" >> $CONFIGFILE
59 fi
60
61 config_get val "$cfg" password
62 if [ -n "$val" ] ; then
63 echo "PasswordAuthentication" >> $CONFIGFILE
64 echo "Password $val" >> $CONFIGFILE
65 fi
66 }
67
68 setup_mac_lists() {
69 local cfg="$1"
70 local MAC=""
71 local val
72
73 append_mac() {
74 append MAC "$1" ","
75 }
76
77 config_get val "$cfg" macmechanism
78 if [ -z "$val" ] ; then
79 # check if we have AllowedMACList or BlockedMACList defined they will be ignored
80 config_get val "$cfg" allowedmac
81 if [ -n "$val" ] ; then
82 echo "Ignoring allowedmac - macmechanism not \"allow\"" >&2
83 fi
84
85 config_get val "$cfg" blockedmac
86 if [ -n "$val" ] ; then
87 echo "Ignoring blockedmac - macmechanism not \"block\"" >&2
88 fi
89 elif [ "$val" == "allow" ] ; then
90 MAC=""
91 config_list_foreach "$cfg" allowedmac append_mac
92 echo "AllowedMACList $MAC" >> $CONFIGFILE
93 elif [ "$val" == "block" ] ; then
94 MAC=""
95 config_list_foreach "$cfg" blockedmac append_mac
96 echo "BlockedMACList $MAC" >> $CONFIGFILE
97 else
98 nolog error "$cfg Invalid macmechanism '$val' - allow or block are valid."
99 return 1
100 fi
101 MAC=""
102 config_list_foreach "$cfg" trustedmac append_mac
103 [ -n "$MAC" ] && echo "TrustedMACList $MAC" >> $CONFIGFILE
104 }
105
106 setup_firewall() {
107 local cfg="$1"
108 local uciname
109 local val
110
111 append_firewall() {
112 echo " FirewallRule $1" >> $CONFIGFILE
113 }
114
115 for rule in $(echo authenticated-users preauthenticated-users users-to-router trusted-users trusted-users-to-router)
116 do
117 uci_name=${rule//-/_}
118 # uci does not allow - dashes
119 echo "FirewallRuleSet $rule {" >> $CONFIGFILE
120 config_list_foreach "$cfg" ${uci_name} append_firewall
121 echo "}" >> $CONFIGFILE
122 config_get val "$cfg" policy_${uci_name}
123 [ -n "$val" ] && echo "EmptyRuleSetPolicy $rule $val" >> $CONFIGFILE
124 done
125 }
126
127 generate_uci_config() {
128 local cfg="$1"
129 local val
130 local ifname
131 local download
132 local upload
133
134 CONFIGFILE="/tmp/etc/nodogsplash_$cfg.conf"
135
136 echo "# auto-generated config file from /etc/config/nodogsplash" > $CONFIGFILE
137
138 config_get val "$cfg" config
139 if [ -n "$val" ] ; then
140 if [ -f "$val" ] ; then
141 nolog error "Configuration file '$file' doesn't exist"
142 return 0
143 fi
144 cat $val > CONFIGFILE
145 fi
146
147 config_get val "$cfg" network
148 if [ -n "$val" ] ; then
149 if ! network_get_device ifname "$val" ; then
150 nolog error "$cfg can not find ifname for network '$val'"
151 return 1
152 fi
153 fi
154
155 config_get val "$cfg" gatewayinterface
156 if [ -n "$val" ] ; then
157 if [ -n "$ifname" ] ; then
158 nolog error "$cfg cannot use both option network and gatewayinterface"
159 return 1
160 fi
161 ifname="$val"
162 fi
163
164 if [ -z "$ifname" ] ; then
165 nolog error "$cfg option network or gatewayinterface missing"
166 return 1
167 fi
168
169 echo "GatewayInterface $ifname" >> $CONFIGFILE
170 config_get val "$cfg" externalnetwork
171 [ -n "$val" ] && network_get_device ifname "$val" && echo "ExternalInterface $ifname" >> $CONFIGFILE
172
173 append_config_option "$CONFIGFILE" "$cfg" gatewayname GatewayName
174 append_config_option "$CONFIGFILE" "$cfg" gatewayaddress GatewayAddress
175 append_config_option "$CONFIGFILE" "$cfg" gatewayport GatewayPort
176 append_config_option "$CONFIGFILE" "$cfg" maxclients MaxClients
177 append_config_option "$CONFIGFILE" "$cfg" imagedir ImagesDir
178 append_config_option "$CONFIGFILE" "$cfg" redirecturl RedirectURL
179 append_config_option "$CONFIGFILE" "$cfg" clientidletimeout ClientIdleTimeout
180 append_config_option "$CONFIGFILE" "$cfg" clientforcetimeout ClientForceTimeout
181 append_config_option "$CONFIGFILE" "$cfg" gatewayiprange GatewayIPRange
182 append_config_option "$CONFIGFILE" "$cfg" passwordattempts PasswordAttempts
183 append_config_option "$CONFIGFILE" "$cfg" macmechanism MACMechanism
184 append_config_option "$CONFIGFILE" "$cfg" uploadlimit UploadLimit
185 append_config_option "$CONFIGFILE" "$cfg" downloadlimit DownloadLimit
186
187 config_get download "$cfg" downloadlimit
188 config_get upload "$cfg" uploadlimit
189 [ -n "$upload" -o -n "$download" ] && echo "TrafficControl yes" >> $CONFIGFILE
190
191 setup_mac_lists "$cfg"
192 setup_user_authentication "$cfg"
193 setup_firewall "$cfg"
194 }
195
196 # setup configuration and start instance
197 create_instance() {
198 local cfg="$1"
199 local manual_config
200 local val
201
202 config_get_bool val "$cfg" enabled 0
203 [ $val -gt 0 ] || return 0
204
205 generate_uci_config "$cfg"
206
207 if ! test_module ; then
208 logger -s -t nodogsplash -p daemon.error "nodogsplash is missing some kernel modules"
209 fi
210
211 procd_open_instance $cfg
212 procd_set_param command /usr/bin/nodogsplash -c $CONFIGFILE $OPTIONS
213 procd_set_param respawn
214 procd_set_param file $CONFIGFILE
215 procd_close_instance
216 }
217
218 start_service() {
219 include /lib/functions
220
221 mkdir -p /tmp/etc/
222 config_load nodogsplash
223
224 config_foreach create_instance instance
225 }
226
227 stop_service() {
228 # nodogsplash doesn't exit fast enought, when procd terminates it.
229 # otherwise procd will restart nodogsplash twice. first time starting nodogsplash fails, second time it succeeds
230 sleep 1
231 }
232
233 status() {
234 $WD_DIR/ndsctl status
235 }
236
237 # Test if we got all modules loaded
238 test_module() {
239 ### Test ipt_mark with iptables
240 test_ipt_mark () {
241 ($IPT -A FORWARD -m mark --mark 2 -j ACCEPT 2>&1) > /dev/null
242 IPTABLES_OK=$?
243 if [ "$IPTABLES_OK" -eq 0 ]; then
244 ($IPT -D FORWARD -m mark --mark 2 -j ACCEPT 2>&1) > /dev/null
245 return 0
246 else
247 return 1
248 fi
249 }
250
251 ### Test ipt_mac with iptables
252 test_ipt_mac () {
253 ($IPT -A INPUT -m mac --mac-source 00:00:00:00:00:00 -j ACCEPT 2>&1) > /dev/null
254 IPTABLES_OK=$?
255 if [ "$IPTABLES_OK" -eq 0 ]; then
256 ($IPT -D INPUT -m mac --mac-source 00:00:00:00:00:00 -j ACCEPT 2>&1) > /dev/null
257 return 0
258 else
259 return 1
260 fi
261 }
262
263 ### Test ipt_IMQ with iptables
264 test_ipt_IMQ () {
265 ($IPT -t mangle -A PREROUTING -j IMQ --todev 0 2>&1) > /dev/null
266 IPTABLES_OK=$?
267 if [ "$IPTABLES_OK" -eq 0 ]; then
268 ($IPT -t mangle -D PREROUTING -j IMQ --todev 0 2>&1) > /dev/null
269 return 0
270 else
271 return 1
272 fi
273 }
274
275 ### Test imq with ip
276 test_imq () {
277 (ip link set imq0 up 2>&1) > /dev/null
278 IMQ0_OK=$?
279 (ip link set imq1 up 2>&1) > /dev/null
280 IMQ1_OK=$?
281 if [ "$IMQ0_OK" -eq 0 -a "$IMQ1_OK" -eq 0 ]; then
282 (ip link set imq0 down 2>&1) > /dev/null
283 (ip link set imq1 down 2>&1) > /dev/null
284 return 0
285 else
286 return 1
287 fi
288 }
289
290 ### Test sch_htb with tc; requires imq0
291 test_sch_htb () {
292 (tc qdisc del dev imq0 root 2>&1) > /dev/null
293 (tc qdisc add dev imq0 root htb 2>&1) > /dev/null
294 TC_OK=$?
295 if [ "$TC_OK" -eq 0 ]; then
296 (tc qdisc del dev imq0 root 2>&1) > /dev/null
297 return 0
298 else
299 return 1
300 fi
301 }
302
303 ### Find a module on disk
304 module_exists () {
305 EXIST=$(find /lib/modules/`uname -r` -name $1.*o 2> /dev/null)
306 if [ -n "$EXIST" ]; then
307 return 0
308 else
309 return 1
310 fi
311 }
312
313 ### Test if a module is in memory
314 module_in_memory () {
315 MODULE=$(lsmod | grep $1 | awk '{print $1}')
316 if [ "$MODULE" = "$1" ]; then
317 return 0
318 else
319 return 1
320 fi
321 }
322
323 ### Test functionality of a module; load if necessary
324 do_module_tests () {
325 echo " Testing module $1 $2"
326 "test_$1"
327 if [ $? -ne 0 ]; then
328 echo " Module $1 $2 needed"
329 echo " Scanning disk for $1 module"
330 module_exists $1
331 if [ $? -ne 0 ]; then
332 echo " $1 module missing: please install it"
333 exit 1
334 else
335 echo " $1 exists, trying to load"
336 insmod $1 $2 > /dev/null
337 if [ $? -ne 0 ]; then
338 echo " Error: insmod $1 $2 failed"
339 exit 1
340 else
341 echo " $1 $2 loaded successfully"
342 fi
343 fi
344 else
345 echo " $1 is working"
346 fi
347 }
348
349 echo " Testing required modules"
350
351 do_module_tests "ipt_mac"
352 do_module_tests "ipt_mark"
353
354 # test for imq modules, only if TrafficControl is enabled in conf
355 if ( grep -q -E '^[[:space:]]*TrafficControl[[:space:]]+(yes|true|1)' "$CONFIGFILE" ) ; then
356 do_module_tests "imq" "numdevs=2"
357 do_module_tests "ipt_IMQ"
358 do_module_tests "sch_htb"
359 fi
360 }