Project

General

Profile

Download (64.7 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
			$gwname = $config['system'][$dnsgw];
242
			if (($gwname <> "") && ($gwname <> "none")) {
243
				$gatewayip = lookup_gateway_ip_by_name($gwname);
244
				if (is_ipaddrv4($gatewayip)) {
245
					/* dns server array starts at 0 */
246
					$dnscountermo = $dnscounter - 1;
247
					mwexec("/sbin/route change -host " . $syscfg['dnsserver'][$dnscountermo] . " {$gatewayip}");
248
					if (isset($config['system']['route-debug'])) {
249
						$mt = microtime();
250
						log_error("ROUTING debug: $mt - route change -host {$syscfg['dnsserver'][$dnscountermo]} $gatewayip ");
251
					}
252
				}
253
				if (is_ipaddrv6($gatewayip)) {
254
					/* dns server array starts at 0 */
255
					$dnscountermo = $dnscounter - 1;
256
					mwexec("/sbin/route change -host -inet6 " . $syscfg['dnsserver'][$dnscountermo] . " {$gatewayip}");
257
					if (isset($config['system']['route-debug'])) {
258
						$mt = microtime();
259
						log_error("ROUTING debug: $mt - route change -host -inet6 {$syscfg['dnsserver'][$dnscountermo]} $gatewayip ");
260
					}
261
				}
262
			}
263
		}
264
	}
265

    
266
	unlock($dnslock);
267

    
268
	return 0;
269
}
270

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

    
274
	$master_list = array();
275

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

    
292
	return $master_list;
293
}
294

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

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

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

    
327
	return $master_list;
328
}
329

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

    
337
	$syscfg = $config['system'];
338
	if (isset($config['unbound']) && isset($config['unbound']['enable'])) {
339
		$dnsmasqcfg = $config['unbound'];
340
	} else {
341
		$dnsmasqcfg = $config['dnsmasq'];
342
	}
343

    
344
	$hosts = "127.0.0.1	localhost localhost.{$syscfg['domain']}\n";
345
	$hosts .= "::1		localhost localhost.{$syscfg['domain']}\n";
346
	$lhosts = "";
347
	$dhosts = "";
348

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

    
380
	if (isset($dnsmasqcfg['enable'])) {
381
		if (!is_array($dnsmasqcfg['hosts'])) {
382
			$dnsmasqcfg['hosts'] = array();
383
		}
384

    
385
		foreach ($dnsmasqcfg['hosts'] as $host) {
386
			if ($host['host'] || $host['host'] == "0") {
387
				$lhosts .= "{$host['ip']}	{$host['host']}.{$host['domain']} {$host['host']}\n";
388
			} else {
389
				$lhosts .= "{$host['ip']}	{$host['domain']}\n";
390
			}
391
			if (!is_array($host['aliases']) || !is_array($host['aliases']['item'])) {
392
				continue;
393
			}
394
			foreach ($host['aliases']['item'] as $alias) {
395
				if ($alias['host'] || $alias['host'] == "0") {
396
					$lhosts .= "{$host['ip']}	{$alias['host']}.{$alias['domain']} {$alias['host']}\n";
397
				} else {
398
					$lhosts .= "{$host['ip']}	{$alias['domain']}\n";
399
				}
400
			}
401
		}
402
		if (isset($dnsmasqcfg['regdhcpstatic']) && is_array($config['dhcpd'])) {
403
			foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {
404
				if (is_array($dhcpifconf['staticmap']) && isset($dhcpifconf['enable'])) {
405
					foreach ($dhcpifconf['staticmap'] as $host) {
406
						if ($host['ipaddr'] && $host['hostname'] && $host['domain']) {
407
							$dhosts .= "{$host['ipaddr']}	{$host['hostname']}.{$host['domain']} {$host['hostname']}\n";
408
						} else if ($host['ipaddr'] && $host['hostname'] && $dhcpifconf['domain']) {
409
							$dhosts .= "{$host['ipaddr']}	{$host['hostname']}.{$dhcpifconf['domain']} {$host['hostname']}\n";
410
						} else if ($host['ipaddr'] && $host['hostname']) {
411
							$dhosts .= "{$host['ipaddr']}	{$host['hostname']}.{$syscfg['domain']} {$host['hostname']}\n";
412
						}
413
					}
414
				}
415
			}
416
		}
417
		if (isset($dnsmasqcfg['regdhcpstatic']) && is_array($config['dhcpdv6'])) {
418
			foreach ($config['dhcpdv6'] as $dhcpif => $dhcpifconf) {
419
				if (is_array($dhcpifconf['staticmap']) && isset($dhcpifconf['enable'])) {
420
					foreach ($dhcpifconf['staticmap'] as $host) {
421
						if ($host['ipaddrv6'] && $host['hostname'] && $host['domain']) {
422
							$dhosts .= "{$host['ipaddrv6']}	{$host['hostname']}.{$host['domain']} {$host['hostname']}\n";
423
						} else if ($host['ipaddrv6'] && $host['hostname'] && $dhcpifconf['domain']) {
424
							$dhosts .= "{$host['ipaddrv6']}	{$host['hostname']}.{$dhcpifconf['domain']} {$host['hostname']}\n";
425
						} else if ($host['ipaddrv6'] && $host['hostname']) {
426
							$dhosts .= "{$host['ipaddrv6']}	{$host['hostname']}.{$syscfg['domain']} {$host['hostname']}\n";
427
						}
428
					}
429
				}
430
			}
431
		}
432

    
433
		if (isset($dnsmasqcfg['dhcpfirst'])) {
434
			$hosts .= $dhosts . $lhosts;
435
		} else {
436
			$hosts .= $lhosts . $dhosts;
437
		}
438
	}
439

    
440
	/*
441
	 * Do not remove this because dhcpleases monitors with kqueue it needs to be
442
	 * killed before writing to hosts files.
443
	 */
444
	if (file_exists("{$g['varrun_path']}/dhcpleases.pid")) {
445
		sigkillbypid("{$g['varrun_path']}/dhcpleases.pid", "TERM");
446
		@unlink("{$g['varrun_path']}/dhcpleases.pid");
447
	}
448
	$fd = fopen("{$g['varetc_path']}/hosts", "w");
449
	if (!$fd) {
450
		log_error("Error: cannot open hosts file in system_hosts_generate().\n");
451
		return 1;
452
	}
453
	fwrite($fd, $hosts);
454
	fclose($fd);
455

    
456
	if (isset($config['unbound']['enable'])) {
457
		require_once("unbound.inc");
458
		unbound_hosts_generate();
459
	}
460

    
461
	return 0;
