Project

General

Profile

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

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

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

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

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

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

    
32
/*
33
	pfSense_BUILDER_BINARIES:	/usr/sbin/powerd	/usr/bin/killall	/sbin/route
34
	pfSense_BUILDER_BINARIES:	/bin/hostname	/bin/ls	/usr/sbin/syslogd
35
	pfSense_BUILDER_BINARIES:	/usr/sbin/pccardd	/usr/local/sbin/lighttpd	/bin/chmod 	/bin/mkdir
36
	pfSense_BUILDER_BINARIES:	/usr/bin/tar		/usr/local/sbin/ntpd	/usr/local/sbin/ntpdate
37
	pfSense_BUILDER_BINARIES:	/usr/bin/nohup	/sbin/dmesg	/usr/local/sbin/atareinit	/sbin/kldload
38
	pfSense_BUILDER_BINARIES:	/usr/local/sbin/filterdns
39
	pfSense_MODULE:	utils
40
*/
41

    
42
function activate_powerd() {
43
	global $config, $g;
44
	if ($g['platform'] == 'jail') {
45
		return;
46
	}
47
	if (is_process_running("powerd")) {
48
		exec("/usr/bin/killall powerd");
49
	}
50
	if (isset($config['system']['powerd_enable'])) {
51
		if ($g["platform"] == "nanobsd") {
52
			exec("/sbin/kldload cpufreq");
53
		}
54

    
55
		$ac_mode = "hadp";
56
		if (!empty($config['system']['powerd_ac_mode'])) {
57
			$ac_mode = $config['system']['powerd_ac_mode'];
58
		}
59

    
60
		$battery_mode = "hadp";
61
		if (!empty($config['system']['powerd_battery_mode'])) {
62
			$battery_mode = $config['system']['powerd_battery_mode'];
63
		}
64

    
65
		$normal_mode = "hadp";
66
		if (!empty($config['system']['powerd_normal_mode'])) {
67
			$normal_mode = $config['system']['powerd_normal_mode'];
68
		}
69

    
70
		mwexec("/usr/sbin/powerd -b $battery_mode -a $ac_mode -n $normal_mode");
71
	}
72
}
73

    
74
function get_default_sysctl_value($id) {
75
	global $sysctls;
76

    
77
	if (isset($sysctls[$id])) {
78
		return $sysctls[$id];
79
	}
80
}
81

    
82
function get_sysctl_descr($sysctl) {
83
	unset($output);
84
	$_gb = exec("/sbin/sysctl -nd {$sysctl}", $output);
85

    
86
	return $output[0];
87
}
88

    
89
function system_get_sysctls() {
90
	global $config, $sysctls;
91

    
92
	$disp_sysctl = array();
93
	$disp_cache = array();
94
	if (is_array($config['sysctl']) && is_array($config['sysctl']['item'])) {
95
		foreach ($config['sysctl']['item'] as $id => $tunable) {
96
			if ($tunable['value'] == "default") {
97
				$value = get_default_sysctl_value($tunable['tunable']);
98
			} else {
99
				$value = $tunable['value'];
100
			}
101

    
102
			$disp_sysctl[$id] = $tunable;
103
			$disp_sysctl[$id]['modified'] = true;
104
			$disp_cache[$tunable['tunable']] = 'set';
105
		}
106
	}
107

    
108
	foreach ($sysctls as $sysctl => $value) {
109
		if (isset($disp_cache[$sysctl])) {
110
			continue;
111
		}
112

    
113
		$disp_sysctl[$sysctl] = array('tunable' => $sysctl, 'value' => $value, 'descr' => get_sysctl_descr($sysctl));
114
	}
115
	unset($disp_cache);
116
	return $disp_sysctl;
117
}
118

    
119
function activate_sysctls() {
120
	global $config, $g, $sysctls;
121

    
122
	if ($g['platform'] == 'jail') {
123
		return;
124
	}
125

    
126
	if (is_array($config['sysctl']) && is_array($config['sysctl']['item'])) {
127
		foreach ($config['sysctl']['item'] as $tunable) {
128
			if ($tunable['value'] == "default") {
129
				$value = get_default_sysctl_value($tunable['tunable']);
130
			} else {
131
				$value = $tunable['value'];
132
			}
133

    
134
			$sysctls[$tunable['tunable']] = $value;
135
		}
136
	}
137

    
138
	set_sysctl($sysctls);
139
}
140

    
141
function system_resolvconf_generate($dynupdate = false) {
142
	global $config, $g;
143

    
144
	if (isset($config['system']['developerspew'])) {
145
		$mt = microtime();
146
		echo "system_resolvconf_generate() being called $mt\n";
147
	}
148

    
149
	$syscfg = $config['system'];
150

    
151
	if ((((isset($config['dnsmasq']['enable'])) &&
152
	      (!isset($config['dnsmasq']['port']) || $config['dnsmasq']['port'] == "53") &&
153
	      (empty($config['dnsmasq']['interface']) ||
154
	       in_array("lo0", explode(",", $config['dnsmasq']['interface'])))) ||
155
	     ((isset($config['unbound']['enable'])) &&
156
	      (!isset($config['unbound']['port']) || $config['unbound']['port'] == "53") &&
157
	      (empty($config['unbound']['active_interface']) ||
158
	       in_array("lo0", explode(",", $config['unbound']['active_interface'])) ||
159
	       in_array("all", explode(",", $config['unbound']['active_interface']), true)))) &&
160
	     (!isset($config['system']['dnslocalhost']))) {
161
		$resolvconf .= "nameserver 127.0.0.1\n";
162
	}
163

    
164
	if (isset($syscfg['dnsallowoverride'])) {
165
		/* get dynamically assigned DNS servers (if any) */
166
		$ns = array_unique(get_searchdomains());
167
		foreach ($ns as $searchserver) {
168
			if ($searchserver) {
169
				$resolvconf .= "search {$searchserver}\n";
170
			}
171
		}
172
		$ns = array_unique(get_nameservers());
173
		foreach ($ns as $nameserver) {
174
			if ($nameserver) {
175
				$resolvconf .= "nameserver $nameserver\n";
176
			}
177
		}
178
	} else {
179
		$ns = array();
180
		// Do not create blank search/domain lines, it can break tools like dig.
181
		if ($syscfg['domain']) {
182
			$resolvconf .= "search {$syscfg['domain']}\n";
183
		}
184
	}
185
	if (is_array($syscfg['dnsserver'])) {
186
		foreach ($syscfg['dnsserver'] as $sys_dnsserver) {
187
			if ($sys_dnsserver && (!in_array($sys_dnsserver, $ns))) {
188
				$resolvconf .= "nameserver $sys_dnsserver\n";
189
			}
190
		}
191
	}
192

    
193
	// Add EDNS support
194
	if (isset($config['unbound']['enable']) && isset($config['unbound']['edns'])) {
195
		$resolvconf .= "options edns0\n";
196
	}
197

    
198
	$dnslock = lock('resolvconf', LOCK_EX);
199

    
200
	$fd = fopen("{$g['varetc_path']}/resolv.conf", "w");
201
	if (!$fd) {
202
		printf("Error: cannot open resolv.conf in system_resolvconf_generate().\n");
203
		unlock($dnslock);
204
		return 1;
205
	}
206

    
207
	fwrite($fd, $resolvconf);
208
	fclose($fd);
209

    
210
	// Prevent resolvconf(8) from rewriting our resolv.conf
211
	$fd = fopen("{$g['varetc_path']}/resolvconf.conf", "w");
212
	if (!$fd) {
213
		printf("Error: cannot open resolvconf.conf in system_resolvconf_generate().\n");
214
		return 1;
215
	}
216
	fwrite($fd, "resolv_conf=\"/dev/null\"\n");
217
	fclose($fd);
218

    
219
	if (!platform_booting()) {
220
		/* restart dhcpd (nameservers may have changed) */
221
		if (!$dynupdate) {
222
			services_dhcpd_configure();
223
		}
224
	}
225

    
226
	/* setup static routes for DNS servers. */
227
	for ($dnscounter=1; $dnscounter<5; $dnscounter++) {
228
		/* setup static routes for dns servers */
229
		$dnsgw = "dns{$dnscounter}gw";
230
		if (isset($config['system'][$dnsgw])) {
231
			$gwname = $config['system'][$dnsgw];
232
			if (($gwname <> "") && ($gwname <> "none")) {
233
				$gatewayip = lookup_gateway_ip_by_name($gwname);
234
				if (is_ipaddrv4($gatewayip)) {
235
					/* dns server array starts at 0 */
236
					$dnscountermo = $dnscounter - 1;
237
					mwexec("/sbin/route change -host " . $syscfg['dnsserver'][$dnscountermo] . " {$gatewayip}");
238
					if (isset($config['system']['route-debug'])) {
239
						$mt = microtime();
240
						log_error("ROUTING debug: $mt - route change -host {$syscfg['dnsserver'][$dnscountermo]} $gatewayip ");
241
					}
242
				}
243
				if (is_ipaddrv6($gatewayip)) {
244
					/* dns server array starts at 0 */
245
					$dnscountermo = $dnscounter - 1;
246
					mwexec("/sbin/route change -host -inet6 " . $syscfg['dnsserver'][$dnscountermo] . " {$gatewayip}");
247
					if (isset($config['system']['route-debug'])) {
248
						$mt = microtime();
249
						log_error("ROUTING debug: $mt - route change -host -inet6 {$syscfg['dnsserver'][$dnscountermo]} $gatewayip ");
250
					}
251
				}
252
			}
253
		}
254
	}
255

    
256
	unlock($dnslock);
257

    
258
	return 0;
259
}
260

    
261
function get_searchdomains() {
262
	global $config, $g;
263

    
264
	$master_list = array();
265

    
266
	// Read in dhclient nameservers
267
	$search_list = glob("/var/etc/searchdomain_*");
268
	if (is_array($search_list)) {
269
		foreach ($search_list as $fdns) {
270
			$contents = file($fdns, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
271
			if (!is_array($contents)) {
272
				continue;
273
			}
274
			foreach ($contents as $dns) {
275
				if (is_hostname($dns)) {
276
					$master_list[] = $dns;
277
				}
278
			}
279
		}
280
	}
281

    
282
	return $master_list;
283
}
284

    
285
function get_nameservers() {
286
	global $config, $g;
287
	$master_list = array();
288

    
289
	// Read in dhclient nameservers
290
	$dns_lists = glob("/var/etc/nameserver_*");
291
	if (is_array($dns_lists)) {
292
		foreach ($dns_lists as $fdns) {
293
			$contents = file($fdns, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
294
			if (!is_array($contents)) {
295
				continue;
296
			}
297
			foreach ($contents as $dns) {
298
				if (is_ipaddr($dns)) {
299
					$master_list[] = $dns;
300
				}
301
			}
302
		}
303
	}
304

    
305
	// Read in any extra nameservers
306
	if (file_exists("/var/etc/nameservers.conf")) {
307
		$dns_s = file("/var/etc/nameservers.conf", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
308
		if (is_array($dns_s)) {
309
			foreach ($dns_s as $dns) {
310
				if (is_ipaddr($dns)) {
311
					$master_list[] = $dns;
312
				}
313
			}
314
		}
315
	}
316

    
317
	return $master_list;
318
}
319

    
320
function system_hosts_generate() {
321
	global $config, $g;
322
	if (isset($config['system']['developerspew'])) {
323
		$mt = microtime();
324
		echo "system_hosts_generate() being called $mt\n";
325
	}
326

    
327
	$syscfg = $config['system'];
328
	if (isset($config['unbound']) && isset($config['unbound']['enable'])) {
329
		$dnsmasqcfg = $config['unbound'];
330
	} else {
331
		$dnsmasqcfg = $config['dnsmasq'];
332
	}
333

    
334
	$hosts =  "127.0.0.1	localhost localhost.{$syscfg['domain']}\n";
335
	$hosts .= "::1		localhost localhost.{$syscfg['domain']}\n";
336
	$lhosts = "";
337
	$dhosts = "";
338

    
339
	if ($config['interfaces']['lan']) {
340
		$cfgip = get_interface_ip("lan");
341
		if (is_ipaddr($cfgip)) {
342
			$hosts .= "{$cfgip}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
343
		}
344
		$cfgipv6 = get_interface_ipv6("lan");
345
		if (is_ipaddrv6($cfgipv6)) {
346
			$hosts .= "{$cfgipv6}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
347
		}
348
	} else {
349
		$sysiflist = get_configured_interface_list();
350
		$hosts_if_found = false;
351
		foreach ($sysiflist as $sysif) {
352
			if (!interface_has_gateway($sysif)) {
353
				$cfgip = get_interface_ip($sysif);
354
				if (is_ipaddr($cfgip)) {
355
					$hosts .= "{$cfgip}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
356
					$hosts_if_found = true;
357
				}
358
				$cfgipv6 = get_interface_ipv6($sysif);
359
				if (is_ipaddrv6($cfgipv6)) {
360
					$hosts .= "{$cfgipv6}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
361
					$hosts_if_found = true;
362
				}
363
				if ($hosts_if_found == true) {
364
					break;
365
				}
366
			}
367
		}
368
	}
369

    
370
	if (isset($dnsmasqcfg['enable'])) {
371
		if (!is_array($dnsmasqcfg['hosts'])) {
372
			$dnsmasqcfg['hosts'] = array();
373
		}
374

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

    
423
		if (isset($dnsmasqcfg['dhcpfirst'])) {
424
			$hosts .= $dhosts . $lhosts;
425
		} else {
426
			$hosts .= $lhosts . $dhosts;
427
		}
428
	}
429

    
430
	/*
431
	 * Do not remove this because dhcpleases monitors with kqueue it needs to be
432
	 * killed before writing to hosts files.
433
	 */
434
	if (file_exists("{$g['varrun_path']}/dhcpleases.pid")) {
435
		sigkillbypid("{$g['varrun_path']}/dhcpleases.pid", "TERM");
436
		@unlink("{$g['varrun_path']}/dhcpleases.pid");
437
	}
438
	$fd = fopen("{$g['varetc_path']}/hosts", "w");
439
	if (!$fd) {
440
		log_error("Error: cannot open hosts file in system_hosts_generate().\n");
441
		return 1;
442
	}
443
	fwrite($fd, $hosts);
444
	fclose($fd);
445

    
446
	if (isset($config['unbound']['enable'])) {
447
		require_once("unbound.inc");
448
		unbound_hosts_generate();
449
	}
450

    
451
	return 0;
452
}
453

    
454
function system_dhcpleases_configure() {
455
	global $config, $g;
456

    
457
	if ($g['platform'] == 'jail') {
458
		return;
459
	}
460
	/* Start the monitoring process for dynamic dhcpclients. */
461
	if ((isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcp'])) ||
462
	    (isset($config['unbound']['enable']) && isset($config['unbound']['regdhcp']))) {
463
		/* Make sure we do not error out */
464
		mwexec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/db");
465
		if (!file_exists("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases")) {
466
			@touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
467
		}
468

    
469
		if (isset($config['unbound']['enable'])) {
470
			$dns_pid = "unbound.pid";
471
			$unbound_conf = "-u {$g['unbound_chroot_path']}/dhcpleases_entries.conf";
472
		} else {
473
			$dns_pid = "dnsmasq.pid";
474
			$unbound_conf = "";
475
		}
476

    
477
		$pidfile = "{$g['varrun_path']}/dhcpleases.pid";
478
		if (isvalidpid($pidfile)) {
479
			/* Make sure dhcpleases is using correct unbound or dnsmasq */
480
			$_gb = exec("/bin/pgrep -F {$pidfile} -f {$dns_pid}", $output, $retval);
481
			if (intval($retval) == 0) {
482
				sigkillbypid($pidfile, "HUP");
483
				return;
484
			} else {
485
				sigkillbypid($pidfile, "TERM");
486
			}
487
		}
488

    
489
		/* To ensure we do not start multiple instances of dhcpleases, perform some clean-up first. */
490
		if (is_process_running("dhcpleases")) {
491
			sigkillbyname('dhcpleases', "TERM");
492
		}
493
		@unlink($pidfile);
494
		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");
495
	} else {
496
		sigkillbypid($pidfile, "TERM");
497
		@unlink($pidfile);
498
	}
499
}
500

    
501
function system_hostname_configure() {
502
	global $config, $g;
503
	if (isset($config['system']['developerspew'])) {
504
		$mt = microtime();
505
		echo "system_hostname_configure() being called $mt\n";
506
	}
507

    
508
	$syscfg = $config['system'];
509

    
510
	/* set hostname */
511
	$status = mwexec("/bin/hostname " .
512
		escapeshellarg("{$syscfg['hostname']}.{$syscfg['domain']}"));
513

    
514
	/* Setup host GUID ID.  This is used by ZFS. */
515
	mwexec("/etc/rc.d/hostid start");
516

    
517
	return $status;
518
}
519

    
520
function system_routing_configure($interface = "") {
521
	global $config, $g;
522
	if ($g['platform'] == 'jail') {
523
		return;
524
	}
525
	if (isset($config['system']['developerspew'])) {
526
		$mt = microtime();
527
		echo "system_routing_configure() being called $mt\n";
528
	}
529

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

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

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

    
621
	system_staticroutes_configure($interface, false);
622

    
623
	return 0;
624
}
625

    
626
function system_staticroutes_configure($interface = "", $update_dns = false) {
627
	global $config, $g, $aliastable;
628

    
629
	$filterdns_list = array();
630

    
631
	$static_routes = get_staticroutes(false, true);
632
	if (count($static_routes)) {
633
		$gateways_arr = return_gateways_array(false, true);
634

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

    
645
			$gatewayip = $gateway['gateway'];
646
			$interfacegw = $gateway['interface'];
647

    
648
			$blackhole = "";
649
			if (!strcasecmp("Null", substr($rtent['gateway'], 0, 3))) {
650
				$blackhole = "-blackhole";
651
			}
652

    
653
			if (!is_fqdn($rtent['network']) && !is_subnet($rtent['network'])) {
654
				continue;
655
			}
656

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

    
668
			if (is_subnet($rtent['network'])) {
669
				$ips = array($rtent['network']);
670
			} else {
671
				if (!isset($rtent['disabled'])) {
672
					$filterdns_list[] = $rtent['network'];
673
				}
674
				$ips = add_hostname_to_watch($rtent['network']);
675
			}
676

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

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

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

    
706
				$inet = (is_subnetv6($ip) ? "-inet6" : "-inet");
707

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

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

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

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

    
754
	return 0;
755
}
756

    
757
function system_routing_enable() {
758
	global $config, $g;
759
	if (isset($config['system']['developerspew'])) {
760
		$mt = microtime();
761
		echo "system_routing_enable() being called $mt\n";
762
	}
763

    
764
	set_sysctl(array(
765
		"net.inet.ip.forwarding" => "1",
766
		"net.inet6.ip6.forwarding" => "1"
767
	));
768

    
769
	return;
770
}
771

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

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

    
799
function system_syslogd_start() {
800
	global $config, $g;
801
	if (isset($config['system']['developerspew'])) {
802
		$mt = microtime();
803
		echo "system_syslogd_start() being called $mt\n";
804
	}
805

    
806
	mwexec("/etc/rc.d/hostid start");
807

    
808
	$syslogcfg = $config['syslog'];
809

    
810
	if (platform_booting()) {
811
		echo gettext("Starting syslog...");
812
	}
813

    
814
	if (is_process_running("fifolog_writer")) {
815
		mwexec('/bin/pkill fifolog_writer');
816
	}
817

    
818
	// Which logging type are we using this week??
819
	if (isset($config['system']['disablesyslogclog'])) {
820
		$log_directive = "";
821
		$log_create_directive = "/usr/bin/touch ";
822
		$log_size = "";
823
	} else if (isset($config['system']['usefifolog'])) {
824
		$log_directive = "|/usr/sbin/fifolog_writer ";
825
		$log_size = isset($config['syslog']['logfilesize']) ? $config['syslog']['logfilesize'] : "10240";
826
		$log_create_directive = "/usr/sbin/fifolog_create -s ";
827
	} else { // Defaults to CLOG
828
		$log_directive = "%";
829
		$log_size = isset($config['syslog']['logfilesize']) ? $config['syslog']['logfilesize'] : "10240";
830
		$log_create_directive = "/usr/local/sbin/clog -i -s ";
831
	}
832

    
833
	$syslogd_extra = "";
834
	if (isset($syslogcfg)) {
835
		$separatelogfacilities = array('ntp','ntpd','ntpdate','charon','ipsec_starter','openvpn','pptps','poes','l2tps','relayd','hostapd','dnsmasq','filterdns','unbound','dhcpd','dhcrelay','dhclient','dhcp6c','apinger','radvd','routed','olsrd','zebra','ospfd','bgpd','miniupnpd','filterlog');
836
		$syslogconf = "";
837
		if ($config['installedpackages']['package']) {
838
			foreach ($config['installedpackages']['package'] as $package) {
839
				if ($package['logging']) {
840
					array_push($separatelogfacilities, $package['logging']['facilityname']);
841
					mwexec("{$log_create_directive} {$log_size} {$g['varlog_path']}/{$package['logging']['logfilename']}");
842
					$syslogconf .= "!{$package['logging']['facilityname']}\n*.*\t\t\t\t\t\t {$log_directive}{$g['varlog_path']}/{$package['logging']['logfilename']}\n";
843
				}
844
			}
845
		}
846
		$facilitylist = implode(',', array_unique($separatelogfacilities));
847
		$syslogconf .= "!radvd,routed,olsrd,zebra,ospfd,bgpd,miniupnpd\n";
848
		if (!isset($syslogcfg['disablelocallogging'])) {
849
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/routing.log\n";
850
		}
851

    
852
		$syslogconf .= "!ntp,ntpd,ntpdate\n";
853
		if (!isset($syslogcfg['disablelocallogging'])) {
854
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ntpd.log\n";
855
		}
856

    
857
		$syslogconf .= "!ppp\n";
858
		if (!isset($syslogcfg['disablelocallogging'])) {
859
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ppp.log\n";
860
		}
861

    
862
		$syslogconf .= "!pptps\n";
863
		if (!isset($syslogcfg['disablelocallogging'])) {
864
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/pptps.log\n";
865
		}
866

    
867
		$syslogconf .= "!poes\n";
868
		if (!isset($syslogcfg['disablelocallogging'])) {
869
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/poes.log\n";
870
		}
871

    
872
		$syslogconf .= "!l2tps\n";
873
		if (!isset($syslogcfg['disablelocallogging'])) {
874
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/l2tps.log\n";
875
		}
876

    
877
		$syslogconf .= "!charon,ipsec_starter\n";
878
		if (!isset($syslogcfg['disablelocallogging'])) {
879
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ipsec.log\n";
880
		}
881
		if (isset($syslogcfg['vpn'])) {
882
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
883
		}
884

    
885
		$syslogconf .= "!openvpn\n";
886
		if (!isset($syslogcfg['disablelocallogging'])) {
887
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/openvpn.log\n";
888
		}
889
		if (isset($syslogcfg['vpn'])) {
890
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
891
		}
892

    
893
		$syslogconf .= "!apinger\n";
894
		if (!isset($syslogcfg['disablelocallogging'])) {
895
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/gateways.log\n";
896
		}
897
		if (isset($syslogcfg['apinger'])) {
898
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
899
		}
900

    
901
		$syslogconf .= "!dnsmasq,filterdns,unbound\n";
902
		if (!isset($syslogcfg['disablelocallogging'])) {
903
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/resolver.log\n";
904
		}
905

    
906
		$syslogconf .= "!dhcpd,dhcrelay,dhclient,dhcp6c\n";
907
		if (!isset($syslogcfg['disablelocallogging'])) {
908
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/dhcpd.log\n";
909
		}
910
		if (isset($syslogcfg['dhcp'])) {
911
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
912
		}
913

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

    
922
		$syslogconf .= "!hostapd\n";
923
		if (!isset($syslogcfg['disablelocallogging'])) {
924
			$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/wireless.log\n";
925
		}
926
		if (isset($syslogcfg['hostapd'])) {
927
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
928
		}
929

    
930
		$syslogconf .= "!filterlog\n";
931
		$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/filter.log\n";
932
		if (isset($syslogcfg['filter'])) {
933
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
934
		}
935

    
936
		$syslogconf .= "!-{$facilitylist}\n";
937
		if (!isset($syslogcfg['disablelocallogging'])) {
938
			$syslogconf .= <<<EOD
939
local3.*							{$log_directive}{$g['varlog_path']}/vpn.log
940
local4.*							{$log_directive}{$g['varlog_path']}/portalauth.log
941
local7.*							{$log_directive}{$g['varlog_path']}/dhcpd.log
942
*.notice;kern.debug;lpr.info;mail.crit;daemon.none;		{$log_directive}{$g['varlog_path']}/system.log
943
news.err;local0.none;local3.none;local4.none;			{$log_directive}{$g['varlog_path']}/system.log
944
local7.none							{$log_directive}{$g['varlog_path']}/system.log
945
security.*							{$log_directive}{$g['varlog_path']}/system.log
946
auth.info;authpriv.info;daemon.info				{$log_directive}{$g['varlog_path']}/system.log
947
auth.info;authpriv.info 					|exec /usr/local/sbin/sshlockout_pf 15
948
*.emerg								*
949

    
950
EOD;
951
		}
952
		if (isset($syslogcfg['vpn'])) {
953
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local3.*");
954
		}
955
		if (isset($syslogcfg['portalauth'])) {
956
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local4.*");
957
		}
958
		if (isset($syslogcfg['dhcp'])) {
959
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local7.*");
960
		}
961
		if (isset($syslogcfg['system'])) {
962
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.notice;kern.debug;lpr.info;mail.crit;");
963
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "news.err;local0.none;local3.none;local7.none");
964
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "security.*");
965
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "auth.info;authpriv.info;daemon.info");
966
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.emerg");
967
		}
968
		if (isset($syslogcfg['logall'])) {
969
			// Make everything mean everything, including facilities excluded above.
970
			$syslogconf .= "!*\n";
971
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
972
		}
973

    
974
		if (isset($syslogcfg['zmqserver'])) {
975
				$syslogconf .= <<<EOD
976
*.*								^{$syslogcfg['zmqserver']}
977

    
978
EOD;
979
		}
980
		/* write syslog.conf */
981
		if (!@file_put_contents("{$g['varetc_path']}/syslog.conf", $syslogconf)) {
982
			printf(gettext("Error: cannot open syslog.conf in system_syslogd_start().%s"), "\n");
983
			unset($syslogconf);
984
			return 1;
985
		}
986
		unset($syslogconf);
987

    
988
		// Ensure that the log directory exists
989
		if (!is_dir("{$g['dhcpd_chroot_path']}/var/run")) {
990
			exec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/run");
991
		}
992

    
993
		$sourceip = "";
994
		if (!empty($syslogcfg['sourceip'])) {
995
			if ($syslogcfg['ipproto'] == "ipv6") {
996
				$ifaddr = is_ipaddr($syslogcfg['sourceip']) ? $syslogcfg['sourceip'] : get_interface_ipv6($syslogcfg['sourceip']);
997
				if (!is_ipaddr($ifaddr)) {
998
					$ifaddr = get_interface_ip($syslogcfg['sourceip']);
999
				}
1000
			} else {
1001
				$ifaddr = is_ipaddr($syslogcfg['sourceip']) ? $syslogcfg['sourceip'] : get_interface_ip($syslogcfg['sourceip']);
1002
				if (!is_ipaddr($ifaddr)) {
1003
					$ifaddr = get_interface_ipv6($syslogcfg['sourceip']);
1004
				}
1005
			}
1006
			if (is_ipaddr($ifaddr)) {
1007
				$sourceip = "-b {$ifaddr}";
1008
			}
1009
		}
1010

    
1011
		$syslogd_extra = "-f {$g['varetc_path']}/syslog.conf {$sourceip}";
1012
	}
1013

    
1014
	if (isvalidpid("{$g['varrun_path']}/syslog.pid")) {
1015
		sigkillbypid("{$g['varrun_path']}/syslog.pid", "TERM");
1016
		usleep(100000); // syslogd often doesn't respond to a TERM quickly enough for the starting of syslogd below to be successful
1017
	}
1018

    
1019
	if (isvalidpid("{$g['varrun_path']}/syslog.pid")) {
1020
		// if it still hasn't responded to the TERM, KILL it.
1021
		sigkillbypid("{$g['varrun_path']}/syslog.pid", "KILL");
1022
		usleep(100000);
1023
	}
1024

    
1025

    
1026
	$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}");
1027

    
1028
	if (platform_booting()) {
1029
		echo gettext("done.") . "\n";
1030
	}
1031

    
1032
	return $retval;
1033
}
1034

    
1035
function system_webgui_create_certificate() {
1036
	global $config, $g;
1037

    
1038
	if (!is_array($config['ca'])) {
1039
		$config['ca'] = array();
1040
	}
1041
	$a_ca =& $config['ca'];
1042
	if (!is_array($config['cert'])) {
1043
		$config['cert'] = array();
1044
	}
1045
	$a_cert =& $config['cert'];
1046
	log_error("Creating SSL Certificate for this host");
1047

    
1048
	$cert = array();
1049
	$cert['refid'] = uniqid();
1050
	$cert['descr'] = gettext("webConfigurator default ({$cert['refid']})");
1051

    
1052
	$dn = array(
1053
		'countryName' => "US",
1054
		'stateOrProvinceName' => "State",
1055
		'localityName' => "Locality",
1056
		'organizationName' => "{$g['product_name']} webConfigurator Self-Signed Certificate",
1057
		'emailAddress' => "admin@{$config['system']['hostname']}.{$config['system']['domain']}",
1058
		'commonName' => "{$config['system']['hostname']}-{$cert['refid']}");
1059
	$old_err_level = error_reporting(0); /* otherwise openssl_ functions throw warnings directly to a page screwing menu tab */
1060
	if (!cert_create($cert, null, 2048, 2000, $dn, "self-signed", "sha256")) {
1061
		while ($ssl_err = openssl_error_string()) {
1062
			log_error("Error creating WebGUI Certificate: openssl library returns: " . $ssl_err);
1063
		}
1064
		error_reporting($old_err_level);
1065
		return null;
1066
	}
1067
	error_reporting($old_err_level);
1068

    
1069
	$a_cert[] = $cert;
1070
	$config['system']['webgui']['ssl-certref'] = $cert['refid'];
1071
	write_config(gettext("Generated new self-signed HTTPS certificate ({$cert['refid']})"));
1072
	return $cert;
1073
}
1074

    
1075
function system_webgui_start() {
1076
	global $config, $g;
1077

    
1078
	if (platform_booting()) {
1079
		echo gettext("Starting webConfigurator...");
1080
	}
1081

    
1082
	chdir($g['www_path']);
1083

    
1084
	/* defaults */
1085
	$portarg = "80";
1086
	$crt = "";
1087
	$key = "";
1088
	$ca = "";
1089

    
1090
	/* non-standard port? */
1091
	if (isset($config['system']['webgui']['port']) && $config['system']['webgui']['port'] <> "") {
1092
		$portarg = "{$config['system']['webgui']['port']}";
1093
	}
1094

    
1095
	if ($config['system']['webgui']['protocol'] == "https") {
1096
		// Ensure that we have a webConfigurator CERT
1097
		$cert =& lookup_cert($config['system']['webgui']['ssl-certref']);
1098
		if (!is_array($cert) || !$cert['crt'] || !$cert['prv']) {
1099
			$cert = system_webgui_create_certificate();
1100
		}
1101
		$crt = base64_decode($cert['crt']);
1102
		$key = base64_decode($cert['prv']);
1103

    
1104
		if (!$config['system']['webgui']['port']) {
1105
			$portarg = "443";
1106
		}
1107
		$ca  = ca_chain($cert);
1108
	}
1109

    
1110
	/* generate lighttpd configuration */
1111
	system_generate_lighty_config("{$g['varetc_path']}/lighty-webConfigurator.conf",
1112
		$crt, $key, $ca, "lighty-webConfigurator.pid", $portarg, "/usr/local/www/",
1113
		"cert.pem", "ca.pem");
1114

    
1115
	/* kill any running lighttpd */
1116
	killbypid("{$g['varrun_path']}/lighty-webConfigurator.pid");
1117

    
1118
	sleep(1);
1119

    
1120
	@unlink("{$g['varrun_path']}/lighty-webConfigurator.pid");
1121

    
1122
	/* attempt to start lighthttpd */
1123
	$res = mwexec("/usr/local/sbin/lighttpd -f {$g['varetc_path']}/lighty-webConfigurator.conf");
1124

    
1125
	if (platform_booting()) {
1126
		if ($res == 0) {
1127
			echo gettext("done.") . "\n";
1128
		} else {
1129
			echo gettext("failed!") . "\n";
1130
		}
1131
	}
1132

    
1133
	return $res;
1134
}
1135

    
1136
function system_generate_lighty_config($filename,
1137
	$cert,
1138
	$key,
1139
	$ca,
1140
	$pid_file,
1141
	$port = 80,
1142
	$document_root = "/usr/local/www/",
1143
	$cert_location = "cert.pem",
1144
	$ca_location = "ca.pem",
1145
	$captive_portal = false) {
1146

    
1147
	global $config, $g;
1148

    
1149
	if (!is_dir("{$g['tmp_path']}/lighttpdcompress")) {
1150
		mkdir("{$g['tmp_path']}/lighttpdcompress");
1151
	}
1152

    
1153
	if (isset($config['system']['developerspew'])) {
1154
		$mt = microtime();
1155
		echo "system_generate_lighty_config() being called $mt\n";
1156
	}
1157

    
1158
	if ($captive_portal !== false)  {
1159
		$captiveportal = ",\"mod_rewrite\",\"mod_evasive\"";
1160
		$captive_portal_rewrite = "url.rewrite-once = ( \"(.*captiveportal.*)\" => \"$1\", \"(.*)\" => \"/index.php?zone={$captive_portal}&redirurl=$1\" )\n";
1161

    
1162
		$maxprocperip = $config['captiveportal'][$captive_portal]['maxprocperip'];
1163
		if (empty($maxprocperip)) {
1164
			$maxprocperip = 10;
1165
		}
1166
		$captive_portal_mod_evasive = "evasive.max-conns-per-ip = {$maxprocperip}";
1167

    
1168
		$server_upload_dirs = "server.upload-dirs = ( \"{$g['tmp_path']}/captiveportal/\" )\n";
1169
		if (!is_dir("{$g['tmp_path']}/captiveportal")) {
1170
			@mkdir("{$g['tmp_path']}/captiveportal", 0555);
1171
		}
1172
		$server_max_request_size = "server.max-request-size    = 384";
1173
		$cgi_config = "";
1174
	} else {
1175
		$captiveportal = ",\"mod_cgi\"";
1176
		$captive_portal_rewrite = "";
1177
		$captive_portal_mod_evasive = "";
1178
		$server_upload_dirs = "server.upload-dirs = ( \"{$g['upload_path']}/\", \"{$g['tmp_path']}/\", \"/var/\" )\n";
1179
		$server_max_request_size = "server.max-request-size    = 2097152";
1180
		$cgi_config = "cgi.assign                 = ( \".cgi\" => \"\" )";
1181
	}
1182

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

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

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

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

    
1214
	} else {
1215
		if ($realmem < 78) {
1216
			$max_php_children = 0;
1217
		} else {
1218
			$max_php_children = 1;
1219
		}
1220
	}
1221

    
1222
	if (!isset($config['syslog']['nologlighttpd'])) {
1223
		$lighty_use_syslog = <<<EOD
1224
## where to send error-messages to
1225
server.errorlog-use-syslog="enable"
1226
EOD;
1227
	}
1228

    
1229

    
1230
	if ($captive_portal !== false) {
1231
		$fast_cgi_path = "{$g['tmp_path']}/php-fastcgi-{$captive_portal}.socket";
1232
		$fastcgi_config = <<<EOD
1233
#### fastcgi module
1234
## read fastcgi.txt for more info
1235
fastcgi.server = ( ".php" =>
1236
	( "localhost" =>
1237
		(
1238
			"socket" => "{$fast_cgi_path}",
1239
			"max-procs" => {$max_procs},
1240
			"bin-environment" => (
1241
				"PHP_FCGI_CHILDREN" => "{$max_php_children}",
1242
				"PHP_FCGI_MAX_REQUESTS" => "500"
1243
			),
1244
			"bin-path" => "/usr/local/bin/php"
1245
		)
1246
	)
1247
)
1248

    
1249
EOD;
1250
	} else {
1251
		$fast_cgi_path = "{$g['varrun_path']}/php-fpm.socket";
1252
		$fastcgi_config = <<<EOD
1253
#### fastcgi module
1254
## read fastcgi.txt for more info
1255
fastcgi.server = ( ".php" =>
1256
	( "localhost" =>
1257
		(
1258
			"socket" => "{$fast_cgi_path}",
1259
			"broken-scriptfilename" => "enable"
1260
		)
1261
	)
1262
)
1263

    
1264
EOD;
1265
	}
1266

    
1267

    
1268
	$lighty_config = <<<EOD
1269
#
1270
# lighttpd configuration file
1271
#
1272
# use a it as base for lighttpd 1.0.0 and above
1273
#
1274
############ Options you really have to take care of ####################
1275

    
1276
## FreeBSD!
1277
server.event-handler	= "freebsd-kqueue"
1278
server.network-backend 	= "writev"
1279
#server.use-ipv6 = "enable"
1280

    
1281
## modules to load
1282
server.modules              =   ( "mod_access", "mod_expire", "mod_compress", "mod_redirect",
1283
	{$captiveportal}, "mod_fastcgi"
1284
)
1285

    
1286
server.max-keep-alive-requests = 15
1287
server.max-keep-alive-idle = 30
1288

    
1289
## a static document-root, for virtual-hosting take look at the
1290
## server.virtual-* options
1291
server.document-root        = "{$document_root}"
1292
{$captive_portal_rewrite}
1293

    
1294
# Maximum idle time with nothing being written (php downloading)
1295
server.max-write-idle = 999
1296

    
1297
{$lighty_use_syslog}
1298

    
1299
# files to check for if .../ is requested
1300
server.indexfiles           = ( "index.php", "index.html",
1301
                                "index.htm", "default.htm" )
1302

    
1303
# mimetype mapping
1304
mimetype.assign             = (
1305
  ".pdf"          =>      "application/pdf",
1306
  ".sig"          =>      "application/pgp-signature",
1307
  ".spl"          =>      "application/futuresplash",
1308
  ".class"        =>      "application/octet-stream",
1309
  ".ps"           =>      "application/postscript",
1310
  ".torrent"      =>      "application/x-bittorrent",
1311
  ".dvi"          =>      "application/x-dvi",
1312
  ".gz"           =>      "application/x-gzip",
1313
  ".pac"          =>      "application/x-ns-proxy-autoconfig",
1314
  ".swf"          =>      "application/x-shockwave-flash",
1315
  ".tar.gz"       =>      "application/x-tgz",
1316
  ".tgz"          =>      "application/x-tgz",
1317
  ".tar"          =>      "application/x-tar",
1318
  ".zip"          =>      "application/zip",
1319
  ".mp3"          =>      "audio/mpeg",
1320
  ".m3u"          =>      "audio/x-mpegurl",
1321
  ".wma"          =>      "audio/x-ms-wma",
1322
  ".wax"          =>      "audio/x-ms-wax",
1323
  ".ogg"          =>      "audio/x-wav",
1324
  ".wav"          =>      "audio/x-wav",
1325
  ".gif"          =>      "image/gif",
1326
  ".jpg"          =>      "image/jpeg",
1327
  ".jpeg"         =>      "image/jpeg",
1328
  ".png"          =>      "image/png",
1329
  ".xbm"          =>      "image/x-xbitmap",
1330
  ".xpm"          =>      "image/x-xpixmap",
1331
  ".xwd"          =>      "image/x-xwindowdump",
1332
  ".css"          =>      "text/css",
1333
  ".html"         =>      "text/html",
1334
  ".htm"          =>      "text/html",
1335
  ".js"           =>      "text/javascript",
1336
  ".asc"          =>      "text/plain",
1337
  ".c"            =>      "text/plain",
1338
  ".conf"         =>      "text/plain",
1339
  ".text"         =>      "text/plain",
1340
  ".txt"          =>      "text/plain",
1341
  ".dtd"          =>      "text/xml",
1342
  ".xml"          =>      "text/xml",
1343
  ".mpeg"         =>      "video/mpeg",
1344
  ".mpg"          =>      "video/mpeg",
1345
  ".mov"          =>      "video/quicktime",
1346
  ".qt"           =>      "video/quicktime",
1347
  ".avi"          =>      "video/x-msvideo",
1348
  ".asf"          =>      "video/x-ms-asf",
1349
  ".asx"          =>      "video/x-ms-asf",
1350
  ".wmv"          =>      "video/x-ms-wmv",
1351
  ".bz2"          =>      "application/x-bzip",
1352
  ".tbz"          =>      "application/x-bzip-compressed-tar",
1353
  ".tar.bz2"      =>      "application/x-bzip-compressed-tar"
1354
 )
1355

    
1356
# Use the "Content-Type" extended attribute to obtain mime type if possible
1357
#mimetypes.use-xattr        = "enable"
1358

    
1359
## deny access the file-extensions
1360
#
1361
# ~    is for backupfiles from vi, emacs, joe, ...
1362
# .inc is often used for code includes which should in general not be part
1363
#      of the document-root
1364
url.access-deny             = ( "~", ".inc" )
1365

    
1366

    
1367
######### Options that are good to be but not necessary to be changed #######
1368

    
1369
## disable server header
1370
server.tag = ""
1371

    
1372
## bind to port (default: 80)
1373

    
1374
EOD;
1375

    
1376
	$lighty_config .= "server.bind  = \"0.0.0.0\"\n";
1377
	$lighty_config .= "server.port  = {$lighty_port}\n";
1378
	$lighty_config .= "\$SERVER[\"socket\"]  == \"0.0.0.0:{$lighty_port}\" { }\n";
1379
	$lighty_config .= "\$SERVER[\"socket\"]  == \"[::]:{$lighty_port}\" { \n";
1380
	if ($cert <> "" and $key <> "") {
1381
		$lighty_config .= "\n";
1382
		$lighty_config .= "## ssl configuration\n";
1383
		$lighty_config .= "ssl.engine = \"enable\"\n";
1384
		$lighty_config .= "ssl.pemfile = \"{$g['varetc_path']}/{$cert_location}\"\n\n";
1385
		if ($ca <> "") {
1386
			$lighty_config .= "ssl.ca-file = \"{$g['varetc_path']}/{$ca_location}\"\n\n";
1387
		}
1388
	}
1389
	$lighty_config .= " }\n";
1390

    
1391

    
1392
	$lighty_config .= <<<EOD
1393

    
1394
## error-handler for status 404
1395
#server.error-handler-404   = "/error-handler.html"
1396
#server.error-handler-404   = "/error-handler.php"
1397

    
1398
## to help the rc.scripts
1399
server.pid-file            = "{$g['varrun_path']}/{$pid_file}"
1400

    
1401
## virtual directory listings
1402
server.dir-listing         = "disable"
1403

    
1404
## enable debugging
1405
debug.log-request-header   = "disable"
1406
debug.log-response-header  = "disable"
1407
debug.log-request-handling = "disable"
1408
debug.log-file-not-found   = "disable"
1409

    
1410
# gzip compression
1411
compress.cache-dir = "{$g['tmp_path']}/lighttpdcompress/"
1412
compress.filetype  = ("text/plain","text/css", "text/xml", "text/javascript" )
1413

    
1414
{$server_upload_dirs}
1415

    
1416
{$server_max_request_size}
1417

    
1418
{$fastcgi_config}
1419

    
1420
{$cgi_config}
1421

    
1422
{$captive_portal_mod_evasive}
1423

    
1424
expire.url = (
1425
		"" => "access 50 hours",
1426
	)
1427

    
1428
EOD;
1429

    
1430
	$cert = str_replace("\r", "", $cert);
1431
	$key = str_replace("\r", "", $key);
1432
	$ca = str_replace("\r", "", $ca);
1433

    
1434
	$cert = str_replace("\n\n", "\n", $cert);
1435
	$key = str_replace("\n\n", "\n", $key);
1436
	$ca = str_replace("\n\n", "\n", $ca);
1437

    
1438
	if ($cert <> "" and $key <> "") {
1439
		$fd = fopen("{$g['varetc_path']}/{$cert_location}", "w");
1440
		if (!$fd) {
1441
			printf(gettext("Error: cannot open cert.pem in system_webgui_start().%s"), "\n");
1442
			return 1;
1443
		}
1444
		chmod("{$g['varetc_path']}/{$cert_location}", 0600);
1445
		fwrite($fd, $cert);
1446
		fwrite($fd, "\n");
1447
		fwrite($fd, $key);
1448
		fclose($fd);
1449
		if (!(empty($ca) || (strlen(trim($ca)) == 0))) {
1450
			$fd = fopen("{$g['varetc_path']}/{$ca_location}", "w");
1451
			if (!$fd) {
1452
				printf(gettext("Error: cannot open ca.pem in system_webgui_start().%s"), "\n");
1453
				return 1;
1454
			}
1455
			chmod("{$g['varetc_path']}/{$ca_location}", 0600);
1456
			fwrite($fd, $ca);
1457
			fclose($fd);
1458
		}
1459
		$lighty_config .= "\n";
1460
		$lighty_config .= "## " . gettext("ssl configuration") . "\n";
1461
		$lighty_config .= "ssl.engine = \"enable\"\n";
1462
		$lighty_config .= "ssl.pemfile = \"{$g['varetc_path']}/{$cert_location}\"\n\n";
1463

    
1464
		// SSLv2/3 is deprecated, force use of TLS
1465
		$lighty_config .= "ssl.use-sslv2 = \"disable\"\n";
1466
		$lighty_config .= "ssl.use-sslv3 = \"disable\"\n";
1467

    
1468
		// where ssl.cipher-list is set, this is automatically enabled, but set it explicitly anyway.
1469
		$lighty_config .= "ssl.honor-cipher-order = \"enable\"\n";
1470

    
1471
		$lighty_config .= "ssl.cipher-list = \"AES128+EECDH:AES256+EECDH:AES128+EDH:AES256+EDH:AES128-SHA:AES256-SHA:!aNULL:!eNULL:!DSS\"\n";
1472

    
1473
		if (!(empty($ca) || (strlen(trim($ca)) == 0))) {
1474
			$lighty_config .= "ssl.ca-file = \"{$g['varetc_path']}/{$ca_location}\"\n\n";
1475
		}
1476
	}
1477

    
1478
	// Add HTTP to HTTPS redirect
1479
	if ($captive_portal === false && $config['system']['webgui']['protocol'] == "https" && !isset($config['system']['webgui']['disablehttpredirect'])) {
1480
		if ($lighty_port != "443") {
1481
			$redirectport = ":{$lighty_port}";
1482
		}
1483
		$lighty_config .= <<<EOD
1484
\$SERVER["socket"] == ":80" {
1485
	\$HTTP["host"] =~ "(.*)" {
1486
		url.redirect = ( "^/(.*)" => "https://%1{$redirectport}/$1" )
1487
	}
1488
}
1489
\$SERVER["socket"] == "[::]:80" {
1490
	\$HTTP["host"] =~ "(.*)" {
1491
		url.redirect = ( "^/(.*)" => "https://%1{$redirectport}/$1" )
1492
	}
1493
}
1494
EOD;
1495
	}
1496

    
1497
	$fd = fopen("{$filename}", "w");
1498
	if (!$fd) {
1499
		printf(gettext("Error: cannot open %s in system_generate_lighty_config().%s"), $filename, "\n");
1500
		return 1;
1501
	}
1502
	fwrite($fd, $lighty_config);
1503
	fclose($fd);
1504

    
1505
	return 0;
1506

    
1507
}
1508

    
1509
function system_timezone_configure() {
1510
	global $config, $g;
1511
	if (isset($config['system']['developerspew'])) {
1512
		$mt = microtime();
1513
		echo "system_timezone_configure() being called $mt\n";
1514
	}
1515

    
1516
	$syscfg = $config['system'];
1517

    
1518
	if (platform_booting()) {
1519
		echo gettext("Setting timezone...");
1520
	}
1521

    
1522
	/* extract appropriate timezone file */
1523
	$timezone = $syscfg['timezone'];
1524
	if ($timezone) {
1525
		exec('/usr/bin/tar -tvzf /usr/share/zoneinfo.tgz', $tzs);
1526
		foreach ($tzs as $tz) {
1527
			if (preg_match(",{$timezone}$,", $tz)) {
1528
				break;
1529
			}
1530
			if (preg_match(",{$timezone} link to *(.*)$,", $tz, $matches)) {
1531
				$timezone = $matches[1];
1532
				break;
1533
			}
1534
		}
1535
	} else {
1536
		$timezone = "Etc/UTC";
1537
	}
1538

    
1539
	conf_mount_rw();
1540

    
1541
	exec("LANG=C /usr/bin/tar xzfO /usr/share/zoneinfo.tgz " .
1542
		escapeshellarg($timezone) . " > /etc/localtime");
1543

    
1544
	mwexec("sync");
1545
	conf_mount_ro();
1546

    
1547
	if (platform_booting()) {
1548
		echo gettext("done.") . "\n";
1549
	}
1550
}
1551

    
1552
function system_ntp_setup_gps($serialport) {
1553
	global $config, $g;
1554
	$gps_device = '/dev/gps0';
1555
	$serialport = '/dev/'.$serialport;
1556

    
1557
	if (!file_exists($serialport)) {
1558
		return false;
1559
	}
1560

    
1561
	conf_mount_rw();
1562
	// Create symlink that ntpd requires
1563
	unlink_if_exists($gps_device);
1564
	@symlink($serialport, $gps_device);
1565

    
1566
	/* Send the following to the GPS port to initialize the GPS */
1567
	if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['type'])) {
1568
		$gps_init = base64_decode($config['ntpd']['gps']['initcmd']);
1569
	} else {
1570
		$gps_init = base64_decode('JFBVQlgsNDAsR1NWLDAsMCwwLDAqNTkNCiRQVUJYLDQwLEdMTCwwLDAsMCwwKjVDDQokUFVCWCw0MCxaREEsMCwwLDAsMCo0NA0KJFBVQlgsNDAsVlRHLDAsMCwwLDAqNUUNCiRQVUJYLDQwLEdTViwwLDAsMCwwKjU5DQokUFVCWCw0MCxHU0EsMCwwLDAsMCo0RQ0KJFBVQlgsNDAsR0dBLDAsMCwwLDANCiRQVUJYLDQwLFRYVCwwLDAsMCwwDQokUFVCWCw0MCxSTUMsMCwwLDAsMCo0Ng0KJFBVQlgsNDEsMSwwMDA3LDAwMDMsNDgwMCwwDQokUFVCWCw0MCxaREEsMSwxLDEsMQ==');
1571
	}
