| 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 | 
 | 
  
    | 84 | if (!empty($cpsessionmac)) {
 | 
  
    | 85 |   $sessionidmac = $cpsessionmac['sessionid'];
 | 
  
    | 86 | }      
 | 
  
    | 87 | 
 | 
  
    | 88 | /* ------- End Kea customized Code   */
 | 
  
    | 89 | 
 | 
  
    | 90 | 
 | 
  
    | 91 | $rfc8910_url = 'https://' . $_SERVER['HTTP_HOST'] . '/index.php?zone=' . $cpzone;
 | 
  
    | 92 | 
 | 
  
    | 93 | if (empty($sessionidmac)) {
 | 
  
    | 94 | /*	captiveportal_logportalauth("rfc8910", "EMPTY SESSION", $clientip, $cpzone); */
 | 
  
    | 95 | /*	$seconds_remaining = $cpcfg['timeout'] * 60; */
 | 
  
    | 96 | 	$json_post  = array (
 | 
  
    | 97 | 		"captive" => true,
 | 
  
    | 98 | 		"user-portal-url" => "$rfc8910_url",
 | 
  
    | 99 | 		"venue-info-url" => "$rfc8910_url"
 | 
  
    | 100 | );
 | 
  
    | 101 | 
 | 
  
    | 102 | echo json_encode($json_post, JSON_PRETTY_PRINT);
 | 
  
    | 103 | 
 | 
  
    | 104 | } else {
 | 
  
    | 105 | /*	captiveportal_logportalauth("rfc8910", "EXISTING SESSION", $clientip, $cpzone); */
 | 
  
    | 106 | /*	$seconds_remaining = (time()-$cpsession['allow_time'])+($cpcfg['timeout']*60); */
 | 
  
    | 107 | 	$json_post  = array (
 | 
  
    | 108 | 		"captive" => false,
 | 
  
    | 109 | 		"user-portal-url" => "$rfc8910_url",
 | 
  
    | 110 | 		"venue-info-url" => "$rfc8910_url"
 | 
  
    | 111 | );
 | 
  
    | 112 | echo json_encode($json_post, JSON_PRETTY_PRINT);
 | 
  
    | 113 | 
 | 
  
    | 114 | }
 | 
  
    | 115 | ob_flush();
 | 
  
    | 116 | 
 | 
  
    | 117 | return;
 | 
  
    | 118 | ?>
 |