Project

General

Profile

Download (66.9 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
	/* Send the following to the GPS port to initialize the GPS */
1439
	if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['type'])) {
1440
		$gps_init = base64_decode($config['ntpd']['gps']['initcmd']);
1441
	}else{
1442
		$gps_init = base64_decode('JFBVQlgsNDAsR1NWLDAsMCwwLDAqNTkNCiRQVUJYLDQwLEdMTCwwLDAsMCwwKjVDDQokUFVCWCw0MCxaREEsMCwwLDAsMCo0NA0KJFBVQlgsNDAsVlRHLDAsMCwwLDAqNUUNCiRQVUJYLDQwLEdTViwwLDAsMCwwKjU5DQokUFVCWCw0MCxHU0EsMCwwLDAsMCo0RQ0KJFBVQlgsNDAsR0dBLDAsMCwwLDANCiRQVUJYLDQwLFRYVCwwLDAsMCwwDQokUFVCWCw0MCxSTUMsMCwwLDAsMCo0Ng0KJFBVQlgsNDEsMSwwMDA3LDAwMDMsNDgwMCwwDQokUFVCWCw0MCxaREEsMSwxLDEsMQ==');
1443
	}
1444

    
1445
	/* XXX: Why not file_put_contents to the device */
1446
	@file_put_contents('/tmp/gps.init', $gps_init);
1447
	`cat /tmp/gps.init > $serialport`;
1448

    
1449
	/* Add /etc/remote entry in case we need to read from the GPS with tip */
1450
	if (intval(`grep -c '^gps0' /etc/remote`) == 0) {
1451
		$gpsbaud = '4800';
1452
		if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['speed'])) {
1453
			switch($config['ntpd']['gps']['speed']) {
1454
				case '16':
1455
					$gpsbaud = '9600';
1456
					break;
1457
				case '32':
1458
					$gpsbaud = '19200';
1459
					break;
1460
				case '48':
1461
					$gpsbaud = '38400';
1462
					break;
1463
				case '64':
1464
					$gpsbaud = '57600';
1465
					break;
1466
				case '80':
1467
					$gpsbaud = '115200';
1468
					break;
1469
			}
1470
		}
1471
		@file_put_contents("/etc/remote", "gps0:dv={$serialport}:br#{$gpsbaud}:pa=none:", FILE_APPEND);
1472
	}
1473

    
1474
	conf_mount_ro();
1475

    
1476
	return true;