1572

    
1573
	/* XXX: Why not file_put_contents to the device */
1574
	@file_put_contents('/tmp/gps.init', $gps_init);
1575
	`cat /tmp/gps.init > $serialport`;
1576

    
1577
	/* Add /etc/remote entry in case we need to read from the GPS with tip */
1578
	if (intval(`grep -c '^gps0' /etc/remote`) == 0) {
1579
		$gpsbaud = '4800';
1580
		if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['speed'])) {
1581
			switch ($config['ntpd']['gps']['speed']) {
1582
				case '16':
1583
					$gpsbaud = '9600';
1584
					break;
1585
				case '32':
1586
					$gpsbaud = '19200';
1587
					break;
1588
				case '48':
1589
					$gpsbaud = '38400';
1590
					break;
1591
				case '64':
1592
					$gpsbaud = '57600';
1593
					break;
1594
				case '80':
1595
					$gpsbaud = '115200';
1596
					break;
1597
			}
1598
		}
1599
		@file_put_contents("/etc/remote", "gps0:dv={$serialport}:br#{$gpsbaud}:pa=none:", FILE_APPEND);
1600
	}
1601

    
1602
	conf_mount_ro();
1603

    
1604
	return true;
1605
}
1606

    
1607
function system_ntp_setup_pps($serialport) {
1608
	global $config, $g;
1609

    
1610
	$pps_device = '/dev/pps0';
1611
	$serialport = '/dev/'.$serialport;
1612

    
1613
	if (!file_exists($serialport)) {
1614
		return false;
1615
	}
1616

    
1617
	conf_mount_rw();
1618
	// Create symlink that ntpd requires
1619
	unlink_if_exists($pps_device);
1620
	@symlink($serialport, $pps_device);
1621

    
1622
	conf_mount_ro();
1623

    
1624
	return true;
1625
}
1626

    
1627

    
1628
function system_ntp_configure($start_ntpd=true) {
1629
	global $config, $g;
1630

    
1631
	$driftfile = "/var/db/ntpd.drift";
1632
	$statsdir = "/var/log/ntp";
1633
	$gps_device = '/dev/gps0';
1634

    
1635
	if ($g['platform'] == 'jail') {
1636
		return;
1637
	}
1638

    
1639
	safe_mkdir($statsdir);
1640

    
1641
	if (!is_array($config['ntpd'])) {
1642
		$config['ntpd'] = array();
1643
	}
1644

    
1645
	$ntpcfg = "# \n";
1646
	$ntpcfg .= "# pfSense ntp configuration file \n";
1647
	$ntpcfg .= "# \n\n";
1648
	$ntpcfg .= "tinker panic 0 \n";
1649

    
1650
	/* Add Orphan mode */
1651
	$ntpcfg .= "# Orphan mode stratum\n";
1652
	$ntpcfg .= 'tos orphan ';
1653
	if (!empty($config['ntpd']['orphan'])) {
1654
		$ntpcfg .= $config['ntpd']['orphan'];
1655
	} else {
1656
		$ntpcfg .= '12';
1657
	}
1658
	$ntpcfg .= "\n";
1659

    
1660
	/* Add PPS configuration */
1661
	if (is_array($config['ntpd']['pps']) && !empty($config['ntpd']['pps']['port']) &&
1662
	    file_exists('/dev/'.$config['ntpd']['pps']['port']) &&
1663
	    system_ntp_setup_pps($config['ntpd']['pps']['port'])) {
1664
		$ntpcfg .= "\n";
1665
		$ntpcfg .= "# PPS Setup\n";
1666
		$ntpcfg .= 'server 127.127.22.0';
1667
		$ntpcfg .= ' minpoll 4 maxpoll 4';
1668
		if (empty($config['ntpd']['pps']['prefer'])) { /*note: this one works backwards */
1669
			$ntpcfg .= ' prefer';
1670
		}
1671
		if (!empty($config['ntpd']['pps']['noselect'])) {
1672
			$ntpcfg .= ' noselect ';
1673
		}
1674
		$ntpcfg .= "\n";
1675
		$ntpcfg .= 'fudge 127.127.22.0';
1676
		if (!empty($config['ntpd']['pps']['fudge1'])) {
1677
			$ntpcfg .= ' time1 ';
1678
			$ntpcfg .= $config['ntpd']['pps']['fudge1'];
1679
		}
1680
		if (!empty($config['ntpd']['pps']['flag2'])) {
1681
			$ntpcfg .= ' flag2 1';
1682
		}
1683
		if (!empty($config['ntpd']['pps']['flag3'])) {
1684
			$ntpcfg .= ' flag3 1';
1685
		} else {
1686
			$ntpcfg .= ' flag3 0';
1687
		}
1688
		if (!empty($config['ntpd']['pps']['flag4'])) {
1689
			$ntpcfg .= ' flag4 1';
1690
		}
1691
		if (!empty($config['ntpd']['pps']['refid'])) {
1692
			$ntpcfg .= ' refid ';
1693
			$ntpcfg .= $config['ntpd']['pps']['refid'];
1694
		}
1695
		$ntpcfg .= "\n";
1696
	}
1697
	/* End PPS configuration */
1698

    
1699
	/* Add GPS configuration */
1700
	if (is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['port']) &&
1701
	    file_exists('/dev/'.$config['ntpd']['gps']['port']) &&
1702
	    system_ntp_setup_gps($config['ntpd']['gps']['port'])) {
1703
		$ntpcfg .= "\n";
1704
		$ntpcfg .= "# GPS Setup\n";
1705
		$ntpcfg .= 'server 127.127.20.0 mode ';
1706
		if (!empty($config['ntpd']['gps']['nmea']) || !empty($config['ntpd']['gps']['speed']) || !empty($config['ntpd']['gps']['subsec'])) {
1707
			if (!empty($config['ntpd']['gps']['nmea'])) {
1708
				$ntpmode = (int) $config['ntpd']['gps']['nmea'];
1709
			}
1710
			if (!empty($config['ntpd']['gps']['speed'])) {
1711
				$ntpmode += (int) $config['ntpd']['gps']['speed'];
1712
			}
1713
			if (!empty($config['ntpd']['gps']['subsec'])) {
1714
				$ntpmode += 128;
1715
			}
1716
			$ntpcfg .= (string) $ntpmode;
1717
		} else {
1718
			$ntpcfg .= '0';
1719
		}
1720
		$ntpcfg .= ' minpoll 4 maxpoll 4';
1721
		if (empty($config['ntpd']['gps']['prefer'])) { /*note: this one works backwards */
1722
			$ntpcfg .= ' prefer';
1723
		}
1724
		if (!empty($config['ntpd']['gps']['noselect'])) {
1725
			$ntpcfg .= ' noselect ';
1726
		}
1727
		$ntpcfg .= "\n";
1728
		$ntpcfg .= 'fudge 127.127.20.0';
1729
		if (!empty($config['ntpd']['gps']['fudge1'])) {
1730
			$ntpcfg .= ' time1 ';
1731
			$ntpcfg .= $config['ntpd']['gps']['fudge1'];
1732
		}
1733
		if (!empty($config['ntpd']['gps']['fudge2'])) {
1734
			$ntpcfg .= ' time2 ';
1735
			$ntpcfg .= $config['ntpd']['gps']['fudge2'];
1736
		}
1737
		if (!empty($config['ntpd']['gps']['flag1'])) {
1738
			$ntpcfg .= ' flag1 1';
1739
		} else {
1740
			$ntpcfg .= ' flag1 0';
1741
		}
1742
		if (!empty($config['ntpd']['gps']['flag2'])) {
1743
			$ntpcfg .= ' flag2 1';
1744
		}
1745
		if (!empty($config['ntpd']['gps']['flag3'])) {
1746
			$ntpcfg .= ' flag3 1';
1747
		} else {
1748
			$ntpcfg .= ' flag3 0';
1749
		}
1750
		if (!empty($config['ntpd']['gps']['flag4'])) {
1751
			$ntpcfg .= ' flag4 1';
1752
		}
1753
		if (!empty($config['ntpd']['gps']['refid'])) {
1754
			$ntpcfg .= ' refid ';
1755
			$ntpcfg .= $config['ntpd']['gps']['refid'];
1756
		}
1757
		$ntpcfg .= "\n";
1758
	} elseif (is_array($config['ntpd']) && !empty($config['ntpd']['gpsport']) &&
1759
	    file_exists('/dev/'.$config['ntpd']['gpsport']) &&
1760
	    system_ntp_setup_gps($config['ntpd']['gpsport'])) {
1761
		/* This handles a 2.1 and earlier config */
1762
		$ntpcfg .= "# GPS Setup\n";
1763
		$ntpcfg .= "server 127.127.20.0 mode 0 minpoll 4 maxpoll 4 prefer\n";
1764
		$ntpcfg .= "fudge 127.127.20.0 time1 0.155 time2 0.000 flag1 1 flag2 0 flag3 1\n";
1765
		// Fall back to local clock if GPS is out of sync?
1766
		$ntpcfg .= "server 127.127.1.0\n";
1767
		$ntpcfg .= "fudge 127.127.1.0 stratum 12\n";
1768
	}
