diff options
-rw-r--r-- | etc/inc/captiveportal.inc | 17 | ||||
-rw-r--r-- | etc/inc/certs.inc | 14 | ||||
-rw-r--r-- | etc/inc/globals.inc | 2 | ||||
-rw-r--r-- | etc/inc/upgrade_config.inc | 39 | ||||
-rwxr-xr-x | usr/local/www/services_captiveportal.php | 121 | ||||
-rw-r--r-- | usr/local/www/system_certmanager.php | 3 |
6 files changed, 141 insertions, 55 deletions
diff --git a/etc/inc/captiveportal.inc b/etc/inc/captiveportal.inc index 653139a..ba9d7e4 100644 --- a/etc/inc/captiveportal.inc +++ b/etc/inc/captiveportal.inc @@ -454,16 +454,19 @@ function captiveportal_init_webgui_zone($cpcfg) { $use_fastcgi = true; if (isset($cpcfg['httpslogin'])) { - $cert = base64_decode($cpcfg['certificate']); - if (isset($cpcfg['cacertificate'])) - $cacert = base64_decode($cpcfg['cacertificate']); - else - $cacert = ""; - $key = base64_decode($cpcfg['private-key']); + $cert = lookup_cert($cpcfg['certref']); + $cert_crt = base64_decode($cert['crt']); + $cert_prv = base64_decode($cert['prv']); + if (isset($cpcfg['caref'])) { + $ca = lookup_ca($cpcfg['caref']); + $ca_crt = base64_decode($ca['crt']); + } + else + $ca_crt = ""; /* generate lighttpd configuration */ $listenporthttps = $cpcfg['listenporthttps'] ? $cpcfg['listenporthttps'] : ($cpcfg['zoneid'] + 1); system_generate_lighty_config("{$g['varetc_path']}/lighty-{$cpzone}-CaptivePortal-SSL.conf", - $cert, $key, $cacert, "lighty-{$cpzone}-CaptivePortal-SSL.pid", $listenporthttps, "/usr/local/captiveportal", + $cert_crt, $cert_prv, $ca_crt, "lighty-{$cpzone}-CaptivePortal-SSL.pid", $listenporthttps, "/usr/local/captiveportal", "cert-portal.pem", "ca-portal.pem", "1", $use_fastcgi, $cpzone); } diff --git a/etc/inc/certs.inc b/etc/inc/certs.inc index ec3227d..862e91b 100644 --- a/etc/inc/certs.inc +++ b/etc/inc/certs.inc @@ -528,12 +528,24 @@ function is_webgui_cert($certref) { return true; } +function is_captiveportal_cert($certref) { + global $config; + if (!is_array($config['captiveportal'])) + return; + foreach ($config['captiveportal'] as $portal) { + if ($portal['enable'] && $portal['httpslogin_enable'] && ($portal['certref'] == $certref)) + return true; + } + return false; +} + function cert_in_use($certref) { return (is_webgui_cert($certref) || is_user_cert($certref) || is_openvpn_server_cert($certref) || is_openvpn_client_cert($certref) || - is_ipsec_cert($certref)); + is_ipsec_cert($certref) || + is_captiveportal_cert($certref)); } /* diff --git a/etc/inc/globals.inc b/etc/inc/globals.inc index 519f28c..23c3a92 100644 --- a/etc/inc/globals.inc +++ b/etc/inc/globals.inc @@ -77,7 +77,7 @@ $g = array( "disablecrashreporter" => false, "crashreporterurl" => "http://crashreporter.pfsense.org/crash_reporter.php", "debug" => false, - "latest_config" => "8.8", + "latest_config" => "8.9", "nopkg_platforms" => array("cdrom"), "minimum_ram_warning" => "101", "minimum_ram_warning_text" => "128 MB", diff --git a/etc/inc/upgrade_config.inc b/etc/inc/upgrade_config.inc index bd12830..88faba4 100644 --- a/etc/inc/upgrade_config.inc +++ b/etc/inc/upgrade_config.inc @@ -2883,4 +2883,43 @@ function upgrade_087_to_088() { $config['system']['crypto_hardware'] = "glxsb"; } } + +function upgrade_088_to_089() { + global $config; + if (!is_array($config['ca'])) + $config['ca'] = array(); + if (!is_array($config['cert'])) + $config['cert'] = array(); + + /* migrate captive portal ssl to certifcate mngr */ + if (is_array($config['captiveportal'])) { + foreach ($config['captiveportal'] as $id => &$setting) { + if (isset($setting['httpslogin'])) { + /* create cert entry */ + $cert = array(); + $cert['refid'] = uniqid(); + $cert['descr'] = "Captive Portal SSL Cert - {$setting['zone']}"; + $cert['crt'] = $setting['certificate']; + $cert['prv'] = $setting['private-key']; + $config['cert'][] = $cert; + + /* create cert reference */ + unset($setting['certificate']); + unset($setting['private-key']); + $setting['certref'] = $cert['refid']; + + /* create ca entry */ + $ca = array(); + $ca['refid'] = uniqid(); + $ca['descr'] = "Captive Portal SSL CA - {$setting['zone']}"; + $ca['crt'] = $setting['cacertificate']; + $config['ca'][] = $ca; + + /* create ca reference */ + unset($setting['cacertificate']); + $setting['caref'] = $ca['refid']; + } + } + } +} ?> diff --git a/usr/local/www/services_captiveportal.php b/usr/local/www/services_captiveportal.php index 6dd23aa..dd59e7a 100755 --- a/usr/local/www/services_captiveportal.php +++ b/usr/local/www/services_captiveportal.php @@ -76,6 +76,16 @@ if ($_GET['act'] == "viewhtml") { exit; } +if (!is_array($config['ca'])) + $config['ca'] = array(); + +$a_ca =& $config['ca']; + +if (!is_array($config['cert'])) + $config['cert'] = array(); + +$a_cert =& $config['cert']; + if ($a_cp[$cpzone]) { $pconfig['zoneid'] = $a_cp[$cpzone]['zoneid']; $pconfig['cinterface'] = $a_cp[$cpzone]['interface']; @@ -97,9 +107,8 @@ if ($a_cp[$cpzone]) { $pconfig['httpslogin_enable'] = isset($a_cp[$cpzone]['httpslogin']); $pconfig['httpsname'] = $a_cp[$cpzone]['httpsname']; $pconfig['preauthurl'] = strtolower($a_cp[$cpzone]['preauthurl']); - $pconfig['cert'] = base64_decode($a_cp[$cpzone]['certificate']); - $pconfig['cacert'] = base64_decode($a_cp[$cpzone]['cacertificate']); - $pconfig['key'] = base64_decode($a_cp[$cpzone]['private-key']); + $pconfig['certref'] = $a_cp[$cpzone]['certref']; + $pconfig['caref'] = $a_cp[$cpzone]['caref']; $pconfig['logoutwin_enable'] = isset($a_cp[$cpzone]['logoutwin_enable']); $pconfig['peruserbw'] = isset($a_cp[$cpzone]['peruserbw']); $pconfig['bwdefaultdn'] = $a_cp[$cpzone]['bwdefaultdn']; @@ -163,17 +172,9 @@ if ($_POST) { } if ($_POST['httpslogin_enable']) { - if (!$_POST['cert'] || !$_POST['key']) { - $input_errors[] = gettext("Certificate and key must be specified for HTTPS login."); - } else { - if (!strstr($_POST['cert'], "BEGIN CERTIFICATE") || !strstr($_POST['cert'], "END CERTIFICATE")) - $input_errors[] = gettext("This certificate does not appear to be valid."); - if (!strstr($_POST['cacert'], "BEGIN CERTIFICATE") || !strstr($_POST['cacert'], "END CERTIFICATE")) - $input_errors[] = gettext("This intermmediate certificate does not appear to be valid."); - if (!strstr($_POST['key'], "BEGIN RSA PRIVATE KEY") || !strstr($_POST['key'], "END RSA PRIVATE KEY")) - $input_errors[] = gettext("This key does not appear to be valid."); + if (!$_POST['certref']) { + $input_errors[] = gettext("Certificate must be specified for HTTPS login."); } - if (!$_POST['httpsname'] || !is_domain($_POST['httpsname'])) { $input_errors[] = gettext("The HTTPS server name must be specified for HTTPS login."); } @@ -263,9 +264,8 @@ if ($_POST) { $newcp['peruserbw'] = $_POST['peruserbw'] ? true : false; $newcp['bwdefaultdn'] = $_POST['bwdefaultdn']; $newcp['bwdefaultup'] = $_POST['bwdefaultup']; - $newcp['certificate'] = base64_encode($_POST['cert']); - $newcp['cacertificate'] = base64_encode($_POST['cacert']); - $newcp['private-key'] = base64_encode($_POST['key']); + $newcp['certref'] = $_POST['certref']; + $newcp['caref'] = $_POST['caref']; $newcp['logoutwin_enable'] = $_POST['logoutwin_enable'] ? true : false; $newcp['nomacfilter'] = $_POST['nomacfilter'] ? true : false; $newcp['noconcurrentlogins'] = $_POST['noconcurrentlogins'] ? true : false; @@ -350,6 +350,7 @@ function enable_change(enable_change) { var endis, radius_endis; endis = !(document.iform.enable.checked || enable_change); radius_endis = !((!endis && document.iform.auth_method[2].checked) || enable_change); + https_endis = !((!endis && document.iform.httpslogin_enable.checked) || enable_change); document.iform.cinterface.disabled = endis; //document.iform.maxproc.disabled = endis; @@ -388,10 +389,9 @@ function enable_change(enable_change) { document.iform.radmac_enable.disabled = radius_endis; document.iform.httpslogin_enable.disabled = endis; document.iform.radmac_format.disabled = radius_endis; - document.iform.httpsname.disabled = endis; - document.iform.cert.disabled = endis; - document.iform.cacert.disabled = endis; - document.iform.key.disabled = endis; + document.iform.httpsname.disabled = https_endis; + document.iform.certref.disabled = https_endis; + document.iform.caref.disabled = https_endis; document.iform.logoutwin_enable.disabled = endis; document.iform.nomacfilter.disabled = endis; document.iform.noconcurrentlogins.disabled = endis; @@ -860,37 +860,66 @@ function enable_change(enable_change) { <tr> <td valign="top" class="vncell"><?=gettext("HTTPS login"); ?></td> <td class="vtable"> - <input name="httpslogin_enable" type="checkbox" class="formfld" id="httpslogin_enable" value="yes" <?php if($pconfig['httpslogin_enable']) echo "checked"; ?>> + <input name="httpslogin_enable" type="checkbox" class="formfld" id="httpslogin_enable" value="yes" onClick="enable_change(false)" <?php if($pconfig['httpslogin_enable']) echo "checked"; ?>> <strong><?=gettext("Enable HTTPS login"); ?></strong><br> - <?=gettext("If enabled, the username and password will be transmitted over an HTTPS connection to protect against eavesdroppers. A server name, certificate and matching private key must also be specified below."); ?></td> - </tr> + <?=gettext("If enabled, the username and password will be transmitted over an HTTPS connection to protect against eavesdroppers. A server name and certificate must also be specified below."); ?></td> + </tr> <tr> <td valign="top" class="vncell"><?=gettext("HTTPS server name"); ?> </td> <td class="vtable"> <input name="httpsname" type="text" class="formfld unknown" id="httpsname" size="30" value="<?=htmlspecialchars($pconfig['httpsname']);?>"><br> <?php printf(gettext("This name will be used in the form action for the HTTPS POST and should match the Common Name (CN) in your certificate (otherwise, the client browser will most likely display a security warning). Make sure captive portal clients can resolve this name in DNS and verify on the client that the IP resolves to the correct interface IP on %s."), $g['product_name']);?> </td> - </tr> - <tr> - <td valign="top" class="vncell"><?=gettext("HTTPS certificate"); ?></td> - <td class="vtable"> - <textarea name="cert" cols="65" rows="7" id="cert" class="formpre"><?=htmlspecialchars($pconfig['cert']);?></textarea> - <br> - <?=gettext("Paste a signed certificate in X.509 PEM format here."); ?></td> - </tr> - <tr> - <td valign="top" class="vncell"><?=gettext("HTTPS private key"); ?></td> - <td class="vtable"> - <textarea name="key" cols="65" rows="7" id="key" class="formpre"><?=htmlspecialchars($pconfig['key']);?></textarea> - <br> - <?=gettext("Paste an RSA private key in PEM format here."); ?></td> - </tr> - <tr> - <td valign="top" class="vncell"><?=gettext("HTTPS intermediate certificate"); ?></td> - <td class="vtable"> - <textarea name="cacert" cols="65" rows="7" id="cacert" class="formpre"><?=htmlspecialchars($pconfig['cacert']);?></textarea> - <br> - <?=gettext("Paste a certificate in X.509 PEM format here."); ?></td> - </tr> + </tr> + <tr id="tls_ca"> + <td width="22%" valign="top" class="vncell"><?=gettext("Certificate Authority"); ?></td> + <td width="78%" class="vtable"> + <?php if (count($a_ca)): ?> + <select name='caref' class="formselect"> + <option value=""><?=gettext("None"); ?></option> + <?php + foreach ($a_ca as $ca): + $selected = ""; + if ($pconfig['caref'] == $ca['refid']) + $selected = "selected"; + ?> + <option value="<?=$ca['refid'];?>" <?=$selected;?>><?=$ca['descr'];?></option> + <?php endforeach; ?> + </select> + <?php else: ?> + <b><?=gettext("No Certificate Authorities defined."); ?></b> <br/>Create one under <a href="system_camanager.php">System > Cert Manager</a>. + <?php endif; ?> + </td> + </tr> + <tr id="tls_cert"> + <td width="22%" valign="top" class="vncell"><?=gettext("Server Certificate"); ?></td> + <td width="78%" class="vtable"> + <?php if (count($a_cert)): ?> + <select name='certref' class="formselect"> + <option value=""><?=gettext("None"); ?></option> + <?php + foreach ($a_cert as $cert): + $selected = ""; + $caname = ""; + $inuse = ""; + $revoked = ""; + $ca = lookup_ca($cert['caref']); + if ($ca) + $caname = " (CA: {$ca['descr']})"; + if ($pconfig['certref'] == $cert['refid']) + $selected = "selected"; + if (cert_in_use($cert['refid'])) + $inuse = " *In Use"; + if (is_cert_revoked($cert)) + $revoked = " *Revoked"; + ?> + <option value="<?=$cert['refid'];?>" <?=$selected;?>><?=$cert['descr'] . $caname . $inuse . $revoked;?></option> + <?php endforeach; ?> + </select> + <?php else: ?> + <b><?=gettext("No Certificates defined."); ?></b> <br/>Create one under <a href="system_certmanager.php">System > Cert Manager</a>. + <?php endif; ?> + </td> + </tr> <tr> <td width="22%" valign="top" class="vncell"><?=gettext("Portal page contents"); ?></td> <td width="78%" class="vtable"> @@ -898,7 +927,7 @@ function enable_change(enable_change) { <?php list($host) = explode(":", $_SERVER['HTTP_HOST']); $zoneid = $pconfig['zoneid'] ? $pconfig['zoneid'] : 8000; - if (isset($pconfig['httpslogin'])) { + if ($pconfig['httpslogin_enable']) { $port = $pconfig['listenporthttps'] ? $pconfig['listenporthttps'] : ($zoneid + 1); $href = "https://{$host}:{$port}"; } else { diff --git a/usr/local/www/system_certmanager.php b/usr/local/www/system_certmanager.php index 6622b40..c9e9826 100644 --- a/usr/local/www/system_certmanager.php +++ b/usr/local/www/system_certmanager.php @@ -1097,6 +1097,9 @@ function internalca_change() { <?php if (is_ipsec_cert($cert['refid'])): ?> IPsec Tunnel<br/> <?php endif; ?> + <?php if (is_captiveportal_cert($cert['refid'])): ?> + Captive Portal<br/> + <?php endif; ?> </td> <td valign="middle" nowrap class="list"> <a href="system_certmanager.php?act=exp&id=<?=$i;?>"> |