Project

General

Profile

Download (62.4 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	system.inc
4
	part of m0n0wall (http://m0n0.ch/wall)
5

    
6
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
7
	All rights reserved.
8

    
9
	Redistribution and use in source and binary forms, with or without
10
	modification, are permitted provided that the following conditions are met:
11

    
12
	1. Redistributions of source code must retain the above copyright notice,
13
	   this list of conditions and the following disclaimer.
14

    
15
	2. Redistributions in binary form must reproduce the above copyright
16
	   notice, this list of conditions and the following disclaimer in the
17
	   documentation and/or other materials provided with the distribution.
18

    
19
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
20
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
21
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
22
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
23
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28
	POSSIBILITY OF SUCH DAMAGE.
29
*/
30

    
31
function activate_powerd() {
32
	global $config, $g;
33

    
34
	if (is_process_running("powerd")) {
35
		exec("/usr/bin/killall powerd");
36
	}
37
	if (isset($config['system']['powerd_enable'])) {
38
		if ($g["platform"] == "nanobsd") {
39
			exec("/sbin/kldload cpufreq");
40
		}
41

    
42
		$ac_mode = "hadp";
43
		if (!empty($config['system']['powerd_ac_mode'])) {
44
			$ac_mode = $config['system']['powerd_ac_mode'];
45
		}
46

    
47
		$battery_mode = "hadp";
48
		if (!empty($config['system']['powerd_battery_mode'])) {
49
			$battery_mode = $config['system']['powerd_battery_mode'];
50
		}
51

    
52
		$normal_mode = "hadp";
53
		if (!empty($config['system']['powerd_normal_mode'])) {
54
			$normal_mode = $config['system']['powerd_normal_mode'];
55
		}
56

    
57
		mwexec("/usr/sbin/powerd -b $battery_mode -a $ac_mode -n $normal_mode");
58
	}
59
}
60

    
61
function get_default_sysctl_value($id) {
62
	global $sysctls;
63

    
64
	if (isset($sysctls[$id])) {
65
		return $sysctls[$id];
66
	}
67
}
68

    
69
function get_sysctl_descr($sysctl) {
70
	unset($output);
71
	$_gb = exec("/sbin/sysctl -nd {$sysctl}", $output);
72

    
73
	return $output[0];
74
}
75

    
76
function system_get_sysctls() {
77
	global $config, $sysctls;
78

    
79
	$disp_sysctl = array();
80
	$disp_cache = array();
81
	if (is_array($config['sysctl']) && is_array($config['sysctl']['item'])) {
82
		foreach ($config['sysctl']['item'] as $id => $tunable) {
83
			if ($tunable['value'] == "default") {
84
				$value = get_default_sysctl_value($tunable['tunable']);
85
			} else {
86
				$value = $tunable['value'];
87
			}
88

    
89
			$disp_sysctl[$id] = $tunable;
90
			$disp_sysctl[$id]['modified'] = true;
91
			$disp_cache[$tunable['tunable']] = 'set';
92
		}
93
	}
94

    
95
	foreach ($sysctls as $sysctl => $value) {
96
		if (isset($disp_cache[$sysctl])) {
97
			continue;
98
		}
99

    
100
		$disp_sysctl[$sysctl] = array('tunable' => $sysctl, 'value' => $value, 'descr' => get_sysctl_descr($sysctl));
101
	}
102
	unset($disp_cache);
103
	return $disp_sysctl;
104
}
105

    
106
function activate_sysctls() {
107
	global $config, $g, $sysctls;
108

    
109
	if (is_array($config['sysctl']) && is_array($config['sysctl']['item'])) {
110
		foreach ($config['sysctl']['item'] as $tunable) {
111
			if ($tunable['value'] == "default") {
112
				$value = get_default_sysctl_value($tunable['tunable']);
113
			} else {
114
				$value = $tunable['value'];
115
			}
116

    
117
			$sysctls[$tunable['tunable']] = $value;
118
		}
119
	}
120

    
121
	set_sysctl($sysctls);
122
}
123

    
124
function system_resolvconf_generate($dynupdate = false) {
125
	global $config, $g;
126

    
127
	if (isset($config['system']['developerspew'])) {
128
		$mt = microtime();
129
		echo "system_resolvconf_generate() being called $mt\n";
130
	}
131

    
132
	$syscfg = $config['system'];
133

    
134
	if ((((isset($config['dnsmasq']['enable'])) &&
135
	      (!isset($config['dnsmasq']['port']) || $config['dnsmasq']['port'] == "53") &&
136
	      (empty($config['dnsmasq']['interface']) ||
137
	       in_array("lo0", explode(",", $config['dnsmasq']['interface'])))) ||
138
	     ((isset($config['unbound']['enable'])) &&
139
	      (!isset($config['unbound']['port']) || $config['unbound']['port'] == "53") &&
140
	      (empty($config['unbound']['active_interface']) ||
141
	       in_array("lo0", explode(",", $config['unbound']['active_interface'])) ||
142
	       in_array("all", explode(",", $config['unbound']['active_interface']), true)))) &&
143
	     (!isset($config['system']['dnslocalhost']))) {
144
		$resolvconf .= "nameserver 127.0.0.1\n";
145
	}
146

    
147
	if (isset($syscfg['dnsallowoverride'])) {
148
		/* get dynamically assigned DNS servers (if any) */
149
		$ns = array_unique(get_searchdomains());
150
		foreach ($ns as $searchserver) {
151
			if ($searchserver) {
152
				$resolvconf .= "search {$searchserver}\n";
153
			}
154
		}
155
		$ns = array_unique(get_nameservers());
156
		foreach ($ns as $nameserver) {
157
			if ($nameserver) {
158
				$resolvconf .= "nameserver $nameserver\n";
159
			}
160
		}
161
	} else {
162
		$ns = array();
163
		// Do not create blank search/domain lines, it can break tools like dig.
164
		if ($syscfg['domain']) {
165
			$resolvconf .= "search {$syscfg['domain']}\n";
166
		}
167
	}
168
	if (is_array($syscfg['dnsserver'])) {
169
		foreach ($syscfg['dnsserver'] as $sys_dnsserver) {
170
			if ($sys_dnsserver && (!in_array($sys_dnsserver, $ns))) {
171
				$resolvconf .= "nameserver $sys_dnsserver\n";
172
			}
173
		}
174
	}
175

    
176
	// Add EDNS support
177
	if (isset($config['unbound']['enable']) && isset($config['unbound']['edns'])) {
178
		$resolvconf .= "options edns0\n";
179
	}
180

    
181
	$dnslock = lock('resolvconf', LOCK_EX);
182

    
183
	$fd = fopen("{$g['varetc_path']}/resolv.conf", "w");
184
	if (!$fd) {
185
		printf("Error: cannot open resolv.conf in system_resolvconf_generate().\n");
186
		unlock($dnslock);
187
		return 1;
188
	}
189

    
190
	fwrite($fd, $resolvconf);
191
	fclose($fd);
192

    
193
	// Prevent resolvconf(8) from rewriting our resolv.conf
194
	$fd = fopen("{$g['varetc_path']}/resolvconf.conf", "w");
195
	if (!$fd) {
196
		printf("Error: cannot open resolvconf.conf in system_resolvconf_generate().\n");
197
		return 1;
198
	}
199
	fwrite($fd, "resolv_conf=\"/dev/null\"\n");
200
	fclose($fd);
201

    
202
	if (!platform_booting()) {
203
		/* restart dhcpd (nameservers may have changed) */
204
		if (!$dynupdate) {
205
			services_dhcpd_configure();
206
		}
207
	}
208

    
209
	/* setup static routes for DNS servers. */
210
	for ($dnscounter=1; $dnscounter<5; $dnscounter++) {
211
		/* setup static routes for dns servers */
212
		$dnsgw = "dns{$dnscounter}gw";
213
		if (isset($config['system'][$dnsgw])) {
214
			$gwname = $config['system'][$dnsgw];
215
			if (($gwname <> "") && ($gwname <> "none")) {
216
				$gatewayip = lookup_gateway_ip_by_name($gwname);
217
				if (is_ipaddrv4($gatewayip)) {
218
					/* dns server array starts at 0 */
219
					$dnscountermo = $dnscounter - 1;
220
					mwexec("/sbin/route change -host " . $syscfg['dnsserver'][$dnscountermo] . " {$gatewayip}");
221
					if (isset($config['system']['route-debug'])) {
222
						$mt = microtime();
223
						log_error("ROUTING debug: $mt - route change -host {$syscfg['dnsserver'][$dnscountermo]} $gatewayip ");
224
					}
225
				}
226
				if (is_ipaddrv6($gatewayip)) {
227
					/* dns server array starts at 0 */
228
					$dnscountermo = $dnscounter - 1;
229
					mwexec("/sbin/route change -host -inet6 " . $syscfg['dnsserver'][$dnscountermo] . " {$gatewayip}");
230
					if (isset($config['system']['route-debug'])) {
231
						$mt = microtime();
232
						log_error("ROUTING debug: $mt - route change -host -inet6 {$syscfg['dnsserver'][$dnscountermo]} $gatewayip ");
233
					}
234
				}
235
			}
236
		}
237
	}
238

    
239
	unlock($dnslock);
240

    
241
	return 0;
242
}
243

    
244
function get_searchdomains() {
245
	global $config, $g;
246

    
247
	$master_list = array();
248

    
249
	// Read in dhclient nameservers
250
	$search_list = glob("/var/etc/searchdomain_*");
251
	if (is_array($search_list)) {
252
		foreach ($search_list as $fdns) {
253
			$contents = file($fdns, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
254
			if (!is_array($contents)) {
255
				continue;
256
			}
257
			foreach ($contents as $dns) {
258
				if (is_hostname($dns)) {
259
					$master_list[] = $dns;
260
				}
261
			}
262
		}
263
	}
264

    
265
	return $master_list;
266
}
267

    
268
function get_nameservers() {
269
	global $config, $g;
270
	$master_list = array();
271

    
272
	// Read in dhclient nameservers
273
	$dns_lists = glob("/var/etc/nameserver_*");
274
	if (is_array($dns_lists)) {
275
		foreach ($dns_lists as $fdns) {
276
			$contents = file($fdns, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
277
			if (!is_array($contents)) {
278
				continue;
279
			}
280
			foreach ($contents as $dns) {
281
				if (is_ipaddr($dns)) {
282
					$master_list[] = $dns;
283
				}
284
			}
285
		}
286
	}
287

    
288
	// Read in any extra nameservers
289
	if (file_exists("/var/etc/nameservers.conf")) {
290
		$dns_s = file("/var/etc/nameservers.conf", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
291
		if (is_array($dns_s)) {
292
			foreach ($dns_s as $dns) {
293
				if (is_ipaddr($dns)) {
294
					$master_list[] = $dns;
295
				}
296
			}
297
		}
298
	}
299

    
300
	return $master_list;
301
}
302

    
303
function system_hosts_generate() {
304
	global $config, $g;
305
	if (isset($config['system']['developerspew'])) {
306
		$mt = microtime();
307
		echo "system_hosts_generate() being called $mt\n";
308
	}
309

    
310
	$syscfg = $config['system'];
311
	if (isset($config['unbound']) && isset($config['unbound']['enable'])) {
312
		$dnsmasqcfg = $config['unbound'];
313
	} else {
314
		$dnsmasqcfg = $config['dnsmasq'];
315
	}
316

    
317
	$hosts = "127.0.0.1	localhost localhost.{$syscfg['domain']}\n";
318
	$hosts .= "::1		localhost localhost.{$syscfg['domain']}\n";
319
	$lhosts = "";
320
	$dhosts = "";
321

    
322
	if ($config['interfaces']['lan']) {
323
		$cfgip = get_interface_ip("lan");
324
		if (is_ipaddr($cfgip)) {
325
			$hosts .= "{$cfgip}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
326
		}
327
		$cfgipv6 = get_interface_ipv6("lan");
328
		if (is_ipaddrv6($cfgipv6)) {
329
			$hosts .= "{$cfgipv6}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
330
		}
331
	} else {
332
		$sysiflist = get_configured_interface_list();
333
		$hosts_if_found = false;
334
		foreach ($sysiflist as $sysif) {
335
			if (!interface_has_gateway($sysif)) {
336
				$cfgip = get_interface_ip($sysif);
337
				if (is_ipaddr($cfgip)) {
338
					$hosts .= "{$cfgip}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
339
					$hosts_if_found = true;
340
				}
341
				$cfgipv6 = get_interface_ipv6($sysif);
342
				if (is_ipaddrv6($cfgipv6)) {
343
					$hosts .= "{$cfgipv6}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
344
					$hosts_if_found = true;
345
				}
346
				if ($hosts_if_found == true) {
347
					break;
348
				}
349
			}
350
		}
351
	}
352

    
353
	if (isset($dnsmasqcfg['enable'])) {
354
		if (!is_array($dnsmasqcfg['hosts'])) {
355
			$dnsmasqcfg['hosts'] = array();
356
		}
357

    
358
		foreach ($dnsmasqcfg['hosts'] as $host) {
359
			if ($host['host'] || $host['host'] == "0") {
360
				$lhosts .= "{$host['ip']}	{$host['host']}.{$host['domain']} {$host['host']}\n";
361
			} else {
362
				$lhosts .= "{$host['ip']}	{$host['domain']}\n";
363
			}
364
			if (!is_array($host['aliases']) || !is_array($host['aliases']['item'])) {
365
				continue;
366
			}
367
			foreach ($host['aliases']['item'] as $alias) {
368
				if ($alias['host'] || $alias['host'] == "0") {
369
					$lhosts .= "{$host['ip']}	{$alias['host']}.{$alias['domain']} {$alias['host']}\n";
370
				} else {
371
					$lhosts .= "{$host['ip']}	{$alias['domain']}\n";
372
				}
373
			}
374
		}
375
		if (isset($dnsmasqcfg['regdhcpstatic']) && is_array($config['dhcpd'])) {
376
			foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) {
377
				if (is_array($dhcpifconf['staticmap']) && isset($dhcpifconf['enable'])) {
378
					foreach ($dhcpifconf['staticmap'] as $host) {
379
						if ($host['ipaddr'] && $host['hostname'] && $host['domain']) {
380
							$dhosts .= "{$host['ipaddr']}	{$host['hostname']}.{$host['domain']} {$host['hostname']}\n";
381
						} else if ($host['ipaddr'] && $host['hostname'] && $dhcpifconf['domain']) {
382
							$dhosts .= "{$host['ipaddr']}	{$host['hostname']}.{$dhcpifconf['domain']} {$host['hostname']}\n";
383
						} else if ($host['ipaddr'] && $host['hostname']) {
384
							$dhosts .= "{$host['ipaddr']}	{$host['hostname']}.{$syscfg['domain']} {$host['hostname']}\n";
385
						}
386
					}
387
				}
388
			}
389
		}
390
		if (isset($dnsmasqcfg['regdhcpstatic']) && is_array($config['dhcpdv6'])) {
391
			foreach ($config['dhcpdv6'] as $dhcpif => $dhcpifconf) {
392
				if (is_array($dhcpifconf['staticmap']) && isset($dhcpifconf['enable'])) {
393
					foreach ($dhcpifconf['staticmap'] as $host) {
394
						if ($host['ipaddrv6'] && $host['hostname'] && $host['domain']) {
395
							$dhosts .= "{$host['ipaddrv6']}	{$host['hostname']}.{$host['domain']} {$host['hostname']}\n";
396
						} else if ($host['ipaddrv6'] && $host['hostname'] && $dhcpifconf['domain']) {
397
							$dhosts .= "{$host['ipaddrv6']}	{$host['hostname']}.{$dhcpifconf['domain']} {$host['hostname']}\n";
398
						} else if ($host['ipaddrv6'] && $host['hostname']) {
399
							$dhosts .= "{$host['ipaddrv6']}	{$host['hostname']}.{$syscfg['domain']} {$host['hostname']}\n";
400
						}
401
					}
402
				}
403
			}
404
		}
405

    
406
		if (isset($dnsmasqcfg['dhcpfirst'])) {
407
			$hosts .= $dhosts . $lhosts;
408
		} else {
409
			$hosts .= $lhosts . $dhosts;
410
		}
411
	}
412

    
413
	/*
414
	 * Do not remove this because dhcpleases monitors with kqueue it needs to be
415
	 * killed before writing to hosts files.
416
	 */
417
	if (file_exists("{$g['varrun_path']}/dhcpleases.pid")) {
418
		sigkillbypid("{$g['varrun_path']}/dhcpleases.pid", "TERM");
419
		@unlink("{$g['varrun_path']}/dhcpleases.pid");
420
	}
421
	$fd = fopen("{$g['varetc_path']}/hosts", "w");
422
	if (!$fd) {
423
		log_error("Error: cannot open hosts file in system_hosts_generate().\n");
424
		return 1;
425
	}
426
	fwrite($fd, $hosts);
427
	fclose($fd);
428

    
429
	if (isset($config['unbound']['enable'])) {
430
		require_once("unbound.inc");
431
		unbound_hosts_generate();
432
	}
433

    
434
	return 0;
435
}
436

    
437
function system_dhcpleases_configure() {
438
	global $config, $g;
439

    
440
	/* Start the monitoring process for dynamic dhcpclients. */
441
	if ((isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcp'])) ||
442
	    (isset($config['unbound']['enable']) && isset($config['unbound']['regdhcp']))) {
443
		/* Make sure we do not error out */
444
		mwexec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/db");
445
		if (!file_exists("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases")) {
446
			@touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
447
		}
448

    
449
		if (isset($config['unbound']['enable'])) {
450
			$dns_pid = "unbound.pid";
451
			$unbound_conf = "-u {$g['unbound_chroot_path']}/dhcpleases_entries.conf";
452
		} else {
453
			$dns_pid = "dnsmasq.pid";
454
			$unbound_conf = "";
455
		}
456

    
457
		$pidfile = "{$g['varrun_path']}/dhcpleases.pid";
458
		if (isvalidpid($pidfile)) {
459
			/* Make sure dhcpleases is using correct unbound or dnsmasq */
460
			$_gb = exec("/bin/pgrep -F {$pidfile} -f {$dns_pid}", $output, $retval);
461
			if (intval($retval) == 0) {
462
				sigkillbypid($pidfile, "HUP");
463
				return;
464
			} else {
465
				sigkillbypid($pidfile, "TERM");
466
			}
467
		}
468

    
469
		/* To ensure we do not start multiple instances of dhcpleases, perform some clean-up first. */
470
		if (is_process_running("dhcpleases")) {
471
			sigkillbyname('dhcpleases', "TERM");
472
		}
473
		@unlink($pidfile);
474
		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");
475
	} else {
476
		sigkillbypid($pidfile, "TERM");
477
		@unlink($pidfile);
478
	}
479
}
480

    
481
function system_hostname_configure() {
482
	global $config, $g;
483
	if (isset($config['system']['developerspew'])) {
484
		$mt = microtime();
485
		echo "system_hostname_configure() being called $mt\n";
486
	}
487

    
488
	$syscfg = $config['system'];
489

    
490
	/* set hostname */
491
	$status = mwexec("/bin/hostname " .
492
		escapeshellarg("{$syscfg['hostname']}.{$syscfg['domain']}"));
493

    
494
	/* Setup host GUID ID.  This is used by ZFS. */
495
	mwexec("/etc/rc.d/hostid start");
496

    
497
	return $status;
498
}
499

    
500
function system_routing_configure($interface = "") {
501
	global $config, $g;
502

    
503
	if (isset($config['system']['developerspew'])) {
504
		$mt = microtime();
505
		echo "system_routing_configure() being called $mt\n";
506
	}
507

    
508
	$gatewayip = "";
509
	$interfacegw = "";
510
	$gatewayipv6 = "";
511
	$interfacegwv6 = "";
512
	$foundgw = false;
513
	$foundgwv6 = false;
514
	/* tack on all the hard defined gateways as well */
515
	if (is_array($config['gateways']['gateway_item'])) {
516
		array_map('unlink', glob("{$g['tmp_path']}/*_defaultgw{,v6}", GLOB_BRACE));
517
		foreach	($config['gateways']['gateway_item'] as $gateway) {
518
			if (isset($gateway['defaultgw'])) {
519
				if ($foundgw == false && ($gateway['ipprotocol'] != "inet6" && (is_ipaddrv4($gateway['gateway']) || $gateway['gateway'] == "dynamic"))) {
520
					if (strpos($gateway['gateway'], ":")) {
521
						continue;
522
					}
523
					if ($gateway['gateway'] == "dynamic") {
524
						$gateway['gateway'] = get_interface_gateway($gateway['interface']);
525
					}
526
					$gatewayip = $gateway['gateway'];
527
					$interfacegw = $gateway['interface'];
528
					if (!empty($gateway['interface'])) {
529
						$defaultif = get_real_interface($gateway['interface']);
530
						if ($defaultif) {
531
							@file_put_contents("{$g['tmp_path']}/{$defaultif}_defaultgw", $gateway['gateway']);
532
						}
533
					}
534
					$foundgw = true;
535
				} else if ($foundgwv6 == false && ($gateway['ipprotocol'] == "inet6" && (is_ipaddrv6($gateway['gateway']) || $gateway['gateway'] == "dynamic"))) {
536
					if ($gateway['gateway'] == "dynamic") {
537
						$gateway['gateway'] = get_interface_gateway_v6($gateway['interface']);
538
					}
539
					$gatewayipv6 = $gateway['gateway'];
540
					$interfacegwv6 = $gateway['interface'];
541
					if (!empty($gateway['interface'])) {
542
						$defaultifv6 = get_real_interface($gateway['interface']);
543
						if ($defaultifv6) {
544
							@file_put_contents("{$g['tmp_path']}/{$defaultifv6}_defaultgwv6", $gateway['gateway']);
545
						}
546
					}
547
					$foundgwv6 = true;
548
				}
549
			}
550
			if ($foundgw === true && $foundgwv6 === true) {
551
				break;
552
			}
553
		}
554
	}
555
	if ($foundgw == false) {
556
		$defaultif = get_real_interface("wan");
557
		$interfacegw = "wan";
558
		$gatewayip = get_interface_gateway("wan");
559
		@file_put_contents("{$g['tmp_path']}/{$defaultif}_defaultgw", $gatewayip);
560
	}
561
	if ($foundgwv6 == false) {
562
		$defaultifv6 = get_real_interface("wan");
563
		$interfacegwv6 = "wan";
564
		$gatewayipv6 = get_interface_gateway_v6("wan");
565
		@file_put_contents("{$g['tmp_path']}/{$defaultifv6}_defaultgwv6", $gatewayipv6);
566
	}
567
	$dont_add_route = false;
568
	/* if OLSRD is enabled, allow WAN to house DHCP. */
569
	if (is_array($config['installedpackages']['olsrd'])) {
570
		foreach ($config['installedpackages']['olsrd']['config'] as $olsrd) {
571
			if (($olsrd['enabledyngw'] == "on") && ($olsrd['enable'] == "on")) {
572
				$dont_add_route = true;
573
				log_error(sprintf(gettext("Not adding default route because OLSR dynamic gateway is enabled.")));
574
				break;
575
			}
576
		}
577
	}
578

    
579
	$gateways_arr = return_gateways_array(false, true);
580
	foreach ($gateways_arr as $gateway) {
581
		// setup static interface routes for nonlocal gateways
582
		if (isset($gateway["nonlocalgateway"])) {
583
			$srgatewayip = $gateway['gateway'];
584
			$srinterfacegw = $gateway['interface'];
585
			if (is_ipaddr($srgatewayip) && !empty($srinterfacegw)) {
586
				$inet = (!is_ipaddrv4($srgatewayip) ? "-inet6" : "-inet");
587
				$cmd = "/sbin/route change {$inet} " . escapeshellarg($srgatewayip) . " ";
588
				mwexec($cmd . "-iface " . escapeshellarg($srinterfacegw));
589
				if (isset($config['system']['route-debug'])) {
590
					$mt = microtime();
591
					log_error("ROUTING debug: $mt - $cmd -iface $srinterfacegw ");
592
				}
593
			}
594
		}
595
	}
596

    
597
	if ($dont_add_route == false) {
598
		if (!empty($interface) && $interface != $interfacegw) {
599
			;
600
		} else if (is_ipaddrv4($gatewayip)) {
601
			log_error("ROUTING: setting default route to $gatewayip");
602
			mwexec("/sbin/route change -inet default " . escapeshellarg($gatewayip));
603
		}
604

    
605
		if (!empty($interface) && $interface != $interfacegwv6) {
606
			;
607
		} else if (is_ipaddrv6($gatewayipv6)) {
608
			$ifscope = "";
609
			if (is_linklocal($gatewayipv6) && !strpos($gatewayipv6, '%')) {
610
				$ifscope = "%{$defaultifv6}";
611
			}
612
			log_error("ROUTING: setting IPv6 default route to {$gatewayipv6}{$ifscope}");
613
			mwexec("/sbin/route change -inet6 default " . escapeshellarg("{$gatewayipv6}{$ifscope}"));
614
		}
615
	}
616

    
617
	system_staticroutes_configure($interface, false);
618

    
619
	return 0;
620
}
621

    
622
function system_staticroutes_configure($interface = "", $update_dns = false) {
623
	global $config, $g, $aliastable;
624

    
625
	$filterdns_list = array();
626

    
627
	$static_routes = get_staticroutes(false, true);
628
	if (count($static_routes)) {
629
		$gateways_arr = return_gateways_array(false, true);
630

    
631
		foreach ($static_routes as $rtent) {
632
			if (empty($gateways_arr[$rtent['gateway']])) {
633
				log_error(sprintf(gettext("Static Routes: Gateway IP could not be found for %s"), $rtent['network']));
634
				continue;
635
			}
636
			$gateway = $gateways_arr[$rtent['gateway']];
637
			if (!empty($interface) && $interface != $gateway['friendlyiface']) {
638
				continue;
639
			}
640

    
641
			$gatewayip = $gateway['gateway'];
642
			$interfacegw = $gateway['interface'];
643

    
644
			$blackhole = "";
645
			if (!strcasecmp("Null", substr($rtent['gateway'], 0, 3))) {
646
				$blackhole = "-blackhole";
647
			}
648

    
649
			if (!is_fqdn($rtent['network']) && !is_subnet($rtent['network'])) {
650
				continue;
651
			}
652

    
653
			$dnscache = array();
654
			if ($update_dns === true) {
655
				if (is_subnet($rtent['network'])) {
656
					continue;
657
				}
658
				$dnscache = explode("\n", trim(compare_hostname_to_dnscache($rtent['network'])));
659
				if (empty($dnscache)) {
660
					continue;
661
				}
662
			}
663

    
664
			if (is_subnet($rtent['network'])) {
665
				$ips = array($rtent['network']);
666
			} else {
667
				if (!isset($rtent['disabled'])) {
668
					$filterdns_list[] = $rtent['network'];
669
				}
670
				$ips = add_hostname_to_watch($rtent['network']);
671
			}
672

    
673
			foreach ($dnscache as $ip) {
674
				if (in_array($ip, $ips)) {
675
					continue;
676
				}
677
				mwexec("/sbin/route delete " . escapeshellarg($ip), true);
678
				if (isset($config['system']['route-debug'])) {
679
					$mt = microtime();
680
					log_error("ROUTING debug: $mt - route delete $ip ");
681
				}
682
			}
683

    
684
			if (isset($rtent['disabled'])) {
685
				/* XXX: This can break things by deleting routes that shouldn't be deleted - OpenVPN, dynamic routing scenarios, etc. redmine #3709 */
686
				foreach ($ips as $ip) {
687
					mwexec("/sbin/route delete " . escapeshellarg($ip), true);
688
					if (isset($config['system']['route-debug'])) {
689
						$mt = microtime();
690
						log_error("ROUTING debug: $mt - route delete $ip ");
691
					}
692
				}
693
				continue;
694
			}
695

    
696
			foreach ($ips as $ip) {
697
				if (is_ipaddrv4($ip)) {
698
					$ip .= "/32";
699
				}
700
				// do NOT do the same check here on v6, is_ipaddrv6 returns true when including the CIDR mask. doing so breaks v6 routes
701

    
702
				$inet = (is_subnetv6($ip) ? "-inet6" : "-inet");
703

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

    
706
				if (is_subnet($ip)) {
707
					if (is_ipaddr($gatewayip)) {
708
						mwexec($cmd . escapeshellarg($gatewayip));
709
						if (isset($config['system']['route-debug'])) {
710
							$mt = microtime();
711
							log_error("ROUTING debug: $mt - $cmd $gatewayip");
712
						}
713
					} else if (!empty($interfacegw)) {
714
						mwexec($cmd . "-iface " . escapeshellarg($interfacegw));
715
						if (isset($config['system']['route-debug'])) {
716
							$mt = microtime();
717
							log_error("ROUTING debug: $mt - $cmd -iface $interfacegw ");
718
						}
719
					}
720
				}
721
			}
722
		}
723
		unset($gateways_arr);
724
	}
725
	unset($static_routes);
726

    
727
	if ($update_dns === false) {
728
		if (count($filterdns_list)) {
729
			$interval = 60;
730
			$hostnames = "";
731
			array_unique($filterdns_list);
732
			foreach ($filterdns_list as $hostname) {
733
				$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload routedns\"'\n";
734
			}
735
			file_put_contents("{$g['varetc_path']}/filterdns-route.hosts", $hostnames);
736
			unset($hostnames);
737

    
738
			if (isvalidpid("{$g['varrun_path']}/filterdns-route.pid")) {
739
				sigkillbypid("{$g['varrun_path']}/filterdns-route.pid", "HUP");
740
			} else {
741
				mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-route.pid -i {$interval} -c {$g['varetc_path']}/filterdns-route.hosts -d 1");
742
			}
743
		} else {
744
			killbypid("{$g['varrun_path']}/filterdns-route.pid");
745
			@unlink("{$g['varrun_path']}/filterdns-route.pid");
746
		}
747
	}
748
	unset($filterdns_list);
749

    
750
	return 0;
751
}
752

    
753
function system_routing_enable() {
754
	global $config, $g;
755
	if (isset($config['system']['developerspew'])) {
756
		$mt = microtime();
757
		echo "system_routing_enable() being called $mt\n";
758
	}
759

    
760
	set_sysctl(array(
761
		"net.inet.ip.forwarding" => "1",
762
		"net.inet6.ip6.forwarding" => "1"
763
	));
764

    
765
	return;
766
}
767

    
768
function system_syslogd_fixup_server($server) {
769
	/* If it's an IPv6 IP alone, encase it in brackets */
770
	if (is_ipaddrv6($server)) {
771
		return "[$server]";
772
	} else {
773
		return $server;
774
	}
775
}
776

    
777
function system_syslogd_get_remote_servers($syslogcfg, $facility = "*.*") {
778
	// Rather than repeatedly use the same code, use this function to build a list of remote servers.
779
	$facility .= " ".
780
	$remote_servers = "";
781
	$pad_to  = max(strlen($facility), 56);
782
	$padding = ceil(($pad_to - strlen($facility))/8)+1;
783
	if ($syslogcfg['remoteserver']) {
784
		$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver']) . "\n";
785
	}
786
	if ($syslogcfg['remoteserver2']) {
787
		$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver2']) . "\n";
788
	}
789
	if ($syslogcfg['remoteserver3']) {
790
		$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver3']) . "\n";
791
	}
792
	return $remote_servers;
793
}
794

    
795
function clear_log_file($logfile = "/var/log/system.log", $restart_syslogd = true) {
796
	global $config, $g;
797
	if ($restart_syslogd) {
798
		exec("/usr/bin/killall syslogd");
799
	}
800
	if (isset($config['system']['disablesyslogclog'])) {
801
		unlink($logfile);
802
		touch($logfile);
803
	} else {
804
		$log_size = isset($config['syslog']['logfilesize']) ? $config['syslog']['logfilesize'] : "511488";
805
		$log_size = isset($config['syslog'][basename($logfile, '.log') . '_settings']['logfilesize']) ? $config['syslog'][basename($logfile, '.log') . '_settings']['logfilesize'] : $log_size;
806
		exec("/usr/local/sbin/clog -i -s {$log_size} " . escapeshellarg($logfile));
807
	}
808
	if ($restart_syslogd) {
809
		system_syslogd_start();
810
	}
811
}
812

    
813
function clear_all_log_files($restart = false) {
814
	global $g;
815
	exec("/usr/bin/killall syslogd");
816

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

    
822
	if ($restart) {
823
		system_syslogd_start();
824
		killbyname("dhcpd");
825
		services_dhcpd_configure();
826
	}
827
	return;
828
}
829

    
830
function system_syslogd_start() {
831
	global $config, $g;
832
	if (isset($config['system']['developerspew'])) {
833
		$mt = microtime();
834
		echo "system_syslogd_start() being called $mt\n";
835
	}
836

    
837
	mwexec("/etc/rc.d/hostid start");
838

    
839
	$syslogcfg = $config['syslog'];
840

    
841
	if (platform_booting()) {
842
		echo gettext("Starting syslog...");
843
	}
844

    
845
	// Which logging type are we using this week??
846
	if (isset($config['system']['disablesyslogclog'])) {
847
		$log_directive = "";
848
		$log_create_directive = "/usr/bin/touch ";
849
		$log_size = "";
850
	} else { // Defaults to CLOG
851
		$log_directive = "%";
852
		$log_size = isset($config['syslog']['logfilesize']) ? $config['syslog']['logfilesize'] : "10240";
853
		$log_create_directive = "/usr/local/sbin/clog -i -s ";
854
	}
855

    
856
	$syslogd_extra = "";
857
	if (isset($syslogcfg)) {
858
		$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');
859
		$syslogconf = "";
860
		if ($config['installedpackages']['package']) {
861
			foreach ($config['installedpackages']['package'] as $package) {
862
				if ($package['logging']) {
863
					array_push($separatelogfacilities, $package['logging']['facilityname']);
864
					if (!is_file($g['varlog_path'].'/'.$package['logging']['logfilename'])) {
865
						mwexec("{$log_create_directive} {$log_size} {$g['varlog_path']}/{$package['logging']['logfilename']}");
866
					}
867
					$syslogconf .= "!{$package['logging']['facilityname']}\n*.*\t\t\t\t\t\t {$log_directive}{$g['varlog_path']}/{$package['logging']['logfilename']}\n";
868
				}
869
			}
870
		}
871
		$facilitylist = implode(',', array_unique($separatelogfacilities));
872
		$syslogconf .= "!radvd,routed,olsrd,zebra,ospfd,bgpd,miniupnpd\n";
873
		if (!isset($syslogcfg['disablelocallogging'])) {
874
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/routing.log\n";
875
		}
876

    
877
		$syslogconf .= "!ntp,ntpd,ntpdate\n";
878
		if (!isset($syslogcfg['disablelocallogging'])) {
879
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ntpd.log\n";
880
		}
881

    
882
		$syslogconf .= "!ppp\n";
883
		if (!isset($syslogcfg['disablelocallogging'])) {
884
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ppp.log\n";
885
		}
886

    
887
		$syslogconf .= "!pptps\n";
888
		if (!isset($syslogcfg['disablelocallogging'])) {
889
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/pptps.log\n";
890
		}
891

    
892
		$syslogconf .= "!poes\n";
893
		if (!isset($syslogcfg['disablelocallogging'])) {
894
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/poes.log\n";
895
		}
896

    
897
		$syslogconf .= "!l2tps\n";
898
		if (!isset($syslogcfg['disablelocallogging'])) {
899
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/l2tps.log\n";
900
		}
901

    
902
		$syslogconf .= "!charon,ipsec_starter\n";
903
		if (!isset($syslogcfg['disablelocallogging'])) {
904
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ipsec.log\n";
905
		}
906
		if (isset($syslogcfg['vpn'])) {
907
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
908
		}
909

    
910
		$syslogconf .= "!openvpn\n";
911
		if (!isset($syslogcfg['disablelocallogging'])) {
912
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/openvpn.log\n";
913
		}
914
		if (isset($syslogcfg['vpn'])) {
915
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
916
		}
917

    
918
		$syslogconf .= "!dpinger\n";
919
		if (!isset($syslogcfg['disablelocallogging'])) {
920
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/gateways.log\n";
921
		}
922
		if (isset($syslogcfg['dpinger'])) {
923
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
924
		}
925

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

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

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

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

    
955
		$syslogconf .= "!filterlog\n";
956
		$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/filter.log\n";
957
		if (isset($syslogcfg['filter'])) {
958
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
959
		}
960

    
961
		$syslogconf .= "!-{$facilitylist}\n";
962
		if (!isset($syslogcfg['disablelocallogging'])) {
963
			$syslogconf .= <<<EOD
964
local3.*							{$log_directive}{$g['varlog_path']}/vpn.log
965
local4.*							{$log_directive}{$g['varlog_path']}/portalauth.log
966
local5.*							{$log_directive}{$g['varlog_path']}/nginx.log
967
local7.*							{$log_directive}{$g['varlog_path']}/dhcpd.log
968
*.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
969
auth.info;authpriv.info 					|exec /usr/local/sbin/sshlockout_pf 15
970
*.emerg								*
971

    
972
EOD;
973
		}
974
		if (isset($syslogcfg['vpn'])) {
975
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local3.*");
976
		}
977
		if (isset($syslogcfg['portalauth'])) {
978
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local4.*");
979
		}
980
		if (isset($syslogcfg['dhcp'])) {
981
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local7.*");
982
		}
983
		if (isset($syslogcfg['system'])) {
984
			$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");
985
		}
986
		if (isset($syslogcfg['logall'])) {
987
			// Make everything mean everything, including facilities excluded above.
988
			$syslogconf .= "!*\n";
989
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
990
		}
991

    
992
		if (isset($syslogcfg['zmqserver'])) {
993
				$syslogconf .= <<<EOD
994
*.*								^{$syslogcfg['zmqserver']}
995

    
996
EOD;
997
		}
998
		/* write syslog.conf */
999
		if (!@file_put_contents("{$g['varetc_path']}/syslog.conf", $syslogconf)) {
1000
			printf(gettext("Error: cannot open syslog.conf in system_syslogd_start().%s"), "\n");
1001
			unset($syslogconf);
1002
			return 1;
1003
		}
1004
		unset($syslogconf);
1005

    
1006
		// Ensure that the log directory exists
1007
		if (!is_dir("{$g['dhcpd_chroot_path']}/var/run")) {
1008
			exec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/run");
1009
		}
1010

    
1011
		$sourceip = "";
1012
		if (!empty($syslogcfg['sourceip'])) {
1013
			if ($syslogcfg['ipproto'] == "ipv6") {
1014
				$ifaddr = is_ipaddr($syslogcfg['sourceip']) ? $syslogcfg['sourceip'] : get_interface_ipv6($syslogcfg['sourceip']);
1015
				if (!is_ipaddr($ifaddr)) {
1016
					$ifaddr = get_interface_ip($syslogcfg['sourceip']);
1017
				}
1018
			} else {
1019
				$ifaddr = is_ipaddr($syslogcfg['sourceip']) ? $syslogcfg['sourceip'] : get_interface_ip($syslogcfg['sourceip']);
1020
				if (!is_ipaddr($ifaddr)) {
1021
					$ifaddr = get_interface_ipv6($syslogcfg['sourceip']);
1022
				}
1023
			}
1024
			if (is_ipaddr($ifaddr)) {
1025
				$sourceip = "-b {$ifaddr}";
1026
			}
1027
		}
1028

    
1029
		$syslogd_extra = "-f {$g['varetc_path']}/syslog.conf {$sourceip}";
1030
	}
1031

    
1032
	if (isvalidpid("{$g['varrun_path']}/syslog.pid")) {
1033
		sigkillbypid("{$g['varrun_path']}/syslog.pid", "TERM");
1034
		usleep(100000); // syslogd often doesn't respond to a TERM quickly enough for the starting of syslogd below to be successful
1035
	}
1036

    
1037
	if (isvalidpid("{$g['varrun_path']}/syslog.pid")) {
1038
		// if it still hasn't responded to the TERM, KILL it.
1039
		sigkillbypid("{$g['varrun_path']}/syslog.pid", "KILL");
1040
		usleep(100000);
1041
	}
1042

    
1043

    
1044
	$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}");
1045

    
1046
	if (platform_booting()) {
1047
		echo gettext("done.") . "\n";
1048
	}
1049

    
1050
	return $retval;
1051
}
1052

    
1053
function system_webgui_create_certificate() {
1054
	global $config, $g;
1055

    
1056
	if (!is_array($config['ca'])) {
1057
		$config['ca'] = array();
1058
	}
1059
	$a_ca =& $config['ca'];
1060
	if (!is_array($config['cert'])) {
1061
		$config['cert'] = array();
1062
	}
1063
	$a_cert =& $config['cert'];
1064
	log_error("Creating SSL Certificate for this host");
1065

    
1066
	$cert = array();
1067
	$cert['refid'] = uniqid();
1068
	$cert['descr'] = gettext("webConfigurator default ({$cert['refid']})");
1069

    
1070
	$dn = array(
1071
		'countryName' => "US",
1072
		'stateOrProvinceName' => "State",
1073
		'localityName' => "Locality",
1074
		'organizationName' => "{$g['product_name']} webConfigurator Self-Signed Certificate",
1075
		'emailAddress' => "admin@{$config['system']['hostname']}.{$config['system']['domain']}",
1076
		'commonName' => "{$config['system']['hostname']}-{$cert['refid']}");
1077
	$old_err_level = error_reporting(0); /* otherwise openssl_ functions throw warnings directly to a page screwing menu tab */
1078
	if (!cert_create($cert, null, 2048, 2000, $dn, "self-signed", "sha256")) {
1079
		while ($ssl_err = openssl_error_string()) {
1080
			log_error("Error creating WebGUI Certificate: openssl library returns: " . $ssl_err);
1081
		}
1082
		error_reporting($old_err_level);
1083
		return null;
1084
	}
1085
	error_reporting($old_err_level);
1086

    
1087
	$a_cert[] = $cert;
1088
	$config['system']['webgui']['ssl-certref'] = $cert['refid'];
1089
	write_config(gettext("Generated new self-signed HTTPS certificate ({$cert['refid']})"));
1090
	return $cert;
1091
}
1092

    
1093
function system_webgui_start() {
1094
	global $config, $g;
1095

    
1096
	if (platform_booting()) {
1097
		echo gettext("Starting webConfigurator...");
1098
	}
1099

    
1100
	chdir($g['www_path']);
1101

    
1102
	/* defaults */
1103
	$portarg = "80";
1104
	$crt = "";
1105
	$key = "";
1106
	$ca = "";
1107

    
1108
	/* non-standard port? */
1109
	if (isset($config['system']['webgui']['port']) && $config['system']['webgui']['port'] <> "") {
1110
		$portarg = "{$config['system']['webgui']['port']}";
1111
	}
1112

    
1113
	if ($config['system']['webgui']['protocol'] == "https") {
1114
		// Ensure that we have a webConfigurator CERT
1115
		$cert =& lookup_cert($config['system']['webgui']['ssl-certref']);
1116
		if (!is_array($cert) || !$cert['crt'] || !$cert['prv']) {
1117
			$cert = system_webgui_create_certificate();
1118
		}
1119
		$crt = base64_decode($cert['crt']);
1120
		$key = base64_decode($cert['prv']);
1121

    
1122
		if (!$config['system']['webgui']['port']) {
1123
			$portarg = "443";
1124
		}
1125
		$ca = ca_chain($cert);
1126
	}
1127

    
1128
	/* generate nginx configuration */
1129
	system_generate_nginx_config("{$g['varetc_path']}/nginx-webConfigurator.conf",
1130
		$crt, $key, $ca, "nginx-webConfigurator.pid", $portarg, "/usr/local/www/",
1131
		"cert.crt", "cert.key");
1132

    
1133
	/* kill any running nginx */
1134
	killbypid("{$g['varrun_path']}/nginx-webConfigurator.pid");
1135

    
1136
	sleep(1);
1137

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

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

    
1143
	if (platform_booting()) {
1144
		if ($res == 0) {
1145
			echo gettext("done.") . "\n";
1146
		} else {
1147
			echo gettext("failed!") . "\n";
1148
		}
1149
	}
1150

    
1151
	return $res;
1152
}
1153

    
1154
function system_generate_nginx_config($filename,
1155
	$cert,
1156
	$key,
1157
	$ca,
1158
	$pid_file,
1159
	$port = 80,
1160
	$document_root = "/usr/local/www/",
1161
	$cert_location = "cert.crt",
1162
	$key_location = "cert.key",
1163
	$captive_portal = false) {
1164

    
1165
	global $config, $g;
1166

    
1167
	if (isset($config['system']['developerspew'])) {
1168
		$mt = microtime();
1169
		echo "system_generate_nginx_config() being called $mt\n";
1170
	}
1171

    
1172
	if ($captive_portal !== false) {
1173
		$captive_portal_rewrite = "url.rewrite-once = ( \"(.*captiveportal.*)\" => \"$1\", \"(.*)\" => \"/index.php?zone={$captive_portal}&redirurl=$1\" )\n";
1174
		
1175
		$maxprocperip = $config['captiveportal'][$captive_portal]['maxprocperip'];
1176
		if (empty($maxprocperip)) {
1177
			$maxprocperip = 10;
1178
		}
1179
		$captive_portal_maxprocperip = "limit_conn_zone \$binary_remote_addr zone=addr:10m;\n";
1180
		$captive_portal_maxprocperip .= "limit_conn addr $maxprocperip\n";
1181

    
1182
	} 
1183

    
1184
	if (empty($port)) {
1185
		$nginx_port = "80";
1186
	} else {
1187
		$nginx_port = $port;
1188
	}
1189

    
1190
	$memory = get_memory();
1191
	$realmem = $memory[1];
1192

    
1193
	// Determine web GUI process settings and take into account low memory systems
1194
	if ($realmem < 255) {
1195
		$max_procs = 1;
1196
	} else {
1197
		$max_procs = ($config['system']['webgui']['max_procs']) ? $config['system']['webgui']['max_procs'] : 2;
1198
	}
1199

    
1200
	// Ramp up captive portal max procs, assuming each PHP process can consume up to 64MB RAM
1201
	if ($captive_portal !== false) {
1202
		if ($realmem > 135 and $realmem < 256) {
1203
			$max_procs += 1; // 2 worker processes
1204
		} else if ($realmem > 255 and $realmem < 513) {
1205
			$max_procs += 2; // 3 worker processes
1206
		} else if ($realmem > 512) {
1207
			$max_procs += 4; // 6 worker processes
1208
		}
1209
	} 
1210

    
1211
	$nginx_config = <<<EOD
1212
#
1213
# nginx configuration file
1214

    
1215
pid {$g['varrun_path']}/{$pid_file};
1216

    
1217
user  root wheel;
1218
worker_processes  {$max_procs};
1219

    
1220
EOD;
1221

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

    
1226
$nginx_config .= <<<EOD
1227

    
1228
events {
1229
    worker_connections  1024;
1230
}
1231

    
1232
http {
1233
	include       /usr/local/etc/nginx/mime.types;
1234
	default_type  application/octet-stream;
1235
	add_header X-Frame-Options SAMEORIGIN;
1236
	server_tokens off;
1237

    
1238
	sendfile        on;
1239
	keepalive_timeout  65;
1240

    
1241
	access_log      syslog:server=unix:/var/run/log,facility=local5 combined;
1242

    
1243
	server {
1244
		listen {$nginx_port};
1245
		listen [::]:{$nginx_port};
1246

    
1247
EOD;
1248

    
1249
	if ($cert <> "" and $key <> "") {
1250
		$nginx_config .= "\t\tssl             on;\n";
1251
		$nginx_config .= "\t\tssl_certificate         {$g['varetc_path']}/{$cert_location};\n";
1252
		$nginx_config .= "\t\tssl_certificate_key     {$g['varetc_path']}/{$key_location};\n";
1253
        $nginx_config .= "\t\tssl_session_timeout     10m;\n";
1254
        $nginx_config .= "\t\tkeepalive_timeout       70;\n";
1255
		$nginx_config .= "\t\tssl_session_cache       shared:SSL:100m;\n";
1256
        $nginx_config .= "\t\tssl_protocols   TLSv1 TLSv1.1 TLSv1.2;\n";
1257
		$nginx_config .= "\t\tssl_ciphers \"EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH\";\n";
1258
		$nginx_config .= "\t\tssl_prefer_server_ciphers       on;\n";
1259
		$nginx_config .= "\t\tadd_header Strict-Transport-Security \"max-age=31536000; preload\";\n";
1260
		$nginx_config .= "\t\tadd_header X-Content-Type-Options nosniff;\n";
1261
		$nginx_config .= "\t\tssl_session_tickets off;\n";
1262
		$nginx_config .= "\t\tssl_stapling on;\n";
1263
		$nginx_config .= "\t\tssl_stapling_verify on;\n";
1264
		$nginx_config .= "\n";
1265
	}
1266

    
1267
	$nginx_config .= <<<EOD
1268
		root "{$document_root}";
1269
		location / {
1270
			index  index.html index.htm index.php;
1271
		}
1272

    
1273
		location ~ \.php$ {
1274
			try_files \$uri =404; #  This line closes a potential security hole
1275
                                    #  ensuring users can't execute uploaded files
1276
     								# see: http://forum.nginx.org/read.php?2,88845,page=3 
1277
			fastcgi_pass   unix:{$g['varrun_path']}/php-fpm.socket;
1278
			fastcgi_index  index.php;
1279
			fastcgi_param  SCRIPT_FILENAME  \$document_root\$fastcgi_script_name;
1280
			include        /usr/local/etc/nginx/fastcgi_params;
1281
		}
1282
	}
1283

    
1284
EOD;
1285

    
1286
	$cert = str_replace("\r", "", $cert);
1287
	$key = str_replace("\r", "", $key);
1288

    
1289
	$cert = str_replace("\n\n", "\n", $cert);
1290
	$key = str_replace("\n\n", "\n", $key);
1291

    
1292
	if ($cert <> "" and $key <> "") {
1293
		$fd = fopen("{$g['varetc_path']}/{$cert_location}", "w");
1294
		if (!$fd) {
1295
			printf(gettext("Error: cannot open certificate file in system_webgui_start().%s"), "\n");
1296
			return 1;
1297
		}
1298
		chmod("{$g['varetc_path']}/{$cert_location}", 0600);
1299
		fwrite($fd, $cert);
1300
		fclose($fd);
1301
		$fd = fopen("{$g['varetc_path']}/{$key_location}", "w");
1302
		if (!$fd) {
1303
			printf(gettext("Error: cannot open certificate key file in system_webgui_start().%s"), "\n");
1304
			return 1;
1305
		}
1306
		chmod("{$g['varetc_path']}/{$key_location}", 0600);
1307
		fwrite($fd, $key);
1308
		fclose($fd);
1309
	}
1310

    
1311
	// Add HTTP to HTTPS redirect
1312
	if ($captive_portal === false && $config['system']['webgui']['protocol'] == "https" && !isset($config['system']['webgui']['disablehttpredirect'])) {
1313
		if ($nginx_port != "443") {
1314
			$redirectport = ":{$nginx_port}";
1315
		}
1316
		$nginx_config .= <<<EOD
1317
	server {
1318
		listen 80;
1319
		listen [::]:80;
1320
		rewrite         ^ https://\$http_host$redirectport\$request_uri? permanent;
1321
	}
1322

    
1323
EOD;
1324
	}
1325
	
1326
	$nginx_config .= "}\n";
1327

    
1328
	$fd = fopen("{$filename}", "w");
1329
	if (!$fd) {
1330
		printf(gettext("Error: cannot open %s in system_generate_nginx_config().%s"), $filename, "\n");
1331
		return 1;
1332
	}
1333
	fwrite($fd, $nginx_config);
1334
	fclose($fd);
1335

    
1336
	return 0;
1337

    
1338
}
1339

    
1340
function system_get_timezone_list() {
1341
	global $g;
1342

    
1343
	$file_list = array_merge(
1344
		glob("/usr/share/zoneinfo/[A-Z]*"),
1345
		glob("/usr/share/zoneinfo/*/*"),
1346
		glob("/usr/share/zoneinfo/*/*/*")
1347
	);
1348

    
1349
	if (empty($file_list)) {
1350
		$file_list[] = $g['default_timezone'];
1351
	} else {
1352
		/* Remove directories from list */
1353
		$file_list = array_filter($file_list, function($v) {
1354
			return !is_dir($v);
1355
		});
1356
	}
1357

    
1358
	/* Remove directory prefix */
1359
	$file_list = str_replace('/usr/share/zoneinfo/', '', $file_list);
1360

    
1361
	sort($file_list);
1362

    
1363
	return $file_list;
1364
}
1365

    
1366
function system_timezone_configure() {
1367
	global $config, $g;
1368
	if (isset($config['system']['developerspew'])) {
1369
		$mt = microtime();
1370
		echo "system_timezone_configure() being called $mt\n";
1371
	}
1372

    
1373
	$syscfg = $config['system'];
1374

    
1375
	if (platform_booting()) {
1376
		echo gettext("Setting timezone...");
1377
	}
1378

    
1379
	/* extract appropriate timezone file */
1380
	$timezone = (isset($syscfg['timezone']) ? $syscfg['timezone'] : $g['default_timezone']);
1381
	conf_mount_rw();
1382
	/* DO NOT remove \n otherwise tzsetup will fail */
1383
	@file_put_contents("/var/db/zoneinfo", $timezone . "\n");
1384
	mwexec("/usr/sbin/tzsetup -r");
1385
	conf_mount_ro();
1386

    
1387
	if (platform_booting()) {
1388
		echo gettext("done.") . "\n";
1389
	}
1390
}
1391

    
1392
function system_ntp_setup_gps($serialport) {
1393
	global $config, $g;
1394
	$gps_device = '/dev/gps0';
1395
	$serialport = '/dev/'.$serialport;
1396

    
1397
	if (!file_exists($serialport)) {
1398
		return false;
1399
	}
1400

    
1401
	conf_mount_rw();
1402
	// Create symlink that ntpd requires
1403
	unlink_if_exists($gps_device);
1404
	@symlink($serialport, $gps_device);
1405

    
1406
	$gpsbaud = '4800';
1407
	if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['speed'])) {
1408
		switch ($config['ntpd']['gps']['speed']) {
1409
			case '16':
1410
				$gpsbaud = '9600';
1411
				break;
1412
			case '32':
1413
				$gpsbaud = '19200';
1414
				break;
1415
			case '48':
1416
				$gpsbaud = '38400';
1417
				break;
1418
			case '64':
1419
				$gpsbaud = '57600';
1420
				break;
1421
			case '80':
1422
				$gpsbaud = '115200';
1423
				break;
1424
		}
1425
	}
1426

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

    
1430
	/* Send the following to the GPS port to initialize the GPS */
1431
	if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['type'])) {
1432
		$gps_init = base64_decode($config['ntpd']['gps']['initcmd']);
1433
	} else {
1434
		$gps_init = base64_decode('JFBVQlgsNDAsR1NWLDAsMCwwLDAqNTkNCiRQVUJYLDQwLEdMTCwwLDAsMCwwKjVDDQokUFVCWCw0MCxaREEsMCwwLDAsMCo0NA0KJFBVQlgsNDAsVlRHLDAsMCwwLDAqNUUNCiRQVUJYLDQwLEdTViwwLDAsMCwwKjU5DQokUFVCWCw0MCxHU0EsMCwwLDAsMCo0RQ0KJFBVQlgsNDAsR0dBLDAsMCwwLDANCiRQVUJYLDQwLFRYVCwwLDAsMCwwDQokUFVCWCw0MCxSTUMsMCwwLDAsMCo0Ng0KJFBVQlgsNDEsMSwwMDA3LDAwMDMsNDgwMCwwDQokUFVCWCw0MCxaREEsMSwxLDEsMQ==');
1435
	}
1436

    
1437
	/* XXX: Why not file_put_contents to the device */
1438
	@file_put_contents('/tmp/gps.init', $gps_init);
1439
	mwexec("cat /tmp/gps.init > {$serialport}");
1440

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

    
1446
	conf_mount_ro();
1447

    
1448
	return true;
1449
}
1450

    
1451
function system_ntp_setup_pps($serialport) {
1452
	global $config, $g;
1453

    
1454
	$pps_device = '/dev/pps0';
1455
	$serialport = '/dev/'.$serialport;
1456

    
1457
	if (!file_exists($serialport)) {
1458
		return false;
1459
	}
1460

    
1461
	conf_mount_rw();
1462
	// Create symlink that ntpd requires
1463
	unlink_if_exists($pps_device);
1464
	@symlink($serialport, $pps_device);
1465

    
1466
	conf_mount_ro();
1467

    
1468
	return true;
1469
}
1470

    
1471

    
1472
function system_ntp_configure($start_ntpd=true) {
1473
	global $config, $g;
1474

    
1475
	$driftfile = "/var/db/ntpd.drift";
1476
	$statsdir = "/var/log/ntp";
1477
	$gps_device = '/dev/gps0';
1478

    
1479
	safe_mkdir($statsdir);
1480

    
1481
	if (!is_array($config['ntpd'])) {
1482
		$config['ntpd'] = array();
1483
	}
1484

    
1485
	$ntpcfg = "# \n";
1486
	$ntpcfg .= "# pfSense ntp configuration file \n";
1487
	$ntpcfg .= "# \n\n";
1488
	$ntpcfg .= "tinker panic 0 \n";
1489

    
1490
	/* Add Orphan mode */
1491
	$ntpcfg .= "# Orphan mode stratum\n";
1492
	$ntpcfg .= 'tos orphan ';
1493
	if (!empty($config['ntpd']['orphan'])) {
1494
		$ntpcfg .= $config['ntpd']['orphan'];
1495
	} else {
1496
		$ntpcfg .= '12';
1497
	}
1498
	$ntpcfg .= "\n";
1499

    
1500
	/* Add PPS configuration */
1501
	if (is_array($config['ntpd']['pps']) && !empty($config['ntpd']['pps']['port']) &&
1502
	    file_exists('/dev/'.$config['ntpd']['pps']['port']) &&
1503
	    system_ntp_setup_pps($config['ntpd']['pps']['port'])) {
1504
		$ntpcfg .= "\n";
1505
		$ntpcfg .= "# PPS Setup\n";
1506
		$ntpcfg .= 'server 127.127.22.0';
1507
		$ntpcfg .= ' minpoll 4 maxpoll 4';
1508
		if (empty($config['ntpd']['pps']['prefer'])) { /*note: this one works backwards */
1509
			$ntpcfg .= ' prefer';
1510
		}
1511
		if (!empty($config['ntpd']['pps']['noselect'])) {
1512
			$ntpcfg .= ' noselect ';
1513
		}
1514
		$ntpcfg .= "\n";
1515
		$ntpcfg .= 'fudge 127.127.22.0';
1516
		if (!empty($config['ntpd']['pps']['fudge1'])) {
1517
			$ntpcfg .= ' time1 ';
1518
			$ntpcfg .= $config['ntpd']['pps']['fudge1'];
1519
		}
1520
		if (!empty($config['ntpd']['pps']['flag2'])) {
1521
			$ntpcfg .= ' flag2 1';
1522
		}
1523
		if (!empty($config['ntpd']['pps']['flag3'])) {
1524
			$ntpcfg .= ' flag3 1';
1525
		} else {
1526
			$ntpcfg .= ' flag3 0';
1527
		}
1528
		if (!empty($config['ntpd']['pps']['flag4'])) {
1529
			$ntpcfg .= ' flag4 1';
1530
		}
1531
		if (!empty($config['ntpd']['pps']['refid'])) {
1532
			$ntpcfg .= ' refid ';
1533
			$ntpcfg .= $config['ntpd']['pps']['refid'];
1534
		}
1535
		$ntpcfg .= "\n";
1536
	}
1537
	/* End PPS configuration */
1538

    
1539
	/* Add GPS configuration */
1540
	if (is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['port']) &&
1541
	    file_exists('/dev/'.$config['ntpd']['gps']['port']) &&
1542
	    system_ntp_setup_gps($config['ntpd']['gps']['port'])) {
1543
		$ntpcfg .= "\n";
1544
		$ntpcfg .= "# GPS Setup\n";
1545
		$ntpcfg .= 'server 127.127.20.0 mode ';
1546
		if (!empty($config['ntpd']['gps']['nmea']) || !empty($config['ntpd']['gps']['speed']) || !empty($config['ntpd']['gps']['subsec'])) {
1547
			if (!empty($config['ntpd']['gps']['nmea'])) {
1548
				$ntpmode = (int) $config['ntpd']['gps']['nmea'];
1549
			}
1550
			if (!empty($config['ntpd']['gps']['speed'])) {
1551
				$ntpmode += (int) $config['ntpd']['gps']['speed'];
1552
			}
1553
			if (!empty($config['ntpd']['gps']['subsec'])) {
1554
				$ntpmode += 128;
1555
			}
1556
			$ntpcfg .= (string) $ntpmode;
1557
		} else {
1558
			$ntpcfg .= '0';
1559
		}
1560
		$ntpcfg .= ' minpoll 4 maxpoll 4';
1561
		if (empty($config['ntpd']['gps']['prefer'])) { /*note: this one works backwards */
1562
			$ntpcfg .= ' prefer';
1563
		}
1564
		if (!empty($config['ntpd']['gps']['noselect'])) {
1565
			$ntpcfg .= ' noselect ';
1566
		}
1567
		$ntpcfg .= "\n";
1568
		$ntpcfg .= 'fudge 127.127.20.0';
1569
		if (!empty($config['ntpd']['gps']['fudge1'])) {
1570
			$ntpcfg .= ' time1 ';
1571
			$ntpcfg .= $config['ntpd']['gps']['fudge1'];
1572
		}
1573
		if (!empty($config['ntpd']['gps']['fudge2'])) {
1574
			$ntpcfg .= ' time2 ';
1575
			$ntpcfg .= $config['ntpd']['gps']['fudge2'];
1576
		}
1577
		if (!empty($config['ntpd']['gps']['flag1'])) {
1578
			$ntpcfg .= ' flag1 1';
1579
		} else {
1580
			$ntpcfg .= ' flag1 0';
1581
		}
1582
		if (!empty($config['ntpd']['gps']['flag2'])) {
1583
			$ntpcfg .= ' flag2 1';
1584
		}
1585
		if (!empty($config['ntpd']['gps']['flag3'])) {
1586
			$ntpcfg .= ' flag3 1';
1587
		} else {
1588
			$ntpcfg .= ' flag3 0';
1589
		}
1590
		if (!empty($config['ntpd']['gps']['flag4'])) {
1591
			$ntpcfg .= ' flag4 1';
1592
		}
1593
		if (!empty($config['ntpd']['gps']['refid'])) {
1594
			$ntpcfg .= ' refid ';
1595
			$ntpcfg .= $config['ntpd']['gps']['refid'];
1596
		}
1597
		if (!empty($config['ntpd']['gps']['stratum'])) {
1598
			$ntpcfg .= ' stratum ';
1599
			$ntpcfg .= $config['ntpd']['gps']['stratum'];
1600
		}
1601
		$ntpcfg .= "\n";
1602
	} elseif (is_array($config['ntpd']) && !empty($config['ntpd']['gpsport']) &&
1603
	    file_exists('/dev/'.$config['ntpd']['gpsport']) &&
1604
	    system_ntp_setup_gps($config['ntpd']['gpsport'])) {
1605
		/* This handles a 2.1 and earlier config */
1606
		$ntpcfg .= "# GPS Setup\n";
1607
		$ntpcfg .= "server 127.127.20.0 mode 0 minpoll 4 maxpoll 4 prefer\n";
1608
		$ntpcfg .= "fudge 127.127.20.0 time1 0.155 time2 0.000 flag1 1 flag2 0 flag3 1\n";
1609
		// Fall back to local clock if GPS is out of sync?
1610
		$ntpcfg .= "server 127.127.1.0\n";
1611
		$ntpcfg .= "fudge 127.127.1.0 stratum 12\n";
1612
	}
1613
	/* End GPS configuration */
1614

    
1615
	$ntpcfg .= "\n\n# Upstream Servers\n";
1616
	/* foreach through ntp servers and write out to ntpd.conf */
1617
	foreach (explode(' ', $config['system']['timeservers']) as $ts) {
1618
		$ntpcfg .= "server {$ts} iburst maxpoll 9";
1619
		if (substr_count($config['ntpd']['prefer'], $ts)) {
1620
			$ntpcfg .= ' prefer';
1621
		}
1622
		if (substr_count($config['ntpd']['noselect'], $ts)) {
1623
			$ntpcfg .= ' noselect';
1624
		}
1625
		$ntpcfg .= "\n";
1626
	}
1627
	unset($ts);
1628

    
1629
	$ntpcfg .= "\n\n";
1630
	$ntpcfg .= "disable monitor\n"; //prevent NTP reflection attack, see https://forum.pfsense.org/index.php/topic,67189.msg389132.html#msg389132
1631
	if (!empty($config['ntpd']['clockstats']) || !empty($config['ntpd']['loopstats']) || !empty($config['ntpd']['peerstats'])) {
1632
		$ntpcfg .= "enable stats\n";
1633
		$ntpcfg .= 'statistics';
1634
		if (!empty($config['ntpd']['clockstats'])) {
1635
			$ntpcfg .= ' clockstats';
1636
		}
1637
		if (!empty($config['ntpd']['loopstats'])) {
1638
			$ntpcfg .= ' loopstats';
1639
		}
1640
		if (!empty($config['ntpd']['peerstats'])) {
1641
			$ntpcfg .= ' peerstats';
1642
		}
1643
		$ntpcfg .= "\n";
1644
	}
1645
	$ntpcfg .= "statsdir {$statsdir}\n";
1646
	$ntpcfg .= 'logconfig =syncall +clockall';
1647
	if (!empty($config['ntpd']['logpeer'])) {
1648
		$ntpcfg .= ' +peerall';
1649
	}
1650
	if (!empty($config['ntpd']['logsys'])) {
1651
		$ntpcfg .= ' +sysall';
1652
	}
1653
	$ntpcfg .= "\n";
1654
	$ntpcfg .= "driftfile {$driftfile}\n";
1655
	/* Access restrictions */
1656
	$ntpcfg .= 'restrict default';
1657
	if (empty($config['ntpd']['kod'])) { /*note: this one works backwards */
1658
		$ntpcfg .= ' kod limited';
1659
	}
1660
	if (empty($config['ntpd']['nomodify'])) { /*note: this one works backwards */
1661
		$ntpcfg .= ' nomodify';
1662
	}
1663
	if (!empty($config['ntpd']['noquery'])) {
1664
		$ntpcfg .= ' noquery';
1665
	}
1666
	if (empty($config['ntpd']['nopeer'])) { /*note: this one works backwards */
1667
		$ntpcfg .= ' nopeer';
1668
	}
1669
	if (empty($config['ntpd']['notrap'])) { /*note: this one works backwards */
1670
		$ntpcfg .= ' notrap';
1671
	}
1672
	if (!empty($config['ntpd']['noserve'])) {
1673
		$ntpcfg .= ' noserve';
1674
	}
1675
	$ntpcfg .= "\nrestrict -6 default";
1676
	if (empty($config['ntpd']['kod'])) { /*note: this one works backwards */
1677
		$ntpcfg .= ' kod limited';
1678
	}
1679
	if (empty($config['ntpd']['nomodify'])) { /*note: this one works backwards */
1680
		$ntpcfg .= ' nomodify';
1681
	}
1682
	if (!empty($config['ntpd']['noquery'])) {
1683
		$ntpcfg .= ' noquery';
1684
	}
1685
	if (empty($config['ntpd']['nopeer'])) { /*note: this one works backwards */
1686
		$ntpcfg .= ' nopeer';
1687
	}
1688
	if (!empty($config['ntpd']['noserve'])) {
1689
		$ntpcfg .= ' noserve';
1690
	}
1691
	if (empty($config['ntpd']['notrap'])) { /*note: this one works backwards */
1692
		$ntpcfg .= ' notrap';
1693
	}
1694
	$ntpcfg .= "\n";
1695

    
1696
	/* A leapseconds file is really only useful if this clock is stratum 1 */
1697
	$ntpcfg .= "\n";
1698
	if (!empty($config['ntpd']['leapsec'])) {
1699
		$leapsec .= base64_decode($config['ntpd']['leapsec']);
1700
		file_put_contents('/var/db/leap-seconds', $leapsec);
1701
		$ntpcfg .= "leapfile /var/db/leap-seconds\n";
1702
	}
1703

    
1704

    
1705
	if (empty($config['ntpd']['interface'])) {
1706
		if (is_array($config['installedpackages']['openntpd']) && !empty($config['installedpackages']['openntpd']['config'][0]['interface'])) {
1707
			$interfaces = explode(",", $config['installedpackages']['openntpd']['config'][0]['interface']);
1708
		} else {
1709
			$interfaces = array();
1710
		}
1711
	} else {
1712
		$interfaces = explode(",", $config['ntpd']['interface']);
1713
	}
1714

    
1715
	if (is_array($interfaces) && count($interfaces)) {
1716
		$ntpcfg .= "interface ignore all\n";
1717
		foreach ($interfaces as $interface) {
1718
			if (strstr($interface, "_vip")) {
1719
				$interface = get_configured_carp_interface_list($interface);
1720
			}
1721
			if (!is_ipaddr($interface)) {
1722
				$interface = get_real_interface($interface);
1723
			}
1724
			if (!empty($interface)) {
1725
				$ntpcfg .= "interface listen {$interface}\n";
1726
			}
1727
		}
1728
	}
1729

    
1730
	/* open configuration for writing or bail */
1731
	if (!@file_put_contents("{$g['varetc_path']}/ntpd.conf", $ntpcfg)) {
1732
		log_error("Could not open {$g['varetc_path']}/ntpd.conf for writing");
1733
		return;
1734
	}
1735

    
1736
	/* At bootup we just want to write out the config. */
1737
	if (!$start_ntpd) {
1738
		return;
1739
	}
1740

    
1741
	/* if ntpd is running, kill it */
1742
	while (isvalidpid("{$g['varrun_path']}/ntpd.pid")) {
1743
		killbypid("{$g['varrun_path']}/ntpd.pid");
1744
	}
1745
	@unlink("{$g['varrun_path']}/ntpd.pid");
1746

    
1747
	/* if /var/empty does not exist, create it */
1748
	if (!is_dir("/var/empty")) {
1749
		mkdir("/var/empty", 0775, true);
1750
	}
1751

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

    
1755
	// Note that we are starting up
1756
	log_error("NTPD is starting up.");
1757
	return;
1758
}
1759

    
1760
function sync_system_time() {
1761
	global $config, $g;
1762

    
1763
	if (platform_booting()) {
1764
		echo gettext("Syncing system time before startup...");
1765
	}
1766

    
1767
	/* foreach through servers and write out to ntpd.conf */
1768
	foreach (explode(' ', $config['system']['timeservers']) as $ts) {
1769
		mwexec("/usr/local/sbin/ntpdate -s $ts");
1770
	}
1771

    
1772
	if (platform_booting()) {
1773
		echo gettext("done.") . "\n";
1774
	}
1775

    
1776
}
1777

    
1778
function system_halt() {
1779
	global $g;
1780

    
1781
	system_reboot_cleanup();
1782

    
1783
	mwexec("/usr/bin/nohup /etc/rc.halt > /dev/null 2>&1 &");
1784
}
1785

    
1786
function system_reboot() {
1787
	global $g;
1788

    
1789
	system_reboot_cleanup();
1790

    
1791
	mwexec("nohup /etc/rc.reboot > /dev/null 2>&1 &");
1792
}
1793

    
1794
function system_reboot_sync() {
1795
	global $g;
1796

    
1797
	system_reboot_cleanup();
1798

    
1799
	mwexec("/etc/rc.reboot > /dev/null 2>&1");
1800
}
1801

    
1802
function system_reboot_cleanup() {
1803
	global $config, $cpzone;
1804

    
1805
	mwexec("/usr/local/bin/beep.sh stop");
1806
	require_once("captiveportal.inc");
1807
	if (is_array($config['captiveportal'])) {
1808
		foreach ($config['captiveportal'] as $cpzone=>$cp) {
1809
			captiveportal_radius_stop_all();
1810
			captiveportal_send_server_accounting(true);
1811
		}
1812
	}
1813
	require_once("voucher.inc");
1814
	voucher_save_db_to_config();
1815
	require_once("pkg-utils.inc");
1816
	stop_packages();
1817
}
1818

    
1819
function system_do_shell_commands($early = 0) {
1820
	global $config, $g;
1821
	if (isset($config['system']['developerspew'])) {
1822
		$mt = microtime();
1823
		echo "system_do_shell_commands() being called $mt\n";
1824
	}
1825

    
1826
	if ($early) {
1827
		$cmdn = "earlyshellcmd";
1828
	} else {
1829
		$cmdn = "shellcmd";
1830
	}
1831

    
1832
	if (is_array($config['system'][$cmdn])) {
1833

    
1834
		/* *cmd is an array, loop through */
1835
		foreach ($config['system'][$cmdn] as $cmd) {
1836
			exec($cmd);
1837
		}
1838

    
1839
	} elseif ($config['system'][$cmdn] <> "") {
1840

    
1841
		/* execute single item */
1842
		exec($config['system'][$cmdn]);
1843

    
1844
	}
1845
}
1846

    
1847
function system_console_configure() {
1848
	global $config, $g;
1849
	if (isset($config['system']['developerspew'])) {
1850
		$mt = microtime();
1851
		echo "system_console_configure() being called $mt\n";
1852
	}
1853

    
1854
	if (isset($config['system']['disableconsolemenu'])) {
1855
		touch("{$g['varetc_path']}/disableconsole");
1856
	} else {
1857
		unlink_if_exists("{$g['varetc_path']}/disableconsole");
1858
	}
1859
}
1860

    
1861
function system_dmesg_save() {
1862
	global $g;
1863
	if (isset($config['system']['developerspew'])) {
1864
		$mt = microtime();
1865
		echo "system_dmesg_save() being called $mt\n";
1866
	}
1867

    
1868
	$dmesg = "";
1869
	$_gb = exec("/sbin/dmesg", $dmesg);
1870

    
1871
	/* find last copyright line (output from previous boots may be present) */
1872
	$lastcpline = 0;
1873

    
1874
	for ($i = 0; $i < count($dmesg); $i++) {
1875
		if (strstr($dmesg[$i], "Copyright (c) 1992-")) {
1876
			$lastcpline = $i;
1877
		}
1878
	}
1879

    
1880
	$fd = fopen("{$g['varlog_path']}/dmesg.boot", "w");
1881
	if (!$fd) {
1882
		printf(gettext("Error: cannot open dmesg.boot in system_dmesg_save().%s"), "\n");
1883
		return 1;
1884
	}
1885

    
1886
	for ($i = $lastcpline; $i < count($dmesg); $i++) {
1887
		fwrite($fd, $dmesg[$i] . "\n");
1888
	}
1889

    
1890
	fclose($fd);
1891
	unset($dmesg);
1892

    
1893
	return 0;
1894
}
1895

    
1896
function system_set_harddisk_standby() {
1897
	global $g, $config;
1898

    
1899
	if (isset($config['system']['developerspew'])) {
1900
		$mt = microtime();
1901
		echo "system_set_harddisk_standby() being called $mt\n";
1902
	}
1903

    
1904
	if (isset($config['system']['harddiskstandby'])) {
1905
		if (platform_booting()) {
1906
			echo gettext('Setting hard disk standby... ');
1907
		}
1908

    
1909
		$standby = $config['system']['harddiskstandby'];
1910
		// Check for a numeric value
1911
		if (is_numeric($standby)) {
1912
			// Get only suitable candidates for standby; using get_smart_drive_list()
1913
			// from utils.inc to get the list of drives.
1914
			$harddisks = get_smart_drive_list();
1915

    
1916
			// Since get_smart_drive_list() only matches ad|da|ada; lets put the check below
1917
			// just in case of some weird pfSense platform installs.
1918
			if (count($harddisks) > 0) {
1919
				// Iterate disks and run the camcontrol command for each
1920
				foreach ($harddisks as $harddisk) {
1921
					mwexec("/sbin/camcontrol standby {$harddisk} -t {$standby}");
1922
				}
1923
				if (platform_booting()) {
1924
					echo gettext("done.") . "\n";
1925
				}
1926
			} else if (platform_booting()) {
1927
				echo gettext("failed!") . "\n";
1928
			}
1929
		} else if (platform_booting()) {
1930
			echo gettext("failed!") . "\n";
1931
		}
1932
	}
1933
}
1934

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

    
1942
	activate_sysctls();