1769
	/* End GPS configuration */
1770

    
1771
	$ntpcfg .= "\n\n# Upstream Servers\n";
1772
	/* foreach through ntp servers and write out to ntpd.conf */
1773
	foreach (explode(' ', $config['system']['timeservers']) as $ts) {
1774
		$ntpcfg .= "server {$ts} iburst maxpoll 9";
1775
		if (substr_count($config['ntpd']['prefer'], $ts)) {
1776
			$ntpcfg .= ' prefer';
1777
		}
1778
		if (substr_count($config['ntpd']['noselect'], $ts)) {
1779
			$ntpcfg .= ' noselect';
1780
		}
1781
		$ntpcfg .= "\n";
1782
	}
1783
	unset($ts);
1784

    
1785
	$ntpcfg .= "\n\n";
1786
	$ntpcfg .= "disable monitor\n"; //prevent NTP reflection attack, see https://forum.pfsense.org/index.php/topic,67189.msg389132.html#msg389132
1787
	if (!empty($config['ntpd']['clockstats']) || !empty($config['ntpd']['loopstats']) || !empty($config['ntpd']['peerstats'])) {
1788
		$ntpcfg .= "enable stats\n";
1789
		$ntpcfg .= 'statistics';
1790
		if (!empty($config['ntpd']['clockstats'])) {
1791
			$ntpcfg .= ' clockstats';
1792
		}
1793
		if (!empty($config['ntpd']['loopstats'])) {
1794
			$ntpcfg .= ' loopstats';
1795
		}
1796
		if (!empty($config['ntpd']['peerstats'])) {
1797
			$ntpcfg .= ' peerstats';
1798
		}
1799
		$ntpcfg .= "\n";
1800
	}
