diff options
author | Ermal <eri@pfsense.org> | 2011-09-07 19:59:56 +0000 |
---|---|---|
committer | Ermal <eri@pfsense.org> | 2011-09-07 19:59:56 +0000 |
commit | ebc0e4b6fdaed4d774e7e312994b4dc34ec095fa (patch) | |
tree | 3c45a668523e56d2136450c1c1755a35b64e1ce2 | |
parent | 5b4f3f1b6055ed2577bf973aff52d6f609bb40b7 (diff) | |
download | pfsense-ebc0e4b6fdaed4d774e7e312994b4dc34ec095fa.zip pfsense-ebc0e4b6fdaed4d774e7e312994b4dc34ec095fa.tar.gz |
Add support for multiple radius server to be used during authentication
-rw-r--r-- | etc/inc/captiveportal.inc | 100 | ||||
-rwxr-xr-x | usr/local/captiveportal/index.php | 30 | ||||
-rwxr-xr-x | usr/local/www/services_captiveportal.php | 90 |
3 files changed, 178 insertions, 42 deletions
diff --git a/etc/inc/captiveportal.inc b/etc/inc/captiveportal.inc index 536147e..a1edb5d 100644 --- a/etc/inc/captiveportal.inc +++ b/etc/inc/captiveportal.inc @@ -688,7 +688,7 @@ function captiveportal_prune_old() { !isset($config['captiveportal'][$cpzone]['radiussession_timeout']) && !isset($config['voucher'][$cpzone]['enable'])) return; - $radiusservers = captiveportal_get_radius_servers(); + $radiussrvs = captiveportal_get_radius_servers(); /* read database */ $cpdb = captiveportal_read_db(); @@ -710,6 +710,9 @@ function captiveportal_prune_old() { $timedout = false; $term_cause = 1; + if (empty($cpentry[10])) + $cpentry[10] = 'first'; + $radiusservers = $radiussrvs[$cpentry[10]]; /* hard timeout? */ if ($timeout) { @@ -897,8 +900,9 @@ function captiveportal_disconnect_client($sessionid, $term_cause = 1, $logoutRea /* write database */ $unsetindex[] = $sessionid; captiveportal_write_db($cpdb, false, $unsetindex); - - captiveportal_disconnect($cpentry, $radiusservers, $term_cause); + if (empty($cpentry[10])) + $cpentry[10] = 'first'; + captiveportal_disconnect($cpentry, $radiusservers[$cpentry[10]], $term_cause); captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "DISCONNECT"); } } @@ -914,14 +918,18 @@ function captiveportal_radius_stop_all() { if (!empty($radiusservers)) { $cpdb = captiveportal_read_db(); foreach ($cpdb as $cpentry) { - RADIUS_ACCOUNTING_STOP($cpentry[1], // ruleno - $cpentry[4], // username - $cpentry[5], // sessionid - $cpentry[0], // start time - $radiusservers, - $cpentry[2], // clientip - $cpentry[3], // clientmac - 7); // Admin Reboot + if (empty($cpentry[10])) + $cpentry[10] = 'first'; + if (!empty($radiusservers[$cpentry[10]])) { + RADIUS_ACCOUNTING_STOP($cpentry[1], // ruleno + $cpentry[4], // username + $cpentry[5], // sessionid + $cpentry[0], // start time + $radiusservers[$cpentry[10]], + $cpentry[2], // clientip + $cpentry[3], // clientmac + 7); // Admin Reboot + } } } } @@ -1141,6 +1149,8 @@ function captiveportal_init_radius_servers() { ($config['captiveportal'][$cpzone]['auth_method'] == "radius"))) { $radiusip = $config['captiveportal'][$cpzone]['radiusip']; $radiusip2 = ($config['captiveportal'][$cpzone]['radiusip2']) ? $config['captiveportal'][$cpzone]['radiusip2'] : null; + $radiusip3 = ($config['captiveportal']['radiusip3']) ? $config['captiveportal']['radiusip3'] : null; + $radiusip4 = ($config['captiveportal']['radiusip4']) ? $config['captiveportal']['radiusip4'] : null; if ($config['captiveportal'][$cpzone]['radiusport']) $radiusport = $config['captiveportal'][$cpzone]['radiusport']; @@ -1154,8 +1164,19 @@ function captiveportal_init_radius_servers() { $radiusport2 = $config['captiveportal'][$cpzone]['radiusport2']; else $radiusport2 = 1812; + if ($config['captiveportal']['radiusport3']) + $radiusport3 = $config['captiveportal']['radiusport3']; + else + $radiusport3 = 1812; + if ($config['captiveportal']['radiusport4']) + $radiusport4 = $config['captiveportal']['radiusport4']; + else + $radiusport4 = 1812; + $radiuskey = $config['captiveportal'][$cpzone]['radiuskey']; $radiuskey2 = ($config['captiveportal'][$cpzone]['radiuskey2']) ? $config['captiveportal'][$cpzone]['radiuskey2'] : null; + $radiuskey3 = ($config['captiveportal']['radiuskey3']) ? $config['captiveportal']['radiuskey3'] : null; + $radiuskey4 = ($config['captiveportal']['radiuskey4']) ? $config['captiveportal']['radiuskey4'] : null; $cprdsrvlck = lock("captiveportalradius{$cpzone}", LOCK_EX); $fd = @fopen("{$g['vardb_path']}/captiveportal_radius_{$cpzone}.db", "w"); @@ -1163,11 +1184,17 @@ function captiveportal_init_radius_servers() { captiveportal_syslog("Error: cannot open radius DB file in captiveportal_configure().\n"); unlock($cprdsrvlck); return 1; - } else if (isset($radiusip2, $radiuskey2)) - fwrite($fd,$radiusip . "," . $radiusport . "," . $radiusacctport . "," . $radiuskey . "\n" - . $radiusip2 . "," . $radiusport2 . "," . $radiusacctport . "," . $radiuskey2); - else - fwrite($fd,$radiusip . "," . $radiusport . "," . $radiusacctport . "," . $radiuskey); + } + if (isset($radiusip, $radiuskey)) + fwrite($fd,$radiusip . "," . $radiusport . "," . $radiusacctport . "," . $radiuskey . ",first"); + if (isset($radiusip2, $radiuskey2)) + fwrite($fd,"\n" . $radiusip2 . "," . $radiusport2 . "," . $radiusacctport . "," . $radiuskey2 . ",first"); + if (isset($radiusip3, $radiuskey3)) + fwrite($fd,"\n" . $radiusip3 . "," . $radiusport3 . "," . $radiusacctport . "," . $radiuskey3 . ",second"); + if (isset($radiusip4, $radiuskey4)) + fwrite($fd,"\n" . $radiusip4 . "," . $radiusport4 . "," . $radiusacctport . "," . $radiuskey4 . ",second"); + + fclose($fd); unlock($cprdsrvlck); } @@ -1187,8 +1214,16 @@ function captiveportal_get_radius_servers() { $line = trim($cpradiusentry); if ($line) { $radsrv = array(); - list($radsrv['ipaddr'],$radsrv['port'],$radsrv['acctport'],$radsrv['key']) = explode(",",$line); - $radiusservers[] = $radsrv; + list($radsrv['ipaddr'],$radsrv['port'],$radsrv['acctport'],$radsrv['key'], $context) = explode(",",$line); + } + if (empty($context)) { + if (!is_array($radiusservers['first'])) + $radiusservers['first'] = array(); + $radiusservers['first'] = $radsrv; + } else { + if (!is_array($radiusservers[$context])) + $radiusservers[$context] = array(); + $radiusservers[$context][] = $radsrv; } } } @@ -1223,7 +1258,7 @@ function captiveportal_syslog($message) { closelog(); } -function radius($username,$password,$clientip,$clientmac,$type) { +function radius($username,$password,$clientip,$clientmac,$type, $radiusctx = null) { global $g, $config; $ruleno = captiveportal_get_next_ipfw_ruleno(); @@ -1238,9 +1273,12 @@ function radius($username,$password,$clientip,$clientmac,$type) { $radiusservers = captiveportal_get_radius_servers(); + if (is_null($radiusctx)) + $radiusctx = 'first'; + $auth_list = RADIUS_AUTHENTICATION($username, $password, - $radiusservers, + $radiusservers[$radiusctx], $clientip, $clientmac, $ruleno); @@ -1252,7 +1290,8 @@ function radius($username,$password,$clientip,$clientmac,$type) { $username, $password, $auth_list, - $ruleno); + $ruleno, + $radiusctx); } return $auth_list; @@ -1621,7 +1660,7 @@ function portal_mac_radius($clientmac,$clientip) { return FALSE; } -function portal_allow($clientip,$clientmac,$username,$password = null, $attributes = null, $ruleno = null) { +function portal_allow($clientip,$clientmac,$username,$password = null, $attributes = null, $ruleno = null, $radiusctx = null) { global $redirurl, $g, $config, $type, $passthrumac, $_POST, $cpzone; @@ -1691,10 +1730,13 @@ function portal_allow($clientip,$clientmac,$username,$password = null, $attribut } } - /* Snaphost the timestamp */ + /* Snapshot the timestamp */ $allow_time = time(); - + if (is_null($radiusctx)) + $radiusctx = 'first'; foreach ($cpdb as $sid => $cpentry) { + if (empty($cpentry[10])) + $cpentry[10] = 'first'; /* on the same ip */ if($cpentry[2] == $clientip) { captiveportal_logportalauth($cpentry[4],$cpentry[3],$cpentry[2],"CONCURRENT LOGIN - REUSING OLD SESSION"); @@ -1709,7 +1751,7 @@ function portal_allow($clientip,$clientmac,$username,$password = null, $attribut $remaining_time = 0; /* This user was already logged in so we disconnect the old one */ - captiveportal_disconnect($cpentry,$radiusservers,13); + captiveportal_disconnect($cpentry,$radiusservers[$cpentry[10]],13); captiveportal_logportalauth($cpentry[4],$cpentry[3],$cpentry[2],"CONCURRENT LOGIN - TERMINATING OLD SESSION"); unset($cpdb[$sid]); break; @@ -1718,7 +1760,7 @@ function portal_allow($clientip,$clientmac,$username,$password = null, $attribut /* on the same username */ if (strcasecmp($cpentry[4], $username) == 0) { /* This user was already logged in so we disconnect the old one */ - captiveportal_disconnect($cpentry,$radiusservers,13); + captiveportal_disconnect($cpentry,$radiusservers[$cpentry[10]],13); captiveportal_logportalauth($cpentry[4],$cpentry[3],$cpentry[2],"CONCURRENT LOGIN - TERMINATING OLD SESSION"); unset($cpdb[$sid]); break; @@ -1802,15 +1844,15 @@ function portal_allow($clientip,$clientmac,$username,$password = null, $attribut /* encode password in Base64 just in case it contains commas */ $bpassword = base64_encode($password); $cpdb[] = array($allow_time, $ruleno, $clientip, $clientmac, $username, $sessionid, $bpassword, - $attributes['session_timeout'], $attributes['idle_timeout'], $attributes['session_terminate_time']); + $attributes['session_timeout'], $attributes['idle_timeout'], $attributes['session_terminate_time'], $radiusctx); /* rewrite information to database */ captiveportal_write_db($cpdb, true); unlock($cpdblck); - if (isset($config['captiveportal'][$cpzone]['radacct_enable']) && !empty($radiusservers)) { + if (isset($config['captiveportal'][$cpzone]['radacct_enable']) && !empty($radiusservers[$radiusctx])) { $acct_val = RADIUS_ACCOUNTING_START($ruleno, - $username, $sessionid, $radiusservers, $clientip, $clientmac); + $username, $sessionid, $radiusservers[$radiusctx], $clientip, $clientmac); if ($acct_val == 1) captiveportal_logportalauth($username,$clientmac,$clientip,$type,"RADIUS ACCOUNTING FAILED"); } diff --git a/usr/local/captiveportal/index.php b/usr/local/captiveportal/index.php index 9ed509f..04f0cc6 100755 --- a/usr/local/captiveportal/index.php +++ b/usr/local/captiveportal/index.php @@ -107,6 +107,11 @@ if (file_exists("{$g['vardb_path']}/captiveportal_radius_{$cpzone}.db")) { $radmac_enable = TRUE; } +/* find radius context */ +$radiusctx = 'first'; +if ($_POST['auth_user2']) + $radiusctx = 'second'; + if ($_POST['logout_id']) { echo <<<EOD <HTML> @@ -126,7 +131,7 @@ setTimeout('window.close();',5000) ; EOD; captiveportal_disconnect_client($_POST['logout_id']); exit; -} else if ($clientmac && $radmac_enable && portal_mac_radius($clientmac,$clientip)) { +} else if ($clientmac && $radmac_enable && portal_mac_radius($clientmac,$clientip, $radiusctx)) { /* radius functions handle everything so we exit here since we're done */ exit; @@ -164,8 +169,15 @@ EOD; } else if ($_POST['accept'] && $radius_enable) { - if ($_POST['auth_user'] && $_POST['auth_pass']) { - $auth_list = radius($_POST['auth_user'],$_POST['auth_pass'],$clientip,$clientmac,"USER LOGIN"); + if (($_POST['auth_user'] && $_POST['auth_pass']) || ($_POST['auth_user2'] && $_POST['auth_pass2'])) { + if (!empty($_POST['auth_user'])) { + $user = $_POST['auth_user']; + $paswd = $_POST['auth_pass']; + } else if (!empty($_POST['auth_user2'])) { + $user = $_POST['auth_user2']; + $paswd = $_POST['auth_pass2']; + } + $auth_list = radius($user,$paswd,$clientip,$clientmac,"USER LOGIN", $radiusctx); $type = "error"; if (!empty($auth_list['url_redirection'])) { $redirurl = $auth_list['url_redirection']; @@ -173,15 +185,21 @@ EOD; } if ($auth_list['auth_val'] == 1) { - captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"ERROR",$auth_list['error']); + 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($_POST['auth_user'],$clientmac,$clientip,"FAILURE",$auth_list['reply_message']); + 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 { - captiveportal_logportalauth($_POST['auth_user'],$clientmac,$clientip,"ERROR"); + if (!empty($_POST['auth_user'])) + $user = $_POST['auth_user']; + else if (!empty($_POST['auth_user2'])) + $user = $_POST['auth_user2']; + else + $user = 'unknown'; + captiveportal_logportalauth($user ,$clientmac,$clientip,"ERROR"); portal_reply_page($redirurl, "error", $errormsg); } diff --git a/usr/local/www/services_captiveportal.php b/usr/local/www/services_captiveportal.php index a54c697..4dc88d4 100755 --- a/usr/local/www/services_captiveportal.php +++ b/usr/local/www/services_captiveportal.php @@ -109,11 +109,17 @@ if (isset($cpzone) && $a_cp[$cpzone]) { $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['radiussrcip_attribute'] = $a_cp[$cpzone]['radiussrcip_attribute']; @@ -192,20 +198,28 @@ if ($_POST) { 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 total maximum number of concurrent connections must be between 4 and 100."); - } - $mymaxproc = $_POST['maxproc'] ? $_POST['maxproc'] : 16; - if ($_POST['maxprocperip'] && (!is_numeric($_POST['maxprocperip']) || ($_POST['maxprocperip'] > $mymaxproc))) { $input_errors[] = gettext("The maximum number of concurrent connections per client IP address may not be larger than the global maximum."); } @@ -255,13 +269,33 @@ if ($_POST) { $newcp['nomacfilter'] = $_POST['nomacfilter'] ? true : false; $newcp['noconcurrentlogins'] = $_POST['noconcurrentlogins'] ? true : false; $newcp['redirurl'] = $_POST['redirurl']; - $newcp['radiusip'] = $_POST['radiusip']; - $newcp['radiusip2'] = $_POST['radiusip2']; + if (isset($_POST['radiusip'])) + $config['captiveportal']['radiusip'] = $_POST['radiusip']; + else + unset($config['captiveportal']['radiusip3']); + if (isset($_POST['radiusip2'])) + $config['captiveportal']['radiusip2'] = $_POST['radiusip2']; + else + unset($config['captiveportal']['radiusip2']); + if (isset($_POST['radiusip3'])) + $config['captiveportal']['radiusip3'] = $_POST['radiusip3']; + else + unset($config['captiveportal']['radiusip3']); + if (isset($_POST['radiusip4'])) + $config['captiveportal']['radiusip4'] = $_POST['radiusip4']; + else + unset($config['captiveportal']['radiusip4']); $newcp['radiusport'] = $_POST['radiusport']; $newcp['radiusport2'] = $_POST['radiusport2']; + if (isset($_POST['radiusport3'])) + $config['captiveportal']['radiusport3'] = $_POST['radiusport3']; + if (isset($_POST['radiusport4'])) + $config['captiveportal']['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['radiussrcip_attribute'] = $_POST['radiussrcip_attribute']; @@ -329,10 +363,14 @@ function enable_change(enable_change) { document.iform.redirurl.disabled = endis; document.iform.radiusip.disabled = radius_endis; document.iform.radiusip2.disabled = radius_endis; + document.iform.radiusip3.disabled = radius_endis; + document.iform.radiusip4.disabled = radius_endis; document.iform.radiusport.disabled = radius_endis; document.iform.radiusport2.disabled = radius_endis; document.iform.radiuskey.disabled = radius_endis; document.iform.radiuskey2.disabled = radius_endis; + document.iform.radiuskey3.disabled = radius_endis; + document.iform.radiuskey4.disabled = radius_endis; document.iform.radacct_enable.disabled = radius_endis; document.iform.peruserbw.disabled = endis; document.iform.bwdefaultdn.disabled = endis; @@ -596,6 +634,44 @@ function enable_change(enable_change) { <td colspan="2" class="list" height="12"></td> </tr> <tr> + <td colspan="2" valign="top" class="optsect_t2"><?=gettext("Primary RADIUS server"); ?></td> + </tr> + <tr> + <td class="vncell" valign="top"><?=gettext("IP address"); ?></td> + <td class="vtable"><input name="radiusip3" type="text" class="formfld unknown" id="radiusip3" size="20" value="<?=htmlspecialchars($pconfig['radiusip3']);?>"><br> + <?=gettext("If you have a second RADIUS server, you can activate it by entering its IP address here."); ?></td> + </tr> + <tr> + <td class="vncell" valign="top"><?=gettext("Port"); ?></td> + <td class="vtable"><input name="radiusport3" type="text" class="formfld unknown" id="radiusport3" size="5" value="<?=htmlspecialchars($pconfig['radiusport3']);?>"></td> + </tr> + <tr> + <td class="vncell" valign="top"><?=gettext("Shared secret"); ?> </td> + <td class="vtable"><input name="radiuskey3" type="text" class="formfld unknown" id="radiuskey3" size="16" value="<?=htmlspecialchars($pconfig['radiuskey3']);?>"></td> + </tr> + <tr> + <td colspan="2" class="list" height="12"></td> + </tr> + <tr> + <td colspan="2" valign="top" class="optsect_t2"><?=gettext("Secondary RADIUS server"); ?></td> + </tr> + <tr> + <td class="vncell" valign="top"><?=gettext("IP address"); ?></td> + <td class="vtable"><input name="radiusip4" type="text" class="formfld unknown" id="radiusip4" size="20" value="<?=htmlspecialchars($pconfig['radiusip4']);?>"><br> + <?=gettext("If you have a second RADIUS server, you can activate it by entering its IP address here."); ?></td> + </tr> + <tr> + <td class="vncell" valign="top"><?=gettext("Port"); ?></td> + <td class="vtable"><input name="radiusport4" type="text" class="formfld unknown" id="radiusport4" size="5" value="<?=htmlspecialchars($pconfig['radiusport4']);?>"></td> + </tr> + <tr> + <td class="vncell" valign="top"><?=gettext("Shared secret"); ?> </td> + <td class="vtable"><input name="radiuskey4" type="text" class="formfld unknown" id="radiuskey4" size="16" value="<?=htmlspecialchars($pconfig['radiuskey4']);?>"></td> + </tr> + <tr> + <td colspan="2" class="list" height="12"></td> + </tr> + <tr> <td colspan="2" valign="top" class="optsect_t2"><?=gettext("Accounting"); ?></td> </tr> <tr> @@ -664,7 +740,7 @@ function enable_change(enable_change) { if (is_ipaddr($ipaddr)) { $selected = ""; if ($ipaddr == $pconfig['radiussrcip_attribute']) - $ifdesc = "selected"; + $selected= "selected"; echo "<option value='{$ifdesc}' {$selected}>{$ifdescr} - {$ipaddr}</option>\n"; } } |