Project

General

Profile

Download (67.1 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
	if(is_process_running("powerd"))
47
		exec("/usr/bin/killall powerd");
48
	if(isset($config['system']['powerd_enable'])) {
49
		if ($g["platform"] == "nanobsd")
50
			exec("/sbin/kldload cpufreq");
51

    
52
		$ac_mode = "hadp";
53
		if (!empty($config['system']['powerd_ac_mode']))
54
			$ac_mode = $config['system']['powerd_ac_mode'];
55

    
56
		$battery_mode = "hadp";
57
		if (!empty($config['system']['powerd_battery_mode']))
58
			$battery_mode = $config['system']['powerd_battery_mode'];
59

    
60
		$normal_mode = "hadp";
61
		if (!empty($config['system']['powerd_normal_mode']))
62
			$normal_mode = $config['system']['powerd_normal_mode'];
63

    
64
		mwexec("/usr/sbin/powerd -b $battery_mode -a $ac_mode -n $normal_mode");
65
	}
66
}
67

    
68
function get_default_sysctl_value($id) {
69
	global $sysctls;
70

    
71
	if (isset($sysctls[$id]))
72
		return $sysctls[$id];
73
}
74

    
75
function get_sysctl_descr($sysctl) {
76
	unset($output);
77
	$_gb = exec("/sbin/sysctl -nd {$sysctl}", $output);
78

    
79
	return $output[0];
80
}
81

    
82
function system_get_sysctls() {
83
	global $config, $sysctls;
84

    
85
	$disp_sysctl = array();
86
	$disp_cache = array();
87
	if (is_array($config['sysctl']) && is_array($config['sysctl']['item'])) {
88
		foreach($config['sysctl']['item'] as $id => $tunable) {
89
			if ($tunable['value'] == "default")
90
				$value = get_default_sysctl_value($tunable['tunable']);
91
			else
92
				$value = $tunable['value'];
93

    
94
			$disp_sysctl[$id] = $tunable;
95
			$disp_sysctl[$id]['modified'] = true;
96
			$disp_cache[$tunable['tunable']] = 'set';
97
		}
98
	}
99

    
100
	foreach ($sysctls as $sysctl => $value) {
101
		if (isset($disp_cache[$sysctl]))
102
			continue;
103

    
104
		$disp_sysctl[$sysctl] = array('tunable' => $sysctl, 'value' => $value, 'descr' => get_sysctl_descr($sysctl));
105
	}
106
	unset($disp_cache);
107
	return $disp_sysctl;
108
}
109

    
110
function activate_sysctls() {
111
	global $config, $g, $sysctls;
112

    
113
	if ($g['platform'] == 'jail')
114
		return;
115

    
116
	if (is_array($config['sysctl']) && is_array($config['sysctl']['item'])) {
117
		foreach($config['sysctl']['item'] as $tunable) {
118
			if($tunable['value'] == "default")
119
				$value = get_default_sysctl_value($tunable['tunable']);
120
			else
121
				$value = $tunable['value'];
122

    
123
			$sysctls[$tunable['tunable']] = $value;
124
		}
125
	}
126

    
127
	set_sysctl($sysctls);
128
}
129

    
130
function system_resolvconf_generate($dynupdate = false) {
131
	global $config, $g;
132

    
133
	if(isset($config['system']['developerspew'])) {
134
		$mt = microtime();
135
		echo "system_resolvconf_generate() being called $mt\n";
136
	}
137

    
138
	$syscfg = $config['system'];
139

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

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

    
171
	// Add EDNS support
172
	if (isset($config['unbound']['enable']) && isset($config['unbound']['edns']))
173
		$resolvconf .= "options edns0\n";
174

    
175
	$dnslock = lock('resolvconf', LOCK_EX);
176

    
177
	$fd = fopen("{$g['varetc_path']}/resolv.conf", "w");
178
	if (!$fd) {
179
		printf("Error: cannot open resolv.conf in system_resolvconf_generate().\n");
180
		unlock($dnslock);
181
		return 1;
182
	}
183

    
184
	fwrite($fd, $resolvconf);
185
	fclose($fd);
186

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

    
196
	if (!platform_booting()) {
197
		/* restart dhcpd (nameservers may have changed) */
198
		if (!$dynupdate)
199
			services_dhcpd_configure();
200
	}
201

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

    
232
	unlock($dnslock);
233

    
234
	return 0;
235
}
236

    
237
function get_searchdomains() {
238
	global $config, $g;
239

    
240
	$master_list = array();
241
	
242
	// Read in dhclient nameservers
243
	$search_list = glob("/var/etc/searchdomain_*");
244
	if (is_array($search_list)) {
245
		foreach($search_list as $fdns) {
246
			$contents = file($fdns, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
247
			if (!is_array($contents))
248
				continue;
249
			foreach ($contents as $dns) {
250
				if(is_hostname($dns)) 
251
					$master_list[] = $dns;
252
			}
253
		}
254
	}
255

    
256
	return $master_list;
257
}
258

    
259
function get_nameservers() {
260
	global $config, $g;
261
	$master_list = array();
262
	
263
	// Read in dhclient nameservers
264
	$dns_lists = glob("/var/etc/nameserver_*");
265
	if (is_array($dns_lists)) {
266
		foreach($dns_lists as $fdns) {
267
			$contents = file($fdns, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
268
			if (!is_array($contents))
269
				continue;
270
			foreach ($contents as $dns) {
271
				if(is_ipaddr($dns)) 
272
					$master_list[] = $dns;
273
			}
274
		}
275
	}
276

    
277
	// Read in any extra nameservers
278
	if(file_exists("/var/etc/nameservers.conf")) {
279
		$dns_s = file("/var/etc/nameservers.conf", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
280
		if(is_array($dns_s)) {
281
			foreach($dns_s as $dns)
282
				if (is_ipaddr($dns))
283
					$master_list[] = $dns;
284
		}
285
	}
286

    
287
	return $master_list;
288
}
289

    
290
function system_hosts_generate() {
291
	global $config, $g;
292
	if (isset($config['system']['developerspew'])) {
293
		$mt = microtime();
294
		echo "system_hosts_generate() being called $mt\n";
295
	}
296

    
297
	$syscfg = $config['system'];
298
	if (isset($config['unbound']) && isset($config['unbound']['enable']))
299
		$dnsmasqcfg = $config['unbound'];
300
	else
301
		$dnsmasqcfg = $config['dnsmasq'];
302

    
303
	$hosts =  "127.0.0.1	localhost localhost.{$syscfg['domain']}\n";
304
	$hosts .= "::1		localhost localhost.{$syscfg['domain']}\n";
305
	$lhosts = "";
306
	$dhosts = "";
307

    
308
	if ($config['interfaces']['lan']) {
309
		$cfgip = get_interface_ip("lan");
310
		if (is_ipaddr($cfgip))
311
			$hosts .= "{$cfgip}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
312
		$cfgipv6 = get_interface_ipv6("lan");
313
		if (is_ipaddrv6($cfgipv6))
314
			$hosts .= "{$cfgipv6}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
315
	} else {
316
		$sysiflist = get_configured_interface_list();
317
		$hosts_if_found = false;
318
		foreach ($sysiflist as $sysif) {
319
			if (!interface_has_gateway($sysif)) {
320
				$cfgip = get_interface_ip($sysif);
321
				if (is_ipaddr($cfgip)) {
322
					$hosts .= "{$cfgip}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
323
					$hosts_if_found = true;
324
				}
325
				$cfgipv6 = get_interface_ipv6($sysif);
326
				if (is_ipaddrv6($cfgipv6)) {
327
					$hosts .= "{$cfgipv6}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
328
					$hosts_if_found = true;
329
				}
330
				if ($hosts_if_found == true)
331
					break;
332
			}
333
		}
334
	}
335

    
336
	if (isset($dnsmasqcfg['enable'])) {
337
		if (!is_array($dnsmasqcfg['hosts']))
338
			$dnsmasqcfg['hosts'] = array();
339

    
340
		foreach ($dnsmasqcfg['hosts'] as $host) {
341
			if ($host['host'] || $host['host'] == "0")
342
				$lhosts .= "{$host['ip']}	{$host['host']}.{$host['domain']} {$host['host']}\n";
343
			else
344
				$lhosts .= "{$host['ip']}	{$host['domain']}\n";
345
			if (!is_array($host['aliases']) || !is_array($host['aliases']['item']))
346
				continue;
347
			foreach ($host['aliases']['item'] as $alias) {
348
				if ($alias['host'] || $alias['host'] == "0")
349
					$lhosts .= "{$host['ip']}	{$alias['host']}.{$alias['domain']} {$alias['host']}\n";
350
				else
351
					$lhosts .= "{$host['ip']}	{$alias['domain']}\n";
352
			}
353
		}
354
		if (isset($dnsmasqcfg['regdhcpstatic']) && is_array($config['dhcpd'])) {
355
			foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf)
356
				if(is_array($dhcpifconf['staticmap']) && isset($dhcpifconf['enable']))
357
						foreach ($dhcpifconf['staticmap'] as $host)
358
							if ($host['ipaddr'] && $host['hostname'] && $host['domain'])
359
								$dhosts .= "{$host['ipaddr']}	{$host['hostname']}.{$host['domain']} {$host['hostname']}\n";
360
							else if ($host['ipaddr'] && $host['hostname'] && $dhcpifconf['domain'])
361
								$dhosts .= "{$host['ipaddr']}	{$host['hostname']}.{$dhcpifconf['domain']} {$host['hostname']}\n";
362
							else if ($host['ipaddr'] && $host['hostname'])
363
								$dhosts .= "{$host['ipaddr']}	{$host['hostname']}.{$syscfg['domain']} {$host['hostname']}\n";
364
		}
365
		if (isset($dnsmasqcfg['regdhcpstatic']) && is_array($config['dhcpdv6'])) {
366
			foreach ($config['dhcpdv6'] as $dhcpif => $dhcpifconf)
367
				if(is_array($dhcpifconf['staticmap']) && isset($dhcpifconf['enable']))
368
						foreach ($dhcpifconf['staticmap'] as $host)
369
							if ($host['ipaddrv6'] && $host['hostname'] && $host['domain'])
370
								$dhosts .= "{$host['ipaddrv6']}	{$host['hostname']}.{$host['domain']} {$host['hostname']}\n";
371
							else if ($host['ipaddrv6'] && $host['hostname'] && $dhcpifconf['domain'])
372
								$dhosts .= "{$host['ipaddrv6']}	{$host['hostname']}.{$dhcpifconf['domain']} {$host['hostname']}\n";
373
							else if ($host['ipaddrv6'] && $host['hostname'])
374
								$dhosts .= "{$host['ipaddrv6']}	{$host['hostname']}.{$syscfg['domain']} {$host['hostname']}\n";
375
		}
376

    
377
		if (isset($dnsmasqcfg['dhcpfirst']))
378
			$hosts .= $dhosts . $lhosts;
379
		else
380
			$hosts .= $lhosts . $dhosts;
381
	}
382

    
383
	/*
384
	 * Do not remove this because dhcpleases monitors with kqueue it needs to be 
385
	 * killed before writing to hosts files.
386
	 */
387
	if (file_exists("{$g['varrun_path']}/dhcpleases.pid")) {
388
		sigkillbypid("{$g['varrun_path']}/dhcpleases.pid", "TERM");
389
		@unlink("{$g['varrun_path']}/dhcpleases.pid");
390
	}
391
	$fd = fopen("{$g['varetc_path']}/hosts", "w");
392
	if (!$fd) {
393
		log_error("Error: cannot open hosts file in system_hosts_generate().\n");
394
		return 1;
395
	}
396
	fwrite($fd, $hosts);
397
	fclose($fd);
398

    
399
	if (isset($config['unbound']['enable'])) {
400
		require_once("unbound.inc");
401
		unbound_hosts_generate();
402
	}
403

    
404
	return 0;
405
}
406

    
407
function system_dhcpleases_configure() {
408
	global $config, $g;
409
	
410
	if ($g['platform'] == 'jail')
411
		return;
412
	/* Start the monitoring process for dynamic dhcpclients. */
413
	if ((isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcp'])) 
414
		|| (isset($config['unbound']['enable']) && isset($config['unbound']['regdhcp']))) {
415
		/* Make sure we do not error out */
416
		mwexec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/db");
417
		if (!file_exists("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases"))
418
			@touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
419

    
420
		if (isset($config['unbound']['enable'])) {
421
			$dns_pid = "unbound.pid";
422
			$unbound_conf = "-u {$g['unbound_chroot_path']}/dhcpleases_entries.conf";
423
		} else {
424
			$dns_pid = "dnsmasq.pid";
425
			$unbound_conf = "";
426
		}
427

    
428
		$pidfile = "{$g['varrun_path']}/dhcpleases.pid";
429
		if (isvalidpid($pidfile)) {
430
			/* Make sure dhcpleases is using correct unbound or dnsmasq */
431
			$_gb = exec("/bin/pgrep -F {$pidfile} -f {$dns_pid}", $output, $retval);
432
			if (intval($retval) == 0) {
433
				sigkillbypid($pidfile, "HUP");
434
				return;
435
			} else
436
				sigkillbypid($pidfile, "TERM");
437
		}
438

    
439
		/* To ensure we do not start multiple instances of dhcpleases, perform some clean-up first. */
440
		if (is_process_running("dhcpleases"))
441
			sigkillbyname('dhcpleases', "TERM");
442
		@unlink($pidfile);
443
		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");
444
	} else {
445
		sigkillbypid($pidfile, "TERM");
446
		@unlink($pidfile);
447
	}
448
}
449

    
450
function system_hostname_configure() {
451
	global $config, $g;
452
	if(isset($config['system']['developerspew'])) {
453
		$mt = microtime();
454
		echo "system_hostname_configure() being called $mt\n";
455
	}
456

    
457
	$syscfg = $config['system'];
458

    
459
	/* set hostname */
460
	$status = mwexec("/bin/hostname " .
461
		escapeshellarg("{$syscfg['hostname']}.{$syscfg['domain']}"));
462

    
463
    /* Setup host GUID ID.  This is used by ZFS. */
464
	mwexec("/etc/rc.d/hostid start");
465

    
466
	return $status;
467
}
468

    
469
function system_routing_configure($interface = "") {
470
	global $config, $g;
471
	if ($g['platform'] == 'jail')
472
		return;
473
	if(isset($config['system']['developerspew'])) {
474
		$mt = microtime();
475
		echo "system_routing_configure() being called $mt\n";
476
	}
477

    
478
	$gatewayip = "";
479
	$interfacegw = "";
480
	$gatewayipv6 = "";
481
	$interfacegwv6 = "";
482
	$foundgw = false;
483
	$foundgwv6 = false;
484
	/* tack on all the hard defined gateways as well */
485
	if (is_array($config['gateways']['gateway_item'])) {
486
		array_map('unlink', glob("{$g['tmp_path']}/*_defaultgw{,v6}", GLOB_BRACE));
487
		foreach	($config['gateways']['gateway_item'] as $gateway) {
488
			if (isset($gateway['defaultgw'])) {
489
				if ($foundgw == false && ($gateway['ipprotocol'] != "inet6" && (is_ipaddrv4($gateway['gateway']) || $gateway['gateway'] == "dynamic"))) {
490
					if(strpos($gateway['gateway'], ":"))
491
						continue;
492
					if ($gateway['gateway'] == "dynamic")
493
						$gateway['gateway'] = get_interface_gateway($gateway['interface']);
494
					$gatewayip = $gateway['gateway'];
495
					$interfacegw = $gateway['interface'];
496
					if (!empty($gateway['interface'])) {
497
						$defaultif = get_real_interface($gateway['interface']);
498
						if ($defaultif)
499
							@file_put_contents("{$g['tmp_path']}/{$defaultif}_defaultgw", $gateway['gateway']);
500
					}
501
					$foundgw = true;
502
				} else if ($foundgwv6 == false && ($gateway['ipprotocol'] == "inet6" && (is_ipaddrv6($gateway['gateway']) || $gateway['gateway'] == "dynamic"))) {
503
					if ($gateway['gateway'] == "dynamic")
504
						$gateway['gateway'] = get_interface_gateway_v6($gateway['interface']);
505
					$gatewayipv6 = $gateway['gateway'];
506
					$interfacegwv6 = $gateway['interface'];
507
					if (!empty($gateway['interface'])) {
508
						$defaultifv6 = get_real_interface($gateway['interface']);
509
						if ($defaultifv6)
510
							@file_put_contents("{$g['tmp_path']}/{$defaultifv6}_defaultgwv6", $gateway['gateway']);
511
					}
512
					$foundgwv6 = true;
513
				}
514
			}
515
			if ($foundgw === true && $foundgwv6 === true)
516
				break;
517
		}
518
	}
519
	if ($foundgw == false) {
520
		$defaultif = get_real_interface("wan");
521
		$interfacegw = "wan";
522
		$gatewayip = get_interface_gateway("wan");
523
		@file_put_contents("{$g['tmp_path']}/{$defaultif}_defaultgw", $gatewayip);
524
	}	
525
	if ($foundgwv6 == false) {
526
		$defaultifv6 = get_real_interface("wan");
527
		$interfacegwv6 = "wan";
528
		$gatewayipv6 = get_interface_gateway_v6("wan");
529
		@file_put_contents("{$g['tmp_path']}/{$defaultifv6}_defaultgwv6", $gatewayipv6);
530
	}
531
	$dont_add_route = false;
532
	/* if OLSRD is enabled, allow WAN to house DHCP. */
533
	if (is_array($config['installedpackages']['olsrd'])) {
534
		foreach($config['installedpackages']['olsrd']['config'] as $olsrd) {
535
			if(($olsrd['enabledyngw'] == "on") && ($olsrd['enable'] == "on")) {
536
				$dont_add_route = true;
537
				log_error(sprintf(gettext("Not adding default route because OLSR dynamic gateway is enabled.")));
538
				break;
539
			}
540
		}
541
	}
542

    
543
	if ($dont_add_route == false ) {
544
		if (!empty($interface) && $interface != $interfacegw)
545
			;
546
		else if (is_ipaddrv4($gatewayip)) {
547
			log_error("ROUTING: setting default route to $gatewayip");
548
			mwexec("/sbin/route change -inet default " . escapeshellarg($gatewayip));
549
		}
550

    
551
		if (!empty($interface) && $interface != $interfacegwv6)
552
			;
553
		else if (is_ipaddrv6($gatewayipv6)) {
554
			$ifscope = "";
555
			if (is_linklocal($gatewayipv6) && !strpos($gatewayipv6, '%'))
556
				$ifscope = "%{$defaultifv6}";
557
			log_error("ROUTING: setting IPv6 default route to {$gatewayipv6}{$ifscope}");
558
			mwexec("/sbin/route change -inet6 default " . escapeshellarg("{$gatewayipv6}{$ifscope}"));
559
		}
560
	}
561

    
562
	system_staticroutes_configure($interface, false);
563

    
564
	return 0;
565
}
566

    
567
function system_staticroutes_configure($interface = "", $update_dns = false) {
568
	global $config, $g, $aliastable;
569

    
570
	$filterdns_list = array();
571

    
572
	$static_routes = get_staticroutes(false, true);
573
	if (count($static_routes)) {
574
		$gateways_arr = return_gateways_array(false, true);
575

    
576
		foreach ($static_routes as $rtent) {
577
			if (empty($gateways_arr[$rtent['gateway']])) {
578
				log_error(sprintf(gettext("Static Routes: Gateway IP could not be found for %s"), $rtent['network']));
579
				continue;
580
			}
581
			$gateway = $gateways_arr[$rtent['gateway']];
582
			if (!empty($interface) && $interface != $gateway['friendlyiface'])
583
				continue;
584

    
585
			$gatewayip = $gateway['gateway'];
586
			$interfacegw = $gateway['interface'];
587

    
588
			$blackhole = "";
589
			if (!strcasecmp("Null", substr($rtent['gateway'], 0, 3)))
590
				$blackhole = "-blackhole";
591

    
592
			if (!is_fqdn($rtent['network']) && !is_subnet($rtent['network']))
593
				continue;
594

    
595
			$dnscache = array();
596
			if ($update_dns === true) {
597
				if (is_subnet($rtent['network']))
598
					continue;
599
				$dnscache = explode("\n", trim(compare_hostname_to_dnscache($rtent['network'])));
600
				if (empty($dnscache))
601
					continue;
602
			}
603

    
604
			if (is_subnet($rtent['network']))
605
				$ips = array($rtent['network']);
606
			else {
607
				if (!isset($rtent['disabled']))
608
					$filterdns_list[] = $rtent['network'];
609
				$ips = add_hostname_to_watch($rtent['network']);
610
			}
611

    
612
			foreach ($dnscache as $ip) {
613
				if (in_array($ip, $ips))
614
					continue;
615
				mwexec("/sbin/route delete " . escapeshellarg($ip), true);
616
				if (isset($config['system']['route-debug'])) {
617
					$mt = microtime();
618
					log_error("ROUTING debug: $mt - route delete $ip ");
619
				}
620
			}
621

    
622
			if (isset($rtent['disabled'])) {
623
				/* XXX: This can break things by deleting routes that shouldn't be deleted - OpenVPN, dynamic routing scenarios, etc. redmine #3709 */
624
				foreach ($ips as $ip) {
625
					mwexec("/sbin/route delete " . escapeshellarg($ip), true);
626
					if (isset($config['system']['route-debug'])) {
627
						$mt = microtime();
628
						log_error("ROUTING debug: $mt - route delete $ip ");
629
					}
630
				}
631
				continue;
632
			}
633

    
634
			foreach ($ips as $ip) {
635
				if (is_ipaddrv4($ip))
636
					$ip .= "/32";
637
				// do NOT do the same check here on v6, is_ipaddrv6 returns true when including the CIDR mask. doing so breaks v6 routes
638
					
639
				$inet = (is_subnetv6($ip) ? "-inet6" : "-inet");
640

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

    
643
				if (is_subnet($ip))
644
					if (is_ipaddr($gatewayip)) {
645
						mwexec($cmd . escapeshellarg($gatewayip));
646
						if (isset($config['system']['route-debug'])) {
647
							$mt = microtime();
648
							log_error("ROUTING debug: $mt - $cmd $gatewayip");
649
						}
650
					} else if (!empty($interfacegw)) {
651
						mwexec($cmd . "-iface " . escapeshellarg($interfacegw));
652
						if (isset($config['system']['route-debug'])) {
653
							$mt = microtime();
654
							log_error("ROUTING debug: $mt - $cmd -iface $interfacegw ");
655
						}
656
					}
657
			}
658
		}
659
		unset($gateways_arr);
660
	}
661
	unset($static_routes);
662

    
663
	if ($update_dns === false) {
664
		if (count($filterdns_list)) {
665
			$interval = 60;
666
			$hostnames = "";
667
			array_unique($filterdns_list);
668
			foreach ($filterdns_list as $hostname)
669
				$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload routedns\"'\n";
670
			file_put_contents("{$g['varetc_path']}/filterdns-route.hosts", $hostnames);
671
			unset($hostnames);
672

    
673
			if (isvalidpid("{$g['varrun_path']}/filterdns-route.pid"))
674
				sigkillbypid("{$g['varrun_path']}/filterdns-route.pid", "HUP");
675
			else
676
				mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-route.pid -i {$interval} -c {$g['varetc_path']}/filterdns-route.hosts -d 1");
677
		} else {
678
			killbypid("{$g['varrun_path']}/filterdns-route.pid");
679
			@unlink("{$g['varrun_path']}/filterdns-route.pid");
680
		}
681
	}
682
	unset($filterdns_list);
683

    
684
	return 0;
685
}
686

    
687
function system_routing_enable() {
688
	global $config, $g;
689
	if(isset($config['system']['developerspew'])) {
690
		$mt = microtime();
691
		echo "system_routing_enable() being called $mt\n";
692
	}
693

    
694
	set_sysctl(array(
695
		"net.inet.ip.forwarding" => "1",
696
		"net.inet6.ip6.forwarding" => "1"
697
	));
698

    
699
	return;
700
}
701

    
702
function system_syslogd_fixup_server($server) {
703
	/* If it's an IPv6 IP alone, encase it in brackets */
704
	if (is_ipaddrv6($server))
705
		return "[$server]";
706
	else
707
		return $server;
708
}
709

    
710
function system_syslogd_get_remote_servers($syslogcfg, $facility = "*.*") {
711
	// Rather than repeatedly use the same code, use this function to build a list of remote servers.
712
	$facility .= " ".
713
	$remote_servers = "";
714
	$pad_to  = 56;
715
	$padding = ceil(($pad_to - strlen($facility))/8)+1;
716
	if($syslogcfg['remoteserver'])
717
		$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver']) . "\n";
718
	if($syslogcfg['remoteserver2'])
719
		$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver2']) . "\n";
720
	if($syslogcfg['remoteserver3'])
721
		$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver3']) . "\n";
722
	return $remote_servers;
723
}
724

    
725
function system_syslogd_start() {
726
	global $config, $g;
727
	if(isset($config['system']['developerspew'])) {
728
		$mt = microtime();
729
		echo "system_syslogd_start() being called $mt\n";
730
	}
731

    
732
	mwexec("/etc/rc.d/hostid start");
733

    
734
	$syslogcfg = $config['syslog'];
735

    
736
	if (platform_booting())
737
		echo gettext("Starting syslog...");
738

    
739
	if (is_process_running("fifolog_writer"))
740
		mwexec('/bin/pkill fifolog_writer');
741

    
742
	// Which logging type are we using this week??
743
	if (isset($config['system']['disablesyslogclog'])) {
744
		$log_directive = "";
745
		$log_create_directive = "/usr/bin/touch ";
746
		$log_size = "";
747
	} else if (isset($config['system']['usefifolog'])) {
748
		$log_directive = "|/usr/sbin/fifolog_writer ";
749
		$log_size = isset($config['syslog']['logfilesize']) ? $config['syslog']['logfilesize'] : "10240";
750
		$log_create_directive = "/usr/sbin/fifolog_create -s ";
751
	} else { // Defaults to CLOG
752
		$log_directive = "%";
753
		$log_size = isset($config['syslog']['logfilesize']) ? $config['syslog']['logfilesize'] : "10240";
754
		$log_create_directive = "/usr/local/sbin/clog -i -s ";
755
	}
756

    
757
	$syslogd_extra = "";
758
	if (isset($syslogcfg)) {
759
		$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');
760
		$syslogconf = "";
761
		if($config['installedpackages']['package']) {
762
			foreach($config['installedpackages']['package'] as $package) {
763
				if($package['logging']) {
764
					array_push($separatelogfacilities, $package['logging']['facilityname']);
765
					if (!is_file($g['varlog_path'].'/'.$package['logging']['logfilename']))
766
						mwexec("{$log_create_directive} {$log_size} {$g['varlog_path']}/{$package['logging']['logfilename']}");
767
					$syslogconf .= "!{$package['logging']['facilityname']}\n*.*\t\t\t\t\t\t {$log_directive}{$g['varlog_path']}/{$package['logging']['logfilename']}\n";
768
				}
769
			}
770
		}
771
		$facilitylist = implode(',', array_unique($separatelogfacilities));
772
		$syslogconf .= "!radvd,routed,olsrd,zebra,ospfd,bgpd,miniupnpd\n";
773
		if (!isset($syslogcfg['disablelocallogging']))
774
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/routing.log\n";
775

    
776
		$syslogconf .= "!ntp,ntpd,ntpdate\n";
777
		if (!isset($syslogcfg['disablelocallogging'])) 
778
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ntpd.log\n";
779

    
780
		$syslogconf .= "!ppp\n";
781
		if (!isset($syslogcfg['disablelocallogging'])) 
782
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ppp.log\n";
783

    
784
		$syslogconf .= "!pptps\n";
785
		if (!isset($syslogcfg['disablelocallogging'])) 
786
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/pptps.log\n";
787

    
788
		$syslogconf .= "!poes\n";
789
		if (!isset($syslogcfg['disablelocallogging'])) 
790
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/poes.log\n";
791

    
792
		$syslogconf .= "!l2tps\n";
793
		if (!isset($syslogcfg['disablelocallogging'])) 
794
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/l2tps.log\n";
795

    
796
		$syslogconf .= "!charon,ipsec_starter\n";
797
		if (!isset($syslogcfg['disablelocallogging'])) 
798
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ipsec.log\n";
799
		if (isset($syslogcfg['vpn']))
800
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
801

    
802
		$syslogconf .= "!openvpn\n";
803
		if (!isset($syslogcfg['disablelocallogging'])) 
804
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/openvpn.log\n";
805
		if (isset($syslogcfg['vpn']))
806
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
807

    
808
		$syslogconf .= "!apinger\n";
809
		if (!isset($syslogcfg['disablelocallogging']))
810
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/gateways.log\n";
811
		if (isset($syslogcfg['apinger']))
812
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
813

    
814
		$syslogconf .= "!dnsmasq,filterdns,unbound\n";
815
		if (!isset($syslogcfg['disablelocallogging']))
816
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/resolver.log\n";
817

    
818
		$syslogconf .= "!dhcpd,dhcrelay,dhclient,dhcp6c\n";
819
		if (!isset($syslogcfg['disablelocallogging']))
820
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/dhcpd.log\n";
821
		if (isset($syslogcfg['dhcp']))
822
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
823

    
824
		$syslogconf .= "!relayd\n";
825
		if (!isset($syslogcfg['disablelocallogging']))
826
			$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/relayd.log\n";
827
		if (isset($syslogcfg['relayd']))
828
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
829

    
830
		$syslogconf .= "!hostapd\n";
831
		if (!isset($syslogcfg['disablelocallogging']))
832
			$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/wireless.log\n";
833
		if (isset($syslogcfg['hostapd']))
834
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
835

    
836
		$syslogconf .= "!filterlog\n";
837
		$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/filter.log\n";
838
		if (isset($syslogcfg['filter']))
839
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
840

    
841
		$syslogconf .= "!-{$facilitylist}\n";
842
		if (!isset($syslogcfg['disablelocallogging'])) 
843
			$syslogconf .= <<<EOD
844
local3.*							{$log_directive}{$g['varlog_path']}/vpn.log
845
local4.*							{$log_directive}{$g['varlog_path']}/portalauth.log
846
local7.*							{$log_directive}{$g['varlog_path']}/dhcpd.log
847
*.notice;kern.debug;lpr.info;mail.crit;daemon.none;		{$log_directive}{$g['varlog_path']}/system.log
848
news.err;local0.none;local3.none;local4.none;			{$log_directive}{$g['varlog_path']}/system.log
849
local7.none							{$log_directive}{$g['varlog_path']}/system.log
850
security.*							{$log_directive}{$g['varlog_path']}/system.log
851
auth.info;authpriv.info;daemon.info				{$log_directive}{$g['varlog_path']}/system.log
852
auth.info;authpriv.info 					|exec /usr/local/sbin/sshlockout_pf 15
853
*.emerg								*
854

    
855
EOD;
856
		if (isset($syslogcfg['vpn']))
857
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local3.*");
858
		if (isset($syslogcfg['portalauth']))
859
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local4.*");
860
		if (isset($syslogcfg['dhcp']))
861
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local7.*");
862
		if (isset($syslogcfg['system'])) {
863
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.notice;kern.debug;lpr.info;mail.crit;");
864
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "news.err;local0.none;local3.none;local7.none");
865
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "security.*");
866
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "auth.info;authpriv.info;daemon.info");
867
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.emerg");
868
		}
869
		if (isset($syslogcfg['logall'])) {
870
			// Make everything mean everything, including facilities excluded above.
871
			$syslogconf .= "!*\n";
872
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
873
		}
874

    
875
		if (isset($syslogcfg['zmqserver'])) {
876
				$syslogconf .= <<<EOD
877
*.*								^{$syslogcfg['zmqserver']}
878

    
879
EOD;
880
		}
881
		/* write syslog.conf */		
882
		if (!@file_put_contents("{$g['varetc_path']}/syslog.conf", $syslogconf)) {
883
			printf(gettext("Error: cannot open syslog.conf in system_syslogd_start().%s"), "\n");
884
			unset($syslogconf);
885
			return 1;
886
		}
887
		unset($syslogconf);
888

    
889
		// Ensure that the log directory exists
890
		if (!is_dir("{$g['dhcpd_chroot_path']}/var/run"))
891
			exec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/run");
892

    
893
		$sourceip = "";
894
		if (!empty($syslogcfg['sourceip'])) {
895
			if ($syslogcfg['ipproto'] == "ipv6") {
896
				$ifaddr = is_ipaddr($syslogcfg['sourceip']) ? $syslogcfg['sourceip'] : get_interface_ipv6($syslogcfg['sourceip']);
897
				if (!is_ipaddr($ifaddr))
898
					$ifaddr = get_interface_ip($syslogcfg['sourceip']);
899
			} else {
900
				$ifaddr = is_ipaddr($syslogcfg['sourceip']) ? $syslogcfg['sourceip'] : get_interface_ip($syslogcfg['sourceip']);
901
				if (!is_ipaddr($ifaddr))
902
					$ifaddr = get_interface_ipv6($syslogcfg['sourceip']);
903
			}
904
			if (is_ipaddr($ifaddr)) {
905
				$sourceip = "-b {$ifaddr}";
906
			}
907
		}
908

    
909
		$syslogd_extra = "-f {$g['varetc_path']}/syslog.conf {$sourceip}";
910
	}
911

    
912
	if (isvalidpid("{$g['varrun_path']}/syslog.pid")) {
913
		sigkillbypid("{$g['varrun_path']}/syslog.pid", "TERM");
914
		usleep(100000); // syslogd often doesn't respond to a TERM quickly enough for the starting of syslogd below to be successful
915
	}
916
	
917
	if (isvalidpid("{$g['varrun_path']}/syslog.pid")) {
918
		// if it still hasn't responded to the TERM, KILL it. 
919
		sigkillbypid("{$g['varrun_path']}/syslog.pid", "KILL");
920
		usleep(100000); 
921
	}
922

    
923
	
924
	$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}");