1943

    
1944
	if (isset($config['system']['sharednet'])) {
1945
		system_disable_arp_wrong_if();
1946
	}
1947
}
1948

    
1949
function system_disable_arp_wrong_if() {
1950
	global $config;
1951
	if (isset($config['system']['developerspew'])) {
1952
		$mt = microtime();
1953
		echo "system_disable_arp_wrong_if() being called $mt\n";
1954
	}
1955
	set_sysctl(array(
1956
		"net.link.ether.inet.log_arp_wrong_iface" => "0",
1957
		"net.link.ether.inet.log_arp_movements" => "0"
1958
	));
1959
}
1960

    
1961
function system_enable_arp_wrong_if() {
1962
	global $config;
1963
	if (isset($config['system']['developerspew'])) {
1964
		$mt = microtime();
1965
		echo "system_enable_arp_wrong_if() being called $mt\n";
1966
	}
1967
	set_sysctl(array(
1968
		"net.link.ether.inet.log_arp_wrong_iface" => "1",
1969
		"net.link.ether.inet.log_arp_movements" => "1"
1970
	));
1971
}
1972

    
1973
function enable_watchdog() {
1974
	global $config;
1975
	return;
1976
	$install_watchdog = false;
1977
	$supported_watchdogs = array("Geode");
1978
	$file = file_get_contents("/var/log/dmesg.boot");
1979
	foreach ($supported_watchdogs as $sd) {
1980
		if (stristr($file, "Geode")) {
1981
			$install_watchdog = true;
1982
		}
1983
	}
1984
	if ($install_watchdog == true) {
1985
		if (is_process_running("watchdogd")) {
1986
			mwexec("/usr/bin/killall watchdogd", true);
1987
		}
1988
		exec("/usr/sbin/watchdogd");
1989
	}
1990
}
1991

    
1992
function system_check_reset_button() {
1993
	global $g;
1994

    
1995
	$specplatform = system_identify_specific_platform();
1996

    
1997
	switch ($specplatform['name']) {
1998
		case 'alix':
1999
		case 'wrap':
2000
		case 'FW7541':
2001
		case 'APU':
2002
		case 'RCC-VE':
2003
		case 'RCC-DFF':
2004
			break;
2005
		default:
2006
			return 0;
2007
	}
2008

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

    
2011
	if ($retval == 99) {
2012
		/* user has pressed reset button for 2 seconds -
2013
		   reset to factory defaults */
2014
		echo <<<EOD
2015

    
2016
***********************************************************************
2017
* Reset button pressed - resetting configuration to factory defaults. *
2018
* The system will reboot after this completes.                        *
2019
***********************************************************************
2020

    
2021

    
2022
EOD;
2023

    
2024
		reset_factory_defaults();
2025
		system_reboot_sync();
2026
		exit(0);
2027
	}
2028

    
2029
	return 0;
2030
}
2031

    
2032
/* attempt to identify the specific platform (for embedded systems)
2033
   Returns an array with two elements:
2034
	name => platform string (e.g. 'wrap', 'alix' etc.)
2035
	descr => human-readable description (e.g. "PC Engines WRAP")
2036
*/
2037
function system_identify_specific_platform() {
2038
	global $g;
2039

    
2040
	if ($g['platform'] == 'generic-pc') {
2041
		return array('name' => 'generic-pc', 'descr' => gettext("Generic PC"));
2042
	}
2043

    
2044
	if ($g['platform'] == 'generic-pc-cdrom') {
2045
		return array('name' => 'generic-pc-cdrom', 'descr' => gettext("Generic PC (CD-ROM)"));
2046
	}
2047

    
2048
	/* Try to guess from smbios strings */
2049
	unset($output);
2050
	$_gb = exec('/bin/kenv smbios.system.product 2>/dev/null', $output);
2051
	switch ($output[0]) {
2052
		case 'FW7541':
2053
			return (array('name' => 'FW7541', 'descr' => 'Netgate FW7541'));
2054
			break;
2055
		case 'APU':
2056
			return (array('name' => 'APU', 'descr' => 'Netgate APU'));
2057
			break;
2058
		case 'RCC-VE':
2059
			return (array('name' => 'RCC-VE', 'descr' => 'Netgate RCC-VE'));
2060
			break;
2061
		case 'DFFv2':
2062
			return (array('name' => 'RCC-DFF', 'descr' => 'Netgate RCC-DFF'));
2063
			break;
2064
		case 'SYS-5018A-FTN4':
2065
		case 'A1SAi':
2066
			return (array('name' => 'C2758', 'descr' => 'Super Micro C2758'));
2067
			break;
2068
		case 'SYS-5018D-FN4T':
2069
			return (array('name' => 'D1540-XG', 'descr' => 'Super Micro D1540-XG'));
2070
			break;
2071
	}
2072

    
2073
	/* the rest of the code only deals with 'embedded' platforms */
2074
	if ($g['platform'] != 'nanobsd') {
2075
		return array('name' => $g['platform'], 'descr' => $g['platform']);
2076
	}
2077

    
2078
	$dmesg = get_single_sysctl('hw.model');
2079

    
2080
	if (strpos($dmesg, "PC Engines WRAP") !== false) {
2081
		return array('name' => 'wrap', 'descr' => gettext('PC Engines WRAP'));
2082
	}
2083

    
2084
	if (strpos($dmesg, "PC Engines ALIX") !== false) {
2085
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
2086
	}
2087

    
2088
	if (preg_match("/Soekris net45../", $dmesg, $matches)) {
2089
		return array('name' => 'net45xx', 'descr' => $matches[0]);
2090
	}
2091

    
2092
	if (preg_match("/Soekris net48../", $dmesg, $matches)) {
2093
		return array('name' => 'net48xx', 'descr' => $matches[0]);
2094
	}
2095

    
2096
	if (preg_match("/Soekris net55../", $dmesg, $matches)) {
2097
		return array('name' => 'net55xx', 'descr' => $matches[0]);
2098
	}
2099

    
2100
	unset($dmesg);
2101

    
2102
	$dmesg_boot = system_get_dmesg_boot();
2103
	if (strpos($dmesg_boot, "PC Engines ALIX") !== false) {
2104
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
2105
	}
2106
	unset($dmesg_boot);
2107

    
2108
	/* unknown embedded platform */
2109
	return array('name' => 'embedded', 'descr' => gettext('embedded (unknown)'));
2110
}
2111

    
2112
function system_get_dmesg_boot() {
2113
	global $g;
2114

    
2115
	return file_get_contents("{$g['varlog_path']}/dmesg.boot");
2116
}
2117

    
2118
?>
(52-52/65)