462
}
463

    
464
function system_dhcpleases_configure() {
465
	global $config, $g;
466

    
467
	/* Start the monitoring process for dynamic dhcpclients. */
468
	if ((isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcp'])) ||
469
	    (isset($config['unbound']['enable']) && isset($config['unbound']['regdhcp']))) {
470
		/* Make sure we do not error out */
471
		mwexec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/db");
472
		if (!file_exists("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases")) {
473
			@touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
474
		}
475

    
476
		if (isset($config['unbound']['enable'])) {
477
			$dns_pid = "unbound.pid";
478
			$unbound_conf = "-u {$g['unbound_chroot_path']}/dhcpleases_entries.conf";
479
		} else {
480
			$dns_pid = "dnsmasq.pid";
481
			$unbound_conf = "";
482
		}
483

    
484
		$pidfile = "{$g['varrun_path']}/dhcpleases.pid";
485
		if (isvalidpid($pidfile)) {
486
			/* Make sure dhcpleases is using correct unbound or dnsmasq */
487
			$_gb = exec("/bin/pgrep -F {$pidfile} -f {$dns_pid}", $output, $retval);
488
			if (intval($retval) == 0) {
489
				sigkillbypid($pidfile, "HUP");
490
				return;
491
			} else {
492
				sigkillbypid($pidfile, "TERM");
493
			}
494
		}
495

    
496
		/* To ensure we do not start multiple instances of dhcpleases, perform some clean-up first. */
497
		if (is_process_running("dhcpleases")) {
498
			sigkillbyname('dhcpleases', "TERM");
499
		}
500
		@unlink($pidfile);
501
		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");
502
	} else {
503
		sigkillbypid($pidfile, "TERM");
504
		@unlink($pidfile);
505
	}
506
}
507

    
508
function system_hostname_configure() {
509
	global $config, $g;
510
	if (isset($config['system']['developerspew'])) {
511
		$mt = microtime();
512
		echo "system_hostname_configure() being called $mt\n";
513
	}
514

    
515
	$syscfg = $config['system'];
516

    
517
	/* set hostname */
518
	$status = mwexec("/bin/hostname " .
519
		escapeshellarg("{$syscfg['hostname']}.{$syscfg['domain']}"));
520

    
521
	/* Setup host GUID ID.  This is used by ZFS. */
522
	mwexec("/etc/rc.d/hostid start");
523

    
524
	return $status;
525
}
526

    
527
function system_routing_configure($interface = "") {
528
	global $config, $g;
529

    
530
	if (isset($config['system']['developerspew'])) {
531
		$mt = microtime();
532
		echo "system_routing_configure() being called $mt\n";
533
	}
534

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

    
606
	$gateways_arr = return_gateways_array(false, true);
607
	foreach ($gateways_arr as $gateway) {
608
		// setup static interface routes for nonlocal gateways
609
		if (isset($gateway["nonlocalgateway"])) {
610
			$srgatewayip = $gateway['gateway'];
611
			$srinterfacegw = $gateway['interface'];
612
			if (is_ipaddr($srgatewayip) && !empty($srinterfacegw)) {
613
				$inet = (!is_ipaddrv4($srgatewayip) ? "-inet6" : "-inet");
614
				$cmd = "/sbin/route change {$inet} " . escapeshellarg($srgatewayip) . " ";
615
				mwexec($cmd . "-iface " . escapeshellarg($srinterfacegw));
616
				if (isset($config['system']['route-debug'])) {
617
					$mt = microtime();
618
					log_error("ROUTING debug: $mt - $cmd -iface $srinterfacegw ");
619
				}
620
			}
621
		}
622
	}
623

    
624
	if ($dont_add_route == false) {
625
		if (!empty($interface) && $interface != $interfacegw) {
626
			;
627
		} else if (is_ipaddrv4($gatewayip)) {
628
			log_error("ROUTING: setting default route to $gatewayip");
629
			mwexec("/sbin/route change -inet default " . escapeshellarg($gatewayip));
630
		}
631

    
632
		if (!empty($interface) && $interface != $interfacegwv6) {
633
			;
634
		} else if (is_ipaddrv6($gatewayipv6)) {
635
			$ifscope = "";
636
			if (is_linklocal($gatewayipv6) && !strpos($gatewayipv6, '%')) {
637
				$ifscope = "%{$defaultifv6}";
638
			}
639
			log_error("ROUTING: setting IPv6 default route to {$gatewayipv6}{$ifscope}");
640
			mwexec("/sbin/route change -inet6 default " . escapeshellarg("{$gatewayipv6}{$ifscope}"));
641
		}
642
	}
643

    
644
	system_staticroutes_configure($interface, false);
645

    
646
	return 0;
647
}
648

    
649
function system_staticroutes_configure($interface = "", $update_dns = false) {
650
	global $config, $g, $aliastable;
651

    
652
	$filterdns_list = array();
653

    
654
	$static_routes = get_staticroutes(false, true);
655
	if (count($static_routes)) {
656
		$gateways_arr = return_gateways_array(false, true);
657

    
658
		foreach ($static_routes as $rtent) {
659
			if (empty($gateways_arr[$rtent['gateway']])) {
660
				log_error(sprintf(gettext("Static Routes: Gateway IP could not be found for %s"), $rtent['network']));
661
				continue;
662
			}
663
			$gateway = $gateways_arr[$rtent['gateway']];
664
			if (!empty($interface) && $interface != $gateway['friendlyiface']) {
665
				continue;
666
			}
667

    
668
			$gatewayip = $gateway['gateway'];
669
			$interfacegw = $gateway['interface'];
670

    
671
			$blackhole = "";
672
			if (!strcasecmp("Null", substr($rtent['gateway'], 0, 3))) {
673
				$blackhole = "-blackhole";
674
			}
675

    
676
			if (!is_fqdn($rtent['network']) && !is_subnet($rtent['network'])) {
677
				continue;
678
			}
679

    
680
			$dnscache = array();
681
			if ($update_dns === true) {
682
				if (is_subnet($rtent['network'])) {
683
					continue;
684
				}
685
				$dnscache = explode("\n", trim(compare_hostname_to_dnscache($rtent['network'])));
686
				if (empty($dnscache)) {
687
					continue;
688
				}
689
			}
690

    
691
			if (is_subnet($rtent['network'])) {
692
				$ips = array($rtent['network']);
693
			} else {
694
				if (!isset($rtent['disabled'])) {
695
					$filterdns_list[] = $rtent['network'];
696
				}
697
				$ips = add_hostname_to_watch($rtent['network']);
698
			}
699

    
700
			foreach ($dnscache as $ip) {
701
				if (in_array($ip, $ips)) {
702
					continue;
703
				}
704
				mwexec("/sbin/route delete " . escapeshellarg($ip), true);
705
				if (isset($config['system']['route-debug'])) {
706
					$mt = microtime();
707
					log_error("ROUTING debug: $mt - route delete $ip ");
708
				}
709
			}
710

    
711
			if (isset($rtent['disabled'])) {
712
				/* XXX: This can break things by deleting routes that shouldn't be deleted - OpenVPN, dynamic routing scenarios, etc. redmine #3709 */
713
				foreach ($ips as $ip) {
714
					mwexec("/sbin/route delete " . escapeshellarg($ip), true);
715
					if (isset($config['system']['route-debug'])) {
716
						$mt = microtime();
717
						log_error("ROUTING debug: $mt - route delete $ip ");
718
					}
719
				}
720
				continue;
721
			}
722

    
723
			foreach ($ips as $ip) {
724
				if (is_ipaddrv4($ip)) {
725
					$ip .= "/32";
726
				}
727
				// do NOT do the same check here on v6, is_ipaddrv6 returns true when including the CIDR mask. doing so breaks v6 routes
728

    
729
				$inet = (is_subnetv6($ip) ? "-inet6" : "-inet");
730

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

    
733
				if (is_subnet($ip)) {
734
					if (is_ipaddr($gatewayip)) {
735
						mwexec($cmd . escapeshellarg($gatewayip));
736
						if (isset($config['system']['route-debug'])) {
737
							$mt = microtime();
738
							log_error("ROUTING debug: $mt - $cmd $gatewayip");
739
						}
740
					} else if (!empty($interfacegw)) {
741
						mwexec($cmd . "-iface " . escapeshellarg($interfacegw));
742
						if (isset($config['system']['route-debug'])) {
743
							$mt = microtime();
744
							log_error("ROUTING debug: $mt - $cmd -iface $interfacegw ");
745
						}
746
					}
747
				}
748
			}
749
		}
750
		unset($gateways_arr);
751
	}
752
	unset($static_routes);
753

    
754
	if ($update_dns === false) {
755
		if (count($filterdns_list)) {
756
			$interval = 60;
757
			$hostnames = "";
758
			array_unique($filterdns_list);
759
			foreach ($filterdns_list as $hostname) {
760
				$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload routedns\"'\n";
761
			}
762
			file_put_contents("{$g['varetc_path']}/filterdns-route.hosts", $hostnames);
763
			unset($hostnames);
764

    
765
			if (isvalidpid("{$g['varrun_path']}/filterdns-route.pid")) {
766
				sigkillbypid("{$g['varrun_path']}/filterdns-route.pid", "HUP");
767
			} else {
768
				mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-route.pid -i {$interval} -c {$g['varetc_path']}/filterdns-route.hosts -d 1");
769
			}
770
		} else {
771
			killbypid("{$g['varrun_path']}/filterdns-route.pid");
772
			@unlink("{$g['varrun_path']}/filterdns-route.pid");
773
		}
774
	}
775
	unset($filterdns_list);
776

    
777
	return 0;
778
}
779

    
780
function system_routing_enable() {
781
	global $config, $g;
782
	if (isset($config['system']['developerspew'])) {
783
		$mt = microtime();
784
		echo "system_routing_enable() being called $mt\n";
785
	}
786

    
787
	set_sysctl(array(
788
		"net.inet.ip.forwarding" => "1",
789
		"net.inet6.ip6.forwarding" => "1"
790
	));
791

    
792
	return;
793
}
794

    
795
function system_syslogd_fixup_server($server) {
796
	/* If it's an IPv6 IP alone, encase it in brackets */
797
	if (is_ipaddrv6($server)) {
798
		return "[$server]";
799
	} else {
800
		return $server;
801
	}
802
}
803

    
804
function system_syslogd_get_remote_servers($syslogcfg, $facility = "*.*") {
805
	// Rather than repeatedly use the same code, use this function to build a list of remote servers.
806
	$facility .= " ".
807
	$remote_servers = "";
808
	$pad_to  = max(strlen($facility), 56);
809
	$padding = ceil(($pad_to - strlen($facility))/8)+1;
810
	if (isset($syslogcfg['enable'])) {
811
		if ($syslogcfg['remoteserver']) {
812
			$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver']) . "\n";
813
		}
814
		if ($syslogcfg['remoteserver2']) {
815
			$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver2']) . "\n";
816
		}
817
		if ($syslogcfg['remoteserver3']) {
818
			$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver3']) . "\n";
819
		}
820
	}
821
	return $remote_servers;
822
}
823

    
824
function clear_log_file($logfile = "/var/log/system.log", $restart_syslogd = true) {
825
	global $config, $g;
826
	if ($restart_syslogd) {
827
		exec("/usr/bin/killall syslogd");
828
	}
829
	if (isset($config['system']['disablesyslogclog'])) {
830
		unlink($logfile);
831
		touch($logfile);
832
	} else {
833
		$log_size = isset($config['syslog']['logfilesize']) ? $config['syslog']['logfilesize'] : "511488";
834
		$log_size = isset($config['syslog'][basename($logfile, '.log') . '_settings']['logfilesize']) ? $config['syslog'][basename($logfile, '.log') . '_settings']['logfilesize'] : $log_size;
835
		exec("/usr/local/sbin/clog -i -s {$log_size} " . escapeshellarg($logfile));
836
	}
837
	if ($restart_syslogd) {
838
		system_syslogd_start();
839
	}
840
}
841

    
842
function clear_all_log_files($restart = false) {
843
	global $g;
844
	exec("/usr/bin/killall syslogd");
845

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

    
851
	if ($restart) {
852
		system_syslogd_start();
853
		killbyname("dhcpd");
854
		services_dhcpd_configure();
855
	}
856
	return;
857
}
858

    
859
function system_syslogd_start() {
860
	global $config, $g;
861
	if (isset($config['system']['developerspew'])) {
862
		$mt = microtime();
863
		echo "system_syslogd_start() being called $mt\n";
864
	}
865

    
866
	mwexec("/etc/rc.d/hostid start");
867

    
868
	$syslogcfg = $config['syslog'];
869

    
870
	if (platform_booting()) {
871
		echo gettext("Starting syslog...");
872
	}
873

    
874
	// Which logging type are we using this week??
875
	if (isset($config['system']['disablesyslogclog'])) {
876
		$log_directive = "";
877
		$log_create_directive = "/usr/bin/touch ";
878
		$log_size = "";
879
	} else { // Defaults to CLOG
880
		$log_directive = "%";
881
		$log_size = isset($config['syslog']['logfilesize']) ? $config['syslog']['logfilesize'] : "10240";
882
		$log_create_directive = "/usr/local/sbin/clog -i -s ";
883
	}
884

    
885
	$syslogd_extra = "";
886
	if (isset($syslogcfg)) {
887
		$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');
888
		$syslogconf = "";
889
		if ($config['installedpackages']['package']) {
890
			foreach ($config['installedpackages']['package'] as $package) {
891
				if ($package['logging']) {
892
					array_push($separatelogfacilities, $package['logging']['facilityname']);
893
					if (!is_file($g['varlog_path'].'/'.$package['logging']['logfilename'])) {
894
						mwexec("{$log_create_directive} {$log_size} {$g['varlog_path']}/{$package['logging']['logfilename']}");
895
					}
896
					$syslogconf .= "!{$package['logging']['facilityname']}\n*.*\t\t\t\t\t\t {$log_directive}{$g['varlog_path']}/{$package['logging']['logfilename']}\n";
897
				}
898
			}
899
		}
900
		$facilitylist = implode(',', array_unique($separatelogfacilities));
901
		$syslogconf .= "!radvd,routed,olsrd,zebra,ospfd,bgpd,miniupnpd\n";
902
		if (!isset($syslogcfg['disablelocallogging'])) {
903
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/routing.log\n";
904
		}
905

    
906
		$syslogconf .= "!ntp,ntpd,ntpdate\n";
907
		if (!isset($syslogcfg['disablelocallogging'])) {
908
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ntpd.log\n";
909
		}
910

    
911
		$syslogconf .= "!ppp\n";
912
		if (!isset($syslogcfg['disablelocallogging'])) {
913
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ppp.log\n";
914
		}
915

    
916
		$syslogconf .= "!pptps\n";
917
		if (!isset($syslogcfg['disablelocallogging'])) {
918
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/pptps.log\n";
919
		}
920

    
921
		$syslogconf .= "!poes\n";
922
		if (!isset($syslogcfg['disablelocallogging'])) {
923
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/poes.log\n";
924
		}
925

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

    
931
		$syslogconf .= "!charon,ipsec_starter\n";
932
		if (!isset($syslogcfg['disablelocallogging'])) {
933
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ipsec.log\n";
934
		}
935
		if (isset($syslogcfg['vpn'])) {
936
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
937
		}
938

    
939
		$syslogconf .= "!openvpn\n";
940
		if (!isset($syslogcfg['disablelocallogging'])) {
941
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/openvpn.log\n";
942
		}
943
		if (isset($syslogcfg['vpn'])) {
944
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
945
		}
946

    
947
		$syslogconf .= "!dpinger\n";
948
		if (!isset($syslogcfg['disablelocallogging'])) {
949
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/gateways.log\n";
950
		}
951
		if (isset($syslogcfg['dpinger'])) {
952
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
953
		}
954

    
955
		$syslogconf .= "!dnsmasq,filterdns,unbound\n";
956
		if (!isset($syslogcfg['disablelocallogging'])) {
957
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/resolver.log\n";
958
		}
959

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

    
968
		$syslogconf .= "!relayd\n";
969
		if (!isset($syslogcfg['disablelocallogging'])) {
970
			$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/relayd.log\n";
971
		}
972
		if (isset($syslogcfg['relayd'])) {
973
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
974
		}
975

    
976
		$syslogconf .= "!hostapd\n";
977
		if (!isset($syslogcfg['disablelocallogging'])) {
978
			$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/wireless.log\n";
979
		}
980
		if (isset($syslogcfg['hostapd'])) {
981
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
982
		}
983

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

    
990
		$syslogconf .= "!-{$facilitylist}\n";
991
		if (!isset($syslogcfg['disablelocallogging'])) {
992
			$syslogconf .= <<<EOD
993
local3.*							{$log_directive}{$g['varlog_path']}/vpn.log
994
local4.*							{$log_directive}{$g['varlog_path']}/portalauth.log
995
local5.*							{$log_directive}{$g['varlog_path']}/nginx.log
996
local7.*							{$log_directive}{$g['varlog_path']}/dhcpd.log
997
*.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
998
auth.info;authpriv.info 					|exec /usr/local/sbin/sshlockout_pf 15
999
*.emerg								*
1000

    
1001
EOD;
1002
		}
1003
		if (isset($syslogcfg['vpn'])) {
1004
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local3.*");
1005
		}
1006
		if (isset($syslogcfg['portalauth'])) {
1007
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local4.*");
1008
		}
1009
		if (isset($syslogcfg['dhcp'])) {
1010
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local7.*");
1011
		}
1012
		if (isset($syslogcfg['system'])) {
1013
			$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");
1014
		}
1015
		if (isset($syslogcfg['logall'])) {
1016
			// Make everything mean everything, including facilities excluded above.
1017
			$syslogconf .= "!*\n";
1018
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
1019
		}
1020

    
1021
		if (isset($syslogcfg['zmqserver'])) {
1022
				$syslogconf .= <<<EOD
1023
*.*								^{$syslogcfg['zmqserver']}
1024

    
1025
EOD;
1026
		}
1027
		/* write syslog.conf */
1028
		if (!@file_put_contents("{$g['varetc_path']}/syslog.conf", $syslogconf)) {
1029
			printf(gettext("Error: cannot open syslog.conf in system_syslogd_start().%s"), "\n");
1030
			unset($syslogconf);
1031
			return 1;
1032
		}
1033
		unset($syslogconf);
1034

    
1035
		// Ensure that the log directory exists
1036
		if (!is_dir("{$g['dhcpd_chroot_path']}/var/run")) {
1037
			exec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/run");
1038
		}
1039

    
1040
		$sourceip = "";
1041
		if (!empty($syslogcfg['sourceip'])) {
1042
			if ($syslogcfg['ipproto'] == "ipv6") {
1043
				$ifaddr = is_ipaddr($syslogcfg['sourceip']) ? $syslogcfg['sourceip'] : get_interface_ipv6($syslogcfg['sourceip']);
1044
				if (!is_ipaddr($ifaddr)) {
1045
					$ifaddr = get_interface_ip($syslogcfg['sourceip']);
1046
				}
1047
			} else {
1048
				$ifaddr = is_ipaddr($syslogcfg['sourceip']) ? $syslogcfg['sourceip'] : get_interface_ip($syslogcfg['sourceip']);
1049
				if (!is_ipaddr($ifaddr)) {
1050
					$ifaddr = get_interface_ipv6($syslogcfg['sourceip']);
1051
				}
1052
			}
1053
			if (is_ipaddr($ifaddr)) {
1054
				$sourceip = "-b {$ifaddr}";
1055
			}
1056
		}
1057

    
1058
		$syslogd_extra = "-f {$g['varetc_path']}/syslog.conf {$sourceip}";
1059
	}
1060

    
1061
	if (isvalidpid("{$g['varrun_path']}/syslog.pid")) {
1062
		sigkillbypid("{$g['varrun_path']}/syslog.pid", "TERM");
1063
		usleep(100000); // syslogd often doesn't respond to a TERM quickly enough for the starting of syslogd below to be successful
1064
	}
1065

    
1066
	if (isvalidpid("{$g['varrun_path']}/syslog.pid")) {
1067
		// if it still hasn't responded to the TERM, KILL it.
1068
		sigkillbypid("{$g['varrun_path']}/syslog.pid", "KILL");
1069
		usleep(100000);
1070
	}
1071

    
1072

    
1073
	$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}");
1074

    
1075
	if (platform_booting()) {
1076
		echo gettext("done.") . "\n";
1077
	}
1078

    
1079
	return $retval;
1080
}
1081

    
1082
function system_webgui_create_certificate() {
1083
	global $config, $g;
1084

    
1085
	if (!is_array($config['ca'])) {
1086
		$config['ca'] = array();
1087
	}
1088
	$a_ca =& $config['ca'];
1089
	if (!is_array($config['cert'])) {
1090
		$config['cert'] = array();
1091
	}
1092
	$a_cert =& $config['cert'];
1093
	log_error("Creating SSL Certificate for this host");
1094

    
1095
	$cert = array();
1096
	$cert['refid'] = uniqid();
1097
	$cert['descr'] = gettext("webConfigurator default ({$cert['refid']})");
1098

    
1099
	$dn = array(
1100
		'countryName' => "US",
1101
		'stateOrProvinceName' => "State",
1102
		'localityName' => "Locality",
1103
		'organizationName' => "{$g['product_name']} webConfigurator Self-Signed Certificate",
1104
		'emailAddress' => "admin@{$config['system']['hostname']}.{$config['system']['domain']}",
1105
		'commonName' => "{$config['system']['hostname']}-{$cert['refid']}");
1106
	$old_err_level = error_reporting(0); /* otherwise openssl_ functions throw warnings directly to a page screwing menu tab */
1107
	if (!cert_create($cert, null, 2048, 2000, $dn, "self-signed", "sha256")) {
1108
		while ($ssl_err = openssl_error_string()) {
1109
			log_error("Error creating WebGUI Certificate: openssl library returns: " . $ssl_err);
1110
		}
1111
		error_reporting($old_err_level);
1112
		return null;
1113
	}
1114
	error_reporting($old_err_level);
1115

    
1116
	$a_cert[] = $cert;
1117
	$config['system']['webgui']['ssl-certref'] = $cert['refid'];
1118
	write_config(gettext("Generated new self-signed HTTPS certificate ({$cert['refid']})"));
1119
	return $cert;
1120
}
1121

    
1122
function system_webgui_start() {
1123
	global $config, $g;
1124

    
1125
	if (platform_booting()) {
1126
		echo gettext("Starting webConfigurator...");
1127
	}
1128

    
1129
	chdir($g['www_path']);
1130

    
1131
	/* defaults */
1132
	$portarg = "80";
1133
	$crt = "";
1134
	$key = "";
1135
	$ca = "";
1136

    
1137
	/* non-standard port? */
1138
	if (isset($config['system']['webgui']['port']) && $config['system']['webgui']['port'] <> "") {
1139
		$portarg = "{$config['system']['webgui']['port']}";
1140
	}
1141

    
1142
	if ($config['system']['webgui']['protocol'] == "https") {
1143
		// Ensure that we have a webConfigurator CERT
1144
		$cert =& lookup_cert($config['system']['webgui']['ssl-certref']);
1145
		if (!is_array($cert) || !$cert['crt'] || !$cert['prv']) {
1146
			$cert = system_webgui_create_certificate();
1147
		}
1148
		$crt = base64_decode($cert['crt']);
1149
		$key = base64_decode($cert['prv']);
1150

    
1151
		if (!$config['system']['webgui']['port']) {
1152
			$portarg = "443";
1153
		}
1154
		$ca = ca_chain($cert);
1155
	}
1156

    
1157
	/* generate nginx configuration */
1158
	system_generate_nginx_config("{$g['varetc_path']}/nginx-webConfigurator.conf",
1159
		$crt, $key, $ca, "nginx-webConfigurator.pid", $portarg, "/usr/local/www/",
1160
		"cert.crt", "cert.key");
1161

    
1162
	/* kill any running nginx */
1163
	killbypid("{$g['varrun_path']}/nginx-webConfigurator.pid");
1164

    
1165
	sleep(1);
1166

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

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

    
1172
	if (platform_booting()) {
1173
		if ($res == 0) {
1174
			echo gettext("done.") . "\n";
1175
		} else {
1176
			echo gettext("failed!") . "\n";
1177
		}
1178
	}
1179

    
1180
	return $res;
1181
}
1182

    
1183
function system_generate_nginx_config($filename,
1184
	$cert,
1185
	$key,
1186
	$ca,
1187
	$pid_file,
1188
	$port = 80,
1189
	$document_root = "/usr/local/www/",
1190
	$cert_location = "cert.crt",
1191
	$key_location = "cert.key",
1192
	$captive_portal = false) {
1193

    
1194
	global $config, $g;
1195

    
1196
	if (isset($config['system']['developerspew'])) {
1197
		$mt = microtime();
1198
		echo "system_generate_nginx_config() being called $mt\n";
1199
	}
1200

    
1201
	if ($captive_portal !== false) {
1202
		$cp_interfaces = explode(",", $config['captiveportal'][$captive_portal]['interface']);
1203
		$cp_hostcheck = "";
1204
		foreach ($cp_interfaces as $cpint) {
1205
			$cpint_ip = get_interface_ip($cpint);
1206
			if (is_ipaddr($cpint_ip)) {
1207
				$cp_hostcheck .= "\t\tif (\$http_host ~* $cpint_ip) {\n";
1208
				$cp_hostcheck .= "\t\t\tset \$cp_redirect no;\n";
1209
				$cp_hostcheck .= "\t\t}\n";
1210
			}
1211
		}
1212
		if (isset($config['captiveportal'][$captive_portal]['httpsname']) &&
1213
		    is_domain($config['captiveportal'][$captive_portal]['httpsname'])) {
1214
			$cp_hostcheck .= "\t\tif (\$http_host ~* {$config['captiveportal'][$captive_portal]['httpsname']}) {\n";
1215
			$cp_hostcheck .= "\t\t\tset \$cp_redirect no;\n";
1216
			$cp_hostcheck .= "\t\t}\n";
1217
		}
1218
		$cp_rewrite = "\t\tif (\$cp_redirect = '') {\n";
1219
		$cp_rewrite .= "\t\t\trewrite	^ /index.php?zone=$captive_portal&redirurl=\$request_uri break;\n";
1220
		$cp_rewrite .= "\t\t}\n";
1221

    
1222
		$maxprocperip = $config['captiveportal'][$captive_portal]['maxprocperip'];
1223
		if (empty($maxprocperip)) {
1224
			$maxprocperip = 10;
1225
		}
1226
		$captive_portal_maxprocperip = "\t\tlimit_conn addr $maxprocperip;\n";
1227

    
1228
	}
1229

    
1230
	if (empty($port)) {
1231
		$nginx_port = "80";
1232
	} else {
1233
		$nginx_port = $port;
1234
	}
1235

    
1236
	$memory = get_memory();
1237
	$realmem = $memory[1];
1238

    
1239
	// Determine web GUI process settings and take into account low memory systems
1240
	if ($realmem < 255) {
1241
		$max_procs = 1;
1242
	} else {
1243
		$max_procs = ($config['system']['webgui']['max_procs']) ? $config['system']['webgui']['max_procs'] : 2;
1244
	}
1245

    
1246
	// Ramp up captive portal max procs, assuming each PHP process can consume up to 64MB RAM
1247
	if ($captive_portal !== false) {
1248
		if ($realmem > 135 and $realmem < 256) {
1249
			$max_procs += 1; // 2 worker processes
1250
		} else if ($realmem > 255 and $realmem < 513) {
1251
			$max_procs += 2; // 3 worker processes
1252
		} else if ($realmem > 512) {
1253
			$max_procs += 4; // 6 worker processes
1254
		}
1255
	}
1256

    
1257
	$nginx_config = <<<EOD
1258
#
1259
# nginx configuration file
1260

    
1261
pid {$g['varrun_path']}/{$pid_file};
1262

    
1263
user  root wheel;
1264
worker_processes  {$max_procs};
1265

    
1266
EOD;
1267

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

    
1272
$nginx_config .= <<<EOD
1273

    
1274
events {
1275
    worker_connections  1024;
1276
}
1277

    
1278
http {
1279
	include       /usr/local/etc/nginx/mime.types;
1280
	default_type  application/octet-stream;
1281
	add_header X-Frame-Options SAMEORIGIN;
1282
	server_tokens off;
1283

    
1284
	sendfile        on;
1285
	keepalive_timeout  65;
1286

    
1287
	access_log      syslog:server=unix:/var/run/log,facility=local5 combined;
1288

    
1289
EOD;
1290

    
1291
if ($captive_portal !== false) {
1292
	$nginx_config .= "\tlimit_conn_zone \$binary_remote_addr zone=addr:10m;\n";
1293
}
1294

    
1295
$nginx_config .= <<<EOD
1296

    
1297
	server {
1298
		listen {$nginx_port};
1299
		listen [::]:{$nginx_port};
1300
		client_max_body_size 200m;
1301

    
1302
EOD;
1303

    
1304
	if ($cert <> "" and $key <> "") {
1305
		$nginx_config .= "\t\tssl             on;\n";
1306
		$nginx_config .= "\t\tssl_certificate         {$g['varetc_path']}/{$cert_location};\n";
1307
		$nginx_config .= "\t\tssl_certificate_key     {$g['varetc_path']}/{$key_location};\n";
1308
		$nginx_config .= "\t\tssl_session_timeout     10m;\n";
1309
		$nginx_config .= "\t\tkeepalive_timeout       70;\n";
1310
		$nginx_config .= "\t\tssl_session_cache       shared:SSL:10m;\n";
1311
		$nginx_config .= "\t\tssl_protocols   TLSv1 TLSv1.1 TLSv1.2;\n";
1312
		$nginx_config .= "\t\tssl_ciphers \"EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH\";\n";
1313
		$nginx_config .= "\t\tssl_prefer_server_ciphers       on;\n";
1314
		$nginx_config .= "\t\tadd_header Strict-Transport-Security \"max-age=31536000\";\n";
1315
		$nginx_config .= "\t\tadd_header X-Content-Type-Options nosniff;\n";
1316
		$nginx_config .= "\t\tssl_session_tickets off;\n";
1317
		$nginx_config .= "\t\tssl_stapling on;\n";
1318
		$nginx_config .= "\t\tssl_stapling_verify on;\n";
1319
		$nginx_config .= "\t\tssl_dhparam /etc/dh-parameters.4096;\n";
1320
		$nginx_config .= "\n";
1321
	}
1322

    
1323
	if ($captive_portal !== false) {
1324
		$nginx_config .= <<<EOD
1325
$captive_portal_maxprocperip
1326
$cp_hostcheck
1327
$cp_rewrite
1328

    
1329
EOD;
1330

    
1331
	}
1332

    
1333
	$nginx_config .= <<<EOD
1334
		root "{$document_root}";
1335
		location / {
1336
			index  index.html index.htm index.php;
1337
		}
1338

    
1339
		location ~ \.php$ {
1340
			try_files \$uri =404; #  This line closes a potential security hole
1341
			# ensuring users can't execute uploaded files
1342
			# see: http://forum.nginx.org/read.php?2,88845,page=3
1343
			fastcgi_pass   unix:{$g['varrun_path']}/php-fpm.socket;
1344
			fastcgi_index  index.php;
1345
			fastcgi_param  SCRIPT_FILENAME  \$document_root\$fastcgi_script_name;
1346
			include        /usr/local/etc/nginx/fastcgi_params;
1347
		}
1348
	}
1349

    
1350
EOD;
1351

    
1352
	$cert = str_replace("\r", "", $cert);
1353
	$key = str_replace("\r", "", $key);
1354

    
1355
	$cert = str_replace("\n\n", "\n", $cert);
1356
	$key = str_replace("\n\n", "\n", $key);
1357

    
1358
	if ($cert <> "" and $key <> "") {
1359
		$fd = fopen("{$g['varetc_path']}/{$cert_location}", "w");
1360
		if (!$fd) {
1361
			printf(gettext("Error: cannot open certificate file in system_webgui_start().%s"), "\n");
1362
			return 1;
1363
		}
1364
		chmod("{$g['varetc_path']}/{$cert_location}", 0600);
1365
		if ($ca <> "") {
1366
			$cert_chain = $cert . "\n" . $ca;
1367
		} else {
1368
			$cert_chain = $cert;
1369
		}
1370
		fwrite($fd, $cert_chain);
1371
		fclose($fd);
1372
		$fd = fopen("{$g['varetc_path']}/{$key_location}", "w");
1373
		if (!$fd) {
1374
			printf(gettext("Error: cannot open certificate key file in system_webgui_start().%s"), "\n");
1375
			return 1;
1376
		}
1377
		chmod("{$g['varetc_path']}/{$key_location}", 0600);
1378
		fwrite($fd, $key);
1379
		fclose($fd);
1380
	}
1381

    
1382
	// Add HTTP to HTTPS redirect
1383
	if ($captive_portal === false && $config['system']['webgui']['protocol'] == "https" && !isset($config['system']['webgui']['disablehttpredirect'])) {
1384
		if ($nginx_port != "443") {
1385
			$redirectport = ":{$nginx_port}";
1386
		}
1387
		$nginx_config .= <<<EOD
1388
	server {
1389
		listen 80;
1390
		listen [::]:80;
1391
		rewrite         ^ https://\$http_host$redirectport\$request_uri? permanent;
1392
	}
1393

    
1394
EOD;
1395
	}
1396

    
1397
	$nginx_config .= "}\n";
1398

    
1399
	$fd = fopen("{$filename}", "w");
1400
	if (!$fd) {
1401
		printf(gettext("Error: cannot open %s in system_generate_nginx_config().%s"), $filename, "\n");
1402
		return 1;
1403
	}
1404
	fwrite($fd, $nginx_config);
1405
	fclose($fd);
1406

    
1407
	/* nginx will fail to start if this directory does not exist. */
1408
	safe_mkdir("/var/tmp/nginx/");
1409

    
1410
	return 0;
1411

    
1412
}
1413

    
1414
function system_get_timezone_list() {
1415
	global $g;
1416

    
1417
	$file_list = array_merge(
1418
		glob("/usr/share/zoneinfo/[A-Z]*"),
1419
		glob("/usr/share/zoneinfo/*/*"),
1420
		glob("/usr/share/zoneinfo/*/*/*")
1421
	);
1422

    
1423
	if (empty($file_list)) {
1424
		$file_list[] = $g['default_timezone'];
1425
	} else {
1426
		/* Remove directories from list */
1427
		$file_list = array_filter($file_list, function($v) {
1428
			return !is_dir($v);
1429
		});
1430
	}
1431

    
1432
	/* Remove directory prefix */
1433
	$file_list = str_replace('/usr/share/zoneinfo/', '', $file_list);
1434

    
1435
	sort($file_list);
1436

    
1437
	return $file_list;
1438
}
1439

    
1440
function system_timezone_configure() {
1441
	global $config, $g;
1442
	if (isset($config['system']['developerspew'])) {
1443
		$mt = microtime();
1444
		echo "system_timezone_configure() being called $mt\n";
1445
	}
1446

    
1447
	$syscfg = $config['system'];
1448

    
1449
	if (platform_booting()) {
1450
		echo gettext("Setting timezone...");
1451
	}
1452

    
1453
	/* extract appropriate timezone file */
1454
	$timezone = (isset($syscfg['timezone']) ? $syscfg['timezone'] : $g['default_timezone']);
1455
	conf_mount_rw();
1456
	/* DO NOT remove \n otherwise tzsetup will fail */
1457
	@file_put_contents("/var/db/zoneinfo", $timezone . "\n");
1458
	mwexec("/usr/sbin/tzsetup -r");
1459
	conf_mount_ro();
1460

    
1461
	if (platform_booting()) {
1462
		echo gettext("done.") . "\n";
1463
	}
1464
}
1465

    
1466
function system_ntp_setup_gps($serialport) {
1467
	global $config, $g;
1468
	$gps_device = '/dev/gps0';
1469
	$serialport = '/dev/'.$serialport;
1470

    
1471
	if (!file_exists($serialport)) {
1472
		return false;
1473
	}
1474

    
1475
	conf_mount_rw();
1476
	// Create symlink that ntpd requires
1477
	unlink_if_exists($gps_device);
1478
	@symlink($serialport, $gps_device);
1479

    
1480
	$gpsbaud = '4800';
1481
	if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['speed'])) {
1482
		switch ($config['ntpd']['gps']['speed']) {
1483
			case '16':
1484
				$gpsbaud = '9600';
1485
				break;
1486
			case '32':
1487
				$gpsbaud = '19200';
1488
				break;
1489
			case '48':
1490
				$gpsbaud = '38400';
1491
				break;
1492
			case '64':
1493
				$gpsbaud = '57600';
1494
				break;
1495
			case '80':
1496
				$gpsbaud = '115200';
1497
				break;
1498
		}
1499
	}