925

    
926
	if (platform_booting())
927
		echo gettext("done.") . "\n";
928

    
929
	return $retval;
930
}
931

    
932
function system_webgui_create_certificate() {
933
	global $config, $g;
934

    
935
	if (!is_array($config['ca']))
936
		$config['ca'] = array();
937
	$a_ca =& $config['ca'];
938
	if (!is_array($config['cert']))
939
		$config['cert'] = array();
940
	$a_cert =& $config['cert'];
941
	log_error("Creating SSL Certificate for this host");
942

    
943
	$cert = array();
944
	$cert['refid'] = uniqid();
945
	$cert['descr'] = gettext("webConfigurator default ({$cert['refid']})");
946

    
947
	$dn = array(
948
		'countryName' => "US",
949
		'stateOrProvinceName' => "State",
950
		'localityName' => "Locality",
951
		'organizationName' => "{$g['product_name']} webConfigurator Self-Signed Certificate",
952
		'emailAddress' => "admin@{$config['system']['hostname']}.{$config['system']['domain']}",
953
		'commonName' => "{$config['system']['hostname']}-{$cert['refid']}");
954
	$old_err_level = error_reporting(0); /* otherwise openssl_ functions throw warnings directly to a page screwing menu tab */
955
	if (!cert_create($cert, null, 2048, 2000, $dn, "self-signed", "sha256")){
956
		while($ssl_err = openssl_error_string()){
957
			log_error("Error creating WebGUI Certificate: openssl library returns: " . $ssl_err);
958
		}
959
		error_reporting($old_err_level);
960
		return null;
961
	}
962
	error_reporting($old_err_level);
963

    
964
	$a_cert[] = $cert;
965
	$config['system']['webgui']['ssl-certref'] = $cert['refid'];
966
	write_config(gettext("Generated new self-signed HTTPS certificate ({$cert['refid']})"));
967
	return $cert;
968
}
969

    
970
function system_webgui_start() {
971
	global $config, $g;
972

    
973
	if (platform_booting())
974
		echo gettext("Starting webConfigurator...");
975

    
976
	chdir($g['www_path']);
977

    
978
	/* defaults */
979
	$portarg = "80";
980
	$crt = "";
981
	$key = "";
982
	$ca = "";
983

    
984
	/* non-standard port? */
985
	if (isset($config['system']['webgui']['port']) && $config['system']['webgui']['port'] <> "")
986
		$portarg = "{$config['system']['webgui']['port']}";
987

    
988
	if ($config['system']['webgui']['protocol'] == "https") {
989
		// Ensure that we have a webConfigurator CERT
990
		$cert =& lookup_cert($config['system']['webgui']['ssl-certref']);
991
		if(!is_array($cert) || !$cert['crt'] || !$cert['prv'])
992
			$cert = system_webgui_create_certificate();
993
		$crt = base64_decode($cert['crt']);
994
		$key = base64_decode($cert['prv']);
995

    
996
		if(!$config['system']['webgui']['port'])
997
			$portarg = "443";
998
		$ca  = ca_chain($cert);
999
	}
1000

    
1001
	/* generate lighttpd configuration */
1002
	system_generate_lighty_config("{$g['varetc_path']}/lighty-webConfigurator.conf",
1003
		$crt, $key, $ca, "lighty-webConfigurator.pid", $portarg, "/usr/local/www/",
1004
		"cert.pem", "ca.pem");
1005

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

    
1009
	sleep(1);
1010

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

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

    
1016
	if (platform_booting()) {
1017
		if ($res == 0)
1018
			echo gettext("done.") . "\n";
1019
		else
1020
			echo gettext("failed!") . "\n";
1021
	}
1022

    
1023
	return $res;
1024
}
1025

    
1026
function system_generate_lighty_config($filename,
1027
	$cert,
1028
	$key,
1029
	$ca,
1030
	$pid_file,
1031
	$port = 80,
1032
	$document_root = "/usr/local/www/",
1033
	$cert_location = "cert.pem",
1034
	$ca_location = "ca.pem",
1035
	$captive_portal = false) {
1036

    
1037
	global $config, $g;
1038

    
1039
	if(!is_dir("{$g['tmp_path']}/lighttpdcompress"))
1040
		mkdir("{$g['tmp_path']}/lighttpdcompress");
1041

    
1042
	if(isset($config['system']['developerspew'])) {
1043
		$mt = microtime();
1044
		echo "system_generate_lighty_config() being called $mt\n";
1045
	}
1046

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

    
1051
		$maxprocperip = $config['captiveportal'][$captive_portal]['maxprocperip'];
1052
		if (empty($maxprocperip))
1053
			$maxprocperip = 10;
1054
		$captive_portal_mod_evasive = "evasive.max-conns-per-ip = {$maxprocperip}";
1055

    
1056
		$server_upload_dirs = "server.upload-dirs = ( \"{$g['tmp_path']}/captiveportal/\" )\n";
1057
		if(!is_dir("{$g['tmp_path']}/captiveportal"))
1058
			@mkdir("{$g['tmp_path']}/captiveportal", 0555);
1059
		$server_max_request_size = "server.max-request-size    = 384";
1060
		$cgi_config = "";
1061
	} else {
1062
		$captiveportal = ",\"mod_cgi\"";
1063
		$captive_portal_rewrite = "";
1064
		$captive_portal_mod_evasive = "";
1065
		$server_upload_dirs = "server.upload-dirs = ( \"{$g['upload_path']}/\", \"{$g['tmp_path']}/\", \"/var/\" )\n";
1066
		$server_max_request_size = "server.max-request-size    = 2097152";
1067
		$cgi_config = "cgi.assign                 = ( \".cgi\" => \"\" )";
1068
	}
