From 7a5948ba60cfcd1a3854d5323bc80e93a1871a41 Mon Sep 17 00:00:00 2001 From: "R. Christian McDonald" Date: Fri, 4 Jun 2021 13:46:48 -0400 Subject: [PATCH] v0.1.2_1 (#101) * back merge main onto devel (#94) * Update main to latest (#77) * Updated pkg-plist * Makefile fix * Experimenting with wireguard service * Update README.md Co-authored-by: vajonam <152501+vajonam@users.noreply.github.com> Co-authored-by: Manojav Sridhar * docs: add theonemcdonald as a contributor (#84) * docs: update README.md [skip ci] * docs: create .all-contributorsrc [skip ci] Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> * Update README.md * Update README.md * Update .all-contributorsrc * Update .all-contributorsrc * Update README.md * Update README.md * Update Makefile * Cleanup * Cleanup * Clean upload of v0.1.2 * Create FUNDING.yml * Add files via upload Co-authored-by: vajonam <152501+vajonam@users.noreply.github.com> Co-authored-by: Manojav Sridhar Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> * Clean ups * Syntax * Updated README * Improve input error clarity * Syntax * More syntax * Fix missing address, allowedip fields after tunnel or peer input errors * Reorganized peer post validation * Reorder all input errors to be consistent with UI order * Fix input being flushed on peer validation error * Fix * Test * Fix #98 * Also Fix #98 * v0.1.3 will be reserved for the next PR with Netgate * Further fixes #98 * More fixes for #98... * Removed exit() while working on #98 * Refactor wg_generate_tunnel_address_popover_link for readability * Working on guiconfig cleaning * Should fix #99 * Fix variable #99 * Fix re-saving unchanged tunnel or peer * Fix broke status icon * Back out some boiler plate code * Relocate pf reload trigger on tunnel sync Co-authored-by: vajonam <152501+vajonam@users.noreply.github.com> Co-authored-by: Manojav Sridhar Co-authored-by: allcontributors[bot] <46447321+allcontributors[bot]@users.noreply.github.com> --- net/pfSense-pkg-WireGuard/Makefile | 3 +- .../files/usr/local/pkg/wireguard/wg.inc | 40 ++-- .../usr/local/pkg/wireguard/wg_guiconfig.inc | 183 ++++++++++++------ .../usr/local/pkg/wireguard/wg_install.inc | 28 +-- .../usr/local/pkg/wireguard/wg_service.inc | 7 +- .../usr/local/pkg/wireguard/wg_validate.inc | 107 ++++++---- .../usr/local/www/wg/status_wireguard.php | 61 +++--- .../files/usr/local/www/wg/vpn_wg_peers.php | 9 +- .../usr/local/www/wg/vpn_wg_peers_edit.php | 12 +- .../files/usr/local/www/wg/vpn_wg_tunnels.php | 3 +- .../usr/local/www/wg/vpn_wg_tunnels_edit.php | 5 +- 11 files changed, 282 insertions(+), 176 deletions(-) diff --git a/net/pfSense-pkg-WireGuard/Makefile b/net/pfSense-pkg-WireGuard/Makefile index 18f19384..60eca529 100644 --- a/net/pfSense-pkg-WireGuard/Makefile +++ b/net/pfSense-pkg-WireGuard/Makefile @@ -1,5 +1,6 @@ PORTNAME= pfSense-pkg-WireGuard -PORTVERSION= 0.1.3 +PORTVERSION= 0.1.2 +PORTREVISION= 1 CATEGORIES= net MASTER_SITES= # empty DISTFILES= # empty diff --git a/net/pfSense-pkg-WireGuard/files/usr/local/pkg/wireguard/wg.inc b/net/pfSense-pkg-WireGuard/files/usr/local/pkg/wireguard/wg.inc index 64043a6f..9587c648 100644 --- a/net/pfSense-pkg-WireGuard/files/usr/local/pkg/wireguard/wg.inc +++ b/net/pfSense-pkg-WireGuard/files/usr/local/pkg/wireguard/wg.inc @@ -60,7 +60,9 @@ function wg_toggle_tunnel($tunnel_name) { if ($enabled && is_wg_tunnel_assigned($tunnel['name'])) { - $input_errors[] = gettext('Cannot disable a WireGuard tunnel while it is assigned as an interface.'); + $wg_pfsense_if = wg_get_pfsense_interface_info($tunnel['name']); + + $input_errors[] = "Cannot disable {$tunnel['name']} while it is assigned to {$wg_pfsense_if['descr']} ({$wg_pfsense_if['name']})"; } @@ -213,7 +215,9 @@ function wg_delete_tunnel($tunnel_name) { // We can't delete assigned tunnels if (is_wg_tunnel_assigned($tunnel['name'])) { - $input_errors[] = gettext('Cannot delete a WireGuard tunnel assigned to a pfSense interface.'); + $wg_pfsense_if = wg_get_pfsense_interface_info($tunnel['name']); + + $input_errors[] = "Cannot delete {$tunnel['name']} while it is assigned to {$wg_pfsense_if['descr']} ({$wg_pfsense_if['name']})"; } @@ -245,7 +249,7 @@ function wg_delete_tunnel($tunnel_name) { function wg_peer_allowedips($post) { // Convert the post into proper arrays - $allowedips = wg_parse_post_repeatables($post, array('address', 'address_subnet', 'address_descr', 'address_route')); + $allowedips = wg_parse_post_repeatables($post, array('address', 'address_subnet', 'address_descr')); $ret_array = array(); @@ -260,13 +264,13 @@ function wg_peer_allowedips($post) { $ret_array[] = array( 'address' => $row['address'], 'mask' => $row['address_subnet'], - 'descr' => $row['address_descr'], - 'route' => $row['address_route']); + 'descr' => $row['address_descr']); } } + // Consumers expect an array return $ret_array; } @@ -298,6 +302,7 @@ function wg_tunnel_addresses($post) { } + // Consumers expect an array return $ret_array; } @@ -346,11 +351,11 @@ function wg_do_peer_post($post) { $peer_idx = $post['index']; + wg_init_config_arr($wgg['peers'][$peer_idx], array('allowedips', 'row')); + // We need to save the "old config" to compare against later... $pconfig = $old_config = $wgg['peers'][$peer_idx]; - wg_init_config_arr($pconfig, array('allowedips', 'row')); - $pconfig['enabled'] = empty($post['enabled']) ? 'no' : $post['enabled']; $old_tun = $pconfig['tun']; @@ -398,7 +403,6 @@ function wg_do_peer_post($post) { // We've got meaningful changes... $changes = true; - // Add peer's tunnel to the list to apply wg_apply_list_add($pconfig['tun'], 'tunnels'); // Now try the old_config tunnel... @@ -407,14 +411,8 @@ function wg_do_peer_post($post) { // We've got meaningful changes... $changes = true; - // Add peer's tunnel to the list to apply wg_apply_list_add($old_config['tun'], 'tunnels'); - // Looks like we are just resaving an unassigned peer... - } else { - - $changes = false; - } } @@ -440,11 +438,11 @@ function wg_do_tunnel_post($post) { $tun_idx = $post['index']; + wg_init_config_arr($wgg['tunnels'][$tun_idx], array('addresses', 'row')); + // We need to save the "old config" to compare against later... $pconfig = $old_config = $wgg['tunnels'][$tun_idx]; - wg_init_config_arr($pconfig, array('addresses', 'row')); - $pconfig['name'] = empty($pconfig['name']) ? next_wg_if() : $pconfig['name']; $pconfig['enabled'] = empty($post['enabled']) ? 'no' : $post['enabled']; @@ -593,6 +591,9 @@ function wg_tunnel_sync($tunnel_names = null) { 'config' => $tun_sync_status['config']); } + + // Reload the filter + filter_configure(); } @@ -709,15 +710,12 @@ function wg_resync() { // Reinstall earlyshellcmd in case it was accidently deleted wg_earlyshellcmd_install(); - // Reinstall interface group in case it was accidently deleted + // Recreate interface group in case it was accidently deleted wg_ifgroup_install(); - // Update by re-installing the Unbound ACL + // Update Unbound ACL by recreating it wg_unbound_acl_install(); - // Reinstall service in case it was accidently deleted - wg_service_install(); - // We don't want active tunnels when the service isn't running if (is_module_loaded($wgg['kmod']) && !wg_is_service_running()) { diff --git a/net/pfSense-pkg-WireGuard/files/usr/local/pkg/wireguard/wg_guiconfig.inc b/net/pfSense-pkg-WireGuard/files/usr/local/pkg/wireguard/wg_guiconfig.inc index b89b91a2..7d23de7e 100644 --- a/net/pfSense-pkg-WireGuard/files/usr/local/pkg/wireguard/wg_guiconfig.inc +++ b/net/pfSense-pkg-WireGuard/files/usr/local/pkg/wireguard/wg_guiconfig.inc @@ -109,24 +109,24 @@ function wg_get_tun_list() { } // Truncates a given string if necessary and formats it to make it look good -function wg_truncate_pretty($str, $length) { +function wg_truncate_pretty($text, $max_length) { - $s_truncated = substr($str, 0, $length); + $s_truncated = substr($text, 0, $max_length); - $s_pretty_dots = (strlen($str) > $length) ? '...' : ''; + $s_pretty_dots = (strlen($text) > $max_length) ? '...' : null; return "{$s_truncated}{$s_pretty_dots}"; } -function wg_interface_status_icon($status, $fa_icon = "fa-ethernet") { +function wg_interface_status_icon($status, $enabled_class = "fa fa-arrow-up text-success", $disabled_class = "fa fa-arrow-down text-danger") { global $wgg; - $ret_class = ($status == "up") ? 'text-success' : null; + $ret_class = ($status === "up" || $status === true) ? " {$enabled_class}" : " {$disabled_class}"; - wg_htmlspecialchars($fa_icon, $ret_class, $status); + wg_htmlspecialchars($ret_class, $status); - $ret_html = ""; + $ret_html = ""; return $ret_html; @@ -243,13 +243,15 @@ function wg_secret_input_type() { wg_globals(); + $type = 'text'; + if (isset($wgg['config']['hide_secrets']) && $wgg['config']['hide_secrets'] =='yes') { - return 'password'; + $type = 'password'; } - return 'text'; + return $type; } @@ -257,21 +259,25 @@ function wg_secret_input_type() { function wg_entrystatus_class($target_device) { global $wgg; + $class = 'disabled'; + if (isset($target_device) && $target_device['enabled'] == 'yes' && is_module_loaded($wgg['kmod'])) { - return 'enabled'; + $class = 'enabled'; } - return 'disabled'; + return $class; } // Generates a toggle icon link based on the status of the target function wg_generate_toggle_icon_link($target_device, $title = '', $href = '#', $usepost = true, $icon_enabled = 'fa-ban', $icon_disabled = 'fa-check-square-o') { + $ret_html = null; + if (isset($target_device)) { $s_icon = (isset($target_device['enabled']) && $target_device['enabled'] == 'yes') ? $icon_enabled : $icon_disabled; @@ -282,78 +288,114 @@ function wg_generate_toggle_icon_link($target_device, $title = '', $href = '#', wg_htmlspecialchars($s_icon, $s_title, $href, $s_usepost); - return ""; + $ret_html = ""; } - return null; + return $ret_html; } -function wg_generate_tunnel_address_popup_link($tunnel_name) { +function wg_generate_tunnel_address_popover_link($tunnel_name) { global $wgg; + $getText = function($text) { return gettext($text); }; + $tun_idx = wg_get_tunnel_array_index($tunnel_name); if (isset($wgg['tunnels'][$tun_idx]) && is_array($wgg['tunnels'][$tun_idx])) { $tunnel = $wgg['tunnels'][$tun_idx]; - $addresses = $tunnel['addresses']['row']; + // Smash address + mask + $addresses = array_map(function($x) { + + return array( + 'address' => "{$x['address']}/{$x['mask']}", + 'descr' => $x['descr']); + + }, $tunnel['addresses']['row']); if (!is_wg_tunnel_assigned($tunnel['name'])) { if (is_array($addresses) && count($addresses) > 0) { - $href = "vpn_wg_tunnels_edit.php?tun={$tunnel['name']}"; - $extras = count($addresses) - 1; if ($extras > 0) { - $data_html = ""; + $data_html = <<<"START" +
AddressDescription
+ + + + + + + START; foreach ($addresses as $address) { wg_htmlspecialchars($address); - $data_html .= ""; + $data_html .= <<<"ROW" + + + + + ROW; + } - $data_html .= '
{$getText('Address')}{$getText('Description')}
{$address['address']}/{$address['mask']}{$address['descr']}
{$address['address']}{$address['descr']}
'; - + $data_html .= <<<"END" + + + END; + + $title = gettext('Interfae Addresses'); + $hint = "{$addresses[0]['address']} (+{$extras})"; - wg_htmlspecialchars($href, $data_html, $hint); - - $ret_html = "{$hint}"; - - return $ret_html; + $popover_params = " data-toggle=\"popover\" data-trigger=\"hover focus\" data-content=\"{$data_html}\" data-html=\"true\""; } else { - wg_htmlspecialchars($href, $addresses[0]); - - $ret_html = "{$addresses[0]['address']}/{$addresses[0]['mask']}"; - - return $ret_html; + $title = $addresses[0]['descr']; + + $hint = $addresses[0]['address']; + + $popover_params = null; } + + $href = "vpn_wg_tunnels_edit.php?tun={$tunnel['name']}"; + + wg_htmlspecialchars($href, $title, $hint); + + $ret_html = "{$hint}"; } else { - return '(none)'; + $ret_html = "({$getText('none')})"; } + return $ret_html; + } else { $wg_pfsense_if = wg_get_pfsense_interface_info($tunnel['name']); wg_htmlspecialchars($wg_pfsense_if); - return "{$wg_pfsense_if['descr']} ({$wg_pfsense_if['name']})"; + $ret_html = <<<"RET" + + {$wg_pfsense_if['descr']} ({$wg_pfsense_if['name']}) + + RET; + + return $ret_html; } @@ -364,59 +406,88 @@ function wg_generate_tunnel_address_popup_link($tunnel_name) { function wg_generate_peer_allowedips_popup_link($peer_idx) { global $wgg; + $getText = function($text) { return gettext($text); }; + if (isset($wgg['peers'][$peer_idx]) && is_array($wgg['peers'][$peer_idx])) { $peer = $wgg['peers'][$peer_idx]; - $allowedips = $peer['allowedips']['row']; + // Smash address + mask + $allowedips = array_map(function($x) { - if (is_array($allowedips) && count($allowedips) > 0) { + return array( + 'address' => "{$x['address']}/{$x['mask']}", + 'descr' => $x['descr']); + + }, $peer['allowedips']['row']); - $href = "vpn_wg_peers_edit.php?peer={$peer_idx}"; + if (is_array($allowedips) && count($allowedips) > 0) { $extras = count($allowedips) - 1; if ($extras > 0) { - $data_html = ""; - - foreach ($allowedips as $address) { + $data_html = <<<"START" +
SubnetDescription
+ + + + + - wg_htmlspecialchars($address); - - $data_html .= ""; + START; + + foreach ($allowedips as $allowedip) { + + wg_htmlspecialchars($allowedip); + $data_html .= <<<"ROW" + + + + + + ROW; + } - $data_html .= '
{$getText('Subnet')}{$getText('Description')}
{$address['address']}/{$address['mask']}{$address['descr']}
{$allowedip['address']}{$allowedip['descr']}
'; - - $hint = "{$allowedips[0]['address']} (+{$extras})"; + $data_html .= <<<"END" + + + END; - wg_htmlspecialchars($href, $data_html, $hint); - - $ret_html = "{$hint}"; + $title = gettext('Allowed IPs'); - return $ret_html; + $hint = "{$allowedips[0]['address']} (+{$extras})"; + + $popover_params = " data-toggle=\"popover\" data-trigger=\"hover focus\" data-content=\"{$data_html}\" data-html=\"true\""; } else { - wg_htmlspecialchars($href, $allowedips[0]); - - $ret_html = "{$allowedips[0]['address']}/{$allowedips[0]['mask']}"; - - return $ret_html; + $title = $allowedips[0]['descr']; + + $hint = $allowedips[0]['address']; + + $popover_params = null; } + $href ="vpn_wg_peers_edit.php?peer={$peer_idx}"; + + wg_htmlspecialchars($href, $title, $hint); + + $ret_html = "{$hint}"; + } else { - return '(none)'; + $ret_html = "({$getText('none')})"; } + return $ret_html; } } -?> +?> \ No newline at end of file diff --git a/net/pfSense-pkg-WireGuard/files/usr/local/pkg/wireguard/wg_install.inc b/net/pfSense-pkg-WireGuard/files/usr/local/pkg/wireguard/wg_install.inc index 3c07c938..cf870a0a 100644 --- a/net/pfSense-pkg-WireGuard/files/usr/local/pkg/wireguard/wg_install.inc +++ b/net/pfSense-pkg-WireGuard/files/usr/local/pkg/wireguard/wg_install.inc @@ -46,24 +46,24 @@ function wg_install() { wg_upgrade_allowedips(); - update_status("done.\n Creating WireGuard early shell commands..."); + update_status("done.\n Installing WireGuard early shell commands..."); // Installs the WireGuard earlyshellcmds wg_earlyshellcmd_install(); update_status("done.\n Creating WireGuard interface group..."); - // Installs the 'WireGuard' interface group + // Create the 'WireGuard' interface group wg_ifgroup_install(); update_status("done.\n Creating WireGuard Unbound access list..."); - // Create Unbound ACL + // Create the WireGuard Unbound ACL wg_unbound_acl_install(); - update_status("done.\n Creating WireGuard service..."); + update_status("done.\n Installing WireGuard service..."); - // Creating service + // Create the WireGuard service wg_service_install(); update_status("done.\n"); @@ -331,10 +331,10 @@ function wg_deinstall() { // Teardown any WireGuard tunnel interfaces wg_destroy_tunnels(); - update_status("done.\n Removing WireGuard service..."); + update_status("done.\n Stopping and removing the WireGuard service..."); - // Remove WireGuard watchdog service - wg_service_deinstall(); + // Stop and remove the WireGuard service + wg_service_deinstall(true); update_status("done.\n"); @@ -382,14 +382,20 @@ function wg_service_install() { wg_service_rcfile(); + wg_service_deinstall(); + link($wgg['php'], $wgg['php_wg']); } -function wg_service_deinstall() { +function wg_service_deinstall($force_stop = false) { global $wgg; + + if ($force_stop) { - wg_service_fpm_stop(); + wg_service_fpm_stop(); + + } unlink_if_exists($wgg['php_wg']); @@ -484,7 +490,7 @@ function wg_earlyshellcmd_deinstall() { $shellcmd_pkg_cmds = array_map(fn($x) => $x['cmd'], $a_shellcmdsettings); - foreach ($wgg['shellcmdsettings'] as $shellcmd) { + foreach ($wgg['shellcmdentries'] as $shellcmd) { // Need to escape slashes from the path $escaped_cmd = preg_quote($shellcmd['cmd'], '/'); diff --git a/net/pfSense-pkg-WireGuard/files/usr/local/pkg/wireguard/wg_service.inc b/net/pfSense-pkg-WireGuard/files/usr/local/pkg/wireguard/wg_service.inc index eb7a0c61..0cec3534 100644 --- a/net/pfSense-pkg-WireGuard/files/usr/local/pkg/wireguard/wg_service.inc +++ b/net/pfSense-pkg-WireGuard/files/usr/local/pkg/wireguard/wg_service.inc @@ -115,7 +115,7 @@ function wg_service_fpm_stop() { $serialized_output = $ret_output = array(); // Invokes service stop with serialization flag so we can cleanly report back to the web frontend. - exec("{$wgg['wg_daemon']} stop serialize", $serialized_output); + exec("{$wgg['wg_daemon']} stop serialize", $serialized_output, $ret_code); if ($ret_output = unserialize($serialized_output[0])) { @@ -224,7 +224,7 @@ function wg_service_cli_start($serialize_output = true) { } - // Build all (null) the tunnels + // Build all (i.e. null) the tunnels $sync_all_status = wg_tunnel_sync(null); if ($sync_all_status['ret_code'] <> 0 ) { @@ -332,9 +332,6 @@ function wg_restart_extra_services() { // unbound services_unbound_configure(); - // pf - filter_configure(); - // This is currently just a best effort attempt... return 0; diff --git a/net/pfSense-pkg-WireGuard/files/usr/local/pkg/wireguard/wg_validate.inc b/net/pfSense-pkg-WireGuard/files/usr/local/pkg/wireguard/wg_validate.inc index 9c74f301..edfc8d22 100644 --- a/net/pfSense-pkg-WireGuard/files/usr/local/pkg/wireguard/wg_validate.inc +++ b/net/pfSense-pkg-WireGuard/files/usr/local/pkg/wireguard/wg_validate.inc @@ -30,11 +30,43 @@ require_once('wireguard/wg_api.inc'); wg_globals(); -// Validate the user's input and return error messages if not acceptable +/* + * Valildate a tunnel + * These validation checks should be in the same order as the UI for consistency + */ function wg_validate_tunnel_post($pconfig) { $input_errors = array(); + // Check enabled/disabled status + if (is_wg_tunnel_assigned($pconfig['name']) && (!isset($pconfig['enabled']) || ($pconfig['enabled'] != 'yes'))) { + + $wg_pfsense_if = wg_get_pfsense_interface_info($pconfig['name']); + + $input_errors[] = "Cannot disable {$pconfig['name']} while it is assigned to {$wg_pfsense_if['name']} ({$wg_pfsense_if['name']})."; + + } + + // Check listen port + $lport = $pconfig['listenport']; + + if (!empty($lport) && (!ctype_digit($lport) || !is_port($lport))) { + + $input_errors[] = "Invalid interface listen port ({$lport})."; + + } + + // Check keys + if (empty($pconfig['privatekey'])) { + + $input_errors[] = gettext('A private key must be specified.'); + + } elseif (!wg_is_valid_key($pconfig['privatekey'])) { + + $input_errors[] = gettext('The private key specified is not a valid WireGuard private key.'); + + } + // Assigned tunnels don't need these validation checks if (!is_wg_tunnel_assigned($pconfig['name'])) { @@ -47,7 +79,7 @@ function wg_validate_tunnel_post($pconfig) { if (!empty($address['address']) && !is_subnet($tmp_subnet)) { - $input_errors[] = gettext("{$tmp_subnet} is not a valid CIDR address"); + $input_errors[] = "Address {$tmp_subnet} is not a valid CIDR address."; } @@ -59,7 +91,7 @@ function wg_validate_tunnel_post($pconfig) { $ifname = strtoupper($conflict['if']); - $input_errors[] = gettext("{$address['address']} is already configured on this firewall: {$ifname} ({$conflict['ip_or_subnet']})"); + $input_errors[] = "Address {$address['address']} is already configured on this firewall. [ {$ifname} ({$conflict['ip_or_subnet']}) ]"; } } @@ -67,49 +99,43 @@ function wg_validate_tunnel_post($pconfig) { } - if (is_wg_tunnel_assigned($pconfig['name']) && (!isset($pconfig['enabled']) || ($pconfig['enabled'] != 'yes'))) { - - $input_errors[] = gettext('Cannot disable a WireGuard tunnel while it is assigned as an interface.'); - - } - - // Check listen port - $lport = $pconfig['listenport']; - - if (!empty($lport) && (!ctype_digit($lport) || !is_port($lport))) { + // Consumers expect an array + return $input_errors; - $input_errors[] = gettext('Invalid interface listen port.'); +} - } +/* + * Valildate a peer + * These validation checks should be in the same order as the UI for consistency + */ +function wg_validate_peer_post($pconfig) { - // Check keys - if (empty($pconfig['privatekey'])) { + $input_errors = array(); - $input_errors[] = gettext('A private key must be specified.'); + // Check remote endpoint + $ep = trim($pconfig['endpoint']); - } elseif (!wg_is_valid_key($pconfig['privatekey'])) { + if (!empty($ep) && !is_hostname($ep) && !is_ipaddr($ep)) { - $input_errors[] = gettext('The private key specified is not a valid WireGuard private key.'); + $input_errors[] = "Endpoint {$ep} must be a valid IPv4 or IPv6 address or hostname."; } - return $input_errors; - -} + // Check remote port + $rport = $pconfig['port']; -// Valildate a peer -function wg_validate_peer_post($pconfig) { + if (!empty($rport) && (!ctype_digit($rport) || !is_port($rport))) { - $input_errors = array(); + $input_errors[] = "Invalid peer remote port ({$rport})."; + } - $peer_idx = wg_get_peer_id($pconfig['publickey'], $pconfig['tun']); + // Check persistent keep alive + $keepalive = $pconfig['persistentkeepalive']; - // Check remote port - $rport = $pconfig['port']; + if (!empty($keepalive) && !is_numericint($keepalive)) { - if (!empty($rport) && (!ctype_digit($rport) || !is_port($rport))) { + $input_errors[] = "Invalid keep alive interval ({$keepalive})."; - $input_errors[] = gettext("Invalid remote port. ({$rport}})"); } // Check public key @@ -119,18 +145,20 @@ function wg_validate_peer_post($pconfig) { } elseif (!wg_is_valid_key($pconfig['publickey'])) { - $input_errors[] = gettext("The public key ({$pconfig['publickey']}) is not a valid WireGuard public key."); + $input_errors[] = "The public key ({$pconfig['publickey']}) is not a valid WireGuard public key."; } elseif (!empty($pconfig['tun'])) { $peers = wg_get_tunnel_peers($pconfig['tun']); + $peer_idx = wg_get_peer_id($pconfig['publickey'], $pconfig['tun']); + foreach ($peers as $peer) { // We don't want to allow duplicate public keys to be assigned on the same tunnel if (($peer['publickey'] == $pconfig['publickey']) && ($peer['index'] != $peer_idx)) { - $input_errors[] = gettext("The public key ({$pconfig['publickey']}) is already assigned to a peer on this tunnel ({$pconfig['tun']})."); + $input_errors[] = "The public key ({$pconfig['publickey']}) is already assigned to a peer on this tunnel ({$pconfig['tun']})."; break; @@ -140,15 +168,7 @@ function wg_validate_peer_post($pconfig) { } - $ep = trim($pconfig['endpoint']); - - if (!empty($ep) && !is_hostname($ep) && !is_ipaddr($ep)) { - - $input_errors[] = gettext('Endpoint must be a valid IPv4 or IPv6 adress or hostname.'); - - } - - // Allowed IPs + // Check allowed ips if (!empty($pconfig['allowedips']['row']) && is_array($pconfig['allowedips']['row'])) { foreach ($pconfig['allowedips']['row'] as $row) { @@ -159,7 +179,7 @@ function wg_validate_peer_post($pconfig) { if (!empty($row['address']) && !is_subnet($tmp_subnet)) { - $input_errors[] = gettext("Address {$tmp_subnet} is not a valid IPv4 or IPv6 CIDR subnet address."); + $input_errors[] = "Address {$tmp_subnet} is not a valid IPv4 or IPv6 CIDR subnet address."; } @@ -167,6 +187,7 @@ function wg_validate_peer_post($pconfig) { } + // Consumers expect an array return $input_errors; } diff --git a/net/pfSense-pkg-WireGuard/files/usr/local/www/wg/status_wireguard.php b/net/pfSense-pkg-WireGuard/files/usr/local/www/wg/status_wireguard.php index 43c1c9df..d3a33d20 100644 --- a/net/pfSense-pkg-WireGuard/files/usr/local/www/wg/status_wireguard.php +++ b/net/pfSense-pkg-WireGuard/files/usr/local/www/wg/status_wireguard.php @@ -35,6 +35,7 @@ // WireGuard includes require_once('wireguard/wg.inc'); require_once('wireguard/wg_guiconfig.inc'); +require_once('wireguard/wg_service.inc'); global $wgg; @@ -97,8 +98,6 @@ $a_devices = wg_status(); -if (!empty($a_devices)): - ?>
@@ -118,10 +117,12 @@ + $device): ?> - @@ -129,20 +130,16 @@ - - + + + + - - 0): -?> @@ -156,7 +153,9 @@ 0): + + foreach($device['peers'] as $peer): ?> - + + + + + +
@@ -164,43 +163,51 @@ + +
+ - + + + + +
- -