1500

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

    
1504
	/* Send the following to the GPS port to initialize the GPS */
1505
	if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['type'])) {
1506
		$gps_init = base64_decode($config['ntpd']['gps']['initcmd']);
1507
	} else {
1508
		$gps_init = base64_decode('JFBVQlgsNDAsR1NWLDAsMCwwLDAqNTkNCiRQVUJYLDQwLEdMTCwwLDAsMCwwKjVDDQokUFVCWCw0MCxaREEsMCwwLDAsMCo0NA0KJFBVQlgsNDAsVlRHLDAsMCwwLDAqNUUNCiRQVUJYLDQwLEdTViwwLDAsMCwwKjU5DQokUFVCWCw0MCxHU0EsMCwwLDAsMCo0RQ0KJFBVQlgsNDAsR0dBLDAsMCwwLDANCiRQVUJYLDQwLFRYVCwwLDAsMCwwDQokUFVCWCw0MCxSTUMsMCwwLDAsMCo0Ng0KJFBVQlgsNDEsMSwwMDA3LDAwMDMsNDgwMCwwDQokUFVCWCw0MCxaREEsMSwxLDEsMQ==');
1509
	}
1510

    
1511
	/* XXX: Why not file_put_contents to the device */
1512
	@file_put_contents('/tmp/gps.init', $gps_init);