1069
	
1070
	if (empty($port))
1071
		$lighty_port = "80";
1072
	else
1073
		$lighty_port = $port;
1074

    
1075
	$memory = get_memory();
1076
	$realmem = $memory[1];
1077

    
1078
	// Determine web GUI process settings and take into account low memory systems
1079
	if ($realmem < 255)
1080
		$max_procs = 1;
1081
	else
1082
		$max_procs = ($config['system']['webgui']['max_procs']) ? $config['system']['webgui']['max_procs'] : 2;
1083

    
1084
	// Ramp up captive portal max procs, assuming each PHP process can consume up to 64MB RAM 
1085
	if ($captive_portal !== false)  {
1086
		if ($realmem > 135 and $realmem < 256) {
1087
			$max_procs += 1; // 2 worker processes
1088
		} else if ($realmem > 255 and $realmem < 513) {
1089
			$max_procs += 2; // 3 worker processes
1090
		} else if ($realmem > 512) {
1091
			$max_procs += 4; // 6 worker processes
1092
		}
1093
		if ($max_procs > 1)
1094
			$max_php_children = intval($max_procs/2);
1095
		else
1096
			$max_php_children = 1;
1097

    
1098
	} else {
1099
		if ($realmem < 78)
1100
			$max_php_children = 0;
1101
		else
1102
			$max_php_children = 1;
1103
	}
