diff options
author | bmeeks8 <bmeeks8@bellsouth.net> | 2014-01-07 20:22:00 -0500 |
---|---|---|
committer | bmeeks8 <bmeeks8@bellsouth.net> | 2014-01-07 20:22:00 -0500 |
commit | a8b5c4c392069ab4c06c19d53d4dccf8c423a9ef (patch) | |
tree | 7fdb7130a804f0191c22bababa62c44e2b88fb50 /config/haproxy-devel | |
parent | 7234111aaac38d620a4e5356d212fa51e2591d8b (diff) | |
parent | b1962cf93379b0f9f3dfbfa69cd67f19af7c1539 (diff) | |
download | pfsense-packages-a8b5c4c392069ab4c06c19d53d4dccf8c423a9ef.tar.gz pfsense-packages-a8b5c4c392069ab4c06c19d53d4dccf8c423a9ef.tar.bz2 pfsense-packages-a8b5c4c392069ab4c06c19d53d4dccf8c423a9ef.zip |
Merge remote-tracking branch 'upstream/master'
Diffstat (limited to 'config/haproxy-devel')
-rw-r--r-- | config/haproxy-devel/haproxy.inc | 231 | ||||
-rw-r--r-- | config/haproxy-devel/haproxy.widget.php | 1 | ||||
-rw-r--r-- | config/haproxy-devel/haproxy.xml | 5 | ||||
-rwxr-xr-x | config/haproxy-devel/haproxy_global.php | 73 | ||||
-rw-r--r-- | config/haproxy-devel/haproxy_htmllist.inc | 246 | ||||
-rw-r--r-- | config/haproxy-devel/haproxy_listeners.php | 44 | ||||
-rw-r--r-- | config/haproxy-devel/haproxy_listeners_edit.php | 472 | ||||
-rw-r--r-- | config/haproxy-devel/haproxy_pool_edit.php | 500 | ||||
-rw-r--r-- | config/haproxy-devel/haproxy_pools.php | 17 | ||||
-rw-r--r-- | config/haproxy-devel/haproxy_socketinfo.inc | 1 | ||||
-rw-r--r-- | config/haproxy-devel/haproxy_utils.inc | 141 | ||||
-rw-r--r-- | config/haproxy-devel/haproxy_xmlrpcsyncclient.inc | 1 |
12 files changed, 903 insertions, 829 deletions
diff --git a/config/haproxy-devel/haproxy.inc b/config/haproxy-devel/haproxy.inc index f768ef01..5e798dc2 100644 --- a/config/haproxy-devel/haproxy.inc +++ b/config/haproxy-devel/haproxy.inc @@ -1,6 +1,7 @@ <?php /* haproxy.inc + Copyright (C) 2013 PiBa-NL Copyright (C) 2009 Scott Ullrich <sullrich@pfsense.com> Copyright (C) 2008 Remco Hoef All rights reserved. @@ -37,43 +38,45 @@ require_once("haproxy_xmlrpcsyncclient.inc"); $d_haproxyconfdirty_path = $g['varrun_path'] . "/haproxy.conf.dirty"; $a_acltypes = array(); -$a_acltypes[] = array('name' => 'host_starts_with', 'descr' => 'Host starts with', +$a_acltypes["host_starts_with"] = array('name' => 'Host starts with', 'mode' => 'http', 'syntax' => 'hdr_beg(host) -i %1$s'); -$a_acltypes[] = array('name' => 'host_ends_with', 'descr' => 'Host ends with', +$a_acltypes["host_ends_with"] = array('name' => 'Host ends with', 'mode' =>'http', 'syntax' => 'hdr_end(host) -i %1$s'); -$a_acltypes[] = array('name' => 'host_matches', 'descr' => 'Host matches', +$a_acltypes["host_matches"] = array('name' => 'Host matches', 'mode' =>'http', 'syntax' => 'hdr(host) -i %1$s'); -$a_acltypes[] = array('name' => 'host_regex', 'descr' => 'Host regex', +$a_acltypes["host_regex"] = array('name' => 'Host regex', 'mode' =>'http', 'syntax' => 'hdr_reg(host) -i %1$s'); -$a_acltypes[] = array('name' => 'host_contains', 'descr' => 'Host contains', +$a_acltypes["host_contains"] = array('name' => 'Host contains', 'mode' => 'http', 'syntax' => 'hdr_dir(host) -i %1$s'); -$a_acltypes[] = array('name' => 'path_starts_with', 'descr' => 'Path starts with', +$a_acltypes["path_starts_with"] = array('name' => 'Path starts with', 'mode' => 'http', 'syntax' => 'path_beg -i %1$s'); -$a_acltypes[] = array('name' => 'path_ends_with', 'descr' => 'Path ends with', +$a_acltypes["path_ends_with"] = array('name' => 'Path ends with', 'mode' => 'http', 'syntax' => 'path_end -i %1$s'); -$a_acltypes[] = array('name' => 'path_matches', 'descr' => 'Path matches', +$a_acltypes["path_matches"] = array('name' => 'Path matches', 'mode' => 'http', 'syntax' => 'path -i %1$s'); -$a_acltypes[] = array('name' => 'path_regex', 'descr' => 'Path regex', +$a_acltypes["path_regex"] = array('name' => 'Path regex', 'mode' => 'http', 'syntax' => 'path_reg -i %1$s'); -$a_acltypes[] = array('name' => 'path_contains', 'descr' => 'Path contains', +$a_acltypes["path_contains"] = array('name' => 'Path contains', 'mode' => 'http', 'syntax' => 'path_dir -i %1$s'); -$a_acltypes[] = array('name' => 'source_ip', 'descr' => 'Source IP', +$a_acltypes["source_ip"] = array('name' => 'Source IP', 'mode' => '', 'syntax' => 'src %1$s'); -$a_acltypes[] = array('name' => 'backendservercount', 'descr' => 'Minimum count usable servers', +$a_acltypes["backendservercount"] = array('name' => 'Minimum count usable servers', 'mode' => '', 'syntax' => 'nbsrv(%2$s) ge %1$d', 'parameters' => 'value,backendname'); // 'ssl_sni_matches' was added in HAProxy1.5dev17 -$a_acltypes[] = array('name' => 'ssl_sni_matches', 'descr' => 'Server Name Indication TLS extension matches', +$a_acltypes["ssl_sni_matches"] = array('name' => 'Server Name Indication TLS extension matches', 'mode' => 'https', 'syntax' => 'req_ssl_sni -i %1$s', 'advancedoptions' => "tcp-request inspect-delay 5s\n\ttcp-request content accept if { req_ssl_hello_type 1 }"); +$a_checktypes = array(); $a_checktypes['none'] = array('name' => 'none', 'syntax' => '', 'descr' => 'No health checks will be performed.'); $a_checktypes['Basic'] = array('name' => 'Basic', 'syntax' => '', 'descr' => 'Basic socket connection check'); $a_checktypes['HTTP'] = array('name' => 'HTTP', 'syntax' => 'httpchk', 'descr' => 'HTTP protocol to check on the servers health, can also be used for HTTPS servers(requirs checking the SSL box for the servers).', 'parameters' => "uri,method,version"); -// 'Agent' was added in HAProxy1.5dev18 +// 'Agent' was added in HAProxy1.5dev18, and removed in 1.5dev20, in favor of the seperate agent-check option. $a_checktypes['Agent'] = array('name' => 'Agent', 'syntax' => 'lb-agent-chk', 'usedifferenport' => 'yes', - 'descr' => 'Use a TCP connection to read an ASCII string of the form 100%,75%,drain,down (others in haproxy manual)'); + 'descr' => 'Use a TCP connection to read an ASCII string of the form 100%,75%,drain,down (others in haproxy manual)', + deprecated => true); $a_checktypes['LDAP'] = array('name' => 'LDAP', 'syntax' => 'ldap-check', 'descr' => 'Use LDAPv3 health checks for server testing'); $a_checktypes['MySQL'] = array('name' => 'MySQL', 'syntax' => 'mysql-check', @@ -89,6 +92,7 @@ $a_checktypes['ESMTP'] = array('name' => 'ESMTP', 'syntax' => 'smtpchk EHLO', $a_checktypes['SSL'] = array('name' => 'SSL', 'syntax' => 'ssl-hello-chk', 'descr' => 'Use SSLv3 client hello health checks for server testing.'); +$a_httpcheck_method = array(); $a_httpcheck_method['OPTIONS'] = array('name' => 'OPTIONS', 'syntax' => 'OPTIONS'); $a_httpcheck_method['HEAD'] = array('name' => 'HEAD', 'syntax' => 'HEAD'); $a_httpcheck_method['GET'] = array('name' => 'GET', 'syntax' => 'GET'); @@ -97,6 +101,7 @@ $a_httpcheck_method['PUT'] = array('name' => 'PUT', 'syntax' => 'PUT'); $a_httpcheck_method['DELETE'] = array('name' => 'DELETE', 'syntax' => 'DELETE'); $a_httpcheck_method['TRACE'] = array('name' => 'TRACE', 'syntax' => 'TRACE'); +$a_closetypes = array(); $a_closetypes['none'] = array('name' => 'none', 'syntax' => '', 'descr' => 'No close headers will be changed.'); $a_closetypes['httpclose'] = array('name' => 'httpclose', 'syntax' => 'httpclose', @@ -105,6 +110,14 @@ $a_closetypes['http-server-close'] = array('name' => 'http-server-close', 'synta 'descr' => 'By default, when a client communicates with a server, HAProxy will only analyze, log, and process the first request of each connection. Setting "option http-server-close" enables HTTP connection-close mode on the server side while keeping the ability to support HTTP keep-alive and pipelining on the client side. This provides the lowest latency on the client side (slow network) and the fastest session reuse on the server side to save server resources.'); $a_closetypes['forceclose'] = array('name' => 'forceclose', 'syntax' => 'forceclose', 'descr' => 'Some HTTP servers do not necessarily close the connections when they receive the "Connection: close" set by "option httpclose", and if the client does not close either, then the connection remains open till the timeout expires. This causes high number of simultaneous connections on the servers and shows high global session times in the logs. Note that this option also enables the parsing of the full request and response, which means we can close the connection to the server very quickly, releasing some resources earlier than with httpclose.'); +$a_closetypes['http-keep-alive'] = array('name' => 'http-keep-alive', 'syntax' => 'http-keep-alive', + 'descr' => 'By default, when a client communicates with a server, HAProxy will only analyze, log, and process the first request of each connection. Setting "option http-keep-alive" enables HTTP keep-alive mode on the client- and server- sides. This provides the lowest latency on the client side (slow network) and the fastest session reuse on the server side at the expense of maintaining idle connections to the servers. In general, it is possible with this option to achieve approximately twice the request rate that the "http-server-close" option achieves on small objects. There are mainly two situations where this option may be useful : - when the server is non-HTTP compliant and authenticates the connection instead of requests (eg: NTLM authentication) - when the cost of establishing the connection to the server is significant compared to the cost of retrieving the associated object from the server.'); + +$a_servermodes = array(); +$a_servermodes["active"]['name'] = "active"; +$a_servermodes["backup"]['name'] = "backup"; +$a_servermodes["disabled"]['name'] = "disabled"; +$a_servermodes["inactive"]['name'] = "inactive"; function haproxy_custom_php_deinstall_command() { exec("cd /var/db/pkg && pkg_delete `ls | grep haproxy`"); @@ -120,6 +133,12 @@ function haproxy_custom_php_install_command() { global $g, $config; conf_mount_rw(); + $freebsd_version = substr(trim(`uname -r`), 0, 1); + if(!file_exists("/usr/bin/limits")) { + exec("fetch -q -o /usr/bin/limits http://files.pfsense.org/extras/{$freebsd_version}/limits"); + exec("chmod a+rx /usr/bin/limits"); + } + $haproxy = <<<EOD #!/bin/sh @@ -299,7 +318,7 @@ EOD; write_config("haproxy, update xml config version"); conf_mount_ro(); - + exec("/usr/local/etc/rc.d/haproxy.sh start"); } @@ -351,8 +370,8 @@ function haproxy_install_cron($should_install) { function haproxy_find_acl($name) { global $a_acltypes; if($a_acltypes) { - foreach ($a_acltypes as $acl) { - if ($acl['name'] == $name) + foreach ($a_acltypes as $key => $acl) { + if ($key == $name) return $acl; } } @@ -486,6 +505,10 @@ function write_backend($fd, $name, $pool, $frontend) { else $checkinter = "check inter 1000"; } + + //agent-check requires at least haproxy v1.5dev20 + if ($pool['agent_check']) + $agentcheck = " agent-check agent-inter {$pool['agent_inter']} agent-port {$pool['agent_port']}"; if (is_array($a_servers)) { @@ -505,7 +528,7 @@ function write_backend($fd, $name, $pool, $frontend) { { $ssl = $backend_type == "http" ? ' ssl' : ' check-ssl'; } - fwrite ($fd, "\tserver\t\t\t" . $be['name'] . " " . $be['address'].":" . $be['port'] . "$ssl $cookie $checkinter$checkport $isbackup weight " . $be['weight'] . "{$advanced_txt} {$be['advanced']}\n"); + fwrite ($fd, "\tserver\t\t\t" . $be['name'] . " " . $be['address'].":" . $be['port'] . "$ssl $cookie $checkinter$checkport$agentcheck $isbackup weight " . $be['weight'] . "{$advanced_txt} {$be['advanced']}\n"); } } fwrite ($fd, "\n"); @@ -514,15 +537,16 @@ function write_backend($fd, $name, $pool, $frontend) { function haproxy_configure() { global $g; // reload haproxy - haproxy_writeconf("{$g['varetc_path']}/haproxy.cfg"); + haproxy_writeconf("{$g['varetc_path']}/haproxy"); return haproxy_check_run(1); } function haproxy_check_and_run(&$messages, $reload) { global $g; - $configname = "{$g['varetc_path']}/haproxy.cfg"; - haproxy_writeconf("$configname.new"); - $retval = exec("haproxy -c -V -f $configname.new 2>&1", $output, $err); + $configpath = "{$g['varetc_path']}/haproxy"; + $testpath = "{$g['varetc_path']}/haproxy_test"; + haproxy_writeconf($testpath); + $retval = exec("haproxy -c -V -f $testpath/haproxy.cfg 2>&1", $output, $err); $messages = ""; if ($err > 1) $messages = "<h2><strong>FATAL ERROR CODE: $err while starting haproxy</strong></h2>"; @@ -537,25 +561,46 @@ function haproxy_check_and_run(&$messages, $reload) { $ok = strstr($retval, "Configuration file is valid"); if ($ok && $reload) { global $haproxy_run_message; - exec("mv $configname.new $configname"); + haproxy_writeconf($configpath); + rmdir_recursive($testpath); $ok = haproxy_check_run(1) == 0; $messages = $haproxy_run_message; } return $ok; } +function haproxy_write_certificate_file($filename, $certid) { + $cert = lookup_cert($certid); + + $certcontent = base64_decode($cert['crt']); + $certcontent .= "\r\n".base64_decode($cert['prv']); + + $certchaincontent = ca_chain($cert); + if ($certchaincontent != "") { + $certcontent .= "\r\n" . $certchaincontent; + } + unset($certchaincontent); + file_put_contents($filename, $certcontent); + unset($certcontent); + unset($cert); +} -function haproxy_writeconf($configfile) { +function haproxy_writeconf($configpath) { global $config; - $a_global = &$config['installedpackages']['haproxy']; - $a_backends = &$config['installedpackages']['haproxy']['ha_backends']['item']; - $a_pools = &$config['installedpackages']['haproxy']['ha_pools']['item']; + $configfile = $configpath . "/haproxy.cfg"; + rmdir_recursive($configpath); + make_dirs($configpath); + + $a_global = &$config['installedpackages']['haproxy']; + $a_frontends = &$config['installedpackages']['haproxy']['ha_backends']['item']; + $a_backends = &$config['installedpackages']['haproxy']['ha_pools']['item']; + $fd = fopen($configfile, "w"); - if(is_array($a_global)) { fwrite ($fd, "global\n"); - fwrite ($fd, "\tmaxconn\t\t\t".$a_global['maxconn']."\n"); + if ($a_global['maxconn']) + fwrite ($fd, "\tmaxconn\t\t\t".$a_global['maxconn']."\n"); if($a_global['remotesyslog']) fwrite ($fd, "\tlog\t\t\t{$a_global['remotesyslog']}\t{$a_global['logfacility']}\t{$a_global['loglevel']}\n"); fwrite ($fd, "\tstats socket /tmp/haproxy.socket level admin\n"); @@ -586,46 +631,48 @@ function haproxy_writeconf($configfile) { // Try and get a unique array for address:port as frontends can duplicate $a_bind = array(); - if(is_array($a_backends)) { - foreach ($a_backends as $backend) { - if($backend['status'] != 'active') + if(is_array($a_frontends)) { + foreach ($a_frontends as $frontend) { + if($frontend['status'] != 'active') { - unlink_if_exists("var/etc/{$backend['name']}.{$backend['port']}.crt"); + unlink_if_exists("var/etc/{$frontend['name']}.{$frontend['port']}.crt"); continue; } - if(!$backend['backend_serverpool']) + if(!$frontend['backend_serverpool']) { - unlink_if_exists("var/etc/{$backend['name']}.{$backend['port']}.crt"); + unlink_if_exists("var/etc/{$frontend['name']}.{$frontend['port']}.crt"); continue; } + + $bname = get_frontend_ipport($frontend); //check ssl info - if (strtolower($backend['type']) == "http" && $backend['ssloffload']){ + if (strtolower($frontend['type']) == "http" && $frontend['ssloffload']){ //ssl crt ./server.pem ca-file ./ca.crt verify optional crt-ignore-err all crl-file ./ca_crl.pem - $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; + $filename = "$configpath/{$frontend['name']}.{$frontend['port']}.pem"; + $ssl_crt = " crt $filename"; + haproxy_write_certificate_file($filename, $frontend['ssloffloadcert']); + $subfolder = "$configpath/{$frontend['name']}.{$frontend['port']}"; + $certs = $frontend['ha_certificates']['item']; + if (is_array($certs)){ + if (count($certs) > 0){ + make_dirs($subfolder); + foreach($certs as $cert){ + haproxy_write_certificate_file("$subfolder/{$cert['ssl_certificate']}.pem", $cert['ssl_certificate']); + } + $ssl_crt .= " crt $subfolder"; + } } - unset($certchaincontent); - - file_put_contents("/var/etc/{$backend['name']}.{$backend['port']}.crt", $certcontent); - unset($certcontent); }else{ $ssl_crt=""; - unlink_if_exists("var/etc/{$backend['name']}.{$backend['port']}.crt"); + unlink_if_exists("var/etc/{$frontend['name']}.{$frontend['port']}.crt"); } - - $bname = get_frontend_ipport($backend); if (!is_array($a_bind[$bname])) { $a_bind[$bname] = array(); $a_bind[$bname]['config'] = array(); // Settings which are used only from the primary frontend - $primaryfrontend = get_primaryfrontend($backend); + $primaryfrontend = get_primaryfrontend($frontend); $a_bind[$bname]['name'] = $primaryfrontend['name']; $a_bind[$bname]['extaddr'] = $primaryfrontend['extaddr']; $a_bind[$bname]['port'] = $primaryfrontend['port']; @@ -640,19 +687,19 @@ function haproxy_writeconf($configfile) { } $b = &$a_bind[$bname]; - if (($backend['secondary'] != 'yes') && ($backend['name'] != $b['name'])) { + if (($frontend['secondary'] != 'yes') && ($frontend['name'] != $b['name'])) { // only 1 frontend can be the primary for a set of frontends that share 1 address:port. $input_errors[] = "Multiple primary frondends for $bname"; } if ($ssl_crt != "") { if ($b['ssl_info'] == "") - $b['ssl_info'] = "ssl {$backend['dcertadv']}"; + $b['ssl_info'] = "ssl {$frontend['dcertadv']}"; $b['ssl_info'] .= $ssl_crt; } - // pointer to each backend - $b['config'][] = $backend; + // pointer to each frontend + $b['config'][] = $frontend; } } @@ -736,32 +783,51 @@ function haproxy_writeconf($configfile) { // Combine the rest of the frontend configs $default_backend = ""; $i = 0; - foreach ($bind['config'] as $bconfig) { - $a_acl=&$bconfig['ha_acls']['item']; + foreach ($bind['config'] as $frontend) { + $a_acl=&$frontend['ha_acls']['item']; if(!is_array($a_acl)) $a_acl=array(); - $poolname = $bconfig['backend_serverpool'] . "_" . strtolower($bconfig['type']); + $poolname = $frontend['backend_serverpool'] . "_" . strtolower($frontend['type']); // Create different pools if the svrport is set - if ($bconfig['svrport'] > 0) - $poolname .= "_" . $bconfig['svrport']; - - // Write this out once, and must be before any backend config text - if ($default_backend == "" || $bconfig['secondary'] != 'yes') { - $default_backend = $poolname; - } + if ($frontend['svrport'] > 0) + $poolname .= "_" . $frontend['svrport']; if (!isset($a_pendingpl[$poolname])) { $a_pendingpl[$poolname] = array(); $a_pendingpl[$poolname]['name'] = $poolname; - $a_pendingpl[$poolname]['frontend'] = $bconfig; + $a_pendingpl[$poolname]['frontend'] = $frontend; } - if (strtolower($bind['type']) == "http" && $bconfig['ssloffload'] && $bconfig['ssloffloadacl']) { + if (strtolower($bind['type']) == "http" && $frontend['ssloffload']) { $aclname = "SNI_" . $poolname; - $cert_cn = cert_get_cn($bconfig['ssloffloadcert'] ,true); - $a_acl[] = array('name' => $aclname,'expression' => 'host_matches', 'value' => $cert_cn); + if ($frontend['ssloffloadacl']){ + $cert = lookup_cert($frontend['ssloffloadcert']); + $cert_cn = cert_get_cn($cert['crt']); + $descr = haproxy_escape_acl_name($cert['descr']); + $a_acl[] = array('name' => "{$aclname}_{$descr}",'expression' => 'host_matches', 'value' => $cert_cn); + unset($cert); + } + if ($frontend['ssloffloadacladditional']){ + $certs = $frontend['ha_certificates']['item']; + if (is_array($certs)){ + if (count($certs) > 0){ + foreach($certs as $certref){ + $cert = lookup_cert($certref['ssl_certificate']); + $cert_cn = cert_get_cn($cert['crt']); + $descr = haproxy_escape_acl_name($cert['descr']); + $a_acl[] = array('name' => "{$aclname}_{$descr}",'expression' => 'host_matches', 'value' => $cert_cn); + unset($cert); + } + } + } + } + } + + // Write this out once, and must be before any backend config text + if (($default_backend == "" || $frontend['secondary'] != 'yes') && count($a_acl) == 0 ) { + $default_backend = $poolname; } // combine acl's with same name to allow for 'combined checks' to check for example hostname and fileextension together.. @@ -795,7 +861,8 @@ function haproxy_writeconf($configfile) { fwrite ($fd, "\tuse_backend\t\t" . $poolname . " if " . $aclnames . "\n"); } } - fwrite ($fd, "\tdefault_backend\t\t" . $default_backend . "\n"); + if ($default_backend) + fwrite ($fd, "\tdefault_backend\t\t" . $default_backend . "\n"); foreach($advancedextra as $extra) fwrite ($fd, "\t".$extra."\n"); @@ -803,9 +870,9 @@ function haproxy_writeconf($configfile) { } } // Construct and write out configuration for each "backend" - if (is_array($a_pendingpl) && is_array($a_pools)) { + if (is_array($a_pendingpl) && is_array($a_backends)) { foreach ($a_pendingpl as $pending) { - foreach ($a_pools as $pool) { + foreach ($a_backends as $pool) { if ($pending['frontend']['backend_serverpool'] == $pool['name']) { write_backend($fd, $pending['name'], $pool, $pending['frontend']); } @@ -832,12 +899,6 @@ function haproxy_writeconf($configfile) { haproxy_install_cron(true); else haproxy_install_cron(false); - - $freebsd_version = substr(trim(`uname -r`), 0, 1); - if(!file_exists("/usr/bin/limits")) { - exec("fetch -q -o /usr/bin/limits http://files.pfsense.org/extras/{$freebsd_version}/limits"); - exec("chmod a+rx /usr/bin/limits"); - } } function haproxy_is_running() { @@ -845,7 +906,6 @@ function haproxy_is_running() { return $running; } - function haproxy_load_modules() { // On FreeBSD 8 ipfw is needed to allow 'transparent' proxying (getting reply's to a non-local ip to pass back to the client-socket).. // On FreeBSD 9 it is probably possible to do the same with the pf option "divert-reply" @@ -932,6 +992,7 @@ function haproxy_check_run($reload) { global $config, $g, $haproxy_run_message; $a_global = &$config['installedpackages']['haproxy']; + $configpath = "{$g['varetc_path']}/haproxy"; exec("/usr/bin/limits -n 300014"); @@ -963,9 +1024,9 @@ function haproxy_check_run($reload) { $sf_st = "-st";//terminate old process as soon as the new process is listening else $sf_st = "-sf";//finish serving existing connections exit when done, and the new process is listening - exec("/usr/local/sbin/haproxy -f /var/etc/haproxy.cfg -p /var/run/haproxy.pid $sf_st `cat /var/run/haproxy.pid` 2>&1", $output, $errcode); + exec("/usr/local/sbin/haproxy -f {$configpath}/haproxy.cfg -p /var/run/haproxy.pid $sf_st `cat /var/run/haproxy.pid` 2>&1", $output, $errcode); } else { - exec("/usr/local/sbin/haproxy -f /var/etc/haproxy.cfg -p /var/run/haproxy.pid -D 2>&1", $output, $errcode); + exec("/usr/local/sbin/haproxy -f {$configpath}/haproxy.cfg -p /var/run/haproxy.pid -D 2>&1", $output, $errcode); } foreach($output as $line) $haproxy_run_message .= "<br/>" . htmlspecialchars($line) . "\n"; @@ -1127,7 +1188,7 @@ function get_frontend_acls($frontend) { continue; $acl_item = array(); - $acl_item['descr'] = $acl['descr'] . ": " . $entry['value']; + $acl_item['descr'] = $acl['name'] . ": " . $entry['value']; $acl_item['ref'] = $entry; $result[] = $acl_item; @@ -1153,4 +1214,8 @@ function haproxy_escapestring($configurationsting) { return str_replace('#', '\\#', $result); } +function haproxy_escape_acl_name($aclname) { + return preg_replace_callback('([^A-Za-z0-9\._\-\:])', function($match){return "_".dechex(ord($match[0]));}, $aclname); +} + ?> diff --git a/config/haproxy-devel/haproxy.widget.php b/config/haproxy-devel/haproxy.widget.php index abc5d935..7954e404 100644 --- a/config/haproxy-devel/haproxy.widget.php +++ b/config/haproxy-devel/haproxy.widget.php @@ -1,5 +1,6 @@ <?php /* + Copyright (C) 2013 PiBa-NL Copyright 2011 Thomas Schaefer - Tomschaefer.org Copyright 2011 Marcello Coutinho Part of pfSense widgets (www.pfsense.com) diff --git a/config/haproxy-devel/haproxy.xml b/config/haproxy-devel/haproxy.xml index 803bd978..6b25dd46 100644 --- a/config/haproxy-devel/haproxy.xml +++ b/config/haproxy-devel/haproxy.xml @@ -102,6 +102,11 @@ <additional_files_needed> <prefix>/usr/local/pkg/</prefix> <chmod>077</chmod> + <item>http://www.pfsense.com/packages/config/haproxy-devel/haproxy_htmllist.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> diff --git a/config/haproxy-devel/haproxy_global.php b/config/haproxy-devel/haproxy_global.php index bd1846e2..0a92cde7 100755 --- a/config/haproxy-devel/haproxy_global.php +++ b/config/haproxy-devel/haproxy_global.php @@ -3,6 +3,7 @@ /* haproxy_global.php part of pfSense (http://www.pfsense.com/) + Copyright (C) 2013 PiBa-NL Copyright (C) 2009 Scott Ullrich <sullrich@pfsense.com> Copyright (C) 2008 Remco Hoef <remcoverhoef@pfsense.com> All rights reserved. @@ -52,15 +53,15 @@ if ($_POST) { if ($result) unlink_if_exists($d_haproxyconfdirty_path); } else { - if ($_POST['enable']) { - $reqdfields = explode(" ", "maxconn"); - $reqdfieldsn = explode(",", "Maximum connections"); - } + //if ($_POST['enable']) { + // $reqdfields = explode(" ", "maxconn"); + // $reqdfieldsn = explode(",", "Maximum connections"); + //} if ($_POST['carpdev'] == "disabled") unset($_POST['carpdev']); - do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); + //do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors); if ($_POST['maxconn'] && (!is_numeric($_POST['maxconn']))) $input_errors[] = "The maximum number of connections should be numeric."; @@ -126,7 +127,7 @@ include("head.inc"); <script type="text/javascript" src="javascript/scriptaculous/prototype.js"></script> <script type="text/javascript" src="javascript/scriptaculous/scriptaculous.js"></script> <?php include("fbegin.inc"); ?> -<script language="JavaScript"> +<script type="text/javascript"> <!-- function enable_change(enable_change) { var endis; @@ -141,8 +142,8 @@ function enable_change(enable_change) { <form action="haproxy_global.php" method="post" name="iform"> <?php if ($input_errors) print_input_errors($input_errors); ?> <?php if ($savemsg) print_info_box($savemsg); ?> -<?php if (file_exists($d_haproxyconfdirty_path)): ?><p> -<?php print_info_box_np("The haproxy configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br> +<?php if (file_exists($d_haproxyconfdirty_path)): ?> +<?php print_info_box_np("The haproxy configuration has been changed.<br/>You must apply the changes in order for them to take effect.");?><br/> <?php endif; ?> <table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr><td class="tabnavtbl"> @@ -165,8 +166,8 @@ function enable_change(enable_change) { <tr> <td width="22%" valign="top" class="vncell"> </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();"> + <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. @@ -179,7 +180,7 @@ function enable_change(enable_change) { <tr> <td width="22%" valign="top" class="vncell"> </td> <td width="78%" class="vtable"> - <input name="enable" type="checkbox" value="yes" <?php if ($pconfig['enable']) echo "checked"; ?> onClick="enable_change(false)"> + <input name="enable" type="checkbox" value="yes" <?php if ($pconfig['enable']) echo "checked"; ?> onClick="enable_change(false)" /> <strong>Enable HAProxy</strong></td> </tr> <tr> @@ -191,7 +192,7 @@ function enable_change(enable_change) { <table cellpadding="0" cellspacing="0"> <tr> <td> - <input name="maxconn" type="text" class="formfld" id="maxconn" size="5" <?if ($pconfig['enable']!='yes') echo "enabled=\"false\"";?> value="<?=htmlspecialchars($pconfig['maxconn']);?>"> per Backend. + <input name="maxconn" type="text" class="formfld" id="maxconn" size="5" <?if ($pconfig['enable']!='yes') echo "enabled=\"false\"";?> value="<?=htmlspecialchars($pconfig['maxconn']);?>" /> per Backend. </td> </tr> </table> @@ -205,29 +206,29 @@ function enable_change(enable_change) { </td><td> <table style="border: 1px solid #000;"> <tr> - <td><font size=-1>Connections</td> - <td><font size=-1>Memory usage</td> + <td><font size=-1>Connections</font></td> + <td><font size=-1>Memory usage</font></td> </tr> <tr> <td colspan="2"> - <hr noshade style="border: 1px solid #000;"> + <hr noshade style="border: 1px solid #000;"></hr> </td> </tr> <tr> - <td align="right"><font size=-1>999</td> - <td><font size=-1>1888K</td> + <td align="right"><font size=-1>999</font></td> + <td><font size=-1>1888K</font></td> </tr> <tr> - <td align="right"><font size=-1>99999</td> - <td><font size=-1>8032K</td> + <td align="right"><font size=-1>99999</font></td> + <td><font size=-1>8032K</font></td> </tr> <tr> - <td align="right"><font size=-1>999999</td> - <td><font size=-1>50016K</td> + <td align="right"><font size=-1>999999</font></td> + <td><font size=-1>50016K</font></td> </tr> <tr> - <td align="right"><font size=-1>9999999</td> - <td><font size=-1>467M</td> + <td align="right"><font size=-1>9999999</font></td> + <td><font size=-1>467M</font></td> </tr> </table> </td></tr></table> @@ -238,17 +239,17 @@ function enable_change(enable_change) { Number of processes to start </td> <td class="vtable"> - <input name="nbproc" type="text" class="formfld" id="nbproc" size="18" value="<?=htmlspecialchars($pconfig['nbproc']);?>"> + <input name="nbproc" type="text" class="formfld" id="nbproc" size="18" value="<?=htmlspecialchars($pconfig['nbproc']);?>" /> <br/> Defaults to 1 if left blank (<?php echo trim(`/sbin/sysctl kern.smp.cpus | cut -d" " -f2`); ?> CPU core(s) detected).<br/> Note : Consider leaving this value empty or 1 because in multi-process mode (nbproc > 1) memory is not shared between the processes, which could result in random behaviours for several options like ACL's, sticky connections and some others.<br/> - For more information about the <b>"nbproc"</b> option please see <b><a href='http://haproxy.1wt.eu/download/1.5/doc/configuration.txt' target='_new'>HAProxy Documentation</a> </b> + For more information about the <b>"nbproc"</b> option please see <b><a href='http://cbonte.github.io/haproxy-dconv/configuration-1.5.html#nbproc' target='_blank'>HAProxy Documentation</a> </b> </td> </tr> <tr> <td width="22%" valign="top" class="vncell">Reload behaviour</td> <td width="78%" class="vtable"> - <input name="terminate_on_reload" type="checkbox" value="yes" <?php if ($pconfig['terminate_on_reload']) echo "checked"; ?>> + <input name="terminate_on_reload" type="checkbox" value="yes" <?php if ($pconfig['terminate_on_reload']) echo "checked"; ?> /> Force immediate stop of old process on reload. (closes existing connections)<br/><br/>Note: when this option is selected connections will be closed when haproxy is restarted. Otherwise the existing connections will be served by the old haproxy process untill they are closed. Checking this option will interupt existing connections on a restart. (which happens when the configuration is applied, @@ -259,7 +260,7 @@ function enable_change(enable_change) { Remote syslog host </td> <td class="vtable"> - <input name="remotesyslog" type="text" class="formfld" id="remotesyslog" size="18" value="<?=htmlspecialchars($pconfig['remotesyslog']);?>"><br/> + <input name="remotesyslog" type="text" class="formfld" id="remotesyslog" size="18" value="<?=htmlspecialchars($pconfig['remotesyslog']);?>" /><br/> To log to the local pfSense systemlog fill the host with the value <b>/var/run/log</b>, however if a lot of messages are generated logging is likely to be incomplete. (Also currently no informational logging gets shown in the systemlog.) </td> </tr> @@ -359,7 +360,7 @@ function enable_change(enable_change) { <tr> <td width="22%" valign="top" class="vncell">HAProxy Sync</td> <td width="78%" class="vtable"> - <input name="enablesync" type="checkbox" value="yes" <?php if ($pconfig['enablesync']) echo "checked"; ?>> + <input name="enablesync" type="checkbox" value="yes" <?php if ($pconfig['enablesync']) echo "checked"; ?> /> <strong>Sync HAProxy configuration to backup CARP members via XMLRPC.</strong><br/> Note: remember to also turn on HAProxy Sync on the backup nodes.<br/> The synchronisation host and password are those configured in pfSense main <a href="/system_hasync.php">"System: High Availability Sync"</a> settings. @@ -406,22 +407,20 @@ function enable_change(enable_change) { </tr> <tr> <td width="22%" valign="top"> </td> - <td width="78%"> - <input name="Submit" type="submit" class="formbtn" value="Save" onClick="enable_change(true)"> - </td> + <td width="78%"> + <input name="Submit" type="submit" class="formbtn" value="Save" onClick="enable_change(true)" /> </td> </tr> </table> </div> </table> -<?php if(file_exists("/var/etc/haproxy.cfg")): ?> - <p/> +<?php if(file_exists("/var/etc/haproxy/haproxy.cfg")): ?> <div id="configuration" style="display:none; border-style:dashed; padding: 8px;"> - <b><i>/var/etc/haproxy.cfg file contents:</b></i> + <b><i>/var/etc/haproxy.cfg file contents:</i></b> <?php - if(file_exists("/var/etc/haproxy.cfg")) { - echo "<pre>" . trim(file_get_contents("/var/etc/haproxy.cfg")) . "</pre>"; + if(file_exists("/var/etc/haproxy/haproxy.cfg")) { + echo "<pre>" . trim(file_get_contents("/var/etc/haproxy/haproxy.cfg")) . "</pre>"; } ?> </div> @@ -431,7 +430,7 @@ function enable_change(enable_change) { <?php endif; ?> </form> -<script language="JavaScript"> +<script type="text/javascript"> function scroll_after_fade() { scrollTo(0,99999999999); } diff --git a/config/haproxy-devel/haproxy_htmllist.inc b/config/haproxy-devel/haproxy_htmllist.inc new file mode 100644 index 00000000..2e93ca2a --- /dev/null +++ b/config/haproxy-devel/haproxy_htmllist.inc @@ -0,0 +1,246 @@ +<?php +/* + haproxy_htmllist.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"); +require_once("haproxy_utils.inc"); + +function haproxy_htmllist_get_values($html_list){ + $values = array(); + for($x=0; $x<99; $x++) { + $value = array(); + $add_item = false; + foreach($html_list as $item){ + $itemname = $item['name']; + $value[$itemname] = $_POST[$itemname.$x]; + $add_item |= isset($_POST[$itemname.$x]); + } + if ($add_item) + $values[] = $value; + } + return $values; +} + +function haproxy_htmllist($tablename,$values,$items,$editstate=false){ + global $g, $counter; + echo "<table class='' width='100%' cellpadding='0' cellspacing='0' id='$tablename'> + <tr>"; + foreach($items as $item){ + echo "<td width='{$item['colwidth']}' class='listhdrr'>{$item['columnheader']}</td>"; + } + echo "<td width='5%' class=''></td> + </tr>"; + if (is_array($values)){ + foreach($values as $value){ + if (!$editstate) { + echo "<tr id='tr_view_$counter' ondblclick='editRow($counter); return false;' >"; + $leftitem = true; + foreach($items as $item){ + $tdclass = $leftitem ? "vtable listlr" : "vtable listr"; + echo "<td class='$tdclass'>"; + $itemname = $item['name']; + $itemtype = $item['type']; + $itemvalue = $value[$itemname]; + if ($itemtype == "select"){ + echo $item['items'][$itemvalue]['name']; + } else + if ($itemtype == "checkbox"){ + echo $itemvalue=='yes' ? gettext('yes') : gettext('no'); + } else + echo $itemvalue; + echo "</td>"; + $leftitem = false; + } + echo " + <td class='list'> + <table border='0' cellspacing='0' cellpadding='1'><tr> + <td valign='middle'> + <img src='/themes/{$g['theme']}/images/icons/icon_e.gif' title='edit entry' width='17' height='17' border='0' onclick='editRow($counter); return false;' /> + </td> + <td valign='middle'> + <img src='/themes/{$g['theme']}/images/icons/icon_x.gif' title='delete entry' width='17' height='17' border='0' onclick='deleteRow($counter, \"$tablename\"); return false;' /> + </td> + <td valign='middle'> + <img src='/themes/{$g['theme']}/images/icons/icon_plus.gif' title='duplicate entry' width='17' height='17' border='0' onclick='dupRow($counter, \"$tablename\"); return false;' /> + </td></tr></table> + </td>"; + echo "</tr>"; + } + $displaystyle = $editstate ? "" : "display: none;"; + echo "<tr id='tr_edit_$counter' style='$displaystyle'>"; + foreach($items as $item){ + $itemname = $item['name']; + $itemtype = $item['type']; + $itemvalue = $value[$itemname]; + $itemnamenr = $itemname.$counter; + echo "<td class='vtable'>"; + if ($itemtype == "select"){ + echo_html_select($itemnamenr, $item['items'], $itemvalue,"","updatevisibility();", "width:{$item['size']}"); + } else + if ($itemtype == "checkbox"){ + $checked = $itemvalue=='yes' ? " checked" : ""; + echo "<input name='$itemnamenr' id='$itemnamenr' type='checkbox'$checked value='yes' size='{$item['size']}' />"; + + } else + echo "<input name='$itemnamenr' id='$itemnamenr' type='text' value='{$itemvalue}' size='{$item['size']}' />"; + echo "</td>"; + } + echo " + <td class='list'> + <table border='0' cellspacing='0' cellpadding='1'><tr> + <td valign='middle'> + <img src='/themes/{$g['theme']}/images/icons/icon_x.gif' title='delete entry' width='17' height='17' border='0' onclick='removeRow(this); return false;' /> + </td> + <td valign='middle'> + <img src='/themes/{$g['theme']}/images/icons/icon_plus.gif' title='duplicate entry' width='17' height='17' border='0' onclick='dupRow($counter, \"$tablename\"); return false;' /> + </td></tr></table> + </td>"; + echo "</tr>"; + $counter++; + } + } + echo "</table> + <a onclick='javascript:addRowTo(\"$tablename\"); return false;' href='#'> + <img border='0' src='/themes/{$g['theme']}/images/icons/icon_plus.gif' alt='' title='add another entry' /> + </a>"; +} + +function haproxy_htmllist_js(){ +?><script type="text/javascript"> + function htmllist_get_select_items(tableId) { + var items; + var i = tableId.lastIndexOf('_'); + var items_name = "fields_"+tableId.substr(i+1); + items = eval(items_name); + return items; + } + + var addRowTo = (function() { + return (function (tableId) { + var d, tbody, tr, td, bgc, i, ii, j, type, seltext, items; + var btable, btbody, btr, btd; + d = document; + + items = htmllist_get_select_items(tableId); + seltext = htmllist_get_select_options(tableId); + + tbody = d.getElementById(tableId).getElementsByTagName("tbody").item(0); + tr = d.createElement("tr"); + totalrows++; + tr.setAttribute("id","aclrow" + totalrows); + + for (var i in items) { + td = d.createElement("td"); + if(items[i]['type'] == 'textbox') { + td.innerHTML="<input size='" + items[i]['size'] + "' name='" + items[i]['name'] + totalrows + + "' id='" + items[i]['name'] + totalrows + + "'><\/input> "; + } else if(items[i]['type'] == 'select') { + td.innerHTML="<select style='width:" + items[i]['size'] + "' name='" + items[i]['name'] + totalrows + + "' id='" + items[i]['name'] + totalrows + + "'>" + seltext + "<\/select> "; + } else { + td.innerHTML="<input type='checkbox' name='" + items[i]['name'] + totalrows + + "' id='" + items[i]['name'] + totalrows + "' value='yes'><\/input> "; + } + tr.appendChild(td); + } + td = d.createElement("td"); + td.rowSpan = "1"; + td.setAttribute("class","list"); + + // Recreate the button table. + btable = document.createElement("table"); + btable.setAttribute("border", "0"); + btable.setAttribute("cellspacing", "0"); + btable.setAttribute("cellpadding", "1"); + btbody = document.createElement("tbody"); + btr = document.createElement("tr"); + btd = document.createElement("td"); + btd.setAttribute("valign", "middle"); + btd.innerHTML = '<img src="/themes/' + theme + '/images/icons/icon_x.gif" title="delete entry" width="17" height="17" border="0" onclick="removeRow(this); return false;" />'; + btr.appendChild(btd); + btd = document.createElement("td"); + btd.setAttribute("valign", "middle"); + btd.innerHTML = '<img src="/themes/' + theme + "/images/icons/icon_plus.gif\" title=\"duplicate entry\" width=\"17\" height=\"17\" border=\"0\" onclick=\"dupRow(" + totalrows + ", '" + tableId + "'); return false;\" />"; + btr.appendChild(btd); + btbody.appendChild(btr); + btable.appendChild(btbody); + td.appendChild(btable); + tr.appendChild(td); + tbody.appendChild(tr); + }); + })(); + function dupRow(rowId, tableId) { + var dupEl; + var newEl; + addRowTo(tableId); + items = htmllist_get_select_items(tableId); + for (var i in items) { + dupEl = document.getElementById(items[i]['name'] + rowId); + newEl = document.getElementById(items[i]['name'] + totalrows); + if (dupEl && newEl) + if(items[i]['type'] == 'checkbox') + newEl.checked = dupEl.checked; + else + newEl.value = dupEl.value; + } + } + function editRow(num) { + var trview = document.getElementById('tr_view_' + num); + var tredit = document.getElementById('tr_edit_' + num); + trview.style.display='none'; + tredit.style.display=''; + } + function deleteRow(rowId, tableId) { + var view = document.getElementById("tr_view_" + rowId); + var edit = document.getElementById("tr_edit_" + rowId); + view.parentNode.removeChild(view); + edit.parentNode.removeChild(edit); + } + function removeRow(el) { + var cel; + // Break out of one table first + while (el && el.nodeName.toLowerCase() != "table") + el = el.parentNode; + while (el && el.nodeName.toLowerCase() != "tr") + el = el.parentNode; + + if (el && el.parentNode) { + cel = el.getElementsByTagName("td").item(0); + el.parentNode.removeChild(el); + } + } +</script><? +} + +?> diff --git a/config/haproxy-devel/haproxy_listeners.php b/config/haproxy-devel/haproxy_listeners.php index d802023c..3ff53cea 100644 --- a/config/haproxy-devel/haproxy_listeners.php +++ b/config/haproxy-devel/haproxy_listeners.php @@ -1,8 +1,9 @@ <?php /* $Id: load_balancer_virtual_server.php,v 1.6.2.1 2006/01/02 23:46:24 sullrich Exp $ */ /* - haproxy_baclkends.php + haproxy_listeners.php part of pfSense (http://www.pfsense.com/) + Copyright (C) 2013 PiBa-NL Copyright (C) 2009 Scott Ullrich <sullrich@pfsense.com> Copyright (C) 2008 Remco Hoef <remcoverhoef@pfsense.com> All rights reserved. @@ -84,16 +85,16 @@ include("head.inc"); <?php endif; ?> <?php if ($input_errors) print_input_errors($input_errors); ?> <?php if ($savemsg) print_info_box($savemsg); ?> -<?php if (file_exists($d_haproxyconfdirty_path)): ?><p> -<?php print_info_box_np("The haproxy configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br> +<?php if (file_exists($d_haproxyconfdirty_path)): ?> +<?php print_info_box_np("The haproxy configuration has been changed.<br/>You must apply the changes in order for them to take effect.");?><br/> <?php endif; ?> <table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr><td class="tabnavtbl"> <?php - /* active tabs */ - $tab_array = array(); + /* active tabs */ + $tab_array = array(); $tab_array[] = array("Settings", false, "haproxy_global.php"); - $tab_array[] = array("Frontend", true, "haproxy_listeners.php"); + $tab_array[] = array("Frontend", true, "haproxy_listeners.php"); $tab_array[] = array("Backend", false, "haproxy_pools.php"); display_top_tabs($tab_array); ?> @@ -139,7 +140,7 @@ include("head.inc"); foreach ($a_frontend_grouped as $a_frontend) { usort($a_frontend,'sort_sharedfrontends'); if (count($a_frontend) > 1 || $last_frontend_shared) { - ?> <tr class="<?=$textgray?>"><td collspan="7"> </td></tr> <? + ?> <tr class="<?=$textgray?>"><td colspan="7"> </td></tr> <? } $last_frontend_shared = count($a_frontend) > 1; foreach ($a_frontend as $frontend) { @@ -154,7 +155,17 @@ include("head.inc"); <? if (strtolower($frontend['type']) == "http" && $frontend['ssloffload']) { $cert = lookup_cert($frontend['ssloffloadcert']); - echo '<img src="'.$img_cert.'" title="SSL offloading cert: '.$cert['descr'].'" alt="SSL offloading" border="0" height="16" width="16" />'; + $descr = htmlspecialchars($cert['descr']); + $certs = $frontend['ha_certificates']['item']; + if (is_array($certs)){ + if (count($certs) > 0){ + foreach($certs as $certitem){ + $cert = lookup_cert($certitem['ssl_certificate']); + $descr .= "\n".htmlspecialchars($cert['descr']); + } + } + } + echo '<img src="'.$img_cert.'" title="SSL offloading cert: '.$descr.'" alt="SSL offloading" border="0" height="16" width="16" />'; } $acls = get_frontend_acls($frontend); @@ -162,14 +173,19 @@ include("head.inc"); foreach ($acls as $acl) { $isaclset .= " " . $acl['descr']; } + if ($frontend['ssloffloadacl']) + $isaclset .= " " . "Certificate ACL"; + if ($frontend['ssloffloadacladditional']) + $isaclset .= " " . "Additional certificate ACLs"; + if ($isaclset) - echo "<img src=\"$img_acl\" title=\"" . gettext("acl's used") . ": {$isaclset}\" border=\"0\">"; + echo "<img src=\"$img_acl\" title=\"" . gettext("acl's used") . ": {$isaclset}\" border=\"0\" />"; $isadvset = ""; if ($frontend['advanced_bind']) $isadvset .= "Advanced bind: {$frontend['advanced_bind']}\r\n"; if ($frontend['advanced']) $isadvset .= "Advanced pass thru setting used\r\n"; if ($isadvset) - echo "<img src=\"$img_adv\" title=\"" . gettext("Advanced settings set") . ": {$isadvset}\" border=\"0\">"; + echo "<img src=\"$img_adv\" title=\"" . gettext("Advanced settings set") . ": {$isadvset}\" border=\"0\" />"; $backend_serverpool = $frontend['backend_serverpool']; $backend = get_backend($backend_serverpool ); @@ -205,9 +221,9 @@ include("head.inc"); <td class="list" nowrap> <table border="0" cellspacing="0" cellpadding="1"> <tr> - <td valign="middle"><a href="haproxy_listeners_edit.php?id=<?=$frontendname;?>"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" title="<?=gettext("edit frontend");?>" width="17" height="17" border="0"></a></td> - <td valign="middle"><a href="haproxy_listeners.php?act=del&id=<?=$frontendname;?>" onclick="return confirm('Do you really want to delete this entry?')"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" title="<?=gettext("delete frontend");?>" width="17" height="17" border="0"></a></td> - <td valign="middle"><a href="haproxy_listeners_edit.php?dup=<?=$frontendname;?>"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" title="<?=gettext("clone frontend");?>" width="17" height="17" border="0"></a></td> + <td valign="middle"><a href="haproxy_listeners_edit.php?id=<?=$frontendname;?>"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" title="<?=gettext("edit frontend");?>" width="17" height="17" border="0" /></a></td> + <td valign="middle"><a href="haproxy_listeners.php?act=del&id=<?=$frontendname;?>" onclick="return confirm('Do you really want to delete this entry?')"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" title="<?=gettext("delete frontend");?>" width="17" height="17" border="0" /></a></td> + <td valign="middle"><a href="haproxy_listeners_edit.php?dup=<?=$frontendname;?>"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" title="<?=gettext("clone frontend");?>" width="17" height="17" border="0" /></a></td> </tr> </table> </td> @@ -220,7 +236,7 @@ include("head.inc"); <td class="list"> <table border="0" cellspacing="0" cellpadding="1"> <tr> - <td valign="middle"><a href="haproxy_listeners_edit.php"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" title="<?=gettext("add new frontend");?>" width="17" height="17" border="0"></a></td> + <td valign="middle"><a href="haproxy_listeners_edit.php"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" title="<?=gettext("add new frontend");?>" width="17" height="17" border="0" /></a></td> </tr> </table> </td> diff --git a/config/haproxy-devel/haproxy_listeners_edit.php b/config/haproxy-devel/haproxy_listeners_edit.php index d5d44e5d..2fd9a6c3 100644 --- a/config/haproxy-devel/haproxy_listeners_edit.php +++ b/config/haproxy-devel/haproxy_listeners_edit.php @@ -33,6 +33,7 @@ $shortcut_section = "haproxy"; require("guiconfig.inc"); require_once("haproxy.inc"); require_once("haproxy_utils.inc"); +require_once("haproxy_htmllist.inc"); /* Compatibility function for pfSense 2.0 */ if (!function_exists("cert_get_purpose")) { @@ -44,76 +45,13 @@ if (!function_exists("cert_get_purpose")) { } /**/ -function get_certificat_usage($refid) { - $usage = array(); - $cert = lookup_cert($refid); - if (is_cert_revoked($cert)) - $usage[] = "Revoked"; - if (is_webgui_cert($refid)) - $usage[] = "webConfigurator"; - if (is_user_cert($refid)) - $usage[] = "User Cert"; - if (is_openvpn_server_cert($refid)) - $usage[] = "OpenVPN Server"; - if (is_openvpn_client_cert($refid)) - $usage[] = "OpenVPN Client"; - if (is_ipsec_cert($cert['refid'])) - $usage[] = "IPsec Tunnel"; - if (function_exists("is_captiveportal_cert")) - if (is_captiveportal_cert($refid)) - $usage[] = "Captive Portal"; - - return $usage; -} - -// This function (is intended to) provides a uniform way to retrieve a list of server certificates -function get_certificates_server($get_includeWebCert=false) { - global $config; - $certificates=array(); - $a_cert = &$config['cert']; - foreach ($a_cert as $cert) - { - if ($get_ca == false && is_webgui_cert($cert['refid'])) - continue; - - $purpose = cert_get_purpose($cert['crt']); - //$certserverpurpose = $purpose['server'] == 'Yes' ? " [Server certificate]" : ""; - $certserverpurpose = ""; - - $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"; - - $usagestr=""; - $usage = get_certificat_usage($cert['refid']); - foreach($usage as $use){ - $usagestr .= " " . $use; - } - if ($usagestr != "") - $usagestr = " (".trim($usagestr).")"; - - $certificates[$cert['refid']]['name'] = $cert['descr'] . $caname . $certserverpurpose . $inuse . $revoked . $usagestr; - } - return $certificates; -} - -function haproxy_acl_select($mode) { +function haproxy_js_acl_select($mode) { global $a_acltypes; $seltext = ''; - foreach ($a_acltypes as $expr) { + foreach ($a_acltypes as $key => $expr) { if ($expr['mode'] == '' || $expr['mode'] == $mode) - $seltext .= "<option value='" . $expr['name'] . "'>" . $expr['descr'] .":</option>"; + $seltext .= "<option value='" . $key . "'>" . $expr['name'] .":<\/option>"; } return $seltext; } @@ -129,7 +67,7 @@ $a_pools = &$config['installedpackages']['haproxy']['ha_pools']['item']; global $simplefields; $simplefields = array('name','desc','status','secondary','primary_frontend','type','forwardfor','httpclose','extaddr','backend_serverpool', - 'max_connections','client_timeout','port','ssloffloadcert','dcertadv','ssloffload','ssloffloadacl','advanced_bind'); + 'max_connections','client_timeout','port','ssloffloadcert','dcertadv','ssloffload','ssloffloadacl','advanced_bind','ssloffloadacladditional'); if (isset($_POST['id'])) $id = $_POST['id']; @@ -141,10 +79,41 @@ if (isset($_GET['dup'])) $id = get_frontend_id($id); +$servercerts = get_certificates_server(); + +$fields_sslCertificates=array(); +$fields_sslCertificates[0]['name']="ssl_certificate"; +$fields_sslCertificates[0]['columnheader']="Certificates"; +$fields_sslCertificates[0]['colwidth']="95%"; +$fields_sslCertificates[0]['type']="select"; +$fields_sslCertificates[0]['size']="500px"; +$fields_sslCertificates[0]['items']=&$servercerts; + +$fields_aclSelectionList=array(); +$fields_aclSelectionList[0]['name']="name"; +$fields_aclSelectionList[0]['columnheader']="Name"; +$fields_aclSelectionList[0]['colwidth']="30%"; +$fields_aclSelectionList[0]['type']="textbox"; +$fields_aclSelectionList[0]['size']="20"; + +$fields_aclSelectionList[1]['name']="expression"; +$fields_aclSelectionList[1]['columnheader']="Expression"; +$fields_aclSelectionList[1]['colwidth']="30%"; +$fields_aclSelectionList[1]['type']="select"; +$fields_aclSelectionList[1]['size']="10"; +$fields_aclSelectionList[1]['items']=&$a_acltypes; + +$fields_aclSelectionList[2]['name']="value"; +$fields_aclSelectionList[2]['columnheader']="Value"; +$fields_aclSelectionList[2]['colwidth']="35%"; +$fields_aclSelectionList[2]['type']="textbox"; +$fields_aclSelectionList[2]['size']="35"; + + if (isset($id) && $a_backend[$id]) { $pconfig['a_acl']=&$a_backend[$id]['ha_acls']['item']; + $pconfig['a_certificates']=&$a_backend[$id]['ha_certificates']['item']; $pconfig['advanced'] = base64_decode($a_backend[$id]['advanced']); - foreach($simplefields as $stat) $pconfig[$stat] = $a_backend[$id][$stat]; } @@ -163,8 +132,8 @@ if ($_POST) { if ($pconfig['secondary'] != "yes") { - $reqdfields = explode(" ", "name type port max_connections"); - $reqdfieldsn = explode(",", "Name,Type,Port,Max connections"); + $reqdfields = explode(" ", "name type port"); + $reqdfieldsn = explode(",", "Name,Type,Port"); } else { $reqdfields = explode(" ", "name"); $reqdfieldsn = explode(",", "Name"); @@ -176,7 +145,7 @@ if ($_POST) { $input_errors[] = "The field 'Name' contains invalid characters."; if ($pconfig['secondary'] != "yes") { - if (!is_numeric($_POST['max_connections'])) + if ($_POST['max_connections'] && !is_numeric($_POST['max_connections'])) $input_errors[] = "The field 'Max connections' value is not a number."; $ports = split(",", $_POST['port'] . ","); @@ -193,36 +162,26 @@ if ($_POST) { if (($_POST['name'] == $config['installedpackages']['haproxy']['ha_backends']['item'][$i]['name']) && ($i != $id)) $input_errors[] = "This frontend name has already been used. Frontend names must be unique. $i != $id"; - $a_acl=array(); - $acl_names=array(); - for($x=0; $x<99; $x++) { - $acl_name=$_POST['acl_name'.$x]; - $acl_expression=$_POST['acl_expression'.$x]; - $acl_value=$_POST['acl_value'.$x]; - - if ($acl_name) { - $acl_names[]=$acl_name; - - $acl=array(); - $acl['name']=$acl_name; - $acl['expression']=$acl_expression; - $acl['value']=$acl_value; - $a_acl[]=$acl; - - if (preg_match("/[^a-zA-Z0-9\.\-_]/", $acl_name)) - $input_errors[] = "The field 'Name' contains invalid characters."; - - if (!preg_match("/.{1,}/", $acl_value)) - $input_errors[] = "The field 'Value' is required."; + $a_certificates = haproxy_htmllist_get_values($fields_sslCertificates); + $pconfig['a_certificates'] = $a_certificates; + + $a_acl = haproxy_htmllist_get_values($fields_aclSelectionList); + $pconfig['a_acl'] = $a_acl; + + foreach($a_acl as $acl) { + $acl_name = $acl['name']; + $acl_value = $acl['value']; + + if (preg_match("/[^a-zA-Z0-9\.\-_]/", $acl_name)) + $input_errors[] = "The field 'Name' contains invalid characters."; - if (!preg_match("/.{2,}/", $acl_name)) - $input_errors[] = "The field 'Name' is required."; + if (!preg_match("/.{1,}/", $acl_value)) + $input_errors[] = "The field 'Value' is required."; - } + if (!preg_match("/.{2,}/", $acl_name)) + $input_errors[] = "The field 'Name' is required with at least 2 characters."; } - $pconfig['a_acl']=$a_acl; - if (!$input_errors) { $backend = array(); if(isset($id) && $a_backend[$id]) @@ -242,10 +201,10 @@ if ($_POST) { foreach($simplefields as $stat) update_if_changed($stat, $backend[$stat], $_POST[$stat]); - update_if_changed("advanced", $backend['advanced'], base64_encode($_POST['advanced'])); $backend['ha_acls']['item'] = $a_acl; + $backend['ha_certificates']['item'] = $a_certificates; if (isset($id) && $a_backend[$id]) { $a_backend[$id] = $backend; @@ -273,170 +232,55 @@ if (!$id) $pconfig['ssloffloadacl'] = "yes"; } +$closehead = false; $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"> +?> <style type="text/css"> .haproxy_mode_http{display:none;} .haproxy_ssloffloading_enabled{display:none;} .haproxy_primary{} .haproxy_secondary{display:none;} </style> +</head> +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> <?php if($one_two): ?> <script type="text/javascript" src="/javascript/scriptaculous/prototype.js"></script> <script type="text/javascript" src="/javascript/scriptaculous/scriptaculous.js"></script> <?php endif; ?> -<script type="text/javascript"> - // Global Variables - var rowname = new Array(99); - var rowtype = new Array(99); - var newrow = new Array(99); - var rowsize = new Array(99); - - for (i = 0; i < 99; i++) { - rowname[i] = ''; - rowtype[i] = ''; - newrow[i] = ''; - rowsize[i] = '25'; - } - var field_counter_js = 0; - var loaded = 0; - var is_streaming_progress_bar = 0; - var temp_streaming_text = ""; - - var addRowTo = (function() { - return (function (tableId) { - var d, tbody, tr, td, bgc, i, ii, j, type, seltext; - var btable, btbody, btr, btd; - - d = document; - type = d.getElementById("type").value; - if (type == 'health') - seltext = "<?php echo haproxy_acl_select('health');?>"; - else if (type == 'tcp') - seltext = "<?php echo haproxy_acl_select('tcp');?>"; - else if (type == 'https') - seltext = "<?php echo haproxy_acl_select('https');?>"; - else - seltext = "<?php echo haproxy_acl_select('http');?>"; - if (seltext == '') { - alert("No ACL types available in current frontend type"); - return; - } - tbody = d.getElementById(tableId).getElementsByTagName("tbody").item(0); - tr = d.createElement("tr"); - totalrows++; - tr.setAttribute("id","aclrow" + totalrows); - for (i = 0; i < field_counter_js; i++) { - td = d.createElement("td"); - if(rowtype[i] == 'textbox') { - td.innerHTML="<INPUT type='hidden' value='" + totalrows +"' name='" + rowname[i] + "_row-" + totalrows + - "'></input><input size='" + rowsize[i] + "' name='" + rowname[i] + totalrows + - "' id='" + rowname[i] + totalrows + - "'></input> "; - } else if(rowtype[i] == 'select') { - td.innerHTML="<INPUT type='hidden' value='" + totalrows +"' name='" + rowname[i] + "_row-" + totalrows + - "'></input><select name='" + rowname[i] + totalrows + - "' id='" + rowname[i] + totalrows + - "'>" + seltext + "</select> "; - } else { - td.innerHTML="<INPUT type='hidden' value='" + totalrows +"' name='" + rowname[i] + "_row-" + totalrows + - "'></input><input type='checkbox' name='" + rowname[i] + totalrows + - "' id='" + rowname[i] + totalrows + "'></input> "; - } - tr.appendChild(td); - } - td = d.createElement("td"); - td.rowSpan = "1"; - td.setAttribute("class","list"); - - // Recreate the button table. - btable = document.createElement("table"); - btable.setAttribute("border", "0"); - btable.setAttribute("cellspacing", "0"); - btable.setAttribute("cellpadding", "1"); - btbody = document.createElement("tbody"); - btr = document.createElement("tr"); - btd = document.createElement("td"); - btd.setAttribute("valign", "middle"); - btd.innerHTML = '<img src="/themes/' + theme + '/images/icons/icon_x.gif" title="delete entry" width="17" height="17" border="0" onclick="removeRow(this); return false;">'; - btr.appendChild(btd); - btd = document.createElement("td"); - btd.setAttribute("valign", "middle"); - btd.innerHTML = '<img src="/themes/' + theme + "/images/icons/icon_plus.gif\" title=\"duplicate entry\" width=\"17\" height=\"17\" border=\"0\" onclick=\"dupRow(" + totalrows + ", 'acltable'); return false;\">"; - btr.appendChild(btd); - btbody.appendChild(btr); - btable.appendChild(btbody); - - td.appendChild(btable); - tr.appendChild(td); - tbody.appendChild(tr); - }); - })(); - - function dupRow(rowId, tableId) { - var dupEl; - var newEl; - - addRowTo(tableId); - for (i = 0; i < field_counter_js; i++) { - dupEl = document.getElementById(rowname[i] + rowId); - newEl = document.getElementById(rowname[i] + totalrows); - if (dupEl && newEl) - newEl.value = dupEl.value; +<script type="text/javascript"> + function htmllist_get_select_options(tableId) { + var seltext; + seltext = ""; + var type = d.getElementById("type").value; + if (tableId == 'tableA_acltable'){ + if (type == 'health') + seltext = "<?php echo haproxy_js_acl_select('health');?>"; + else if (type == 'tcp') + seltext = "<?php echo haproxy_js_acl_select('tcp');?>"; + else if (type == 'https') + seltext = "<?php echo haproxy_js_acl_select('https');?>"; + else + seltext = "<?php echo haproxy_js_acl_select('http');?>"; + if (seltext == '') { + alert("No ACL types available in current frontend type"); + return; + } } + if (tableId == 'tableA_sslCertificates'){ + seltext = "<?=haproxy_js_select_options($servercerts);?>"; + } + return seltext; } - function removeRow(el) { - var cel; - // Break out of one table first - while (el && el.nodeName.toLowerCase() != "table") - el = el.parentNode; - while (el && el.nodeName.toLowerCase() != "tr") - el = el.parentNode; - - if (el && el.parentNode) { - cel = el.getElementsByTagName("td").item(0); - el.parentNode.removeChild(el); - } - } - - function find_unique_field_name(field_name) { - // loop through field_name and strip off -NUMBER - var last_found_dash = 0; - for (var i = 0; i < field_name.length; i++) { - // is this a dash, if so, update - // last_found_dash - if (field_name.substr(i,1) == "-" ) - last_found_dash = i; - } - if (last_found_dash < 1) - return field_name; - return(field_name.substr(0,last_found_dash)); - } - - rowname[0] = "acl_name"; - rowtype[0] = "textbox"; - rowsize[0] = "20"; - - rowname[1] = "acl_expression"; - rowtype[1] = "select"; - rowsize[1] = "10"; - - rowname[2] = "acl_value"; - rowtype[2] = "textbox"; - rowsize[2] = "35"; - - function setCSSdisplay(cssID, display) - { + function setCSSdisplay(cssID, display) { var ss = document.styleSheets; for (var i=0; i<ss.length; i++) { var rules = ss[i].cssRules || ss[i].rules; @@ -448,8 +292,7 @@ $interfaces = haproxy_get_bindable_interfaces(); } } - function updatevisibility() - { + function updatevisibility() { d = document; ssloffload = d.getElementById("ssloffload"); type = d.getElementById("type"); @@ -478,8 +321,8 @@ $interfaces = haproxy_get_bindable_interfaces(); function type_change(type) { var d, i, j, el, row; var count = <?=count($a_acltypes);?>; - var acl = [ <?php foreach ($a_acltypes as $expr) echo "'".$expr['name']."'," ?> ]; - var mode = [ <?php foreach ($a_acltypes as $expr) echo "'".$expr['mode']."'," ?> ]; + var acl = [ <?php foreach ($a_acltypes as $key => $expr) echo "'".$key."'," ?> ]; + var mode = [ <?php foreach ($a_acltypes as $key => $expr) echo "'".$expr['mode']."'," ?> ]; d = document; for (i = 0; i < 99; i++) { @@ -497,6 +340,26 @@ $interfaces = haproxy_get_bindable_interfaces(); } } } + + for (i = 0; i < 99; i++) { + el = d.getElementById("expression" + i); + //row_v = d.getElementById("tr_view_" + i); + row_e = d.getElementById("tr_edit_" + i); + if (!el) + continue; + for (j = 0; j < count; j++) { + if (acl[j] == el.value) { + if (mode[j] != '' && mode[j] != type) { + //Effect.Fade(row_v,{ duration: 1.0 }); + Effect.Fade(row_e,{ duration: 1.0 }); + } else { + //Effect.Appear(row_v,{ duration: 1.0 }); + Effect.Appear(row_e,{ duration: 1.0 }); + } + } + } + } + } </script> <?php include("fbegin.inc"); ?> @@ -526,13 +389,13 @@ $interfaces = haproxy_get_bindable_interfaces(); <tr> <td width="22%" valign="top" class="vncellreq">Name</td> <td width="78%" class="vtable" colspan="2"> - <input name="name" type="text" <?if(isset($pconfig['name'])) echo "value=\"{$pconfig['name']}\"";?> size="25" maxlength="25"> + <input name="name" type="text" <?if(isset($pconfig['name'])) echo "value=\"{$pconfig['name']}\"";?> size="25" maxlength="25" /> </td> </tr> <tr align="left"> <td width="22%" valign="top" class="vncell">Description</td> <td width="78%" class="vtable" colspan="2"> - <input name="desc" type="text" <?if(isset($pconfig['desc'])) echo "value=\"{$pconfig['desc']}\"";?> size="64"> + <input name="desc" type="text" <?if(isset($pconfig['desc'])) echo "value=\"{$pconfig['desc']}\"";?> size="64" /> </td> </tr> <tr align="left"> @@ -550,7 +413,7 @@ $interfaces = haproxy_get_bindable_interfaces(); <?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();"/> + <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/> @@ -583,14 +446,14 @@ $interfaces = haproxy_get_bindable_interfaces(); <tr class="haproxy_primary" align="left"> <td width="22%" valign="top" class="vncellreq">External port</td> <td width="78%" class="vtable" colspan="2"> - <input name="port" type="text" <?if(isset($pconfig['port'])) echo "value=\"{$pconfig['port']}\"";?> size="10" maxlength="500"> + <input name="port" type="text" <?if(isset($pconfig['port'])) echo "value=\"{$pconfig['port']}\"";?> size="10" maxlength="500" /> <div>The port to listen to. To specify multiple ports, separate with a comma (,). EXAMPLE: 80,443</div> </td> </tr> <tr class="haproxy_primary" align="left"> - <td width="22%" valign="top" class="vncellreq">Max connections</td> + <td width="22%" valign="top" class="vncell">Max connections</td> <td width="78%" class="vtable" colspan="2"> - <input name="max_connections" type="text" <?if(isset($pconfig['max_connections'])) echo "value=\"{$pconfig['max_connections']}\"";?> size="10" maxlength="10"> + <input name="max_connections" type="text" <?if(isset($pconfig['max_connections'])) echo "value=\"{$pconfig['max_connections']}\"";?> size="10" maxlength="10" /> </td> </tr> <tr> @@ -628,58 +491,14 @@ $interfaces = haproxy_get_bindable_interfaces(); <tr> <td width="22%" valign="top" class="vncell">Access Control lists</td> <td width="78%" class="vtable" colspan="2" valign="top"> - <table class="" width="100%" cellpadding="0" cellspacing="0" id='acltable'> - <tr> - <td width="35%" class="">Name</td> - <td width="40%" class="">Expression</td> - <td width="20%" class="">Value</td> - <td width="5%" class=""></td> - </tr> - <?php - $a_acl=$pconfig['a_acl']; - - if (!is_array($a_acl)) { - $a_acl=array(); - } - - $counter=0; - foreach ($a_acl as $acl) { - $t = haproxy_find_acl($acl['expression']); - $display = ''; - if (!$t || ($t['mode'] != '' && $t['mode'] != strtolower($pconfig['type']))) - $display = 'style="display: none;"'; - ?> - <tr id="aclrow<?=$counter;?>" <?=$display;?>> - <td><input name="acl_name<?=$counter;?>" id="acl_name<?=$counter;?>" type="text" value="<?=$acl['name']; ?>" size="20"/></td> - <td> - <select name="acl_expression<?=$counter;?>" id="acl_expression<?=$counter;?>"> - <?php - foreach ($a_acltypes as $expr) { ?> - <option value="<?=$expr['name'];?>"<?php if($acl['expression'] == $expr['name']) echo " SELECTED"; ?>><?=$expr['descr'];?>:</option> - <?php } ?> - </select> - </td> - <td><input name="acl_value<?=$counter;?>" id="acl_value<?=$counter;?>" type="text" value="<?=$acl['value']; ?>" size="35"/></td> - <td class="list"> - <table border="0" cellspacing="0" cellpadding="1"><tr> - <td valign="middle"> - <img src="/themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" title="delete entry" width="17" height="17" border="0" onclick="removeRow(this); return false;"> - </td> - <td valign="middle"> - <img src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" title="duplicate entry" width="17" height="17" border="0" onclick="dupRow(<?=$counter;?>, 'acltable'); return false;"> - </td></tr></table> - </td> - </tr> - <?php - $counter++; - } - ?> - </table> - <a onclick="javascript:addRowTo('acltable'); return false;" href="#"> - <img border="0" src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" alt="" title="add another entry" /> - </a><br/> + <? + $counter=0; + $a_acl = $pconfig['a_acl']; + haproxy_htmllist("tableA_acltable", $a_acl, $fields_aclSelectionList, true); + ?> + <br/> acl's with the same name wil be 'combined', acl's with different names will be evaluated seperately.<br/> - For more information about ACL's please see <a href='http://haproxy.1wt.eu/download/1.5/doc/configuration.txt' target='_new'>HAProxy Documentation</a> Section 7 - Using ACL's + For more information about ACL's please see <a href='http://haproxy.1wt.eu/download/1.5/doc/configuration.txt' target='_blank'>HAProxy Documentation</a> Section 7 - Using ACL's </td> </tr> </table> @@ -691,14 +510,14 @@ $interfaces = haproxy_get_bindable_interfaces(); <tr align="left"> <td width="22%" valign="top" class="vncell">Client timeout</td> <td width="78%" class="vtable" colspan="2"> - <input name="client_timeout" type="text" <?if(isset($pconfig['client_timeout'])) echo "value=\"{$pconfig['client_timeout']}\"";?> size="10" maxlength="10"> + <input name="client_timeout" type="text" <?if(isset($pconfig['client_timeout'])) echo "value=\"{$pconfig['client_timeout']}\"";?> size="10" maxlength="10" /> <div>the time (in milliseconds) we accept to wait for data from the client, or for the client to accept data (default 30000).</div> </td> </tr> <tr align="left" class="haproxy_mode_http"> <td width="22%" valign="top" class="vncell">Use 'forwardfor' option</td> <td width="78%" class="vtable" colspan="2"> - <input id="forwardfor" name="forwardfor" type="checkbox" value="yes" <?php if ($pconfig['forwardfor']=='yes') echo "checked"; ?>> + <input id="forwardfor" name="forwardfor" type="checkbox" value="yes" <?php if ($pconfig['forwardfor']=='yes') echo "checked"; ?> /> <br/> The 'forwardfor' option creates an HTTP 'X-Forwarded-For' header which contains the client's IP address. This is useful to let the final web server @@ -721,7 +540,7 @@ $interfaces = haproxy_get_bindable_interfaces(); <tr align="left"> <td width="22%" valign="top" class="vncell">Bind pass thru</td> <td width="78%" class="vtable" colspan="2"> - <input name="advanced_bind" type="text" <?if(isset($pconfig['advanced_bind'])) echo "value=\"".htmlspecialchars($pconfig['advanced_bind'])."\"";?> size="64"> + <input name="advanced_bind" type="text" <?if(isset($pconfig['advanced_bind'])) echo "value=\"".htmlspecialchars($pconfig['advanced_bind'])."\"";?> size="64" /> <br/> NOTE: paste text into this box that you would like to pass behind the bind option. </td> @@ -745,11 +564,11 @@ $interfaces = haproxy_get_bindable_interfaces(); <tr align="left"> <td width="22%" valign="top" class="vncell">Use Offloading</td> <td width="78%" class="vtable" colspan="2"> - <input id="ssloffload" name="ssloffload" type="checkbox" value="yes" <?php if ($pconfig['ssloffload']=='yes') echo "checked";?> onclick="updatevisibility();"><strong>Use Offloading</strong></input> + <input id="ssloffload" name="ssloffload" type="checkbox" value="yes" <?php if ($pconfig['ssloffload']=='yes') echo "checked";?> onclick="updatevisibility();" /><strong>Use Offloading</strong> <br/> SSL Offloading will reduce web servers load by maintaining and encrypting connection with users on internet while sending and retrieving data without encrytion to internal servers. Also more ACL rules and http logging may be configured when this option is used. - Certificates can be imported into the <a href="/system_camanager.php" target="_new">pfSense "Certificate Authority Manager"</a> + Certificates can be imported into the <a href="/system_camanager.php" target="_blank">pfSense "Certificate Authority Manager"</a> Please be aware this possibly will not work with all web applications. Some applications will require setting the SSL checkbox on the backend server configurations so the connection to the webserver will also be a encrypted connection, in that case there will be a slight overall performance loss. </td> </tr> @@ -757,25 +576,32 @@ $interfaces = haproxy_get_bindable_interfaces(); <td width="22%" valign="top" class="vncell">Certificate</td> <td width="78%" class="vtable" colspan="2"> <? - $servercerts = get_certificates_server(); echo_html_select("ssloffloadcert", $servercerts, $pconfig['ssloffloadcert'], '<b>No Certificates defined.</b> <br/>Create one under <a href="system_certmanager.php">System > Cert Manager</a>.'); ?> <br/> NOTE: choose the cert to use on this frontend. + <br/> + <input id="ssloffloadacl" name="ssloffloadacl" type="checkbox" value="yes" <?php if ($pconfig['ssloffloadacl']=='yes') echo "checked";?> onclick="updatevisibility();" />Add ACL for certificate CommonName. </td> </tr> - <tr class="haproxy_ssloffloading_enabled" align="left"> - <td width="22%" valign="top" class="vncell">ACL for certificate CN</td> - <td width="78%" class="vtable" colspan="2"> - <input id="ssloffloadacl" name="ssloffloadacl" type="checkbox" value="yes" <?php if ($pconfig['ssloffloadacl']=='yes') echo "checked";?> onclick="updatevisibility();">Add ACL for certificate CommonName.</input> + <tr class="haproxy_ssloffloading_enabled"> + <td width="22%" valign="top" class="vncell">Additional certificates</td> + <td width="78%" class="vtable" colspan="2" valign="top"> + Which of these certificate will be send will be determined by haproxys SNI recognition. If the browser does not send SNI this will not work properly. (IE on XP is one example, possibly also older browsers or mobile devices) + <? + $a_certificates = $pconfig['a_certificates']; + haproxy_htmllist("tableA_sslCertificates", $a_certificates, $fields_sslCertificates); + ?> + <br/> + <input id="ssloffloadacladditional" name="ssloffloadacladditional" type="checkbox" value="yes" <?php if ($pconfig['ssloffloadacladditional']=='yes') echo "checked";?> onclick="updatevisibility();" />Add ACL for certificate CommonName. </td> </tr> <tr class="haproxy_ssloffloading_enabled haproxy_primary" align="left"> <td width="22%" valign="top" class="vncell">Advanced ssl options</td> <td width="78%" class="vtable" colspan="2"> - <input type='text' name='dcertadv' size="64" id='dcertadv' <?if(isset($pconfig['dcertadv'])) echo "value=\"{$pconfig['dcertadv']}\"";?> size="10" maxlength="64"> + <input type='text' name='dcertadv' size="64" id='dcertadv' <?if(isset($pconfig['dcertadv'])) echo "value=\"{$pconfig['dcertadv']}\"";?> maxlength="64" /> <br/> - NOTE: Paste additional ssl options(without commas) to include on ssl listening options.<br> + NOTE: Paste additional ssl options(without commas) to include on ssl listening options.<br/> some options: force-sslv3, force-tlsv10 force-tlsv11 force-tlsv12 no-sslv3 no-tlsv10 no-tlsv11 no-tlsv12 no-tls-tickets </td> </tr> @@ -787,10 +613,10 @@ $interfaces = haproxy_get_bindable_interfaces(); <tr align="left"> <td width="22%" valign="top"> </td> <td width="78%"> - <input name="Submit" type="submit" class="formbtn" value="Save"> - <input type="button" class="formbtn" value="Cancel" onclick="history.back()"> + <input name="Submit" type="submit" class="formbtn" value="Save" /> + <input type="button" class="formbtn" value="Cancel" onclick="history.back()" /> <?php if (isset($id) && $a_backend[$id]): ?> - <input name="id" type="hidden" value="<?=$a_backend[$id]['name'];?>"> + <input name="id" type="hidden" value="<?=$a_backend[$id]['name'];?>" /> <?php endif; ?> </td> </tr> @@ -802,23 +628,21 @@ $interfaces = haproxy_get_bindable_interfaces(); </table> </div></td></tr></table> </form> -<br> +<br/> <script type="text/javascript"> <? phparray_to_javascriptarray($primaryfrontends,"primaryfrontends",Array('/*','/*/name','/*/ref','/*/ref/type','/*/ref/ssloffload')); phparray_to_javascriptarray($a_closetypes,"closetypes",Array('/*','/*/name','/*/descr')); - + phparray_to_javascriptarray($fields_sslCertificates,"fields_sslCertificates",Array('/*','/*/name','/*/type','/*/size','/*/items','/*/items/*','/*/items/*/*','/*/items/*/*/name')); + phparray_to_javascriptarray($fields_aclSelectionList,"fields_acltable",Array('/*','/*/name','/*/type','/*/size','/*/items','/*/items/*','/*/items/*/*','/*/items/*/*/name')); ?> - </script> <script type="text/javascript"> - field_counter_js = 3; - rows = 1; totalrows = <?php echo $counter; ?>; - loaded = <?php echo $counter; ?>; - updatevisibility(); </script> -<?php include("fend.inc"); ?> +<?php +haproxy_htmllist_js(); +include("fend.inc"); ?> </body> </html> diff --git a/config/haproxy-devel/haproxy_pool_edit.php b/config/haproxy-devel/haproxy_pool_edit.php index b6673a0a..93fa20dc 100644 --- a/config/haproxy-devel/haproxy_pool_edit.php +++ b/config/haproxy-devel/haproxy_pool_edit.php @@ -3,6 +3,7 @@ /* haproxy_pool_edit.php part of pfSense (http://www.pfsense.com/) + Copyright (C) 2013 PiBa-NL Copyright (C) 2009 Scott Ullrich <sullrich@pfsense.com> Copyright (C) 2008 Remco Hoef <remcoverhoef@pfsense.com> All rights reserved. @@ -32,6 +33,7 @@ $shortcut_section = "haproxy"; require("guiconfig.inc"); require_once("haproxy.inc"); require_once("haproxy_utils.inc"); +require_once("haproxy_htmllist.inc"); $d_haproxyconfdirty_path = $g['varrun_path'] . "/haproxy.conf.dirty"; @@ -53,9 +55,48 @@ global $simplefields; $simplefields = array( "name","cookie","balance","transparent_clientip","transparent_interface", "check_type","checkinter","httpcheck_method","monitor_uri","monitor_httpversion","monitor_username","monitor_domain","monitor_agentport", +"agent_check","agent_port","agent_inter", "connection_timeout","server_timeout","retries", "stats_enabled","stats_username","stats_password","stats_uri","stats_realm","stats_admin","stats_node_enabled","stats_node","stats_desc","stats_refresh"); +$fields_servers=array(); +$fields_servers[0]['name']="name"; +$fields_servers[0]['columnheader']="Name"; +$fields_servers[0]['colwidth']="20%"; +$fields_servers[0]['type']="textbox"; +$fields_servers[0]['size']="30"; +$fields_servers[1]['name']="address"; +$fields_servers[1]['columnheader']="Address"; +$fields_servers[1]['colwidth']="10%"; +$fields_servers[1]['type']="textbox"; +$fields_servers[1]['size']="20"; +$fields_servers[2]['name']="port"; +$fields_servers[2]['columnheader']="Port"; +$fields_servers[2]['colwidth']="5%"; +$fields_servers[2]['type']="textbox"; +$fields_servers[2]['size']="5"; +$fields_servers[3]['name']="ssl"; +$fields_servers[3]['columnheader']="SSL"; +$fields_servers[3]['colwidth']="5%"; +$fields_servers[3]['type']="checkbox"; +$fields_servers[3]['size']="30"; +$fields_servers[4]['name']="weight"; +$fields_servers[4]['columnheader']="Weight"; +$fields_servers[4]['colwidth']="8%"; +$fields_servers[4]['type']="textbox"; +$fields_servers[4]['size']="5"; +$fields_servers[5]['name']="status"; +$fields_servers[5]['columnheader']="Mode"; +$fields_servers[5]['colwidth']="5%"; +$fields_servers[5]['type']="select"; +$fields_servers[5]['size']="5"; +$fields_servers[5]['items']=&$a_servermodes; +$fields_servers[6]['name']="advanced"; +$fields_servers[6]['columnheader']="Advanced"; +$fields_servers[6]['colwidth']="15%"; +$fields_servers[6]['type']="textbox"; +$fields_servers[6]['size']="20"; + if (isset($id) && $a_pools[$id]) { $pconfig['advanced'] = base64_decode($a_pools[$id]['advanced']); $pconfig['advanced_backend'] = base64_decode($a_pools[$id]['advanced_backend']); @@ -115,45 +156,28 @@ if ($_POST) { if (($_POST['name'] == $config['installedpackages']['haproxy']['ha_pools']['item'][$i]['name']) && ($i != $id)) $input_errors[] = "This pool name has already been used. Pool names must be unique."; - $a_servers=array(); - for($x=0; $x<99; $x++) { - $server_name = $_POST['server_name'.$x]; - $server_address = $_POST['server_address'.$x]; - $server_port = $_POST['server_port'.$x]; - $server_ssl = $_POST['server_ssl'.$x]; - $server_weight = $_POST['server_weight'.$x]; - $server_status = $_POST['server_status'.$x]; - $server_advanced = $_POST['server_advanced'.$x]; - - if ($server_address) { - $server = array(); - $server['name'] = $server_name; - $server['address'] = $server_address; - $server['port'] = $server_port; - $server['ssl'] = $server_ssl; - $server['weight'] = $server_weight; - $server['status'] = $server_status; - $server['advanced'] = $server_advanced; - $a_servers[] = $server; - - if (preg_match("/[^a-zA-Z0-9\.\-_]/", $server_name)) - $input_errors[] = "The field 'Name' contains invalid characters."; - if (!is_ipaddr($server_address)) - $input_errors[] = "The field 'Address' contains invalid characters."; - - if (!preg_match("/.{2,}/", $server_name)) - $input_errors[] = "The field 'Name' is required (and must be at least 2 characters)."; - - if (!preg_match("/.{2,}/", $server_address)) - $input_errors[] = "The field 'Address' is required (and must be at least 2 characters)."; - - - if (!is_numeric($server_weight)) - $input_errors[] = "The field 'Weight' value is not a number."; - - if ($server_port && !is_numeric($server_port)) - $input_errors[] = "The field 'Port' value is not a number."; - } + $a_servers = haproxy_htmllist_get_values($fields_servers); + foreach($a_servers as $server){ + $server_name = $server['name']; + $server_address = $server['address']; + $server_port = $server['port']; + $server_weight = $server['weight']; + if (preg_match("/[^a-zA-Z0-9\.\-_]/", $server_name)) + $input_errors[] = "The field 'Name' contains invalid characters."; + if (!is_ipaddr($server_address)) + $input_errors[] = "The field 'Address' is not a valid ip address."; + + if (!preg_match("/.{2,}/", $server_name)) + $input_errors[] = "The field 'Name' is required (and must be at least 2 characters)."; + + if (!preg_match("/.{2,}/", $server_address)) + $input_errors[] = "The field 'Address' is required (and must be at least 2 characters)."; + + if (!is_numeric($server_weight)) + $input_errors[] = "The field 'Weight' value is not a number."; + + if ($server_port && !is_numeric($server_port)) + $input_errors[] = "The field 'Port' value is not a number."; } if (!$input_errors) { @@ -216,20 +240,16 @@ $pfSversion = str_replace("\n", "", file_get_contents("/etc/version")); if(strstr($pfSversion, "1.2")) $one_two = true; +$closehead = false; $pgtitle = "HAProxy: Backend server pool: Edit"; include("head.inc"); -row_helper(); - // 'processing' done, make all simple fields usable in html. foreach($simplefields as $field){ $pconfig[$field] = htmlspecialchars($pconfig[$field]); } -?> - -<input type='hidden' name='address_type' value='textbox' /> -<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +?> <style type="text/css"> .haproxy_stats_visible{display:none;} .haproxy_check_enabled{display:none;} @@ -238,8 +258,15 @@ foreach($simplefields as $field){ .haproxy_check_smtp{display:none;} .haproxy_transparent_clientip{display:none;} .haproxy_check_agent{display:none;} + .haproxy_agent_check{display:none;} </style> -<script language="javascript"> +</head> +<body link="#0000CC" vlink="#0000CC" alink="#0000CC"> +<script type="text/javascript"> + function htmllist_get_select_options(tableId) { + return "<?=haproxy_js_select_options($a_servermodes);?>"; + } + function clearcombo(){ for (var i=document.iform.serversSelect.options.length-1; i>=0; i--){ document.iform.serversSelect.options[i] = null; @@ -273,6 +300,8 @@ foreach($simplefields as $field){ setCSSdisplay(".haproxy_check_username", check_type == 'MySQL' || check_type == 'PostgreSQL'); setCSSdisplay(".haproxy_check_smtp", check_type == 'SMTP' || check_type == 'ESMTP'); setCSSdisplay(".haproxy_check_agent", check_type == 'Agent'); + + setCSSdisplay(".haproxy_agent_check", agent_check.checked); transparent_clientip = d.getElementById("transparent_clientip"); setCSSdisplay(".haproxy_transparent_clientip", transparent_clientip.checked); @@ -285,31 +314,6 @@ foreach($simplefields as $field){ sqlcheckusername.innerText = monitor_username.value; } } - - -</script> -<script type="text/javascript"> - rowname[0] = "server_name"; - rowtype[0] = "textbox"; - rowsize[0] = "30"; - rowname[1] = "server_address"; - rowtype[1] = "textbox"; - rowsize[1] = "20"; - rowname[2] = "server_port"; - rowtype[2] = "textbox"; - rowsize[2] = "5"; - rowname[3] = "server_ssl"; - rowtype[3] = "checkbox"; - rowsize[3] = "5"; - rowname[4] = "server_weight"; - rowtype[4] = "textbox"; - rowsize[4] = "5"; - rowname[5] = "server_status"; - rowtype[5] = "select"; - rowsize[5] = "1"; - rowname[6] = "server_advanced"; - rowtype[6] = "textbox"; - rowsize[6] = "20"; </script> <?php include("fbegin.inc"); ?> <?php if ($input_errors) print_input_errors($input_errors); ?> @@ -339,13 +343,13 @@ foreach($simplefields as $field){ <tr align="left"> <td width="22%" valign="top" class="vncellreq">Name</td> <td width="78%" class="vtable" colspan="2"> - <input name="name" type="text" <?if(isset($pconfig['name'])) echo "value=\"{$pconfig['name']}\"";?> size="16" maxlength="16"> + <input name="name" type="text" <?if(isset($pconfig['name'])) echo "value=\"{$pconfig['name']}\"";?> size="16" maxlength="16" /> </td> </tr> <tr align="left"> <td width="22%" valign="top" class="vncell">Cookie</td> <td width="78%" class="vtable" colspan="2"> - <input name="cookie" type="text" <?if(isset($pconfig['cookie'])) echo "value=\"{$pconfig['cookie']}\"";?>size="64"><br/> + <input name="cookie" type="text" <?if(isset($pconfig['cookie'])) echo "value=\"{$pconfig['cookie']}\"";?>size="64" /><br/> This value will be checked in incoming requests, and the first operational pool possessing the same value will be selected. In return, in cookie insertion or rewrite modes, this value will be assigned to the cookie @@ -357,88 +361,11 @@ foreach($simplefields as $field){ </tr> <tr align="left"> <td class="vncell" colspan="3"><strong>Server list</strong> - - <table class="" width="100%" cellpadding="0" cellspacing="0" id='servertable'> - <tr> - <td width="20%" class="listhdrr">Name</td> - <td width="10%" class="listhdrr">Address</td> - <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="listhdrr">Mode</td> - <td width="15%" class="listhdr">Advanced</td> - <td width="4%" class=""></td> - </tr> - <?php - $a_servers=$pconfig['a_servers']; - - if (!is_array($a_servers)) { - $a_servers=array(); - } - + <? $counter=0; - foreach ($a_servers as $server) { - ?> - <tr id="tr_view_<?=$counter;?>" name="tr_view_<?=$counter;?>" ondblclick="editRow(<?=$counter;?>); return false;" > - <td class="vtable listlr"><?=$server['name']; ?></td> - <td class="vtable listr"><?=$server['address']; ?></td> - <td class="vtable listr"><?=$server['port']; ?></td> - <td class="vtable listr"><?=$server['ssl']=='yes'?'yes':'no'; ?></td> - <td class="vtable listr"><?=$server['weight']; ?></td> - <td class="vtable listr"><?=$server['status']; ?></td> - <td class="vtable listr"><?=htmlspecialchars($server['advanced']); ?></td> - <td class="list"> - <table border="0" cellspacing="0" cellpadding="1"><tr> - <td valign="middle"> - <img src="/themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" title="edit entry" width="17" height="17" border="0" onclick="editRow(<?=$counter;?>); return false;"> - </td> - <td valign="middle"> - <img src="/themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" title="delete entry" width="17" height="17" border="0" onclick="deleteRow(<?=$counter;?>, 'servertable'); return false;"> - </td> - <td valign="middle"> - <img src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" title="duplicate entry" width="17" height="17" border="0" onclick="dupRow(<?=$counter;?>, 'servertable'); return false;"> - </td></tr></table> - </td> - </tr> - <tr id="tr_edit_<?=$counter;?>" name="tr_edit_<?=$counter;?>" style="display: none;"> - <td class="vtable"> - <input name="server_name<?=$counter;?>" id="server_name<?=$counter;?>" type="text" value="<?=$server['name']; ?>" size="30"/></td> - <td class="vtable"> - <input name="server_address<?=$counter;?>" id="server_address<?=$counter;?>" type="text" value="<?=$server['address']; ?>" size="20"/></td> - <td class="vtable"> - <input name="server_port<?=$counter;?>" id="server_port<?=$counter;?>" type="text" value="<?=$server['port']; ?>" size="5"/></td> - <td class="vtable"> - <input name="server_ssl<?=$counter;?>" id="server_ssl<?=$counter;?>" type="checkbox" value="yes" <?=$server['ssl']=='yes'?"checked":""; ?> size="5"/></td> - <td class="vtable"> - <input name="server_weight<?=$counter;?>" id="server_weight<?=$counter;?>" type="text" value="<?=$server['weight']; ?>" size="5"/></td> - <td class="vtable"> - <select name="server_status<?=$counter;?>" id="server_status<?=$counter;?>"> - <option value="active" <?php if($server['status']=='active') echo "SELECTED";?>>active</option> - <option value="backup" <?php if($server['status']=='backup') echo "SELECTED";?>>backup</option> - <option value="disabled" <?php if($server['status']=='disabled') echo "SELECTED";?>>disabled</option> - <option value="inactive" <?php if($server['status']=='inactive') echo "SELECTED";?>>inactive</option> - </select> - </td> - <td class="vtable"> - <input name="server_advanced<?=$counter;?>" id="server_advanced<?=$counter;?>" type="text" value="<?=htmlspecialchars($server['advanced']); ?>" size="20"/></td> - <td class="list"> - <table border="0" cellspacing="0" cellpadding="1"><tr> - <td valign="middle"> - <img src="/themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" title="delete entry" width="17" height="17" border="0" onclick="removeRow(this); return false;"> - </td> - <td valign="middle"> - <img src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" title="duplicate entry" width="17" height="17" border="0" onclick="dupRow(<?=$counter;?>, 'servertable'); return false;"> - </td></tr></table> - </td> - </tr> - <?php - $counter++; - } + $a_servers = $pconfig['a_servers']; + haproxy_htmllist("tableA_servers", $a_servers, $fields_servers); ?> - </table> - <a onclick="javascript:addRowTo('servertable'); return false;" href="#"> - <img border="0" src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" alt="" title="add another entry" /> - </a> </td> </tr> <tr align="left"> @@ -447,7 +374,7 @@ foreach($simplefields as $field){ <table width="100%"> <tr> <td width="25%" valign="top"> - <input type="radio" name="balance" id="balance" value="roundrobin"<?php if($pconfig['balance'] == "roundrobin") echo " CHECKED"; ?>>Round robin</input> + <input type="radio" name="balance" value="roundrobin"<?php if($pconfig['balance'] == "roundrobin") echo " CHECKED"; ?> />Round robin </td> <td> Each server is used in turns, according to their weights. @@ -459,7 +386,7 @@ foreach($simplefields as $field){ </tr> <tr> <td width="25%" valign="top"> - <input type="radio" name="balance" id="balance" value="static-rr"<?php if($pconfig['balance'] == "static-rr") echo " CHECKED"; ?>>Static Round Robin</input> + <input type="radio" name="balance" value="static-rr"<?php if($pconfig['balance'] == "static-rr") echo " CHECKED"; ?> />Static Round Robin </td> <td> Each server is used in turns, according to their weights. @@ -474,7 +401,7 @@ foreach($simplefields as $field){ </tr> <tr> <td width="25%" valign="top"> - <input type="radio" name="balance" id="balance" value="leastconn"<?php if($pconfig['balance'] == "leastconn") echo " CHECKED"; ?>>Least Connections</input> + <input type="radio" name="balance" value="leastconn"<?php if($pconfig['balance'] == "leastconn") echo " CHECKED"; ?> />Least Connections </td> <td> The server with the lowest number of connections receives the @@ -487,8 +414,9 @@ foreach($simplefields as $field){ adjusted on the fly for slow starts for instance. </td> </tr> - <tr><td valign="top"><input type="radio" name="balance" id="balance" value="source"<?php if($pconfig['balance'] == -"source") echo " CHECKED"; ?>>Source</input></td><td> + <tr><td valign="top"><input type="radio" name="balance" value="source"<?php if($pconfig['balance'] == "source") echo " CHECKED"; ?> />Source + </td> + <td> The source IP address is hashed and divided by the total weight of the running servers to designate which server will receive the request. This ensures that the same client IP @@ -509,7 +437,7 @@ foreach($simplefields as $field){ <tr align="left"> <td width="22%" valign="top" class="vncell">Transparent ClientIP</td> <td width="78%" class="vtable" colspan="2"> - <input id="transparent_clientip" name="transparent_clientip" type="checkbox" value="yes" <?php if ($pconfig['transparent_clientip']=='yes') echo "checked"; ?> onclick='updatevisibility();'> + <input id="transparent_clientip" name="transparent_clientip" type="checkbox" value="yes" <?php if ($pconfig['transparent_clientip']=='yes') echo "checked"; ?> onclick='updatevisibility();' /> Use Client-IP to connect to backend servers. <div class="haproxy_transparent_clientip"> @@ -535,7 +463,7 @@ foreach($simplefields as $field){ <tr align="left"> <td width="22%" valign="top" class="vncell">Per server pass thru</td> <td width="78%" class="vtable" colspan="2"> - <input type="text" name='advanced' id='advanced' value='<?php echo $pconfig['advanced']; ?>' size="64"> + <input type="text" name='advanced' id='advanced' value='<?php echo $pconfig['advanced']; ?>' size="64" /> <br/> NOTE: paste text into this box that you would like to pass thru. Applied to each 'server' line. </td> @@ -565,7 +493,7 @@ foreach($simplefields as $field){ <tr align="left" class="haproxy_check_enabled"> <td width="22%" valign="top" class="vncell">Check frequency</td> <td width="78%" class="vtable" colspan="2"> - <input name="checkinter" type="text" <?if(isset($pconfig['checkinter'])) echo "value=\"{$pconfig['checkinter']}\"";?>size="20"> milliseconds + <input name="checkinter" type="text" <?if(isset($pconfig['checkinter'])) echo "value=\"{$pconfig['checkinter']}\"";?> size="20" /> milliseconds <br/>For HTTP/HTTPS defaults to 1000 if left blank. For TCP no check will be performed if left empty. </td> </tr> @@ -581,14 +509,14 @@ foreach($simplefields as $field){ <tr align="left" class="haproxy_check_http"> <td width="22%" valign="top" class="vncell">Http check URI</td> <td width="78%" class="vtable" colspan="2"> - <input name="monitor_uri" type="text" <?if(isset($pconfig['monitor_uri'])) echo "value=\"{$pconfig['monitor_uri']}\"";?>size="64"> + <input name="monitor_uri" type="text" <?if(isset($pconfig['monitor_uri'])) echo "value=\"{$pconfig['monitor_uri']}\"";?>size="64" /> <br/>Defaults to / if left blank. </td> </tr> <tr align="left" class="haproxy_check_http"> <td width="22%" valign="top" class="vncell">Http check version</td> <td width="78%" class="vtable" colspan="2"> - <input name="monitor_httpversion" type="text" <?if(isset($pconfig['monitor_httpversion'])) echo "value=\"{$pconfig['monitor_httpversion']}\"";?>size="64"> + <input name="monitor_httpversion" type="text" <?if(isset($pconfig['monitor_httpversion'])) echo "value=\"{$pconfig['monitor_httpversion']}\"";?> size="64" /> <br/>Defaults to "HTTP/1.0" if left blank. Note that the Host field is mandatory in HTTP/1.1, and as a trick, it is possible to pass it after "\r\n" following the version string like this:<br/> @@ -600,29 +528,56 @@ foreach($simplefields as $field){ <tr align="left" class="haproxy_check_username"> <td width="22%" valign="top" class="vncell">Check with Username</td> <td width="78%" class="vtable" colspan="2"> - <input name="monitor_username" id="monitor_username" type="text" <?if(isset($pconfig['monitor_username'])) echo "value=\"{$pconfig['monitor_username']}\"";?>size="64" onchange="updatevisibility();" onkeyup="updatevisibility();"> + <input name="monitor_username" id="monitor_username" type="text" <?if(isset($pconfig['monitor_username'])) echo "value=\"{$pconfig['monitor_username']}\"";?>size="64" onchange="updatevisibility();" onkeyup="updatevisibility();" /> <br/> This is the username which will be used when connecting to MySQL/PostgreSQL server. <pre> USE mysql; -CREATE USER '<span id="sqlcheckusername" name="sqlcheckusername"></span>'@'<pfSenseIP>'; +CREATE USER '<span id="sqlcheckusername"></span>'@'<pfSenseIP>'; FLUSH PRIVILEGES;</pre> </td> </tr> <tr align="left" class="haproxy_check_smtp"> <td width="22%" valign="top" class="vncell">Domain</td> <td width="78%" class="vtable" colspan="2"> - <input name="monitor_domain" type="text" <?if(isset($pconfig['monitor_domain'])) echo "value=\"{$pconfig['monitor_domain']}\"";?>size="64"> + <input name="monitor_domain" type="text" <?if(isset($pconfig['monitor_domain'])) echo "value=\"{$pconfig['monitor_domain']}\"";?> size="64" /> </td> </tr> <tr align="left" class="haproxy_check_agent"> <td width="22%" valign="top" class="vncell">Agentport</td> <td width="78%" class="vtable" colspan="2"> - <input name="monitor_agentport" type="text" <?if(isset($pconfig['monitor_agentport'])) echo "value=\"{$pconfig['monitor_agentport']}\"";?>size="64"> + <input name="monitor_agentport" type="text" <?if(isset($pconfig['monitor_agentport'])) echo "value=\"{$pconfig['monitor_agentport']}\"";?> size="64" /> + <br/> + Fill in the TCP portnumber the healthcheck should be performed on. + </td> + </tr> + <tr><td> </td></tr> + <tr> + <td colspan="2" valign="top" class="listtopic">Agent checks</td> + </tr> + <tr align="left"> + <td width="22%" valign="top" class="vncell">Use agent checks</td> + <td width="78%" class="vtable" colspan="2"> + <input id="agent_check" name="agent_check" type="checkbox" value="yes" <?php if ($pconfig['agent_check']=='yes') echo "checked"; ?> onclick='updatevisibility();' /> + Use a TCP connection to read an ASCII string of the form 100%,75%,drain,down (more about this in the <a href='http://cbonte.github.io/haproxy-dconv/configuration-1.5.html#agent-check' target='_blank'>haproxy manual</a>) + </td> + </tr> + <tr align="left" class="haproxy_agent_check"> + <td width="22%" valign="top" class="vncell">Agent port</td> + <td width="78%" class="vtable" colspan="2"> + <input name="agent_port" type="text" <?if(isset($pconfig['agent_port'])) echo "value=\"{$pconfig['agent_port']}\"";?> size="64" /> <br/> Fill in the TCP portnumber the healthcheck should be performed on. </td> </tr> + <tr align="left" class="haproxy_agent_check"> + <td width="22%" valign="top" class="vncell">Agent interval</td> + <td width="78%" class="vtable" colspan="2"> + <input name="agent_inter" type="text" <?if(isset($pconfig['agent_inter'])) echo "value=\"{$pconfig['agent_inter']}\"";?> size="64" /> + <br/> + Interval between two agent checks, defaults to 2000 ms. + </td> + </tr> <tr><td> </td></tr> <tr> <td colspan="2" valign="top" class="listtopic">Advanced settings</td> @@ -630,21 +585,21 @@ FLUSH PRIVILEGES;</pre> <tr align="left"> <td width="22%" valign="top" class="vncell">Connection timeout</td> <td width="78%" class="vtable" colspan="2"> - <input name="connection_timeout" type="text" <?if(isset($pconfig['connection_timeout'])) echo "value=\"{$pconfig['connection_timeout']}\"";?> size="20"> + <input name="connection_timeout" type="text" <?if(isset($pconfig['connection_timeout'])) echo "value=\"{$pconfig['connection_timeout']}\"";?> size="20" /> <div>the time (in milliseconds) we give up if the connection does not complete within (default 30000).</div> </td> </tr> <tr align="left"> <td width="22%" valign="top" class="vncell">Server timeout</td> <td width="78%" class="vtable" colspan="2"> - <input name="server_timeout" type="text" <?if(isset($pconfig['server_timeout'])) echo "value=\"{$pconfig['server_timeout']}\"";?> size="20"> + <input name="server_timeout" type="text" <?if(isset($pconfig['server_timeout'])) echo "value=\"{$pconfig['server_timeout']}\"";?> size="20" /> <div>the time (in milliseconds) we accept to wait for data from the server, or for the server to accept data (default 30000).</div> </td> </tr> <tr align="left"> <td width="22%" valign="top" class="vncell">Retries</td> <td width="78%" class="vtable" colspan="2"> - <input name="retries" type="text" <?if(isset($pconfig['retries'])) echo "value=\"{$pconfig['retries']}\"";?> size="20"> + <input name="retries" type="text" <?if(isset($pconfig['retries'])) echo "value=\"{$pconfig['retries']}\"";?> size="20" /> <div>After a connection failure to a server, it is possible to retry, potentially on another server. This is useful if health-checks are too rare and you don't want the clients to see the failures. The number of attempts to reconnect is @@ -658,72 +613,72 @@ set by the 'retries' parameter.</div> <tr align="left"> <td width="22%" valign="top" class="vncell">Stats Enabled</td> <td width="78%" class="vtable" colspan="2"> - <input id="stats_enabled" name="stats_enabled" type="checkbox" value="yes" <?php if ($pconfig['stats_enabled']=='yes') echo "checked"; ?> onclick='updatevisibility();'> + <input id="stats_enabled" name="stats_enabled" type="checkbox" value="yes" <?php if ($pconfig['stats_enabled']=='yes') echo "checked"; ?> onclick='updatevisibility();' /> </td> </tr> - <tr class="haproxy_stats_visible" align="left" id='stats_realm_row' name='stats_realm_row'> + <tr class="haproxy_stats_visible" align="left" id='stats_realm_row'> <td width="22%" valign="top" class="vncellreq">Stats Realm</td> <td width="78%" class="vtable" colspan="2"> - <input id="stats_realm" name="stats_realm" type="text" <?if(isset($pconfig['stats_realm'])) echo "value=\"{$pconfig['stats_realm']}\"";?> size="64"><br/> + <input id="stats_realm" name="stats_realm" type="text" <?if(isset($pconfig['stats_realm'])) echo "value=\"{$pconfig['stats_realm']}\"";?> size="64" /><br/> EXAMPLE: haproxystats </td> </tr> - <tr class="haproxy_stats_visible" align="left" id='stats_uri_row' name='stats_uri_row'> + <tr class="haproxy_stats_visible" align="left" id='stats_uri_row'> <td width="22%" valign="top" class="vncellreq">Stats Uri</td> <td width="78%" class="vtable" colspan="2"> - <input id="stats_uri" name="stats_uri" type="text" <?if(isset($pconfig['stats_uri'])) echo "value=\"{$pconfig['stats_uri']}\"";?> size="64"><br/> + <input id="stats_uri" name="stats_uri" type="text" <?if(isset($pconfig['stats_uri'])) echo "value=\"{$pconfig['stats_uri']}\"";?> size="64" /><br/> EXAMPLE: /haproxy?stats </td> </tr> - <tr class="haproxy_stats_visible" align="left" id='stats_username_row' name='stats_username_row'> + <tr class="haproxy_stats_visible" align="left" id='stats_username_row'> <td width="22%" valign="top" class="vncellreq">Stats Username</td> <td width="78%" class="vtable" colspan="2"> - <input id="stats_username" name="stats_username" type="text" <?if(isset($pconfig['stats_username'])) echo "value=\"".$pconfig['stats_username']."\"";?> size="64"> + <input id="stats_username" name="stats_username" type="text" <?if(isset($pconfig['stats_username'])) echo "value=\"".$pconfig['stats_username']."\"";?> size="64" /> </td> </tr> - <tr class="haproxy_stats_visible" align="left" id='stats_password_row' name='stats_password_row'> + <tr class="haproxy_stats_visible" align="left" id='stats_password_row'> <td width="22%" valign="top" class="vncellreq">Stats Password</td> <td width="78%" class="vtable" colspan="2"> <input id="stats_password" name="stats_password" type="password" <? if(isset($pconfig['stats_password'])) echo "value=\"".$pconfig['stats_password']."\""; - ?> size="64"> + ?> size="64" /> <br/> </td> </tr> - <tr class="haproxy_stats_visible" align="left" id='stats_node_admin_row' name='stats_node_enabled_row'> + <tr class="haproxy_stats_visible" align="left" id='stats_node_admin_row'> <td width="22%" valign="top" class="vncell">Stats Admin</td> <td width="78%" class="vtable" colspan="2"> - <input id="stats_admin" name="stats_admin" type="checkbox" value="yes" <?php if ($pconfig['stats_admin']=='yes') echo "checked"; ?>> + <input id="stats_admin" name="stats_admin" type="checkbox" value="yes" <?php if ($pconfig['stats_admin']=='yes') echo "checked"; ?> /> <br/> </td> </tr> - <tr class="haproxy_stats_visible" align="left" id='stats_node_enabled_row' name='stats_node_enabled_row'> + <tr class="haproxy_stats_visible" align="left" id='stats_node_enabled_row'> <td width="22%" valign="top" class="vncell">Stats Enable Node Name</td> <td width="78%" class="vtable" colspan="2"> - <input id="stats_node_enabled" name="stats_node_enabled" type="checkbox" value="yes" <?php if ($pconfig['stats_node_enabled']=='yes') echo "checked"; ?>> + <input id="stats_node_enabled" name="stats_node_enabled" type="checkbox" value="yes" <?php if ($pconfig['stats_node_enabled']=='yes') echo "checked"; ?> /> <br/> </td> </tr> - <tr class="haproxy_stats_visible" align="left" id='stats_node_row' name='stats_node_row'> + <tr class="haproxy_stats_visible" align="left" id='stats_node_row'> <td width="22%" valign="top" class="vncell">Stats Node</td> <td width="78%" class="vtable" colspan="2"> - <input id="stats_node" name="stats_node" type="text" <?if(isset($pconfig['stats_node'])) echo "value=\"{$pconfig['stats_node']}\"";?> size="64"><br/> + <input id="stats_node" name="stats_node" type="text" <?if(isset($pconfig['stats_node'])) echo "value=\"{$pconfig['stats_node']}\"";?> size="64" /><br/> The node name is displayed in the stats and helps to differentiate which server in a cluster is actually serving clients.<br/> Leave blank to use the system name. </td> </tr> - <tr class="haproxy_stats_visible" align="left" id='stats_desc_row' name='stats_desc_row'> + <tr class="haproxy_stats_visible" align="left" id='stats_desc_row'> <td width="22%" valign="top" class="vncell">Stats Description</td> <td width="78%" class="vtable" colspan="2"> - <input id="stats_desc" name="stats_desc" type="text" <?if(isset($pconfig['stats_node'])) echo "value=\"{$pconfig['stats_desc']}\"";?> size="64"><br/> + <input id="stats_desc" name="stats_desc" type="text" <?if(isset($pconfig['stats_node'])) echo "value=\"{$pconfig['stats_desc']}\"";?> size="64" /><br/> </td> </tr> - <tr class="haproxy_stats_visible" align="left" id='stats_refresh_row' name='stats_refresh_row'> + <tr class="haproxy_stats_visible" align="left" id='stats_refresh_row'> <td width="22%" valign="top" class="vncell">Stats Refresh</td> <td width="78%" class="vtable" colspan="2"> - <input id="stats_refresh" name="stats_refresh" type="text" <?if(isset($pconfig['stats_refresh'])) echo "value=\"{$pconfig['stats_refresh']}\"";?> size="10" maxlength="30"><br/> + <input id="stats_refresh" name="stats_refresh" type="text" <?if(isset($pconfig['stats_refresh'])) echo "value=\"{$pconfig['stats_refresh']}\"";?> size="10" maxlength="30" /><br/> Specify the refresh rate of the stats page in seconds, or specified time unit (us, ms, s, m, h, d). </td> </tr> @@ -731,10 +686,10 @@ set by the 'retries' parameter.</div> <tr align="left"> <td width="22%" valign="top"> </td> <td width="78%"> - <input name="Submit" type="submit" class="formbtn" value="Save"> - <input type="button" class="formbtn" value="Cancel" onclick="history.back()"> + <input name="Submit" type="submit" class="formbtn" value="Save" /> + <input type="button" class="formbtn" value="Cancel" onclick="history.back()" /> <?php if (isset($id) && $a_pools[$id]): ?> - <input name="id" type="hidden" value="<?=$id;?>"> + <input name="id" type="hidden" value="<?=$id;?>" /> <?php endif; ?> </td> </tr> @@ -742,170 +697,19 @@ set by the 'retries' parameter.</div> </div> </td></tr></table> </form> -<br> -<?php include("fend.inc"); ?> +<br/> <script type="text/javascript"> <? + phparray_to_javascriptarray($fields_servers,"fields_servers",Array('/*','/*/name','/*/type','/*/size','/*/items','/*/items/*','/*/items/*/*','/*/items/*/*/name')); phparray_to_javascriptarray($a_checktypes,"checktypes",Array('/*','/*/name','/*/descr')); ?> browser_InnerText_support = (document.getElementsByTagName("body")[0].innerText != undefined) ? true : false; - field_counter_js = 7; - rows = 1; totalrows = <?php echo $counter; ?>; - loaded = <?php echo $counter; ?>; updatevisibility(); </script> +<?php +haproxy_htmllist_js(); +include("fend.inc"); ?> </body> </html> - -<?php - -function row_helper() { - $options = <<<EOD - <option value='active' SELECTED>active</option>"+ -" <option value='backup'>backup</option>"+ -" <option value='disabled'>disabled</option>"+ -" <option value='inactive'>inactive</option> -EOD; - - echo <<<EOF -<script type="text/javascript"> -// Global Variables -var rowname = new Array(99); -var rowtype = new Array(99); -var newrow = new Array(99); -var rowsize = new Array(99); - -for (i = 0; i < 99; i++) { - rowname[i] = ''; - rowtype[i] = ''; - newrow[i] = ''; - rowsize[i] = '25'; -} - -var field_counter_js = 0; -var loaded = 0; -var is_streaming_progress_bar = 0; -var temp_streaming_text = ""; - -var addRowTo = (function() { - return (function (tableId) { - var d, tbody, tr, td, bgc, i, ii, j; - var btable, btbody, btr, btd; - - d = document; - tbody = d.getElementById(tableId).getElementsByTagName("tbody").item(0); - tr = d.createElement("tr"); - totalrows++; - for (i = 0; i < field_counter_js; i++) { - td = d.createElement("td"); - if(rowtype[i] == 'textbox') { - td.innerHTML="<INPUT type='hidden' value='" + totalrows +"' name='" + rowname[i] + "_row-" + totalrows + - "'></input><input size='" + rowsize[i] + "' name='" + rowname[i] + totalrows + - "' id='" + rowname[i] + totalrows + "'></input> "; - } else if(rowtype[i] == 'select') { - td.innerHTML="<INPUT type='hidden' value='" + totalrows +"' name='" + rowname[i] + "_row-" + totalrows + - "'></input><select size='" + rowsize[i] + "' name='" + rowname[i] + totalrows + - "' id='" + rowname[i] + totalrows + "'>$options</select> "; - } else { - td.innerHTML="<INPUT type='hidden' value='" + totalrows +"' name='" + rowname[i] + "_row-" + totalrows + - "'></input><input type='checkbox' name='" + rowname[i] + totalrows + - "' id='" + rowname[i] + totalrows + "' value='yes'></input> "; - } - td.setAttribute("class","vtable"); - tr.appendChild(td); - } - td = d.createElement("td"); - td.rowSpan = "1"; - td.setAttribute("class","list"); - - // Recreate the button table. - btable = document.createElement("table"); - btable.setAttribute("border", "0"); - btable.setAttribute("cellspacing", "0"); - btable.setAttribute("cellpadding", "1"); - btbody = document.createElement("tbody"); - btr = document.createElement("tr"); - btd = document.createElement("td"); - btd.setAttribute("valign", "middle"); - btd.innerHTML = '<img src="/themes/' + theme + '/images/icons/icon_x.gif" title="delete entry" width="17" height="17" border="0" onclick="removeRow(this); return false;">'; - btr.appendChild(btd); - btd = document.createElement("td"); - btd.setAttribute("valign", "middle"); - btd.innerHTML = '<img src="/themes/' + theme + "/images/icons/icon_plus.gif\" title=\"duplicate entry\" width=\"17\" height=\"17\" border=\"0\" onclick=\"dupRow(" + totalrows + ", 'servertable'); return false;\">"; - btr.appendChild(btd); - btbody.appendChild(btr); - btable.appendChild(btbody); - - td.appendChild(btable); - tr.appendChild(td); - tbody.appendChild(tr); - }); -})(); - -function dupRow(rowId, tableId) { - var dupEl; - var newEl; - - addRowTo(tableId); - for (i = 0; i < field_counter_js; i++) { - dupEl = document.getElementById(rowname[i] + rowId); - newEl = document.getElementById(rowname[i] + totalrows); - if (dupEl && newEl) - if(rowtype[i] == 'checkbox') - newEl.checked = dupEl.checked; - else - newEl.value = dupEl.value; - } -} - -function deleteRow(rowId, tableId) { - var view = document.getElementById("tr_view_" + rowId); - var edit = document.getElementById("tr_edit_" + rowId); - - view.parentNode.removeChild(view); - edit.parentNode.removeChild(edit); -} - -function removeRow(el) { - var cel; - // Break out of one table first - while (el && el.nodeName.toLowerCase() != "table") - el = el.parentNode; - while (el && el.nodeName.toLowerCase() != "tr") - el = el.parentNode; - - if (el && el.parentNode) { - cel = el.getElementsByTagName("td").item(0); - el.parentNode.removeChild(el); - } -} -function editRow(num) { - var trview = document.getElementById('tr_view_' + num); - var tredit = document.getElementById('tr_edit_' + num); - - trview.style.display='none'; - tredit.style.display=''; -} - -function find_unique_field_name(field_name) { - // loop through field_name and strip off -NUMBER - var last_found_dash = 0; - for (var i = 0; i < field_name.length; i++) { - // is this a dash, if so, update - // last_found_dash - if (field_name.substr(i,1) == "-" ) - last_found_dash = i; - } - if (last_found_dash < 1) - return field_name; - return(field_name.substr(0,last_found_dash)); -} -</script> - -EOF; - -} - -?> diff --git a/config/haproxy-devel/haproxy_pools.php b/config/haproxy-devel/haproxy_pools.php index faffa810..39009633 100644 --- a/config/haproxy-devel/haproxy_pools.php +++ b/config/haproxy-devel/haproxy_pools.php @@ -3,6 +3,7 @@ /* haproxy_pools.php part of pfSense (http://www.pfsense.com/) + Copyright (C) 2013 PiBa-NL Copyright (C) 2009 Scott Ullrich <sullrich@pfsense.com> Copyright (C) 2008 Remco Hoef <remcoverhoef@pfsense.com> All rights reserved. @@ -79,8 +80,8 @@ include("head.inc"); <form action="haproxy_pools.php" method="post"> <?php if ($input_errors) print_input_errors($input_errors); ?> <?php if ($savemsg) print_info_box($savemsg); ?> -<?php if (file_exists($d_haproxyconfdirty_path)): ?><p> -<?php print_info_box_np("The haproxy configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br> +<?php if (file_exists($d_haproxyconfdirty_path)): ?> +<?php print_info_box_np("The haproxy configuration has been changed.<br/>You must apply the changes in order for them to take effect.");?><br/> <?php endif; ?> <table width="100%" border="0" cellpadding="0" cellspacing="0"> <tr><td class="tabnavtbl"> @@ -128,13 +129,13 @@ include("head.inc"); <td class="listlr" ondblclick="document.location='haproxy_pool_edit.php?id=<?=$i;?>';"> <? if ($pool['stats_enabled']=='yes'){ - echo "<img src=\"./themes/{$g['theme']}/images/icons/icon_log_s.gif\"" . ' title="stats enabled" width="11" height="15" border="0">'; + echo "<img src=\"./themes/{$g['theme']}/images/icons/icon_log_s.gif\"" . ' title="stats enabled" width="11" height="15" border="0" />'; } $isadvset = ""; if ($pool['advanced']) $isadvset .= "Per server pass thru\r\n"; if ($pool['advanced_backend']) $isadvset .= "Backend pass thru\r\n"; if ($isadvset) - echo "<img src=\"$img_adv\" title=\"" . gettext("advanced settings set") . ": {$isadvset}\" border=\"0\">"; + echo "<img src=\"$img_adv\" title=\"" . gettext("advanced settings set") . ": {$isadvset}\" border=\"0\" />"; ?> </td> <td class="listlr" ondblclick="document.location='haproxy_pool_edit.php?id=<?=$i;?>';"> @@ -152,9 +153,9 @@ include("head.inc"); <td class="list" nowrap> <table border="0" cellspacing="0" cellpadding="1"> <tr> - <td valign="middle"><a href="haproxy_pool_edit.php?id=<?=$i;?>"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" title="<?=gettext("edit backend");?>" width="17" height="17" border="0"></a></td> - <td valign="middle"><a href="haproxy_pools.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this entry?')"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" title="<?=gettext("delete backend");?>" width="17" height="17" border="0"></a></td> - <td valign="middle"><a href="haproxy_pool_edit.php?dup=<?=$i;?>"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" title="<?=gettext("clone backend");?>" width="17" height="17" border="0"></a></td> + <td valign="middle"><a href="haproxy_pool_edit.php?id=<?=$i;?>"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" title="<?=gettext("edit backend");?>" width="17" height="17" border="0" /></a></td> + <td valign="middle"><a href="haproxy_pools.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this entry?')"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" title="<?=gettext("delete backend");?>" width="17" height="17" border="0" /></a></td> + <td valign="middle"><a href="haproxy_pool_edit.php?dup=<?=$i;?>"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" title="<?=gettext("clone backend");?>" width="17" height="17" border="0" /></a></td> </tr> </table> </td> @@ -169,7 +170,7 @@ include("head.inc"); <td class="list"> <table border="0" cellspacing="0" cellpadding="1"> <tr> - <td valign="middle"><a href="haproxy_pool_edit.php"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" title="<?=gettext("add new backend");?>" width="17" height="17" border="0"></a></td> + <td valign="middle"><a href="haproxy_pool_edit.php"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" title="<?=gettext("add new backend");?>" width="17" height="17" border="0" /></a></td> </tr> </table> </td> diff --git a/config/haproxy-devel/haproxy_socketinfo.inc b/config/haproxy-devel/haproxy_socketinfo.inc index 5b31afeb..eeaba8b6 100644 --- a/config/haproxy-devel/haproxy_socketinfo.inc +++ b/config/haproxy-devel/haproxy_socketinfo.inc @@ -1,5 +1,6 @@ <?php /* + Copyright (C) 2013 PiBa-NL Copyright 2011 Thomas Schaefer - Tomschaefer.org Copyright 2011 Marcello Coutinho Part of pfSense widgets (www.pfsense.com) diff --git a/config/haproxy-devel/haproxy_utils.inc b/config/haproxy-devel/haproxy_utils.inc index f4df2433..058efc98 100644 --- a/config/haproxy-devel/haproxy_utils.inc +++ b/config/haproxy-devel/haproxy_utils.inc @@ -41,6 +41,7 @@ function haproxy_interface_ip($interfacebindname,$userfriendly=false){ $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. @@ -73,9 +74,18 @@ function haproxy_get_bindable_interfaces($ipv="ipv4,ipv6", $interfacetype="any,l continue; if (!isset($ifdetail['ipaddr'])) continue; + $descr = $ifdetail['descr']; + if (!$descr){ + if ($if == "wan" && !$ifdetail['descr']) + $descr = "WAN"; + else if ($if == "lan" && !$ifdetail['descr']) + $descr = "LAN"; + else + $descr = $if; + } $item = array(); - $item[ip] = get_interface_ip($if); - $item[name] = $ifdetail['descr'].' address (IPv4)'; + $item['ip'] = get_interface_ip($if); + $item['name'] = "$descr address (IPv4)"; $bindable[$if.'_ipv4'] = $item; } } @@ -103,6 +113,9 @@ function haproxy_get_bindable_interfaces($ipv="ipv4,ipv6", $interfacetype="any,l } } } + if (!isset($config['system']['ipv6allow'])) + return $bindable;// skip adding the IPv6 addresses if those are not 'allowed' + if (in_array("ipv6",$ipverions)){ if (in_array('any',$interfacetypes)){ $item = array(); @@ -122,9 +135,18 @@ function haproxy_get_bindable_interfaces($ipv="ipv4,ipv6", $interfacetype="any,l continue; if (!isset($ifdetail['ipaddrv6'])) continue; + $descr = $ifdetail['descr']; + if (!$descr){ + if ($if == "wan" && !$ifdetail['descr']) + $descr = "WAN"; + else if ($if == "lan" && !$ifdetail['descr']) + $descr = "LAN"; + else + $descr = $if; + } $item = array(); - $item[ip] = get_interface_ipv6($if); - $item[name] = $ifdetail['descr'].' address (IPv6)'; + $item['ip'] = get_interface_ipv6($if); + $item['name'] = "$descr address (IPv6)"; $bindable[$if.'_ipv6'] = $item; } } @@ -225,6 +247,69 @@ function haproxy_recalculate_certifcate_chain(){ return $items_recalculated; } +function get_certificat_usage($refid) { + $usage = array(); + $cert = lookup_cert($refid); + if (is_cert_revoked($cert)) + $usage[] = "Revoked"; + if (is_webgui_cert($refid)) + $usage[] = "webConfigurator"; + if (is_user_cert($refid)) + $usage[] = "User Cert"; + if (is_openvpn_server_cert($refid)) + $usage[] = "OpenVPN Server"; + if (is_openvpn_client_cert($refid)) + $usage[] = "OpenVPN Client"; + if (is_ipsec_cert($cert['refid'])) + $usage[] = "IPsec Tunnel"; + if (function_exists("is_captiveportal_cert")) + if (is_captiveportal_cert($refid)) + $usage[] = "Captive Portal"; + + return $usage; +} +function get_certificates_server($get_includeWebCert=false) { + // This function (is intended to) provide a uniform way to retrieve a list of server certificates + global $config; + $certificates=array(); + $a_cert = &$config['cert']; + foreach ($a_cert as $cert) + { + if ($get_ca == false && is_webgui_cert($cert['refid'])) + continue; + + $purpose = cert_get_purpose($cert['crt']); + //$certserverpurpose = $purpose['server'] == 'Yes' ? " [Server certificate]" : ""; + $certserverpurpose = ""; + + $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"; + + $usagestr=""; + $usage = get_certificat_usage($cert['refid']); + foreach($usage as $use){ + $usagestr .= " " . $use; + } + if ($usagestr != "") + $usagestr = " (".trim($usagestr).")"; + + $certificates[$cert['refid']]['name'] = $cert['descr'] . $caname . $certserverpurpose . $inuse . $revoked . $usagestr; + } + return $certificates; +} + + function phparray_to_javascriptarray_recursive($nestID, $path, $items, $nodeName, $includeitems) { $offset = str_repeat(' ',$nestID); $itemName = "item$nestID"; @@ -241,25 +326,51 @@ function phparray_to_javascriptarray_recursive($nestID, $path, $items, $nodeName $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"; + } else { + $item = json_encode($item); + echo "{$offset}{$nodeName}['$key'] = $item;\n"; + } } } } function phparray_to_javascriptarray($items, $javaMapName, $includeitems) { - phparray_to_javascriptarray_recursive(1,'',$items, $javaMapName, $includeitems); + phparray_to_javascriptarray_recursive(1,'',$items, $javaMapName, $includeitems); +} + +function haproxy_html_select_options($keyvaluelist, $selected="") { + $result = ""; + foreach($keyvaluelist as $key => $desc){ + $selectedhtml = $key == $selected ? "selected" : ""; + if ($desc['deprecated'] && $key != $selected){ + continue; + } + $name = htmlspecialchars($desc['name']); + $result .= "<option value='{$key}' {$selectedhtml}>{$name}</option>"; + } + return $result; } -function echo_html_select($name, $keyvaluelist, $selected, $listEmptyMessage="", $onchangeEvent="") { +function haproxy_js_select_options($keyvaluelist, $selected="") { + $result = ""; + foreach($keyvaluelist as $key => $desc){ + $selectedhtml = $key == $selected ? "selected" : ""; + if ($desc['deprecated'] && $key != $selected){ + continue; + } + $name = htmlspecialchars($desc['name']); + $result .= "<option value='{$key}' {$selectedhtml}>{$name}<\/option>"; + } + return $result; +} + +function echo_html_select($name, $keyvaluelist, $selected, $listEmptyMessage="", $onchangeEvent="", $style="") { 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" : ""; - $name = htmlspecialchars($desc['name']); - echo "<option value=\"{$key}\" {$selectedhtml}>{$name}</option>"; - } + $onchangeEvent = " onchange='$onchangeEvent'"; + if ($style != "") + $style = " style='$style'"; + echo "<select name=\"$name\" id=\"$name\" class=\"formselect\"$onchangeEvent$style>"; + echo haproxy_html_select_options($keyvaluelist, $selected); echo "</select>"; } else { echo $listEmptyMessage; diff --git a/config/haproxy-devel/haproxy_xmlrpcsyncclient.inc b/config/haproxy-devel/haproxy_xmlrpcsyncclient.inc index 781b7544..699dffd1 100644 --- a/config/haproxy-devel/haproxy_xmlrpcsyncclient.inc +++ b/config/haproxy-devel/haproxy_xmlrpcsyncclient.inc @@ -1,6 +1,7 @@ <?php /* haproxy_xmlrpcsyncclient.inc + Copyright (C) 2013 PiBa-NL Copyright (C) 2009 Scott Ullrich <sullrich@pfsense.com> Copyright (C) 2008 Remco Hoef All rights reserved. |