1513
	mwexec("cat /tmp/gps.init > {$serialport}");
1514

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

    
1520
	conf_mount_ro();
1521

    
1522
	return true;
1523
}
1524

    
1525
function system_ntp_setup_pps($serialport) {
1526
	global $config, $g;
1527

    
1528
	$pps_device = '/dev/pps0';
1529
	$serialport = '/dev/'.$serialport;
1530

    
1531
	if (!file_exists($serialport)) {
1532
		return false;
1533
	}
1534

    
1535
	conf_mount_rw();
1536
	// Create symlink that ntpd requires
1537
	unlink_if_exists($pps_device);
1538
	@symlink($serialport, $pps_device);
1539

    
1540
	conf_mount_ro();
1541

    
1542
	return true;
1543
}
1544

    
1545

    
1546
function system_ntp_configure($start_ntpd=true) {
1547
	global $config, $g;
1548

    
1549
	$driftfile = "/var/db/ntpd.drift";
1550
	$statsdir = "/var/log/ntp";
1551
	$gps_device = '/dev/gps0';
1552

    
1553
	safe_mkdir($statsdir);
1554

    
1555
	if (!is_array($config['ntpd'])) {
1556
		$config['ntpd'] = array();
1557
	}
1558

    
1559
	$ntpcfg = "# \n";
1560
	$ntpcfg .= "# pfSense ntp configuration file \n";
1561
	$ntpcfg .= "# \n\n";
1562
	$ntpcfg .= "tinker panic 0 \n";
1563

    
1564
	/* Add Orphan mode */
1565
	$ntpcfg .= "# Orphan mode stratum\n";
1566
	$ntpcfg .= 'tos orphan ';
1567
	if (!empty($config['ntpd']['orphan'])) {
1568
		$ntpcfg .= $config['ntpd']['orphan'];
1569
	} else {
1570
		$ntpcfg .= '12';
1571
	}
1572
	$ntpcfg .= "\n";
1573

    
1574
	/* Add PPS configuration */
1575
	if (is_array($config['ntpd']['pps']) && !empty($config['ntpd']['pps']['port']) &&
1576
	    file_exists('/dev/'.$config['ntpd']['pps']['port']) &&
1577
	    system_ntp_setup_pps($config['ntpd']['pps']['port'])) {
1578
		$ntpcfg .= "\n";
1579
		$ntpcfg .= "# PPS Setup\n";
1580
		$ntpcfg .= 'server 127.127.22.0';
1581
		$ntpcfg .= ' minpoll 4 maxpoll 4';
1582
		if (empty($config['ntpd']['pps']['prefer'])) { /*note: this one works backwards */
1583
			$ntpcfg .= ' prefer';
1584
		}
1585
		if (!empty($config['ntpd']['pps']['noselect'])) {
1586
			$ntpcfg .= ' noselect ';
1587
		}
1588
		$ntpcfg .= "\n";
1589
		$ntpcfg .= 'fudge 127.127.22.0';
1590
		if (!empty($config['ntpd']['pps']['fudge1'])) {
1591
			$ntpcfg .= ' time1 ';
1592
			$ntpcfg .= $config['ntpd']['pps']['fudge1'];
1593
		}
1594
		if (!empty($config['ntpd']['pps']['flag2'])) {
1595
			$ntpcfg .= ' flag2 1';
1596
		}
1597
		if (!empty($config['ntpd']['pps']['flag3'])) {
1598
			$ntpcfg .= ' flag3 1';
1599
		} else {
1600
			$ntpcfg .= ' flag3 0';
1601
		}
1602
		if (!empty($config['ntpd']['pps']['flag4'])) {
1603
			$ntpcfg .= ' flag4 1';
1604
		}
1605
		if (!empty($config['ntpd']['pps']['refid'])) {
1606
			$ntpcfg .= ' refid ';
1607
			$ntpcfg .= $config['ntpd']['pps']['refid'];
1608
		}
1609
		$ntpcfg .= "\n";
1610
	}
1611
	/* End PPS configuration */
1612

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

    
1689
	$ntpcfg .= "\n\n# Upstream Servers\n";
1690
	/* foreach through ntp servers and write out to ntpd.conf */
1691
	foreach (explode(' ', $config['system']['timeservers']) as $ts) {
1692
		$ntpcfg .= "server {$ts} iburst maxpoll 9";
1693
		if (substr_count($config['ntpd']['prefer'], $ts)) {
1694
			$ntpcfg .= ' prefer';
1695
		}
1696
		if (substr_count($config['ntpd']['noselect'], $ts)) {
1697
			$ntpcfg .= ' noselect';
1698
		}
1699
		$ntpcfg .= "\n";
1700
	}
1701
	unset($ts);
1702

    
1703
	$ntpcfg .= "\n\n";
1704
	$ntpcfg .= "disable monitor\n"; //prevent NTP reflection attack, see https://forum.pfsense.org/index.php/topic,67189.msg389132.html#msg389132
1705
	if (!empty($config['ntpd']['clockstats']) || !empty($config['ntpd']['loopstats']) || !empty($config['ntpd']['peerstats'])) {
1706
		$ntpcfg .= "enable stats\n";
1707
		$ntpcfg .= 'statistics';
1708
		if (!empty($config['ntpd']['clockstats'])) {
1709
			$ntpcfg .= ' clockstats';
1710
		}
1711
		if (!empty($config['ntpd']['loopstats'])) {
1712
			$ntpcfg .= ' loopstats';
1713
		}
1714
		if (!empty($config['ntpd']['peerstats'])) {
1715
			$ntpcfg .= ' peerstats';
1716
		}
1717
		$ntpcfg .= "\n";
1718
	}
1719
	$ntpcfg .= "statsdir {$statsdir}\n";
1720
	$ntpcfg .= 'logconfig =syncall +clockall';
1721
	if (!empty($config['ntpd']['logpeer'])) {
1722
		$ntpcfg .= ' +peerall';
1723
	}
1724
	if (!empty($config['ntpd']['logsys'])) {
1725
		$ntpcfg .= ' +sysall';
1726
	}
1727
	$ntpcfg .= "\n";
1728
	$ntpcfg .= "driftfile {$driftfile}\n";
1729
	/* Access restrictions */
1730
	$ntpcfg .= 'restrict default';
1731
	if (empty($config['ntpd']['kod'])) { /*note: this one works backwards */
1732
		$ntpcfg .= ' kod limited';
1733
	}
1734
	if (empty($config['ntpd']['nomodify'])) { /*note: this one works backwards */
1735
		$ntpcfg .= ' nomodify';
1736
	}
1737
	if (!empty($config['ntpd']['noquery'])) {
1738
		$ntpcfg .= ' noquery';
1739
	}
1740
	if (empty($config['ntpd']['nopeer'])) { /*note: this one works backwards */
1741
		$ntpcfg .= ' nopeer';
1742
	}
1743
	if (empty($config['ntpd']['notrap'])) { /*note: this one works backwards */
1744
		$ntpcfg .= ' notrap';
1745
	}
1746
	if (!empty($config['ntpd']['noserve'])) {
1747
		$ntpcfg .= ' noserve';
1748
	}
1749
	$ntpcfg .= "\nrestrict -6 default";
1750
	if (empty($config['ntpd']['kod'])) { /*note: this one works backwards */
1751
		$ntpcfg .= ' kod limited';
1752
	}
1753
	if (empty($config['ntpd']['nomodify'])) { /*note: this one works backwards */
1754
		$ntpcfg .= ' nomodify';
1755
	}
1756
	if (!empty($config['ntpd']['noquery'])) {
1757
		$ntpcfg .= ' noquery';
1758
	}
1759
	if (empty($config['ntpd']['nopeer'])) { /*note: this one works backwards */
1760
		$ntpcfg .= ' nopeer';
1761
	}
1762
	if (!empty($config['ntpd']['noserve'])) {
1763
		$ntpcfg .= ' noserve';
1764
	}
1765
	if (empty($config['ntpd']['notrap'])) { /*note: this one works backwards */
1766
		$ntpcfg .= ' notrap';
1767
	}
1768
	$ntpcfg .= "\n";
1769

    
1770
	/* A leapseconds file is really only useful if this clock is stratum 1 */
1771
	$ntpcfg .= "\n";
1772
	if (!empty($config['ntpd']['leapsec'])) {
1773
		$leapsec .= base64_decode($config['ntpd']['leapsec']);
1774
		file_put_contents('/var/db/leap-seconds', $leapsec);
1775
		$ntpcfg .= "leapfile /var/db/leap-seconds\n";
1776
	}
1777

    
1778

    
1779
	if (empty($config['ntpd']['interface'])) {
1780
		if (is_array($config['installedpackages']['openntpd']) && !empty($config['installedpackages']['openntpd']['config'][0]['interface'])) {
1781
			$interfaces = explode(",", $config['installedpackages']['openntpd']['config'][0]['interface']);
1782
		} else {
1783
			$interfaces = array();
1784
		}
1785
	} else {
1786
		$interfaces = explode(",", $config['ntpd']['interface']);
1787
	}
1788

    
1789
	if (is_array($interfaces) && count($interfaces)) {
1790
		$ntpcfg .= "interface ignore all\n";
1791
		foreach ($interfaces as $interface) {
1792
			if (strstr($interface, "_vip")) {
1793
				$interface = get_configured_carp_interface_list($interface);
1794
			}
1795
			if (!is_ipaddr($interface)) {
1796
				$interface = get_real_interface($interface);
1797
			}
1798
			if (!empty($interface)) {
1799
				$ntpcfg .= "interface listen {$interface}\n";
1800
			}
1801
		}
1802
	}
1803

    
1804
	/* open configuration for writing or bail */
1805
	if (!@file_put_contents("{$g['varetc_path']}/ntpd.conf", $ntpcfg)) {
1806
		log_error("Could not open {$g['varetc_path']}/ntpd.conf for writing");
1807
		return;
1808
	}
1809

    
1810
	/* At bootup we just want to write out the config. */
1811
	if (!$start_ntpd) {
1812
		return;
1813
	}
1814

    
1815
	/* if ntpd is running, kill it */
1816
	while (isvalidpid("{$g['varrun_path']}/ntpd.pid")) {
1817
		killbypid("{$g['varrun_path']}/ntpd.pid");
1818
	}
1819
	@unlink("{$g['varrun_path']}/ntpd.pid");
1820

    
1821
	/* if /var/empty does not exist, create it */
1822
	if (!is_dir("/var/empty")) {
1823
		mkdir("/var/empty", 0775, true);
1824
	}
1825

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

    
1829
	// Note that we are starting up
1830
	log_error("NTPD is starting up.");
1831
	return;
1832
}
1833

    
1834
function sync_system_time() {
1835
	global $config, $g;
1836

    
1837
	if (platform_booting()) {
1838
		echo gettext("Syncing system time before startup...");
1839
	}
1840

    
1841
	/* foreach through servers and write out to ntpd.conf */
1842
	foreach (explode(' ', $config['system']['timeservers']) as $ts) {
1843
		mwexec("/usr/local/sbin/ntpdate -s $ts");
1844
	}
1845

    
1846
	if (platform_booting()) {
1847
		echo gettext("done.") . "\n";
1848
	}
1849

    
1850
}
1851

    
1852
function system_halt() {
1853
	global $g;
1854

    
1855
	system_reboot_cleanup();
1856

    
1857
	mwexec("/usr/bin/nohup /etc/rc.halt > /dev/null 2>&1 &");
1858
}
1859

    
1860
function system_reboot() {
1861
	global $g;
1862

    
1863
	system_reboot_cleanup();
1864

    
1865
	mwexec("nohup /etc/rc.reboot > /dev/null 2>&1 &");
1866
}
1867

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

    
1871
	system_reboot_cleanup();
