mirror of
https://github.com/pfsense/pfsense.git
synced 2025-10-26 11:38:35 +00:00
Merge pull request #3640 from Augustin-FL/master
This commit is contained in:
commit
e1916b45d0
@ -1341,15 +1341,18 @@ function ldap_format_host($host) {
|
||||
return is_ipaddrv6($host) ? "[$host]" : $host ;
|
||||
}
|
||||
|
||||
function ldap_backed($username, $passwd, $authcfg) {
|
||||
function ldap_backed($username, $passwd, $authcfg, &$attributes = array()) {
|
||||
global $debug, $config;
|
||||
|
||||
if (!$username) {
|
||||
return;
|
||||
$attributes['error_message'] = gettext("Invalid Login.");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!function_exists("ldap_connect")) {
|
||||
return;
|
||||
log_error(gettext("ERROR! unable to find ldap_connect() function."));
|
||||
$attributes['error_message'] = gettext("Internal error during authentication.");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!isset($authcfg['ldap_nostrip_at']) && stristr($username, "@")) {
|
||||
@ -1398,19 +1401,14 @@ function ldap_backed($username, $passwd, $authcfg) {
|
||||
$ldapscope = $authcfg['ldap_scope'];
|
||||
$ldaptimeout = is_numeric($authcfg['ldap_timeout']) ? $authcfg['ldap_timeout'] : 5;
|
||||
} else {
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
|
||||
/* first check if there is even an LDAP server populated */
|
||||
if (!$ldapserver) {
|
||||
if ($ldapfallback) {
|
||||
log_error(gettext("ERROR! ldap_backed() called with no LDAP authentication server defined. Defaulting to local user database. Visit System -> User Manager."));
|
||||
return local_backed($username, $passwd);
|
||||
} else {
|
||||
log_error(gettext("ERROR! ldap_backed() called with no LDAP authentication server defined."));
|
||||
}
|
||||
|
||||
return false;
|
||||
log_error(gettext("ERROR! could not find details of the LDAP server used for authentication."));
|
||||
$attributes['error_message'] = gettext("Internal error during authentication.");
|
||||
return null;
|
||||
}
|
||||
|
||||
/* Setup CA environment if needed. */
|
||||
@ -1430,15 +1428,17 @@ function ldap_backed($username, $passwd, $authcfg) {
|
||||
|
||||
if (strstr($authcfg['ldap_urltype'], "STARTTLS")) {
|
||||
if (!(@ldap_start_tls($ldap))) {
|
||||
log_error(sprintf(gettext("ERROR! ldap_backed() could not STARTTLS to server %s."), $ldapname));
|
||||
log_error(sprintf(gettext("ERROR! could not connect to LDAP server %s using STARTTLS."), $ldapname));
|
||||
$attributes['error_message'] = gettext("Error : could not connect to authentication server.");
|
||||
@ldap_close($ldap);
|
||||
return false;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if ($error == true) {
|
||||
log_error(sprintf(gettext("ERROR! Could not connect to server %s."), $ldapname));
|
||||
return false;
|
||||
$errormsg = sprintf(gettext("ERROR! Could not connect to server %s."), $ldapname);
|
||||
$attributes['error_message'] = gettext("Error : could not connect to authentication server.");
|
||||
return null;
|
||||
}
|
||||
|
||||
/* ok, its up. now, lets bind as the bind user so we can search it */
|
||||
@ -1455,8 +1455,9 @@ function ldap_backed($username, $passwd, $authcfg) {
|
||||
|
||||
if ($error == true) {
|
||||
@ldap_close($ldap);
|
||||
log_error(sprintf(gettext("ERROR! Could not bind to server %s."), $ldapname));
|
||||
return false;
|
||||
log_error(sprintf(gettext("ERROR! Could not bind to LDAP server %s. Please check the bind credentials."), $ldapname));
|
||||
$attributes['error_message'] = gettext("Error : could not connect to authentication server.");
|
||||
return null;
|
||||
}
|
||||
|
||||
/* Get LDAP Authcontainers and split em up. */
|
||||
@ -1512,14 +1513,23 @@ function ldap_backed($username, $passwd, $authcfg) {
|
||||
|
||||
if ($usercount != 1) {
|
||||
@ldap_unbind($ldap);
|
||||
log_error(gettext("ERROR! Either LDAP search failed, or multiple users were found."));
|
||||
if ($debug) {
|
||||
if ($usercount === 0) {
|
||||
log_error(sprintf(gettext("ERROR! LDAP search failed, no user matching %s was found."), $username));
|
||||
} else {
|
||||
log_error(sprintf(gettext("ERROR! LDAP search failed, multiple users matching %s were found."), $username));
|
||||
}
|
||||
}
|
||||
$attributes['error_message'] = gettext("Invalid login specified.");
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Now lets bind as the user we found */
|
||||
$passwd = isset($authcfg['ldap_utf8']) ? utf8_encode($passwd) : $passwd;
|
||||
if (!($res = @ldap_bind($ldap, $userdn, $passwd))) {
|
||||
log_error(sprintf(gettext('ERROR! Could not login to server %1$s as user %2$s: %3$s'), $ldapname, $username, ldap_error($ldap)));
|
||||
if ($debug) {
|
||||
log_error(sprintf(gettext('ERROR! Could not login to server %1$s as user %2$s: %3$s'), $ldapname, $username, ldap_error($ldap)));
|
||||
}
|
||||
@ldap_unbind($ldap);
|
||||
return false;
|
||||
}
|
||||
@ -1554,7 +1564,9 @@ function radius_backed($username, $password, $authcfg, &$attributes = array()) {
|
||||
$radius_protocol = 'PAP';
|
||||
}
|
||||
} else {
|
||||
return false;
|
||||
log_error(gettext("ERROR! could not find details of the RADIUS server used for authentication."));
|
||||
$attributes['error_message'] = gettext("Internal error during authentication.");
|
||||
return null;
|
||||
}
|
||||
|
||||
// Create our instance
|
||||
@ -1598,10 +1610,43 @@ function radius_backed($username, $password, $authcfg, &$attributes = array()) {
|
||||
}
|
||||
|
||||
if (PEAR::isError($rauth->start())) {
|
||||
$retvalue['auth_val'] = 1;
|
||||
$retvalue['error'] = $rauth->getError();
|
||||
if ($debug) {
|
||||
printf(gettext("RADIUS start: %s") . "<br />\n", $retvalue['error']);
|
||||
$ret = null;
|
||||
log_error(sprintf(gettext("Error during RADIUS authentication : %s"), $rauth->getError()));
|
||||
$attributes['error_message'] = gettext("Error : could not connect to authentication server.");
|
||||
} else {
|
||||
$nasid = $attributes['nas_identifier'];
|
||||
$nasip = $authcfg['radius_nasip_attribute'];
|
||||
if (empty($nasid)) {
|
||||
$nasid = gethostname(); //If no RADIUS NAS-Identifier is given : we use pfsense's hostname as NAS-Identifier
|
||||
}
|
||||
if (!is_ipaddr($nasip)) {
|
||||
$nasip = get_interface_ip($nasip);
|
||||
|
||||
if (!is_ipaddr($nasip)) {
|
||||
$nasip = get_interface_ip();//We use wan interface IP as fallback for NAS-IP-Address
|
||||
}
|
||||
}
|
||||
$nasmac = get_interface_mac(find_ip_interface($nasip));
|
||||
|
||||
$rauth->putAttribute(RADIUS_NAS_IP_ADDRESS, $nasip, "addr");
|
||||
$rauth->putAttribute(RADIUS_NAS_IDENTIFIER, $nasid);
|
||||
|
||||
if(!empty($attributes['calling_station_id'])) {
|
||||
$rauth->putAttribute(RADIUS_CALLING_STATION_ID, $attributes['calling_station_id']);
|
||||
}
|
||||
// Carefully check that interface has a MAC address
|
||||
if(!empty($nasmac)) {
|
||||
$nasmac = mac_format($nasmac);
|
||||
$rauth->putAttribute(RADIUS_CALLED_STATION_ID, $nasmac.':'.gethostname());
|
||||
}
|
||||
if(!empty($attributes['nas_port_type'])) {
|
||||
$rauth->putAttribute(RADIUS_NAS_PORT_TYPE, $attributes['nas_port_type']);
|
||||
}
|
||||
if(!empty($attributes['nas_port'])) {
|
||||
$rauth->putAttribute(RADIUS_NAS_PORT, intval($attributes['nas_port']), 'integer');
|
||||
}
|
||||
if(!empty($attributes['framed_ip']) && is_ipaddr($attributes['framed_ip'])) {
|
||||
$rauth->putAttribute(RADIUS_FRAMED_IP_ADDRESS, $attributes['framed_ip'], "addr");
|
||||
}
|
||||
}
|
||||
|
||||
@ -1610,27 +1655,28 @@ function radius_backed($username, $password, $authcfg, &$attributes = array()) {
|
||||
/* Send request */
|
||||
$result = $rauth->send();
|
||||
if (PEAR::isError($result)) {
|
||||
$retvalue['auth_val'] = 1;
|
||||
$retvalue['error'] = $result->getMessage();
|
||||
if ($debug) {
|
||||
printf(gettext("RADIUS send failed: %s") . "<br />\n", $retvalue['error']);
|
||||
}
|
||||
log_error(sprintf(gettext("Error during RADIUS authentication : %s"), $rauth->getError()));
|
||||
$attributes['error_message'] = gettext("Error : could not connect to authentication server.");
|
||||
$ret = null;
|
||||
} else if ($result === true) {
|
||||
if ($rauth->getAttributes()) {
|
||||
$attributes = $rauth->listAttributes();
|
||||
}
|
||||
$retvalue['auth_val'] = 2;
|
||||
if ($debug) {
|
||||
printf(gettext("RADIUS Auth succeeded")."<br />\n");
|
||||
}
|
||||
$ret = true;
|
||||
} else {
|
||||
$retvalue['auth_val'] = 3;
|
||||
if ($debug) {
|
||||
printf(gettext("RADIUS Auth rejected")."<br />\n");
|
||||
}
|
||||
$ret = false;
|
||||
}
|
||||
|
||||
|
||||
// Get attributes, even if auth failed.
|
||||
if ($rauth->getAttributes()) {
|
||||
$attributes = array_merge($attributes,$rauth->listAttributes());
|
||||
|
||||
// We convert the session_terminate_time to unixtimestamp if its set before returning the whole array to our caller
|
||||
if (!empty($attributes['session_terminate_time'])) {
|
||||
$stt = &$attributes['session_terminate_time'];
|
||||
$stt = strtotime(preg_replace("/\+(\d+):(\d+)$/", " +\${1}\${2}", preg_replace("/(\d+)T(\d+)/", "\${1} \${2}",$stt)));
|
||||
}
|
||||
}
|
||||
|
||||
// close OO RADIUS_AUTHENTICATION
|
||||
$rauth->close();
|
||||
|
||||
return $ret;
|
||||
@ -1821,6 +1867,12 @@ function getUserGroups($username, $authcfg, &$attributes = array()) {
|
||||
return $member_groups;
|
||||
}
|
||||
|
||||
/*
|
||||
Possible return values :
|
||||
true : authentication worked
|
||||
false : authentication failed (invalid login/password, not enought permission, etc...)
|
||||
null : error during authentication process (unable to reach remote server, etc...)
|
||||
*/
|
||||
function authenticate_user($username, $password, $authcfg = NULL, &$attributes = array()) {
|
||||
|
||||
if (is_array($username) || is_array($password)) {
|
||||
@ -1828,26 +1880,20 @@ function authenticate_user($username, $password, $authcfg = NULL, &$attributes =
|
||||
}
|
||||
|
||||
if (!$authcfg) {
|
||||
return local_backed($username, $password);
|
||||
return local_backed($username, $password, $attributes);
|
||||
}
|
||||
|
||||
$authenticated = false;
|
||||
switch ($authcfg['type']) {
|
||||
case 'ldap':
|
||||
if (ldap_backed($username, $password, $authcfg)) {
|
||||
$authenticated = true;
|
||||
}
|
||||
$authenticated = ldap_backed($username, $password, $authcfg, $attributes);
|
||||
break;
|
||||
case 'radius':
|
||||
if (radius_backed($username, $password, $authcfg, $attributes)) {
|
||||
$authenticated = true;
|
||||
}
|
||||
$authenticated = radius_backed($username, $password, $authcfg, $attributes);
|
||||
break;
|
||||
default:
|
||||
/* lookup user object by name */
|
||||
if (local_backed($username, $password)) {
|
||||
$authenticated = true;
|
||||
}
|
||||
$authenticated = local_backed($username, $password, $attributes);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -69,7 +69,7 @@ $g = array(
|
||||
"disablecrashreporter" => false,
|
||||
"crashreporterurl" => "https://crashreporter.pfsense.org/crash_reporter.php",
|
||||
"debug" => false,
|
||||
"latest_config" => "18.6",
|
||||
"latest_config" => "18.7",
|
||||
"minimum_ram_warning" => "101",
|
||||
"minimum_ram_warning_text" => "128 MB",
|
||||
"wan_interface_name" => "wan",
|
||||
|
||||
@ -32,38 +32,7 @@ require_once("config.inc");
|
||||
require_once("auth.inc");
|
||||
require_once("interfaces.inc");
|
||||
|
||||
/**
|
||||
* Get the NAS-Identifier
|
||||
*
|
||||
* We will use our local hostname to make up the nas_id
|
||||
*/
|
||||
if (!function_exists("getNasID")) {
|
||||
function getNasID() {
|
||||
global $g;
|
||||
|
||||
$nasId = gethostname();
|
||||
if (empty($nasId)) {
|
||||
$nasId = $g['product_name'];
|
||||
}
|
||||
return $nasId;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the NAS-IP-Address based on the current wan address
|
||||
*
|
||||
* Use functions in interfaces.inc to find this out
|
||||
*
|
||||
*/
|
||||
if (!function_exists("getNasIP")) {
|
||||
function getNasIP() {
|
||||
$nasIp = get_interface_ip();
|
||||
if (!$nasIp) {
|
||||
$nasIp = "0.0.0.0";
|
||||
}
|
||||
return $nasIp;
|
||||
}
|
||||
}
|
||||
/* setup syslog logging */
|
||||
openlog("charon", LOG_ODELAY, LOG_AUTH);
|
||||
|
||||
@ -106,7 +75,7 @@ if (($strictusercn === true) && ($common_name != $username)) {
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = array();
|
||||
$attributes = array("nas_identifier" => "xauthIPsec");
|
||||
foreach ($authmodes as $authmode) {
|
||||
$authcfg = auth_get_authserver($authmode);
|
||||
if (!$authcfg && $authmode != "Local Database") {
|
||||
|
||||
@ -31,66 +31,6 @@ require_once("config.inc");
|
||||
require_once("auth.inc");
|
||||
require_once("interfaces.inc");
|
||||
|
||||
/**
|
||||
* Get the NAS-Identifier
|
||||
*
|
||||
* We will return "openVPN" so that connections can be distinguished by the Radius
|
||||
*/
|
||||
if (!function_exists("getNasID")) {
|
||||
function getNasID() {
|
||||
return "openVPN";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the NAS-IP-Address based on the current wan address
|
||||
*
|
||||
* Use functions in interfaces.inc to find this out
|
||||
*
|
||||
*/
|
||||
if (!function_exists("getNasIP")) {
|
||||
function getNasIP() {
|
||||
$nasIp = get_interface_ip();
|
||||
if (!$nasIp) {
|
||||
$nasIp = "0.0.0.0";
|
||||
}
|
||||
return $nasIp;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the NAS-Port-Type
|
||||
*
|
||||
* Should be "Virtual" since that denotes VPN connections
|
||||
*/
|
||||
if (!function_exists("getNasPortType")) {
|
||||
function getNasPortType() {
|
||||
return RADIUS_VIRTUAL;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the NAS-Port
|
||||
*
|
||||
* We will return the port the client connected to
|
||||
*/
|
||||
if (!function_exists("getNasPort")) {
|
||||
function getNasPort() {
|
||||
return $_GET['nas_port'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the Called-Station-ID
|
||||
*
|
||||
* We will return the IP and port the client connected to
|
||||
*/
|
||||
if (!function_exists("getCalledStationId")) {
|
||||
function getCalledStationId() {
|
||||
return get_interface_ip() . ":" . getNasPort();
|
||||
}
|
||||
}
|
||||
|
||||
/* setup syslog logging */
|
||||
openlog("openvpn", LOG_ODELAY, LOG_AUTH);
|
||||
|
||||
@ -157,7 +97,11 @@ if (!is_array($authmodes)) {
|
||||
}
|
||||
}
|
||||
|
||||
$attributes = array();
|
||||
|
||||
$attributes = array("nas_identifier" => "openVPN",
|
||||
"nas_port_type" => RADIUS_VIRTUAL,
|
||||
"nas_port" => $_GET['nas_port']);
|
||||
|
||||
foreach ($authmodes as $authmode) {
|
||||
$authcfg = auth_get_authserver($authmode);
|
||||
if (!$authcfg && $authmode != "Local Database") {
|
||||
|
||||
@ -2104,7 +2104,7 @@ function system_reboot_cleanup() {
|
||||
$cpzoneid = $cp['zoneid'];
|
||||
captiveportal_radius_stop_all(7); // Admin-Reboot
|
||||
/* Send Accounting-Off packet to the RADIUS server */
|
||||
captiveportal_send_server_accounting(true);
|
||||
captiveportal_send_server_accounting('off');
|
||||
}
|
||||
}
|
||||
require_once("voucher.inc");
|
||||
|
||||
@ -5794,6 +5794,110 @@ function upgrade_185_to_186() {
|
||||
}
|
||||
}
|
||||
|
||||
function generate_usermanager_radius_config($cpzone, $counter, $protocol, $ip, $key, $port, $radiussrcip_attribute, $is_accounting=false, $accounting_port=false) {
|
||||
global $config;
|
||||
$pconfig = array();
|
||||
|
||||
if (!is_array($config['system']['authserver'])) {
|
||||
$config['system']['authserver'] = array();
|
||||
}
|
||||
|
||||
$pconfig['name'] = "Auto generated from Captive Portal {$cpzone}";
|
||||
if ($counter != 1) {
|
||||
$pconfig['name'] .= " {$counter}";
|
||||
}
|
||||
$pconfig['radius_srvcs'] = "auth";
|
||||
$pconfig['type'] = 'radius';
|
||||
$pconfig['radius_protocol'] = $protocol;
|
||||
$pconfig['host'] = $ip;
|
||||
$pconfig['radius_secret'] = $key;
|
||||
$pconfig['radius_timeout'] = 3;
|
||||
$pconfig['radius_auth_port'] = $port;
|
||||
$pconfig['radius_nasip_attribute'] = $radiussrcip_attribute;
|
||||
|
||||
if($is_accounting) {
|
||||
$pconfig['radius_srvcs'] = "both";
|
||||
$pconfig['radius_acct_port'] = $accounting_port;
|
||||
}
|
||||
|
||||
$config['system']['authserver'][] = $pconfig;
|
||||
|
||||
return 'radius - '.$pconfig['name'];
|
||||
}
|
||||
|
||||
function upgrade_186_to_187() {
|
||||
global $config;
|
||||
global $g;
|
||||
|
||||
if (is_array($config['captiveportal'])) {
|
||||
foreach ($config['captiveportal'] as $cpzone => $cp) {
|
||||
// we flush any existing sqlite3 db.
|
||||
// It will be automatically re-generated on next captiveportal_readdb()/captiveportal_writedb()
|
||||
$db_path = "{$g['vardb_path']}/captiveportal{$cpzone}.db";
|
||||
unlink_if_exists($db_path);
|
||||
|
||||
if ($cp['auth_method'] === 'radius') { // Radius Auth
|
||||
$auth_servers = array();
|
||||
$auth_servers2 = array();
|
||||
$radiuscounter = 1;
|
||||
|
||||
if (intval($cp['radiusport']) == 0) {
|
||||
$cp['radiusport'] = 1812;
|
||||
}
|
||||
if (intval($cp['radiusacctport']) == 0) {
|
||||
$cp['radiusacctport'] = 1813;
|
||||
}
|
||||
if (!isset($cp['radiussrcip_attribute'])) {
|
||||
$cp['radiussrcip_attribute'] = 'wan';
|
||||
}
|
||||
$auth_servers[] = generate_usermanager_radius_config($cpzone, $radiuscounter, $cp['radius_protocol'], $cp['radiusip'], $cp['radiuskey'], $cp['radiusport'], $cp['radiussrcip_attribute'], isset($cp['radacct_enable']), $cp['radiusacctport']);
|
||||
|
||||
if (!empty($cp['radiusip2'])) {
|
||||
$radiuscounter++;
|
||||
if (intval($cp['radiusport2']) == 0) {
|
||||
$cp['radiusport2'] = 1812;
|
||||
}
|
||||
$auth_servers[] = generate_usermanager_radius_config($cpzone, $radiuscounter, $cp['radius_protocol'], $cp['radiusip2'], $cp['radiuskey2'], $cp['radiusport2'], $cp['radiussrcip_attribute'], false, 0);
|
||||
}
|
||||
if (!empty($cp['radiusip3'])) {
|
||||
$radiuscounter++;
|
||||
if (intval($cp['radiusport3']) == 0) {
|
||||
$cp['radiusport3'] = 1812;
|
||||
}
|
||||
$auth_servers2[] = generate_usermanager_radius_config($cpzone, $radiuscounter, $cp['radius_protocol'], $cp['radiusip3'], $cp['radiuskey3'], $cp['radiusport3'], $cp['radiussrcip_attribute'], false, 0);
|
||||
}
|
||||
if (!empty($cp['radiusip4'])) {
|
||||
$radiuscounter++;
|
||||
if (intval($cp['radiusport4']) == 0) {
|
||||
$cp['radiusport4'] = 1812;
|
||||
}
|
||||
$auth_servers2[] = generate_usermanager_radius_config($cpzone, $radiuscounter, $cp['radius_protocol'], $cp['radiusip4'], $cp['radiuskey4'], $cp['radiusport4'], $cp['radiussrcip_attribute'], false, 0);
|
||||
}
|
||||
|
||||
$cp['auth_method'] = 'authserver';
|
||||
$cp['auth_server'] = implode(",", $auth_servers);
|
||||
$cp['auth_server2'] = implode(",", $auth_servers2);
|
||||
|
||||
if (isset($cp['radmac_enable'])) { // RadMac
|
||||
$cp['auth_method'] = 'radmac';
|
||||
}
|
||||
if (isset($cp['radacct_enable'])) { // If accounting was enabled : we select the primary radius server for accounting
|
||||
$cp['radacct_server'] = "Auto generated from Captive Portal {$cpzone}";
|
||||
if ($cp['reauthenticateacct'] === "") {
|
||||
$cp['reauthenticateacct'] = 'none';
|
||||
}
|
||||
}
|
||||
} elseif ($cp['auth_method'] === 'local') { // Local Auth
|
||||
$cp['auth_method'] = 'authserver';
|
||||
$cp['auth_server'] = "Local Auth - Local Database";
|
||||
}
|
||||
// we don't need to update anything when "none" auth method is selected
|
||||
|
||||
$config['captiveportal'][$cpzone] = $cp;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Special function that is called independent of current config version. It's
|
||||
* a workaround to have config_upgrade running on older versions after next
|
||||
|
||||
@ -100,9 +100,8 @@ function xmlrpc_sync_voucher_disconnect($dbent, $syncip, $port, $password, $user
|
||||
require_once('/etc/inc/captiveportal.inc');
|
||||
require_once('/etc/inc/voucher.inc');
|
||||
\$cpzone = "$cpzone";
|
||||
\$radiusservers = captiveportal_get_radius_servers();
|
||||
\$dbent = unserialize("$dbent_str");
|
||||
return captiveportal_disconnect(\$dbent, \$radiusservers, $term_cause, $tmp_stop_time);
|
||||
return captiveportal_disconnect(\$dbent, $term_cause, $tmp_stop_time);
|
||||
|
||||
EOF;
|
||||
$rpc_client = new pfsense_xmlrpc_client();
|
||||
@ -222,7 +221,7 @@ function voucher_expire($voucher_received) {
|
||||
$cpzoneid = $config['captiveportal'][$cpzone]['zoneid'];
|
||||
}
|
||||
$cpentry = $cpentry[0];
|
||||
captiveportal_disconnect($cpentry, null, 13);
|
||||
captiveportal_disconnect($cpentry, 13);
|
||||
captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "FORCLY TERMINATING VOUCHER {$voucher} SESSION");
|
||||
$unsetindexes[] = $cpentry[5];
|
||||
}
|
||||
|
||||
@ -586,6 +586,8 @@
|
||||
/usr/local/bin/spawn-fcgi
|
||||
/usr/local/bin/tickadj
|
||||
/usr/local/bin/verifysig
|
||||
/usr/local/captiveportal/radius_accounting.inc
|
||||
/usr/local/captiveportal/radius_authentication.inc
|
||||
/usr/local/etc/pkg.conf
|
||||
/usr/local/info
|
||||
/usr/local/lib/engines
|
||||
|
||||
@ -27,8 +27,6 @@ require_once("auth.inc");
|
||||
require_once("functions.inc");
|
||||
require_once("captiveportal.inc");
|
||||
|
||||
$errormsg = "Invalid credentials specified.";
|
||||
|
||||
header("Expires: 0");
|
||||
header("Cache-Control: no-cache, no-store, must-revalidate");
|
||||
header("Pragma: no-cache");
|
||||
@ -40,7 +38,7 @@ $cpzone = strtolower($_REQUEST['zone']);
|
||||
$cpcfg = $config['captiveportal'][$cpzone];
|
||||
if (empty($cpcfg)) {
|
||||
log_error("Submission to captiveportal with unknown parameter zone: " . htmlspecialchars($cpzone));
|
||||
portal_reply_page($redirurl, "error", $errormsg);
|
||||
portal_reply_page($redirurl, "error", gettext("Internal error"));
|
||||
ob_flush();
|
||||
return;
|
||||
}
|
||||
@ -55,7 +53,7 @@ $clientip = $_SERVER['REMOTE_ADDR'];
|
||||
if (!$clientip) {
|
||||
/* not good - bail out */
|
||||
log_error("Zone: {$cpzone} - Captive portal could not determine client's IP address.");
|
||||
$error_message = "An error occurred. Please check the system logs for more information.";
|
||||
$errormsg = gettext("An error occurred. Please check the system logs for more information.");
|
||||
portal_reply_page($redirurl, "error", $errormsg);
|
||||
ob_flush();
|
||||
return;
|
||||
@ -79,7 +77,12 @@ if ((!empty($cpsession)) && (! $_POST['logout_id']) && (!empty($cpcfg['page']['l
|
||||
include("{$g['varetc_path']}/captiveportal-{$cpzone}-logout.html");
|
||||
ob_flush();
|
||||
return;
|
||||
} else if ($orig_host != $ourhostname) {
|
||||
} elseif (!empty($cpsession)) {
|
||||
/*If someone try to access captive portal page while already connected*/
|
||||
echo gettext("You are connected.");
|
||||
ob_flush();
|
||||
return;
|
||||
} elseif ($orig_host != $ourhostname) {
|
||||
/* the client thinks it's connected to the desired web server, but instead
|
||||
it's connected to us. Issue a redirect... */
|
||||
$protocol = (isset($cpcfg['httpslogin'])) ? 'https://' : 'http://';
|
||||
@ -91,9 +94,9 @@ if ((!empty($cpsession)) && (! $_POST['logout_id']) && (!empty($cpcfg['page']['l
|
||||
|
||||
if (!empty($cpcfg['redirurl'])) {
|
||||
$redirurl = $cpcfg['redirurl'];
|
||||
} else if (preg_match("/redirurl=(.*)/", $orig_request, $matches)) {
|
||||
} elseif (preg_match("/redirurl=(.*)/", $orig_request, $matches)) {
|
||||
$redirurl = urldecode($matches[1]);
|
||||
} else if ($_REQUEST['redirurl']) {
|
||||
} elseif ($_REQUEST['redirurl']) {
|
||||
$redirurl = $_REQUEST['redirurl'];
|
||||
}
|
||||
|
||||
@ -115,20 +118,6 @@ if ($macfilter || $passthrumac) {
|
||||
unset($tmpres);
|
||||
}
|
||||
|
||||
/* find out if we need RADIUS + RADIUSMAC or not */
|
||||
if (file_exists("{$g['vardb_path']}/captiveportal_radius_{$cpzone}.db")) {
|
||||
$radius_enable = TRUE;
|
||||
if (isset($cpcfg['radmac_enable'])) {
|
||||
$radmac_enable = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
/* find radius context */
|
||||
$radiusctx = 'first';
|
||||
if ($_POST['auth_user2']) {
|
||||
$radiusctx = 'second';
|
||||
}
|
||||
|
||||
if ($_POST['logout_id']) {
|
||||
echo <<<EOD
|
||||
<html>
|
||||
@ -150,24 +139,25 @@ EOD;
|
||||
$safe_logout_id = SQLite3::escapeString($_POST['logout_id']);
|
||||
captiveportal_disconnect_client($safe_logout_id);
|
||||
|
||||
} else if ($macfilter && $clientmac && captiveportal_blocked_mac($clientmac)) {
|
||||
} elseif (($_POST['accept'] || $cpcfg['auth_method'] === 'radmac') && $macfilter && $clientmac && captiveportal_blocked_mac($clientmac)) {
|
||||
captiveportal_logportalauth($clientmac, $clientmac, $clientip, "Blocked MAC address");
|
||||
if (!empty($cpcfg['blockedmacsurl'])) {
|
||||
portal_reply_page($cpcfg['blockedmacsurl'], "redir");
|
||||
} else {
|
||||
portal_reply_page($redirurl, "error", "This MAC address has been blocked");
|
||||
if ($cpcfg['auth_method'] === 'radmac') {
|
||||
echo gettext("This MAC address has been blocked");
|
||||
} else {
|
||||
portal_reply_page($redirurl, "error", "This MAC address has been blocked");
|
||||
}
|
||||
}
|
||||
|
||||
} else if ($clientmac && $radmac_enable && portal_mac_radius($clientmac, $clientip, $radiusctx)) {
|
||||
/* radius functions handle everything so we exit here since we're done */
|
||||
|
||||
} else if (portal_consume_passthrough_credit($clientmac)) {
|
||||
} elseif (portal_consume_passthrough_credit($clientmac)) {
|
||||
/* allow the client through if it had a pass-through credit for its MAC */
|
||||
captiveportal_logportalauth("unauthenticated", $clientmac, $clientip, "ACCEPT");
|
||||
portal_allow($clientip, $clientmac, "unauthenticated");
|
||||
|
||||
} else if (isset($config['voucher'][$cpzone]['enable']) && $_POST['accept'] && $_POST['auth_voucher']) {
|
||||
} elseif (isset($config['voucher'][$cpzone]['enable']) && $_POST['accept'] && $_POST['auth_voucher']) {
|
||||
$voucher = trim($_POST['auth_voucher']);
|
||||
$errormsg = gettext("Invalid credentials specified.");
|
||||
$timecredit = voucher_auth($voucher);
|
||||
// $timecredit contains either a credit in minutes or an error message
|
||||
if ($timecredit > 0) { // voucher is valid. Remaining minutes returned
|
||||
@ -178,13 +168,13 @@ EOD;
|
||||
'voucher' => 1,
|
||||
'session_timeout' => $timecredit*60,
|
||||
'session_terminate_time' => 0);
|
||||
if (portal_allow($clientip, $clientmac, $voucher, null, $attr)) {
|
||||
if (portal_allow($clientip, $clientmac, $voucher, null, $attr, null, 'voucher', 'voucher')) {
|
||||
// YES: user is good for $timecredit minutes.
|
||||
captiveportal_logportalauth($voucher, $clientmac, $clientip, "Voucher login good for $timecredit min.");
|
||||
} else {
|
||||
portal_reply_page($redirurl, "error", $config['voucher'][$cpzone]['descrmsgexpired'] ? $config['voucher'][$cpzone]['descrmsgexpired']: $errormsg);
|
||||
}
|
||||
} else if (-1 == $timecredit) { // valid but expired
|
||||
} elseif (-1 == $timecredit) { // valid but expired
|
||||
captiveportal_logportalauth($voucher, $clientmac, $clientip, "FAILURE", "voucher expired");
|
||||
portal_reply_page($redirurl, "error", $config['voucher'][$cpzone]['descrmsgexpired'] ? $config['voucher'][$cpzone]['descrmsgexpired']: $errormsg);
|
||||
} else {
|
||||
@ -192,65 +182,65 @@ EOD;
|
||||
portal_reply_page($redirurl, "error", $config['voucher'][$cpzone]['descrmsgnoaccess'] ? $config['voucher'][$cpzone]['descrmsgnoaccess'] : $errormsg);
|
||||
}
|
||||
|
||||
} else if ($_POST['accept'] && $radius_enable) {
|
||||
if (($_POST['auth_user'] && isset($_POST['auth_pass'])) || ($_POST['auth_user2'] && isset($_POST['auth_pass2']))) {
|
||||
if (!empty($_POST['auth_user'])) {
|
||||
$user = $_POST['auth_user'];
|
||||
$paswd = $_POST['auth_pass'];
|
||||
} else if (!empty($_POST['auth_user2'])) {
|
||||
} elseif ($_POST['accept'] || $cpcfg['auth_method'] === 'radmac') {
|
||||
|
||||
if (!empty($_POST['auth_user2'])) {
|
||||
$user = $_POST['auth_user2'];
|
||||
$paswd = $_POST['auth_pass2'];
|
||||
$passwd = $_POST['auth_pass2'];
|
||||
$context = 'second'; // Assume users to use the first context if auth_user2 is empty/does not exist
|
||||
} else {
|
||||
$user = $_POST['auth_user'];
|
||||
$passwd = $_POST['auth_pass'];
|
||||
$context = 'first';
|
||||
}
|
||||
$auth_list = radius($user, $paswd, $clientip, $clientmac, "USER LOGIN", $radiusctx);
|
||||
|
||||
$pipeno = captiveportal_get_next_dn_ruleno();
|
||||
/* if the pool is empty, return appropriate message and exit */
|
||||
if (is_null($pipeno)) {
|
||||
$replymsg = gettext("System reached maximum login capacity");
|
||||
if ($cpcfg['auth_method'] === 'radmac') {
|
||||
echo $replymsg;
|
||||
ob_flush();
|
||||
return;
|
||||
} else {
|
||||
portal_reply_page($redirurl, "error", $replymsg);
|
||||
}
|
||||
log_error("Zone: {$cpzone} - WARNING! Captive portal has reached maximum login capacity");
|
||||
|
||||
}
|
||||
|
||||
$auth_result = captiveportal_authenticate_user($user, $passwd, $clientmac, $clientip, $pipeno, $context);
|
||||
|
||||
if ($auth_result['result']) {
|
||||
captiveportal_logportalauth($user, $clientmac, $clientip, $auth_result['login_status']);
|
||||
portal_allow($clientip, $clientmac, $user, $passwd, $auth_result['attributes'], $pipeno, $auth_result['auth_method'], $context);
|
||||
|
||||
} else {
|
||||
captiveportal_free_dn_ruleno($pipeno);
|
||||
$type = "error";
|
||||
if (!empty($auth_list['url_redirection'])) {
|
||||
$redirurl = $auth_list['url_redirection'];
|
||||
|
||||
if (!empty($auth_result['attributes']['url_redirection'])) {
|
||||
$redirurl = $auth_result['attributes']['url_redirection'];
|
||||
$type = "redir";
|
||||
}
|
||||
|
||||
if ($auth_list['auth_val'] == 1) {
|
||||
captiveportal_logportalauth($user, $clientmac, $clientip, "ERROR", $auth_list['error']);
|
||||
portal_reply_page($redirurl, $type, $auth_list['error'] ? $auth_list['error'] : $errormsg);
|
||||
} else if ($auth_list['auth_val'] == 3) {
|
||||
captiveportal_logportalauth($user, $clientmac, $clientip, "FAILURE", $auth_list['reply_message']);
|
||||
portal_reply_page($redirurl, $type, $auth_list['reply_message'] ? $auth_list['reply_message'] : $errormsg);
|
||||
}
|
||||
} else {
|
||||
if (!empty($_POST['auth_user'])) {
|
||||
$user = $_POST['auth_user'];
|
||||
} else if (!empty($_POST['auth_user2'])) {
|
||||
$user = $_POST['auth_user2'];
|
||||
|
||||
if ($auth_result['login_message']) {
|
||||
$replymsg = $auth_result['login_message'];
|
||||
} else {
|
||||
$user = 'unknown';
|
||||
$replymsg = gettext("Invalid credentials specified.");
|
||||
}
|
||||
captiveportal_logportalauth($user, $clientmac, $clientip, "ERROR");
|
||||
portal_reply_page($redirurl, "error", $errormsg);
|
||||
}
|
||||
|
||||
captiveportal_logportalauth($user, $clientmac, $clientip, $auth_result['login_status'], $replymsg);
|
||||
|
||||
} else if ($_POST['accept'] && $cpcfg['auth_method'] == "local") {
|
||||
if ($_POST['auth_user'] && $_POST['auth_pass']) {
|
||||
//check against local user manager
|
||||
$loginok = local_backed($_POST['auth_user'], $_POST['auth_pass']);
|
||||
|
||||
if ($loginok && isset($cpcfg['localauth_priv'])) {
|
||||
$loginok = userHasPrivilege(getUserEntry($_POST['auth_user']), "user-services-captiveportal-login");
|
||||
}
|
||||
|
||||
if ($loginok) {
|
||||
captiveportal_logportalauth($_POST['auth_user'], $clientmac, $clientip, "LOGIN");
|
||||
portal_allow($clientip, $clientmac, $_POST['auth_user']);
|
||||
/*Radius MAC authentication. */
|
||||
if ($cpcfg['auth_method'] === 'radmac' && $type !== 'redir') {
|
||||
echo gettext("RADIUS MAC Authentication Failed.");
|
||||
ob_flush();
|
||||
exit();
|
||||
} else {
|
||||
captiveportal_logportalauth($_POST['auth_user'], $clientmac, $clientip, "FAILURE");
|
||||
portal_reply_page($redirurl, "error", $errormsg);
|
||||
portal_reply_page($redirurl, $type, $replymsg);
|
||||
}
|
||||
} else {
|
||||
portal_reply_page($redirurl, "error", $errormsg);
|
||||
}
|
||||
|
||||
} else if ($_POST['accept'] && $clientip && $cpcfg['auth_method'] == "none") {
|
||||
captiveportal_logportalauth("unauthenticated", $clientmac, $clientip, "ACCEPT");
|
||||
portal_allow($clientip, $clientmac, "unauthenticated");
|
||||
|
||||
} else {
|
||||
/* display captive portal page */
|
||||
portal_reply_page($redirurl, "login", null, $clientmac, $clientip);
|
||||
|
||||
@ -1,327 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
Copyright (c) 2006, Jonathan De Graeve <jonathan.de.graeve@imelda.be>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. The names of the authors may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
This code cannot simply be copied and put under the GNU Public License or
|
||||
any other GPL-like (LGPL, GPL2) License.
|
||||
|
||||
This code is made possible thx to samples made by
|
||||
Michael Bretterklieber <michael@bretterklieber.com>
|
||||
author of the PHP PECL Radius package
|
||||
*/
|
||||
|
||||
require_once("PEAR.php");
|
||||
require_once("Auth/RADIUS.php");
|
||||
|
||||
define('GIGAWORDS_RIGHT_OPERAND', '4294967296'); // 2^32
|
||||
|
||||
PEAR::loadExtension('bcmath');
|
||||
|
||||
function RADIUS_ACCOUNTING_START($ruleno, $username, $sessionid, $radiusservers,
|
||||
$clientip, $clientmac) {
|
||||
global $config, $cpzone;
|
||||
|
||||
$retvalue = array();
|
||||
$nas_mac = mac_format(get_interface_mac("wan"));
|
||||
$clientmac = mac_format($clientmac);
|
||||
$nas_port = intval($ruleno);
|
||||
$radiusvendor = $config['captiveportal'][$cpzone]['radiusvendor']
|
||||
? $config['captiveportal'][$cpzone]['radiusvendor'] : null;
|
||||
|
||||
switch ($radiusvendor) {
|
||||
case 'cisco':
|
||||
$calledstationid = $clientmac;
|
||||
$callingstationid = $clientip;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!function_exists('getNasIP'))
|
||||
require_once("captiveportal.inc");
|
||||
$calledstationid = getNasIP();
|
||||
$callingstationid = $clientmac;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Create our instance */
|
||||
$racct = new Auth_RADIUS_Acct_Start;
|
||||
|
||||
/*
|
||||
* Different Authentication options
|
||||
*
|
||||
* Its possible todo other authentication methods but still do radius
|
||||
* accounting
|
||||
*
|
||||
* RADIUS_AUTH_RADIUS => authenticated via Radius
|
||||
* RADIUS_AUTH_LOCAL => authenticated local
|
||||
* RADIUS_AUTH_REMOTE => authenticated remote
|
||||
*/
|
||||
$racct->authentic = RADIUS_AUTH_RADIUS;
|
||||
|
||||
/* Construct data package */
|
||||
$racct->username = $username;
|
||||
/*
|
||||
* Add support for more then one radiusserver.
|
||||
* At most 10 servers may be specified.
|
||||
* When multiple servers are given, they are tried in round-robin
|
||||
* fashion until a valid response is received
|
||||
*/
|
||||
foreach ($radiusservers as $radsrv) {
|
||||
/* Add a new server to our instance */
|
||||
$racct->addServer($radsrv['ipaddr'], $radsrv['acctport'],
|
||||
$radsrv['key']);
|
||||
}
|
||||
|
||||
if (PEAR::isError($racct->start())) {
|
||||
$retvalue['acct_val'] = 1;
|
||||
$retvalue['error'] = $racct->getMessage();
|
||||
|
||||
/*
|
||||
* If we encounter an error immediately stop this function and
|
||||
* go back
|
||||
*/
|
||||
$racct->close();
|
||||
return $retvalue;
|
||||
}
|
||||
|
||||
/*
|
||||
* NAS_PORT_TYPE, int => RADIUS_ETHERNET (15),
|
||||
* RADIUS_WIRELESS_OTHER (18), RADIUS_WIRELESS_IEEE_802_11 (19)
|
||||
*/
|
||||
|
||||
/* Default attributes */
|
||||
$racct->putAttribute(RADIUS_NAS_PORT_TYPE, RADIUS_ETHERNET);
|
||||
$racct->putAttribute(RADIUS_NAS_PORT, $nas_port, 'integer');
|
||||
$racct->putAttribute(RADIUS_ACCT_SESSION_ID, $sessionid);
|
||||
|
||||
/* Extra data to identify the client and nas */
|
||||
$racct->putAttribute(RADIUS_FRAMED_IP_ADDRESS, $clientip, "addr");
|
||||
$racct->putAttribute(RADIUS_CALLED_STATION_ID, $calledstationid);
|
||||
$racct->putAttribute(RADIUS_CALLING_STATION_ID, $callingstationid);
|
||||
|
||||
/* Send request */
|
||||
$result = $racct->send();
|
||||
|
||||
/*
|
||||
* Evaluation of the response
|
||||
* 5 -> Accounting-Response
|
||||
* See RFC2866 for this.
|
||||
*/
|
||||
if (PEAR::isError($result)) {
|
||||
$retvalue['acct_val'] = 1;
|
||||
$retvalue['error'] = $result->getMessage();
|
||||
|
||||
} else if ($result === true) {
|
||||
$retvalue['acct_val'] = 5 ;
|
||||
|
||||
} else {
|
||||
$retvalue['acct_val'] = 1 ;
|
||||
|
||||
}
|
||||
|
||||
/* close OO RADIUS_ACCOUNTING */
|
||||
$racct->close();
|
||||
unset($racct);
|
||||
|
||||
return $retvalue ;
|
||||
|
||||
}
|
||||
|
||||
function RADIUS_ACCOUNTING_STOP($ruleno, $username, $sessionid, $start_time,
|
||||
$radiusservers, $clientip, $clientmac, $term_cause = 1,
|
||||
$interimupdate = false, $stop_time = null) {
|
||||
global $config, $cpzone;
|
||||
|
||||
$retvalue = array();
|
||||
$nas_mac = mac_format(get_interface_mac("wan"));
|
||||
$volume = getVolume($clientip);
|
||||
$clientmac = mac_format($clientmac);
|
||||
$nas_port = intval($ruleno);
|
||||
$radiusvendor = $config['captiveportal'][$cpzone]['radiusvendor']
|
||||
? $config['captiveportal'][$cpzone]['radiusvendor'] : null;
|
||||
$stop_time = (empty($stop_time)) ? time() : $stop_time;
|
||||
$session_time = $stop_time - $start_time;
|
||||
$volume['input_bytes_radius'] = remainder($volume['input_bytes']);
|
||||
$volume['input_gigawords'] = gigawords($volume['input_bytes']);
|
||||
$volume['output_bytes_radius'] = remainder($volume['output_bytes']);
|
||||
$volume['output_gigawords'] = gigawords($volume['output_bytes']);
|
||||
|
||||
switch($radiusvendor) {
|
||||
|
||||
case 'cisco':
|
||||
$calledstationid = $clientmac;
|
||||
$callingstationid = $clientip;
|
||||
break;
|
||||
|
||||
default:
|
||||
$calledstationid = getNasIP();
|
||||
$callingstationid = $clientmac;
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create our instance, see if we should use Accounting Interim Updates
|
||||
* or Accounting STOP messages
|
||||
*/
|
||||
if ($interimupdate) {
|
||||
$racct = new Auth_RADIUS_Acct_Update;
|
||||
} else {
|
||||
$racct = new Auth_RADIUS_Acct_Stop;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add support for more then one radiusserver.
|
||||
* At most 10 servers may be specified.
|
||||
* When multiple servers are given, they are tried in round-robin
|
||||
* fashion until a valid response is received
|
||||
*/
|
||||
foreach ($radiusservers as $radsrv) {
|
||||
/* Add a new server to our instance */
|
||||
$racct->addServer($radsrv['ipaddr'], $radsrv['acctport'],
|
||||
$radsrv['key']);
|
||||
}
|
||||
|
||||
/* See RADIUS_ACCOUNTING_START for info */
|
||||
$racct->authentic = RADIUS_AUTH_RADIUS;
|
||||
|
||||
/* Construct data package */
|
||||
$racct->username = $username;
|
||||
/* Set session_time */
|
||||
$racct->session_time = $session_time;
|
||||
|
||||
if (PEAR::isError($racct->start())) {
|
||||
$retvalue['acct_val'] = 1;
|
||||
$retvalue['error'] = $racct->getMessage();
|
||||
|
||||
/*
|
||||
* If we encounter an error immediately stop this function and
|
||||
* go back
|
||||
*/
|
||||
$racct->close();
|
||||
return $retvalue;
|
||||
}
|
||||
|
||||
/*
|
||||
* The RADIUS PECL Package doesn't have this vars so we create them
|
||||
* ourself
|
||||
*/
|
||||
define("RADIUS_ACCT_INPUT_GIGAWORDS", "52");
|
||||
define("RADIUS_ACCT_OUTPUT_GIGAWORDS", "53");
|
||||
|
||||
/* Default attributes */
|
||||
$racct->putAttribute(RADIUS_NAS_PORT_TYPE, RADIUS_ETHERNET);
|
||||
$racct->putAttribute(RADIUS_NAS_PORT, $nas_port, 'integer');
|
||||
$racct->putAttribute(RADIUS_ACCT_SESSION_ID, $sessionid);
|
||||
|
||||
/* Extra data to identify the client and nas */
|
||||
$racct->putAttribute(RADIUS_FRAMED_IP_ADDRESS, $clientip, "addr");
|
||||
$racct->putAttribute(RADIUS_CALLED_STATION_ID, $calledstationid);
|
||||
$racct->putAttribute(RADIUS_CALLING_STATION_ID, $callingstationid);
|
||||
|
||||
/* Volume stuff: Ingress */
|
||||
$racct->putAttribute(RADIUS_ACCT_INPUT_PACKETS, $volume['input_pkts'],
|
||||
"integer");
|
||||
$racct->putAttribute(RADIUS_ACCT_INPUT_OCTETS,
|
||||
$volume['input_bytes_radius'], "integer");
|
||||
$racct->putAttribute(RADIUS_ACCT_INPUT_GIGAWORDS,
|
||||
$volume['input_gigawords'], "integer");
|
||||
/* Volume stuff: Outgress */
|
||||
$racct->putAttribute(RADIUS_ACCT_OUTPUT_PACKETS,
|
||||
$volume['output_pkts'], "integer");
|
||||
$racct->putAttribute(RADIUS_ACCT_OUTPUT_OCTETS,
|
||||
$volume['output_bytes_radius'], "integer");
|
||||
$racct->putAttribute(RADIUS_ACCT_OUTPUT_GIGAWORDS,
|
||||
$volume['output_gigawords'], "integer");
|
||||
$racct->putAttribute(RADIUS_ACCT_SESSION_TIME,
|
||||
$session_time, "integer");
|
||||
|
||||
if (!$interimupdate)
|
||||
$racct->putAttribute(RADIUS_ACCT_TERMINATE_CAUSE, $term_cause);
|
||||
|
||||
/* Send request */
|
||||
$result = $racct->send();
|
||||
|
||||
/*
|
||||
* Evaluation of the response
|
||||
* 5 -> Accounting-Response
|
||||
* See RFC2866 for this.
|
||||
*/
|
||||
if (PEAR::isError($result)) {
|
||||
$retvalue['acct_val'] = 1;
|
||||
$retvalue['error'] = $result->getMessage();
|
||||
|
||||
} else if ($result === true) {
|
||||
$retvalue['acct_val'] = 5 ;
|
||||
|
||||
} else {
|
||||
$retvalue['acct_val'] = 1 ;
|
||||
|
||||
}
|
||||
|
||||
/* close OO RADIUS_ACCOUNTING */
|
||||
$racct->close();
|
||||
|
||||
return $retvalue;
|
||||
}
|
||||
|
||||
function gigawords($bytes) {
|
||||
/*
|
||||
* RFC2866 Specifies a 32bit unsigned integer, which is a max of
|
||||
* 4294967295
|
||||
* Currently there is a fault in the PECL radius_put_int function which
|
||||
* can handle only 32bit signed integer.
|
||||
*/
|
||||
|
||||
/*
|
||||
* We use BCMath functions since normal integers don't work with so
|
||||
* large numbers
|
||||
*/
|
||||
$gigawords = bcdiv( bcsub( $bytes, remainder($bytes) ) ,
|
||||
GIGAWORDS_RIGHT_OPERAND) ;
|
||||
|
||||
/*
|
||||
* We need to manually set this to a zero instead of NULL for put_int()
|
||||
* safety
|
||||
*/
|
||||
if (is_null($gigawords)) {
|
||||
$gigawords = 0;
|
||||
}
|
||||
|
||||
return $gigawords;
|
||||
}
|
||||
|
||||
function remainder($bytes) {
|
||||
/* Calculate the bytes we are going to send to the radius */
|
||||
$bytes = bcmod($bytes, GIGAWORDS_RIGHT_OPERAND);
|
||||
|
||||
if (is_null($bytes)) {
|
||||
$bytes = 0;
|
||||
}
|
||||
|
||||
return $bytes;
|
||||
}
|
||||
|
||||
?>
|
||||
@ -1,202 +0,0 @@
|
||||
<?php
|
||||
/*
|
||||
Copyright (c) 2006, Jonathan De Graeve <jonathan.de.graeve@imelda.be>
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met:
|
||||
|
||||
1. Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
2. Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
3. The names of the authors may not be used to endorse or promote products
|
||||
derived from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
|
||||
IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
|
||||
INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
|
||||
OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
This code cannot simply be copied and put under the GNU Public License or
|
||||
any other GPL-like (LGPL, GPL2) License.
|
||||
|
||||
This code is made possible thx to samples made by Michael Bretterklieber <michael@bretterklieber.com>
|
||||
author of the PHP PECL Radius package
|
||||
|
||||
*/
|
||||
|
||||
require_once("PEAR.php");
|
||||
require_once("Auth/RADIUS.php");
|
||||
require_once("Crypt/CHAP.php");
|
||||
|
||||
function RADIUS_AUTHENTICATION($username,$password,$radiusservers,$clientip,$clientmac,$ruleno) {
|
||||
global $config, $cpzone;
|
||||
|
||||
$retvalue = array();
|
||||
$clientmac = mac_format($clientmac);
|
||||
$nas_port = $ruleno;
|
||||
$radiusvendor = $config['captiveportal'][$cpzone]['radiusvendor']
|
||||
? $config['captiveportal'][$cpzone]['radiusvendor']
|
||||
: null;
|
||||
$radius_protocol = $config['captiveportal'][$cpzone]['radius_protocol'];
|
||||
/* Do we even need to set it to NULL? */
|
||||
$retvalue['error'] = null;
|
||||
$retvalue['reply_message'] = null;
|
||||
$retvalue['url_redirection'] = null;
|
||||
$retvalue['session_timeout'] = null;
|
||||
$retvalue['idle_timeout'] = null;
|
||||
$retvalue['session_terminate_time'] = null;
|
||||
$retvalue['interim_interval'] = null;
|
||||
|
||||
switch($radiusvendor) {
|
||||
case 'cisco':
|
||||
$calledstationid = $clientmac;
|
||||
$callingstationid = $clientip;
|
||||
break;
|
||||
default:
|
||||
if (!function_exists('getNasIP')) {
|
||||
require_once("captiveportal.inc");
|
||||
}
|
||||
$calledstationid = getNasIP();
|
||||
$callingstationid = $clientmac;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Create our instance */
|
||||
$classname = 'Auth_RADIUS_' . $radius_protocol;
|
||||
$rauth = new $classname($username, $password);
|
||||
|
||||
/*
|
||||
* Add support for more then one radiusserver.
|
||||
* At most 10 servers may be specified.
|
||||
* When multiple servers are given, they are tried in round-robin
|
||||
* fashion until a valid response is received
|
||||
*/
|
||||
foreach ($radiusservers as $radsrv) {
|
||||
/* Add a new server to our instance */
|
||||
$rauth->addServer($radsrv['ipaddr'], $radsrv['port'],
|
||||
$radsrv['key']);
|
||||
}
|
||||
|
||||
/* Construct data package */
|
||||
$rauth->username = $username;
|
||||
switch ($radius_protocol) {
|
||||
case 'CHAP_MD5':
|
||||
case 'MSCHAPv1':
|
||||
$classname = $radius_protocol == 'MSCHAPv1'
|
||||
? 'Crypt_CHAP_MSv1' : 'Crypt_CHAP_MD5';
|
||||
$crpt = new $classname;
|
||||
$crpt->username = $username;
|
||||
$crpt->password = $password;
|
||||
$rauth->challenge = $crpt->challenge;
|
||||
$rauth->chapid = $crpt->chapid;
|
||||
$rauth->response = $crpt->challengeResponse();
|
||||
$rauth->flags = 1;
|
||||
/*
|
||||
* If you must use deprecated and weak LAN-Manager-Responses
|
||||
* use this:
|
||||
* $rauth->lmResponse = $crpt->lmChallengeResponse();
|
||||
* $rauth->flags = 0;
|
||||
*/
|
||||
break;
|
||||
|
||||
case 'MSCHAPv2':
|
||||
/* Construct data package */
|
||||
$crpt = new Crypt_CHAP_MSv2;
|
||||
$crpt->username = $username;
|
||||
$crpt->password = $password;
|
||||
$rauth->challenge = $crpt->authChallenge;
|
||||
$rauth->peerChallenge = $crpt->peerChallenge;
|
||||
$rauth->chapid = $crpt->chapid;
|
||||
$rauth->response = $crpt->challengeResponse();
|
||||
break;
|
||||
|
||||
default:
|
||||
$rauth->password = $password;
|
||||
break;
|
||||
}
|
||||
|
||||
if (PEAR::isError($rauth->start())) {
|
||||
$retvalue['auth_val'] = 1;
|
||||
$retvalue['error'] = $rauth->getError();
|
||||
|
||||
/*
|
||||
* If we encounter an error immediately stop this function
|
||||
* and go back
|
||||
*/
|
||||
$rauth->close();
|
||||
return $retvalue;
|
||||
}
|
||||
|
||||
/* Default attributes */
|
||||
$rauth->putAttribute(RADIUS_SERVICE_TYPE, RADIUS_LOGIN);
|
||||
$rauth->putAttribute(RADIUS_NAS_PORT_TYPE, RADIUS_ETHERNET);
|
||||
$rauth->putAttribute(RADIUS_NAS_PORT, $nas_port, 'integer');
|
||||
|
||||
/* Extra data to identify the client and nas */
|
||||
$rauth->putAttribute(RADIUS_FRAMED_IP_ADDRESS, $clientip, 'addr');
|
||||
$rauth->putAttribute(RADIUS_CALLED_STATION_ID, $calledstationid);
|
||||
$rauth->putAttribute(RADIUS_CALLING_STATION_ID, $callingstationid);
|
||||
|
||||
/* Send request */
|
||||
$result = $rauth->send();
|
||||
|
||||
/*
|
||||
* Evaluation of the response
|
||||
* 1 -> Access-Request => We will use this value as an error indicator
|
||||
* since we can't get a 1 back from the radius
|
||||
* 2 -> Access-Accept
|
||||
* 3 -> Access-Reject
|
||||
* See RFC2865 for this.
|
||||
*/
|
||||
if (PEAR::isError($result)) {
|
||||
$retvalue['auth_val'] = 1;
|
||||
$retvalue['error'] = $result->getMessage();
|
||||
|
||||
} else if ($result === true) {
|
||||
$retvalue['auth_val'] = 2;
|
||||
|
||||
} else {
|
||||
$retvalue['auth_val'] = 3;
|
||||
|
||||
}
|
||||
|
||||
/*
|
||||
* Get attributes, even if auth failed.
|
||||
* We will push the results in the retvalue array
|
||||
*/
|
||||
if (!$rauth->getAttributes()) {
|
||||
$retvalue['error'] = $rauth->getError();
|
||||
|
||||
} else {
|
||||
$retvalue = array_merge($retvalue,$rauth->listAttributes());
|
||||
|
||||
/*
|
||||
* We convert the session_terminate_time to unixtimestamp if
|
||||
* its set before returning the whole array to our caller
|
||||
*/
|
||||
if (!empty($retvalue['session_terminate_time'])) {
|
||||
$stt = &$retvalue['session_terminate_time'];
|
||||
$stt = strtotime(preg_replace("/\+(\d+):(\d+)$/",
|
||||
" +\${1}\${2}", preg_replace("/(\d+)T(\d+)/",
|
||||
"\${1} \${2}",$stt)));
|
||||
}
|
||||
}
|
||||
|
||||
/* close OO RADIUS_AUTHENTICATION */
|
||||
$rauth->close();
|
||||
unset($rauth);
|
||||
|
||||
return $retvalue;
|
||||
}
|
||||
|
||||
?>
|
||||
@ -140,6 +140,7 @@ $a_cert =& $config['cert'];
|
||||
|
||||
if ($a_cp[$cpzone]) {
|
||||
$cpzoneid = $pconfig['zoneid'] = $a_cp[$cpzone]['zoneid'];
|
||||
$pconfig['descr'] = $a_cp[$cpzone]['descr'];
|
||||
$pconfig['cinterface'] = $a_cp[$cpzone]['interface'];
|
||||
$pconfig['maxproc'] = $a_cp[$cpzone]['maxproc'];
|
||||
$pconfig['maxprocperip'] = $a_cp[$cpzone]['maxprocperip'];
|
||||
@ -151,9 +152,11 @@ if ($a_cp[$cpzone]) {
|
||||
$pconfig['freelogins_updatetimeouts'] = isset($a_cp[$cpzone]['freelogins_updatetimeouts']);
|
||||
$pconfig['enable'] = isset($a_cp[$cpzone]['enable']);
|
||||
$pconfig['auth_method'] = $a_cp[$cpzone]['auth_method'];
|
||||
$pconfig['auth_server'] = explode(",", $a_cp[$cpzone]['auth_server']);
|
||||
$pconfig['auth_server2'] = explode(",", $a_cp[$cpzone]['auth_server2']);
|
||||
$pconfig['localauth_priv'] = isset($a_cp[$cpzone]['localauth_priv']);
|
||||
$pconfig['radacct_server'] = $a_cp[$cpzone]['radacct_server'];
|
||||
$pconfig['radacct_enable'] = isset($a_cp[$cpzone]['radacct_enable']);
|
||||
$pconfig['radmac_enable'] = isset($a_cp[$cpzone]['radmac_enable']);
|
||||
$pconfig['radmac_secret'] = $a_cp[$cpzone]['radmac_secret'];
|
||||
$pconfig['reauthenticate'] = isset($a_cp[$cpzone]['reauthenticate']);
|
||||
$pconfig['reauthenticateacct'] = $a_cp[$cpzone]['reauthenticateacct'];
|
||||
@ -169,32 +172,15 @@ if ($a_cp[$cpzone]) {
|
||||
$pconfig['bwdefaultup'] = $a_cp[$cpzone]['bwdefaultup'];
|
||||
$pconfig['nomacfilter'] = isset($a_cp[$cpzone]['nomacfilter']);
|
||||
$pconfig['noconcurrentlogins'] = isset($a_cp[$cpzone]['noconcurrentlogins']);
|
||||
$pconfig['radius_protocol'] = $a_cp[$cpzone]['radius_protocol'];
|
||||
$pconfig['redirurl'] = $a_cp[$cpzone]['redirurl'];
|
||||
$pconfig['radiusip'] = $a_cp[$cpzone]['radiusip'];
|
||||
$pconfig['radiusip2'] = $a_cp[$cpzone]['radiusip2'];
|
||||
$pconfig['radiusip3'] = $a_cp[$cpzone]['radiusip3'];
|
||||
$pconfig['radiusip4'] = $a_cp[$cpzone]['radiusip4'];
|
||||
$pconfig['radiusport'] = $a_cp[$cpzone]['radiusport'];
|
||||
$pconfig['radiusport2'] = $a_cp[$cpzone]['radiusport2'];
|
||||
$pconfig['radiusport3'] = $a_cp[$cpzone]['radiusport3'];
|
||||
$pconfig['radiusport4'] = $a_cp[$cpzone]['radiusport4'];
|
||||
$pconfig['radiusacctport'] = $a_cp[$cpzone]['radiusacctport'];
|
||||
$pconfig['radiuskey'] = $a_cp[$cpzone]['radiuskey'];
|
||||
$pconfig['radiuskey2'] = $a_cp[$cpzone]['radiuskey2'];
|
||||
$pconfig['radiuskey3'] = $a_cp[$cpzone]['radiuskey3'];
|
||||
$pconfig['radiuskey4'] = $a_cp[$cpzone]['radiuskey4'];
|
||||
$pconfig['radiusvendor'] = $a_cp[$cpzone]['radiusvendor'];
|
||||
$pconfig['radiussession_timeout'] = isset($a_cp[$cpzone]['radiussession_timeout']);
|
||||
$pconfig['radiustraffic_quota'] = isset($a_cp[$cpzone]['radiustraffic_quota']);
|
||||
$pconfig['radiusperuserbw'] = isset($a_cp[$cpzone]['radiusperuserbw']);
|
||||
$pconfig['radiussrcip_attribute'] = $a_cp[$cpzone]['radiussrcip_attribute'];
|
||||
$pconfig['passthrumacadd'] = isset($a_cp[$cpzone]['passthrumacadd']);
|
||||
$pconfig['passthrumacaddusername'] = isset($a_cp[$cpzone]['passthrumacaddusername']);
|
||||
$pconfig['radmac_format'] = $a_cp[$cpzone]['radmac_format'];
|
||||
$pconfig['reverseacct'] = isset($a_cp[$cpzone]['reverseacct']);
|
||||
$pconfig['includeidletime'] = isset($a_cp[$cpzone]['includeidletime']);
|
||||
$pconfig['radiusnasid'] = $a_cp[$cpzone]['radiusnasid'];
|
||||
$pconfig['page'] = array();
|
||||
if ($a_cp[$cpzone]['page']['htmltext']) {
|
||||
$pconfig['page']['htmltext'] = $a_cp[$cpzone]['page']['htmltext'];
|
||||
@ -217,13 +203,6 @@ if ($_POST['save']) {
|
||||
$reqdfields = explode(" ", "zone cinterface auth_method");
|
||||
$reqdfieldsn = array(gettext("Zone name"), gettext("Interface"), gettext("Authentication method"));
|
||||
|
||||
if (isset($_POST['auth_method']) && $_POST['auth_method'] == "radius") {
|
||||
$reqdfields[] = "radius_protocol";
|
||||
$reqdfieldsn[] = gettext("RADIUS Protocol");
|
||||
$reqdfields[] = "radiusip";
|
||||
$reqdfieldsn[] = gettext("Primary RADIUS server IP address");
|
||||
}
|
||||
|
||||
do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
|
||||
|
||||
/* make sure no interfaces are bridged or used on other zones */
|
||||
@ -242,8 +221,8 @@ if ($_POST['save']) {
|
||||
}
|
||||
}
|
||||
|
||||
if ($_POST['auth_method'] && !in_array($_POST['auth_method'], array('none', 'local', 'radius'))) {
|
||||
$input_errors[] = sprintf(gettext("Authentication method %s is invalid."), $_POST['auth_method']);
|
||||
if ($_POST['auth_method'] && !in_array($_POST['auth_method'], array('none', 'authserver', 'radmac'))) {
|
||||
$input_errors[] = gettext("Authentication method is invalid.");
|
||||
}
|
||||
|
||||
if ($_POST['httpslogin_enable']) {
|
||||
@ -296,48 +275,39 @@ if ($_POST['save']) {
|
||||
}
|
||||
}
|
||||
|
||||
if (($_POST['radiusip'] && !is_ipaddr($_POST['radiusip']))) {
|
||||
$input_errors[] = sprintf(gettext("A valid IP address must be specified. [%s]"), $_POST['radiusip']);
|
||||
}
|
||||
|
||||
if (($_POST['radiusip2'] && !is_ipaddr($_POST['radiusip2']))) {
|
||||
$input_errors[] = sprintf(gettext("A valid IP address must be specified. [%s]"), $_POST['radiusip2']);
|
||||
}
|
||||
|
||||
if (($_POST['radiusip3'] && !is_ipaddr($_POST['radiusip3']))) {
|
||||
$input_errors[] = sprintf(gettext("A valid IP address must be specified. [%s]"), $_POST['radiusip3']);
|
||||
}
|
||||
|
||||
if (($_POST['radiusip4'] && !is_ipaddr($_POST['radiusip4']))) {
|
||||
$input_errors[] = sprintf(gettext("A valid IP address must be specified. [%s]"), $_POST['radiusip4']);
|
||||
}
|
||||
|
||||
if (($_POST['radiusport'] && !is_port($_POST['radiusport']))) {
|
||||
$input_errors[] = sprintf(gettext("A valid port number must be specified. [%s]"), $_POST['radiusport']);
|
||||
}
|
||||
|
||||
if (($_POST['radiusport2'] && !is_port($_POST['radiusport2']))) {
|
||||
$input_errors[] = sprintf(gettext("A valid port number must be specified. [%s]"), $_POST['radiusport2']);
|
||||
}
|
||||
|
||||
if (($_POST['radiusport3'] && !is_port($_POST['radiusport3']))) {
|
||||
$input_errors[] = sprintf(gettext("A valid port number must be specified. [%s]"), $_POST['radiusport3']);
|
||||
}
|
||||
|
||||
if (($_POST['radiusport4'] && !is_port($_POST['radiusport4']))) {
|
||||
$input_errors[] = sprintf(gettext("A valid port number must be specified. [%s]"), $_POST['radiusport4']);
|
||||
}
|
||||
|
||||
if (($_POST['radiusacctport'] && !is_port($_POST['radiusacctport']))) {
|
||||
$input_errors[] = sprintf(gettext("A valid port number must be specified. [%s]"), $_POST['radiusacctport']);
|
||||
}
|
||||
|
||||
if ($_POST['maxproc'] && (!is_numeric($_POST['maxproc']) || ($_POST['maxproc'] < 4) || ($_POST['maxproc'] > 100))) {
|
||||
$input_errors[] = gettext("The maximum number of concurrent connections per client IP address may not be larger than the global maximum.");
|
||||
}
|
||||
|
||||
if (trim($_POST['radiusnasid']) !== "" && !preg_match("/^[\x21-\x7e]{3,253}$/i", trim($_POST['radiusnasid']))) {
|
||||
$input_errors[] = gettext("The NAS-Identifier must be 3-253 characters long and should only contain ASCII characters.");
|
||||
|
||||
if ($_POST['auth_method']) {
|
||||
if ($_POST['auth_method'] !== 'none' && empty($_POST['auth_server'])) {
|
||||
$input_errors[] = gettext("You need to select at least one authentication server.");
|
||||
}
|
||||
/* If RADMAC auth method is selected : carefully check that the selected server is a RADIUS one */
|
||||
if ($_POST['auth_method'] === 'radmac') {
|
||||
foreach ($_POST['auth_server'] as $server) {
|
||||
|
||||
$realauthserver = explode(' - ', $server);
|
||||
array_shift($realauthserver);
|
||||
$realauthserver = implode(' - ', $realauthserver);
|
||||
$realauthserver = auth_get_authserver($realauthserver);
|
||||
|
||||
if ($realauthserver === null || $realauthserver['type'] !== 'radius') {
|
||||
$input_errors[] = gettext("RADIUS MAC Authentication can only be performed on a RADIUS server.");
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_POST['nomacfilter'])) {
|
||||
$input_errors[] = gettext("RADIUS MAC Authentication cannot be used if MAC filtering is disabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($_POST['radacct_enable']) && empty(auth_get_authserver($_POST['radacct_server']))) {
|
||||
$input_errors[] = gettext("You need to select at least one accounting server.");
|
||||
}
|
||||
if (isset($_POST['radacct_enable']) && !in_array($_POST['reauthenticateacct'], array('none', 'stopstart', 'stopstartfreeradius', 'interimupdate'))) {
|
||||
$input_errors[] = gettext("You need to select an option for Accounting Updates !");
|
||||
}
|
||||
|
||||
if (!$input_errors) {
|
||||
@ -356,6 +326,7 @@ if ($_POST['save']) {
|
||||
if (is_array($_POST['cinterface'])) {
|
||||
$newcp['interface'] = implode(",", $_POST['cinterface']);
|
||||
}
|
||||
$newcp['descr'] = $_POST['descr'];
|
||||
$newcp['maxproc'] = $_POST['maxproc'];
|
||||
$newcp['maxprocperip'] = $_POST['maxprocperip'] ? $_POST['maxprocperip'] : false;
|
||||
$newcp['timeout'] = $_POST['timeout'];
|
||||
@ -370,10 +341,15 @@ if ($_POST['save']) {
|
||||
unset($newcp['enable']);
|
||||
}
|
||||
$newcp['auth_method'] = $_POST['auth_method'];
|
||||
$newcp['auth_server'] = '';
|
||||
if ($_POST['auth_method'] != 'none') {
|
||||
$newcp['auth_server'] = implode(",", $_POST['auth_server']);
|
||||
}
|
||||
$newcp['auth_server2'] = implode(",", $_POST['auth_server2']);
|
||||
$newcp['radacct_server'] = $_POST['radacct_server'];
|
||||
$newcp['localauth_priv'] = isset($_POST['localauth_priv']);
|
||||
$newcp['radacct_enable'] = $_POST['radacct_enable'] ? true : false;
|
||||
$newcp['reauthenticate'] = $_POST['reauthenticate'] ? true : false;
|
||||
$newcp['radmac_enable'] = $_POST['radmac_enable'] ? true : false;
|
||||
$newcp['radmac_secret'] = $_POST['radmac_secret'] ? $_POST['radmac_secret'] : false;
|
||||
$newcp['reauthenticateacct'] = $_POST['reauthenticateacct'];
|
||||
if ($_POST['httpslogin_enable']) {
|
||||
@ -400,52 +376,15 @@ if ($_POST['save']) {
|
||||
$newcp['logoutwin_enable'] = $_POST['logoutwin_enable'] ? true : false;
|
||||
$newcp['nomacfilter'] = $_POST['nomacfilter'] ? true : false;
|
||||
$newcp['noconcurrentlogins'] = $_POST['noconcurrentlogins'] ? true : false;
|
||||
$newcp['radius_protocol'] = $_POST['radius_protocol'];
|
||||
$newcp['redirurl'] = $_POST['redirurl'];
|
||||
if (isset($_POST['radiusip'])) {
|
||||
$newcp['radiusip'] = $_POST['radiusip'];
|
||||
} else {
|
||||
unset($newcp['radiusip']);
|
||||
}
|
||||
if (isset($_POST['radiusip2'])) {
|
||||
$newcp['radiusip2'] = $_POST['radiusip2'];
|
||||
} else {
|
||||
unset($newcp['radiusip2']);
|
||||
}
|
||||
if (isset($_POST['radiusip3'])) {
|
||||
$newcp['radiusip3'] = $_POST['radiusip3'];
|
||||
} else {
|
||||
unset($newcp['radiusip3']);
|
||||
}
|
||||
if (isset($_POST['radiusip4'])) {
|
||||
$newcp['radiusip4'] = $_POST['radiusip4'];
|
||||
} else {
|
||||
unset($newcp['radiusip4']);
|
||||
}
|
||||
$newcp['radiusport'] = $_POST['radiusport'];
|
||||
$newcp['radiusport2'] = $_POST['radiusport2'];
|
||||
if (isset($_POST['radiusport3'])) {
|
||||
$newcp['radiusport3'] = $_POST['radiusport3'];
|
||||
}
|
||||
if (isset($_POST['radiusport4'])) {
|
||||
$newcp['radiusport4'] = $_POST['radiusport4'];
|
||||
}
|
||||
$newcp['radiusacctport'] = $_POST['radiusacctport'];
|
||||
$newcp['radiuskey'] = $_POST['radiuskey'];
|
||||
$newcp['radiuskey2'] = $_POST['radiuskey2'];
|
||||
$newcp['radiuskey3'] = $_POST['radiuskey3'];
|
||||
$newcp['radiuskey4'] = $_POST['radiuskey4'];
|
||||
$newcp['radiusvendor'] = $_POST['radiusvendor'] ? $_POST['radiusvendor'] : false;
|
||||
$newcp['radiussession_timeout'] = $_POST['radiussession_timeout'] ? true : false;
|
||||
$newcp['radiustraffic_quota'] = $_POST['radiustraffic_quota'] ? true : false;
|
||||
$newcp['radiusperuserbw'] = $_POST['radiusperuserbw'] ? true : false;
|
||||
$newcp['radiussrcip_attribute'] = $_POST['radiussrcip_attribute'];
|
||||
$newcp['passthrumacadd'] = $_POST['passthrumacadd'] ? true : false;
|
||||
$newcp['passthrumacaddusername'] = $_POST['passthrumacaddusername'] ? true : false;
|
||||
$newcp['radmac_format'] = $_POST['radmac_format'] ? $_POST['radmac_format'] : false;
|
||||
$newcp['reverseacct'] = $_POST['reverseacct'] ? true : false;
|
||||
$newcp['includeidletime'] = $_POST['includeidletime'] ? true : false;
|
||||
$newcp['radiusnasid'] = trim($_POST['radiusnasid']);
|
||||
|
||||
if (!is_array($newcp['page'])) {
|
||||
$newcp['page'] = array();
|
||||
@ -476,38 +415,6 @@ if ($_POST['save']) {
|
||||
}
|
||||
}
|
||||
|
||||
function build_radiusnas_list() {
|
||||
global $config;
|
||||
$list = array();
|
||||
|
||||
$iflist = get_configured_interface_with_descr();
|
||||
foreach ($iflist as $ifdesc => $ifdescr) {
|
||||
$ipaddr = get_interface_ip($ifdesc);
|
||||
if (is_ipaddr($ipaddr)) {
|
||||
$list[$ifdesc] = $ifdescr . ' - ' . $ipaddr;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($config['virtualip']['vip'])) {
|
||||
foreach ($config['virtualip']['vip'] as $sn) {
|
||||
if ($sn['mode'] == "proxyarp" && $sn['type'] == "network") {
|
||||
$start = ip2long32(gen_subnet($sn['subnet'], $sn['subnet_bits']));
|
||||
$end = ip2long32(gen_subnet_max($sn['subnet'], $sn['subnet_bits']));
|
||||
$len = $end - $start;
|
||||
|
||||
for ($i = 0; $i <= $len; $i++) {
|
||||
$snip = long2ip32($start+$i);
|
||||
$list[$snip] = $sn['descr'] . ' - ' . $snip;
|
||||
}
|
||||
} else {
|
||||
$list[$sn['subnet']] = $sn['descr'] . ' - ' . $sn['subnet'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return($list);
|
||||
}
|
||||
|
||||
function build_cert_list() {
|
||||
global $a_cert;
|
||||
|
||||
@ -520,6 +427,20 @@ function build_cert_list() {
|
||||
return($list);
|
||||
}
|
||||
|
||||
function build_authserver_list() {
|
||||
|
||||
$authlist = auth_get_authserver_list();
|
||||
$options = array();
|
||||
|
||||
/* auth types are used by javascript */
|
||||
foreach ($authlist as $i => $auth) {
|
||||
if ($auth['type'] != 'radius' || $auth['type'] == 'radius' && !empty($auth['radius_auth_port'])) {
|
||||
$options[$auth['type'].' - '.$auth['name']] = $auth['name'];
|
||||
}
|
||||
}
|
||||
return $options;
|
||||
}
|
||||
|
||||
include("head.inc");
|
||||
|
||||
if ($input_errors) {
|
||||
@ -547,6 +468,13 @@ $section->addInput(new Form_Checkbox(
|
||||
$pconfig['enable']
|
||||
));
|
||||
|
||||
$section->addInput(new Form_Input(
|
||||
'descr',
|
||||
'Description',
|
||||
'text',
|
||||
$pconfig['descr']
|
||||
))->setHelp('A description may be entered here for administrative reference (not parsed).');
|
||||
|
||||
$section->addInput(new Form_Select(
|
||||
'cinterface',
|
||||
'*Interfaces',
|
||||
@ -624,14 +552,14 @@ $section->addInput(new Form_Input(
|
||||
'Pre-authentication redirect URL',
|
||||
'text',
|
||||
$pconfig['preauthurl']
|
||||
))->setHelp('Use this field to set $PORTAL_REDIRURL$ variable which can be accessed using the custom captive portal index.php page or error pages.');
|
||||
))->setHelp('Set a default redirection URL. Visitors will be redirected to this URL after authentication only if the captive portal don\'t know where to redirect them. This field will be accessible through $PORTAL_REDIRURL$ variable in captiveportal\'s HTML pages.');
|
||||
|
||||
$section->addInput(new Form_Input(
|
||||
'redirurl',
|
||||
'After authentication Redirection URL',
|
||||
'text',
|
||||
$pconfig['redirurl']
|
||||
))->setHelp('Clients will be redirected to this URL instead of the one they initially tried to access after they\'ve authenticated.');
|
||||
))->setHelp('Set a forced redirection URL. Clients will be redirected to this URL instead of the one they initially tried to access after they\'ve authenticated.');
|
||||
|
||||
$section->addInput(new Form_Input(
|
||||
'blockedmacsurl',
|
||||
@ -665,16 +593,14 @@ $section->addInput(new Form_Checkbox(
|
||||
))->setHelp('When enabled, a MAC passthrough entry is automatically added after the user has successfully authenticated. Users of that MAC address will ' .
|
||||
'never have to authenticate again. To remove the passthrough MAC entry either log in and remove it manually from the ' .
|
||||
'%1$sMAC tab%2$s or send a POST from another system. ' .
|
||||
'If this is enabled, RADIUS MAC authentication cannot be used. Also, the logout window will not be shown.', "<a href=\"services_captiveportal_mac.php?zone={$cpzone}\">", '</a>');
|
||||
'If this is enabled, the logout window will not be shown.', "<a href=\"services_captiveportal_mac.php?zone={$cpzone}\">", '</a>');
|
||||
|
||||
$section->addInput(new Form_Checkbox(
|
||||
'passthrumacaddusername',
|
||||
null,
|
||||
'Enable Pass-through MAC automatic addition with username',
|
||||
'Include username in the created Pass-through entry',
|
||||
$pconfig['passthrumacaddusername']
|
||||
))->setHelp('If enabled with the automatically MAC passthrough entry created, the username used during authentication will be saved. ' .
|
||||
'To remove the passthrough MAC entry either log in and remove it manually from the %1$sMAC tab%2$s or send a POST from another system.',
|
||||
"<a href=\"services_captiveportal_mac.php?zone={$cpzone}\">", '</a>');
|
||||
))->setHelp('If enabled the username used during authentication will be saved in the "Description" Field.');
|
||||
|
||||
$section->addInput(new Form_Checkbox(
|
||||
'peruserbw',
|
||||
@ -696,7 +622,7 @@ $section->addInput(new Form_Input(
|
||||
'number',
|
||||
$pconfig['bwdefaultup']
|
||||
))->setHelp('If this option is set, the captive portal will restrict each user who logs in to the specified default bandwidth. ' .
|
||||
'RADIUS can override the default settings. Leave empty for no limit.');
|
||||
'RADIUS servers can override the default settings. Leave empty for no limit.');
|
||||
|
||||
$form->add($section);
|
||||
|
||||
@ -705,183 +631,110 @@ $section->addClass('Authentication');
|
||||
|
||||
$group = new Form_Group('*Authentication Method');
|
||||
|
||||
$group->add(new Form_Checkbox(
|
||||
'auth_method',
|
||||
null,
|
||||
'No Authentication',
|
||||
$pconfig['auth_method'] == 'none' || empty($pconfig['auth_method']),
|
||||
'none'
|
||||
))->displayasRadio();
|
||||
$options['authserver'] = 'Use an Authentication backend';
|
||||
$options['none'] = 'None, don\'t authenticate users';
|
||||
$options['radmac'] = 'Use RADIUS MAC Authentication';
|
||||
|
||||
$group->add(new Form_Checkbox(
|
||||
$group->add(new Form_Select(
|
||||
'auth_method',
|
||||
null,
|
||||
'Local User Manager / Vouchers',
|
||||
$pconfig['auth_method'] == 'local',
|
||||
'local'
|
||||
))->displayasRadio();
|
||||
|
||||
$group->add(new Form_Checkbox(
|
||||
'auth_method',
|
||||
null,
|
||||
'RADIUS Authentication',
|
||||
$pconfig['auth_method'] == 'radius',
|
||||
'radius'
|
||||
))->displayasRadio();
|
||||
|
||||
$group->setHelp('Select an Authentication Method to use for this zone. One method must be selected.');
|
||||
'Authentication Method',
|
||||
$pconfig['auth_method'],
|
||||
$options
|
||||
))->setHelp('Select an Authentication Method to use for this zone. One method must be selected.<br />'.
|
||||
'- "Authentication backend" will force the login page to be displayed and will authenticate users using their login and password, or using vouchers.<br />'.
|
||||
'- "None" method will force the login page to be displayed but will accept any visitor that clicks the "submit" button.<br/>'.
|
||||
'- "RADIUS MAC Authentication" method will try to authenticate devices automatically with their MAC address without displaying any login page.');
|
||||
|
||||
$section->add($group);
|
||||
|
||||
$group = new Form_Group('*Authentication Server');
|
||||
$group->addClass('auth_server');
|
||||
|
||||
$group->add(new Form_Select(
|
||||
'auth_server',
|
||||
'*Authentication Server',
|
||||
$pconfig['auth_server'],
|
||||
build_authserver_list(),
|
||||
true
|
||||
))->setHelp("You can add a remote authentication server in the <a href=\"/system_authservers.php\">User Manager</a>.<br/>".
|
||||
"<span class=\"vouchers_helptext\">Vouchers could also be used, please go to ".
|
||||
"the <a href=\"services_captiveportal_vouchers.php?zone={$cpzone}\">Voutchers Page</a> to enable them.</span>");
|
||||
$section->add($group);
|
||||
|
||||
$group = new Form_Group('Secondary authentication Server');
|
||||
$group->addClass('auth_server2');
|
||||
|
||||
$group->add(new Form_Select(
|
||||
'auth_server2',
|
||||
'',
|
||||
$pconfig['auth_server2'],
|
||||
build_authserver_list(),
|
||||
true
|
||||
))->setHelp("You can optionally select a second set of servers to to authenticate users. Users will then be able to login using separated HTML inputs.<br />".
|
||||
"This setting is useful if you want to provide multiple authentication method to your users. If you don't need multiple authentication method, then leave this setting empty.");
|
||||
$section->add($group);
|
||||
|
||||
$section->addInput(new Form_Checkbox(
|
||||
'reauthenticate',
|
||||
'Reauthenticate Users',
|
||||
'Reauthenticate connected users every minute',
|
||||
$pconfig['reauthenticate']
|
||||
))->setHelp('If reauthentication is enabled, request are made to the server for each user that is logged in every minute. ' .
|
||||
'If an access denied is received for a user, that user is disconnected from the captive portal immediately. ' .
|
||||
'Reauthentication requires user credentials to be cached in the captive portal database while a user is logged in; ' .
|
||||
'The cached credentials are necessary for the portal to perform automatic reauthentication requests.');
|
||||
|
||||
|
||||
|
||||
$section->addInput(new Form_Checkbox(
|
||||
'localauth_priv',
|
||||
null,
|
||||
'Local Authentication Privileges',
|
||||
'Allow only users/groups with "Captive portal login" privilege set',
|
||||
$pconfig['localauth_priv']
|
||||
));
|
||||
|
||||
$group = new Form_Group('*RADIUS protocol');
|
||||
$group->addClass("radiusproto");
|
||||
|
||||
$group->add(new Form_Checkbox(
|
||||
'radius_protocol',
|
||||
null,
|
||||
'PAP',
|
||||
$pconfig['radius_protocol'] == 'PAP',
|
||||
'PAP'
|
||||
))->displayasRadio();
|
||||
|
||||
$group->add(new Form_Checkbox(
|
||||
'radius_protocol',
|
||||
null,
|
||||
'CHAP-MD5',
|
||||
$pconfig['radius_protocol'] == 'CHAP_MD5',
|
||||
'CHAP_MD5'
|
||||
))->displayasRadio();
|
||||
|
||||
$group->add(new Form_Checkbox(
|
||||
'radius_protocol',
|
||||
null,
|
||||
'MSCHAPv1',
|
||||
$pconfig['radius_protocol'] == 'MSCHAPv1',
|
||||
'MSCHAPv1'
|
||||
))->displayasRadio();
|
||||
|
||||
$group->add(new Form_Checkbox(
|
||||
'radius_protocol',
|
||||
null,
|
||||
'MSCHAPv2',
|
||||
$pconfig['radius_protocol'] == 'MSCHAPv2',
|
||||
'MSCHAPv2'
|
||||
))->displayasRadio();
|
||||
|
||||
$section->add($group);
|
||||
|
||||
$form->add($section);
|
||||
|
||||
$section = new Form_Section('Primary Authentication Source');
|
||||
$section->addClass('Primary');
|
||||
|
||||
$group = new Form_Group('*Primary RADIUS server');
|
||||
|
||||
$group->add(new Form_IpAddress(
|
||||
'radiusip',
|
||||
null,
|
||||
$pconfig['radiusip']
|
||||
));
|
||||
|
||||
$group->add(new Form_Input(
|
||||
'radiusport',
|
||||
null,
|
||||
'number',
|
||||
$pconfig['radiusport']
|
||||
));
|
||||
|
||||
$group->add(new Form_Input(
|
||||
'radiuskey',
|
||||
null,
|
||||
$section->addInput(new Form_Input(
|
||||
'radmac_secret',
|
||||
'RADIUS MAC Secret',
|
||||
'text',
|
||||
$pconfig['radiuskey']
|
||||
));
|
||||
$pconfig['radmac_secret']
|
||||
))->setHelp('RADIUS MAC will automatically try to authenticate devices with their MAC address as username, and the password entered below as password. Devices will still need to make one HTTP request to get connected, throught.');
|
||||
|
||||
$section->add($group);
|
||||
$section->addInput(new Form_Checkbox(
|
||||
'radiussession_timeout',
|
||||
'Session timeout',
|
||||
'Use RADIUS Session-Timeout attributes',
|
||||
$pconfig['radiussession_timeout']
|
||||
))->setHelp('When enabled, clients will be disconnected after the amount of time retrieved from the RADIUS Session-Timeout attribute.');
|
||||
|
||||
$group = new Form_Group('Secondary RADIUS server');
|
||||
$section->addInput(new Form_Checkbox(
|
||||
'radiustraffic_quota',
|
||||
'Traffic quota',
|
||||
'Use RADIUS pfSense-Max-Total-Octets attribute',
|
||||
$pconfig['radiustraffic_quota']
|
||||
))->setHelp('When enabled, clients will be disconnected after exceeding the amount of traffic, inclusive of both downloads and uploads, retrieved from the RADIUS pfSense-Max-Total-Octets attribute.');
|
||||
|
||||
$group->add(new Form_IpAddress(
|
||||
'radiusip2',
|
||||
null,
|
||||
$pconfig['radiusip2']
|
||||
))->setHelp('IP address of the RADIUS server to authenticate against.');
|
||||
$section->addInput(new Form_Checkbox(
|
||||
'radiusperuserbw',
|
||||
'Per-user bandwidth restrictions',
|
||||
'Use RADIUS pfSense-Bandwidth-Max-Up and pfSense-Bandwidth-Max-Down attributes',
|
||||
$pconfig['radiusperuserbw']
|
||||
))->setHelp('When enabled, the bandwidth assigned to a client will be limited to the values retrieved from the RADIUS pfSense-Bandwidth-Max-Up and ' .
|
||||
'pfSense-Bandwidth-Max-Down attributes or from the comparable WISPr attributes.');
|
||||
|
||||
$group->add(new Form_Input(
|
||||
'radiusport2',
|
||||
null,
|
||||
'number',
|
||||
$pconfig['radiusport2']
|
||||
))->setHelp('RADIUS port. Leave blank for default (1812)');
|
||||
$section->addInput(new Form_Select(
|
||||
'radmac_format',
|
||||
'MAC address format',
|
||||
$pconfig['radmac_format'],
|
||||
['default' => 'Default', 'singledash' => gettext('Single dash'), 'ietf' => 'IETF', 'cisco' => 'Cisco', 'unformatted' => gettext('Unformatted')]
|
||||
))->setHelp('This option changes the MAC address format used when performing a RADIUS authentication. %1$s' .
|
||||
'Default: 00:11:22:33:44:55 %1$s' .
|
||||
'Single dash: 001122-334455 %1$s' .
|
||||
'IETF: 00-11-22-33-44-55 %1$s' .
|
||||
'Cisco: 0011.2233.4455 %1$s' .
|
||||
'Unformatted: 001122334455', '<br />');
|
||||
|
||||
$group->add(new Form_Input(
|
||||
'radiuskey2',
|
||||
null,
|
||||
'text',
|
||||
$pconfig['radiuskey2']
|
||||
))->setHelp('RADIUS shared secret. Leave blank to not use a shared secret (not recommended)');
|
||||
|
||||
$section->add($group);
|
||||
|
||||
$form->add($section);
|
||||
|
||||
$section = new Form_Section('Secondary Authentication Source');
|
||||
$section->addClass('Secondary');
|
||||
|
||||
$group = new Form_Group('Primary RADIUS server');
|
||||
|
||||
$group->add(new Form_IpAddress(
|
||||
'radiusip3',
|
||||
null,
|
||||
$pconfig['radiusip3']
|
||||
));
|
||||
|
||||
$group->add(new Form_Input(
|
||||
'radiusport3',
|
||||
null,
|
||||
'number',
|
||||
$pconfig['radiusport3']
|
||||
));
|
||||
|
||||
$group->add(new Form_Input(
|
||||
'radiuskey3',
|
||||
null,
|
||||
'text',
|
||||
$pconfig['radiuskey3']
|
||||
));
|
||||
|
||||
$section->add($group);
|
||||
|
||||
$group = new Form_Group('Secondary RADIUS server');
|
||||
|
||||
$group->add(new Form_IpAddress(
|
||||
'radiusip4',
|
||||
null,
|
||||
$pconfig['radiusip4']
|
||||
))->setHelp('IP address of the RADIUS server to authenticate against.');
|
||||
|
||||
$group->add(new Form_Input(
|
||||
'radiusport4',
|
||||
null,
|
||||
'number',
|
||||
$pconfig['radiusport4']
|
||||
))->setHelp('RADIUS port. Leave blank for default (1812)');
|
||||
|
||||
$group->add(new Form_Input(
|
||||
'radiuskey4',
|
||||
null,
|
||||
'text',
|
||||
$pconfig['radiuskey4']
|
||||
))->setHelp('RADIUS shared secret. Leave blank to not use a shared secret (not recommended)');
|
||||
|
||||
$section->add($group);
|
||||
$form->add($section);
|
||||
|
||||
$section = new Form_Section('Accounting');
|
||||
@ -890,25 +743,44 @@ $section->addClass('Accounting');
|
||||
$section->addInput(new Form_Checkbox(
|
||||
'radacct_enable',
|
||||
'RADIUS',
|
||||
'Send RADIUS accounting packets to the primary RADIUS server.',
|
||||
'Send RADIUS accounting packets.',
|
||||
$pconfig['radacct_enable']
|
||||
))->setHelp('If enabled, accounting request will be made for users identified against any RADIUS server.');
|
||||
|
||||
|
||||
$options = array();
|
||||
|
||||
foreach (auth_get_authserver_list() as $i => $auth) {
|
||||
if ($auth['type'] == 'radius' && !empty($auth['radius_acct_port'])) {
|
||||
$options[$auth['name']] = $auth['name'];
|
||||
}
|
||||
}
|
||||
|
||||
$group = new Form_Group('Accounting Server');
|
||||
|
||||
|
||||
$group->add(new Form_Select(
|
||||
'radacct_server',
|
||||
'Accounting Server',
|
||||
$pconfig['radacct_server'],
|
||||
$options
|
||||
));
|
||||
|
||||
$section->addInput(new Form_Input(
|
||||
'radiusacctport',
|
||||
'Accounting Port',
|
||||
'text',
|
||||
$pconfig['radiusacctport']
|
||||
))->setHelp('Leave blank to use the default port (1813).');
|
||||
$group->addClass('radacct_enable');
|
||||
$group->setHelp('You can add a Radius Accounting server in the <a href="/system_authservers.php">User Manager</a>.');
|
||||
|
||||
$group = new Form_Group('Accounting updates');
|
||||
$section->add($group);
|
||||
|
||||
$group = new Form_Group('Send accounting updates');
|
||||
|
||||
$group->addClass('reauthenticateacct');
|
||||
|
||||
$group->add(new Form_Checkbox(
|
||||
'reauthenticateacct',
|
||||
null,
|
||||
'No updates',
|
||||
$pconfig['reauthenticateacct'] == "",
|
||||
""
|
||||
$pconfig['reauthenticateacct'] == 'none',
|
||||
"none"
|
||||
))->displayasRadio();
|
||||
|
||||
$group->add(new Form_Checkbox(
|
||||
@ -935,76 +807,13 @@ $group->add(new Form_Checkbox(
|
||||
"interimupdate"
|
||||
))->displayasRadio();
|
||||
|
||||
$group->setHelp('This field set the way Accounting Updates should be done : <br />'.
|
||||
'- If "No updates" is selected, then only one "Accounting Start" and one "Accounting Stop" request will be sent, when any user get connected and disconnected.<br />'.
|
||||
'- If "Interim" is selected, then "Accounting Update" requests will be send regularly (every minute) to the RADIUS server, for each connected user.<br />'.
|
||||
'- In some rare cases, you would like to simulate users to disconnect and reconnect every minute (eg, to send an Accounting Stop then an Accounting Start) instead of sending Accounting updates, this is the purpose of "Stop/Start" option. FreeRADIUS does not support this option very well, you should select "Stop/Start (FreeRADIUS)" instead.');
|
||||
|
||||
$section->add($group);
|
||||
|
||||
$form->add($section);
|
||||
|
||||
$section = new Form_Section('RADIUS Options');
|
||||
$section->addClass('Radius');
|
||||
|
||||
$section->addInput(new Form_Checkbox(
|
||||
'reauthenticate',
|
||||
'Reauthentication',
|
||||
'Reauthenticate connected users every minute',
|
||||
$pconfig['reauthenticate']
|
||||
))->setHelp('If reauthentication is enabled, Access-Requests will be sent to the RADIUS server for each user that is logged in every minute. ' .
|
||||
'If an Access-Reject is received for a user, that user is disconnected from the captive portal immediately. ' .
|
||||
'Reauthentication requires user credentials to be cached in the captive portal database while a user is logged in; ' .
|
||||
'The cached credentials are necessary for the portal to perform automatic reauthentication requests.');
|
||||
|
||||
$section->addInput(new Form_Checkbox(
|
||||
'radmac_enable',
|
||||
'RADIUS MAC Authentication',
|
||||
'Enable RADIUS MAC authentication',
|
||||
$pconfig['radmac_enable']
|
||||
))->setHelp('If this option is enabled, the captive portal will try to authenticate users by sending their MAC address as the username ' .
|
||||
'and the password entered below to the RADIUS server.');
|
||||
|
||||
$section->addInput(new Form_Input(
|
||||
'radmac_secret',
|
||||
'MAC authentication secret',
|
||||
'text',
|
||||
$pconfig['radmac_secret']
|
||||
));
|
||||
|
||||
$section->addInput(new Form_Select(
|
||||
'radiussrcip_attribute',
|
||||
'RADIUS NAS IP Attribute',
|
||||
$pconfig['radiussrcip_attribute'],
|
||||
build_radiusnas_list()
|
||||
))->setHelp('Choose the IP to use for calling station attribute.');
|
||||
|
||||
$section->addInput(new Form_Checkbox(
|
||||
'radiussession_timeout',
|
||||
'Session timeout',
|
||||
'Use RADIUS Session-Timeout attributes',
|
||||
$pconfig['radiussession_timeout']
|
||||
))->setHelp('When enabled, clients will be disconnected after the amount of time retrieved from the RADIUS Session-Timeout attribute.');
|
||||
|
||||
$section->addInput(new Form_Checkbox(
|
||||
'radiustraffic_quota',
|
||||
'Traffic quota',
|
||||
'Use RADIUS pfSense-Max-Total-Octets attribute',
|
||||
$pconfig['radiustraffic_quota']
|
||||
))->setHelp('When enabled, clients will be disconnected after exceeding the amount of traffic, inclusive of both downloads and uploads, retrieved from the RADIUS pfSense-Max-Total-Octets attribute.');
|
||||
|
||||
$section->addInput(new Form_Checkbox(
|
||||
'radiusperuserbw',
|
||||
'Per-user bandwidth restrictions',
|
||||
'Use RADIUS pfSense-Bandwidth-Max-Up and pfSense-Bandwidth-Max-Down attributes',
|
||||
$pconfig['radiusperuserbw']
|
||||
))->setHelp('When enabled, the bandwidth assigned to a client will be limited to the values retrieved from the RADIUS pfSense-Bandwidth-Max-Up and ' .
|
||||
'pfSense-Bandwidth-Max-Down attributes or from the comparable WISPr attributes.');
|
||||
|
||||
$section->addInput(new Form_Select(
|
||||
'radiusvendor',
|
||||
'Type',
|
||||
$pconfig['radiusvendor'],
|
||||
['default' => gettext('default'), 'cisco' => 'cisco']
|
||||
))->setHelp('If RADIUS type is set to Cisco, in Access-Requests the value of Calling-Station-ID will be set to the client\'s IP address and the ' .
|
||||
'Called-Station-Id to the client\'s MAC address. Default behavior is Calling-Station-Id = client\'s MAC address and ' .
|
||||
'Called-Station-ID = pfSense\'s WAN IP address.');
|
||||
|
||||
$section->addInput(new Form_Checkbox(
|
||||
'reverseacct',
|
||||
'Accounting style',
|
||||
@ -1016,32 +825,10 @@ $section->addInput(new Form_Checkbox(
|
||||
$section->addInput(new Form_Checkbox(
|
||||
'includeidletime',
|
||||
'Idle time accounting',
|
||||
'Include idle time in session time',
|
||||
'Include idle time when users get disconnected due to idle timeout',
|
||||
$pconfig['includeidletime']
|
||||
))->setHelp('When enabled, if a client is disconnected for exceeding the idle timeout the time spent idle is included in the total session time. ' .
|
||||
'Otherwise the session time reported to the RADIUS server is the time between when the session started and when the last ' .
|
||||
'activity was recorded.');
|
||||
|
||||
$section->addInput(new Form_Input(
|
||||
'radiusnasid',
|
||||
'NAS Identifier',
|
||||
'text',
|
||||
$pconfig['radiusnasid']
|
||||
))->setHelp('Specify a NAS identifier to override the default value (pfSense.localdomain)');
|
||||
|
||||
$section->addInput(new Form_Select(
|
||||
'radmac_format',
|
||||
'MAC address format',
|
||||
$pconfig['radmac_format'],
|
||||
['default' => 'Default', 'singledash' => gettext('Single dash'), 'ietf' => 'IETF', 'cisco' => 'Cisco', 'unformatted' => gettext('Unformatted')]
|
||||
))->setHelp('This option changes the MAC address format used in the whole RADIUS system. Change this if the username format also needs to be changed for ' .
|
||||
'RADIUS MAC authentication. %1$s' .
|
||||
'Default: 00:11:22:33:44:55 %1$s' .
|
||||
'Single dash: 001122-334455 %1$s' .
|
||||
'IETF: 00-11-22-33-44-55 %1$s' .
|
||||
'Cisco: 0011.2233.4455 %1$s' .
|
||||
'Unformatted: 001122334455', '<br />');
|
||||
|
||||
))->setHelp('This setting change the stop time that will be send in the Accounting Stop request, when a user get disconnected after exceeding the idle timeout. ' .
|
||||
'If not checked, the sent stop time will be the last activity time.');
|
||||
$form->add($section);
|
||||
|
||||
$section = new Form_Section('HTTPS Options');
|
||||
@ -1234,24 +1021,18 @@ events.push(function() {
|
||||
// ------- Show/hide sections based on checkbox settings --------------------------------------
|
||||
function hideSections(hide) {
|
||||
hideClass('Authentication', hide);
|
||||
hideRadius();
|
||||
hideHTTPS();
|
||||
hideClass('HTTPS', hide);
|
||||
hideClass('HTML', hide);
|
||||
hideGeneral(hide)
|
||||
hideGeneral(hide);
|
||||
hideClass('Accounting', hide);
|
||||
}
|
||||
|
||||
function hideRadius() {
|
||||
hide = (!$('#enable').prop('checked') || (!($('input[name="auth_method"]:checked').val() == 'radius')));
|
||||
|
||||
hideClass('Primary', hide);
|
||||
hideClass('Secondary', hide);
|
||||
hideClass('Accounting', hide);
|
||||
hideClass('Radius', hide);
|
||||
|
||||
disableInput('localauth_priv', !($('input[name="auth_method"]:checked').val() == 'local'));
|
||||
hideCheckbox('localauth_priv', !($('input[name="auth_method"]:checked').val() == 'local'));
|
||||
hideClass("radiusproto", !($('input[name="auth_method"]:checked').val() == 'radius'));
|
||||
function hideRadius(hide) {
|
||||
hideCheckbox('radiussession_timeout', hide);
|
||||
hideInput('radmac_format', hide);
|
||||
hideCheckbox('radiusperuserbw', hide);
|
||||
hideCheckbox('radiustraffic_quota', hide);
|
||||
}
|
||||
|
||||
function hideHTTPS() {
|
||||
@ -1278,29 +1059,183 @@ events.push(function() {
|
||||
hideCheckbox('noconcurrentlogins', hide);
|
||||
hideCheckbox('nomacfilter', hide);
|
||||
hideCheckbox('passthrumacadd', hide);
|
||||
hideCheckbox('passthrumacaddusername', hide);
|
||||
hideCheckbox('peruserbw', hide);
|
||||
hideCheckbox('reauthenticate', hide);
|
||||
}
|
||||
|
||||
function hideRadiusAccounting(radiusServerSelected, hide) {
|
||||
if(radiusServerSelected) return;
|
||||
|
||||
hideInput('radacct_server', hide);
|
||||
hideClass('reauthenticateacct', hide);
|
||||
hideCheckbox('reverseacct', hide);
|
||||
hideCheckbox('includeidletime', hide);
|
||||
}
|
||||
|
||||
function hidePassthru(hide) {
|
||||
if(!$('#enable').prop('checked')) {
|
||||
hide = true;
|
||||
}
|
||||
else if(!hide) {
|
||||
$('#logoutwin_enable').prop('checked', false);
|
||||
}
|
||||
|
||||
disableInput("logoutwin_enable", !hide);
|
||||
hideCheckbox('passthrumacaddusername', hide);
|
||||
}
|
||||
|
||||
function hidePerUserBandwith(hide) {
|
||||
if(!$('#enable').prop('checked')) {
|
||||
hide = true;
|
||||
}
|
||||
hideInput('bwdefaultdn', hide);
|
||||
hideInput('bwdefaultup', hide);
|
||||
}
|
||||
|
||||
function triggerChangesAuthMethod() {
|
||||
if(!$('#enable').prop('checked')) return;
|
||||
|
||||
let authserver_list = <?php echo json_encode(build_authserver_list()); ?>;
|
||||
let auth_method = $('#auth_method').val();
|
||||
let saved_values = $('select[name="auth_server[]"]').val(); // we save the current list of selected servers
|
||||
|
||||
if(auth_method.indexOf("authserver") === 0) {
|
||||
// If authserver is selected : we display all the server list.
|
||||
$('select[name="auth_server[]"]').find('option').remove();
|
||||
$.each(authserver_list, function(key, value) {
|
||||
$('<option>').val(key).text(value).appendTo($('select[name="auth_server[]"]'));
|
||||
});
|
||||
|
||||
hideCheckbox('reauthenticate', false);
|
||||
hideClass('auth_server', false);
|
||||
hideInput('radmac_secret', true);
|
||||
$('.auth_server .vouchers_helptext').removeClass('hidden');
|
||||
}
|
||||
else if(auth_method.indexOf("radmac") === 0) {
|
||||
// If Radmac is selected : only RADIUS servers should be displayed
|
||||
$('select[name="auth_server[]"]').find('option').remove();
|
||||
|
||||
$.each(authserver_list, function(key, value) {
|
||||
if(key.indexOf("radius") === 0) {
|
||||
$('<option>').val(key).text(value).appendTo($('select[name="auth_server[]"]'));
|
||||
}
|
||||
});
|
||||
hideCheckbox('reauthenticate', false);
|
||||
hideClass('auth_server', false);
|
||||
hideInput('radmac_secret', false);
|
||||
$('.auth_server .vouchers_helptext').addClass('hidden');
|
||||
} else {
|
||||
// if "none" is selected : we hide most of authentication settings
|
||||
hideRadius(true);
|
||||
hideCheckbox('reauthenticate', true);
|
||||
hideClass('auth_server', true);
|
||||
hideInput('radmac_secret', true);
|
||||
}
|
||||
|
||||
|
||||
// we try to restore all previous selected servers
|
||||
$.each(saved_values, function(key, value) {
|
||||
$('select[name="auth_server[]"] option').filter(function(i, e) {return $(e).val() == value}).attr("selected", "selected");
|
||||
});
|
||||
|
||||
triggerChangesAuthServer();
|
||||
}
|
||||
|
||||
function triggerChangesAuthServer() {
|
||||
if(!$('#enable').prop('checked')) return;
|
||||
|
||||
let shouldHideLocal = true;
|
||||
let shouldHideRadius = true;
|
||||
let shouldHideLdap = true;
|
||||
let shouldHideSecondAuth = true;
|
||||
|
||||
if($('#auth_method').val().indexOf("none") !== 0) {
|
||||
$.each($('select[name="auth_server[]"]').val(), function(key,value) {
|
||||
if(value.indexOf("radius") === 0) {
|
||||
shouldHideRadius = false;
|
||||
} else if(value.indexOf("ldap") === 0) {
|
||||
shouldHideLdap = false;
|
||||
}
|
||||
else if(value.indexOf("Local Auth") === 0) {
|
||||
shouldHideLocal = false;
|
||||
}
|
||||
if($('#auth_method').val().indexOf("authserver") === 0) { // There is no second auth possiblity when none/radmac are selected
|
||||
shouldHideSecondAuth = false;
|
||||
}
|
||||
});
|
||||
|
||||
$.each($('select[name="auth_server2[]"]').val(), function(key,value) {
|
||||
if(value.indexOf("radius") === 0) {
|
||||
shouldHideRadius = false;
|
||||
} else if(value.indexOf("ldap") === 0) {
|
||||
shouldHideLdap = false;
|
||||
}
|
||||
else if(value.indexOf("Local Auth") === 0) {
|
||||
shouldHideLocal = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
hideCheckbox('localauth_priv', shouldHideLocal); // Hide/Show Local Auth options
|
||||
hideClass('auth_server2', shouldHideSecondAuth); // Hide/show second auth context
|
||||
hideRadius(shouldHideRadius); // Hide/Show Radius authentication options
|
||||
hideClass('Accounting', shouldHideRadius);
|
||||
hideRadiusAccounting(shouldHideRadius, !$('input[name="radacct_enable"]').prop('checked'));
|
||||
}
|
||||
// ---------- Click checkbox handlers ---------------------------------------------------------
|
||||
$("#enable").click(function() {
|
||||
hideSections(!this.checked);
|
||||
hidePerUserBandwith(!$("#peruserbw").prop('checked'));
|
||||
hidePassthru(!$("#passthrumacadd").prop('checked'));
|
||||
triggerChangesAuthMethod();
|
||||
triggerChangesAuthServer();
|
||||
});
|
||||
|
||||
$('input[name="auth_method"]').on('change', function() {
|
||||
hideRadius();
|
||||
$('select[name="auth_server[]"]').on('change', function() {
|
||||
triggerChangesAuthServer();
|
||||
});
|
||||
$('select[name="auth_server2[]"]').on('change', function() {
|
||||
triggerChangesAuthServer();
|
||||
});
|
||||
$('select[name="auth_method"]').on('change', function() {
|
||||
triggerChangesAuthMethod();
|
||||
});
|
||||
$('input[name="radacct_enable"]').on('change', function() {
|
||||
hideRadiusAccounting(false, !this.checked);
|
||||
});
|
||||
|
||||
|
||||
$("#httpslogin_enable").click(function() {
|
||||
hideHTTPS(!this.checked);
|
||||
});
|
||||
$("#nomacfilter").click(function()
|
||||
{
|
||||
let radmac_option = $('select[name="auth_method"] option[value="radmac"]');
|
||||
if(this.checked) {
|
||||
radmac_option.prop('disabled','disabled');
|
||||
if($('select[name="auth_method"]').val() == radmac_option.val() || $('select[name="auth_method"]').val() == null) {
|
||||
$('select[name="auth_method"]').val($('select[name="auth_method"] option:first').val());
|
||||
}
|
||||
} else {
|
||||
radmac_option.removeAttr('disabled');
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
$("#peruserbw").click(function() {
|
||||
hidePerUserBandwith(!this.checked);
|
||||
});
|
||||
|
||||
$("#passthrumacadd").click(function() {
|
||||
hidePassthru(!this.checked);
|
||||
});
|
||||
|
||||
// ---------- On initial page load ------------------------------------------------------------
|
||||
hideSections(!$('#enable').prop('checked'));
|
||||
disableInput('localauth_priv', !($('input[name="auth_method"]:checked').val() == 'local'));
|
||||
hidePerUserBandwith(!$("#peruserbw").prop('checked'));
|
||||
hidePassthru(!$("#passthrumacadd").prop('checked'));
|
||||
triggerChangesAuthMethod();
|
||||
triggerChangesAuthServer();
|
||||
|
||||
});
|
||||
//]]>
|
||||
</script>
|
||||
|
||||
@ -36,6 +36,35 @@ require_once("filter.inc");
|
||||
require_once("shaper.inc");
|
||||
require_once("captiveportal.inc");
|
||||
|
||||
/*
|
||||
Return true if multiple servers type are selected in captiveportal config, false otherwise
|
||||
*/
|
||||
function mutiple_auth_server_type() {
|
||||
global $config, $cpzone;
|
||||
|
||||
$auth_types = array();
|
||||
|
||||
$fullauthservers = explode(",", $config['captiveportal'][$cpzone]['auth_server']);
|
||||
foreach($fullauthservers as $authserver) {
|
||||
if(strpos($authserver, ' - ') !== false) {
|
||||
$authserver = explode(' - ', $authserver);
|
||||
$auth_types[array_shift($authserver)] = true;
|
||||
}
|
||||
}
|
||||
$fullauthservers2 = explode(",", $config['captiveportal'][$cpzone]['auth_server2']);
|
||||
foreach($fullauthservers2 as $authserver) {
|
||||
if(strpos($authserver, ' - ') !== false) {
|
||||
$authserver = explode(' - ', $authserver);
|
||||
$auth_types[array_shift($authserver)] = true;
|
||||
}
|
||||
}
|
||||
if($config['captiveportal'][$cpzone]['auth_method'] === 'authserver' && count($auth_types)>1) {
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function print_details($cpent) {
|
||||
global $config, $cpzone, $cpzoneid;
|
||||
|
||||
@ -108,7 +137,7 @@ if (isset($cpzone) && !empty($cpzone) && isset($a_cp[$cpzone]['zoneid'])) {
|
||||
}
|
||||
|
||||
if ($_POST['act'] == "del" && !empty($cpzone) && isset($cpzoneid) && isset($_POST['id'])) {
|
||||
captiveportal_disconnect_client($_POST['id'], 6);
|
||||
captiveportal_disconnect_client($_POST['id'], 6, "DISCONNECT - KIKED OUT BY ADMINISTRATOR");
|
||||
/* keep displaying last activity times */
|
||||
if ($_POST['showact']) {
|
||||
header("Location: status_captiveportal.php?zone={$cpzone}&showact=1");
|
||||
@ -195,6 +224,14 @@ if (!empty($cpzone)): ?>
|
||||
endif;
|
||||
?>
|
||||
<th><?=gettext("Username")?></th>
|
||||
<?php
|
||||
// if multiple auth method are selected
|
||||
if (mutiple_auth_server_type()):
|
||||
?>
|
||||
<th><?=gettext("Authentication method")?></th>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
<th><?=gettext("Session start")?></th>
|
||||
<?php
|
||||
if ($_REQUEST['showact']):
|
||||
@ -231,6 +268,13 @@ if (!empty($cpzone)): ?>
|
||||
}
|
||||
?>
|
||||
<td><?php print_details($cpent); ?></td>
|
||||
<?php
|
||||
if (mutiple_auth_server_type()):
|
||||
?>
|
||||
<td><?=htmlspecialchars($cpent[12]);?></td>
|
||||
<?php
|
||||
endif;
|
||||
?>
|
||||
<?php
|
||||
if ($_REQUEST['showact']):
|
||||
$last_act = captiveportal_get_last_activity($cpent[2]);
|
||||
|
||||
@ -173,6 +173,7 @@ if ($act == "edit") {
|
||||
if ($pconfig['type'] == "radius") {
|
||||
$pconfig['radius_protocol'] = $a_server[$id]['radius_protocol'];
|
||||
$pconfig['radius_host'] = $a_server[$id]['host'];
|
||||
$pconfig['radius_nasip_attribute'] = $a_server[$id]['radius_nasip_attribute'];
|
||||
$pconfig['radius_auth_port'] = $a_server[$id]['radius_auth_port'];
|
||||
$pconfig['radius_acct_port'] = $a_server[$id]['radius_acct_port'];
|
||||
$pconfig['radius_secret'] = $a_server[$id]['radius_secret'];
|
||||
@ -358,6 +359,7 @@ if ($_POST['save']) {
|
||||
|
||||
$server['radius_protocol'] = $pconfig['radius_protocol'];
|
||||
$server['host'] = $pconfig['radius_host'];
|
||||
$server['radius_nasip_attribute'] = $pconfig['radius_nasip_attribute'];
|
||||
|
||||
if ($pconfig['radius_secret']) {
|
||||
$server['radius_secret'] = $pconfig['radius_secret'];
|
||||
@ -397,6 +399,38 @@ if ($_POST['save']) {
|
||||
}
|
||||
}
|
||||
|
||||
function build_radiusnas_list() {
|
||||
global $config;
|
||||
$list = array();
|
||||
|
||||
$iflist = get_configured_interface_with_descr();
|
||||
foreach ($iflist as $ifdesc => $ifdescr) {
|
||||
$ipaddr = get_interface_ip($ifdesc);
|
||||
if (is_ipaddr($ipaddr)) {
|
||||
$list[$ifdesc] = $ifdescr . ' - ' . $ipaddr;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_array($config['virtualip']['vip'])) {
|
||||
foreach ($config['virtualip']['vip'] as $sn) {
|
||||
if ($sn['mode'] == "proxyarp" && $sn['type'] == "network") {
|
||||
$start = ip2long32(gen_subnet($sn['subnet'], $sn['subnet_bits']));
|
||||
$end = ip2long32(gen_subnet_max($sn['subnet'], $sn['subnet_bits']));
|
||||
$len = $end - $start;
|
||||
|
||||
for ($i = 0; $i <= $len; $i++) {
|
||||
$snip = long2ip32($start+$i);
|
||||
$list[$snip] = $sn['descr'] . ' - ' . $snip;
|
||||
}
|
||||
} else {
|
||||
$list[$sn['subnet']] = $sn['descr'] . ' - ' . $sn['subnet'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return($list);
|
||||
}
|
||||
|
||||
// On error, restore the form contents so the user doesn't have to re-enter too much
|
||||
if ($_POST && $input_errors) {
|
||||
$pconfig = $_POST;
|
||||
@ -783,6 +817,14 @@ $section->addInput(new Form_Input(
|
||||
'authentication system, increase this timeout to account for how long it will '.
|
||||
'take the user to receive and enter a token.');
|
||||
|
||||
$section->addInput(new Form_Select(
|
||||
'radius_nasip_attribute',
|
||||
'RADIUS NAS IP Attribute',
|
||||
$pconfig['radius_nasip_attribute'],
|
||||
build_radiusnas_list()
|
||||
))->setHelp('Enter the IP to use for the "NAS-IP-Address" attribute during RADIUS Acccess-Requests.<br />'.
|
||||
'Please note that this choice won\'t change the interface used for contacting the RADIUS server.');
|
||||
|
||||
if (isset($id) && $a_server[$id])
|
||||
{
|
||||
$section->addInput(new Form_Input(
|
||||
|
||||
Loading…
Reference in New Issue
Block a user