Project

General

Profile

Feature #15904 » RFC8910-Dec11.php

Dale Harron, 12/12/2024 11:09 AM

 
1
<?php
2

    
3
require_once("auth.inc");
4
require_once("util.inc");
5
require_once("functions.inc");
6
require_once("captiveportal.inc");
7

    
8
header("Expires: 0");
9
header("Cache-Control: no-cache, no-store, must-revalidate");
10
header("Connection: close");
11

    
12
global $cpzone, $cpzoneid, $cpzoneprefix;
13

    
14
$cpzone = strtolower($_REQUEST['zone']);
15
$cpcfg = config_get_path("captiveportal/{$cpzone}", []);
16

    
17
if (empty($cpcfg)) {
18
	log_error("rfc8910.php - Submission to captiveportal with unknown parameter zone: " . htmlspecialchars($cpzone));
19
	portal_reply_page($redirurl, "error", gettext("Internal error"));
20
	ob_flush();
21
	return;
22
}
23

    
24
$cpzoneid = $cpcfg['zoneid'];
25
$clientip = $_SERVER['REMOTE_ADDR'];
26

    
27
if (is_array($cpcfg['allowedip'])) {
28
	foreach ($cpcfg['allowedip'] as $ipent) {
29
		if ($ipent['ip'] == $clientip) {
30
			if ($ipent['dir'] != 'to') {
31
				// 'clientip' is part of the 'allowedip' list
32
				ob_flush();
33
				return;
34
			}
35
		}
36
	}
37
}
38

    
39
$clientmac = pfSense_ip_to_mac($clientip);
40
if (!is_array($clientmac)) {
41
	if (!isset($cpcfg['nomacfilter']) || isset($cpcfg['passthrumacadd'])) {
42
		/* unable to find MAC address - shouldn't happen! - bail out */
43
		captiveportal_logportalauth("unauthenticated", "noclientmac", $clientip, "ERROR");
44
		echo "An error occurred.  Please check the system logs for more information.";
45
		log_error("Zone: {$cpzone} - Captive portal could not determine client's MAC address.  Disable MAC address filtering in captive portal if you do not need this functionality.");
46
		ob_flush();
47
		return;
48
	}
49
}
50
else if (is_array($cpcfg['passthrumac'])) {
51
	foreach ($cpcfg['passthrumac'] as $macent) {
52
		if ($macent['mac'] == $clientmac['macaddr']) {
53
			if ($macent['action'] == 'pass') {
54
				// 'clientmac' is part of the 'allowed MAC' list
55
				ob_flush();
56
				return;
57
			}
58
		}
59
	}
60
}
61

    
62
/* ---- RFC8910.php Custom Code for Kea DHCP, check MAC address instead of IP to verify a sesson ID exists
63
        Kea reclaims the IP quickly after the client disconnects, creating IP/MAC conflicts 
64
        when reallocated within the captive portal database of validated clients.  
65
        It is the MAC that it validated, not the IP as IP can change frequently
66
        This code matches the MAC in the database and assess if it is currently validated by the Portal
67
        so that The correct True/False string for DCHP 114 is sent.   
68
*/
69

    
70
//Check to see if that IP is associated with this device's MAC address in the captive portal database?
71
$ARPforIP = shell_exec("arp '$clientip'");
72
$clientmac = substr($ARPforIP, 17, 24);
73
if (preg_match('/([a-fA-F0-9]{2}[:|\-]?){6}/', "'{$clientmac}'", $matches)) {
74
    $clientmac = $matches[0];
75
}
76

    
77
/* read in client database and verify IP/MAC matches */
78
$query = "WHERE mac = '{$clientmac}'";
79
$cpdbmac = captiveportal_read_db($query);
80
foreach ($cpdbmac as $cpentrymac) {
81
              $cpsessionmac = $cpentrymac;
82
}
83
$checkip = $cpentrymac[2];
84

    
85
if (!empty($cpsessionmac)) {
86
  $sessionidmac = $cpsessionmac['sessionid'];
87
}      
88

    
89
unset($cpdbmac);
90

    
91
/* ------- End Kea customized Code   */
92

    
93

    
94
$rfc8910_url = 'https://' . $_SERVER['HTTP_HOST'] . '/index.php?zone=' . $cpzone;
95

    
96
if (empty($sessionidmac) || ($checkip <> $clientip)) {
97
/*	captiveportal_logportalauth("rfc8910", "EMPTY SESSION", $clientip, $cpzone); */
98
/*	$seconds_remaining = $cpcfg['timeout'] * 60; */
99
	$json_post  = array (
100
		"captive" => true,
101
		"user-portal-url" => "$rfc8910_url",
102
		"venue-info-url" => "$rfc8910_url"
103
);
104

    
105
echo json_encode($json_post, JSON_PRETTY_PRINT);
106

    
107
} else {
108
/*	captiveportal_logportalauth("rfc8910", "EXISTING SESSION", $clientip, $cpzone); */
109
/*	$seconds_remaining = (time()-$cpsession['allow_time'])+($cpcfg['timeout']*60); */
110
	$json_post  = array (
111
		"captive" => false,
112
		"user-portal-url" => "$rfc8910_url",
113
		"venue-info-url" => "$rfc8910_url"
114
);
115
echo json_encode($json_post, JSON_PRETTY_PRINT);
116

    
117
}
118
ob_flush();
119

    
120
return;
121
?>
(6-6/7)