1104

    
1105
	if(!isset($config['syslog']['nologlighttpd'])) {
1106
		$lighty_use_syslog = <<<EOD
1107
## where to send error-messages to
1108
server.errorlog-use-syslog="enable"
1109
EOD;
1110
	}
1111

    
1112

    
1113
	if ($captive_portal !== false) {
1114
		$fast_cgi_path = "{$g['tmp_path']}/php-fastcgi-{$captive_portal}.socket";
1115
		$fastcgi_config = <<<EOD
1116
#### fastcgi module
1117
## read fastcgi.txt for more info
1118
fastcgi.server = ( ".php" =>
1119
	( "localhost" =>
1120
		(
1121
			"socket" => "{$fast_cgi_path}",
1122
			"max-procs" => {$max_procs},
1123
			"bin-environment" => (
1124
				"PHP_FCGI_CHILDREN" => "{$max_php_children}",
1125
				"PHP_FCGI_MAX_REQUESTS" => "500"
1126
			),
1127
			"bin-path" => "/usr/local/bin/php"
1128
		)
1129
	)
1130
)
1131

    
1132
EOD;
1133
	} else {
1134
		$fast_cgi_path = "{$g['varrun_path']}/php-fpm.socket";
1135
		$fastcgi_config = <<<EOD
1136
#### fastcgi module
1137
## read fastcgi.txt for more info
1138
fastcgi.server = ( ".php" =>
1139
	( "localhost" =>
1140
		(
1141
			"socket" => "{$fast_cgi_path}",
1142
			"broken-scriptfilename" => "enable"
1143
		)
1144
	)
1145
)
1146

    
1147
EOD;
1148
	}
