From b0b6d5754fe5c313f4c83b18dabf2cff1310dea3 Mon Sep 17 00:00:00 2001 From: jim-p Date: Mon, 30 Aug 2010 12:04:54 -0400 Subject: [PATCH 01/19] Require an authentication backend if the user chooses an OpenVPN server mode that needs user auth. Failing to do so can result in a configuration error. --- usr/local/www/vpn_openvpn_server.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/usr/local/www/vpn_openvpn_server.php b/usr/local/www/vpn_openvpn_server.php index f085f27a1a..222ed5176c 100644 --- a/usr/local/www/vpn_openvpn_server.php +++ b/usr/local/www/vpn_openvpn_server.php @@ -179,6 +179,9 @@ if ($_POST) { } } + if (empty($pconfig['authmode']) && (($pconfig['mode'] == "server_user") || ($pconfig['mode'] == "server_tls_user"))) + $input_errors[] = gettext("You must select a Backend for Authentication if the server mode requires User Auth."); + /* input validation */ if ($result = openvpn_validate_port($pconfig['local_port'], 'Local port')) $input_errors[] = $result; From 44c7cce5f93a1ab0cddbb547c06fdff4d797a2d4 Mon Sep 17 00:00:00 2001 From: jim-p Date: Mon, 30 Aug 2010 12:50:13 -0400 Subject: [PATCH 02/19] Fix gettext mishap/typo. Cosmetic only. Fixes #857 --- usr/local/www/firewall_rules_edit.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/usr/local/www/firewall_rules_edit.php b/usr/local/www/firewall_rules_edit.php index 3cc5bad5ab..34cfc5d08b 100755 --- a/usr/local/www/firewall_rules_edit.php +++ b/usr/local/www/firewall_rules_edit.php @@ -854,7 +854,7 @@ include("head.inc");
- "").")."
".

+ "").
.

