Project

General

Profile

Download (66.8 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
					mwexec("{$log_create_directive} {$log_size} {$g['varlog_path']}/{$package['logging']['logfilename']}");
766
					$syslogconf .= "!{$package['logging']['facilityname']}\n*.*\t\t\t\t\t\t {$log_directive}{$g['varlog_path']}/{$package['logging']['logfilename']}\n";
767
				}
768
			}
769
		}
770
		$facilitylist = implode(',', array_unique($separatelogfacilities));
771
		$syslogconf .= "!radvd,routed,olsrd,zebra,ospfd,bgpd,miniupnpd\n";
772
		if (!isset($syslogcfg['disablelocallogging']))
773
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/routing.log\n";
774

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
928
	return $retval;
929
}
930

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1008
	sleep(1);
1009

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

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

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

    
1022
	return $res;
1023
}
1024

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

    
1036
	global $config, $g;
1037

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

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

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

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

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

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

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

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

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

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

    
1111

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

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

    
1146
EOD;
1147
	}
1148

    
1149

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

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

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

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

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

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

    
1179
{$lighty_use_syslog}
1180

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

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

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

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

    
1248

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

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

    
1253
EOD;
1254

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

    
1269

    
1270
	$lighty_config .= <<<EOD
1271

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

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

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

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

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

    
1292
{$server_upload_dirs}
1293

    
1294
{$server_max_request_size}
1295

    
1296
{$fastcgi_config}
1297

    
1298
{$cgi_config}
1299

    
1300
{$captive_portal_mod_evasive}
1301

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

    
1306
EOD;
1307

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

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

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

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

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

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

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

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

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

    
1381
	return 0;
1382

    
1383
}
1384

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

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

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

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

    
1412
	conf_mount_rw();
1413

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

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

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

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

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

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

    
1437
	/* Send the following to the GPS port to initialize the GPS */
1438
	if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['type'])) {
1439
		$gps_init = base64_decode($config['ntpd']['gps']['initcmd']);
1440
	}else{
1441
		$gps_init = base64_decode('JFBVQlgsNDAsR1NWLDAsMCwwLDAqNTkNCiRQVUJYLDQwLEdMTCwwLDAsMCwwKjVDDQokUFVCWCw0MCxaREEsMCwwLDAsMCo0NA0KJFBVQlgsNDAsVlRHLDAsMCwwLDAqNUUNCiRQVUJYLDQwLEdTViwwLDAsMCwwKjU5DQokUFVCWCw0MCxHU0EsMCwwLDAsMCo0RQ0KJFBVQlgsNDAsR0dBLDAsMCwwLDANCiRQVUJYLDQwLFRYVCwwLDAsMCwwDQokUFVCWCw0MCxSTUMsMCwwLDAsMCo0Ng0KJFBVQlgsNDEsMSwwMDA3LDAwMDMsNDgwMCwwDQokUFVCWCw0MCxaREEsMSwxLDEsMQ==');
1442
	}
1443

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

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

    
1473
	conf_mount_ro();
1474

    
1475
	return true;
1476
}
1477

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

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

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

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

    
1492
	conf_mount_ro();
1493

    
1494
	return true;
1495
}
1496

    
1497

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

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

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

    
1508
	safe_mkdir($statsdir);
1509

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1791
	system_reboot_cleanup();
1792

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

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

    
1799
	system_reboot_cleanup();
1800

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

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

    
1807
	system_reboot_cleanup();
1808

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

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

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

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

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

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

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

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

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

    
1853
	}
1854
}
1855

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

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

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

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

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

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

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

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

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

    
1900
	return 0;
1901
}
1902

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

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

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

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

    
1942
	activate_sysctls();	
1943

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

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

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

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

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

    
1994
	$specplatform = system_identify_specific_platform();
1995

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

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

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

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

    
2019

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

    
2027
	return 0;
2028
}
2029

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

    
2059
	/* the rest of the code only deals with 'embedded' platforms */
2060
	if ($g['platform'] != 'nanobsd')
2061
		return array('name' => $g['platform'], 'descr' => $g['platform']);
2062

    
2063
	$dmesg = get_single_sysctl('hw.model');
2064

    
2065
	if (strpos($dmesg, "PC Engines WRAP") !== false)
2066
		return array('name' => 'wrap', 'descr' => gettext('PC Engines WRAP'));
2067
	
2068
	if (strpos($dmesg, "PC Engines ALIX") !== false)
2069
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
2070

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

    
2080
	unset($dmesg);
2081

    
2082
	$dmesg_boot = system_get_dmesg_boot();
2083
	if (strpos($dmesg_boot, "PC Engines ALIX") !== false)
2084
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
2085
	unset($dmesg_boot);
2086

    
2087
	/* unknown embedded platform */
2088
	return array('name' => 'embedded', 'descr' => gettext('embedded (unknown)'));
2089
}
2090

    
2091
function system_get_dmesg_boot() {
2092
	global $g;
2093
		
2094
	return file_get_contents("{$g['varlog_path']}/dmesg.boot");
2095
}
2096

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

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