1801
	$ntpcfg .= "statsdir {$statsdir}\n";
1802
	$ntpcfg .= 'logconfig =syncall +clockall';
1803
	if (!empty($config['ntpd']['logpeer'])) {
1804
		$ntpcfg .= ' +peerall';
1805
	}
1806
	if (!empty($config['ntpd']['logsys'])) {
1807
		$ntpcfg .= ' +sysall';
1808
	}
1809
	$ntpcfg .= "\n";
1810
	$ntpcfg .= "driftfile {$driftfile}\n";
1811
	/* Access restrictions */
1812
	$ntpcfg .= 'restrict default';
1813
	if (empty($config['ntpd']['kod'])) { /*note: this one works backwards */
1814
		$ntpcfg .= ' kod limited';
1815
	}
1816
	if (empty($config['ntpd']['nomodify'])) { /*note: this one works backwards */
1817
		$ntpcfg .= ' nomodify';
1818
	}
1819
	if (!empty($config['ntpd']['noquery'])) {
1820
		$ntpcfg .= ' noquery';
1821
	}
1822
	if (empty($config['ntpd']['nopeer'])) { /*note: this one works backwards */
1823
		$ntpcfg .= ' nopeer';
1824
	}
1825
	if (empty($config['ntpd']['notrap'])) { /*note: this one works backwards */
1826
		$ntpcfg .= ' notrap';
1827
	}