1872

    
1873
	mwexec("/etc/rc.reboot > /dev/null 2>&1");
1874
}
1875

    
1876
function system_reboot_cleanup() {
1877
	global $config, $cpzone;
1878

    
1879
	mwexec("/usr/local/bin/beep.sh stop");
1880
	require_once("captiveportal.inc");
1881
	if (is_array($config['captiveportal'])) {
1882
		foreach ($config['captiveportal'] as $cpzone=>$cp) {
1883
			captiveportal_radius_stop_all();
1884
			captiveportal_send_server_accounting(true);
1885
		}
1886
	}
1887
	require_once("voucher.inc");
1888
	voucher_save_db_to_config();
1889
	require_once("pkg-utils.inc");
1890
	stop_packages();
1891
}
1892

    
1893
function system_do_shell_commands($early = 0) {
1894
	global $config, $g;
1895
	if (isset($config['system']['developerspew'])) {
1896
		$mt = microtime();
1897
		echo "system_do_shell_commands() being called $mt\n";
1898
	}
1899

    
1900
	if ($early) {
1901
		$cmdn = "earlyshellcmd";
1902
	} else {
1903
		$cmdn = "shellcmd";
1904
	}
1905

    
1906
	if (is_array($config['system'][$cmdn])) {
1907

    
1908
		/* *cmd is an array, loop through */
1909
		foreach ($config['system'][$cmdn] as $cmd) {
1910
			exec($cmd);
1911
		}
1912

    
1913
	} elseif ($config['system'][$cmdn] <> "") {
1914

    
1915
		/* execute single item */
1916
		exec($config['system'][$cmdn]);
1917

    
1918
	}
1919
}
1920

    
1921
function system_console_configure() {
1922
	global $config, $g;
1923
	if (isset($config['system']['developerspew'])) {
1924
		$mt = microtime();
1925
		echo "system_console_configure() being called $mt\n";
1926
	}
1927

    
1928
	if (isset($config['system']['disableconsolemenu'])) {
1929
		touch("{$g['varetc_path']}/disableconsole");
1930
	} else {
1931
		unlink_if_exists("{$g['varetc_path']}/disableconsole");
1932
	}
1933
}
1934

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

    
1942
	$dmesg = "";
