<?php /* Copyright (C) 2014-2016 Deciso B.V. Copyright (C) 2008 Shrew Soft Inc. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ require_once("guiconfig.inc"); require_once("openvpn.inc"); require_once("services.inc"); require_once("interfaces.inc"); require_once('pfsense-utils.inc'); $service_hook = 'openvpn'; if (!isset($config['openvpn']['openvpn-client'])) { $config['openvpn']['openvpn-client'] = array(); } $a_client = &$config['openvpn']['openvpn-client']; $vpnid = 0; $act = null; if ($_SERVER['REQUEST_METHOD'] === 'GET') { if (isset($_GET['dup']) && isset($a_client[$_GET['dup']])) { $configId = $_GET['dup']; } elseif (isset($_GET['id']) && isset($a_client[$_GET['id']])) { $id = $_GET['id']; $configId = $id; } if (isset($_GET['act'])) { $act = $_GET['act']; } $pconfig = array(); // set defaults $pconfig['autokey_enable'] = "yes"; // just in case the modes switch $pconfig['autotls_enable'] = "yes"; // just in case the modes switch $pconfig['tlsauth_enable'] = "yes"; $pconfig['digest'] = "SHA1"; $pconfig['verbosity_level'] = 1; // Default verbosity is 1 // edit existing. if (isset($configId)) { // 1 on 1 copy of config attributes $copy_fields = "auth_user,auth_pass,disable,mode,protocol,interface ,local_port,server_addr,server_port,resolve_retry ,proxy_addr,proxy_port,proxy_user,proxy_passwd,proxy_authtype,description ,custom_options,ns_cert_type,dev_mode,caref,certref,crypto,digest,engine ,tunnel_network,tunnel_networkv6,remote_network,remote_networkv6,use_shaper ,compression,passtos,no_tun_ipv6,route_no_pull,route_no_exec,verbosity_level"; foreach (explode(",", $copy_fields) as $fieldname) { $fieldname = trim($fieldname); if (isset($a_client[$configId][$fieldname])) { $pconfig[$fieldname] = $a_client[$configId][$fieldname]; } elseif (!isset($pconfig[$fieldname])) { // initialize element $pconfig[$fieldname] = null; } } // load / convert if (!empty($a_client[$configId]['ipaddr'])) { $pconfig['interface'] = $pconfig['interface'] . '|' . $a_client[$configId]['ipaddr']; } if (isset($a_client[$configId]['tls'])) { $pconfig['tls'] = base64_decode($a_client[$configId]['tls']); } else { $pconfig['tls'] = null; $pconfig['tlsauth_enable'] = null; } if (isset($a_client[$configId]['shared_key'])) { $pconfig['shared_key'] = base64_decode($a_client[$configId]['shared_key']); } else { $pconfig['shared_key'] = null ; } if (isset($id)) { $vpnid = $a_client[$id]['vpnid']; } } elseif ($act=="new") { // create new $pconfig['interface'] = "wan"; $pconfig['server_port'] = 1194; $init_fields = "auth_user,auth_pass,disable,mode,protocol,interface ,local_port,server_addr,server_port,resolve_retry ,proxy_addr,proxy_port,proxy_user,proxy_passwd,proxy_authtype,description ,custom_options,ns_cert_type,dev_mode,caref,certref,crypto,digest,engine ,tunnel_network,tunnel_networkv6,remote_network,remote_networkv6,use_shaper ,compression,passtos,no_tun_ipv6,route_no_pull,route_no_exec,verbosity_level"; foreach (explode(",", $init_fields) as $fieldname) { $fieldname = trim($fieldname); if (!isset($pconfig[$fieldname])) { $pconfig[$fieldname] = null; } } } } elseif ($_SERVER['REQUEST_METHOD'] === 'POST') { $pconfig = $_POST; $input_errors = array(); if (isset($_POST['id']) && isset($a_client[$_POST['id']])) { $id = $_POST['id']; } if (isset($_POST['act'])) { $act = $_POST['act']; } if ($act == "del") { // remove client if (isset($id)) { openvpn_delete('client', $a_client[$id]); unset($a_client[$id]); write_config(); } header("Location: vpn_openvpn_client.php"); exit; } elseif ($act == "del_x") { if (!empty($pconfig['rule']) && is_array($pconfig['rule'])) { foreach ($pconfig['rule'] as $rulei) { if (isset($a_client[$rulei])) { openvpn_delete('client', $a_client[$rulei]); unset($a_client[$rulei]); } } write_config(); } header("Location: vpn_openvpn_client.php"); exit; } elseif ($act == "move"){ // move selected items if (!isset($id)) { // if id not set/found, move to end $id = count($a_client); } $a_client = legacy_move_config_list_items($a_client, $id, $pconfig['rule']); write_config(); header("Location: vpn_openvpn_client.php"); exit; } elseif ($act == "toggle") { if (isset($id)) { if (isset($a_client[$id]['disable'])) { unset($a_client[$id]['disable']); } else { $a_client[$id]['disable'] = true; } openvpn_resync('client', $a_client[$id]); write_config(); } header("Location: vpn_openvpn_client.php"); exit; } else { // update client (after validation) if (isset($id)) { $vpnid = $a_client[$id]['vpnid']; } if (isset($pconfig['mode']) && $pconfig['mode'] != "p2p_shared_key") { $tls_mode = true; } else { $tls_mode = false; } // generate new key if (!empty($pconfig['autokey_enable'])) { $pconfig['shared_key'] = openvpn_create_key(); } /* input validation */ if (strpos($pconfig['interface'], '|') !== false) { list($iv_iface, $iv_ip) = explode("|", $pconfig['interface']); } else { $iv_iface = $pconfig['interface']; $iv_ip = null; } if (is_ipaddrv4($iv_ip) && (stristr($pconfig['protocol'], "6") !== false)) { $input_errors[] = gettext("Protocol and IP address families do not match. You cannot select an IPv6 protocol and an IPv4 IP address."); } elseif (is_ipaddrv6($iv_ip) && (stristr($pconfig['protocol'], "6") === false)) { $input_errors[] = gettext("Protocol and IP address families do not match. You cannot select an IPv4 protocol and an IPv6 IP address."); } elseif ((stristr($pconfig['protocol'], "6") === false) && !get_interface_ip($iv_iface) && ($pconfig['interface'] != "any")) { $input_errors[] = gettext("An IPv4 protocol was selected, but the selected interface has no IPv4 address."); } elseif ((stristr($pconfig['protocol'], "6") !== false) && !get_interface_ipv6($iv_iface) && ($pconfig['interface'] != "any")) { $input_errors[] = gettext("An IPv6 protocol was selected, but the selected interface has no IPv6 address."); } if (!empty($pconfig['local_port'])) { if (empty($pconfig['local_port']) || !is_numeric($pconfig['local_port']) || $pconfig['local_port'] < 0 || ($pconfig['local_port'] > 65535)) { $input_errors[] = gettext("The field Local port must contain a valid port, ranging from 0 to 65535."); } $portused = openvpn_port_used($pconfig['protocol'], $pconfig['interface'], $pconfig['local_port'], $vpnid); if (($portused != $vpnid) && ($portused != 0)) { $input_errors[] = gettext("The specified 'Local port' is in use. Please select another value"); } } if (empty($pconfig['server_addr']) || (!is_domain($pconfig['server_addr']) && !is_ipaddr($pconfig['server_addr']))) { $input_errors[] = gettext("The field Server host or address must contain a valid IP address or domain name.") ; } if (empty($pconfig['server_port']) || !is_numeric($pconfig['server_port']) || $pconfig['server_port'] < 0 || ($pconfig['server_port'] > 65535)) { $input_errors[] = gettext("The field Server port must contain a valid port, ranging from 0 to 65535."); } if (!empty($pconfig['proxy_addr'])) { if (empty($pconfig['proxy_addr']) || (!is_domain($pconfig['proxy_addr']) && !is_ipaddr($pconfig['proxy_addr']))) { $input_errors[] = gettext("The field Proxy host or address must contain a valid IP address or domain name.") ; } if (empty($pconfig['proxy_port']) || !is_numeric($pconfig['proxy_port']) || $pconfig['proxy_port'] < 0 || ($pconfig['proxy_port'] > 65535)) { $input_errors[] = gettext("The field Proxy port must contain a valid port, ranging from 0 to 65535."); } if (isset($pconfig['proxy_authtype']) && $pconfig['proxy_authtype'] != "none") { if (empty($pconfig['proxy_user']) || empty($pconfig['proxy_passwd'])) { $input_errors[] = gettext("User name and password are required for proxy with authentication."); } } } if (!empty($pconfig['tunnel_network'])) { if ($result = openvpn_validate_cidr($pconfig['tunnel_network'], 'IPv4 Tunnel Network', false, "ipv4")) { $input_errors[] = $result; } } if (!empty($pconfig['tunnel_networkv6'])) { if ($result = openvpn_validate_cidr($pconfig['tunnel_networkv6'], 'IPv6 Tunnel Network', false, "ipv6")) { $input_errors[] = $result; } } if ($result = openvpn_validate_cidr($pconfig['remote_network'], 'IPv4 Remote Network', true, "ipv4")) { $input_errors[] = $result; } if ($result = openvpn_validate_cidr($pconfig['remote_networkv6'], 'IPv6 Remote Network', true, "ipv6")) { $input_errors[] = $result; } if (!empty($pconfig['use_shaper']) && (!is_numeric($pconfig['use_shaper']) || ($pconfig['use_shaper'] <= 0))) { $input_errors[] = gettext("The bandwidth limit must be a positive numeric value."); } if (!$tls_mode && empty($pconfig['autokey_enable'])) { if (!strstr($pconfig['shared_key'], "-----BEGIN OpenVPN Static key V1-----") || !strstr($pconfig['shared_key'], "-----END OpenVPN Static key V1-----")) { $input_errors[] = gettext("The field 'Shared Key' does not appear to be valid"); } } if ($tls_mode && !empty($pconfig['tlsauth_enable']) && empty($pconfig['autotls_enable'])) { if (!strstr($pconfig['tls'], "-----BEGIN OpenVPN Static key V1-----") || !strstr($pconfig['tls'], "-----END OpenVPN Static key V1-----")) { $input_errors[] = gettext("The field 'TLS Authentication Key' does not appear to be valid"); } } /* If we are not in shared key mode, then we need the CA/Cert. */ if (isset($pconfig['mode']) && $pconfig['mode'] != "p2p_shared_key") { $reqdfields = explode(" ", "caref"); $reqdfieldsn = array(gettext("Certificate Authority")); } elseif (empty($pconfig['autokey_enable'])) { /* We only need the shared key filled in if we are in shared key mode and autokey is not selected. */ $reqdfields = array('shared_key'); $reqdfieldsn = array(gettext('Shared key')); } do_input_validation($pconfig, $reqdfields, $reqdfieldsn, $input_errors); if (($pconfig['mode'] != "p2p_shared_key") && empty($pconfig['certref']) && empty($pconfig['auth_user']) && empty($pconfig['auth_pass'])) { $input_errors[] = gettext("If no Client Certificate is selected, a username and password must be entered."); } if (count($input_errors) == 0) { // save data $client = array(); // 1 on 1 copy of config attributes $copy_fields = "auth_user,auth_pass,protocol,dev_mode,local_port ,server_addr,server_port,resolve_retry,proxy_addr,proxy_port ,proxy_authtype,proxy_user,proxy_passwd,description,mode,crypto,digest ,engine,tunnel_network,tunnel_networkv6,remote_network,remote_networkv6 ,use_shaper,compression,passtos,no_tun_ipv6,route_no_pull,route_no_exec ,verbosity_level,interface"; foreach (explode(",", $copy_fields) as $fieldname) { $fieldname = trim($fieldname); if (!empty($pconfig[$fieldname])) { $client[$fieldname] = $pconfig[$fieldname]; } } // attributes containing some kind of logic if ($vpnid) { $client['vpnid'] = $vpnid; } else { $client['vpnid'] = openvpn_vpnid_next(); } if (isset($pconfig['disable']) && $pconfig['disable'] == "yes") { $client['disable'] = true; } if (strpos($pconfig['interface'], "|") !== false) { list($client['interface'], $client['ipaddr']) = explode("|", $pconfig['interface']); } $client['custom_options'] = str_replace("\r\n", "\n", $pconfig['custom_options']); if ($tls_mode) { $client['caref'] = $pconfig['caref']; $client['certref'] = $pconfig['certref']; if (!empty($pconfig['tlsauth_enable'])) { if (!empty($pconfig['autotls_enable'])) { $pconfig['tls'] = openvpn_create_key(); } $client['tls'] = base64_encode($pconfig['tls']); } } else { $client['shared_key'] = base64_encode($pconfig['shared_key']); } if (isset($id)) { $a_client[$id] = $client; } else { $a_client[] = $client; } openvpn_resync('client', $client); write_config(); header("Location: vpn_openvpn_client.php"); exit; } } } // escape form output before processing legacy_html_escape_form_data($pconfig); include("head.inc"); $main_buttons = array( array('href'=>'vpn_openvpn_client.php?act=new', 'label'=>gettext("add client")), ); ?> <body> <?php include("fbegin.inc"); ?> <script type="text/javascript"> //<![CDATA[ $( document ).ready(function() { // init form (old stuff) if (document.iform != undefined) { mode_change(); autokey_change(); tlsauth_change(); useproxy_changed(); } // link delete buttons $(".act_delete").click(function(){ var id = $(this).data("id"); if (id != 'x') { BootstrapDialog.show({ type:BootstrapDialog.TYPE_DANGER, title: "<?= gettext("OpenVPN");?>", message: "<?= gettext("Do you really want to delete this client?"); ?>", buttons: [{ label: "<?= gettext("No");?>", action: function(dialogRef) { dialogRef.close(); }}, { label: "<?= gettext("Yes");?>", action: function(dialogRef) { $.post(window.location, {act: 'del', id:id}, function(data) { location.reload(); }); dialogRef.close(); } }] }); } else { // delete selected BootstrapDialog.show({ type:BootstrapDialog.TYPE_DANGER, title: "<?=gettext("OpenVPN");?>", message: "<?=gettext("Do you really want to delete the selected clients?");?>", buttons: [{ label: "<?= gettext("No");?>", action: function(dialogRef) { dialogRef.close(); }}, { label: "<?= gettext("Yes");?>", action: function(dialogRef) { $("#id").val(""); $("#action").val("del_x"); $("#iform2").submit() } }] }); } }); // link toggle buttons $(".act_toggle").click(function(){ $.post(window.location, {act: 'toggle', id:$(this).data("id")}, function(data) { location.reload(); }); }); // link move buttons $(".act_move").click(function(){ $("#id").val($(this).data("id")); $("#action").val("move"); $("#iform2").submit(); }); }); function mode_change() { index = document.iform.mode.selectedIndex; value = document.iform.mode.options[index].value; switch(value) { case "p2p_tls": document.getElementById("tls").style.display=""; document.getElementById("tls_ca").style.display=""; document.getElementById("tls_cert").style.display=""; document.getElementById("psk").style.display="none"; break; case "p2p_shared_key": document.getElementById("tls").style.display="none"; document.getElementById("tls_ca").style.display="none"; document.getElementById("tls_cert").style.display="none"; document.getElementById("psk").style.display=""; break; } } function dev_mode_change() { index = document.iform.dev_mode.selectedIndex; value = document.iform.dev_mode.options[index].value; switch(value) { case "tun": document.getElementById("chkboxNoTunIPv6").style.display=""; break; case "tap": document.getElementById("chkboxNoTunIPv6").style.display="none"; break; } } function autokey_change() { if (document.iform.autokey_enable != undefined && document.iform.autokey_enable.checked) { document.getElementById("autokey_opts").style.display="none"; } else { document.getElementById("autokey_opts").style.display=""; } } function useproxy_changed() { if ($('#proxy_authtype').val() != 'none') { $('#proxy_authtype_opts').show(); } else { $('#proxy_authtype_opts').hide(); } } function tlsauth_change() { <?php if (empty($pconfig['tls'])) : ?> if (document.iform.tlsauth_enable.checked) document.getElementById("tlsauth_opts").style.display=""; else document.getElementById("tlsauth_opts").style.display="none"; <?php endif; ?> autotls_change(); } function autotls_change() { <?php if (empty($pconfig['tls'])) : ?> autocheck = document.iform.autotls_enable.checked; <?php else : ?> autocheck = false; <?php endif; ?> if (document.iform.tlsauth_enable.checked && !autocheck) { document.getElementById("autotls_opts").style.display=""; } else { document.getElementById("autotls_opts").style.display="none"; } } //]]> </script> <section class="page-content-main"> <div class="container-fluid"> <div class="row"> <?php if (isset($input_errors) && count($input_errors) > 0) { print_input_errors($input_errors); } if (isset($savemsg)) { print_info_box($savemsg); }?> <section class="col-xs-12"> <div class="tab-content content-box col-xs-12"> <?php if ($act=="new" || $act=="edit") :?> <form action="vpn_openvpn_client.php" method="post" name="iform" id="iform"> <div class="table-responsive"> <table class="table table-striped"> <tr> <td width="22%"><?=gettext("General information"); ?></td> <td width="78%" align="right"> <small><?=gettext("full help"); ?> </small> <i class="fa fa-toggle-off text-danger" style="cursor: pointer;" id="show_all_help_page" type="button"></i></a> </td> </tr> <tr> <td><a id="help_for_disable" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a><?=gettext("Disabled"); ?></td> <td> <input name="disable" type="checkbox" value="yes" <?= !empty($pconfig['disable']) ? "checked=\"checked\"" : "";?> /> <div class="hidden" for="help_for_disable"> <small><?=gettext("Set this option to disable this client without removing it from the list"); ?>.</small> </div> </td> </tr> <tr> <td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Server Mode");?></td> <td> <select name="mode" id="mode" class="form-control" onchange="mode_change()"> <?php $openvpn_client_modes = array( 'p2p_tls' => gettext("Peer to Peer ( SSL/TLS )"), 'p2p_shared_key' => gettext("Peer to Peer ( Shared Key )") ); foreach ($openvpn_client_modes as $name => $desc) : $selected = ""; if ($pconfig['mode'] == $name) { $selected = "selected=\"selected\""; }?> <option value="<?=$name;?>" <?=$selected;?>><?=$desc;?></option> <?php endforeach; ?> </select> </td> </tr> <tr> <td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Protocol");?></td> <td> <select name='protocol' class="form-control"> <?php foreach (array("UDP", "UDP6", "TCP", "TCP6") as $prot) : $selected = ""; if ($pconfig['protocol'] == $prot) { $selected = "selected=\"selected\""; }?> <option value="<?=$prot;?>" <?=$selected;?>><?=$prot;?></option> <?php endforeach; ?> </select> </td> </tr> <tr> <td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Device mode");?></td> <td> <select name='dev_mode' class="form-control" onchange="dev_mode_change()"> <?php foreach (array("tun", "tap") as $mode) : $selected = ""; if ($pconfig['dev_mode'] == $mode) { $selected = "selected=\"selected\""; }?> <option value="<?=$mode;?>" <?=$selected;?>><?=$mode;?></option> <?php endforeach; ?> </select> </td> </tr> <tr> <td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Interface"); ?></td> <td> <select name="interface" class="form-control"> <?php $interfaces = get_configured_interface_with_descr(); $carplist = get_configured_carp_interface_list(); foreach ($carplist as $cif => $carpip) { $interfaces[$cif.'|'.$carpip] = $carpip." (".get_vip_descr($carpip).")"; } $aliaslist = get_configured_ip_aliases_list(); foreach ($aliaslist as $aliasip => $aliasif) { $interfaces[$aliasif.'|'.$aliasip] = $aliasip." (".get_vip_descr($aliasip).")"; } $grouplist = return_gateway_groups_array(); foreach ($grouplist as $name => $group) { if ($group['ipprotocol'] != inet) { continue; } if ($group[0]['vip'] <> "") { $vipif = $group[0]['vip']; } else { $vipif = $group[0]['int']; } $interfaces[$name] = "GW Group {$name}"; } $interfaces['lo0'] = "Localhost"; $interfaces['any'] = "any"; foreach ($interfaces as $iface => $ifacename) : $selected = ""; if ($iface == $pconfig['interface']) { $selected = "selected=\"selected\""; }?> <option value="<?=$iface;?>" <?=$selected;?>><?=htmlspecialchars($ifacename);?></option> <?php endforeach; ?> </select> <br /> </td> </tr> <tr> <td><a id="help_for_local_port" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Local port");?></td> <td> <input name="local_port" type="text" class="form-control unknown" size="5" value="<?=$pconfig['local_port'];?>" /> <div class="hidden" for="help_for_local_port"> <em><small><?=gettext("Set this option if you would like to bind to a specific port. Leave this blank or enter 0 for a random dynamic port."); ?></small></em> </div> </td> </tr> <tr> <td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Server host or address");?></td> <td> <input name="server_addr" type="text" class="form-control unknown" size="30" value="<?=$pconfig['server_addr'];?>" /> </td> </tr> <tr> <td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Server port");?></td> <td> <input name="server_port" type="text" class="form-control unknown" size="5" value="<?=$pconfig['server_port'];?>" /> </td> </tr> <tr> <td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Proxy host or address");?></td> <td> <input name="proxy_addr" type="text" class="form-control unknown" size="30" value="<?=$pconfig['proxy_addr'];?>" /> </td> </tr> <tr> <td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Proxy port");?></td> <td> <input name="proxy_port" type="text" class="form-control unknown" size="5" value="<?=$pconfig['proxy_port'];?>" /> </td> </tr> <tr> <td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Proxy authentication extra options");?></td> <td> <?=gettext("Authentication method"); ?> <select name="proxy_authtype" id="proxy_authtype" class="form-control select" onchange="useproxy_changed()"> <option value="none" <?=$pconfig['proxy_authtype'] == "none" ? "selected=\"selected\"" : "" ?> > <?=gettext("none"); ?></option> <option value="basic" <?=$pconfig['proxy_authtype'] == "basic" ? "selected=\"selected\"" : "" ?> > <?=gettext("basic"); ?></option> <option value="basic" <?=$pconfig['proxy_authtype'] == "ntlm" ? "selected=\"selected\"" : "" ?> > <?=gettext("ntlm"); ?></option> </select> <div style="display:none" id="proxy_authtype_opts"> <div><?=gettext("Username"); ?> <br/></div> <div><input name="proxy_user" id="proxy_user" class="form-control unknown" type="text" size="20" value="<?=$pconfig['proxy_user'];?>" /></div> <div><?=gettext("Password"); ?> </div> <div><input name="proxy_passwd" id="proxy_passwd" type="password" class="form-control pwd" size="20" value="<?=$pconfig['proxy_passwd'];?>" /></div> </div> </td> </tr> <tr> <td><a id="help_for_resolve_retry" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Server host name resolution"); ?></td> <td> <input name="resolve_retry" type="checkbox" value="yes" <?= !empty($pconfig['resolve_retry']) ? "checked=\"checked\"" : "";?> /> <div class="hidden" for="help_for_resolve_retry"> <div><?=gettext("Infinitely resolve server"); ?></div> <div><small><?=gettext("Continuously attempt to resolve the server host name. Useful when communicating with a server that is not permanently connected to the Internet"); ?></small></div> </div> </td> </tr> <tr> <td><a id="help_for_description" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Description"); ?></td> <td> <input name="description" type="text" class="form-control unknown" size="30" value="<?=$pconfig['description'];?>" /> <div class="hidden" for="help_for_description"> <small><?=gettext("You may enter a description here for your reference (not parsed)"); ?>.</small> </div> </td> </tr> <tr> <td colspan="2" class="list" height="12"></td> </tr> <tr> <td colspan="2"><?=gettext("User Authentication Settings"); ?></td> </tr> <tr> <td><a id="help_for_auth_user_pass" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("User name/pass"); ?></td> <td> <div><?=gettext("Username"); ?></div> <div><input name="auth_user" id="auth_user" class="form-control unknown" type="text" size="20" value="<?=htmlspecialchars($pconfig['auth_user']);?>" /></div> <div><?=gettext("Password"); ?></div> <div><input name="auth_pass" id="auth_pass" type="password" class="form-control pwd" size="20" value="<?=htmlspecialchars($pconfig['auth_pass']);?>" /></div> <div class="hidden" for="help_for_auth_user_pass"> <?=gettext("Leave empty when no user name and password are needed."); ?> </div> <br/> </td> </tr> <tr> <td colspan="2"><?=gettext("Cryptographic Settings"); ?></td> </tr> <tr id="tls"> <td><i class="fa fa-info-circle text-muted"></i> <?=gettext("TLS Authentication"); ?></td> <td> <input name="tlsauth_enable" id="tlsauth_enable" type="checkbox" value="yes" <?= !empty($pconfig['tlsauth_enable']) ? "checked=\"checked\"" : "";?> onclick="tlsauth_change()" /> <?=gettext("Enable authentication of TLS packets"); ?>. <?php if (empty($pconfig['tls'])) :?> <div id="tlsauth_opts"> <input name="autotls_enable" id="autotls_enable" type="checkbox" value="yes" <?= !empty($pconfig['autotls_enable']) ? "checked=\"checked\"" : "";?> onclick="autotls_change()" > <?=gettext("Automatically generate a shared TLS authentication key"); ?>. </div> <?php endif; ?> <div id="autotls_opts"> <textarea name="tls" cols="65" rows="7" class="formpre"><?=isset($pconfig['tls'])?$pconfig['tls']:"";?></textarea> <p class="text-muted"><em><small><?=gettext("Paste your shared key here"); ?>.</small></em></p> </div> </td> </tr> <tr id="tls_ca"> <td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Peer Certificate Authority"); ?></td> <td> <?php if (isset($config['ca'])) :?> <select name='caref' class="form-control"> <?php foreach ($config['ca'] as $ca) : $selected = ""; if (isset($pconfig['caref']) && $pconfig['caref'] == $ca['refid']) { $selected = "selected=\"selected\""; }?> <option value="<?=$ca['refid'];?>" <?=$selected;?>><?=$ca['descr'];?></option> <?php endforeach; ?> </select> <?php else :?> <b><?=gettext("No Certificate Authorities defined.");?></b> <br /> <?=gettext("Create one under");?> <a href="system_camanager.php"><?=gettext("System: Certificates");?></a>. <?php endif; ?> </td> </tr> <tr id="tls_cert"> <td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Client Certificate"); ?></td> <td> <select name='certref' class="form-control"> <?php foreach (isset($config['cert']) ? $config['cert'] : array() as $cert) : $selected = ""; $caname = ""; $inuse = ""; $revoked = ""; if (isset($cert['caref'])) { $ca = lookup_ca($cert['caref']); if (!empty($ca)) { $caname = " (CA: {$ca['descr']})"; } } if (isset($pconfig['certref']) && $pconfig['certref'] == $cert['refid']) { $selected = "selected=\"selected\""; } if (isset($cert['refid']) && cert_in_use($cert['refid'])) { $inuse = " *In Use"; } if (is_cert_revoked($cert)) { $revoked = " *Revoked"; }?> <option value="<?=$cert['refid'];?>" <?=$selected;?>><?=$cert['descr'] . $caname . $inuse . $revoked;?></option> <?php endforeach; ?> <option value="" <?=empty($pconfig['certref'])? "selected=\"selected\"" : "";?>> <?=gettext("None");?> <?=gettext("(Username and Password required)");?> </option> </select> <?php if (!isset($config['cert']) || count($config['cert']) == 0) :?> <b><?=gettext("No Certificates defined.");?></b> <br /><?=gettext("Create one under");?> <a href="system_certmanager.php"><?=gettext("System: Certificates");?></a> <?=gettext("if one is required for this connection.");?> <?php endif; ?> </td> </tr> <tr id="psk"> <td><?=gettext("Shared Key"); ?></td> <td> <?php if (empty($pconfig['shared_key'])) :?> <input name="autokey_enable" id="autokey_enable" type="checkbox" value="yes" <?= !empty($pconfig['autokey_enable']) ? "checked=\"checked\"" : "";?> onclick="autokey_change()" /> <?=gettext("Automatically generate a shared key"); ?>. <?php endif; ?> <div id="autokey_opts"> <textarea name="shared_key" cols="65" rows="7" class="formpre"><?=isset($pconfig['shared_key']) ? $pconfig['shared_key'] : "";?></textarea> <em><small><?=gettext("Paste your shared key here"); ?>.</small></em> </div> </td> </tr> <tr> <td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Encryption algorithm"); ?></td> <td> <select name="crypto" class="form-control"> <?php $cipherlist = openvpn_get_cipherlist(); foreach ($cipherlist as $name => $desc) : $selected = ""; if ($name == $pconfig['crypto']) { $selected = " selected=\"selected\""; }?> <option value="<?=$name;?>"<?=$selected?>><?=htmlspecialchars($desc);?></option> <?php endforeach; ?> </select> </td> </tr> <tr> <td><a id="help_for_digest" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Auth Digest Algorithm"); ?></td> <td> <select name="digest" class="form-control"> <?php $digestlist = openvpn_get_digestlist(); foreach ($digestlist as $name => $desc) : $selected = ""; if ($name == $pconfig['digest']) { $selected = " selected=\"selected\""; }?> <option value="<?=$name;?>"<?=$selected?>><?=htmlspecialchars($desc);?></option> <?php endforeach; ?> </select> <div class="hidden" for="help_for_digest"> <?=gettext("NOTE: Leave this set to SHA1 unless the server is set to match. SHA1 is the default for OpenVPN."); ?> </div> </td> </tr> <tr id="engine"> <td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Hardware Crypto"); ?></td> <td> <select name="engine" class="form-control"> <?php $engines = openvpn_get_engines(); foreach ($engines as $name => $desc) : $selected = ""; if ($name == $pconfig['engine']) { $selected = " selected=\"selected\""; }?> <option value="<?=$name;?>"<?=$selected?>><?=htmlspecialchars($desc);?></option> <?php endforeach; ?> </select> </td> </tr> <tr> <td colspan="2" class="list" height="12"></td> </tr> <tr> <td colspan="2"><?=gettext("Tunnel Settings"); ?></td> </tr> <tr> <td><a id="help_for_tunnel_network" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("IPv4 Tunnel Network"); ?></td> <td> <input name="tunnel_network" type="text" class="form-control unknown" size="20" value="<?=$pconfig['tunnel_network'];?>" /> <div class="hidden" for="help_for_tunnel_network"> <?=gettext("This is the virtual network used for private " . "communications between this client and the " . "server expressed using CIDR (eg. 10.0.8.0/24). " . "The first network address is assumed to be the " . "server address and the second network address " . "will be assigned to the client virtual " . "interface"); ?>. </div> </td> </tr> <tr> <td><a id="help_for_tunnel_networkv6" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("IPv6 Tunnel Network"); ?></td> <td> <input name="tunnel_networkv6" type="text" class="form-control unknown" size="20" value="<?=$pconfig['tunnel_networkv6'];?>" /> <div class="hidden" for="help_for_tunnel_networkv6"> <?=gettext("This is the IPv6 virtual network used for private " . "communications between this client and the " . "server expressed using CIDR (eg. fe80::/64). " . "The first network address is assumed to be the " . "server address and the second network address " . "will be assigned to the client virtual " . "interface"); ?>. </div> </td> </tr> <tr> <td><a id="help_for_remote_network" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("IPv4 Remote Network/s"); ?></td> <td> <input name="remote_network" type="text" class="form-control unknown" size="40" value="<?=$pconfig['remote_network'];?>" /> <div class="hidden" for="help_for_remote_network"> <?=gettext("These are the IPv4 networks that will be routed through " . "the tunnel, so that a site-to-site VPN can be " . "established without manually changing the routing tables. " . "Expressed as a comma-separated list of one or more CIDR ranges. " . "If this is a site-to-site VPN, enter the " . "remote LAN/s here. You may leave this blank to " . "only communicate with other clients"); ?>. </div> </td> </tr> <tr> <td><a id="help_for_remote_networkv6" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("IPv6 Remote Network/s"); ?></td> <td> <input name="remote_networkv6" type="text" class="form-control unknown" size="40" value="<?=$pconfig['remote_networkv6'];?>" /> <div class="hidden" for="help_for_remote_networkv6"> <?=gettext("These are the IPv6 networks that will be routed through " . "the tunnel, so that a site-to-site VPN can be " . "established without manually changing the routing tables. " . "Expressed as a comma-separated list of one or more IP/PREFIX. " . "If this is a site-to-site VPN, enter the " . "remote LAN/s here. You may leave this blank to " . "only communicate with other clients"); ?>. </div> </td> </tr> <tr> <td><a id="help_for_use_shaper" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Limit outgoing bandwidth");?></td> <td> <input name="use_shaper" type="text" class="form-control unknown" size="5" value="<?=$pconfig['use_shaper'];?>" /> <div class="hidden" for="help_for_use_shaper"> <?=gettext("Maximum outgoing bandwidth for this tunnel. " . "Leave empty for no limit. The input value has " . "to be something between 100 bytes/sec and 100 " . "Mbytes/sec (entered as bytes per second)"); ?>. </div> </td> </tr> <tr> <td><a id="help_for_compression" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Compression"); ?></td> <td> <select name="compression" class="form-control"> <?php foreach ($openvpn_compression_modes as $cmode => $cmodedesc) : $selected = ""; if ($cmode == $pconfig['compression']) { $selected = " selected=\"selected\""; } ?> <option value="<?= $cmode ?>" <?= $selected ?>><?= $cmodedesc ?></option> <?php endforeach; ?> </select> <div class="hidden" for="help_for_compression"> <?=gettext("Compress tunnel packets using the LZO algorithm. Adaptive compression will dynamically disable compression for a period of time if OpenVPN detects that the data in the packets is not being compressed efficiently."); ?>. </div> </td> </tr> <tr> <td><a id="help_for_passtos" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Type-of-Service"); ?></td> <td> <input name="passtos" type="checkbox" value="yes" <?=!empty($pconfig['passtos']) ? "checked=\"checked\"" : "" ;?> /> <div class="hidden" for="help_for_passtos"> <?=gettext("Set the TOS IP header value of tunnel packets to match the encapsulated packet value"); ?>. </div> </td> </tr> <tr id="chkboxNoTunIPv6"> <td><a id="help_for_no_tun_ipv6" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Disable IPv6"); ?></td> <td> <input name="no_tun_ipv6" type="checkbox" value="yes" <?=!empty($pconfig['no_tun_ipv6']) ? "checked=\"checked\"" : "" ;?> /> <div class="hidden" for="help_for_no_tun_ipv6"> <?=gettext("Don't forward IPv6 traffic"); ?>. </div> </td> </tr> <tr id="chkboxRouteNoPull"> <td><a id="help_for_route_no_pull" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Don't pull routes"); ?></td> <td> <input name="route_no_pull" type="checkbox" value="yes" <?=!empty($pconfig['route_no_pull']) ? "checked=\"checked\"" : "" ;?> /> <div class="hidden" for="help_for_route_no_pull"> <?=sprintf(gettext("Don't add or remove routes automatically. Instead pass routes to %s--route-up%s script using environmental variables"),'<strong>','</strong>') ?>. </div> </td> </tr> <tr id="chkboxRouteNoExec"> <td><a id="help_for_route_no_exec" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Don't add/remove routes"); ?></td> <td> <input name="route_no_exec" type="checkbox" value="yes" <?=!empty($pconfig['route_no_exec']) ? "checked=\"checked\"" : "" ;?> /> <div class="hidden" for="help_for_route_no_exec"> <?=gettext("This option effectively bars the server from adding routes to the client's routing table, however note that this option still allows the server to set the TCP/IP properties of the client's TUN/TAP interface"); ?>. </div> </td> </tr> <tr> <td colspan="2" class="list" height="12"></td> </tr> <tr> <td colspan="2"><?=gettext("Advanced configuration"); ?></td> </tr> <tr> <td><a id="help_for_custom_options" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Advanced"); ?></td> <td> <textarea rows="6" cols="78" name="custom_options" id="custom_options"><?=$pconfig['custom_options'];?></textarea><br /> <div class="hidden" for="help_for_custom_options"> <?=gettext("Enter any additional options you would like to add to the OpenVPN client configuration here, separated by a semicolon"); ?><br /> <?=gettext("EXAMPLE:"); ?> <strong>remote server.mysite.com 1194;</strong> or <strong>remote 1.2.3.4 1194;</strong> </div> </td> </tr> <tr id="comboboxVerbosityLevel"> <td><a id="help_for_verbosity_level" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext("Verbosity level");?></td> <td> <select name="verbosity_level" class="form-control"> <?php foreach ($openvpn_verbosity_level as $verb_value => $verb_desc) : $selected = ''; if ($pconfig['verbosity_level'] == $verb_value) { $selected = 'selected="selected"'; } ?> <option value="<?=$verb_value; ?>" <?=$selected; ?>><?=$verb_desc;?></option> <?php endforeach; ?> </select> <div class="hidden" for="help_for_verbosity_level"> <?=gettext("Each level shows all info from the previous levels. Level 3 is recommended if you want a good summary of what's happening without being swamped by output.") ?> <br /> <br /> <?=sprintf(gettext("%snone%s -- No output except fatal errors."),'<strong>','</strong>') ?> <br /> <?=sprintf(gettext("%sdefault%s-%s4%s -- Normal usage range."),'<strong>','</strong>','<strong>','</strong>'); ?> <br /> <?=sprintf(gettext("%s5%s -- Output R and W characters to the console for each packet read and write, uppercase is used for TCP/UDP packets and lowercase is used for TUN/TAP packets."),'<strong>','</strong>') ?> <br /> <?=sprintf(gettext("%s6%s-%s11%s -- Debug info range."),'<strong>','</strong>','<strong>','</strong>') ?> </div> </td> </tr> </table> <br /> <table width="100%" border="0" cellpadding="6" cellspacing="0" summary="icons"> <tr> <td> </td> <td width="78%"> <input name="save" type="submit" class="btn btn-primary" value="<?=gettext("Save"); ?>" /> <input name="act" type="hidden" value="<?=$act;?>" /> <?php if (isset($id) && $a_client[$id]) :?> <input name="id" type="hidden" value="<?=htmlspecialchars($id);?>" /> <?php endif; ?> </td> </tr> </table> </div> </form> <?php else:?> <form method="post" name="iform2" id="iform2"> <input type="hidden" id="id" name="id" value="" /> <input type="hidden" id="action" name="act" value="" /> <table class="table table-striped"> <thead> <tr> <td></td> <td><?=gettext("Protocol"); ?></td> <td><?=gettext("Server"); ?></td> <td><?=gettext("Description"); ?></td> <td></td> </tr> </thead> <tbody> <?php $i = 0; foreach ($a_client as $client) : $server = "{$client['server_addr']}:{$client['server_port']}";?> <tr> <td> <input type="checkbox" name="rule[]" value="<?=$i;?>" /> <a href="#" class="act_toggle" data-id="<?=$i;?>" data-toggle="tooltip" title="<?=(empty($client['disable'])) ? gettext("disable") : gettext("enable");?>"> <span class="glyphicon glyphicon-play <?=(empty($client['disable'])) ? "text-success" : "text-muted";?>"></span> </a> </td> <td> <?=htmlspecialchars($client['protocol']);?> </td> <td> <?=htmlspecialchars($server);?> </td> <td> <?=htmlspecialchars($client['description']);?> </td> <td> <a data-id="<?=$i;?>" data-toggle="tooltip" title="<?=gettext("move selected before this item");?>" class="act_move btn btn-default btn-xs"> <span class="glyphicon glyphicon-arrow-left"></span> </a> <a href="vpn_openvpn_client.php?act=edit&id=<?=$i;?>" class="btn btn-default btn-xs"> <span class="glyphicon glyphicon-pencil"></span> </a> <a data-id="<?=$i;?>" title="<?=gettext("delete client"); ?>" class="act_delete btn btn-default btn-xs"> <span class="fa fa-trash text-muted"></span> </a> <a href="vpn_openvpn_client.php?act=new&dup=<?=$i;?>" class="btn btn-default btn-xs" data-toggle="tooltip" title="<?=gettext("clone rule");?>"> <span class="fa fa-clone text-muted"></span> </a> </td> </tr> <?php $i++; endforeach;?> <tr> <td colspan="4"></td> <td> <a data-id="<?=$i;?>" data-toggle="tooltip" title="<?=gettext("move selected items to end");?>" class="act_move btn btn-default btn-xs"> <span class="glyphicon glyphicon-arrow-down"></span> </a> <a data-id="x" title="<?=gettext("delete selected rules"); ?>" data-toggle="tooltip" class="act_delete btn btn-default btn-xs"> <span class="fa fa-trash text-muted"></span> </a> </td> </tr> </tbody> </table> <form> <?php endif; ?> </div> </section> </div> </div> </section> <?php include("foot.inc"); ?>