1828
	if (!empty($config['ntpd']['noserve'])) {
1829
		$ntpcfg .= ' noserve';
1830
	}
1831
	$ntpcfg .= "\nrestrict -6 default";
1832
	if (empty($config['ntpd']['kod'])) { /*note: this one works backwards */
1833
		$ntpcfg .= ' kod limited';
1834
	}
1835
	if (empty($config['ntpd']['nomodify'])) { /*note: this one works backwards */
1836
		$ntpcfg .= ' nomodify';
1837
	}
1838
	if (!empty($config['ntpd']['noquery'])) {
1839
		$ntpcfg .= ' noquery';
1840
	}
1841
	if (empty($config['ntpd']['nopeer'])) { /*note: this one works backwards */
1842
		$ntpcfg .= ' nopeer';
1843
	}
1844
	if (!empty($config['ntpd']['noserve'])) {
1845
		$ntpcfg .= ' noserve';
1846
	}
1847
	if (empty($config['ntpd']['notrap'])) { /*note: this one works backwards */
1848
		$ntpcfg .= ' notrap';
1849
	}
1850
	$ntpcfg .= "\n";
1851

    
1852
	/* A leapseconds file is really only useful if this clock is stratum 1 */
1853
	$ntpcfg .= "\n";
1854
	if (!empty($config['ntpd']['leapsec'])) {
1855
		$leapsec .= base64_decode($config['ntpd']['leapsec']);
1856
		file_put_contents('/var/db/leap-seconds', $leapsec);
1857
		$ntpcfg .= "leapfile /var/db/leap-seconds\n";
1858
	}