1943
	$_gb = exec("/sbin/dmesg", $dmesg);
1944

    
1945
	/* find last copyright line (output from previous boots may be present) */
1946
	$lastcpline = 0;
1947

    
1948
	for ($i = 0; $i < count($dmesg); $i++) {
1949
		if (strstr($dmesg[$i], "Copyright (c) 1992-")) {
1950
			$lastcpline = $i;
1951
		}
1952
	}
1953

    
1954
	$fd = fopen("{$g['varlog_path']}/dmesg.boot", "w");
1955
	if (!$fd) {
1956
		printf(gettext("Error: cannot open dmesg.boot in system_dmesg_save().%s"), "\n");
1957
		return 1;
1958
	}
1959

    
1960
	for ($i = $lastcpline; $i < count($dmesg); $i++) {
1961
		fwrite($fd, $dmesg[$i] . "\n");
1962
	}
1963

    
1964
	fclose($fd);
1965
	unset($dmesg);
1966

    
1967
	return 0;
1968
}
1969

    
1970
function system_set_harddisk_standby() {
1971
	global $g, $config;
1972

    
1973
	if (isset($config['system']['developerspew'])) {
1974
		$mt = microtime();
1975
		echo "system_set_harddisk_standby() being called $mt\n";
1976
	}
1977

    
1978
	if (isset($config['system']['harddiskstandby'])) {
1979
		if (platform_booting()) {
1980
			echo gettext('Setting hard disk standby... ');
1981
		}
1982

    
1983
		$standby = $config['system']['harddiskstandby'];
1984
		// Check for a numeric value
1985
		if (is_numeric($standby)) {
1986
			// Get only suitable candidates for standby; using get_smart_drive_list()
1987
			// from utils.inc to get the list of drives.
1988
			$harddisks = get_smart_drive_list();
1989

    
1990
			// Since get_smart_drive_list() only matches ad|da|ada; lets put the check below
1991
			// just in case of some weird pfSense platform installs.
1992
			if (count($harddisks) > 0) {
1993
				// Iterate disks and run the camcontrol command for each
1994
				foreach ($harddisks as $harddisk) {
1995
					mwexec("/sbin/camcontrol standby {$harddisk} -t {$standby}");
1996
				}
1997
				if (platform_booting()) {
1998
					echo gettext("done.") . "\n";
1999
				}
2000
			} else if (platform_booting()) {
2001
				echo gettext("failed!") . "\n";
2002
			}
2003
		} else if (platform_booting()) {
2004
			echo gettext("failed!") . "\n";
2005
		}
2006
	}
2007
}
2008

    
2009
function system_setup_sysctl() {
2010
	global $config;
2011
	if (isset($config['system']['developerspew'])) {
2012
		$mt = microtime();
2013
		echo "system_setup_sysctl() being called $mt\n";
2014
	}
2015

    
2016
	activate_sysctls();
2017

    
2018
	if (isset($config['system']['sharednet'])) {
2019
		system_disable_arp_wrong_if();
2020
	}
2021
}
2022

    
2023
function system_disable_arp_wrong_if() {
2024
	global $config;
2025
	if (isset($config['system']['developerspew'])) {
2026
		$mt = microtime();
2027
		echo "system_disable_arp_wrong_if() being called $mt\n";
2028
	}
2029
	set_sysctl(array(
2030
		"net.link.ether.inet.log_arp_wrong_iface" => "0",
2031
		"net.link.ether.inet.log_arp_movements" => "0"
2032
	));
2033
}
2034

    
2035
function system_enable_arp_wrong_if() {
2036
	global $config;
2037
	if (isset($config['system']['developerspew'])) {
2038
		$mt = microtime();
2039
		echo "system_enable_arp_wrong_if() being called $mt\n";
2040
	}
2041
	set_sysctl(array(
2042
		"net.link.ether.inet.log_arp_wrong_iface" => "1",
2043
		"net.link.ether.inet.log_arp_movements" => "1"
2044
	));
2045
}
2046

    
2047
function enable_watchdog() {
2048
	global $config;
2049
	return;
2050
	$install_watchdog = false;
2051
	$supported_watchdogs = array("Geode");
2052
	$file = file_get_contents("/var/log/dmesg.boot");
2053
	foreach ($supported_watchdogs as $sd) {
2054
		if (stristr($file, "Geode")) {
2055
			$install_watchdog = true;
2056
		}
2057
	}
2058
	if ($install_watchdog == true) {
2059
		if (is_process_running("watchdogd")) {
2060
			mwexec("/usr/bin/killall watchdogd", true);
2061
		}
2062
		exec("/usr/sbin/watchdogd");
2063
	}
2064
}
2065

    
2066
function system_check_reset_button() {
2067
	global $g;
2068

    
2069
	$specplatform = system_identify_specific_platform();
2070

    
2071
	switch ($specplatform['name']) {
2072
		case 'alix':
2073
		case 'wrap':
2074
		case 'FW7541':
2075
		case 'APU':
2076
		case 'RCC-VE':
2077
		case 'RCC-DFF':
2078
			break;
2079
		default:
2080
			return 0;
2081
	}
2082

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

    
2085
	if ($retval == 99) {
2086
		/* user has pressed reset button for 2 seconds -
2087
		   reset to factory defaults */
2088
		echo <<<EOD
2089

    
2090
***********************************************************************
2091
* Reset button pressed - resetting configuration to factory defaults. *
2092
* The system will reboot after this completes.                        *
2093
***********************************************************************
2094

    
2095

    
2096
EOD;
2097

    
2098
		reset_factory_defaults();
2099
		system_reboot_sync();
2100
		exit(0);
2101
	}
2102

    
2103
	return 0;
2104
}
2105

    
2106
/*
2107
 * attempt to identify the specific platform (for embedded systems)
2108
 * Returns an array with two elements:
2109
 * name => platform string (e.g. 'wrap', 'alix' etc.)
2110
 * descr => human-readable description (e.g. "PC Engines WRAP")
2111
 */
