Project

General

Profile

Download (65.1 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	system.inc
4

    
5
	part of pfSense (https://www.pfsense.org)
6
	Copyright (c) 2004-2016 Electric Sheep Fencing, LLC.
7
	All rights reserved.
8

    
9
	originally part of m0n0wall (http://m0n0.ch/wall)
10
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
11
	All rights reserved.
12

    
13
	Redistribution and use in source and binary forms, with or without
14
	modification, are permitted provided that the following conditions are met:
15

    
16
	1. Redistributions of source code must retain the above copyright notice,
17
	   this list of conditions and the following disclaimer.
18

    
19
	2. Redistributions in binary form must reproduce the above copyright
20
	   notice, this list of conditions and the following disclaimer in
21
	   the documentation and/or other materials provided with the
22
	   distribution.
23

    
24
	3. All advertising materials mentioning features or use of this software
25
	   must display the following acknowledgment:
26
	   "This product includes software developed by the pfSense Project
27
	   for use in the pfSense® software distribution. (http://www.pfsense.org/).
28

    
29
	4. The names "pfSense" and "pfSense Project" must not be used to
30
	   endorse or promote products derived from this software without
31
	   prior written permission. For written permission, please contact
32
	   coreteam@pfsense.org.
33

    
34
	5. Products derived from this software may not be called "pfSense"
35
	   nor may "pfSense" appear in their names without prior written
36
	   permission of the Electric Sheep Fencing, LLC.
37

    
38
	6. Redistributions of any form whatsoever must retain the following
39
	   acknowledgment:
40

    
41
	"This product includes software developed by the pfSense Project
42
	for use in the pfSense software distribution (http://www.pfsense.org/).
43

    
44
	THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
45
	EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46
	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
47
	PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
48
	ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
49
	SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
50
	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51
	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52
	HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
53
	STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
55
	OF THE POSSIBILITY OF SUCH DAMAGE.
56
*/
57

    
58
function activate_powerd() {
59
	global $config, $g;
60

    
61
	if (is_process_running("powerd")) {
62
		exec("/usr/bin/killall powerd");
63
	}
64
	if (isset($config['system']['powerd_enable'])) {
65
		if ($g["platform"] == "nanobsd") {
66
			exec("/sbin/kldload cpufreq");
67
		}
68

    
69
		$ac_mode = "hadp";
70
		if (!empty($config['system']['powerd_ac_mode'])) {
71
			$ac_mode = $config['system']['powerd_ac_mode'];
72
		}
73

    
74
		$battery_mode = "hadp";
75
		if (!empty($config['system']['powerd_battery_mode'])) {
76
			$battery_mode = $config['system']['powerd_battery_mode'];
77
		}
78

    
79
		$normal_mode = "hadp";
80
		if (!empty($config['system']['powerd_normal_mode'])) {
81
			$normal_mode = $config['system']['powerd_normal_mode'];
82
		}
83

    
84
		mwexec("/usr/sbin/powerd -b $battery_mode -a $ac_mode -n $normal_mode");
85
	}
86
}
87

    
88
function get_default_sysctl_value($id) {
89
	global $sysctls;
90

    
91
	if (isset($sysctls[$id])) {
92
		return $sysctls[$id];
93
	}
94
}
95

    
96
function get_sysctl_descr($sysctl) {
97
	unset($output);
98
	$_gb = exec("/sbin/sysctl -nd {$sysctl}", $output);
99

    
100
	return $output[0];
101
}
102

    
103
function system_get_sysctls() {
104
	global $config, $sysctls;
105

    
106
	$disp_sysctl = array();
107
	$disp_cache = array();
108
	if (is_array($config['sysctl']) && is_array($config['sysctl']['item'])) {
109
		foreach ($config['sysctl']['item'] as $id => $tunable) {
110
			if ($tunable['value'] == "default") {
111
				$value = get_default_sysctl_value($tunable['tunable']);
112
			} else {
113
				$value = $tunable['value'];
114
			}
115

    
116
			$disp_sysctl[$id] = $tunable;
117
			$disp_sysctl[$id]['modified'] = true;
118
			$disp_cache[$tunable['tunable']] = 'set';
119
		}
120
	}
121

    
122
	foreach ($sysctls as $sysctl => $value) {
123
		if (isset($disp_cache[$sysctl])) {
124
			continue;
125
		}
126

    
127
		$disp_sysctl[$sysctl] = array('tunable' => $sysctl, 'value' => $value, 'descr' => get_sysctl_descr($sysctl));
128
	}
129
	unset($disp_cache);
130
	return $disp_sysctl;
131
}
132

    
133
function activate_sysctls() {
134
	global $config, $g, $sysctls;
135

    
136
	if (is_array($config['sysctl']) && is_array($config['sysctl']['item'])) {
137
		foreach ($config['sysctl']['item'] as $tunable) {
138
			if ($tunable['value'] == "default") {
139
				$value = get_default_sysctl_value($tunable['tunable']);
140
			} else {
141
				$value = $tunable['value'];
142
			}
143

    
144
			$sysctls[$tunable['tunable']] = $value;
145
		}
146
	}
147

    
148
	set_sysctl($sysctls);
149
}
150

    
151
function system_resolvconf_generate($dynupdate = false) {
152
	global $config, $g;
153

    
154
	if (isset($config['system']['developerspew'])) {
155
		$mt = microtime();
156
		echo "system_resolvconf_generate() being called $mt\n";
157
	}
158

    
159
	$syscfg = $config['system'];
160

    
161
	if ((((isset($config['dnsmasq']['enable'])) &&
162
	      (empty($config['dnsmasq']['port']) || $config['dnsmasq']['port'] == "53") &&
163
	      (empty($config['dnsmasq']['interface']) ||
164
	       in_array("lo0", explode(",", $config['dnsmasq']['interface'])))) ||
165
	     ((isset($config['unbound']['enable'])) &&
166
	      (empty($config['unbound']['port']) || $config['unbound']['port'] == "53") &&
167
	      (empty($config['unbound']['active_interface']) ||
168
	       in_array("lo0", explode(",", $config['unbound']['active_interface'])) ||
169
	       in_array("all", explode(",", $config['unbound']['active_interface']), true)))) &&
170
	     (!isset($config['system']['dnslocalhost']))) {
171
		$resolvconf .= "nameserver 127.0.0.1\n";
172
	}
173

    
174
	if (isset($syscfg['dnsallowoverride'])) {
175
		/* get dynamically assigned DNS servers (if any) */
176
		$ns = array_unique(get_searchdomains());
177
		foreach ($ns as $searchserver) {
178
			if ($searchserver) {
179
				$resolvconf .= "search {$searchserver}\n";
180
			}
181
		}
182
		$ns = array_unique(get_nameservers());
183
		foreach ($ns as $nameserver) {
184
			if ($nameserver) {
185
				$resolvconf .= "nameserver $nameserver\n";
186
			}
187
		}
188
	} else {
189
		$ns = array();
190
		// Do not create blank search/domain lines, it can break tools like dig.
191
		if ($syscfg['domain']) {
192
			$resolvconf .= "search {$syscfg['domain']}\n";
193
		}
194
	}
195
	if (is_array($syscfg['dnsserver'])) {
196
		foreach ($syscfg['dnsserver'] as $sys_dnsserver) {
197
			if ($sys_dnsserver && (!in_array($sys_dnsserver, $ns))) {
198
				$resolvconf .= "nameserver $sys_dnsserver\n";
199
			}
200
		}
201
	}
202

    
203
	// Add EDNS support
204
	if (isset($config['unbound']['enable']) && isset($config['unbound']['edns'])) {
205
		$resolvconf .= "options edns0\n";
206
	}
207

    
208
	$dnslock = lock('resolvconf', LOCK_EX);
209

    
210
	$fd = fopen("{$g['varetc_path']}/resolv.conf", "w");
211
	if (!$fd) {
212
		printf("Error: cannot open resolv.conf in system_resolvconf_generate().\n");
213
		unlock($dnslock);
214
		return 1;
215
	}
216

    
217
	fwrite($fd, $resolvconf);
218
	fclose($fd);
219

    
220
	// Prevent resolvconf(8) from rewriting our resolv.conf
221
	$fd = fopen("{$g['varetc_path']}/resolvconf.conf", "w");
222
	if (!$fd) {
223
		printf("Error: cannot open resolvconf.conf in system_resolvconf_generate().\n");
224
		return 1;
225
	}
226
	fwrite($fd, "resolv_conf=\"/dev/null\"\n");
227
	fclose($fd);
228

    
229
	if (!platform_booting()) {
230
		/* restart dhcpd (nameservers may have changed) */
231
		if (!$dynupdate) {
232
			services_dhcpd_configure();
233
		}
234
	}
235

    
236
	/* setup static routes for DNS servers. */
237
	for ($dnscounter=1; $dnscounter<5; $dnscounter++) {
238
		/* setup static routes for dns servers */
239
		$dnsgw = "dns{$dnscounter}gw";
240
		if (isset($config['system'][$dnsgw])) {
241
			if (empty($config['system'][$dnsgw]) ||
242
			    $config['system'][$dnsgw] == "none") {
243
				continue;
244
			}
245
			$gwname = $config['system'][$dnsgw];
246
			$gatewayip = lookup_gateway_ip_by_name($gwname);
247
			$inet6 = is_ipaddrv6($gatewayip) ? '-inet6 ' : '';
248
			/* dns server array starts at 0 */
249
			$dnsserver = $syscfg['dnsserver'][$dnscounter - 1];
250

    
251
			if (is_ipaddr($gatewayip)) {
252
				$cmd = 'change';
253
			} else {
254
				/* Remove old route when disable gw */
255
				$cmd = 'delete';
256
				$gatewayip = '';
257
			}
258

    
259
			mwexec("/sbin/route {$cmd} -host {$inet6}{$dnsserver} {$gatewayip}");
260
			if (isset($config['system']['route-debug'])) {
261
				$mt = microtime();
262
				log_error("ROUTING debug: $mt - route {$cmd} -host {$inet6}{$dnsserver} {$gatewayip}");
263
			}
264
		}
265
	}
266

    
267
	unlock($dnslock);
268

    
269
	return 0;
270
}
271

    
272
function get_searchdomains() {
273
	global $config, $g;
274

    
275
	$master_list = array();
276

    
277
	// Read in dhclient nameservers
278
	$search_list = glob("/var/etc/searchdomain_*");
279
	if (is_array($search_list)) {
280
		foreach ($search_list as $fdns) {
281
			$contents = file($fdns, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
282
			if (!is_array($contents)) {
283
				continue;
284
			}
285
			foreach ($contents as $dns) {
286
				if (is_hostname($dns)) {
287
					$master_list[] = $dns;
288
				}
289
			}
290
		}
291
	}
292

    
293
	return $master_list;
294
}
295

    
296
function get_nameservers() {
297
	global $config, $g;
298
	$master_list = array();
299

    
300
	// Read in dhclient nameservers
301
	$dns_lists = glob("/var/etc/nameserver_*");
302
	if (is_array($dns_lists)) {
303
		foreach ($dns_lists as $fdns) {
304
			$contents = file($fdns, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
305
			if (!is_array($contents)) {
306
				continue;
307
			}
308
			foreach ($contents as $dns) {
309
				if (is_ipaddr($dns)) {
310
					$master_list[] = $dns;
311
				}
312
			}
313
		}
314
	}
315

    
316
	// Read in any extra nameservers
317
	if (file_exists("/var/etc/nameservers.conf")) {
318
		$dns_s = file("/var/etc/nameservers.conf", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
319
		if (is_array($dns_s)) {
320
			foreach ($dns_s as $dns) {
321
				if (is_ipaddr($dns)) {
322
					$master_list[] = $dns;
323
				}
324
			}
325
		}
326
	}
327

    
328
	return $master_list;
329
}
330

    
331
function system_hosts_generate() {
332
	global $config, $g;
333
	if (isset($config['system']['developerspew'])) {
334
		$mt = microtime();
335
		echo "system_hosts_generate() being called $mt\n";
336
	}
337

    
338
	$syscfg = $config['system'];
339
	// prefer dnsmasq for hosts generation where it's enabled. It relies
340
	// on hosts for name resolution of its overrides, unbound does not.
341
	if (isset($config['dnsmasq']) && isset($config['dnsmasq']['enable'])) {
342
		$dnsmasqcfg = $config['dnsmasq'];
343
	} else {
344
		$dnsmasqcfg = $config['unbound'];
345
	}
346

    
347
	$hosts = "127.0.0.1	localhost localhost.{$syscfg['domain']}\n";
348
	$hosts .= "::1		localhost localhost.{$syscfg['domain']}\n";
349
	$lhosts = "";
350
	$dhosts = "";
351

    
352
	if ($config['interfaces']['lan']) {
353
		$cfgip = get_interface_ip("lan");
354
		if (is_ipaddr($cfgip)) {
355
			$hosts .= "{$cfgip}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
356
		}
357
		$cfgipv6 = get_interface_ipv6("lan");
358
		if (is_ipaddrv6($cfgipv6)) {
359
			$hosts .= "{$cfgipv6}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
360
		}
361
	} else {
362
		$sysiflist = get_configured_interface_list();
363
		$hosts_if_found = false;
364
		foreach ($sysiflist as $sysif) {
365
			if (!interface_has_gateway($sysif)) {
366
				$cfgip = get_interface_ip($sysif);
367
				if (is_ipaddr($cfgip)) {
368
					$hosts .= "{$cfgip}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
369
					$hosts_if_found = true;
370
				}
371
				$cfgipv6 = get_interface_ipv6($sysif);
372
				if (is_ipaddrv6($cfgipv6)) {
373
					$hosts .= "{$cfgipv6}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
374
					$hosts_if_found = true;
375
				}
376
				if ($hosts_if_found == true) {
377
					break;
378
				}
379
			}
380
		}
381
	}
382

    
383
	if (isset($dnsmasqcfg['enable'])) {
384
		if (!is_array($dnsmasqcfg['hosts'])) {
385
			$dnsmasqcfg['hosts'] = array();
386
		}
387

    
388
		foreach ($dnsmasqcfg['hosts'] as $host) {
389
			if ($host['host'] || $host['host'] == "0") {
390
				$lhosts .= "{$host['ip']}	{$host['host']}.{$host['domain']} {$host['host']}\n";
391
			} else {
392
				$lhosts .= "{$host['ip']}	{$host['domain']}\n";
393
			}
394
			if (!is_array($host['aliases']) || !is_array($host['aliases']['item'])) {
395
				continue;
396
			}
397
			foreach ($host['aliases']['item'] as $alias) {
398
				if ($alias['host'] || $alias['host'] == "0") {
399
					$lhosts .= "{$host['ip']}	{$alias['host']}.{$alias['domain']} {$alias['host']}\n";
400
				} else {
401
					$lhosts .= "{$host['ip']}	{$alias['domain']}\n";
402
				}
403
			}
404
		}
405
		if (isset($dnsmasqcfg['regdhcpstatic']) && is_array($config['dhcpd'])) {
406
			foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {
407
				if (is_array($dhcpifconf['staticmap']) && isset($dhcpifconf['enable'])) {
408
					foreach ($dhcpifconf['staticmap'] as $host) {
409
						if ($host['ipaddr'] && $host['hostname'] && $host['domain']) {
410
							$dhosts .= "{$host['ipaddr']}	{$host['hostname']}.{$host['domain']} {$host['hostname']}\n";
411
						} else if ($host['ipaddr'] && $host['hostname'] && $dhcpifconf['domain']) {
412
							$dhosts .= "{$host['ipaddr']}	{$host['hostname']}.{$dhcpifconf['domain']} {$host['hostname']}\n";
413
						} else if ($host['ipaddr'] && $host['hostname']) {
414
							$dhosts .= "{$host['ipaddr']}	{$host['hostname']}.{$syscfg['domain']} {$host['hostname']}\n";
415
						}
416
					}
417
				}
418
			}
419
		}
420
		if (isset($dnsmasqcfg['regdhcpstatic']) && is_array($config['dhcpdv6'])) {
421
			foreach ($config['dhcpdv6'] as $dhcpif => $dhcpifconf) {
422
				if (is_array($dhcpifconf['staticmap']) && isset($dhcpifconf['enable'])) {
423
					$isdelegated = $config['interfaces'][$dhcpif]['ipaddrv6'] == 'track6';
424
					foreach ($dhcpifconf['staticmap'] as $host) {
425
						$ipaddrv6 = $host['ipaddrv6'];
426
						if ($ipaddrv6 && $host['hostname']) {
427
							if ($isdelegated) {
428
								$trackifname = $config['interfaces'][$dhcpif]['track6-interface'];
429
								$trackcfg = $config['interfaces'][$trackifname];
430
								$pdlen = 64 - $trackcfg['dhcp6-ia-pd-len'];
431
								$ipaddrv6 = merge_ipv6_delegated_prefix(get_interface_ipv6($dhcpif), $ipaddrv6, $pdlen);
432
							}
433
							if ($host['domain']) {
434
								$dhosts .= "{$ipaddrv6}	{$host['hostname']}.{$host['domain']} {$host['hostname']}\n";
435
							} else if ($dhcpifconf['domain']) {
436
								$dhosts .= "{$ipaddrv6}	{$host['hostname']}.{$dhcpifconf['domain']} {$host['hostname']}\n";
437
							} else {
438
								$dhosts .= "{$ipaddrv6}	{$host['hostname']}.{$syscfg['domain']} {$host['hostname']}\n";
439
							}
440
						}
441
					}
442
				}
443
			}
444
		}
445

    
446
		if (isset($dnsmasqcfg['dhcpfirst'])) {
447
			$hosts .= $dhosts . $lhosts;
448
		} else {
449
			$hosts .= $lhosts . $dhosts;
450
		}
451
	}
452

    
453
	/*
454
	 * Do not remove this because dhcpleases monitors with kqueue it needs to be
455
	 * killed before writing to hosts files.
456
	 */
457
	if (file_exists("{$g['varrun_path']}/dhcpleases.pid")) {
458
		sigkillbypid("{$g['varrun_path']}/dhcpleases.pid", "TERM");
459
		@unlink("{$g['varrun_path']}/dhcpleases.pid");
460
	}
461
	$fd = fopen("{$g['varetc_path']}/hosts", "w");
462
	if (!$fd) {
463
		log_error(gettext("Error: cannot open hosts file in system_hosts_generate()."));
464
		return 1;
465
	}
466
	fwrite($fd, $hosts);
467
	fclose($fd);
468

    
469
	if (isset($config['unbound']['enable'])) {
470
		require_once("unbound.inc");
471
		unbound_hosts_generate();
472
	}
473

    
474
	return 0;
475
}
476

    
477
function system_dhcpleases_configure() {
478
	global $config, $g;
479

    
480
	/* Start the monitoring process for dynamic dhcpclients. */
481
	if ((isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcp'])) ||
482
	    (isset($config['unbound']['enable']) && isset($config['unbound']['regdhcp']))) {
483
		/* Make sure we do not error out */
484
		mwexec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/db");
485
		if (!file_exists("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases")) {
486
			@touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
487
		}
488

    
489
		if (isset($config['unbound']['enable'])) {
490
			$dns_pid = "unbound.pid";
491
			$unbound_conf = "-u {$g['unbound_chroot_path']}/dhcpleases_entries.conf";
492
		} else {
493
			$dns_pid = "dnsmasq.pid";
494
			$unbound_conf = "";
495
		}
496

    
497
		$pidfile = "{$g['varrun_path']}/dhcpleases.pid";
498
		if (isvalidpid($pidfile)) {
499
			/* Make sure dhcpleases is using correct unbound or dnsmasq */
500
			$_gb = exec("/bin/pgrep -F {$pidfile} -f {$dns_pid}", $output, $retval);
501
			if (intval($retval) == 0) {
502
				sigkillbypid($pidfile, "HUP");
503
				return;
504
			} else {
505
				sigkillbypid($pidfile, "TERM");
506
			}
507
		}
508

    
509
		/* To ensure we do not start multiple instances of dhcpleases, perform some clean-up first. */
510
		if (is_process_running("dhcpleases")) {
511
			sigkillbyname('dhcpleases', "TERM");
512
		}
513
		@unlink($pidfile);
514
		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");
515
	} else {
516
		sigkillbypid($pidfile, "TERM");
517
		@unlink($pidfile);
518
	}
519
}
520

    
521
function system_hostname_configure() {
522
	global $config, $g;
523
	if (isset($config['system']['developerspew'])) {
524
		$mt = microtime();
525
		echo "system_hostname_configure() being called $mt\n";
526
	}
527

    
528
	$syscfg = $config['system'];
529

    
530
	/* set hostname */
531
	$status = mwexec("/bin/hostname " .
532
		escapeshellarg("{$syscfg['hostname']}.{$syscfg['domain']}"));
533

    
534
	/* Setup host GUID ID.  This is used by ZFS. */
535
	mwexec("/etc/rc.d/hostid start");
536

    
537
	return $status;
538
}
539

    
540
function system_routing_configure($interface = "") {
541
	global $config, $g;
542

    
543
	if (isset($config['system']['developerspew'])) {
544
		$mt = microtime();
545
		echo "system_routing_configure() being called $mt\n";
546
	}
547

    
548
	$gatewayip = "";
549
	$interfacegw = "";
550
	$gatewayipv6 = "";
551
	$interfacegwv6 = "";
552
	$foundgw = false;
553
	$foundgwv6 = false;
554
	/* tack on all the hard defined gateways as well */
555
	if (is_array($config['gateways']['gateway_item'])) {
556
		array_map('unlink', glob("{$g['tmp_path']}/*_defaultgw{,v6}", GLOB_BRACE));
557
		foreach	($config['gateways']['gateway_item'] as $gateway) {
558
			if (isset($gateway['defaultgw'])) {
559
				if ($foundgw == false && ($gateway['ipprotocol'] != "inet6" && (is_ipaddrv4($gateway['gateway']) || $gateway['gateway'] == "dynamic"))) {
560
					if (strpos($gateway['gateway'], ":")) {
561
						continue;
562
					}
563
					if ($gateway['gateway'] == "dynamic") {
564
						$gateway['gateway'] = get_interface_gateway($gateway['interface']);
565
					}
566
					$gatewayip = $gateway['gateway'];
567
					$interfacegw = $gateway['interface'];
568
					if (!empty($gateway['interface'])) {
569
						$defaultif = get_real_interface($gateway['interface']);
570
						if ($defaultif) {
571
							@file_put_contents("{$g['tmp_path']}/{$defaultif}_defaultgw", $gateway['gateway']);
572
						}
573
					}
574
					$foundgw = true;
575
				} else if ($foundgwv6 == false && ($gateway['ipprotocol'] == "inet6" && (is_ipaddrv6($gateway['gateway']) || $gateway['gateway'] == "dynamic"))) {
576
					if ($gateway['gateway'] == "dynamic") {
577
						$gateway['gateway'] = get_interface_gateway_v6($gateway['interface']);
578
					}
579
					$gatewayipv6 = $gateway['gateway'];
580
					$interfacegwv6 = $gateway['interface'];
581
					if (!empty($gateway['interface'])) {
582
						$defaultifv6 = get_real_interface($gateway['interface']);
583
						if ($defaultifv6) {
584
							@file_put_contents("{$g['tmp_path']}/{$defaultifv6}_defaultgwv6", $gateway['gateway']);
585
						}
586
					}
587
					$foundgwv6 = true;
588
				}
589
			}
590
			if ($foundgw === true && $foundgwv6 === true) {
591
				break;
592
			}
593
		}
594
	}
595
	if ($foundgw == false) {
596
		$defaultif = get_real_interface("wan");
597
		$interfacegw = "wan";
598
		$gatewayip = get_interface_gateway("wan");
599
		@file_put_contents("{$g['tmp_path']}/{$defaultif}_defaultgw", $gatewayip);
600
	}
601
	if ($foundgwv6 == false) {
602
		$defaultifv6 = get_real_interface("wan");
603
		$interfacegwv6 = "wan";
604
		$gatewayipv6 = get_interface_gateway_v6("wan");
605
		@file_put_contents("{$g['tmp_path']}/{$defaultifv6}_defaultgwv6", $gatewayipv6);
606
	}
607
	$dont_add_route = false;
608
	/* if OLSRD is enabled, allow WAN to house DHCP. */
609
	if (is_array($config['installedpackages']['olsrd'])) {
610
		foreach ($config['installedpackages']['olsrd']['config'] as $olsrd) {
611
			if (($olsrd['enabledyngw'] == "on") && ($olsrd['enable'] == "on")) {
612
				$dont_add_route = true;
613
				log_error(gettext("Not adding default route because OLSR dynamic gateway is enabled."));
614
				break;
615
			}
616
		}
617
	}
618

    
619
	$gateways_arr = return_gateways_array(false, true);
620
	foreach ($gateways_arr as $gateway) {
621
		// setup static interface routes for nonlocal gateways
622
		if (isset($gateway["nonlocalgateway"])) {
623
			$srgatewayip = $gateway['gateway'];
624
			$srinterfacegw = $gateway['interface'];
625
			if (is_ipaddr($srgatewayip) && !empty($srinterfacegw)) {
626
				$inet = (!is_ipaddrv4($srgatewayip) ? "-inet6" : "-inet");
627
				$cmd = "/sbin/route change {$inet} " . escapeshellarg($srgatewayip) . " ";
628
				mwexec($cmd . "-iface " . escapeshellarg($srinterfacegw));
629
				if (isset($config['system']['route-debug'])) {
630
					$mt = microtime();
631
					log_error("ROUTING debug: $mt - $cmd -iface $srinterfacegw ");
632
				}
633
			}
634
		}
635
	}
636

    
637
	if ($dont_add_route == false) {
638
		if (!empty($interface) && $interface != $interfacegw) {
639
			;
640
		} else if (is_ipaddrv4($gatewayip)) {
641
			log_error(sprintf(gettext("ROUTING: setting default route to %s"), $gatewayip));
642
			mwexec("/sbin/route change -inet default " . escapeshellarg($gatewayip));
643
		}
644

    
645
		if (!empty($interface) && $interface != $interfacegwv6) {
646
			;
647
		} else if (is_ipaddrv6($gatewayipv6)) {
648
			$ifscope = "";
649
			if (is_linklocal($gatewayipv6) && !strpos($gatewayipv6, '%')) {
650
				$ifscope = "%{$defaultifv6}";
651
			}
652
			log_error(sprintf(gettext("ROUTING: setting IPv6 default route to %s"), $gatewayipv6 . $ifscope));
653
			mwexec("/sbin/route change -inet6 default " . escapeshellarg("{$gatewayipv6}{$ifscope}"));
654
		}
655
	}
656

    
657
	system_staticroutes_configure($interface, false);
658

    
659
	return 0;
660
}
661

    
662
function system_staticroutes_configure($interface = "", $update_dns = false) {
663
	global $config, $g, $aliastable;
664

    
665
	$filterdns_list = array();
666

    
667
	$static_routes = get_staticroutes(false, true);
668
	if (count($static_routes)) {
669
		$gateways_arr = return_gateways_array(false, true);
670

    
671
		foreach ($static_routes as $rtent) {
672
			if (empty($gateways_arr[$rtent['gateway']])) {
673
				log_error(sprintf(gettext("Static Routes: Gateway IP could not be found for %s"), $rtent['network']));
674
				continue;
675
			}
676
			$gateway = $gateways_arr[$rtent['gateway']];
677
			if (!empty($interface) && $interface != $gateway['friendlyiface']) {
678
				continue;
679
			}
680

    
681
			$gatewayip = $gateway['gateway'];
682
			$interfacegw = $gateway['interface'];
683

    
684
			$blackhole = "";
685
			if (!strcasecmp("Null", substr($rtent['gateway'], 0, 3))) {
686
				$blackhole = "-blackhole";
687
			}
688

    
689
			if (!is_fqdn($rtent['network']) && !is_subnet($rtent['network'])) {
690
				continue;
691
			}
692

    
693
			$dnscache = array();
694
			if ($update_dns === true) {
695
				if (is_subnet($rtent['network'])) {
696
					continue;
697
				}
698
				$dnscache = explode("\n", trim(compare_hostname_to_dnscache($rtent['network'])));
699
				if (empty($dnscache)) {
700
					continue;
701
				}
702
			}
703

    
704
			if (is_subnet($rtent['network'])) {
705
				$ips = array($rtent['network']);
706
			} else {
707
				if (!isset($rtent['disabled'])) {
708
					$filterdns_list[] = $rtent['network'];
709
				}
710
				$ips = add_hostname_to_watch($rtent['network']);
711
			}
712

    
713
			foreach ($dnscache as $ip) {
714
				if (in_array($ip, $ips)) {
715
					continue;
716
				}
717
				mwexec("/sbin/route delete " . escapeshellarg($ip), true);
718
				if (isset($config['system']['route-debug'])) {
719
					$mt = microtime();
720
					log_error("ROUTING debug: $mt - route delete $ip ");
721
				}
722
			}
723

    
724
			if (isset($rtent['disabled'])) {
725
				/* XXX: This can break things by deleting routes that shouldn't be deleted - OpenVPN, dynamic routing scenarios, etc. redmine #3709 */
726
				foreach ($ips as $ip) {
727
					mwexec("/sbin/route delete " . escapeshellarg($ip), true);
728
					if (isset($config['system']['route-debug'])) {
729
						$mt = microtime();
730
						log_error("ROUTING debug: $mt - route delete $ip ");
731
					}
732
				}
733
				continue;
734
			}
735

    
736
			foreach ($ips as $ip) {
737
				if (is_ipaddrv4($ip)) {
738
					$ip .= "/32";
739
				}
740
				// do NOT do the same check here on v6, is_ipaddrv6 returns true when including the CIDR mask. doing so breaks v6 routes
741

    
742
				$inet = (is_subnetv6($ip) ? "-inet6" : "-inet");
743

    
744
				$cmd = "/sbin/route change {$inet} {$blackhole} " . escapeshellarg($ip) . " ";
745

    
746
				if (is_subnet($ip)) {
747
					if (is_ipaddr($gatewayip)) {
748
						mwexec($cmd . escapeshellarg($gatewayip));
749
						if (isset($config['system']['route-debug'])) {
750
							$mt = microtime();
751
							log_error("ROUTING debug: $mt - $cmd $gatewayip");
752
						}
753
					} else if (!empty($interfacegw)) {
754
						mwexec($cmd . "-iface " . escapeshellarg($interfacegw));
755
						if (isset($config['system']['route-debug'])) {
756
							$mt = microtime();
757
							log_error("ROUTING debug: $mt - $cmd -iface $interfacegw ");
758
						}
759
					}
760
				}
761
			}
762
		}
763
		unset($gateways_arr);
764
	}
765
	unset($static_routes);
766

    
767
	if ($update_dns === false) {
768
		if (count($filterdns_list)) {
769
			$interval = 60;
770
			$hostnames = "";
771
			array_unique($filterdns_list);
772
			foreach ($filterdns_list as $hostname) {
773
				$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload routedns\"'\n";
774
			}
775
			file_put_contents("{$g['varetc_path']}/filterdns-route.hosts", $hostnames);
776
			unset($hostnames);
777

    
778
			if (isvalidpid("{$g['varrun_path']}/filterdns-route.pid")) {
779
				sigkillbypid("{$g['varrun_path']}/filterdns-route.pid", "HUP");
780
			} else {
781
				mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-route.pid -i {$interval} -c {$g['varetc_path']}/filterdns-route.hosts -d 1");
782
			}
783
		} else {
784
			killbypid("{$g['varrun_path']}/filterdns-route.pid");
785
			@unlink("{$g['varrun_path']}/filterdns-route.pid");
786
		}
787
	}
788
	unset($filterdns_list);
789

    
790
	return 0;
791
}
792

    
793
function system_routing_enable() {
794
	global $config, $g;
795
	if (isset($config['system']['developerspew'])) {
796
		$mt = microtime();
797
		echo "system_routing_enable() being called $mt\n";
798
	}
799

    
800
	set_sysctl(array(
801
		"net.inet.ip.forwarding" => "1",
802
		"net.inet6.ip6.forwarding" => "1"
803
	));
804

    
805
	return;
806
}
807

    
808
function system_syslogd_fixup_server($server) {
809
	/* If it's an IPv6 IP alone, encase it in brackets */
810
	if (is_ipaddrv6($server)) {
811
		return "[$server]";
812
	} else {
813
		return $server;
814
	}
815
}
816

    
817
function system_syslogd_get_remote_servers($syslogcfg, $facility = "*.*") {
818
	// Rather than repeatedly use the same code, use this function to build a list of remote servers.
819
	$facility .= " ".
820
	$remote_servers = "";
821
	$pad_to  = max(strlen($facility), 56);
822
	$padding = ceil(($pad_to - strlen($facility))/8)+1;
823
	if (isset($syslogcfg['enable'])) {
824
		if ($syslogcfg['remoteserver']) {
825
			$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver']) . "\n";
826
		}
827
		if ($syslogcfg['remoteserver2']) {
828
			$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver2']) . "\n";
829
		}
830
		if ($syslogcfg['remoteserver3']) {
831
			$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver3']) . "\n";
832
		}
833
	}
834
	return $remote_servers;
835
}
836

    
837
function clear_log_file($logfile = "/var/log/system.log", $restart_syslogd = true) {
838
	global $config, $g;
839
	if ($restart_syslogd) {
840
		exec("/usr/bin/killall syslogd");
841
	}
842
	if (isset($config['system']['disablesyslogclog'])) {
843
		unlink($logfile);
844
		touch($logfile);
845
	} else {
846
		$log_size = isset($config['syslog']['logfilesize']) ? $config['syslog']['logfilesize'] : "511488";
847
		$log_size = isset($config['syslog'][basename($logfile, '.log') . '_settings']['logfilesize']) ? $config['syslog'][basename($logfile, '.log') . '_settings']['logfilesize'] : $log_size;
848
		exec("/usr/local/sbin/clog -i -s {$log_size} " . escapeshellarg($logfile));
849
	}
850
	if ($restart_syslogd) {
851
		system_syslogd_start();
852
	}
853
}
854

    
855
function clear_all_log_files($restart = false) {
856
	global $g;
857
	exec("/usr/bin/killall syslogd");
858

    
859
	$log_files = array("system", "filter", "dhcpd", "vpn", "pptps", "poes", "l2tps", "openvpn", "portalauth", "ipsec", "ppp", "relayd", "wireless", "nginx", "ntpd", "gateways", "resolver", "routing");
860
	foreach ($log_files as $lfile) {
861
		clear_log_file("{$g['varlog_path']}/{$lfile}.log", false);
862
	}
863

    
864
	if ($restart) {
865
		system_syslogd_start();
866
		killbyname("dhcpd");
867
		services_dhcpd_configure();
868
	}
869
	return;
870
}
871

    
872
function system_syslogd_start() {
873
	global $config, $g;
874
	if (isset($config['system']['developerspew'])) {
875
		$mt = microtime();
876
		echo "system_syslogd_start() being called $mt\n";
877
	}
878

    
879
	mwexec("/etc/rc.d/hostid start");
880

    
881
	$syslogcfg = $config['syslog'];
882

    
883
	if (platform_booting()) {
884
		echo gettext("Starting syslog...");
885
	}
886

    
887
	// Which logging type are we using this week??
888
	if (isset($config['system']['disablesyslogclog'])) {
889
		$log_directive = "";
890
		$log_create_directive = "/usr/bin/touch ";
891
		$log_size = "";
892
	} else { // Defaults to CLOG
893
		$log_directive = "%";
894
		$log_size = isset($config['syslog']['logfilesize']) ? $config['syslog']['logfilesize'] : "10240";
895
		$log_create_directive = "/usr/local/sbin/clog -i -s ";
896
	}
897

    
898
	$syslogd_extra = "";
899
	if (isset($syslogcfg)) {
900
		$separatelogfacilities = array('ntp', 'ntpd', 'ntpdate', 'charon', 'ipsec_starter', 'openvpn', 'pptps', 'poes', 'l2tps', 'relayd', 'hostapd', 'dnsmasq', 'filterdns', 'unbound', 'dhcpd', 'dhcrelay', 'dhclient', 'dhcp6c', 'dpinger', 'radvd', 'routed', 'olsrd', 'zebra', 'ospfd', 'bgpd', 'miniupnpd', 'filterlog');
901
		$syslogconf = "";
902
		if ($config['installedpackages']['package']) {
903
			foreach ($config['installedpackages']['package'] as $package) {
904
				if ($package['logging']) {
905
					array_push($separatelogfacilities, $package['logging']['facilityname']);
906
					if (!is_file($g['varlog_path'].'/'.$package['logging']['logfilename'])) {
907
						mwexec("{$log_create_directive} {$log_size} {$g['varlog_path']}/{$package['logging']['logfilename']}");
908
					}
909
					$syslogconf .= "!{$package['logging']['facilityname']}\n*.*\t\t\t\t\t\t {$log_directive}{$g['varlog_path']}/{$package['logging']['logfilename']}\n";
910
				}
911
			}
912
		}
913
		$facilitylist = implode(',', array_unique($separatelogfacilities));
914
		$syslogconf .= "!radvd,routed,olsrd,zebra,ospfd,bgpd,miniupnpd\n";
915
		if (!isset($syslogcfg['disablelocallogging'])) {
916
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/routing.log\n";
917
		}
918

    
919
		$syslogconf .= "!ntp,ntpd,ntpdate\n";
920
		if (!isset($syslogcfg['disablelocallogging'])) {
921
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ntpd.log\n";
922
		}
923

    
924
		$syslogconf .= "!ppp\n";
925
		if (!isset($syslogcfg['disablelocallogging'])) {
926
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ppp.log\n";
927
		}
928

    
929
		$syslogconf .= "!pptps\n";
930
		if (!isset($syslogcfg['disablelocallogging'])) {
931
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/pptps.log\n";
932
		}
933

    
934
		$syslogconf .= "!poes\n";
935
		if (!isset($syslogcfg['disablelocallogging'])) {
936
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/poes.log\n";
937
		}
938

    
939
		$syslogconf .= "!l2tps\n";
940
		if (!isset($syslogcfg['disablelocallogging'])) {
941
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/l2tps.log\n";
942
		}
943

    
944
		$syslogconf .= "!charon,ipsec_starter\n";
945
		if (!isset($syslogcfg['disablelocallogging'])) {
946
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ipsec.log\n";
947
		}
948
		if (isset($syslogcfg['vpn'])) {
949
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
950
		}
951

    
952
		$syslogconf .= "!openvpn\n";
953
		if (!isset($syslogcfg['disablelocallogging'])) {
954
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/openvpn.log\n";
955
		}
956
		if (isset($syslogcfg['vpn'])) {
957
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
958
		}
959

    
960
		$syslogconf .= "!dpinger\n";
961
		if (!isset($syslogcfg['disablelocallogging'])) {
962
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/gateways.log\n";
963
		}
964
		if (isset($syslogcfg['dpinger'])) {
965
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
966
		}
967

    
968
		$syslogconf .= "!dnsmasq,filterdns,unbound\n";
969
		if (!isset($syslogcfg['disablelocallogging'])) {
970
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/resolver.log\n";
971
		}
972

    
973
		$syslogconf .= "!dhcpd,dhcrelay,dhclient,dhcp6c\n";
974
		if (!isset($syslogcfg['disablelocallogging'])) {
975
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/dhcpd.log\n";
976
		}
977
		if (isset($syslogcfg['dhcp'])) {
978
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
979
		}
980

    
981
		$syslogconf .= "!relayd\n";
982
		if (!isset($syslogcfg['disablelocallogging'])) {
983
			$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/relayd.log\n";
984
		}
985
		if (isset($syslogcfg['relayd'])) {
986
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
987
		}
988

    
989
		$syslogconf .= "!hostapd\n";
990
		if (!isset($syslogcfg['disablelocallogging'])) {
991
			$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/wireless.log\n";
992
		}
993
		if (isset($syslogcfg['hostapd'])) {
994
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
995
		}
996

    
997
		$syslogconf .= "!filterlog\n";
998
		$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/filter.log\n";
999
		if (isset($syslogcfg['filter'])) {
1000
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
1001
		}
1002

    
1003
		$syslogconf .= "!-{$facilitylist}\n";
1004
		if (!isset($syslogcfg['disablelocallogging'])) {
1005
			$syslogconf .= <<<EOD
1006
local3.*							{$log_directive}{$g['varlog_path']}/vpn.log
1007
local4.*							{$log_directive}{$g['varlog_path']}/portalauth.log
1008
local5.*							{$log_directive}{$g['varlog_path']}/nginx.log
1009
local7.*							{$log_directive}{$g['varlog_path']}/dhcpd.log
1010
*.notice;kern.debug;lpr.info;mail.crit;daemon.none;news.err;local0.none;local3.none;local4.none;local7.none;security.*;auth.info;authpriv.info;daemon.info	{$log_directive}{$g['varlog_path']}/system.log
1011
auth.info;authpriv.info 					|exec /usr/local/sbin/sshlockout_pf 15
1012
*.emerg								*
1013

    
1014
EOD;
1015
		}
1016
		if (isset($syslogcfg['vpn'])) {
1017
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local3.*");
1018
		}
1019
		if (isset($syslogcfg['portalauth'])) {
1020
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local4.*");
1021
		}
1022
		if (isset($syslogcfg['dhcp'])) {
1023
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local7.*");
1024
		}
1025
		if (isset($syslogcfg['system'])) {
1026
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.emerg;*.notice;kern.debug;lpr.info;mail.crit;news.err;local0.none;local3.none;local7.none;security.*;auth.info;authpriv.info;daemon.info");
1027
		}
1028
		if (isset($syslogcfg['logall'])) {
1029
			// Make everything mean everything, including facilities excluded above.
1030
			$syslogconf .= "!*\n";
1031
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
1032
		}
1033

    
1034
		if (isset($syslogcfg['zmqserver'])) {
1035
				$syslogconf .= <<<EOD
1036
*.*								^{$syslogcfg['zmqserver']}
1037

    
1038
EOD;
1039
		}
1040
		/* write syslog.conf */
1041
		if (!@file_put_contents("{$g['varetc_path']}/syslog.conf", $syslogconf)) {
1042
			printf(gettext("Error: cannot open syslog.conf in system_syslogd_start().%s"), "\n");
1043
			unset($syslogconf);
1044
			return 1;
1045
		}
1046
		unset($syslogconf);
1047

    
1048
		// Ensure that the log directory exists
1049
		if (!is_dir("{$g['dhcpd_chroot_path']}/var/run")) {
1050
			exec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/run");
1051
		}
1052

    
1053
		$sourceip = "";
1054
		if (!empty($syslogcfg['sourceip'])) {
1055
			if ($syslogcfg['ipproto'] == "ipv6") {
1056
				$ifaddr = is_ipaddr($syslogcfg['sourceip']) ? $syslogcfg['sourceip'] : get_interface_ipv6($syslogcfg['sourceip']);
1057
				if (!is_ipaddr($ifaddr)) {
1058
					$ifaddr = get_interface_ip($syslogcfg['sourceip']);
1059
				}
1060
			} else {
1061
				$ifaddr = is_ipaddr($syslogcfg['sourceip']) ? $syslogcfg['sourceip'] : get_interface_ip($syslogcfg['sourceip']);
1062
				if (!is_ipaddr($ifaddr)) {
1063
					$ifaddr = get_interface_ipv6($syslogcfg['sourceip']);
1064
				}
1065
			}
1066
			if (is_ipaddr($ifaddr)) {
1067
				$sourceip = "-b {$ifaddr}";
1068
			}
1069
		}
1070

    
1071
		$syslogd_extra = "-f {$g['varetc_path']}/syslog.conf {$sourceip}";
1072
	}
1073

    
1074
	if (isvalidpid("{$g['varrun_path']}/syslog.pid")) {
1075
		sigkillbypid("{$g['varrun_path']}/syslog.pid", "TERM");
1076
		usleep(100000); // syslogd often doesn't respond to a TERM quickly enough for the starting of syslogd below to be successful
1077
	}
1078

    
1079
	if (isvalidpid("{$g['varrun_path']}/syslog.pid")) {
1080
		// if it still hasn't responded to the TERM, KILL it.
1081
		sigkillbypid("{$g['varrun_path']}/syslog.pid", "KILL");
1082
		usleep(100000);
1083
	}
1084

    
1085

    
1086
	$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}");
1087

    
1088
	if (platform_booting()) {
1089
		echo gettext("done.") . "\n";
1090
	}
1091

    
1092
	return $retval;
1093
}
1094

    
1095
function system_webgui_create_certificate() {
1096
	global $config, $g;
1097

    
1098
	if (!is_array($config['ca'])) {
1099
		$config['ca'] = array();
1100
	}
1101
	$a_ca =& $config['ca'];
1102
	if (!is_array($config['cert'])) {
1103
		$config['cert'] = array();
1104
	}
1105
	$a_cert =& $config['cert'];
1106
	log_error(gettext("Creating SSL Certificate for this host"));
1107

    
1108
	$cert = array();
1109
	$cert['refid'] = uniqid();
1110
	$cert['descr'] = sprintf(gettext("webConfigurator default (%s)"), $cert['refid']);
1111

    
1112
	$dn = array(
1113
		'countryName' => "US",
1114
		'stateOrProvinceName' => "State",
1115
		'localityName' => "Locality",
1116
		'organizationName' => "{$g['product_name']} webConfigurator Self-Signed Certificate",
1117
		'emailAddress' => "admin@{$config['system']['hostname']}.{$config['system']['domain']}",
1118
		'commonName' => "{$config['system']['hostname']}-{$cert['refid']}");
1119
	$old_err_level = error_reporting(0); /* otherwise openssl_ functions throw warnings directly to a page screwing menu tab */
1120
	if (!cert_create($cert, null, 2048, 2000, $dn, "self-signed", "sha256")) {
1121
		while ($ssl_err = openssl_error_string()) {
1122
			log_error(sprintf(gettext("Error creating WebGUI Certificate: openssl library returns: %s"), $ssl_err));
1123
		}
1124
		error_reporting($old_err_level);
1125
		return null;
1126
	}
1127
	error_reporting($old_err_level);
1128

    
1129
	$a_cert[] = $cert;
1130
	$config['system']['webgui']['ssl-certref'] = $cert['refid'];
1131
	write_config(sprintf(gettext("Generated new self-signed HTTPS certificate (%s)"), $cert['refid']));
1132
	return $cert;
1133
}
1134

    
1135
function system_webgui_start() {
1136
	global $config, $g;
1137

    
1138
	if (platform_booting()) {
1139
		echo gettext("Starting webConfigurator...");
1140
	}
1141

    
1142
	chdir($g['www_path']);
1143

    
1144
	/* defaults */
1145
	$portarg = "80";
1146
	$crt = "";
1147
	$key = "";
1148
	$ca = "";
1149

    
1150
	/* non-standard port? */
1151
	if (isset($config['system']['webgui']['port']) && $config['system']['webgui']['port'] <> "") {
1152
		$portarg = "{$config['system']['webgui']['port']}";
1153
	}
1154

    
1155
	if ($config['system']['webgui']['protocol'] == "https") {
1156
		// Ensure that we have a webConfigurator CERT
1157
		$cert =& lookup_cert($config['system']['webgui']['ssl-certref']);
1158
		if (!is_array($cert) || !$cert['crt'] || !$cert['prv']) {
1159
			$cert = system_webgui_create_certificate();
1160
		}
1161
		$crt = base64_decode($cert['crt']);
1162
		$key = base64_decode($cert['prv']);
1163

    
1164
		if (!$config['system']['webgui']['port']) {
1165
			$portarg = "443";
1166
		}
1167
		$ca = ca_chain($cert);
1168
	}
1169

    
1170
	/* generate nginx configuration */
1171
	system_generate_nginx_config("{$g['varetc_path']}/nginx-webConfigurator.conf",
1172
		$crt, $key, $ca, "nginx-webConfigurator.pid", $portarg, "/usr/local/www/",
1173
		"cert.crt", "cert.key");
1174

    
1175
	/* kill any running nginx */
1176
	killbypid("{$g['varrun_path']}/nginx-webConfigurator.pid");
1177

    
1178
	sleep(1);
1179

    
1180
	@unlink("{$g['varrun_path']}/nginx-webConfigurator.pid");
1181

    
1182
	/* start nginx */
1183
	$res = mwexec("/usr/local/sbin/nginx -c {$g['varetc_path']}/nginx-webConfigurator.conf");
1184

    
1185
	if (platform_booting()) {
1186
		if ($res == 0) {
1187
			echo gettext("done.") . "\n";
1188
		} else {
1189
			echo gettext("failed!") . "\n";
1190
		}
1191
	}
1192

    
1193
	return $res;
1194
}
1195

    
1196
function system_generate_nginx_config($filename,
1197
	$cert,
1198
	$key,
1199
	$ca,
1200
	$pid_file,
1201
	$port = 80,
1202
	$document_root = "/usr/local/www/",
1203
	$cert_location = "cert.crt",
1204
	$key_location = "cert.key",
1205
	$captive_portal = false) {
1206

    
1207
	global $config, $g;
1208

    
1209
	if (isset($config['system']['developerspew'])) {
1210
		$mt = microtime();
1211
		echo "system_generate_nginx_config() being called $mt\n";
1212
	}
1213

    
1214
	if ($captive_portal !== false) {
1215
		$cp_interfaces = explode(",", $config['captiveportal'][$captive_portal]['interface']);
1216
		$cp_hostcheck = "";
1217
		foreach ($cp_interfaces as $cpint) {
1218
			$cpint_ip = get_interface_ip($cpint);
1219
			if (is_ipaddr($cpint_ip)) {
1220
				$cp_hostcheck .= "\t\tif (\$http_host ~* $cpint_ip) {\n";
1221
				$cp_hostcheck .= "\t\t\tset \$cp_redirect no;\n";
1222
				$cp_hostcheck .= "\t\t}\n";
1223
			}
1224
		}
1225
		if (isset($config['captiveportal'][$captive_portal]['httpsname']) &&
1226
		    is_domain($config['captiveportal'][$captive_portal]['httpsname'])) {
1227
			$cp_hostcheck .= "\t\tif (\$http_host ~* {$config['captiveportal'][$captive_portal]['httpsname']}) {\n";
1228
			$cp_hostcheck .= "\t\t\tset \$cp_redirect no;\n";
1229
			$cp_hostcheck .= "\t\t}\n";
1230
		}
1231
		$cp_rewrite = "\t\tif (\$cp_redirect = '') {\n";
1232
		$cp_rewrite .= "\t\t\trewrite	^ /index.php?zone=$captive_portal&redirurl=\$request_uri break;\n";
1233
		$cp_rewrite .= "\t\t}\n";
1234

    
1235
		$maxprocperip = $config['captiveportal'][$captive_portal]['maxprocperip'];
1236
		if (empty($maxprocperip)) {
1237
			$maxprocperip = 10;
1238
		}
1239
		$captive_portal_maxprocperip = "\t\tlimit_conn addr $maxprocperip;\n";
1240

    
1241
	}
1242

    
1243
	if (empty($port)) {
1244
		$nginx_port = "80";
1245
	} else {
1246
		$nginx_port = $port;
1247
	}
1248

    
1249
	$memory = get_memory();
1250
	$realmem = $memory[1];
1251

    
1252
	// Determine web GUI process settings and take into account low memory systems
1253
	if ($realmem < 255) {
1254
		$max_procs = 1;
1255
	} else {
1256
		$max_procs = ($config['system']['webgui']['max_procs']) ? $config['system']['webgui']['max_procs'] : 2;
1257
	}
1258

    
1259
	// Ramp up captive portal max procs, assuming each PHP process can consume up to 64MB RAM
1260
	if ($captive_portal !== false) {
1261
		if ($realmem > 135 and $realmem < 256) {
1262
			$max_procs += 1; // 2 worker processes
1263
		} else if ($realmem > 255 and $realmem < 513) {
1264
			$max_procs += 2; // 3 worker processes
1265
		} else if ($realmem > 512) {
1266
			$max_procs += 4; // 6 worker processes
1267
		}
1268
	}
1269

    
1270
	$nginx_config = <<<EOD
1271
#
1272
# nginx configuration file
1273

    
1274
pid {$g['varrun_path']}/{$pid_file};
1275

    
1276
user  root wheel;
1277
worker_processes  {$max_procs};
1278

    
1279
EOD;
1280

    
1281
if (!isset($config['syslog']['nolognginx'])) {
1282
	$nginx_config .= "error_log  syslog:server=unix:/var/run/log,facility=local5;\n";
1283
}
1284

    
1285
$nginx_config .= <<<EOD
1286

    
1287
events {
1288
    worker_connections  1024;
1289
}
1290

    
1291
http {
1292
	include       /usr/local/etc/nginx/mime.types;
1293
	default_type  application/octet-stream;
1294
	add_header X-Frame-Options SAMEORIGIN;
1295
	server_tokens off;
1296

    
1297
	sendfile        on;
1298
	keepalive_timeout  65;
1299

    
1300
	access_log      syslog:server=unix:/var/run/log,facility=local5 combined;
1301

    
1302
EOD;
1303

    
1304
if ($captive_portal !== false) {
1305
	$nginx_config .= "\tlimit_conn_zone \$binary_remote_addr zone=addr:10m;\n";
1306
}
1307

    
1308
$nginx_config .= <<<EOD
1309

    
1310
	server {
1311
		listen {$nginx_port};
1312
		listen [::]:{$nginx_port};
1313
		client_max_body_size 200m;
1314

    
1315
		gzip on;
1316
		gzip_types text/html text/plain text/css text/javascript;
1317

    
1318
EOD;
1319

    
1320
	if ($cert <> "" and $key <> "") {
1321
		$nginx_config .= "\t\tssl             on;\n";
1322
		$nginx_config .= "\t\tssl_certificate         {$g['varetc_path']}/{$cert_location};\n";
1323
		$nginx_config .= "\t\tssl_certificate_key     {$g['varetc_path']}/{$key_location};\n";
1324
		$nginx_config .= "\t\tssl_session_timeout     10m;\n";
1325
		$nginx_config .= "\t\tkeepalive_timeout       70;\n";
1326
		$nginx_config .= "\t\tssl_session_cache       shared:SSL:10m;\n";
1327
		$nginx_config .= "\t\tssl_protocols   TLSv1 TLSv1.1 TLSv1.2;\n";
1328
		$nginx_config .= "\t\tssl_ciphers \"EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH\";\n";
1329
		$nginx_config .= "\t\tssl_prefer_server_ciphers       on;\n";
1330
		$nginx_config .= "\t\tadd_header Strict-Transport-Security \"max-age=31536000\";\n";
1331
		$nginx_config .= "\t\tadd_header X-Content-Type-Options nosniff;\n";
1332
		$nginx_config .= "\t\tssl_session_tickets off;\n";
1333
		$nginx_config .= "\t\tssl_stapling on;\n";
1334
		$nginx_config .= "\t\tssl_stapling_verify on;\n";
1335
		$nginx_config .= "\t\tssl_dhparam /etc/dh-parameters.4096;\n";
1336
		$nginx_config .= "\n";
1337
	}
1338

    
1339
	if ($captive_portal !== false) {
1340
		$nginx_config .= <<<EOD
1341
$captive_portal_maxprocperip
1342
$cp_hostcheck
1343
$cp_rewrite
1344

    
1345
EOD;
1346

    
1347
	}
1348

    
1349
	$nginx_config .= <<<EOD
1350
		root "{$document_root}";
1351
		location / {
1352
			index  index.html index.htm index.php;
1353
		}
1354

    
1355
		location ~ \.php$ {
1356
			try_files \$uri =404; #  This line closes a potential security hole
1357
			# ensuring users can't execute uploaded files
1358
			# see: http://forum.nginx.org/read.php?2,88845,page=3
1359
			fastcgi_pass   unix:{$g['varrun_path']}/php-fpm.socket;
1360
			fastcgi_index  index.php;
1361
			fastcgi_param  SCRIPT_FILENAME  \$document_root\$fastcgi_script_name;
1362
			fastcgi_read_timeout 180;
1363
			include        /usr/local/etc/nginx/fastcgi_params;
1364
		}
1365
	}
1366

    
1367
EOD;
1368

    
1369
	$cert = str_replace("\r", "", $cert);
1370
	$key = str_replace("\r", "", $key);
1371

    
1372
	$cert = str_replace("\n\n", "\n", $cert);
1373
	$key = str_replace("\n\n", "\n", $key);
1374

    
1375
	if ($cert <> "" and $key <> "") {
1376
		$fd = fopen("{$g['varetc_path']}/{$cert_location}", "w");
1377
		if (!$fd) {
1378
			printf(gettext("Error: cannot open certificate file in system_webgui_start().%s"), "\n");
1379
			return 1;
1380
		}
1381
		chmod("{$g['varetc_path']}/{$cert_location}", 0600);
1382
		if ($ca <> "") {
1383
			$cert_chain = $cert . "\n" . $ca;
1384
		} else {
1385
			$cert_chain = $cert;
1386
		}
1387
		fwrite($fd, $cert_chain);
1388
		fclose($fd);
1389
		$fd = fopen("{$g['varetc_path']}/{$key_location}", "w");
1390
		if (!$fd) {
1391
			printf(gettext("Error: cannot open certificate key file in system_webgui_start().%s"), "\n");
1392
			return 1;
1393
		}
1394
		chmod("{$g['varetc_path']}/{$key_location}", 0600);
1395
		fwrite($fd, $key);
1396
		fclose($fd);
1397
	}
1398

    
1399
	// Add HTTP to HTTPS redirect
1400
	if ($captive_portal === false && $config['system']['webgui']['protocol'] == "https" && !isset($config['system']['webgui']['disablehttpredirect'])) {
1401
		if ($nginx_port != "443") {
1402
			$redirectport = ":{$nginx_port}";
1403
		}
1404
		$nginx_config .= <<<EOD
1405
	server {
1406
		listen 80;
1407
		listen [::]:80;
1408
		rewrite         ^ https://\$http_host$redirectport\$request_uri? permanent;
1409
	}
1410

    
1411
EOD;
1412
	}
1413

    
1414
	$nginx_config .= "}\n";
1415

    
1416
	$fd = fopen("{$filename}", "w");
1417
	if (!$fd) {
1418
		printf(gettext("Error: cannot open %s in system_generate_nginx_config().%s"), $filename, "\n");
1419
		return 1;
1420
	}
1421
	fwrite($fd, $nginx_config);
1422
	fclose($fd);
1423

    
1424
	/* nginx will fail to start if this directory does not exist. */
1425
	safe_mkdir("/var/tmp/nginx/");
1426

    
1427
	return 0;
1428

    
1429
}
1430

    
1431
function system_get_timezone_list() {
1432
	global $g;
1433

    
1434
	$file_list = array_merge(
1435
		glob("/usr/share/zoneinfo/[A-Z]*"),
1436
		glob("/usr/share/zoneinfo/*/*"),
1437
		glob("/usr/share/zoneinfo/*/*/*")
1438
	);
1439

    
1440
	if (empty($file_list)) {
1441
		$file_list[] = $g['default_timezone'];
1442
	} else {
1443
		/* Remove directories from list */
1444
		$file_list = array_filter($file_list, function($v) {
1445
			return !is_dir($v);
1446
		});
1447
	}
1448

    
1449
	/* Remove directory prefix */
1450
	$file_list = str_replace('/usr/share/zoneinfo/', '', $file_list);
1451

    
1452
	sort($file_list);
1453

    
1454
	return $file_list;
1455
}
1456

    
1457
function system_timezone_configure() {
1458
	global $config, $g;
1459
	if (isset($config['system']['developerspew'])) {
1460
		$mt = microtime();
1461
		echo "system_timezone_configure() being called $mt\n";
1462
	}
1463

    
1464
	$syscfg = $config['system'];
1465

    
1466
	if (platform_booting()) {
1467
		echo gettext("Setting timezone...");
1468
	}
1469

    
1470
	/* extract appropriate timezone file */
1471
	$timezone = (isset($syscfg['timezone']) ? $syscfg['timezone'] : $g['default_timezone']);
1472
	conf_mount_rw();
1473
	/* DO NOT remove \n otherwise tzsetup will fail */
1474
	@file_put_contents("/var/db/zoneinfo", $timezone . "\n");
1475
	mwexec("/usr/sbin/tzsetup -r");
1476
	conf_mount_ro();
1477

    
1478
	if (platform_booting()) {
1479
		echo gettext("done.") . "\n";
1480
	}
1481
}
1482

    
1483
function system_ntp_setup_gps($serialport) {
1484
	global $config, $g;
1485
	$gps_device = '/dev/gps0';
1486
	$serialport = '/dev/'.$serialport;
1487

    
1488
	if (!file_exists($serialport)) {
1489
		return false;
1490
	}
1491

    
1492
	conf_mount_rw();
1493
	// Create symlink that ntpd requires
1494
	unlink_if_exists($gps_device);
1495
	@symlink($serialport, $gps_device);
1496

    
1497
	$gpsbaud = '4800';
1498
	if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['speed'])) {
1499
		switch ($config['ntpd']['gps']['speed']) {
1500
			case '16':
1501
				$gpsbaud = '9600';
1502
				break;
1503
			case '32':
1504
				$gpsbaud = '19200';
1505
				break;
1506
			case '48':
1507
				$gpsbaud = '38400';
1508
				break;
1509
			case '64':
1510
				$gpsbaud = '57600';
1511
				break;
1512
			case '80':
1513
				$gpsbaud = '115200';
1514
				break;
1515
		}
1516
	}
1517

    
1518
	/* Configure the serial port for raw IO and set the speed */
1519
	mwexec("stty -f {$serialport}.init raw speed {$gpsbaud}");
1520

    
1521
	/* Send the following to the GPS port to initialize the GPS */
1522
	if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['type'])) {
1523
		$gps_init = base64_decode($config['ntpd']['gps']['initcmd']);
1524
	} else {
1525
		$gps_init = base64_decode('JFBVQlgsNDAsR1NWLDAsMCwwLDAqNTkNCiRQVUJYLDQwLEdMTCwwLDAsMCwwKjVDDQokUFVCWCw0MCxaREEsMCwwLDAsMCo0NA0KJFBVQlgsNDAsVlRHLDAsMCwwLDAqNUUNCiRQVUJYLDQwLEdTViwwLDAsMCwwKjU5DQokUFVCWCw0MCxHU0EsMCwwLDAsMCo0RQ0KJFBVQlgsNDAsR0dBLDAsMCwwLDANCiRQVUJYLDQwLFRYVCwwLDAsMCwwDQokUFVCWCw0MCxSTUMsMCwwLDAsMCo0Ng0KJFBVQlgsNDEsMSwwMDA3LDAwMDMsNDgwMCwwDQokUFVCWCw0MCxaREEsMSwxLDEsMQ==');
1526
	}
1527

    
1528
	/* XXX: Why not file_put_contents to the device */
1529
	@file_put_contents('/tmp/gps.init', $gps_init);
1530
	mwexec("cat /tmp/gps.init > {$serialport}");
1531

    
1532
	/* Add /etc/remote entry in case we need to read from the GPS with tip */
1533
	if (intval(`grep -c '^gps0' /etc/remote`) == 0) {
1534
		@file_put_contents("/etc/remote", "gps0:dv={$serialport}:br#{$gpsbaud}:pa=none:", FILE_APPEND);
1535
	}
1536

    
1537
	conf_mount_ro();
1538

    
1539
	return true;
1540
}
1541

    
1542
function system_ntp_setup_pps($serialport) {
1543
	global $config, $g;
1544

    
1545
	$pps_device = '/dev/pps0';
1546
	$serialport = '/dev/'.$serialport;
1547

    
1548
	if (!file_exists($serialport)) {
1549
		return false;
1550
	}
1551

    
1552
	conf_mount_rw();
1553
	// Create symlink that ntpd requires
1554
	unlink_if_exists($pps_device);
1555
	@symlink($serialport, $pps_device);
1556

    
1557
	conf_mount_ro();
1558

    
1559
	return true;
1560
}
1561

    
1562

    
1563
function system_ntp_configure($start_ntpd=true) {
1564
	global $config, $g;
1565

    
1566
	$driftfile = "/var/db/ntpd.drift";
1567
	$statsdir = "/var/log/ntp";
1568
	$gps_device = '/dev/gps0';
1569

    
1570
	safe_mkdir($statsdir);
1571

    
1572
	if (!is_array($config['ntpd'])) {
1573
		$config['ntpd'] = array();
1574
	}
1575

    
1576
	$ntpcfg = "# \n";
1577
	$ntpcfg .= "# pfSense ntp configuration file \n";
1578
	$ntpcfg .= "# \n\n";
1579
	$ntpcfg .= "tinker panic 0 \n";
1580

    
1581
	/* Add Orphan mode */
1582
	$ntpcfg .= "# Orphan mode stratum\n";
1583
	$ntpcfg .= 'tos orphan ';
1584
	if (!empty($config['ntpd']['orphan'])) {
1585
		$ntpcfg .= $config['ntpd']['orphan'];
1586
	} else {
1587
		$ntpcfg .= '12';
1588
	}
1589
	$ntpcfg .= "\n";
1590

    
1591
	/* Add PPS configuration */
1592
	if (is_array($config['ntpd']['pps']) && !empty($config['ntpd']['pps']['port']) &&
1593
	    file_exists('/dev/'.$config['ntpd']['pps']['port']) &&
1594
	    system_ntp_setup_pps($config['ntpd']['pps']['port'])) {
1595
		$ntpcfg .= "\n";
1596
		$ntpcfg .= "# PPS Setup\n";
1597
		$ntpcfg .= 'server 127.127.22.0';
1598
		$ntpcfg .= ' minpoll 4 maxpoll 4';
1599
		if (empty($config['ntpd']['pps']['prefer'])) { /*note: this one works backwards */
1600
			$ntpcfg .= ' prefer';
1601
		}
1602
		if (!empty($config['ntpd']['pps']['noselect'])) {
1603
			$ntpcfg .= ' noselect ';
1604
		}
1605
		$ntpcfg .= "\n";
1606
		$ntpcfg .= 'fudge 127.127.22.0';
1607
		if (!empty($config['ntpd']['pps']['fudge1'])) {
1608
			$ntpcfg .= ' time1 ';
1609
			$ntpcfg .= $config['ntpd']['pps']['fudge1'];
1610
		}
1611
		if (!empty($config['ntpd']['pps']['flag2'])) {
1612
			$ntpcfg .= ' flag2 1';
1613
		}
1614
		if (!empty($config['ntpd']['pps']['flag3'])) {
1615
			$ntpcfg .= ' flag3 1';
1616
		} else {
1617
			$ntpcfg .= ' flag3 0';
1618
		}
1619
		if (!empty($config['ntpd']['pps']['flag4'])) {
1620
			$ntpcfg .= ' flag4 1';
1621
		}
1622
		if (!empty($config['ntpd']['pps']['refid'])) {
1623
			$ntpcfg .= ' refid ';
1624
			$ntpcfg .= $config['ntpd']['pps']['refid'];
1625
		}
1626
		$ntpcfg .= "\n";
1627
	}
1628
	/* End PPS configuration */
1629

    
1630
	/* Add GPS configuration */
1631
	if (is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['port']) &&
1632
	    file_exists('/dev/'.$config['ntpd']['gps']['port']) &&
1633
	    system_ntp_setup_gps($config['ntpd']['gps']['port'])) {
1634
		$ntpcfg .= "\n";
1635
		$ntpcfg .= "# GPS Setup\n";
1636
		$ntpcfg .= 'server 127.127.20.0 mode ';
1637
		if (!empty($config['ntpd']['gps']['nmea']) || !empty($config['ntpd']['gps']['speed']) || !empty($config['ntpd']['gps']['subsec'])) {
1638
			if (!empty($config['ntpd']['gps']['nmea'])) {
1639
				$ntpmode = (int) $config['ntpd']['gps']['nmea'];
1640
			}
1641
			if (!empty($config['ntpd']['gps']['speed'])) {
1642
				$ntpmode += (int) $config['ntpd']['gps']['speed'];
1643
			}
1644
			if (!empty($config['ntpd']['gps']['subsec'])) {
1645
				$ntpmode += 128;
1646
			}
1647
			$ntpcfg .= (string) $ntpmode;
1648
		} else {
1649
			$ntpcfg .= '0';
1650
		}
1651
		$ntpcfg .= ' minpoll 4 maxpoll 4';
1652
		if (empty($config['ntpd']['gps']['prefer'])) { /*note: this one works backwards */
1653
			$ntpcfg .= ' prefer';
1654
		}
1655
		if (!empty($config['ntpd']['gps']['noselect'])) {
1656
			$ntpcfg .= ' noselect ';
1657
		}
1658
		$ntpcfg .= "\n";
1659
		$ntpcfg .= 'fudge 127.127.20.0';
1660
		if (!empty($config['ntpd']['gps']['fudge1'])) {
1661
			$ntpcfg .= ' time1 ';
1662
			$ntpcfg .= $config['ntpd']['gps']['fudge1'];
1663
		}
1664
		if (!empty($config['ntpd']['gps']['fudge2'])) {
1665
			$ntpcfg .= ' time2 ';
1666
			$ntpcfg .= $config['ntpd']['gps']['fudge2'];
1667
		}
1668
		if (!empty($config['ntpd']['gps']['flag1'])) {
1669
			$ntpcfg .= ' flag1 1';
1670
		} else {
1671
			$ntpcfg .= ' flag1 0';
1672
		}
1673
		if (!empty($config['ntpd']['gps']['flag2'])) {
1674
			$ntpcfg .= ' flag2 1';
1675
		}
1676
		if (!empty($config['ntpd']['gps']['flag3'])) {
1677
			$ntpcfg .= ' flag3 1';
1678
		} else {
1679
			$ntpcfg .= ' flag3 0';
1680
		}
1681
		if (!empty($config['ntpd']['gps']['flag4'])) {
1682
			$ntpcfg .= ' flag4 1';
1683
		}
1684
		if (!empty($config['ntpd']['gps']['refid'])) {
1685
			$ntpcfg .= ' refid ';
1686
			$ntpcfg .= $config['ntpd']['gps']['refid'];
1687
		}
1688
		if (!empty($config['ntpd']['gps']['stratum'])) {
1689
			$ntpcfg .= ' stratum ';
1690
			$ntpcfg .= $config['ntpd']['gps']['stratum'];
1691
		}
1692
		$ntpcfg .= "\n";
1693
	} elseif (is_array($config['ntpd']) && !empty($config['ntpd']['gpsport']) &&
1694
	    file_exists('/dev/'.$config['ntpd']['gpsport']) &&
1695
	    system_ntp_setup_gps($config['ntpd']['gpsport'])) {
1696
		/* This handles a 2.1 and earlier config */
1697
		$ntpcfg .= "# GPS Setup\n";
1698
		$ntpcfg .= "server 127.127.20.0 mode 0 minpoll 4 maxpoll 4 prefer\n";
1699
		$ntpcfg .= "fudge 127.127.20.0 time1 0.155 time2 0.000 flag1 1 flag2 0 flag3 1\n";
1700
		// Fall back to local clock if GPS is out of sync?
1701
		$ntpcfg .= "server 127.127.1.0\n";
1702
		$ntpcfg .= "fudge 127.127.1.0 stratum 12\n";
1703
	}
1704
	/* End GPS configuration */
1705

    
1706
	$ntpcfg .= "\n\n# Upstream Servers\n";
1707
	/* foreach through ntp servers and write out to ntpd.conf */
1708
	foreach (explode(' ', $config['system']['timeservers']) as $ts) {
1709
		$ntpcfg .= "server {$ts} iburst maxpoll 9";
1710
		if (substr_count($config['ntpd']['prefer'], $ts)) {
1711
			$ntpcfg .= ' prefer';
1712
		}
1713
		if (substr_count($config['ntpd']['noselect'], $ts)) {
1714
			$ntpcfg .= ' noselect';
1715
		}
1716
		$ntpcfg .= "\n";
1717
	}
1718
	unset($ts);
1719

    
1720
	$ntpcfg .= "\n\n";
1721
	$ntpcfg .= "disable monitor\n"; //prevent NTP reflection attack, see https://forum.pfsense.org/index.php/topic,67189.msg389132.html#msg389132
1722
	if (!empty($config['ntpd']['clockstats']) || !empty($config['ntpd']['loopstats']) || !empty($config['ntpd']['peerstats'])) {
1723
		$ntpcfg .= "enable stats\n";
1724
		$ntpcfg .= 'statistics';
1725
		if (!empty($config['ntpd']['clockstats'])) {
1726
			$ntpcfg .= ' clockstats';
1727
		}
1728
		if (!empty($config['ntpd']['loopstats'])) {
1729
			$ntpcfg .= ' loopstats';
1730
		}
1731
		if (!empty($config['ntpd']['peerstats'])) {
1732
			$ntpcfg .= ' peerstats';
1733
		}
1734
		$ntpcfg .= "\n";
1735
	}
1736
	$ntpcfg .= "statsdir {$statsdir}\n";
1737
	$ntpcfg .= 'logconfig =syncall +clockall';
1738
	if (!empty($config['ntpd']['logpeer'])) {
1739
		$ntpcfg .= ' +peerall';
1740
	}
1741
	if (!empty($config['ntpd']['logsys'])) {
1742
		$ntpcfg .= ' +sysall';
1743
	}
1744
	$ntpcfg .= "\n";
1745
	$ntpcfg .= "driftfile {$driftfile}\n";
1746
	/* Access restrictions */
1747
	$ntpcfg .= 'restrict default';
1748
	if (empty($config['ntpd']['kod'])) { /*note: this one works backwards */
1749
		$ntpcfg .= ' kod limited';
1750
	}
1751
	if (empty($config['ntpd']['nomodify'])) { /*note: this one works backwards */
1752
		$ntpcfg .= ' nomodify';
1753
	}
1754
	if (!empty($config['ntpd']['noquery'])) {
1755
		$ntpcfg .= ' noquery';
1756
	}
1757
	if (empty($config['ntpd']['nopeer'])) { /*note: this one works backwards */
1758
		$ntpcfg .= ' nopeer';
1759
	}
1760
	if (empty($config['ntpd']['notrap'])) { /*note: this one works backwards */
1761
		$ntpcfg .= ' notrap';
1762
	}
1763
	if (!empty($config['ntpd']['noserve'])) {
1764
		$ntpcfg .= ' noserve';
1765
	}
1766
	$ntpcfg .= "\nrestrict -6 default";
1767
	if (empty($config['ntpd']['kod'])) { /*note: this one works backwards */
1768
		$ntpcfg .= ' kod limited';
1769
	}
1770
	if (empty($config['ntpd']['nomodify'])) { /*note: this one works backwards */
1771
		$ntpcfg .= ' nomodify';
1772
	}
1773
	if (!empty($config['ntpd']['noquery'])) {
1774
		$ntpcfg .= ' noquery';
1775
	}
1776
	if (empty($config['ntpd']['nopeer'])) { /*note: this one works backwards */
1777
		$ntpcfg .= ' nopeer';
1778
	}
1779
	if (!empty($config['ntpd']['noserve'])) {
1780
		$ntpcfg .= ' noserve';
1781
	}
1782
	if (empty($config['ntpd']['notrap'])) { /*note: this one works backwards */
1783
		$ntpcfg .= ' notrap';
1784
	}
1785
	$ntpcfg .= "\n";
1786

    
1787
	/* A leapseconds file is really only useful if this clock is stratum 1 */
1788
	$ntpcfg .= "\n";
1789
	if (!empty($config['ntpd']['leapsec'])) {
1790
		$leapsec .= base64_decode($config['ntpd']['leapsec']);
1791
		file_put_contents('/var/db/leap-seconds', $leapsec);
1792
		$ntpcfg .= "leapfile /var/db/leap-seconds\n";
1793
	}
1794

    
1795

    
1796
	if (empty($config['ntpd']['interface'])) {
1797
		if (is_array($config['installedpackages']['openntpd']) && !empty($config['installedpackages']['openntpd']['config'][0]['interface'])) {
1798
			$interfaces = explode(",", $config['installedpackages']['openntpd']['config'][0]['interface']);
1799
		} else {
1800
			$interfaces = array();
1801
		}
1802
	} else {
1803
		$interfaces = explode(",", $config['ntpd']['interface']);
1804
	}
1805

    
1806
	if (is_array($interfaces) && count($interfaces)) {
1807
		$finterfaces = array();
1808
		$ntpcfg .= "interface ignore all\n";
1809
		foreach ($interfaces as $interface) {
1810
			$interface = get_real_interface($interface);
1811
			if (!empty($interface)) {
1812
				$finterfaces[] = $interface;
1813
			}
1814
		}
1815
		foreach ($finterfaces as $interface) {
1816
			$ntpcfg .= "interface listen {$interface}\n";
1817
		}
1818
	}
1819

    
1820
	/* open configuration for writing or bail */
1821
	if (!@file_put_contents("{$g['varetc_path']}/ntpd.conf", $ntpcfg)) {
1822
		log_error(sprintf(gettext("Could not open %s/ntpd.conf for writing"), $g['varetc_path']));
1823
		return;
1824
	}
1825

    
1826
	/* At bootup we just want to write out the config. */
1827
	if (!$start_ntpd) {
1828
		return;
1829
	}
1830

    
1831
	/* if ntpd is running, kill it */
1832
	while (isvalidpid("{$g['varrun_path']}/ntpd.pid")) {
1833
		killbypid("{$g['varrun_path']}/ntpd.pid");
1834
	}
1835
	@unlink("{$g['varrun_path']}/ntpd.pid");
1836

    
1837
	/* if /var/empty does not exist, create it */
1838
	if (!is_dir("/var/empty")) {
1839
		mkdir("/var/empty", 0775, true);
1840
	}
1841

    
1842
	/* start opentpd, set time now and use /var/etc/ntpd.conf */
1843
	mwexec("/usr/local/sbin/ntpd -g -c {$g['varetc_path']}/ntpd.conf -p {$g['varrun_path']}/ntpd.pid", false, true);
1844

    
1845
	// Note that we are starting up
1846
	log_error("NTPD is starting up.");
1847
	return;
1848
}
1849

    
1850
function sync_system_time() {
1851
	global $config, $g;
1852

    
1853
	if (platform_booting()) {
1854
		echo gettext("Syncing system time before startup...");
1855
	}
1856

    
1857
	/* foreach through servers and write out to ntpd.conf */
1858
	foreach (explode(' ', $config['system']['timeservers']) as $ts) {
1859
		mwexec("/usr/local/sbin/ntpdate -s $ts");
1860
	}
1861

    
1862
	if (platform_booting()) {
1863
		echo gettext("done.") . "\n";
1864
	}
1865

    
1866
}
1867

    
1868
function system_halt() {
1869
	global $g;
1870

    
1871
	system_reboot_cleanup();
1872

    
1873
	mwexec("/usr/bin/nohup /etc/rc.halt > /dev/null 2>&1 &");
1874
}
1875

    
1876
function system_reboot() {
1877
	global $g;
1878

    
1879
	system_reboot_cleanup();
1880

    
1881
	mwexec("nohup /etc/rc.reboot > /dev/null 2>&1 &");
1882
}
1883

    
1884
function system_reboot_sync() {
1885
	global $g;
1886

    
1887
	system_reboot_cleanup();
1888

    
1889
	mwexec("/etc/rc.reboot > /dev/null 2>&1");
1890
}
1891

    
1892
function system_reboot_cleanup() {
1893
	global $config, $cpzone;
1894

    
1895
	mwexec("/usr/local/bin/beep.sh stop");
1896
	require_once("captiveportal.inc");
1897
	if (is_array($config['captiveportal'])) {
1898
		foreach ($config['captiveportal'] as $cpzone=>$cp) {
1899
			captiveportal_radius_stop_all();
1900
			captiveportal_send_server_accounting(true);
1901
		}
1902
	}
1903
	require_once("voucher.inc");
1904
	voucher_save_db_to_config();
1905
	require_once("pkg-utils.inc");
1906
	stop_packages();
1907
}
1908

    
1909
function system_do_shell_commands($early = 0) {
1910
	global $config, $g;
1911
	if (isset($config['system']['developerspew'])) {
1912
		$mt = microtime();
1913
		echo "system_do_shell_commands() being called $mt\n";
1914
	}
1915

    
1916
	if ($early) {
1917
		$cmdn = "earlyshellcmd";
1918
	} else {
1919
		$cmdn = "shellcmd";
1920
	}
1921

    
1922
	if (is_array($config['system'][$cmdn])) {
1923

    
1924
		/* *cmd is an array, loop through */
1925
		foreach ($config['system'][$cmdn] as $cmd) {
1926
			exec($cmd);
1927
		}
1928

    
1929
	} elseif ($config['system'][$cmdn] <> "") {
1930

    
1931
		/* execute single item */
1932
		exec($config['system'][$cmdn]);
1933

    
1934
	}
1935
}
1936

    
1937
function system_console_configure() {
1938
	global $config, $g;
1939
	if (isset($config['system']['developerspew'])) {
1940
		$mt = microtime();
1941
		echo "system_console_configure() being called $mt\n";
1942
	}
1943

    
1944
	if (isset($config['system']['disableconsolemenu'])) {
1945
		touch("{$g['varetc_path']}/disableconsole");
1946
	} else {
1947
		unlink_if_exists("{$g['varetc_path']}/disableconsole");
1948
	}
1949
}
1950

    
1951
function system_dmesg_save() {
1952
	global $g;
1953
	if (isset($config['system']['developerspew'])) {
1954
		$mt = microtime();
1955
		echo "system_dmesg_save() being called $mt\n";
1956
	}
1957

    
1958
	$dmesg = "";
1959
	$_gb = exec("/sbin/dmesg", $dmesg);
1960

    
1961
	/* find last copyright line (output from previous boots may be present) */
1962
	$lastcpline = 0;
1963

    
1964
	for ($i = 0; $i < count($dmesg); $i++) {
1965
		if (strstr($dmesg[$i], "Copyright (c) 1992-")) {
1966
			$lastcpline = $i;
1967
		}
1968
	}
1969

    
1970
	$fd = fopen("{$g['varlog_path']}/dmesg.boot", "w");
1971
	if (!$fd) {
1972
		printf(gettext("Error: cannot open dmesg.boot in system_dmesg_save().%s"), "\n");
1973
		return 1;
1974
	}
1975

    
1976
	for ($i = $lastcpline; $i < count($dmesg); $i++) {
1977
		fwrite($fd, $dmesg[$i] . "\n");
1978
	}
1979

    
1980
	fclose($fd);
1981
	unset($dmesg);
1982

    
1983
	return 0;
1984
}
1985

    
1986
function system_set_harddisk_standby() {
1987
	global $g, $config;
1988

    
1989
	if (isset($config['system']['developerspew'])) {
1990
		$mt = microtime();
1991
		echo "system_set_harddisk_standby() being called $mt\n";
1992
	}
1993

    
1994
	if (isset($config['system']['harddiskstandby'])) {
1995
		if (platform_booting()) {
1996
			echo gettext('Setting hard disk standby... ');
1997
		}
1998

    
1999
		$standby = $config['system']['harddiskstandby'];
2000
		// Check for a numeric value
2001
		if (is_numeric($standby)) {
2002
			// Get only suitable candidates for standby; using get_smart_drive_list()
2003
			// from utils.inc to get the list of drives.
2004
			$harddisks = get_smart_drive_list();
2005

    
2006
			// Since get_smart_drive_list() only matches ad|da|ada; lets put the check below
2007
			// just in case of some weird pfSense platform installs.
2008
			if (count($harddisks) > 0) {
2009
				// Iterate disks and run the camcontrol command for each
2010
				foreach ($harddisks as $harddisk) {
2011
					mwexec("/sbin/camcontrol standby {$harddisk} -t {$standby}");
2012
				}
2013
				if (platform_booting()) {
2014
					echo gettext("done.") . "\n";
2015
				}
2016
			} else if (platform_booting()) {
2017
				echo gettext("failed!") . "\n";
2018
			}
2019
		} else if (platform_booting()) {
2020
			echo gettext("failed!") . "\n";
2021
		}
2022
	}
2023
}
2024

    
2025
function system_setup_sysctl() {
2026
	global $config;
2027
	if (isset($config['system']['developerspew'])) {
2028
		$mt = microtime();
2029
		echo "system_setup_sysctl() being called $mt\n";
2030
	}
2031

    
2032
	activate_sysctls();
2033

    
2034
	if (isset($config['system']['sharednet'])) {
2035
		system_disable_arp_wrong_if();
2036
	}
2037
}
2038

    
2039
function system_disable_arp_wrong_if() {
2040
	global $config;
2041
	if (isset($config['system']['developerspew'])) {
2042
		$mt = microtime();
2043
		echo "system_disable_arp_wrong_if() being called $mt\n";
2044
	}
2045
	set_sysctl(array(
2046
		"net.link.ether.inet.log_arp_wrong_iface" => "0",
2047
		"net.link.ether.inet.log_arp_movements" => "0"
2048
	));
2049
}
2050

    
2051
function system_enable_arp_wrong_if() {
2052
	global $config;
2053
	if (isset($config['system']['developerspew'])) {
2054
		$mt = microtime();
2055
		echo "system_enable_arp_wrong_if() being called $mt\n";
2056
	}
2057
	set_sysctl(array(
2058
		"net.link.ether.inet.log_arp_wrong_iface" => "1",
2059
		"net.link.ether.inet.log_arp_movements" => "1"
2060
	));
2061
}
2062

    
2063
function enable_watchdog() {
2064
	global $config;
2065
	return;
2066
	$install_watchdog = false;
2067
	$supported_watchdogs = array("Geode");
2068
	$file = file_get_contents("/var/log/dmesg.boot");
2069
	foreach ($supported_watchdogs as $sd) {
2070
		if (stristr($file, "Geode")) {
2071
			$install_watchdog = true;
2072
		}
2073
	}
2074
	if ($install_watchdog == true) {
2075
		if (is_process_running("watchdogd")) {
2076
			mwexec("/usr/bin/killall watchdogd", true);
2077
		}
2078
		exec("/usr/sbin/watchdogd");
2079
	}
2080
}
2081

    
2082
function system_check_reset_button() {
2083
	global $g;
2084

    
2085
	$specplatform = system_identify_specific_platform();
2086

    
2087
	switch ($specplatform['name']) {
2088
		case 'alix':
2089
		case 'wrap':
2090
		case 'FW7541':
2091
		case 'APU':
2092
		case 'RCC-VE':
2093
		case 'RCC-DFF':
2094
			break;
2095
		default:
2096
			return 0;
2097
	}
2098

    
2099
	$retval = mwexec("/usr/local/sbin/" . $specplatform['name'] . "resetbtn");
2100

    
2101
	if ($retval == 99) {
2102
		/* user has pressed reset button for 2 seconds -
2103
		   reset to factory defaults */
2104
		echo <<<EOD
2105

    
2106
***********************************************************************
2107
* Reset button pressed - resetting configuration to factory defaults. *
2108
* All additional packages installed will be removed                   *
2109
* The system will reboot after this completes.                        *
2110
***********************************************************************
2111

    
2112

    
2113
EOD;
2114

    
2115
		reset_factory_defaults();
2116
		system_reboot_sync();
2117
		exit(0);
2118
	}
2119

    
2120
	return 0;
2121
}
2122

    
2123
/*
2124
 * attempt to identify the specific platform (for embedded systems)
2125
 * Returns an array with two elements:
2126
 * name => platform string (e.g. 'wrap', 'alix' etc.)
2127
 * descr => human-readable description (e.g. "PC Engines WRAP")
2128
 */
2129
function system_identify_specific_platform() {
2130
	global $g;
2131

    
2132
	if ($g['platform'] == 'generic-pc') {
2133
		return array('name' => 'generic-pc', 'descr' => gettext("Generic PC"));
2134
	}
2135

    
2136
	if ($g['platform'] == 'generic-pc-cdrom') {
2137
		return array('name' => 'generic-pc-cdrom', 'descr' => gettext("Generic PC (CD-ROM)"));
2138
	}
2139

    
2140
	/* Try to guess from smbios strings */
2141
	unset($output);
2142
	$_gb = exec('/bin/kenv smbios.system.product 2>/dev/null', $output);
2143
	switch ($output[0]) {
2144
		case 'FW7541':
2145
			return (array('name' => 'FW7541', 'descr' => 'Netgate FW7541'));
2146
			break;
2147
		case 'APU':
2148
			return (array('name' => 'APU', 'descr' => 'Netgate APU'));
2149
			break;
2150
		case 'RCC-VE':
2151
			return (array('name' => 'RCC-VE', 'descr' => 'Netgate RCC-VE'));
2152
			break;
2153
		case 'DFFv2':
2154
			return (array('name' => 'RCC-DFF', 'descr' => 'Netgate RCC-DFF'));
2155
			break;
2156
		case 'SYS-5018A-FTN4':
2157
		case 'A1SAi':
2158
			return (array('name' => 'C2758', 'descr' => 'Super Micro C2758'));
2159
			break;
2160
		case 'SYS-5018D-FN4T':
2161
			return (array('name' => 'D1540-XG', 'descr' => 'Super Micro D1540-XG'));
2162
			break;
2163
	}
2164

    
2165
	/* the rest of the code only deals with 'embedded' platforms */
2166
	if ($g['platform'] != 'nanobsd') {
2167
		return array('name' => $g['platform'], 'descr' => $g['platform']);
2168
	}
2169

    
2170
	$dmesg = get_single_sysctl('hw.model');
2171

    
2172
	if (strpos($dmesg, "PC Engines WRAP") !== false) {
2173
		return array('name' => 'wrap', 'descr' => gettext('PC Engines WRAP'));
2174
	}
2175

    
2176
	if (strpos($dmesg, "PC Engines ALIX") !== false) {
2177
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
2178
	}
2179

    
2180
	if (preg_match("/Soekris net45../", $dmesg, $matches)) {
2181
		return array('name' => 'net45xx', 'descr' => $matches[0]);
2182
	}
2183

    
2184
	if (preg_match("/Soekris net48../", $dmesg, $matches)) {
2185
		return array('name' => 'net48xx', 'descr' => $matches[0]);
2186
	}
2187

    
2188
	if (preg_match("/Soekris net55../", $dmesg, $matches)) {
2189
		return array('name' => 'net55xx', 'descr' => $matches[0]);
2190
	}
2191

    
2192
	unset($dmesg);
2193

    
2194
	$dmesg_boot = system_get_dmesg_boot();
2195
	if (strpos($dmesg_boot, "PC Engines ALIX") !== false) {
2196
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
2197
	}
2198
	unset($dmesg_boot);
2199

    
2200
	/* unknown embedded platform */
2201
	return array('name' => 'embedded', 'descr' => gettext('embedded (unknown)'));
2202
}
2203

    
2204
function system_get_dmesg_boot() {
2205
	global $g;
2206

    
2207
	return file_get_contents("{$g['varlog_path']}/dmesg.boot");
2208
}
2209

    
2210
?>
(52-52/65)