1149

    
1150

    
1151
	$lighty_config = <<<EOD
1152
#
1153
# lighttpd configuration file
1154
#
1155
# use a it as base for lighttpd 1.0.0 and above
1156
#
1157
############ Options you really have to take care of ####################
1158

    
1159
## FreeBSD!
1160
server.event-handler	= "freebsd-kqueue"
1161
server.network-backend 	= "writev"
1162
#server.use-ipv6 = "enable"
1163

    
1164
## modules to load
1165
server.modules              =   ( "mod_access", "mod_expire", "mod_compress", "mod_redirect",
1166
	{$captiveportal}, "mod_fastcgi"
1167
)
1168

    
1169
server.max-keep-alive-requests = 15
1170
server.max-keep-alive-idle = 30
1171

    
1172
## a static document-root, for virtual-hosting take look at the
1173
## server.virtual-* options
1174
server.document-root        = "{$document_root}"
1175
{$captive_portal_rewrite}
1176

    
1177
# Maximum idle time with nothing being written (php downloading)
1178
server.max-write-idle = 999
1179

    
1180
{$lighty_use_syslog}
1181

    
1182
# files to check for if .../ is requested
1183
server.indexfiles           = ( "index.php", "index.html",
1184
                                "index.htm", "default.htm" )
1185

    
1186
# mimetype mapping
1187
mimetype.assign             = (
1188
  ".pdf"          =>      "application/pdf",
1189
  ".sig"          =>      "application/pgp-signature",
1190
  ".spl"          =>      "application/futuresplash",
1191
  ".class"        =>      "application/octet-stream",
1192
  ".ps"           =>      "application/postscript",
1193
  ".torrent"      =>      "application/x-bittorrent",
1194
  ".dvi"          =>      "application/x-dvi",
1195
  ".gz"           =>      "application/x-gzip",
1196
  ".pac"          =>      "application/x-ns-proxy-autoconfig",
1197
  ".swf"          =>      "application/x-shockwave-flash",
1198
  ".tar.gz"       =>      "application/x-tgz",
1199
  ".tgz"          =>      "application/x-tgz",
1200
  ".tar"          =>      "application/x-tar",
1201
  ".zip"          =>      "application/zip",
1202
  ".mp3"          =>      "audio/mpeg",
1203
  ".m3u"          =>      "audio/x-mpegurl",
1204
  ".wma"          =>      "audio/x-ms-wma",
1205
  ".wax"          =>      "audio/x-ms-wax",
1206
  ".ogg"          =>      "audio/x-wav",
1207
  ".wav"          =>      "audio/x-wav",
1208
  ".gif"          =>      "image/gif",
1209
  ".jpg"          =>      "image/jpeg",
1210
  ".jpeg"         =>      "image/jpeg",
1211
  ".png"          =>      "image/png",
1212
  ".xbm"          =>      "image/x-xbitmap",
1213
  ".xpm"          =>      "image/x-xpixmap",
1214
  ".xwd"          =>      "image/x-xwindowdump",
1215
  ".css"          =>      "text/css",
1216
  ".html"         =>      "text/html",
1217
  ".htm"          =>      "text/html",
1218
  ".js"           =>      "text/javascript",
1219
  ".asc"          =>      "text/plain",
1220
  ".c"            =>      "text/plain",
1221
  ".conf"         =>      "text/plain",
1222
  ".text"         =>      "text/plain",
1223
  ".txt"          =>      "text/plain",
1224
  ".dtd"          =>      "text/xml",
1225
  ".xml"          =>      "text/xml",
1226
  ".mpeg"         =>      "video/mpeg",
1227
  ".mpg"          =>      "video/mpeg",
1228
  ".mov"          =>      "video/quicktime",
1229
  ".qt"           =>      "video/quicktime",
1230
  ".avi"          =>      "video/x-msvideo",
1231
  ".asf"          =>      "video/x-ms-asf",
1232
  ".asx"          =>      "video/x-ms-asf",
1233
  ".wmv"          =>      "video/x-ms-wmv",
1234
  ".bz2"          =>      "application/x-bzip",
1235
  ".tbz"          =>      "application/x-bzip-compressed-tar",
1236
  ".tar.bz2"      =>      "application/x-bzip-compressed-tar"
1237
 )
1238

    
1239
# Use the "Content-Type" extended attribute to obtain mime type if possible
1240
#mimetypes.use-xattr        = "enable"
1241

    
1242
## deny access the file-extensions
1243
#
1244
# ~    is for backupfiles from vi, emacs, joe, ...
1245
# .inc is often used for code includes which should in general not be part
1246
#      of the document-root
1247
url.access-deny             = ( "~", ".inc" )
1248

    
1249

    
1250
######### Options that are good to be but not necessary to be changed #######
1251

    
1252
## bind to port (default: 80)
1253

    
1254
EOD;
1255

    
1256
	$lighty_config .= "server.bind  = \"0.0.0.0\"\n";
1257
	$lighty_config .= "server.port  = {$lighty_port}\n";
1258
	$lighty_config .= "\$SERVER[\"socket\"]  == \"0.0.0.0:{$lighty_port}\" { }\n";
1259
	$lighty_config .= "\$SERVER[\"socket\"]  == \"[::]:{$lighty_port}\" { \n";
1260
	if($cert <> "" and $key <> "") {
1261
		$lighty_config .= "\n";
1262
		$lighty_config .= "## ssl configuration\n";
1263
		$lighty_config .= "ssl.engine = \"enable\"\n";
1264
		$lighty_config .= "ssl.pemfile = \"{$g['varetc_path']}/{$cert_location}\"\n\n";
1265
		if($ca <> "")
1266
			$lighty_config .= "ssl.ca-file = \"{$g['varetc_path']}/{$ca_location}\"\n\n";
1267
	}
1268
	$lighty_config .= " }\n";
1269

    
1270

    
1271
	$lighty_config .= <<<EOD
1272

    
1273
## error-handler for status 404
1274
#server.error-handler-404   = "/error-handler.html"
1275
#server.error-handler-404   = "/error-handler.php"
1276

    
1277
## to help the rc.scripts
1278
server.pid-file            = "{$g['varrun_path']}/{$pid_file}"
1279

    
1280
## virtual directory listings
1281
server.dir-listing         = "disable"
1282

    
1283
## enable debugging
1284
debug.log-request-header   = "disable"
1285
debug.log-response-header  = "disable"
1286
debug.log-request-handling = "disable"
1287
debug.log-file-not-found   = "disable"
1288

    
1289
# gzip compression
1290
compress.cache-dir = "{$g['tmp_path']}/lighttpdcompress/"
1291
compress.filetype  = ("text/plain","text/css", "text/xml", "text/javascript" )
1292

    
1293
{$server_upload_dirs}
1294

    
1295
{$server_max_request_size}
1296

    
1297
{$fastcgi_config}
1298

    
1299
{$cgi_config}
1300

    
1301
{$captive_portal_mod_evasive}
1302

    
1303
expire.url = (
1304
				"" => "access 50 hours",	
1305
        )
1306

    
1307
EOD;
1308

    
1309
	$cert = str_replace("\r", "", $cert);
1310
	$key = str_replace("\r", "", $key);
1311
	$ca = str_replace("\r", "", $ca);
1312

    
1313
	$cert = str_replace("\n\n", "\n", $cert);
1314
	$key = str_replace("\n\n", "\n", $key);
1315
	$ca = str_replace("\n\n", "\n", $ca);
1316

    
1317
	if($cert <> "" and $key <> "") {
1318
		$fd = fopen("{$g['varetc_path']}/{$cert_location}", "w");
1319
		if (!$fd) {
1320
			printf(gettext("Error: cannot open cert.pem in system_webgui_start().%s"), "\n");
1321
			return 1;
1322
		}
1323
		chmod("{$g['varetc_path']}/{$cert_location}", 0600);
1324
		fwrite($fd, $cert);
1325
		fwrite($fd, "\n");
1326
		fwrite($fd, $key);
1327
		fclose($fd);
1328
		if(!(empty($ca) || (strlen(trim($ca)) == 0))) {
1329
			$fd = fopen("{$g['varetc_path']}/{$ca_location}", "w");
1330
			if (!$fd) {
1331
				printf(gettext("Error: cannot open ca.pem in system_webgui_start().%s"), "\n");
1332
				return 1;
1333
			}
1334
			chmod("{$g['varetc_path']}/{$ca_location}", 0600);
1335
			fwrite($fd, $ca);
1336
			fclose($fd);
1337
		}
1338
		$lighty_config .= "\n";
1339
		$lighty_config .= "## " . gettext("ssl configuration") . "\n";
1340
		$lighty_config .= "ssl.engine = \"enable\"\n";
1341
		$lighty_config .= "ssl.pemfile = \"{$g['varetc_path']}/{$cert_location}\"\n\n";
1342

    
1343
		// SSLv2/3 is deprecated, force use of TLS
1344
		$lighty_config .= "ssl.use-sslv2 = \"disable\"\n";
1345
		$lighty_config .= "ssl.use-sslv3 = \"disable\"\n";
1346

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

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

    
1352
		if(!(empty($ca) || (strlen(trim($ca)) == 0)))
1353
			$lighty_config .= "ssl.ca-file = \"{$g['varetc_path']}/{$ca_location}\"\n\n";
1354
	}
