summaryrefslogtreecommitdiffstats
path: root/src/etc/inc/system.inc
diff options
context:
space:
mode:
Diffstat (limited to 'src/etc/inc/system.inc')
-rw-r--r--src/etc/inc/system.inc2258
1 files changed, 2258 insertions, 0 deletions
diff --git a/src/etc/inc/system.inc b/src/etc/inc/system.inc
new file mode 100644
index 0000000..41e798e
--- /dev/null
+++ b/src/etc/inc/system.inc
@@ -0,0 +1,2258 @@
+<?php
+/* $Id$ */
+/*
+ system.inc
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+ All rights reserved.
+
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
+
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
+
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+ AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+ OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/*
+ pfSense_BUILDER_BINARIES: /usr/sbin/powerd /usr/bin/killall /sbin/route
+ pfSense_BUILDER_BINARIES: /bin/hostname /bin/ls /usr/sbin/syslogd
+ pfSense_BUILDER_BINARIES: /usr/sbin/pccardd /usr/local/sbin/lighttpd /bin/chmod /bin/mkdir
+ pfSense_BUILDER_BINARIES: /usr/bin/tar /usr/local/sbin/ntpd /usr/local/sbin/ntpdate
+ pfSense_BUILDER_BINARIES: /usr/bin/nohup /sbin/dmesg /usr/local/sbin/atareinit /sbin/kldload
+ pfSense_BUILDER_BINARIES: /usr/local/sbin/filterdns
+ pfSense_MODULE: utils
+*/
+
+function activate_powerd() {
+ global $config, $g;
+
+ if (is_process_running("powerd")) {
+ exec("/usr/bin/killall powerd");
+ }
+ if (isset($config['system']['powerd_enable'])) {
+ if ($g["platform"] == "nanobsd") {
+ exec("/sbin/kldload cpufreq");
+ }
+
+ $ac_mode = "hadp";
+ if (!empty($config['system']['powerd_ac_mode'])) {
+ $ac_mode = $config['system']['powerd_ac_mode'];
+ }
+
+ $battery_mode = "hadp";
+ if (!empty($config['system']['powerd_battery_mode'])) {
+ $battery_mode = $config['system']['powerd_battery_mode'];
+ }
+
+ $normal_mode = "hadp";
+ if (!empty($config['system']['powerd_normal_mode'])) {
+ $normal_mode = $config['system']['powerd_normal_mode'];
+ }
+
+ mwexec("/usr/sbin/powerd -b $battery_mode -a $ac_mode -n $normal_mode");
+ }
+}
+
+function get_default_sysctl_value($id) {
+ global $sysctls;
+
+ if (isset($sysctls[$id])) {
+ return $sysctls[$id];
+ }
+}
+
+function get_sysctl_descr($sysctl) {
+ unset($output);
+ $_gb = exec("/sbin/sysctl -nd {$sysctl}", $output);
+
+ return $output[0];
+}
+
+function system_get_sysctls() {
+ global $config, $sysctls;
+
+ $disp_sysctl = array();
+ $disp_cache = array();
+ if (is_array($config['sysctl']) && is_array($config['sysctl']['item'])) {
+ foreach ($config['sysctl']['item'] as $id => $tunable) {
+ if ($tunable['value'] == "default") {
+ $value = get_default_sysctl_value($tunable['tunable']);
+ } else {
+ $value = $tunable['value'];
+ }
+
+ $disp_sysctl[$id] = $tunable;
+ $disp_sysctl[$id]['modified'] = true;
+ $disp_cache[$tunable['tunable']] = 'set';
+ }
+ }
+
+ foreach ($sysctls as $sysctl => $value) {
+ if (isset($disp_cache[$sysctl])) {
+ continue;
+ }
+
+ $disp_sysctl[$sysctl] = array('tunable' => $sysctl, 'value' => $value, 'descr' => get_sysctl_descr($sysctl));
+ }
+ unset($disp_cache);
+ return $disp_sysctl;
+}
+
+function activate_sysctls() {
+ global $config, $g, $sysctls;
+
+ if (is_array($config['sysctl']) && is_array($config['sysctl']['item'])) {
+ foreach ($config['sysctl']['item'] as $tunable) {
+ if ($tunable['value'] == "default") {
+ $value = get_default_sysctl_value($tunable['tunable']);
+ } else {
+ $value = $tunable['value'];
+ }
+
+ $sysctls[$tunable['tunable']] = $value;
+ }
+ }
+
+ set_sysctl($sysctls);
+}
+
+function system_resolvconf_generate($dynupdate = false) {
+ global $config, $g;
+
+ if (isset($config['system']['developerspew'])) {
+ $mt = microtime();
+ echo "system_resolvconf_generate() being called $mt\n";
+ }
+
+ $syscfg = $config['system'];
+
+ if ((((isset($config['dnsmasq']['enable'])) &&
+ (!isset($config['dnsmasq']['port']) || $config['dnsmasq']['port'] == "53") &&
+ (empty($config['dnsmasq']['interface']) ||
+ in_array("lo0", explode(",", $config['dnsmasq']['interface'])))) ||
+ ((isset($config['unbound']['enable'])) &&
+ (!isset($config['unbound']['port']) || $config['unbound']['port'] == "53") &&
+ (empty($config['unbound']['active_interface']) ||
+ in_array("lo0", explode(",", $config['unbound']['active_interface'])) ||
+ in_array("all", explode(",", $config['unbound']['active_interface']), true)))) &&
+ (!isset($config['system']['dnslocalhost']))) {
+ $resolvconf .= "nameserver 127.0.0.1\n";
+ }
+
+ if (isset($syscfg['dnsallowoverride'])) {
+ /* get dynamically assigned DNS servers (if any) */
+ $ns = array_unique(get_searchdomains());
+ foreach ($ns as $searchserver) {
+ if ($searchserver) {
+ $resolvconf .= "search {$searchserver}\n";
+ }
+ }
+ $ns = array_unique(get_nameservers());
+ foreach ($ns as $nameserver) {
+ if ($nameserver) {
+ $resolvconf .= "nameserver $nameserver\n";
+ }
+ }
+ } else {
+ $ns = array();
+ // Do not create blank search/domain lines, it can break tools like dig.
+ if ($syscfg['domain']) {
+ $resolvconf .= "search {$syscfg['domain']}\n";
+ }
+ }
+ if (is_array($syscfg['dnsserver'])) {
+ foreach ($syscfg['dnsserver'] as $sys_dnsserver) {
+ if ($sys_dnsserver && (!in_array($sys_dnsserver, $ns))) {
+ $resolvconf .= "nameserver $sys_dnsserver\n";
+ }
+ }
+ }
+
+ // Add EDNS support
+ if (isset($config['unbound']['enable']) && isset($config['unbound']['edns'])) {
+ $resolvconf .= "options edns0\n";
+ }
+
+ $dnslock = lock('resolvconf', LOCK_EX);
+
+ $fd = fopen("{$g['varetc_path']}/resolv.conf", "w");
+ if (!$fd) {
+ printf("Error: cannot open resolv.conf in system_resolvconf_generate().\n");
+ unlock($dnslock);
+ return 1;
+ }
+
+ fwrite($fd, $resolvconf);
+ fclose($fd);
+
+ // Prevent resolvconf(8) from rewriting our resolv.conf
+ $fd = fopen("{$g['varetc_path']}/resolvconf.conf", "w");
+ if (!$fd) {
+ printf("Error: cannot open resolvconf.conf in system_resolvconf_generate().\n");
+ return 1;
+ }
+ fwrite($fd, "resolv_conf=\"/dev/null\"\n");
+ fclose($fd);
+
+ if (!platform_booting()) {
+ /* restart dhcpd (nameservers may have changed) */
+ if (!$dynupdate) {
+ services_dhcpd_configure();
+ }
+ }
+
+ /* setup static routes for DNS servers. */
+ for ($dnscounter=1; $dnscounter<5; $dnscounter++) {
+ /* setup static routes for dns servers */
+ $dnsgw = "dns{$dnscounter}gw";
+ if (isset($config['system'][$dnsgw])) {
+ $gwname = $config['system'][$dnsgw];
+ if (($gwname <> "") && ($gwname <> "none")) {
+ $gatewayip = lookup_gateway_ip_by_name($gwname);
+ if (is_ipaddrv4($gatewayip)) {
+ /* dns server array starts at 0 */
+ $dnscountermo = $dnscounter - 1;
+ mwexec("/sbin/route change -host " . $syscfg['dnsserver'][$dnscountermo] . " {$gatewayip}");
+ if (isset($config['system']['route-debug'])) {
+ $mt = microtime();
+ log_error("ROUTING debug: $mt - route change -host {$syscfg['dnsserver'][$dnscountermo]} $gatewayip ");
+ }
+ }
+ if (is_ipaddrv6($gatewayip)) {
+ /* dns server array starts at 0 */
+ $dnscountermo = $dnscounter - 1;
+ mwexec("/sbin/route change -host -inet6 " . $syscfg['dnsserver'][$dnscountermo] . " {$gatewayip}");
+ if (isset($config['system']['route-debug'])) {
+ $mt = microtime();
+ log_error("ROUTING debug: $mt - route change -host -inet6 {$syscfg['dnsserver'][$dnscountermo]} $gatewayip ");
+ }
+ }
+ }
+ }
+ }
+
+ unlock($dnslock);
+
+ return 0;
+}
+
+function get_searchdomains() {
+ global $config, $g;
+
+ $master_list = array();
+
+ // Read in dhclient nameservers
+ $search_list = glob("/var/etc/searchdomain_*");
+ if (is_array($search_list)) {
+ foreach ($search_list as $fdns) {
+ $contents = file($fdns, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
+ if (!is_array($contents)) {
+ continue;
+ }
+ foreach ($contents as $dns) {
+ if (is_hostname($dns)) {
+ $master_list[] = $dns;
+ }
+ }
+ }
+ }
+
+ return $master_list;
+}
+
+function get_nameservers() {
+ global $config, $g;
+ $master_list = array();
+
+ // Read in dhclient nameservers
+ $dns_lists = glob("/var/etc/nameserver_*");
+ if (is_array($dns_lists)) {
+ foreach ($dns_lists as $fdns) {
+ $contents = file($fdns, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
+ if (!is_array($contents)) {
+ continue;
+ }
+ foreach ($contents as $dns) {
+ if (is_ipaddr($dns)) {
+ $master_list[] = $dns;
+ }
+ }
+ }
+ }
+
+ // Read in any extra nameservers
+ if (file_exists("/var/etc/nameservers.conf")) {
+ $dns_s = file("/var/etc/nameservers.conf", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
+ if (is_array($dns_s)) {
+ foreach ($dns_s as $dns) {
+ if (is_ipaddr($dns)) {
+ $master_list[] = $dns;
+ }
+ }
+ }
+ }
+
+ return $master_list;
+}
+
+function system_hosts_generate() {
+ global $config, $g;
+ if (isset($config['system']['developerspew'])) {
+ $mt = microtime();
+ echo "system_hosts_generate() being called $mt\n";
+ }
+
+ $syscfg = $config['system'];
+ if (isset($config['unbound']) && isset($config['unbound']['enable'])) {
+ $dnsmasqcfg = $config['unbound'];
+ } else {
+ $dnsmasqcfg = $config['dnsmasq'];
+ }
+
+ $hosts = "127.0.0.1 localhost localhost.{$syscfg['domain']}\n";
+ $hosts .= "::1 localhost localhost.{$syscfg['domain']}\n";
+ $lhosts = "";
+ $dhosts = "";
+
+ if ($config['interfaces']['lan']) {
+ $cfgip = get_interface_ip("lan");
+ if (is_ipaddr($cfgip)) {
+ $hosts .= "{$cfgip} {$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
+ }
+ $cfgipv6 = get_interface_ipv6("lan");
+ if (is_ipaddrv6($cfgipv6)) {
+ $hosts .= "{$cfgipv6} {$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
+ }
+ } else {
+ $sysiflist = get_configured_interface_list();
+ $hosts_if_found = false;
+ foreach ($sysiflist as $sysif) {
+ if (!interface_has_gateway($sysif)) {
+ $cfgip = get_interface_ip($sysif);
+ if (is_ipaddr($cfgip)) {
+ $hosts .= "{$cfgip} {$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
+ $hosts_if_found = true;
+ }
+ $cfgipv6 = get_interface_ipv6($sysif);
+ if (is_ipaddrv6($cfgipv6)) {
+ $hosts .= "{$cfgipv6} {$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
+ $hosts_if_found = true;
+ }
+ if ($hosts_if_found == true) {
+ break;
+ }
+ }
+ }
+ }
+
+ if (isset($dnsmasqcfg['enable'])) {
+ if (!is_array($dnsmasqcfg['hosts'])) {
+ $dnsmasqcfg['hosts'] = array();
+ }
+
+ foreach ($dnsmasqcfg['hosts'] as $host) {
+ if ($host['host'] || $host['host'] == "0") {
+ $lhosts .= "{$host['ip']} {$host['host']}.{$host['domain']} {$host['host']}\n";
+ } else {
+ $lhosts .= "{$host['ip']} {$host['domain']}\n";
+ }
+ if (!is_array($host['aliases']) || !is_array($host['aliases']['item'])) {
+ continue;
+ }
+ foreach ($host['aliases']['item'] as $alias) {
+ if ($alias['host'] || $alias['host'] == "0") {
+ $lhosts .= "{$host['ip']} {$alias['host']}.{$alias['domain']} {$alias['host']}\n";
+ } else {
+ $lhosts .= "{$host['ip']} {$alias['domain']}\n";
+ }
+ }
+ }
+ if (isset($dnsmasqcfg['regdhcpstatic']) && is_array($config['dhcpd'])) {
+ foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {
+ if (is_array($dhcpifconf['staticmap']) && isset($dhcpifconf['enable'])) {
+ foreach ($dhcpifconf['staticmap'] as $host) {
+ if ($host['ipaddr'] && $host['hostname'] && $host['domain']) {
+ $dhosts .= "{$host['ipaddr']} {$host['hostname']}.{$host['domain']} {$host['hostname']}\n";
+ } else if ($host['ipaddr'] && $host['hostname'] && $dhcpifconf['domain']) {
+ $dhosts .= "{$host['ipaddr']} {$host['hostname']}.{$dhcpifconf['domain']} {$host['hostname']}\n";
+ } else if ($host['ipaddr'] && $host['hostname']) {
+ $dhosts .= "{$host['ipaddr']} {$host['hostname']}.{$syscfg['domain']} {$host['hostname']}\n";
+ }
+ }
+ }
+ }
+ }
+ if (isset($dnsmasqcfg['regdhcpstatic']) && is_array($config['dhcpdv6'])) {
+ foreach ($config['dhcpdv6'] as $dhcpif => $dhcpifconf) {
+ if (is_array($dhcpifconf['staticmap']) && isset($dhcpifconf['enable'])) {
+ foreach ($dhcpifconf['staticmap'] as $host) {
+ if ($host['ipaddrv6'] && $host['hostname'] && $host['domain']) {
+ $dhosts .= "{$host['ipaddrv6']} {$host['hostname']}.{$host['domain']} {$host['hostname']}\n";
+ } else if ($host['ipaddrv6'] && $host['hostname'] && $dhcpifconf['domain']) {
+ $dhosts .= "{$host['ipaddrv6']} {$host['hostname']}.{$dhcpifconf['domain']} {$host['hostname']}\n";
+ } else if ($host['ipaddrv6'] && $host['hostname']) {
+ $dhosts .= "{$host['ipaddrv6']} {$host['hostname']}.{$syscfg['domain']} {$host['hostname']}\n";
+ }
+ }
+ }
+ }
+ }
+
+ if (isset($dnsmasqcfg['dhcpfirst'])) {
+ $hosts .= $dhosts . $lhosts;
+ } else {
+ $hosts .= $lhosts . $dhosts;
+ }
+ }
+
+ /*
+ * Do not remove this because dhcpleases monitors with kqueue it needs to be
+ * killed before writing to hosts files.
+ */
+ if (file_exists("{$g['varrun_path']}/dhcpleases.pid")) {
+ sigkillbypid("{$g['varrun_path']}/dhcpleases.pid", "TERM");
+ @unlink("{$g['varrun_path']}/dhcpleases.pid");
+ }
+ $fd = fopen("{$g['varetc_path']}/hosts", "w");
+ if (!$fd) {
+ log_error("Error: cannot open hosts file in system_hosts_generate().\n");
+ return 1;
+ }
+ fwrite($fd, $hosts);
+ fclose($fd);
+
+ if (isset($config['unbound']['enable'])) {
+ require_once("unbound.inc");
+ unbound_hosts_generate();
+ }
+
+ return 0;
+}
+
+function system_dhcpleases_configure() {
+ global $config, $g;
+
+ /* Start the monitoring process for dynamic dhcpclients. */
+ if ((isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcp'])) ||
+ (isset($config['unbound']['enable']) && isset($config['unbound']['regdhcp']))) {
+ /* Make sure we do not error out */
+ mwexec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/db");
+ if (!file_exists("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases")) {
+ @touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
+ }
+
+ if (isset($config['unbound']['enable'])) {
+ $dns_pid = "unbound.pid";
+ $unbound_conf = "-u {$g['unbound_chroot_path']}/dhcpleases_entries.conf";
+ } else {
+ $dns_pid = "dnsmasq.pid";
+ $unbound_conf = "";
+ }
+
+ $pidfile = "{$g['varrun_path']}/dhcpleases.pid";
+ if (isvalidpid($pidfile)) {
+ /* Make sure dhcpleases is using correct unbound or dnsmasq */
+ $_gb = exec("/bin/pgrep -F {$pidfile} -f {$dns_pid}", $output, $retval);
+ if (intval($retval) == 0) {
+ sigkillbypid($pidfile, "HUP");
+ return;
+ } else {
+ sigkillbypid($pidfile, "TERM");
+ }
+ }
+
+ /* To ensure we do not start multiple instances of dhcpleases, perform some clean-up first. */
+ if (is_process_running("dhcpleases")) {
+ sigkillbyname('dhcpleases', "TERM");
+ }
+ @unlink($pidfile);
+ mwexec("/usr/local/sbin/dhcpleases -l {$g['dhcpd_chroot_path']}/var/db/dhcpd.leases -d {$config['system']['domain']} -p {$g['varrun_path']}/{$dns_pid} {$unbound_conf} -h {$g['varetc_path']}/hosts");
+ } else {
+ sigkillbypid($pidfile, "TERM");
+ @unlink($pidfile);
+ }
+}
+
+function system_hostname_configure() {
+ global $config, $g;
+ if (isset($config['system']['developerspew'])) {
+ $mt = microtime();
+ echo "system_hostname_configure() being called $mt\n";
+ }
+
+ $syscfg = $config['system'];
+
+ /* set hostname */
+ $status = mwexec("/bin/hostname " .
+ escapeshellarg("{$syscfg['hostname']}.{$syscfg['domain']}"));
+
+ /* Setup host GUID ID. This is used by ZFS. */
+ mwexec("/etc/rc.d/hostid start");
+
+ return $status;
+}
+
+function system_routing_configure($interface = "") {
+ global $config, $g;
+
+ if (isset($config['system']['developerspew'])) {
+ $mt = microtime();
+ echo "system_routing_configure() being called $mt\n";
+ }
+
+ $gatewayip = "";
+ $interfacegw = "";
+ $gatewayipv6 = "";
+ $interfacegwv6 = "";
+ $foundgw = false;
+ $foundgwv6 = false;
+ /* tack on all the hard defined gateways as well */
+ if (is_array($config['gateways']['gateway_item'])) {
+ array_map('unlink', glob("{$g['tmp_path']}/*_defaultgw{,v6}", GLOB_BRACE));
+ foreach ($config['gateways']['gateway_item'] as $gateway) {
+ if (isset($gateway['defaultgw'])) {
+ if ($foundgw == false && ($gateway['ipprotocol'] != "inet6" && (is_ipaddrv4($gateway['gateway']) || $gateway['gateway'] == "dynamic"))) {
+ if (strpos($gateway['gateway'], ":")) {
+ continue;
+ }
+ if ($gateway['gateway'] == "dynamic") {
+ $gateway['gateway'] = get_interface_gateway($gateway['interface']);
+ }
+ $gatewayip = $gateway['gateway'];
+ $interfacegw = $gateway['interface'];
+ if (!empty($gateway['interface'])) {
+ $defaultif = get_real_interface($gateway['interface']);
+ if ($defaultif) {
+ @file_put_contents("{$g['tmp_path']}/{$defaultif}_defaultgw", $gateway['gateway']);
+ }
+ }
+ $foundgw = true;
+ } else if ($foundgwv6 == false && ($gateway['ipprotocol'] == "inet6" && (is_ipaddrv6($gateway['gateway']) || $gateway['gateway'] == "dynamic"))) {
+ if ($gateway['gateway'] == "dynamic") {
+ $gateway['gateway'] = get_interface_gateway_v6($gateway['interface']);
+ }
+ $gatewayipv6 = $gateway['gateway'];
+ $interfacegwv6 = $gateway['interface'];
+ if (!empty($gateway['interface'])) {
+ $defaultifv6 = get_real_interface($gateway['interface']);
+ if ($defaultifv6) {
+ @file_put_contents("{$g['tmp_path']}/{$defaultifv6}_defaultgwv6", $gateway['gateway']);
+ }
+ }
+ $foundgwv6 = true;
+ }
+ }
+ if ($foundgw === true && $foundgwv6 === true) {
+ break;
+ }
+ }
+ }
+ if ($foundgw == false) {
+ $defaultif = get_real_interface("wan");
+ $interfacegw = "wan";
+ $gatewayip = get_interface_gateway("wan");
+ @file_put_contents("{$g['tmp_path']}/{$defaultif}_defaultgw", $gatewayip);
+ }
+ if ($foundgwv6 == false) {
+ $defaultifv6 = get_real_interface("wan");
+ $interfacegwv6 = "wan";
+ $gatewayipv6 = get_interface_gateway_v6("wan");
+ @file_put_contents("{$g['tmp_path']}/{$defaultifv6}_defaultgwv6", $gatewayipv6);
+ }
+ $dont_add_route = false;
+ /* if OLSRD is enabled, allow WAN to house DHCP. */
+ if (is_array($config['installedpackages']['olsrd'])) {
+ foreach ($config['installedpackages']['olsrd']['config'] as $olsrd) {
+ if (($olsrd['enabledyngw'] == "on") && ($olsrd['enable'] == "on")) {
+ $dont_add_route = true;
+ log_error(sprintf(gettext("Not adding default route because OLSR dynamic gateway is enabled.")));
+ break;
+ }
+ }
+ }
+
+ if ($dont_add_route == false) {
+ if (!empty($interface) && $interface != $interfacegw) {
+ ;
+ } else if (is_ipaddrv4($gatewayip)) {
+ log_error("ROUTING: setting default route to $gatewayip");
+ mwexec("/sbin/route change -inet default " . escapeshellarg($gatewayip));
+ }
+
+ if (!empty($interface) && $interface != $interfacegwv6) {
+ ;
+ } else if (is_ipaddrv6($gatewayipv6)) {
+ $ifscope = "";
+ if (is_linklocal($gatewayipv6) && !strpos($gatewayipv6, '%')) {
+ $ifscope = "%{$defaultifv6}";
+ }
+ log_error("ROUTING: setting IPv6 default route to {$gatewayipv6}{$ifscope}");
+ mwexec("/sbin/route change -inet6 default " . escapeshellarg("{$gatewayipv6}{$ifscope}"));
+ }
+ }
+
+ system_staticroutes_configure($interface, false);
+
+ return 0;
+}
+
+function system_staticroutes_configure($interface = "", $update_dns = false) {
+ global $config, $g, $aliastable;
+
+ $filterdns_list = array();
+
+ $static_routes = get_staticroutes(false, true);
+ if (count($static_routes)) {
+ $gateways_arr = return_gateways_array(false, true);
+
+ foreach ($static_routes as $rtent) {
+ if (empty($gateways_arr[$rtent['gateway']])) {
+ log_error(sprintf(gettext("Static Routes: Gateway IP could not be found for %s"), $rtent['network']));
+ continue;
+ }
+ $gateway = $gateways_arr[$rtent['gateway']];
+ if (!empty($interface) && $interface != $gateway['friendlyiface']) {
+ continue;
+ }
+
+ $gatewayip = $gateway['gateway'];
+ $interfacegw = $gateway['interface'];
+
+ $blackhole = "";
+ if (!strcasecmp("Null", substr($rtent['gateway'], 0, 3))) {
+ $blackhole = "-blackhole";
+ }
+
+ if (!is_fqdn($rtent['network']) && !is_subnet($rtent['network'])) {
+ continue;
+ }
+
+ $dnscache = array();
+ if ($update_dns === true) {
+ if (is_subnet($rtent['network'])) {
+ continue;
+ }
+ $dnscache = explode("\n", trim(compare_hostname_to_dnscache($rtent['network'])));
+ if (empty($dnscache)) {
+ continue;
+ }
+ }
+
+ if (is_subnet($rtent['network'])) {
+ $ips = array($rtent['network']);
+ } else {
+ if (!isset($rtent['disabled'])) {
+ $filterdns_list[] = $rtent['network'];
+ }
+ $ips = add_hostname_to_watch($rtent['network']);
+ }
+
+ foreach ($dnscache as $ip) {
+ if (in_array($ip, $ips)) {
+ continue;
+ }
+ mwexec("/sbin/route delete " . escapeshellarg($ip), true);
+ if (isset($config['system']['route-debug'])) {
+ $mt = microtime();
+ log_error("ROUTING debug: $mt - route delete $ip ");
+ }
+ }
+
+ if (isset($rtent['disabled'])) {
+ /* XXX: This can break things by deleting routes that shouldn't be deleted - OpenVPN, dynamic routing scenarios, etc. redmine #3709 */
+ foreach ($ips as $ip) {
+ mwexec("/sbin/route delete " . escapeshellarg($ip), true);
+ if (isset($config['system']['route-debug'])) {
+ $mt = microtime();
+ log_error("ROUTING debug: $mt - route delete $ip ");
+ }
+ }
+ continue;
+ }
+
+ foreach ($ips as $ip) {
+ if (is_ipaddrv4($ip)) {
+ $ip .= "/32";
+ }
+ // do NOT do the same check here on v6, is_ipaddrv6 returns true when including the CIDR mask. doing so breaks v6 routes
+
+ $inet = (is_subnetv6($ip) ? "-inet6" : "-inet");
+
+ $cmd = "/sbin/route change {$inet} {$blackhole} " . escapeshellarg($ip) . " ";
+
+ if (is_subnet($ip)) {
+ if (is_ipaddr($gatewayip)) {
+ mwexec($cmd . escapeshellarg($gatewayip));
+ if (isset($config['system']['route-debug'])) {
+ $mt = microtime();
+ log_error("ROUTING debug: $mt - $cmd $gatewayip");
+ }
+ } else if (!empty($interfacegw)) {
+ mwexec($cmd . "-iface " . escapeshellarg($interfacegw));
+ if (isset($config['system']['route-debug'])) {
+ $mt = microtime();
+ log_error("ROUTING debug: $mt - $cmd -iface $interfacegw ");
+ }
+ }
+ }
+ }
+ }
+ unset($gateways_arr);
+ }
+ unset($static_routes);
+
+ if ($update_dns === false) {
+ if (count($filterdns_list)) {
+ $interval = 60;
+ $hostnames = "";
+ array_unique($filterdns_list);
+ foreach ($filterdns_list as $hostname) {
+ $hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload routedns\"'\n";
+ }
+ file_put_contents("{$g['varetc_path']}/filterdns-route.hosts", $hostnames);
+ unset($hostnames);
+
+ if (isvalidpid("{$g['varrun_path']}/filterdns-route.pid")) {
+ sigkillbypid("{$g['varrun_path']}/filterdns-route.pid", "HUP");
+ } else {
+ mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-route.pid -i {$interval} -c {$g['varetc_path']}/filterdns-route.hosts -d 1");
+ }
+ } else {
+ killbypid("{$g['varrun_path']}/filterdns-route.pid");
+ @unlink("{$g['varrun_path']}/filterdns-route.pid");
+ }
+ }
+ unset($filterdns_list);
+
+ return 0;
+}
+
+function system_routing_enable() {
+ global $config, $g;
+ if (isset($config['system']['developerspew'])) {
+ $mt = microtime();
+ echo "system_routing_enable() being called $mt\n";
+ }
+
+ set_sysctl(array(
+ "net.inet.ip.forwarding" => "1",
+ "net.inet6.ip6.forwarding" => "1"
+ ));
+
+ return;
+}
+
+function system_syslogd_fixup_server($server) {
+ /* If it's an IPv6 IP alone, encase it in brackets */
+ if (is_ipaddrv6($server)) {
+ return "[$server]";
+ } else {
+ return $server;
+ }
+}
+
+function system_syslogd_get_remote_servers($syslogcfg, $facility = "*.*") {
+ // Rather than repeatedly use the same code, use this function to build a list of remote servers.
+ $facility .= " ".
+ $remote_servers = "";
+ $pad_to = 56;
+ $padding = ceil(($pad_to - strlen($facility))/8)+1;
+ if ($syslogcfg['remoteserver']) {
+ $remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver']) . "\n";
+ }
+ if ($syslogcfg['remoteserver2']) {
+ $remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver2']) . "\n";
+ }
+ if ($syslogcfg['remoteserver3']) {
+ $remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver3']) . "\n";
+ }
+ return $remote_servers;
+}
+
+function system_syslogd_start() {
+ global $config, $g;
+ if (isset($config['system']['developerspew'])) {
+ $mt = microtime();
+ echo "system_syslogd_start() being called $mt\n";
+ }
+
+ mwexec("/etc/rc.d/hostid start");
+
+ $syslogcfg = $config['syslog'];
+
+ if (platform_booting()) {
+ echo gettext("Starting syslog...");
+ }
+
+ if (is_process_running("fifolog_writer")) {
+ mwexec('/bin/pkill fifolog_writer');
+ }
+
+ // Which logging type are we using this week??
+ if (isset($config['system']['disablesyslogclog'])) {
+ $log_directive = "";
+ $log_create_directive = "/usr/bin/touch ";
+ $log_size = "";
+ } else if (isset($config['system']['usefifolog'])) {
+ $log_directive = "|/usr/sbin/fifolog_writer ";
+ $log_size = isset($config['syslog']['logfilesize']) ? $config['syslog']['logfilesize'] : "10240";
+ $log_create_directive = "/usr/sbin/fifolog_create -s ";
+ } else { // Defaults to CLOG
+ $log_directive = "%";
+ $log_size = isset($config['syslog']['logfilesize']) ? $config['syslog']['logfilesize'] : "10240";
+ $log_create_directive = "/usr/local/sbin/clog -i -s ";
+ }
+
+ $syslogd_extra = "";
+ if (isset($syslogcfg)) {
+ $separatelogfacilities = array('ntp', 'ntpd', 'ntpdate', 'charon', 'ipsec_starter', 'openvpn', 'pptps', 'poes', 'l2tps', 'relayd', 'hostapd', 'dnsmasq', 'filterdns', 'unbound', 'dhcpd', 'dhcrelay', 'dhclient', 'dhcp6c', 'apinger', 'radvd', 'routed', 'olsrd', 'zebra', 'ospfd', 'bgpd', 'miniupnpd', 'filterlog');
+ $syslogconf = "";
+ if ($config['installedpackages']['package']) {
+ foreach ($config['installedpackages']['package'] as $package) {
+ if ($package['logging']) {
+ array_push($separatelogfacilities, $package['logging']['facilityname']);
+ if (!is_file($g['varlog_path'].'/'.$package['logging']['logfilename'])) {
+ mwexec("{$log_create_directive} {$log_size} {$g['varlog_path']}/{$package['logging']['logfilename']}");
+ }
+ $syslogconf .= "!{$package['logging']['facilityname']}\n*.*\t\t\t\t\t\t {$log_directive}{$g['varlog_path']}/{$package['logging']['logfilename']}\n";
+ }
+ }
+ }
+ $facilitylist = implode(',', array_unique($separatelogfacilities));
+ $syslogconf .= "!radvd,routed,olsrd,zebra,ospfd,bgpd,miniupnpd\n";
+ if (!isset($syslogcfg['disablelocallogging'])) {
+ $syslogconf .= "*.* {$log_directive}{$g['varlog_path']}/routing.log\n";
+ }
+
+ $syslogconf .= "!ntp,ntpd,ntpdate\n";
+ if (!isset($syslogcfg['disablelocallogging'])) {
+ $syslogconf .= "*.* {$log_directive}{$g['varlog_path']}/ntpd.log\n";
+ }
+
+ $syslogconf .= "!ppp\n";
+ if (!isset($syslogcfg['disablelocallogging'])) {
+ $syslogconf .= "*.* {$log_directive}{$g['varlog_path']}/ppp.log\n";
+ }
+
+ $syslogconf .= "!pptps\n";
+ if (!isset($syslogcfg['disablelocallogging'])) {
+ $syslogconf .= "*.* {$log_directive}{$g['varlog_path']}/pptps.log\n";
+ }
+
+ $syslogconf .= "!poes\n";
+ if (!isset($syslogcfg['disablelocallogging'])) {
+ $syslogconf .= "*.* {$log_directive}{$g['varlog_path']}/poes.log\n";
+ }
+
+ $syslogconf .= "!l2tps\n";
+ if (!isset($syslogcfg['disablelocallogging'])) {
+ $syslogconf .= "*.* {$log_directive}{$g['varlog_path']}/l2tps.log\n";
+ }
+
+ $syslogconf .= "!charon,ipsec_starter\n";
+ if (!isset($syslogcfg['disablelocallogging'])) {
+ $syslogconf .= "*.* {$log_directive}{$g['varlog_path']}/ipsec.log\n";
+ }
+ if (isset($syslogcfg['vpn'])) {
+ $syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
+ }
+
+ $syslogconf .= "!openvpn\n";
+ if (!isset($syslogcfg['disablelocallogging'])) {
+ $syslogconf .= "*.* {$log_directive}{$g['varlog_path']}/openvpn.log\n";
+ }
+ if (isset($syslogcfg['vpn'])) {
+ $syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
+ }
+
+ $syslogconf .= "!apinger\n";
+ if (!isset($syslogcfg['disablelocallogging'])) {
+ $syslogconf .= "*.* {$log_directive}{$g['varlog_path']}/gateways.log\n";
+ }
+ if (isset($syslogcfg['apinger'])) {
+ $syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
+ }
+
+ $syslogconf .= "!dnsmasq,filterdns,unbound\n";
+ if (!isset($syslogcfg['disablelocallogging'])) {
+ $syslogconf .= "*.* {$log_directive}{$g['varlog_path']}/resolver.log\n";
+ }
+
+ $syslogconf .= "!dhcpd,dhcrelay,dhclient,dhcp6c\n";
+ if (!isset($syslogcfg['disablelocallogging'])) {
+ $syslogconf .= "*.* {$log_directive}{$g['varlog_path']}/dhcpd.log\n";
+ }
+ if (isset($syslogcfg['dhcp'])) {
+ $syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
+ }
+
+ $syslogconf .= "!relayd\n";
+ if (!isset($syslogcfg['disablelocallogging'])) {
+ $syslogconf .= "*.* {$log_directive}{$g['varlog_path']}/relayd.log\n";
+ }
+ if (isset($syslogcfg['relayd'])) {
+ $syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
+ }
+
+ $syslogconf .= "!hostapd\n";
+ if (!isset($syslogcfg['disablelocallogging'])) {
+ $syslogconf .= "*.* {$log_directive}{$g['varlog_path']}/wireless.log\n";
+ }
+ if (isset($syslogcfg['hostapd'])) {
+ $syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
+ }
+
+ $syslogconf .= "!filterlog\n";
+ $syslogconf .= "*.* {$log_directive}{$g['varlog_path']}/filter.log\n";
+ if (isset($syslogcfg['filter'])) {
+ $syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
+ }
+
+ $syslogconf .= "!-{$facilitylist}\n";
+ if (!isset($syslogcfg['disablelocallogging'])) {
+ $syslogconf .= <<<EOD
+local3.* {$log_directive}{$g['varlog_path']}/vpn.log
+local4.* {$log_directive}{$g['varlog_path']}/portalauth.log
+local7.* {$log_directive}{$g['varlog_path']}/dhcpd.log
+*.notice;kern.debug;lpr.info;mail.crit;daemon.none; {$log_directive}{$g['varlog_path']}/system.log
+news.err;local0.none;local3.none;local4.none; {$log_directive}{$g['varlog_path']}/system.log
+local7.none {$log_directive}{$g['varlog_path']}/system.log
+security.* {$log_directive}{$g['varlog_path']}/system.log
+auth.info;authpriv.info;daemon.info {$log_directive}{$g['varlog_path']}/system.log
+auth.info;authpriv.info |exec /usr/local/sbin/sshlockout_pf 15
+*.emerg *
+
+EOD;
+ }
+ if (isset($syslogcfg['vpn'])) {
+ $syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local3.*");
+ }
+ if (isset($syslogcfg['portalauth'])) {
+ $syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local4.*");
+ }
+ if (isset($syslogcfg['dhcp'])) {
+ $syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local7.*");
+ }
+ if (isset($syslogcfg['system'])) {
+ $syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.notice;kern.debug;lpr.info;mail.crit;");
+ $syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "news.err;local0.none;local3.none;local7.none");
+ $syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "security.*");
+ $syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "auth.info;authpriv.info;daemon.info");
+ $syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.emerg");
+ }
+ if (isset($syslogcfg['logall'])) {
+ // Make everything mean everything, including facilities excluded above.
+ $syslogconf .= "!*\n";
+ $syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
+ }
+
+ if (isset($syslogcfg['zmqserver'])) {
+ $syslogconf .= <<<EOD
+*.* ^{$syslogcfg['zmqserver']}
+
+EOD;
+ }
+ /* write syslog.conf */
+ if (!@file_put_contents("{$g['varetc_path']}/syslog.conf", $syslogconf)) {
+ printf(gettext("Error: cannot open syslog.conf in system_syslogd_start().%s"), "\n");
+ unset($syslogconf);
+ return 1;
+ }
+ unset($syslogconf);
+
+ // Ensure that the log directory exists
+ if (!is_dir("{$g['dhcpd_chroot_path']}/var/run")) {
+ exec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/run");
+ }
+
+ $sourceip = "";
+ if (!empty($syslogcfg['sourceip'])) {
+ if ($syslogcfg['ipproto'] == "ipv6") {
+ $ifaddr = is_ipaddr($syslogcfg['sourceip']) ? $syslogcfg['sourceip'] : get_interface_ipv6($syslogcfg['sourceip']);
+ if (!is_ipaddr($ifaddr)) {
+ $ifaddr = get_interface_ip($syslogcfg['sourceip']);
+ }
+ } else {
+ $ifaddr = is_ipaddr($syslogcfg['sourceip']) ? $syslogcfg['sourceip'] : get_interface_ip($syslogcfg['sourceip']);
+ if (!is_ipaddr($ifaddr)) {
+ $ifaddr = get_interface_ipv6($syslogcfg['sourceip']);
+ }
+ }
+ if (is_ipaddr($ifaddr)) {
+ $sourceip = "-b {$ifaddr}";
+ }
+ }
+
+ $syslogd_extra = "-f {$g['varetc_path']}/syslog.conf {$sourceip}";
+ }
+
+ if (isvalidpid("{$g['varrun_path']}/syslog.pid")) {
+ sigkillbypid("{$g['varrun_path']}/syslog.pid", "TERM");
+ usleep(100000); // syslogd often doesn't respond to a TERM quickly enough for the starting of syslogd below to be successful
+ }
+
+ if (isvalidpid("{$g['varrun_path']}/syslog.pid")) {
+ // if it still hasn't responded to the TERM, KILL it.
+ sigkillbypid("{$g['varrun_path']}/syslog.pid", "KILL");
+ usleep(100000);
+ }
+
+
+ $retval = mwexec_bg("/usr/sbin/syslogd -s -c -c -l {$g['dhcpd_chroot_path']}/var/run/log -P {$g['varrun_path']}/syslog.pid {$syslogd_extra}");
+
+ if (platform_booting()) {
+ echo gettext("done.") . "\n";
+ }
+
+ return $retval;
+}
+
+function system_webgui_create_certificate() {
+ global $config, $g;
+
+ if (!is_array($config['ca'])) {
+ $config['ca'] = array();
+ }
+ $a_ca =& $config['ca'];
+ if (!is_array($config['cert'])) {
+ $config['cert'] = array();
+ }
+ $a_cert =& $config['cert'];
+ log_error("Creating SSL Certificate for this host");
+
+ $cert = array();
+ $cert['refid'] = uniqid();
+ $cert['descr'] = gettext("webConfigurator default ({$cert['refid']})");
+
+ $dn = array(
+ 'countryName' => "US",
+ 'stateOrProvinceName' => "State",
+ 'localityName' => "Locality",
+ 'organizationName' => "{$g['product_name']} webConfigurator Self-Signed Certificate",
+ 'emailAddress' => "admin@{$config['system']['hostname']}.{$config['system']['domain']}",
+ 'commonName' => "{$config['system']['hostname']}-{$cert['refid']}");
+ $old_err_level = error_reporting(0); /* otherwise openssl_ functions throw warnings directly to a page screwing menu tab */
+ if (!cert_create($cert, null, 2048, 2000, $dn, "self-signed", "sha256")) {
+ while ($ssl_err = openssl_error_string()) {
+ log_error("Error creating WebGUI Certificate: openssl library returns: " . $ssl_err);
+ }
+ error_reporting($old_err_level);
+ return null;
+ }
+ error_reporting($old_err_level);
+
+ $a_cert[] = $cert;
+ $config['system']['webgui']['ssl-certref'] = $cert['refid'];
+ write_config(gettext("Generated new self-signed HTTPS certificate ({$cert['refid']})"));
+ return $cert;
+}
+
+function system_webgui_start() {
+ global $config, $g;
+
+ if (platform_booting()) {
+ echo gettext("Starting webConfigurator...");
+ }
+
+ chdir($g['www_path']);
+
+ /* defaults */
+ $portarg = "80";
+ $crt = "";
+ $key = "";
+ $ca = "";
+
+ /* non-standard port? */
+ if (isset($config['system']['webgui']['port']) && $config['system']['webgui']['port'] <> "") {
+ $portarg = "{$config['system']['webgui']['port']}";
+ }
+
+ if ($config['system']['webgui']['protocol'] == "https") {
+ // Ensure that we have a webConfigurator CERT
+ $cert =& lookup_cert($config['system']['webgui']['ssl-certref']);
+ if (!is_array($cert) || !$cert['crt'] || !$cert['prv']) {
+ $cert = system_webgui_create_certificate();
+ }
+ $crt = base64_decode($cert['crt']);
+ $key = base64_decode($cert['prv']);
+
+ if (!$config['system']['webgui']['port']) {
+ $portarg = "443";
+ }
+ $ca = ca_chain($cert);
+ }
+
+ /* generate lighttpd configuration */
+ system_generate_lighty_config("{$g['varetc_path']}/lighty-webConfigurator.conf",
+ $crt, $key, $ca, "lighty-webConfigurator.pid", $portarg, "/usr/local/www/",
+ "cert.pem", "ca.pem");
+
+ /* kill any running lighttpd */
+ killbypid("{$g['varrun_path']}/lighty-webConfigurator.pid");
+
+ sleep(1);
+
+ @unlink("{$g['varrun_path']}/lighty-webConfigurator.pid");
+
+ /* attempt to start lighthttpd */
+ $res = mwexec("/usr/local/sbin/lighttpd -f {$g['varetc_path']}/lighty-webConfigurator.conf");
+
+ if (platform_booting()) {
+ if ($res == 0) {
+ echo gettext("done.") . "\n";
+ } else {
+ echo gettext("failed!") . "\n";
+ }
+ }
+
+ return $res;
+}
+
+function system_generate_lighty_config($filename,
+ $cert,
+ $key,
+ $ca,
+ $pid_file,
+ $port = 80,
+ $document_root = "/usr/local/www/",
+ $cert_location = "cert.pem",
+ $ca_location = "ca.pem",
+ $captive_portal = false) {
+
+ global $config, $g;
+
+ if (!is_dir("{$g['tmp_path']}/lighttpdcompress")) {
+ mkdir("{$g['tmp_path']}/lighttpdcompress");
+ }
+
+ if (isset($config['system']['developerspew'])) {
+ $mt = microtime();
+ echo "system_generate_lighty_config() being called $mt\n";
+ }
+
+ if ($captive_portal !== false) {
+ $captiveportal = ",\"mod_rewrite\",\"mod_evasive\"";
+ $captive_portal_rewrite = "url.rewrite-once = ( \"(.*captiveportal.*)\" => \"$1\", \"(.*)\" => \"/index.php?zone={$captive_portal}&redirurl=$1\" )\n";
+
+ $maxprocperip = $config['captiveportal'][$captive_portal]['maxprocperip'];
+ if (empty($maxprocperip)) {
+ $maxprocperip = 10;
+ }
+ $captive_portal_mod_evasive = "evasive.max-conns-per-ip = {$maxprocperip}";
+
+ $server_upload_dirs = "server.upload-dirs = ( \"{$g['tmp_path']}/captiveportal/\" )\n";
+ if (!is_dir("{$g['tmp_path']}/captiveportal")) {
+ @mkdir("{$g['tmp_path']}/captiveportal", 0555);
+ }
+ $server_max_request_size = "server.max-request-size = 384";
+ $cgi_config = "";
+ } else {
+ $captiveportal = ",\"mod_cgi\"";
+ $captive_portal_rewrite = "";
+ $captive_portal_mod_evasive = "";
+ $server_upload_dirs = "server.upload-dirs = ( \"{$g['upload_path']}/\", \"{$g['tmp_path']}/\", \"/var/\" )\n";
+ $server_max_request_size = "server.max-request-size = 2097152";
+ $cgi_config = "cgi.assign = ( \".cgi\" => \"\" )";
+ }
+
+ if (empty($port)) {
+ $lighty_port = "80";
+ } else {
+ $lighty_port = $port;
+ }
+
+ $memory = get_memory();
+ $realmem = $memory[1];
+
+ // Determine web GUI process settings and take into account low memory systems
+ if ($realmem < 255) {
+ $max_procs = 1;
+ } else {
+ $max_procs = ($config['system']['webgui']['max_procs']) ? $config['system']['webgui']['max_procs'] : 2;
+ }
+
+ // Ramp up captive portal max procs, assuming each PHP process can consume up to 64MB RAM
+ if ($captive_portal !== false) {
+ if ($realmem > 135 and $realmem < 256) {
+ $max_procs += 1; // 2 worker processes
+ } else if ($realmem > 255 and $realmem < 513) {
+ $max_procs += 2; // 3 worker processes
+ } else if ($realmem > 512) {
+ $max_procs += 4; // 6 worker processes
+ }
+ if ($max_procs > 1) {
+ $max_php_children = intval($max_procs/2);
+ } else {
+ $max_php_children = 1;
+ }
+
+ } else {
+ if ($realmem < 78) {
+ $max_php_children = 0;
+ } else {
+ $max_php_children = 1;
+ }
+ }
+
+ if (!isset($config['syslog']['nologlighttpd'])) {
+ $lighty_use_syslog = <<<EOD
+## where to send error-messages to
+server.errorlog-use-syslog="enable"
+EOD;
+ }
+
+
+ if ($captive_portal !== false) {
+ $fast_cgi_path = "{$g['tmp_path']}/php-fastcgi-{$captive_portal}.socket";
+ $fastcgi_config = <<<EOD
+#### fastcgi module
+## read fastcgi.txt for more info
+fastcgi.server = ( ".php" =>
+ ( "localhost" =>
+ (
+ "socket" => "{$fast_cgi_path}",
+ "max-procs" => {$max_procs},
+ "bin-environment" => (
+ "PHP_FCGI_CHILDREN" => "{$max_php_children}",
+ "PHP_FCGI_MAX_REQUESTS" => "500"
+ ),
+ "bin-path" => "/usr/local/bin/php-cgi"
+ )
+ )
+)
+
+EOD;
+ } else {
+ $fast_cgi_path = "{$g['varrun_path']}/php-fpm.socket";
+ $fastcgi_config = <<<EOD
+#### fastcgi module
+## read fastcgi.txt for more info
+fastcgi.server = ( ".php" =>
+ ( "localhost" =>
+ (
+ "socket" => "{$fast_cgi_path}",
+ "broken-scriptfilename" => "enable"
+ )
+ )
+)
+
+EOD;
+ }
+
+
+ $lighty_config = <<<EOD
+#
+# lighttpd configuration file
+#
+# use a it as base for lighttpd 1.0.0 and above
+#
+############ Options you really have to take care of ####################
+
+## FreeBSD!
+server.event-handler = "freebsd-kqueue"
+server.network-backend = "writev"
+#server.use-ipv6 = "enable"
+
+## modules to load
+server.modules = ( "mod_access", "mod_expire", "mod_compress", "mod_redirect",
+ {$captiveportal}, "mod_fastcgi"
+)
+
+server.max-keep-alive-requests = 15
+server.max-keep-alive-idle = 30
+
+## a static document-root, for virtual-hosting take look at the
+## server.virtual-* options
+server.document-root = "{$document_root}"
+{$captive_portal_rewrite}
+
+# Maximum idle time with nothing being written (php downloading)
+server.max-write-idle = 999
+
+{$lighty_use_syslog}
+
+# files to check for if .../ is requested
+server.indexfiles = ( "index.php", "index.html",
+ "index.htm", "default.htm" )
+
+# mimetype mapping
+mimetype.assign = (
+ ".pdf" => "application/pdf",
+ ".sig" => "application/pgp-signature",
+ ".spl" => "application/futuresplash",
+ ".class" => "application/octet-stream",
+ ".ps" => "application/postscript",
+ ".torrent" => "application/x-bittorrent",
+ ".dvi" => "application/x-dvi",
+ ".gz" => "application/x-gzip",
+ ".pac" => "application/x-ns-proxy-autoconfig",
+ ".swf" => "application/x-shockwave-flash",
+ ".tar.gz" => "application/x-tgz",
+ ".tgz" => "application/x-tgz",
+ ".tar" => "application/x-tar",
+ ".zip" => "application/zip",
+ ".mp3" => "audio/mpeg",
+ ".m3u" => "audio/x-mpegurl",
+ ".wma" => "audio/x-ms-wma",
+ ".wax" => "audio/x-ms-wax",
+ ".ogg" => "audio/x-wav",
+ ".wav" => "audio/x-wav",
+ ".gif" => "image/gif",
+ ".jpg" => "image/jpeg",
+ ".jpeg" => "image/jpeg",
+ ".png" => "image/png",
+ ".xbm" => "image/x-xbitmap",
+ ".xpm" => "image/x-xpixmap",
+ ".xwd" => "image/x-xwindowdump",
+ ".css" => "text/css",
+ ".html" => "text/html",
+ ".htm" => "text/html",
+ ".js" => "text/javascript",
+ ".asc" => "text/plain",
+ ".c" => "text/plain",
+ ".conf" => "text/plain",
+ ".text" => "text/plain",
+ ".txt" => "text/plain",
+ ".dtd" => "text/xml",
+ ".xml" => "text/xml",
+ ".mpeg" => "video/mpeg",
+ ".mpg" => "video/mpeg",
+ ".mov" => "video/quicktime",
+ ".qt" => "video/quicktime",
+ ".avi" => "video/x-msvideo",
+ ".asf" => "video/x-ms-asf",
+ ".asx" => "video/x-ms-asf",
+ ".wmv" => "video/x-ms-wmv",
+ ".bz2" => "application/x-bzip",
+ ".tbz" => "application/x-bzip-compressed-tar",
+ ".tar.bz2" => "application/x-bzip-compressed-tar"
+ )
+
+# Use the "Content-Type" extended attribute to obtain mime type if possible
+#mimetypes.use-xattr = "enable"
+
+## deny access the file-extensions
+#
+# ~ is for backupfiles from vi, emacs, joe, ...
+# .inc is often used for code includes which should in general not be part
+# of the document-root
+url.access-deny = ( "~", ".inc" )
+
+
+######### Options that are good to be but not necessary to be changed #######
+
+## disable server header
+server.tag = ""
+
+## bind to port (default: 80)
+
+EOD;
+
+ $lighty_config .= "server.bind = \"0.0.0.0\"\n";
+ $lighty_config .= "server.port = {$lighty_port}\n";
+ $lighty_config .= "\$SERVER[\"socket\"] == \"0.0.0.0:{$lighty_port}\" { }\n";
+ $lighty_config .= "\$SERVER[\"socket\"] == \"[::]:{$lighty_port}\" { \n";
+ if ($cert <> "" and $key <> "") {
+ $lighty_config .= "\n";
+ $lighty_config .= "## ssl configuration\n";
+ $lighty_config .= "ssl.engine = \"enable\"\n";
+ $lighty_config .= "ssl.pemfile = \"{$g['varetc_path']}/{$cert_location}\"\n\n";
+ if ($ca <> "") {
+ $lighty_config .= "ssl.ca-file = \"{$g['varetc_path']}/{$ca_location}\"\n\n";
+ }
+ }
+ $lighty_config .= " }\n";
+
+
+ $lighty_config .= <<<EOD
+
+## error-handler for status 404
+#server.error-handler-404 = "/error-handler.html"
+#server.error-handler-404 = "/error-handler.php"
+
+## to help the rc.scripts
+server.pid-file = "{$g['varrun_path']}/{$pid_file}"
+
+## virtual directory listings
+server.dir-listing = "disable"
+
+## enable debugging
+debug.log-request-header = "disable"
+debug.log-response-header = "disable"
+debug.log-request-handling = "disable"
+debug.log-file-not-found = "disable"
+
+# gzip compression
+compress.cache-dir = "{$g['tmp_path']}/lighttpdcompress/"
+compress.filetype = ("text/plain","text/css", "text/xml", "text/javascript" )
+
+{$server_upload_dirs}
+
+{$server_max_request_size}
+
+{$fastcgi_config}
+
+{$cgi_config}
+
+{$captive_portal_mod_evasive}
+
+expire.url = (
+ "" => "access 50 hours",
+ )
+
+EOD;
+
+ $cert = str_replace("\r", "", $cert);
+ $key = str_replace("\r", "", $key);
+ $ca = str_replace("\r", "", $ca);
+
+ $cert = str_replace("\n\n", "\n", $cert);
+ $key = str_replace("\n\n", "\n", $key);
+ $ca = str_replace("\n\n", "\n", $ca);
+
+ if ($cert <> "" and $key <> "") {
+ $fd = fopen("{$g['varetc_path']}/{$cert_location}", "w");
+ if (!$fd) {
+ printf(gettext("Error: cannot open cert.pem in system_webgui_start().%s"), "\n");
+ return 1;
+ }
+ chmod("{$g['varetc_path']}/{$cert_location}", 0600);
+ fwrite($fd, $cert);
+ fwrite($fd, "\n");
+ fwrite($fd, $key);
+ fclose($fd);
+ if (!(empty($ca) || (strlen(trim($ca)) == 0))) {
+ $fd = fopen("{$g['varetc_path']}/{$ca_location}", "w");
+ if (!$fd) {
+ printf(gettext("Error: cannot open ca.pem in system_webgui_start().%s"), "\n");
+ return 1;
+ }
+ chmod("{$g['varetc_path']}/{$ca_location}", 0600);
+ fwrite($fd, $ca);
+ fclose($fd);
+ }
+ $lighty_config .= "\n";
+ $lighty_config .= "## " . gettext("ssl configuration") . "\n";
+ $lighty_config .= "ssl.engine = \"enable\"\n";
+ $lighty_config .= "ssl.pemfile = \"{$g['varetc_path']}/{$cert_location}\"\n\n";
+
+ // SSLv2/3 is deprecated, force use of TLS
+ $lighty_config .= "ssl.use-sslv2 = \"disable\"\n";
+ $lighty_config .= "ssl.use-sslv3 = \"disable\"\n";
+
+ // where ssl.cipher-list is set, this is automatically enabled, but set it explicitly anyway.
+ $lighty_config .= "ssl.honor-cipher-order = \"enable\"\n";
+
+ $lighty_config .= "ssl.cipher-list = \"AES128+EECDH:AES256+EECDH:AES128+EDH:AES256+EDH:AES128-SHA:AES256-SHA:!aNULL:!eNULL:!DSS\"\n";
+
+ if (!(empty($ca) || (strlen(trim($ca)) == 0))) {
+ $lighty_config .= "ssl.ca-file = \"{$g['varetc_path']}/{$ca_location}\"\n\n";
+ }
+ }
+
+ // Add HTTP to HTTPS redirect
+ if ($captive_portal === false && $config['system']['webgui']['protocol'] == "https" && !isset($config['system']['webgui']['disablehttpredirect'])) {
+ if ($lighty_port != "443") {
+ $redirectport = ":{$lighty_port}";
+ }
+ $lighty_config .= <<<EOD
+\$SERVER["socket"] == ":80" {
+ \$HTTP["host"] =~ "(.*)" {
+ url.redirect = ( "^/(.*)" => "https://%1{$redirectport}/$1" )
+ }
+}
+\$SERVER["socket"] == "[::]:80" {
+ \$HTTP["host"] =~ "(.*)" {
+ url.redirect = ( "^/(.*)" => "https://%1{$redirectport}/$1" )
+ }
+}
+EOD;
+ }
+
+ $fd = fopen("{$filename}", "w");
+ if (!$fd) {
+ printf(gettext("Error: cannot open %s in system_generate_lighty_config().%s"), $filename, "\n");
+ return 1;
+ }
+ fwrite($fd, $lighty_config);
+ fclose($fd);
+
+ return 0;
+
+}
+
+function system_timezone_configure() {
+ global $config, $g;
+ if (isset($config['system']['developerspew'])) {
+ $mt = microtime();
+ echo "system_timezone_configure() being called $mt\n";
+ }
+
+ $syscfg = $config['system'];
+
+ if (platform_booting()) {
+ echo gettext("Setting timezone...");
+ }
+
+ /* extract appropriate timezone file */
+ $timezone = $syscfg['timezone'];
+ if ($timezone) {
+ exec('/usr/bin/tar -tvzf /usr/share/zoneinfo.tgz', $tzs);
+ foreach ($tzs as $tz) {
+ if (preg_match(",{$timezone}$,", $tz)) {
+ break;
+ }
+ if (preg_match(",{$timezone} link to *(.*)$,", $tz, $matches)) {
+ $timezone = $matches[1];
+ break;
+ }
+ }
+ } else {
+ $timezone = "Etc/UTC";
+ }
+
+ conf_mount_rw();
+
+ exec("LANG=C /usr/bin/tar xzfO /usr/share/zoneinfo.tgz " .
+ escapeshellarg($timezone) . " > /etc/localtime");
+
+ mwexec("sync");
+ conf_mount_ro();
+
+ if (platform_booting()) {
+ echo gettext("done.") . "\n";
+ }
+}
+
+function system_ntp_setup_gps($serialport) {
+ global $config, $g;
+ $gps_device = '/dev/gps0';
+ $serialport = '/dev/'.$serialport;
+
+ if (!file_exists($serialport)) {
+ return false;
+ }
+
+ conf_mount_rw();
+ // Create symlink that ntpd requires
+ unlink_if_exists($gps_device);
+ @symlink($serialport, $gps_device);
+
+ $gpsbaud = '4800';
+ if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['speed'])) {
+ switch ($config['ntpd']['gps']['speed']) {
+ case '16':
+ $gpsbaud = '9600';
+ break;
+ case '32':
+ $gpsbaud = '19200';
+ break;
+ case '48':
+ $gpsbaud = '38400';
+ break;
+ case '64':
+ $gpsbaud = '57600';
+ break;
+ case '80':
+ $gpsbaud = '115200';
+ break;
+ }
+ }
+
+ /* Configure the serial port for raw IO and set the speed */
+ mwexec("stty -f {$serialport}.init raw speed {$gpsbaud}");
+
+ /* Send the following to the GPS port to initialize the GPS */
+ if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['type'])) {
+ $gps_init = base64_decode($config['ntpd']['gps']['initcmd']);
+ } else {
+ $gps_init = base64_decode('JFBVQlgsNDAsR1NWLDAsMCwwLDAqNTkNCiRQVUJYLDQwLEdMTCwwLDAsMCwwKjVDDQokUFVCWCw0MCxaREEsMCwwLDAsMCo0NA0KJFBVQlgsNDAsVlRHLDAsMCwwLDAqNUUNCiRQVUJYLDQwLEdTViwwLDAsMCwwKjU5DQokUFVCWCw0MCxHU0EsMCwwLDAsMCo0RQ0KJFBVQlgsNDAsR0dBLDAsMCwwLDANCiRQVUJYLDQwLFRYVCwwLDAsMCwwDQokUFVCWCw0MCxSTUMsMCwwLDAsMCo0Ng0KJFBVQlgsNDEsMSwwMDA3LDAwMDMsNDgwMCwwDQokUFVCWCw0MCxaREEsMSwxLDEsMQ==');
+ }
+
+ /* XXX: Why not file_put_contents to the device */
+ @file_put_contents('/tmp/gps.init', $gps_init);
+ mwexec("cat /tmp/gps.init > {$serialport}");
+
+ /* Add /etc/remote entry in case we need to read from the GPS with tip */
+ if (intval(`grep -c '^gps0' /etc/remote`) == 0) {
+ @file_put_contents("/etc/remote", "gps0:dv={$serialport}:br#{$gpsbaud}:pa=none:", FILE_APPEND);
+ }
+
+ conf_mount_ro();
+
+ return true;
+}
+
+function system_ntp_setup_pps($serialport) {
+ global $config, $g;
+
+ $pps_device = '/dev/pps0';
+ $serialport = '/dev/'.$serialport;
+
+ if (!file_exists($serialport)) {
+ return false;
+ }
+
+ conf_mount_rw();
+ // Create symlink that ntpd requires
+ unlink_if_exists($pps_device);
+ @symlink($serialport, $pps_device);
+
+ conf_mount_ro();
+
+ return true;
+}
+
+
+function system_ntp_configure($start_ntpd=true) {
+ global $config, $g;
+
+ $driftfile = "/var/db/ntpd.drift";
+ $statsdir = "/var/log/ntp";
+ $gps_device = '/dev/gps0';
+
+ safe_mkdir($statsdir);
+
+ if (!is_array($config['ntpd'])) {
+ $config['ntpd'] = array();
+ }
+
+ $ntpcfg = "# \n";
+ $ntpcfg .= "# pfSense ntp configuration file \n";
+ $ntpcfg .= "# \n\n";
+ $ntpcfg .= "tinker panic 0 \n";
+
+ /* Add Orphan mode */
+ $ntpcfg .= "# Orphan mode stratum\n";
+ $ntpcfg .= 'tos orphan ';
+ if (!empty($config['ntpd']['orphan'])) {
+ $ntpcfg .= $config['ntpd']['orphan'];
+ } else {
+ $ntpcfg .= '12';
+ }
+ $ntpcfg .= "\n";
+
+ /* Add PPS configuration */
+ if (is_array($config['ntpd']['pps']) && !empty($config['ntpd']['pps']['port']) &&
+ file_exists('/dev/'.$config['ntpd']['pps']['port']) &&
+ system_ntp_setup_pps($config['ntpd']['pps']['port'])) {
+ $ntpcfg .= "\n";
+ $ntpcfg .= "# PPS Setup\n";
+ $ntpcfg .= 'server 127.127.22.0';
+ $ntpcfg .= ' minpoll 4 maxpoll 4';
+ if (empty($config['ntpd']['pps']['prefer'])) { /*note: this one works backwards */
+ $ntpcfg .= ' prefer';
+ }
+ if (!empty($config['ntpd']['pps']['noselect'])) {
+ $ntpcfg .= ' noselect ';
+ }
+ $ntpcfg .= "\n";
+ $ntpcfg .= 'fudge 127.127.22.0';
+ if (!empty($config['ntpd']['pps']['fudge1'])) {
+ $ntpcfg .= ' time1 ';
+ $ntpcfg .= $config['ntpd']['pps']['fudge1'];
+ }
+ if (!empty($config['ntpd']['pps']['flag2'])) {
+ $ntpcfg .= ' flag2 1';
+ }
+ if (!empty($config['ntpd']['pps']['flag3'])) {
+ $ntpcfg .= ' flag3 1';
+ } else {
+ $ntpcfg .= ' flag3 0';
+ }
+ if (!empty($config['ntpd']['pps']['flag4'])) {
+ $ntpcfg .= ' flag4 1';
+ }
+ if (!empty($config['ntpd']['pps']['refid'])) {
+ $ntpcfg .= ' refid ';
+ $ntpcfg .= $config['ntpd']['pps']['refid'];
+ }
+ $ntpcfg .= "\n";
+ }
+ /* End PPS configuration */
+
+ /* Add GPS configuration */
+ if (is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['port']) &&
+ file_exists('/dev/'.$config['ntpd']['gps']['port']) &&
+ system_ntp_setup_gps($config['ntpd']['gps']['port'])) {
+ $ntpcfg .= "\n";
+ $ntpcfg .= "# GPS Setup\n";
+ $ntpcfg .= 'server 127.127.20.0 mode ';
+ if (!empty($config['ntpd']['gps']['nmea']) || !empty($config['ntpd']['gps']['speed']) || !empty($config['ntpd']['gps']['subsec'])) {
+ if (!empty($config['ntpd']['gps']['nmea'])) {
+ $ntpmode = (int) $config['ntpd']['gps']['nmea'];
+ }
+ if (!empty($config['ntpd']['gps']['speed'])) {
+ $ntpmode += (int) $config['ntpd']['gps']['speed'];
+ }
+ if (!empty($config['ntpd']['gps']['subsec'])) {
+ $ntpmode += 128;
+ }
+ $ntpcfg .= (string) $ntpmode;
+ } else {
+ $ntpcfg .= '0';
+ }
+ $ntpcfg .= ' minpoll 4 maxpoll 4';
+ if (empty($config['ntpd']['gps']['prefer'])) { /*note: this one works backwards */
+ $ntpcfg .= ' prefer';
+ }
+ if (!empty($config['ntpd']['gps']['noselect'])) {
+ $ntpcfg .= ' noselect ';
+ }
+ $ntpcfg .= "\n";
+ $ntpcfg .= 'fudge 127.127.20.0';
+ if (!empty($config['ntpd']['gps']['fudge1'])) {
+ $ntpcfg .= ' time1 ';
+ $ntpcfg .= $config['ntpd']['gps']['fudge1'];
+ }
+ if (!empty($config['ntpd']['gps']['fudge2'])) {
+ $ntpcfg .= ' time2 ';
+ $ntpcfg .= $config['ntpd']['gps']['fudge2'];
+ }
+ if (!empty($config['ntpd']['gps']['flag1'])) {
+ $ntpcfg .= ' flag1 1';
+ } else {
+ $ntpcfg .= ' flag1 0';
+ }
+ if (!empty($config['ntpd']['gps']['flag2'])) {
+ $ntpcfg .= ' flag2 1';
+ }
+ if (!empty($config['ntpd']['gps']['flag3'])) {
+ $ntpcfg .= ' flag3 1';
+ } else {
+ $ntpcfg .= ' flag3 0';
+ }
+ if (!empty($config['ntpd']['gps']['flag4'])) {
+ $ntpcfg .= ' flag4 1';
+ }
+ if (!empty($config['ntpd']['gps']['refid'])) {
+ $ntpcfg .= ' refid ';
+ $ntpcfg .= $config['ntpd']['gps']['refid'];
+ }
+ $ntpcfg .= "\n";
+ } elseif (is_array($config['ntpd']) && !empty($config['ntpd']['gpsport']) &&
+ file_exists('/dev/'.$config['ntpd']['gpsport']) &&
+ system_ntp_setup_gps($config['ntpd']['gpsport'])) {
+ /* This handles a 2.1 and earlier config */
+ $ntpcfg .= "# GPS Setup\n";
+ $ntpcfg .= "server 127.127.20.0 mode 0 minpoll 4 maxpoll 4 prefer\n";
+ $ntpcfg .= "fudge 127.127.20.0 time1 0.155 time2 0.000 flag1 1 flag2 0 flag3 1\n";
+ // Fall back to local clock if GPS is out of sync?
+ $ntpcfg .= "server 127.127.1.0\n";
+ $ntpcfg .= "fudge 127.127.1.0 stratum 12\n";
+ }
+ /* End GPS configuration */
+
+ $ntpcfg .= "\n\n# Upstream Servers\n";
+ /* foreach through ntp servers and write out to ntpd.conf */
+ foreach (explode(' ', $config['system']['timeservers']) as $ts) {
+ $ntpcfg .= "server {$ts} iburst maxpoll 9";
+ if (substr_count($config['ntpd']['prefer'], $ts)) {
+ $ntpcfg .= ' prefer';
+ }
+ if (substr_count($config['ntpd']['noselect'], $ts)) {
+ $ntpcfg .= ' noselect';
+ }
+ $ntpcfg .= "\n";
+ }
+ unset($ts);
+
+ $ntpcfg .= "\n\n";
+ $ntpcfg .= "disable monitor\n"; //prevent NTP reflection attack, see https://forum.pfsense.org/index.php/topic,67189.msg389132.html#msg389132
+ if (!empty($config['ntpd']['clockstats']) || !empty($config['ntpd']['loopstats']) || !empty($config['ntpd']['peerstats'])) {
+ $ntpcfg .= "enable stats\n";
+ $ntpcfg .= 'statistics';
+ if (!empty($config['ntpd']['clockstats'])) {
+ $ntpcfg .= ' clockstats';
+ }
+ if (!empty($config['ntpd']['loopstats'])) {
+ $ntpcfg .= ' loopstats';
+ }
+ if (!empty($config['ntpd']['peerstats'])) {
+ $ntpcfg .= ' peerstats';
+ }
+ $ntpcfg .= "\n";
+ }
+ $ntpcfg .= "statsdir {$statsdir}\n";
+ $ntpcfg .= 'logconfig =syncall +clockall';
+ if (!empty($config['ntpd']['logpeer'])) {
+ $ntpcfg .= ' +peerall';
+ }
+ if (!empty($config['ntpd']['logsys'])) {
+ $ntpcfg .= ' +sysall';
+ }
+ $ntpcfg .= "\n";
+ $ntpcfg .= "driftfile {$driftfile}\n";
+ /* Access restrictions */
+ $ntpcfg .= 'restrict default';
+ if (empty($config['ntpd']['kod'])) { /*note: this one works backwards */
+ $ntpcfg .= ' kod limited';
+ }
+ if (empty($config['ntpd']['nomodify'])) { /*note: this one works backwards */
+ $ntpcfg .= ' nomodify';
+ }
+ if (!empty($config['ntpd']['noquery'])) {
+ $ntpcfg .= ' noquery';
+ }
+ if (empty($config['ntpd']['nopeer'])) { /*note: this one works backwards */
+ $ntpcfg .= ' nopeer';
+ }
+ if (empty($config['ntpd']['notrap'])) { /*note: this one works backwards */
+ $ntpcfg .= ' notrap';
+ }
+ if (!empty($config['ntpd']['noserve'])) {
+ $ntpcfg .= ' noserve';
+ }
+ $ntpcfg .= "\nrestrict -6 default";
+ if (empty($config['ntpd']['kod'])) { /*note: this one works backwards */
+ $ntpcfg .= ' kod limited';
+ }
+ if (empty($config['ntpd']['nomodify'])) { /*note: this one works backwards */
+ $ntpcfg .= ' nomodify';
+ }
+ if (!empty($config['ntpd']['noquery'])) {
+ $ntpcfg .= ' noquery';
+ }
+ if (empty($config['ntpd']['nopeer'])) { /*note: this one works backwards */
+ $ntpcfg .= ' nopeer';
+ }
+ if (!empty($config['ntpd']['noserve'])) {
+ $ntpcfg .= ' noserve';
+ }
+ if (empty($config['ntpd']['notrap'])) { /*note: this one works backwards */
+ $ntpcfg .= ' notrap';
+ }
+ $ntpcfg .= "\n";
+
+ /* A leapseconds file is really only useful if this clock is stratum 1 */
+ $ntpcfg .= "\n";
+ if (!empty($config['ntpd']['leapsec'])) {
+ $leapsec .= base64_decode($config['ntpd']['leapsec']);
+ file_put_contents('/var/db/leap-seconds', $leapsec);
+ $ntpcfg .= "leapfile /var/db/leap-seconds\n";
+ }
+
+
+ if (empty($config['ntpd']['interface'])) {
+ if (is_array($config['installedpackages']['openntpd']) && !empty($config['installedpackages']['openntpd']['config'][0]['interface'])) {
+ $interfaces = explode(",", $config['installedpackages']['openntpd']['config'][0]['interface']);
+ } else {
+ $interfaces = array();
+ }
+ } else {
+ $interfaces = explode(",", $config['ntpd']['interface']);
+ }
+
+ if (is_array($interfaces) && count($interfaces)) {
+ $ntpcfg .= "interface ignore all\n";
+ foreach ($interfaces as $interface) {
+ if (strstr($interface, "_vip")) {
+ $interface = get_configured_carp_interface_list($interface);
+ }
+ if (!is_ipaddr($interface)) {
+ $interface = get_real_interface($interface);
+ }
+ if (!empty($interface)) {
+ $ntpcfg .= "interface listen {$interface}\n";
+ }
+ }
+ }
+
+ /* open configuration for writing or bail */
+ if (!@file_put_contents("{$g['varetc_path']}/ntpd.conf", $ntpcfg)) {
+ log_error("Could not open {$g['varetc_path']}/ntpd.conf for writing");
+ return;
+ }
+
+ /* At bootup we just want to write out the config. */
+ if (!$start_ntpd) {
+ return;
+ }
+
+ /* if ntpd is running, kill it */
+ while (isvalidpid("{$g['varrun_path']}/ntpd.pid")) {
+ killbypid("{$g['varrun_path']}/ntpd.pid");
+ }
+ @unlink("{$g['varrun_path']}/ntpd.pid");
+
+ /* if /var/empty does not exist, create it */
+ if (!is_dir("/var/empty")) {
+ mkdir("/var/empty", 0775, true);
+ }
+
+ /* start opentpd, set time now and use /var/etc/ntpd.conf */
+ mwexec("/usr/local/sbin/ntpd -g -c {$g['varetc_path']}/ntpd.conf -p {$g['varrun_path']}/ntpd.pid", false, true);
+
+ // Note that we are starting up
+ log_error("NTPD is starting up.");
+ return;
+}
+
+function sync_system_time() {
+ global $config, $g;
+
+ if (platform_booting()) {
+ echo gettext("Syncing system time before startup...");
+ }
+
+ /* foreach through servers and write out to ntpd.conf */
+ foreach (explode(' ', $config['system']['timeservers']) as $ts) {
+ mwexec("/usr/local/sbin/ntpdate -s $ts");
+ }
+
+ if (platform_booting()) {
+ echo gettext("done.") . "\n";
+ }
+
+}
+
+function system_halt() {
+ global $g;
+
+ system_reboot_cleanup();
+
+ mwexec("/usr/bin/nohup /etc/rc.halt > /dev/null 2>&1 &");
+}
+
+function system_reboot() {
+ global $g;
+
+ system_reboot_cleanup();
+
+ mwexec("nohup /etc/rc.reboot > /dev/null 2>&1 &");
+}
+
+function system_reboot_sync() {
+ global $g;
+
+ system_reboot_cleanup();
+
+ mwexec("/etc/rc.reboot > /dev/null 2>&1");
+}
+
+function system_reboot_cleanup() {
+ global $config, $cpzone;
+
+ 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();
+ captiveportal_send_server_accounting(true);
+ }
+ }
+ require_once("voucher.inc");
+ voucher_save_db_to_config();
+ require_once("pkg-utils.inc");
+ stop_packages();
+}
+
+function system_do_shell_commands($early = 0) {
+ global $config, $g;
+ if (isset($config['system']['developerspew'])) {
+ $mt = microtime();
+ echo "system_do_shell_commands() being called $mt\n";
+ }
+
+ if ($early) {
+ $cmdn = "earlyshellcmd";
+ } else {
+ $cmdn = "shellcmd";
+ }
+
+ if (is_array($config['system'][$cmdn])) {
+
+ /* *cmd is an array, loop through */
+ foreach ($config['system'][$cmdn] as $cmd) {
+ exec($cmd);
+ }
+
+ } elseif ($config['system'][$cmdn] <> "") {
+
+ /* execute single item */
+ exec($config['system'][$cmdn]);
+
+ }
+}
+
+function system_console_configure() {
+ global $config, $g;
+ if (isset($config['system']['developerspew'])) {
+ $mt = microtime();
+ echo "system_console_configure() being called $mt\n";
+ }
+
+ if (isset($config['system']['disableconsolemenu'])) {
+ touch("{$g['varetc_path']}/disableconsole");
+ } else {
+ unlink_if_exists("{$g['varetc_path']}/disableconsole");
+ }
+}
+
+function system_dmesg_save() {
+ global $g;
+ if (isset($config['system']['developerspew'])) {
+ $mt = microtime();
+ echo "system_dmesg_save() being called $mt\n";
+ }
+
+ $dmesg = "";
+ $_gb = exec("/sbin/dmesg", $dmesg);
+
+ /* find last copyright line (output from previous boots may be present) */
+ $lastcpline = 0;
+
+ for ($i = 0; $i < count($dmesg); $i++) {
+ if (strstr($dmesg[$i], "Copyright (c) 1992-")) {
+ $lastcpline = $i;
+ }
+ }
+
+ $fd = fopen("{$g['varlog_path']}/dmesg.boot", "w");
+ if (!$fd) {
+ printf(gettext("Error: cannot open dmesg.boot in system_dmesg_save().%s"), "\n");
+ return 1;
+ }
+
+ for ($i = $lastcpline; $i < count($dmesg); $i++) {
+ fwrite($fd, $dmesg[$i] . "\n");
+ }
+
+ fclose($fd);
+ unset($dmesg);
+
+ return 0;
+}
+
+function system_set_harddisk_standby() {
+ global $g, $config;
+ if (isset($config['system']['developerspew'])) {
+ $mt = microtime();
+ echo "system_set_harddisk_standby() being called $mt\n";
+ }
+
+ if (isset($config['system']['harddiskstandby'])) {
+ if (platform_booting()) {
+ echo gettext('Setting hard disk standby... ');
+ }
+
+ $standby = $config['system']['harddiskstandby'];
+ // Check for a numeric value
+ if (is_numeric($standby)) {
+ // Sync the disk(s)
+ pfSense_sync();
+ if (set_single_sysctl('hw.ata.standby', (int)$standby)) {
+ // Reinitialize ATA-drives
+ mwexec('/usr/local/sbin/atareinit');
+ if (platform_booting()) {
+ echo gettext("done.") . "\n";
+ }
+ } else if (platform_booting()) {
+ echo gettext("failed!") . "\n";
+ }
+ } else if (platform_booting()) {
+ echo gettext("failed!") . "\n";
+ }
+ }
+}
+
+function system_setup_sysctl() {
+ global $config;
+ if (isset($config['system']['developerspew'])) {
+ $mt = microtime();
+ echo "system_setup_sysctl() being called $mt\n";
+ }
+
+ activate_sysctls();
+
+ if (isset($config['system']['sharednet'])) {
+ system_disable_arp_wrong_if();
+ }
+}
+
+function system_disable_arp_wrong_if() {
+ global $config;
+ if (isset($config['system']['developerspew'])) {
+ $mt = microtime();
+ echo "system_disable_arp_wrong_if() being called $mt\n";
+ }
+ set_sysctl(array(
+ "net.link.ether.inet.log_arp_wrong_iface" => "0",
+ "net.link.ether.inet.log_arp_movements" => "0"
+ ));
+}
+
+function system_enable_arp_wrong_if() {
+ global $config;
+ if (isset($config['system']['developerspew'])) {
+ $mt = microtime();
+ echo "system_enable_arp_wrong_if() being called $mt\n";
+ }
+ set_sysctl(array(
+ "net.link.ether.inet.log_arp_wrong_iface" => "1",
+ "net.link.ether.inet.log_arp_movements" => "1"
+ ));
+}
+
+function enable_watchdog() {
+ global $config;
+ return;
+ $install_watchdog = false;
+ $supported_watchdogs = array("Geode");
+ $file = file_get_contents("/var/log/dmesg.boot");
+ foreach ($supported_watchdogs as $sd) {
+ if (stristr($file, "Geode")) {
+ $install_watchdog = true;
+ }
+ }
+ if ($install_watchdog == true) {
+ if (is_process_running("watchdogd")) {
+ mwexec("/usr/bin/killall watchdogd", true);
+ }
+ exec("/usr/sbin/watchdogd");
+ }
+}
+
+function system_check_reset_button() {
+ global $g;
+
+ $specplatform = system_identify_specific_platform();
+
+ switch ($specplatform['name']) {
+ case 'alix':
+ case 'wrap':
+ case 'FW7541':
+ case 'APU':
+ case 'RCC-VE':
+ case 'RCC-DFF':
+ break;
+ default:
+ return 0;
+ }
+
+ $retval = mwexec("/usr/local/sbin/" . $specplatform['name'] . "resetbtn");
+
+ if ($retval == 99) {
+ /* user has pressed reset button for 2 seconds -
+ reset to factory defaults */
+ echo <<<EOD
+
+***********************************************************************
+* Reset button pressed - resetting configuration to factory defaults. *
+* The system will reboot after this completes. *
+***********************************************************************
+
+
+EOD;
+
+ reset_factory_defaults();
+ system_reboot_sync();
+ exit(0);
+ }
+
+ return 0;
+}
+
+/* attempt to identify the specific platform (for embedded systems)
+ Returns an array with two elements:
+ name => platform string (e.g. 'wrap', 'alix' etc.)
+ descr => human-readable description (e.g. "PC Engines WRAP")
+*/
+function system_identify_specific_platform() {
+ global $g;
+
+ if ($g['platform'] == 'generic-pc') {
+ return array('name' => 'generic-pc', 'descr' => gettext("Generic PC"));
+ }
+
+ if ($g['platform'] == 'generic-pc-cdrom') {
+ return array('name' => 'generic-pc-cdrom', 'descr' => gettext("Generic PC (CD-ROM)"));
+ }
+
+ /* Try to guess from smbios strings */
+ unset($output);
+ $_gb = exec('/bin/kenv smbios.system.product 2>/dev/null', $output);
+ switch ($output[0]) {
+ case 'FW7541':
+ return (array('name' => 'FW7541', 'descr' => 'Netgate FW7541'));
+ break;
+ case 'APU':
+ return (array('name' => 'APU', 'descr' => 'Netgate APU'));
+ break;
+ case 'RCC-VE':
+ return (array('name' => 'RCC-VE', 'descr' => 'Netgate RCC-VE'));
+ break;
+ case 'DFFv2':
+ return (array('name' => 'RCC-DFF', 'descr' => 'Netgate RCC-DFF'));
+ break;
+ case 'SYS-5018A-FTN4':
+ case 'A1SAi':
+ return (array('name' => 'C2758', 'descr' => 'Super Micro C2758'));
+ break;
+ case 'SYS-5018D-FN4T':
+ return (array('name' => 'D1540-XG', 'descr' => 'Super Micro D1540-XG'));
+ break;
+ }
+
+ /* the rest of the code only deals with 'embedded' platforms */
+ if ($g['platform'] != 'nanobsd') {
+ return array('name' => $g['platform'], 'descr' => $g['platform']);
+ }
+
+ $dmesg = get_single_sysctl('hw.model');
+
+ if (strpos($dmesg, "PC Engines WRAP") !== false) {
+ return array('name' => 'wrap', 'descr' => gettext('PC Engines WRAP'));
+ }
+
+ if (strpos($dmesg, "PC Engines ALIX") !== false) {
+ return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
+ }
+
+ if (preg_match("/Soekris net45../", $dmesg, $matches)) {
+ return array('name' => 'net45xx', 'descr' => $matches[0]);
+ }
+
+ if (preg_match("/Soekris net48../", $dmesg, $matches)) {
+ return array('name' => 'net48xx', 'descr' => $matches[0]);
+ }
+
+ if (preg_match("/Soekris net55../", $dmesg, $matches)) {
+ return array('name' => 'net55xx', 'descr' => $matches[0]);
+ }
+
+ unset($dmesg);
+
+ $dmesg_boot = system_get_dmesg_boot();
+ if (strpos($dmesg_boot, "PC Engines ALIX") !== false) {
+ return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
+ }
+ unset($dmesg_boot);
+
+ /* unknown embedded platform */
+ return array('name' => 'embedded', 'descr' => gettext('embedded (unknown)'));
+}
+
+function system_get_dmesg_boot() {
+ global $g;
+
+ return file_get_contents("{$g['varlog_path']}/dmesg.boot");
+}
+
+?>
OpenPOWER on IntegriCloud