aboutsummaryrefslogtreecommitdiffstats
path: root/config/ovpnenhance
diff options
context:
space:
mode:
authormfuchs <martin.fuchs@trendchiller.com>2009-05-19 21:30:08 +0200
committermfuchs <martin.fuchs@trendchiller.com>2009-05-19 21:30:08 +0200
commit7d9e42f0b179417650e9b336fdf925b058863250 (patch)
treea37ab8059813e7ce843f44b8374f29c146d2e1df /config/ovpnenhance
parent1e6391adbc715503f008ec7efa0f5355d54bb558 (diff)
downloadpfsense-packages-7d9e42f0b179417650e9b336fdf925b058863250.tar.gz
pfsense-packages-7d9e42f0b179417650e9b336fdf925b058863250.tar.bz2
pfsense-packages-7d9e42f0b179417650e9b336fdf925b058863250.zip
add OpenVPN-TLS, etc... enhancements package for 1.2.x
Diffstat (limited to 'config/ovpnenhance')
-rw-r--r--config/ovpnenhance/openvpn.inc_tls668
-rw-r--r--config/ovpnenhance/openvpn.xml_tls329
-rw-r--r--config/ovpnenhance/openvpn_cli.xml_tls240
-rw-r--r--config/ovpnenhance/openvpn_csc.xml_tls169
-rw-r--r--config/ovpnenhance/ovpnenhance.inc13
-rw-r--r--config/ovpnenhance/ovpnenhance.xml40
6 files changed, 1459 insertions, 0 deletions
diff --git a/config/ovpnenhance/openvpn.inc_tls b/config/ovpnenhance/openvpn.inc_tls
new file mode 100644
index 00000000..9ea4c7da
--- /dev/null
+++ b/config/ovpnenhance/openvpn.inc_tls
@@ -0,0 +1,668 @@
+<?php
+
+/* $Id: openvpn.inc,v 1.55 2007/06/30 21:20:11 sullrich Exp $ */
+/*
+ $RCSfile: openvpn.inc,v $
+ Copyright (C) 2006 Fernando Lemos
+ All rights reserved.
+
+ Copyright (C) 2005 Peter Allgeyer <allgeyer_AT_web.de>
+ All rights reserved.
+
+ Copyright (C) 2004 Peter Curran (peter@closeconsultants.com).
+ 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 notices,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notices, 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, INDIRECT, 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.
+*/
+
+require_once('config.inc');
+require_once('pfsense-utils.inc');
+require_once('util.inc');
+
+// Return the list of ciphers OpenVPN supports
+function openvpn_get_ciphers($pkg) {
+ foreach ($pkg['fields']['field'] as $i => $field) {
+ if ($field['fieldname'] == 'crypto') break;
+ }
+ $option_array = &$pkg['fields']['field'][$i]['options']['option'];
+ $ciphers_out = shell_exec('openvpn --show-ciphers | grep "default key" | awk \'{print $1, "(" $2 "-" $3 ")";}\'');
+ $ciphers = explode("\n", trim($ciphers_out));
+ sort($ciphers);
+ foreach ($ciphers as $cipher) {
+ $value = explode(' ', $cipher);
+ $value = $value[0];
+ $option_array[] = array('value' => $value, 'name' => $cipher);
+ }
+}
+
+
+function openvpn_validate_port($value, $name) {
+ $value = trim($value);
+ if (!empty($value) && !(is_numeric($value) && ($value > 0) && ($value < 65535)))
+ return "The field '$name' must contain a valid port, ranging from 0 to 65535.";
+ return false;
+}
+
+
+function openvpn_validate_cidr($value, $name) {
+ $value = trim($value);
+ if (!empty($value)) {
+ list($ip, $mask) = explode('/', $value);
+ if (!is_ipaddr($ip) or !is_numeric($mask) or ($mask > 32) or ($mask < 0))
+ return "The field '$name' must contain a valid CIDR range.";
+ }
+ return false;
+}
+
+
+// Do the input validation
+function openvpn_validate_input($mode, $post, $input_errors) {
+ $Mode = ucfirst($mode);
+
+ if ($mode == 'server') {
+ if ($result = openvpn_validate_port($post['local_port'], 'Local port'))
+ $input_errors[] = $result;
+
+ if ($result = openvpn_validate_cidr($post['addresspool'], 'Address pool'))
+ $input_errors[] = $result;
+
+ if ($result = openvpn_validate_cidr($post['local_network'], 'Local network'))
+ $input_errors[] = $result;
+
+/* check for port in use - update of existing entries not possible because $_GET['act'] is not passed from pkg_edit.php :-( mfuchs
+ $portinuse = shell_exec('sockstat | grep '.$post['local_port'].' | grep '.strtolower($post['protocol']));
+ if (!empty($portinuse))
+ $input_errors[] = 'The port '.$post['local_port'].'/'.strtolower($post['protocol']).' is already in use.';
+*/
+
+ if (!empty($post['dhcp_dns'])) {
+ $servers = explode(';', $post['dhcp_dns']);
+ foreach ($servers as $server) if (!is_ipaddr($server))
+ {$input_errors[] = 'The field \'DHCP-Opt.: DNS-Server\' must contain a valid IP address and no whitespaces.';
+ break;}}
+ if (!empty($post['dhcp_wins'])) {
+ $servers = explode(';', $post['dhcp_wins']);
+ foreach ($servers as $server) if (!is_ipaddr($server))
+ {$input_errors[] = 'The field \'DHCP-Opt.: WINS-Server\' must contain a valid IP address and no whitespaces.';
+ break;}}
+ if (!empty($post['dhcp_nbdd'])) {
+ $servers = explode(';', $post['dhcp_nbdd']);
+ foreach ($servers as $server) if (!is_ipaddr($server))
+ {$input_errors[] = 'The field \'DHCP-Opt.: NBDD-Server\' must contain a valid IP address and no whitespaces.';
+ break;}}
+ if (!empty($post['dhcp_ntp'])) {
+ $servers = explode(';', $post['dhcp_ntp']);
+ foreach ($servers as $server) if (!is_ipaddr($server))
+ {$input_errors[] = 'The field \'DHCP-Opt.: NTP-Server\' must contain a valid IP address and no whitespaces.';
+ break;}}
+ if (isset($post['maxclients']) && $post['maxclients'] != "") {
+ if (!is_numeric($post['maxclients']))
+ $input_errors[] = 'The field \'Maximum clients\' must be numeric.';
+ }
+
+ }
+
+ else { // Client mode
+ if ($result = openvpn_validate_port($post['serverport'], 'Server port'))
+ $input_errors[] = $result;
+
+ $server_addr = trim($post['serveraddr']);
+ if (!empty($value) && !(is_domain($server_addr) || is_ipaddr($server_addr)))
+ $input_errors[] = 'The field \'Server address\' must contain a valid IP address or domain name.';
+
+ if ($result = openvpn_validate_cidr($post['interface_ip'], 'Interface IP'))
+ $input_errors[] = $result;
+
+ if ($post['auth_method'] == 'shared_key') {
+ if (empty($post['interface_ip']))
+ $input_errors[] = 'The field \'Interface IP\' is required.';
+ }
+ if (isset($post['proxy_hostname']) && $post['proxy_hostname'] != "") {
+ if (!is_domain($post['proxy_hostname']) || is_ipaddr($post['proxy_hostname']))
+ $input_errors[] = 'The field \'Proxy Host\' must contain a valid IP address or domain name.';
+ if (!is_port($post['proxy_port']))
+ $input_errors[] = 'The field \'Proxy port\' must contain a valid port number.';
+ if ($post['protocol'] != "TCP")
+ $input_errors[] = 'The protocol must be TCP to use a HTTP proxy server.';
+ }
+ if (isset($post['use_shaper']) && $post['use_shaper'] != "") {
+ if (!is_numeric($post['use_shaper']))
+ $input_errors[] = 'The field \'Limit outgoing bandwidth\' must be numeric.';
+ }
+
+ }
+
+ if ($result = openvpn_validate_cidr($post['remote_network'], 'Remote network'))
+ $input_errors[] = $result;
+
+ if ($_POST['auth_method'] == 'shared_key') {
+ $reqfields[] = 'shared_key';
+ $reqfieldsn[] = 'Shared key';
+ }
+ else {
+ $req = explode(' ', "ca_cert {$mode}_cert {$mode}_key");
+ $reqn = array( 'CA certificate',
+ ucfirst($mode) . ' certificate',
+ ucfirst($mode) . ' key');
+ $reqfields = array_merge($reqfields, $req);
+ $reqfieldsn = array_merge($reqfieldsn, $reqn);
+ if ($mode == 'server') {
+ $reqfields[] = 'dh_params';
+ $reqfieldsn[] = 'DH parameters';
+ }
+ }
+ do_input_validation($post, $reqfields, $reqfieldsn, &$input_errors);
+
+ $value = trim($post['shared_key']);
+ $items = array();
+
+ if ($_POST['auth_method'] == 'shared_key') {
+ $items[] = array( 'field' => 'shared_key',
+ 'string' => 'OpenVPN Static key V1',
+ 'name' => 'Shared key');
+ }
+ else {
+ $items[] = array( 'field' => 'ca_cert',
+ 'string' => 'CERTIFICATE',
+ 'name' => 'CA certificate');
+ $items[] = array( 'field' => "{$mode}_cert",
+ 'string' => 'CERTIFICATE',
+ 'name' => "$Mode certificate");
+ $items[] = array( 'field' => "{$mode}_key",
+ 'string' => 'RSA PRIVATE KEY',
+ 'name' => "$Mode key");
+ $items[] = array( 'field' => 'tls',
+ 'string' => 'OpenVPN Static key V1',
+ 'name' => 'TLS');
+ if ($mode == 'server') {
+ $items[] = array( 'field' => 'dh_params',
+ 'string' => 'DH PARAMETERS',
+ 'name' => 'DH parameters');
+ $items[] = array( 'field' => 'crl',
+ 'string' => 'X509 CRL',
+ 'name' => 'CRL');
+ }
+ }
+ foreach ($items as $item) {
+ $value = trim($_POST[$item['field']]);
+ $string = $item['string'];
+ if ($value && (!strstr($value, "-----BEGIN {$string}-----") || !strstr($value, "-----END {$string}-----")))
+ $input_errors[] = "The field '{$item['name']}' does not appear to be valid";
+ }
+}
+
+
+function openvpn_validate_input_csc($post, $input_errors) {
+ if ($result = openvpn_validate_cidr($post['ifconfig_push'], 'Interface IP'))
+ $input_errors[] = $result;
+
+ if ($post['push_reset'] != 'on') {
+ if (!empty($post['dhcp_domainname']))
+ $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
+ elseif (!empty($post['dhcp_dns']))
+ $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
+ elseif (!empty($post['dhcp_wins']))
+ $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
+ elseif (!empty($post['dhcp_nbdd']))
+ $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
+ elseif (!empty($post['dhcp_ntp']))
+ $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
+ elseif ($post['dhcp_nbttype'])
+ $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
+ elseif (!empty($post['dhcp_nbtscope']))
+ $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
+ elseif ($post['dhcp_nbtdisable'])
+ $input_errors[] = 'It makes no sense to unselect push reset and configure dhcp-options';
+
+ }
+ else {
+
+ if (!empty($post['dhcp_dns'])) {
+ $servers = explode(';', $post['dhcp_dns']);
+ foreach ($servers as $server) if (!is_ipaddr($server))
+ {$input_errors[] = 'The field \'DHCP-Opt.: DNS-Server\' must contain a valid IP address and no whitespaces.';
+ break;}}
+ if (!empty($post['dhcp_wins'])) {
+ $servers = explode(';', $post['dhcp_wins']);
+ foreach ($servers as $server) if (!is_ipaddr($server))
+ {$input_errors[] = 'The field \'DHCP-Opt.: WINS-Server\' must contain a valid IP address and no whitespaces.';
+ break;}}
+ if (!empty($post['dhcp_nbdd'])) {
+ $servers = explode(';', $post['dhcp_nbdd']);
+ foreach ($servers as $server) if (!is_ipaddr($server))
+ {$input_errors[] = 'The field \'DHCP-Opt.: NBDD-Server\' must contain a valid IP address and no whitespaces.';
+ break;}}
+ if (!empty($post['dhcp_ntp'])) {
+ $servers = explode(';', $post['dhcp_ntp']);
+ foreach ($servers as $server) if (!is_ipaddr($server))
+ {$input_errors[] = 'The field \'DHCP-Opt.: NTP-Server\' must contain a valid IP address and no whitespaces.';
+ break;}}
+
+}}
+
+// Rewrite the settings
+function openvpn_reconfigure($mode, $id) {
+ global $g, $config;
+
+ $settings = $config['installedpackages']["openvpn$mode"]['config'][$id];
+ if ($settings['disable']) return;
+
+ $lport = 1194 + $id;
+
+ // Set the keys up
+ // Note that the keys' extension is also the directive that goes to the config file
+ $base_file = $g['varetc_path'] . "/openvpn_{$mode}{$id}.";
+ $keys = array();
+ if ($settings['auth_method'] == 'shared_key')
+ $keys[] = array('field' => 'shared_key', 'ext' => 'secret', 'directive' => 'secret');
+ else {
+ $keys[] = array('field' => 'ca_cert', 'ext' => 'ca', 'directive' => 'ca');
+ $keys[] = array('field' => "{$mode}_cert", 'ext' => 'cert', 'directive' => 'cert');
+ $keys[] = array('field' => "{$mode}_key", 'ext' => 'key', 'directive' => 'key');
+ if ($mode == 'server')
+ $keys[] = array('field' => 'dh_params', 'ext' => 'dh', 'directive' => 'dh');
+ if ($settings['crl'])
+ $keys[] = array('field' => 'crl', 'ext' => 'crl', 'directive' => 'crl-verify');
+ if ($settings['tls'])
+ $keys[] = array('field' => 'tls', 'ext' => 'tls', 'directive' => 'tls-auth');
+
+ }
+ foreach($keys as $key) {
+ $filename = $base_file . $key['ext'];
+ file_put_contents($filename, base64_decode($settings[$key['field']]));
+ chown($filename, 'nobody');
+ chgrp($filename, 'nobody');
+ }
+
+ $pidfile = $g['varrun_path'] . "/openvpn_{$mode}{$id}.pid";
+ $proto = ($settings['protocol'] == 'UDP' ? 'udp' : "tcp-{$mode}");
+ $cipher = $settings['crypto'];
+ $openvpn_conf = <<<EOD
+writepid $pidfile
+#user nobody
+#group nobody
+daemon
+keepalive 10 60
+ping-timer-rem
+persist-tun
+persist-key
+dev tun
+proto $proto
+cipher $cipher
+up /etc/rc.filter_configure
+down /etc/rc.filter_configure
+
+EOD;
+
+ // Mode-specific stuff
+ if ($mode == 'server') {
+ list($ip, $mask) = explode('/', $settings['addresspool']);
+ $mask = gen_subnet_mask($mask);
+
+ // Using a shared key or not dynamically assigning IPs to the clients
+ if (($settings['auth_method'] == 'shared_key') || ($settings['nopool'] == 'on')) {
+ if ($settings['auth_method'] == 'pki') $openvpn_conf .= "tls-server\n";
+
+ $baselong = ip2long($ip) & ip2long($mask);
+ $ip1 = long2ip($baselong + 1);
+ $ip2 = long2ip($baselong + 2);
+ $openvpn_conf .= "ifconfig $ip1 $ip2\n";
+ }
+ // Using a PKI
+ else if ($settings['auth_method'] == 'pki') {
+ if ($settings['client2client']) $openvpn_conf .= "client-to-client\n";
+ $openvpn_conf .= "server $ip $mask\n";
+ $csc_dir = "{$g['varetc_path']}/openvpn_csc";
+ $openvpn_conf .= "client-config-dir $csc_dir\n";
+ }
+
+ // We can push routes
+ if (!empty($settings['local_network'])) {
+ list($ip, $mask) = explode('/', $settings['local_network']);
+ $mask = gen_subnet_mask($mask);
+ $openvpn_conf .= "push \"route $ip $mask\"\n";
+ }
+
+ // The port we'll listen at
+ $openvpn_conf .= "lport {$settings['local_port']}\n";
+
+ // DHCP-Options
+ if (!empty($settings['dhcp_domainname'])) $openvpn_conf .= "push \"dhcp-option DOMAIN {$settings['dhcp_domainname']}\"\n";
+
+ if (!empty($settings['dhcp_dns'])) {
+ $servers = explode(';', $settings['dhcp_dns']);
+ if (is_array($servers)) {
+ foreach ($servers as $server) $openvpn_conf .= "push \"dhcp-option DNS {$server}\"\n";
+ }
+ else {
+ $openvpn_conf .= "push \"dhcp-option DNS {$settings['dhcp_dns']}\"\n";
+ }
+ }
+
+ if (!empty($settings['dhcp_wins'])) {
+ $servers = explode(';', $settings['dhcp_wins']);
+ if (is_array($servers)) {
+ foreach ($servers as $server) $openvpn_conf .= "push \"dhcp-option WINS {$server}\"\n";
+ }
+ else {
+ $openvpn_conf .= "push \"dhcp-option WINS {$settings['dhcp_wins']}\"\n";
+ }
+ }
+
+ if (!empty($settings['dhcp_nbdd'])) {
+ $servers = explode(';', $settings['dhcp_nbdd']);
+ if (is_array($servers)) {
+ foreach ($servers as $server) $openvpn_conf .= "push \"dhcp-option NBDD {$server}\"\n";
+ }
+ else {
+ $openvpn_conf .= "push \"dhcp-option NBDD {$settings['dhcp_nbdd']}\"\n";
+ }
+ }
+
+ if (!empty($settings['dhcp_ntp'])) {
+ $servers = explode(';', $settings['dhcp_ntp']);
+ if (is_array($servers)) {
+ foreach ($servers as $server) $openvpn_conf .= "push \"dhcp-option NTP {$server}\"\n";
+ }
+ else {
+ $openvpn_conf .= "push \"dhcp-option NTP {$settings['dhcp_ntp']}\"\n";
+ }
+ }
+
+ if (!empty($settings['dhcp_nbttype']) && $settings['dhcp_nbttype'] !=0) $openvpn_conf .= "push \"dhcp-option NBT {$settings['dhcp_nbttype']}\"\n";
+ if (!empty($settings['dhcp_nbtscope'])) $openvpn_conf .= "push \"dhcp-option NBS {$settings['dhcp_nbtscope']}\"\n";
+ if (!empty($settings['dhcp_nbtdisable'])) $openvpn_conf .= "push \"dhcp-option DISABLE-NBT\"\n";
+ if (!empty($settings['tls'])) $openvpn_conf .= "tls-auth {$g['varetc_path']}/openvpn_server{$id}.tls 0\n";
+ if (!empty($settings['maxclients'])) $openvpn_conf .= "max-clients {$settings['maxclients']}\n";
+ if ($settings['gwredir']) $openvpn_conf .= "push \"redirect-gateway def1\"\n";
+ }
+
+ else { // $mode == client
+ // The remote server
+ $openvpn_conf .= "remote {$settings['serveraddr']} {$settings['serverport']}\n";
+
+ if ($settings['auth_method'] == 'pki') $openvpn_conf .= "client\n";
+
+ if ($settings['use_dynamicport']) $openvpn_conf .= "nobind\n";
+ else
+ // The port we'll listen at
+ $openvpn_conf .= "lport {$lport}\n";
+
+ if (!empty($settings['use_shaper'])) $openvpn_conf .= "shaper {$settings['use_shaper']}\n";
+
+ if (!empty($settings['interface_ip'])) {
+ // Configure the IPs according to the address pool
+ list($ip, $mask) = explode('/', $settings['interface_ip']);
+ $mask = gen_subnet_mask($mask);
+ $baselong = ip2long($ip) & ip2long($mask);
+ $ip1 = long2ip($baselong + 1);
+ $ip2 = long2ip($baselong + 2);
+ $openvpn_conf .= "ifconfig $ip2 $ip1\n";
+ }
+ if (isset($settings['proxy_hostname']) && $settings['proxy_hostname'] != "") {
+ /* ;http-proxy-retry # retry on connection failures */
+ $openvpn_conf .= "http-proxy {$settings['proxy_hostname']} {$settings['proxy_port']}\n";
+ }
+
+ if (!empty($settings['tls'])) $openvpn_conf .= "tls-auth {$g['varetc_path']}/openvpn_client{$id}.tls 1\n";
+
+ }
+
+ // Add the routes if they're set
+ if (!empty($settings['remote_network'])) {
+ list($ip, $mask) = explode('/', $settings['remote_network']);
+ $mask = gen_subnet_mask($mask);
+ $openvpn_conf .= "route $ip $mask\n";
+ }
+
+ // Write the settings for the keys
+ foreach ($keys as $key)
+ if ($key['directive'] != 'tls-auth') {
+ $openvpn_conf .= $key['directive'] . ' ' . $base_file . $key['ext'] . "\n";
+ }
+
+ if ($settings['use_lzo']) $openvpn_conf .= "comp-lzo\n";
+
+ if ($settings['passtos']) $openvpn_conf .= "passtos\n";
+
+ if ($settings['infiniteresolvretry']) $openvpn_conf .= "resolv-retry infinite\n";
+
+ if ($settings['dynamic_ip']) {
+ $openvpn_conf .= "persist-remote-ip\n";
+ $openvpn_conf .= "float\n";
+ }
+
+ if (!empty($settings['custom_options'])) {
+ $options = explode(';', $settings['custom_options']);
+ if (is_array($options)) {
+ foreach ($options as $option)
+ $openvpn_conf .= "$option\n";
+ }
+ else {
+ $openvpn_conf .= "{$settings['custom_options']}\n";
+ }
+ }
+
+ file_put_contents($g['varetc_path'] . "/openvpn_{$mode}{$id}.conf", $openvpn_conf);
+}
+
+
+function openvpn_resync_csc($id) {
+ global $g, $config;
+
+ $settings = $config['installedpackages']['openvpncsc']['config'][$id];
+
+ if ($settings['disable'] == 'on') {
+ $filename = "{$g['varetc_path']}/openvpn_csc/{$settings['commonname']}";
+ unlink_if_exists($filename);
+ return;
+ }
+
+ $conf = '';
+ if ($settings['block'] == 'on') $conf .= "disable\n";
+ if ($settings['push_reset'] == 'on') $conf .= "push-reset\n";
+ if (!empty($settings['ifconfig_push'])) {
+ list($ip, $mask) = explode('/', $settings['ifconfig_push']);
+ $baselong = ip2long($ip) & gen_subnet_mask_long($mask);
+ $conf .= 'ifconfig-push ' . long2ip($baselong + 1) . ' ' . long2ip($baselong + 2) . "\n";
+ }
+
+// DHCP-Options
+ if (!empty($settings['dhcp_domainname'])) $conf .= "push \"dhcp-option DOMAIN {$settings['dhcp_domainname']}\"\n";
+
+ if (!empty($settings['dhcp_dns'])) {
+ $servers = explode(';', $settings['dhcp_dns']);
+ if (is_array($servers)) {
+ foreach ($servers as $server) $conf .= "push \"dhcp-option DNS {$server}\"\n";
+ }
+ else {
+ $conf .= "push \"dhcp-option DNS {$settings['dhcp_dns']}\"\n";
+ }
+ }
+
+ if (!empty($settings['dhcp_wins'])) {
+ $servers = explode(';', $settings['dhcp_wins']);
+ if (is_array($servers)) {
+ foreach ($servers as $server) $conf .= "push \"dhcp-option WINS {$server}\"\n";
+ }
+ else {
+ $conf .= "push \"dhcp-option WINS {$settings['dhcp_wins']}\"\n";
+ }
+ }
+
+ if (!empty($settings['dhcp_nbdd'])) {
+ $servers = explode(';', $settings['dhcp_nbdd']);
+ if (is_array($servers)) {
+ foreach ($servers as $server) $conf .= "push \"dhcp-option NBDD {$server}\"\n";
+ }
+ else {
+ $conf .= "push \"dhcp-option NBDD {$settings['dhcp_nbdd']}\"\n";
+ }
+ }
+
+ if (!empty($settings['dhcp_ntp'])) {
+ $servers = explode(';', $settings['dhcp_ntp']);
+ if (is_array($servers)) {
+ foreach ($servers as $server) $conf .= "push \"dhcp-option NTP {$server}\"\n";
+ }
+ else {
+ $conf .= "push \"dhcp-option NTP {$settings['dhcp_ntp']}\"\n";
+ }
+ }
+
+ if (!empty($settings['dhcp_nbttype']) && $settings['dhcp_nbttype'] !=0) $conf .= "push \"dhcp-option NBT {$settings['dhcp_nbttype']}\"\n";
+ if (!empty($settings['dhcp_nbtscope'])) $conf .= "push \"dhcp-option NBS {$settings['dhcp_nbtscope']}\"\n";
+ if ($settings['dhcp_nbtdisable']) $conf .= "push \"dhcp-option DISABLE-NBT\"\n";
+ if ($settings['gwredir']) $conf .= "push \"redirect-gateway def1\"\n";
+
+
+ if (!empty($settings['custom_options'])) {
+ $options = explode(';', $settings['custom_options']);
+ if (is_array($options)) {
+ foreach ($options as $option)
+ $conf .= "$option\n";
+ }
+ else {
+ $conf .= "{$settings['custom_options']}\n";
+ }
+ }
+
+ $filename = "{$g['varetc_path']}/openvpn_csc/{$settings['commonname']}";
+ file_put_contents($filename, $conf);
+ chown($filename, 'nobody');
+ chgrp($filename, 'nogroup');
+
+}
+
+
+function openvpn_restart($mode, $id) {
+ global $g, $config;
+
+ $pidfile = $g['varrun_path'] . "/openvpn_{$mode}{$id}.pid";
+ killbypid($pidfile);
+ sleep(2);
+
+ $settings = $config['installedpackages']["openvpn$mode"]['config'][$id];
+ if ($settings['disable']) return;
+
+ $configfile = $g['varetc_path'] . "/openvpn_{$mode}{$id}.conf";
+ mwexec_bg("nohup openvpn --config $configfile");
+ touch("{$g['tmp_path']}/filter_dirty");
+}
+
+
+// Resync the configuration and restart the VPN
+function openvpn_resync($mode, $id) {
+ openvpn_reconfigure($mode, $id);
+ openvpn_restart($mode, $id);
+}
+
+function openvpn_create_cscdir() {
+ global $g;
+
+ $csc_dir = "{$g['varetc_path']}/openvpn_csc";
+ if (is_dir($csc_dir))
+ rmdir_recursive($csc_dir);
+ make_dirs($csc_dir);
+ chown($csc_dir, 'nobody');
+ chgrp($csc_dir, 'nobody');
+}
+
+// Resync and restart all VPNs
+function openvpn_resync_all() {
+ global $config;
+
+ foreach (array('server', 'client') as $mode) {
+ if (is_array($config['installedpackages']["openvpn$mode"]['config'])) {
+ foreach ($config['installedpackages']["openvpn$mode"]['config'] as $id => $settings)
+ openvpn_resync($mode, $id);
+ }
+ }
+
+ openvpn_create_cscdir();
+ if (is_array($config['installedpackages']['openvpncsc']['config'])) {
+ foreach ($config['installedpackages']['openvpncsc']['config'] as $id => $csc)
+ openvpn_resync_csc($id);
+ }
+
+ /* give speedy machines time to settle */
+ sleep(5);
+
+ /* reload the filter policy */
+ filter_configure();
+
+}
+
+function openvpn_print_javascript($mode) {
+ $javascript = <<<EOD
+<script language="JavaScript">
+<!--
+function onAuthMethodChanged() {
+ var method = document.iform.auth_method;
+ var endis = (method.options[method.selectedIndex].value == 'shared_key');
+
+ document.iform.shared_key.disabled = !endis;
+ document.iform.ca_cert.disabled = endis;
+ document.iform.{$mode}_cert.disabled = endis;
+ document.iform.{$mode}_key.disabled = endis;
+ document.iform.tls.disabled = endis;
+
+EOD;
+ if ($mode == 'server') {
+ $javascript .= <<<EOD
+ document.iform.dh_params.disabled = endis;
+ document.iform.crl.disabled = endis;
+ document.iform.tls.disabled = endis;
+ document.iform.nopool.disabled = endis;
+ document.iform.local_network.disabled = endis;
+ document.iform.client2client.disabled = endis;
+ document.iform.maxclients.disabled = endis;
+
+EOD;
+ }
+
+ else { // Client mode
+ $javascript .= "\tdocument.iform.remote_network.disabled = !endis;\n";
+ }
+
+ $javascript .= <<<EOD
+}
+//-->
+</script>
+
+EOD;
+ print($javascript);
+}
+
+
+function openvpn_print_javascript2() {
+ $javascript = <<<EOD
+<script language="JavaScript">
+<!--
+ onAuthMethodChanged();
+//-->
+</script>
+
+EOD;
+ print($javascript);
+}
+?>
diff --git a/config/ovpnenhance/openvpn.xml_tls b/config/ovpnenhance/openvpn.xml_tls
new file mode 100644
index 00000000..e7932e38
--- /dev/null
+++ b/config/ovpnenhance/openvpn.xml_tls
@@ -0,0 +1,329 @@
+<packagegui>
+ <name>openvpnserver</name>
+ <title>OpenVPN: Server</title>
+ <include_file>openvpn.inc</include_file>
+ <delete_string>An OpenVPN server has been deleted.</delete_string>
+ <addedit_string>An OpenVPN server has been created/modified.</addedit_string>
+ <tabs>
+ <tab>
+ <text>Server</text>
+ <url>/pkg.php?xml=openvpn.xml</url>
+ <active/>
+ </tab>
+ <tab>
+ <text>Client</text>
+ <url>/pkg.php?xml=openvpn_cli.xml</url>
+ </tab>
+ <tab>
+ <text>Client-specific configuration</text>
+ <url>/pkg.php?xml=openvpn_csc.xml</url>
+ </tab>
+ </tabs>
+ <adddeleteeditpagefields>
+ <columnitem>
+ <fieldname>disable</fieldname>
+ <fielddescr>Disabled</fielddescr>
+ <type>checkbox</type>
+ </columnitem>
+ <columnitem>
+ <fieldname>protocol</fieldname>
+ <fielddescr>Protocol</fielddescr>
+ </columnitem>
+ <columnitem>
+ <fieldname>addresspool</fieldname>
+ <fielddescr>Address pool</fielddescr>
+ </columnitem>
+ <columnitem>
+ <fieldname>description</fieldname>
+ <fielddescr>Description</fielddescr>
+ </columnitem>
+ </adddeleteeditpagefields>
+ <fields>
+ <field>
+ <fieldname>disable</fieldname>
+ <fielddescr>Disable this tunnel</fielddescr>
+ <description>This allows you to disable this tunnel without removing it from the list.</description>
+ <required/>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fieldname>protocol</fieldname>
+ <fielddescr>Protocol</fielddescr>
+ <description>The protocol to be used for the VPN.</description>
+ <required/>
+ <type>select</type>
+ <options>
+ <option>
+ <value>TCP</value>
+ <name>TCP</name>
+ </option>
+ <option>
+ <value>UDP</value>
+ <name>UDP</name>
+ </option>
+ </options>
+ <default_value>UDP</default_value>
+ </field>
+ <field>
+ <fieldname>dynamic_ip</fieldname>
+ <fielddescr>Dynamic IP</fielddescr>
+ <description>Assume dynamic IPs, so that DHCP clients can connect.</description>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fieldname>local_port</fieldname>
+ <fielddescr>Local port</fielddescr>
+ <description>The port OpenVPN will listen on. You generally want 1194 here.</description>
+ <required/>
+ <type>input</type>
+ <default_value>1194</default_value>
+ <size>5</size>
+ </field>
+ <field>
+ <fieldname>addresspool</fieldname>
+ <fielddescr>Address pool</fielddescr>
+ <description>This is the address pool to be assigned to the clients. Expressed as a CIDR range (eg. 10.0.8.0/24). If the 'Use static IPs' field isn't set, clients will be assigned addresses from this pool. Otherwise, this will be used to set the local interface's IP.</description>
+ <required/>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>nopool</fieldname>
+ <fielddescr>Use static IPs</fielddescr>
+ <description>If this option is set, IPs won't be assigned to clients. Instead, the server will use static IPs on its side, and the clients are expected to use this same value in the 'Address pool' field.</description>
+ <required/>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fieldname>local_network</fieldname>
+ <fielddescr>Local network</fielddescr>
+ <description>This is the network that will be accessable from the remote endpoint. Expressed as a CIDR range. You may leave this blank you don't want to add a route to your network through this tunnel in the remote machine. This is generally set to your LAN network.</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>remote_network</fieldname>
+ <fielddescr>Remote network</fielddescr>
+ <description>This is a network that will be routed through the tunnel, so that a site-to-site VPN can be established without manually changing the routing tables. Expressed as a CIDR range. If this is a site-to-site VPN, enter here the remote LAN here. You may leave this blank if you don't want a site-to-site VPN.</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>client2client</fieldname>
+ <fielddescr>Client-to-client VPN</fielddescr>
+ <description>If this option is set, clients will be able to talk to each other. Otherwise, they will only be able to talk to the server.</description>
+ <required/>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fieldname>crypto</fieldname>
+ <fielddescr>Cryptography</fielddescr>
+ <description>Here you can choose the cryptography algorithm to be used.</description>
+ <required/>
+ <type>select</type>
+ <default_value>BF-CBC</default_value>
+ </field>
+ <field>
+ <fieldname>auth_method</fieldname>
+ <fielddescr>Authentication method</fielddescr>
+ <description>The authentication method to be used.</description>
+ <required/>
+ <type>select</type>
+ <options>
+ <option>
+ <value>shared_key</value>
+ <name>Shared key</name>
+ </option>
+ <option>
+ <value>pki</value>
+ <name>PKI (Public Key Infrastructure)</name>
+ </option>
+ </options>
+ <onchange>onAuthMethodChanged()</onchange>
+ </field>
+ <field>
+ <fieldname>shared_key</fieldname>
+ <fielddescr>Shared key</fielddescr>
+ <description>Paste your shared key here.</description>
+ <type>textarea</type>
+ <encoding>base64</encoding>
+ <rows>8</rows>
+ <cols>40</cols>
+ </field>
+ <field>
+ <fieldname>ca_cert</fieldname>
+ <fielddescr>CA certificate</fielddescr>
+ <description>Paste your CA certificate in X.509 format here.</description>
+ <type>textarea</type>
+ <encoding>base64</encoding>
+ <rows>8</rows>
+ <cols>40</cols>
+ </field>
+ <field>
+ <fieldname>server_cert</fieldname>
+ <fielddescr>Server certificate</fielddescr>
+ <description>Paste your server certificate in X.509 format here.</description>
+ <type>textarea</type>
+ <encoding>base64</encoding>
+ <rows>8</rows>
+ <cols>40</cols>
+ </field>
+ <field>
+ <fieldname>server_key</fieldname>
+ <fielddescr>Server key</fielddescr>
+ <description>Paste your server key in RSA format here.</description>
+ <type>textarea</type>
+ <encoding>base64</encoding>
+ <rows>8</rows>
+ <cols>40</cols>
+ </field>
+ <field>
+ <fieldname>dh_params</fieldname>
+ <fielddescr>DH parameters</fielddescr>
+ <description>Paste your Diffie Hellman parameters in PEM format here.</description>
+ <type>textarea</type>
+ <encoding>base64</encoding>
+ <rows>8</rows>
+ <cols>40</cols>
+ </field>
+ <field>
+ <fieldname>crl</fieldname>
+ <fielddescr>CRL</fielddescr>
+ <description>Paste your certificate revocation list (CRL) in PEM format here (optional).</description>
+ <type>textarea</type>
+ <encoding>base64</encoding>
+ <rows>8</rows>
+ <cols>40</cols>
+ </field>
+ <field>
+ <fieldname>tls</fieldname>
+ <fielddescr>TLS</fielddescr>
+ <description>Paste your HMAC signature (TLS) here (optional).</description>
+ <type>textarea</type>
+ <encoding>base64</encoding>
+ <rows>8</rows>
+ <cols>40</cols>
+ </field>
+ <field>
+ <fieldname>dhcp_domainname</fieldname>
+ <fielddescr>DHCP-Opt.: DNS-Domainname</fielddescr>
+ <description>Set connection-specific DNS Suffix.</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>dhcp_dns</fieldname>
+ <fielddescr>DHCP-Opt.: DNS-Server</fielddescr>
+ <description>Set domain name server addresses, separated by semi-colons (;).</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>dhcp_wins</fieldname>
+ <fielddescr>DHCP-Opt.: WINS-Server</fielddescr>
+ <description>Set WINS server addresses (NetBIOS over TCP/IP Name Server), separated by semi-colons (;).</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>dhcp_nbdd</fieldname>
+ <fielddescr>DHCP-Opt.: NBDD-Server</fielddescr>
+ <description>Set NBDD server addresses (NetBIOS over TCP/IP Datagram Distribution Server), separated by semi-colons (;).</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>dhcp_ntp</fieldname>
+ <fielddescr>DHCP-Opt.: NTP-Server</fielddescr>
+ <description>Set NTP server addresses (Network Time Protocol), separated by semi-colons (;).</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>dhcp_nbttype</fieldname>
+ <fielddescr>DHCP-Opt.: NetBIOS node type</fielddescr>
+ <description>Set NetBIOS over TCP/IP Node type. Possible options: b-node (broadcasts), p-node (point-to-point name queries to a WINS server), m-node (broadcast then query name server), and h-node (query name server, then broadcast).</description>
+ <type>select</type>
+ <options>
+ <option>
+ <value>0</value>
+ <name>none</name>
+ </option>
+ <option>
+ <value>1</value>
+ <name>b-node</name>
+ </option>
+ <option>
+ <value>2</value>
+ <name>p-node</name>
+ </option>
+ <option>
+ <value>4</value>
+ <name>m-node</name>
+ </option>
+ <option>
+ <value>8</value>
+ <name>h-node</name>
+ </option>
+ </options>
+ <default_value>0</default_value>
+ </field>
+ <field>
+ <fieldname>dhcp_nbtscope</fieldname>
+ <fielddescr>DHCP-Opt.: NetBIOS Scope</fielddescr>
+ <description>Set NetBIOS over TCP/IP Scope. A NetBIOS Scope ID provides an extended naming service for NetBIOS over TCP/IP. The NetBIOS scope ID isolates NetBIOS traffic on a single network to only those nodes with the same NetBIOS scope ID.</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>dhcp_nbtdisable</fieldname>
+ <fielddescr>DHCP-Opt.: Disable NetBIOS</fielddescr>
+ <description>If this option is set, Netbios-over-TCP/IP will be disabled.</description>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fieldname>use_lzo</fieldname>
+ <fielddescr>LZO compression</fielddescr>
+ <description>Checking this will compress the packets using the LZO algorithm before sending them.</description>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fieldname>maxclients</fieldname>
+ <fielddescr>Maximum clients</fielddescr>
+ <description>The maximum number of concurrently connected clients we want to allow.</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>passtos</fieldname>
+ <fielddescr>Pass Type-Of-Service</fielddescr>
+ <description>Checking this will set the TOS field of the tunnel packet to what the payload's TOS is.</description>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fieldname>gwredir</fieldname>
+ <fielddescr>Redirect Gateway</fielddescr>
+ <description>Redirect ALL traffic through the OpenVPN server.</description>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fieldname>custom_options</fieldname>
+ <fielddescr>Custom options</fielddescr>
+ <description>You can put your own custom options here, separated by semi-colons (;). They'll be added to the server configuration.</description>
+ <type>textarea</type>
+ <cols>65</cols>
+ <rows>5</rows>
+ </field>
+ <field>
+ <fieldname>description</fieldname>
+ <fielddescr>Description</fielddescr>
+ <description>You may enter a description here. This is optional and is not parsed.</description>
+ <type>input</type>
+ </field>
+ </fields>
+ <custom_php_command_before_form>
+ openvpn_get_ciphers(&amp;$pkg);
+ </custom_php_command_before_form>
+ <custom_php_after_head_command>
+ openvpn_print_javascript('server');
+ </custom_php_after_head_command>
+ <custom_php_after_form_command>
+ openvpn_print_javascript2();
+ </custom_php_after_form_command>
+ <custom_php_validation_command>
+ openvpn_validate_input('server', $_POST, &amp;$input_errors);
+ </custom_php_validation_command>
+ <custom_php_resync_config_command>
+ openvpn_resync('server', $id);
+ </custom_php_resync_config_command>
+</packagegui>
diff --git a/config/ovpnenhance/openvpn_cli.xml_tls b/config/ovpnenhance/openvpn_cli.xml_tls
new file mode 100644
index 00000000..b9b85cf6
--- /dev/null
+++ b/config/ovpnenhance/openvpn_cli.xml_tls
@@ -0,0 +1,240 @@
+<packagegui>
+ <name>openvpnclient</name>
+ <title>OpenVPN: Client</title>
+ <include_file>openvpn.inc</include_file>
+ <delete_string>An OpenVPN client has been deleted.</delete_string>
+ <addedit_string>An OpenVPN client has been created/modified.</addedit_string>
+ <tabs>
+ <tab>
+ <text>Server</text>
+ <url>/pkg.php?xml=openvpn.xml</url>
+ </tab>
+ <tab>
+ <text>Client</text>
+ <url>/pkg.php?xml=openvpn_cli.xml</url>
+ <active/>
+ </tab>
+ <tab>
+ <text>Client-specific configuration</text>
+ <url>/pkg.php?xml=openvpn_csc.xml</url>
+ </tab>
+ </tabs>
+ <adddeleteeditpagefields>
+ <columnitem>
+ <fieldname>disable</fieldname>
+ <fielddescr>Disabled</fielddescr>
+ <type>checkbox</type>
+ </columnitem>
+ <columnitem>
+ <fieldname>serveraddr</fieldname>
+ <fielddescr>Server</fielddescr>
+ </columnitem>
+ <columnitem>
+ <fieldname>protocol</fieldname>
+ <fielddescr>Protocol</fielddescr>
+ </columnitem>
+ <columnitem>
+ <fieldname>description</fieldname>
+ <fielddescr>Description</fielddescr>
+ </columnitem>
+ </adddeleteeditpagefields>
+ <fields>
+ <field>
+ <fieldname>disable</fieldname>
+ <fielddescr>Disable this tunnel</fielddescr>
+ <description>This allows you to disable this tunnel without removing it from the list.</description>
+ <required/>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fieldname>protocol</fieldname>
+ <fielddescr>Protocol</fielddescr>
+ <description>The protocol to be used for the VPN.</description>
+ <required/>
+ <type>select</type>
+ <options>
+ <option>
+ <value>TCP</value>
+ <name>TCP</name>
+ </option>
+ <option>
+ <value>UDP</value>
+ <name>UDP</name>
+ </option>
+ </options>
+ <default_value>UDP</default_value>
+ </field>
+ <field>
+ <fieldname>serveraddr</fieldname>
+ <fielddescr>Server address</fielddescr>
+ <description>This is the address OpenVPN will try to connect to in order to establish the tunnel. Set it to the remote endpoint's address.</description>
+ <required/>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>serverport</fieldname>
+ <fielddescr>Server port</fielddescr>
+ <description>The port OpenVPN will use to connect to the server. Most people would want to use 1194 here.</description>
+ <required/>
+ <type>input</type>
+ <default_value>1194</default_value>
+ <size>5</size>
+ </field>
+ <field>
+ <fieldname>interface_ip</fieldname>
+ <fielddescr>Interface IP</fielddescr>
+ <description>This specifies the IPs to be assigned to the local interface. Expressed as a CIDR range. The first address in the range will be set to the remote endpoint of the interface, and the second will be assigned to the local endpoint. For TLS VPNs, the interface IPs are assigned by the server pool.</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>remote_network</fieldname>
+ <fielddescr>Remote network</fielddescr>
+ <description>This is the network that will be accessable from your endpoint. Expressed as a CIDR range. You may leave this blank if all you want is to access the VPN clients. You normally want this set to the remote endpoint's LAN network.</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>proxy_hostname</fieldname>
+ <fielddescr>Proxy Host</fielddescr>
+ <description>Proxy server hostname.</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>proxy_port</fieldname>
+ <fielddescr>Proxy port</fielddescr>
+ <description>The port OpenVPN will use on the proxy server.</description>
+ <type>input</type>
+ <default_value>3128</default_value>
+ <size>5</size>
+ </field>
+ <field>
+ <fieldname>crypto</fieldname>
+ <fielddescr>Cryptography</fielddescr>
+ <description>Here you can choose the cryptography algorithm to be used.</description>
+ <required/>
+ <type>select</type>
+ <default_value>BF-CBC</default_value>
+ </field>
+ <field>
+ <fieldname>auth_method</fieldname>
+ <fielddescr>Authentication method</fielddescr>
+ <description>The authentication method to be used.</description>
+ <required/>
+ <type>select</type>
+ <options>
+ <option>
+ <value>shared_key</value>
+ <name>Shared key</name>
+ </option>
+ <option>
+ <value>pki</value>
+ <name>PKI (Public Key Infrastructure)</name>
+ </option>
+ </options>
+ <onchange>onAuthMethodChanged()</onchange>
+ </field>
+ <field>
+ <fieldname>shared_key</fieldname>
+ <fielddescr>Shared key</fielddescr>
+ <description>Paste your shared key here.</description>
+ <type>textarea</type>
+ <encoding>base64</encoding>
+ <rows>8</rows>
+ <cols>40</cols>
+ </field>
+ <field>
+ <fieldname>ca_cert</fieldname>
+ <fielddescr>CA certificate</fielddescr>
+ <description>Paste the server's CA certificate in X.509 format here.</description>
+ <type>textarea</type>
+ <encoding>base64</encoding>
+ <rows>8</rows>
+ <cols>40</cols>
+ </field>
+ <field>
+ <fieldname>client_cert</fieldname>
+ <fielddescr>Client certificate</fielddescr>
+ <description>Paste your client certificate in X.509 format here.</description>
+ <type>textarea</type>
+ <encoding>base64</encoding>
+ <rows>8</rows>
+ <cols>40</cols>
+ </field>
+ <field>
+ <fieldname>client_key</fieldname>
+ <fielddescr>Client key</fielddescr>
+ <description>Paste your client key in RSA format here.</description>
+ <type>textarea</type>
+ <encoding>base64</encoding>
+ <rows>8</rows>
+ <cols>40</cols>
+ </field>
+ <field>
+ <fieldname>tls</fieldname>
+ <fielddescr>TLS</fielddescr>
+ <description>Paste your HMAC signature (TLS) here (optional).</description>
+ <type>textarea</type>
+ <encoding>base64</encoding>
+ <rows>8</rows>
+ <cols>40</cols>
+ </field>
+ <field>
+ <fieldname>use_lzo</fieldname>
+ <fielddescr>LZO compression</fielddescr>
+ <description>Checking this will compress the packets using the LZO algorithm before sending them.</description>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fieldname>use_shaper</fieldname>
+ <fielddescr>Limit outgoing bandwidth</fielddescr>
+ <description>Maximum outgoing bandwidth for this tunnel. Leave empty for no limit. The input value has to be something between 100 bytes/sec and 100 Mbytes/sec (entered as bytes per second).</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>use_dynamicport</fieldname>
+ <fielddescr>Dynamic sourceport</fielddescr>
+ <description>Checking this will let the openvpn client choose a dynamic sourceport for this connection.</description>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fieldname>passtos</fieldname>
+ <fielddescr>Pass Type-Of-Service</fielddescr>
+ <description>Checking this will set the TOS field of the tunnel packet to what the payload's TOS is.</description>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fieldname>infiniteresolvretry</fieldname>
+ <fielddescr>Infinitely resolve server</fielddescr>
+ <description>Infinitely retry to resolve the host name of the OpenVPN server. Useful for not permanently internet-connected machines.</description>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fieldname>custom_options</fieldname>
+ <fielddescr>Custom options</fielddescr>
+ <description>You can put your own custom options here, separated by semi-colons (;). They'll be added to the client configuration.</description>
+ <type>textarea</type>
+ <cols>65</cols>
+ <rows>5</rows>
+ </field>
+ <field>
+ <fieldname>description</fieldname>
+ <fielddescr>Description</fielddescr>
+ <description>You may enter a description here. This is optional and is not parsed.</description>
+ <type>input</type>
+ </field>
+ </fields>
+ <custom_php_command_before_form>
+ openvpn_get_ciphers(&amp;$pkg);
+ </custom_php_command_before_form>
+ <custom_php_after_head_command>
+ openvpn_print_javascript('client');
+ </custom_php_after_head_command>
+ <custom_php_after_form_command>
+ openvpn_print_javascript2();
+ </custom_php_after_form_command>
+ <custom_php_validation_command>
+ openvpn_validate_input('client', $_POST, &amp;$input_errors);
+ </custom_php_validation_command>
+ <custom_php_resync_config_command>
+ openvpn_resync('client', $id);
+ </custom_php_resync_config_command>
+</packagegui>
diff --git a/config/ovpnenhance/openvpn_csc.xml_tls b/config/ovpnenhance/openvpn_csc.xml_tls
new file mode 100644
index 00000000..1025ad09
--- /dev/null
+++ b/config/ovpnenhance/openvpn_csc.xml_tls
@@ -0,0 +1,169 @@
+<packagegui>
+ <name>openvpncsc</name>
+ <title>OpenVPN: Client-specific configuration</title>
+ <include_file>openvpn.inc</include_file>
+ <delete_string>An OpenVPN client-specific configuration has been deleted.</delete_string>
+ <addedit_string>An OpenVPN client-specific configuration has been created/modified.</addedit_string>
+ <tabs>
+ <tab>
+ <text>Server</text>
+ <url>/pkg.php?xml=openvpn.xml</url>
+ </tab>
+ <tab>
+ <text>Client</text>
+ <url>/pkg.php?xml=openvpn_cli.xml</url>
+ </tab>
+ <tab>
+ <text>Client-specific configuration</text>
+ <url>/pkg.php?xml=openvpn_csc.xml</url>
+ <active/>
+ </tab>
+ </tabs>
+ <adddeleteeditpagefields>
+ <columnitem>
+ <fieldname>disable</fieldname>
+ <fielddescr>Disabled</fielddescr>
+ <type>checkbox</type>
+ </columnitem>
+ <columnitem>
+ <fieldname>commonname</fieldname>
+ <fielddescr>Common name</fielddescr>
+ </columnitem>
+ <columnitem>
+ <fieldname>description</fieldname>
+ <fielddescr>Description</fielddescr>
+ </columnitem>
+ </adddeleteeditpagefields>
+ <fields>
+ <field>
+ <fieldname>disable</fieldname>
+ <fielddescr>Disabled</fielddescr>
+ <description>Set this option to disable this client-specific configuration without removing it from the list.</description>
+ <required/>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fieldname>commonname</fieldname>
+ <fielddescr>Common name</fielddescr>
+ <description>Enter the client's X.509 common name here.</description>
+ <required/>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>block</fieldname>
+ <fielddescr>Blocked</fielddescr>
+ <description>Check this to block (disable) this client, based on its common name. Don't use this option to disable a client due to key or password compromise. Use a CRL (certificate revocation list) instead.</description>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fieldname>push_reset</fieldname>
+ <fielddescr>Push reset</fielddescr>
+ <description>Setting this option will make this client not inherit the global push options.</description>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fieldname>ifconfig_push</fieldname>
+ <fielddescr>Interface IP</fielddescr>
+ <description>Set this option to push an IP to the client's interface. Expressed as a CIDR range (e.g. 10.5.0.0/16). The first IP in the range will be used as the remote IP of the interface, and the second IP will be used as the local IP of the interface.</description>
+ <type>input</type>
+ </field>
+
+ <field>
+ <fieldname>dhcp_domainname</fieldname>
+ <fielddescr>DHCP-Opt.: DNS-Domainname</fielddescr>
+ <description>Set connection-specific DNS Suffix.</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>dhcp_dns</fieldname>
+ <fielddescr>DHCP-Opt.: DNS-Server</fielddescr>
+ <description>Set domain name server addresses, separated by semi-colons (;).</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>dhcp_wins</fieldname>
+ <fielddescr>DHCP-Opt.: WINS-Server</fielddescr>
+ <description>Set WINS server addresses (NetBIOS over TCP/IP Name Server), separated by semi-colons (;).</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>dhcp_nbdd</fieldname>
+ <fielddescr>DHCP-Opt.: NBDD-Server</fielddescr>
+ <description>Set NBDD server addresses (NetBIOS over TCP/IP Datagram Distribution Server), separated by semi-colons (;).</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>dhcp_ntp</fieldname>
+ <fielddescr>DHCP-Opt.: NTP-Server</fielddescr>
+ <description>Set NTP server addresses (Network Time Protocol), separated by semi-colons (;).</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>dhcp_nbttype</fieldname>
+ <fielddescr>DHCP-Opt.: NetBIOS node type</fielddescr>
+ <description>Set NetBIOS over TCP/IP Node type. Possible options: b-node (broadcasts), p-node (point-to-point name queries to a WINS server), m-node (broadcast then query name server), and h-node (query name server, then broadcast).</description>
+ <type>select</type>
+ <options>
+ <option>
+ <value>0</value>
+ <name>none</name>
+ </option>
+ <option>
+ <value>1</value>
+ <name>b-node</name>
+ </option>
+ <option>
+ <value>2</value>
+ <name>p-node</name>
+ </option>
+ <option>
+ <value>4</value>
+ <name>m-node</name>
+ </option>
+ <option>
+ <value>8</value>
+ <name>h-node</name>
+ </option>
+ </options>
+ <default_value>0</default_value>
+ </field>
+ <field>
+ <fieldname>dhcp_nbtscope</fieldname>
+ <fielddescr>DHCP-Opt.: NetBIOS Scope</fielddescr>
+ <description>Set NetBIOS over TCP/IP Scope. A NetBIOS Scope ID provides an extended naming service for NetBIOS over TCP/IP. The NetBIOS scope ID isolates NetBIOS traffic on a single network to only those nodes with the same NetBIOS scope ID.</description>
+ <type>input</type>
+ </field>
+ <field>
+ <fieldname>dhcp_nbtdisable</fieldname>
+ <fielddescr>DHCP-Opt.: Disable NetBIOS</fielddescr>
+ <description>If this option is set, Netbios-over-TCP/IP will be disabled.</description>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fieldname>gwredir</fieldname>
+ <fielddescr>Redirect Gateway</fielddescr>
+ <description>Redirect ALL traffic through the OpenVPN server.</description>
+ <type>checkbox</type>
+ </field>
+ <field>
+ <fieldname>custom_options</fieldname>
+ <fielddescr>Custom options</fielddescr>
+ <description>You can put your own custom options here, separated by semi-colons (;). They'll be added to the client-specific configuration.</description>
+ <type>textarea</type>
+ <cols>65</cols>
+ <rows>5</rows>
+ </field>
+ <field>
+ <fieldname>description</fieldname>
+ <fielddescr>Description</fielddescr>
+ <description>You may enter a description here for your reference (not parsed).</description>
+ <type>input</type>
+ </field>
+ </fields>
+ <custom_php_validation_command>
+ openvpn_validate_input_csc($_POST, &amp;$input_errors);
+ </custom_php_validation_command>
+ <custom_php_resync_config_command>
+ openvpn_resync_csc($id);
+ </custom_php_resync_config_command>
+</packagegui>
diff --git a/config/ovpnenhance/ovpnenhance.inc b/config/ovpnenhance/ovpnenhance.inc
new file mode 100644
index 00000000..4c2a82db
--- /dev/null
+++ b/config/ovpnenhance/ovpnenhance.inc
@@ -0,0 +1,13 @@
+<?php
+
+function ovpnenhance_install() {
+ global $g, $config;
+
+mwexec("mv /usr/local/pkg/openvpn.inc_tls /usr/local/pkg/openvpn.inc");
+mwexec("mv /usr/local/pkg/openvpn.xml_tls /usr/local/pkg/openvpn.xml");
+mwexec("mv /usr/local/pkg/openvpn_cli.xml_tls /usr/local/pkg/openvpn_cli.xml");
+mwexec("mv /usr/local/pkg/openvpn_csc.xml_tls /usr/local/pkg/openvpn_csc.xml");
+mwexec("rm /usr/local/pkg/ovpnenhance.inc");
+}
+
+?> \ No newline at end of file
diff --git a/config/ovpnenhance/ovpnenhance.xml b/config/ovpnenhance/ovpnenhance.xml
new file mode 100644
index 00000000..a45f4a58
--- /dev/null
+++ b/config/ovpnenhance/ovpnenhance.xml
@@ -0,0 +1,40 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!DOCTYPE packagegui SYSTEM "../schema/packages.dtd">
+<?xml-stylesheet type="text/xsl" href="../xsl/package.xsl"?>
+<packagegui>
+ <description>Enhance OpenVPN with TLS-auth and client/server-options</description>
+ <requirements>pfSense 1.2.x</requirements>
+ <faq>Enhances OpenVPN with TLS-auth and client/server-options.</faq>
+ <name>ovpnenhance</name>
+ <version>0.1</version>
+ <title>ovpnenhance</title>
+ <include_file>/usr/local/pkg/ovpnenhance.inc</include_file>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>077</chmod>
+ <item>http://www.pfsense.com/packages/config/ovpnenhance/ovpnenhance.inc</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>077</chmod>
+ <item>http://www.pfsense.com/packages/config/ovpnenhance/openvpn.inc_tls</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>077</chmod>
+ <item>http://www.pfsense.com/packages/config/ovpnenhance/openvpn.xml_tls</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>077</chmod>
+ <item>http://www.pfsense.com/packages/config/ovpnenhance/openvpn_cli.xml_tls</item>
+ </additional_files_needed>
+ <additional_files_needed>
+ <prefix>/usr/local/pkg/</prefix>
+ <chmod>077</chmod>
+ <item>http://www.pfsense.com/packages/config/ovpnenhance/openvpn_csc.xml_tls</item>
+ </additional_files_needed>
+ <custom_php_install_command>
+ ovpnenhance_install();
+ </custom_php_install_command>
+</packagegui>