1355

    
1356
	// Add HTTP to HTTPS redirect	
1357
	if ($captive_portal === false && $config['system']['webgui']['protocol'] == "https" && !isset($config['system']['webgui']['disablehttpredirect'])) {
1358
		if($lighty_port != "443") 
1359
			$redirectport = ":{$lighty_port}";
1360
		$lighty_config .= <<<EOD
1361
\$SERVER["socket"] == ":80" {
1362
	\$HTTP["host"] =~ "(.*)" {
1363
		url.redirect = ( "^/(.*)" => "https://%1{$redirectport}/$1" )
1364
	}
1365
}
1366
\$SERVER["socket"] == "[::]:80" {
1367
	\$HTTP["host"] =~ "(.*)" {
1368
		url.redirect = ( "^/(.*)" => "https://%1{$redirectport}/$1" )
1369
	}
1370
}
1371
EOD;
1372
	}
1373

    
1374
	$fd = fopen("{$filename}", "w");
1375
	if (!$fd) {
1376
		printf(gettext("Error: cannot open %s in system_generate_lighty_config().%s"), $filename, "\n");
1377
		return 1;
1378
	}
1379
	fwrite($fd, $lighty_config);
1380
	fclose($fd);
1381

    
1382
	return 0;
1383

    
1384
}
1385

    
1386
function system_timezone_configure() {
1387
	global $config, $g;
1388
	if(isset($config['system']['developerspew'])) {
1389
		$mt = microtime();
1390
		echo "system_timezone_configure() being called $mt\n";
1391
	}
1392

    
1393
	$syscfg = $config['system'];
1394

    
1395
	if (platform_booting())
1396
		echo gettext("Setting timezone...");
1397

    
1398
	/* extract appropriate timezone file */
1399
	$timezone = $syscfg['timezone'];
1400
	if ($timezone) {
1401
		exec('/usr/bin/tar -tvzf /usr/share/zoneinfo.tgz', $tzs);
1402
		foreach ($tzs as $tz) {
1403
			if (preg_match(",{$timezone}$,", $tz))
1404
				break;
1405
			if (preg_match(",{$timezone} link to *(.*)$,", $tz, $matches)) {
1406
				$timezone = $matches[1];
1407
				break;
1408
			}
1409
		}
1410
	} else
1411
		$timezone = "Etc/UTC";
1412

    
1413
	conf_mount_rw();
1414

    
1415
	exec("LANG=C /usr/bin/tar xzfO /usr/share/zoneinfo.tgz " .
1416
		escapeshellarg($timezone) . " > /etc/localtime");
1417

    
1418
	mwexec("sync");
1419
	conf_mount_ro();
1420

    
1421
	if (platform_booting())
1422
		echo gettext("done.") . "\n";
1423
}
1424

    
1425
function system_ntp_setup_gps($serialport) {
1426
	global $config, $g;
1427
	$gps_device = '/dev/gps0';
1428
	$serialport = '/dev/'.$serialport;
1429

    
1430
	if (!file_exists($serialport))
1431
		return false;
1432

    
1433
	conf_mount_rw();
1434
	// Create symlink that ntpd requires
1435
	unlink_if_exists($gps_device);
1436
	@symlink($serialport, $gps_device);
1437

    
1438
	$gpsbaud = '4800';
1439
	if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['speed'])) {
1440
		switch ($config['ntpd']['gps']['speed']) {
1441
			case '16':
1442
				$gpsbaud = '9600';
1443
				break;
1444
			case '32':
1445
				$gpsbaud = '19200';
1446
				break;
1447
			case '48':
1448
				$gpsbaud = '38400';
1449
				break;
1450
			case '64':
1451
				$gpsbaud = '57600';
1452
				break;
1453
			case '80':
1454
				$gpsbaud = '115200';
1455
				break;
1456
		}
1457
	}
1458

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

    
1462
	/* Send the following to the GPS port to initialize the GPS */
1463
	if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['type'])) {
1464
		$gps_init = base64_decode($config['ntpd']['gps']['initcmd']);
1465
	}else{
1466
		$gps_init = base64_decode('JFBVQlgsNDAsR1NWLDAsMCwwLDAqNTkNCiRQVUJYLDQwLEdMTCwwLDAsMCwwKjVDDQokUFVCWCw0MCxaREEsMCwwLDAsMCo0NA0KJFBVQlgsNDAsVlRHLDAsMCwwLDAqNUUNCiRQVUJYLDQwLEdTViwwLDAsMCwwKjU5DQokUFVCWCw0MCxHU0EsMCwwLDAsMCo0RQ0KJFBVQlgsNDAsR0dBLDAsMCwwLDANCiRQVUJYLDQwLFRYVCwwLDAsMCwwDQokUFVCWCw0MCxSTUMsMCwwLDAsMCo0Ng0KJFBVQlgsNDEsMSwwMDA3LDAwMDMsNDgwMCwwDQokUFVCWCw0MCxaREEsMSwxLDEsMQ==');
1467
	}
1468

    
1469
	/* XXX: Why not file_put_contents to the device */
1470
	@file_put_contents('/tmp/gps.init', $gps_init);
1471
	mwexec("cat /tmp/gps.init > {$serialport}");
1472

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

    
1478
	conf_mount_ro();
1479

    
1480
	return true;
1481
}
1482

    
1483
function system_ntp_setup_pps($serialport) {
1484
	global $config, $g;
1485

    
1486
	$pps_device = '/dev/pps0';
1487
	$serialport = '/dev/'.$serialport;
1488

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

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

    
1497
	conf_mount_ro();
1498

    
1499
	return true;
1500
}
1501

    
1502

    
1503
function system_ntp_configure($start_ntpd=true) {
1504
	global $config, $g;
1505

    
1506
	$driftfile = "/var/db/ntpd.drift";
1507
	$statsdir = "/var/log/ntp";
1508
	$gps_device = '/dev/gps0';
1509

    
1510
	if ($g['platform'] == 'jail')
1511
		return;
1512

    
1513
	safe_mkdir($statsdir);
1514

    
1515
	if (!is_array($config['ntpd']))
1516
		$config['ntpd'] = array();
1517

    
1518
	$ntpcfg = "# \n";
1519
	$ntpcfg .= "# pfSense ntp configuration file \n";
1520
	$ntpcfg .= "# \n\n";
1521
	$ntpcfg .= "tinker panic 0 \n";
1522

    
1523
	/* Add Orphan mode */
1524
	$ntpcfg .= "# Orphan mode stratum\n";
1525
	$ntpcfg .= 'tos orphan ';
1526
	if (!empty($config['ntpd']['orphan'])) {
1527
		$ntpcfg .= $config['ntpd']['orphan'];
1528
	}else{
1529
		$ntpcfg .= '12';
1530
	}
1531
	$ntpcfg .= "\n";
1532

    
1533
	/* Add PPS configuration */
1534
	if (is_array($config['ntpd']['pps']) && !empty($config['ntpd']['pps']['port'])
1535
		&& file_exists('/dev/'.$config['ntpd']['pps']['port'])
1536
		&& system_ntp_setup_pps($config['ntpd']['pps']['port'])) {
1537
		$ntpcfg .= "\n";
1538
		$ntpcfg .= "# PPS Setup\n";
1539
		$ntpcfg .= 'server 127.127.22.0';
1540
		$ntpcfg .= ' minpoll 4 maxpoll 4';
1541
		if (empty($config['ntpd']['pps']['prefer'])) { /*note: this one works backwards */
1542
			$ntpcfg .= ' prefer'; 
1543
		}
1544
		if (!empty($config['ntpd']['pps']['noselect'])) {
1545
			$ntpcfg .= ' noselect ';
1546
		}
1547
		$ntpcfg .= "\n";
1548
		$ntpcfg .= 'fudge 127.127.22.0';
1549
		if (!empty($config['ntpd']['pps']['fudge1'])) {
1550
			$ntpcfg .= ' time1 ';
1551
			$ntpcfg .= $config['ntpd']['pps']['fudge1'];
1552
		}
1553
		if (!empty($config['ntpd']['pps']['flag2'])) {
1554
			$ntpcfg .= ' flag2 1';
1555
		}
1556
		if (!empty($config['ntpd']['pps']['flag3'])) {
1557
			$ntpcfg .= ' flag3 1';
1558
		}else{
1559
			$ntpcfg .= ' flag3 0';
1560
		}
1561
		if (!empty($config['ntpd']['pps']['flag4'])) {
1562
			$ntpcfg .= ' flag4 1';
1563
		}
1564
		if (!empty($config['ntpd']['pps']['refid'])) {
1565
			$ntpcfg .= ' refid ';
1566
			$ntpcfg .= $config['ntpd']['pps']['refid'];
1567
		}
1568
		$ntpcfg .= "\n";
1569
	}
1570
	/* End PPS configuration */
1571

    
1572
	/* Add GPS configuration */
1573
	if (is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['port'])
1574
		&& file_exists('/dev/'.$config['ntpd']['gps']['port'])
1575
		&& system_ntp_setup_gps($config['ntpd']['gps']['port'])) {
1576
		$ntpcfg .= "\n";
1577
		$ntpcfg .= "# GPS Setup\n";
1578
		$ntpcfg .= 'server 127.127.20.0 mode ';
1579
		if (!empty($config['ntpd']['gps']['nmea']) || !empty($config['ntpd']['gps']['speed']) || !empty($config['ntpd']['gps']['subsec'])) {
1580
			if (!empty($config['ntpd']['gps']['nmea'])) {
1581
				$ntpmode = (int) $config['ntpd']['gps']['nmea'];
1582
			}
1583
			if (!empty($config['ntpd']['gps']['speed'])) {
1584
				$ntpmode += (int) $config['ntpd']['gps']['speed'];
1585
			}
1586
			if (!empty($config['ntpd']['gps']['subsec'])) {
1587
				$ntpmode += 128;
1588
			}
1589
			$ntpcfg .= (string) $ntpmode;
1590
		}else{
1591
			$ntpcfg .= '0';
1592
		}
1593
		$ntpcfg .= ' minpoll 4 maxpoll 4';
1594
		if (empty($config['ntpd']['gps']['prefer'])) { /*note: this one works backwards */
1595
			$ntpcfg .= ' prefer'; 
1596
		}
1597
		if (!empty($config['ntpd']['gps']['noselect'])) {
1598
			$ntpcfg .= ' noselect ';
1599
		}
1600
		$ntpcfg .= "\n";
1601
		$ntpcfg .= 'fudge 127.127.20.0';
1602
		if (!empty($config['ntpd']['gps']['fudge1'])) {
1603
			$ntpcfg .= ' time1 ';
1604
			$ntpcfg .= $config['ntpd']['gps']['fudge1'];
1605
		}
1606
		if (!empty($config['ntpd']['gps']['fudge2'])) {
1607
			$ntpcfg .= ' time2 ';
1608
			$ntpcfg .= $config['ntpd']['gps']['fudge2'];
1609
		}
1610
		if (!empty($config['ntpd']['gps']['flag1'])) {
1611
			$ntpcfg .= ' flag1 1';
1612
		}else{
1613
			$ntpcfg .= ' flag1 0';
1614
		}
1615
		if (!empty($config['ntpd']['gps']['flag2'])) {
1616
			$ntpcfg .= ' flag2 1';
1617
		}
1618
		if (!empty($config['ntpd']['gps']['flag3'])) {
1619
			$ntpcfg .= ' flag3 1';
1620
		}else{
1621
			$ntpcfg .= ' flag3 0';
1622
		}
1623
		if (!empty($config['ntpd']['gps']['flag4'])) {
1624
			$ntpcfg .= ' flag4 1';
1625
		}
1626
		if (!empty($config['ntpd']['gps']['refid'])) {
1627
			$ntpcfg .= ' refid ';
1628
			$ntpcfg .= $config['ntpd']['gps']['refid'];
1629
		}
1630
		$ntpcfg .= "\n";
1631
	}elseif (is_array($config['ntpd']) && !empty($config['ntpd']['gpsport'])
1632
		&& file_exists('/dev/'.$config['ntpd']['gpsport'])
1633
		&& system_ntp_setup_gps($config['ntpd']['gpsport'])) {
1634
		/* This handles a 2.1 and earlier config */
1635
		$ntpcfg .= "# GPS Setup\n";
1636
		$ntpcfg .= "server 127.127.20.0 mode 0 minpoll 4 maxpoll 4 prefer\n";
1637
		$ntpcfg .= "fudge 127.127.20.0 time1 0.155 time2 0.000 flag1 1 flag2 0 flag3 1\n";
1638
		// Fall back to local clock if GPS is out of sync?
1639
		$ntpcfg .= "server 127.127.1.0\n";
1640
		$ntpcfg .= "fudge 127.127.1.0 stratum 12\n";
1641
	}