1477
}
1478

    
1479
function system_ntp_setup_pps($serialport) {
1480
	global $config, $g;
1481

    
1482
	$pps_device = '/dev/pps0';
1483
	$serialport = '/dev/'.$serialport;
1484

    
1485
	if (!file_exists($serialport))
1486
		return false;
1487

    
1488
	conf_mount_rw();
1489
	// Create symlink that ntpd requires
1490
	unlink_if_exists($pps_device);
1491
	@symlink($serialport, $pps_device);
1492

    
1493
	conf_mount_ro();
1494

    
1495
	return true;
1496
}
1497

    
1498

    
1499
function system_ntp_configure($start_ntpd=true) {
1500
	global $config, $g;
1501

    
1502
	$driftfile = "/var/db/ntpd.drift";
1503
	$statsdir = "/var/log/ntp";
1504
	$gps_device = '/dev/gps0';
1505

    
1506
	if ($g['platform'] == 'jail')
1507
		return;
1508

    
1509
	safe_mkdir($statsdir);
1510

    
1511
	if (!is_array($config['ntpd']))
1512
		$config['ntpd'] = array();
1513

    
1514
	$ntpcfg = "# \n";
1515
	$ntpcfg .= "# pfSense ntp configuration file \n";
1516
	$ntpcfg .= "# \n\n";
1517
	$ntpcfg .= "tinker panic 0 \n";
1518

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

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

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

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

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

    
1726
	if (empty($config['ntpd']['interface'])) {
1727
		if (is_array($config['installedpackages']['openntpd']) && !empty($config['installedpackages']['openntpd']['config'][0]['interface']))
1728
			$interfaces = explode(",", $config['installedpackages']['openntpd']['config'][0]['interface']);
1729
		else
1730
			$interfaces = array();
1731
	} else
1732
		$interfaces = explode(",", $config['ntpd']['interface']);
1733

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

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

    
1751
	/* At bootup we just want to write out the config. */
1752
	if (!$start_ntpd)
1753
		return;
1754

    
1755
	/* if ntpd is running, kill it */
1756
	while (isvalidpid("{$g['varrun_path']}/ntpd.pid")) {
1757
		killbypid("{$g['varrun_path']}/ntpd.pid");
1758
	}
1759
	@unlink("{$g['varrun_path']}/ntpd.pid");
1760

    
1761
	/* if /var/empty does not exist, create it */
1762
	if(!is_dir("/var/empty"))
1763
		mkdir("/var/empty", 0775, true);
1764

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

    
1773
function sync_system_time() {
1774
	global $config, $g;
1775

    
1776
	if (platform_booting())
1777
		echo gettext("Syncing system time before startup...");
1778

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

    
1789
function system_halt() {
1790
	global $g;
1791

    
1792
	system_reboot_cleanup();
1793

    
1794
	mwexec("/usr/bin/nohup /etc/rc.halt > /dev/null 2>&1 &");
1795
}
1796

    
1797
function system_reboot() {
1798
	global $g;
1799

    
1800
	system_reboot_cleanup();
1801

    
1802
	mwexec("nohup /etc/rc.reboot > /dev/null 2>&1 &");
1803
}
1804

    
1805
function system_reboot_sync() {
1806
	global $g;
1807

    
1808
	system_reboot_cleanup();
1809

    
1810
	mwexec("/etc/rc.reboot > /dev/null 2>&1");
1811
}
1812

    
1813
function system_reboot_cleanup() {
1814
	global $config, $cpzone;
1815

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

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

    
1837
	if ($early)
1838
		$cmdn = "earlyshellcmd";
1839
	else
1840
		$cmdn = "shellcmd";
1841

    
1842
	if (is_array($config['system'][$cmdn])) {
1843

    
1844
		/* *cmd is an array, loop through */
1845
		foreach ($config['system'][$cmdn] as $cmd) {
1846
			exec($cmd);
1847
		}
1848

    
1849
	} elseif($config['system'][$cmdn] <> "") {
1850

    
1851
		/* execute single item */
1852
		exec($config['system'][$cmdn]);
1853

    
1854
	}
1855
}
1856

    
1857
function system_console_configure() {
1858
	global $config, $g;
1859
	if(isset($config['system']['developerspew'])) {
1860
		$mt = microtime();
1861
		echo "system_console_configure() being called $mt\n";
1862
	}
1863

    
1864
	if (isset($config['system']['disableconsolemenu'])) {
1865
		touch("{$g['varetc_path']}/disableconsole");
1866
	} else {
1867
		unlink_if_exists("{$g['varetc_path']}/disableconsole");
1868
	}
1869
}
1870

    
1871
function system_dmesg_save() {
1872
	global $g;
1873
	if(isset($config['system']['developerspew'])) {
1874
		$mt = microtime();
1875
		echo "system_dmesg_save() being called $mt\n";
1876
	}
1877

    
1878
	$dmesg = "";
1879
	$_gb = exec("/sbin/dmesg", $dmesg);
1880

    
1881
	/* find last copyright line (output from previous boots may be present) */
1882
	$lastcpline = 0;
1883

    
1884
	for ($i = 0; $i < count($dmesg); $i++) {
1885
		if (strstr($dmesg[$i], "Copyright (c) 1992-"))
1886
			$lastcpline = $i;
1887
	}
1888

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

    
1895
	for ($i = $lastcpline; $i < count($dmesg); $i++)
1896
		fwrite($fd, $dmesg[$i] . "\n");
1897

    
1898
	fclose($fd);
1899
	unset($dmesg);
1900

    
1901
	return 0;
1902
}
1903

    
1904
function system_set_harddisk_standby() {
1905
	global $g, $config;
1906
	if(isset($config['system']['developerspew'])) {
1907
		$mt = microtime();
1908
		echo "system_set_harddisk_standby() being called $mt\n";
1909
	}
1910

    
1911
	if (isset($config['system']['harddiskstandby'])) {
1912
		if (platform_booting()) {
1913
			echo gettext('Setting hard disk standby... ');
1914
		}
1915

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

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

    
1943
	activate_sysctls();	
1944

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

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

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

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

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

    
1995
	$specplatform = system_identify_specific_platform();
1996

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

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

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

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

    
2020

    
2021
EOD;
2022
		
2023
		reset_factory_defaults();
2024
		system_reboot_sync();
2025
		exit(0);
2026
	}
2027

    
2028
	return 0;
2029
}
2030

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

    
2063
	/* the rest of the code only deals with 'embedded' platforms */
2064
	if ($g['platform'] != 'nanobsd')
2065
		return array('name' => $g['platform'], 'descr' => $g['platform']);
2066

    
2067
	$dmesg = get_single_sysctl('hw.model');
2068

    
2069
	if (strpos($dmesg, "PC Engines WRAP") !== false)
2070
		return array('name' => 'wrap', 'descr' => gettext('PC Engines WRAP'));
2071
	
2072
	if (strpos($dmesg, "PC Engines ALIX") !== false)
2073
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
2074

    
2075
	if (preg_match("/Soekris net45../", $dmesg, $matches))
2076
		return array('name' => 'net45xx', 'descr' => $matches[0]);
2077
	
2078
	if (preg_match("/Soekris net48../", $dmesg, $matches))
2079
		return array('name' => 'net48xx', 'descr' => $matches[0]);
2080
		
2081
	if (preg_match("/Soekris net55../", $dmesg, $matches))
2082
		return array('name' => 'net55xx', 'descr' => $matches[0]);
2083

    
2084
	unset($dmesg);
2085

    
2086
	$dmesg_boot = system_get_dmesg_boot();
2087
	if (strpos($dmesg_boot, "PC Engines ALIX") !== false)
2088
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
2089
	unset($dmesg_boot);
2090

    
2091
	/* unknown embedded platform */
2092
	return array('name' => 'embedded', 'descr' => gettext('embedded (unknown)'));
2093
}
2094

    
2095
function system_get_dmesg_boot() {
2096
	global $g;
2097
		
2098
	return file_get_contents("{$g['varlog_path']}/dmesg.boot");
2099
}
2100

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

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