summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorScott Ullrich <sullrich@pfsense.org>2005-10-12 16:49:15 +0000
committerScott Ullrich <sullrich@pfsense.org>2005-10-12 16:49:15 +0000
commitafb07cf1534c335bc9cffd49f00ba171cea5702c (patch)
treee5cc650292f7dd67af9b77de4e3b61bd027ec840
parent8d3a4a1e12e23b6d3333de75f403c712a99d3c64 (diff)
downloadpfsense-afb07cf1534c335bc9cffd49f00ba171cea5702c.zip
pfsense-afb07cf1534c335bc9cffd49f00ba171cea5702c.tar.gz
Sync OpenVPN with http://www.protec-t.de/m0n0wall/downloads from Peter Allgeyer
-rw-r--r--etc/inc/openvpn.inc1291
-rwxr-xr-xusr/local/www/vpn_openvpn.php2
-rwxr-xr-xusr/local/www/vpn_openvpn_ccd.php192
-rwxr-xr-xusr/local/www/vpn_openvpn_ccd_edit.php420
-rwxr-xr-xusr/local/www/vpn_openvpn_cli.php50
-rwxr-xr-xusr/local/www/vpn_openvpn_cli_edit.php608
-rwxr-xr-xusr/local/www/vpn_openvpn_crl.php159
-rwxr-xr-xusr/local/www/vpn_openvpn_crl_edit.php241
-rwxr-xr-xusr/local/www/vpn_openvpn_srv.php187
-rwxr-xr-xusr/local/www/vpn_openvpn_srv_edit.php1167
10 files changed, 3831 insertions, 486 deletions
diff --git a/etc/inc/openvpn.inc b/etc/inc/openvpn.inc
index 0953779..1036f31 100644
--- a/etc/inc/openvpn.inc
+++ b/etc/inc/openvpn.inc
@@ -3,6 +3,7 @@
openvpn.inc
Copyright (C) 2004 Peter Curran (peter@closeconsultants.com).
+ Copyright (C) 2005 Peter Allgeyer (allgeyer@web.de).
All rights reserved.
Redistribution and use in source and binary forms, with or without
@@ -35,6 +36,8 @@ require_once("functions.inc");
function ovpn_configure($reconfigure) {
global $config;
if (is_array($config['ovpn']['server']))
+ ovpn_server_crl_add();
+ ovpn_server_ccd_add();
ovpn_config_server($reconfigure);
if (is_array($config['ovpn']['client']))
ovpn_config_client();
@@ -50,13 +53,13 @@ function ovpn_link_tap() {
mwexec("/sbin/kldload if_tap");
$fd = fopen($g['vardb_path'] ."/ovpn_tap_link", 'w');
}
- else {
- $fd = fopen($g['vardb_path'] ."/ovpn_tap_link", 'r+');
- $link_count = fread($fd);
- $link_count ++;
- }
- fwrite($fd, $link_count);
- fclose($fd);
+ //else {
+ // $fd = fopen($g['vardb_path'] ."/ovpn_tap_link", 'r+');
+ // $link_count = fread($fd, filesize($g['vardb_path'] ."/ovpn_tap_link"));
+ // $link_count ++;
+ //}
+ //fwrite($fd, $link_count);
+ //fclose($fd);
return true;
}
@@ -68,8 +71,8 @@ function ovpn_unlink_tap() {
return false; //no file, no links so why are we called?
$fd = fopen($g['vardb_path'] ."/ovpn_tap_link", 'r+');
- $link_count = fread($fd);
- $link_count --;
+ $link_count = fread($fd, filesize($g['vardb_path'] ."/ovpn_tap_link"));
+ $link_count--;
fwrite($fd, $link_count);
fclose($fd);
@@ -82,146 +85,103 @@ function ovpn_unlink_tap() {
/* Server related functions */
/*****************************/
-function getnxt_server_if($type) {
- /* find the first available device of type $type */
- global $config;
- $a_server = $config['ovpn']['server']['tunnel'];
- $max = ($type == 'tun') ? 17 : 4;
- for ($i = 0; $i < $max ; $i++) {
- $hit = false;
- foreach ($a_server as $server) {
- if ($server['tun_iface'] == $type . $i) {
- $hit = true;
- break;
- }
- }
- if (!$hit)
- return $type . $i;
- }
- return false;
-}
-
-function getnxt_server_port() {
- /* Get first unused port */
- global $config;
- $a_server = $config['ovpn']['server']['tunnel'];
- $port = 1194;
- while (true) {
- $hit = false;
- foreach ($a_server as $server) {
- if ($server['port'] == $port) {
- $hit = true;
- break;
- }
- }
- if (!$hit)
- if (!ovpn_port_inuse_client($port))
- return $port;
- $port++;
- }
- return false; /* should never get here */
-}
-
/* Configure the server */
function ovpn_config_server($reconfigure) {
- global $config, $g;
+ global $config, $g, $d_ovpnsrvdirty_path;
foreach ($config['ovpn']['server']['tunnel'] as $id => $server) {
/* get tunnel interface */
$tun = $server['tun_iface'];
- /* kill any running openvpn daemon */
- killbypid($g['varrun_path']."/ovpn_srv_{$tun}.pid");
-
if (isset($server['enable'])) {
- if ($g['booting'])
+ if ($g['booting']) {
echo "Starting OpenVPN server $id... ";
+ /* define configuration options */
+ ovpn_srv_config_generate($id);
+
+ /* Start the openvpn daemon */
+ mwexec("/usr/local/sbin/openvpn {$g['varetc_path']}/ovpn_srv_{$tun}.conf");
+
+ /* Send the boot message */
+ echo "done\n";
+
+ /* next server */
+ continue;
+ }
+
/* send SIGUSR1 to running openvpn daemon */
if ( $reconfigure == "true" && isset($server['dynip'])) {
sigkillbypid($g['varrun_path']."/ovpn_srv_{$tun}.pid", "SIGUSR1");
continue;
}
- /* Remove old certs & keys */
- unlink_if_exists("{$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem");
- unlink_if_exists("{$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem");
- unlink_if_exists("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem");
- unlink_if_exists("{$g['vardb_path']}/ovpn_dh_{$tun}.pem");
- unlink_if_exists("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem");
- unlink_if_exists("{$g['varetc_path']}/ovpn_srv_up_{$tun}.pem");
- unlink_if_exists("{$g['varetc_path']}/ovpn_cli_up_{$tun}.pem");
-
- /* Copy the TLS-Server certs & keys to disk */
- $fd = fopen("{$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem", "w");
- if ($fd) {
- fwrite($fd, base64_decode($server['ca_cert'])."\n");
- fclose($fd);
- }
- $fd = fopen("{$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem", "w");
- if ($fd) {
- fwrite($fd, base64_decode($server['srv_cert'])."\n");
- fclose($fd);
- }
- touch ("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem");
- chmod ("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem", 0600);
- $fd = fopen("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem", "w");
- if ($fd) {
- fwrite($fd, base64_decode($server['srv_key'])."\n");
- fclose($fd);
- }
- $fd = fopen("{$g['vardb_path']}/ovpn_dh_{$tun}.pem", "w");
- if ($fd) {
- fwrite($fd, base64_decode($server['dh_param'])."\n");
- fclose($fd);
- }
+ /* read dirtyfile */
+ if (is_readable($d_ovpnsrvdirty_path))
+ $lines = file($d_ovpnsrvdirty_path);
+
+ /* reconfigure server */
+ if (is_array($lines) && in_array($tun, $lines)) {
+
+ /* kill running server */
+ ovpn_server_kill($tun);
+
+ /* remove old certs & keys */
+ ovpn_server_certs_del($tun);
- touch ("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem");
- chmod ("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem", 0600);
- $fd = fopen("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem", "w");
- if ($fd) {
- fwrite($fd, base64_decode($server['pre-shared-key'])."\n");
- fclose($fd);
+ /* define configuration options */
+ ovpn_srv_config_generate($id);
}
/* Start the openvpn daemon */
- mwexec("/usr/local/sbin/openvpn " . ovpn_srv_config_generate($id));
+ if (!is_readable("{$g['varrun_path']}/ovpn_srv_{$tun}.pid"))
+ mwexec("/usr/local/sbin/openvpn {$g['varetc_path']}/ovpn_srv_{$tun}.conf");
- if ($g['booting'])
- /* Send the boot message */
- echo "done\n";
+ /* next server */
+ continue;
}
- else {
- if (!$g['booting']){
- /* stop any processes, unload the tap module */
- /* Remove old certs & keys */
- ovpn_server_kill($tun);
- if ($server['type'] == "tap")
- ovpn_unlink_tap();
- }
+ /* server disabled */
+ if (!$g['booting']) {
+ /* kill running server */
+ ovpn_server_kill($tun);
+
+ /* Remove old certs & keys */
+ ovpn_server_certs_del($tun);
+
+ /* stop any processes, unload the tap module */
+ //if ($server['type'] == "tap")
+ // ovpn_unlink_tap();
}
}
return 0;
}
/* Kill off a running server process */
-function ovpn_server_kill($tun) {
+function ovpn_server_certs_del($tun) {
global $g;
- killbypid("{$g['varrun_path']}/ovpn_srv_{$tun}.pid");
-
/* Remove old certs & keys */
unlink_if_exists("{$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem");
unlink_if_exists("{$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem");
unlink_if_exists("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem");
unlink_if_exists("{$g['vardb_path']}/ovpn_dh_{$tun}.pem");
unlink_if_exists("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem");
+ unlink_if_exists("{$g['varetc_path']}/ovpn_srv_up_{$tun}.sh");
+ unlink_if_exists("{$g['varetc_path']}/ovpn_srv_{$tun}.conf");
return 0;
}
+/* Kill off a running server process */
+function ovpn_server_kill($tun) {
+ global $g;
+
+ /* kill running server */
+ killbypid("{$g['varrun_path']}/ovpn_srv_{$tun}.pid");
+}
+
/* Generate the config for a OpenVPN server */
function ovpn_srv_config_generate($id) {
global $config, $g;
@@ -233,140 +193,253 @@ function ovpn_srv_config_generate($id) {
/* get optional interface name */
$iface = ovpn_get_opt_interface($tun);
+ /* Copy the TLS-Server certs & keys to disk */
+ if ($server['authentication_method'] != "pre_shared_key" ) {
+
+ $fd = fopen("{$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem", "w");
+ if ($fd) {
+ fwrite($fd, base64_decode($server['ca_cert'])."\n");
+ fclose($fd);
+ }
+
+ $fd = fopen("{$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem", "w");
+ if ($fd) {
+ fwrite($fd, base64_decode($server['srv_cert'])."\n");
+ fclose($fd);
+ }
+
+ touch ("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem");
+ chmod ("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem", 0600);
+ $fd = fopen("{$g['vardb_path']}/ovpn_srv_key_{$tun}.pem", "w");
+ if ($fd) {
+ fwrite($fd, base64_decode($server['srv_key'])."\n");
+ fclose($fd);
+ }
+
+ $fd = fopen("{$g['vardb_path']}/ovpn_dh_{$tun}.pem", "w");
+ if ($fd) {
+ fwrite($fd, base64_decode($server['dh_param'])."\n");
+ fclose($fd);
+ }
+ }
+
+ if ($server['authentication_method'] == "pre_shared_key" || isset($server['tlsauth'])) {
+ touch ("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem");
+ chmod ("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem", 0600);
+ $fd = fopen("{$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem", "w");
+ if ($fd) {
+ fwrite($fd, base64_decode($server['pre-shared-key'])."\n");
+ fclose($fd);
+ }
+ }
+
+ $fd = fopen("{$g['varetc_path']}/ovpn_srv_{$tun}.conf", "w");
+ if (!$fd) {
+ printf("Error: cannot open ovpn_srv_{$tun}.conf in ovpn_srv_config_generate($id).\n");
+ return 1;
+ }
+
/* First the generic stuff:
- We are a server
- - We are a TLS Server (for authentication)
- We will run without privilege
*/
- $ovpn_config = "--daemon --user nobody --group nobody --verb {$server['verb']} --persist-tun --persist-key --status /var/log/openvpn_{$tun}.log 60 ";
-
- /* pid file */
- $ovpn_config .= "--writepid {$g['varrun_path']}/ovpn_srv_{$tun}.pid ";
-
- /* interface */
- $ovpn_config .= "--dev {$server['tun_iface']} ";
-
- /* port */
- $ovpn_config .= "--port {$server['port']} ";
+ $ovpn_config = "";
+ $ovpn_config .= <<<EOD
+daemon
+user nobody
+group nobody
+verb {$server['verb']}
+persist-tun
+persist-key
+status /var/log/openvpn_{$tun}.log 60
+writepid {$g['varrun_path']}/ovpn_srv_{$tun}.pid
+dev {$server['tun_iface']}
+port {$server['port']}
+cipher {$server['crypto']}
+
+EOD;
/* Set protocol being used (p = udp (default), tcp-server) */
- if ($server['proto'] == 'tcp') {
- $ovpn_config .= "--proto tcp ";
- }
-
+ if ($server['proto'] == "tcp")
+ $ovpn_config .= "proto tcp-server\n";
+
/* Interface binding - 1 or all */
- if ($server['bind_iface'] != 'all') {
+ if ($server['bind_iface'] != 'all')
if ($ipaddr = ovpn_get_ip($server['bind_iface']))
- $ovpn_config .= "--local $ipaddr ";
- else
- return "Interface bridged";
- }
+ $ovpn_config .= "local {$ipaddr}\n";
/* are we using dynamic ip addresses? */
if (isset($server['dynip']))
- $ovpn_config .= "--persist-remote-ip ";
-
+ $ovpn_config .= "persist-remote-ip\n";
+
/* Client to client routing (off by default) */
if (isset($server['cli2cli']))
- $ovpn_config .= "--client-to-client ";
-
- /* Set maximum simultaneous clients */
- $ovpn_config .= "--max-clients {$server['maxcli']} ";
-
- /* bridging enabled? */
- if (($ifname = $config['interfaces'][$iface]['bridge']) && $server['type'] == "tap") {
- $gateway = $config['interfaces'][$ifname]['ipaddr'];
- $netmask = gen_subnet_mask($config['interfaces'][$ifname]['subnet']);
- $poolstart = $server['ipblock'];
- $poolend = gen_subnet_max($server['ipblock'], $server['prefix']);
+ $ovpn_config .= "client-to-client\n";
- $ovpn_config .= "--server-bridge $gateway $netmask $poolstart $poolend ";
+ /* Limit server to a maximum of n concurrent clients. */
+ if (!empty($server['maxcli']))
+ $ovpn_config .= "max-clients {$server['maxcli']}\n";
- $lastdigits = substr($tun, 3) + 2;
- $ovpn_srv_up = "/sbin/ifconfig " . $tun . " 127.0.0." . $lastdigits . "/32\n";
+ /* Authentication method */
+ if ($server['authentication_method'] != "pre_shared_key") {
- $fd = fopen("{$g['varetc_path']}/ovpn_srv_up_{$tun}.sh", "w");
- if ($fd) {
- fwrite($fd, $ovpn_srv_up);
- fclose($fd);
- chmod ("{$g['varetc_path']}/ovpn_srv_up_{$tun}.sh", 0755);
- $ovpn_config .= "--up /var/etc/ovpn_srv_up_{$tun}.sh ";
+ $ovpn_config .= <<<EOD
+client-config-dir {$g['vardb_path']}/ccd
+ca {$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem
+cert {$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem
+key {$g['vardb_path']}/ovpn_srv_key_{$tun}.pem
+dh {$g['vardb_path']}/ovpn_dh_{$tun}.pem
+
+EOD;
+
+ /* CRL list */
+ if (isset($server['crlname']) &&
+ is_readable("{$g['vardb_path']}/{$server['crlname']}.crl.pem")) {
+ $ovpn_config .= "crl-verify {$g['vardb_path']}/{$server['crlname']}.crl.pem\n";
}
+
+ /* TLS auth */
+ if (isset($server['tlsauth']))
+ $ovpn_config .= "tls-auth {$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem 0\n";
+
+ /* bridging enabled? */
+ if ($server['bridge'] && $server['type'] == "tap") {
+ if ($server['method'] == "ovpn") {
+ $netmask = gen_subnet_mask($config['interfaces'][$server['bridge']]['subnet']);
+ $ovpn_config .= "server-bridge {$server['gateway']} {$netmask} {$server['range_from']} {$server['range_to']}\n";
+ } else {
+ $ovpn_config .= <<<EOD
+mode server
+tls-server
+
+EOD;
+ }
+
+ $lastdigits = substr($tun, 3) + 2;
+ $ovpn_srv_up = "/sbin/ifconfig " . $tun . " 127.0.0." . $lastdigits . "/32\n";
+
+ $fdo = fopen("{$g['varetc_path']}/ovpn_srv_up_{$tun}.sh", "w");
+ if ($fdo) {
+ fwrite($fdo, $ovpn_srv_up);
+ fclose($fdo);
+ chmod ("{$g['varetc_path']}/ovpn_srv_up_{$tun}.sh", 0755);
+ $ovpn_config .= "up /var/etc/ovpn_srv_up_{$tun}.sh\n";
+ }
+
+ } else {
+ /* Not bridged, can be tun or tap, doesn't matter */
+ $netmask = gen_subnet_mask($server['prefix']);
+
+ if ($server['method'] == "ovpn") {
+ /* new --server macro simplifies config */
+ $ovpn_config .= "server {$server['ipblock']} {$netmask}\n";
+ } else {
+ $ovpn_config .= <<<EOD
+mode server
+tls-server
+ifconfig {$server['ipblock']} {$netmask}
+
+EOD;
+ }
+ } /* end bridging */
+
+ /* Duplicate CNs */
+ if (isset($server['dupcn']))
+ $ovpn_config .= "duplicate-cn\n";
+
} else {
- /* New --server macro simplifies config */
- $netmask = gen_subnet_mask($server['prefix']);
+ /* 'authentication_method' == "pre_shared_key" */
+ $network = gen_subnet($server['lipaddr'], $server['netmask']);
+ $netmask = gen_subnet_mask($server['netmask']);
- $ovpn_config .= "--server {$server['ipblock']} {$netmask} ";
- }
-
- /* TLS-Server params */
- $ovpn_config .= "--ca {$g['vardb_path']}/ovpn_ca_cert_{$tun}.pem ";
- $ovpn_config .= "--cert {$g['vardb_path']}/ovpn_srv_cert_{$tun}.pem ";
- $ovpn_config .= "--key {$g['vardb_path']}/ovpn_srv_key_{$tun}.pem ";
- $ovpn_config .= "--dh {$g['vardb_path']}/ovpn_dh_{$tun}.pem ";
-
- /* TLS auth */
- if (isset($server['tlsauth']))
- $ovpn_config .= "--tls-auth {$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem 0 ";
-
- /* Data channel encryption cipher*/
- $ovpn_config .= "--cipher {$server['crypto']} ";
+ $ovpn_config .= "secret {$g['vardb_path']}/ovpn_srv_psk_{$tun}.pem 0\n";
+
+ if (strstr($server['type'], "tun")) {
+ $ovpn_config .= "ifconfig {$server['lipaddr']} {$server['ripaddr']}\n";
+ $ovpn_config .= "route {$network} {$netmask}\n";
+ } else {
+ $ovpn_config .= "ifconfig {$server['lipaddr']} {$netmask}\n";
+ }
+
+ if (isset($server['client-to-client']))
+ $ovpn_config .= "push \"route {$network} {$netmask}\"\n";
+ else
+ $ovpn_config .= "push \"route {$server['lipaddr']}\"\n";
+
+ } /* end authentication_method */
+
+ $push_options = "";
- /* Duplicate CNs */
- if (isset($server['dupcn']))
- $ovpn_config .= "--duplicate-cn ";
-
/* Client push - redirect gateway */
- if (isset($server['psh_options']['redir'])){
+ if (isset($server['psh_options']['redir'])) {
if (isset($server['psh_options']['redir_loc']))
- $ovpn_config .= "--push \"redirect-gateway local\" ";
+ $push_config .= "push \"redirect-gateway local\"\n";
else
- $ovpn_config .= "--push \"redirect-gateway\" ";
+ $push_config .= "push \"redirect-gateway\"\n";
+ if ($server['method'] != "ovpn")
+ $push_config .= "push \"route-gateway {$server['ipblock']}\"\n";
}
-
+
/* Client push - route delay */
if (isset($server['psh_options']['rte_delay']))
- $ovpn_config .= "--push \"route-delay {$server['psh_options']['rte_delay_int']}\" ";
-
+ $push_config .= "push \"route-delay {$server['psh_options']['rte_delay_int']}\"\n";
+
/* Client push - ping (note we set both server and client) */
if (isset ($server['psh_options']['ping'])){
$conflict = true;
$interval = $server['psh_options']['ping_int'];
- $ovpn_config .= "--ping {$server['psh_options']['ping_int']} ";
- $ovpn_config .= "--push \"ping {$server['psh_options']['ping_int']}\" ";
+ $ovpn_config .= "ping {$server['psh_options']['ping_int']}\n ";
+ $push_config .= "push \"ping {$server['psh_options']['ping_int']}\"\n";
}
-
+
/* Client push - ping-restart (note server uses 2 x client interval) */
if (isset ($server['psh_options']['pingrst'])){
$conflict = true;
$interval = $server['psh_options']['pingrst_int'];
- $ovpn_config .= "--ping-restart " . ($interval * 2) . " ";
- $ovpn_config .= "--push \"ping-restart $interval\" ";
+ $ovpn_config .= "ping-restart " . ($interval * 2) . "\n";
+ $push_config .= "push \"ping-restart $interval\"\n";
}
-
+
/* Client push - ping-exit (set on client) */
if (isset ($server['psh_options']['pingexit'])){
$conflict = true;
- $ovpn_config .= "--ping-exit {$server['psh_options']['pingexit_int']} ";
- $ovpn_config .= "--push \"ping-exit {$server['psh_options']['pingexit_int']}\" ";
+ $ovpn_config .= "ping-exit {$server['psh_options']['pingexit_int']}\n";
+ $push_config .= "push \"ping-exit {$server['psh_options']['pingexit_int']}\"\n";
}
-
+
/* Client push - inactive (set on client) */
if (isset ($server['psh_options']['inact'])){
- $ovpn_config .= "--inactive {$server['psh_options']['inact_int']} ";
- $ovpn_config .= "--push \"inactive {$server['psh_options']['inact_int']}\" ";
+ $ovpn_config .= "inactive {$server['psh_options']['inact_int']}\n";
+ $push_config .= "push \"inactive {$server['psh_options']['inact_int']}\"\n";
}
-
+
+ if (isset($push_config))
+ $ovpn_config .= $push_config;
+
if (!isset($conflict))
- $ovpn_config .= "--keepalive 10 60 ";
+ $ovpn_config .= "keepalive 10 60\n";
+
+ /* Expert mode paramters */
+ if (isset($server['expertmode_enabled']) && is_array($server['expertmode'])) {
+ $ovpn_config .= ";begin expertmode\n";
+ foreach ($server['expertmode']['option'] as $option) {
+ $ovpn_config .= "{$option}\n";
+ }
+ $ovpn_config .= ";end expertmode\n";
+ }
+
+ fwrite($fd, $ovpn_config);
+ fclose($fd);
//trigger_error("OVPN: $ovpn_config", E_USER_NOTICE);
- return $ovpn_config;
}
/* Define an OVPN Server tunnel interface in the interfaces array and assign a name */
function ovpn_server_iface(){
global $config, $g;
+
+ unset($filter_configure);
+ unset($bridge_configure);
foreach ($config['ovpn']['server']['tunnel'] as $id => $server) {
if (isset($server['enable'])) {
@@ -382,17 +455,31 @@ function ovpn_server_iface(){
&& ($config['interfaces'][$ifname]['ovpn'] == "server_{$tun}"))
/* Already an interface defined - overwrite */
break;
- }
- else {
+ } else {
+
/* No existing entry, this is first unused */
$config['interfaces'][$ifname] = array();
+
+ /* add new filter rules */
+ $filter_configure = true;
break;
}
$i++;
}
- $config['interfaces'][$ifname]['descr'] = strtoupper($ifname);
+ $config['interfaces'][$ifname]['descr'] = strtoupper($server['tun_iface']);
$config['interfaces'][$ifname]['if'] = $server['tun_iface'];
- $config['interfaces'][$ifname]['ipaddr'] = long2ip( ip2long($server['ipblock']) + 1);
+ if ($server['method'] == "ovpn")
+ $config['interfaces'][$ifname]['ipaddr'] = long2ip( ip2long($server['ipblock']) + 1);
+ else
+ $config['interfaces'][$ifname]['ipaddr'] = $server['ipblock'];
+ if (isset($server['bridge'])) {
+ $config['interfaces'][$ifname]['bridge'] = $server['bridge'];
+ $bridge_configure = true;
+ } else if (isset($config['interfaces'][$ifname]['bridge'])) {
+ /* bridge config removed */
+ unset ($config['interfaces'][$ifname]['bridge']);
+ $bridge_configure = true;
+ }
$config['interfaces'][$ifname]['subnet'] = $server['prefix'];
$config['interfaces'][$ifname]['enable'] = isset($server['enable']) ? true : false;
$config['interfaces'][$ifname]['ovpn'] = "server_{$tun}";
@@ -400,6 +487,13 @@ function ovpn_server_iface(){
write_config();
}
}
+
+ /* do we have to reconfigure filter rules? */
+ if (isset($bridge_configure))
+ interfaces_optional_configure();
+ else if (isset($filter_configure))
+ filter_configure();
+
return "OpenVPN server interface defined";
}
@@ -416,7 +510,6 @@ function ovpn_server_iface_del($tun) {
}
}
-
/* shift down other OPTn interfaces to get rid of holes */
$i++;
@@ -428,153 +521,339 @@ function ovpn_server_iface_del($tun) {
unset($config['interfaces']['opt' . $i]);
$i++;
}
+
+ /* reconfigure filter rules */
+ interfaces_optional_configure();
}
+/* Add client config file */
+function ovpn_server_ccd_add() {
+ global $config, $g;
-/****************************/
-/* Client related functions */
-/****************************/
+ if (is_array($config['ovpn']['server']['ccd'])) {
+ foreach ($config['ovpn']['server']['ccd'] as $id => $server) {
+ /* define configuration options */
+ ovpn_server_ccd_generate($id);
+ }
+ }
+}
-function getnxt_client_if($type) {
- /* find the first available device of type $type */
- global $config;
- $max = ($type == 'tun') ? 17 : 4;
- for ($i = 0; $i < $max; $i++) {
- $hit = false;
- foreach ($a_client as $client) {
- if ($client['if'] == $type . $i) {
- $hit = true;
- break;
- }
+
+/* Construct client config file */
+function ovpn_server_ccd_generate($id) {
+ global $config, $g;
+ $ovpnccd = $config['ovpn']['server']['ccd'][$id];
+
+ $cn = $ovpnccd['cn'];
+ $ccd_config = "";
+ $push_options = "";
+
+ /* Push reset */
+ if (!isset($ovpnccd['disable']) && isset($ovpnccd['psh_reset'])) {
+ $ccd_config .= "push-reset\n";
+
+ /* Client push - redirect gateway */
+ if (isset($ovpnccd['psh_options']['redir'])) {
+ if (isset($ovpnccd['psh_options']['redir_loc']))
+ $push_config .= "push \"redirect-gateway local\"\n";
+ else
+ $push_config .= "push \"redirect-gateway\"\n";
+ }
+
+ /* Client push - route delay */
+ if (isset($ovpnccd['psh_options']['rte_delay']))
+ $push_config .= "push \"route-delay {$ovpnccd['psh_options']['rte_delay_int']}\"\n";
+
+ /* Client push - ping (note we set both server and client) */
+ if (isset ($ovpnccd['psh_options']['ping'])){
+ $ccd_config .= "ping {$server['psh_options']['ping_int']}\n ";
+ $push_config .= "push \"ping {$ovpnccd['psh_options']['ping_int']}\"\n";
+ }
+
+ /* Client push - ping-restart (note server uses 2 x client interval) */
+ if (isset ($ovpnccd['psh_options']['pingrst'])){
+ $interval = $ovpnccd['psh_options']['pingrst_int'];
+ $ccd_config .= "ping-restart " . ($interval * 2) . "\n";
+ $push_config .= "push \"ping-restart $interval\"\n";
+ }
+
+ /* Client push - ping-exit (set on client) */
+ if (isset ($ovpnccd['psh_options']['pingexit'])){
+ $ccd_config .= "ping-exit {$ovpnccd['psh_options']['pingexit_int']}\n";
+ $push_config .= "push \"ping-exit {$ovpnccd['psh_options']['pingexit_int']}\"\n";
+ }
+
+ /* Client push - inactive (set on client) */
+ if (isset ($ovpnccd['psh_options']['inact'])){
+ $ccd_config .= "inactive {$ovpnccd['psh_options']['inact_int']}\n";
+ $push_config .= "push \"inactive {$ovpnccd['psh_options']['inact_int']}\"\n";
+ }
+
+ if (isset($push_config))
+ $ccd_config .= $push_config;
+ }
+
+ if (!isset($ovpnccd['disable']) && is_array($ovpnccd['options'])) {
+ foreach ($ovpnccd['options']['option'] as $option) {
+ $ccd_config .= "{$option}\n";
+ }
+ }
+
+ /* Disable client from connecting */
+ if (isset($ovpnccd['disable']))
+ $ccd_config = "disable\n";
+
+ unlink_if_exists("{$g['vardb_path']}/ccd/{$cn}");
+
+ if (isset($ccd_config) && isset($ovpnccd['enable'])) {
+ $fd = fopen("{$g['vardb_path']}/ccd/{$cn}", "w");
+ if ($fd) {
+ fwrite($fd, $ccd_config."\n");
+ fclose($fd);
}
- if (!$hit)
- return $type . $i;
}
- return false;
}
-function getnxt_client_port() {
- /* Get first unused port */
- global $config;
- $a_client = $config['ovpn']['client']['tunnel'];
- $port = 1194;
- while (true) {
- $hit = false;
- foreach ($a_client as $client) {
- if ($client['port'] == $port) {
- $hit = true;
- break;
+/* Delete client config file */
+function ovpn_server_ccd_del($cn) {
+ global $g;
+
+ unlink_if_exists("{$g['vardb_path']}/ccd/{$cn}");
+ return 0;
+}
+
+/* Add CRL file */
+function ovpn_server_crl_add() {
+ global $config, $g, $d_ovpncrldirty_path;
+
+ if (is_array($config['ovpn']['server']['crl'])) {
+ foreach ($config['ovpn']['server']['crl'] as $id => $crlent) {
+ /* get crl file name */
+ $name = $crlent['crlname'];
+
+ if (isset($crlent['enable'])) {
+
+ /* add file */
+ ovpn_server_crl_generate($id);
+
+ if ($g['booting']) {
+ /* next crl file */
+ continue;
+ }
+
+ /* read dirtyfile */
+ if (is_readable($d_ovpncrldirty_path))
+ $lines = file($d_ovpncrldirty_path);
+
+ /* reconfigure crl file */
+ if (is_array($lines) && in_array($name, $lines)) {
+
+ /* restart running openvpn daemon */
+ foreach ($config['ovpn']['server']['tunnel'] as $id => $server) {
+ $tun = $server['tun_iface'];
+
+ if ($server['enable'] &&
+ isset($server['crlname']) && $server['crlname'] == $name)
+ /* kill running server */
+ ovpn_server_kill($tun);
+
+ /* Start the openvpn daemon */
+ mwexec("/usr/local/sbin/openvpn {$g['varetc_path']}/ovpn_srv_{$tun}.conf");
+ }
+
+ }
+
+ /* next crl file */
+ continue;
}
+
+ /* crl file disabled: remove file */
+ ovpn_server_crl_del($name);
}
- if (!$hit)
- if (!ovpn_port_inuse_server($port))
- return $port;
- $port++;
}
- return false; /* should never get here */
+ return 0;
}
-/* Port in use */
-function ovpn_port_inuse_client($port){
+/* Write CRL to file */
+function ovpn_server_crl_generate($id) {
+ global $config, $g;
+
+ $ovpncrl = $config['ovpn']['server']['crl'][$id];
+
+ $fd = fopen("{$g['vardb_path']}/{$ovpncrl['crlname']}.crl.pem", "w");
+ if ($fd) {
+ fwrite($fd, base64_decode($ovpncrl['crl_list'])."\n");
+ fclose($fd);
+ }
+}
+
+/* Delete CRL file */
+function ovpn_server_crl_del($name) {
+ global $config, $g;
+
+ /* have to wipe out the crl from the server config */
+ foreach ($config['ovpn']['server']['tunnel'] as $id => $server) {
+ if (isset($server['crlname']) && $server['crlname'] == $name) {
+
+ /* get tunnel interface */
+ $tun = $server['tun_iface'];
+
+ /* remove crl file entry */
+ unset($config['ovpn']['server']['tunnel'][$id]['crlname']);
+ write_config();
+
+ /* kill running server */
+ ovpn_server_kill($tun);
+
+ /* remove old certs & keys */
+ ovpn_server_certs_del($tun);
+
+ /* reconfigure daemon */
+ ovpn_srv_config_generate($id);
+
+ /* Start the openvpn daemon */
+ mwexec("/usr/local/sbin/openvpn {$g['varetc_path']}/ovpn_srv_{$tun}.conf");
+ }
+ }
+
+ unlink_if_exists("{$g['vardb_path']}/{$name}.crl.pem");
+ return 0;
+}
+
+
+/* Get a list of crl files */
+function ovpn_get_crl_list() {
global $config;
- $a_client = $config['ovpn']['client']['tunnel'];
- foreach ($a_client as $client) {
- if ($client['port'] == $port) {
- return true;
+
+ $crl_list = array();
+
+ if (is_array($config['ovpn']['server']['crl'])) {
+ foreach ($config['ovpn']['server']['crl'] as $crlent) {
+ if (isset($crlent['enable']))
+ $crl_list[] = $crlent['crlname'];
}
}
- return false;
+ return $crl_list;
+}
+
+/* append interface to $_ovpnsrvdirty_path */
+function ovpn_srv_dirty($tun) {
+ global $d_ovpnsrvdirty_path;
+
+ $fd = fopen($d_ovpnsrvdirty_path, 'a');
+ if ($fd) {
+ fwrite($fd, $tun);
+ fclose($fd);
+ }
}
+/* append file name to $_ovpncrldirty_path */
+function ovpn_crl_dirty($name) {
+ global $d_ovpncrldirty_path;
+
+ $fd = fopen($d_ovpncrldirty_path, 'a');
+ if ($fd) {
+ fwrite($fd, $name);
+ fclose($fd);
+ }
+}
+
+
+/****************************/
+/* Client related functions */
+/****************************/
+
function ovpn_config_client() {
/* Boot time configuration */
- global $config, $g;
+ global $config, $g, $d_ovpnclidirty_path;;
foreach ($config['ovpn']['client']['tunnel'] as $id => $client) {
/* get tunnel interface */
$tun = $client['if'];
- /* kill any running openvpn daemon */
- killbypid($g['varrun_path']."/ovpn_cli_{$tun}.pid");
-
if (isset($client['enable'])) {
-
- if ($g['booting'])
+
+ if ($g['booting']) {
echo "Starting OpenVPN client $id... ";
- /* Remove old certs & keys */
- unlink_if_exists("{$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem");
- unlink_if_exists("{$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem");
- unlink_if_exists("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem");
- unlink_if_exists("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem");
- unlink_if_exists("{$g['varetc_path']}/ovpn_cli_up_{$tun}.pem");
-
- /* Copy the TLS-Client certs & keys to disk */
- $fd = fopen("{$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem", "w");
- if ($fd) {
- fwrite($fd, base64_decode($client['ca_cert'])."\n");
- fclose($fd);
- }
- else
- trigger_error("OVPN: No open for CA", E_USER_NOTICE);
- $fd = fopen("{$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem", "w");
- if ($fd) {
- fwrite($fd, base64_decode($client['cli_cert'])."\n");
- fclose($fd);
- }
- touch ("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem");
- chmod ("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem", 0600);
- $fd = fopen("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem", "w");
- if ($fd) {
- fwrite($fd, base64_decode($client['cli_key'])."\n");
- fclose($fd);
- }
- touch ("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem");
- chmod ("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem", 0600);
- $fd = fopen("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem", "w");
- if ($fd) {
- fwrite($fd, base64_decode($client['pre-shared-key'])."\n");
- fclose($fd);
- }
-
- /* Start openvpn for this client */
- mwexec("/usr/local/sbin/openvpn " . ovpn_cli_config_generate($id));
+ /* define configuration options */
+ ovpn_cli_config_generate($id);
+
+ /* Start openvpn for this client */
+ mwexec("/usr/local/sbin/openvpn {$g['varetc_path']}/ovpn_cli_{$tun}.conf");
- if ($g['booting'])
/* Send the boot message */
echo "done\n";
- }
- else {
- if (!$g['booting']){
- /* stop any processes, unload the tap module */
- /* Remove old certs & keys */
+
+ /* next client */
+ continue;
+ }
+
+ /* read dirtyfile */
+ if (is_readable($d_ovpnclidirty_path))
+ $lines = file($d_ovpnclidirty_path);
+
+ /* reconfigure client */
+ if (is_array($lines) && in_array($tun, $lines)) {
+
+ /* kill running client */
ovpn_client_kill($tun);
- if ($client['type'] == "tap")
- ovpn_unlink_tap();
+ /* remove old certs & keys */
+ ovpn_client_certs_del($tun);
+
+ /* define configuration options */
+ ovpn_cli_config_generate($id);
}
+
+ /* Start the openvpn daemon */
+ if (!is_readable("{$g['varrun_path']}/ovpn_cli_{$tun}.pid"))
+ mwexec("/usr/local/sbin/openvpn {$g['varetc_path']}/ovpn_cli_{$tun}.conf");
+
+ /* next client */
+ continue;
+ }
+
+ /* client disabled */
+ if (!$g['booting']) {
+ /* kill running client */
+ ovpn_client_kill($tun);
+
+ /* remove old certs & keys */
+ ovpn_client_certs_del($tun);
+
+ /* stop any processes, unload the tap module */
+ //if ($client['type'] == "tap")
+ // ovpn_unlink_tap();
}
}
return 0;
-
}
/* Kill off a running client process */
-function ovpn_client_kill($tun) {
+function ovpn_client_certs_del($tun) {
global $g;
- killbypid("{$g['varrun_path']}/ovpn_cli_{$tun}.pid");
-
/* Remove old certs & keys */
unlink_if_exists("{$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem");
unlink_if_exists("{$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem");
unlink_if_exists("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem");
unlink_if_exists("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem");
+ unlink_if_exists("{$g['varetc_path']}/ovpn_cli_up_{$tun}.pem");
+ unlink_if_exists("{$g['varetc_path']}/ovpn_cli_{$tun}.conf");
return 0;
}
+/* Kill off a running client process */
+function ovpn_client_kill($tun) {
+ global $g;
+
+ /* kill running client */
+ killbypid("{$g['varrun_path']}/ovpn_cli_{$tun}.pid");
+}
+
/* Generate the config for a OpenVPN client */
function ovpn_cli_config_generate($id) {
/* configure the named client */
@@ -583,65 +862,151 @@ function ovpn_cli_config_generate($id) {
/* get tunnel interface */
$tun = $client['if'];
-
+
/* get optional interface name */
$iface = ovpn_get_opt_interface($tun);
- /* Client support in 2.0 is very simple */
- $ovpn_config = "--client --daemon --verb 1 --status /var/log/openvpn_{$tun}.log 60 ";
-
- /* pid file */
- $ovpn_config .= "--writepid {$g['varrun_path']}/ovpn_cli_{$tun}.pid ";
-
- /* interface */
- $ovpn_config .= "--dev {$client['if']} ";
-
- /* protocol */
- /* Set protocol being used (p = udp (default), tcp-client)
- if ($client['proto'] == 'tcp') {
- $ovpn_config .= "--proto tcp-client ";
+ /* Copy the TLS-Client certs & keys to disk */
+ if ($client['authentication_method'] != "pre_shared_key" ) {
+
+ $fd = fopen("{$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem", "w");
+ if ($fd) {
+ fwrite($fd, base64_decode($client['ca_cert'])."\n");
+ fclose($fd);
+ }
+
+ $fd = fopen("{$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem", "w");
+ if ($fd) {
+ fwrite($fd, base64_decode($client['cli_cert'])."\n");
+ fclose($fd);
+ }
+
+ touch ("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem");
+ chmod ("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem", 0600);
+ $fd = fopen("{$g['vardb_path']}/ovpn_cli_key_{$tun}.pem", "w");
+ if ($fd) {
+ fwrite($fd, base64_decode($client['cli_key'])."\n");
+ fclose($fd);
+ }
}
-
- /* port */
- $ovpn_config .= "--lport {$client['port']} ";
-
- /* server location */
- $ovpn_config .= "--remote {$client['saddr']} {$client['sport']} ";
-
- /* bridging enabled? */
- if (($ifname = $config['interfaces'][$iface]['bridge']) && $client['type'] == "tap") {
- $lastdigits = substr($tun, 3) + 2;
- $ovpn_srv_up = "/sbin/ifconfig " . $tun . " 127.0.0." . $lastdigits . "/32\n";
- $fd = fopen("{$g['varetc_path']}/ovpn_cli_up_{$tun}.sh", "w");
+ if ($client['authentication_method'] == "pre_shared_key" || isset($client['tlsauth'])) {
+ touch ("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem");
+ chmod ("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem", 0600);
+ $fd = fopen("{$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem", "w");
if ($fd) {
- fwrite($fd, $ovpn_cli_up);
- fclose($fd);
- chmod ("{$g['varetc_path']}/ovpn_cli_up_{$tun}.sh", 0755);
- $ovpn_config .= "--up /var/etc/ovpn_cli_up_{$tun}.sh ";
+ fwrite($fd, base64_decode($client['pre-shared-key'])."\n");
+ fclose($fd);
}
}
+ $fd = fopen("{$g['varetc_path']}/ovpn_cli_{$tun}.conf", "w");
+ if (!$fd) {
+ printf("Error: cannot open ovpn_cli_{$tun}.conf in ovpn_cli_config_generate($id).\n");
+ return 1;
+ }
+
+ /* Client support in 2.0 is very simple */
+ $ovpn_config = "";
+ $ovpn_config .= <<<EOD
+daemon
+verb 1
+status /var/log/openvpn_{$tun}.log 60
+writepid {$g['varrun_path']}/ovpn_cli_{$tun}.pid
+dev {$client['if']}
+lport {$client['cport']}
+remote {$client['saddr']} {$client['sport']}
+cipher {$client['crypto']}
+
+EOD;
+
+ /* Version 1.0 compatibility; http://openvpn.net/compat.html */
+ if ($client['ver'] != "2") {
+ $ovpn_config .= <<<EOD
+key-method 1
+tun-mtu 1500
+tun-mtu-extra 32
+mssfix 1450
+
+EOD;
+ }
+
+ /* Set protocol being used (p = udp (default), tcp-client) */
+ if ($client['proto'] == "tcp")
+ $ovpn_config .= "proto tcp-client\n";
+
/* TLS-Client params */
- $ovpn_config .= "--ca {$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem ";
- $ovpn_config .= "--cert {$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem ";
- $ovpn_config .= "--key {$g['vardb_path']}/ovpn_cli_key_{$tun}.pem ";
+ if ($client['authentication_method'] != "pre_shared_key") {
+ $ovpn_config .= <<<EOD
+ca {$g['vardb_path']}/ovpn_cli_ca_cert_{$tun}.pem
+cert {$g['vardb_path']}/ovpn_cli_cert_{$tun}.pem
+key {$g['vardb_path']}/ovpn_cli_key_{$tun}.pem
- /* TLS auth */
- if (isset($client['tlsauth']))
- $ovpn_config .= "--tls-auth {$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem 1 ";
+EOD;
- /* Data channel encryption cipher*/
- $ovpn_config .= "--cipher {$client['crypto']} ";
-
- //trigger_error("OVPN: $ovpn_config", E_USER_NOTICE);
- return $ovpn_config;
+ if (isset($client['pull']))
+ $ovpn_config .= "client\n";
+ else
+ $ovpn_config .= "tls-client\n";
+
+ /* TLS auth */
+ if (isset($client['ns_cert_type']))
+ $ovpn_config .= "ns-cert-type server\n";
+
+ /* TLS auth */
+ if (isset($client['tlsauth']))
+ $ovpn_config .= "tls-auth {$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem 1\n";
+
+ /* bridging enabled? */
+ if ($client['bridge'] && $client['type'] == "tap") {
+ $lastdigits = substr($tun, 3) + 2;
+ $ovpn_cli_up = "/sbin/ifconfig " . $tun . " 127.0.0." . $lastdigits . "/32\n";
+
+ $fdo = fopen("{$g['varetc_path']}/ovpn_cli_up_{$tun}.sh", "w");
+ if ($fdo) {
+ fwrite($fdo, $ovpn_cli_up);
+ fclose($fdo);
+ chmod ("{$g['varetc_path']}/ovpn_cli_up_{$tun}.sh", 0755);
+ $ovpn_config .= "up /var/etc/ovpn_cli_up_{$tun}.sh\n";
+ }
+ }
+
+ } else {
+ /* 'authentication_method' == "pre_shared_key" */
+ $ovpn_config .= "secret {$g['vardb_path']}/ovpn_cli_psk_{$tun}.pem 0\n";
+
+ $network = gen_subnet($client['lipaddr'], $client['netmask']);
+ $netmask = gen_subnet_mask($client['netmask']);
+
+ if (strstr($client['type'], "tap"))
+ $ovpn_config .= "ifconfig {$client['lipaddr']} {$netmask}\n";
+ else
+ $ovpn_config .= "ifconfig {$client['lipaddr']} {$client['ripaddr']}\n";
+
+ } /* end authentication_method */
+
+ /* Expert mode paramters */
+ if (isset($client['expertmode_enabled']) && is_array($client['expertmode'])) {
+ $ovpn_config .= ";begin expertmode\n";
+ foreach ($client['expertmode']['option'] as $option) {
+ $ovpn_config .= "{$option}\n";
+ }
+ $ovpn_config .= ";end expertmode\n";
+ }
+
+ fwrite($fd, $ovpn_config);
+ fclose($fd);
+
+ /* trigger_error("OVPN: $ovpn_config", E_USER_NOTICE); */
}
/* Define an OVPN tunnel interface in the interfaces array for each client */
function ovpn_client_iface(){
global $config;
+ unset($filter_configure);
+ unset($bridge_configure);
+
foreach ($config['ovpn']['client']['tunnel'] as $id => $client) {
if (isset($client['enable'])) {
@@ -656,23 +1021,41 @@ function ovpn_client_iface(){
&& ($config['interfaces'][$ifname]['ovpn'] == "client_{$tun}"))
/* Already an interface defined - overwrite */
break;
- }
- else {
+ } else {
+
/* No existing entry, this is first unused */
$config['interfaces'][$ifname] = array();
+
+ /* add new filter rules */
+ $filter_configure = true;
break;
}
$i++;
}
- $config['interfaces'][$ifname]['descr'] = strtoupper($ifname);
+ $config['interfaces'][$ifname]['descr'] = strtoupper($client['if']);
$config['interfaces'][$ifname]['if'] = $client['if'];
$config['interfaces'][$ifname]['ipaddr'] = "0.0.0.0";
$config['interfaces'][$ifname]['subnet'] = "0";
+ if (isset($client['bridge'])) {
+ $config['interfaces'][$ifname]['bridge'] = $client['bridge'];
+ $bridge_configure = true;
+ } else if (isset($config['interfaces'][$ifname]['bridge'])) {
+ /* bridge config removed */
+ unset ($config['interfaces'][$ifname]['bridge']);
+ $bridge_configure = true;
+ }
$config['interfaces'][$ifname]['enable'] = isset($client['enable']) ? true : false;
$config['interfaces'][$ifname]['ovpn'] = "client_{$tun}";
write_config();
}
}
+
+ /* do we have to reconfigure filter rules? */
+ if (isset($bridge_configure))
+ interfaces_optional_configure();
+ else if (isset($filter_configure))
+ filter_configure();
+
return "OpenVPN client interfaces defined";
}
@@ -689,7 +1072,6 @@ function ovpn_client_iface_del($tun) {
}
}
-
/* shift down other OPTn interfaces to get rid of holes */
$i++;
@@ -701,15 +1083,165 @@ function ovpn_client_iface_del($tun) {
unset($config['interfaces']['opt' . $i]);
$i++;
}
+
+ /* reconfigure filter rules */
+ interfaces_optional_configure();
+}
+
+/* append interface to ovpndirty_path */
+function ovpn_cli_dirty($tun) {
+ global $d_ovpnclidirty_path;
+
+ $fd = fopen($d_ovpnclidirty_path, 'a');
+ if ($fd) {
+ fwrite($fd, $tun);
+ fclose($fd);
+ }
}
/******************/
/* Misc functions */
+/******************/
+
+/* find the first available device of type $type */
+function getnxt_if($type) {
+ global $config;
+
+ /* initialize variables */
+ $iface_list = array();
+ $max = ($type == 'tun') ? 17 : 4;
+
+ /* construct list of valid interfaces */
+ for ($i = 0; $i < $max ; $i++)
+ array_push($iface_list, $type . $i);
+
+ /* delete interface in use from the list */
+ if ($a_server = $config['ovpn']['server']['tunnel']) {
+ foreach ($a_server as $server) {
+ $entry = array();
+ array_push($entry, $server['tun_iface']);
+ $iface_list = array_diff($iface_list, $entry);
+ }
+ }
+
+ /* same for list of client tunnels */
+ if ($a_client = $config['ovpn']['client']['tunnel']) {
+ foreach ($a_client as $client) {
+ $entry = array();
+ array_push($entry, $client['if']);
+ $iface_list = array_diff($iface_list, $entry);
+ }
+ }
+
+ /* return first element of list, if list of interfaces isn't empty */
+ if (count($iface_list))
+ return array_shift($iface_list);
+ else
+ return false;
+}
+
+/* find the next best available port */
+function getnxt_port() {
+
+ /* construct list of valid ports */
+ $port_list = free_port_list();
+
+ /* return first element of list, if list of ports isn't empty */
+ if (count($port_list))
+ return array_shift($port_list);
+ else
+ return false;
+}
+
+/* construct list of free ports */
+function free_port_list() {
+ global $config;
+
+ /* initialize variables */
+ $port_list = array();
+ $first_port = 1194;
+ $max = $first_port + 21;
+
+ for ($i = $first_port; $i < $max; $i++)
+ array_push($port_list, $i);
+
+ /* delete port in use from the list */
+ if ($a_server = $config['ovpn']['server']['tunnel']) {
+ foreach ($a_server as $server) {
+ $entry = array();
+ array_push($entry, $server['port']);
+ $port_list = array_diff($port_list, $entry);
+ }
+ }
+
+ /* same for list of client tunnels */
+ if ($a_client = $config['ovpn']['client']['tunnel']) {
+ foreach ($a_client as $client) {
+ $entry = array();
+ array_push($entry, $client['cport']);
+ $port_list = array_diff($port_list, $entry);
+ }
+ }
+
+ return $port_list;
+}
+
+/* construct list of used ports */
+function used_port_list() {
+ global $config;
+
+ /* initialize variables */
+ $port_list = array();
+
+ /* add used ports to the list */
+ if ($a_server = $config['ovpn']['server']['tunnel']) {
+ foreach ($a_server as $server) {
+ if (isset($server['enable']))
+ array_push($port_list, $server['port']);
+ }
+ }
+
+ /* same for list of client tunnels */
+ if ($a_client = $config['ovpn']['client']['tunnel']) {
+ foreach ($a_client as $client) {
+ if (isset($client['enable']))
+ array_push($port_list, $client['cport']);
+ }
+ }
+
+ return $port_list;
+}
+
+/* construct list of bindings used for a specified port */
+function used_bind_list($port) {
+ global $config;
+
+ /* initialize variables */
+ $bind_list = array();
+
+ /* add used bindings to the list */
+ if ($a_server = $config['ovpn']['server']['tunnel']) {
+ foreach ($a_server as $server) {
+ if (isset($server['enable']) && $server['port'] == $port)
+ array_push($bind_list, $server['bind_iface']);
+ }
+ }
+
+ /* client daemon always binds to 0.0.0.0 */
+ if ($a_client = $config['ovpn']['client']['tunnel']) {
+ foreach ($a_client as $client) {
+ if (isset($client['enable']) && $client['cport'] == $port)
+ array_push($bind_list, "all");
+ }
+ }
+
+ /* return list of bindings */
+ return $bind_list;
+}
/* Calculate the last address in a range given the start and /prefix */
function ovpn_calc_end($start, $prefix){
-
$first = ip2long($start);
$last = pow(2,(32 - $prefix)) - 1 + $first;
return long2ip($last);
@@ -717,17 +1249,17 @@ function ovpn_calc_end($start, $prefix){
/* Calculate a mask given a /prefix */
function ovpn_calc_mask($prefix){
-
return long2ip(ip2long("255.255.255.255") - (pow( 2, (32 - $prefix)) - 1));
}
/* Port in use */
function ovpn_port_inuse_server($port){
global $config;
- $a_server = $config['ovpn']['server']['tunnel'];
- foreach ($a_server as $server) {
- if ($server['port'] == $port) {
- return true;
+ if ($a_server = $config['ovpn']['server']['tunnel']) {
+ foreach ($a_server as $server) {
+ if ($server['port'] == $port) {
+ return true;
+ }
}
}
return false;
@@ -824,6 +1356,83 @@ function ovpn_real_interface_list(){
return $interfaces;
}
+/* called by interfaces_opt.php */
+function ovpn_ccd_sort() {
+ global $g, $config;
+
+ function ccdcmp($a, $b) {
+ return strcmp($a['cn'][0], $b['cn'][0]);
+ }
+
+ usort($config['ovpn']['server']['ccd'], "ccdcmp");
+
+}
+
+/* called by interfaces_opt.php */
+function ovpn_config_post() {
+ global $_POST, $optcfg, $pconfig;
+
+ unset($input_errors);
+
+ /* bridge check */
+ if ($_POST['bridge'] && strstr($optcfg['if'], "tun"))
+ $input_errors[] = "Bridging a tun interface isn't possible.";
+
+ if (($_POST['enable'] && !isset($optcfg['enable'])) || (!$_POST['enable'] && isset($optcfg['enable'])))
+ $input_errors[] = "Enabling or disabling a tunneling interface isn't supported on this page.";
+
+ if ($_POST['ipaddr'] != $optcfg['ipaddr'])
+ $input_errors[] = "Changing the IP address of a tunneling interfaces isn't supported on this page.";
+
+ if ($_POST['subnet'] != $optcfg['subnet'])
+ $input_errors[] = "Changing the subnet mask of a tunneling interfaces isn't supported on this page.";
+
+ if ($input_errors) {
+ $pconfig['ipaddr'] = $optcfg['ipaddr'];
+ $pconfig['subnet'] = $optcfg['subnet'];
+ $pconfig['bridge'] = $optcfg['bridge'];
+ $pconfig['enable'] = isset($optcfg['enable']);
+ }
+
+ return $input_errors;
+}
+
+function check_bridging($bridge) {
+ global $config;
+ unset($input_errors);
+
+ /* double bridging? */
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ if ($i != $index) {
+ if ($config['interfaces']['opt' . $i]['bridge'] == $bridge) {
+ $input_errors = "Optional interface {$i} " .
+ "({$config['interfaces']['opt' . $i]['descr']}) is already bridged to " .
+ "the specified interface.";
+ } else if ($config['interfaces']['opt' . $i]['bridge'] == "opt{$index}") {
+ $input_errors = "Optional interface {$i} " .
+ "({$config['interfaces']['opt' . $i]['descr']}) is already bridged to " .
+ "this interface.";
+ }
+ }
+ }
+
+ if ($config['interfaces'][$bridge]['bridge'])
+ $input_errors = "The specified interface is already bridged to another interface.";
+
+ return $input_errors;
+}
+
+/*
+function is_specialnet($net) {
+ $specialsrcdst = explode(" ", "lan");
+
+ if (in_array($net, $specialsrcdst))
+ return true;
+ else
+ return false;
+}
+*/
+
/* lock openvpn information, decide that the lock file is stale after
10 seconds */
diff --git a/usr/local/www/vpn_openvpn.php b/usr/local/www/vpn_openvpn.php
index 3388536..0f7175e 100755
--- a/usr/local/www/vpn_openvpn.php
+++ b/usr/local/www/vpn_openvpn.php
@@ -149,8 +149,8 @@ include("head.inc");
?>
-<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
<?php include("fbegin.inc"); ?>
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
<p class="pgtitle"><?=$pgtitle?></p>
<?php if ($input_errors) print_input_errors($input_errors); ?>
diff --git a/usr/local/www/vpn_openvpn_ccd.php b/usr/local/www/vpn_openvpn_ccd.php
new file mode 100755
index 0000000..8bf448e
--- /dev/null
+++ b/usr/local/www/vpn_openvpn_ccd.php
@@ -0,0 +1,192 @@
+#!/usr/local/bin/php
+<?php
+/*
+ vpn_openvpn_ccd.php
+
+ Copyright (C) 2005 Peter Allgeyer (allgeyer@web.de).
+ 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.
+*/
+
+require("guiconfig.inc");
+require_once("openvpn.inc");
+
+if (!is_array($config['ovpn']))
+ $config['ovpn'] = array();
+if (!is_array($config['ovpn']['server'])){
+ $config['ovpn']['server'] = array();
+ $config['ovpn']['server']['tunnel'] = array();
+}
+if (!is_array($config['ovpn']['server']['ccd']))
+ $config['ovpn']['server']['ccd'] = array();
+
+$ovpnccd = &$config['ovpn']['server']['ccd'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+
+if ($_POST['apply']) {
+ $retval = 0;
+
+ $retval = ovpn_server_ccd_add();
+
+#
+# /* should we send a SIGUSR1 to openvpn daemon? */
+# foreach ($config['ovpn']['server']['tunnel'] as $id => $server) {
+# /* get tunnel interface */
+# $tun = $server['tun_iface'];
+#
+# /* send SIGUSR1 to running openvpn daemon */
+# if (isset($server['enable']))
+# sigkillbypid($g['varrun_path']."/ovpn_srv_{$tun}.pid", "SIGUSR1");
+# }
+#
+
+ /* remove dirty flag */
+ unlink_if_exists($d_ovpnccddirty_path);
+
+ $savemsg = get_std_save_message($retval);
+}
+
+if ($_GET['act'] == "del") {
+ if ($ovpnccd[$id]) {
+ $ovpnent = $ovpnccd[$id];
+
+ unset($ovpnccd[$id]);
+ write_config();
+
+ /* Remove config files */
+ ovpn_server_ccd_del($ovpnent['cn']);
+
+ header("Location: vpn_openvpn_ccd.php");
+ exit;
+ }
+
+} else if ($_GET['act'] == "toggle") {
+ if ($ovpnccd[$_GET['id']]) {
+ $ovpnccd[$_GET['id']]['enable'] = !isset($ovpnccd[$_GET['id']]['enable']);
+ write_config();
+ touch($d_ovpnccddirty_path);
+ header("Location: vpn_openvpn_ccd.php");
+ exit;
+ }
+}
+
+$pgtitle = "VPN: OpenVPN";
+include("head.inc");
+
+?>
+
+<?php include("fbegin.inc"); ?>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if (file_exists($d_sysrebootreqd_path) && !file_exists($d_ovpnccddirty_path)) print_info_box(get_std_save_message(0)); ?>
+<form action="vpn_openvpn_ccd.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
+<?php if (file_exists($d_ovpnccddirty_path)): ?><p>
+<?php print_info_box_np("OpenVPN client-specific configuration options have been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="vpn_openvpn_srv.php">Server</a></li>
+ <li class="tabinact"><a href="vpn_openvpn_cli.php">Client</a></li>
+ <li class="tabact">Client-specific Configuration</li>
+ <li class="tabinact"><a href="vpn_openvpn_crl.php">CRL</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <strong><span class="red">WARNING: This feature is experimental and modifies your optional interface configuration.
+ Backup your configuration before using OpenVPN, and restore it before upgrading.<br>
+&nbsp; <br>
+ </span></strong>
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="5%" class="list">&nbsp;</td>
+ <td width="38%" class="listhdrr">Common Name</td>
+ <td width="47%" class="listhdr">Description</td>
+ <td width="10%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($ovpnccd as $ccd):
+
+ if (isset($ccd['disable']))
+ $iconfn = "block";
+ else
+ $iconfn = "pass";
+
+ if (!isset($ccd['enable'])) {
+ $spans = "<span class=\"gray\">";
+ $spane = "</span>";
+ $iconfn .= "_d";
+ } else {
+ $spans = $spane = "";
+ }
+ ?>
+
+ <tr>
+ <td class="listt" align="center">
+ <a href="?act=toggle&id=<?=$i;?>"><img src="<?=$iconfn;?>.gif"
+ width="11" height="11" border="0" title="click to toggle enabled/disabled status"></a>
+ </td>
+ <td class="listlr"><?=$spans;?>
+ <?= $ccd['cn'];?>
+ <?=$spane;?></td>
+ <td class="listbg"><?=$spans;?>
+ <?= htmlspecialchars($ccd['descr']);?>&nbsp;
+ <?=$spane;?></td>
+ <td valign="middle" nowrap class="list"><a href="vpn_openvpn_ccd_edit.php?id=<?=$i;?>"><img src="e.gif" title="edit client-specific configuration" width="17" height="17" border="0"></a>
+ &nbsp;<a href="vpn_openvpn_ccd.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this client-specific configuration?')"><img src="x.gif" title="delete client-specific configuration" width="17" height="17" border="0"></a></td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="3">&nbsp;</td>
+ <td class="list"><a href="vpn_openvpn_ccd_edit.php"><img src="plus.gif" title="add client-specific configuration" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td width="16"><img src="pass.gif" width="11" height="11"></td>
+ <td>pass</td>
+ <td width="14"></td>
+ <td width="16"><img src="block.gif" width="11" height="11"></td>
+ <td>block</td>
+ </tr>
+ <tr>
+ <td colspan="5" height="4"></td>
+ </tr>
+ <tr>
+ <td><img src="pass_d.gif" width="11" height="11"></td>
+ <td>pass (disabled)</td>
+ <td></td>
+ <td><img src="block_d.gif" width="11" height="11"></td>
+ <td>block (disabled)</td>
+ </tr>
+ </table>
+ </td>
+</tr>
+</table>
+</form>
+<?php include("fend.inc"); ?>
diff --git a/usr/local/www/vpn_openvpn_ccd_edit.php b/usr/local/www/vpn_openvpn_ccd_edit.php
new file mode 100755
index 0000000..850bc80
--- /dev/null
+++ b/usr/local/www/vpn_openvpn_ccd_edit.php
@@ -0,0 +1,420 @@
+#!/usr/local/bin/php
+<?php
+/*
+ vpn_openvpn_ccd_edit.php
+
+ Copyright (C) 2005 Peter Allgeyer (allgeyer@web.de).
+ 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.
+*/
+
+$pgtitle = array("VPN", "OpenVPN", "Edit client-specific configuration");
+require("guiconfig.inc");
+require_once("openvpn.inc");
+
+if (!is_array($config['ovpn']))
+ $config['ovpn'] = array();
+if (!is_array($config['ovpn']['server']))
+ $config['ovpn']['server'] = array();
+if (!is_array($config['ovpn']['server']['ccd']))
+ $config['ovpn']['server']['ccd'] = array();
+
+$ovpnccd =& $config['ovpn']['server']['ccd'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $ovpnccd[$id]) {
+
+ $pconfig = $config['ovpn']['server']['ccd'][$id];
+
+ if (isset($ovpnccd[$id]['enable']))
+ $pconfig['enable'] = true;
+
+ if (is_array($config['ovpn']['server']['ccd'][$id]['options'])) {
+ $pconfig['options'] = "";
+ foreach ($ovpnccd[$id]['options']['option'] as $optent) {
+ $pconfig['options'] .= $optent . "\n";
+ }
+ $pconfig['options'] = rtrim($pconfig['options']);
+ }
+
+} else {
+ /* creating - set defaults */
+ $pconfig = array();
+ $pconfig['enable'] = true;
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "cn");
+ $reqdfieldsn = explode(",", "Common name");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (preg_match("/[^a-zA-Z0-9\.\-_\:\/\@]/", $_POST['cn']))
+ $input_errors[] = "The common name contains invalid characters.";
+
+ if ($_POST['psh_pingrst'] && $_POST['psh_pingexit'])
+ $input_errors[] = "Ping-restart and Ping-exit are mutually exclusive and cannot be used together";
+
+ if ($_POST['psh_rtedelay'] && !is_numeric($_POST['psh_rtedelay_int']))
+ $input_errors[] = "Route-delay needs a numerical interval setting.";
+
+ if ($_POST['psh_inact'] && !is_numeric($_POST['psh_inact_int']))
+ $input_errors[] = "Inactive needs a numerical interval setting.";
+
+ if ($_POST['psh_ping'] && !is_numeric($_POST['psh_ping_int']))
+ $input_errors[] = "Ping needs a numerical interval setting.";
+
+ if ($_POST['psh_pingexit'] && !is_numeric($_POST['psh_pingexit_int']))
+ $input_errors[] = "Ping-exit needs a numerical interval setting.";
+
+ if ($_POST['psh_pingrst'] && !is_numeric($_POST['psh_pingrst_int']))
+ $input_errors[] = "Ping-restart needs a numerical interval setting.";
+
+ /* Editing an existing entry? */
+ if (!$input_errors && !(isset($id) && $ovpnccd[$id])) {
+ /* make sure there are no dupes */
+ foreach ($ovpnccd as $ccdent) {
+ if ($ccdent['cn'] == $_POST['cn']) {
+ $input_errors[] = "Another entry with the same common name already exists.";
+ break;
+ }
+ }
+ }
+
+ if (isset($id) && $ovpnccd[$id]) {
+ $ccdent = $ovpnccd[$id];
+
+ /* Has the enable/disable state changed? */
+ if (isset($ccdent['enable']) && isset($_POST['disabled'])) {
+ /* status changed to disabled */
+ touch($d_ovpnccddirty_path);
+ }
+
+ /* status changed to enable */
+ if (!isset($ccdent['enable']) && !isset($_POST['disabled'])) {
+ /* touch($d_sysrebootreqd_path); */
+ touch($d_ovpnccddirty_path);
+ }
+ }
+
+ if (!$input_errors) {
+
+ $ccdent = array();
+
+ if (isset($id) && $ovpnccd[$id])
+ $ccdent = $ovpnccd[$id];
+
+ $ccdent['cn'] = $_POST['cn'];
+ $ccdent['descr'] = $_POST['descr'];
+ $ccdent['enable'] = $_POST['disabled'] ? false : true;
+ $ccdent['disable'] = $_POST['disable'] ? true : false;
+
+
+ if (!is_array($options))
+ $options = array();
+ if (!is_array($ccdent['options']))
+ $ccdent['options'] = array();
+
+ $options['option'] = array_map('trim', explode("\n", trim($_POST['options'])));
+ $ccdent['options'] = $options;
+
+ $ccdent['psh_reset'] = $_POST['psh_reset'] ? true : false;
+ $ccdent['psh_options']['redir'] = $_POST['psh_redir'] ? true : false;
+ $ccdent['psh_options']['redir_loc'] = $_POST['psh_redir_loc'] ? true : false;
+ $ccdent['psh_options']['rtedelay'] = $_POST['psh_rtedelay'] ? true : false;
+ $ccdent['psh_options']['inact'] = $_POST['psh_inact'] ? true : false;
+ $ccdent['psh_options']['ping'] = $_POST['psh_ping'] ? true : false;
+ $ccdent['psh_options']['pingrst'] = $_POST['psh_pingrst'] ? true : false;
+ $ccdent['psh_options']['pingexit'] = $_POST['psh_pingexit'] ? true : false;
+
+ unset($ccdent['psh_options']['rtedelay_int']);
+ unset($ccdent['psh_options']['inact_int']);
+ unset($ccdent['psh_options']['ping_int']);
+ unset($ccdent['psh_options']['pingrst_int']);
+ unset($ccdent['psh_options']['pingexit_int']);
+
+ if ($_POST['psh_rtedelay_int'])
+ $ccdent['psh_options']['rtedelay_int'] = $_POST['psh_rtedelay_int'];
+ if ($_POST['psh_inact_int'])
+ $ccdent['psh_options']['inact_int'] = $_POST['psh_inact_int'];
+ if ($_POST['psh_ping_int'])
+ $ccdent['psh_options']['ping_int'] = $_POST['psh_ping_int'];
+ if ($_POST['psh_pingrst_int'])
+ $ccdent['psh_options']['pingrst_int'] = $_POST['psh_pingrst_int'];
+ if ($_POST['psh_pingexit_int'])
+ $ccdent['psh_options']['pingexit_int'] = $_POST['psh_pingexit_int'];
+
+ if (isset($id) && $ovpnccd[$id])
+ $ovpnccd[$id] = $ccdent;
+ else
+ $ovpnccd[] = $ccdent;
+
+ write_config();
+ touch($d_ovpnccddirty_path);
+
+ header("Location: vpn_openvpn_ccd.php");
+ exit;
+
+ } else {
+
+ $pconfig = $_POST;
+
+ $pconfig['enable'] = "true";
+ if (isset($_POST['disabled']))
+ unset($pconfig['enable']);
+
+ $pconfig['psh_reset'] = $_POST['psh_reset'];
+ $pconfig['psh_options']['redir'] = $_POST['psh_redir'];
+ $pconfig['psh_options']['redir_loc'] = $_POST['psh_redir_loc'];
+ $pconfig['psh_options']['rtedelay'] = $_POST['psh_rtedelay'];
+ $pconfig['psh_options']['inact'] = $_POST['psh_inact'];
+ $pconfig['psh_options']['ping'] = $_POST['psh_ping'];
+ $pconfig['psh_options']['pingrst'] = $_POST['psh_pingrst'];
+ $pconfig['psh_options']['pingexit'] = $_POST['psh_pingexit'];
+
+ $pconfig['psh_options']['rtedelay_int'] = $_POST['psh_rtedelay_int'];
+ $pconfig['psh_options']['inact_int'] = $_POST['psh_inact_int'];
+ $pconfig['psh_options']['ping_int'] = $_POST['psh_ping_int'];
+ $pconfig['psh_options']['pingrst_int'] = $_POST['psh_pingrst_int'];
+ $pconfig['psh_options']['pingexit_int'] = $_POST['psh_pingexit_int'];
+ }
+}
+
+$pgtitle = "VPN: OpenVPN: Edit client-specific configuration";
+include("head.inc");
+include("fbegin.inc");
+?>
+<script language="JavaScript">
+function enable_change(enable_over) {
+ var endis;
+ endis = !(!document.iform.disabled.checked || enable_over);
+
+ document.iform.cn.disabled = endis;
+ document.iform.disable.disabled = endis;
+ document.iform.descr.disabled = endis;
+ document.iform.psh_reset.disabled = endis;
+ document.iform.psh_redir.disabled = endis;
+ document.iform.psh_redir_loc.disabled = endis;
+ document.iform.psh_rtedelay.disabled = endis;
+ document.iform.psh_rtedelay_int.disabled = endis;
+ document.iform.psh_inact.disabled = endis;
+ document.iform.psh_inact_int.disabled = endis;
+ document.iform.psh_ping.disabled = endis;
+ document.iform.psh_ping_int.disabled = endis;
+ document.iform.psh_pingexit.disabled = endis;
+ document.iform.psh_pingexit_int.disabled = endis;
+ document.iform.psh_pingrst.disabled = endis;
+ document.iform.psh_pingrst_int.disabled = endis;
+ document.iform.options.disabled = endis;
+
+ if (!document.iform.disabled.checked) {
+ push_change(false);
+ disable_change(false);
+ }
+
+}
+
+function disable_change(enable_over) {
+ var endis;
+ endis = !(!document.iform.disable.checked || enable_over);
+
+ document.iform.psh_reset.disabled = endis;
+ document.iform.psh_redir.disabled = endis;
+ document.iform.psh_redir_loc.disabled = endis;
+ document.iform.psh_rtedelay.disabled = endis;
+ document.iform.psh_rtedelay_int.disabled = endis;
+ document.iform.psh_inact.disabled = endis;
+ document.iform.psh_inact_int.disabled = endis;
+ document.iform.psh_ping.disabled = endis;
+ document.iform.psh_ping_int.disabled = endis;
+ document.iform.psh_pingexit.disabled = endis;
+ document.iform.psh_pingexit_int.disabled = endis;
+ document.iform.psh_pingrst.disabled = endis;
+ document.iform.psh_pingrst_int.disabled = endis;
+ document.iform.options.disabled = endis;
+
+ if (!document.iform.disable.checked) {
+ push_change(enable_over);
+ }
+
+}
+
+function push_change(enable_over) {
+ var endis;
+ endis = !(document.iform.psh_reset.checked || enable_over);
+
+ document.iform.psh_redir.disabled = endis;
+ document.iform.psh_redir_loc.disabled = endis;
+ document.iform.psh_rtedelay.disabled = endis;
+ document.iform.psh_rtedelay_int.disabled = endis;
+ document.iform.psh_inact.disabled = endis;
+ document.iform.psh_inact_int.disabled = endis;
+ document.iform.psh_ping.disabled = endis;
+ document.iform.psh_ping_int.disabled = endis;
+ document.iform.psh_pingexit.disabled = endis;
+ document.iform.psh_pingexit_int.disabled = endis;
+ document.iform.psh_pingrst.disabled = endis;
+ document.iform.psh_pingrst_int.disabled = endis;
+}
+
+//-->
+</script>
+
+<?php if ($input_errors) print_input_errors($input_errors);?>
+<form action="vpn_openvpn_ccd_edit.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
+<strong><span class="red">WARNING: This feature is experimental and modifies your optional interface configuration.
+ Backup your configuration before using OpenVPN, and restore it before upgrading.<br>&nbsp;<br>
+</span></strong>
+<table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Disabled</td>
+ <td width="78%" class="vtable">
+ <input name="disabled" type="checkbox" value="yes" onclick="enable_change(false)" <?php if (!isset($pconfig['enable'])) echo "checked"; ?>>
+ <strong>Disable this entry</strong><br>
+ <span class="vexpl">Set this option to disable this client-specific configuration
+ without removing it from the list.</span></td>
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Common Name</td>
+ <td width="78%" class="vtable">
+ <input name="cn" type="text" class="formfld" id="cn" size="40" value="<?=htmlspecialchars($pconfig['cn']);?>">
+ <br><span class="vexpl">Enter client's X.509 common name here.</span></td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Description</td>
+ <td width="78%" class="vtable">
+ <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
+ <br><span class="vexpl">You may enter a description here for your reference (not parsed).</span></td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Block client</td>
+ <td width="78%" class="vtable">
+ <input name="disable" type="checkbox" value="yes" onclick="disable_change(false)" <?php if (isset($pconfig['disable'])) echo "checked"; ?>>
+ <strong>Disable this client from connecting</strong><br>
+ <span class="vexpl">Disable a particular client (based on the common name) from connecting.
+ Don't use this option to disable a client due to key
+ or password compromise. Use a CRL (certificate revocation list)
+ instead.</span></td>
+ </td>
+ </tr>
+
+ <tr>
+ <tr>
+ <td colspan="2" valign="top" height="16"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Push options</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Client-Push Inheritation</td>
+ <td width="78%" class="vtable">
+ <input type="checkbox" name="psh_reset" value="yes" onchange="push_change(false)" <?php if (isset($pconfig['psh_reset'])) echo "checked"; ?>>Push reset
+ <br><span class="vexpl">Set this option to on, if you don't want to inherit
+ the global push list for this client from the server page.</span>
+ </td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Client-push options</td>
+ <td width="78%" class="vtable">
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td><input type="checkbox" name="psh_redir" value="yes" <?php if (isset($pconfig['psh_options']['redir'])) echo "checked"; ?>>
+ Redirect-gateway</td>
+ <td>&nbsp;</td>
+ <td><input type="checkbox" name="psh_redir_loc" value="yes" <?php if (isset($pconfig['psh_options']['redir_loc'])) echo "checked"; ?>>
+ Local</td>
+ </tr>
+ <tr>
+ <td><input type="checkbox" name="psh_rtedelay" value="yes" <?php if (isset($pconfig['psh_options']['rtedelay'])) echo "checked"; ?>> Route-delay</td>
+ <td width="16">&nbsp;</td>
+ <td><input type="text" name="psh_rtedelay_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['rtedelay_int']?>"> seconds</td>
+ </tr>
+ <tr>
+ <td><input type="checkbox" name="psh_inact" value="yes" <?php if (isset($pconfig['psh_options']['inact'])) echo "checked"; ?>>
+ Inactive</td>
+ <td>&nbsp;</td>
+ <td><input type="text" name="psh_inact_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['inact_int']?>">
+ seconds</td>
+ </tr>
+ <tr>
+ <td><input type="checkbox" name="psh_ping" value="yes" <?php if (isset($pconfig['psh_options']['ping'])) echo "checked"; ?>> Ping</td>
+ <td>&nbsp;</td>
+ <td>Interval: <input type="text" name="psh_ping_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['ping_int']?>"> seconds</td>
+ </tr>
+ <tr>
+ <td><input type="checkbox" name="psh_pingexit" value="yes" <?php if (isset($pconfig['psh_options']['pingexit'])) echo "checked"; ?>> Ping-exit</td>
+ <td>&nbsp;</td>
+ <td>Interval: <input type="text" name="psh_pingexit_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['pingexit_int']?>"> seconds</td>
+ </tr>
+ <tr>
+ <td><input type="checkbox" name="psh_pingrst" value="yes" <?php if (isset($pconfig['psh_options']['pingrst'])) echo "checked"; ?>> Ping-restart</td>
+ <td>&nbsp;</td>
+ <td>Interval: <input type="text" name="psh_pingrst_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['pingrst_int']?>"> seconds</td>
+ </tr>
+ </table></td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Custom client options</td>
+ <td width="78%" class="vtable">
+ <span>The following options are legal in a client-specific context:<br>
+ push, push-reset, iroute, ifconfig-push and config.</span><br>
+ <textarea name="options" id="options" cols="65" rows="4" class="formpre"><?=htmlspecialchars($pconfig['options']);?></textarea>
+ <strong><span class="red">Note:</span></strong><br>
+ Commands in here aren't supported.</span></strong>
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true);disable_change(true)">
+ <?php if (isset($id)): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+</table>
+</form>
+<script language="JavaScript">
+<!--
+disable_change(false);
+push_change(false);
+enable_change(false);
+//-->
+</script>
+<?php include("fend.inc");
+?>
diff --git a/usr/local/www/vpn_openvpn_cli.php b/usr/local/www/vpn_openvpn_cli.php
index e7cc879..fe01ee0 100755
--- a/usr/local/www/vpn_openvpn_cli.php
+++ b/usr/local/www/vpn_openvpn_cli.php
@@ -28,7 +28,6 @@
POSSIBILITY OF SUCH DAMAGE.
*/
-$pgtitle = array("VPN", "OpenVPN");
require("guiconfig.inc");
require_once("openvpn.inc");
@@ -53,6 +52,7 @@ if ($_POST['apply']) {
}
else{
ovpn_lock();
+ $retval = ovpn_client_iface();
$retval = ovpn_config_client();
ovpn_unlock();
}
@@ -67,26 +67,27 @@ if ($_GET['act'] == "del") {
unset($ovpncli[$id]);
/* Kill running processes */
- /* Remove old certs & keys */
ovpn_client_kill($ovpnent['if']);
+ /* Remove old certs & keys */
+ ovpn_client_certs_del($ovpnent['if']);
+
/* Remove interface from list of optional interfaces */
ovpn_client_iface_del($ovpnent['if']);
write_config();
- touch($d_sysrebootreqd_path);
+ //touch($d_sysrebootreqd_path);
header("Location: vpn_openvpn_cli.php");
exit;
}
}
+
$pgtitle = "VPN: OpenVPN";
include("head.inc");
?>
-<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
<?php include("fbegin.inc"); ?>
-<p class="pgtitle"><?=$pgtitle?></p>
<?php if ($input_errors) print_input_errors($input_errors); ?>
<?php if (file_exists($d_sysrebootreqd_path) && !file_exists($d_ovpnclidirty_path)) print_info_box(get_std_save_message(0)); ?>
<form action="vpn_openvpn_cli.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
@@ -97,30 +98,27 @@ include("head.inc");
<table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr><td>
-<?php
- $tab_array = array();
- $tab_array[] = array("Server", false, "vpn_openvpn.php");
- $tab_array[] = array("Client", true, "vpn_openvpn.php");
- display_top_tabs($tab_array);
-?>
+ <ul id="tabnav">
+ <li class="tabinact1"><a href="vpn_openvpn_srv.php">Server</a></li>
+ <li class="tabact">Client</li>
+ <li class="tabinact"><a href="vpn_openvpn_ccd.php">Client-specific Configuration</a></li>
+ <li class="tabinact"><a href="vpn_openvpn_crl.php">CRL</a></li>
+ </ul>
</td></tr>
<tr>
- <td>
- <div id="mainarea">
- <table class="tabcont" width="100%" border="0" cellspacing="0" cellpadding="0">
- <tr>
- <td colspan="6">
+ <td class="tabcont">
<strong><span class="red">WARNING: This feature is experimental and modifies your optional interface configuration.
Backup your configuration before using OpenVPN, and restore it before upgrading.<br>
&nbsp; <br>
</span></strong>
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
<tr>
<td width="10%" class="listhdrr">Interface</td>
- <td width="10%" class="listhdrr">Protocol</td>
+ <td width="5%" class="listhdrr">Protocol</td>
<td width="15%" class="listhdrr">Socket</td>
<td width="15%" class="listhdrr">Server address</td>
- <td width="5%" class="listhdrr" align="middle">Version</td>
- <td width="35%" class="listhdr">Description</td>
+ <td width="5%" class="listhdrr" align="center">Version</td>
+ <td width="40%" class="listhdr">Description</td>
<td width="10%" class="list"></td>
</tr>
@@ -135,13 +133,16 @@ include("head.inc");
<tr>
<td class="listlr"><?=$spans;?>
- <?= $client['if'];?>
+ <?php if ($interface = ovpn_get_opt_interface($client['if']))
+ $iface = $config['interfaces'][$interface]['descr'];
+ else $iface = strtoupper($client['if']);?>
+ <?= $iface;?>
<?=$spane;?></td>
<td class="listr"><?=$spans;?>
<?= strtoupper($client['proto']);?>
<?=$spane;?></td>
<td class="listr"><?=$spans;?>
- <?= "0.0.0.0:" . $client['port'];?>
+ <?= "0.0.0.0:" . $client['cport'];?>
<?=$spane;?></td>
<td class="listr"><?=$spans;?>
<?= $client['saddr'].":".$client['sport'];?>
@@ -152,16 +153,15 @@ include("head.inc");
<td class="listbg"><?=$spans;?>
<?= htmlspecialchars($client['descr']);?>&nbsp;
<?=$spane;?></td>
- <td valign="middle" nowrap class="list"> <a href="vpn_openvpn_cli_edit.php?id=<?=$i;?>"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_e.gif" title="edit client configuration" width="17" height="17" border="0"></a>
- &nbsp;<a href="vpn_openvpn_cli.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this client configuration?')"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_x.gif" title="delete client configuration" width="17" height="17" border="0"></a></td>
+ <td valign="middle" nowrap class="list"> <a href="vpn_openvpn_cli_edit.php?id=<?=$i;?>"><img src="e.gif" title="edit client configuration" width="17" height="17" border="0"></a>
+ &nbsp;<a href="vpn_openvpn_cli.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this client configuration?')"><img src="x.gif" title="delete client configuration" width="17" height="17" border="0"></a></td>
</tr>
<?php $i++; endforeach; ?>
<tr>
<td class="list" colspan="6">&nbsp;</td>
- <td class="list"> <a href="vpn_openvpn_cli_edit.php"><img src="/themes/<?= $g['theme']; ?>/images/icons/icon_plus.gif" title="add client configuration" width="17" height="17" border="0"></a></td>
+ <td class="list"> <a href="vpn_openvpn_cli_edit.php"><img src="plus.gif" title="add client configuration" width="17" height="17" border="0"></a></td>
</tr>
</table>
- </div>
</td>
</tr>
</table>
diff --git a/usr/local/www/vpn_openvpn_cli_edit.php b/usr/local/www/vpn_openvpn_cli_edit.php
index c4136e4..1f4fca3 100755
--- a/usr/local/www/vpn_openvpn_cli_edit.php
+++ b/usr/local/www/vpn_openvpn_cli_edit.php
@@ -28,7 +28,6 @@
POSSIBILITY OF SUCH DAMAGE.
*/
-$pgtitle = array("VPN", "OpenVPN", "Edit client");
require("guiconfig.inc");
require_once("openvpn.inc");
@@ -50,10 +49,18 @@ if (isset($id) && $ovpncli[$id]) {
$pconfig = $config['ovpn']['client']['tunnel'][$id];
if (isset($ovpncli[$id]['pull']))
$pconfig['pull'] = true;
-}
-else {
+ if (is_array($ovpncli[$id]['expertmode'])) {
+ $pconfig['expertmode_options'] = "";
+ foreach ($ovpncli[$id]['expertmode']['option'] as $optent) {
+ $pconfig['expertmode_options'] .= $optent . "\n";
+ }
+ $pconfig['expertmode_options'] = rtrim($pconfig['expertmode_options']);
+ }
+
+} else {
/* creating - set defaults */
$pconfig = array();
+ $pconfig['authentication_method'] = "rsasig";
$pconfig['type'] = 'tun';
$pconfig['proto'] = 'udp';
$pconfig['sport'] = '1194';
@@ -63,13 +70,7 @@ else {
$pconfig['enable'] = true;
}
-if (isset($_POST['pull'])) {
-
- $pconfig = $_POST;
-
- $pconfig['ca_cert'] = base64_encode($pconfig['ca_cert']);
- $pconfig['cli_cert'] = base64_encode($pconfig['cli_cert']);
- $pconfig['cli_key'] = base64_encode($pconfig['cli_key']);
+if ($_POST) {
/* Called from form */
unset($input_errors);
@@ -78,77 +79,157 @@ if (isset($_POST['pull'])) {
$reqdfields = explode(" ", "type saddr sport");
$reqdfieldsn = explode(",", "Tunnel type,Address,Port");
+ if ($_POST['authentication_method'] == "pre_shared_key") {
+ $reqdfields = array_merge($reqdfields, explode(" ", "lipaddr pre-shared-key"));
+ $reqdfieldsn = array_merge($reqdfieldsn, explode(",", "Local IP address,Pre-shared secret"));
+
+ if ($_POST['type'] == "tun") {
+ /* tun */
+ $reqdfields = array_merge($reqdfields, explode(" ", "ripaddr"));
+ $reqdfieldsn = array_merge($reqdfieldsn, explode(",", "Remote IP address"));
+
+ /* subnet or ip address */
+ if ($_POST['ripaddr']) {
+ if (!is_ipaddr($_POST['ripaddr']))
+ $input_errors[] = "A valid static remote IP address must be specified.";
+ else if (ip2long($_POST['lipaddr']) == ip2long($_POST['ripaddr']))
+ $input_errors[] = "Local IP address and remote IP address are the same.";
+ }
+ if ($_POST['lipaddr'])
+ if (!is_ipaddr($_POST['lipaddr']))
+ $input_errors[] = "A valid static local IP address must be specified.";
+
+ } else {
+ /* tap */
+ if ($_POST['lipaddr']) {
+ if (!is_ipaddr($_POST['lipaddr']))
+ $input_errors[] = "A valid static local IP address must be specified.";
+ else if (gen_subnet($_POST['lipaddr'], $_POST['netmask']) == $_POST['lipaddr'])
+ $input_errors[] = "Local IP address is subnet address.";
+ else if (gen_subnet_max($_POST['lipaddr'], $_POST['netmask']) == $_POST['lipaddr'])
+ $input_errors[] = "Local IP address is broadcast address.";
+ }
+ }
+
+ if (!empty($_POST['pre-shared-key']) &&
+ (!strstr($_POST['pre-shared-key'], "BEGIN OpenVPN Static key") ||
+ !strstr($_POST['pre-shared-key'], "END OpenVPN Static key")))
+ $input_errors[] = "Pre-shared secret does not appear to be valid.";
+
+ } else {
+ /* rsa */
+ $reqdfields = array_merge($reqdfields, explode(" ", "ca_cert cli_cert cli_key"));
+ $reqdfieldsn = array_merge($reqdfieldsn, explode(",", "CA certificate,Client certificate,Client key"));
+
+ if (!empty($_POST['ca_cert']) &&
+ (!strstr($_POST['ca_cert'], "BEGIN CERTIFICATE") ||
+ !strstr($_POST['ca_cert'], "END CERTIFICATE")))
+ $input_errors[] = "The CA certificate does not appear to be valid.";
+
+ if (!empty($_POST['cli_cert']) &&
+ (!strstr($_POST['cli_cert'], "BEGIN CERTIFICATE") ||
+ !strstr($_POST['cli_cert'], "END CERTIFICATE")))
+ $input_errors[] = "The client certificate does not appear to be valid.";
+
+ if (!empty($_POST['cli_key']) &&
+ (!strstr($_POST['cli_key'], "BEGIN RSA PRIVATE KEY") ||
+ !strstr($_POST['cli_key'], "END RSA PRIVATE KEY")))
+ $input_errors[] = "The client key does not appear to be valid.";
+
+ if (!empty($_POST['pre-shared-key']) &&
+ (!strstr($_POST['pre-shared-key'], "BEGIN OpenVPN Static key") ||
+ !strstr($_POST['pre-shared-key'], "END OpenVPN Static key")))
+ $input_errors[] = "Pre-shared secret does not appear to be valid.";
+
+ if (isset($_POST['tlsauth']) && empty($_POST['pre-shared-key'])) {
+ $reqdfields = array_merge($reqdfields, explode(" ", "pre-shared-key"));
+ $reqdfieldsn = array_merge($reqdfieldsn, explode(",", "Pre-shared secret"));
+ }
+ }
+
do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
/* valid Port */
if (($_POST['sport'] && !is_port($_POST['sport'])))
- $input_errors[] = "The server's port must be an integer between 1 and 65535 (default 1194).";
+ $input_errors[] = "The server's port must be an integer between 1 and 65535.";
- if (is_null($_POST['ca_cert']))
- $input_errors[] = "You must provide a CA certificate file";
- elseif (!strstr($_POST['ca_cert'], "BEGIN CERTIFICATE") || !strstr($_POST['ca_cert'], "END CERTIFICATE"))
- $input_errors[] = "The CA certificate does not appear to be valid.";
-
- if (is_null($_POST['cli_cert']))
- $input_errors[] = "You must provide a client certificate file";
- elseif (!strstr($_POST['cli_cert'], "BEGIN CERTIFICATE") || !strstr($_POST['cli_cert'], "END CERTIFICATE"))
- $input_errors[] = "The client certificate does not appear to be valid.";
-
- if (is_null($_POST['cli_key']))
- $input_errors[] = "You must provide a client key file";
- elseif (!strstr($_POST['cli_key'], "BEGIN RSA PRIVATE KEY") || !strstr($_POST['cli_key'], "END RSA PRIVATE KEY"))
- $input_errors[] = "The client key does not appear to be valid.";
-
- if (!$input_errors) {
- if (isset($id)) {
- /* Editing an existing entry */
- $ovpnent = $ovpncli[$id];
+ /* valid FQDN or IP address */
+ if (($_POST['saddr'] && !is_ipaddr($_POST['saddr']) && !is_domain($_POST['saddr'])))
+ $input_errors[] = "The server name contains invalid characters.";
- if ( $ovpncli[$id]['sport'] != $_POST['sport'] ||
- $ovpncli[$id]['proto'] != $_POST['proto'] ) {
+ if (isset($id) && $ovpncli[$id]) {
+ /* Editing an existing entry */
+ $ovpnent = $ovpncli[$id];
- /* some entries changed */
- for ($i = 0; isset($config['ovpn']['client']['tunnel'][$i]); $i++) {
- $current = &$config['ovpn']['client']['tunnel'][$i];
+ if ($ovpncli[$id]['bridge'] != $_POST['bridge']) {
+ /* double bridging? */
+ if ($_POST['bridge'] &&
+ $_POST['type'] == "tap" &&
+ $_POST['authentication_method'] == "rsasig")
+ $retval = check_bridging($_POST['bridge']);
- if ($current['sport'] == $_POST['sport'])
- if ($current['proto'] == $_POST['proto'])
- $input_errors[] = "You already have this combination for port and protocol settings. You can't use it twice";
- }
- }
+ if (!empty($retval))
+ $input_errors[] = $retval;
+ else
+ ovpn_cli_dirty($ovpnent['if']);
+ }
- /* Test Server type hasn't changed */
- if ($ovpnent['type'] != $_POST['type']) {
- $nxt_if = getnxt_client_if($_POST['type']);
- if (!$nxt_if)
- $input_errors[] = "Run out of devices for a tunnel of type {$_POST['type']}";
- else
- $ovpnent['if'] = $nxt_if;
- /* Need to reboot in order to create interfaces cleanly */
- touch($d_sysrebootreqd_path);
- }
- /* Has the enable/disable state changed? */
- if (isset($ovpnent['enable']) && isset($_POST['disabled'])) {
- touch($d_ovpnclidirty_path);
- }
- if (!isset($ovpnent['enable']) && !isset($_POST['disabled'])) {
- touch($d_ovpnclidirty_path);
+ if ( $ovpncli[$id]['sport'] != $_POST['sport'] ||
+ $ovpncli[$id]['proto'] != $_POST['proto'] ) {
+
+ /* some entries changed */
+ for ($i = 0; isset($config['ovpn']['client']['tunnel'][$i]); $i++) {
+ $current = &$config['ovpn']['client']['tunnel'][$i];
+
+ if ($current['sport'] == $_POST['sport'])
+ if ($current['proto'] == $_POST['proto'])
+ $input_errors[] = "You already have this combination for port and protocol settings. You can't use it twice";
}
}
- else {
- /* Creating a new entry */
- $ovpnent = array();
- $nxt_if = getnxt_client_if($_POST['type']);
- if (!$nxt_if)
- $input_errors[] = "Run out of devices for a tunnel of type {$_POST['type']}";
+
+ /* Test Server type hasn't changed */
+ if ($ovpnent['type'] != $_POST['type'])
+ $input_errors[] = "Delete this interface first before changing the type of the tunnel to "
+ . strtoupper($_POST['type']) .".";
+
+ /* Has the enable/disable state changed? */
+ if (isset($ovpnent['enable']) && isset($_POST['disabled'])) {
+ ovpn_cli_dirty($ovpnent['if']);
+ }
+ if (!isset($ovpnent['enable']) && !isset($_POST['disabled'])) {
+
+ /* check if port number is free, else choose another one */
+ if (in_array($ovpnent['cport'], used_port_list()))
+ $ovpnent['cport'] = getnxt_port();
+
+ ovpn_cli_dirty($ovpnent['if']);
+ }
+ } else {
+ /* Creating a new entry */
+ $ovpnent = array();
+ if (!($ovpnent['if'] = getnxt_if($_POST['type'])))
+ $input_errors[] = "Run out of devices for a tunnel of type {$_POST['type']}";
+
+ $ovpnent['cport'] = getnxt_port();
+
+ /* double bridging? */
+ if ($_POST['bridge'] &&
+ $_POST['type'] == "tap" &&
+ $_POST['authentication_method'] == "rsasig") {
+ $retval = check_bridging($_POST['bridge']);
+
+ if (!empty($retval))
+ $input_errors[] = $retval;
else
- $ovpnent['if'] = $nxt_if;
- $ovpnent['port'] = getnxt_client_port();
- /* I think we have to reboot to have the interface created cleanly */
- touch($d_sysrebootreqd_path);
+ ovpn_cli_dirty($ovpnent['if']);
}
+ }
+ if (!$input_errors) {
+
+ $ovpnent['enable'] = isset($_POST['disabled']) ? false : true;
$ovpnent['type'] = $_POST['type'];
+ $ovpnent['authentication_method'] = $_POST['authentication_method'];
$ovpnent['proto'] = $_POST['proto'];
$ovpnent['sport'] = $_POST['sport'];
$ovpnent['ver'] = $_POST['ver'];
@@ -158,10 +239,33 @@ if (isset($_POST['pull'])) {
$ovpnent['cli_cert'] = $pconfig['cli_cert'];
$ovpnent['cli_key'] = $pconfig['cli_key'];
$ovpnent['crypto'] = $_POST['crypto'];
- $ovpnent['pull'] = true; //This is a fixed config for this version
- $ovpnent['enable'] = isset($_POST['disabled']) ? false : true;
-
-
+ $ovpnent['ns_cert_type'] = $_POST['ns_cert_type'] ? true : false;
+ $ovpnent['pull'] = $_POST['pull'] ? true : false;
+ $ovpnent['tlsauth'] = $_POST['tlsauth'] ? true : false;
+ $ovpnent['bridge'] = $_POST['bridge'];
+ $ovpnent['lipaddr'] = $_POST['lipaddr'];
+ $ovpnent['ripaddr'] = $_POST['ripaddr'];
+ $ovpnent['netmask'] = $_POST['netmask'];
+
+ unset($ovpnent['pre-shared-key']);
+ if ($_POST['pre-shared-key'])
+ $ovpnent['pre-shared-key'] = base64_encode($_POST['pre-shared-key']);
+
+ $ovpnent['ca_cert'] = base64_encode($_POST['ca_cert']);
+ $ovpnent['cli_cert'] = base64_encode($_POST['cli_cert']);
+ $ovpnent['cli_key'] = base64_encode($_POST['cli_key']);
+
+ /* expertmode params */
+ $ovpnent['expertmode_enabled'] = $_POST['expertmode_enabled'] ? true : false;
+
+ if (!is_array($options))
+ $options = array();
+ if (!is_array($ovpnent['expertmode']))
+ $ovpnent['expertmode'] = array();
+
+ $options['option'] = array_map('trim', explode("\n", trim($_POST['expertmode_options'])));
+ $ovpnent['expertmode'] = $options;
+
if (isset($id) && $ovpncli[$id]){
$ovpncli[$id] = $ovpnent;
}
@@ -170,15 +274,157 @@ if (isset($_POST['pull'])) {
}
write_config();
- touch($d_ovpnclidirty_path);
+ ovpn_cli_dirty($ovpnent['if']);
header("Location: vpn_openvpn_cli.php");
exit;
+ } else {
+ $pconfig = $_POST;
+
+ $pconfig['enable'] = "true";
+ if (isset($_POST['disabled']))
+ unset($pconfig['enable']);
+
+ $pconfig['pre-shared-key'] = base64_encode($_POST['pre-shared-key']);
+ $pconfig['ca_cert'] = base64_encode($_POST['ca_cert']);
+ $pconfig['cli_cert'] = base64_encode($_POST['cli_cert']);
+ $pconfig['cli_key'] = base64_encode($_POST['cli_key']);
}
}
+
+$pgtitle = "VPN: OpenVPN: Edit client";
+include("head.inc");
+
?>
+
<?php include("fbegin.inc"); ?>
+<script language="JavaScript">
+function enable_change(enable_over) {
+ var endis;
+ endis = !(!document.iform.disabled.checked || enable_over);
+
+ document.iform.type[0].disabled = endis;
+ document.iform.type[1].disabled = endis;
+ document.iform.proto[0].disabled = endis;
+ document.iform.proto[1].disabled = endis;
+ document.iform.sport.disabled = endis;
+ document.iform.saddr.disabled = endis;
+ document.iform.ver[0].disabled = endis;
+ document.iform.ver[1].disabled = endis;
+ document.iform.descr.disabled = endis;
+ document.iform.authentication_method.disabled = endis;
+ document.iform.ca_cert.disabled = endis;
+ document.iform.cli_cert.disabled = endis;
+ document.iform.cli_key.disabled = endis;
+ document.iform.crypto.disabled = endis;
+ document.iform.ns_cert_type.disabled = endis;
+ document.iform.pull.disabled = endis;
+ document.iform.tlsauth.disabled = endis;
+ document.iform.lipaddr.disabled = endis;
+ document.iform.ripaddr.disabled = endis;
+ document.iform.netmask.disabled = endis;
+ document.iform.psk.disabled = endis;
+ document.iform.expertmode_enabled.disabled = endis;
+ document.iform.expertmode_options.disabled = endis;
+
+ if (!document.iform.disabled.checked) {
+ tls_change(enable_over);
+ expertmode_change(enable_over);
+ methodsel_change(enable_over);
+ }
+}
+
+function expertmode_change(enable_over) {
+ var endis;
+ endis = !(document.iform.expertmode_enabled.checked || enable_over);
+
+ document.iform.expertmode_options.disabled = endis;
+}
+
+
+function tls_change(enable_over) {
+ var endis;
+ endis = !(document.iform.tlsauth.checked || enable_over);
+
+ document.iform.psk.disabled = endis;
+}
+
+function methodsel_change(enable_over) {
+ var endis;
+
+ switch (document.iform.authentication_method.selectedIndex) {
+ case 1: /* rsa */
+ if (get_radio_value(document.iform.type) == "tap") {
+ /* tap */
+ document.iform.bridge.disabled = 0;
+ } else {
+ /* tun */
+ document.iform.bridge.disabled = 1;
+ document.iform.bridge.selectedIndex = 0;
+ }
+
+ document.iform.psk.disabled = 1;
+ document.iform.ca_cert.disabled = 0;
+ document.iform.cli_cert.disabled = 0;
+ document.iform.cli_key.disabled = 0;
+ document.iform.ns_cert_type.disabled = 0;
+ document.iform.tlsauth.disabled = 0;
+ document.iform.lipaddr.disabled = 1;
+ document.iform.ripaddr.disabled = 1;
+ document.iform.netmask.disabled = 1;
+ document.iform.pull.disabled = 0;
+ tls_change();
+ break;
+ default: /* pre-shared */
+ if (get_radio_value(document.iform.type) == "tap") {
+ /* tap */
+ document.iform.ripaddr.disabled = 1;
+ document.iform.netmask.disabled = 0;
+ } else {
+ /* tun */
+ document.iform.ripaddr.disabled = 0;
+ document.iform.netmask.disabled = 1;
+ }
+
+ document.iform.lipaddr.disabled = 0;
+ document.iform.psk.disabled = 0;
+ document.iform.ca_cert.disabled = 1;
+ document.iform.cli_cert.disabled = 1;
+ document.iform.cli_key.disabled = 1;
+ document.iform.ns_cert_type.disabled = 1;
+ document.iform.tlsauth.disabled = 1;
+ document.iform.bridge.disabled = 1;
+ document.iform.bridge.selectedIndex = 0;
+ document.iform.pull.disabled = 1;
+ break;
+ }
+
+ if (enable_over) {
+ document.iform.psk.disabled = 0;
+ document.iform.ca_cert.disabled = 0;
+ document.iform.cli_cert.disabled = 0;
+ document.iform.cli_key.disabled = 0;
+ document.iform.tlsauth.disabled = 0;
+ document.iform.bridge.disabled = 0;
+ document.iform.lipaddr.disabled = 0;
+ document.iform.ripaddr.disabled = 0;
+ document.iform.netmask.disabled = 0;
+ document.iform.pull.disabled = 0;
+ }
+}
+
+function get_radio_value(obj) {
+ for (i = 0; i < obj.length; i++) {
+ if (obj[i].checked)
+ return obj[i].value;
+ }
+ return null;
+}
+
+//-->
+</script>
+
<?php if ($input_errors) print_input_errors($input_errors); ?>
<form action="vpn_openvpn_cli_edit.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
@@ -186,7 +432,7 @@ if (isset($_POST['pull'])) {
<tr>
<td width="22%" valign="top" class="vncellreq">Disabled</td>
<td width="78%" class="vtable">
- <input name="disabled" type="checkbox" id="disabled" value="yes" <?php if (!isset($pconfig['enable'])) echo "checked"; ?>>
+ <input name="disabled" type="checkbox" id="disabled" value="yes" onclick="enable_change(false)" <?php if (!isset($pconfig['enable'])) echo "checked"; ?>>
<strong>Disable this client</strong><br>
<span class="vexpl">Set this option to disable this client without removing it from the list.</span>
</td>
@@ -199,20 +445,14 @@ if (isset($_POST['pull'])) {
<tr>
<td colspan="2" valign="top" class="listtopic">Server information</td>
</tr>
- <tr>
- <td valign="top" class="vncellreq">Tunnel type</td>
- <td class="vtable">
- <input name="type" type="radio" class="formfld" value="tun" <?php if ($pconfig['type'] == 'tun') echo "checked"; ?>> TUN&nbsp;
-<input name="type" type="radio" class="formfld" value="tap" <?php if ($pconfig['type'] == 'tap') echo "checked"; ?>> TAP</td>
- </tr>
<tr>
- <td width="22%" valign="top" class="vncellreq">Tunnel protocol</td>
- <td width="78%" class="vtable">
-<input name="proto" type="radio" class="formfld" value="udp" <?php if ($pconfig['proto'] == 'udp') echo "checked"; ?>> UDP&nbsp;
-<input name="proto" type="radio" class="formfld" value="tcp" <?php if ($pconfig['proto'] == 'tcp') echo "checked"; ?>> TCP<br>
- <span class="vexpl">Important: These settings must match the server's configuration.</span></td>
- </tr>
+ <td width="22%" valign="top" class="vncellreq">Address</td>
+ <td width="78%" class="vtable">
+ <input name="saddr" type="text" class="formfld" size="20" maxlength="255" value="<?=htmlspecialchars($pconfig['saddr']);?>">
+ <br>
+ Enter the server's IP address or FQDN.</td>
+ </tr>
<tr>
<td width="22%" valign="top" class="vncellreq">Port</td>
@@ -222,14 +462,6 @@ if (isset($_POST['pull'])) {
</tr>
<tr>
- <td width="22%" valign="top" class="vncellreq">Address</td>
- <td width="78%" class="vtable">
- <input name="saddr" type="text" class="formfld" size="20" maxlength="255" value="<?=htmlspecialchars($pconfig['saddr']);?>">
- <br>
- Enter the server's IP address or FQDN.</td>
- </tr>
-
- <tr>
<td width="22%" valign="top" class="vncellreq">Version</td>
<td width="78%" class="vtable">
<input name="ver" type="radio" class="formfld" value="2" <?php if ($pconfig['ver'] == '2') echo "checked"; ?>> 2.0&nbsp;
@@ -249,24 +481,21 @@ if (isset($_POST['pull'])) {
<td colspan="2" class="list" height="12"></td>
</tr>
- <tr>
- <td colspan="2" valign="top" class="listtopic">Client configuration</td>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Cryptographic options</td>
</tr>
-
<tr>
- <td width="22%" valign="top" class="vncell">Interface</td>
- <td width="78%" class="vtable">
- <strong>Auto</strong>
- </td>
- </tr>
-
- <tr>
- <td width="22%" valign="top" class="vncell">Port</td>
- <td width="78%" class="vtable">
- <strong>Auto</strong>
- </td>
+ <td width="22%" valign="top" class="vncellreq">Authentication method</td>
+ <td width="78%" class="vtable">
+ <select name="authentication_method" class="formfld" onchange="methodsel_change(false)">
+ <?php foreach ($p1_authentication_methods as $method => $methodname): ?>
+ <option value="<?=$method;?>" <?php if ($method == $pconfig['authentication_method']) echo "selected"; ?>>
+ <?=htmlspecialchars($methodname);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br> <span class="vexpl">Must match the setting chosen on the remote side.</span></td>
</tr>
-
+
<tr>
<td width="22%" valign="top" class="vncellreq">CA certificate</td>
<td width="78%" class="vtable">
@@ -309,24 +538,165 @@ if (isset($_POST['pull'])) {
Select the data channel encryption cipher. This must match the setting on the server.
</td>
</tr>
-
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">nsCertType</td>
+ <td width="78%" class="vtable">
+ <input name="ns_cert_type" type="checkbox" value="yes" <?php if (isset($pconfig['ns_cert_type'])) echo "checked";?>>
+ <strong>nsCertType</strong><br>
+ Require that peer certificate was signed with an explicit
+ nsCertType designation of "server".
+ This is a useful security option for clients, to ensure that the
+ host they connect with is a designated server.
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">TLS auth</td>
+ <td width="78%" class="vtable">
+ <input name="tlsauth" type="checkbox" value="yes" onclick="tls_change(false)" <?php if (isset($pconfig['tlsauth'])) echo "checked";?>>
+ <strong>TLS auth</strong><br>
+ The tls-auth directive adds an additional HMAC signature to all SSL/TLS handshake packets for integrity verification.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Pre-shared secret</td>
+ <td width="78%" class="vtable">
+ <textarea name="pre-shared-key" id="psk" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['pre-shared-key']));?></textarea>
+ <br>
+ Paste your own pre-shared secret here.</td>
+ </tr>
+
+ <tr>
+ <td colspan="2" class="list" height="12"></td>
+ </tr>
+
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Client configuration</td>
+ </tr>
+
+ <tr>
+ <td valign="top" class="vncellreq">Tunnel type</td>
+ <td class="vtable">
+ <input name="type" type="radio" class="formfld" value="tun" onclick="methodsel_change(false)" <?php if ($pconfig['type'] == 'tun') echo "checked"; ?>> TUN&nbsp;
+ <input name="type" type="radio" class="formfld" value="tap" onclick="methodsel_change(false)" <?php if ($pconfig['type'] == 'tap') echo "checked"; ?>> TAP</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Tunnel protocol</td>
+ <td width="78%" class="vtable">
+<input name="proto" type="radio" class="formfld" value="udp" <?php if ($pconfig['proto'] == 'udp') echo "checked"; ?>> UDP&nbsp;
+<input name="proto" type="radio" class="formfld" value="tcp" <?php if ($pconfig['proto'] == 'tcp') echo "checked"; ?>> TCP<br>
+ <span class="vexpl">Important: These settings must match the server's configuration.</span></td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Interface</td>
+ <td width="78%" class="vtable">
+ <strong>Auto</strong>
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Port</td>
+ <td width="78%" class="vtable">
+ <strong>Auto</strong>
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Bridge with</td>
+ <td width="78%" class="vtable">
+ <select name="bridge" class="formfld" id="bridge" onchange="methodsel_change(false)">
+ <option <?php if (!$pconfig['bridge']) echo "selected";?> value="">none</option>
+ <?php $opts = array('lan' => "LAN", 'wan' => "WAN");
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ if ($i != $index && !($config['interfaces']['opt' . $i]['ovpn']))
+ $opts['opt' . $i] = "Optional " . $i . " (" . $config['interfaces']['opt' . $i]['descr'] . ")";
+ }
+ foreach ($opts as $opt => $optname): ?>
+ <option <?php if ($opt == $pconfig['bridge']) echo "selected";?> value="<?=htmlspecialchars($opt);?>">
+ <?=htmlspecialchars($optname);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br> <span class="vexpl">Only supported with authentication method set to RSA signature.</span>
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">OpenVPN address assignment</td>
+ <td width="78%" class="vtable">
+ When using pre-shared keys, enter the IP address and subnet mask
+ of the local and remote VPN endpoint here. For TAP devices, only the
+ IP address of the local VPN endpoint is needed. The netmask is the subnet mask
+ of the virtual ethernet segment which is being created or connected to.<br>
+ <br>
+ <table cellpadding="0" cellspacing="0">
+ <tr>
+ <td>Local IP address:&nbsp;&nbsp;</td>
+ <td valign="top"><input name="lipaddr" id="lipaddr" type="text" class="formfld" size="20" value="<?=htmlspecialchars($pconfig['lipaddr']);?>">
+ /
+ <select name="netmask" id="netmask" class="formfld">
+ <?php for ($i = 30; $i > 19; $i--): ?>
+ <option value="<?=$i;?>" <?php if ($i == $pconfig['netmask']) echo "selected"; ?>>
+ <?=$i;?>
+ </option>
+ <?php endfor; ?>
+ </select>
+ </td>
+ </tr>
+ <tr>
+ <td>Remote IP address:&nbsp;&nbsp;</td>
+ <td valign="top"><input name="ripaddr" id="ripaddr" type="text" class="formfld" size="20" value="<?=htmlspecialchars($pconfig['ripaddr']);?>">
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <td colspan="2" valign="top" height="12"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Client Options</td>
+ </tr>
+ <tr>
+
<tr>
- <td width="22%" valign="top" class="vncellreq">Options</td>
+ <td width="22%" valign="top" class="vncell">Options</td>
<td width="78%" class="vtable">
<input type="checkbox" name="pull" value="yes" <?php if ($pconfig['pull']) echo "checked"; ?>>
- Client-pull</td>
+ <strong>Client-pull</strong></td>
</tr>
-
- <tr>
- <td width="22%" valign="top">&nbsp;</td>
- <td width="78%">
- <input name="Submit" type="submit" class="formbtn" value="Save">
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Expert mode</td>
+ <td width="78%" class="vtable">
+ <input name="expertmode_enabled" type="checkbox" value="yes" onclick="expertmode_change(false)" <?php if (isset($pconfig['expertmode_enabled'])) echo "checked"; ?>>
+ <strong>Enable expert OpenVPN mode</strong><br>
+ If this option is on, you can specify your own extra commands for the OpenVPN server.<br/>
+ <textarea name="expertmode_options" id="expertmode_options" cols="65" rows="4" class="formpre"><?=htmlspecialchars($pconfig['expertmode_options']);?></textarea>
+ <strong><span class="red">Note:</span></strong><br>
+ Commands in expert mode aren't supported.
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save" onclick="methodsel_change(true);tls_change(true);expertmode_change(true);enable_change(true)">
<?php if (isset($id)): ?>
<input name="id" type="hidden" value="<?=$id;?>">
<?php endif; ?>
- </td>
- </tr>
- </table>
+ </td>
+ </tr>
+ </table>
</form>
-
+<script language="JavaScript">
+<!--
+tls_change(false);
+methodsel_change(false);
+expertmode_change(false);
+enable_change(false);
+//-->
+</script>
<?php include("fend.inc"); ?>
diff --git a/usr/local/www/vpn_openvpn_crl.php b/usr/local/www/vpn_openvpn_crl.php
new file mode 100755
index 0000000..cfafe89
--- /dev/null
+++ b/usr/local/www/vpn_openvpn_crl.php
@@ -0,0 +1,159 @@
+#!/usr/local/bin/php
+<?php
+/*
+ vpn_openvpn_crl.php
+
+ Copyright (C) 2005 Peter Allgeyer (allgeyer@web.de).
+ 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.
+*/
+
+require("guiconfig.inc");
+require_once("openvpn.inc");
+
+if (!is_array($config['ovpn']))
+ $config['ovpn'] = array();
+if (!is_array($config['ovpn']['server'])){
+ $config['ovpn']['server'] = array();
+ $config['ovpn']['server']['tunnel'] = array();
+}
+if (!is_array($config['ovpn']['server']['crl']))
+ $config['ovpn']['server']['crl'] = array();
+
+$ovpncrl = &$config['ovpn']['server']['crl'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+
+if ($_POST['apply']) {
+ $retval = 0;
+ $retval = ovpn_server_crl_add();
+
+ /* remove dirty flag */
+ unlink_if_exists($d_ovpncrldirty_path);
+
+ $savemsg = get_std_save_message($retval);
+}
+
+if ($_GET['act'] == "del") {
+ if ($ovpncrl[$id]) {
+ $ovpnent = $ovpncrl[$id];
+
+ unset($ovpncrl[$id]);
+ write_config();
+
+ /* Remove crl file */
+ ovpn_server_crl_del($ovpnent['crlname']);
+
+ /* we should send a SIGUSR1 to openvpn daemon */
+ touch($d_ovpncrldirty_path);
+
+ header("Location: vpn_openvpn_crl.php");
+ exit;
+ }
+}
+
+$pgtitle = "VPN: OpenVPN";
+include("head.inc");
+
+?>
+
+<?php include("fbegin.inc"); ?>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if (file_exists($d_sysrebootreqd_path) && !file_exists($d_ovpncrldirty_path)) print_info_box(get_std_save_message(0)); ?>
+<form action="vpn_openvpn_crl.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
+<?php if (file_exists($d_ovpncrldirty_path)): ?><p>
+<?php print_info_box_np("OpenVPN CRL files have been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="vpn_openvpn_srv.php">Server</a></li>
+ <li class="tabinact"><a href="vpn_openvpn_cli.php">Client</a></li>
+ <li class="tabinact"><a href="vpn_openvpn_ccd.php">Client-specific Configuration</a></li>
+ <li class="tabact">CRL</li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <strong><span class="red">WARNING: This feature is experimental and modifies your optional interface configuration.
+ Backup your configuration before using OpenVPN, and restore it before upgrading.<br>
+ &nbsp;<br>
+ </span></strong>
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="40%" class="listhdrr">CRL name</td>
+ <td width="50%" class="listhdr">Description</td>
+ <td width="10%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($ovpncrl as $crl):
+
+ if (!isset($crl['enable'])) {
+ $spans = "<span class=\"gray\">";
+ $spane = "</span>";
+ } else {
+ $spans = $spane = "";
+ }
+ ?>
+
+ <tr>
+ <td class="listlr"><?=$spans;?>
+ <?= $crl['crlname'];?>
+ <?=$spane;?></td>
+ <td class="listbg"><?=$spans;?>
+ <?= htmlspecialchars($crl['descr']);?>&nbsp;
+ <?=$spane;?></td>
+ <td valign="middle" nowrap class="list"><a href="vpn_openvpn_crl_edit.php?id=<?=$i;?>"><img src="e.gif" title="edit CRL file" width="17" height="17" border="0"></a>
+ &nbsp;<a href="vpn_openvpn_crl.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this CRL file?')"><img src="x.gif" title="delete CRL file" width="17" height="17" border="0"></a></td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="2">&nbsp;</td>
+ <td class="list"><a href="vpn_openvpn_crl_edit.php"><img src="plus.gif" title="add CRL file" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table><br>
+ <span class="vexpl">
+ <span class="red"><strong>Note:</strong></span><br>
+ A CRL (certificate revocation list) is used when a particular
+ key is compromised but when the overall PKI is still intact.<br>
+ <br>
+ Suppose you had a PKI consisting of a CA, root certificate, and
+ a number of client certificates. Suppose a laptop computer
+ containing a client key and certificate was stolen. By adding the
+ stolen certificate to the CRL file, you could reject any connection
+ which attempts to use it, while preserving the overall
+ integrity of the PKI.<br>
+ <br>
+ The only time when it would be necessary to rebuild the entire
+ PKI from scratch would be if the root certificate key itself was
+ compromised.
+ </span>
+ </td>
+</tr>
+</table>
+</form>
+<?php include("fend.inc"); ?>
diff --git a/usr/local/www/vpn_openvpn_crl_edit.php b/usr/local/www/vpn_openvpn_crl_edit.php
new file mode 100755
index 0000000..7b5d463
--- /dev/null
+++ b/usr/local/www/vpn_openvpn_crl_edit.php
@@ -0,0 +1,241 @@
+#!/usr/local/bin/php
+<?php
+/*
+ vpn_openvpn_crl_edit.php
+
+ Copyright (C) 2005 Peter Allgeyer (allgeyer@web.de).
+ 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.
+*/
+
+require("guiconfig.inc");
+require_once("openvpn.inc");
+
+if (!is_array($config['ovpn']))
+ $config['ovpn'] = array();
+if (!is_array($config['ovpn']['server']))
+ $config['ovpn']['server'] = array();
+if (!is_array($config['ovpn']['server']['crl']))
+ $config['ovpn']['server']['crl'] = array();
+
+$ovpncrl =& $config['ovpn']['server']['crl'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $ovpncrl[$id]) {
+
+ $pconfig = $config['ovpn']['server']['crl'][$id];
+
+ if (isset($ovpncrl[$id]['enable']))
+ $pconfig['enable'] = true;
+
+} else {
+ /* creating - set defaults */
+ $pconfig = array();
+ $pconfig['enable'] = true;
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "crlname");
+ $reqdfieldsn = explode(",", "Name");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (preg_match("/[^a-zA-Z0-9\.\-_]/", $_POST['crlname']))
+ $input_errors[] = "The name contains invalid characters.";
+
+ /* Editing an existing entry? */
+ if (!$input_errors && !(isset($id) && $ovpncrl[$id])) {
+ /* make sure there are no dupes */
+ foreach ($ovpncrl as $crlent) {
+ if ($crlent['crlname'] == $_POST['crlname']) {
+ $input_errors[] = "Another entry with the same name already exists.";
+ break;
+ }
+ }
+ }
+
+ /* check if a crl was given */
+ if (is_uploaded_file($_FILES['filename']['tmp_name']) && !empty($_FILES['filename']['size'])) {
+ $content = file_get_contents($_FILES['filename']['tmp_name']);
+ } else if (!empty($_POST['crl_list'])) {
+ $content = $_POST['crl_list'];
+ } else {
+ $content = "";
+ $input_errors[] = "A valid X.509 CRL is required.";
+ }
+
+ /* check if crl is valid */
+ if (!empty($content) &&
+ (!strstr($content, "BEGIN X509 CRL") ||
+ !strstr($content, "END X509 CRL")))
+ $input_errors[] = "The X.509 CRL file content does not appear to be valid.";
+
+ if (isset($id) && $ovpncrl[$id]) {
+ $crlent = $ovpncrl[$id];
+
+ /* Has the enable/disable state changed? */
+ if (isset($crlent['enable']) && isset($_POST['disabled'])) {
+ /* status changed to disabled */
+ ovpn_crl_dirty($ovpncrl['crlname']);
+ } else if (!isset($crlent['enable']) && !isset($_POST['disabled'])) {
+ /* status changed to enable */
+ ovpn_crl_dirty($ovpncrl['crlname']);
+ }
+ }
+
+ if (!$input_errors) {
+
+ $crlent = array();
+
+ if (isset($id) && $ovpncrl[$id])
+ $crlent = $ovpncrl[$id];
+
+ $crlent['crlname'] = $_POST['crlname'];
+ $crlent['descr'] = $_POST['descr'];
+ $crlent['enable'] = $_POST['disabled'] ? false : true;
+
+ /* file upload? */
+ if ($_POST['crlname'] && is_uploaded_file($_FILES['filename']['tmp_name']))
+ $crlent['crl_list'] = base64_encode(file_get_contents($_FILES['filename']['tmp_name']));
+ else if (!empty($_POST['crl_list']))
+ $crlent['crl_list'] = base64_encode($_POST['crl_list']);
+
+ if (isset($id) && $ovpncrl[$id])
+ $ovpncrl[$id] = $crlent;
+ else
+ $ovpncrl[] = $crlent;
+
+ write_config();
+ ovpn_crl_dirty($ovpncrl['crlname']);
+
+ header("Location: vpn_openvpn_crl.php");
+ exit;
+
+ } else {
+
+ $pconfig = $_POST;
+
+ $pconfig['enable'] = "true";
+ if (isset($_POST['disabled']))
+ unset($pconfig['enable']);
+
+ $pconfig['crl_list'] = base64_encode($_POST['crl_list']);
+ }
+}
+
+$pgtitle = "VPN: OpenVPN: Edit client-specific configuration";
+include("head.inc");
+
+?>
+
+<?php include("fbegin.inc"); ?>
+<script language="JavaScript">
+function enable_change(enable_over) {
+ var endis;
+ endis = !(!document.iform.disabled.checked || enable_over);
+
+ document.iform.crlname.disabled = endis;
+ document.iform.descr.disabled = endis;
+ document.iform.crl_list.disabled = endis;
+ document.iform.filename.disabled = endis;
+
+}
+
+//-->
+</script>
+
+<?php if ($input_errors) print_input_errors($input_errors);?>
+<form action="vpn_openvpn_crl_edit.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
+<strong><span class="red">WARNING: This feature is experimental and modifies your optional interface configuration.
+ Backup your configuration before using OpenVPN, and restore it before upgrading.<br>&nbsp;<br>
+</span></strong>
+<table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Disabled</td>
+ <td width="78%" class="vtable">
+ <input name="disabled" type="checkbox" value="yes" onclick="enable_change(false)" <?php if (!isset($pconfig['enable'])) echo "checked"; ?>>
+ <strong>Disable this X.509 CRL list</strong><br>
+ <span class="vexpl">Set this option to on to disable this X.509 CRL file
+ without removing it from the list.</span></td>
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Name</td>
+ <td width="78%" class="vtable">
+ <input name="crlname" type="text" class="formfld" id="crlname" size="40" value="<?=htmlspecialchars($pconfig['crlname']);?>">
+ <br><span class="vexpl">Enter a unique name here, to describe the X.509 CRL list.</span></td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Description</td>
+ <td width="78%" class="vtable">
+ <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
+ <br><span class="vexpl">You may enter a description here for your reference (not parsed).</span></td>
+ </tr>
+
+ <tr>
+ <td valign="top" class="vncellreq">X.509 CRL file content</td>
+ <td class="vtable">
+ <textarea name="crl_list" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['crl_list']));?></textarea>
+ <br>
+ Paste the contents of a X.509 CRL file in PEM format here.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">X.509 CRL file</td>
+ <td class="vtable">
+ <input name="filename" type="file" class="formfld" id="filename"><br>
+ Instead of pasting the contents of a X.509 CRL file above,
+ you can upload a X.509 CRL file in PEM format here. It will
+ overwrite the values entered in the "X.509 CRL file content"
+ field.
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)">
+ <?php if (isset($id)): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+</table>
+</form>
+<script language="JavaScript">
+<!--
+enable_change(false);
+//-->
+</script>
+<?php include("fend.inc");
+?>
diff --git a/usr/local/www/vpn_openvpn_srv.php b/usr/local/www/vpn_openvpn_srv.php
new file mode 100755
index 0000000..5cd6ff1
--- /dev/null
+++ b/usr/local/www/vpn_openvpn_srv.php
@@ -0,0 +1,187 @@
+#!/usr/local/bin/php
+<?php
+/*
+ vpn_openvpn_srv.php
+
+ Copyright (C) 2004 Peter Curran (peter@closeconsultants.com).
+ Copyright (C) 2005 Peter Allgeyer (allgeyer@web.de).
+ 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.
+*/
+
+require("guiconfig.inc");
+require_once("openvpn.inc");
+
+if (!is_array($config['ovpn']))
+ $config['ovpn'] = array();
+if (!is_array($config['ovpn']['server'])){
+ $config['ovpn']['server'] = array();
+ $config['ovpn']['server']['tunnel'] = array();
+}
+
+$ovpnsrv = &$config['ovpn']['server']['tunnel'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+
+if ($_POST['apply']) {
+ $retval = 0;
+ if (file_exists($d_sysrebootreqd_path)) {
+ /* Rewrite interface definitions */
+ $retval = ovpn_server_iface();
+ } else {
+ ovpn_lock();
+ $retval = ovpn_server_iface();
+ $retval = ovpn_config_server(false);
+ ovpn_unlock();
+ }
+ if (file_exists($d_ovpnsrvdirty_path))
+ unlink($d_ovpnsrvdirty_path);
+ $savemsg = get_std_save_message($retval);
+}
+
+if ($_GET['act'] == "del") {
+ if ($ovpnsrv[$id]) {
+ $ovpnent = $ovpnsrv[$id];
+ unset($ovpnsrv[$id]);
+
+ /* Kill running processes */
+ ovpn_server_kill($ovpnent['tun_iface']);
+
+ /* Remove old certs & keys */
+ ovpn_server_certs_del($ovpnent['tun_iface']);
+
+ /* Remove interface from list of optional interfaces */
+ ovpn_server_iface_del($ovpnent['tun_iface']);
+
+ write_config();
+ //touch($d_sysrebootreqd_path);
+ header("Location: vpn_openvpn_srv.php");
+ exit;
+ }
+}
+
+$pgtitle = "VPN: OpenVPN";
+include("head.inc");
+
+?>
+
+<?php include("fbegin.inc"); ?>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if (file_exists($d_sysrebootreqd_path) && !file_exists($d_ovpnsrvdirty_path)) print_info_box(get_std_save_message(0)); ?>
+<form action="vpn_openvpn_srv.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
+<?php if (file_exists($d_ovpnsrvdirty_path)): ?><p>
+<?php print_info_box_np("The OpenVPN server configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabact">Server</li>
+ <li class="tabinact"><a href="vpn_openvpn_cli.php">Client</a></li>
+ <li class="tabinact"><a href="vpn_openvpn_ccd.php">Client-specific Configuration</a></li>
+ <li class="tabinact"><a href="vpn_openvpn_crl.php">CRL</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <strong><span class="red">WARNING: This feature is experimental and modifies your optional interface configuration.
+ Backup your configuration before using OpenVPN, and restore it before upgrading.<br>
+&nbsp; <br>
+ </span></strong>
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="5%" class="listhdrr">Interface</td>
+ <td width="5%" class="listhdrr">Protocol</td>
+ <td width="5%" class="listhdrr">Socket</td>
+ <td width="25%" class="listhdrr">IP Block</td>
+ <td width="15%" class="listhdrr">Crypto</td>
+ <td width="35%" class="listhdr">Description</td>
+ <td width="10%" class="list"></td>
+ </tr>
+
+ <?php $i = 0; foreach ($ovpnsrv as $server):
+ if (!isset($server['enable'])) {
+ $spans = "<span class=\"gray\">";
+ $spane = "</span>";
+ } else {
+ $spans = $spane = "";
+ }
+
+ if ($server['bind_iface'] == 'all')
+ $ipaddr = "0.0.0.0";
+ else
+ $ipaddr = ovpn_get_ip($server['bind_iface']);
+ ?>
+
+ <tr>
+ <td class="listlr"><?=$spans;?>
+ <?php if ($interface = ovpn_get_opt_interface($server['tun_iface']))
+ $iface = $config['interfaces'][$interface]['descr'];
+ else $iface = strtoupper($server['tun_iface']);?>
+ <?= $iface;?>
+ <?=$spane;?></td>
+ <td class="listr"><?=$spans;?>
+ <?= strtoupper($server['proto']);?>
+ <?=$spane;?></td>
+ <td class="listr"><?=$spans;?>
+ <?= $ipaddr.":".$server['port'];?>
+ <?=$spane;?></td>
+ <td nowrap class="listr"><?=$spans;?>
+ <?php if ($server['authentication_method'] == "pre_shared_key") {
+ if ($server['type'] == "tun") {
+ $ipblock = $server['lipaddr'] . " / " . $server['ripaddr'];
+ } else {
+ $ipblock = $server['lipaddr'] . "/" . $server['netmask'];
+ }
+ } else if (!$server['bridge'])
+ $ipblock = $server['ipblock'] . "/" . $server['prefix'];
+ else if ($server['range_from'])
+ $ipblock = $server['range_from'] . " - " . $server['range_to'];
+ else
+ $ipblock = "--";?>
+ <?= $ipblock;?>
+ <?=$spane;?></td>
+ <td class="listr"><?=$spans;?>
+ <?= $server['crypto'];?>
+ <?=$spane;?></td>
+ <td class="listbg"><?=$spans;?>
+ <?= htmlspecialchars($server['descr']);?>&nbsp;
+ <?=$spane;?></td>
+ <td valign="middle" nowrap class="list"> <a href="vpn_openvpn_srv_edit.php?id=<?=$i;?>"><img src="e.gif" title="edit server configuration" width="17" height="17" border="0"></a>
+ &nbsp;<a href="vpn_openvpn_srv.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this server configuration?')"><img src="x.gif" title="delete server configuration" width="17" height="17" border="0"></a></td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="6">&nbsp;</td>
+ <td class="list"> <a href="vpn_openvpn_srv_edit.php"><img src="plus.gif" title="add server configuration" width="17" height="17" border="0"></a></td>
+ </tr>
+ </table>
+ </td>
+</tr>
+</table>
+</form>
+<?php include("fend.inc"); ?>
diff --git a/usr/local/www/vpn_openvpn_srv_edit.php b/usr/local/www/vpn_openvpn_srv_edit.php
new file mode 100755
index 0000000..e2ac9f1
--- /dev/null
+++ b/usr/local/www/vpn_openvpn_srv_edit.php
@@ -0,0 +1,1167 @@
+#!/usr/local/bin/php
+<?php
+/*
+ vpn_openvpn_srv_edit.php
+
+ Copyright (C) 2004 Peter Curran (peter@closeconsultants.com).
+ Copyright (C) 2005 Peter Allgeyer (allgeyer@web.de).
+ 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.
+*/
+
+require("guiconfig.inc");
+require_once("openvpn.inc");
+
+if (!is_array($config['ovpn']))
+ $config['ovpn'] = array();
+if (!is_array($config['ovpn']['server'])){
+ $config['ovpn']['server'] = array();
+ $config['ovpn']['server']['tunnel'] = array();
+}
+
+$ovpnsrv =& $config['ovpn']['server']['tunnel'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $ovpnsrv[$id]) {
+ $pconfig = $config['ovpn']['server']['tunnel'][$id];
+ if (isset($ovpnsrv[$id]['enable']))
+ $pconfig['enable'] = true;
+ if (!isset($ovpnsrv[$id]['method']))
+ $pconfig['method'] = "ovpn";
+ if (is_array($ovpnsrv[$id]['expertmode'])) {
+ $pconfig['expertmode_options'] = "";
+ foreach ($ovpnsrv[$id]['expertmode']['option'] as $optent) {
+ $pconfig['expertmode_options'] .= $optent . "\n";
+ }
+ $pconfig['expertmode_options'] = rtrim($pconfig['expertmode_options']);
+ }
+
+} else {
+ /* creating - set defaults */
+ $pconfig = array();
+ $pconfig['type'] = "tun";
+ $pconfig['psh_options'] = array();
+ /* Initialise with some sensible defaults */
+ $pconfig['authentication_method'] = "rsasig";
+ $pconfig['port'] = getnxt_port();
+ $pconfig['proto'] = 'udp';
+ $pconfig['method'] = 'ovpn';
+ $pconfig['maxcli'] = '';
+ $pconfig['crypto'] = 'BF-CBC';
+ $pconfig['dupcn'] = false;
+ $pconfig['verb'] = 1;
+ $pconfig['enable'] = true;
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ unset($check_ipblock);
+ unset($bridge_reset);
+
+ /* input validation */
+ $reqdfields = explode(" ", "type bind_iface");
+ $reqdfieldsn = explode(",", "Tunnel type,Interface binding");
+
+ if ($_POST['authentication_method'] == "pre_shared_key") {
+ $reqdfields = array_merge($reqdfields, explode(" ", "lipaddr pre-shared-key"));
+ $reqdfieldsn = array_merge($reqdfieldsn, explode(",", "Local IP address,Pre-shared secret"));
+
+ if ($_POST['type'] == "tun") {
+ /* tun */
+ $reqdfields = array_merge($reqdfields, explode(" ", "ripaddr"));
+ $reqdfieldsn = array_merge($reqdfieldsn, explode(",", "Remote IP address"));
+
+ /* subnet or ip address */
+ if ($_POST['ripaddr']) {
+ if (!is_ipaddr($_POST['ripaddr']))
+ $input_errors[] = "A valid static remote IP address must be specified.";
+ else if (ip2long($_POST['lipaddr']) == ip2long($_POST['ripaddr']))
+ $input_errors[] = "Local IP address and remote IP address are the same.";
+ }
+ if ($_POST['lipaddr'])
+ if (!is_ipaddr($_POST['lipaddr']))
+ $input_errors[] = "A valid local static IP address must be specified.";
+
+ } else {
+ /* tap */
+ if ($_POST['lipaddr']) {
+ if (!is_ipaddr($_POST['lipaddr']))
+ $input_errors[] = "A valid local static IP address must be specified.";
+ if (gen_subnet($_POST['lipaddr'], $_POST['netmask']) == $_POST['lipaddr'])
+ $input_errors[] = "Local IP address is subnet address.";
+ if (gen_subnet_max($_POST['lipaddr'], $_POST['netmask']) == $_POST['lipaddr'])
+ $input_errors[] = "Local IP address is broadcast address.";
+ }
+ }
+
+ if (intval($_POST['maxcli']) > 1)
+ $input_errors[] = "Maximum number of simultaneous clients should not be greater than \"1\".";
+
+ /* checked also by javascript */
+ if ($_POST['method'] != "static")
+ $input_errors[] = "Only static address assignment is supported.";
+
+ } else {
+ /* rsa */
+ $reqdfields = array_merge($reqdfields, explode(" ", "ca_cert srv_cert srv_key dh_param"));
+ $reqdfieldsn = array_merge($reqdfieldsn, explode(",", "CA certificate,Server certificate,Server key,DH parameters"));
+
+ if ($_POST['type'] == "tap") {
+ /* tap*/
+ if (!$_POST['bridge']) {
+ if ($_POST['method'] == "ovpn") {
+ $reqdfields = array_merge($reqdfields, "ipblock");
+ $reqdfieldsn = array_merge($reqdfieldsn, "IP address block");
+
+ $check_ipblock = 1;
+ } else {
+ $input_errors[] = "Only supported address assignment is \"Managed by OpenVPN\".";
+ }
+ } else {
+ if ($_POST['method'] == "ovpn") {
+ $reqdfields = array_merge($reqdfields, explode(" ", "range_from range_to gateway"));
+ $reqdfieldsn = array_merge($reqdfieldsn, explode(",", "Range begin,Range end,Gateway"));
+ if (intval($_POST['maxcli']) > (ip2long($_POST['range_to']) - ip2long($_POST['range_from']) + 1))
+ $input_errors[] = "IP range to small for maximum number of simultaneous clients.";
+
+ } else if ($_POST['method'] != "dhcp") {
+ $input_errors[] = "Wrong or emtpy OpenVPN address assignment.";
+ }
+ }
+
+ } else {
+ /* tun*/
+ $reqdfields = array_merge($reqdfields, "ipblock");
+ $reqdfieldsn = array_merge($reqdfieldsn, "IP address block");
+
+ /* checked also by javascript */
+ if ($_POST['method'] != "ovpn")
+ $input_errors[] = "Only supported address assignment is \"Managed by OpenVPN\".";
+
+ $check_ipblock = 1;
+ }
+
+
+ /* valid IP */
+ if ($_POST['ipblock'] && $check_ipblock) {
+ if (!is_ipaddr($_POST['ipblock'])) {
+ $input_errors[] = "A valid IP netblock must be specified.";
+ } else {
+ $network = ip2long(gen_subnet($_POST['ipblock'], $_POST['prefix']));
+ $broadcast = ip2long(gen_subnet_max($_POST['ipblock'], $_POST['prefix']));
+
+ if ($_POST['maxcli']) {
+ if ($_POST['type'] == "tap") {
+ if (intval($_POST['maxcli']) > ($broadcast - $network - 3))
+ $input_errors[] = "Maximum number of simultaneous clients too high";
+ } else {
+ if (intval($_POST['maxcli']) > floor(($broadcast - $network) / 4))
+ $input_errors[] = "Maximum number of simultaneous clients too high";
+ }
+ }
+ }
+ }
+
+ /* Sort out the cert+key files */
+ if (!empty($_POST['ca_cert']) &&
+ (!strstr($_POST['ca_cert'], "BEGIN CERTIFICATE") ||
+ !strstr($_POST['ca_cert'], "END CERTIFICATE")))
+ $input_errors[] = "The CA certificate does not appear to be valid.";
+
+ if (!empty($_POST['srv_cert']) &&
+ (!strstr($_POST['srv_cert'], "BEGIN CERTIFICATE") ||
+ !strstr($_POST['srv_cert'], "END CERTIFICATE")))
+ $input_errors[] = "The server certificate does not appear to be valid.";
+
+ if (!empty($_POST['srv_key']) &&
+ (!strstr($_POST['srv_key'], "BEGIN RSA PRIVATE KEY") ||
+ !strstr($_POST['srv_key'], "END RSA PRIVATE KEY")))
+ $input_errors[] = "The server key does not appear to be valid.";
+
+ if (!empty($_POST['dh_param']) &&
+ (!strstr($_POST['dh_param'], "BEGIN DH PARAMETERS") ||
+ !strstr($_POST['dh_param'], "END DH PARAMETERS")))
+ $input_errors[] = "The DH parameters do not appear to be valid.";
+
+ if (isset($_POST['tlsauth']) && empty($_POST['pre-shared-key']))
+ $input_errors[] = "The field 'Pre-shared secret' is required.";
+ }
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (($_POST['range_from'] && !is_ipaddr($_POST['range_from'])))
+ $input_errors[] = "A valid range must be specified.";
+
+ if (($_POST['range_to'] && !is_ipaddr($_POST['range_to'])))
+ $input_errors[] = "A valid range must be specified.";
+
+ if ($_POST['gateway'] && !is_ipaddr($_POST['gateway']))
+ $input_errors[] = "A valid gateway IP address must be specified.";
+
+ /* make sure the range lies within the bridged subnet */
+ if ($_POST['bridge']) {
+ if ($_POST['method'] == "ovpn") {
+
+ $ipaddr = $config['interfaces'][$_POST['bridge']]['ipaddr'];
+ $subnet = $config['interfaces'][$_POST['bridge']]['subnet'];
+
+ $subnet_start = (ip2long($ipaddr) & gen_subnet_mask_long($subnet));
+ $subnet_end = (ip2long($ipaddr) | (~gen_subnet_mask_long($subnet)));
+
+ if (!ip_in_subnet($_POST['gateway'], gen_subnet($ipaddr, $subnet) . "/" . $subnet))
+ $input_errors[] = "The specified gateway lies outside of the bridged subnet.";
+
+ if ((ip2long($_POST['range_from']) < $subnet_start) || (ip2long($_POST['range_from']) > $subnet_end) ||
+ (ip2long($_POST['range_to']) < $subnet_start) || (ip2long($_POST['range_to']) > $subnet_end)) {
+ $input_errors[] = "The specified range lies outside of the bridged subnet.";
+ }
+
+ if (ip2long($_POST['range_from']) > ip2long($_POST['range_to']))
+ $input_errors[] = "The range is invalid (first element higher than second element).";
+
+ if (!($_POST['type'] == "tap" && $_POST['authentication_method'] == "rsasig"))
+ $bridge_reset = 1;
+ }
+ }
+
+ /* valid Port */
+ if (empty($_POST['port']))
+ $input_errors[] = "You must provide a server in between 1 and 65535.";
+ else if (!is_port($_POST['port']))
+ $input_errors[] = "The server port must be an integer between 1 and 65535.";
+
+ /* check if dynip is set correctly */
+ if ($_POST['dynip'] && $_POST['bind_iface'] != 'all')
+ $input_errors[] = "Dynamic IP address can only be set with interface binding set to ALL.";
+
+ if (!empty($_POST['pre-shared-key']))
+ if (!strstr($_POST['pre-shared-key'], "BEGIN OpenVPN Static key") ||
+ !strstr($_POST['pre-shared-key'], "END OpenVPN Static key"))
+ $input_errors[] = "Pre-shared secret does not appear to be valid.";
+
+ if ($_POST['psh_pingrst'] && $_POST['psh_pingexit'])
+ $input_errors[] = "Ping-restart and Ping-exit are mutually exclusive and cannot be used together";
+
+ if ($_POST['psh_rtedelay'] && !is_numeric($_POST['psh_rtedelay_int']))
+ $input_errors[] = "Route-delay needs a numerical interval setting.";
+
+ if ($_POST['psh_inact'] && !is_numeric($_POST['psh_inact_int']))
+ $input_errors[] = "Inactive needs a numerical interval setting.";
+
+ if ($_POST['psh_ping'] && !is_numeric($_POST['psh_ping_int']))
+ $input_errors[] = "Ping needs a numerical interval setting.";
+
+ if ($_POST['psh_pingexit'] && !is_numeric($_POST['psh_pingexit_int']))
+ $input_errors[] = "Ping-exit needs a numerical interval setting.";
+
+ if ($_POST['psh_pingrst'] && !is_numeric($_POST['psh_pingrst_int']))
+ $input_errors[] = "Ping-restart needs a numerical interval setting.";
+
+ /* Editing an existing entry? */
+ if (isset($id) && $ovpnsrv[$id]) {
+ $ovpnent = $ovpnsrv[$id];
+
+ /* bridging changed */
+ if ($ovpnent['bridge'] != $_POST['bridge']) {
+ /* double bridging? */
+ if ($_POST['bridge'] &&
+ $_POST['type'] == "tap" &&
+ $_POST['authentication_method'] == "rsasig")
+ $retval = check_bridging($_POST['bridge']);
+
+ if (!empty($retval))
+ $input_errors[] = $retval;
+ else
+ ovpn_srv_dirty($ovpnent['tun_iface']);
+ }
+
+ /* port number syntactically valid, so lets check, if it is free */
+ if (isset($ovpnent['enable']) &&
+ !isset($_POST['disabled']) &&
+ $ovpnent['port'] != $_POST['port']) {
+ /* port number has changed */
+
+ if (in_array($_POST['port'], used_port_list())) {
+ /* port in use, check binding */
+
+ /* return interfaces bind to this port */
+ $bind_list = used_bind_list($_POST['port']);
+
+ /* check if binding is in use */
+ if (($_POST['bind_iface'] == "all") ||
+ in_array("all", $bind_list) ||
+ in_array($_POST['bind_iface'], $bind_list) ) {
+ $input_errors[] = "OpenVPN binding already in use by another OpenVPN daemon.";
+ }
+ }
+ }
+
+ /* binding free? */
+ if (isset($ovpnent['enable']) &&
+ !isset($_POST['disabled']) &&
+ $ovpnent['bind_iface'] != $_POST['bind_iface']) {
+ /* binding has changed, remove existing old entry from list */
+ $entry = array();
+ array_push($entry, $ovpnent['bind_iface']);
+ $bind_list = array_diff(used_bind_list($_POST['port']), $entry);
+
+ if (count($bind_list)) {
+ if ($_POST['bind_iface'] == "all")
+ $input_errors[] = "Interface binding is already in use.";
+ else if (in_array("all", $bind_list) ||
+ in_array($_POST['bind_iface'], $bind_list))
+ $input_errors[] = "Interface binding is already in use.";
+ }
+ }
+
+ /* Test Server type hasn't changed */
+ if ($ovpnent['type'] != $_POST['type']) {
+ $input_errors[] = "Delete this interface first before changing the type of the tunnel to " . strtoupper($_POST['type']) .".";
+
+ }
+
+ /* Has the enable/disable state changed? */
+ if (isset($ovpnent['enable']) && isset($_POST['disabled'])) {
+ /* status changed to disabled */
+ ovpn_srv_dirty($ovpnent['tun_iface']);
+ }
+
+ /* status changed to enable */
+ if (!isset($ovpnent['enable']) && !isset($_POST['disabled'])) {
+
+ /* check if port number is free */
+ if (in_array($_POST['port'], used_port_list())) {
+ /* port in use, check binding */
+
+ /* return interfaces bind to this port */
+ $bind_list = used_bind_list($_POST['port']);
+
+ if (($_POST['bind_iface'] == "all") ||
+ in_array("all", $bind_list ) ||
+ in_array($_POST['bind_iface'], $bind_list) ) {
+ /* binding in use */
+ $input_errors[] = "OpenVPN binding already in use by another OpenVPN daemon.";
+ }
+ }
+
+ ovpn_srv_dirty($ovpnent['tun_iface']);
+ }
+
+ } else {
+ /* Creating a new entry */
+ $ovpnent = array();
+
+ /* port number syntactically valid, so lets check, if it is free */
+ if ($_POST['port']) {
+ /* new port number */
+ $bind_list = used_bind_list($_POST['port']);
+
+ if (in_array($_POST['port'], used_port_list())) {
+ /* port in use, check binding */
+ if (($_POST['bind_iface'] == "all") ||
+ in_array("all", $bind_list ) ||
+ in_array($_POST['bind_iface'], $bind_list) ) {
+ /* binding in use */
+ $input_errors[] = "Port {$_POST['port']} is already used for another interface.";
+ }
+ }
+ }
+
+ if (!($ovpnent['tun_iface'] = getnxt_if($_POST['type'])))
+ $input_errors[] = "Run out of devices for a tunnel of type {$_POST['type']}";
+
+ /* double bridging? */
+ if ($ovpnent['bridge'] != $_POST['bridge']) {
+ /* double bridging? */
+ if ($_POST['bridge'] &&
+ $_POST['type'] == "tap" &&
+ $_POST['authentication_method'] == "rsasig")
+ $retval = check_bridging($_POST['bridge']);
+
+ if (!empty($retval))
+ $input_errors[] = $retval;
+ else
+ ovpn_srv_dirty($ovpnent['tun_iface']);
+ }
+ }
+
+ if (!$input_errors) {
+
+ $ovpnent['enable'] = isset($_POST['disabled']) ? false : true;
+ $ovpnent['bind_iface'] = $_POST['bind_iface'];
+ $ovpnent['port'] = $_POST['port'];
+ $ovpnent['proto'] = $_POST['proto'];
+ $ovpnent['type'] = $_POST['type'];
+ $ovpnent['method'] = $_POST['method'];
+ $ovpnent['authentication_method'] = $_POST['authentication_method'];
+
+ /* convert IP address block to a correct network IP address */
+ $ovpnent['ipblock'] = gen_subnet($_POST['ipblock'], $_POST['prefix']);
+ $ovpnent['prefix'] = $_POST['prefix'];
+ $ovpnent['lipaddr'] = $_POST['lipaddr'];
+ $ovpnent['ripaddr'] = $_POST['ripaddr'];
+ $ovpnent['netmask'] = $_POST['netmask'];
+ $ovpnent['range_from'] = $_POST['range_from'];
+ $ovpnent['range_to'] = $_POST['range_to'];
+ $ovpnent['gateway'] = $_POST['gateway'];
+ $ovpnent['bridge'] = $_POST['bridge'];
+
+ $ovpnent['descr'] = $_POST['descr'];
+ $ovpnent['verb'] = $_POST['verb'];
+ $ovpnent['maxcli'] = $_POST['maxcli'];
+ $ovpnent['crypto'] = $_POST['crypto'];
+ $ovpnent['cli2cli'] = $_POST['cli2cli'] ? true : false;
+ $ovpnent['dupcn'] = $_POST['dupcn'] ? true : false;
+ $ovpnent['dynip'] = $_POST['dynip'] ? true : false;
+ $ovpnent['tlsauth'] = $_POST['tlsauth'] ? true : false;
+ $ovpnent['crlname'] = $_POST['crlname'];
+
+ unset($ovpnent['pre-shared-key']);
+ if ($_POST['pre-shared-key'])
+ $ovpnent['pre-shared-key'] = base64_encode($_POST['pre-shared-key']);
+
+ $ovpnent['psh_options']['redir'] = $_POST['psh_redir'] ? true : false;
+ $ovpnent['psh_options']['redir_loc'] = $_POST['psh_redir_loc'] ? true : false;
+ $ovpnent['psh_options']['rtedelay'] = $_POST['psh_rtedelay'] ? true : false;
+ $ovpnent['psh_options']['inact'] = $_POST['psh_inact'] ? true : false;
+ $ovpnent['psh_options']['ping'] = $_POST['psh_ping'] ? true : false;
+ $ovpnent['psh_options']['pingrst'] = $_POST['psh_pingrst'] ? true : false;
+ $ovpnent['psh_options']['pingexit'] = $_POST['psh_pingexit'] ? true : false;
+
+ unset($ovpnent['psh_options']['rtedelay_int']);
+ unset($ovpnent['psh_options']['inact_int']);
+ unset($ovpnent['psh_options']['ping_int']);
+ unset($ovpnent['psh_options']['pingrst_int']);
+ unset($ovpnent['psh_options']['pingexit_int']);
+
+ if ($_POST['psh_rtedelay_int'])
+ $ovpnent['psh_options']['rtedelay_int'] = $_POST['psh_rtedelay_int'];
+ if ($_POST['psh_inact_int'])
+ $ovpnent['psh_options']['inact_int'] = $_POST['psh_inact_int'];
+ if ($_POST['psh_ping_int'])
+ $ovpnent['psh_options']['ping_int'] = $_POST['psh_ping_int'];
+ if ($_POST['psh_pingrst_int'])
+ $ovpnent['psh_options']['pingrst_int'] = $_POST['psh_pingrst_int'];
+ if ($_POST['psh_pingexit_int'])
+ $ovpnent['psh_options']['pingexit_int'] = $_POST['psh_pingexit_int'];
+
+ $ovpnent['ca_cert'] = base64_encode($_POST['ca_cert']);
+ $ovpnent['srv_cert'] = base64_encode($_POST['srv_cert']);
+ $ovpnent['srv_key'] = base64_encode($_POST['srv_key']);
+ $ovpnent['dh_param'] = base64_encode($_POST['dh_param']);
+
+ /* expertmode params */
+ $ovpnent['expertmode_enabled'] = $_POST['expertmode_enabled'] ? true : false;
+
+ if (!is_array($options))
+ $options = array();
+ if (!is_array($ovpnent['expertmode']))
+ $ovpnent['expertmode'] = array();
+
+ $options['option'] = array_map('trim', explode("\n", trim($_POST['expertmode_options'])));
+ $ovpnent['expertmode'] = $options;
+
+ if (isset($id) && $ovpnsrv[$id])
+ $ovpnsrv[$id] = $ovpnent;
+ else
+ $ovpnsrv[] = $ovpnent;
+
+ write_config();
+ ovpn_srv_dirty($ovpnent['tun_iface']);
+
+ header("Location: vpn_openvpn_srv.php");
+ exit;
+ } else {
+
+ $pconfig = $_POST;
+
+ $pconfig['enable'] = "true";
+ if (isset($_POST['disabled']))
+ unset($pconfig['enable']);
+
+ $pconfig['pre-shared-key'] = base64_encode($_POST['pre-shared-key']);
+ $pconfig['ca_cert'] = base64_encode($_POST['ca_cert']);
+ $pconfig['srv_cert'] = base64_encode($_POST['srv_cert']);
+ $pconfig['srv_key'] = base64_encode($_POST['srv_key']);
+ $pconfig['dh_param'] = base64_encode($_POST['dh_param']);
+
+ $pconfig['psh_options']['redir'] = $_POST['psh_redir'];
+ $pconfig['psh_options']['redir_loc'] = $_POST['psh_redir_loc'];
+ $pconfig['psh_options']['rtedelay'] = $_POST['psh_rtedelay'];
+ $pconfig['psh_options']['inact'] = $_POST['psh_inact'];
+ $pconfig['psh_options']['ping'] = $_POST['psh_ping'];
+ $pconfig['psh_options']['pingrst'] = $_POST['psh_pingrst'];
+ $pconfig['psh_options']['pingexit'] = $_POST['psh_pingexit'];
+
+ $pconfig['psh_options']['rtedelay_int'] = $_POST['psh_rtedelay_int'];
+ $pconfig['psh_options']['inact_int'] = $_POST['psh_inact_int'];
+ $pconfig['psh_options']['ping_int'] = $_POST['psh_ping_int'];
+ $pconfig['psh_options']['pingrst_int'] = $_POST['psh_pingrst_int'];
+ $pconfig['psh_options']['pingexit_int'] = $_POST['psh_pingexit_int'];
+ }
+}
+
+$pgtitle = "VPN: OpenVPN: Edit Server";
+include("head.inc");
+
+?>
+
+<?php include("fbegin.inc"); ?>
+<script language="JavaScript">
+function enable_change(enable_over) {
+ var endis;
+ endis = !(!document.iform.disabled.checked || enable_over);
+
+ document.iform.proto[0].disabled = endis;
+ document.iform.proto[1].disabled = endis;
+ document.iform.port.disabled = endis;
+ document.iform.bind_iface.disabled = endis;
+ document.iform.dynip.disabled = endis;
+ document.iform.descr.disabled = endis;
+ document.iform.authentication_method.disabled = endis;
+ document.iform.ca_cert.disabled = endis;
+ document.iform.srv_cert.disabled = endis;
+ document.iform.srv_key.disabled = endis;
+ document.iform.dh_param.disabled = endis;
+ document.iform.crypto.disabled = endis;
+ document.iform.tlsauth.disabled = endis;
+ document.iform.crlname.disabled = endis;
+ document.iform.psk.disabled = endis;
+ document.iform.type[0].disabled = endis;
+ document.iform.type[1].disabled = endis;
+ document.iform.bridge.disabled = endis;
+ document.iform.method[0].disabled = endis;
+ document.iform.method[1].disabled = endis;
+ document.iform.method[2].disabled = endis;
+ document.iform.maxcli.disabled = endis;
+ document.iform.ipblock.disabled = endis;
+ document.iform.prefix.disabled = endis;
+ document.iform.range_from.disabled = endis;
+ document.iform.range_to.disabled = endis;
+ document.iform.gateway.disabled = endis;
+ document.iform.lipaddr.disabled = endis;
+ document.iform.ripaddr.disabled = endis;
+ document.iform.netmask.disabled = endis;
+ document.iform.cli2cli.disabled = endis;
+ document.iform.dupcn.disabled = endis;
+ document.iform.psh_redir.disabled = endis;
+ document.iform.psh_redir_loc.disabled = endis;
+ document.iform.psh_rtedelay.disabled = endis;
+ document.iform.psh_rtedelay_int.disabled = endis;
+ document.iform.psh_inact.disabled = endis;
+ document.iform.psh_inact_int.disabled = endis;
+ document.iform.psh_ping.disabled = endis;
+ document.iform.psh_ping_int.disabled = endis;
+ document.iform.psh_pingexit.disabled = endis;
+ document.iform.psh_pingexit_int.disabled = endis;
+ document.iform.psh_pingrst.disabled = endis;
+ document.iform.psh_pingrst_int.disabled = endis;
+ document.iform.expertmode_enabled.disabled = endis;
+ document.iform.expertmode_options.disabled = endis;
+
+ if (!document.iform.disabled.checked) {
+ type_change();
+ tls_change(enable_over);
+ expertmode_change(enable_over);
+ methodsel_change(enable_over);
+ }
+}
+
+function type_change() {
+ switch (document.iform.bind_iface.selectedIndex) {
+ /* ALL */
+ case 0:
+ document.iform.dynip.disabled = 0;
+ break;
+ default:
+ document.iform.dynip.disabled = 1;
+ }
+}
+
+function tls_change(enable_over) {
+ var endis;
+ endis = !(document.iform.tlsauth.checked || enable_over);
+
+ document.iform.psk.disabled = endis;
+}
+
+
+function expertmode_change(enable_over) {
+ var endis;
+ endis = !(document.iform.expertmode_enabled.checked || enable_over);
+
+ document.iform.expertmode_options.disabled = endis;
+}
+
+function methodsel_change(enable_over) {
+ var endis;
+
+ switch (document.iform.authentication_method.selectedIndex) {
+ case 1: /* rsa */
+ if (get_radio_value(document.iform.type) == "tap") {
+ /* tap */
+
+ endis = !((document.iform.bridge.selectedIndex == 0) || enable_over);
+
+ if (document.iform.bridge.selectedIndex == 0)
+ document.iform.method[0].checked = 1;
+
+ document.iform.method[0].disabled = 0;
+ document.iform.method[1].disabled = !endis;
+ document.iform.method[2].disabled = 1;
+ document.iform.method[2].checked = 0;
+ document.iform.bridge.disabled = 0;
+
+ if (get_radio_value(document.iform.method) == "ovpn") {
+ document.iform.ipblock.disabled = endis;
+ document.iform.prefix.disabled = endis;
+ document.iform.range_from.disabled = !endis;
+ document.iform.range_to.disabled = !endis;
+ document.iform.gateway.disabled = !endis;
+ } else if (get_radio_value(document.iform.method) == "dhcp") {
+ document.iform.ipblock.disabled = 1;
+ document.iform.prefix.disabled = 1;
+ document.iform.range_from.disabled = 1;
+ document.iform.range_to.disabled = 1;
+ document.iform.gateway.disabled = 1;
+ }
+ } else {
+ /* tun */
+ document.iform.method[0].disabled = 0;
+ document.iform.method[0].checked = 1;
+ document.iform.method[1].disabled = 1;
+ document.iform.method[2].disabled = 1;
+ document.iform.bridge.disabled = 1;
+ document.iform.bridge.selectedIndex = 0;
+ document.iform.ipblock.disabled = 0;
+ document.iform.prefix.disabled = 0;
+ document.iform.range_from.disabled = 1;
+ document.iform.range_to.disabled = 1;
+ document.iform.gateway.disabled = 1;
+ }
+
+ document.iform.psk.disabled = 1;
+ document.iform.ca_cert.disabled = 0;
+ document.iform.srv_cert.disabled = 0;
+ document.iform.srv_key.disabled = 0;
+ document.iform.dh_param.disabled = 0;
+ document.iform.tlsauth.disabled = 0;
+ document.iform.crlname.disabled = 0;
+ document.iform.maxcli.disabled = 0;
+ document.iform.dupcn.disabled = 0;
+ document.iform.lipaddr.disabled = 1;
+ document.iform.ripaddr.disabled = 1;
+ document.iform.netmask.disabled = 1;
+ tls_change();
+ break;
+ default: /* pre-shared */
+ if (get_radio_value(document.iform.type) == "tap") {
+ /* tap */
+ document.iform.ripaddr.disabled = 1;
+ document.iform.netmask.disabled = 0;
+ } else {
+ /* tun */
+ document.iform.ripaddr.disabled = 0;
+ document.iform.netmask.disabled = 1;
+ }
+
+ document.iform.psk.disabled = 0;
+ document.iform.ca_cert.disabled = 1;
+ document.iform.srv_cert.disabled = 1;
+ document.iform.srv_key.disabled = 1;
+ document.iform.dh_param.disabled = 1;
+ document.iform.tlsauth.disabled = 1;
+ document.iform.crlname.disabled = 1;
+
+ document.iform.method[0].disabled = 1;
+ document.iform.method[1].disabled = 1;
+ document.iform.method[2].disabled = 0;
+ document.iform.method[2].checked = 1;
+ document.iform.bridge.disabled = 1;
+ document.iform.bridge.selectedIndex = 0;
+ document.iform.ipblock.disabled = 1;
+ document.iform.prefix.disabled = 1;
+ document.iform.range_from.disabled = 1;
+ document.iform.range_to.disabled = 1;
+ document.iform.gateway.disabled = 1;
+ document.iform.lipaddr.disabled = 0;
+ document.iform.maxcli.disabled = 1;
+ document.iform.maxcli.value = "";
+ document.iform.dupcn.disabled = 1;
+ document.iform.dupcn.checked = 0;
+ document.iform.cli2cli.disabled = 1;
+ document.iform.cli2cli.checked = 0;
+ break;
+ }
+
+ if (enable_over) {
+ document.iform.psk.disabled = 0;
+ document.iform.ca_cert.disabled = 0;
+ document.iform.srv_cert.disabled = 0;
+ document.iform.srv_key.disabled = 0;
+ document.iform.dh_param.disabled = 0;
+ document.iform.tlsauth.disabled = 0;
+ document.iform.crlname.disabled = 0;
+ document.iform.bridge.disabled = 0;
+ document.iform.ipblock.disabled = 0;
+ document.iform.prefix.disabled = 0;
+ document.iform.range_from.disabled = 0;
+ document.iform.range_to.disabled = 0;
+ document.iform.gateway.disabled = 0;
+ document.iform.lipaddr.disabled = 0;
+ document.iform.ripaddr.disabled = 0;
+ document.iform.netmask.disabled = 0;
+ document.iform.maxcli.disabled = 0;
+ document.iform.method[0].disabled = 0;
+ document.iform.method[1].disabled = 0;
+ document.iform.method[2].disabled = 0;
+ }
+}
+
+function get_radio_value(obj) {
+ for (i = 0; i < obj.length; i++) {
+ if (obj[i].checked)
+ return obj[i].value;
+ }
+ return null;
+}
+
+//-->
+</script>
+<?php if ($input_errors) print_input_errors($input_errors);?>
+<form action="vpn_openvpn_srv_edit.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
+<strong><span class="red">WARNING: This feature is experimental and modifies your optional interface configuration.
+ Backup your configuration before using OpenVPN, and restore it before upgrading.<br>&nbsp;<br>
+</span></strong>
+<table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Disabled</td>
+ <td width="78%" class="vtable">
+ <input name="disabled" type="checkbox" value="yes" onclick="enable_change(false)" <?php if (!isset($pconfig['enable'])) echo "checked"; ?>>
+ <strong>Disable this server</strong><br>
+ <span class="vexpl">Set this option to disable this server without removing it from the list.</span>
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">OpenVPN protocol/port</td>
+ <td width="78%" class="vtable">
+ <input type="radio" name="proto" class="formfld" value="udp" <?php if ($pconfig['proto'] == 'udp') echo "checked"; ?>>
+ UDP&nbsp;
+ <input type="radio" name="proto" class="formfld" value="tcp" <?php if ($pconfig['proto'] == 'tcp') echo "checked"; ?>>
+ TCP<br><br>
+ Port:
+ <input name="port" type="text" class="formfld" size="5" maxlength="5" value="<?= $pconfig['port']; ?>"><br>
+ Enter the port number to use for the server (default is 1194).</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Interface binding</td>
+ <td width="78%" class="vtable">
+ <select name="bind_iface" class="formfld" onchange="type_change()">
+ <?php
+ $interfaces = ovpn_real_interface_list();
+ foreach ($interfaces as $key => $iface):
+ ?>
+ <option value="<?=$key;?>" <?php if ($key == $pconfig['bind_iface']) echo "selected"; ?>> <?= $iface;?>
+ </option>
+ <?php endforeach;?>
+ </select>
+ <span class="vexpl"><br>
+ Choose an interface for the OpenVPN server to listen on.</span></td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Dynamic IP address</td>
+ <td width="78%" class="vtable">
+ <input name="dynip" type="checkbox" value="yes" <?php if (isset($pconfig['dynip'])) echo "checked"; ?>>
+ <strong>Dynamic IP address</strong><br>
+ Set this option to on, if your IP addresses are being assigned dynamically. Can only be used with interface binding set to ALL.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Description</td>
+ <td width="78%" class="vtable">
+ <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
+ <br> <span class="vexpl">You may enter a description here for your reference (not parsed).</span></td>
+ </tr>
+
+ <tr>
+ <td colspan="2" valign="top" height="12"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Cryptographic options</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Authentication method</td>
+ <td width="78%" class="vtable">
+ <select name="authentication_method" class="formfld" onChange="methodsel_change(false)">
+ <?php foreach ($p1_authentication_methods as $method => $methodname): ?>
+ <option value="<?=$method;?>" <?php if ($method == $pconfig['authentication_method']) echo "selected"; ?>>
+ <?=htmlspecialchars($methodname);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br> <span class="vexpl">Must match the setting chosen on the remote side.</span></td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">CA certificate</td>
+ <td width="78%" class="vtable">
+ <textarea name="ca_cert" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['ca_cert']));?></textarea>
+ <br>
+ Paste a CA certificate in X.509 PEM format here.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Server certificate</td>
+ <td width="78%" class="vtable">
+ <textarea name="srv_cert" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['srv_cert']));?></textarea>
+ <br>
+ Paste a server certificate in X.509 PEM format here.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Server key</td>
+ <td width="78%" class="vtable">
+ <textarea name="srv_key" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['srv_key']));?></textarea>
+ <br>Paste the server RSA private key here.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">DH parameters</td>
+ <td width="78%" class="vtable">
+ <textarea name="dh_param" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['dh_param']));?></textarea>
+ <br>
+ Paste the Diffie-Hellman parameters in PEM format here.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Crypto</td>
+ <td width="78%" class="vtable">
+ <select name="crypto" class="formfld">
+ <?php $cipher_list = ovpn_get_cipher_list();
+ foreach($cipher_list as $key => $value){
+ ?>
+ <option value="<?= $key ?>" <?php if ($pconfig['crypto'] == $key) echo "selected"; ?>>
+ <?= $value ?>
+ </option>
+ <?php
+ }
+ ?>
+ </select>
+ <br>
+ Select a data channel encryption cipher.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">TLS auth</td>
+ <td width="78%" class="vtable">
+ <input name="tlsauth" type="checkbox" value="yes" <?php if (isset($pconfig['tlsauth'])) echo "checked";?> onclick="tls_change(false)">
+ <strong>TLS auth</strong><br>
+ The tls-auth directive adds an additional HMAC signature to all SSL/TLS handshake packets for integrity verification.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Pre-shared secret</td>
+ <td width="78%" class="vtable">
+ <textarea name="pre-shared-key" id="psk" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['pre-shared-key']));?></textarea>
+ <br>
+ Paste your own pre-shared secret here.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">CRL</td>
+ <td width="78%" class="vtable">
+ <select name="crlname" class="formfld" id="crlname">
+ <option <?php if (!$pconfig['crlname']) echo "selected";?> value="">none</option>
+ <?php $crl_list = ovpn_get_crl_list();
+ foreach($crl_list as $crlname): ?>
+ <option value="<?=$crlname;?>" <?php if ($crlname == $pconfig['crlname']) echo "selected";?>>
+ <?=htmlspecialchars($crlname);?>
+ </option>
+ <?php endforeach; ?>
+ </select>
+ <br> <span class="vexpl">
+ You can choose a CRL (certificate revocation list) file in PEM format here.
+ Each peer certificate is checked against this file.</span></td>
+ </tr>
+
+ <tr>
+ <td colspan="2" valign="top" height="12"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">IP configuration</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Tunnel type</td>
+ <td width="78%" class="vtable">
+ <input type="radio" name="type" class="formfld" value="tun" onclick="methodsel_change(false)" <?php if ($pconfig['type'] == 'tun') echo "checked"; ?>>
+ TUN&nbsp;
+ <input type="radio" name="type" class="formfld" value="tap" onclick="methodsel_change(false)" <?php if ($pconfig['type'] == 'tap') echo "checked"; ?>>
+ TAP
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Bridge with</td>
+ <td width="78%" class="vtable">
+ <select name="bridge" class="formfld" id="bridge" onChange="methodsel_change(false)">
+ <option <?php if (!$pconfig['bridge']) echo "selected";?> value="">none</option>
+ <?php $opts = array('lan' => "LAN", 'wan' => "WAN");
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ if ($i != $index && !($config['interfaces']['opt' . $i]['ovpn']))
+ $opts['opt' . $i] = "Optional " . $i . " (" . $config['interfaces']['opt' . $i]['descr'] . ")";
+ }
+ foreach ($opts as $opt => $optname): ?>
+ <option <?php if ($opt == $pconfig['bridge']) echo "selected";?> value="<?=htmlspecialchars($opt);?>">
+ <?=htmlspecialchars($optname);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br> <span class="vexpl">Only supported with authentication method set to RSA signature.</span>
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">OpenVPN address assignment</td>
+ <td width="78%" class="vtable">
+ <table cellpadding="0" cellspacing="0">
+ <tr>
+ <td colspan="2"><input name="method" type="radio" id="method" value="ovpn" onclick="methodsel_change(false)" <?php if($pconfig['method'] == "ovpn" || $pconfig['type'] == "tun") echo "checked"; ?>>
+ Managed by OpenVPN
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2"><input name="method" type="radio" id="method" value="dhcp" onclick="methodsel_change(false)" <?php if($pconfig['method'] == "dhcp") echo "checked"; ?>>
+ Configure manually or by DHCP Server
+ </td>
+ </tr>
+ <tr>
+ <td colspan="2"><input name="method" type="radio" id="method" value="static" onclick="methodsel_change(false)" <?php if($pconfig['method'] == "static") echo "checked"; ?>>
+ Static assignment
+ </td>
+ </tr>
+ <tr>
+ <td>&nbsp;</td>
+ <td>&nbsp;</td>
+ </tr>
+ <tr>
+ <td>Maximum number of simultaneous clients:&nbsp;&nbsp;<br>(leave blank to disable)</td>
+ <td valign="top">
+ <input name="maxcli" type="text" class="formfld" size="3" maxlength="3" value="<?=htmlspecialchars($pconfig['maxcli']);?>">
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell"></td>
+ <td width="78%" class="vtable">
+ When using OpenVPN for address assignment, set aside a pool of subnets to be
+ dynamically allocated to connecting clients, similar to a DHCP server.<br>
+ <br>
+ For tun-style tunnels, each client will be given a /30 subnet
+ (for interoperability with Windows clients).<br>
+ For tap-style tunnels, individual addresses will be allocated, and the optional
+ netmask parameter will also be pushed to clients.<br>
+ <br>
+
+ <table cellpadding="0" cellspacing="0">
+ <tr>
+ <td>IP address block:&nbsp;&nbsp;</td>
+ <td valign="top"><input name="ipblock" type="text" class="formfld" size="20" value="<?=htmlspecialchars($pconfig['ipblock']);?>">
+ /
+ <select name="prefix" class="formfld">
+ <?php for ($i = 30; $i > 19; $i--): ?>
+ <option value="<?=$i;?>" <?php if ($i == $pconfig['prefix']) echo "selected"; ?>>
+ <?=$i;?>
+ </option>
+ <?php endfor; ?>
+ </select>
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell"></td>
+ <td width="78%" class="vtable">
+ For bridges interfaces OpenVPN will allocate
+ an IP range in the bridged subnet to connecting clients.<br><br>
+ The gateway and netmask parameters
+ can be set to either the IP of the bridge interface, or to
+ the IP of the default gateway/router on the bridged subnet.<br>
+ <br>
+
+ <table cellpadding="0" cellspacing="0">
+ <tr>
+ <td>Range:&nbsp;&nbsp;</td>
+ <td valign="top"><input name="range_from" type="text" class="formfld" size="20" value="<?=htmlspecialchars($pconfig['range_from']);?>">
+ &nbsp;to&nbsp;<input name="range_to" type="text" class="formfld" size="20" value="<?=htmlspecialchars($pconfig['range_to']);?>">
+ </td>
+ </tr>
+
+ <tr>
+ <td>Gateway:&nbsp;&nbsp;</td>
+ <td valign="top"><input name="gateway" type="text" class="formfld" size="20" value="<?=htmlspecialchars($pconfig['gateway']);?>">
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">&nbsp;</td>
+ <td width="78%" class="vtable">
+ When using pre-shared keys, enter the IP address and subnet mask
+ of the local and remote VPN endpoint here. For TAP devices, only the
+ IP address of the local VPN endpoint is needed. The netmask is the subnet mask
+ of the virtual ethernet segment which is being created or connected to.<br>
+ <br>
+ <table cellpadding="0" cellspacing="0">
+ <tr>
+ <td>Local IP address:&nbsp;&nbsp;</td>
+ <td valign="top"><input name="lipaddr" id="lipaddr" type="text" class="formfld" size="20" value="<?=htmlspecialchars($pconfig['lipaddr']);?>">
+ /
+ <select name="netmask" id="netmask" class="formfld">
+ <?php for ($i = 30; $i > 19; $i--): ?>
+ <option value="<?=$i;?>" <?php if ($i == $pconfig['netmask']) echo "selected"; ?>>
+ <?=$i;?>
+ </option>
+ <?php endfor; ?>
+ </select>
+ </td>
+ </tr>
+
+ <tr>
+ <td>Remote IP address:&nbsp;&nbsp;</td>
+ <td valign="top"><input name="ripaddr" id="ripaddr" type="text" class="formfld" size="20" value="<?=htmlspecialchars($pconfig['ripaddr']);?>">
+ </td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <td colspan="2" valign="top" height="12"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Server Options</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Internal routing mode</td>
+ <td width="78%" class="vtable">
+ <input name="cli2cli" type="checkbox" value="yes" <?php if (isset($pconfig['cli2cli'])) echo "checked"; ?>>
+ <strong>Enable client-to-client routing</strong><br>
+ If this option is on, clients are allowed to talk to each other.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Client authentication</td>
+ <td width="78%" class="vtable">
+ <input name="dupcn" type="checkbox" value="yes" <?php if (isset($pconfig['dupcn'])) echo "checked"; ?>>
+ <strong>Permit duplicate client certificates</strong><br>
+ If this option is on, clients with duplicate certificates will not be disconnected.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Client-push options</td>
+ <td width="78%" class="vtable">
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td><input type="checkbox" name="psh_redir" value="yes" <?php if (isset($pconfig['psh_options']['redir'])) echo "checked"; ?>>
+ Redirect-gateway</td>
+ <td>&nbsp;</td>
+ <td><input type="checkbox" name="psh_redir_loc" value="yes" <?php if (isset($pconfig['psh_options']['redir_loc'])) echo "checked"; ?>>
+ Local</td>
+ </tr>
+ <tr>
+ <td><input type="checkbox" name="psh_rtedelay" value="yes" <?php if (isset($pconfig['psh_options']['rtedelay'])) echo "checked"; ?>> Route-delay</td>
+ <td width="16">&nbsp;</td>
+ <td><input type="text" name="psh_rtedelay_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['rtedelay_int']?>"> seconds</td>
+ </tr>
+ <tr>
+ <td><input type="checkbox" name="psh_inact" value="yes" <?php if (isset($pconfig['psh_options']['inact'])) echo "checked"; ?>>
+ Inactive</td>
+ <td>&nbsp;</td>
+ <td><input type="text" name="psh_inact_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['inact_int']?>">
+ seconds</td>
+ </tr>
+ <tr>
+ <td><input type="checkbox" name="psh_ping" value="yes" <?php if (isset($pconfig['psh_options']['ping'])) echo "checked"; ?>> Ping</td>
+ <td>&nbsp;</td>
+ <td>Interval: <input type="text" name="psh_ping_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['ping_int']?>"> seconds</td>
+ </tr>
+ <tr>
+ <td><input type="checkbox" name="psh_pingexit" value="yes" <?php if (isset($pconfig['psh_options']['pingexit'])) echo "checked"; ?>> Ping-exit</td>
+ <td>&nbsp;</td>
+ <td>Interval: <input type="text" name="psh_pingexit_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['pingexit_int']?>"> seconds</td>
+ </tr>
+ <tr>
+ <td><input type="checkbox" name="psh_pingrst" value="yes" <?php if (isset($pconfig['psh_options']['pingrst'])) echo "checked"; ?>> Ping-restart</td>
+ <td>&nbsp;</td>
+ <td>Interval: <input type="text" name="psh_pingrst_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['pingrst_int']?>"> seconds</td>
+ </tr>
+ </table></td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Expert mode</td>
+ <td width="78%" class="vtable">
+ <input name="expertmode_enabled" type="checkbox" value="yes" onclick="expertmode_change(false);" <?php if (isset($pconfig['expertmode_enabled'])) echo "checked"; ?>>
+ <strong>Enable expert OpenVPN mode</strong><br>
+ If this option is on, you can specify your own extra commands for the OpenVPN server.<br/>
+ <textarea name="expertmode_options" id="expertmode_options" cols="65" rows="4" class="formpre"><?=htmlspecialchars($pconfig['expertmode_options']);?></textarea>
+ <strong><span class="red">Note:</span></strong><br>
+ Commands in expert mode aren't supported.
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Save" onclick="methodsel_change(true);tls_change(true);expertmode_change(true);enable_change(true)">
+ <input name="verb" type="hidden" value="<?=$pconfig['verb'];?>">
+ <?php if (isset($id)): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+</table>
+</form>
+<script language="JavaScript">
+<!--
+type_change();
+tls_change(false);
+methodsel_change(false);
+expertmode_change(false);
+enable_change(false);
+//-->
+</script>
+<?php include("fend.inc");
+?>
OpenPOWER on IntegriCloud