1642
	/* End GPS configuration */
1643
	
1644
	$ntpcfg .= "\n\n# Upstream Servers\n";
1645
	/* foreach through ntp servers and write out to ntpd.conf */
1646
	foreach (explode(' ', $config['system']['timeservers']) as $ts) {
1647
		$ntpcfg .= "server {$ts} iburst maxpoll 9";
1648
		if (substr_count($config['ntpd']['prefer'], $ts)) $ntpcfg .= ' prefer';
1649
		if (substr_count($config['ntpd']['noselect'], $ts)) $ntpcfg .= ' noselect';
1650
		$ntpcfg .= "\n";
1651
	}
1652
	unset($ts);
1653

    
1654
	$ntpcfg .= "\n\n";
1655
	$ntpcfg .= "disable monitor\n"; //prevent NTP reflection attack, see https://forum.pfsense.org/index.php/topic,67189.msg389132.html#msg389132
1656
	if (!empty($config['ntpd']['clockstats']) || !empty($config['ntpd']['loopstats']) || !empty($config['ntpd']['peerstats'])) {
1657
		$ntpcfg .= "enable stats\n";
1658
		$ntpcfg .= 'statistics';
1659
		if (!empty($config['ntpd']['clockstats'])) {
1660
			$ntpcfg .= ' clockstats';
1661
		}
1662
		if (!empty($config['ntpd']['loopstats'])) {
1663
			$ntpcfg .= ' loopstats';
1664
		}
1665
		if (!empty($config['ntpd']['peerstats'])) {
1666
			$ntpcfg .= ' peerstats';
1667
		}
1668
		$ntpcfg .= "\n";
1669
	}
1670
	$ntpcfg .= "statsdir {$statsdir}\n";
1671
	$ntpcfg .= 'logconfig =syncall +clockall';
1672
	if (!empty($config['ntpd']['logpeer'])) {
1673
		$ntpcfg .= ' +peerall';
1674
	}
1675
	if (!empty($config['ntpd']['logsys'])) {
1676
		$ntpcfg .= ' +sysall';
1677
	}
1678
	$ntpcfg .= "\n";
1679
	$ntpcfg .= "driftfile {$driftfile}\n";
1680
	/* Access restrictions */
1681
	$ntpcfg .= 'restrict default';
1682
	if (empty($config['ntpd']['kod'])) { /*note: this one works backwards */
1683
		$ntpcfg .= ' kod limited'; 
1684
	}
1685
	if (empty($config['ntpd']['nomodify'])) { /*note: this one works backwards */
1686
		$ntpcfg .= ' nomodify'; 
1687
	}
1688
	if (!empty($config['ntpd']['noquery'])) {
1689
		$ntpcfg .= ' noquery';
1690
	}
1691
	if (empty($config['ntpd']['nopeer'])) { /*note: this one works backwards */
1692
		$ntpcfg .= ' nopeer'; 
1693
	}
1694
	if (empty($config['ntpd']['notrap'])) { /*note: this one works backwards */
1695
		$ntpcfg .= ' notrap'; 
1696
	}
1697
	if (!empty($config['ntpd']['noserve'])) {
1698
		$ntpcfg .= ' noserve';
1699
	}
1700
	$ntpcfg .= "\nrestrict -6 default";
1701
	if (empty($config['ntpd']['kod'])) { /*note: this one works backwards */
1702
		$ntpcfg .= ' kod limited'; 
1703
	}
1704
	if (empty($config['ntpd']['nomodify'])) { /*note: this one works backwards */
1705
		$ntpcfg .= ' nomodify'; 
1706
	}
1707
	if (!empty($config['ntpd']['noquery'])) {
1708
		$ntpcfg .= ' noquery';
1709
	}
1710
	if (empty($config['ntpd']['nopeer'])) { /*note: this one works backwards */
1711
		$ntpcfg .= ' nopeer'; 
1712
	}
1713
	if (!empty($config['ntpd']['noserve'])) {
1714
		$ntpcfg .= ' noserve';
1715
	}
1716
	if (empty($config['ntpd']['notrap'])) { /*note: this one works backwards */
1717
		$ntpcfg .= ' notrap'; 
1718
	}
1719
	$ntpcfg .= "\n";
1720

    
1721
	/* A leapseconds file is really only useful if this clock is stratum 1 */
1722
	$ntpcfg .= "\n";
1723
	if (!empty($config['ntpd']['leapsec'])) {
1724
		$leapsec .= base64_decode($config['ntpd']['leapsec']);
1725
		file_put_contents('/var/db/leap-seconds', $leapsec);
1726
		$ntpcfg .= "leapfile /var/db/leap-seconds\n";
1727
	}
1728
	
1729

    
1730
	if (empty($config['ntpd']['interface'])) {
1731
		if (is_array($config['installedpackages']['openntpd']) && !empty($config['installedpackages']['openntpd']['config'][0]['interface']))
1732
			$interfaces = explode(",", $config['installedpackages']['openntpd']['config'][0]['interface']);
1733
		else
1734
			$interfaces = array();
1735
	} else
1736
		$interfaces = explode(",", $config['ntpd']['interface']);
1737

    
1738
	if (is_array($interfaces) && count($interfaces)) {
1739
		$ntpcfg .= "interface ignore all\n";
1740
		foreach ($interfaces as $interface) {
1741
			if (!is_ipaddr($interface)) {
1742
				$interface = get_real_interface($interface);
1743
			}
1744
			if (!empty($interface))
1745
				$ntpcfg .= "interface listen {$interface}\n";
1746
		}
1747
	}
1748

    
1749
	/* open configuration for writing or bail */
1750
	if (!@file_put_contents("{$g['varetc_path']}/ntpd.conf", $ntpcfg)) {
1751
		log_error("Could not open {$g['varetc_path']}/ntpd.conf for writing");
1752
		return;
1753
	}
1754

    
1755
	/* At bootup we just want to write out the config. */
1756
	if (!$start_ntpd)
1757
		return;
1758

    
1759
	/* if ntpd is running, kill it */
1760
	while (isvalidpid("{$g['varrun_path']}/ntpd.pid")) {
1761
		killbypid("{$g['varrun_path']}/ntpd.pid");
1762
	}
1763
	@unlink("{$g['varrun_path']}/ntpd.pid");
1764

    
1765
	/* if /var/empty does not exist, create it */
1766
	if(!is_dir("/var/empty"))
1767
		mkdir("/var/empty", 0775, true);
1768

    
1769
	/* start opentpd, set time now and use /var/etc/ntpd.conf */
1770
	mwexec("/usr/local/sbin/ntpd -g -c {$g['varetc_path']}/ntpd.conf -p {$g['varrun_path']}/ntpd.pid", false, true);
1771
	
1772
	// Note that we are starting up
1773
	log_error("NTPD is starting up.");
1774
	return;
