diff options
author | Phil Davis <phil.davis@inf.org> | 2017-01-11 07:24:39 +0545 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-11 07:24:39 +0545 |
commit | 753280bb6c75fb3aa5a1fcc2ef65640faa78340d (patch) | |
tree | 3e3abc677eabc41bb8f99c3d3c2b16b5cf76ee74 /src | |
parent | 9187d6f7ea47bd44a9f4908f916c507419986c52 (diff) | |
parent | 6a9a75958c21ab3011ea6d52c00d5e370c08cf89 (diff) | |
download | pfsense-753280bb6c75fb3aa5a1fcc2ef65640faa78340d.zip pfsense-753280bb6c75fb3aa5a1fcc2ef65640faa78340d.tar.gz |
Merge branch 'master' into sysprvwarn2
Diffstat (limited to 'src')
120 files changed, 1995 insertions, 1080 deletions
diff --git a/src/etc/inc/captiveportal.inc b/src/etc/inc/captiveportal.inc index 31b7149..449d75c 100644 --- a/src/etc/inc/captiveportal.inc +++ b/src/etc/inc/captiveportal.inc @@ -347,15 +347,10 @@ EOD; @unlink("{$g['varetc_path']}/captiveportal-{$cpzone}-error.html"); @unlink("{$g['varetc_path']}/captiveportal-{$cpzone}-logout.html"); - captiveportal_radius_stop_all(); + captiveportal_radius_stop_all(10); // NAS-Request captiveportal_filterdns_configure(); - /* send Accounting-Off to server */ - if (!platform_booting()) { - captiveportal_send_server_accounting(true); - } - /* remove old information */ unlink_if_exists("{$g['vardb_path']}/captiveportal{$cpzone}.db"); unlink_if_exists("{$g['vardb_path']}/captiveportal_radius_{$cpzone}.db"); @@ -1086,10 +1081,24 @@ function captiveportal_disconnect_client($sessionid, $term_cause = 1, $logoutRea function captiveportal_disconnect_all($term_cause = 6, $logoutReason = "DISCONNECT") { global $g, $config, $cpzone, $cpzoneid; + /* check if we're pruning old entries and eventually wait */ + $rcprunelock = try_lock("rcprunecaptiveportal{$cpzone}", 60); + + /* if we still don't have the lock, unlock forcefully and take it */ + if (!$rcprunelock) { + log_error("CP zone ${cpzone}: could not obtain the lock for more than 60 seconds, lock taken forcefully to disconnect all users"); + unlock_force("rcprunecaptiveportal{$cpzone}"); + $rcprunelock = lock("rcprunecaptiveportal{$cpzone}", LOCK_EX); + } + $radiussrvs = captiveportal_get_radius_servers(); $cpdb = captiveportal_read_db(); - $unsetindexes = array(); + /* remove immediately the active users from the database to avoid races */ + $unsetindexes = array_column($cpdb,5); + if (!empty($unsetindexes)) { + captiveportal_remove_entries($unsetindexes); + } foreach ($cpdb as $cpentry) { if (empty($cpentry[11])) { @@ -1099,42 +1108,44 @@ function captiveportal_disconnect_all($term_cause = 6, $logoutReason = "DISCONNE captiveportal_disconnect($cpentry, $radiusservers, $term_cause); captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], $logoutReason); - $unsetindexes[] = $cpentry[5]; } unset($cpdb); - if (!empty($unsetindexes)) { - captiveportal_remove_entries($unsetindexes); - } + unlock($rcprunelock); } /* send RADIUS acct stop for all current clients */ -function captiveportal_radius_stop_all() { - global $config, $cpzone; +function captiveportal_radius_stop_all($term_cause = 6, $logoutReason = "DISCONNECT") { + global $g, $config, $cpzone, $cpzoneid; - if (!isset($config['captiveportal'][$cpzone]['radacct_enable'])) { - return; + $cpdb = captiveportal_read_db(); + + $radacct = isset($config['captiveportal'][$cpzone]['radacct_enable']) ? true : false; + if ($radacct) { + $radiusservers = captiveportal_get_radius_servers(); } - $radiusservers = captiveportal_get_radius_servers(); - if (!empty($radiusservers)) { - $cpdb = captiveportal_read_db(); - foreach ($cpdb as $cpentry) { - if (empty($cpentry[11])) { - $cpentry[11] = 'first'; - } - if (!empty($radiusservers[$cpentry[11]])) { - RADIUS_ACCOUNTING_STOP($cpentry[1], // ruleno - $cpentry[4], // username - $cpentry[5], // sessionid - $cpentry[0], // start time - $radiusservers[$cpentry[11]], - $cpentry[2], // clientip - $cpentry[3], // clientmac - 7); // Admin Reboot + foreach ($cpdb as $cpentry) { + if ($radacct) { + if (!empty($radiusservers)) { + if (empty($cpentry[11])) { + $cpentry[11] = 'first'; + } + if (!empty($radiusservers[$cpentry[11]])) { + RADIUS_ACCOUNTING_STOP($cpentry[1], // ruleno + $cpentry[4], // username + $cpentry[5], // sessionid + $cpentry[0], // start time + $radiusservers[$cpentry[11]], + $cpentry[2], // clientip + $cpentry[3], // clientmac + $term_cause); + } } } + captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], $logoutReason); } + unset($cpdb); } function captiveportal_passthrumac_configure_entry($macent, $pipeinrule = false) { diff --git a/src/etc/inc/dyndns.class b/src/etc/inc/dyndns.class index 8f1dcd9..d0d27cf 100644 --- a/src/etc/inc/dyndns.class +++ b/src/etc/inc/dyndns.class @@ -98,7 +98,7 @@ * SelfHost - Last Tested: 26 December 2011 * Amazon Route 53 - Last Tested: 30 August 2016 * DNS-O-Matic - Last Tested: 9 September 2010 - * CloudFlare - Last Tested: 17 July 2016 + * CloudFlare - Last Tested: 05 September 2016 * CloudFlare IPv6 - Last Tested: 17 July 2016 * Eurodns - Last Tested: 27 June 2013 * GratisDNS - Last Tested: 15 August 2012 @@ -139,6 +139,7 @@ var $_FQDN; var $_dnsIP; var $_dnsWildcard; + var $_dnsProxied; var $_dnsMX; var $_dnsBackMX; var $_dnsServer; @@ -170,7 +171,7 @@ * - $For custom requests, $dnsUpdateURL is parsed for '%IP%', which is replaced with the new IP. */ function updatedns ($dnsService = '', $dnsHost = '', $dnsDomain = '', $dnsUser = '', $dnsPass = '', - $dnsWildcard = 'OFF', $dnsMX = '', $dnsIf = '', $dnsBackMX = '', + $dnsWildcard = 'OFF', $dnsProxied = false, $dnsMX = '', $dnsIf = '', $dnsBackMX = '', $dnsServer = '', $dnsPort = '', $dnsUpdateURL = '', $forceUpdate = false, $dnsZoneID ='', $dnsTTL='', $dnsResultMatch = '', $dnsRequestIf = '', $dnsID = '', $dnsVerboseLog = false, $curlIpresolveV4 = false, $curlSslVerifypeer = true) { @@ -247,6 +248,7 @@ $this->_dnsServer = $dnsServer; $this->_dnsPort = $dnsPort; $this->_dnsWildcard = $dnsWildcard; + $this->_dnsProxied = $dnsProxied; $this->_dnsMX = $dnsMX; $this->_dnsZoneID = $dnsZoneID; $this->_dnsTTL = $dnsTTL; @@ -359,8 +361,7 @@ curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); } - if ($this->_dnsService != 'ods' and $this->_dnsService != 'route53 ') { - curl_setopt($ch, CURLOPT_HEADER, 1); + if ($this->_dnsService != 'ods') { curl_setopt($ch, CURLOPT_USERAGENT, $this->_UserAgent); curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($ch, CURLOPT_INTERFACE, 'if!' . $realparentif); @@ -713,6 +714,7 @@ $hostData = array( "content" => "{$this->_dnsIP}", "type" => "{$recordType}", + "proxied" => $this->_dnsProxied, "name" => "{$this->_dnsHost}" ); $data_json = json_encode($hostData); @@ -774,7 +776,6 @@ $server = 'https://api.dnsimple.com/v1/domains/'; $token = $this->_dnsUser . ':' . $this->_dnsPass; $jsondata = '{"record":{"content":"' . $this->_dnsIP . '","ttl":"' . $this->_dnsTTL . '"}}'; - curl_setopt($ch, CURLOPT_HEADER, 1); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT"); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Accept: application/json', 'Content-Type: application/json', 'X-DNSimple-Token: ' . $token)); curl_setopt($ch, CURLOPT_URL, $server . $this->_dnsHost . '/records/' . $this->_dnsZoneID); @@ -821,6 +822,7 @@ break; } if ($this->_dnsService != 'ods') { + curl_setopt($ch, CURLOPT_HEADER, 1); $response = curl_exec($ch); $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); $header = substr($response, 0, $header_size); @@ -834,7 +836,7 @@ * Private Function (added 12 July 2005) [beta] * Retrieve Update Status */ - function _checkStatus($ch, $data) { + function _checkStatus($ch, $data, $header) { if ($this->_dnsVerboseLog) { log_error(sprintf(gettext('Dynamic DNS %1$s (%2$s): _checkStatus() starting.'), $this->_dnsService, $this->_FQDN)); } diff --git a/src/etc/inc/globals.inc b/src/etc/inc/globals.inc index 1bb734c..ed635c3 100644 --- a/src/etc/inc/globals.inc +++ b/src/etc/inc/globals.inc @@ -71,7 +71,7 @@ $g = array( "disablecrashreporter" => false, "crashreporterurl" => "https://crashreporter.pfsense.org/crash_reporter.php", "debug" => false, - "latest_config" => "16.0", + "latest_config" => "16.1", "minimum_ram_warning" => "101", "minimum_ram_warning_text" => "128 MB", "wan_interface_name" => "wan", diff --git a/src/etc/inc/gwlb.inc b/src/etc/inc/gwlb.inc index b240c12..fdb0151 100644 --- a/src/etc/inc/gwlb.inc +++ b/src/etc/inc/gwlb.inc @@ -466,6 +466,8 @@ function return_gateways_status($byname = false) { $status[$target]['loss'] = ""; $status[$target]['status'] = "none"; } + + $status[$target]['monitor_disable'] = true; } return($status); } diff --git a/src/etc/inc/interfaces.inc b/src/etc/inc/interfaces.inc index c1fe817..ef9af77 100644 --- a/src/etc/inc/interfaces.inc +++ b/src/etc/inc/interfaces.inc @@ -3868,6 +3868,13 @@ function interface_dhcpv6_configure($interface = "wan", $wancfg) { $wanif = get_real_interface($interface, "inet6"); $dhcp6cconf = ""; + if (!empty($config['system']['global-v6duid'])) { + // Write the DUID file + if(!write_dhcp6_duid($config['system']['global-v6duid'])) { + log_error(gettext("Failed to write user DUID file!")); + } + } + if ($wancfg['adv_dhcp6_config_file_override']) { // DHCP6 Config File Override $dhcp6cconf = DHCP6_Config_File_Override($wancfg, $wanif); diff --git a/src/etc/inc/ipsec.inc b/src/etc/inc/ipsec.inc index c16e854..5b4cbcc 100644 --- a/src/etc/inc/ipsec.inc +++ b/src/etc/inc/ipsec.inc @@ -819,4 +819,21 @@ function ipsec_new_reqid() { return $keyid; } +function ipsec_get_loglevels() { + global $config, $ipsec_log_cats; + $def_loglevel = '1'; + + $levels = array(); + + foreach (array_keys($ipsec_log_cats) as $cat) { + if (isset($config['ipsec']['logging'][$cat])) { + $levels[$cat] = $config['ipsec']['logging'][$cat]; + } elseif (in_array($cat, array('ike', 'chd', 'cfg'))) { + $levels[$cat] = "2"; + } else { + $levels[$cat] = $def_loglevel; + } + } + return $levels; +} ?> diff --git a/src/etc/inc/openvpn.inc b/src/etc/inc/openvpn.inc index 727a4af..abef6a8 100644 --- a/src/etc/inc/openvpn.inc +++ b/src/etc/inc/openvpn.inc @@ -43,7 +43,10 @@ $openvpn_prots = array( ); global $openvpn_dev_mode; -$openvpn_dev_mode = array("tun", "tap"); +$openvpn_dev_mode = array( + "tun" => "tun - Layer 3 Tunnel Mode", + "tap" => "tap - Layer 2 Tap Mode" +); global $openvpn_verbosity_level; $openvpn_verbosity_level = array( @@ -119,11 +122,16 @@ $openvpn_client_modes = array( global $openvpn_compression_modes; $openvpn_compression_modes = array( - '' => gettext("No Preference"), - 'noadapt' => gettext("No Preference and Adaptive Compression Disabled"), - 'no' => gettext("Disabled - No Compression"), - 'adaptive' => gettext("Enabled with Adaptive Compression"), - 'yes' => gettext("Enabled without Adaptive Compression")); + '' => gettext("Omit Preference (Use OpenVPN Default)"), + 'lz4' => gettext("LZ4 Compression [compress lz4]"), + 'lz4-v2' => gettext("LZ4 Comression v2 [compress lz4-v2]"), + 'lzo' => gettext("LZO Compression [compress lzo, equivalent to comp-lzo yes for compatibility]"), + 'stub' => gettext("Enable Compression (stub) [compress]"), + 'noadapt' => gettext("Omit Preference, + Disable Adaptive LZO Compression [Legacy style, comp-noadapt]"), + 'adaptive' => gettext("Adaptive LZO Compression [Legacy style, comp-lzo adaptive]"), + 'yes' => gettext("LZO Compression [Legacy style, comp-lzo yes]"), + 'no' => gettext("No LZO Compression [Legacy style, comp-lzo no]"), +); global $openvpn_topologies; $openvpn_topologies = array( @@ -132,6 +140,12 @@ $openvpn_topologies = array( // 'p2p => gettext("Peer to Peer -- One IP address per client peer-to-peer style. Does not work on Windows.") ); +global $openvpn_tls_modes; +$openvpn_tls_modes = array( + 'auth' => gettext("TLS Authentication"), + 'crypt' => gettext("TLS Encryption and Authentication") +); + function openvpn_build_mode_list() { global $openvpn_server_modes; @@ -335,37 +349,38 @@ function openvpn_vpnid_next() { function openvpn_port_used($prot, $interface, $port, $curvpnid = 0) { global $config; + $ovpn_settings = array(); if (is_array($config['openvpn']['openvpn-server'])) { - foreach ($config['openvpn']['openvpn-server'] as & $settings) { - if (isset($settings['disable'])) { - continue; - } - - if ($curvpnid != 0 && $curvpnid == $settings['vpnid']) { - continue; - } + $ovpn_settings = $config['openvpn']['openvpn-server']; + } + if (is_array($config['openvpn']['openvpn-client'])) { + $ovpn_settings = array_merge($ovpn_settings, + $config['openvpn']['openvpn-client']); + } - if ($port == $settings['local_port'] && $prot == $settings['protocol'] && - ($interface == $settings['interface'] || $interface == "any" || $settings['interface'] == "any")) { - return $settings['vpnid']; - } + foreach ($ovpn_settings as $settings) { + if (isset($settings['disable'])) { + continue; } - } - if (is_array($config['openvpn']['openvpn-client'])) { - foreach ($config['openvpn']['openvpn-client'] as & $settings) { - if (isset($settings['disable'])) { - continue; - } + if ($curvpnid != 0 && $curvpnid == $settings['vpnid']) { + continue; + } - if ($curvpnid != 0 && $curvpnid == $settings['vpnid']) { - continue; - } + /* (TCP|UDP)(4|6) does not conflict unless interface is any */ + if (($interface != "any" && $settings['interface'] != "any") && + (strlen($prot) == 4) && + (strlen($settings['protocol']) == 4) && + substr($prot,0,3) == substr($settings['protocol'],0,3) && + substr($prot,3,1) != substr($settings['protocol'],3,1)) { + continue; + } - if ($port == $settings['local_port'] && $prot == $settings['protocol'] && - ($interface == $settings['interface'] || $interface == "any" || $settings['interface'] == "any")) { - return $settings['vpnid']; - } + if ($port == $settings['local_port'] && + substr($prot,0,3) == substr($settings['protocol'],0,3) && + ($interface == $settings['interface'] || + $interface == "any" || $settings['interface'] == "any")) { + return $settings['vpnid']; } } @@ -638,7 +653,7 @@ function openvpn_add_keyfile(& $data, & $conf, $mode_id, $directive, $opt = "") } function openvpn_reconfigure($mode, $settings) { - global $g, $config, $openvpn_tls_server_modes; + global $g, $config, $openvpn_tls_server_modes, $openvpn_dh_lengths; if (empty($settings)) { return; @@ -866,7 +881,7 @@ function openvpn_reconfigure($mode, $settings) { // configure user auth modes switch ($settings['mode']) { case 'server_user': - $conf .= "client-cert-not-required\n"; + $conf .= "verify-client-cert none\n"; case 'server_tls_user': /* username-as-common-name is not compatible with server-bridge */ if (stristr($conf, "server-bridge") === false) { @@ -1072,21 +1087,58 @@ function openvpn_reconfigure($mode, $settings) { openvpn_add_keyfile($crl['text'], $conf, $mode_id, "crl-verify"); } if ($settings['tls']) { - if ($mode == "server") { - $tlsopt = 0; + if ($settings['tls_type'] == "crypt") { + $tls_directive = "tls-crypt"; + $tlsopt = ""; } else { - $tlsopt = 1; + $tls_directive = "tls-auth"; + if ($mode == "server") { + $tlsopt = 0; + } else { + $tlsopt = 1; + } } - openvpn_add_keyfile($settings['tls'], $conf, $mode_id, "tls-auth", $tlsopt); + openvpn_add_keyfile($settings['tls'], $conf, $mode_id, $tls_directive, $tlsopt); } + + /* NCP support. If it is not set, assume enabled since that is OpenVPN's default. */ + if ($settings['ncp_enable'] == "disabled") { + $conf .= "ncp-disable\n"; + } else { + /* If the ncp-ciphers list is empty, don't specify a list so OpenVPN's default will be used. */ + if (!empty($settings['ncp-ciphers'])) { + $conf .= "ncp-ciphers " . str_replace(',', ':', $settings['ncp-ciphers']) . "\n"; + } + } + break; } - if (!empty($settings['compression'])) { - if ($settings['compression'] == "noadapt") { - $conf .= "comp-noadapt\n"; - } else { - $conf .= "comp-lzo {$settings['compression']}\n"; + $compression = ""; + switch ($settings['compression']) { + case 'lz4': + case 'lz4-v2': + case 'lzo': + case 'stub': + $compression .= "compress {$settings['compression']}"; + break; + case 'noadapt': + $compression .= "comp-noadapt"; + break; + case 'adaptive': + case 'yes': + case 'no': + $compression .= "comp-lzo {$settings['compression']}"; + break; + default: + /* Add nothing to the configuration */ + break; + } + + if (!empty($compression)) { + $conf .= "{$compression}\n"; + if ($settings['compression_push']) { + $conf .= "push \"{$compression}\"\n"; } } @@ -1205,19 +1257,12 @@ function openvpn_restart($mode, $settings) { unlock($lockhandle); } -function openvpn_delete($mode, & $settings) { +function openvpn_delete($mode, $settings) { global $g, $config; $vpnid = $settings['vpnid']; $mode_id = $mode.$vpnid; - if (isset($settings['dev_mode'])) { - $tunname = "{$settings['dev_mode']}{$vpnid}"; - } else { - /* defaults to tun */ - $tunname = "tun{$vpnid}"; - } - if ($mode == "server") { $devname = "ovpns{$vpnid}"; } else { @@ -1236,11 +1281,8 @@ function openvpn_delete($mode, & $settings) { posix_kill($pid, SIGTERM); } - /* remove the device from the openvpn group */ - mwexec("/sbin/ifconfig " . escapeshellarg($devname) . " -group openvpn"); - - /* restore the original adapter name */ - mwexec("/sbin/ifconfig " . escapeshellarg($devname) . " name " . escapeshellarg($tunname)); + /* destroy the device */ + pfSense_interface_destroy($devname); /* remove the configuration files */ @array_map('unlink', glob("{$g['varetc_path']}/openvpn/{$mode_id}.*")); @@ -1314,6 +1356,13 @@ function openvpn_resync_csc(& $settings) { $csc_conf .= "ifconfig-push {$clientip} {$serverip}\n"; } } + + if (!empty($serversettings['tunnel_networkv6']) && !empty($settings['tunnel_networkv6'])) { + list($ipv6, $prefix) = explode('/', trim($serversettings['tunnel_networkv6'])); + list($ipv6_1, $ipv6_2) = openvpn_get_interface_ipv6($ipv6, $prefix); + $csc_conf .= "ifconfig-ipv6-push {$settings['tunnel_networkv6']} {$ipv6_1}\n"; + } + file_put_contents($csc_path, $csc_conf); chown($csc_path, 'nobody'); chgrp($csc_path, 'nobody'); diff --git a/src/etc/inc/pfsense-utils.inc b/src/etc/inc/pfsense-utils.inc index aca0e90..847826b 100644 --- a/src/etc/inc/pfsense-utils.inc +++ b/src/etc/inc/pfsense-utils.inc @@ -2395,13 +2395,12 @@ function process_alias_urltable($name, $type, $url, $freq, $forceupdate=false, $ touch($urltable_filename); } - /* If this backup is still there on a full install, but we aren't going to use ram disks, remove the archive since this is a transition. */ - if (!isset($config['system']['use_mfs_tmpvar'])) { - unlink_if_exists("{$g['cf_conf_path']}/RAM_Disk_Store{$urltable_filename}.tgz"); - } else { - /* Update the RAM disk store with the new/updated table file. */ - mwexec("cd / && /usr/bin/tar -czf \"{$g['cf_conf_path']}/RAM_Disk_Store{$urltable_filename}.tgz\" -C / \"{$urltable_filename}\""); + /* Remove existing archive and create an up to date archive if RAM disk is enabled. */ + unlink_if_exists("{$g['cf_conf_path']}/RAM_Disk_Store/{$name}.txt.tgz"); + if (isset($config['system']['use_mfs_tmpvar'])) { + mwexec("/usr/bin/tar -czf " . escapeshellarg("{$g['cf_conf_path']}/RAM_Disk_Store/{$name}.txt.tgz") . " -C / " . escapeshellarg($urltable_filename)); } + unlink_if_exists($tmp_urltable_filename); } else { if (!$validateonly) { @@ -3154,38 +3153,6 @@ function pkg_call_plugins($plugin_type, $plugin_params) { return $results; } -function restore_aliastables() { - global $g, $config; - - $dbpath = "{$g['vardb_path']}/aliastables/"; - - /* restore the alias tables, if we have them */ - $files = glob("{$g['cf_conf_path']}/RAM_Disk_Store{$dbpath}*.tgz"); - if (count($files)) { - echo "Restoring alias tables..."; - foreach ($files as $file) { - if (file_exists($file)) { - $aliastablesrestore = ""; - $aliastablesreturn = ""; - exec("cd /;LANG=C /usr/bin/tar -xzf {$file} 2>&1", $aliastablesrestore, $aliastablesreturn); - $aliastablesrestore = implode(" ", $aliastablesrestore); - if ($aliastablesreturn <> 0) { - log_error(sprintf(gettext('Alias table restore failed exited with %1$s, the error is: %2$s %3$s%4$s'), $aliastablesreturn, $aliastablesrestore, $file, "\n")); - } else { - log_error(sprintf(gettext('Alias table restore succeeded exited with %1$s, the result is: %2$s %3$s%4$s'), $aliastablesreturn, $aliastablesrestore, $dbpath.basename($file, ".tgz"), "\n")); - } - } - /* If this backup is still there on a full install, but we aren't going to use ram disks, remove the archive since this is a transition. */ - if (!isset($config['system']['use_mfs_tmpvar'])) { - unlink_if_exists("{$file}"); - } - } - echo "done.\n"; - return true; - } - return false; -} - // Convert IPv6 addresses to lower case function addrtolower($ip) { if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false) { diff --git a/src/etc/inc/priv.inc b/src/etc/inc/priv.inc index c430ced..58dfe09 100644 --- a/src/etc/inc/priv.inc +++ b/src/etc/inc/priv.inc @@ -182,7 +182,7 @@ function get_user_privdesc(& $user) { return $privs; } -function isAllowed($username, $page) { +function isAdminUID($username) { global $_SESSION; if (!isset($username)) { @@ -199,6 +199,20 @@ function isAllowed($username, $page) { } } + return false; +} + +function isAllowed($username, $page) { + global $_SESSION; + + if (!isset($username)) { + return false; + } + + if (isAdminUID($username)) { + return true; + } + /* user privilege access check */ if (cmp_page_matches($page, $_SESSION['page-match'])) { return true; @@ -207,7 +221,6 @@ function isAllowed($username, $page) { return false; } - function isAllowedPage($page) { global $_SESSION; @@ -218,14 +231,8 @@ function isAllowedPage($page) { return false; } - /* admin/root access check */ - $user = getUserEntry($username); - if (isset($user)) { - if (isset($user['uid'])) { - if ($user['uid'] == 0) { - return true; - } - } + if (isAdminUID($username)) { + return true; } /* user privilege access check */ @@ -269,12 +276,33 @@ function getAllowedPages($username, &$attributes = array()) { if ($_SESSION['remoteauth']) { $authcfg = auth_get_authserver($config['system']['webgui']['authmode']); + // cache auth results for a short time to ease load on auth services & logs + if (isset($config['system']['webgui']['auth_refresh_time'])) { + $recheck_time = $config['system']['webgui']['auth_refresh_time']; + } else { + $recheck_time = 30; + } // obtain ldap groups if we are in ldap mode if ($authcfg['type'] == "ldap") { - $allowed_groups = @ldap_get_groups($username, $authcfg); + if ( isset($_SESSION["ldap_allowed_groups"]) && + ( time() <= $_SESSION["auth_check_time"]+ $recheck_time) ) { + $allowed_groups = $_SESSION["ldap_allowed_groups"]; + } else { + $allowed_groups = @ldap_get_groups($username, $authcfg); + $_SESSION["ldap_allowed_groups"] = $allowed_groups; + $_SESSION["auth_check_time"] = time(); + } } elseif ($authcfg['type'] == "radius") { - $allowed_groups = @radius_get_groups($attributes); + if ( isset($_SESSION["radius_allowed_groups"]) && + (time() <= $_SESSION["auth_check_time"] + $recheck_time) ) { + $allowed_groups = $_SESSION["radius_allowed_groups"]; + } else { + $allowed_groups = @radius_get_groups($attributes); + $_SESSION["radius_allowed_groups"] = $allowed_groups; + $_SESSION["auth_check_time"] = time(); + } } + } if (!$allowed_groups) { // search for a local user by name diff --git a/src/etc/inc/rrd.inc b/src/etc/inc/rrd.inc index 183f84a..cf3a1a9 100644 --- a/src/etc/inc/rrd.inc +++ b/src/etc/inc/rrd.inc @@ -34,54 +34,6 @@ function dump_rrd_to_xml($rrddatabase, $xmldumpfile) { return($dumpret); } -function restore_rrd() { - global $g, $config; - - $rrddbpath = "{$g['vardb_path']}/rrd/"; - $rrdtool = "/usr/bin/nice -n20 /usr/local/bin/rrdtool"; - - $rrdrestore = ""; - $rrdreturn = ""; - if (file_exists("{$g['cf_conf_path']}/rrd.tgz") && isset($config['system']['use_mfs_tmpvar'])) { - foreach (glob("{$rrddbpath}/*.xml") as $xml_file) { - @unlink($xml_file); - } - unset($rrdrestore); - $_gb = exec("cd /;LANG=C /usr/bin/tar -tf {$g['cf_conf_path']}/rrd.tgz", $rrdrestore, $rrdreturn); - if ($rrdreturn != 0) { - log_error(sprintf(gettext('RRD restore failed exited with %1$s, the error is: %2$s'), $rrdreturn, $rrdrestore)); - return; - } - foreach ($rrdrestore as $xml_file) { - $rrd_file = '/' . substr($xml_file, 0, -4) . '.rrd'; - if (file_exists("{$rrd_file}")) { - @unlink($rrd_file); - } - file_put_contents("{$g['tmp_path']}/rrd_restore", $xml_file); - $_gb = exec("cd /;LANG=C /usr/bin/tar -xf {$g['cf_conf_path']}/rrd.tgz -T {$g['tmp_path']}/rrd_restore"); - if (!file_exists("/{$xml_file}")) { - log_error(sprintf(gettext("Could not extract %s RRD xml file from archive!"), $xml_file)); - continue; - } - $_gb = exec("$rrdtool restore -f '/{$xml_file}' '{$rrd_file}'", $output, $status); - if ($status) { - log_error(sprintf(gettext("rrdtool restore -f '%1\$s' '%2\$s' failed returning %3\$s."), $xml_file, $rrd_file, $status)); - continue; - } - unset($output); - @unlink("/{$xml_file}"); - } - unset($rrdrestore); - @unlink("{$g['tmp_path']}/rrd_restore"); - /* If this backup is still there on a full install, but we aren't going to use ram disks, remove the archive since this is a transition. */ - if (!isset($config['system']['use_mfs_tmpvar'])) { - unlink_if_exists("{$g['cf_conf_path']}/rrd.tgz"); - } - return true; - } - return false; -} - function create_new_rrd($rrdcreatecmd) { $rrdcreateoutput = array(); $rrdcreatereturn = 0; @@ -281,10 +233,6 @@ function enable_rrd_graphing() { } chown($rrddbpath, "nobody"); - if (platform_booting()) { - restore_rrd(); - } - /* db update script */ $rrdupdatesh = "#!/bin/sh\n"; $rrdupdatesh .= "\n"; @@ -309,14 +257,6 @@ function enable_rrd_graphing() { } } - if (platform_booting()) { - if (!is_dir($rrddbpath)) { - mkdir($rrddbpath, 0775); - } - - @chown($rrddbpath, "nobody"); - } - /* process all real and pseudo interfaces */ foreach ($ifdescrs as $ifname => $ifdescr) { $temp = get_real_interface($ifname); diff --git a/src/etc/inc/services.inc b/src/etc/inc/services.inc index ffabbbd..45177d2 100644 --- a/src/etc/inc/services.inc +++ b/src/etc/inc/services.inc @@ -263,10 +263,22 @@ function services_radvd_configure($blacklist = array()) { $radvdconf .= "\tRDNSS {$dnsstring} { };\n"; } } + + $searchlist = array(); + $domainsearchlist = explode(';', $dhcpv6ifconf['radomainsearchlist']); + foreach ($domainsearchlist as $sd) { + $sd = trim($sd); + if (is_hostname($sd)) { + $searchlist[] = $sd; + } + } + if (count($searchlist) > 0) { + $searchliststring = trim(implode(" ", $searchlist)); + } if (!empty($dhcpv6ifconf['domain'])) { - $radvdconf .= "\tDNSSL {$dhcpv6ifconf['domain']} { };\n"; + $radvdconf .= "\tDNSSL {$dhcpv6ifconf['domain']} {$searchliststring} { };\n"; } elseif (!empty($config['system']['domain'])) { - $radvdconf .= "\tDNSSL {$config['system']['domain']} { };\n"; + $radvdconf .= "\tDNSSL {$config['system']['domain']} {$searchliststring} { };\n"; } $radvdconf .= "};\n"; } @@ -468,23 +480,6 @@ function services_dhcpdv4_configure() { } } - if (platform_booting()) { - /* restore the leases, if we have them */ - if (file_exists("{$g['cf_conf_path']}/dhcpleases.tgz")) { - $dhcprestore = ""; - $dhcpreturn = ""; - exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/dhcpleases.tgz 2>&1", $dhcprestore, $dhcpreturn); - $dhcprestore = implode(" ", $dhcprestore); - if ($dhcpreturn <> 0) { - log_error(sprintf(gettext('DHCP leases restore failed exited with %1$s, the error is: %2$s%3$s'), $dhcpreturn, $dhcprestore, "\n")); - } - } - /* If this backup is still there on a full install, but we aren't going to use ram disks, remove the archive since this is a transition. */ - if (!isset($config['system']['use_mfs_tmpvar'])) { - unlink_if_exists("{$g['cf_conf_path']}/dhcpleases.tgz"); - } - } - $syscfg = $config['system']; if (!is_array($config['dhcpd'])) { $config['dhcpd'] = array(); @@ -1265,22 +1260,6 @@ function services_dhcpdv6_configure($blacklist = array()) { return 0; } - /* restore the leases, if we have them */ - if (platform_booting() && - isset($config['system']['use_mfs_tmpvar']) && - file_exists("{$g['cf_conf_path']}/dhcp6leases.tgz")) { - $dhcprestore = ""; - $dhcpreturn = ""; - exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/dhcp6leases.tgz 2>&1", - $dhcprestore, $dhcpreturn); - $dhcprestore = implode(" ", $dhcprestore); - if ($dhcpreturn <> 0) { - log_error(sprintf(gettext( - 'DHCP leases v6 restore failed exited with %1$s, the error is: %2$s'), - $dhcpreturn, $dhcprestore)); - } - } - $syscfg = $config['system']; if (!is_array($config['dhcpdv6'])) { $config['dhcpdv6'] = array(); @@ -1961,6 +1940,7 @@ function services_dyndns_configure_client($conf) { $dnsUser = $conf['username'], $dnsPass = $conf['password'], $dnsWildcard = $conf['wildcard'], + $dnsProxied = $conf['proxied'], $dnsMX = $conf['mx'], $dnsIf = "{$conf['interface']}", $dnsBackMX = NULL, @@ -2457,7 +2437,8 @@ begemotSnmpdModulePath."pf" = "/usr/lib/snmp_pf.so" EOD; } - if (isset($config['snmpd']['modules']['hostres'])) { + if (isset($config['snmpd']['modules']['hostres']) + && !(($specplatform['name'] == 'VMware') && (file_exists('/dev/cd0')))) { $snmpdconf .= <<<EOD begemotSnmpdModulePath."hostres" = "/usr/lib/snmp_hostres.so" @@ -2509,155 +2490,220 @@ function services_dnsupdate_process($int = "", $updatehost = "", $forced = false } /* Dynamic DNS updating active? */ - if (is_array($config['dnsupdates']['dnsupdate'])) { - $notify_text = ""; - $gwgroups = return_gateway_groups_array(); - foreach ($config['dnsupdates']['dnsupdate'] as $i => $dnsupdate) { - if (!isset($dnsupdate['enable'])) { - continue; - } - /* - * If it's using a gateway group, check if interface is - * the active gateway for that group - */ - $group_int = ''; - if (is_array($gwgroups[$dnsupdate['interface']])) { - if (!empty($gwgroups[$dnsupdate['interface']][0]['vip'])) { - $group_int = $gwgroups[$dnsupdate['interface']][0]['vip']; - } else { - $group_int = $gwgroups[$dnsupdate['interface']][0]['int']; - } - } - if (!empty($int) && ($int != $dnsupdate['interface']) && ($int != $group_int)) { - continue; - } - if (!empty($updatehost) && ($updatehost != $dnsupdate['host'])) { - continue; - } - - /* determine interface name */ - $if = get_failover_interface($dnsupdate['interface']); + if (!is_array($config['dnsupdates']['dnsupdate'])) { + return 0; + } - if (isset($dnsupdate['usepublicip'])) { - $wanip = dyndnsCheckIP($if); + $notify_text = ""; + $gwgroups = return_gateway_groups_array(); + foreach ($config['dnsupdates']['dnsupdate'] as $i => $dnsupdate) { + if (!isset($dnsupdate['enable'])) { + continue; + } + /* + * If it's using a gateway group, check if interface is + * the active gateway for that group + */ + $group_int = ''; + if (is_array($gwgroups[$dnsupdate['interface']])) { + if (!empty($gwgroups[$dnsupdate['interface']][0]['vip'])) { + $group_int = $gwgroups[$dnsupdate['interface']][0]['vip']; } else { - $wanip = get_interface_ip($if); + $group_int = $gwgroups[$dnsupdate['interface']][0]['int']; } + } + if (!empty($int) && ($int != $dnsupdate['interface']) && ($int != $group_int)) { + continue; + } + if (!empty($updatehost) && ($updatehost != $dnsupdate['host'])) { + continue; + } - $wanipv6 = get_interface_ipv6($if); - $cacheFile = "{$g['conf_path']}/dyndns_{$dnsupdate['interface']}_rfc2136_" . escapeshellarg($dnsupdate['host']) . "_{$dnsupdate['server']}.cache"; - $currentTime = time(); + /* determine interface name */ + $if = get_failover_interface($dnsupdate['interface']); - if ($wanip || $wanipv6) { - $keyname = $dnsupdate['keyname']; - /* trailing dot */ - if (substr($keyname, -1) != ".") { - $keyname .= "."; - } + if (isset($dnsupdate['usepublicip'])) { + $wanip = dyndnsCheckIP($if); + } else { + $wanip = get_interface_ip($if); + } - $hostname = $dnsupdate['host']; - /* trailing dot */ - if (substr($hostname, -1) != ".") { - $hostname .= "."; - } + $wanipv6 = get_interface_ipv6($if); + $cacheFile = $g['conf_path'] . + "/dyndns_{$dnsupdate['interface']}_rfc2136_" . + escapeshellarg($dnsupdate['host']) . + "_{$dnsupdate['server']}.cache"; + $cacheFilev6 = $cacheFile . ".ipv6"; + $currentTime = time(); + + if (!$wanip && !$wanipv6) { + continue; + } + + $keyname = $dnsupdate['keyname']; + /* trailing dot */ + if (substr($keyname, -1) != ".") { + $keyname .= "."; + } - /* write private key file - this is dumb - public and private keys are the same for HMAC-MD5, - but nsupdate insists on having both */ - $fd = fopen("{$g['varetc_path']}/K{$i}{$keyname}+157+00000.private", "w"); - $privkey = <<<EOD + $hostname = $dnsupdate['host']; + /* trailing dot */ + if (substr($hostname, -1) != ".") { + $hostname .= "."; + } + + /* + * write private key file + * this is dumb - public and private keys are the same for + * HMAC-MD5, but nsupdate insists on having both + */ + $fd = fopen($g['varetc_path'] . + "/K{$i}{$keyname}+157+00000.private", "w"); + $privkey = <<<EOD Private-key-format: v1.2 Algorithm: 157 (HMAC) Key: {$dnsupdate['keydata']} EOD; - fwrite($fd, $privkey); - fclose($fd); - - /* write public key file */ - if ($dnsupdate['keytype'] == "zone") { - $flags = 257; - $proto = 3; - } else if ($dnsupdate['keytype'] == "host") { - $flags = 513; - $proto = 3; - } else if ($dnsupdate['keytype'] == "user") { - $flags = 0; - $proto = 2; - } - - $fd = fopen("{$g['varetc_path']}/K{$i}{$keyname}+157+00000.key", "w"); - fwrite($fd, "{$keyname} IN KEY {$flags} {$proto} 157 {$dnsupdate['keydata']}\n"); - fclose($fd); - - /* generate update instructions */ - $upinst = ""; - if (!empty($dnsupdate['server'])) { - $upinst .= "server {$dnsupdate['server']}\n"; - } - - if (file_exists($cacheFile)) { - list($cachedipv4, $cacheTimev4) = explode("|", file_get_contents($cacheFile)); - } - if (file_exists("{$cacheFile}.ipv6")) { - list($cachedipv6, $cacheTimev6) = explode("|", file_get_contents("{$cacheFile}.ipv6")); - } - - // 25 Days - $maxCacheAgeSecs = 25 * 24 * 60 * 60; - $need_update = false; - - /* Update IPv4 if we have it. */ - if (is_ipaddrv4($wanip) && $dnsupdate['recordtype'] != "AAAA") { - if (($wanip != $cachedipv4) || (($currentTime - $cacheTimev4) > $maxCacheAgeSecs) || $forced) { - $upinst .= "update delete {$dnsupdate['host']}. A\n"; - $upinst .= "update add {$dnsupdate['host']}. {$dnsupdate['ttl']} A {$wanip}\n"; - $notify_text .= sprintf(gettext('DynDNS updated IP Address (A) for %1$s on %2$s (%3$s) to %4$s'), $dnsupdate['host'], convert_real_interface_to_friendly_descr($if), $if, $wanip) . "\n"; - @file_put_contents($cacheFile, "{$wanip}|{$currentTime}"); - log_error(sprintf(gettext('phpDynDNS: updating cache file %1$s: %2$s'), $cacheFile, $wanip)); - $need_update = true; - } else { - log_error(sprintf(gettext("phpDynDNS: Not updating %s A record because the IP address has not changed."), $dnsupdate['host'])); - } - } else { - @unlink($cacheFile); - } - - /* Update IPv6 if we have it. */ - if (is_ipaddrv6($wanipv6) && $dnsupdate['recordtype'] != "A") { - if (($wanipv6 != $cachedipv6) || (($currentTime - $cacheTimev6) > $maxCacheAgeSecs) || $forced) { - $upinst .= "update delete {$dnsupdate['host']}. AAAA\n"; - $upinst .= "update add {$dnsupdate['host']}. {$dnsupdate['ttl']} AAAA {$wanipv6}\n"; - $notify_text .= sprintf(gettext('DynDNS updated IPv6 Address (AAAA) for %1$s on %2$s (%3$s) to %4$s'), $dnsupdate['host'], convert_real_interface_to_friendly_descr($if), $if, $wanipv6) . "\n"; - @file_put_contents("{$cacheFile}.ipv6", "{$wanipv6}|{$currentTime}"); - log_error(sprintf(gettext('phpDynDNS: updating cache file %1$s.ipv6: %2$s'), $cacheFile, $wanipv6)); - $need_update = true; - } else { - log_error(sprintf(gettext("phpDynDNS: Not updating %s AAAA record because the IPv6 address has not changed."), $dnsupdate['host'])); - } - } else { - @unlink("{$cacheFile}.ipv6"); - } + fwrite($fd, $privkey); + fclose($fd); - $upinst .= "\n"; /* mind that trailing newline! */ + /* write public key file */ + if ($dnsupdate['keytype'] == "zone") { + $flags = 257; + $proto = 3; + } else if ($dnsupdate['keytype'] == "host") { + $flags = 513; + $proto = 3; + } else if ($dnsupdate['keytype'] == "user") { + $flags = 0; + $proto = 2; + } + + $fd = fopen($g['varetc_path'] . + "/K{$i}{$keyname}+157+00000.key", "w"); + fwrite($fd, "{$keyname} IN KEY {$flags} {$proto} 157 " . + "{$dnsupdate['keydata']}\n"); + fclose($fd); - if ($need_update) { - @file_put_contents("{$g['varetc_path']}/nsupdatecmds{$i}", $upinst); - unset($upinst); - /* invoke nsupdate */ - $cmd = "/usr/local/bin/nsupdate -k {$g['varetc_path']}/K{$i}{$keyname}+157+00000.key"; - if (isset($dnsupdate['usetcp'])) { - $cmd .= " -v"; - } - $cmd .= " {$g['varetc_path']}/nsupdatecmds{$i}"; - mwexec_bg($cmd); - unset($cmd); - } + /* generate update instructions */ + $upinst = ""; + if (!empty($dnsupdate['server'])) { + $upinst .= "server {$dnsupdate['server']}\n"; + } + + if (file_exists($cacheFile)) { + list($cachedipv4, $cacheTimev4) = explode("|", + file_get_contents($cacheFile)); + } + if (file_exists($cacheFilev6)) { + list($cachedipv6, $cacheTimev6) = explode("|", + file_get_contents($cacheFilev6)); + } + + // 25 Days + $maxCacheAgeSecs = 25 * 24 * 60 * 60; + $need_update = false; + + /* Update IPv4 if we have it. */ + if (is_ipaddrv4($wanip) && $dnsupdate['recordtype'] != "AAAA") { + if (($wanip != $cachedipv4) || $forced || + (($currentTime - $cacheTimev4) > $maxCacheAgeSecs)) { + $upinst .= "update delete " . + "{$dnsupdate['host']}. A\n"; + $upinst .= "update add {$dnsupdate['host']}. " . + "{$dnsupdate['ttl']} A {$wanip}\n"; + $need_update = true; + } else { + log_error(sprintf(gettext( + "phpDynDNS: Not updating %s A record because the IP address has not changed."), + $dnsupdate['host'])); } + } else { + @unlink($cacheFile); + unset($cacheFile); + } + + /* Update IPv6 if we have it. */ + if (is_ipaddrv6($wanipv6) && $dnsupdate['recordtype'] != "A") { + if (($wanipv6 != $cachedipv6) || $forced || + (($currentTime - $cacheTimev6) > $maxCacheAgeSecs)) { + $upinst .= "update delete " . + "{$dnsupdate['host']}. AAAA\n"; + $upinst .= "update add {$dnsupdate['host']}. " . + "{$dnsupdate['ttl']} AAAA {$wanipv6}\n"; + $need_update = true; + } else { + log_error(sprintf(gettext( + "phpDynDNS: Not updating %s AAAA record because the IPv6 address has not changed."), + $dnsupdate['host'])); + } + } else { + @unlink($cacheFilev6); + unset($cacheFilev6); + } + + $upinst .= "\n"; /* mind that trailing newline! */ + + if (!$need_update) { + continue; } - if (!empty($notify_text)) { - notify_all_remote($notify_text); + + @file_put_contents("{$g['varetc_path']}/nsupdatecmds{$i}", + $upinst); + unset($upinst); + /* invoke nsupdate */ + $cmd = "/usr/local/bin/nsupdate -k " . + "{$g['varetc_path']}/K{$i}{$keyname}+157+00000.key"; + + if (isset($dnsupdate['usetcp'])) { + $cmd .= " -v"; + } + + $cmd .= " {$g['varetc_path']}/nsupdatecmds{$i}"; + + if (mwexec($cmd) == 0) { + if (!empty($cacheFile)) { + @file_put_contents($cacheFile, + "{$wanip}|{$currentTime}"); + log_error(sprintf(gettext( + 'phpDynDNS: updating cache file %1$s: %2$s'), + $cacheFile, $wanip)); + $notify_text .= sprintf(gettext( + 'DynDNS updated IP Address (A) for %1$s on %2$s (%3$s) to %4$s'), + $dnsupdate['host'], + convert_real_interface_to_friendly_descr($if), + $if, $wanip) . "\n"; + } + if (!empty($cacheFilev6)) { + @file_put_contents($cacheFilev6, + "{$wanipv6}|{$currentTime}"); + log_error(sprintf(gettext( + 'phpDynDNS: updating cache file %1$s: %2$s'), + $cacheFilev6, $wanipv6)); + $notify_text .= sprintf(gettext( + 'DynDNS updated IPv6 Address (AAAA) for %1$s on %2$s (%3$s) to %4$s'), + $dnsupdate['host'], + convert_real_interface_to_friendly_descr($if), + $if, $wanipv6) . "\n"; + } + } else { + if (!empty($cacheFile)) { + log_error(sprintf(gettext( + 'phpDynDNS: ERROR while updating IP Address (A) for %1$s (%2$s)'), + $dnsupdate['host'], $wanip)); + } + if (!empty($cacheFilev6)) { + log_error(sprintf(gettext( + 'phpDynDNS: ERROR while updating IP Address (AAAA) for %1$s (%2$s)'), + $dnsupdate['host'], $wanipv6)); + } } + unset($cmd); + } + + if (!empty($notify_text)) { + notify_all_remote($notify_text); } return 0; diff --git a/src/etc/inc/system.inc b/src/etc/inc/system.inc index 573f074..1067316 100644 --- a/src/etc/inc/system.inc +++ b/src/etc/inc/system.inc @@ -1931,13 +1931,16 @@ function system_reboot_sync($reroot=false) { } function system_reboot_cleanup() { - global $config, $cpzone; + global $config, $cpzone, $cpzoneid; mwexec("/usr/local/bin/beep.sh stop"); require_once("captiveportal.inc"); if (is_array($config['captiveportal'])) { foreach ($config['captiveportal'] as $cpzone=>$cp) { - captiveportal_radius_stop_all(); + /* send Accounting-Stop packet for all clients, termination cause 'Admin-Reboot' */ + $cpzoneid = $cp[zoneid]; + captiveportal_radius_stop_all(7); // Admin-Reboot + /* Send Accounting-Off packet to the RADIUS server */ captiveportal_send_server_accounting(true); } } @@ -2230,6 +2233,11 @@ function system_identify_specific_platform() { return (array('name' => 'Hyper-V', 'descr' => 'Hyper-V Virtual Machine')); } break; + case 'VMware Virtual Platform': + if ($maker[0] == "VMware, Inc.") { + return (array('name' => 'VMware', 'descr' => 'VMware Virtual Machine')); + } + break; } if (strpos($hw_model, "PC Engines WRAP") !== false) { diff --git a/src/etc/inc/upgrade_config.inc b/src/etc/inc/upgrade_config.inc index 61ecc51..41b4e3a 100644 --- a/src/etc/inc/upgrade_config.inc +++ b/src/etc/inc/upgrade_config.inc @@ -5063,4 +5063,86 @@ function upgrade_159_to_160() { } } } + +/* RAM Disk Management */ +function upgrade_160_to_161() { + global $g, $config; + + if (!isset($config['system']['use_mfs_tmpvar'])) { + return; + } + + // Move existing RRD backup to the RAM Disk Store if it don't already exist there. + // Restore existing RRD XML dump backup. + if (file_exists("{$g['cf_conf_path']}/rrd.tgz") && !file_exists("{$g['cf_conf_path']}/RAM_Disk_Store/rrd.tgz")) { + $rrddbpath = "{$g['vardb_path']}/rrd/"; + $rrdtool = "/usr/bin/nice -n20 /usr/local/bin/rrdtool"; + + $rrdrestore = ""; + $rrdreturn = ""; + unlink_if_exists("{$rrddbpath}/*.xml"); + + unset($rrdrestore); + $_gb = exec("LANG=C /usr/bin/tar -tf {$g['cf_conf_path']}/rrd.tgz", $rrdrestore, $rrdreturn); + if ($rrdreturn != 0) { + log_error(sprintf(gettext('RRD restore failed exited with %1$s, the error is: %2$s'), $rrdreturn, $rrdrestore)); + } else { + foreach ($rrdrestore as $xml_file) { + $rrd_file = '/' . substr($xml_file, 0, -4) . '.rrd'; + unlink_if_exists("{$rrd_file}"); + + file_put_contents("{$g['tmp_path']}/rrd_restore", $xml_file); + $_gb = exec("LANG=C /usr/bin/tar -xf {$g['cf_conf_path']}/rrd.tgz -C / -T {$g['tmp_path']}/rrd_restore"); + if (!file_exists("/{$xml_file}")) { + log_error(sprintf(gettext("Could not extract %s RRD xml file from archive!"), $xml_file)); + continue; + } + $_gb = exec("$rrdtool restore -f '/{$xml_file}' '{$rrd_file}'", $output, $status); + if ($status) { + log_error(sprintf(gettext("rrdtool restore -f '%1\$s' '%2\$s' failed returning %3\$s."), $xml_file, $rrd_file, $status)); + continue; + } + unset($output); + @unlink("/{$xml_file}"); + } + unset($rrdrestore); + @unlink("{$g['tmp_path']}/rrd_restore"); + + // Create a new RRD backup to the RAM Disk Store (without RRD XML dump). + exec("/etc/rc.backup_rrd.sh"); + $ramds_updated = true; + + // Rename previous RRD backup so it will not restore again. Don't delete in case needed for recovery. + rename("{$g['cf_conf_path']}/rrd.tgz", "{$g['cf_conf_path']}/rrd.tgz.old"); + } + } + + // Move existing DHCP leases backup to the RAM Disk Store if it don't already exist there. + if (file_exists("{$g['cf_conf_path']}/dhcpleases.tgz") && ! file_exists("{$g['cf_conf_path']}/RAM_Disk_Store/dhcpleases.tgz")) { + rename("{$g['cf_conf_path']}/dhcpleases.tgz", "{$g['cf_conf_path']}/RAM_Disk_Store/dhcpleases.tgz"); + $ramds_updated = true; + } + + // Move existing alias table backups to the RAM Disk Store if they don't already exist there. + $dbpath = "{$g['vardb_path']}/aliastables/"; + $files = glob("{$g['cf_conf_path']}/RAM_Disk_Store{$dbpath}*.tgz"); + if (count($files)) { + foreach ($files as $file) { + if (! file_exists("{$g['cf_conf_path']}/RAM_Disk_Store/".basename($file))) { + rename($file, "{$g['cf_conf_path']}/RAM_Disk_Store/".basename($file)); + $ramds_updated = true; + } + } + // Remove existing alias table backups directory if empty. + @rmdir("{$g['cf_conf_path']}/RAM_Disk_Store/var/db/aliastables"); + @rmdir("{$g['cf_conf_path']}/RAM_Disk_Store/var/db/"); + @rmdir("{$g['cf_conf_path']}/RAM_Disk_Store/var/"); + } + + // Restore RAM Disk Store if updated. + if ($ramds_updated) { + exec("/etc/rc.restore_ramdisk_store"); + } +} + ?> diff --git a/src/etc/inc/util.inc b/src/etc/inc/util.inc index 78bf1b6..2176423 100644 --- a/src/etc/inc/util.inc +++ b/src/etc/inc/util.inc @@ -485,32 +485,32 @@ function ip_range_to_address_array($startip, $endip, $max_size = 5000) { return $rangeaddresses; } -/* Convert an IPv4 or IPv6 IP range to an array of subnets which can contain the range. - Algorithm and embodying code PD'ed by Stilez - enjoy as you like :-) - - Documented on pfsense dev list 19-20 May 2013. Summary: - - The algorithm looks at patterns of 0's and 1's in the least significant bit(s), whether IPv4 or IPv6. - These are all that needs checking to identify a _guaranteed_ correct, minimal and optimal subnet array. - - As a result, string/binary pattern matching of the binary IP is very efficient. It uses just 2 pattern-matching rules - to chop off increasingly larger subnets at both ends that can't be part of larger subnets, until nothing's left. - - (a) If any range has EITHER low bit 1 (in startip) or 0 (in endip), that end-point is _always guaranteed_ to be optimally - represented by its own 'single IP' CIDR; the remaining range then shrinks by one IP up or down, causing the new end-point's - low bit to change from 1->0 (startip) or 0->1 (endip). Only one edge case needs checking: if a range contains exactly 2 - adjacent IPs of this format, then the two IPs themselves are required to span it, and we're done. - Once this rule is applied, the remaining range is _guaranteed_ to end in 0's and 1's so rule (b) can now be used, and its - low bits can now be ignored. - - (b) If any range has BOTH startip and endip ending in some number of 0's and 1's respectively, these low bits can - *always* be ignored and "bit-shifted" for subnet spanning. So provided we remember the bits we've place-shifted, we can - _always_ right-shift and chop off those bits, leaving a smaller range that has EITHER startip ending in 1 or endip ending - in 0 (ie can now apply (a) again) or the entire range has vanished and we're done. - We then loop to redo (a) again on the remaining (place shifted) range until after a few loops, the remaining (place shifted) - range 'vanishes' by meeting the exit criteria of (a) or (b), and we're done. -*/ - +/* + * Convert an IPv4 or IPv6 IP range to an array of subnets which can contain the range. + * Algorithm and embodying code PD'ed by Stilez - enjoy as you like :-) + * + * Documented on pfsense dev list 19-20 May 2013. Summary: + * + * The algorithm looks at patterns of 0's and 1's in the least significant bit(s), whether IPv4 or IPv6. + * These are all that needs checking to identify a _guaranteed_ correct, minimal and optimal subnet array. + * + * As a result, string/binary pattern matching of the binary IP is very efficient. It uses just 2 pattern-matching rules + * to chop off increasingly larger subnets at both ends that can't be part of larger subnets, until nothing's left. + * + * (a) If any range has EITHER low bit 1 (in startip) or 0 (in endip), that end-point is _always guaranteed_ to be optimally + * represented by its own 'single IP' CIDR; the remaining range then shrinks by one IP up or down, causing the new end-point's + * low bit to change from 1->0 (startip) or 0->1 (endip). Only one edge case needs checking: if a range contains exactly 2 + * adjacent IPs of this format, then the two IPs themselves are required to span it, and we're done. + * Once this rule is applied, the remaining range is _guaranteed_ to end in 0's and 1's so rule (b) can now be used, and its + * low bits can now be ignored. + * + * (b) If any range has BOTH startip and endip ending in some number of 0's and 1's respectively, these low bits can + * *always* be ignored and "bit-shifted" for subnet spanning. So provided we remember the bits we've place-shifted, we can + * _always_ right-shift and chop off those bits, leaving a smaller range that has EITHER startip ending in 1 or endip ending + * in 0 (ie can now apply (a) again) or the entire range has vanished and we're done. + * We then loop to redo (a) again on the remaining (place shifted) range until after a few loops, the remaining (place shifted) + * range 'vanishes' by meeting the exit criteria of (a) or (b), and we're done. + */ function ip_range_to_subnet_array($ip1, $ip2) { if (is_ipaddrv4($ip1) && is_ipaddrv4($ip2)) { @@ -986,12 +986,18 @@ function is_domain($domain, $allow_wildcard=false) { } /* returns true if $macaddr is a valid MAC address */ -function is_macaddr($macaddr) { +function is_macaddr($macaddr, $partial=false) { $values = explode(":", $macaddr); - if (count($values) != 6) { + + /* Verify if the MAC address has a proper amount of parts for either a partial or full match. */ + if ($partial) { + if ((count($values) < 1) || (count($values) > 6)) { + return false; + } + } elseif (count($values) != 6) { return false; } - for ($i = 0; $i < 6; $i++) { + for ($i = 0; $i < count($values); $i++) { if (ctype_xdigit($values[$i]) == false) return false; if (hexdec($values[$i]) < 0 || hexdec($values[$i]) > 255) @@ -1784,10 +1790,11 @@ function arp_get_mac_by_ip($ip) { /* return a fieldname that is safe for xml usage */ function xml_safe_fieldname($fieldname) { - $replace = array('/', '-', ' ', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', - '_', '+', '=', '{', '}', '[', ']', '|', '/', '<', '>', '?', - ':', ',', '.', '\'', '\\' - ); + $replace = array( + '/', '-', ' ', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', + '_', '+', '=', '{', '}', '[', ']', '|', '/', '<', '>', '?', + ':', ',', '.', '\'', '\\' + ); return strtolower(str_replace($replace, "", $fieldname)); } @@ -2546,4 +2553,92 @@ function validateipaddr(&$addr, $type, $label, &$err_msg, $alias=false) { return false; } + +/* format a string to look (more) like the expected DUID format: + * 1) Replace any "-" with ":" + * 2) If the user inputs 14 components, then add the expected "0e:00:" to the front. + * This is convenience, because the actual DUID (which is reported in logs) is the last 14 components. + * 3) If any components are input with just a single char (hex digit hopefully), put a "0" in front. + * + * The final result should be closer to: + * + * "0e:00:00:01:00:01:nn:nn:nn:nn:nn:nn:nn:nn:nn:nn" + * + * This function does not validate the input. is_duid() will do validation. +*/ +function format_duid($dhcp6duid) { + $values = explode(":", strtolower(str_replace("-", ":", $dhcp6duid))); + if (count($values) == 14) { + array_unshift($values, "0e", "00"); + } + + array_walk($values, function(&$value) { + $value = str_pad($value, 2, '0', STR_PAD_LEFT); + }); + + return implode(":", $values); +} + +/* returns true if $dhcp6duid is a valid duid entry */ +function is_duid($dhcp6duid) { + $values = explode(":", $dhcp6duid); + if (count($values) != 16 || strlen($dhcp6duid) != 47) { + return false; + } + for ($i = 0; $i < 16; $i++) { + if (ctype_xdigit($values[$i]) == false) + return false; + if (hexdec($values[$i]) < 0 || hexdec($values[$i]) > 255) + return false; + } + return true; +} + +/* Write the DHCP6 DUID file */ +function write_dhcp6_duid($duidstring) { + // Create the hex array from the dhcp6duid config entry and write to file + global $g; + + if(!is_duid($duidstring)) { + log_error(gettext("Error: attempting to write DUID file - Invalid DUID detected")); + return false; + } + $temp = str_replace(":","",$duidstring); + $duid_binstring = pack("H*",$temp); + if ($fd = fopen("{$g['vardb_path']}/dhcp6c_duid", "wb")) { + fwrite($fd, $duid_binstring); + fclose($fd); + return true; + } + log_error(gettext("Error: attempting to write DUID file - File write error")); + return false; +} + +/* returns duid string from 'vardb_path']}/dhcp6c_duid' */ +function get_duid_from_file() { + global $g; + + $duid_ASCII = ""; + $count = 0; + + if (file_exists("{$g['vardb_path']}/dhcp6c_duid") && + ($fd = fopen("{$g['vardb_path']}/dhcp6c_duid", "r"))) { + if(filesize("{$g['vardb_path']}/dhcp6c_duid")==16) { + $buffer = fread($fd,16); + while($count < 16) { + $duid_ASCII .= bin2hex($buffer[$count]); + $count++; + if($count < 16) { + $duid_ASCII .= ":"; + } + } + } + fclose($fd); + } + //if no file or error with read then the string returns blanked DUID string + if(!is_duid($duid_ASCII)) { + return "--:--:--:--:--:--:--:--:--:--:--:--:--:--:--:--"; + } + return($duid_ASCII); +} ?> diff --git a/src/etc/inc/vpn.inc b/src/etc/inc/vpn.inc index f4fa23d..7cd3475 100644 --- a/src/etc/inc/vpn.inc +++ b/src/etc/inc/vpn.inc @@ -47,10 +47,11 @@ function vpn_logging_cfgtxt() { global $config, $ipsec_log_cats, $ipsec_log_sevs; $cfgtext = array(); + $log_levels = ipsec_get_loglevels(); foreach (array_keys($ipsec_log_cats) as $cat) { - if (is_numeric($config['ipsec']['logging'][$cat]) && - in_array(intval($config['ipsec']['logging'][$cat]), array_keys($ipsec_log_sevs), true)) { - $cfgtext[] = "${cat} = {$config['ipsec']['logging'][$cat]}"; + if (is_numeric($log_levels[$cat]) && + in_array(intval($log_levels[$cat]), array_keys($ipsec_log_sevs), true)) { + $cfgtext[] = "${cat} = {$log_levels[$cat]}"; } } diff --git a/src/etc/pfSense-rc b/src/etc/pfSense-rc index 382da91..2bc0ab8 100755 --- a/src/etc/pfSense-rc +++ b/src/etc/pfSense-rc @@ -105,6 +105,20 @@ while [ ${mount_rc} -ne 0 -a ${attempts} -lt 3 ]; do attempts=$((attempts+1)) done +# Handle ZFS read-only case +/sbin/kldstat -qm zfs +if [ $? -eq 0 ]; then + ZFSFSAVAILABLE=$(/sbin/zfs mount 2>/dev/null | wc -l) + if [ $ZFSFSAVAILABLE -eq 0 ]; then + /sbin/kldunload zfs + elif [ -f /usr/bin/grep ]; then + ZFSROOT=`/sbin/zfs mount | /usr/bin/grep ' /$' | /usr/bin/cut -d ' ' -f 1` + if [ "$ZFSROOT" != "" ]; then + /sbin/zfs set readonly=off $ZFSROOT + fi + fi +fi + # If /conf is a directory, convert it to a symlink to /cf/conf if [ -d "/conf" ]; then # If item is not a symlink then rm and recreate @@ -122,14 +136,16 @@ if [ "${USE_MFS_TMPVAR}" != "true" -a -f /root/var/db/pkg/local.sqlite ]; then MOVE_PKG_DATA=1 rm -rf /var/db/pkg 2>/dev/null rm -rf /var/cache/pkg 2>/dev/null - mv /root/var/db/pkg /var/db - mv /root/var/cache/pkg /var/cache + mv -f /root/var/db/pkg /var/db + mv -f /root/var/cache/pkg /var/cache # If use MFS var is enabled, move files to a safe place elif [ "${USE_MFS_TMPVAR}" = "true" -a -f /var/db/pkg/local.sqlite ]; then MOVE_PKG_DATA=1 + rm -rf /root/var/db/pkg 2>/dev/null + rm -rf /root/var/cache/pkg 2>/dev/null /bin/mkdir -p /root/var/db /root/var/cache - mv /var/db/pkg /root/var/db - mv /var/cache/pkg /root/var/cache + mv -f /var/db/pkg /root/var/db + mv -f /var/cache/pkg /root/var/cache fi if [ "${USE_MFS_TMPVAR}" = "true" ]; then @@ -142,6 +158,9 @@ if [ -n "${MOVE_PKG_DATA}" -o "${USE_MFS_TMPVAR}" = "true" ]; then ln -sf ../../root/var/cache/pkg /var/cache/pkg fi +# Restore contents of the RAM disk store +/etc/rc.restore_ramdisk_store + # Make sure /home exists [ -d /home ] \ || mkdir /home @@ -150,20 +169,6 @@ fi /bin/rm -f /root/TRIM_set /bin/rm -f /root/TRIM_unset -# Handle ZFS read-only case -/sbin/kldstat -qm zfs -if [ $? -eq 0 ]; then - ZFSFSAVAILABLE=$(/sbin/zfs mount 2>/dev/null | wc -l) - if [ $ZFSFSAVAILABLE -eq 0 ]; then - /sbin/kldunload zfs - elif [ -f /usr/bin/grep ]; then - ZFSROOT=`/sbin/zfs mount | /usr/bin/grep ' /$' | /usr/bin/cut -d ' ' -f 1` - if [ "$ZFSROOT" != "" ]; then - /sbin/zfs set readonly=off $ZFSROOT - fi - fi -fi - # Disable APM on ATA drives. Leaving this on will kill drives long-term, especially laptop drives, by generating excessive Load Cycles. if [ -f /etc/rc.disable_hdd_apm ]; then /etc/rc.disable_hdd_apm diff --git a/src/etc/pfSense-rc.shutdown b/src/etc/pfSense-rc.shutdown index dc6221f..0f7b48c 100755 --- a/src/etc/pfSense-rc.shutdown +++ b/src/etc/pfSense-rc.shutdown @@ -50,4 +50,5 @@ if [ "${USE_MFS_TMPVAR}" = "true" ] || [ "${DISK_TYPE}" = "md" ]; then /etc/rc.backup_aliastables.sh /etc/rc.backup_rrd.sh /etc/rc.backup_dhcpleases.sh + /etc/rc.backup_logs.sh fi diff --git a/src/etc/rc.backup_aliastables.sh b/src/etc/rc.backup_aliastables.sh index 7999b0a..b25d20c 100755 --- a/src/etc/rc.backup_aliastables.sh +++ b/src/etc/rc.backup_aliastables.sh @@ -3,18 +3,23 @@ : ${DBPATH:=/var/db/aliastables} : ${CF_CONF_PATH:=/cf/conf} -: ${RAM_Disk_Store:=${CF_CONF_PATH}/RAM_Disk_Store/${DBPATH}} +: ${RAM_Disk_Store:=${CF_CONF_PATH}/RAM_Disk_Store} # Save the alias tables database to the RAM disk store. if [ -d "${DBPATH}" ]; then + echo -n "Saving Alias Tables to RAM disk store..."; + if [ ! -d "${RAM_Disk_Store}" ]; then mkdir -p "${RAM_Disk_Store}" fi for aliastablefile in "${DBPATH}"/* ; do filename="$(basename ${aliastablefile})" - if [ ! -f "${RAM_Disk_Store}/${filename}.tgz" ]; then - cd / && /usr/bin/tar -czf "${RAM_Disk_Store}/${filename}.tgz" -C / "${DBPATH}/${filename}" + if [ ! -f "${RAM_Disk_Store}/${filename}.tgz" -o "${RAM_Disk_Store}/${filename}.tgz" -ot "${DBPATH#/}/${filename}" ]; then + [ -f "${RAM_Disk_Store}/${filename}.tgz" ] && /bin/rm -f "${RAM_Disk_Store}/${filename}.tgz" + /usr/bin/tar -czf "${RAM_Disk_Store}/${filename}.tgz" -C / "${DBPATH#/}/${filename}" fi done + + echo "done."; fi diff --git a/src/etc/rc.backup_dhcpleases.sh b/src/etc/rc.backup_dhcpleases.sh index 7a8e741..d7c154a 100755 --- a/src/etc/rc.backup_dhcpleases.sh +++ b/src/etc/rc.backup_dhcpleases.sh @@ -1,6 +1,21 @@ #!/bin/sh -# Save the DHCP lease database to the config path. -if [ -d "/var/dhcpd/var/db" ]; then - cd / && tar -czf /cf/conf/dhcpleases.tgz -C / var/dhcpd/var/db/ +: ${DBPATH:=/var/dhcpd/var/db} +: ${CF_CONF_PATH:=/cf/conf} + +: ${RAM_Disk_Store:=${CF_CONF_PATH}/RAM_Disk_Store} + +# Save the DHCP lease database to the RAM disk store. +if [ -d "${DBPATH}" ]; then + echo -n "Saving DHCP Leases to RAM disk store..."; + + [ -f "${RAM_Disk_Store}/dhcpleases.tgz" ] && /bin/rm -f "${RAM_Disk_Store}/dhcpleases.tgz" + + if [ ! -d "${RAM_Disk_Store}" ]; then + mkdir -p "${RAM_Disk_Store}" + fi + + /usr/bin/tar -czf "${RAM_Disk_Store}/dhcpleases.tgz" -C / "${DBPATH#/}/" + + echo "done."; fi diff --git a/src/etc/rc.backup_logs.sh b/src/etc/rc.backup_logs.sh new file mode 100755 index 0000000..89495e5 --- /dev/null +++ b/src/etc/rc.backup_logs.sh @@ -0,0 +1,41 @@ +#!/bin/sh +# +# rc.backup_logs.sh +# +# part of pfSense (https://www.pfsense.org) +# Copyright (c) 2016 Rubicon Communications, LLC (Netgate) +# All rights reserved. +# +# Based on src/etc/rc.d/savecore from FreeBSD +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +: ${DBPATH:=/var/log} +: ${CF_CONF_PATH:=/cf/conf} + +: ${RAM_Disk_Store:=${CF_CONF_PATH}/RAM_Disk_Store} + +# Save the logs database to the RAM disk store. +if [ -d "${DBPATH}" ]; then + echo -n "Saving Logs to RAM disk store..."; + + [ -f "${RAM_Disk_Store}/logs.tgz" ] && /bin/rm -f "${RAM_Disk_Store}/logs.tgz" + + if [ ! -d "${RAM_Disk_Store}" ]; then + mkdir -p "${RAM_Disk_Store}" + fi + + /usr/bin/tar -czf "${RAM_Disk_Store}/logs.tgz" -C / "${DBPATH#/}/" + + echo "done."; +fi diff --git a/src/etc/rc.backup_rrd.sh b/src/etc/rc.backup_rrd.sh index 7914bd1..ca3d67c 100755 --- a/src/etc/rc.backup_rrd.sh +++ b/src/etc/rc.backup_rrd.sh @@ -1,25 +1,21 @@ #!/bin/sh -: ${RRDDBPATH:=/var/db/rrd} +: ${DBPATH:=/var/db/rrd} : ${CF_CONF_PATH:=/cf/conf} -# Save the rrd databases to the config path. -if [ -d "${RRDDBPATH}" ]; then - [ -f "${CF_CONF_PATH}/rrd.tgz" ] && /bin/rm -f "${CF_CONF_PATH}"/rrd.tgz +: ${RAM_Disk_Store:=${CF_CONF_PATH}/RAM_Disk_Store} - tgzlist="" +# Save the rrd databases to the RAM disk store. +if [ -d "${DBPATH}" ]; then + echo -n "Saving RRD to RAM disk store..."; - for rrdfile in "${RRDDBPATH}"/*.rrd ; do - xmlfile="${rrdfile%.rrd}.xml" - tgzfile="${rrdfile%.rrd}.tgz" - /usr/bin/nice -n20 /usr/local/bin/rrdtool dump "$rrdfile" "$xmlfile" - cd / && /usr/bin/tar -czf "${tgzfile}" -C / "${RRDDBPATH#/}"/*.xml - /bin/rm -f "${RRDDBPATH}"/*.xml - tgzlist="${tgzlist} @${tgzfile}" - done - if [ -n "${tgzlist}" ]; then - cd / && /usr/bin/tar -czf "${CF_CONF_PATH}/rrd.tgz" ${tgzlist} - /bin/rm -f "${RRDDBPATH}"/*.tgz + [ -f "${RAM_Disk_Store}/rrd.tgz" ] && /bin/rm -f "${RAM_Disk_Store}/rrd.tgz" + + if [ ! -d "${RAM_Disk_Store}" ]; then + mkdir -p "${RAM_Disk_Store}" fi -fi + /usr/bin/tar -czf "${RAM_Disk_Store}/rrd.tgz" -C / "${DBPATH#/}/" + + echo "done."; +fi diff --git a/src/etc/rc.bootup b/src/etc/rc.bootup index 5629102..8fe9b16 100755 --- a/src/etc/rc.bootup +++ b/src/etc/rc.bootup @@ -176,8 +176,10 @@ interfaces_loopback_configure(); /* start syslogd */ system_syslogd_start(); -/* restore alias tables */ -restore_aliastables(); +/* Log the RAM disk restore messages. */ +if (file_exists("/var/log/restore_ramdisk_store.boot")) { + exec("logger -f /var/log/restore_ramdisk_store.boot"); +} echo "Starting Secure Shell Services..."; send_event("service reload sshd"); diff --git a/src/etc/rc.prunecaptiveportal b/src/etc/rc.prunecaptiveportal index 8a5253b..89e6328 100755 --- a/src/etc/rc.prunecaptiveportal +++ b/src/etc/rc.prunecaptiveportal @@ -43,18 +43,16 @@ if (!is_array($config['captiveportal'][$cpzone])) { } $cpzoneid = $config['captiveportal'][$cpzone]['zoneid']; -if (file_exists("{$g['tmp_path']}/.rc.prunecaptiveportal.{$cpzone}.running")) { - $stat = stat("{$g['tmp_path']}/.rc.prunecaptiveportal.{$cpzone}.running"); - if (time() - $stat['mtime'] >= 120) { - @unlink("{$g['tmp_path']}/.rc.prunecaptiveportal.{$cpzone}.running"); - } else { - log_error("Skipping CP pruning process because previous/another instance is already running"); - return; - } +$rcprunelock = try_lock("rcprunecaptiveportal{$cpzone}", 3); + +if (!$rcprunelock) { + log_error("Skipping CP pruning process for zone {$cpzone} because previous/another instance is already running"); + unlock_force("rcprunecaptiveportal{$cpzone}"); + return; } -@file_put_contents("{$g['tmp_path']}/.rc.prunecaptiveportal.{$cpzone}.running", ""); captiveportal_prune_old(); -@unlink("{$g['tmp_path']}/.rc.prunecaptiveportal.{$cpzone}.running"); + +unlock($rcprunelock); ?> diff --git a/src/etc/rc.reboot b/src/etc/rc.reboot index e48f927..c547456 100755 --- a/src/etc/rc.reboot +++ b/src/etc/rc.reboot @@ -44,6 +44,7 @@ if [ "${USE_MFS_TMPVAR}" = "true" ] || [ "${DISK_TYPE}" = "md" ]; then /etc/rc.backup_aliastables.sh /etc/rc.backup_rrd.sh /etc/rc.backup_dhcpleases.sh + /etc/rc.backup_logs.sh fi sleep 1 diff --git a/src/etc/rc.restore_ramdisk_store b/src/etc/rc.restore_ramdisk_store new file mode 100755 index 0000000..cd33324 --- /dev/null +++ b/src/etc/rc.restore_ramdisk_store @@ -0,0 +1,82 @@ +#!/bin/sh +# +# rc.restore_ramdisk_store +# +# part of pfSense (https://www.pfsense.org) +# Copyright (c) 2004-2016 Rubicon Communications, LLC (Netgate) +# All rights reserved. +# +# Based on src/etc/rc.d/savecore from FreeBSD +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Wildcard file existence check function +wildcard_file_exists() { + for file in "$1"; do + if [ -f "$file" ]; then + return 0 + fi + done + return 1 +} + +: ${DBPATH:=/var/dhcpd/var/db} +: ${CF_CONF_PATH:=/cf/conf} + +: ${RAM_Disk_Store:=${CF_CONF_PATH}/RAM_Disk_Store} + +# See if there are any backup files (*.tgz) in the RAM disk store. If so, restore them. +if wildcard_file_exists "${RAM_Disk_Store}/"*".tgz"; then + + mesg="Restoring contents of RAM disk store..." + echo -n "$mesg" + + USE_MFS_TMPVAR=$(/usr/local/sbin/read_xml_tag.sh boolean system/use_mfs_tmpvar) + + # Restore the ram disk + for backup_file in "${RAM_Disk_Store}/"*".tgz"; do + if [ -f "$backup_file" ]; then + /usr/bin/tar -xzf "${backup_file}" -C / 2>&1 + exit_code=$? + if [ $exit_code -ne 0 ]; then + mesg="$mesg\nRAM disk restore failed: exit code $exit_code: $backup_file" + error=1; + continue + fi + + mesg="$mesg\nRAM disk restore succeeded: $backup_file" + + #If this backup is still there on a full install, but we aren't going to use ram disks, remove the archive since this is a transition. + if [ "${USE_MFS_TMPVAR}" != "true" ]; then + /bin/rm -f "${backup_file}" + fi + fi + done + + if [ $error ]; then + mesg="$mesg\nRAM disk restore failed." + echo " error."; + else + mesg="$mesg\nRAM disk restore succeeded." + echo " done."; + fi + + /bin/mkdir -p /var/log/ + printf "$mesg" > /var/log/restore_ramdisk_store.boot + + # See if there are any backup files (*.tgz) in the RAM disk store. If not, and no error, clean up. + if ! wildcard_file_exists "${RAM_Disk_Store}/"*".tgz" && [ ! $error ]; then + /bin/rmdir "$RAM_Disk_Store" >/dev/null 2>&1 + /bin/rm -f /var/log/restore_ramdisk_store.boot + fi +fi diff --git a/src/etc/skel/dot.shrc b/src/etc/skel/dot.shrc index e72197b..e9f0ca6 100644 --- a/src/etc/skel/dot.shrc +++ b/src/etc/skel/dot.shrc @@ -32,6 +32,12 @@ if [ "${HTTP_PROXY_AUTH_USER}" != "" ] && [ "${HTTP_PROXY_AUTH_PASS}" != "" ]; t export HTTP_PROXY_AUTH fi +USE_MFS_TMPVAR=$(/usr/local/sbin/read_xml_tag.sh boolean system/use_mfs_tmpvar) +if [ "${USE_MFS_TMPVAR}" = "true" ]; then + export PKG_DBDIR='/root/var/db/pkg' + export PKG_CACHEDIR='/root/var/cache/pkg' +fi + # Detect interactive logins and display the shell unset _interactive if [ -n "${SSH_TTY}" ]; then diff --git a/src/etc/skel/dot.tcshrc b/src/etc/skel/dot.tcshrc index db9846f..28e3fc8 100644 --- a/src/etc/skel/dot.tcshrc +++ b/src/etc/skel/dot.tcshrc @@ -55,3 +55,9 @@ if ( ${http_proxy_auth_user} != "" && ${http_proxy_auth_pass} != "" ) then set http_proxy_auth="basic:*:${http_proxy_auth_user}:${http_proxy_auth_pass}" setenv HTTP_PROXY_AUTH "${http_proxy_auth}" endif + +set use_mfs_tmpvar=`/usr/local/sbin/read_xml_tag.sh boolean system/use_mfs_tmpvar` +if ( $use_mfs_tmpvar == "true" ) then + setenv PKG_DBDIR '/root/var/db/pkg' + setenv PKG_CACHEDIR '/root/var/cache/pkg' +endif diff --git a/src/usr/local/www/crash_reporter.php b/src/usr/local/www/crash_reporter.php index 9a74c3e..4bb2ad7 100644 --- a/src/usr/local/www/crash_reporter.php +++ b/src/usr/local/www/crash_reporter.php @@ -103,8 +103,10 @@ exec("/bin/cat /tmp/PHP_errors.log", $php_errors); if (count($php_errors) > 0) { $crash_reports .= "\nPHP Errors:\n"; $crash_reports .= implode("\n", $php_errors) . "\n\n"; + } else { + $crash_reports .= "\nNo PHP errors found.\n"; } - if (is_array($crash_files)) { + if (count($crash_files) > 0) { foreach ($crash_files as $cf) { if (filesize($cf) < FILE_SIZE) { $crash_reports .= "\nFilename: {$cf}\n"; @@ -112,7 +114,7 @@ exec("/bin/cat /tmp/PHP_errors.log", $php_errors); } } } else { - echo gettext("Could not locate any crash data."); + $crash_reports .= "\nNo FreeBSD crash data found.\n"; } ?> <div class="panel panel-default"> diff --git a/src/usr/local/www/css/pfSense-BETA.css b/src/usr/local/www/css/pfSense-BETA.css index 4550601..dbf35a4 100644 --- a/src/usr/local/www/css/pfSense-BETA.css +++ b/src/usr/local/www/css/pfSense-BETA.css @@ -86,3 +86,10 @@ a.fa, i.fa { .ui-widget { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; } + +/** This style adds a gray outline around unchecked checkboxes to +make them more visible. Unfortunately the exact alignment of those +outlines varies considerably with browser/OS **/ +input[type="checkbox"]:not(:checked) { + outline: 1px solid #888888; +} diff --git a/src/usr/local/www/css/pfSense.css b/src/usr/local/www/css/pfSense.css index 6cf0945..6c43c24 100644 --- a/src/usr/local/www/css/pfSense.css +++ b/src/usr/local/www/css/pfSense.css @@ -70,7 +70,7 @@ h1 a:hover, h1 a:active { } /* Zero-width optional linebreaks can help the browser to linebreak at 'good' places. - Unfortunately the two most compatible options aren't consistently supported. + Unfortunately the two most compatible options aren't consistently supported. "\00200B" or #8203; is part of unicode and widely implemented; and <wbr> is widely supported even on old browsers but not IE<5.5 and IE>7. http://stackoverflow.com/a/23759279/2238378 suggests a neat "80%" solution for broad diff --git a/src/usr/local/www/diag_reboot.php b/src/usr/local/www/diag_reboot.php index 8b6229e..8052e40 100644 --- a/src/usr/local/www/diag_reboot.php +++ b/src/usr/local/www/diag_reboot.php @@ -43,8 +43,8 @@ $guiretry = 20; // Seconds to try again if $guitimeout was not long enough $pgtitle = array(gettext("Diagnostics"), gettext("Reboot")); include("head.inc"); - -if (($_SERVER['REQUEST_METHOD'] == 'POST') && ($_POST['override'] != "yes")) { +if (($_SERVER['REQUEST_METHOD'] == 'POST') && (empty($_POST['override']) || + ($_POST['override'] != "yes"))): if (DEBUG) { print_info_box(gettext("Not actually rebooting (DEBUG is set true)."), 'success'); } else { @@ -98,7 +98,7 @@ events.push(function() { //]]> </script> <?php -} else { +else: ?> @@ -135,6 +135,6 @@ events.push(function() { </script> <?php -} +endif; include("foot.inc"); diff --git a/src/usr/local/www/firewall_aliases.php b/src/usr/local/www/firewall_aliases.php index 55069d8..ec98e15 100644 --- a/src/usr/local/www/firewall_aliases.php +++ b/src/usr/local/www/firewall_aliases.php @@ -48,15 +48,8 @@ if ($_POST) { $retval = 0; /* reload all components that use aliases */ - $retval = filter_configure(); + $retval |= filter_configure(); - if (stristr($retval, "error") <> true) { - $savemsg = get_std_save_message($retval); - $class = "success"; - } else { - $savemsg = $retval; - $class = "danger"; - } if ($retval == 0) { clear_subsystem_dirty('aliases'); } @@ -99,8 +92,7 @@ if ($_GET['act'] == "del") { // Static routes find_alias_reference(array('staticroutes', 'route'), array('network'), $alias_name, $is_alias_referenced, $referenced_by); if ($is_alias_referenced == true) { - $savemsg = sprintf(gettext("Cannot delete alias. Currently in use by %s."), htmlspecialchars($referenced_by)); - $class = "danger"; + $delete_error = sprintf(gettext("Cannot delete alias. Currently in use by %s."), htmlspecialchars($referenced_by)); } else { if (preg_match("/urltable/i", $a_aliases[$_GET['id']]['type'])) { // this is a URL table type alias, delete its file as well @@ -173,8 +165,11 @@ $shortcut_section = "aliases"; include("head.inc"); -if ($savemsg) { - print_info_box($savemsg, $class); +if ($delete_error) { + print_info_box($delete_error, 'danger'); +} +if ($_POST['apply']) { + print_apply_result_box($retval); } if (is_subsystem_dirty('aliases')) { diff --git a/src/usr/local/www/firewall_nat.php b/src/usr/local/www/firewall_nat.php index 3fd7c36..681c981 100644 --- a/src/usr/local/www/firewall_nat.php +++ b/src/usr/local/www/firewall_nat.php @@ -86,7 +86,6 @@ if ($_POST) { $retval = 0; $retval |= filter_configure(); - $savemsg = get_std_save_message($retval); pfSense_handle_custom_code("/usr/local/pkg/firewall_nat/apply"); @@ -186,8 +185,8 @@ if (isset($_POST['del_x'])) { $pgtitle = array(gettext("Firewall"), gettext("NAT"), gettext("Port Forward")); include("head.inc"); -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($_POST['apply']) { + print_apply_result_box($retval); } if (is_subsystem_dirty('natconf')) { diff --git a/src/usr/local/www/firewall_nat_1to1.php b/src/usr/local/www/firewall_nat_1to1.php index 5ae075b..87f9169 100644 --- a/src/usr/local/www/firewall_nat_1to1.php +++ b/src/usr/local/www/firewall_nat_1to1.php @@ -68,7 +68,6 @@ if ($_POST) { if ($_POST['apply']) { $retval = 0; $retval |= filter_configure(); - $savemsg = get_std_save_message($retval); if ($retval == 0) { clear_subsystem_dirty('natconf'); @@ -122,8 +121,8 @@ if (isset($_POST['del_x'])) { $pgtitle = array(gettext("Firewall"), gettext("NAT"), gettext("1:1")); include("head.inc"); -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($_POST['apply']) { + print_apply_result_box($retval); } if (is_subsystem_dirty('natconf')) { diff --git a/src/usr/local/www/firewall_nat_npt.php b/src/usr/local/www/firewall_nat_npt.php index b585d99..e2d7856 100644 --- a/src/usr/local/www/firewall_nat_npt.php +++ b/src/usr/local/www/firewall_nat_npt.php @@ -69,7 +69,6 @@ if ($_POST) { if ($_POST['apply']) { $retval = 0; $retval |= filter_configure(); - $savemsg = get_std_save_message($retval); if ($retval == 0) { clear_subsystem_dirty('natconf'); @@ -122,8 +121,8 @@ if (isset($_POST['del_x'])) { $pgtitle = array(gettext("Firewall"), gettext("NAT"), gettext("NPt")); include("head.inc"); -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($_POST['apply']) { + print_apply_result_box($retval); } if (is_subsystem_dirty('natconf')) { diff --git a/src/usr/local/www/firewall_nat_out.php b/src/usr/local/www/firewall_nat_out.php index 6915780..a09988c 100644 --- a/src/usr/local/www/firewall_nat_out.php +++ b/src/usr/local/www/firewall_nat_out.php @@ -82,12 +82,6 @@ if ($_POST['apply']) { $retval = 0; $retval |= filter_configure(); - if (stristr($retval, "error") <> true) { - $savemsg = get_std_save_message($retval); - } else { - $savemsg = $retval; - } - if ($retval == 0) { clear_subsystem_dirty('natconf'); clear_subsystem_dirty('filter'); @@ -139,7 +133,7 @@ if ($_POST['save']) { } } } - $savemsg = gettext("Default rules for each interface have been created."); + $default_rules_msg = gettext("Default rules for each interface have been created."); unset($FilterIflist, $GatewaysList); } @@ -206,8 +200,12 @@ if (isset($_POST['del_x'])) { $pgtitle = array(gettext("Firewall"), gettext("NAT"), gettext("Outbound")); include("head.inc"); -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($default_rules_msg) { + print_info_box($default_rules_msg, 'success'); +} + +if ($_POST['apply']) { + print_apply_result_box($retval); } if (is_subsystem_dirty('natconf')) { diff --git a/src/usr/local/www/firewall_rules_edit.php b/src/usr/local/www/firewall_rules_edit.php index 9e72d9c..f280691 100644 --- a/src/usr/local/www/firewall_rules_edit.php +++ b/src/usr/local/www/firewall_rules_edit.php @@ -1245,7 +1245,7 @@ if ($if == "FloatingRules" || isset($pconfig['floating'])) { ) )); - $section->addInput(new Form_Input( + $form->addGlobal(new Form_Input( 'floating', 'Floating', 'hidden', diff --git a/src/usr/local/www/firewall_shaper.php b/src/usr/local/www/firewall_shaper.php index 82410cc..ef50e8b 100644 --- a/src/usr/local/www/firewall_shaper.php +++ b/src/usr/local/www/firewall_shaper.php @@ -121,19 +121,11 @@ if ($_GET) { } if (write_config()) { + $changes_applied = true; $retval = 0; $retval |= filter_configure(); - - if (stristr($retval, "error") <> true) { - $savemsg = get_std_save_message($retval); - $class = 'success'; - } else { - $savemsg = $retval; - $class = 'warning'; - } } else { - $savemsg = gettext("Unable to write config.xml (Access Denied?)."); - $class = 'warning'; + $no_write_config_msg = gettext("Unable to write config.xml (Access Denied?)."); } $dfltmsg = true; @@ -280,17 +272,9 @@ if ($_POST) { } } else if ($_POST['apply']) { write_config(); - + $changes_applied = true; $retval = 0; - $retval = filter_configure(); - - if (stristr($retval, "error") <> true) { - $savemsg = get_std_save_message($retval); - $class = 'success'; - } else { - $savemsg = $retval; - $class = 'warning'; - } + $retval |= filter_configure(); /* reset rrd queues */ system("rm -f /var/db/rrd/*queuedrops.rrd"); @@ -369,8 +353,12 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, $class); +if ($no_write_config_msg) { + print_info_box($no_write_config_msg, 'danger'); +} + +if ($changes_applied) { + print_apply_result_box($retval); } if (is_subsystem_dirty('shaper')) { @@ -452,7 +440,7 @@ if (!$dfltmsg && $sform) { </table> </div> -<?php if (empty(get_interface_list_to_show())): ?> +<?php if (empty(get_interface_list_to_show()) && (!is_array($altq_list_queues) || (count($altq_list_queues) == 0))): ?> <div> <div class="infoblock blockopen"> <?php print_info_box(gettext("This firewall does not have any interfaces assigned that are capable of using ALTQ traffic shaping."), 'danger', false); ?> diff --git a/src/usr/local/www/firewall_shaper_queues.php b/src/usr/local/www/firewall_shaper_queues.php index 0bdb99e..a25c470 100644 --- a/src/usr/local/www/firewall_shaper_queues.php +++ b/src/usr/local/www/firewall_shaper_queues.php @@ -167,15 +167,7 @@ if ($_POST['apply']) { $retval = 0; /* Setup pf rules since the user may have changed the optimization value */ - $retval = filter_configure(); - $savemsg = get_std_save_message($retval); - if (stristr($retval, "error") <> true) { - $savemsg = get_std_save_message($retval); - $class = 'alert-success'; - } else { - $savemsg = $retval; - $class = 'alert-danger'; - } + $retval |= filter_configure(); /* reset rrd queues */ system("rm -f /var/db/rrd/*queuedrops.rrd"); @@ -198,8 +190,8 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, $class); +if ($_POST['apply']) { + print_apply_result_box($retval); } if (is_subsystem_dirty('shaper')) { @@ -231,7 +223,7 @@ display_top_tabs($tab_array); </div> </form> -<?php if (empty(get_interface_list_to_show())): ?> +<?php if (empty(get_interface_list_to_show()) && (!is_array($altq_list_queues) || (count($altq_list_queues) == 0))): ?> <div> <div class="infoblock blockopen"> <?php print_info_box(gettext("This firewall does not have any interfaces assigned that are capable of using ALTQ traffic shaping."), 'danger', false); ?> diff --git a/src/usr/local/www/firewall_shaper_vinterface.php b/src/usr/local/www/firewall_shaper_vinterface.php index 74526e9..5de573f 100644 --- a/src/usr/local/www/firewall_shaper_vinterface.php +++ b/src/usr/local/www/firewall_shaper_vinterface.php @@ -134,20 +134,11 @@ if ($_GET) { } } if (write_config()) { + $changes_applied = true; $retval = 0; - $retval = filter_configure(); - - if (stristr($retval, "error") != true) { - $savemsg = get_std_save_message($retval); - $class = 'success'; - } else { - $savemsg = $retval; - $class = 'danger'; - } - + $retval |= filter_configure(); } else { - $savemsg = gettext("Unable to write config.xml (Access Denied?)."); - $class = 'danger'; + $no_write_config_msg = gettext("Unable to write config.xml (Access Denied?)."); } $dfltmsg = true; @@ -271,16 +262,9 @@ if ($_POST) { } else if ($_POST['apply']) { write_config(); + $changes_applied = true; $retval = 0; - $retval = filter_configure(); - - if (stristr($retval, "error") != true) { - $savemsg = get_std_save_message($retval); - $class = 'success'; - } else { - $savemsg = $retval; - $class = 'danger'; - } + $retval |= filter_configure(); /* XXX: TODO Make dummynet pretty graphs */ // enable_rrd_graphing(); @@ -369,8 +353,12 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, $class); +if ($no_write_config_msg) { + print_info_box($no_write_config_msg, 'danger'); +} + +if ($changes_applied) { + print_apply_result_box($retval); } if (is_subsystem_dirty('shaper')) { diff --git a/src/usr/local/www/firewall_shaper_wizards.php b/src/usr/local/www/firewall_shaper_wizards.php index 594ed63..b9d647e 100644 --- a/src/usr/local/www/firewall_shaper_wizards.php +++ b/src/usr/local/www/firewall_shaper_wizards.php @@ -42,14 +42,7 @@ if ($_POST['apply']) { $retval = 0; /* Setup pf rules since the user may have changed the optimization value */ - $retval = filter_configure(); - if (stristr($retval, "error") <> true) { - $savemsg = get_std_save_message($retval); - $class = 'success'; - } else { - $savemsg = $retval; - $class = 'warning'; - } + $retval |= filter_configure(); /* reset rrd queues */ unlink_if_exists("/var/db/rrd/*queuedrops.rrd"); @@ -82,8 +75,8 @@ $tab_array[] = array(gettext("Limiters"), false, "firewall_shaper_vinterface.php $tab_array[] = array(gettext("Wizards"), true, "firewall_shaper_wizards.php"); display_top_tabs($tab_array); -if ($savemsg) { - print_info_box($savemsg, $class); +if ($_POST['apply']) { + print_apply_result_box($retval); } if (is_subsystem_dirty('shaper')) { diff --git a/src/usr/local/www/firewall_virtual_ip.php b/src/usr/local/www/firewall_virtual_ip.php index 33a1f4f..a15a60b 100644 --- a/src/usr/local/www/firewall_virtual_ip.php +++ b/src/usr/local/www/firewall_virtual_ip.php @@ -79,7 +79,6 @@ if ($_POST) { $retval = 0; $retval |= filter_configure(); - $savemsg = get_std_save_message($retval); clear_subsystem_dirty('vip'); } @@ -240,8 +239,8 @@ include("head.inc"); if ($input_errors) { print_input_errors($input_errors); -} else if ($savemsg) { - print_info_box($savemsg, 'success'); +} else if ($_POST['apply']) { + print_apply_result_box($retval); } else if (is_subsystem_dirty('vip')) { print_apply_box(gettext("The VIP configuration has been changed.") . "<br />" . gettext("The changes must be applied for them to take effect.")); } diff --git a/src/usr/local/www/guiconfig.inc b/src/usr/local/www/guiconfig.inc index d4fc383..c9e78dc 100644 --- a/src/usr/local/www/guiconfig.inc +++ b/src/usr/local/www/guiconfig.inc @@ -323,6 +323,27 @@ function print_apply_box($msg) { print_info_box($msg, "warning", "apply", gettext("Apply Changes"), 'fa-check', 'success'); } +// Format and print a box reporting that changes have been applied +// $retval = status value from the functions called to apply the changes +// 0 is good +// non-zero is a problem +// $extra_text = optional extra text to display after the standard message +function print_apply_result_box($retval, $extra_text="") { + $result_msg = get_std_save_message($retval); + if ($retval === 0) { + // 0 is success + $severity = "success"; + } else { + // non-zero means there was some problem + $severity = "warning"; + } + + if (strlen($extra_text) > 0) { + $result_msg .= " " . $extra_text; + } + print_info_box($result_msg, $severity); +} + /* * Print Bootstrap callout * @@ -350,10 +371,16 @@ function print_callout($msg, $class = 'info', $heading = '') { echo $callout; } -function get_std_save_message($ok) { +function get_std_save_message($retval) { $filter_related = false; $filter_pages = array("nat", "filter"); - $to_return = gettext("The changes have been applied successfully."); + if ($retval === 0) { + // 0 is success + $to_return = gettext("The changes have been applied successfully."); + } else { + // non-zero means there was some problem + $to_return = gettext("There was a problem applying the changes. See the <a href=\"status_logs.php\">System Logs</a>."); + } foreach ($filter_pages as $fp) { if (stristr($_SERVER['SCRIPT_FILENAME'], $fp)) { $filter_related = true; @@ -508,7 +535,7 @@ function genhtmltitle($title) { $bc = ""; } - return $heading . $bc; + return $bc; } /* update the changedesc and changecount(er) variables */ diff --git a/src/usr/local/www/head.inc b/src/usr/local/www/head.inc index 24bf835..6205772 100644 --- a/src/usr/local/www/head.inc +++ b/src/usr/local/www/head.inc @@ -425,7 +425,7 @@ $allow_clear_notices = false; if (are_notices_pending()) { // Evaluate user privs to determine if notices should be displayed, and if the user can clear them. $user_entry = getUserEntry($_SESSION['Username']); - if (userHasPrivilege($user_entry, "user-view-clear-notices") || userHasPrivilege($user_entry, "page-all")) { + if (isAdminUID($_SESSION['Username']) || userHasPrivilege($user_entry, "user-view-clear-notices") || userHasPrivilege($user_entry, "page-all")) { $display_notices = true; $allow_clear_notices = true; } elseif (userHasPrivilege($user_entry, "user-view-notices")) { diff --git a/src/usr/local/www/interfaces.php b/src/usr/local/www/interfaces.php index a63144d..8391461 100755 --- a/src/usr/local/www/interfaces.php +++ b/src/usr/local/www/interfaces.php @@ -407,11 +407,14 @@ if (isset($wancfg['wireless'])) { } +$changes_applied = false; + if ($_POST['apply']) { unset($input_errors); if (!is_subsystem_dirty('interfaces')) { $input_errors[] = gettext("The settings have already been applied!"); } else { + $retval = 0; unlink_if_exists("{$g['tmp_path']}/config.cache"); clear_subsystem_dirty('interfaces'); @@ -440,24 +443,24 @@ if ($_POST['apply']) { } } /* restart snmp so that it binds to correct address */ - services_snmpd_configure(); + $retval |= services_snmpd_configure(); /* sync filter configuration */ setup_gateways_monitor(); clear_subsystem_dirty('interfaces'); - filter_configure(); + $retval |= filter_configure(); enable_rrd_graphing(); + $changes_applied = true; + if (is_subsystem_dirty('staticroutes') && (system_routing_configure() == 0)) { clear_subsystem_dirty('staticroutes'); } } @unlink("{$g['tmp_path']}/.interfaces.apply"); - header("Location: interfaces.php?if={$if}"); - exit; } else if ($_POST) { unset($input_errors); @@ -1611,7 +1614,7 @@ function check_wireless_mode() { if (!interface_wireless_clone("{$wlanif}_", $wancfg)) { $input_errors[] = sprintf(gettext("Unable to change mode to %s. The maximum number of wireless clones supported in this mode may have been reached."), $wlan_modes[$wancfg['wireless']['mode']]); } else { - mwexec("/sbin/ifconfig " . escapeshellarg($wlanif) . "_ destroy"); + pfSense_interface_destroy("{$wlanif}_"); } $wancfg['wireless']['mode'] = $old_wireless_mode; } @@ -1695,11 +1698,10 @@ if (is_subsystem_dirty('interfaces')) { gettext("Don't forget to adjust the DHCP Server range if needed after applying.")); } -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($changes_applied) { + print_apply_result_box($retval); } - $form = new Form(); $section = new Form_Section('General Configuration'); diff --git a/src/usr/local/www/interfaces_assign.php b/src/usr/local/www/interfaces_assign.php index b647fea..26b7a88 100644 --- a/src/usr/local/www/interfaces_assign.php +++ b/src/usr/local/www/interfaces_assign.php @@ -244,7 +244,7 @@ if (isset($_POST['add']) && isset($_POST['if_add'])) { write_config(); - $savemsg = gettext("Interface has been added."); + $action_msg = gettext("Interface has been added."); $class = "success"; } @@ -255,15 +255,9 @@ if (isset($_POST['add']) && isset($_POST['if_add'])) { } else { write_config(); - $retval = filter_configure(); - - if (stristr($retval, "error") <> true) { - $savemsg = get_std_save_message($retval); - $class = "success"; - } else { - $savemsg = $retval; - $class = "danger"; - } + $changes_applied = true; + $retval = 0; + $retval |= filter_configure(); } } else if (isset($_POST['Submit'])) { @@ -438,7 +432,7 @@ if (isset($_POST['add']) && isset($_POST['if_add'])) { link_interface_to_vlans($realid, "update"); - $savemsg = gettext("Interface has been deleted."); + $action_msg = gettext("Interface has been deleted."); $class = "success"; } } @@ -464,14 +458,14 @@ include("head.inc"); if (file_exists("/var/run/interface_mismatch_reboot_needed")) { if ($_POST) { if ($rebootingnow) { - $savemsg = gettext("The system is now rebooting. Please wait."); + $action_msg = gettext("The system is now rebooting. Please wait."); $class = "success"; } else { $applymsg = gettext("Reboot is needed. Please apply the settings in order to reboot."); $class = "warning"; } } else { - $savemsg = gettext("Interface mismatch detected. Please resolve the mismatch, save and then click 'Apply Changes'. The firewall will reboot afterwards."); + $action_msg = gettext("Interface mismatch detected. Please resolve the mismatch, save and then click 'Apply Changes'. The firewall will reboot afterwards."); $class = "warning"; } } @@ -482,8 +476,10 @@ if (file_exists("/tmp/reload_interfaces")) { echo "<br /></p>\n"; } elseif ($applymsg) { print_apply_box($applymsg); -} elseif ($savemsg) { - print_info_box($savemsg, $class); +} elseif ($action_msg) { + print_info_box($action_msg, $class); +} elseif ($changes_applied) { + print_apply_result_box($retval); } pfSense_handle_custom_code("/usr/local/pkg/interfaces_assign/pre_input_errors"); diff --git a/src/usr/local/www/interfaces_bridge.php b/src/usr/local/www/interfaces_bridge.php index c9631d7..359af1c 100644 --- a/src/usr/local/www/interfaces_bridge.php +++ b/src/usr/local/www/interfaces_bridge.php @@ -60,7 +60,7 @@ if ($_GET['act'] == "del") { if (!does_interface_exist($a_bridges[$_GET['id']]['bridgeif'])) { log_error("Bridge interface does not exist, skipping ifconfig destroy."); } else { - mwexec("/sbin/ifconfig " . $a_bridges[$_GET['id']]['bridgeif'] . " destroy"); + pfSense_interface_destroy($a_bridges[$_GET['id']]['bridgeif']); } unset($a_bridges[$_GET['id']]); diff --git a/src/usr/local/www/interfaces_gif.php b/src/usr/local/www/interfaces_gif.php index 1797092..b0581ec 100644 --- a/src/usr/local/www/interfaces_gif.php +++ b/src/usr/local/www/interfaces_gif.php @@ -56,7 +56,7 @@ if ($_GET['act'] == "del") { } else if (gif_inuse($_GET['id'])) { $input_errors[] = gettext("This gif TUNNEL cannot be deleted because it is still being used as an interface."); } else { - mwexec("/sbin/ifconfig " . $a_gifs[$_GET['id']]['gifif'] . " destroy"); + pfSense_interface_destroy($a_gifs[$_GET['id']]['gifif']); unset($a_gifs[$_GET['id']]); write_config(); diff --git a/src/usr/local/www/interfaces_gre.php b/src/usr/local/www/interfaces_gre.php index a69edd6..9f2d8c0 100644 --- a/src/usr/local/www/interfaces_gre.php +++ b/src/usr/local/www/interfaces_gre.php @@ -57,7 +57,7 @@ if ($_GET['act'] == "del") { } else if (gre_inuse($_GET['id'])) { $input_errors[] = gettext("This GRE tunnel cannot be deleted because it is still being used as an interface."); } else { - mwexec("/sbin/ifconfig " . $a_gres[$_GET['id']]['greif'] . " destroy"); + pfSense_interface_destroy($a_gres[$_GET['id']]['greif']); unset($a_gres[$_GET['id']]); write_config(); diff --git a/src/usr/local/www/interfaces_lagg.php b/src/usr/local/www/interfaces_lagg.php index c521558..23deb7d 100644 --- a/src/usr/local/www/interfaces_lagg.php +++ b/src/usr/local/www/interfaces_lagg.php @@ -63,7 +63,7 @@ if ($_GET['act'] == "del") { } else if (lagg_inuse($_GET['id'])) { $input_errors[] = gettext("This LAGG interface cannot be deleted because it is still being used."); } else { - mwexec_bg("/sbin/ifconfig " . $a_laggs[$_GET['id']]['laggif'] . " destroy"); + pfSense_interface_destroy($a_laggs[$_GET['id']]['laggif']); unset($a_laggs[$_GET['id']]); write_config(); diff --git a/src/usr/local/www/interfaces_qinq.php b/src/usr/local/www/interfaces_qinq.php index 63fa1b4..1997c19 100644 --- a/src/usr/local/www/interfaces_qinq.php +++ b/src/usr/local/www/interfaces_qinq.php @@ -67,7 +67,7 @@ if ($_GET['act'] == "del") { } mwexec("/usr/sbin/ngctl shutdown {$qinq['vlanif']}qinq:"); mwexec("/usr/sbin/ngctl shutdown {$qinq['vlanif']}:"); - mwexec("/sbin/ifconfig {$qinq['vlanif']} destroy"); + pfSense_interface_destroy($qinq['vlanif']); unset($a_qinqs[$id]); write_config(); diff --git a/src/usr/local/www/interfaces_wireless.php b/src/usr/local/www/interfaces_wireless.php index dafe49d..304eca2 100644 --- a/src/usr/local/www/interfaces_wireless.php +++ b/src/usr/local/www/interfaces_wireless.php @@ -57,7 +57,7 @@ if ($_GET['act'] == "del") { if (clone_inuse($_GET['id'])) { $input_errors[] = gettext("This wireless clone cannot be deleted because it is assigned as an interface."); } else { - mwexec("/sbin/ifconfig " . $a_clones[$_GET['id']]['cloneif'] . " destroy"); + pfSense_interface_destroy($a_clones[$_GET['id']]['cloneif']); unset($a_clones[$_GET['id']]); write_config(); diff --git a/src/usr/local/www/interfaces_wireless_edit.php b/src/usr/local/www/interfaces_wireless_edit.php index 419f9c6..d30b5c4 100644 --- a/src/usr/local/www/interfaces_wireless_edit.php +++ b/src/usr/local/www/interfaces_wireless_edit.php @@ -125,7 +125,7 @@ if ($_POST) { } else { if (isset($id) && $a_clones[$id]) { if ($clone['if'] != $a_clones[$id]['if']) { - mwexec("/sbin/ifconfig " . $a_clones[$id]['cloneif'] . " destroy"); + pfSense_interface_destroy($a_clones[$id]['cloneif']); } $input_errors[] = sprintf(gettext("Created with id %s"), $id); $a_clones[$id] = $clone; diff --git a/src/usr/local/www/js/pfSense.js b/src/usr/local/www/js/pfSense.js index da33129..2a6bc16 100644 --- a/src/usr/local/www/js/pfSense.js +++ b/src/usr/local/www/js/pfSense.js @@ -143,7 +143,7 @@ $(function() { // Use element title in the confirmation message, or if not available // the element value $('.btn-danger, .fa-trash').on('click', function(e){ - if (!($(this).hasClass('no-confirm'))) { + if (!($(this).hasClass('no-confirm')) && !($(this).hasClass('icon-embed-btn'))) { var msg = $.trim(this.textContent).toLowerCase(); if (!msg) @@ -230,7 +230,7 @@ $(function() { $('.table-rowdblclickedit>tbody>tr').dblclick(function () { $(this).find(".fa-pencil")[0].click(); }); - + // Focus first input $(':input:enabled:visible:first').focus(); @@ -238,7 +238,7 @@ $(function() { $(this).css('height', 80).resizable({minHeight: 80, minWidth: 200}).parent().css('padding-bottom', 0); $(this).css('height', 78); }); - + // Run in-page defined events while (func = window.events.shift()) func(); diff --git a/src/usr/local/www/js/pfSenseHelpers.js b/src/usr/local/www/js/pfSenseHelpers.js index b77ec1f..2eac30a 100644 --- a/src/usr/local/www/js/pfSenseHelpers.js +++ b/src/usr/local/www/js/pfSenseHelpers.js @@ -353,9 +353,9 @@ function add_row() { $('[id^=delete]').click(function(event) { if ($('.repeatable').length > 1) { if ((typeof retainhelp) == "undefined") - moveHelpText(event.target.id); + moveHelpText($(this).attr("id")); - delete_row(event.target.id); + delete_row($(this).attr("id")); } else { alert('The last row may not be deleted.'); } @@ -375,9 +375,9 @@ $('[id^=addrow]').click(function() { $('[id^=delete]').click(function(event) { if ($('.repeatable').length > 1) { if ((typeof retainhelp) == "undefined") - moveHelpText(event.target.id); + moveHelpText($(this).attr("id")); - delete_row(event.target.id); + delete_row($(this).attr("id")); } else { alert('The last row may not be deleted.'); } diff --git a/src/usr/local/www/load_balancer_monitor.php b/src/usr/local/www/load_balancer_monitor.php index a6875ca..f85f972 100644 --- a/src/usr/local/www/load_balancer_monitor.php +++ b/src/usr/local/www/load_balancer_monitor.php @@ -43,7 +43,6 @@ if ($_POST) { $retval |= filter_configure(); $retval |= relayd_configure(); - $savemsg = get_std_save_message($retval); clear_subsystem_dirty('loadbalancer'); } } @@ -79,8 +78,8 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($_POST['apply']) { + print_apply_result_box($retval); } if (is_subsystem_dirty('loadbalancer')) { diff --git a/src/usr/local/www/load_balancer_pool.php b/src/usr/local/www/load_balancer_pool.php index d9788cd..48b33ee 100644 --- a/src/usr/local/www/load_balancer_pool.php +++ b/src/usr/local/www/load_balancer_pool.php @@ -47,7 +47,6 @@ if ($_POST) { $retval |= filter_configure(); $retval |= relayd_configure(); - $savemsg = get_std_save_message($retval); clear_subsystem_dirty('loadbalancer'); } } @@ -93,8 +92,8 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($_POST['apply']) { + print_apply_result_box($retval); } if (is_subsystem_dirty('loadbalancer')) { diff --git a/src/usr/local/www/load_balancer_setting.php b/src/usr/local/www/load_balancer_setting.php index 9ae4a95..a8470c3 100644 --- a/src/usr/local/www/load_balancer_setting.php +++ b/src/usr/local/www/load_balancer_setting.php @@ -46,7 +46,6 @@ if ($_POST) { $retval |= filter_configure(); $retval |= relayd_configure(); - $savemsg = get_std_save_message($retval); clear_subsystem_dirty('loadbalancer'); } else { unset($input_errors); @@ -92,8 +91,8 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($_POST['apply']) { + print_apply_result_box($retval); } if (is_subsystem_dirty('loadbalancer')) { diff --git a/src/usr/local/www/load_balancer_virtual_server.php b/src/usr/local/www/load_balancer_virtual_server.php index f07c7ac..8082203 100644 --- a/src/usr/local/www/load_balancer_virtual_server.php +++ b/src/usr/local/www/load_balancer_virtual_server.php @@ -45,7 +45,6 @@ if ($_POST) { $retval = 0; $retval |= filter_configure(); $retval |= relayd_configure(); - $savemsg = get_std_save_message($retval); /* Wipe out old relayd anchors no longer in use. */ cleanup_lb_marked(); clear_subsystem_dirty('loadbalancer'); @@ -113,8 +112,8 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($_POST['apply']) { + print_apply_result_box($retval); } if (is_subsystem_dirty('loadbalancer')) { diff --git a/src/usr/local/www/pkg_edit.php b/src/usr/local/www/pkg_edit.php index bfb4514..ba8815d 100644 --- a/src/usr/local/www/pkg_edit.php +++ b/src/usr/local/www/pkg_edit.php @@ -1500,6 +1500,10 @@ if ($pkg['custom_php_after_form_command']) { eval($pkg['custom_php_after_form_command']); } + +$hidemsg = gettext("Show Advanced Options"); +$showmsg = gettext("Hide Advanced Options"); + if ($pkg['fields']['field'] != "") { ?> <script type="text/javascript"> //<![CDATA[ @@ -1520,10 +1524,10 @@ if ($pkg['fields']['field'] != "") { ?> if (advanced_visible) { $('.advancedoptions').show(); - $("#showadv").prop('value', 'Hide advanced Options'); + $("#showadv").html('<i class="fa fa-cog icon-embed-btn"></i>' + "<?=$showmsg?>"); } else { $('.advancedoptions').hide(); - $("#showadv").prop('value', 'Show advanced Options'); + $("#showadv").html('<i class="fa fa-cog icon-embed-btn"></i>' + "<?=$hidemsg?>"); } }); diff --git a/src/usr/local/www/services_captiveportal.php b/src/usr/local/www/services_captiveportal.php index 4922a07..14a9293 100644 --- a/src/usr/local/www/services_captiveportal.php +++ b/src/usr/local/www/services_captiveportal.php @@ -512,10 +512,6 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); -} - $tab_array = array(); $tab_array[] = array(gettext("Configuration"), true, "services_captiveportal.php?zone={$cpzone}"); $tab_array[] = array(gettext("MACs"), false, "services_captiveportal_mac.php?zone={$cpzone}"); diff --git a/src/usr/local/www/services_captiveportal_hostname.php b/src/usr/local/www/services_captiveportal_hostname.php index d93dd79..433f5b9 100644 --- a/src/usr/local/www/services_captiveportal_hostname.php +++ b/src/usr/local/www/services_captiveportal_hostname.php @@ -98,10 +98,6 @@ if ($_GET['act'] == "del" && !empty($cpzone) && isset($cpzoneid)) { include("head.inc"); -if ($savemsg) { - print_info_box($savemsg, 'success'); -} - $tab_array = array(); $tab_array[] = array(gettext("Configuration"), false, "services_captiveportal.php?zone={$cpzone}"); $tab_array[] = array(gettext("MACs"), false, "services_captiveportal_mac.php?zone={$cpzone}"); diff --git a/src/usr/local/www/services_captiveportal_ip.php b/src/usr/local/www/services_captiveportal_ip.php index b2da179..0a729eb 100644 --- a/src/usr/local/www/services_captiveportal_ip.php +++ b/src/usr/local/www/services_captiveportal_ip.php @@ -92,10 +92,6 @@ if ($_GET['act'] == "del" && !empty($cpzone) && isset($cpzoneid)) { include("head.inc"); -if ($savemsg) { - print_info_box($savemsg, 'success'); -} - $tab_array = array(); $tab_array[] = array(gettext("Configuration"), false, "services_captiveportal.php?zone={$cpzone}"); $tab_array[] = array(gettext("MACs"), false, "services_captiveportal_mac.php?zone={$cpzone}"); diff --git a/src/usr/local/www/services_captiveportal_mac.php b/src/usr/local/www/services_captiveportal_mac.php index 8e37a1e..79cfee3 100644 --- a/src/usr/local/www/services_captiveportal_mac.php +++ b/src/usr/local/www/services_captiveportal_mac.php @@ -76,7 +76,6 @@ if ($_POST) { mwexec("/sbin/ipfw {$g['tmp_path']}/passthrumac_gui"); @unlink("{$g['tmp_path']}/passthrumac_gui"); } - $savemsg = get_std_save_message($retval); if ($retval == 0) { clear_subsystem_dirty('passthrumac'); } @@ -152,8 +151,8 @@ if ($_GET['act'] == "del") { include("head.inc"); -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($_POST['apply']) { + print_apply_result_box($retval); } if (is_subsystem_dirty('passthrumac')) { diff --git a/src/usr/local/www/services_captiveportal_vouchers_edit.php b/src/usr/local/www/services_captiveportal_vouchers_edit.php index bad9d32..8f3e1e0 100644 --- a/src/usr/local/www/services_captiveportal_vouchers_edit.php +++ b/src/usr/local/www/services_captiveportal_vouchers_edit.php @@ -175,10 +175,6 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); -} - $form = new Form(); $section = new Form_Section('Voucher Rolls'); diff --git a/src/usr/local/www/services_captiveportal_zones.php b/src/usr/local/www/services_captiveportal_zones.php index 12f301c..6454a2a 100644 --- a/src/usr/local/www/services_captiveportal_zones.php +++ b/src/usr/local/www/services_captiveportal_zones.php @@ -60,10 +60,6 @@ $pgtitle = array(gettext("Services"), gettext("Captive Portal")); $shortcut_section = "captiveportal"; include("head.inc"); -if ($savemsg) { - print_info_box($savemsg, 'success'); -} - if (is_subsystem_dirty('captiveportal')) { print_apply_box(gettext("The Captive Portal entry list has been changed.") . "<br />" . gettext("The changes must be applied for them to take effect.")); } diff --git a/src/usr/local/www/services_checkip_edit.php b/src/usr/local/www/services_checkip_edit.php index 932366e..2774c27 100644 --- a/src/usr/local/www/services_checkip_edit.php +++ b/src/usr/local/www/services_checkip_edit.php @@ -110,10 +110,6 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); -} - $form = new Form; $section = new Form_Section('Check IP Service'); diff --git a/src/usr/local/www/services_dhcp.php b/src/usr/local/www/services_dhcp.php index 426f1c3..db5ce1c 100644 --- a/src/usr/local/www/services_dhcp.php +++ b/src/usr/local/www/services_dhcp.php @@ -610,39 +610,38 @@ if (isset($_POST['save'])) { } if ((isset($_POST['save']) || isset($_POST['apply'])) && (!$input_errors)) { + $changes_applied = true; $retval = 0; $retvaldhcp = 0; $retvaldns = 0; /* dnsmasq_configure calls dhcpd_configure */ /* no need to restart dhcpd twice */ if (isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcpstatic'])) { - $retvaldns = services_dnsmasq_configure(); + $retvaldns |= services_dnsmasq_configure(); if ($retvaldns == 0) { clear_subsystem_dirty('hosts'); clear_subsystem_dirty('staticmaps'); } } else if (isset($config['unbound']['enable']) && isset($config['unbound']['regdhcpstatic'])) { - $retvaldns = services_unbound_configure(); + $retvaldns |= services_unbound_configure(); if ($retvaldns == 0) { clear_subsystem_dirty('unbound'); clear_subsystem_dirty('hosts'); clear_subsystem_dirty('staticmaps'); } } else { - $retvaldhcp = services_dhcpd_configure(); + $retvaldhcp |= services_dhcpd_configure(); if ($retvaldhcp == 0) { clear_subsystem_dirty('staticmaps'); } } if ($dhcpd_enable_changed) { - $retvalfc = filter_configure(); + $retvalfc |= filter_configure(); } if ($retvaldhcp == 1 || $retvaldns == 1 || $retvalfc == 1) { $retval = 1; } - - $savemsg = get_std_save_message($retval); } if ($act == "delpool") { @@ -733,8 +732,8 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($changes_applied) { + print_apply_result_box($retval); } if (is_subsystem_dirty('staticmaps')) { diff --git a/src/usr/local/www/services_dhcp_relay.php b/src/usr/local/www/services_dhcp_relay.php index e824b44..fc8e367 100644 --- a/src/usr/local/www/services_dhcp_relay.php +++ b/src/usr/local/www/services_dhcp_relay.php @@ -114,10 +114,10 @@ if ($_POST) { write_config(); + $changes_applied = true; $retval = 0; - $retval = services_dhcrelay_configure(); - $savemsg = get_std_save_message($retval); - filter_configure(); + $retval |= services_dhcrelay_configure(); + $retval |= filter_configure(); } } @@ -135,8 +135,8 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($changes_applied) { + print_apply_result_box($retval); } $form = new Form; diff --git a/src/usr/local/www/services_dhcpv6.php b/src/usr/local/www/services_dhcpv6.php index 44afcc4..820f89b 100644 --- a/src/usr/local/www/services_dhcpv6.php +++ b/src/usr/local/www/services_dhcpv6.php @@ -44,30 +44,30 @@ function dhcpv6_apply_changes($dhcpdv6_enable_changed) { /* dnsmasq_configure calls dhcpd_configure */ /* no need to restart dhcpd twice */ if (isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcpstatic'])) { - $retvaldns = services_dnsmasq_configure(); + $retvaldns |= services_dnsmasq_configure(); if ($retvaldns == 0) { clear_subsystem_dirty('hosts'); clear_subsystem_dirty('staticmaps'); } } else if (isset($config['unbound']['enable']) && isset($config['unbound']['regdhcpstatic'])) { - $retvaldns = services_unbound_configure(); + $retvaldns |= services_unbound_configure(); if ($retvaldns == 0) { clear_subsystem_dirty('unbound'); clear_subsystem_dirty('staticmaps'); } } else { - $retvaldhcp = services_dhcpd_configure(); + $retvaldhcp |= services_dhcpd_configure(); if ($retvaldhcp == 0) { clear_subsystem_dirty('staticmaps'); } } if ($dhcpdv6_enable_changed) { - $retvalfc = filter_configure(); + $retvalfc |= filter_configure(); } if ($retvaldhcp == 1 || $retvaldns == 1 || $retvalfc == 1) { $retval = 1; } - return get_std_save_message($retval); + return $retval; } if (!$g['services_dhcp_server_enable']) { @@ -184,7 +184,8 @@ if (is_array($dhcrelaycfg) && isset($dhcrelaycfg['enable']) && isset($dhcrelaycf } if (isset($_POST['apply'])) { - $savemsg = dhcpv6_apply_changes(false); + $changes_applied = true; + $retval = dhcpv6_apply_changes(false); } elseif (isset($_POST['save'])) { unset($input_errors); @@ -459,7 +460,8 @@ if (isset($_POST['apply'])) { write_config(); - $savemsg = dhcpv6_apply_changes($dhcpdv6_enable_changed); + $changes_applied = true; + $retval = dhcpv6_apply_changes($dhcpdv6_enable_changed); } } @@ -492,8 +494,8 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($changes_applied) { + print_apply_result_box($retval); } if (is_subsystem_dirty('staticmaps')) { diff --git a/src/usr/local/www/services_dhcpv6_relay.php b/src/usr/local/www/services_dhcpv6_relay.php index b6f1964..8f4135b 100644 --- a/src/usr/local/www/services_dhcpv6_relay.php +++ b/src/usr/local/www/services_dhcpv6_relay.php @@ -115,9 +115,9 @@ if ($_POST) { write_config(); + $changes_applied = true; $retval = 0; - $retval = services_dhcrelay6_configure(); - $savemsg = get_std_save_message($retval); + $retval |= services_dhcrelay6_configure(); } } @@ -135,8 +135,8 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($changes_applied) { + print_apply_result_box($retval); } $form = new Form; diff --git a/src/usr/local/www/services_dnsmasq.php b/src/usr/local/www/services_dnsmasq.php index fb74e7b..2885edd 100644 --- a/src/usr/local/www/services_dnsmasq.php +++ b/src/usr/local/www/services_dnsmasq.php @@ -113,8 +113,7 @@ domains_sort(); if ($_POST) { if ($_POST['apply']) { $retval = 0; - $retval = services_dnsmasq_configure(); - $savemsg = get_std_save_message($retval); + $retval |= services_dnsmasq_configure(); // Reload filter (we might need to sync to CARP hosts) filter_configure(); @@ -232,8 +231,8 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($_POST['apply']) { + print_apply_result_box($retval); } if (is_subsystem_dirty('hosts')) { diff --git a/src/usr/local/www/services_dyndns_edit.php b/src/usr/local/www/services_dyndns_edit.php index 55860f0..f270f75 100644 --- a/src/usr/local/www/services_dyndns_edit.php +++ b/src/usr/local/www/services_dyndns_edit.php @@ -64,6 +64,7 @@ if (isset($id) && isset($a_dyndns[$id])) { $pconfig['enable'] = !isset($a_dyndns[$id]['enable']); $pconfig['interface'] = $a_dyndns[$id]['interface']; $pconfig['wildcard'] = isset($a_dyndns[$id]['wildcard']); + $pconfig['proxied'] = isset($a_dyndns[$id]['proxied']); $pconfig['verboselog'] = isset($a_dyndns[$id]['verboselog']); $pconfig['curl_ipresolve_v4'] = isset($a_dyndns[$id]['curl_ipresolve_v4']); $pconfig['curl_ssl_verifypeer'] = isset($a_dyndns[$id]['curl_ssl_verifypeer']); @@ -158,6 +159,7 @@ if ($_POST) { $dyndns['domainname'] = $_POST['domainname']; $dyndns['mx'] = $_POST['mx']; $dyndns['wildcard'] = $_POST['wildcard'] ? true : false; + $dyndns['proxied'] = $_POST['proxied'] ? true : false; $dyndns['verboselog'] = $_POST['verboselog'] ? true : false; $dyndns['curl_ipresolve_v4'] = $_POST['curl_ipresolve_v4'] ? true : false; $dyndns['curl_ssl_verifypeer'] = $_POST['curl_ssl_verifypeer'] ? true : false; @@ -244,10 +246,6 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); -} - $form = new Form; $section = new Form_Section('Dynamic DNS Client'); @@ -323,6 +321,15 @@ $section->addInput(new Form_Checkbox( )); $section->addInput(new Form_Checkbox( + 'proxied', + 'CloudFlare Proxy', + 'Enable Proxy', + $pconfig['proxied'] +))->setHelp('Note: This enables CloudFlares Virtual DNS proxy. When Enabled it will route all traffic '. + 'through their servers. By Default this is disabled and your Real IP is exposed.'. + 'More info: <a href="https://blog.cloudflare.com/announcing-virtual-dns-ddos-mitigation-and-global-distribution-for-dns-traffic/" target="_blank">CloudFlare Blog</a>'); + +$section->addInput(new Form_Checkbox( 'verboselog', 'Verbose logging', 'Enable verbose logging', @@ -441,6 +448,7 @@ events.push(function() { hideInput('host', true); hideInput('mx', true); hideCheckbox('wildcard', true); + hideCheckbox('proxied', true); hideInput('zoneid', true); hideInput('ttl', true); break; @@ -456,6 +464,7 @@ events.push(function() { hideInput('host', false); hideInput('mx', false); hideCheckbox('wildcard', false); + hideCheckbox('proxied', true); hideInput('zoneid', false); hideInput('ttl', false); break; @@ -472,9 +481,24 @@ events.push(function() { hideInput('host', false); hideInput('mx', false); hideCheckbox('wildcard', false); + hideCheckbox('proxied', true); hideInput('zoneid', true); hideInput('ttl', true); break; + case "cloudflare-v6": + case "cloudflare": + hideGroupInput('domainname', true); + hideInput('resultmatch', true); + hideInput('updateurl', true); + hideInput('requestif', true); + hideCheckbox('curl_ipresolve_v4', true); + hideCheckbox('curl_ssl_verifypeer', true); + hideInput('host', false); + hideInput('mx', false); + hideCheckbox('wildcard', false); + hideCheckbox('proxied', false); + hideInput('zoneid', true); + hideInput('ttl', true); default: hideGroupInput('domainname', true); hideInput('resultmatch', true); @@ -485,6 +509,7 @@ events.push(function() { hideInput('host', false); hideInput('mx', false); hideCheckbox('wildcard', false); + hideCheckbox('proxied', true); hideInput('zoneid', true); hideInput('ttl', true); } diff --git a/src/usr/local/www/services_igmpproxy.php b/src/usr/local/www/services_igmpproxy.php index f3b8775..5de6aa1 100644 --- a/src/usr/local/www/services_igmpproxy.php +++ b/src/usr/local/www/services_igmpproxy.php @@ -42,15 +42,10 @@ $a_igmpproxy = &$config['igmpproxy']['igmpentry']; if ($_POST) { $pconfig = $_POST; + $changes_applied = true; $retval = 0; /* reload all components that use igmpproxy */ - $retval = services_igmpproxy_configure(); - - if (stristr($retval, "error") <> true) { - $savemsg = get_std_save_message($retval); - } else { - $savemsg = $retval; - } + $retval |= services_igmpproxy_configure(); clear_subsystem_dirty('igmpproxy'); } @@ -68,8 +63,8 @@ if ($_GET['act'] == "del") { $pgtitle = array(gettext("Services"), gettext("IGMP Proxy")); include("head.inc"); -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($changes_applied) { + print_apply_result_box($retval); } if (is_subsystem_dirty('igmpproxy')) { diff --git a/src/usr/local/www/services_ntpd.php b/src/usr/local/www/services_ntpd.php index 2adcfe0..47804c5 100644 --- a/src/usr/local/www/services_ntpd.php +++ b/src/usr/local/www/services_ntpd.php @@ -53,6 +53,10 @@ if ($_POST) { unset($input_errors); $pconfig = $_POST; + if ((strlen($pconfig['ntporphan']) > 0) && (!is_numericint($pconfig['ntporphan']) || ($pconfig['ntporphan'] < 1) || ($pconfig['ntporphan'] > 15))) { + $input_errors[] = gettext("The supplied value for NTP Orphan Mode is invalid."); + } + if (!$input_errors) { if (is_array($_POST['interface'])) { $config['ntpd']['interface'] = implode(",", $_POST['interface']); @@ -91,11 +95,7 @@ if ($_POST) { } $config['system']['timeservers'] = trim($timeservers); - if (!empty($_POST['ntporphan']) && ($_POST['ntporphan'] < 17) && ($_POST['ntporphan'] != '12')) { - $config['ntpd']['orphan'] = $_POST['ntporphan']; - } elseif (isset($config['ntpd']['orphan'])) { - unset($config['ntpd']['orphan']); - } + $config['ntpd']['orphan'] = trim($pconfig['ntporphan']); if (!empty($_POST['logpeer'])) { $config['ntpd']['logpeer'] = $_POST['logpeer']; @@ -151,9 +151,9 @@ if ($_POST) { write_config("Updated NTP Server Settings"); + $changes_applied = true; $retval = 0; - $retval = system_ntp_configure(); - $savemsg = get_std_save_message($retval); + $retval |= system_ntp_configure(); } } @@ -192,8 +192,9 @@ include("head.inc"); if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); + +if ($changes_applied) { + print_apply_result_box($retval); } $tab_array = array(); diff --git a/src/usr/local/www/services_ntpd_acls.php b/src/usr/local/www/services_ntpd_acls.php index 19c057d..ea80ea4 100644 --- a/src/usr/local/www/services_ntpd_acls.php +++ b/src/usr/local/www/services_ntpd_acls.php @@ -150,9 +150,9 @@ if ($_POST) { write_config("Updated NTP ACL Settings"); + $changes_applied = true; $retval = 0; - $retval = system_ntp_configure(); - $savemsg = get_std_save_message($retval); + $retval |= system_ntp_configure(); } } @@ -165,8 +165,9 @@ include("head.inc"); if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); + +if ($changes_applied) { + print_apply_result_box($retval); } $tab_array = array(); diff --git a/src/usr/local/www/services_ntpd_gps.php b/src/usr/local/www/services_ntpd_gps.php index 971d57e..f06e03e 100644 --- a/src/usr/local/www/services_ntpd_gps.php +++ b/src/usr/local/www/services_ntpd_gps.php @@ -154,8 +154,9 @@ if ($_POST) { write_config(gettext("Updated NTP GPS Settings")); - $retval = system_ntp_configure(); - $savemsg = get_std_save_message($retval); + $changes_applied = true; + $retval = 0; + $retval |= system_ntp_configure(); } else { /* set defaults if they do not already exist */ if (!is_array($config['ntpd']) || !is_array($config['ntpd']['gps']) || empty($config['ntpd']['gps']['type'])) { @@ -192,6 +193,10 @@ $pgtitle = array(gettext("Services"), gettext("NTP"), gettext("Serial GPS")); $shortcut_section = "ntp"; include("head.inc"); +if ($changes_applied) { + print_apply_result_box($retval); +} + $tab_array = array(); $tab_array[] = array(gettext("Settings"), false, "services_ntpd.php"); $tab_array[] = array(gettext("ACLs"), false, "services_ntpd_acls.php"); diff --git a/src/usr/local/www/services_ntpd_pps.php b/src/usr/local/www/services_ntpd_pps.php index da987f7..c3d70df 100644 --- a/src/usr/local/www/services_ntpd_pps.php +++ b/src/usr/local/www/services_ntpd_pps.php @@ -91,9 +91,9 @@ if ($_POST) { write_config("Updated NTP PPS Settings"); + $changes_applied = true; $retval = 0; - $retval = system_ntp_configure(); - $savemsg = get_std_save_message($retval); + $retval |= system_ntp_configure(); } } @@ -107,8 +107,8 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($changes_applied) { + print_apply_result_box($retval); } $tab_array = array(); diff --git a/src/usr/local/www/services_pppoe.php b/src/usr/local/www/services_pppoe.php index a8b0f03..85b3531 100644 --- a/src/usr/local/www/services_pppoe.php +++ b/src/usr/local/www/services_pppoe.php @@ -59,7 +59,6 @@ if ($_POST) { } $retval = 0; $retval |= filter_configure(); - $savemsg = get_std_save_message($retval); clear_subsystem_dirty('vpnpppoe'); } } @@ -83,8 +82,8 @@ $pgtitle = array(gettext("Services"), gettext("PPPoE Server")); $shortcut_section = "pppoes"; include("head.inc"); -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($_POST['apply']) { + print_apply_result_box($retval); } if (is_subsystem_dirty('vpnpppoe')) { diff --git a/src/usr/local/www/services_pppoe_edit.php b/src/usr/local/www/services_pppoe_edit.php index 633af97..014f21d 100644 --- a/src/usr/local/www/services_pppoe_edit.php +++ b/src/usr/local/www/services_pppoe_edit.php @@ -285,10 +285,6 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); -} - $form = new Form(); $section = new Form_Section('PPPoE Server Configuration'); diff --git a/src/usr/local/www/services_rfc2136_edit.php b/src/usr/local/www/services_rfc2136_edit.php index 41a7c5b..4ca7cb8 100644 --- a/src/usr/local/www/services_rfc2136_edit.php +++ b/src/usr/local/www/services_rfc2136_edit.php @@ -152,10 +152,6 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); -} - $form = new Form; $section = new Form_Section('RFC 2136 Client'); diff --git a/src/usr/local/www/services_router_advertisements.php b/src/usr/local/www/services_router_advertisements.php index e369d37..367aedb 100644 --- a/src/usr/local/www/services_router_advertisements.php +++ b/src/usr/local/www/services_router_advertisements.php @@ -54,7 +54,7 @@ if ($config['installedpackages']['olsrd']) { } if (!$_GET['if']) { - $savemsg = gettext("The DHCPv6 Server can only be enabled on interfaces configured with static, non unique local IP addresses.") . "<br />" . + $info_msg = gettext("The DHCPv6 Server can only be enabled on interfaces configured with static, non unique local IP addresses.") . "<br />" . gettext("Only interfaces configured with a static IP will be shown."); } @@ -243,8 +243,9 @@ if ($_POST) { } write_config(); - $retval = services_radvd_configure(); - $savemsg = get_std_save_message($retval); + $changes_applied = true; + $retval = 0; + $retval |= services_radvd_configure(); } } @@ -261,8 +262,12 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($changes_applied) { + print_apply_result_box($retval); +} + +if ($info_msg) { + print_info_box($info_msg, 'success'); } /* active tabs */ diff --git a/src/usr/local/www/services_snmp.php b/src/usr/local/www/services_snmp.php index 66caf4f..0811cc9 100644 --- a/src/usr/local/www/services_snmp.php +++ b/src/usr/local/www/services_snmp.php @@ -33,6 +33,8 @@ require_once("guiconfig.inc"); require_once("functions.inc"); +$specplatform = system_identify_specific_platform(); + if (!is_array($config['snmpd'])) { $config['snmpd'] = array(); $config['snmpd']['rocommunity'] = "public"; @@ -161,9 +163,9 @@ if ($_POST) { write_config(); + $changes_applied = true; $retval = 0; - $retval = services_snmpd_configure(); - $savemsg = get_std_save_message($retval); + $retval |= services_snmpd_configure(); } } @@ -200,8 +202,8 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($changes_applied) { + print_apply_result_box($retval); } $form = new Form(); @@ -316,12 +318,14 @@ $group->add(new Form_MultiCheckbox( $pconfig['pf'] )); -$group->add(new Form_MultiCheckbox( - 'hostres', - null, - 'Host Resources', - $pconfig['hostres'] -)); +if (!(($specplatform['name'] == 'VMware') && (file_exists('/dev/cd0')))) { + $group->add(new Form_MultiCheckbox( + 'hostres', + null, + 'Host Resources', + $pconfig['hostres'] + )); +} $group->add(new Form_MultiCheckbox( 'ucd', @@ -338,6 +342,14 @@ $group->add(new Form_MultiCheckbox( )); $section->add($group); +if ((($specplatform['name'] == 'VMware') && (file_exists('/dev/cd0')))) { + $section->addInput(new Form_StaticText( + NULL, + NULL + ))->setHelp(sprint_info_box('The hostres module is not compatible with VMware virtual ' . + 'machines configured with a virtual CD/DVD Drive.', 'warning', false)); +} + $form->add($section); $section = new Form_Section('Interface Binding'); diff --git a/src/usr/local/www/services_unbound.php b/src/usr/local/www/services_unbound.php index b79548c..c2ba2b7 100644 --- a/src/usr/local/www/services_unbound.php +++ b/src/usr/local/www/services_unbound.php @@ -88,8 +88,8 @@ if (empty($a_unboundcfg['system_domain_local_zone_type'])) { if ($_POST) { if ($_POST['apply']) { - $retval = services_unbound_configure(); - $savemsg = get_std_save_message($retval); + $retval = 0; + $retval |= services_unbound_configure(); if ($retval == 0) { clear_subsystem_dirty('unbound'); } @@ -128,7 +128,7 @@ if ($_POST) { } } if ($founddns == false) { - $input_errors[] = gettext("At least one DNS server must be specified under System>General Setup to enable Forwarding mode."); + $input_errors[] = gettext("At least one DNS server must be specified under System > General Setup to enable Forwarding mode."); } } @@ -244,8 +244,8 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($_POST['apply']) { + print_apply_result_box($retval); } if (is_subsystem_dirty('unbound')) { @@ -317,7 +317,9 @@ $section->addInput(new Form_Checkbox( 'DNS Query Forwarding', 'Enable Forwarding Mode', $pconfig['forwarding'] -)); +))->setHelp(sprintf('If this option is set, DNS queries will be forwarded to the upstream DNS servers defined under'. + ' %sSystem > General Setup%s or those obtained via DHCP/PPP on WAN'. + ' (if DNS Server Override is enabled there).','<a href="system.php">','</a>')); $section->addInput(new Form_Checkbox( 'regdhcp', @@ -326,7 +328,7 @@ $section->addInput(new Form_Checkbox( $pconfig['regdhcp'] ))->setHelp(sprintf('If this option is set, then machines that specify their hostname when requesting a DHCP lease will be registered'. ' in the DNS Resolver, so that their name can be resolved.'. - ' The domain in %sSystem: General Setup%s should also be set to the proper value.','<a href="system.php">','</a>')); + ' The domain in %sSystem > General Setup%s should also be set to the proper value.','<a href="system.php">','</a>')); $section->addInput(new Form_Checkbox( 'regdhcpstatic', @@ -334,7 +336,7 @@ $section->addInput(new Form_Checkbox( 'Register DHCP static mappings in the DNS Resolver', $pconfig['regdhcpstatic'] ))->setHelp(sprintf('If this option is set, then DHCP static mappings will be registered in the DNS Resolver, so that their name can be resolved. '. - 'The domain in %sSystem: General Setup%s should also be set to the proper value.','<a href="system.php">','</a>')); + 'The domain in %sSystem > General Setup%s should also be set to the proper value.','<a href="system.php">','</a>')); $btnadv = new Form_Button( 'btnadvcustom', @@ -555,7 +557,7 @@ endforeach; " service (if enabled) will automatically serve the LAN IP". " address as a DNS server to DHCP clients so they will use". " the DNS Resolver. If Forwarding is enabled, the DNS Resolver will use the DNS servers". - " entered in %sSystem: General Setup%s". + " entered in %sSystem > General Setup%s". " or those obtained via DHCP or PPP on WAN if "Allow". " DNS server list to be overridden by DHCP/PPP on WAN"". " is checked."), '<a href="system.php">', '</a>'), 'info', false); ?> diff --git a/src/usr/local/www/services_unbound_acls.php b/src/usr/local/www/services_unbound_acls.php index 1174202..31e2180 100644 --- a/src/usr/local/www/services_unbound_acls.php +++ b/src/usr/local/www/services_unbound_acls.php @@ -99,8 +99,8 @@ if ($_POST) { } if ($_POST['apply']) { - $retval = services_unbound_configure(); - $savemsg = get_std_save_message($retval); + $retval = 0; + $retval |= services_unbound_configure(); if ($retval == 0) { clear_subsystem_dirty('unbound'); } @@ -185,8 +185,8 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($_POST['apply']) { + print_apply_result_box($retval); } if (is_subsystem_dirty('unbound')) { diff --git a/src/usr/local/www/services_unbound_advanced.php b/src/usr/local/www/services_unbound_advanced.php index 14bb376..1f869de 100644 --- a/src/usr/local/www/services_unbound_advanced.php +++ b/src/usr/local/www/services_unbound_advanced.php @@ -77,8 +77,8 @@ if (isset($config['unbound']['use_caps'])) { if ($_POST) { if ($_POST['apply']) { - $retval = services_unbound_configure(); - $savemsg = get_std_save_message($retval); + $retval = 0; + $retval |= services_unbound_configure(); if ($retval == 0) { clear_subsystem_dirty('unbound'); } @@ -192,8 +192,8 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($_POST['apply']) { + print_apply_result_box($retval); } if (is_subsystem_dirty('unbound')) { diff --git a/src/usr/local/www/status_gateways.php b/src/usr/local/www/status_gateways.php index d633fab..5b5125c 100644 --- a/src/usr/local/www/status_gateways.php +++ b/src/usr/local/www/status_gateways.php @@ -140,11 +140,17 @@ display_top_tabs($tab_array); $online = gettext("Warning, Latency") . ': ' . $status['delay']; $bgcolor = "bg-warning"; } elseif ($status['status'] == "none") { - $online = gettext("Online"); + if ($status['monitor_disable'] || ($status['monitorip'] == "none")) { + $online = gettext("Online (unmonitored)"); + } else { + $online = gettext("Online"); + } $bgcolor = "bg-success"; } } else if (isset($gateway['monitor_disable'])) { - $online = gettext("Online"); + // Note: return_gateways_status() always returns an array entry for all gateways, + // so this "else if" never happens. + $online = gettext("Online (unmonitored)"); $bgcolor = "bg-success"; } else { $online = gettext("Pending"); diff --git a/src/usr/local/www/status_lb_pool.php b/src/usr/local/www/status_lb_pool.php index 911e891..7d22242 100644 --- a/src/usr/local/www/status_lb_pool.php +++ b/src/usr/local/www/status_lb_pool.php @@ -68,7 +68,6 @@ if ($_POST) { $retval = 0; $retval |= filter_configure(); $retval |= relayd_configure(); - $savemsg = get_std_save_message($retval); clear_subsystem_dirty('loadbalancer'); } else { /* Keep a list of servers we find in POST variables */ @@ -110,6 +109,10 @@ if (is_subsystem_dirty('loadbalancer')) { print_apply_box(gettext("The load balancer configuration has been changed.") . "<br />" . gettext("The changes must be applied for them to take effect.")); } +if ($_POST['apply']) { + print_apply_result_box($retval); +} + /* active tabs */ $tab_array = array(); $tab_array[] = array(gettext("Pools"), true, "status_lb_pool.php"); diff --git a/src/usr/local/www/status_logs.php b/src/usr/local/www/status_logs.php index 7435974..74f94a9 100644 --- a/src/usr/local/www/status_logs.php +++ b/src/usr/local/www/status_logs.php @@ -99,8 +99,8 @@ if (in_array($logfile, array('system', 'gateways', 'routing', 'resolver', 'wirel } include("head.inc"); -if (!$input_errors && $savemsg) { - print_info_box($savemsg, 'success'); +if ($changes_applied) { + print_apply_result_box($retval, $extra_save_msg); $manage_log_active = false; } diff --git a/src/usr/local/www/status_logs_common.inc b/src/usr/local/www/status_logs_common.inc index f35b9a2..be05902 100644 --- a/src/usr/local/www/status_logs_common.inc +++ b/src/usr/local/www/status_logs_common.inc @@ -584,8 +584,10 @@ function manage_log_code() { return; } - global $logfile, $specific_log, $config, $pconfig, $save_settings, $input_errors, $savemsg; + global $logfile, $specific_log, $config, $pconfig, $save_settings, $input_errors, $extra_save_msg, $retval, $changes_applied; + $changes_applied = false; + $extra_save_msg = ""; $specific_log = basename($logfile) . '_settings'; // Common to All Logs @@ -711,28 +713,27 @@ function manage_log_code() { } } + $retval = 0; + $changes_applied = true; // If any of the logging settings were changed then backup and sync (standard write_config). Otherwise only write config (don't backup, don't sync). - if ($logging_changed) { - write_config($desc = gettext("Log Display Settings Saved: ") . gettext($allowed_logs[$logfile]["name"]), $backup = true, $write_config_only = false); - $retval = 0; - $retval = system_syslogd_start(); - $savemsg = gettext("The changes have been applied successfully."); - } else { - write_config($desc = gettext("Log Display Settings Saved (no backup, no sync): ") . gettext($allowed_logs[$logfile]["name"]), $backup = false, $write_config_only = true); - $savemsg = ''; - } + if ($logging_changed) { + write_config($desc = gettext("Log Display Settings Saved: ") . gettext($allowed_logs[$logfile]["name"]), $backup = true, $write_config_only = false); + system_syslogd_start(); + } else { + write_config($desc = gettext("Log Display Settings Saved (no backup, no sync): ") . gettext($allowed_logs[$logfile]["name"]), $backup = false, $write_config_only = true); + } // Specific to System General (main) Log - if ($logfile == 'system') { - if ($nginx_logging_changed) { - ob_flush(); - flush(); - log_error(gettext("webConfigurator configuration has changed. Restarting webConfigurator.")); - send_event("service restart webgui"); - $savemsg .= "<br />" . gettext("WebGUI process is restarting."); + if ($logfile == 'system') { + if ($nginx_logging_changed) { + ob_flush(); + flush(); + log_error(gettext("webConfigurator configuration has changed. Restarting webConfigurator.")); + send_event("service restart webgui"); + $extra_save_msg = gettext("WebGUI process is restarting."); + } } - } // Specific to Firewall Log if ($logfile == 'filter') { @@ -740,8 +741,6 @@ function manage_log_code() { require_once("filter.inc"); $retval |= filter_configure(); filter_pflog_start(true); - - $savemsg = get_std_save_message($retval); } } } diff --git a/src/usr/local/www/status_logs_filter.php b/src/usr/local/www/status_logs_filter.php index 4c37c91..2f1b86e 100644 --- a/src/usr/local/www/status_logs_filter.php +++ b/src/usr/local/www/status_logs_filter.php @@ -102,12 +102,11 @@ status_logs_common_code(); $pgtitle = array(gettext("Status"), gettext("System Logs"), gettext($allowed_logs[$logfile]["name"]), $view_title); include("head.inc"); -if (!$input_errors && $savemsg) { - print_info_box($savemsg, 'success'); +if ($changes_applied) { + print_apply_result_box($retval, $extra_save_msg); $manage_log_active = false; } - // Tab Array tab_array_logs_common(); diff --git a/src/usr/local/www/status_logs_filter_dynamic.php b/src/usr/local/www/status_logs_filter_dynamic.php index 4ea4d4a..04d70c2 100644 --- a/src/usr/local/www/status_logs_filter_dynamic.php +++ b/src/usr/local/www/status_logs_filter_dynamic.php @@ -82,12 +82,11 @@ status_logs_common_code(); $pgtitle = array(gettext("Status"), gettext("System Logs"), gettext($allowed_logs[$logfile]["name"]), $view_title); include("head.inc"); -if (!$input_errors && $savemsg) { - print_info_box($savemsg, 'success'); +if ($changes_applied) { + print_apply_result_box($retval, $extra_save_msg); $manage_log_active = false; } - // Tab Array tab_array_logs_common(); diff --git a/src/usr/local/www/status_logs_filter_summary.php b/src/usr/local/www/status_logs_filter_summary.php index 124d190..333c97e 100644 --- a/src/usr/local/www/status_logs_filter_summary.php +++ b/src/usr/local/www/status_logs_filter_summary.php @@ -67,12 +67,11 @@ status_logs_common_code(); $pgtitle = array(gettext("Status"), gettext("System Logs"), gettext($allowed_logs[$logfile]["name"]), $view_title); include("head.inc"); -if (!$input_errors && $savemsg) { - print_info_box($savemsg, 'success'); +if ($changes_applied) { + print_apply_result_box($retval, $extra_save_msg); $manage_log_active = false; } - // Tab Array tab_array_logs_common(); diff --git a/src/usr/local/www/status_logs_settings.php b/src/usr/local/www/status_logs_settings.php index 33881ed..add7a80 100644 --- a/src/usr/local/www/status_logs_settings.php +++ b/src/usr/local/www/status_logs_settings.php @@ -80,7 +80,7 @@ function is_valid_syslog_server($target) { if ($_POST['resetlogs'] == gettext("Reset Log Files")) { clear_all_log_files(true); - $savemsg .= gettext("The log files have been reset."); + $reset_msg = gettext("The log files have been reset."); } elseif ($_POST) { unset($input_errors); $pconfig = $_POST; @@ -162,8 +162,9 @@ if ($_POST['resetlogs'] == gettext("Reset Log Files")) { write_config(); + $changes_applied = true; $retval = 0; - $retval = system_syslogd_start(); + system_syslogd_start(); if (($oldnologdefaultblock !== isset($config['syslog']['nologdefaultblock'])) || ($oldnologdefaultpass !== isset($config['syslog']['nologdefaultpass'])) || ($oldnologbogons !== isset($config['syslog']['nologbogons'])) || @@ -171,14 +172,12 @@ if ($_POST['resetlogs'] == gettext("Reset Log Files")) { $retval |= filter_configure(); } - $savemsg = get_std_save_message($retval); - if ($oldnolognginx !== isset($config['syslog']['nolognginx'])) { ob_flush(); flush(); log_error(gettext("webConfigurator configuration has changed. Restarting webConfigurator.")); send_event("service restart webgui"); - $savemsg .= "<br />" . gettext("WebGUI process is restarting."); + $extra_save_msg = gettext("WebGUI process is restarting."); } filter_pflog_start(true); @@ -204,8 +203,12 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($reset_msg) { + print_info_box($reset_msg, 'success'); +} + +if ($changes_applied) { + print_apply_result_box($retval, $extra_save_msg); } $tab_array = array(); diff --git a/src/usr/local/www/status_ntpd.php b/src/usr/local/www/status_ntpd.php index 56725ab..c37052d 100644 --- a/src/usr/local/www/status_ntpd.php +++ b/src/usr/local/www/status_ntpd.php @@ -110,6 +110,8 @@ if (!isset($config['ntpd']['noquery'])) { $gps_lat = $gps_lat * (($gps_vars[4] == "N") ? 1 : -1); $gps_lon = $gps_lon_deg + $gps_lon_min; $gps_lon = $gps_lon * (($gps_vars[6] == "E") ? 1 : -1); + $gps_la = $gps_vars[4]; + $gps_lo = $gps_vars[6]; } elseif (substr($tmp, 0, 6) == '$GPGGA') { $gps_vars = explode(",", $tmp); $gps_ok = $gps_vars[6]; @@ -123,9 +125,11 @@ if (!isset($config['ntpd']['noquery'])) { $gps_lon = $gps_lon * (($gps_vars[5] == "E") ? 1 : -1); $gps_alt = $gps_vars[9]; $gps_alt_unit = $gps_vars[10]; - $gps_sat = $gps_vars[7]; + $gps_sat = (int)$gps_vars[7]; + $gps_la = $gps_vars[3]; + $gps_lo = $gps_vars[5]; } elseif (substr($tmp, 0, 6) == '$GPGLL') { - $gps_vars = explode(",", $tmp); + $gps_vars = preg_split('/[,\*]+/', $tmp); $gps_ok = ($gps_vars[6] == "A"); $gps_lat_deg = substr($gps_vars[1], 0, 2); $gps_lat_min = substr($gps_vars[1], 2) / 60.0; @@ -135,6 +139,8 @@ if (!isset($config['ntpd']['noquery'])) { $gps_lat = $gps_lat * (($gps_vars[2] == "N") ? 1 : -1); $gps_lon = $gps_lon_deg + $gps_lon_min; $gps_lon = $gps_lon * (($gps_vars[4] == "E") ? 1 : -1); + $gps_la = $gps_vars[2]; + $gps_lo = $gps_vars[4]; } } } @@ -205,7 +211,7 @@ function print_status() { } function print_gps() { - global $gps_lat, $gps_lon, $gps_lat_deg, $gps_lon_deg, $gps_lat_min, $gps_lon_min, $gps_vars, + global $gps_lat, $gps_lon, $gps_lat_deg, $gps_lon_deg, $gps_lat_min, $gps_lon_min, $gps_la, $gps_lo, $gps_alt, $gps_alt_unit, $gps_sat, $gps_satview, $gps_goo_lnk; print("<tr>\n"); @@ -214,7 +220,7 @@ function print_gps() { print(" ("); printf("%d%s", $gps_lat_deg, "°"); printf("%.5f", $gps_lat_min*60); - print($gps_vars[4]); + print($gps_la); print(")"); print("</td>\n"); print("<td>\n"); @@ -222,7 +228,7 @@ function print_gps() { print(" ("); printf("%d%s", $gps_lon_deg, "°"); printf("%.5f", $gps_lon_min*60); - print($gps_vars[6]); + print($gps_lo); print(")"); print("</td>\n"); @@ -233,7 +239,7 @@ function print_gps() { } if (isset($gps_sat) || isset($gps_satview)) { - print('<td class="text-center">'); + print('<td>'); if (isset($gps_satview)) { print(gettext('in view ') . intval($gps_satview)); diff --git a/src/usr/local/www/status_openvpn.php b/src/usr/local/www/status_openvpn.php index 9997703..0a71ac2 100644 --- a/src/usr/local/www/status_openvpn.php +++ b/src/usr/local/www/status_openvpn.php @@ -312,7 +312,13 @@ include("head.inc"); ?> <td><?=htmlspecialchars($client['name']);?></td> <td><?=$client['status'];?></td> <td><?=$client['connect_time'];?></td> - <td><?=$client['local_host'];?>:<?=$client['local_port'];?></td> + <td> + <?php if (empty($client['local_host']) && empty($client['local_port'])): ?> + (pending) + <?php else: ?> + <?=$client['local_host'];?>:<?=$client['local_port'];?> + <?php endif; ?> + </td> <td> <?=$client['virtual_addr'];?> <?php if (!empty($client['virtual_addr']) && !empty($client['virtual_addr6'])): ?> @@ -320,7 +326,13 @@ include("head.inc"); ?> <?php endif; ?> <?=$client['virtual_addr6'];?> </td> - <td><?=$client['remote_host'];?>:<?=$client['remote_port'];?></td> + <td> + <?php if (empty($client['remote_host']) && empty($client['remote_port'])): ?> + (pending) + <?php else: ?> + <?=$client['remote_host'];?>:<?=$client['remote_port'];?> + <?php endif; ?> + </td> <td><?=format_bytes($client['bytes_sent']);?> / <?=format_bytes($client['bytes_recv']);?></td> <td> <table> diff --git a/src/usr/local/www/system.php b/src/usr/local/www/system.php index 83ab5e7..86b9d76 100644 --- a/src/usr/local/www/system.php +++ b/src/usr/local/www/system.php @@ -93,6 +93,38 @@ if ($pconfig['timezone'] <> $_POST['timezone']) { } $timezonelist = system_get_timezone_list(); +$timezonedesc = $timezonelist; + +/* + * Etc/GMT entries work the opposite way to what people expect. + * Ref: https://github.com/eggert/tz/blob/master/etcetera and Redmine issue 7089 + * Add explanatory text to entries like: + * Etc/GMT+1 and Etc/GMT-1 + * but not: + * Etc/GMT or Etc/GMT+0 + */ +foreach ($timezonedesc as $idx => $desc) { + if (substr($desc, 0, 7) != "Etc/GMT" || substr($desc, 8, 1) == "0") { + continue; + } + + $direction = substr($desc, 7, 1); + + switch ($direction) { + case '-': + $direction_str = gettext('AHEAD of'); + break; + case '+': + $direction_str = gettext('BEHIND'); + break; + default: + continue; + } + + $hr_offset = substr($desc, 8); + $timezonedesc[$idx] = $desc . " " . + sprintf(ngettext('(%1$s hour %2$s GMT)', '(%1$s hours %2$s GMT)', $hr_offset), $hr_offset, $direction_str); +} $multiwan = false; $interfaces = get_configured_interface_list(); @@ -314,8 +346,9 @@ if ($_POST) { write_config($changedesc); } + $changes_applied = true; $retval = 0; - $retval = system_hostname_configure(); + $retval |= system_hostname_configure(); $retval |= system_hosts_generate(); $retval |= system_resolvconf_generate(); if (isset($config['dnsmasq']['enable'])) { @@ -332,8 +365,6 @@ if ($_POST) { // Reload the filter - plugins might need to be run. $retval |= filter_configure(); - - $savemsg = get_std_save_message($retval); } unset($ignore_posted_dnsgw); @@ -346,8 +377,8 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($changes_applied) { + print_apply_result_box($retval); } ?> <div id="container"> @@ -391,7 +422,8 @@ for ($i=1; $i<5; $i++) { ))->setHelp(($i == 4) ? 'Address':null); $help = "Enter IP addresses to be used by the system for DNS resolution. " . - "These are also used for the DHCP service, DNS forwarder and for PPTP VPN clients."; + "These are also used for the DHCP service, DNS Forwarder and DNS Resolver " . + "when it has DNS Query Forwarding enabled."; if ($multiwan) { $options = array('none' => 'none'); @@ -433,18 +465,18 @@ $section->addInput(new Form_Checkbox( $pconfig['dnsallowoverride'] ))->setHelp(sprintf(gettext('If this option is set, %s will use DNS servers '. 'assigned by a DHCP/PPP server on WAN for its own purposes (including '. - 'the DNS forwarder). However, they will not be assigned to DHCP and PPTP '. - 'VPN clients.'), $g['product_name'])); + 'the DNS Forwarder/DNS Resolver). However, they will not be assigned to DHCP '. + 'clients.'), $g['product_name'])); $section->addInput(new Form_Checkbox( 'dnslocalhost', 'Disable DNS Forwarder', - 'Do not use the DNS Forwarder as a DNS server for the firewall', + 'Do not use the DNS Forwarder/DNS Resolver as a DNS server for the firewall', $pconfig['dnslocalhost'] ))->setHelp('By default localhost (127.0.0.1) will be used as the first DNS '. 'server where the DNS Forwarder or DNS Resolver is enabled and set to '. - 'listen on Localhost, so system can use the local DNS service to perform '. - 'lookups. Checking this box omits localhost from the list of DNS servers.'); + 'listen on localhost, so system can use the local DNS service to perform '. + 'lookups. Checking this box omits localhost from the list of DNS servers in resolv.conf.'); $form->add($section); @@ -454,8 +486,9 @@ $section->addInput(new Form_Select( 'timezone', 'Timezone', $pconfig['timezone'], - array_combine($timezonelist, $timezonelist) -))->setHelp('Select the timezone or location within the timezone to be used by this system.'); + array_combine($timezonelist, $timezonedesc) +))->setHelp('Select a geographic region name (Continent/Location) to determine the timezone for the firewall. ' . + '<br/>Choose a special or "Etc" zone only in cases where the geographic zones do not properly handle the clock offset required for this firewall.'); $section->addInput(new Form_Input( 'timeservers', diff --git a/src/usr/local/www/system_advanced_admin.php b/src/usr/local/www/system_advanced_admin.php index b7207c4..d0da2a3 100644 --- a/src/usr/local/www/system_advanced_admin.php +++ b/src/usr/local/www/system_advanced_admin.php @@ -263,11 +263,12 @@ if ($_POST) { write_config(); - $retval = filter_configure(); - $savemsg = get_std_save_message($retval); + $changes_applied = true; + $retval = 0; + $retval |= filter_configure(); if ($restart_webgui) { - $savemsg .= sprintf("<br />" . gettext("One moment...redirecting to %s in 20 seconds."), $url); + $extra_save_msg = sprintf("<br />" . gettext("One moment...redirecting to %s in 20 seconds."), $url); } setup_serial_port(); @@ -287,8 +288,8 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($changes_applied) { + print_apply_result_box($retval, $extra_save_msg); } $tab_array = array(); diff --git a/src/usr/local/www/system_advanced_firewall.php b/src/usr/local/www/system_advanced_firewall.php index 1d0e811..e74d8f5 100644 --- a/src/usr/local/www/system_advanced_firewall.php +++ b/src/usr/local/www/system_advanced_firewall.php @@ -356,15 +356,9 @@ if ($_POST) { killbypid("{$g['varrun_path']}/filterdns.pid"); } + $changes_applied = true; $retval = 0; - $retval = filter_configure(); - if (stristr($retval, "error") <> true) { - $savemsg = get_std_save_message($retval); - $class = 'success'; - } else { - $savemsg = $retval; - $class = 'warning'; - } + $retval |= filter_configure(); } } @@ -374,8 +368,9 @@ include("head.inc"); if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, $class); + +if ($changes_applied) { + print_apply_result_box($retval); } $tab_array = array(); diff --git a/src/usr/local/www/system_advanced_misc.php b/src/usr/local/www/system_advanced_misc.php index 817b745..3d1268b 100644 --- a/src/usr/local/www/system_advanced_misc.php +++ b/src/usr/local/www/system_advanced_misc.php @@ -251,6 +251,13 @@ if ($_POST) { unset($config['system']['dhcpbackup']); } } + if (isset($_POST['logsbackup'])) { + if (($_POST['logsbackup'] > 0) && ($_POST['logsbackup'] <= 24)) { + $config['system']['logsbackup'] = intval($_POST['logsbackup']); + } else { + unset($config['system']['logsbackup']); + } + } // Add/Remove RAM disk periodic backup cron jobs according to settings and installation type. // Remove the cron jobs on full install if not using RAM disk. @@ -258,21 +265,19 @@ if ($_POST) { if (!isset($config['system']['use_mfs_tmpvar'])) { install_cron_job("/etc/rc.backup_rrd.sh", false); install_cron_job("/etc/rc.backup_dhcpleases.sh", false); + install_cron_job("/etc/rc.backup_logs.sh", false); } else { install_cron_job("/etc/rc.backup_rrd.sh", ($config['system']['rrdbackup'] > 0), $minute="0", "*/{$config['system']['rrdbackup']}"); install_cron_job("/etc/rc.backup_dhcpleases.sh", ($config['system']['dhcpbackup'] > 0), $minute="0", "*/{$config['system']['dhcpbackup']}"); + install_cron_job("/etc/rc.backup_logs.sh", ($config['system']['logsbackup'] > 0), $minute="0", "*/{$config['system']['logsbackup']}"); } write_config(); + $changes_applied = true; $retval = 0; system_resolvconf_generate(true); - $retval = filter_configure(); - if (stristr($retval, "error") <> true) { - $savemsg = get_std_save_message(gettext($retval)); - } else { - $savemsg = gettext($retval); - } + $retval |= filter_configure(); activate_powerd(); load_crypto(); @@ -291,8 +296,8 @@ if ($input_errors) { unset($pconfig['doreboot']); } -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($changes_applied) { + print_apply_result_box($retval); } $tab_array = array(); @@ -541,6 +546,16 @@ $section->addInput(new Form_Input( 'it can be restored automatically on the next boot. Keep in mind that the more '. 'frequent the backup, the more writes will happen to the media.'); +$section->addInput(new Form_Input( + 'logsbackup', + 'Periodic Logs Backup', + 'number', + $config['system']['logsbackup'], + ['min' => 0, 'max' => 24, 'placeholder' => 'Period between 1 and 24 hours'] +))->setHelp('This will periodically backup the log directory so '. + 'it can be restored automatically on the next boot. Keep in mind that the more '. + 'frequent the backup, the more writes will happen to the media.'); + $form->add($section); $section = new Form_Section('Hardware Settings'); @@ -590,7 +605,7 @@ events.push(function() { } }); - drb = "<?=$pconfig['doreboot']?>"; + drb = "<?=$pconfig['doreboot']?>"; if (drb == "yes") { $('form').append("<input type=\"hidden\" name=\"override\" value=\"yes\" />"); diff --git a/src/usr/local/www/system_advanced_network.php b/src/usr/local/www/system_advanced_network.php index 06a4e2d..f90240f 100644 --- a/src/usr/local/www/system_advanced_network.php +++ b/src/usr/local/www/system_advanced_network.php @@ -40,6 +40,7 @@ require_once("shaper.inc"); $pconfig['ipv6nat_enable'] = isset($config['diag']['ipv6nat']['enable']); $pconfig['ipv6nat_ipaddr'] = $config['diag']['ipv6nat']['ipaddr']; $pconfig['ipv6allow'] = isset($config['system']['ipv6allow']); +$pconfig['global-v6duid'] = $config['system']['global-v6duid']; $pconfig['prefer_ipv4'] = isset($config['system']['prefer_ipv4']); $pconfig['sharednet'] = $config['system']['sharednet']; $pconfig['disablechecksumoffloading'] = isset($config['system']['disablechecksumoffloading']); @@ -55,6 +56,14 @@ if ($_POST) { $input_errors[] = gettext("An IP address to NAT IPv6 packets must be specified."); } + if (!empty($_POST['global-v6duid'])) { + $_POST['global-v6duid'] = format_duid($_POST['global-v6duid']); + $pconfig['global-v6duid'] = $_POST['global-v6duid']; + if (!is_duid($_POST['global-v6duid'])) { + $input_errors[] = gettext("A valid DUID must be specified"); + } + } + ob_flush(); flush(); if (!$input_errors) { @@ -83,6 +92,12 @@ if ($_POST) { unset($config['system']['prefer_ipv4']); } + if (!empty($_POST['global-v6duid'])) { + $config['system']['global-v6duid'] = $_POST['global-v6duid']; + } else { + unset($config['system']['global-v6duid']); + } + if ($_POST['sharednet'] == "yes") { $config['system']['sharednet'] = true; system_disable_arp_wrong_if(); @@ -117,14 +132,9 @@ if ($_POST) { // Set preferred protocol prefer_ipv4_or_ipv6(); - $retval = filter_configure(); - if (stristr($retval, "error") <> true) { - $savemsg = get_std_save_message(gettext($retval)); - $class = 'success'; - } else { - $savemsg = gettext($retval); - $class = 'warning'; - } + $changes_applied = true; + $retval = 0; + $retval |= filter_configure(); } } @@ -134,8 +144,9 @@ include("head.inc"); if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, $class); + +if ($changes_applied) { + print_apply_result_box($retval); } $tab_array = array(); @@ -145,6 +156,7 @@ $tab_array[] = array(gettext("Networking"), true, "system_advanced_network.php") $tab_array[] = array(gettext("Miscellaneous"), false, "system_advanced_misc.php"); $tab_array[] = array(gettext("System Tunables"), false, "system_advanced_sysctl.php"); $tab_array[] = array(gettext("Notifications"), false, "system_advanced_notifications.php"); +$duid = get_duid_from_file(); display_top_tabs($tab_array); $form = new Form; @@ -158,23 +170,27 @@ $section->addInput(new Form_Checkbox( ))->setHelp('NOTE: This does not disable any IPv6 features on the firewall, it only '. 'blocks traffic.'); -$group = new Form_Group('IPv6 over IPv4 Tunneling'); + +$group = new Form_Group('IPv6 over IPv4'); + $group->add(new Form_Checkbox( 'ipv6nat_enable', 'IPv6 over IPv4 Tunneling', - 'Enable IPv4 NAT encapsulation of IPv6 packets', + 'Enable IPv6 over IPv4 tunneling', $pconfig['ipv6nat_enable'] )); $group->add(new Form_Input( 'ipv6nat_ipaddr', - 'IP address', + 'IPv4 address of Tunnel Peer', 'text', $pconfig['ipv6nat_ipaddr'] -))->setHelp('Enable IPv4 NAT encapsulation of IPv6 packets. <br/>This provides an '. - 'RFC 2893 compatibility mechanism that can be used to tunneling IPv6 packets over '. - 'IPv4 routing infrastructures. If enabled, don\'t forget to add a firewall rule to '. - 'permit IPv6 packets.'); +)); + +$group->setHelp('These options create an RFC 2893 compatible mechanism for IPv4 NAT encapsulation of IPv6 packets, ' . + 'that can be used to tunnel IPv6 packets over IPv4 routing infrastructures. ' . + 'IPv6 firewall rules are <a href="firewall_rules.php">also required</a>, to control and pass encapsulated traffic.'); + $section->add($group); @@ -186,6 +202,20 @@ $section->addInput(new Form_Checkbox( ))->setHelp('By default, if IPv6 is configured and a hostname resolves IPv6 and IPv4 addresses, '. 'IPv6 will be used. If this option is selected, IPv4 will be preferred over IPv6.'); +$section->addInput(new Form_Input( + 'global-v6duid', + 'DHCP6 DUID', + 'text', + $pconfig['global-v6duid'], + ['placeholder' => $duid] + ))->setWidth(9)->sethelp('This is the DHCPv6 Unique Identifier (DUID) used by the firewall when requesting an IPv6 address. ' . + '<br />' . + 'By default, the firewall automatically creates a dynamic DUID which is not saved in the firewall configuration. '. + 'To ensure the same DUID is retained by the firewall at all times, enter a DUID in this field. ' . + 'The new DUID will take effect after a reboot or when the WAN interface(s) are reconfigured by the firewall.' . + '<br />' . + 'If the firewall is configured to use a RAM disk for /var, the best practice is to store a DUID here otherwise the DUID will change on each reboot. '); + $form->add($section); $section = new Form_Section('Network Interfaces'); diff --git a/src/usr/local/www/system_advanced_sysctl.php b/src/usr/local/www/system_advanced_sysctl.php index 3ab51fd..a8556b9 100644 --- a/src/usr/local/www/system_advanced_sysctl.php +++ b/src/usr/local/www/system_advanced_sysctl.php @@ -87,7 +87,6 @@ if ($_POST) { if ($_POST['apply']) { $retval = 0; system_setup_sysctl(); - $savemsg = get_std_save_message($retval); clear_subsystem_dirty('sysctl'); } @@ -129,8 +128,8 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($_POST['apply']) { + print_apply_result_box($retval); } if (is_subsystem_dirty('sysctl') && ($act != "edit" )) { diff --git a/src/usr/local/www/system_crlmanager.php b/src/usr/local/www/system_crlmanager.php index 58ea4cd..f5d3b3d 100644 --- a/src/usr/local/www/system_crlmanager.php +++ b/src/usr/local/www/system_crlmanager.php @@ -82,12 +82,14 @@ if (!$thiscrl && (($act != "") && ($act != "new"))) { pfSenseHeader("system_crlmanager.php"); $act=""; $savemsg = gettext("Invalid CRL reference."); + $class = "danger"; } if ($act == "del") { $name = htmlspecialchars($thiscrl['descr']); if (crl_in_use($id)) { $savemsg = sprintf(gettext("Certificate Revocation List %s is in use and cannot be deleted."), $name); + $class = "danger"; } else { foreach ($a_crl as $cid => $acrl) { if ($acrl['refid'] == $thiscrl['refid']) { @@ -96,6 +98,7 @@ if ($act == "del") { } write_config("Deleted CRL {$name}."); $savemsg = sprintf(gettext("Certificate Revocation List %s successfully deleted."), $name); + $class = "success"; } } @@ -177,12 +180,14 @@ if ($act == "delcert") { $crlname = htmlspecialchars($thiscrl['descr']); if (cert_unrevoke($thiscert, $thiscrl)) { $savemsg = sprintf(gettext("Deleted Certificate %s from CRL %s."), $certname, $crlname); + $class = "success"; // refresh IPsec and OpenVPN CRLs openvpn_refresh_crls(); vpn_ipsec_configure(); write_config($savemsg); } else { $savemsg = sprintf(gettext("Failed to delete Certificate %s from CRL %s."), $certname, $crlname); + $class = "danger"; } $act="edit"; } @@ -327,7 +332,7 @@ if ($input_errors) { } if ($savemsg) { - print_info_box($savemsg, 'success'); + print_info_box($savemsg, $class); } $tab_array = array(); diff --git a/src/usr/local/www/system_gateway_groups.php b/src/usr/local/www/system_gateway_groups.php index c8f956d..436faec 100644 --- a/src/usr/local/www/system_gateway_groups.php +++ b/src/usr/local/www/system_gateway_groups.php @@ -49,13 +49,12 @@ if ($_POST) { $retval = 0; - $retval = system_routing_configure(); + $retval |= system_routing_configure(); send_multiple_events(array("service reload dyndnsall", "service reload ipsecdns", "filter reload")); /* reconfigure our gateway monitor */ setup_gateways_monitor(); - $savemsg = get_std_save_message($retval); if ($retval == 0) { clear_subsystem_dirty('staticroutes'); } @@ -106,8 +105,8 @@ $shortcut_section = "gateway-groups"; include("head.inc"); -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($_POST['apply']) { + print_apply_result_box($retval); } if (is_subsystem_dirty('staticroutes')) { diff --git a/src/usr/local/www/system_gateways.php b/src/usr/local/www/system_gateways.php index 9eb95de..2927f0f 100644 --- a/src/usr/local/www/system_gateways.php +++ b/src/usr/local/www/system_gateways.php @@ -53,7 +53,7 @@ if ($_POST) { $retval = 0; - $retval = system_routing_configure(); + $retval |= system_routing_configure(); $retval |= system_resolvconf_generate(); $retval |= filter_configure(); /* reconfigure our gateway monitor */ @@ -61,7 +61,6 @@ if ($_POST) { /* Dynamic DNS on gw groups may have changed */ send_event("service reload dyndnsall"); - $savemsg = get_std_save_message($retval); if ($retval == 0) { clear_subsystem_dirty('staticroutes'); } @@ -230,8 +229,9 @@ include("head.inc"); if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); + +if ($_POST['apply']) { + print_apply_result_box($retval); } if (is_subsystem_dirty('staticroutes')) { diff --git a/src/usr/local/www/system_groupmanager_addprivs.php b/src/usr/local/www/system_groupmanager_addprivs.php index 69ffadc..c165078 100644 --- a/src/usr/local/www/system_groupmanager_addprivs.php +++ b/src/usr/local/www/system_groupmanager_addprivs.php @@ -89,19 +89,13 @@ if ($_POST) { } } - $retval = write_config(); - $savemsg = get_std_save_message($retval); + write_config(); pfSenseHeader("system_groupmanager.php?act=edit&groupid={$groupid}"); exit; } } -/* if ajax is calling, give them an update message */ -if (isAjax()) { - print_info_box($savemsg, 'success'); -} - function build_priv_list() { global $spriv_list, $a_group; @@ -138,10 +132,6 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); -} - $tab_array = array(); $tab_array[] = array(gettext("Users"), false, "system_usermanager.php"); $tab_array[] = array(gettext("Groups"), true, "system_groupmanager.php"); diff --git a/src/usr/local/www/system_routes.php b/src/usr/local/www/system_routes.php index cac6cce..48925c1 100644 --- a/src/usr/local/www/system_routes.php +++ b/src/usr/local/www/system_routes.php @@ -61,12 +61,11 @@ if ($_POST) { @unlink("{$g['tmp_path']}/.system_routes.apply"); } - $retval = system_routing_configure(); + $retval |= system_routing_configure(); $retval |= filter_configure(); /* reconfigure our gateway monitor */ setup_gateways_monitor(); - $savemsg = get_std_save_message($retval); if ($retval == 0) { clear_subsystem_dirty('staticroutes'); } @@ -218,8 +217,8 @@ include("head.inc"); if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($_POST['apply']) { + print_apply_result_box($retval); } if (is_subsystem_dirty('staticroutes')) { print_apply_box(gettext("The static route configuration has been changed.") . "<br />" . gettext("The changes must be applied for them to take effect.")); diff --git a/src/usr/local/www/system_usermanager_addprivs.php b/src/usr/local/www/system_usermanager_addprivs.php index d649cff..8babcd5 100644 --- a/src/usr/local/www/system_usermanager_addprivs.php +++ b/src/usr/local/www/system_usermanager_addprivs.php @@ -85,8 +85,7 @@ if ($_POST) { $a_user['priv'] = sort_user_privs($a_user['priv']); local_user_set($a_user); - $retval = write_config(); - $savemsg = get_std_save_message($retval); + write_config(); post_redirect("system_usermanager.php", array('act' => 'edit', 'userid' => $userid)); @@ -125,21 +124,12 @@ function get_root_priv_item_text() { return($priv_text); } -/* if ajax is calling, give them an update message */ -if (isAjax()) { - print_info_box($savemsg, 'success'); -} - include("head.inc"); if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); -} - $tab_array = array(); $tab_array[] = array(gettext("Users"), true, "system_usermanager.php"); $tab_array[] = array(gettext("Groups"), false, "system_groupmanager.php"); diff --git a/src/usr/local/www/system_usermanager_settings.php b/src/usr/local/www/system_usermanager_settings.php index a6df556..501070d 100644 --- a/src/usr/local/www/system_usermanager_settings.php +++ b/src/usr/local/www/system_usermanager_settings.php @@ -93,15 +93,17 @@ if ($_REQUEST['ajax']) { } } -$pconfig['session_timeout'] = &$config['system']['webgui']['session_timeout']; +$pconfig['session_timeout'] = $config['system']['webgui']['session_timeout']; if (isset($config['system']['webgui']['authmode'])) { - $pconfig['authmode'] = &$config['system']['webgui']['authmode']; + $pconfig['authmode'] = $config['system']['webgui']['authmode']; } else { $pconfig['authmode'] = "Local Database"; } -$pconfig['backend'] = &$config['system']['webgui']['backend']; +$pconfig['backend'] = $config['system']['webgui']['backend']; + +$pconfig['auth_refresh_time'] = $config['system']['webgui']['auth_refresh_time']; // Page title for main admin $pgtitle = array(gettext("System"), gettext("User Manager"), gettext("Settings")); @@ -119,6 +121,13 @@ if ($_POST) { } } + if (isset($_POST['auth_refresh_time'])) { + $timeout = intval($_POST['auth_refresh_time']); + if (!is_numeric($timeout) || $timeout < 0 || $timeout > 3600 ) { + $input_errors[] = gettext("Authentication refresh time must be an integer between 0 and 3600 (inclusive)."); + } + } + if (($_POST['authmode'] == "Local Database") && $_POST['savetest']) { $savemsg = gettext("Settings have been saved, but the test was not performed because it is not supported for local databases."); } @@ -146,6 +155,12 @@ if ($_POST) { } else { unset($config['system']['webgui']['authmode']); } + + if (isset($_POST['auth_refresh_time']) && $_POST['auth_refresh_time'] != "") { + $config['system']['webgui']['auth_refresh_time'] = intval($_POST['auth_refresh_time']); + } else { + unset($config['system']['webgui']['auth_refresh_time']); + } write_config(); @@ -200,6 +215,15 @@ $section->addInput(new Form_Select( $auth_servers )); +$section->addInput(new Form_Input( + 'auth_refresh_time', + 'Auth Refresh Time', + 'number', + $pconfig['auth_refresh_time'], + ['min' => 0, 'max' => 3600] +))->setHelp('Time in seconds to cache authentication results. The default is 30 seconds, maximum 3600 (one hour). '. + 'Shorter times result in more frequent queries to authentication servers.'); + $form->addGlobal(new Form_Button( 'savetest', 'Save & Test', diff --git a/src/usr/local/www/vpn_ipsec.php b/src/usr/local/www/vpn_ipsec.php index 64b628d..4a69ad4 100644 --- a/src/usr/local/www/vpn_ipsec.php +++ b/src/usr/local/www/vpn_ipsec.php @@ -50,11 +50,11 @@ $a_phase2 = &$config['ipsec']['phase2']; if ($_POST) { if ($_POST['apply']) { - $retval = vpn_ipsec_configure(); + $ipsec_dynamic_hosts = vpn_ipsec_configure(); /* reload the filter in the background */ - filter_configure(); - $savemsg = get_std_save_message($retval); - if ($retval >= 0) { + $retval = 0; + $retval |= filter_configure(); + if ($ipsec_dynamic_hosts >= 0) { if (is_subsystem_dirty('ipsec')) { clear_subsystem_dirty('ipsec'); } @@ -228,13 +228,13 @@ $tab_array[] = array(gettext("Pre-Shared Keys"), false, "vpn_ipsec_keys.php"); $tab_array[] = array(gettext("Advanced Settings"), false, "vpn_ipsec_settings.php"); display_top_tabs($tab_array); - if ($savemsg) { - print_info_box($savemsg, 'success'); - } +if ($_POST['apply']) { + print_apply_result_box($retval); +} - if (is_subsystem_dirty('ipsec')) { - print_apply_box(gettext("The IPsec tunnel configuration has been changed.") . "<br />" . gettext("The changes must be applied for them to take effect.")); - } +if (is_subsystem_dirty('ipsec')) { + print_apply_box(gettext("The IPsec tunnel configuration has been changed.") . "<br />" . gettext("The changes must be applied for them to take effect.")); +} ?> <form name="mainform" method="post"> diff --git a/src/usr/local/www/vpn_ipsec_keys.php b/src/usr/local/www/vpn_ipsec_keys.php index 46b2e7a..25acd38 100644 --- a/src/usr/local/www/vpn_ipsec_keys.php +++ b/src/usr/local/www/vpn_ipsec_keys.php @@ -50,10 +50,10 @@ foreach ($config['system']['user'] as $id => $user) { } if (isset($_POST['apply'])) { - $retval = vpn_ipsec_configure(); + vpn_ipsec_configure(); /* reload the filter in the background */ - filter_configure(); - $savemsg = get_std_save_message($retval); + $retval = 0; + $retval |= filter_configure(); if (is_subsystem_dirty('ipsec')) { clear_subsystem_dirty('ipsec'); } @@ -74,8 +74,8 @@ $shortcut_section = "ipsec"; include("head.inc"); -if ($savemsg) { - print_info_box($savemsg); +if ($_POST['apply']) { + print_apply_result_box($retval); } if (is_subsystem_dirty('ipsec')) { diff --git a/src/usr/local/www/vpn_ipsec_mobile.php b/src/usr/local/www/vpn_ipsec_mobile.php index 05df61d..f9c0dde 100644 --- a/src/usr/local/www/vpn_ipsec_mobile.php +++ b/src/usr/local/www/vpn_ipsec_mobile.php @@ -129,9 +129,8 @@ if ($_POST['create']) { if ($_POST['apply']) { $retval = 0; /* NOTE: #4353 Always restart ipsec when mobile clients settings change */ - $retval = vpn_ipsec_configure(true); - $savemsg = get_std_save_message($retval); - if ($retval >= 0) { + $ipsec_dynamic_hosts = vpn_ipsec_configure(true); + if ($ipsec_dynamic_hosts >= 0) { if (is_subsystem_dirty('ipsec')) { clear_subsystem_dirty('ipsec'); } @@ -400,8 +399,8 @@ include("head.inc"); </script> <?php -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($_POST['apply']) { + print_apply_result_box($retval); } if (is_subsystem_dirty('ipsec')) { print_apply_box(gettext("The IPsec tunnel configuration has been changed.") . "<br />" . gettext("The changes must be applied for them to take effect.")); diff --git a/src/usr/local/www/vpn_ipsec_settings.php b/src/usr/local/www/vpn_ipsec_settings.php index 4360837..9e21937 100644 --- a/src/usr/local/www/vpn_ipsec_settings.php +++ b/src/usr/local/www/vpn_ipsec_settings.php @@ -33,16 +33,7 @@ require_once("shaper.inc"); require_once("ipsec.inc"); require_once("vpn.inc"); -$def_loglevel = '1'; - -foreach (array_keys($ipsec_log_cats) as $cat) { - if (isset($config['ipsec']['logging'][$cat])) { - $pconfig[$cat] = $config['ipsec']['logging'][$cat]; - } else { - $pconfig[$cat] = $def_loglevel; - } -} - +$pconfig['logging'] = ipsec_get_loglevels(); $pconfig['unityplugin'] = isset($config['ipsec']['unityplugin']); $pconfig['strictcrlpolicy'] = isset($config['ipsec']['strictcrlpolicy']); $pconfig['makebeforebreak'] = isset($config['ipsec']['makebeforebreak']); @@ -59,8 +50,10 @@ if ($_POST) { $pconfig = $_POST; foreach ($ipsec_log_cats as $cat => $desc) { - if (!in_array(intval($pconfig[$cat]), array_keys($ipsec_log_sevs), true)) { + if (!in_array(intval($pconfig['logging_' . $cat]), array_keys($ipsec_log_sevs), true)) { $input_errors[] = sprintf(gettext("A valid value must be specified for %s debug."), $desc); + } else { + $pconfig['logging'][$cat] = $pconfig['logging_' . $cat]; } } @@ -79,12 +72,12 @@ if ($_POST) { * get set when we save, even if it's to the default level. */ foreach (array_keys($ipsec_log_cats) as $cat) { - if (!isset($pconfig[$cat])) { + if (!isset($pconfig['logging'][$cat])) { continue; } - if ($pconfig[$cat] != $config['ipsec']['logging'][$cat]) { - $config['ipsec']['logging'][$cat] = $pconfig[$cat]; - vpn_update_daemon_loglevel($cat, $pconfig[$cat]); + if ($pconfig['logging'][$cat] != $config['ipsec']['logging'][$cat]) { + $config['ipsec']['logging'][$cat] = $pconfig['logging'][$cat]; + vpn_update_daemon_loglevel($cat, $pconfig['logging'][$cat]); } } @@ -172,20 +165,11 @@ if ($_POST) { write_config(); + $changes_applied = true; $retval = 0; - $retval = filter_configure(); - if (stristr($retval, "error") <> true) { - $savemsg = get_std_save_message(gettext($retval)); - $class = 'success'; - } else { - $savemsg = gettext($retval); - $class = 'warning'; - } + $retval |= filter_configure(); vpn_ipsec_configure($needsrestart); - - header("Location: vpn_ipsec_settings.php"); - return; } // The logic value sent by $POST for autoexcludelanaddress is opposite to @@ -220,8 +204,8 @@ function maxmss_checked(obj) { </script> <?php -if ($savemsg) { - print_info_box($savemsg, $class); +if ($changes_applied) { + print_apply_result_box($retval); } if ($input_errors) { @@ -241,9 +225,9 @@ $section = new Form_Section('IPsec Logging Controls'); foreach ($ipsec_log_cats as $cat => $desc) { $section->addInput(new Form_Select( - $cat, + 'logging_' . $cat, $desc, - $pconfig[$cat], + $pconfig['logging'][$cat], $ipsec_log_sevs ))->setWidth(2); } diff --git a/src/usr/local/www/vpn_l2tp.php b/src/usr/local/www/vpn_l2tp.php index 1adf21b..29cddc1 100644 --- a/src/usr/local/www/vpn_l2tp.php +++ b/src/usr/local/www/vpn_l2tp.php @@ -159,14 +159,9 @@ if ($_POST) { write_config(); + $changes_applied = true; $retval = 0; - $retval = vpn_l2tp_configure(); - $savemsg = get_std_save_message($retval); - - /* if ajax is calling, give them an update message */ - if (isAjax()) { - print_info_box($savemsg, 'success'); - } + $retval |= vpn_l2tp_configure(); } } @@ -178,8 +173,8 @@ if ($input_errors) { print_input_errors($input_errors); } -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($changes_applied) { + print_apply_result_box($retval); } $tab_array = array(); diff --git a/src/usr/local/www/vpn_l2tp_users.php b/src/usr/local/www/vpn_l2tp_users.php index 3bfaec1..4c31eb8 100644 --- a/src/usr/local/www/vpn_l2tp_users.php +++ b/src/usr/local/www/vpn_l2tp_users.php @@ -44,9 +44,8 @@ if ($_POST) { if ($_POST['apply']) { $retval = 0; if (!is_subsystem_dirty('rebootreq')) { - $retval = vpn_l2tp_configure(); + $retval |= vpn_l2tp_configure(); } - $savemsg = get_std_save_message($retval); if ($retval == 0) { if (is_subsystem_dirty('l2tpusers')) { clear_subsystem_dirty('l2tpusers'); @@ -67,8 +66,8 @@ if ($_GET['act'] == "del") { include("head.inc"); -if ($savemsg) { - print_info_box($savemsg, 'success'); +if ($_POST['apply']) { + print_apply_result_box($retval); } if (isset($config['l2tp']['radius']['enable'])) { diff --git a/src/usr/local/www/vpn_openvpn_client.php b/src/usr/local/www/vpn_openvpn_client.php index 399d099..e3bc9f1 100644 --- a/src/usr/local/www/vpn_openvpn_client.php +++ b/src/usr/local/www/vpn_openvpn_client.php @@ -31,7 +31,7 @@ require_once("guiconfig.inc"); require_once("openvpn.inc"); require_once("pkg-utils.inc"); -global $openvpn_topologies; +global $openvpn_topologies, $openvpn_tls_modes; if (!is_array($config['openvpn']['openvpn-client'])) { $config['openvpn']['openvpn-client'] = array(); @@ -90,6 +90,8 @@ if ($_GET['act'] == "del") { } if ($_GET['act'] == "new") { + $pconfig['ncp_enable'] = "enabled"; + $pconfig['ncp-ciphers'] = "AES-256-GCM,AES-128-GCM"; $pconfig['autokey_enable'] = "yes"; $pconfig['tlsauth_enable'] = "yes"; $pconfig['autotls_enable'] = "yes"; @@ -129,6 +131,16 @@ if ($_GET['act'] == "edit") { $pconfig['description'] = $a_client[$id]['description']; $pconfig['custom_options'] = $a_client[$id]['custom_options']; $pconfig['ns_cert_type'] = $a_client[$id]['ns_cert_type']; + if (isset($a_client[$id]['ncp-ciphers'])) { + $pconfig['ncp-ciphers'] = $a_client[$id]['ncp-ciphers']; + } else { + $pconfig['ncp-ciphers'] = "AES-256-GCM,AES-128-GCM"; + } + if (isset($a_client[$id]['ncp_enable'])) { + $pconfig['ncp_enable'] = $a_client[$id]['ncp_enable']; + } else { + $pconfig['ncp_enable'] = "enabled"; + } $pconfig['dev_mode'] = $a_client[$id]['dev_mode']; if ($pconfig['mode'] != "p2p_shared_key") { @@ -137,6 +149,7 @@ if ($_GET['act'] == "edit") { if ($a_client[$id]['tls']) { $pconfig['tlsauth_enable'] = "yes"; $pconfig['tls'] = base64_decode($a_client[$id]['tls']); + $pconfig['tls_type'] = $a_client[$id]['tls_type']; } } else { $pconfig['shared_key'] = base64_decode($a_client[$id]['shared_key']); @@ -180,6 +193,11 @@ if ($_POST) { $vpnid = 0; } + $cipher_validation_list = array_keys(openvpn_get_cipherlist()); + if (!in_array($pconfig['crypto'], $cipher_validation_list)) { + $input_errors[] = gettext("The selected Encryption Algorithm is not valid."); + } + list($iv_iface, $iv_ip) = explode ("|", $pconfig['interface']); if (is_ipaddrv4($iv_ip) && (stristr($pconfig['protocol'], "6") !== false)) { $input_errors[] = gettext("Protocol and IP address families do not match. An IPv6 protocol and an IPv4 IP address cannot be selected."); @@ -289,12 +307,26 @@ if ($_POST) { if ($tls_mode && $pconfig['tlsauth_enable'] && !$pconfig['autotls_enable']) { if (!strstr($pconfig['tls'], "-----BEGIN OpenVPN Static key V1-----") || !strstr($pconfig['tls'], "-----END OpenVPN Static key V1-----")) { - $input_errors[] = gettext("The field 'TLS Authentication Key' does not appear to be valid"); + $input_errors[] = gettext("The field 'TLS Key' does not appear to be valid"); + } + if (!in_array($pconfig['tls_type'], array_keys($openvpn_tls_modes))) { + $input_errors[] = gettext("The field 'TLS Key Usage Mode' is not valid"); } } + if (($pconfig['mode'] == "p2p_shared_key") && strstr($pconfig['crypto'], "GCM")) { + $input_errors[] = gettext("GCM Encryption Algorithms cannot be used with Shared Key mode."); + } + /* If we are not in shared key mode, then we need the CA/Cert. */ if ($pconfig['mode'] != "p2p_shared_key") { + if (($pconfig['ncp_enable'] != "disabled") && !empty($pconfig['ncp-ciphers']) && is_array($pconfig['ncp-ciphers'])) { + foreach ($pconfig['ncp-ciphers'] as $ncpc) { + if (!in_array(trim($ncpc), $cipher_validation_list)) { + $input_errors[] = gettext("One or more of the selected NCP Algorithms is not valid."); + } + } + } $reqdfields = explode(" ", "caref"); $reqdfieldsn = array(gettext("Certificate Authority")); } elseif (!$pconfig['autokey_enable']) { @@ -317,6 +349,15 @@ if ($_POST) { $client = array(); + if (isset($id) && $a_client[$id] && + $pconfig['dev_mode'] <> $a_client[$id]['dev_mode']) { + /* + * delete old interface so a new TUN or TAP interface + * can be created. + */ + openvpn_delete('client', $a_client[$id]); + } + foreach ($simplefields as $stat) { if (($stat == 'auth_pass') && ($_POST[$stat] == DMYPWD)) { $client[$stat] = $a_client[$id]['auth_pass']; @@ -361,6 +402,7 @@ if ($_POST) { $pconfig['tls'] = openvpn_create_key(); } $client['tls'] = base64_encode($pconfig['tls']); + $client['tls_type'] = $pconfig['tls_type']; } } else { $client['shared_key'] = base64_encode($pconfig['shared_key']); @@ -381,6 +423,12 @@ if ($_POST) { $client['route_no_exec'] = $pconfig['route_no_exec']; $client['verbosity_level'] = $pconfig['verbosity_level']; + if (!empty($pconfig['ncp-ciphers'])) { + $client['ncp-ciphers'] = implode(",", $pconfig['ncp-ciphers']); + } + + $client['ncp_enable'] = $pconfig['ncp_enable'] ? "enabled":"disabled"; + if (isset($id) && $a_client[$id]) { $a_client[$id] = $client; } else { @@ -393,6 +441,10 @@ if ($_POST) { header("Location: vpn_openvpn_client.php"); exit; } + + if (!empty($pconfig['ncp-ciphers'])) { + $pconfig['ncp-ciphers'] = implode(",", $pconfig['ncp-ciphers']); + } } $pgtitle = array(gettext("VPN"), gettext("OpenVPN"), gettext("Clients")); @@ -447,22 +499,23 @@ if ($act=="new" || $act=="edit"): 'protocol', 'Protocol', $pconfig['protocol'], - array_combine($openvpn_prots, $openvpn_prots) + $openvpn_prots )); $section->addInput(new Form_Select( 'dev_mode', 'Device mode', empty($pconfig['dev_mode']) ? 'tun':$pconfig['dev_mode'], - array_combine($openvpn_dev_mode, $openvpn_dev_mode) - )); + $openvpn_dev_mode + ))->setHelp("\"tun\" mode carries IPv4 and IPv6 (OSI layer 3) and is the most common and compatible mode across all platforms." . + "<br/>\"tap\" mode is capable of carrying 802.3 (OSI Layer 2.)"); $section->addInput(new Form_Select( 'interface', 'Interface', $pconfig['interface'], openvpn_build_if_list() - )); + ))->setHelp("The interface used by the firewall to originate this OpenVPN client connection"); $section->addInput(new Form_Input( 'local_port', @@ -477,21 +530,30 @@ if ($act=="new" || $act=="edit"): 'Server host or address', 'text', $pconfig['server_addr'] - )); + ))->setHelp("The IP address or hostname of the OpenVPN server."); + + $section->addInput(new Form_Checkbox( + 'resolve_retry', + 'Server hostname resolution', + 'Infinitely resolve server ', + $pconfig['resolve_retry'] + ))->setHelp('Continuously attempt to resolve the server host name. ' . + 'Useful when communicating with a server that is not permanently connected to the Internet.'); $section->addInput(new Form_Input( 'server_port', 'Server port', 'number', $pconfig['server_port'] - )); + ))->setHelp("The port used by the server to receive client connections."); $section->addInput(new Form_Input( 'proxy_addr', 'Proxy host or address', 'text', $pconfig['proxy_addr'] - )); + ))->setHelp("The address for an HTTP Proxy this client can use to connect to a remote server." . + "<br/>TCP must be used for the client and server protocol."); $section->addInput(new Form_Input( 'proxy_port', @@ -502,10 +564,10 @@ if ($act=="new" || $act=="edit"): $section->addInput(new Form_Select( 'proxy_authtype', - 'Proxy Auth. - Extra options', + 'Proxy Authentication', $pconfig['proxy_authtype'], array('none' => gettext('none'), 'basic' => gettext('basic'), 'ntlm' => gettext('ntlm')) - )); + ))->setHelp("The type of authentication used by the proxy server."); $section->addInput(new Form_Input( 'proxy_user', @@ -521,14 +583,6 @@ if ($act=="new" || $act=="edit"): $pconfig['proxy_passwd'] )); - $section->addInput(new Form_Checkbox( - 'resolve_retry', - 'Server hostname resolution', - 'Infinitely resolve server ', - $pconfig['resolve_retry'] - ))->setHelp('Continuously attempt to resolve the server host name. ' . - 'Useful when communicating with a server that is not permanently connected to the Internet.'); - $section->addInput(new Form_Input( 'description', 'Description', @@ -560,25 +614,38 @@ if ($act=="new" || $act=="edit"): $section->addInput(new Form_Checkbox( 'tlsauth_enable', - 'TLS authentication', - 'Enable authentication of TLS packets.', + 'TLS Configuration', + 'Use a TLS Key', $pconfig['tlsauth_enable'] - )); + ))->setHelp("A TLS key enhances security of an OpenVPN connection by requiring both parties to have a common key before a peer can perform a TLS handshake. " . + "This layer of HMAC authentication allows control channel packets without the proper key to be dropped, protecting the peers from attack or unauthorized connections." . + "The TLS Key does not have any effect on tunnel data."); if (!$pconfig['tls']) { $section->addInput(new Form_Checkbox( 'autotls_enable', null, - 'Automatically generate a shared TLS authentication key.', + 'Automatically generate a TLS Key.', $pconfig['autotls_enable'] )); } $section->addInput(new Form_Textarea( 'tls', - 'Key', + 'TLS Key', $pconfig['tls'] - ))->setHelp('Paste the shared key here'); + ))->setHelp("Paste the TLS key here." . + "<br/>" . + "This key is used to sign control channel packets with an HMAC signature for authentication when establishing the tunnel. "); + + $section->addInput(new Form_Select( + 'tls_type', + 'TLS Key Usage Mode', + empty($pconfig['tls_type']) ? 'auth':$pconfig['tls_type'], + $openvpn_tls_modes + ))->setHelp("In Authentication mode the TLS key is used only as HMAC authentication for the control channel, protecting the peers from unauthorized connections. " . + "<br/>" . + "Encryption and Authentication mode also encrypts control channel communication, providing more privacy and traffic control channel obfuscation."); if (count($a_ca)) { $list = array(); @@ -640,14 +707,60 @@ if ($act=="new" || $act=="edit"): 'Encryption Algorithm', $pconfig['crypto'], openvpn_get_cipherlist() - )); + ))->setHelp('The Encryption Algorithm used for data channel packets when Negotiable Cryptographic Parameter (NCP) support is not available.'); + + $section->addInput(new Form_Checkbox( + 'ncp_enable', + 'Enable NCP', + 'Enable Negotiable Cryptographic Parameters', + ($pconfig['ncp_enable'] == "enabled") + ))->setHelp( 'Check this option to allow OpenVPN clients and servers to negotiate a compatible set of acceptable cryptographic ' . + 'Encryption Algorithms from those selected in the NCP Algorithms list below.' . + '<div class="infoblock">' . sprint_info_box('When both peers support NCP and have it enabled, NCP overrides the Encryption Algorithm above.' . '<br />' . + 'When disabled, only the selected Encryption Algorithm is allowed.', 'info', false) . '</div>'); + + foreach (explode(",", $pconfig['ncp-ciphers']) as $cipher) { + $ncp_ciphers_list[$cipher] = $cipher; + } + $group = new Form_Group('NCP Algorithms'); + + $group->add(new Form_Select( + 'availciphers', + null, + array(), + openvpn_get_cipherlist(), + true + ))->setAttribute('size', '10') + ->setHelp('Available NCP Encryption Algorithms<br />Click to add or remove an algorithm from the list'); + + $group->add(new Form_Select( + 'ncp-ciphers', + null, + array(), + $ncp_ciphers_list, + true + ))->setReadonly() + ->setAttribute('size', '10') + ->setHelp('Allowed NCP Encryption Algorithms. Click an algorithm name to remove it from the list'); + + $group->setHelp( 'The order of the selected NCP Encryption Algorithms is respected by OpenVPN.' . + '<div class="infoblock">' . sprint_info_box( + 'For backward compatibility, when an older peer connects that does not support NCP, OpenVPN will use the Encryption Algorithm ' . + 'requested by the peer so long as it is selected in this list or chosen as the Encryption Algorithm.', 'info', false) . + '</div>'); + + $section->add($group); $section->addInput(new Form_Select( 'digest', 'Auth digest algorithm', $pconfig['digest'], openvpn_get_digestlist() - ))->setHelp('Leave this set to SHA1 unless all clients are set to match. SHA1 is the default for OpenVPN. '); + ))->setHelp('The algorithm used to authenticate data channel packets, and control channel packets if a TLS Key is present.' . + '<br />' . + 'When an AEAD Encryption Algorithm mode is used, such as AES-GCM, this digest is used for the control channel only, not the data channel.' . + '<br />' . + 'Leave this set to SHA1 unless the server uses a different value. SHA1 is the default for OpenVPN. '); $section->addInput(new Form_Select( 'engine', @@ -768,7 +881,7 @@ if ($act=="new" || $act=="edit"): $act )); - if (isset($id) && $a_server[$id]) { + if (isset($id) && $a_client[$id]) { $section->addInput(new Form_Input( 'id', null, @@ -896,6 +1009,7 @@ events.push(function() { // Process "Automatically generate a shared TLS authentication key" checkbox function autotls_change() { hideInput('tls', $('#autotls_enable').prop('checked') || !$('#tlsauth_enable').prop('checked')); + hideInput('tls_type', $('#autotls_enable').prop('checked') || !$('#tlsauth_enable').prop('checked')); } // ---------- Monitor elements for change and call the appropriate display functions ------------------------------ @@ -930,6 +1044,45 @@ events.push(function() { autotls_change(); }); + function updateCiphers(mem) { + var found = false; + + // If the cipher exists, remove it + $('[id="ncp-ciphers[]"] option').each(function() { + if($(this).val() == mem) { + $(this).remove(); + found = true; + } + }); + + // If not, add it + if (!found) { + $('[id="ncp-ciphers[]"]').append(new Option(mem , mem)); + } + + // Unselect all options + $('[id="availciphers[]"] option:selected').removeAttr("selected"); + } + + // On click, update the ciphers list + $('[id="availciphers[]"]').click(function () { + updateCiphers($(this).val()); + }); + + // On click, remove the cipher from the list + $('[id="ncp-ciphers[]"]').click(function () { + if ($(this).val() != null) { + updateCiphers($(this).val()); + } + }); + + // Make sure the "Available ciphers" selector is not submitted with the form, + // and select all of the chosen ciphers so that they are submitted + $('form').submit(function() { + $("#availciphers" ).prop( "disabled", true); + $('[id="ncp-ciphers[]"] option').attr("selected", "selected"); + }); + // ---------- Set initial page display state ---------------------------------------------------------------------- mode_change(); autokey_change(); diff --git a/src/usr/local/www/vpn_openvpn_csc.php b/src/usr/local/www/vpn_openvpn_csc.php index 16ba076..65932c2 100644 --- a/src/usr/local/www/vpn_openvpn_csc.php +++ b/src/usr/local/www/vpn_openvpn_csc.php @@ -74,6 +74,7 @@ if ($_GET['act'] == "edit") { $pconfig['description'] = $a_csc[$id]['description']; $pconfig['tunnel_network'] = $a_csc[$id]['tunnel_network']; + $pconfig['tunnel_networkv6'] = $a_csc[$id]['tunnel_networkv6']; $pconfig['local_network'] = $a_csc[$id]['local_network']; $pconfig['local_networkv6'] = $a_csc[$id]['local_networkv6']; $pconfig['remote_network'] = $a_csc[$id]['remote_network']; @@ -132,7 +133,10 @@ if ($_POST) { $pconfig = $_POST; /* input validation */ - if ($result = openvpn_validate_cidr($pconfig['tunnel_network'], 'Tunnel network')) { + if ($result = openvpn_validate_cidr($pconfig['tunnel_network'], 'IPv4 Tunnel Network')) { + $input_errors[] = $result; + } + if ($result = openvpn_validate_cidr($pconfig['tunnel_networkv6'], 'IPv6 Tunnel Network', false, "ipv6")) { $input_errors[] = $result; } @@ -219,6 +223,7 @@ if ($_POST) { $csc['block'] = $pconfig['block']; $csc['description'] = $pconfig['description']; $csc['tunnel_network'] = $pconfig['tunnel_network']; + $csc['tunnel_networkv6'] = $pconfig['tunnel_networkv6']; $csc['local_network'] = $pconfig['local_network']; $csc['local_networkv6'] = $pconfig['local_networkv6']; $csc['remote_network'] = $pconfig['remote_network']; @@ -320,7 +325,7 @@ if ($act == "new" || $act == "edit"): $pconfig['server_list'], $serveroptionlist, true - ))->setHelp('Select the servers for which the override will apply. Selecting no servers will also apply the override to all servers.'); + ))->setHelp('Select the servers that will utilize this override. When no servers are selected, the override will apply to all servers.'); $section->addInput(new Form_Checkbox( @@ -332,24 +337,24 @@ if ($act == "new" || $act == "edit"): $section->addInput(new Form_Input( 'common_name', - 'Common name', + 'Common Name', 'text', $pconfig['common_name'] - ))->setHelp('Enter the client\'s X.509 common name.'); + ))->setHelp('Enter the X.509 common name for the client certificate, or the username for VPNs utilizing password authentication. This match is case sensitive.'); $section->addInput(new Form_Input( 'description', 'Description', 'text', $pconfig['description'] - ))->setHelp('A description may be entered here for administrative reference (not parsed). '); + ))->setHelp('A description for administrative reference (not parsed).'); $section->addInput(new Form_Checkbox( 'block', 'Connection blocking', - 'Block this client connection based on its common name. ', + 'Block this client connection based on its common name.', $pconfig['block'] - ))->setHelp('Don\'t use this option to permanently disable a client due to a compromised key or password. Use a CRL (certificate revocation list) instead. '); + ))->setHelp('Prevents the client from connecting to this server. Do not use this option to permanently disable a client due to a compromised key or password. Use a CRL (certificate revocation list) instead.'); $form->add($section); @@ -357,45 +362,57 @@ if ($act == "new" || $act == "edit"): $section->addInput(new Form_Input( 'tunnel_network', - 'Tunnel Network', + 'IPv4 Tunnel Network', 'text', $pconfig['tunnel_network'] - ))->setHelp('This is the virtual network used for private communications between this client and the server expressed using CIDR (e.g. 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. '); + ))->setHelp('The virtual IPv4 network used for private communications between this client and the server expressed using CIDR (e.g. 10.0.8.5/24). ' . + '<br />' . + 'With subnet topology, enter the client IP address and the subnet mask must match the IPv4 Tunnel Network on the server. ' . + '<br />' . + 'With net30 topology, the first network address of the /30 is assumed to be the server address and the second network address will be assigned to the client.'); + + $section->addInput(new Form_Input( + 'tunnel_networkv6', + 'IPv6 Tunnel Network', + 'text', + $pconfig['tunnel_networkv6'] + ))->setHelp('The virtual IPv6 network used for private communications between this client and the server expressed using prefix (e.g. 2001:db9:1:1::100/64). ' . + '<br />' . + 'Enter the client IPv6 address and prefix. The prefix must match the IPv6 Tunnel Network prefix on the server. '); $section->addInput(new Form_Input( 'local_network', 'IPv4 Local Network/s', 'text', $pconfig['local_network'] - ))->setHelp('These are the IPv4 networks that will be accessible from this particular client. Expressed as a comma-separated list of one or more CIDR ranges. ' . '<br />' . - 'NOTE: Networks do not need to be specified here if they have already been defined on the main server configuration.'); + ))->setHelp('These are the IPv4 server-side networks that will be accessible from this particular client. Expressed as a comma-separated list of one or more CIDR networks. ' . '<br />' . + 'NOTE: Networks do not need to be specified here if they have already been defined on the main server configuration.'); $section->addInput(new Form_Input( 'local_networkv6', 'IPv6 Local Network/s', 'text', $pconfig['local_networkv6'] - ))->setHelp('These are the IPv4 networks that will be accessible from this particular client. Expressed as a comma-separated list of one or more IP/PREFIX networks.' . '<br />' . - 'NOTE: Networks do not need to be specified here if they have already been defined on the main server configuration.'); + ))->setHelp('These are the IPv6 server-side networks that will be accessible from this particular client. Expressed as a comma-separated list of one or more IP/PREFIX networks.' . '<br />' . + 'NOTE: Networks do not need to be specified here if they have already been defined on the main server configuration.'); $section->addInput(new Form_Input( 'remote_network', 'IPv4 Remote Network/s', 'text', $pconfig['remote_network'] - ))->setHelp('These are the IPv4 networks that will be routed to this client specifically using iroute, so that a site-to-site VPN can be established. ' . - 'Expressed as a comma-separated list of one or more CIDR ranges. May be left blank if there are no client-side networks to be routed.' . '<br />' . - 'NOTE: Remember to add these subnets to the IPv4 Remote Networks list on the corresponding OpenVPN server settings.'); + ))->setHelp('These are the IPv4 client-side networks that will be routed to this client specifically using iroute, so that a site-to-site VPN can be established. ' . + 'Expressed as a comma-separated list of one or more CIDR ranges. May be left blank if there are no client-side networks to be routed.' . '<br />' . + 'NOTE: Remember to add these subnets to the IPv4 Remote Networks list on the corresponding OpenVPN server settings.'); $section->addInput(new Form_Input( 'remote_networkv6', 'IPv6 Remote Network/s', 'text', $pconfig['remote_networkv6'] - ))->setHelp('These are the IPv6 networks that will be routed to this client specifically using iroute, so that a site-to-site VPN can be established. ' . - 'Expressed as a comma-separated list of one or more IP/PREFIX networks. May be left blank if there are no client-side networks to be routed.' . '<br />' . - 'NOTE: Remember to add these subnets to the IPv6 Remote Networks list on the corresponding OpenVPN server settings.'); + ))->setHelp('These are the IPv6 client-side networks that will be routed to this client specifically using iroute, so that a site-to-site VPN can be established. ' . + 'Expressed as a comma-separated list of one or more IP/PREFIX networks. May be left blank if there are no client-side networks to be routed.' . '<br />' . + 'NOTE: Remember to add these subnets to the IPv6 Remote Networks list on the corresponding OpenVPN server settings.'); $section->addInput(new Form_Checkbox( 'gwredir', diff --git a/src/usr/local/www/vpn_openvpn_server.php b/src/usr/local/www/vpn_openvpn_server.php index 433b689..efd3b26 100644 --- a/src/usr/local/www/vpn_openvpn_server.php +++ b/src/usr/local/www/vpn_openvpn_server.php @@ -31,7 +31,7 @@ require_once("guiconfig.inc"); require_once("openvpn.inc"); require_once("pkg-utils.inc"); -global $openvpn_topologies; +global $openvpn_topologies, $openvpn_tls_modes; if (!is_array($config['openvpn']['openvpn-server'])) { $config['openvpn']['openvpn-server'] = array(); @@ -96,6 +96,8 @@ if ($_GET['act'] == "del") { } if ($_GET['act'] == "new") { + $pconfig['ncp_enable'] = "enabled"; + $pconfig['ncp-ciphers'] = "AES-256-GCM,AES-128-GCM"; $pconfig['autokey_enable'] = "yes"; $pconfig['tlsauth_enable'] = "yes"; $pconfig['autotls_enable'] = "yes"; @@ -117,6 +119,16 @@ if ($_GET['act'] == "edit") { $pconfig['mode'] = $a_server[$id]['mode']; $pconfig['protocol'] = $a_server[$id]['protocol']; $pconfig['authmode'] = $a_server[$id]['authmode']; + if (isset($a_server[$id]['ncp-ciphers'])) { + $pconfig['ncp-ciphers'] = $a_server[$id]['ncp-ciphers']; + } else { + $pconfig['ncp-ciphers'] = "AES-256-GCM,AES-128-GCM"; + } + if (isset($a_server[$id]['ncp_enable'])) { + $pconfig['ncp_enable'] = $a_server[$id]['ncp_enable']; + } else { + $pconfig['ncp_enable'] = "enabled"; + } $pconfig['dev_mode'] = $a_server[$id]['dev_mode']; $pconfig['interface'] = $a_server[$id]['interface']; @@ -132,6 +144,7 @@ if ($_GET['act'] == "edit") { if ($a_server[$id]['tls']) { $pconfig['tlsauth_enable'] = "yes"; $pconfig['tls'] = base64_decode($a_server[$id]['tls']); + $pconfig['tls_type'] = $a_server[$id]['tls_type']; } $pconfig['caref'] = $a_server[$id]['caref']; @@ -165,6 +178,7 @@ if ($_GET['act'] == "edit") { $pconfig['local_networkv6'] = $a_server[$id]['local_networkv6']; $pconfig['maxclients'] = $a_server[$id]['maxclients']; $pconfig['compression'] = $a_server[$id]['compression']; + $pconfig['compression_push'] = $a_server[$id]['compression_push']; $pconfig['passtos'] = $a_server[$id]['passtos']; $pconfig['client2client'] = $a_server[$id]['client2client']; @@ -240,8 +254,8 @@ if ($_GET['act'] == "edit") { $pconfig['push_register_dns'] = $a_server[$id]['push_register_dns']; } } -if ($_POST) { +if ($_POST) { unset($input_errors); $pconfig = $_POST; @@ -251,6 +265,11 @@ if ($_POST) { $vpnid = 0; } + $cipher_validation_list = array_keys(openvpn_get_cipherlist()); + if (!in_array($pconfig['crypto'], $cipher_validation_list)) { + $input_errors[] = gettext("The selected Encryption Algorithm is not valid."); + } + list($iv_iface, $iv_ip) = explode ("|", $pconfig['interface']); if (is_ipaddrv4($iv_ip) && (stristr($pconfig['protocol'], "6") !== false)) { $input_errors[] = gettext("Protocol and IP address families do not match. An IPv6 protocol and an IPv4 IP address cannot be selected."); @@ -328,7 +347,10 @@ if ($_POST) { if ($tls_mode && $pconfig['tlsauth_enable'] && !$pconfig['autotls_enable']) { if (!strstr($pconfig['tls'], "-----BEGIN OpenVPN Static key V1-----") || !strstr($pconfig['tls'], "-----END OpenVPN Static key V1-----")) { - $input_errors[] = gettext("The field 'TLS Authentication Key' does not appear to be valid"); + $input_errors[] = gettext("The field 'TLS Key' does not appear to be valid"); + } + if (!in_array($pconfig['tls_type'], array_keys($openvpn_tls_modes))) { + $input_errors[] = gettext("The field 'TLS Key Usage Mode' is not valid"); } } @@ -406,6 +428,14 @@ if ($_POST) { $input_errors[] = gettext("The specified ECDH Curve is invalid."); } + if (($pconfig['ncp_enable'] != "disabled") && !empty($pconfig['ncp-ciphers']) && is_array($pconfig['ncp-ciphers'])) { + foreach ($pconfig['ncp-ciphers'] as $ncpc) { + if (!in_array(trim($ncpc), $cipher_validation_list)) { + $input_errors[] = gettext("One or more of the selected NCP Algorithms is not valid."); + } + } + } + $reqdfields = explode(" ", "caref certref"); $reqdfieldsn = array(gettext("Certificate Authority"), gettext("Certificate")); } elseif (!$pconfig['autokey_enable']) { @@ -414,6 +444,10 @@ if ($_POST) { $reqdfieldsn = array(gettext('Shared key')); } + if (($pconfig['mode'] == "p2p_shared_key") && strstr($pconfig['crypto'], "GCM")) { + $input_errors[] = gettext("GCM Encryption Algorithms cannot be used with Shared Key mode."); + } + if ($pconfig['dev_mode'] != "tap") { $reqdfields[] = 'tunnel_network'; $reqdfieldsn[] = gettext('Tunnel network'); @@ -435,14 +469,20 @@ if ($_POST) { $input_errors[] = gettext("The Server Bridge DHCP range is invalid (start higher than end)."); } } + do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors); if (!$input_errors) { $server = array(); - if ($id && $pconfig['dev_mode'] <> $a_server[$id]['dev_mode']) { - openvpn_delete('server', $a_server[$id]);// delete(rename) old interface so a new TUN or TAP interface can be created. + if (isset($id) && $a_server[$id] && + $pconfig['dev_mode'] <> $a_server[$id]['dev_mode']) { + /* + * delete old interface so a new TUN or TAP interface + * can be created. + */ + openvpn_delete('server', $a_server[$id]); } if ($vpnid) { @@ -471,6 +511,7 @@ if ($_POST) { $pconfig['tls'] = openvpn_create_key(); } $server['tls'] = base64_encode($pconfig['tls']); + $server['tls_type'] = $pconfig['tls_type']; } $server['caref'] = $pconfig['caref']; $server['crlref'] = $pconfig['crlref']; @@ -498,6 +539,7 @@ if ($_POST) { $server['local_networkv6'] = $pconfig['local_networkv6']; $server['maxclients'] = $pconfig['maxclients']; $server['compression'] = $pconfig['compression']; + $server['compression_push'] = $pconfig['compression_push']; $server['passtos'] = $pconfig['passtos']; $server['client2client'] = $pconfig['client2client']; @@ -559,6 +601,12 @@ if ($_POST) { $server['duplicate_cn'] = true; } + if (!empty($pconfig['ncp-ciphers'])) { + $server['ncp-ciphers'] = implode(",", $pconfig['ncp-ciphers']); + } + + $server['ncp_enable'] = $pconfig['ncp_enable'] ? "enabled":"disabled"; + if (isset($id) && $a_server[$id]) { $a_server[$id] = $server; } else { @@ -572,6 +620,11 @@ if ($_POST) { header("Location: vpn_openvpn_server.php"); exit; } + + if (!empty($pconfig['ncp-ciphers'])) { + $pconfig['ncp-ciphers'] = implode(",", $pconfig['ncp-ciphers']); + } + if (!empty($pconfig['authmode'])) { $pconfig['authmode'] = implode(",", $pconfig['authmode']); } @@ -629,9 +682,14 @@ if ($act=="new" || $act=="edit"): $options = array(); $authmodes = array(); - $authmodes = explode(",", $pconfig['authmode']); + $auth_servers = auth_get_authserver_list(); + + foreach (explode(",", $pconfig['ncp-ciphers']) as $cipher) { + $ncp_ciphers_list[$cipher] = $cipher; + } + // If no authmodes set then default to selecting the first entry in auth_servers if (empty($authmodes[0]) && !empty(key($auth_servers))) { $authmodes[0] = key($auth_servers); @@ -660,15 +718,16 @@ if ($act=="new" || $act=="edit"): 'dev_mode', 'Device mode', empty($pconfig['dev_mode']) ? 'tun':$pconfig['dev_mode'], - array_combine($openvpn_dev_mode, $openvpn_dev_mode) - )); + $openvpn_dev_mode + ))->setHelp("\"tun\" mode carries IPv4 and IPv6 (OSI layer 3) and is the most common and compatible mode across all platforms." . + "<br/>\"tap\" mode is capable of carrying 802.3 (OSI Layer 2.)"); $section->addInput(new Form_Select( 'interface', 'Interface', $pconfig['interface'], openvpn_build_if_list() - )); + ))->setHelp("The interface or Virtual IP address where OpenVPN will receive client connections."); $section->addInput(new Form_Input( 'local_port', @@ -676,7 +735,7 @@ if ($act=="new" || $act=="edit"): 'number', $pconfig['local_port'], ['min' => '0'] - )); + ))->setHelp("The port used by OpenVPN to receive client connections."); $section->addInput(new Form_Input( 'description', @@ -691,25 +750,38 @@ if ($act=="new" || $act=="edit"): $section->addInput(new Form_Checkbox( 'tlsauth_enable', - 'TLS authentication', - 'Enable authentication of TLS packets.', + 'TLS Configuration', + 'Use a TLS Key', $pconfig['tlsauth_enable'] - )); + ))->setHelp("A TLS key enhances security of an OpenVPN connection by requiring both parties to have a common key before a peer can perform a TLS handshake. " . + "This layer of HMAC authentication allows control channel packets without the proper key to be dropped, protecting the peers from attack or unauthorized connections." . + "The TLS Key does not have any effect on tunnel data."); if (!$pconfig['tls']) { $section->addInput(new Form_Checkbox( 'autotls_enable', null, - 'Automatically generate a shared TLS authentication key.', + 'Automatically generate a TLS Key.', $pconfig['autotls_enable'] )); } $section->addInput(new Form_Textarea( 'tls', - 'Key', + 'TLS Key', $pconfig['tls'] - ))->setHelp('Paste the shared key here'); + ))->setHelp("Paste the TLS key here." . + "<br/>" . + "This key is used to sign control channel packets with an HMAC signature for authentication when establishing the tunnel. "); + + $section->addInput(new Form_Select( + 'tls_type', + 'TLS Key Usage Mode', + empty($pconfig['tls_type']) ? 'auth':$pconfig['tls_type'], + $openvpn_tls_modes + ))->setHelp("In Authentication mode the TLS key is used only as HMAC authentication for the control channel, protecting the peers from unauthorized connections. " . + "<br/>" . + "Encryption and Authentication mode also encrypts control channel communication, providing more privacy and traffic control channel obfuscation."); if (count($a_ca)) { @@ -775,14 +847,24 @@ if ($act=="new" || $act=="edit"): 'DH Parameter Length', $pconfig['dh_length'], $openvpn_dh_lengths - ))->setHelp(count($a_cert) ? '':sprintf('No Certificates defined. One may be created here: %s', '<a href="system_camanager.php">System > Cert. Manager</a>')); + ))->setHelp('Diffie-Hellman (DH) parameter set used for key exchange.' . + '<div class="infoblock">' . + sprint_info_box('Only DH parameter sets which exist in /etc/ are shown. ' . + '<br/>' . + 'Generating new or stronger DH parameters is CPU-intensive and must be performed manually. ' . + 'Consult <a href="https://doc.pfsense.org/index.php/DH_Parameters">the doc wiki article on DH Parameters</a> ' . + 'for information on generating new or stronger paramater sets.', 'info', false) . + '</div>'); $section->addInput(new Form_Select( 'ecdh_curve', 'ECDH Curve', $pconfig['ecdh_curve'], openvpn_get_curvelist() - )); + ))->setHelp('The Elliptic Curve to use for key exchange. ' . + '<br/>' . + 'The curve from the server certificate is used by default when the server uses an ECDSA certificate. ' . + 'Otherwise, secp384r1 is used as a fallback.'); if (!$pconfig['shared_key']) { $section->addInput(new Form_Checkbox( @@ -804,14 +886,57 @@ if ($act=="new" || $act=="edit"): 'Encryption Algorithm', $pconfig['crypto'], openvpn_get_cipherlist() - )); + ))->setHelp('The Encryption Algorithm used for data channel packets when Negotiable Cryptographic Parameter (NCP) support is not available.'); + + $section->addInput(new Form_Checkbox( + 'ncp_enable', + 'Enable NCP', + 'Enable Negotiable Cryptographic Parameters', + ($pconfig['ncp_enable'] == "enabled") + ))->setHelp( 'Check this option to allow OpenVPN clients and servers to negotiate a compatible set of acceptable cryptographic ' . + 'Encryption Algorithms from those selected in the NCP Algorithms list below.' . + '<div class="infoblock">' . sprint_info_box('When both peers support NCP and have it enabled, NCP overrides the Encryption Algorithm above.' . '<br />' . + 'When disabled, only the selected Encryption Algorithm is allowed.', 'info', false) . '</div>'); + + $group = new Form_Group('NCP Algorithms'); + + $group->add(new Form_Select( + 'availciphers', + null, + array(), + openvpn_get_cipherlist(), + true + ))->setAttribute('size', '10') + ->setHelp('Available NCP Encryption Algorithms<br />Click to add or remove an algorithm from the list'); + + $group->add(new Form_Select( + 'ncp-ciphers', + null, + array(), + $ncp_ciphers_list, + true + ))->setReadonly() + ->setAttribute('size', '10') + ->setHelp('Allowed NCP Encryption Algorithms. Click an algorithm name to remove it from the list'); + + $group->setHelp( 'The order of the selected NCP Encryption Algorithms is respected by OpenVPN.' . + '<div class="infoblock">' . sprint_info_box( + 'For backward compatibility, when an older peer connects that does not support NCP, OpenVPN will use the Encryption Algorithm ' . + 'requested by the peer so long as it is selected in this list or chosen as the Encryption Algorithm.', 'info', false) . + '</div>'); + + $section->add($group); $section->addInput(new Form_Select( 'digest', 'Auth digest algorithm', $pconfig['digest'], openvpn_get_digestlist() - ))->setHelp('Leave this set to SHA1 unless all clients are set to match. SHA1 is the default for OpenVPN. '); + ))->setHelp('The algorithm used to authenticate data channel packets, and control channel packets if a TLS Key is present.' . + '<br />' . + 'When an AEAD Encryption Algorithm mode is used, such as AES-GCM, this digest is used for the control channel only, not the data channel.' . + '<br />' . + 'Leave this set to SHA1 unless all clients are set to match. SHA1 is the default for OpenVPN. '); $section->addInput(new Form_Select( 'engine', @@ -952,6 +1077,13 @@ if ($act=="new" || $act=="edit"): 'packets is not being compressed efficiently.'); $section->addInput(new Form_Checkbox( + 'compression_push', + 'Push Compression', + 'Push the selected Compression setting to connecting clients.', + $pconfig['compression_push'] + )); + + $section->addInput(new Form_Checkbox( 'passtos', 'Type-of-Service', 'Set the TOS IP header value of tunnel packets to match the encapsulated packet value.', @@ -1290,6 +1422,7 @@ events.push(function() { case "server_tls": case "server_user": hideInput('tls', false); + hideInput('tls_type', false); hideInput('certref', false); hideInput('dh_length', false); hideInput('ecdh_curve', false); @@ -1298,9 +1431,11 @@ events.push(function() { hideCheckbox('autokey_enable', true); hideInput('shared_key', false); hideInput('topology', false); + hideCheckbox('compression_push', false); break; case "server_tls_user": hideInput('tls', false); + hideInput('tls_type', false); hideInput('certref', false); hideInput('dh_length', false); hideInput('ecdh_curve', false); @@ -1309,9 +1444,11 @@ events.push(function() { hideCheckbox('autokey_enable', true); hideInput('shared_key', true); hideInput('topology', false); + hideCheckbox('compression_push', false); break; case "p2p_shared_key": hideInput('tls', true); + hideInput('tls_type', true); hideInput('caref', true); hideInput('crlref', true); hideLabel('Peer Certificate Revocation list', true); @@ -1325,6 +1462,7 @@ events.push(function() { hideCheckbox('autokey_enable', true); hideInput('shared_key', false); hideInput('topology', true); + hideCheckbox('compression_push', true); break; } @@ -1394,10 +1532,12 @@ events.push(function() { function autotls_change() { if (($('#mode').val() == 'p2p_shared_key') || (!$('#tlsauth_enable').prop('checked'))) { hideInput('tls', true); + hideInput('tls_type', true); hideInput('autotls_enable', true); } else { hideInput('autotls_enable', false); hideInput('tls', $('#autotls_enable').prop('checked') || !$('#tlsauth_enable').prop('checked')); + hideInput('tls_type', $('#autotls_enable').prop('checked') || !$('#tlsauth_enable').prop('checked')); } } @@ -1617,6 +1757,45 @@ events.push(function() { $('#certtype').html(errmsg); }); + function updateCiphers(mem) { + var found = false; + + // If the cipher exists, remove it + $('[id="ncp-ciphers[]"] option').each(function() { + if($(this).val() == mem) { + $(this).remove(); + found = true; + } + }); + + // If not, add it + if (!found) { + $('[id="ncp-ciphers[]"]').append(new Option(mem , mem)); + } + + // Unselect all options + $('[id="availciphers[]"] option:selected').removeAttr("selected"); + } + + // On click, update the ciphers list + $('[id="availciphers[]"]').click(function () { + updateCiphers($(this).val()); + }); + + // On click, remove the cipher from the list + $('[id="ncp-ciphers[]"]').click(function () { + if ($(this).val() != null) { + updateCiphers($(this).val()); + } + }); + + // Make sure the "Available ciphers" selector is not submitted with the form, + // and select all of the chosen ciphers so that they are submitted + $('form').submit(function() { + $("#availciphers" ).prop( "disabled", true); + $('[id="ncp-ciphers[]"] option').attr("selected", "selected"); + }); + // ---------- Set initial page display state ---------------------------------------------------------------------- mode_change(); autokey_change(); diff --git a/src/usr/local/www/widgets/widgets/gateways.widget.php b/src/usr/local/www/widgets/widgets/gateways.widget.php index 34f4d2e..c854df5 100644 --- a/src/usr/local/www/widgets/widgets/gateways.widget.php +++ b/src/usr/local/www/widgets/widgets/gateways.widget.php @@ -38,12 +38,29 @@ if ($_REQUEST && $_REQUEST['ajax']) { } if ($_POST) { + + if (!is_array($user_settings["widgets"]["gateways_widget"])) { $user_settings["widgets"]["gateways_widget"] = array(); } + if (isset($_POST["display_type"])) { $user_settings["widgets"]["gateways_widget"]["display_type"] = $_POST["display_type"]; } + + if (is_array($_POST['show'])) { + $validNames = array(); + $a_gateways = return_gateways_array(); + + foreach ($a_gateways as $gname => $gateway) { + array_push($validNames, $gname); + } + + $user_settings["widgets"]["gateways_widget"]["gatewaysfilter"] = implode(',', array_diff($validNames, $_POST['show'])); + } else { + $user_settings["widgets"]["gateways_widget"]["gatewaysfilter"] = ""; + } + save_widget_settings($_SESSION['Username'], $user_settings["widgets"], gettext("Updated gateways widget settings via dashboard.")); header("Location: /"); exit(0); @@ -71,55 +88,86 @@ $widgetperiod = isset($config['widgets']['period']) ? $config['widgets']['period </table> </div> <!-- close the body we're wrapped in and add a configuration-panel --> -</div> - -<div id="widget-<?=$widgetname?>_panel-footer" class="panel-footer collapse"> -<input type="hidden" id="gateways-config" name="gateways-config" value="" /> - -<div id="gateways-settings" class="widgetconfigdiv" > - <form action="/widgets/widgets/gateways.widget.php" method="post" name="gateways_widget_iform" id="gateways_widget_iform"> - Display: - <?php - $display_type_gw_ip = "checked"; - $display_type_monitor_ip = ""; - $display_type_both_ip = ""; - if (isset($user_settings["widgets"]["gateways_widget"]["display_type"])) { - $selected_radio = $user_settings["widgets"]["gateways_widget"]["display_type"]; - if ($selected_radio == "gw_ip") { - $display_type_gw_ip = "checked"; - $display_type_monitor_ip = ""; - $display_type_both_ip = ""; - } else if ($selected_radio == "monitor_ip") { - $display_type_gw_ip = ""; - $display_type_monitor_ip = "checked"; - $display_type_both_ip = ""; - } else if ($selected_radio == "both_ip") { - $display_type_gw_ip = ""; - $display_type_monitor_ip = ""; - $display_type_both_ip = "checked"; - } +</div><div id="widget-<?=$widgetname?>_panel-footer" class="panel-footer collapse"> +<form action="/widgets/widgets/gateways.widget.php" method="post" class="form-horizontal"> + <div class="form-group"> + <label class="col-sm-3 control-label"><?=gettext('Display')?></label> + <?php + $display_type_gw_ip = "checked"; + $display_type_monitor_ip = ""; + $display_type_both_ip = ""; + if (isset($user_settings["widgets"]["gateways_widget"]["display_type"])) { + $selected_radio = $user_settings["widgets"]["gateways_widget"]["display_type"]; + if ($selected_radio == "gw_ip") { + $display_type_gw_ip = "checked"; + $display_type_monitor_ip = ""; + $display_type_both_ip = ""; + } else if ($selected_radio == "monitor_ip") { + $display_type_gw_ip = ""; + $display_type_monitor_ip = "checked"; + $display_type_both_ip = ""; + } else if ($selected_radio == "both_ip") { + $display_type_gw_ip = ""; + $display_type_monitor_ip = ""; + $display_type_both_ip = "checked"; } - ?> - - <div class="radio"> - <label><input name="display_type" type="radio" id="display_type_gw_ip" value="gw_ip" <?=$display_type_gw_ip;?> onchange="updateGatewayDisplays();" /> <?=gettext('Gateway IP')?></label> - </div> - <div class="radio"> - <label><input name="display_type" type="radio" id="display_type_monitor_ip" value="monitor_ip" <?=$display_type_monitor_ip;?> onchange="updateGatewayDisplays();" /><?=gettext('Monitor IP')?></label> + } +?> + <div class="col-sm-6"> + <div class="radio"> + <label><input name="display_type" type="radio" id="display_type_gw_ip" value="gw_ip" <?=$display_type_gw_ip;?> onchange="updateGatewayDisplays();" /> <?=gettext('Gateway IP')?></label> + </div> + <div class="radio"> + <label><input name="display_type" type="radio" id="display_type_monitor_ip" value="monitor_ip" <?=$display_type_monitor_ip;?> onchange="updateGatewayDisplays();" /><?=gettext('Monitor IP')?></label> + </div> + <div class="radio"> + <label><input name="display_type" type="radio" id="display_type_both_ip" value="both_ip" <?=$display_type_both_ip;?> onchange="updateGatewayDisplays();" /><?=gettext('Both')?></label> + </div> </div> - <div class="radio"> - <label><input name="display_type" type="radio" id="display_type_both_ip" value="both_ip" <?=$display_type_both_ip;?> onchange="updateGatewayDisplays();" /><?=gettext('Both')?></label> + </div> + + <br /> + + <div class="panel panel-default col-sm-10"> + <div class="panel-body"> + <div class="table responsive"> + <table class="table table-striped table-hover table-condensed"> + <thead> + <tr> + <th><?=gettext("Gateway")?></th> + <th><?=gettext("Show")?></th> + </tr> + </thead> + <tbody> +<?php + $a_gateways = return_gateways_array(); + $hiddengateways = explode(",", $user_settings["widgets"]["gateways_widget"]["gatewaysfilter"]); + $idx = 0; + + foreach ($a_gateways as $gname => $gateway): +?> + <tr> + <td><?=$gname?></td> + <td class="col-sm-2"><input id="show[]" name ="show[]" value="<?=$gname?>" type="checkbox" <?=(!in_array($gname, $hiddengateways) ? 'checked':'')?>></td> + </tr> +<?php + endforeach; +?> + </tbody> + </table> + </div> </div> - <br /> - <button id="submit_settings" name="submit_settings" type="submit" onclick="return updatePref();" class="btn btn-primary btn-sm" value="<?=gettext('Save Settings')?>"> - <i class="fa fa-save icon-embed-btn"></i> - <?=gettext('Save Settings')?> - </button> + </div> - </form> -</div> + <div class="form-group"> + <div class="col-sm-offset-3 col-sm-6"> + <button type="submit" class="btn btn-primary"><i class="fa fa-save icon-embed-btn"></i><?=gettext('Save')?></button> + <button id="showallgateways" type="button" class="btn btn-info"><i class="fa fa-undo icon-embed-btn"></i><?=gettext('All')?></button> + </div> + </div> +</form> -<script type="text/javascript"> +<script> //<![CDATA[ function get_gw_stats() { @@ -140,6 +188,12 @@ $widgetperiod = isset($config['widgets']['period']) ? $config['widgets']['period } events.push(function(){ + $("#showallgateways").click(function() { + $("[id^=show]").each(function() { + $(this).prop("checked", true); + }); + }); + // Start polling for updates some small random number of seconds from now (so that all the widgets don't // hit the server at exactly the same time) setTimeout(get_gw_stats, Math.floor((Math.random() * 10000) + 1000)); @@ -163,7 +217,15 @@ function compose_table_body_contents() { $display_type = "gw_ip"; } + $hiddengateways = explode(",", $user_settings["widgets"]["gateways_widget"]["gatewaysfilter"]); + $gw_displayed = false; + foreach ($a_gateways as $gname => $gateway) { + if (in_array($gname, $hiddengateways)) { + continue; + } + + $gw_displayed = true; $rtnstr .= "<tr>\n"; $rtnstr .= "<td>\n"; $rtnstr .= htmlspecialchars($gateway['name']) . "<br />"; @@ -233,7 +295,7 @@ function compose_table_body_contents() { $online = gettext("Latency"); $bgcolor = "warning"; // khaki } elseif ($gateways_status[$gname]['status'] == "none") { - if ($gateways_status[$gname]['monitorip'] == "none") { + if ($gateways_status[$gname]['monitor_disable'] || ($gateways_status[$gname]['monitorip'] == "none")) { $online = gettext("Online <br/>(unmonitored)"); } else { $online = gettext("Online"); @@ -254,6 +316,18 @@ function compose_table_body_contents() { $rtnstr .= '<td class="bg-' . $bgcolor . '">' . $online . "</td>\n"; $rtnstr .= "</tr>\n"; } + + if (!$gw_displayed) { + $rtnstr .= '<tr>'; + $rtnstr .= '<td colspan="5">'; + if (count($a_gateways)) { + $rtnstr .= gettext('All gateways are hidden.'); + } else { + $rtnstr .= gettext('No gateways found.'); + } + $rtnstr .= '</td>'; + $rtnstr .= '</tr>'; + } return($rtnstr); } ?> diff --git a/src/usr/local/www/widgets/widgets/ntp_status.widget.php b/src/usr/local/www/widgets/widgets/ntp_status.widget.php index b47a6fd..e29f381 100644 --- a/src/usr/local/www/widgets/widgets/ntp_status.widget.php +++ b/src/usr/local/www/widgets/widgets/ntp_status.widget.php @@ -105,11 +105,11 @@ if ($_REQUEST['updateme']) { $gps_lon = $gps_lon * (($gps_vars[5] == "E") ? 1 : -1); $gps_alt = $gps_vars[9]; $gps_alt_unit = $gps_vars[10]; - $gps_sat = $gps_vars[7]; + $gps_sat = (int)$gps_vars[7]; $gps_la = $gps_vars[3]; $gps_lo = $gps_vars[5]; } elseif (substr($tmp, 0, 6) == '$GPGLL') { - $gps_vars = explode(",", $tmp); + $gps_vars = preg_split('/[,\*]+/', $tmp); $gps_ok = ($gps_vars[6] == "A"); $gps_lat_deg = substr($gps_vars[1], 0, 2); $gps_lat_min = substr($gps_vars[1], 2) / 60.0; |