1859

    
1860

    
1861
	if (empty($config['ntpd']['interface'])) {
1862
		if (is_array($config['installedpackages']['openntpd']) && !empty($config['installedpackages']['openntpd']['config'][0]['interface'])) {
1863
			$interfaces = explode(",", $config['installedpackages']['openntpd']['config'][0]['interface']);
1864
		} else {
1865
			$interfaces = array();
1866
		}
1867
	} else {
1868
		$interfaces = explode(",", $config['ntpd']['interface']);
1869
	}
1870

    
1871
	if (is_array($interfaces) && count($interfaces)) {
1872
		$ntpcfg .= "interface ignore all\n";
1873
		foreach ($interfaces as $interface) {
1874
			if (!is_ipaddr($interface)) {
1875
				$interface = get_real_interface($interface);
1876
			}
1877
			if (!empty($interface)) {
1878
				$ntpcfg .= "interface listen {$interface}\n";
1879
			}
1880
		}
1881
	}
1882

    
1883
	/* open configuration for writing or bail */
1884
	if (!@file_put_contents("{$g['varetc_path']}/ntpd.conf", $ntpcfg)) {
1885
		log_error("Could not open {$g['varetc_path']}/ntpd.conf for writing");
1886
		return;
1887
	}
1888

    
1889
	/* At bootup we just want to write out the config. */
