Revision 769e254e
Added by Ermal LUÇI almost 15 years ago
etc/inc/captiveportal.inc | ||
---|---|---|
52 | 52 |
|
53 | 53 |
$captiveportallck = lock('captiveportal'); |
54 | 54 |
|
55 |
$cpactive = false; |
|
56 | 55 |
if (isset($config['captiveportal']['enable'])) { |
57 |
$cpips = array(); |
|
58 |
$ifaces = get_configured_interface_list(); |
|
59 |
foreach ($ifaces as $kiface => $kiface2) { |
|
60 |
$tmpif = get_real_interface($kiface); |
|
61 |
pfSense_interface_flags($tmpif, -IFF_IPFW_FILTER); |
|
62 |
} |
|
63 |
$cpinterfaces = explode(",", $config['captiveportal']['interface']); |
|
64 |
$firsttime = 0; |
|
65 |
foreach ($cpinterfaces as $cpifgrp) { |
|
66 |
if (!isset($ifaces[$cpifgrp])) |
|
67 |
continue; |
|
68 |
$tmpif = get_real_interface($cpifgrp); |
|
69 |
if (!empty($tmpif)) { |
|
70 |
if ($firsttime > 0) |
|
71 |
$cpinterface .= " or "; |
|
72 |
$cpinterface .= "via {$tmpif}"; |
|
73 |
$firsttime = 1; |
|
74 |
$cpipm = get_interface_ip($cpifgrp); |
|
75 |
if (is_ipaddr($cpipm)) { |
|
76 |
$carpif = link_ip_to_carp_interface($cpipm); |
|
77 |
if (!empty($carpif)) { |
|
78 |
$carpsif = explode(" ", $carpif); |
|
79 |
foreach ($carpsif as $cpcarp) { |
|
80 |
pfSense_interface_flags($cpcarp, IFF_IPFW_FILTER); |
|
81 |
$carpip = find_interface_ip($cpcarp); |
|
82 |
if (is_ipaddr($carpip)) |
|
83 |
$cpips[] = $carpip; |
|
84 |
} |
|
85 |
} |
|
86 |
$cpips[] = $cpipm; |
|
87 |
pfSense_interface_flags($tmpif, IFF_IPFW_FILTER); |
|
88 |
} |
|
89 |
} |
|
90 |
} |
|
91 |
if (count($cpips) > 0) { |
|
92 |
$cpactive = true; |
|
93 |
$cpinterface = "{ {$cpinterface} } "; |
|
94 |
} |
|
95 |
} |
|
96 |
|
|
97 |
if ($cpactive == true) { |
|
98 | 56 |
|
99 | 57 |
if ($g['booting']) |
100 | 58 |
echo "Starting captive portal... "; |
... | ... | |
108 | 66 |
unlink_if_exists("{$g['vardb_path']}/captiveportal_mac.db"); |
109 | 67 |
unlink_if_exists("{$g['vardb_path']}/captiveportal_ip.db"); |
110 | 68 |
unlink_if_exists("{$g['vardb_path']}/captiveportal_radius.db"); |
111 |
mwexec("/sbin/ipfw -q table all flush", true); |
|
112 | 69 |
|
113 | 70 |
/* setup new database in case someone tries to access the status -> captive portal page */ |
114 | 71 |
touch("{$g['vardb_path']}/captiveportal.db"); |
... | ... | |
116 | 73 |
/* kill any running minicron */ |
117 | 74 |
killbypid("{$g['varrun_path']}/minicron.pid"); |
118 | 75 |
|
119 |
/* make sure ipfw is loaded */ |
|
120 |
if (!is_module_loaded("ipfw.ko")) |
|
121 |
filter_load_ipfw(); |
|
122 |
/* Always load dummynet now that even allowed ip and mac passthrough use it. */ |
|
123 |
if (!is_module_loaded("dummynet.ko")) |
|
124 |
mwexec("/sbin/kldload dummynet"); |
|
125 |
|
|
126 |
/* generate ipfw rules */ |
|
76 |
/* init dummynet/ipfw rules number database */ |
|
127 | 77 |
captiveportal_init_ipfw_ruleno(); |
128 |
$cprules = captiveportal_rules_generate($cpinterface, $cpips); |
|
129 |
$cprules .= "\n"; |
|
130 |
/* generate passthru mac database */ |
|
131 |
$cprules .= captiveportal_passthrumac_configure(true); |
|
132 |
$cprules .= "\n"; |
|
133 |
/* allowed ipfw rules to make allowed ip work */ |
|
134 |
$cprules .= captiveportal_allowedip_configure(); |
|
78 |
|
|
79 |
/* init ipfw rules */ |
|
80 |
captiveportal_init_rules(); |
|
135 | 81 |
|
136 | 82 |
/* stop accounting on all clients */ |
137 | 83 |
captiveportal_radius_stop_all(true); |
... | ... | |
277 | 223 |
/* write elements */ |
278 | 224 |
captiveportal_write_elements(); |
279 | 225 |
|
280 |
/* load rules */ |
|
281 |
mwexec("/sbin/ipfw -q flush"); |
|
282 |
|
|
283 |
/* ipfw cannot accept rules directly on stdin, |
|
284 |
so we have to write them to a temporary file first */ |
|
285 |
$fd = @fopen("{$g['tmp_path']}/ipfw.cp.rules", "w"); |
|
286 |
if (!$fd) { |
|
287 |
printf("Cannot open ipfw.cp.rules in captiveportal_configure()\n"); |
|
288 |
return 1; |
|
289 |
} |
|
290 |
|
|
291 |
fwrite($fd, $cprules); |
|
292 |
fclose($fd); |
|
293 |
|
|
294 |
mwexec("/sbin/ipfw -q {$g['tmp_path']}/ipfw.cp.rules"); |
|
295 |
|
|
296 |
@unlink("{$g['tmp_path']}/ipfw.cp.rules"); |
|
297 |
|
|
298 |
/* filter on layer2 as well so we can check MAC addresses */ |
|
299 |
mwexec("/sbin/sysctl net.link.ether.ipfw=1"); |
|
300 |
|
|
301 |
chdir($g['captiveportal_path']); |
|
302 |
|
|
303 |
if ($config['captiveportal']['maxproc']) |
|
304 |
$maxproc = $config['captiveportal']['maxproc']; |
|
305 |
else |
|
306 |
$maxproc = 16; |
|
307 |
|
|
308 |
$use_fastcgi = true; |
|
309 |
|
|
310 |
if(isset($config['captiveportal']['httpslogin'])) { |
|
311 |
$cert = base64_decode($config['captiveportal']['certificate']); |
|
312 |
if (isset($config['captiveportal']['cacertificate'])) |
|
313 |
$cacert = base64_decode($config['captiveportal']['cacertificate']); |
|
314 |
else |
|
315 |
$cacert = ""; |
|
316 |
$key = base64_decode($config['captiveportal']['private-key']); |
|
317 |
/* generate lighttpd configuration */ |
|
318 |
system_generate_lighty_config("{$g['varetc_path']}/lighty-CaptivePortal-SSL.conf", |
|
319 |
$cert, $key, $cacert, "lighty-CaptivePortal-ssl.pid", "8001", "/usr/local/captiveportal/", |
|
320 |
"cert-portal.pem", "ca-portal.pem", "1", $maxproc, $use_fastcgi, true); |
|
321 |
} |
|
322 |
|
|
323 |
/* generate lighttpd configuration */ |
|
324 |
system_generate_lighty_config("{$g['varetc_path']}/lighty-CaptivePortal.conf", |
|
325 |
"", "", "", "lighty-CaptivePortal.pid", "8000", "/usr/local/captiveportal/", |
|
326 |
"cert-portal.pem", "ca-portal.pem", "1", $maxproc, $use_fastcgi, true); |
|
327 |
|
|
328 |
/* attempt to start lighttpd */ |
|
329 |
$res = mwexec("/usr/local/sbin/lighttpd -f {$g['varetc_path']}/lighty-CaptivePortal.conf"); |
|
330 |
|
|
331 |
/* fire up https instance */ |
|
332 |
if(isset($config['captiveportal']['httpslogin'])) |
|
333 |
$res = mwexec("/usr/local/sbin/lighttpd -f {$g['varetc_path']}/lighty-CaptivePortal-SSL.conf"); |
|
226 |
/* start up the webserving daemon */ |
|
227 |
captiveportal_init_webgui(); |
|
334 | 228 |
|
335 | 229 |
/* start pruning process (interval defaults to 60 seconds) */ |
336 | 230 |
mwexec("/usr/local/bin/minicron $croninterval {$g['varrun_path']}/minicron.pid " . |
... | ... | |
408 | 302 |
return 0; |
409 | 303 |
} |
410 | 304 |
|
411 |
function captiveportal_rules_generate($cpif, &$cpiparray) { |
|
305 |
function captiveportal_init_webgui() { |
|
306 |
global $g, $config; |
|
307 |
|
|
308 |
if (!isset($config['captiveportal']['enable'])) |
|
309 |
return; |
|
310 |
|
|
311 |
if ($config['captiveportal']['maxproc']) |
|
312 |
$maxproc = $config['captiveportal']['maxproc']; |
|
313 |
else |
|
314 |
$maxproc = 16; |
|
315 |
|
|
316 |
$use_fastcgi = true; |
|
317 |
|
|
318 |
if (isset($config['captiveportal']['httpslogin'])) { |
|
319 |
$cert = base64_decode($config['captiveportal']['certificate']); |
|
320 |
if (isset($config['captiveportal']['cacertificate'])) |
|
321 |
$cacert = base64_decode($config['captiveportal']['cacertificate']); |
|
322 |
else |
|
323 |
$cacert = ""; |
|
324 |
$key = base64_decode($config['captiveportal']['private-key']); |
|
325 |
/* generate lighttpd configuration */ |
|
326 |
system_generate_lighty_config("{$g['varetc_path']}/lighty-CaptivePortal-SSL.conf", |
|
327 |
$cert, $key, $cacert, "lighty-CaptivePortal-ssl.pid", "8001", "/usr/local/captiveportal/", |
|
328 |
"cert-portal.pem", "ca-portal.pem", "1", $maxproc, $use_fastcgi, true); |
|
329 |
} |
|
330 |
|
|
331 |
/* generate lighttpd configuration */ |
|
332 |
system_generate_lighty_config("{$g['varetc_path']}/lighty-CaptivePortal.conf", |
|
333 |
"", "", "", "lighty-CaptivePortal.pid", "8000", "/usr/local/captiveportal/", |
|
334 |
"cert-portal.pem", "ca-portal.pem", "1", $maxproc, $use_fastcgi, true); |
|
335 |
|
|
336 |
/* attempt to start lighttpd */ |
|
337 |
$res = mwexec("/usr/local/sbin/lighttpd -f {$g['varetc_path']}/lighty-CaptivePortal.conf"); |
|
338 |
|
|
339 |
/* fire up https instance */ |
|
340 |
if (isset($config['captiveportal']['httpslogin'])) |
|
341 |
$res = mwexec("/usr/local/sbin/lighttpd -f {$g['varetc_path']}/lighty-CaptivePortal-SSL.conf"); |
|
342 |
} |
|
343 |
|
|
344 |
function captiveportal_init_rules() { |
|
412 | 345 |
global $config, $g; |
413 | 346 |
|
347 |
if (!isset($config['captiveportal']['enable'])) |
|
348 |
return; |
|
349 |
|
|
350 |
$cpips = array(); |
|
351 |
$ifaces = get_configured_interface_list(); |
|
352 |
foreach ($ifaces as $kiface => $kiface2) { |
|
353 |
$tmpif = get_real_interface($kiface); |
|
354 |
pfSense_interface_flags($tmpif, -IFF_IPFW_FILTER); |
|
355 |
} |
|
356 |
$cpinterfaces = explode(",", $config['captiveportal']['interface']); |
|
357 |
$firsttime = 0; |
|
358 |
foreach ($cpinterfaces as $cpifgrp) { |
|
359 |
if (!isset($ifaces[$cpifgrp])) |
|
360 |
continue; |
|
361 |
$tmpif = get_real_interface($cpifgrp); |
|
362 |
if (!empty($tmpif)) { |
|
363 |
if ($firsttime > 0) |
|
364 |
$cpinterface .= " or "; |
|
365 |
$cpinterface .= "via {$tmpif}"; |
|
366 |
$firsttime = 1; |
|
367 |
$cpipm = get_interface_ip($cpifgrp); |
|
368 |
if (is_ipaddr($cpipm)) { |
|
369 |
$carpif = link_ip_to_carp_interface($cpipm); |
|
370 |
if (!empty($carpif)) { |
|
371 |
$carpsif = explode(" ", $carpif); |
|
372 |
foreach ($carpsif as $cpcarp) { |
|
373 |
pfSense_interface_flags($cpcarp, IFF_IPFW_FILTER); |
|
374 |
$carpip = find_interface_ip($cpcarp); |
|
375 |
if (is_ipaddr($carpip)) |
|
376 |
$cpips[] = $carpip; |
|
377 |
} |
|
378 |
} |
|
379 |
$cpips[] = $cpipm; |
|
380 |
pfSense_interface_flags($tmpif, IFF_IPFW_FILTER); |
|
381 |
} |
|
382 |
} |
|
383 |
} |
|
384 |
if (count($cpips) > 0) { |
|
385 |
$cpactive = true; |
|
386 |
$cpinterface = "{ {$cpinterface} } "; |
|
387 |
} else |
|
388 |
return false; |
|
389 |
|
|
390 |
/* make sure ipfw is loaded */ |
|
391 |
if (!is_module_loaded("ipfw.ko")) |
|
392 |
filter_load_ipfw(); |
|
393 |
/* Always load dummynet now that even allowed ip and mac passthrough use it. */ |
|
394 |
if (!is_module_loaded("dummynet.ko")) |
|
395 |
mwexec("/sbin/kldload dummynet"); |
|
396 |
|
|
414 | 397 |
$cprules = "add 65291 set 1 allow pfsync from any to any\n"; |
415 | 398 |
$cprules .= "add 65292 set 1 allow carp from any to any\n"; |
416 | 399 |
|
... | ... | |
436 | 419 |
|
437 | 420 |
$rulenum = 65310; |
438 | 421 |
$ips = "255.255.255.255 "; |
439 |
foreach ($cpiparray as $cpip)
|
|
422 |
foreach ($cpips as $cpip)
|
|
440 | 423 |
$ips .= "or {$cpip} "; |
441 | 424 |
$ips = "{ {$ips} }"; |
442 | 425 |
//# allow access to our DHCP server (which needs to be able to ping clients as well) |
... | ... | |
522 | 505 |
|
523 | 506 |
EOD; |
524 | 507 |
|
525 |
return $cprules; |
|
508 |
/* generate passthru mac database */ |
|
509 |
$cprules .= captiveportal_passthrumac_configure(true); |
|
510 |
$cprules .= "\n"; |
|
511 |
/* allowed ipfw rules to make allowed ip work */ |
|
512 |
$cprules .= captiveportal_allowedip_configure(); |
|
513 |
|
|
514 |
/* load rules */ |
|
515 |
$cprules = "table all flush\nflush\n{$cprules}"; |
|
516 |
if (file_put_contents("{$g['tmp_path']}/ipfw.cp.rules", $cprules)) { |
|
517 |
mwexec("/sbin/ipfw -q {$g['tmp_path']}/ipfw.cp.rules", true); |
|
518 |
//@unlink("{$g['tmp_path']}/ipfw.cp.rules"); |
|
519 |
} |
|
520 |
|
|
521 |
/* filter on layer2 as well so we can check MAC addresses */ |
|
522 |
mwexec("/sbin/sysctl net.link.ether.ipfw=1"); |
|
523 |
|
|
524 |
return $cprules; |
|
526 | 525 |
} |
527 | 526 |
|
528 | 527 |
/* remove clients that have been around for longer than the specified amount of time */ |
... | ... | |
1071 | 1070 |
} |
1072 | 1071 |
|
1073 | 1072 |
function captiveportal_write_elements() { |
1074 |
global $g, $config; |
|
1075 |
|
|
1076 |
/* delete any existing elements */ |
|
1077 |
if (is_dir($g['captiveportal_element_path'])) { |
|
1078 |
$dh = opendir($g['captiveportal_element_path']); |
|
1079 |
while (($file = readdir($dh)) !== false) { |
|
1080 |
if ($file != "." && $file != "..") |
|
1081 |
unlink($g['captiveportal_element_path'] . "/" . $file); |
|
1082 |
} |
|
1083 |
closedir($dh); |
|
1084 |
} else { |
|
1085 |
@mkdir($g['captiveportal_element_path']); |
|
1086 |
} |
|
1073 |
global $g, $config; |
|
1087 | 1074 |
|
1075 |
/* delete any existing elements */ |
|
1076 |
if (is_dir($g['captiveportal_element_path'])) { |
|
1077 |
$dh = opendir($g['captiveportal_element_path']); |
|
1078 |
while (($file = readdir($dh)) !== false) { |
|
1079 |
if ($file != "." && $file != "..") |
|
1080 |
unlink($g['captiveportal_element_path'] . "/" . $file); |
|
1081 |
} |
|
1082 |
closedir($dh); |
|
1083 |
} else |
|
1084 |
@mkdir($g['captiveportal_element_path']); |
|
1085 |
|
|
1088 | 1086 |
if (is_array($config['captiveportal']['element'])) { |
1089 | 1087 |
conf_mount_rw(); |
1090 | 1088 |
foreach ($config['captiveportal']['element'] as $data) { |
... | ... | |
1103 | 1101 |
conf_mount_ro(); |
1104 | 1102 |
} |
1105 | 1103 |
|
1106 |
return 0;
|
|
1104 |
return 0;
|
|
1107 | 1105 |
} |
1108 | 1106 |
|
1109 | 1107 |
function captiveportal_init_ipfw_ruleno($rulenos_start = 2000, $rulenos_range_max = 49899) { |
Also available in: Unified diff
Do not reconfigure CP on every event of interfaces or while reloading the webGUI. Create 2 new function to just rewrite rules and restart the webserver for CP repctively for interface events and webGUI restart events.