2112
function system_identify_specific_platform() {
2113
	global $g;
2114

    
2115
	if ($g['platform'] == 'generic-pc') {
2116
		return array('name' => 'generic-pc', 'descr' => gettext("Generic PC"));
2117
	}
2118

    
2119
	if ($g['platform'] == 'generic-pc-cdrom') {
2120
		return array('name' => 'generic-pc-cdrom', 'descr' => gettext("Generic PC (CD-ROM)"));
2121
	}
2122

    
2123
	/* Try to guess from smbios strings */
2124
	unset($output);
2125
	$_gb = exec('/bin/kenv smbios.system.product 2>/dev/null', $output);
2126
	switch ($output[0]) {
2127
		case 'FW7541':
2128
			return (array('name' => 'FW7541', 'descr' => 'Netgate FW7541'));
2129
			break;
2130
		case 'APU':
2131
			return (array('name' => 'APU', 'descr' => 'Netgate APU'));
2132
			break;
2133
		case 'RCC-VE':
2134
			return (array('name' => 'RCC-VE', 'descr' => 'Netgate RCC-VE'));
2135
			break;
2136
		case 'DFFv2':
2137
			return (array('name' => 'RCC-DFF', 'descr' => 'Netgate RCC-DFF'));
2138
			break;
2139
		case 'SYS-5018A-FTN4':
2140
		case 'A1SAi':
2141
			return (array('name' => 'C2758', 'descr' => 'Super Micro C2758'));
2142
			break;
2143
		case 'SYS-5018D-FN4T':
2144
			return (array('name' => 'D1540-XG', 'descr' => 'Super Micro D1540-XG'));
2145
			break;
2146
	}
2147

    
2148
	/* the rest of the code only deals with 'embedded' platforms */
2149
	if ($g['platform'] != 'nanobsd') {
2150
		return array('name' => $g['platform'], 'descr' => $g['platform']);
2151
	}
2152

    
2153
	$dmesg = get_single_sysctl('hw.model');
2154

    
2155
	if (strpos($dmesg, "PC Engines WRAP") !== false) {
2156
		return array('name' => 'wrap', 'descr' => gettext('PC Engines WRAP'));
2157
	}
2158

    
2159
	if (strpos($dmesg, "PC Engines ALIX") !== false) {
2160
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
2161
	}
2162

    
2163
	if (preg_match("/Soekris net45../", $dmesg, $matches)) {
2164
		return array('name' => 'net45xx', 'descr' => $matches[0]);
2165
	}
2166

    
2167
	if (preg_match("/Soekris net48../", $dmesg, $matches)) {
2168
		return array('name' => 'net48xx', 'descr' => $matches[0]);
2169
	}
2170

    
2171
	if (preg_match("/Soekris net55../", $dmesg, $matches)) {
2172
		return array('name' => 'net55xx', 'descr' => $matches[0]);
2173
	}
2174

    
2175
	unset($dmesg);
2176

    
2177
	$dmesg_boot = system_get_dmesg_boot();
2178
	if (strpos($dmesg_boot, "PC Engines ALIX") !== false) {
2179
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
2180
	}
2181
	unset($dmesg_boot);
2182

    
2183
	/* unknown embedded platform */
2184
	return array('name' => 'embedded', 'descr' => gettext('embedded (unknown)'));
2185
}
2186

    
2187
function system_get_dmesg_boot() {
2188
	global $g;
2189

    
2190
	return file_get_contents("{$g['varlog_path']}/dmesg.boot");
2191
}
2192

    
2193
?>
(52-52/65)