1890
	if (!$start_ntpd) {
1891
		return;
1892
	}
1893

    
1894
	/* if ntpd is running, kill it */
1895
	while (isvalidpid("{$g['varrun_path']}/ntpd.pid")) {
1896
		killbypid("{$g['varrun_path']}/ntpd.pid");
1897
	}
1898
	@unlink("{$g['varrun_path']}/ntpd.pid");
1899

    
1900
	/* if /var/empty does not exist, create it */
1901
	if (!is_dir("/var/empty")) {
1902
		mkdir("/var/empty", 0775, true);
1903
	}
1904

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

    
1908
	// Note that we are starting up
1909
	log_error("NTPD is starting up.");
1910
	return;
1911
}
1912

    
1913
function sync_system_time() {
1914
	global $config, $g;
1915

    
1916
	if (platform_booting()) {
1917
		echo gettext("Syncing system time before startup...");
1918
	}
1919

    
1920
	/* foreach through servers and write out to ntpd.conf */
1921
	foreach (explode(' ', $config['system']['timeservers']) as $ts) {
1922
		mwexec("/usr/local/sbin/ntpdate -s $ts");
1923
	}
1924

    
1925
	if (platform_booting()) {
1926
		echo gettext("done.") . "\n";
1927
	}
1928

    
1929
}
1930

    
1931
function system_halt() {
1932
	global $g;
1933

    
1934
	system_reboot_cleanup();
1935

    
1936
	mwexec("/usr/bin/nohup /etc/rc.halt > /dev/null 2>&1 &");
1937
}
1938

    
1939
function system_reboot() {
1940
	global $g;
1941

    
1942
	system_reboot_cleanup();
1943

    
1944
	mwexec("nohup /etc/rc.reboot > /dev/null 2>&1 &");
1945
}
1946

    
1947
function system_reboot_sync() {
1948
	global $g;
1949

    
1950
	system_reboot_cleanup();
1951

    
1952
	mwexec("/etc/rc.reboot > /dev/null 2>&1");
1953
}
1954

    
1955
function system_reboot_cleanup() {
1956
	global $config, $cpzone;
1957

    
1958
	mwexec("/usr/local/bin/beep.sh stop");
1959
	require_once("captiveportal.inc");
1960
	if (is_array($config['captiveportal'])) {
1961
		foreach ($config['captiveportal'] as $cpzone=>$cp) {
1962
			captiveportal_radius_stop_all();
1963
			captiveportal_send_server_accounting(true);
1964
		}
1965
	}
1966
	require_once("voucher.inc");
1967
	voucher_save_db_to_config();
1968
	require_once("pkg-utils.inc");
1969
	stop_packages();
1970
}
1971

    
1972
function system_do_shell_commands($early = 0) {
1973
	global $config, $g;
1974
	if (isset($config['system']['developerspew'])) {
1975
		$mt = microtime();
1976
		echo "system_do_shell_commands() being called $mt\n";
1977
	}
1978

    
1979
	if ($early) {
1980
		$cmdn = "earlyshellcmd";
1981
	} else {
1982
		$cmdn = "shellcmd";
1983
	}
1984

    
1985
	if (is_array($config['system'][$cmdn])) {
1986

    
1987
		/* *cmd is an array, loop through */
1988
		foreach ($config['system'][$cmdn] as $cmd) {
1989
			exec($cmd);
1990
		}
1991

    
1992
	} elseif ($config['system'][$cmdn] <> "") {
1993

    
1994
		/* execute single item */
1995
		exec($config['system'][$cmdn]);
1996

    
1997
	}
1998
}
1999

    
2000
function system_console_configure() {
2001
	global $config, $g;
2002
	if (isset($config['system']['developerspew'])) {
2003
		$mt = microtime();
2004
		echo "system_console_configure() being called $mt\n";
2005
	}
2006

    
2007
	if (isset($config['system']['disableconsolemenu'])) {
2008
		touch("{$g['varetc_path']}/disableconsole");
2009
	} else {
2010
		unlink_if_exists("{$g['varetc_path']}/disableconsole");
2011
	}
2012
}
2013

    
2014
function system_dmesg_save() {
2015
	global $g;
2016
	if (isset($config['system']['developerspew'])) {
2017
		$mt = microtime();
2018
		echo "system_dmesg_save() being called $mt\n";
2019
	}
2020

    
2021
	$dmesg = "";
2022
	$_gb = exec("/sbin/dmesg", $dmesg);
2023

    
2024
	/* find last copyright line (output from previous boots may be present) */
2025
	$lastcpline = 0;
2026

    
2027
	for ($i = 0; $i < count($dmesg); $i++) {
2028
		if (strstr($dmesg[$i], "Copyright (c) 1992-")) {
2029
			$lastcpline = $i;
2030
		}
2031
	}
2032

    
2033
	$fd = fopen("{$g['varlog_path']}/dmesg.boot", "w");
2034
	if (!$fd) {
2035
		printf(gettext("Error: cannot open dmesg.boot in system_dmesg_save().%s"), "\n");
2036
		return 1;
2037
	}
2038

    
2039
	for ($i = $lastcpline; $i < count($dmesg); $i++) {
2040
		fwrite($fd, $dmesg[$i] . "\n");
2041
	}
2042

    
2043
	fclose($fd);
2044
	unset($dmesg);
2045

    
2046
	return 0;
2047
}
2048

    
2049
function system_set_harddisk_standby() {
2050
	global $g, $config;
2051
	if (isset($config['system']['developerspew'])) {
2052
		$mt = microtime();
2053
		echo "system_set_harddisk_standby() being called $mt\n";
2054
	}
2055

    
2056
	if (isset($config['system']['harddiskstandby'])) {
2057
		if (platform_booting()) {
2058
			echo gettext('Setting hard disk standby... ');
2059
		}
2060

    
2061
		$standby = $config['system']['harddiskstandby'];
2062
		// Check for a numeric value
2063
		if (is_numeric($standby)) {
2064
			// Sync the disk(s)
2065
			pfSense_sync();
2066
			if (set_single_sysctl('hw.ata.standby', (int)$standby)) {
2067
				// Reinitialize ATA-drives
2068
				mwexec('/usr/local/sbin/atareinit');
2069
				if (platform_booting()) {
2070
					echo gettext("done.") . "\n";
2071
				}
2072
			} else if (platform_booting()) {
2073
				echo gettext("failed!") . "\n";
2074
			}
2075
		} else if (platform_booting()) {
2076
			echo gettext("failed!") . "\n";
2077
		}
2078
	}
2079
}
2080

    
2081
function system_setup_sysctl() {
2082
	global $config;
2083
	if (isset($config['system']['developerspew'])) {
2084
		$mt = microtime();
2085
		echo "system_setup_sysctl() being called $mt\n";
2086
	}
2087

    
2088
	activate_sysctls();
2089

    
2090
	if (isset($config['system']['sharednet'])) {
2091
		system_disable_arp_wrong_if();
2092
	}
2093
}
2094

    
2095
function system_disable_arp_wrong_if() {
2096
	global $config;
2097
	if (isset($config['system']['developerspew'])) {
2098
		$mt = microtime();
2099
		echo "system_disable_arp_wrong_if() being called $mt\n";
2100
	}
2101
	set_sysctl(array(
2102
		"net.link.ether.inet.log_arp_wrong_iface" => "0",
2103
		"net.link.ether.inet.log_arp_movements" => "0"
2104
	));
2105
}
2106

    
2107
function system_enable_arp_wrong_if() {
2108
	global $config;
2109
	if (isset($config['system']['developerspew'])) {
2110
		$mt = microtime();
2111
		echo "system_enable_arp_wrong_if() being called $mt\n";
2112
	}
2113
	set_sysctl(array(
2114
		"net.link.ether.inet.log_arp_wrong_iface" => "1",
2115
		"net.link.ether.inet.log_arp_movements" => "1"
2116
	));
2117
}
2118

    
2119
function enable_watchdog() {
2120
	global $config;
2121
	return;
2122
	$install_watchdog = false;
2123
	$supported_watchdogs = array("Geode");
2124
	$file = file_get_contents("/var/log/dmesg.boot");
2125
	foreach ($supported_watchdogs as $sd) {
2126
		if (stristr($file, "Geode")) {
2127
			$install_watchdog = true;
2128
		}
2129
	}
2130
	if ($install_watchdog == true) {
2131
		if (is_process_running("watchdogd")) {
2132
			mwexec("/usr/bin/killall watchdogd", true);
2133
		}
2134
		exec("/usr/sbin/watchdogd");
2135
	}
2136
}
2137

    
2138
function system_check_reset_button() {
2139
	global $g;
2140

    
2141
	$specplatform = system_identify_specific_platform();
2142

    
2143
	switch ($specplatform['name']) {
2144
		case 'alix':
2145
		case 'wrap':
2146
		case 'FW7541':
2147
		case 'APU':
2148
		case 'RCC-VE':
2149
			break;
2150
		default:
2151
			return 0;
2152
	}
2153

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

    
2156
	if ($retval == 99) {
2157
		/* user has pressed reset button for 2 seconds -
2158
		   reset to factory defaults */
2159
		echo <<<EOD
2160

    
2161
***********************************************************************
2162
* Reset button pressed - resetting configuration to factory defaults. *
2163
* The system will reboot after this completes.                        *
2164
***********************************************************************
2165

    
2166

    
2167
EOD;
2168

    
2169
		reset_factory_defaults();
2170
		system_reboot_sync();
2171
		exit(0);
2172
	}
2173

    
2174
	return 0;
2175
}
2176

    
2177
/* attempt to identify the specific platform (for embedded systems)
2178
   Returns an array with two elements:
2179
	name => platform string (e.g. 'wrap', 'alix' etc.)
2180
	descr => human-readable description (e.g. "PC Engines WRAP")
2181
*/
2182
function system_identify_specific_platform() {
2183
	global $g;
2184

    
2185
	if ($g['platform'] == 'generic-pc') {
2186
		return array('name' => 'generic-pc', 'descr' => gettext("Generic PC"));
2187
	}
2188

    
2189
	if ($g['platform'] == 'generic-pc-cdrom') {
2190
		return array('name' => 'generic-pc-cdrom', 'descr' => gettext("Generic PC (CD-ROM)"));
2191
	}
2192

    
2193
	/* Try to guess from smbios strings */
2194
	unset($output);
2195
	$_gb = exec('/bin/kenv smbios.system.product 2>/dev/null', $output);
2196
	switch ($output[0]) {
2197
		case 'FW7541':
2198
			return (array('name' => 'FW7541', 'descr' => 'Netgate FW7541'));
2199
			break;
2200
		case 'APU':
2201
			return (array('name' => 'APU', 'descr' => 'Netgate APU'));
2202
			break;
2203
		case 'RCC-VE':
2204
			return (array('name' => 'RCC-VE', 'descr' => 'Netgate RCC-VE'));
2205
			break;
2206
	}
2207

    
2208
	/* the rest of the code only deals with 'embedded' platforms */
2209
	if ($g['platform'] != 'nanobsd') {
2210
		return array('name' => $g['platform'], 'descr' => $g['platform']);
2211
	}
2212

    
2213
	$dmesg = get_single_sysctl('hw.model');
2214

    
2215
	if (strpos($dmesg, "PC Engines WRAP") !== false) {
2216
		return array('name' => 'wrap', 'descr' => gettext('PC Engines WRAP'));
2217
	}
2218

    
2219
	if (strpos($dmesg, "PC Engines ALIX") !== false) {
2220
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
2221
	}
2222

    
2223
	if (preg_match("/Soekris net45../", $dmesg, $matches)) {
2224
		return array('name' => 'net45xx', 'descr' => $matches[0]);
2225
	}
2226

    
2227
	if (preg_match("/Soekris net48../", $dmesg, $matches)) {
2228
		return array('name' => 'net48xx', 'descr' => $matches[0]);
2229
	}
2230

    
2231
	if (preg_match("/Soekris net55../", $dmesg, $matches)) {
2232
		return array('name' => 'net55xx', 'descr' => $matches[0]);
2233
	}
2234

    
2235
	unset($dmesg);
2236

    
2237
	$dmesg_boot = system_get_dmesg_boot();
2238
	if (strpos($dmesg_boot, "PC Engines ALIX") !== false) {
2239
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
2240
	}
2241
	unset($dmesg_boot);
2242

    
2243
	/* unknown embedded platform */
2244
	return array('name' => 'embedded', 'descr' => gettext('embedded (unknown)'));
2245
}
2246

    
2247
function system_get_dmesg_boot() {
2248
	global $g;
2249

    
2250
	return file_get_contents("{$g['varlog_path']}/dmesg.boot");
2251
}
2252

    
2253
?>
(52-52/67)