1775
}
1776

    
1777
function sync_system_time() {
1778
	global $config, $g;
1779

    
1780
	if (platform_booting())
1781
		echo gettext("Syncing system time before startup...");
1782

    
1783
	/* foreach through servers and write out to ntpd.conf */
1784
	foreach (explode(' ', $config['system']['timeservers']) as $ts) {
1785
		mwexec("/usr/local/sbin/ntpdate -s $ts");
1786
	}
1787
	
1788
	if (platform_booting())
1789
		echo gettext("done.") . "\n";
1790
	
1791
}
1792

    
1793
function system_halt() {
1794
	global $g;
1795

    
1796
	system_reboot_cleanup();
1797

    
1798
	mwexec("/usr/bin/nohup /etc/rc.halt > /dev/null 2>&1 &");
1799
}
1800

    
1801
function system_reboot() {
1802
	global $g;
1803

    
1804
	system_reboot_cleanup();
1805

    
1806
	mwexec("nohup /etc/rc.reboot > /dev/null 2>&1 &");
1807
}
1808

    
1809
function system_reboot_sync() {
1810
	global $g;
1811

    
1812
	system_reboot_cleanup();
1813

    
1814
	mwexec("/etc/rc.reboot > /dev/null 2>&1");
1815
}
1816

    
1817
function system_reboot_cleanup() {
1818
	global $config, $cpzone;
1819

    
1820
	mwexec("/usr/local/bin/beep.sh stop");
1821
	require_once("captiveportal.inc");
1822
	if (is_array($config['captiveportal'])) {
1823
		foreach ($config['captiveportal'] as $cpzone=>$cp) {
1824
			captiveportal_radius_stop_all();
1825
			captiveportal_send_server_accounting(true);
1826
		}
1827
	}
1828
	require_once("voucher.inc");
1829
	voucher_save_db_to_config();
1830
	require_once("pkg-utils.inc");
1831
	stop_packages();
1832
}
1833

    
1834
function system_do_shell_commands($early = 0) {
1835
	global $config, $g;
1836
	if(isset($config['system']['developerspew'])) {
1837
		$mt = microtime();
1838
		echo "system_do_shell_commands() being called $mt\n";
1839
	}
1840

    
1841
	if ($early)
1842
		$cmdn = "earlyshellcmd";
1843
	else
1844
		$cmdn = "shellcmd";
1845

    
1846
	if (is_array($config['system'][$cmdn])) {
1847

    
1848
		/* *cmd is an array, loop through */
1849
		foreach ($config['system'][$cmdn] as $cmd) {
1850
			exec($cmd);
1851
		}
1852

    
1853
	} elseif($config['system'][$cmdn] <> "") {
1854

    
1855
		/* execute single item */
1856
		exec($config['system'][$cmdn]);
1857

    
1858
	}
1859
}
1860

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

    
1868
	if (isset($config['system']['disableconsolemenu'])) {
1869
		touch("{$g['varetc_path']}/disableconsole");
1870
	} else {
1871
		unlink_if_exists("{$g['varetc_path']}/disableconsole");
1872
	}
1873
}
1874

    
1875
function system_dmesg_save() {
1876
	global $g;
1877
	if(isset($config['system']['developerspew'])) {
1878
		$mt = microtime();
1879
		echo "system_dmesg_save() being called $mt\n";
1880
	}
1881

    
1882
	$dmesg = "";
1883
	$_gb = exec("/sbin/dmesg", $dmesg);
1884

    
1885
	/* find last copyright line (output from previous boots may be present) */
1886
	$lastcpline = 0;
1887

    
1888
	for ($i = 0; $i < count($dmesg); $i++) {
1889
		if (strstr($dmesg[$i], "Copyright (c) 1992-"))
1890
			$lastcpline = $i;
1891
	}
1892

    
1893
	$fd = fopen("{$g['varlog_path']}/dmesg.boot", "w");
1894
	if (!$fd) {
1895
		printf(gettext("Error: cannot open dmesg.boot in system_dmesg_save().%s"), "\n");
1896
		return 1;
1897
	}
1898

    
1899
	for ($i = $lastcpline; $i < count($dmesg); $i++)
1900
		fwrite($fd, $dmesg[$i] . "\n");
1901

    
1902
	fclose($fd);
1903
	unset($dmesg);
1904

    
1905
	return 0;
1906
}
1907

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

    
1915
	if (isset($config['system']['harddiskstandby'])) {
1916
		if (platform_booting()) {
1917
			echo gettext('Setting hard disk standby... ');
1918
		}
1919

    
1920
		$standby = $config['system']['harddiskstandby'];
1921
		// Check for a numeric value
1922
		if (is_numeric($standby)) {
1923
			// Sync the disk(s)
1924
			pfSense_sync();
1925
			if (set_single_sysctl('hw.ata.standby', (int)$standby)) {
1926
				// Reinitialize ATA-drives
1927
				mwexec('/usr/local/sbin/atareinit');
1928
				if (platform_booting()) {
1929
					echo gettext("done.") . "\n";
1930
				}
1931
			} else if (platform_booting()) {
1932
				echo gettext("failed!") . "\n";
1933
			}
1934
		} else if (platform_booting()) {
1935
			echo gettext("failed!") . "\n";
1936
		}
1937
	}
1938
}
1939

    
1940
function system_setup_sysctl() {
1941
	global $config;
1942
	if(isset($config['system']['developerspew'])) {
1943
		$mt = microtime();
1944
		echo "system_setup_sysctl() being called $mt\n";
1945
	}
1946

    
1947
	activate_sysctls();	
1948

    
1949
	if (isset($config['system']['sharednet'])) {
1950
		system_disable_arp_wrong_if();
1951
	}
1952
}
1953

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

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

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

    
1996
function system_check_reset_button() {
1997
	global $g;
1998

    
1999
	$specplatform = system_identify_specific_platform();
2000

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

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

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

    
2019
***********************************************************************
2020
* Reset button pressed - resetting configuration to factory defaults. *
2021
* The system will reboot after this completes.                        *
2022
***********************************************************************
2023

    
2024

    
2025
EOD;
2026
		
2027
		reset_factory_defaults();
2028
		system_reboot_sync();
2029
		exit(0);
2030
	}
2031

    
2032
	return 0;
2033
}
2034

    
2035
/* attempt to identify the specific platform (for embedded systems)
2036
   Returns an array with two elements:
2037
	name => platform string (e.g. 'wrap', 'alix' etc.)
2038
	descr => human-readable description (e.g. "PC Engines WRAP")
2039
*/
2040
function system_identify_specific_platform() {
2041
	global $g;
2042
	
2043
	if ($g['platform'] == 'generic-pc')
2044
		return array('name' => 'generic-pc', 'descr' => gettext("Generic PC"));
2045
	
2046
	if ($g['platform'] == 'generic-pc-cdrom')
2047
		return array('name' => 'generic-pc-cdrom', 'descr' => gettext("Generic PC (CD-ROM)"));
2048
	
2049
	/* Try to guess from smbios strings */
2050
	unset($output);
2051
	$_gb = exec('/bin/kenv smbios.system.product 2>/dev/null', $output);
2052
	switch ($output[0]) {
2053
	case 'FW7541':
2054
		return (array('name' => 'FW7541', 'descr' => 'Netgate FW7541'));
2055
		break;
2056
	case 'APU':
2057
		return (array('name' => 'APU', 'descr' => 'Netgate APU'));
2058
		break;
2059
	case 'RCC-VE':
2060
		return (array('name' => 'RCC-VE', 'descr' => 'Netgate RCC-VE'));
2061
		break;
2062
	case 'SYS-5018A-FTN4':
2063
	case 'A1SAi':
2064
		return (array('name' => 'C2758', 'descr' => 'Super Micro C2758'));
2065
		break;
2066
	}
2067

    
2068
	/* the rest of the code only deals with 'embedded' platforms */
2069
	if ($g['platform'] != 'nanobsd')
2070
		return array('name' => $g['platform'], 'descr' => $g['platform']);
2071

    
2072
	$dmesg = get_single_sysctl('hw.model');
2073

    
2074
	if (strpos($dmesg, "PC Engines WRAP") !== false)
2075
		return array('name' => 'wrap', 'descr' => gettext('PC Engines WRAP'));
2076
	
2077
	if (strpos($dmesg, "PC Engines ALIX") !== false)
2078
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
2079

    
2080
	if (preg_match("/Soekris net45../", $dmesg, $matches))
2081
		return array('name' => 'net45xx', 'descr' => $matches[0]);
2082
	
2083
	if (preg_match("/Soekris net48../", $dmesg, $matches))
2084
		return array('name' => 'net48xx', 'descr' => $matches[0]);
2085
		
2086
	if (preg_match("/Soekris net55../", $dmesg, $matches))
2087
		return array('name' => 'net55xx', 'descr' => $matches[0]);
2088

    
2089
	unset($dmesg);
2090

    
2091
	$dmesg_boot = system_get_dmesg_boot();
2092
	if (strpos($dmesg_boot, "PC Engines ALIX") !== false)
2093
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
2094
	unset($dmesg_boot);
2095

    
2096
	/* unknown embedded platform */
2097
	return array('name' => 'embedded', 'descr' => gettext('embedded (unknown)'));
2098
}
2099

    
2100
function system_get_dmesg_boot() {
2101
	global $g;
2102
		
2103
	return file_get_contents("{$g['varlog_path']}/dmesg.boot");
2104
}
2105

    
2106
function get_possible_listen_ips($include_ipv6_link_local=false) {
2107
	$interfaces = get_configured_interface_with_descr();
2108
	$carplist = get_configured_carp_interface_list();
2109
	$listenips = array();
2110
	foreach ($carplist as $cif => $carpip)
2111
		$interfaces[$cif] = $carpip." (".get_vip_descr($carpip).")";
2112
	$aliaslist = get_configured_ip_aliases_list();
2113
	foreach ($aliaslist as $aliasip => $aliasif)
2114
		$interfaces[$aliasip] = $aliasip." (".get_vip_descr($aliasip).")";
2115
	foreach ($interfaces as $iface => $ifacename) {
2116
		$tmp["name"]  = $ifacename;
2117
		$tmp["value"] = $iface;
2118
		$listenips[] = $tmp;
2119
		if ($include_ipv6_link_local) {
2120
			$llip = find_interface_ipv6_ll(get_real_interface($iface));
2121
			if (!empty($llip)) {
2122
				$tmp["name"]  = "{$ifacename} IPv6 Link-Local";
2123
				$tmp["value"] = $llip;
2124
				$listenips[] = $tmp;
2125
			}
2126
		}
2127
	}
2128
	$tmp["name"]  = "Localhost";
2129
	$tmp["value"] = "lo0";
2130
	$listenips[] = $tmp;
2131
	return $listenips;
2132
}
2133

    
2134
function get_possible_traffic_source_addresses($include_ipv6_link_local=false) {
2135
	global $config;
2136
	$sourceips = get_possible_listen_ips($include_ipv6_link_local);
2137
	foreach (array('server', 'client') as $mode) {
2138
		if (is_array($config['openvpn']["openvpn-{$mode}"])) {
2139
			foreach ($config['openvpn']["openvpn-{$mode}"] as $id => $setting) {
2140
				if (!isset($setting['disable'])) {
2141
					$vpn = array();
2142
					$vpn['value'] = 'ovpn' . substr($mode, 0, 1) . $setting['vpnid'];
2143
					$vpn['name'] = gettext("OpenVPN") . " ".$mode.": ".htmlspecialchars($setting['description']);
2144
					$sourceips[] = $vpn;
2145
				}
2146
			}
2147
		}
2148
	}
2149
	return $sourceips;
2150
}
2151
?>
(52-52/67)