aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--config/haproxy-devel/haproxy.inc80
-rw-r--r--config/haproxy-devel/haproxy.xml5
-rwxr-xr-xconfig/haproxy-devel/haproxy_global.php18
-rw-r--r--config/haproxy-devel/haproxy_listeners.php7
-rw-r--r--config/haproxy-devel/haproxy_listeners_edit.php29
-rw-r--r--config/haproxy-devel/haproxy_pool_edit.php21
-rw-r--r--config/haproxy-devel/haproxy_utils.inc267
7 files changed, 333 insertions, 94 deletions
diff --git a/config/haproxy-devel/haproxy.inc b/config/haproxy-devel/haproxy.inc
index 912f1fb3..4da961de 100644
--- a/config/haproxy-devel/haproxy.inc
+++ b/config/haproxy-devel/haproxy.inc
@@ -31,6 +31,7 @@
require_once("functions.inc");
require_once("pkg-utils.inc");
require_once("notices.inc");
+require_once("haproxy_utils.inc");
require_once("haproxy_xmlrpcsyncclient.inc");
$d_haproxyconfdirty_path = $g['varrun_path'] . "/haproxy.conf.dirty";
@@ -107,7 +108,7 @@ $a_closetypes['forceclose'] = array('name' => 'forceclose', 'syntax' => 'forcecl
function haproxy_custom_php_deinstall_command() {
exec("cd /var/db/pkg && pkg_delete `ls | grep haproxy`");
- exec("rm /usr/local/pkg/haproxy.inc");
+ exec("rm /usr/local/pkg/haproxy*");
exec("rm /usr/local/www/haproxy*");
exec("rm /usr/local/etc/rc.d/haproxy.sh");
exec("rm /etc/devd/haproxy.conf");
@@ -592,6 +593,13 @@ function haproxy_writeconf($configfile) {
$ssl_crt=" crt /var/etc/{$backend['name']}.{$backend['port']}.crt";
$cert = lookup_cert($backend['ssloffloadcert']);
$certcontent = base64_decode($cert['crt'])."\r\n".base64_decode($cert['prv']);
+
+ $certchaincontent = ca_chain($cert);
+ if ($certchaincontent != "") {
+ $certcontent .= "\r\n" . $certchaincontent;
+ }
+ unset($certchaincontent);
+
file_put_contents("/var/etc/{$backend['name']}.{$backend['port']}.crt", $certcontent);
unset($certcontent);
}else{
@@ -657,14 +665,12 @@ function haproxy_writeconf($configfile) {
$listenip = "";
// Process and add bind directives for ports
- foreach($ports as $port) {
- if($port) {
- if($bind['extaddr'] == "any")
- $listenip .= "\tbind\t\t\t0.0.0.0:{$port} {$ssl_info} {$advanced_bind}\n";
- elseif($bind['extaddr'])
- $listenip .= "\tbind\t\t\t{$bind['extaddr']}:{$port} {$ssl_info} {$advanced_bind}\n";
- else
- $listenip .= "\tbind\t\t\t" . get_current_wan_address('wan') . ":{$port} {$ssl_info} {$advanced_bind}\n";
+ $ip = haproxy_interface_ip($bind['extaddr']);
+ if ($ip){
+ foreach($ports as $port) {
+ if($port) {
+ $listenip .= "\tbind\t\t\t$ip:{$port} {$ssl_info} {$advanced_bind}\n";
+ }
}
}
@@ -1039,16 +1045,11 @@ function get_primaryfrontend($frontend) {
return $mainfrontend;
}
-function get_frontend_ipport($frontend) {
+function get_frontend_ipport($frontend,$userfriendly=false) {
$mainfrontend = get_primaryfrontend($frontend);
- if($mainfrontend['extaddr'] == "any")
- $result = "0.0.0.0";
- elseif ($mainfrontend['extaddr'] == "localhost")
- $result = "127.0.0.1";
- elseif($mainfrontend['extaddr'])
- $result = $mainfrontend['extaddr'];
- else
- $result = get_current_wan_address('wan');
+ $result = haproxy_interface_ip($mainfrontend['extaddr'],$userfriendly);
+ if ($userfriendly and is_ipaddrv6($result))
+ $result = "[{$result}]";
return $result . ":" . $mainfrontend['port'];
}
@@ -1099,7 +1100,7 @@ function get_haproxy_frontends($excludeitem="") {
return $result;
}
-function get_frontent_acls($frontend) {
+function get_frontend_acls($frontend) {
$result = array();
$a_acl = &$frontend['ha_acls']['item'];
if (is_array($a_acl))
@@ -1123,51 +1124,10 @@ function get_frontent_acls($frontend) {
return $result;
}
-function phparray_to_javascriptarray_recursive($nestID, $path, $items, $nodeName, $includeitems) {
- $offset = str_repeat(' ',$nestID);
- $itemName = "item$nestID";
- echo "{$offset}$nodeName = {};\n";
- if (is_array($items))
- foreach ($items as $key => $item)
- {
- if (in_array($path.'/'.$key, $includeitems))
- $subpath = $path.'/'.$key;
- else
- $subpath = $path.'/*';
- if (in_array($subpath, $includeitems) || in_array($path.'/*', $includeitems)) {
- if (is_array($item)) {
- $subNodeName = "item$nestID";
- phparray_to_javascriptarray_recursive($nestID+1, $subpath, $items[$key], $subNodeName, $includeitems);
- echo "{$offset}{$nodeName}['{$key}'] = $itemName;\n";
- } else
- echo "{$offset}{$nodeName}['$key'] = '$item';\n";
- }
- }
-}
-
-function phparray_to_javascriptarray($items, $javaMapName, $includeitems) {
- phparray_to_javascriptarray_recursive(1,'',$items, $javaMapName, $includeitems);
-}
-
function haproxy_escapestring($configurationsting) {
$result = str_replace('\\', '\\\\', $configurationsting);
$result = str_replace(' ', '\\ ', $result);
return str_replace('#', '\\#', $result);
}
-function echo_html_select($name, $keyvaluelist, $selected, $listEmptyMessage="", $onchangeEvent="") {
- if (count($keyvaluelist)>0){
- if ($onchangeEvent != "")
- $onchangeEvent .= " onchange=$onchangeEvent";
- echo "<select name=\"$name\" id=\"$name\" class=\"formselect\"$onchangeEvent>";
- foreach($keyvaluelist as $key => $desc){
- $selectedhtml = $key == $selected ? "selected" : "";
- echo "<option value=\"{$key}\" {$selectedhtml}>{$desc['name']}</option>";
- }
- echo "</select>";
- } else {
- echo $listEmptyMessage;
- }
-}
-
?>
diff --git a/config/haproxy-devel/haproxy.xml b/config/haproxy-devel/haproxy.xml
index bfd7f437..299d76c6 100644
--- a/config/haproxy-devel/haproxy.xml
+++ b/config/haproxy-devel/haproxy.xml
@@ -100,6 +100,11 @@
<item>http://www.pfsense.com/packages/config/haproxy-devel/haproxy_xmlrpcsyncclient.inc</item>
</additional_files_needed>
<additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>077</chmod>
+ <item>http://www.pfsense.com/packages/config/haproxy-devel/haproxy_utils.inc</item>
+ </additional_files_needed>
+ <additional_files_needed>
<prefix>/usr/local/www/widgets/widgets/</prefix>
<chmod>077</chmod>
<item>http://www.pfsense.com/packages/config/haproxy-devel/haproxy.widget.php</item>
diff --git a/config/haproxy-devel/haproxy_global.php b/config/haproxy-devel/haproxy_global.php
index ff8d1280..0ff0e10e 100755
--- a/config/haproxy-devel/haproxy_global.php
+++ b/config/haproxy-devel/haproxy_global.php
@@ -31,6 +31,7 @@
require_once("guiconfig.inc");
require_once("haproxy.inc");
+require_once("haproxy_utils.inc");
require_once("globals.inc");
if (!is_array($config['installedpackages']['haproxy']))
@@ -41,6 +42,9 @@ if ($_POST) {
unset($input_errors);
$pconfig = $_POST;
+ if ($_POST['calculate_certificate_chain']) {
+ haproxy_recalculate_certifcate_chain();
+ } else
if ($_POST['apply']) {
$result = haproxy_check_and_run($savemsg, true);
if ($result)
@@ -154,6 +158,20 @@ function enable_change(enable_change) {
<div id="mainarea">
<table class="tabcont" width="100%" border="0" cellpadding="6" cellspacing="0">
<tr>
+ <td colspan="2" valign="top" class="listtopic">Recalculate certificate chain.</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">&nbsp;</td>
+ <td width="78%" class="vtable">
+ <input type="hidden" name="calculate_certificate_chain" id="calculate_certificate_chain">
+ <input type="button" class="formbtn" value="Recalculate certificate chains" onclick="$('calculate_certificate_chain').value='true';document.iform.submit();">
+ <br/>
+ This can be required after certificates have been created or imported. As pfSense 2.1.0 currently does not
+ always keep track of these dependencies which might be required to create a proper certificate chain when using SSLoffloading.
+ </td>
+ </tr>
+
+ <tr>
<td colspan="2" valign="top" class="listtopic">General settings</td>
</tr>
<tr>
diff --git a/config/haproxy-devel/haproxy_listeners.php b/config/haproxy-devel/haproxy_listeners.php
index 6d9c9dc1..397cef5c 100644
--- a/config/haproxy-devel/haproxy_listeners.php
+++ b/config/haproxy-devel/haproxy_listeners.php
@@ -32,6 +32,7 @@
require_once("guiconfig.inc");
require_once("haproxy.inc");
require_once("certs.inc");
+require_once("haproxy_utils.inc");
if (!is_array($config['installedpackages']['haproxy']['ha_backends']['item'])) {
$config['installedpackages']['haproxy']['ha_backends']['item'] = array();
@@ -125,7 +126,7 @@ include("head.inc");
$a_frontend_grouped = array();
foreach($a_frontend as &$frontend2) {
- $ipport = get_frontend_ipport($frontend2);
+ $ipport = get_frontend_ipport($frontend2, true);
$frontend2['ipport'] = $ipport;
$a_frontend_grouped[$ipport][] = $frontend2;
}
@@ -156,7 +157,7 @@ include("head.inc");
echo '<img src="'.$img_cert.'" title="SSL offloading cert: '.$cert['descr'].'" alt="SSL offloading" border="0" height="16" width="16" />';
}
- $acls = get_frontent_acls($frontend);
+ $acls = get_frontend_acls($frontend);
$isaclset = "";
foreach ($acls as $acl) {
$isaclset .= "&#10;" . $acl['descr'];
@@ -179,7 +180,7 @@ include("head.inc");
<?=$frontend['desc'];?>
</td>
<td class="listlr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';">
- <?=$frontend['ipport'];?>
+ <?=str_replace(" ","&nbsp;",$frontend['ipport']);?>
</td>
<td class="listlr" ondblclick="document.location='haproxy_listeners_edit.php?id=<?=$frontendname;?>';">
<?=$frontend['type']?>
diff --git a/config/haproxy-devel/haproxy_listeners_edit.php b/config/haproxy-devel/haproxy_listeners_edit.php
index d37444c0..98fba74a 100644
--- a/config/haproxy-devel/haproxy_listeners_edit.php
+++ b/config/haproxy-devel/haproxy_listeners_edit.php
@@ -32,6 +32,7 @@
require("guiconfig.inc");
require_once("haproxy.inc");
+require_once("haproxy_utils.inc");
/* Compatibility function for pfSense 2.0 */
if (!function_exists("cert_get_purpose")) {
@@ -274,6 +275,9 @@ if (!$id)
$pgtitle = "HAProxy: Frontend: Edit";
include("head.inc");
+
+$primaryfrontends = get_haproxy_frontends($pconfig['name']);
+$interfaces = haproxy_get_bindable_interfaces();
?>
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
@@ -526,11 +530,16 @@ include("head.inc");
<option value="disabled"<?php if($pconfig['status'] == "disabled") echo " SELECTED"; ?>>Disabled</option>
</select>
</td>
- </tr>
+ </tr>
<tr align="left">
<td width="22%" valign="top" class="vncell">Shared Frontend</td>
<td width="78%" class="vtable" colspan="2">
+ <?if (count($primaryfrontends)==0){ ?>
+ <b>At least 1 primary frontend is needed.</b><br/><br/>
+ <? } else{ ?>
<input id="secondary" name="secondary" type="checkbox" value="yes" <?php if ($pconfig['secondary']=='yes') echo "checked"; ?> onclick="updatevisibility();"/>
+ <? } ?>
+ This can be used to host a second or more website on the same IP:Port combination.<br/>
Use this setting to configure multiple backends/accesslists for a single frontend.<br/>
All settings of which only 1 can exist will be hidden.<br/>
The frontend settings will be merged into 1 set of frontend configuration.
@@ -540,7 +549,6 @@ include("head.inc");
<td width="22%" valign="top" class="vncellreq">Primary frontend</td>
<td width="78%" class="vtable" colspan="2">
<?
- $primaryfrontends = get_haproxy_frontends($pconfig['name']);
echo_html_select('primary_frontend',$primaryfrontends, $pconfig['primary_frontend'],"You must first create a 'primary' frontend.","updatevisibility();");
?>
</td>
@@ -548,22 +556,9 @@ include("head.inc");
<tr class="haproxy_primary">
<td width="22%" valign="top" class="vncellreq">External address</td>
<td width="78%" class="vtable">
- <select name="extaddr" class="formfld">
- <option value="" <?php if (!$pconfig['extaddr']) echo "selected"; ?>>Interface address</option>
- <option value="localhost" <?php if ('localhost' == $pconfig['extaddr']) echo "selected"; ?>>Localhost</option>
- <?php
- if (is_array($config['virtualip']['vip'])):
- foreach ($config['virtualip']['vip'] as $sn):
- ?>
- <option value="<?=$sn['subnet'];?>" <?php if ($sn['subnet'] == $pconfig['extaddr']) echo "selected"; ?>>
- <?=htmlspecialchars("{$sn['subnet']} ({$sn['descr']})");?>
- </option>
- <?php
- endforeach;
- endif;
+ <?
+ echo_html_select('extaddr', $interfaces, $pconfig['extaddr']);
?>
- <option value="any" <?php if($pconfig['extaddr'] == "any") echo "selected"; ?>>any</option>
- </select>
<br />
<span class="vexpl">
If you want this rule to apply to another IP address than the IP address of the interface chosen above,
diff --git a/config/haproxy-devel/haproxy_pool_edit.php b/config/haproxy-devel/haproxy_pool_edit.php
index a7a56b1c..92f4177e 100644
--- a/config/haproxy-devel/haproxy_pool_edit.php
+++ b/config/haproxy-devel/haproxy_pool_edit.php
@@ -31,6 +31,7 @@
require("guiconfig.inc");
require_once("haproxy.inc");
+require_once("haproxy_utils.inc");
$d_haproxyconfdirty_path = $g['varrun_path'] . "/haproxy.conf.dirty";
@@ -137,7 +138,7 @@ if ($_POST) {
if (preg_match("/[^a-zA-Z0-9\.\-_]/", $server_name))
$input_errors[] = "The field 'Name' contains invalid characters.";
- if (preg_match("/[^a-zA-Z0-9\.\-_]/", $server_address))
+ if (!is_ipaddr($server_address))
$input_errors[] = "The field 'Address' contains invalid characters.";
if (!preg_match("/.{2,}/", $server_name))
@@ -350,7 +351,7 @@ foreach($simplefields as $field){
<td width="5%" class="listhdrr">Port</td>
<td width="5%" class="listhdrr">SSL</td>
<td width="8%" class="listhdrr">Weight</td>
- <td width="5%" class="listhdr">Backup</td>
+ <td width="5%" class="listhdrr">Mode</td>
<td width="15%" class="listhdr">Advanced</td>
<td width="4%" class=""></td>
</tr>
@@ -534,10 +535,7 @@ foreach($simplefields as $field){
NOTE: paste text into this box that you would like to pass thru. Applied to the backend section.
</td>
</tr>
-
- </table>
- <br/>
- <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr><td>&nbsp;</td></tr>
<tr>
<td colspan="2" valign="top" class="listtopic">Health checking</td>
</tr>
@@ -611,9 +609,7 @@ FLUSH PRIVILEGES;</pre>
Fill in the TCP portnumber the healthcheck should be performed on.
</td>
</tr>
- </table>
- <br/>
- <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr><td>&nbsp;</td></tr>
<tr>
<td colspan="2" valign="top" class="listtopic">Advanced settings</td>
</tr>
@@ -641,9 +637,7 @@ want the clients to see the failures. The number of attempts to reconnect is
set by the 'retries' parameter.</div>
</td>
</tr>
- </table>
- <br/>&nbsp;<br/>
- <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr><td>&nbsp;</td></tr>
<tr>
<td colspan="2" valign="top" class="listtopic">Statistics</td>
</tr>
@@ -719,8 +713,7 @@ set by the 'retries' parameter.</div>
Specify the refresh rate of the stats page in seconds, or specified time unit (us, ms, s, m, h, d).
</td>
</tr>
- </table>
- <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr><td>&nbsp;</td></tr>
<tr align="left">
<td width="22%" valign="top">&nbsp;</td>
<td width="78%">
diff --git a/config/haproxy-devel/haproxy_utils.inc b/config/haproxy-devel/haproxy_utils.inc
new file mode 100644
index 00000000..940c816f
--- /dev/null
+++ b/config/haproxy-devel/haproxy_utils.inc
@@ -0,0 +1,267 @@
+<?php
+/*
+ haproxy_utils.php
+ part of pfSense (http://www.pfsense.com/)
+ Copyright (C) 2013 PiBa-NL
+ 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.
+
+ THIS SOFTWARE IS PROVIDED ``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
+ AUTHOR BE LIABLE FOR ANY DIRECT, 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 file contains functions which are NOT specific to HAProxy and may/could/should
+ be moved to the general pfSense php library for possible easy use by other parts of pfSense
+*/
+
+require_once("config.inc");
+
+function haproxy_interface_ip($interfacebindname,$userfriendly=false){
+ $list = haproxy_get_bindable_interfaces();
+ $item = $list[$interfacebindname];
+ $result = $item['ip'];
+ if ($userfriendly && !$result)
+ $result = $item['name'];
+ return $result;
+}
+function haproxy_get_bindable_interfaces($ipv="ipv4,ipv6", $interfacetype="any,localhost,real,carp,ipalias"){
+ // returns a list of ALL interface/IPs that can be used to bind a service to.
+ // filtered by the conditions given in the two filter parameters.
+ // result array includes:
+ // $bindable[key] can be stored and compared with previous setings
+ // $bindable[key]['ip'] the current IP (possibly changes for dhcp enabled interfaces..)
+ // $bindable[key]['description'] can be shown to user in a selection box
+
+ global $config;
+ $ipverions = split(',',$ipv);
+ $interfacetypes= split(',',$interfacetype);
+
+ $bindable = array();
+ if (in_array("ipv4",$ipverions)){
+ if (in_array('any',$interfacetypes)){
+ $item = array();
+ $item[ip] = '0.0.0.0';
+ $item[name] = 'any (IPv4)';
+ $bindable['any_ipv4'] = $item;
+ }
+ if (in_array('localhost',$interfacetypes)){
+ $item = array();
+ $item[ip] = '127.0.0.1';
+ $item[name] = 'localhost (IPv4)';
+ $bindable['localhost_ipv4'] = $item;
+ }
+ if (in_array('real',$interfacetypes)){
+ foreach($config['interfaces'] as $if => $ifdetail) {
+ if (!isset($ifdetail['enable']))
+ continue;
+ if (!isset($ifdetail['ipaddr']))
+ continue;
+ $item = array();
+ $item[ip] = get_interface_ip($if);
+ $item[name] = $ifdetail['descr'].' address (IPv4)';
+ $bindable[$if.'_ipv4'] = $item;
+ }
+ }
+ if (in_array('carp',$interfacetypes)){
+ $carplist = get_configured_carp_interface_list();
+ foreach ($carplist as $carpif => $carpip){
+ if (is_ipaddrv4($carpip)){
+ $item = array();
+ $item['ip'] = $carpip;
+ $item['name'] = $carpip." (".get_vip_descr($carpip).")";
+ $bindable[$carpip] = $item;
+ }
+ }
+
+ }
+ if (in_array('ipalias',$interfacetypes)){
+ $aliaslist = get_configured_ip_aliases_list();
+ foreach ($aliaslist as $aliasip => $aliasif){
+ if (is_ipaddrv4($aliasip)){
+ $item = array();
+ $item['ip'] = $aliasip;
+ $item['name'] = $aliasip." (".get_vip_descr($aliasip).")";
+ $bindable[$aliasip.'_ipv4'] = $item;
+ }
+ }
+ }
+ }
+ if (in_array("ipv6",$ipverions)){
+ if (in_array('any',$interfacetypes)){
+ $item = array();
+ $item[ip] = '::';
+ $item[name] = 'any (IPv6)';
+ $bindable['any_ipv6'] = $item;
+ }
+ if (in_array('localhost',$interfacetypes)){
+ $item = array();
+ $item[ip] = '::1';
+ $item[name] = 'localhost (IPv6)';
+ $bindable['localhost_ipv6'] = $item;
+ }
+ if (in_array('real',$interfacetypes)){
+ foreach($config['interfaces'] as $if => $ifdetail) {
+ if (!isset($ifdetail['enable']))
+ continue;
+ if (!isset($ifdetail['ipaddrv6']))
+ continue;
+ $item = array();
+ $item[ip] = get_interface_ipv6($if);
+ $item[name] = $ifdetail['descr'].' address (IPv6)';
+ $bindable[$if.'_ipv6'] = $item;
+ }
+ }
+ if (in_array('carp',$interfacetypes)){
+ $carplist = get_configured_carp_interface_list();
+ foreach ($carplist as $carpif => $carpip){
+ if (is_ipaddrv6($carpip)){
+ $item = array();
+ $item['ip'] = $carpip;
+ $item['name'] = $carpip." (".get_vip_descr($carpip).")";
+ $bindable[$carpip] = $item;
+ }
+ }
+
+ }
+ if (in_array('ipalias',$interfacetypes)){
+ $aliaslist = get_configured_ip_aliases_list();
+ foreach ($aliaslist as $aliasip => $aliasif){
+ if (is_ipaddrv6($aliasip)){
+ $item = array();
+ $item['ip'] = $aliasip;
+ $item['name'] = $aliasip." (".get_vip_descr($aliasip).")";
+ $bindable[$aliasip] = $item;
+ }
+ }
+ }
+ }
+ return $bindable;
+}
+
+function haproxy_get_cert_extensions($crt){
+ $cert = openssl_x509_parse(base64_decode($crt['crt']));
+ return $cert['extensions'];
+}
+
+function haproxy_get_cert_authoritykeyidentifier($cert)
+{
+ $certextension = haproxy_get_cert_extensions($cert);
+ $lines = preg_split('/[\n]+/',$certextension['authorityKeyIdentifier']);
+ return substr($lines[0],6);// cut off the starting string 'keyid:'
+}
+function haproxy_get_cert_subjectKeyIdentifier($cert)
+{
+ $certextension = haproxy_get_cert_extensions($cert);
+ $lines = preg_split('/[\n]+/',$certextension['subjectKeyIdentifier']);
+ return $lines[0];
+}
+
+function haproxy_cert_signed_by($cert, $signedbycert) {
+ // checks if $cert was signed by $signedbycert
+ // this does NOT validate a proper signature but only checks if the extension properties match.
+ $authoritykeyid = haproxy_get_cert_authoritykeyidentifier($cert);
+ $subjectid = haproxy_get_cert_subjectKeyIdentifier($signedbycert);
+ return $authoritykeyid == $subjectid;
+}
+
+function haproxy_get_certificates(){
+ global $config;
+ $allcerts = array();
+ foreach($config['cert'] as &$cert)
+ $allcerts[] = &$cert;
+ foreach($config['ca'] as &$cert)
+ $allcerts[] = &$cert;
+ return $allcerts;
+}
+function haproxy_recalculate_certifcate_chain(){
+ // and set "selfsigned" for certificates that where used to sign themselves
+ // recalculate the "caref" for all certificates where it is currently unkown.
+
+ $allcertificates = haproxy_get_certificates();
+ $items_recalculated = 0;
+ foreach($allcertificates as &$cert){
+ $recalculate=false;
+ if (!isset($cert['selfsigned'])){
+ if (!isset($cert['caref']))
+ $recalculate=true;
+ else {
+ $ca = lookup_ca($cert['caref']);
+ if (!$ca)
+ $recalculate=true;
+ }
+ }
+ if ($recalculate){
+ foreach($allcertificates as &$signedbycert){
+ if(haproxy_cert_signed_by($cert, $signedbycert)){
+ if ($cert['refid'] == $signedbycert['refid']){
+ $cert['selfsigned'] = true;
+ } else {
+ $cert['caref'] = $signedbycert['refid'];
+ }
+ $items_recalculated++;
+ }
+ }
+ }
+ }
+ if ($items_recalculated > 0)
+ write_config("Recalculated $items_recalculated certificate chains.");
+}
+
+function phparray_to_javascriptarray_recursive($nestID, $path, $items, $nodeName, $includeitems) {
+ $offset = str_repeat(' ',$nestID);
+ $itemName = "item$nestID";
+ echo "{$offset}$nodeName = {};\n";
+ if (is_array($items))
+ foreach ($items as $key => $item)
+ {
+ if (in_array($path.'/'.$key, $includeitems))
+ $subpath = $path.'/'.$key;
+ else
+ $subpath = $path.'/*';
+ if (in_array($subpath, $includeitems) || in_array($path.'/*', $includeitems)) {
+ if (is_array($item)) {
+ $subNodeName = "item$nestID";
+ phparray_to_javascriptarray_recursive($nestID+1, $subpath, $items[$key], $subNodeName, $includeitems);
+ echo "{$offset}{$nodeName}['{$key}'] = $itemName;\n";
+ } else
+ echo "{$offset}{$nodeName}['$key'] = '$item';\n";
+ }
+ }
+}
+function phparray_to_javascriptarray($items, $javaMapName, $includeitems) {
+ phparray_to_javascriptarray_recursive(1,'',$items, $javaMapName, $includeitems);
+}
+
+function echo_html_select($name, $keyvaluelist, $selected, $listEmptyMessage="", $onchangeEvent="") {
+ if (count($keyvaluelist)>0){
+ if ($onchangeEvent != "")
+ $onchangeEvent .= " onchange=$onchangeEvent";
+ echo "<select name=\"$name\" id=\"$name\" class=\"formselect\"$onchangeEvent>";
+ foreach($keyvaluelist as $key => $desc){
+ $selectedhtml = $key == $selected ? "selected" : "";
+ echo "<option value=\"{$key}\" {$selectedhtml}>{$desc['name']}</option>";
+ }
+ echo "</select>";
+ } else {
+ echo $listEmptyMessage;
+ }
+}
+
+?> \ No newline at end of file