diff options
-rw-r--r-- | etc/inc/config.inc | 17 | ||||
-rwxr-xr-x | etc/inc/openvpn.auth-user.php | 79 | ||||
-rw-r--r-- | etc/inc/openvpn.inc | 219 | ||||
-rw-r--r-- | usr/local/www/vpn_openvpn_client.php | 220 | ||||
-rw-r--r-- | usr/local/www/vpn_openvpn_server.php | 264 |
5 files changed, 610 insertions, 189 deletions
diff --git a/etc/inc/config.inc b/etc/inc/config.inc index 5a52611..0cd4476 100644 --- a/etc/inc/config.inc +++ b/etc/inc/config.inc @@ -1747,6 +1747,16 @@ endif; $index++; } + /* determine operational mode */ + if ($server['auth_method'] == 'pki') { + if($server['nopool']) + $server['mode'] = "p2p_tls"; + else + $server['mode'] = "server_tls"; + } else + $server['mode'] = "p2p_shared_key"; + unset($server['auth_method']); + /* modify configuration values */ unset($server['dh_params']); if (!$server['interface']) @@ -1829,6 +1839,13 @@ endif; $index++; } + /* determine operational mode */ + if ($client['auth_method'] == 'pki') + $client['mode'] = "p2p_tls"; + else + $client['mode'] = "p2p_shared_key"; + unset($client['auth_method']); + /* modify configuration values */ if (!$client['interface']) $client['interface'] = 'wan'; diff --git a/etc/inc/openvpn.auth-user.php b/etc/inc/openvpn.auth-user.php new file mode 100755 index 0000000..275f54d --- /dev/null +++ b/etc/inc/openvpn.auth-user.php @@ -0,0 +1,79 @@ +#!/usr/local/bin/php -f +<?php +/* $Id$ */ +/* + openvpn.auth-user.php + + Copyright (C) 2008 Shrew Soft Inc + 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, 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. +*/ + +/* + * OpenVPN calls this script to authenticate a user + * based on a username and password. We lookup these + * in our config.xml file and check the credentials. + */ + +require_once("config.inc"); + +function & lookup_user($name) { + global $config; + + foreach($config['system']['user'] as & $userent) + if ($userent['name'] == $name) + return $userent; +} + +/* setup syslog logging */ +openlog("openvpn", LOG_ODELAY, LOG_AUTH); + +/* read data from environment */ +$username = getenv("username"); +$password = getenv("password"); + +if (!$username || !$password) { + syslog(LOG_ERROR, "invalid user authentication environment"); + exit(-1); +} + +/* lookup user object by name */ +$user =& lookup_user($username); + +if (!$user) { + syslog(LOG_WARNING, "user {$username} is unknown"); + exit(-2); +} + +/* authenticate the user */ +$password = crypt($password, $user['password']); + +if ($password != $user['password']) { + syslog(LOG_WARNING, "user {$username} supplied an invalid password\n"); + exit(-3); +} + +syslog(LOG_WARNING, "user {$username} authenticated\n"); +exit(0); + +?> diff --git a/etc/inc/openvpn.inc b/etc/inc/openvpn.inc index 8dda12e..abc2337 100644 --- a/etc/inc/openvpn.inc +++ b/etc/inc/openvpn.inc @@ -49,13 +49,45 @@ require_once('util.inc'); $openvpn_prots = array("UDP", "TCP"); -$openvpn_auth_methods = array( - 'pki' => "Public Key Infrastructure", - 'shared_key' => "Pre Shared Key"); +/* + * The User Auth mode below is disabled because + * OpenVPN erroneously requires that we provide + * a CA configuration parameter. In this mode, + * clients don't send a certificate so there is + * no need for a CA. If we require that admins + * provide one in the pfSense UI due to a bogus + * requirement imposed by OpenVPN, it could be + * considered very confusing ( I know I was ). + * + * -mgrooms + */ + +$openvpn_server_modes = array( + 'p2p_tls' => "Peer to Peer ( SSL/TLS )", + 'p2p_shared_key' => "Peer to Peer ( Shared Key )", + 'server_tls' => "Remote Access ( SSL/TLS )", +// 'server_user' => "Remote Access ( User Auth )", + 'server_tls_user' => "Remote Access ( SSL/TLS + User Auth )"); + +$openvpn_client_modes = array( + 'p2p_tls' => "Peer to Peer ( SSL/TLS )", + 'p2p_shared_key' => "Peer to Peer ( Shared Key )" ); + +function openvpn_create_key() { + + $fp = popen("/usr/local/sbin/openvpn --genkey --secret /dev/stdout 2>/dev/null", "r"); + if (!$fp) + return false; + + $rslt = stream_get_contents($fp); + pclose($fp); + + return $rslt; +} function openvpn_create_dhparams($bits) { - $fp = popen("/usr/bin/openssl dhparam {$bits}", "r"); + $fp = popen("/usr/bin/openssl dhparam {$bits} 2>/dev/null", "r"); if (!$fp) return false; @@ -268,61 +300,64 @@ function openvpn_reconfigure($mode,& $settings) { $lines = explode(' ', trim(shell_exec("ifconfig {$iface} | grep inet | grep -v inet6"))); $iface_ip = $lines[1]; -$conf .= <<<EOD -dev {$devname} -dev-type tun -dev-node /dev/{$tunname} -writepid {$pfile} -#user nobody -#group nobody -daemon -keepalive 10 60 -ping-timer-rem -persist-tun -persist-key -proto $proto -cipher $cipher -up /etc/rc.filter_configure -down /etc/rc.filter_configure -local {$iface_ip} - -EOD; - - // Mode specific stuff + $conf = "dev {$devname}\n"; + $conf .= "dev-type tun\n"; + $conf .= "dev-node /dev/{$tunname}\n"; + $conf .= "writepid {$pfile}\n"; + $conf .= "#user nobody\n"; + $conf .= "#group nobody\n"; + $conf .= "daemon\n"; + $conf .= "keepalive 10 60\n"; + $conf .= "ping-timer-rem\n"; + $conf .= "persist-tun\n"; + $conf .= "persist-key\n"; + $conf .= "proto {$proto}\n"; + $conf .= "cipher {$cipher}\n"; + $conf .= "up /etc/rc.filter_configure\n"; + $conf .= "down /etc/rc.filter_configure\n"; + $conf .= "local {$iface_ip}\n"; + + // server specific settings if ($mode == 'server') { list($ip, $mask) = explode('/', $settings['tunnel_network']); $mask = gen_subnet_mask($mask); - // Using a shared key or not dynamically assigning IPs to the clients - if (($settings['auth_method'] == 'shared_key') || (!$settings['pool_enable'] == 'on')) { - - if ($settings['auth_method'] == 'pki') + // configure tls modes + switch($settings['mode']) { + case 'p2p_tls': + case 'server_tls': + case 'server_tls_user': $conf .= "tls-server\n"; - - $baselong = ip2long($ip) & ip2long($mask); - $ip1 = long2ip($baselong + 1); - $ip2 = long2ip($baselong + 2); - $conf .= "ifconfig $ip1 $ip2\n"; + break; } - // Using a PKI - else if ($settings['auth_method'] == 'pki') { - if ($settings['client2client']) - $conf .= "client-to-client\n"; - - $conf .= "server $ip $mask\n"; - $csc_dir = "{$g['varetc_path']}/openvpn-csc"; - $conf .= "client-config-dir $csc_dir\n"; + // configure p2p/server modes + switch($settings['mode']) { + case 'p2p_tls': + case 'p2p_shared_key': + $baselong = ip2long($ip) & ip2long($mask); + $ip1 = long2ip($baselong + 1); + $ip2 = long2ip($baselong + 2); + $conf .= "ifconfig $ip1 $ip2\n"; + break; + case 'server_tls': + case 'server_user': + case 'server_tls_user': + $conf .= "server {$ip} {$mask}\n"; + $conf .= "client-config-dir {$g['varetc_path']}/openvpn-csc\n"; + break; } - // We can push routes - if (!empty($settings['local_network'])) { - - list($ip, $mask) = explode('/', $settings['local_network']); - $mask = gen_subnet_mask($mask); - $conf .= "push \"route $ip $mask\"\n"; + // configure user auth modes + switch($settings['mode']) { + case 'server_user': + $conf .= "client-cert-not-required\n"; + case 'server_tls_user': + $conf .= "username-as-common-name\n"; + $conf .= "auth-user-pass-verify /etc/inc/openvpn.auth-user.php via-env\n"; + break; } // The local port to listen on @@ -331,33 +366,52 @@ EOD; // The management port to listen on $conf .= "management 127.0.0.1 {$settings['local_port']}\n"; - if (!empty($settings['maxclients'])) + if ($settings['maxclients']) $conf .= "max-clients {$settings['maxclients']}\n"; - openvpn_add_dhcpopts($settings, $conf); + // Can we push routes + if ($settings['local_network']) { + list($ip, $mask) = explode('/', $settings['local_network']); + $mask = gen_subnet_mask($mask); + $conf .= "push \"route $ip $mask\"\n"; + } + + // Configure client dhcp options + switch($settings['mode']) { + case 'server_tls': + case 'server_user': + case 'server_tls_user': + openvpn_add_dhcpopts($settings, $conf); + break; + } } - if ($mode == 'client') { + // client specific settings - // The remote server - $conf .= "remote {$settings['server_addr']} {$settings['server_port']}\n"; + if ($mode == 'client') { - if ($settings['auth_method'] == 'pki') - $conf .= "client\n"; + // configure p2p mode + switch($settings['mode']) { + case 'p2p_tls': + $conf .= "tls-client\n"; + case 'shared_key': + $conf .= "client\n"; + break; + } - // FIXME : This should be a gui option // The port we'll listen at if ($settings['local_port']) $conf .= "lport {$settings['local_port']}\n"; else $conf .= "nobind\n"; + // The remote server + $conf .= "remote {$settings['server_addr']} {$settings['server_port']}\n"; + if (!empty($settings['use_shaper'])) $conf .= "shaper {$settings['use_shaper']}\n"; if (!empty($settings['tunnel_network'])) { - - // Configure the IPs according to the address pool list($ip, $mask) = explode('/', $settings['tunnel_network']); $mask = gen_subnet_mask($mask); $baselong = ip2long($ip) & ip2long($mask); @@ -366,41 +420,38 @@ EOD; $conf .= "ifconfig $ip2 $ip1\n"; } - if ($settings['proxy_addr']) { - /* ;http-proxy-retry # retry on connection failures */ + if ($settings['proxy_addr']) $conf .= "http-proxy {$settings['proxy_addr']} {$settings['proxy_port']}\n"; - } } - // Add the routes if they're set - if (!empty($settings['remote_network'])) { + // Add a remote network route if set + if ($settings['remote_network']) { list($ip, $mask) = explode('/', $settings['remote_network']); $mask = gen_subnet_mask($mask); $conf .= "route $ip $mask\n"; } // Write the settings for the keys - if ($settings['auth_method'] == 'shared_key') - openvpn_add_keyfile($settings['shared_key'], $conf, $mode_id, "secret"); - - if ($settings['auth_method'] == 'pki') { - - $ca = lookup_ca($settings['caref']); - $cert = lookup_cert($settings['certref']); - - openvpn_add_keyfile($ca['crt'], $conf, $mode_id, "ca"); - openvpn_add_keyfile($cert['crt'], $conf, $mode_id, "cert"); - openvpn_add_keyfile($cert['prv'], $conf, $mode_id, "key"); - - if ($mode == 'server') { - $path_ovdh = $g['varetc_path']."/openvpn/dh-parameters"; - $conf .= "dh {$path_ovdh}\n"; - } - - if ($settings['crl']) - openvpn_add_keyfile($settings['crl'], $conf, $mode_id, "crl-verify"); - if ($settings['tls']) - openvpn_add_keyfile($settings['tls'], $conf, $mode_id, "tls-auth"); + switch($settings['mode']) { + case 'p2p_shared_key': + openvpn_add_keyfile($settings['shared_key'], $conf, $mode_id, "secret"); + break; + case 'p2p_tls': + case 'server_tls': + case 'server_tls_user': + $ca = lookup_ca($settings['caref']); + openvpn_add_keyfile($ca['crt'], $conf, $mode_id, "ca"); + case 'server_user': + $cert = lookup_cert($settings['certref']); + openvpn_add_keyfile($cert['crt'], $conf, $mode_id, "cert"); + openvpn_add_keyfile($cert['prv'], $conf, $mode_id, "key"); + if ($mode == 'server') + $conf .= "dh {$g['varetc_path']}/openvpn/dh-parameters\n"; + if ($settings['crl']) + openvpn_add_keyfile($settings['crl'], $conf, $mode_id, "crl-verify"); + if ($settings['tls']) + openvpn_add_keyfile($settings['tls'], $conf, $mode_id, "tls-auth"); + break; } if ($settings['compression']) diff --git a/usr/local/www/vpn_openvpn_client.php b/usr/local/www/vpn_openvpn_client.php index c3fbcb5..724668d 100644 --- a/usr/local/www/vpn_openvpn_client.php +++ b/usr/local/www/vpn_openvpn_client.php @@ -66,6 +66,9 @@ if ($_GET['act'] == "del") { } if($_GET['act']=="new"){ + $pconfig['autokey_enable'] = "yes"; + $pconfig['tlsauth_enable'] = "yes"; + $pconfig['autotls_enable'] = "yes"; $pconfig['interface'] = "wan"; $pconfig['server_port'] = 1194; } @@ -75,6 +78,7 @@ if($_GET['act']=="edit"){ if (isset($id) && $a_client[$id]) { $pconfig['disable'] = $a_client[$id]['disable']; + $pconfig['mode'] = $a_client[$id]['mode']; $pconfig['protocol'] = $a_client[$id]['protocol']; $pconfig['interface'] = $a_client[$id]['interface']; $pconfig['local_port'] = $a_client[$id]['local_port']; @@ -85,19 +89,25 @@ if($_GET['act']=="edit"){ $pconfig['proxy_port'] = $a_client[$id]['proxy_port']; $pconfig['description'] = $a_client[$id]['description']; - $pconfig['auth_method'] = $a_client[$id]['auth_method']; - if ($pconfig['auth_method'] == "shared_key") - $pconfig['shared_key'] = base64_decode($a_client[$id]['shared_key']); - else { + if ($pconfig['mode'] != "p2p_shared_key") { $pconfig['caref'] = $a_client[$id]['caref']; $pconfig['certref'] = $a_client[$id]['certref']; - } + if ($a_client[$id]['tls']) { + $pconfig['tlsauth_enable'] = "yes"; + $pconfig['tls'] = base64_decode($a_client[$id]['tls']); + } + } else + $pconfig['shared_key'] = base64_decode($a_client[$id]['shared_key']); $pconfig['crypto'] = $a_client[$id]['crypto']; $pconfig['tunnel_network'] = $a_client[$id]['tunnel_network']; $pconfig['remote_network'] = $a_client[$id]['remote_network']; $pconfig['compression'] = $a_client[$id]['compression']; $pconfig['passtos'] = $a_client[$id]['passtos']; + + // just in case the modes switch + $pconfig['autokey_enable'] = "yes"; + $pconfig['autotls_enable'] = "yes"; } } @@ -111,6 +121,11 @@ if ($_POST) { else $vpnid = 0; + if ($client['mode'] != "p2p_shared_key") + $tls_mode = true; + else + $tls_mode = false; + /* input validation */ if ($pconfig['local_port']) { @@ -142,12 +157,17 @@ if ($_POST) { if ($result = openvpn_validate_cidr($pconfig['remote_network'], 'Remote network')) $input_errors[] = $result; - if ($pconfig['auth_method'] == 'shared_key') + if (!$tls_mode && !$pconfig['autokey_enable']) if (!strstr($pconfig['shared_key'], "-----BEGIN OpenVPN Static key V1-----") || !strstr($pconfig['shared_key'], "-----END OpenVPN Static key V1-----")) - $input_errors[] = "The field 'Shared Key' does not appear to be valid"; + $input_errors[] = "The field 'Shared Key' does not appear to be valid"; + + if ($tls_mode && $pconfig['tlsauth_enable'] && !$pconfig['autotls_enable']) + if (!strstr($pconfig['tls'], "-----BEGIN OpenVPN Static key V1-----") || + !strstr($pconfig['tls'], "-----END OpenVPN Static key V1-----")) + $input_errors[] = "The field 'TLS Authentication Key' does not appear to be valid"; - if ($pconfig['auth_method'] == 'shared_key') { + if (!$tls_mode) { $reqdfields = array('shared_key'); $reqdfieldsn = array('Shared key'); } else { @@ -180,13 +200,19 @@ if ($_POST) { $client['proxy_port'] = $pconfig['proxy_port']; $client['description'] = $pconfig['description']; - $client['auth_method'] = $pconfig['auth_method']; - if ($client['auth_method'] == "shared_key") - $client['shared_key'] = base64_encode($pconfig['shared_key']); - else { - $client['caref'] = $pconfig['caref']; - $client['certref'] = $pconfig['certref']; - } + if ($tls_mode) { + $client['caref'] = $pconfig['caref']; + $client['certref'] = $pconfig['certref']; + if ($pconfig['tlsauth_enable']) { + if ($pconfig['autotls_enable']) + $pconfig['tls'] = openvpn_create_key(); + $client['tls'] = base64_encode($pconfig['tls']); + } + } else { + if ($pconfig['autokey_enable']) + $pconfig['shared_key'] = openvpn_create_key(); + $client['shared_key'] = base64_encode($pconfig['shared_key']); + } $client['crypto'] = $pconfig['crypto']; $client['tunnel_network'] = $pconfig['tunnel_network']; @@ -215,23 +241,58 @@ include("head.inc"); <script language="JavaScript"> <!-- -function method_change() { - index = document.iform.auth_method.selectedIndex; - value = document.iform.auth_method.options[index].value; +function mode_change() { + index = document.iform.mode.selectedIndex; + value = document.iform.mode.options[index].value; switch(value) { - case "pki": - document.getElementById("pki_ca").style.display=""; - document.getElementById("pki_cert").style.display=""; + case "p2p_tls": + document.getElementById("tls").style.display=""; + document.getElementById("tls_ca").style.display=""; + document.getElementById("tls_cert").style.display=""; document.getElementById("psk").style.display="none"; break; - case "shared_key": - document.getElementById("pki_ca").style.display="none"; - document.getElementById("pki_cert").style.display="none"; + case "p2p_shared_key": + document.getElementById("tls").style.display="none"; + document.getElementById("tls_ca").style.display="none"; + document.getElementById("tls_cert").style.display="none"; document.getElementById("psk").style.display=""; break; } } +function autokey_change() { + if (document.iform.autokey_enable.checked) + document.getElementById("autokey_opts").style.display="none"; + else + document.getElementById("autokey_opts").style.display=""; +} + +function tlsauth_change() { + +<?php if (!$pconfig['tls']): ?> + if (document.iform.tlsauth_enable.checked) + document.getElementById("tlsauth_opts").style.display=""; + else + document.getElementById("tlsauth_opts").style.display="none"; +<?php endif; ?> + + autotls_change(); +} + +function autotls_change() { + +<?php if (!$pconfig['tls']): ?> + autocheck = document.iform.autotls_enable.checked; +<?php else: ?> + autocheck = false; +<?php endif; ?> + + if (document.iform.tlsauth_enable.checked && !autocheck) + document.getElementById("autotls_opts").style.display=""; + else + document.getElementById("autotls_opts").style.display="none"; +} + //--> </script> <?php @@ -285,6 +346,21 @@ function method_change() { </td> </tr> <tr> + <td width="22%" valign="top" class="vncellreq"><?=gettext("Server Mode");?></td> + <td width="78%" class="vtable"> + <select name='mode' id='mode' class="formselect" onchange='mode_change()'> + <?php + foreach ($openvpn_client_modes as $name => $desc): + $selected = ""; + if ($pconfig['mode'] == $name) + $selected = "selected"; + ?> + <option value="<?=$name;?>" <?=$selected;?>><?=$desc;?></option> + <?php endforeach; ?> + </select> + </td> + </tr> + <tr> <td width="22%" valign="top" class="vncellreq"><?=gettext("Protocol");?></td> <td width="78%" class="vtable"> <select name='protocol' class="formselect"> @@ -386,23 +462,50 @@ function method_change() { <tr> <td colspan="2" valign="top" class="listtopic">Cryptographic Settings</td> </tr> - <tr> - <td width="22%" valign="top" class="vncellreq">Authentication Method</td> - <td width="78%" class="vtable"> - <select name='auth_method' id='auth_method' class="formselect" onchange='method_change()'> - <?php - foreach ($openvpn_auth_methods as $method => $name): - $selected = ""; - if ($pconfig['auth_method'] == $method) - $selected = "selected"; - ?> - <option value="<?=$method;?>" <?=$selected;?>><?=$name;?></option> - <?php endforeach; ?> - </select> - </td> + <tr id="tls"> + <td width="22%" valign="top" class="vncellreq">TLS Authentication</td> + <td width="78%" class="vtable"> + <table border="0" cellpadding="2" cellspacing="0"> + <tr> + <td> + <?php set_checked($pconfig['tlsauth_enable'],$chk); ?> + <input name="tlsauth_enable" id="tlsauth_enable" type="checkbox" value="yes" <?=$chk;?> onClick="tlsauth_change()"> + </td> + <td> + <span class="vexpl"> + Enable authentication of TLS packets. + </span> + </td> + </tr> + </table> + <?php if (!$pconfig['tls']): ?> + <table border="0" cellpadding="2" cellspacing="0" id='tlsauth_opts'> + <tr> + <td> + <?php set_checked($pconfig['autotls_enable'],$chk); ?> + <input name="autotls_enable" id="autotls_enable" type="checkbox" value="yes" <?=$chk;?> onClick="autotls_change()"> + </td> + <td> + <span class="vexpl"> + Automatically generate a shared TLS authentication key. + </span> + </td> + </tr> + </table> + <?php endif; ?> + <table border="0" cellpadding="2" cellspacing="0" id='autotls_opts'> + <tr> + <td> + <textarea name="tls" cols="65" rows="7" class="formpre"><?=htmlspecialchars($pconfig['tls']);?></textarea> + <br/> + Paste your shared key here. + </td> + </tr> + </table> + </td> </tr> - <tr id="pki_ca"> - <td width="22%" valign="top" class="vncellreq">Certificate Authority</td> + <tr id="tls_ca"> + <td width="22%" valign="top" class="vncellreq">Peer Certificate Authority</td> <td width="78%" class="vtable"> <select name='caref' class="formselect"> <?php @@ -416,8 +519,8 @@ function method_change() { </select> </td> </tr> - <tr id="pki_cert"> - <td width="22%" valign="top" class="vncellreq">Certificate</td> + <tr id="tls_cert"> + <td width="22%" valign="top" class="vncellreq">Client Certificate</td> <td width="78%" class="vtable"> <select name='certref' class="formselect"> <?php @@ -433,10 +536,31 @@ function method_change() { </tr> <tr id="psk"> <td width="22%" valign="top" class="vncellreq">Shared Key</td> - <td width="78%" class="vtable"> - <textarea name="shared_key" cols="65" rows="7" class="formpre"><?=htmlspecialchars($pconfig['shared_key']);?></textarea> - <br/> - Paste your shared key here. + <td width="78%" class="vtable"> + <?php if (!$pconfig['shared_key']): ?> + <table border="0" cellpadding="2" cellspacing="0"> + <tr> + <td> + <?php set_checked($pconfig['autokey_enable'],$chk); ?> + <input name="autokey_enable" type="checkbox" value="yes" <?=$chk;?> onClick="autokey_change()"> + </td> + <td> + <span class="vexpl"> + Automatically generate a shared key. + </span> + </td> + </tr> + </table> + <?php endif; ?> + <table border="0" cellpadding="2" cellspacing="0" id='autokey_opts'> + <tr> + <td> + <textarea name="shared_key" cols="65" rows="7" class="formpre"><?=htmlspecialchars($pconfig['shared_key']);?></textarea> + <br/> + Paste your shared key here. + </td> + </tr> + </table> </td> </tr> <tr> @@ -619,7 +743,9 @@ function method_change() { </table> <script language="JavaScript"> <!-- -method_change(); +mode_change(); +autokey_change(); +tlsauth_change(); //--> </script> </body> diff --git a/usr/local/www/vpn_openvpn_server.php b/usr/local/www/vpn_openvpn_server.php index 41ec000..60cefce 100644 --- a/usr/local/www/vpn_openvpn_server.php +++ b/usr/local/www/vpn_openvpn_server.php @@ -66,6 +66,9 @@ if ($_GET['act'] == "del") { } if($_GET['act']=="new"){ + $pconfig['autokey_enable'] = "yes"; + $pconfig['tlsauth_enable'] = "yes"; + $pconfig['autotls_enable'] = "yes"; $pconfig['interface'] = "wan"; $pconfig['local_port'] = openvpn_port_next('UDP'); $pconfig['pool_enable'] = "yes"; @@ -76,18 +79,21 @@ if($_GET['act']=="edit"){ if (isset($id) && $a_server[$id]) { $pconfig['disable'] = $a_server[$id]['disable']; + $pconfig['mode'] = $a_server[$id]['mode']; $pconfig['protocol'] = $a_server[$id]['protocol']; $pconfig['interface'] = $a_server[$id]['interface']; $pconfig['local_port'] = $a_server[$id]['local_port']; $pconfig['description'] = $a_server[$id]['description']; - $pconfig['auth_method'] = $a_server[$id]['auth_method']; - if ($pconfig['auth_method'] == "shared_key") - $pconfig['shared_key'] = base64_decode($a_server[$id]['shared_key']); - else { + if ($pconfig['mode'] != "p2p_shared_key") { $pconfig['caref'] = $a_server[$id]['caref']; $pconfig['certref'] = $a_server[$id]['certref']; - } + if ($a_server[$id]['tls']) { + $pconfig['tlsauth_enable'] = "yes"; + $pconfig['tls'] = base64_decode($a_server[$id]['tls']); + } + } else + $pconfig['shared_key'] = base64_decode($a_server[$id]['shared_key']); $pconfig['crypto'] = $a_server[$id]['crypto']; $pconfig['tunnel_network'] = $a_server[$id]['tunnel_network']; @@ -134,6 +140,10 @@ if($_GET['act']=="edit"){ $pconfig['nbdd_server1'] = $a_server[$id]['nbdd_server1']; if ($pconfig['nbdd_server1']) $pconfig['nbdd_server_enable'] = true; + + // just in case the modes switch + $pconfig['autokey_enable'] = "yes"; + $pconfig['autotls_enable'] = "yes"; } } @@ -147,6 +157,11 @@ if ($_POST) { else $vpnid = 0; + if ($server['mode'] != "p2p_shared_key") + $tls_mode = true; + else + $tls_mode = false; + /* input validation */ if ($result = openvpn_validate_port($pconfig['local_port'], 'Local port')) $input_errors[] = $result; @@ -163,10 +178,15 @@ if ($_POST) { if (openvpn_port_used($pconfig['protocol'], $pconfig['local_port']) != $vpnid) $input_errors[] = "The specified 'Local port' is in use. Please select another value"; - if ($pconfig['auth_method'] == 'shared_key') + if (!$tls_mode && !$pconfig['autokey_enable']) if (!strstr($pconfig['shared_key'], "-----BEGIN OpenVPN Static key V1-----") || !strstr($pconfig['shared_key'], "-----END OpenVPN Static key V1-----")) - $input_errors[] = "The field 'Shared Key' does not appear to be valid"; + $input_errors[] = "The field 'Shared Key' does not appear to be valid"; + + if ($tls_mode && $pconfig['tlsauth_enable'] && !$pconfig['autotls_enable']) + if (!strstr($pconfig['tls'], "-----BEGIN OpenVPN Static key V1-----") || + !strstr($pconfig['tls'], "-----END OpenVPN Static key V1-----")) + $input_errors[] = "The field 'TLS Authentication Key' does not appear to be valid"; if ($pconfig['dns_server_enable']) { if (!empty($pconfig['dns_server1']) && !is_ipaddr(trim($pconfig['dns_server1']))) @@ -205,7 +225,7 @@ if ($_POST) { if ($pconfig['maxclients'] && !is_numeric($pconfig['maxclients'])) $input_errors[] = "The field 'Concurrent connections' must be numeric."; - if ($pconfig['auth_method'] == 'shared_key') { + if (!$tls_mode) { $reqdfields = array('shared_key'); $reqfieldsn = array('Shared key'); } else { @@ -228,17 +248,24 @@ if ($_POST) { $server['vpnid'] = openvpn_vpnid_next(); $server['disable'] = $pconfig['disable']; + $server['mode'] = $pconfig['mode']; $server['protocol'] = $pconfig['protocol']; $server['interface'] = $pconfig['interface']; $server['local_port'] = $pconfig['local_port']; $server['description'] = $pconfig['description']; - $server['auth_method'] = $pconfig['auth_method']; - if ($server['auth_method'] == "shared_key") - $server['shared_key'] = base64_encode($pconfig['shared_key']); - else { + if ($tls_mode) { $server['caref'] = $pconfig['caref']; $server['certref'] = $pconfig['certref']; + if ($pconfig['tlsauth_enable']) { + if ($pconfig['autotls_enable']) + $pconfig['tls'] = openvpn_create_key(); + $server['tls'] = base64_encode($pconfig['tls']); + } + } else { + if ($pconfig['autokey_enable']) + $pconfig['shared_key'] = openvpn_create_key(); + $server['shared_key'] = base64_encode($pconfig['shared_key']); } $server['crypto'] = $pconfig['crypto']; @@ -305,21 +332,71 @@ include("head.inc"); <script language="JavaScript"> <!-- -function method_change() { - index = document.iform.auth_method.selectedIndex; - value = document.iform.auth_method.options[index].value; +function mode_change() { + index = document.iform.mode.selectedIndex; + value = document.iform.mode.options[index].value; switch(value) { - case "pki": - document.getElementById("pki_ca").style.display=""; - document.getElementById("pki_cert").style.display=""; + case "p2p_tls": + case "server_tls": + case "server_user": + case "server_tls_user": + document.getElementById("tls").style.display=""; + document.getElementById("tls_ca").style.display=""; + document.getElementById("tls_cert").style.display=""; document.getElementById("psk").style.display="none"; break; - case "shared_key": - document.getElementById("pki_ca").style.display="none"; - document.getElementById("pki_cert").style.display="none"; + case "p2p_shared_key": + document.getElementById("tls").style.display="none"; + document.getElementById("tls_ca").style.display="none"; + document.getElementById("tls_cert").style.display="none"; document.getElementById("psk").style.display=""; break; } + switch(value) { + case "p2p_tls": + case "p2p_shared_key": + document.getElementById("client_opts").style.display="none"; + document.getElementById("remote_opts").style.display=""; + break; + default: + document.getElementById("client_opts").style.display=""; + document.getElementById("remote_opts").style.display="none"; + break; + } +} + +function autokey_change() { + + if (document.iform.autokey_enable.checked) + document.getElementById("autokey_opts").style.display="none"; + else + document.getElementById("autokey_opts").style.display=""; +} + +function tlsauth_change() { + +<?php if (!$pconfig['tls']): ?> + if (document.iform.tlsauth_enable.checked) + document.getElementById("tlsauth_opts").style.display=""; + else + document.getElementById("tlsauth_opts").style.display="none"; +<?php endif; ?> + + autotls_change(); +} + +function autotls_change() { + +<?php if (!$pconfig['tls']): ?> + autocheck = document.iform.autotls_enable.checked; +<?php else: ?> + autocheck = false; +<?php endif; ?> + + if (document.iform.tlsauth_enable.checked && !autocheck) + document.getElementById("autotls_opts").style.display=""; + else + document.getElementById("autotls_opts").style.display="none"; } function gwredir_change() { @@ -426,6 +503,21 @@ function netbios_change() { </td> </tr> <tr> + <td width="22%" valign="top" class="vncellreq"><?=gettext("Server Mode");?></td> + <td width="78%" class="vtable"> + <select name='mode' id='mode' class="formselect" onchange='mode_change()'> + <?php + foreach ($openvpn_server_modes as $name => $desc): + $selected = ""; + if ($pconfig['mode'] == $name) + $selected = "selected"; + ?> + <option value="<?=$name;?>" <?=$selected;?>><?=$desc;?></option> + <?php endforeach; ?> + </select> + </td> + </tr> + <tr> <td width="22%" valign="top" class="vncellreq"><?=gettext("Protocol");?></td> <td width="78%" class="vtable"> <select name='protocol' class="formselect"> @@ -480,23 +572,50 @@ function netbios_change() { <tr> <td colspan="2" valign="top" class="listtopic">Cryptographic Settings</td> </tr> - <tr> - <td width="22%" valign="top" class="vncellreq">Authentication Method</td> - <td width="78%" class="vtable"> - <select name='auth_method' id='auth_method' class="formselect" onchange='method_change()'> - <?php - foreach ($openvpn_auth_methods as $method => $name): - $selected = ""; - if ($pconfig['auth_method'] == $method) - $selected = "selected"; - ?> - <option value="<?=$method;?>" <?=$selected;?>><?=$name;?></option> - <?php endforeach; ?> - </select> - </td> + <tr id="tls"> + <td width="22%" valign="top" class="vncellreq">TLS Authentication</td> + <td width="78%" class="vtable"> + <table border="0" cellpadding="2" cellspacing="0"> + <tr> + <td> + <?php set_checked($pconfig['tlsauth_enable'],$chk); ?> + <input name="tlsauth_enable" id="tlsauth_enable" type="checkbox" value="yes" <?=$chk;?> onClick="tlsauth_change()"> + </td> + <td> + <span class="vexpl"> + Enable authentication of TLS packets. + </span> + </td> + </tr> + </table> + <?php if (!$pconfig['tls']): ?> + <table border="0" cellpadding="2" cellspacing="0" id='tlsauth_opts'> + <tr> + <td> + <?php set_checked($pconfig['autotls_enable'],$chk); ?> + <input name="autotls_enable" id="autotls_enable" type="checkbox" value="yes" <?=$chk;?> onClick="autotls_change()"> + </td> + <td> + <span class="vexpl"> + Automatically generate a shared TLS authentication key. + </span> + </td> + </tr> + </table> + <?php endif; ?> + <table border="0" cellpadding="2" cellspacing="0" id='autotls_opts'> + <tr> + <td> + <textarea name="tls" cols="65" rows="7" class="formpre"><?=htmlspecialchars($pconfig['tls']);?></textarea> + <br/> + Paste your shared key here. + </td> + </tr> + </table> + </td> </tr> - <tr id="pki_ca"> - <td width="22%" valign="top" class="vncellreq">Certificate Authority</td> + <tr id="tls_ca"> + <td width="22%" valign="top" class="vncellreq">Peer Certificate Authority</td> <td width="78%" class="vtable"> <select name='caref' class="formselect"> <?php @@ -510,8 +629,8 @@ function netbios_change() { </select> </td> </tr> - <tr id="pki_cert"> - <td width="22%" valign="top" class="vncellreq">Certificate</td> + <tr id="tls_cert"> + <td width="22%" valign="top" class="vncellreq">Server Certificate</td> <td width="78%" class="vtable"> <select name='certref' class="formselect"> <?php @@ -527,10 +646,31 @@ function netbios_change() { </tr> <tr id="psk"> <td width="22%" valign="top" class="vncellreq">Shared Key</td> - <td width="78%" class="vtable"> - <textarea name="shared_key" cols="65" rows="7" class="formpre"><?=htmlspecialchars($pconfig['shared_key']);?></textarea> - <br/> - Paste your shared key here. + <td width="78%" class="vtable"> + <?php if (!$pconfig['shared_key']): ?> + <table border="0" cellpadding="2" cellspacing="0"> + <tr> + <td> + <?php set_checked($pconfig['autokey_enable'],$chk); ?> + <input name="autokey_enable" type="checkbox" value="yes" <?=$chk;?> onClick="autokey_change()"> + </td> + <td> + <span class="vexpl"> + Automatically generate a shared key. + </span> + </td> + </tr> + </table> + <?php endif; ?> + <table border="0" cellpadding="2" cellspacing="0" id='autokey_opts'> + <tr> + <td> + <textarea name="shared_key" cols="65" rows="7" class="formpre"><?=htmlspecialchars($pconfig['shared_key']);?></textarea> + <br/> + Paste your shared key here. + </td> + </tr> + </table> </td> </tr> <tr> @@ -572,20 +712,6 @@ function netbios_change() { </td> </tr> <tr> - <td width="22%" valign="top" class="vncell">Remote Network</td> - <td width="78%" class="vtable"> - <input name="remote_network" type="text" class="formfld unknown" size="20" value="<?=htmlspecialchars($pconfig['remote_network']);?>"> - <br> - 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. - </td> - </tr> - <tr> <td width="22%" valign="top" class="vncell">Redirect Gateway</td> <td width="78%" class="vtable"> <table border="0" cellpadding="2" cellspacing="0"> @@ -616,6 +742,20 @@ function netbios_change() { This is generally set to your LAN network. </td> </tr> + <tr id="remote_opts"> + <td width="22%" valign="top" class="vncell">Remote Network</td> + <td width="78%" class="vtable"> + <input name="remote_network" type="text" class="formfld unknown" size="20" value="<?=htmlspecialchars($pconfig['remote_network']);?>"> + <br> + 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. + </td> + </tr> <tr> <td width="22%" valign="top" class="vncell"><?=gettext("Concurrent connections");?></td> <td width="78%" class="vtable"> @@ -678,6 +818,9 @@ function netbios_change() { </table> </td> </tr> + </table> + + <table width="100%" border="0" cellpadding="6" cellspacing="0" id="client_opts"> <tr> <td colspan="2" class="list" height="12"></td> </tr> @@ -911,6 +1054,9 @@ function netbios_change() { </table> </td> </tr> + </table> + + <table width="100%" border="0" cellpadding="6" cellspacing="0" id="client_opts"> <tr> <td width="22%" valign="top"> </td> <td width="78%"> @@ -991,7 +1137,9 @@ function netbios_change() { </table> <script language="JavaScript"> <!-- -method_change(); +mode_change(); +autokey_change(); +tlsauth_change(); gwredir_change(); dns_domain_change(); dns_server_change(); |