diff options
author | Scott Ullrich <sullrich@pfsense.org> | 2005-10-12 16:49:15 +0000 |
---|---|---|
committer | Scott Ullrich <sullrich@pfsense.org> | 2005-10-12 16:49:15 +0000 |
commit | afb07cf1534c335bc9cffd49f00ba171cea5702c (patch) | |
tree | e5cc650292f7dd67af9b77de4e3b61bd027ec840 /usr | |
parent | 8d3a4a1e12e23b6d3333de75f403c712a99d3c64 (diff) | |
download | pfsense-afb07cf1534c335bc9cffd49f00ba171cea5702c.zip pfsense-afb07cf1534c335bc9cffd49f00ba171cea5702c.tar.gz |
Sync OpenVPN with http://www.protec-t.de/m0n0wall/downloads from Peter Allgeyer
Diffstat (limited to 'usr')
-rwxr-xr-x | usr/local/www/vpn_openvpn.php | 2 | ||||
-rwxr-xr-x | usr/local/www/vpn_openvpn_ccd.php | 192 | ||||
-rwxr-xr-x | usr/local/www/vpn_openvpn_ccd_edit.php | 420 | ||||
-rwxr-xr-x | usr/local/www/vpn_openvpn_cli.php | 50 | ||||
-rwxr-xr-x | usr/local/www/vpn_openvpn_cli_edit.php | 608 | ||||
-rwxr-xr-x | usr/local/www/vpn_openvpn_crl.php | 159 | ||||
-rwxr-xr-x | usr/local/www/vpn_openvpn_crl_edit.php | 241 | ||||
-rwxr-xr-x | usr/local/www/vpn_openvpn_srv.php | 187 | ||||
-rwxr-xr-x | usr/local/www/vpn_openvpn_srv_edit.php | 1167 |
9 files changed, 2881 insertions, 145 deletions
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> + <br> + </span></strong> + <table width="100%" border="0" cellpadding="0" cellspacing="0"> + <tr> + <td width="5%" class="list"> </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']);?> + <?=$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> + <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"> </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> <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> </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"> </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> </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> </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> </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> </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"> </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> <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']);?> <?=$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> - <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> + <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"> </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 -<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 -<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 @@ -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 + <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 +<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: </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: </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"> </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"> </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> + <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']);?> + <?=$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> + <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"> </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> <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"> </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> + <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']);?> + <?=$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> + <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"> </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> <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 + <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 + <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> </td> + <td> </td> + </tr> + <tr> + <td>Maximum number of simultaneous clients: <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: </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: </td> + <td valign="top"><input name="range_from" type="text" class="formfld" size="20" value="<?=htmlspecialchars($pconfig['range_from']);?>"> + to <input name="range_to" type="text" class="formfld" size="20" value="<?=htmlspecialchars($pconfig['range_to']);?>"> + </td> + </tr> + + <tr> + <td>Gateway: </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"> </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: </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: </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> </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"> </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> </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> </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> </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> </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"> </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"); +?> |