From 830c33be3c3e4cf2216672d17b9c40be99828784 Mon Sep 17 00:00:00 2001 From: Scott Ullrich Date: Mon, 30 Aug 2010 12:57:27 -0400 Subject: [PATCH 03/19] Add Captive Portal voucher database sync to secondary nodes. How this works is you designate one of your access points with a voucher database as the master and then on the slave nodes you setup the 4 fields on the voucher edit screen. This will then sync the voucher database and anytime someone attempts to authenticate the slave nodes will use XMLRPC over to the master node to ensure that the voucher has not been used, etc. Add generate certificate option on the voucher edit screen --- etc/inc/voucher.inc | 62 +- .../www/services_captiveportal_vouchers.php | 712 +++++++++++------- 2 files changed, 511 insertions(+), 263 deletions(-) diff --git a/etc/inc/voucher.inc b/etc/inc/voucher.inc index 056172b0a5..ec3ecd9c31 100644 --- a/etc/inc/voucher.inc +++ b/etc/inc/voucher.inc @@ -136,12 +136,24 @@ function voucher_auth($voucher_received, $test = 0) { // the user wouldn't know that he used at least one invalid voucher. if ($error) { - unlock($voucherlck); + unlock($voucherlck); if ($total_minutes > 0) // probably not needed, but want to make sure $total_minutes = 0; // we only report -1 (expired) or 0 (no access) return $total_minutes; // well, at least one voucher had errors. Say NO ACCESS } + // XMLRPC Call over to the master Voucher node + $a_voucher = &$config['voucher']; + if($a_voucher['vouchersyncdbip']) { + $syncip = $a_voucher['vouchersyncdbip']; + $syncport = $a_voucher['vouchersyncport']; + $syncpass = $a_voucher['vouchersyncpass']; + $syncpass = $a_voucher['vouchersyncusername']; + $remote_time_used = sync_used_voucher($voucher_received, $syncip, $syncport, $syncpass, $vouchersyncusername); + if($remote_time_used['timeleft'] < 1) + $total_minutes = $remote_time_used['timeleft']; + } + // All given vouchers were valid and this isn't simply a test. // Write back the used DB's @@ -179,6 +191,54 @@ function voucher_auth($voucher_received, $test = 0) { return $total_minutes; } +function sync_used_voucher($voucher_received, $syncip, $port, $password, $username) { + require_once("xmlrpc.inc"); + if($port == "443") + $url = "https://{$syncip}:{$port}"; + else + $url = "http://{$syncip}:{$port}"; + + /* Construct code that is run on remote machine */ + $method = 'pfsense.exec_php'; + $execcmd = <<setCredentials('admin', $password); + $resp = $cli->send($msg, "250"); + if(!$resp) { + $error = "A communications error occurred while attempting CaptivePortalVoucherSync XMLRPC sync with {$url}:{$port} (pfsense.exec_php)."; + log_error($error); + file_notice("CaptivePortalVoucherSync", $error, "Communications error occurred", ""); + return array("timeleft" => "0"); + } elseif($resp->faultCode()) { + $cli->setDebug(1); + $resp = $cli->send($msg, "250"); + $error = "An error code was received while attempting CaptivePortalVoucherSync XMLRPC sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString(); + log_error($error); + file_notice("CaptivePortalVoucherSync", $error, "Error code received", ""); + return array("timeleft" => "0"); + } else { + log_error("CaptivePortalVoucherSync XMLRPC reload data success with {$url}:{$port} (pfsense.exec_php)."); + } + $timeleft = XML_RPC_Decode($resp->value()); + //print_r($timeleft); + return $timeleft; +} + function voucher_configure() { global $config, $g; diff --git a/usr/local/www/services_captiveportal_vouchers.php b/usr/local/www/services_captiveportal_vouchers.php index 2450fd2391..f45e60cf0a 100644 --- a/usr/local/www/services_captiveportal_vouchers.php +++ b/usr/local/www/services_captiveportal_vouchers.php @@ -46,98 +46,103 @@ require("shaper.inc"); require("captiveportal.inc"); require_once("voucher.inc"); +if($_REQUEST['generatekey']) { + exec("openssl genrsa 64 > /tmp/key64.private"); + exec("openssl rsa -pubout < /tmp/key64.private > /tmp/key64.public"); + $privatekey = str_replace("\n", "\\n", file_get_contents("/tmp/key64.private")); + $publickey = str_replace("\n", "\\n", file_get_contents("/tmp/key64.public")); + exec("rm /tmp/key64.private /tmp/key64.public"); + $alertmessage = gettext("You will need to recreate any existing Voucher Rolls due to the public and private key changes."); + echo <<0)) { + if ($_POST['charset'] && (strpos($_POST['charset'],"\"")>0)) $input_errors[] = gettext("Double quotes aren't allowed."); - } - if ($_POST['charset'] && (strpos($_POST['charset'],",")>0)) { + if ($_POST['charset'] && (strpos($_POST['charset'],",")>0)) $input_errors[] = "',' " . gettext("aren't allowed."); - } - if ($_POST['rollbits'] && (!is_numeric($_POST['rollbits']) || ($_POST['rollbits'] < 1) || ($_POST['rollbits'] > 31))) { + if ($_POST['rollbits'] && (!is_numeric($_POST['rollbits']) || ($_POST['rollbits'] < 1) || ($_POST['rollbits'] > 31))) $input_errors[] = gettext("# of Bits to store Roll Id needs to be between 1..31."); - } - if ($_POST['ticketbits'] && (!is_numeric($_POST['ticketbits']) || ($_POST['ticketbits'] < 1) || ($_POST['ticketbits'] > 16))) { + if ($_POST['ticketbits'] && (!is_numeric($_POST['ticketbits']) || ($_POST['ticketbits'] < 1) || ($_POST['ticketbits'] > 16))) $input_errors[] = gettext("# of Bits to store Ticket Id needs to be between 1..16."); - } - if ($_POST['checksumbits'] && (!is_numeric($_POST['checksumbits']) || ($_POST['checksumbits'] < 1) || ($_POST['checksumbits'] > 31))) { + if ($_POST['checksumbits'] && (!is_numeric($_POST['checksumbits']) || ($_POST['checksumbits'] < 1) || ($_POST['checksumbits'] > 31))) $input_errors[] = gettext("# of Bits to store checksum needs to be between 1..31."); - } - if ($_POST['saveinterval'] && (!is_numeric($_POST['saveinterval']) || ($_POST['saveinterval'] < 1))) { + if ($_POST['saveinterval'] && (!is_numeric($_POST['saveinterval']) || ($_POST['saveinterval'] < 1))) $input_errors[] = gettext("Save interval in minutes cant be negative."); - } - if ($_POST['publickey'] && (!strstr($_POST['publickey'],"BEGIN PUBLIC KEY"))) { + if ($_POST['publickey'] && (!strstr($_POST['publickey'],"BEGIN PUBLIC KEY"))) $input_errors[] = gettext("This doesn't look like an RSA Public key."); - } - if ($_POST['privatekey'] && (!strstr($_POST['privatekey'],"BEGIN RSA PRIVATE KEY"))) { + if ($_POST['privatekey'] && (!strstr($_POST['privatekey'],"BEGIN RSA PRIVATE KEY"))) $input_errors[] = gettext("This doesn't look like an RSA Private key."); - } if (!$input_errors) { - $config['voucher']['enable'] = $_POST['enable'] ? true : false; - $config['voucher']['charset'] = $_POST['charset']; - $config['voucher']['rollbits'] = $_POST['rollbits']; - $config['voucher']['ticketbits'] = $_POST['ticketbits']; - $config['voucher']['checksumbits'] = $_POST['checksumbits']; - $config['voucher']['magic'] = $_POST['magic']; - $config['voucher']['saveinterval'] = $_POST['saveinterval']; - $config['voucher']['publickey'] = base64_encode($_POST['publickey']); - $config['voucher']['privatekey'] = base64_encode($_POST['privatekey']); - $config['voucher']['msgnoaccess'] = $_POST['msgnoaccess']; - $config['voucher']['msgexpired'] = $_POST['msgexpired']; - - write_config(); - voucher_configure(); - if (isset($config['voucher']['enable']) && !isset($config['captiveportal']['enable'])) { - $savemsg = gettext("Don't forget to configure and enable Captive Portal."); - } + $config['voucher']['enable'] = $_POST['enable'] ? true : false; + $config['voucher']['charset'] = $_POST['charset']; + $config['voucher']['rollbits'] = $_POST['rollbits']; + $config['voucher']['ticketbits'] = $_POST['ticketbits']; + $config['voucher']['checksumbits'] = $_POST['checksumbits']; + $config['voucher']['magic'] = $_POST['magic']; + $config['voucher']['saveinterval'] = $_POST['saveinterval']; + $config['voucher']['publickey'] = base64_encode($_POST['publickey']); + $config['voucher']['privatekey'] = base64_encode($_POST['privatekey']); + $config['voucher']['msgnoaccess'] = $_POST['msgnoaccess']; + $config['voucher']['msgexpired'] = $_POST['msgexpired']; + $config['voucher']['vouchersyncdbip'] = $_POST['vouchersyncdbip']; + $config['voucher']['vouchersyncport'] = $_POST['vouchersyncport']; + $config['voucher']['vouchersyncusername'] = $_POST['vouchersyncusername']; + $config['voucher']['vouchersyncpass'] = $_POST['vouchersyncpass']; + if($config['voucher']['vouchersyncpass'] && $config['voucher']['vouchersyncusername'] && + $config['voucher']['vouchersyncport'] && $config['voucher']['vouchersyncdbip']) { + // Synchronize the voucher DB from the master node + require_once("xmlrpc.inc"); + if($config['voucher']['vouchersyncport'] == "443") + $url = "https://{$config['voucher']['vouchersyncdbip']}:{$config['voucher']['vouchersyncport']}"; + else + $url = "http://{$config['voucher']['vouchersyncdbip']}:{$config['voucher']['vouchersyncport']}"; + $execcmd = <<setCredentials($config['voucher']['vouchersyncusername'], $config['voucher']['vouchersyncpass']); + $resp = $cli->send($msg, "250"); + if(!$resp) { + $error = "A communications error occurred while attempting CaptivePortalVoucherSync XMLRPC sync with {$url}:{$port} (pfsense.exec_php)."; + log_error($error); + file_notice("CaptivePortalVoucherSync", $error, "Communications error occurred", ""); + $input_errors[] = $error; + } elseif($resp->faultCode()) { + $cli->setDebug(1); + $resp = $cli->send($msg, "250"); + $error = "An error code was received while attempting CaptivePortalVoucherSync XMLRPC sync with {$url}:{$port} - Code " . $resp->faultCode() . ": " . $resp->faultString(); + log_error($error); + file_notice("CaptivePortalVoucherSync", $error, "Error code received", ""); + $input_errors[] = $error; + } else { + log_error("The Captive Portal voucher database has been synchronized with {$url}:{$port} (pfsense.exec_php)."); + } + $toreturn = XML_RPC_Decode($resp->value()); + if(!is_array($toreturn)) { + if($toreturn == "Authentication failed") + $input_errors[] = "Could not synchronize the voucher database: Authentication Failed."; + } else { + // If we received back the voucher roll and other information then store it. + if($toreturn['voucher']['roll']) + $config['voucher']['roll'] = $toreturn['voucher']['roll']; + if($toreturn['voucher']['rollbits']) + $config['voucher']['rollbits'] = $toreturn['voucher']['rollbits']; + if($toreturn['voucher']['ticketbits']) + $config['voucher']['ticketbits'] = $toreturn['voucher']['ticketbits']; + if($toreturn['voucher']['saveinterval']) + $config['voucher']['saveinterval'] = $toreturn['voucher']['saveinterval']; + if($toreturn['voucher']['checksumbits']) + $config['voucher']['checksumbits'] = $toreturn['voucher']['checksumbits']; + if($toreturn['voucher']['magic']) + $config['voucher']['magic'] = $toreturn['voucher']['magic']; + if($toreturn['voucher']['publickey']) + $config['voucher']['publickey'] = $toreturn['voucher']['publickey']; + if($toreturn['voucher']['privatekey']) + $config['voucher']['privatekey'] = $toreturn['voucher']['privatekey']; + if($toreturn['voucher']['msgnoaccess']) + $config['voucher']['msgnoaccess'] = $toreturn['voucher']['msgnoaccess']; + if($toreturn['voucher']['msgexpired']) + $config['voucher']['msgexpired'] = $toreturn['voucher']['msgexpired']; + if($toreturn['voucher']['msgnoaccess']) + $config['voucher']['msgnoaccess'] = $toreturn['voucher']['msgnoaccess']; + $savemsg = gettext("Voucher database has been synchronized from {$url}"); + } + } + write_config(); + voucher_configure(); + if($savemsg && isset($config['voucher']['enable']) && !isset($config['captiveportal']['enable'])) + $savemsg .= "
"; + if (isset($config['voucher']['enable']) && !isset($config['captiveportal']['enable'])) + $savemsg .= gettext("Don't forget to configure and enable Captive Portal."); } } include("head.inc"); @@ -218,10 +301,34 @@ include("head.inc"); @@ -239,167 +369,225 @@ function enable_change(enable_change) {
- + - - - -
-
    +
+
    -
-
- - - - + + - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
  - onClick="enable_change(false)"> -
- - - - - - - - - - - - - - - - - - - - - \"""; - } - ?> - -
##
-   - -   - -   - -   - - - " width="17" height="17" border="0" alt=""> - ')">" width="17" height="17" border="0" alt=""> - " width="11" height="15" border="0" alt=""> - -
- - - -
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  + onClick="enable_change(false)"> + +
+ + (Synchronized from {$pconfig['vouchersyncdbip']})"; + ?> + + + + + + + + + + + + + + + + + + + + +
\""
"; + ?> + +
##
+   + +   + +   + +   + + +
+ + + +
+ + + +
+ .
+ +
+ .
+ +
+ +
# + +
+ +
# + +
+ +
# + +
+ +
+ +
+ +
+ +
+ +
+ +
($PORTAL_MESSAGE$). +
+ +
($PORTAL_MESSAGE$). +
  +   +
+ +
+
+ +
+
+ +
+
+ +
+
  + " onClick="enable_change(true); before_save();"> + " onclick="history.back()"> +

+
+ +

+
+
- -
-
- -
-
- -
-
# - -
-
# - -
-
# - -
-
- -
-
- -
-
- -
($PORTAL_MESSAGE$).
- -
($PORTAL_MESSAGE$).
  - " onClick="enable_change(true)"> -

-
- -

-
-
+