Project

General

Profile

Download (63.2 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 activate_sysctls() {
76
	global $config, $g;
77

    
78
	if ($g['platform'] == 'jail')
79
		return;
80

    
81
	$sysctls = array(
82
		"net.enc.out.ipsec_bpf_mask" => "0x0001",
83
		"net.enc.out.ipsec_filter_mask" => "0x0001",
84
		"net.enc.in.ipsec_bpf_mask" => "0x0002",
85
		"net.enc.in.ipsec_filter_mask" => "0x0002"
86
	);
87

    
88
	if(is_array($config['sysctl'])) {
89
		foreach($config['sysctl']['item'] as $tunable) {
90
			if($tunable['value'] == "default")
91
				$value = get_default_sysctl_value($tunable['tunable']);
92
			else
93
				$value = $tunable['value'];
94

    
95
			$sysctls[$tunable['tunable']] = $value;
96
		}
97
	}
98

    
99
	set_sysctl($sysctls);
100
}
101

    
102
function system_resolvconf_generate($dynupdate = false) {
103
	global $config, $g;
104

    
105
	if(isset($config['system']['developerspew'])) {
106
		$mt = microtime();
107
		echo "system_resolvconf_generate() being called $mt\n";
108
	}
109

    
110
	$syscfg = $config['system'];
111

    
112
	if (((isset($config['dnsmasq']['enable']) && (empty($config['dnsmasq']['interface']) || in_array("lo0", explode(",", $config['dnsmasq']['interface']))))
113
		|| (isset($config['unbound']['enable'])) && (empty($config['unbound']['active_interface']) || in_array("lo0", explode(",", $config['unbound']['active_interface']))))
114
		&& !isset($config['system']['dnslocalhost']))
115
		$resolvconf .= "nameserver 127.0.0.1\n";
116

    
117
	if (isset($syscfg['dnsallowoverride'])) {
118
		/* get dynamically assigned DNS servers (if any) */
119
		$ns = array_unique(get_searchdomains());
120
		foreach($ns as $searchserver) {
121
			if($searchserver)
122
				$resolvconf .= "search {$searchserver}\n";
123
		}
124
		$ns = array_unique(get_nameservers());
125
		foreach($ns as $nameserver) {
126
			if($nameserver)
127
				$resolvconf .= "nameserver $nameserver\n";
128
		}
129
	} else {
130
		// Do not create blank search/domain lines, it can break tools like dig.
131
		if($syscfg['domain'])
132
			$resolvconf = "search {$syscfg['domain']}\n";
133
	}
134
	if (is_array($syscfg['dnsserver'])) {
135
		foreach ($syscfg['dnsserver'] as $ns) {
136
			if ($ns)
137
				$resolvconf .= "nameserver $ns\n";
138
		}
139
	}
140

    
141
	// Add EDNS support
142
	if (isset($config['unbound']['enable']) && isset($config['unbound']['edns']))
143
		$resolvconf .= "options edns0\n";
144

    
145
	$dnslock = lock('resolvconf', LOCK_EX);
146

    
147
	$fd = fopen("{$g['varetc_path']}/resolv.conf", "w");
148
	if (!$fd) {
149
		printf("Error: cannot open resolv.conf in system_resolvconf_generate().\n");
150
		unlock($dnslock);
151
		return 1;
152
	}
153

    
154
	fwrite($fd, $resolvconf);
155
	fclose($fd);
156

    
157
	if (!$g['booting']) {
158
		/* restart dhcpd (nameservers may have changed) */
159
		if (!$dynupdate)
160
			services_dhcpd_configure();
161
	}
162

    
163
	/* setup static routes for DNS servers. */
164
	for ($dnscounter=1; $dnscounter<5; $dnscounter++) {
165
		/* setup static routes for dns servers */
166
		$dnsgw = "dns{$dnscounter}gw";
167
		if (isset($config['system'][$dnsgw])) {
168
			$gwname = $config['system'][$dnsgw];
169
			if (($gwname <> "") && ($gwname <> "none")) {
170
				$gatewayip = lookup_gateway_ip_by_name($gwname);
171
				if (is_ipaddrv4($gatewayip)) {
172
					/* dns server array starts at 0 */
173
					$dnscountermo = $dnscounter - 1;
174
					mwexec("/sbin/route change -host " . $syscfg['dnsserver'][$dnscountermo] . " {$gatewayip}");
175
				}
176
				if (is_ipaddrv6($gatewayip)) {
177
					/* dns server array starts at 0 */
178
					$dnscountermo = $dnscounter - 1;
179
					mwexec("/sbin/route change -host -inet6 " . $syscfg['dnsserver'][$dnscountermo] . " {$gatewayip}");
180
				}
181
			}
182
		}
183
	}
184

    
185
	unlock($dnslock);
186

    
187
	return 0;
188
}
189

    
190
function get_searchdomains() {
191
	global $config, $g;
192

    
193
	$master_list = array();
194
	
195
	// Read in dhclient nameservers
196
	$search_list = glob("/var/etc/searchdomain_*");
197
	if (is_array($search_list)) {
198
		foreach($search_list as $fdns) {
199
			$contents = file($fdns, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
200
			if (!is_array($contents))
201
				continue;
202
			foreach ($contents as $dns) {
203
				if(is_hostname($dns)) 
204
					$master_list[] = $dns;
205
			}
206
		}
207
	}
208

    
209
	return $master_list;
210
}
211

    
212
function get_nameservers() {
213
	global $config, $g;
214
	$master_list = array();
215
	
216
	// Read in dhclient nameservers
217
	$dns_lists = glob("/var/etc/nameserver_*");
218
	if (is_array($dns_lists)) {
219
		foreach($dns_lists as $fdns) {
220
			$contents = file($fdns, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
221
			if (!is_array($contents))
222
				continue;
223
			foreach ($contents as $dns) {
224
				if(is_ipaddr($dns)) 
225
					$master_list[] = $dns;
226
			}
227
		}
228
	}
229

    
230
	// Read in any extra nameservers
231
	if(file_exists("/var/etc/nameservers.conf")) {
232
		$dns_s = file("/var/etc/nameservers.conf", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
233
		if(is_array($dns_s)) {
234
			foreach($dns_s as $dns)
235
				if (is_ipaddr($dns))
236
					$master_list[] = $dns;
237
		}
238
	}
239

    
240
	return $master_list;
241
}
242

    
243
function system_hosts_generate() {
244
	global $config, $g;
245
	if (isset($config['system']['developerspew'])) {
246
		$mt = microtime();
247
		echo "system_hosts_generate() being called $mt\n";
248
	}
249

    
250
	$syscfg = $config['system'];
251
	$dnsmasqcfg = $config['dnsmasq'];
252

    
253
	$hosts = "127.0.0.1	localhost localhost.{$syscfg['domain']}\n";
254
	$lhosts = "";
255
	$dhosts = "";
256

    
257
	if ($config['interfaces']['lan']) {
258
		$cfgip = get_interface_ip("lan");
259
		if (is_ipaddr($cfgip))
260
			$hosts .= "{$cfgip}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
261
	} else {
262
		$sysiflist = get_configured_interface_list();
263
		foreach ($sysiflist as $sysif) {
264
			if (!interface_has_gateway($sysif)) {
265
				$cfgip = get_interface_ip($sysif);
266
				if (is_ipaddr($cfgip)) {
267
					$hosts .= "{$cfgip}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
268
					break;
269
				}
270
			}
271
		}
272
	}
273

    
274
	if (isset($dnsmasqcfg['enable'])) {
275
		if (!is_array($dnsmasqcfg['hosts']))
276
			$dnsmasqcfg['hosts'] = array();
277

    
278
		foreach ($dnsmasqcfg['hosts'] as $host) {
279
			if ($host['host'])
280
				$lhosts .= "{$host['ip']}	{$host['host']}.{$host['domain']} {$host['host']}\n";
281
			else
282
				$lhosts .= "{$host['ip']}	{$host['domain']}\n";
283
			if (!is_array($host['aliases']) || !is_array($host['aliases']['item']))
284
				continue;
285
			foreach ($host['aliases']['item'] as $alias) {
286
				if ($alias['host'])
287
					$lhosts .= "{$host['ip']}	{$alias['host']}.{$alias['domain']} {$alias['host']}\n";
288
				else
289
					$lhosts .= "{$host['ip']}	{$alias['domain']}\n";
290
			}
291
		}
292
		if (isset($dnsmasqcfg['regdhcpstatic']) && is_array($config['dhcpd'])) {
293
			foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf)
294
				if(is_array($dhcpifconf['staticmap']) && isset($dhcpifconf['enable']))
295
						foreach ($dhcpifconf['staticmap'] as $host)
296
							if ($host['ipaddr'] && $host['hostname'] && $host['domain'])
297
								$dhosts .= "{$host['ipaddr']}	{$host['hostname']}.{$host['domain']} {$host['hostname']}\n";
298
							else if ($host['ipaddr'] && $host['hostname'] && $dhcpifconf['domain'])
299
								$dhosts .= "{$host['ipaddr']}	{$host['hostname']}.{$dhcpifconf['domain']} {$host['hostname']}\n";
300
							else if ($host['ipaddr'] && $host['hostname'])
301
								$dhosts .= "{$host['ipaddr']}	{$host['hostname']}.{$syscfg['domain']} {$host['hostname']}\n";
302
		}
303
		if (isset($dnsmasqcfg['regdhcpstatic']) && is_array($config['dhcpdv6'])) {
304
			foreach ($config['dhcpdv6'] as $dhcpif => $dhcpifconf)
305
				if(is_array($dhcpifconf['staticmap']) && isset($dhcpifconf['enable']))
306
						foreach ($dhcpifconf['staticmap'] as $host)
307
							if ($host['ipaddrv6'] && $host['hostname'] && $host['domain'])
308
								$dhosts .= "{$host['ipaddrv6']}	{$host['hostname']}.{$host['domain']} {$host['hostname']}\n";
309
							else if ($host['ipaddrv6'] && $host['hostname'] && $dhcpifconf['domain'])
310
								$dhosts .= "{$host['ipaddrv6']}	{$host['hostname']}.{$dhcpifconf['domain']} {$host['hostname']}\n";
311
							else if ($host['ipaddrv6'] && $host['hostname'])
312
								$dhosts .= "{$host['ipaddrv6']}	{$host['hostname']}.{$syscfg['domain']} {$host['hostname']}\n";
313
		}
314

    
315
		if (isset($dnsmasqcfg['dhcpfirst']))
316
			$hosts .= $dhosts . $lhosts;
317
		else
318
			$hosts .= $lhosts . $dhosts;
319
	}
320

    
321
	/*
322
	 * Do not remove this because dhcpleases monitors with kqueue it needs to be 
323
	 * killed before writing to hosts files.
324
	 */
325
	if (file_exists("{$g['varrun_path']}/dhcpleases.pid")) {
326
		sigkillbypid("{$g['varrun_path']}/dhcpleases.pid", "TERM");
327
		@unlink("{$g['varrun_path']}/dhcpleases.pid");
328
	}
329
	$fd = fopen("{$g['varetc_path']}/hosts", "w");
330
	if (!$fd) {
331
		log_error("Error: cannot open hosts file in system_hosts_generate().\n");
332
		return 1;
333
	}
334
	fwrite($fd, $hosts);
335
	fclose($fd);
336

    
337
	if (isset($config['unbound']['enable'])) {
338
		require_once("unbound.inc");
339
		unbound_hosts_generate();
340
	}
341

    
342
	system_dhcpleases_configure();
343

    
344
	return 0;
345
}
346

    
347
function system_dhcpleases_configure() {
348
	global $config, $g;
349
	
350
	if ($g['platform'] == 'jail')
351
		return;
352
	/* Start the monitoring process for dynamic dhcpclients. */
353
	if ((isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcp'])) 
354
		|| (isset($config['unbound']['enable']) && isset($config['unbound']['regdhcp']))) {
355
		/* Make sure we do not error out */
356
		mwexec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/db");
357
		if (!file_exists("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases"))
358
			@touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
359
		if (isvalidpid("{$g['varrun_path']}/dhcpleases.pid"))
360
			sigkillbypid("{$g['varrun_path']}/dhcpleases.pid", "HUP");
361
		else {
362
			/* To ensure we do not start multiple instances of dhcpleases, perform some clean-up first. */
363
			if (is_process_running("dhcpleases"))
364
				mwexec('/bin/pkill dhcpleases');
365
			@unlink("{$g['varrun_path']}/dhcpleases.pid");
366
			if (isset($config['unbound']['enable']))
367
				$dns_pid = "unbound.pid";
368
			else
369
				$dns_pid = "dnsmasq.pid";
370
			mwexec("/usr/local/sbin/dhcpleases -l {$g['dhcpd_chroot_path']}/var/db/dhcpd.leases -d {$config['system']['domain']} -p {$g['varrun_path']}/{$dns_pid} -h {$g['varetc_path']}/hosts");
371
		}
372
	} else {
373
		sigkillbypid("{$g['varrun_path']}/dhcpleases.pid", "TERM");
374
		@unlink("{$g['varrun_path']}/dhcpleases.pid");
375
	}
376
}
377

    
378
function system_hostname_configure() {
379
	global $config, $g;
380
	if(isset($config['system']['developerspew'])) {
381
		$mt = microtime();
382
		echo "system_hostname_configure() being called $mt\n";
383
	}
384

    
385
	$syscfg = $config['system'];
386

    
387
	/* set hostname */
388
	$status = mwexec("/bin/hostname " .
389
		escapeshellarg("{$syscfg['hostname']}.{$syscfg['domain']}"));
390

    
391
    /* Setup host GUID ID.  This is used by ZFS. */
392
	mwexec("/etc/rc.d/hostid start");
393

    
394
	return $status;
395
}
396

    
397
function system_routing_configure($interface = "") {
398
	global $config, $g;
399
	if ($g['platform'] == 'jail')
400
		return;
401
	if(isset($config['system']['developerspew'])) {
402
		$mt = microtime();
403
		echo "system_routing_configure() being called $mt\n";
404
	}
405

    
406
	$gatewayip = "";
407
	$interfacegw = "";
408
	$gatewayipv6 = "";
409
	$interfacegwv6 = "";
410
	$foundgw = false;
411
	$foundgwv6 = false;
412
	/* tack on all the hard defined gateways as well */
413
	if (is_array($config['gateways']['gateway_item'])) {
414
		array_map('unlink', glob("{$g['tmp_path']}/*_defaultgw{,v6}", GLOB_BRACE));
415
		foreach	($config['gateways']['gateway_item'] as $gateway) {
416
			if (isset($gateway['defaultgw'])) {
417
				if ($foundgw == false && ($gateway['ipprotocol'] != "inet6" && (is_ipaddrv4($gateway['gateway']) || $gateway['gateway'] == "dynamic"))) {
418
					if(strpos($gateway['gateway'], ":"))
419
						continue;
420
					if ($gateway['gateway'] == "dynamic")
421
						$gateway['gateway'] = get_interface_gateway($gateway['interface']);
422
					$gatewayip = $gateway['gateway'];
423
					$interfacegw = $gateway['interface'];
424
					if (!empty($gateway['interface'])) {
425
						$defaultif = get_real_interface($gateway['interface']);
426
						if ($defaultif)
427
							@file_put_contents("{$g['tmp_path']}/{$defaultif}_defaultgw", $gateway['gateway']);
428
					}
429
					$foundgw = true;
430
				} else if ($foundgwv6 == false && ($gateway['ipprotocol'] == "inet6" && (is_ipaddrv6($gateway['gateway']) || $gateway['gateway'] == "dynamic"))) {
431
					if ($gateway['gateway'] == "dynamic")
432
						$gateway['gateway'] = get_interface_gateway_v6($gateway['interface']);
433
					$gatewayipv6 = $gateway['gateway'];
434
					$interfacegwv6 = $gateway['interface'];
435
					if (!empty($gateway['interface'])) {
436
						$defaultifv6 = get_real_interface($gateway['interface']);
437
						if ($defaultifv6)
438
							@file_put_contents("{$g['tmp_path']}/{$defaultifv6}_defaultgwv6", $gateway['gateway']);
439
					}
440
					$foundgwv6 = true;
441
				}
442
			}
443
			if ($foundgw === true && $foundgwv6 === true)
444
				break;
445
		}
446
	}
447
	if ($foundgw == false) {
448
		$defaultif = get_real_interface("wan");
449
		$interfacegw = "wan";
450
		$gatewayip = get_interface_gateway("wan");
451
		@file_put_contents("{$g['tmp_path']}/{$defaultif}_defaultgw", $gatewayip);
452
	}	
453
	if ($foundgwv6 == false) {
454
		$defaultifv6 = get_real_interface("wan");
455
		$interfacegwv6 = "wan";
456
		$gatewayipv6 = get_interface_gateway_v6("wan");
457
		@file_put_contents("{$g['tmp_path']}/{$defaultifv6}_defaultgwv6", $gatewayipv6);
458
	}
459
	$dont_add_route = false;
460
	/* if OLSRD is enabled, allow WAN to house DHCP. */
461
	if (is_array($config['installedpackages']['olsrd'])) {
462
		foreach($config['installedpackages']['olsrd']['config'] as $olsrd) {
463
			if(($olsrd['enabledyngw'] == "on") && ($olsrd['enable'] == "on")) {
464
				$dont_add_route = true;
465
				log_error(sprintf(gettext("Not adding default route because OLSR dynamic gateway is enabled.")));
466
				break;
467
			}
468
		}
469
	}
470

    
471
	if ($dont_add_route == false ) {
472
		if (!empty($interface) && $interface != $interfacegw)
473
			;
474
		else if (is_ipaddrv4($gatewayip)) {
475
			log_error("ROUTING: setting default route to $gatewayip");
476
			mwexec("/sbin/route change -inet default " . escapeshellarg($gatewayip));
477
		}
478

    
479
		if (!empty($interface) && $interface != $interfacegwv6)
480
			;
481
		else if (is_ipaddrv6($gatewayipv6)) {
482
			$ifscope = "";
483
			if (is_linklocal($gatewayipv6))
484
				$ifscope = "%{$defaultifv6}";
485
			log_error("ROUTING: setting IPv6 default route to {$gatewayipv6}{$ifscope}");
486
			mwexec("/sbin/route change -inet6 default " . escapeshellarg("{$gatewayipv6}{$ifscope}"));
487
		}
488
	}
489

    
490
	system_staticroutes_configure($interface, false);
491

    
492
	return 0;
493
}
494

    
495
function system_staticroutes_configure($interface = "", $update_dns = false) {
496
	global $config, $g, $aliastable;
497

    
498
	$filterdns_list = array();
499

    
500
	$static_routes = get_staticroutes(false, true);
501
	if (count($static_routes)) {
502
		$gateways_arr = return_gateways_array(false, true);
503

    
504
		foreach ($static_routes as $rtent) {
505
			if (empty($gateways_arr[$rtent['gateway']])) {
506
				log_error(sprintf(gettext("Static Routes: Gateway IP could not be found for %s"), $rtent['network']));
507
				continue;
508
			}
509
			$gateway = $gateways_arr[$rtent['gateway']];
510
			if (!empty($interface) && $interface != $gateway['friendlyiface'])
511
				continue;
512

    
513
			$gatewayip = $gateway['gateway'];
514
			$interfacegw = $gateway['interface'];
515

    
516
			$blackhole = "";
517
			if (!strcasecmp("Null", substr($rtent['gateway'], 0, 3)))
518
				$blackhole = "-blackhole";
519

    
520
			if (!is_fqdn($rtent['network']) && !is_subnet($rtent['network']))
521
				continue;
522

    
523
			$dnscache = array();
524
			if ($update_dns === true) {
525
				if (is_subnet($rtent['network']))
526
					continue;
527
				$dnscache = explode("\n", trim(compare_hostname_to_dnscache($rtent['network'])));
528
				if (empty($dnscache))
529
					continue;
530
			}
531

    
532
			if (is_subnet($rtent['network']))
533
				$ips = array($rtent['network']);
534
			else {
535
				if (!isset($rtent['disabled']))
536
					$filterdns_list[] = $rtent['network'];
537
				$ips = add_hostname_to_watch($rtent['network']);
538
			}
539

    
540
			foreach ($dnscache as $ip) {
541
				if (in_array($ip, $ips))
542
					continue;
543
				mwexec("/sbin/route delete " . escapeshellarg($ip), true);
544
			}
545

    
546
			if (isset($rtent['disabled'])) {
547
				/* XXX: This can break things by deleting routes that shouldn't be deleted - OpenVPN, dynamic routing scenarios, etc. redmine #3709 */
548
				foreach ($ips as $ip)
549
					mwexec("/sbin/route delete " . escapeshellarg($ip), true);
550
				continue;
551
			}
552

    
553
			foreach ($ips as $ip) {
554
				if (is_ipaddrv4($ip))
555
					$ip .= "/32";
556
				else if (is_ipaddrv6($ip))
557
					$ip .= "/128";
558

    
559
				$inet = (is_subnetv6($ip) ? "-inet6" : "-inet");
560

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

    
563
				if (is_subnet($ip))
564
					if (is_ipaddr($gatewayip))
565
						mwexec($cmd . escapeshellarg($gatewayip));
566
					else if (!empty($interfacegw))
567
						mwexec($cmd . "-iface " . escapeshellarg($interfacegw));
568
			}
569
		}
570
		unset($gateways_arr);
571
	}
572
	unset($static_routes);
573

    
574
	if ($update_dns === false) {
575
		if (count($filterdns_list)) {
576
			$interval = 60;
577
			$hostnames = "";
578
			array_unique($filterdns_list);
579
			foreach ($filterdns_list as $hostname)
580
				$hostnames .= "cmd {$hostname} '/usr/local/sbin/pfSctl -c \"service reload routedns\"'\n";
581
			file_put_contents("{$g['varetc_path']}/filterdns-route.hosts", $hostnames);
582
			unset($hostnames);
583

    
584
			if (isvalidpid("{$g['varrun_path']}/filterdns-route.pid"))
585
				sigkillbypid("{$g['varrun_path']}/filterdns-route.pid", "HUP");
586
			else
587
				mwexec("/usr/local/sbin/filterdns -p {$g['varrun_path']}/filterdns-route.pid -i {$interval} -c {$g['varetc_path']}/filterdns-route.hosts -d 1");
588
		} else {
589
			killbypid("{$g['varrun_path']}/filterdns-route.pid");
590
			@unlink("{$g['varrun_path']}/filterdns-route.pid");
591
		}
592
	}
593
	unset($filterdns_list);
594

    
595
	return 0;
596
}
597

    
598
function system_routing_enable() {
599
	global $config, $g;
600
	if(isset($config['system']['developerspew'])) {
601
		$mt = microtime();
602
		echo "system_routing_enable() being called $mt\n";
603
	}
604

    
605
	set_sysctl(array(
606
		"net.inet.ip.forwarding" => "1",
607
		"net.inet6.ip6.forwarding" => "1"
608
	));
609

    
610
	return;
611
}
612

    
613
function system_syslogd_fixup_server($server) {
614
	/* If it's an IPv6 IP alone, encase it in brackets */
615
	if (is_ipaddrv6($server))
616
		return "[$server]";
617
	else
618
		return $server;
619
}
620

    
621
function system_syslogd_get_remote_servers($syslogcfg, $facility = "*.*") {
622
	// Rather than repeatedly use the same code, use this function to build a list of remote servers.
623
	$facility .= " ".
624
	$remote_servers = "";
625
	$pad_to  = 56;
626
	$padding = ceil(($pad_to - strlen($facility))/8)+1;
627
	if($syslogcfg['remoteserver'])
628
		$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver']) . "\n";
629
	if($syslogcfg['remoteserver2'])
630
		$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver2']) . "\n";
631
	if($syslogcfg['remoteserver3'])
632
		$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver3']) . "\n";
633
	return $remote_servers;
634
}
635

    
636
function system_syslogd_start() {
637
	global $config, $g;
638
	if(isset($config['system']['developerspew'])) {
639
		$mt = microtime();
640
		echo "system_syslogd_start() being called $mt\n";
641
	}
642

    
643
	mwexec("/etc/rc.d/hostid start");
644

    
645
	$syslogcfg = $config['syslog'];
646

    
647
	if ($g['booting'])
648
		echo gettext("Starting syslog...");
649

    
650
	if (is_process_running("fifolog_writer"))
651
		mwexec('/bin/pkill fifolog_writer');
652

    
653
	// Which logging type are we using this week??
654
	if (isset($config['system']['disablesyslogclog'])) {
655
		$log_directive = "";
656
		$log_create_directive = "/usr/bin/touch ";
657
		$log_size = "";
658
	} else if (isset($config['system']['usefifolog'])) {
659
		$log_directive = "|/usr/sbin/fifolog_writer ";
660
		$log_size = isset($config['syslog']['logfilesize']) ? $config['syslog']['logfilesize'] : "10240";
661
		$log_create_directive = "/usr/sbin/fifolog_create -s ";
662
	} else { // Defaults to CLOG
663
		$log_directive = "%";
664
		$log_size = isset($config['syslog']['logfilesize']) ? $config['syslog']['logfilesize'] : "10240";
665
		$log_create_directive = "/usr/local/sbin/clog -i -s ";
666
	}
667

    
668
	$syslogd_extra = "";
669
	if (isset($syslogcfg)) {
670
		$separatelogfacilities = array('ntp','ntpd','ntpdate','charon','openvpn','pptps','poes','l2tps','relayd','hostapd','dnsmasq','filterdns','unbound','dhcpd','dhcrelay','dhclient','dhcp6c','apinger','radvd','routed','olsrd','zebra','ospfd','bgpd','miniupnpd','filterlog');
671
		$syslogconf = "";
672
		if($config['installedpackages']['package']) {
673
			foreach($config['installedpackages']['package'] as $package) {
674
				if($package['logging']) {
675
					array_push($separatelogfacilities, $package['logging']['facilityname']);
676
					mwexec("{$log_create_directive} {$log_size} {$g['varlog_path']}/{$package['logging']['logfilename']}");
677
					$syslogconf .= "!{$package['logging']['facilityname']}\n*.*\t\t\t\t\t\t {$log_directive}{$g['varlog_path']}/{$package['logging']['logfilename']}\n";
678
				}
679
			}
680
		}
681
		$facilitylist = implode(',', array_unique($separatelogfacilities));
682
		$syslogconf .= "!radvd,routed,olsrd,zebra,ospfd,bgpd,miniupnpd\n";
683
		if (!isset($syslogcfg['disablelocallogging']))
684
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/routing.log\n";
685

    
686
		$syslogconf .= "!ntp,ntpd,ntpdate\n";
687
		if (!isset($syslogcfg['disablelocallogging'])) 
688
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ntpd.log\n";
689

    
690
		$syslogconf .= "!ppp\n";
691
		if (!isset($syslogcfg['disablelocallogging'])) 
692
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ppp.log\n";
693

    
694
		$syslogconf .= "!pptps\n";
695
		if (!isset($syslogcfg['disablelocallogging'])) 
696
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/pptps.log\n";
697

    
698
		$syslogconf .= "!poes\n";
699
		if (!isset($syslogcfg['disablelocallogging'])) 
700
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/poes.log\n";
701

    
702
		$syslogconf .= "!l2tps\n";
703
		if (!isset($syslogcfg['disablelocallogging'])) 
704
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/l2tps.log\n";
705

    
706
		$syslogconf .= "!charon\n";
707
		if (!isset($syslogcfg['disablelocallogging'])) 
708
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ipsec.log\n";
709
		if (isset($syslogcfg['vpn']))
710
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
711

    
712
		$syslogconf .= "!openvpn\n";
713
		if (!isset($syslogcfg['disablelocallogging'])) 
714
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/openvpn.log\n";
715
		if (isset($syslogcfg['vpn']))
716
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
717

    
718
		$syslogconf .= "!apinger\n";
719
		if (!isset($syslogcfg['disablelocallogging']))
720
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/gateways.log\n";
721
		if (isset($syslogcfg['apinger']))
722
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
723

    
724
		$syslogconf .= "!dnsmasq,filterdns,unbound\n";
725
		if (!isset($syslogcfg['disablelocallogging']))
726
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/resolver.log\n";
727

    
728
		$syslogconf .= "!dhcpd,dhcrelay,dhclient,dhcp6c\n";
729
		if (!isset($syslogcfg['disablelocallogging']))
730
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/dhcpd.log\n";
731
		if (isset($syslogcfg['dhcp']))
732
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
733

    
734
		$syslogconf .= "!relayd\n";
735
		if (!isset($syslogcfg['disablelocallogging']))
736
			$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/relayd.log\n";
737
		if (isset($syslogcfg['relayd']))
738
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
739

    
740
		$syslogconf .= "!hostapd\n";
741
		if (!isset($syslogcfg['disablelocallogging']))
742
			$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/wireless.log\n";
743
		if (isset($syslogcfg['hostapd']))
744
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
745

    
746
		$syslogconf .= "!filterlog\n";
747
		$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/filter.log\n";
748
		if (isset($syslogcfg['filter']))
749
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
750

    
751
		$syslogconf .= "!-{$facilitylist}\n";
752
		if (!isset($syslogcfg['disablelocallogging'])) 
753
			$syslogconf .= <<<EOD
754
local3.*							{$log_directive}{$g['varlog_path']}/vpn.log
755
local4.*							{$log_directive}{$g['varlog_path']}/portalauth.log
756
local7.*							{$log_directive}{$g['varlog_path']}/dhcpd.log
757
*.notice;kern.debug;lpr.info;mail.crit;daemon.none;		{$log_directive}{$g['varlog_path']}/system.log
758
news.err;local0.none;local3.none;local4.none;			{$log_directive}{$g['varlog_path']}/system.log
759
local7.none							{$log_directive}{$g['varlog_path']}/system.log
760
security.*							{$log_directive}{$g['varlog_path']}/system.log
761
auth.info;authpriv.info;daemon.info				{$log_directive}{$g['varlog_path']}/system.log
762
auth.info;authpriv.info 					|exec /usr/local/sbin/sshlockout_pf 15
763
*.emerg								*
764

    
765
EOD;
766
		if (isset($syslogcfg['vpn']))
767
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local3.*");
768
		if (isset($syslogcfg['portalauth']))
769
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local4.*");
770
		if (isset($syslogcfg['dhcp']))
771
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local7.*");
772
		if (isset($syslogcfg['system'])) {
773
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.notice;kern.debug;lpr.info;mail.crit;");
774
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "news.err;local0.none;local3.none;local7.none");
775
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "security.*");
776
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "auth.info;authpriv.info;daemon.info");
777
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.emerg");
778
		}
779
		if (isset($syslogcfg['logall'])) {
780
			// Make everything mean everything, including facilities excluded above.
781
			$syslogconf .= "!*\n";
782
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
783
		}
784

    
785
		if (isset($syslogcfg['zmqserver'])) {
786
				$syslogconf .= <<<EOD
787
*.*								^{$syslogcfg['zmqserver']}
788

    
789
EOD;
790
		}
791
		/* write syslog.conf */		
792
		if (!@file_put_contents("{$g['varetc_path']}/syslog.conf", $syslogconf)) {
793
			printf(gettext("Error: cannot open syslog.conf in system_syslogd_start().%s"), "\n");
794
			unset($syslogconf);
795
			return 1;
796
		}
797
		unset($syslogconf);
798

    
799
		// Ensure that the log directory exists
800
		if (!is_dir("{$g['dhcpd_chroot_path']}/var/run"))
801
			exec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/run");
802

    
803
		$sourceip = "";
804
		if (!empty($syslogcfg['sourceip'])) {
805
			if ($syslogcfg['ipproto'] == "ipv6") {
806
				$ifaddr = is_ipaddr($syslogcfg['sourceip']) ? $syslogcfg['sourceip'] : get_interface_ipv6($syslogcfg['sourceip']);
807
				if (!is_ipaddr($ifaddr))
808
					$ifaddr = get_interface_ip($syslogcfg['sourceip']);
809
			} else {
810
				$ifaddr = is_ipaddr($syslogcfg['sourceip']) ? $syslogcfg['sourceip'] : get_interface_ip($syslogcfg['sourceip']);
811
				if (!is_ipaddr($ifaddr))
812
					$ifaddr = get_interface_ipv6($syslogcfg['sourceip']);
813
			}
814
			if (is_ipaddr($ifaddr)) {
815
				$sourceip = "-b {$ifaddr}";
816
			}
817
		}
818

    
819
		$syslogd_extra = "-f {$g['varetc_path']}/syslog.conf {$sourceip}";
820
	}
821

    
822
	if (isvalidpid("{$g['varrun_path']}/syslog.pid"))
823
		sigkillbypid("{$g['varrun_path']}/syslog.pid", "HUP");
824
	else
825
		$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}");
826

    
827
	if ($g['booting'])
828
		echo gettext("done.") . "\n";
829

    
830
	return $retval;
831
}
832

    
833
function system_webgui_create_certificate() {
834
	global $config, $g;
835

    
836
	if (!is_array($config['ca']))
837
		$config['ca'] = array();
838
	$a_ca =& $config['ca'];
839
	if (!is_array($config['cert']))
840
		$config['cert'] = array();
841
	$a_cert =& $config['cert'];
842
	log_error("Creating SSL Certificate for this host");
843

    
844
	$cert = array();
845
	$cert['refid'] = uniqid();
846
	$cert['descr'] = gettext("webConfigurator default ({$cert['refid']})");
847

    
848
	$dn = array(
849
		'countryName' => "US",
850
		'stateOrProvinceName' => "State",
851
		'localityName' => "Locality",
852
		'organizationName' => "{$g['product_name']} webConfigurator Self-Signed Certificate",
853
		'emailAddress' => "admin@{$config['system']['hostname']}.{$config['system']['domain']}",
854
		'commonName' => "{$config['system']['hostname']}-{$cert['refid']}");
855
	$old_err_level = error_reporting(0); /* otherwise openssl_ functions throw warings directly to a page screwing menu tab */
856
	if (!cert_create($cert, null, 2048, 2000, $dn, "self-signed", "sha256")){
857
		while($ssl_err = openssl_error_string()){
858
			log_error("Error creating WebGUI Certificate: openssl library returns: " . $ssl_err);
859
		}
860
		error_reporting($old_err_level);
861
		return null;
862
	}
863
	error_reporting($old_err_level);
864

    
865
	$a_cert[] = $cert;
866
	$config['system']['webgui']['ssl-certref'] = $cert['refid'];
867
	write_config(gettext("Generated new self-signed HTTPS certificate ({$cert['refid']})"));
868
	return $cert;
869
}
870

    
871
function system_webgui_start() {
872
	global $config, $g;
873

    
874
	if ($g['booting'])
875
		echo gettext("Starting webConfigurator...");
876

    
877
	chdir($g['www_path']);
878

    
879
	/* defaults */
880
	$portarg = "80";
881
	$crt = "";
882
	$key = "";
883
	$ca = "";
884

    
885
	/* non-standard port? */
886
	if (isset($config['system']['webgui']['port']) && $config['system']['webgui']['port'] <> "")
887
		$portarg = "{$config['system']['webgui']['port']}";
888

    
889
	if ($config['system']['webgui']['protocol'] == "https") {
890
		// Ensure that we have a webConfigurator CERT
891
		$cert =& lookup_cert($config['system']['webgui']['ssl-certref']);
892
		if(!is_array($cert) || !$cert['crt'] || !$cert['prv'])
893
			$cert = system_webgui_create_certificate();
894
		$crt = base64_decode($cert['crt']);
895
		$key = base64_decode($cert['prv']);
896

    
897
		if(!$config['system']['webgui']['port'])
898
			$portarg = "443";
899
		$ca  = ca_chain($cert);
900
	}
901

    
902
	/* generate lighttpd configuration */
903
	system_generate_lighty_config("{$g['varetc_path']}/lighty-webConfigurator.conf",
904
		$crt, $key, $ca, "lighty-webConfigurator.pid", $portarg, "/usr/local/www/",
905
		"cert.pem", "ca.pem");
906

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

    
910
	sleep(1);
911

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

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

    
917
	if ($g['booting']) {
918
		if ($res == 0)
919
			echo gettext("done.") . "\n";
920
		else
921
			echo gettext("failed!") . "\n";
922
	}
923

    
924
	return $res;
925
}
926

    
927
function system_generate_lighty_config($filename,
928
	$cert,
929
	$key,
930
	$ca,
931
	$pid_file,
932
	$port = 80,
933
	$document_root = "/usr/local/www/",
934
	$cert_location = "cert.pem",
935
	$ca_location = "ca.pem",
936
	$captive_portal = false) {
937

    
938
	global $config, $g;
939

    
940
	if(!is_dir("{$g['tmp_path']}/lighttpdcompress"))
941
		mkdir("{$g['tmp_path']}/lighttpdcompress");
942

    
943
	if(isset($config['system']['developerspew'])) {
944
		$mt = microtime();
945
		echo "system_generate_lighty_config() being called $mt\n";
946
	}
947

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

    
952
		$maxprocperip = $config['captiveportal'][$captive_portal]['maxprocperip'];
953
		if (empty($maxprocperip))
954
			$maxprocperip = 10;
955
		$captive_portal_mod_evasive = "evasive.max-conns-per-ip = {$maxprocperip}";
956

    
957
		$server_upload_dirs = "server.upload-dirs = ( \"{$g['tmp_path']}/captiveportal/\" )\n";
958
		if(!is_dir("{$g['tmp_path']}/captiveportal"))
959
			@mkdir("{$g['tmp_path']}/captiveportal", 0555);
960
		$server_max_request_size = "server.max-request-size    = 384";
961
		$cgi_config = "";
962
	} else {
963
		$captiveportal = ",\"mod_cgi\"";
964
		$captive_portal_rewrite = "";
965
		$captive_portal_mod_evasive = "";
966
		$server_upload_dirs = "server.upload-dirs = ( \"{$g['upload_path']}/\", \"{$g['tmp_path']}/\", \"/var/\" )\n";
967
		$server_max_request_size = "server.max-request-size    = 2097152";
968
		$cgi_config = "cgi.assign                 = ( \".cgi\" => \"\" )";
969
	}
970
	
971
	if (empty($port))
972
		$lighty_port = "80";
973
	else
974
		$lighty_port = $port;
975

    
976
	$memory = get_memory();
977
	$realmem = $memory[1];
978

    
979
	// Determine web GUI process settings and take into account low memory systems
980
	if ($realmem < 255)
981
		$max_procs = 1;
982
	else
983
		$max_procs = ($config['system']['webgui']['max_procs']) ? $config['system']['webgui']['max_procs'] : 2;
984

    
985
	// Ramp up captive portal max procs, assuming each PHP process can consume up to 64MB RAM 
986
	if ($captive_portal !== false)  {
987
		if ($realmem > 135 and $realmem < 256) {
988
			$max_procs += 1; // 2 worker processes
989
		} else if ($realmem > 255 and $realmem < 513) {
990
			$max_procs += 2; // 3 worker processes
991
		} else if ($realmem > 512) {
992
			$max_procs += 4; // 6 worker processes
993
		}
994
		if ($max_procs > 1)
995
			$max_php_children = intval($max_procs/2);
996
		else
997
			$max_php_children = 1;
998

    
999
	} else {
1000
		if ($realmem < 78)
1001
			$max_php_children = 0;
1002
		else
1003
			$max_php_children = 1;
1004
	}
1005

    
1006
	if(!isset($config['syslog']['nologlighttpd'])) {
1007
		$lighty_use_syslog = <<<EOD
1008
## where to send error-messages to
1009
server.errorlog-use-syslog="enable"
1010
EOD;
1011
	}
1012

    
1013

    
1014
	if ($captive_portal !== false) {
1015
		$fast_cgi_path = "{$g['tmp_path']}/php-fastcgi-{$captive_portal}.socket";
1016
		$fastcgi_config = <<<EOD
1017
#### fastcgi module
1018
## read fastcgi.txt for more info
1019
fastcgi.server = ( ".php" =>
1020
	( "localhost" =>
1021
		(
1022
			"socket" => "{$fast_cgi_path}",
1023
			"max-procs" => {$max_procs},
1024
			"bin-environment" => (
1025
				"PHP_FCGI_CHILDREN" => "{$max_php_children}",
1026
				"PHP_FCGI_MAX_REQUESTS" => "500"
1027
			),
1028
			"bin-path" => "/usr/local/bin/php"
1029
		)
1030
	)
1031
)
1032

    
1033
EOD;
1034
	} else {
1035
		$fast_cgi_path = "{$g['varrun_path']}/php-fpm.socket";
1036
		$fastcgi_config = <<<EOD
1037
#### fastcgi module
1038
## read fastcgi.txt for more info
1039
fastcgi.server = ( ".php" =>
1040
	( "localhost" =>
1041
		(
1042
			"socket" => "{$fast_cgi_path}",
1043
			"broken-scriptfilename" => "enable"
1044
		)
1045
	)
1046
)
1047

    
1048
EOD;
1049
	}
1050

    
1051

    
1052
	$lighty_config = <<<EOD
1053
#
1054
# lighttpd configuration file
1055
#
1056
# use a it as base for lighttpd 1.0.0 and above
1057
#
1058
############ Options you really have to take care of ####################
1059

    
1060
## FreeBSD!
1061
server.event-handler	= "freebsd-kqueue"
1062
server.network-backend 	= "writev"
1063
#server.use-ipv6 = "enable"
1064

    
1065
## modules to load
1066
server.modules              =   ( "mod_access", "mod_expire", "mod_compress", "mod_redirect",
1067
	{$captiveportal}, "mod_fastcgi"
1068
)
1069

    
1070
server.max-keep-alive-requests = 15
1071
server.max-keep-alive-idle = 30
1072

    
1073
## a static document-root, for virtual-hosting take look at the
1074
## server.virtual-* options
1075
server.document-root        = "{$document_root}"
1076
{$captive_portal_rewrite}
1077

    
1078
# Maximum idle time with nothing being written (php downloading)
1079
server.max-write-idle = 999
1080

    
1081
{$lighty_use_syslog}
1082

    
1083
# files to check for if .../ is requested
1084
server.indexfiles           = ( "index.php", "index.html",
1085
                                "index.htm", "default.htm" )
1086

    
1087
# mimetype mapping
1088
mimetype.assign             = (
1089
  ".pdf"          =>      "application/pdf",
1090
  ".sig"          =>      "application/pgp-signature",
1091
  ".spl"          =>      "application/futuresplash",
1092
  ".class"        =>      "application/octet-stream",
1093
  ".ps"           =>      "application/postscript",
1094
  ".torrent"      =>      "application/x-bittorrent",
1095
  ".dvi"          =>      "application/x-dvi",
1096
  ".gz"           =>      "application/x-gzip",
1097
  ".pac"          =>      "application/x-ns-proxy-autoconfig",
1098
  ".swf"          =>      "application/x-shockwave-flash",
1099
  ".tar.gz"       =>      "application/x-tgz",
1100
  ".tgz"          =>      "application/x-tgz",
1101
  ".tar"          =>      "application/x-tar",
1102
  ".zip"          =>      "application/zip",
1103
  ".mp3"          =>      "audio/mpeg",
1104
  ".m3u"          =>      "audio/x-mpegurl",
1105
  ".wma"          =>      "audio/x-ms-wma",
1106
  ".wax"          =>      "audio/x-ms-wax",
1107
  ".ogg"          =>      "audio/x-wav",
1108
  ".wav"          =>      "audio/x-wav",
1109
  ".gif"          =>      "image/gif",
1110
  ".jpg"          =>      "image/jpeg",
1111
  ".jpeg"         =>      "image/jpeg",
1112
  ".png"          =>      "image/png",
1113
  ".xbm"          =>      "image/x-xbitmap",
1114
  ".xpm"          =>      "image/x-xpixmap",
1115
  ".xwd"          =>      "image/x-xwindowdump",
1116
  ".css"          =>      "text/css",
1117
  ".html"         =>      "text/html",
1118
  ".htm"          =>      "text/html",
1119
  ".js"           =>      "text/javascript",
1120
  ".asc"          =>      "text/plain",
1121
  ".c"            =>      "text/plain",
1122
  ".conf"         =>      "text/plain",
1123
  ".text"         =>      "text/plain",
1124
  ".txt"          =>      "text/plain",
1125
  ".dtd"          =>      "text/xml",
1126
  ".xml"          =>      "text/xml",
1127
  ".mpeg"         =>      "video/mpeg",
1128
  ".mpg"          =>      "video/mpeg",
1129
  ".mov"          =>      "video/quicktime",
1130
  ".qt"           =>      "video/quicktime",
1131
  ".avi"          =>      "video/x-msvideo",
1132
  ".asf"          =>      "video/x-ms-asf",
1133
  ".asx"          =>      "video/x-ms-asf",
1134
  ".wmv"          =>      "video/x-ms-wmv",
1135
  ".bz2"          =>      "application/x-bzip",
1136
  ".tbz"          =>      "application/x-bzip-compressed-tar",
1137
  ".tar.bz2"      =>      "application/x-bzip-compressed-tar"
1138
 )
1139

    
1140
# Use the "Content-Type" extended attribute to obtain mime type if possible
1141
#mimetypes.use-xattr        = "enable"
1142

    
1143
## deny access the file-extensions
1144
#
1145
# ~    is for backupfiles from vi, emacs, joe, ...
1146
# .inc is often used for code includes which should in general not be part
1147
#      of the document-root
1148
url.access-deny             = ( "~", ".inc" )
1149

    
1150

    
1151
######### Options that are good to be but not neccesary to be changed #######
1152

    
1153
## bind to port (default: 80)
1154

    
1155
EOD;
1156

    
1157
	$lighty_config .= "server.bind  = \"0.0.0.0\"\n";
1158
	$lighty_config .= "server.port  = {$lighty_port}\n";
1159
	$lighty_config .= "\$SERVER[\"socket\"]  == \"0.0.0.0:{$lighty_port}\" { }\n";
1160
	$lighty_config .= "\$SERVER[\"socket\"]  == \"[::]:{$lighty_port}\" { \n";
1161
	if($cert <> "" and $key <> "") {
1162
		$lighty_config .= "\n";
1163
		$lighty_config .= "## ssl configuration\n";
1164
		$lighty_config .= "ssl.engine = \"enable\"\n";
1165
		$lighty_config .= "ssl.pemfile = \"{$g['varetc_path']}/{$cert_location}\"\n\n";
1166
		if($ca <> "")
1167
			$lighty_config .= "ssl.ca-file = \"{$g['varetc_path']}/{$ca_location}\"\n\n";
1168
	}
1169
	$lighty_config .= " }\n";
1170

    
1171

    
1172
	$lighty_config .= <<<EOD
1173

    
1174
## error-handler for status 404
1175
#server.error-handler-404   = "/error-handler.html"
1176
#server.error-handler-404   = "/error-handler.php"
1177

    
1178
## to help the rc.scripts
1179
server.pid-file            = "{$g['varrun_path']}/{$pid_file}"
1180

    
1181
## virtual directory listings
1182
server.dir-listing         = "disable"
1183

    
1184
## enable debugging
1185
debug.log-request-header   = "disable"
1186
debug.log-response-header  = "disable"
1187
debug.log-request-handling = "disable"
1188
debug.log-file-not-found   = "disable"
1189

    
1190
# gzip compression
1191
compress.cache-dir = "{$g['tmp_path']}/lighttpdcompress/"
1192
compress.filetype  = ("text/plain","text/css", "text/xml", "text/javascript" )
1193

    
1194
{$server_upload_dirs}
1195

    
1196
{$server_max_request_size}
1197

    
1198
{$fastcgi_config}
1199

    
1200
{$cgi_config}
1201

    
1202
{$captive_portal_mod_evasive}
1203

    
1204
expire.url = (
1205
				"" => "access 50 hours",	
1206
        )
1207

    
1208
EOD;
1209

    
1210
	$cert = str_replace("\r", "", $cert);
1211
	$key = str_replace("\r", "", $key);
1212
	$ca = str_replace("\r", "", $ca);
1213

    
1214
	$cert = str_replace("\n\n", "\n", $cert);
1215
	$key = str_replace("\n\n", "\n", $key);
1216
	$ca = str_replace("\n\n", "\n", $ca);
1217

    
1218
	if($cert <> "" and $key <> "") {
1219
		$fd = fopen("{$g['varetc_path']}/{$cert_location}", "w");
1220
		if (!$fd) {
1221
			printf(gettext("Error: cannot open cert.pem in system_webgui_start().%s"), "\n");
1222
			return 1;
1223
		}
1224
		chmod("{$g['varetc_path']}/{$cert_location}", 0600);
1225
		fwrite($fd, $cert);
1226
		fwrite($fd, "\n");
1227
		fwrite($fd, $key);
1228
		fclose($fd);
1229
		if(!(empty($ca) || (strlen(trim($ca)) == 0))) {
1230
			$fd = fopen("{$g['varetc_path']}/{$ca_location}", "w");
1231
			if (!$fd) {
1232
				printf(gettext("Error: cannot open ca.pem in system_webgui_start().%s"), "\n");
1233
				return 1;
1234
			}
1235
			chmod("{$g['varetc_path']}/{$ca_location}", 0600);
1236
			fwrite($fd, $ca);
1237
			fclose($fd);
1238
		}
1239
		$lighty_config .= "\n";
1240
		$lighty_config .= "## " . gettext("ssl configuration") . "\n";
1241
		$lighty_config .= "ssl.engine = \"enable\"\n";
1242
		$lighty_config .= "ssl.pemfile = \"{$g['varetc_path']}/{$cert_location}\"\n\n";
1243

    
1244
		// SSLv2/3 is deprecated, force use of TLS
1245
		$lighty_config .= "ssl.use-sslv2 = \"disable\"\n";
1246
		$lighty_config .= "ssl.use-sslv3 = \"disable\"\n";
1247

    
1248
		/* Hifn accelerators do NOT work with the BEAST mitigation code. Do not allow it to be enabled if a Hifn card has been detected. */
1249
		$fd = @fopen("{$g['varlog_path']}/dmesg.boot", "r");
1250
		if ($fd) {
1251
			while (!feof($fd)) {
1252
				$dmesgl = fgets($fd);
1253
				if (preg_match("/^hifn.: (.*?),/", $dmesgl, $matches) && isset($config['system']['webgui']['beast_protection'])) {
1254
						unset($config['system']['webgui']['beast_protection']);
1255
						log_error("BEAST Protection disabled because a conflicting cryptographic accelerator card has been detected (" . $matches[1] . ")");
1256
					break;
1257
				}
1258
			}
1259
			fclose($fd);
1260
		}
1261

    
1262
		if (isset($config['system']['webgui']['beast_protection'])) {
1263
			$lighty_config .= "ssl.honor-cipher-order = \"enable\"\n";
1264
			$lighty_config .= "ssl.cipher-list = \"ECDHE-RSA-AES256-SHA384:AES256-SHA256:RC4-SHA:RC4:HIGH:!MD5:!aNULL:!EDH:!AESGCM\"\n";
1265
		} else {
1266
			$lighty_config .= "ssl.cipher-list = \"DHE-RSA-CAMELLIA256-SHA:DHE-DSS-CAMELLIA256-SHA:CAMELLIA256-SHA:DHE-DSS-AES256-SHA:AES256-SHA:DHE-RSA-CAMELLIA128-SHA:DHE-DSS-CAMELLIA128-SHA:CAMELLIA128-SHA:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA:AES128-SHA:RC4-SHA:RC4-MD5:!aNULL:!eNULL:!3DES:@STRENGTH\"\n";
1267
		}
1268

    
1269
		if(!(empty($ca) || (strlen(trim($ca)) == 0)))
1270
			$lighty_config .= "ssl.ca-file = \"{$g['varetc_path']}/{$ca_location}\"\n\n";
1271
	}
1272

    
1273
	// Add HTTP to HTTPS redirect	
1274
	if ($captive_portal === false && $config['system']['webgui']['protocol'] == "https" && !isset($config['system']['webgui']['disablehttpredirect'])) {
1275
		if($lighty_port != "443") 
1276
			$redirectport = ":{$lighty_port}";
1277
		$lighty_config .= <<<EOD
1278
\$SERVER["socket"] == ":80" {
1279
	\$HTTP["host"] =~ "(.*)" {
1280
		url.redirect = ( "^/(.*)" => "https://%1{$redirectport}/$1" )
1281
	}
1282
}
1283
\$SERVER["socket"] == "[::]:80" {
1284
	\$HTTP["host"] =~ "(.*)" {
1285
		url.redirect = ( "^/(.*)" => "https://%1{$redirectport}/$1" )
1286
	}
1287
}
1288
EOD;
1289
	}
1290

    
1291
	$fd = fopen("{$filename}", "w");
1292
	if (!$fd) {
1293
		printf(gettext("Error: cannot open %s in system_generate_lighty_config().%s"), $filename, "\n");
1294
		return 1;
1295
	}
1296
	fwrite($fd, $lighty_config);
1297
	fclose($fd);
1298

    
1299
	return 0;
1300

    
1301
}
1302

    
1303
function system_timezone_configure() {
1304
	global $config, $g;
1305
	if(isset($config['system']['developerspew'])) {
1306
		$mt = microtime();
1307
		echo "system_timezone_configure() being called $mt\n";
1308
	}
1309

    
1310
	$syscfg = $config['system'];
1311

    
1312
	if ($g['booting'])
1313
		echo gettext("Setting timezone...");
1314

    
1315
	/* extract appropriate timezone file */
1316
	$timezone = $syscfg['timezone'];
1317
	if ($timezone) {
1318
		exec('/usr/bin/tar -tvzf /usr/share/zoneinfo.tgz', $tzs);
1319
		foreach ($tzs as $tz) {
1320
			if (preg_match(",{$timezone}$,", $tz))
1321
				break;
1322
			if (preg_match(",{$timezone} link to *(.*)$,", $tz, $matches)) {
1323
				$timezone = $matches[1];
1324
				break;
1325
			}
1326
		}
1327
	} else
1328
		$timezone = "Etc/UTC";
1329

    
1330
	conf_mount_rw();
1331

    
1332
	exec("LANG=C /usr/bin/tar xzfO /usr/share/zoneinfo.tgz " .
1333
		escapeshellarg($timezone) . " > /etc/localtime");
1334

    
1335
	mwexec("sync");
1336
	conf_mount_ro();
1337

    
1338
	if ($g['booting'])
1339
		echo gettext("done.") . "\n";
1340
}
1341

    
1342
function system_ntp_setup_gps($serialport) {
1343
	global $config, $g;
1344
	$gps_device = '/dev/gps0';
1345
	$serialport = '/dev/'.$serialport;
1346

    
1347
	if (!file_exists($serialport))
1348
		return false;
1349

    
1350
	conf_mount_rw();
1351
	// Create symlink that ntpd requires
1352
	unlink_if_exists($gps_device);
1353
	symlink($serialport, $gps_device);
1354

    
1355
	/* Send the following to the GPS port to initialize the GPS */
1356
	if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['type'])) {
1357
		$gps_init = base64_decode($config['ntpd']['gps']['initcmd']);
1358
	}else{
1359
		$gps_init = base64_decode('JFBVQlgsNDAsR1NWLDAsMCwwLDAqNTkNCiRQVUJYLDQwLEdMTCwwLDAsMCwwKjVDDQokUFVCWCw0MCxaREEsMCwwLDAsMCo0NA0KJFBVQlgsNDAsVlRHLDAsMCwwLDAqNUUNCiRQVUJYLDQwLEdTViwwLDAsMCwwKjU5DQokUFVCWCw0MCxHU0EsMCwwLDAsMCo0RQ0KJFBVQlgsNDAsR0dBLDAsMCwwLDANCiRQVUJYLDQwLFRYVCwwLDAsMCwwDQokUFVCWCw0MCxSTUMsMCwwLDAsMCo0Ng0KJFBVQlgsNDEsMSwwMDA3LDAwMDMsNDgwMCwwDQokUFVCWCw0MCxaREEsMSwxLDEsMQ==');
1360
	}
1361

    
1362
	/* XXX: Why not file_put_contents to the device */
1363
	@file_put_contents('/tmp/gps.init', $gps_init);
1364
	`cat /tmp/gps.init > $serialport`;
1365

    
1366
	/* Add /etc/remote entry in case we need to read from the GPS with tip */
1367
	if (intval(`grep -c '^gps0' /etc/remote`) == 0) {
1368
		$gpsbaud = '4800';
1369
		if (is_array($config['ntpd']) && is_array($config['ntpd']['gps']) && !empty($config['ntpd']['gps']['speed'])) {
1370
			switch($config['ntpd']['gps']['speed']) {
1371
				case '16':
1372
					$gpsbaud = '9600';
1373
					break;
1374
				case '32':
1375
					$gpsbaud = '19200';
1376
					break;
1377
				case '48':
1378
					$gpsbaud = '38400';
1379
					break;
1380
				case '64':
1381
					$gpsbaud = '57600';
1382
					break;
1383
				case '80':
1384
					$gpsbaud = '115200';
1385
					break;
1386
			}
1387
		}
1388
		@file_put_contents("/etc/remote", "gps0:dv={$serialport}:br#{$gpsbaud}:pa=none:", FILE_APPEND);
1389
	}
1390

    
1391
	conf_mount_ro();
1392

    
1393
	return true;
1394
}
1395

    
1396
function system_ntp_setup_pps($serialport) {
1397
	global $config, $g;
1398

    
1399
	$pps_device = '/dev/pps0';
1400
	$serialport = '/dev/'.$serialport;
1401

    
1402
	if (!file_exists($serialport))
1403
		return false;
1404

    
1405
	conf_mount_rw();
1406
	// Create symlink that ntpd requires
1407
	unlink_if_exists($pps_device);
1408
	@symlink($serialport, $pps_device);
1409

    
1410
	conf_mount_ro();
1411

    
1412
	return true;
1413
}
1414

    
1415

    
1416
function system_ntp_configure($start_ntpd=true) {
1417
	global $config, $g;
1418

    
1419
	$driftfile = "/var/db/ntpd.drift";
1420
	$statsdir = "/var/log/ntp";
1421
	$gps_device = '/dev/gps0';
1422

    
1423
	if ($g['platform'] == 'jail')
1424
		return;
1425

    
1426
	safe_mkdir($statsdir);
1427

    
1428
	if (!is_array($config['ntpd']))
1429
		$config['ntpd'] = array();
1430

    
1431
	$ntpcfg = "# \n";
1432
	$ntpcfg .= "# pfSense ntp configuration file \n";
1433
	$ntpcfg .= "# \n\n";
1434
	$ntpcfg .= "tinker panic 0 \n";
1435

    
1436
	/* Add Orphan mode */
1437
	$ntpcfg .= "# Orphan mode stratum\n";
1438
	$ntpcfg .= 'tos orphan ';
1439
	if (!empty($config['ntpd']['orphan'])) {
1440
		$ntpcfg .= $config['ntpd']['orphan'];
1441
	}else{
1442
		$ntpcfg .= '12';
1443
	}
1444
	$ntpcfg .= "\n";
1445

    
1446
	/* Add PPS configuration */
1447
	if (!empty($config['ntpd']['pps'])
1448
		&& file_exists('/dev/'.$config['ntpd']['pps']['port'])
1449
		&& system_ntp_setup_pps($config['ntpd']['pps']['port'])) {
1450
		$ntpcfg .= "\n";
1451
		$ntpcfg .= "# PPS Setup\n";
1452
		$ntpcfg .= 'server 127.127.22.0';
1453
		$ntpcfg .= ' minpoll 4 maxpoll 4';
1454
		if (empty($config['ntpd']['pps']['prefer'])) { /*note: this one works backwards */
1455
			$ntpcfg .= ' prefer'; 
1456
		}
1457
		if (!empty($config['ntpd']['pps']['noselect'])) {
1458
			$ntpcfg .= ' noselect ';
1459
		}
1460
		$ntpcfg .= "\n";
1461
		$ntpcfg .= 'fudge 127.127.22.0';
1462
		if (!empty($config['ntpd']['pps']['fudge1'])) {
1463
			$ntpcfg .= ' time1 ';
1464
			$ntpcfg .= $config['ntpd']['pps']['fudge1'];
1465
		}
1466
		if (!empty($config['ntpd']['pps']['flag2'])) {
1467
			$ntpcfg .= ' flag2 1';
1468
		}
1469
		if (!empty($config['ntpd']['pps']['flag3'])) {
1470
			$ntpcfg .= ' flag3 1';
1471
		}else{
1472
			$ntpcfg .= ' flag3 0';
1473
		}
1474
		if (!empty($config['ntpd']['pps']['flag4'])) {
1475
			$ntpcfg .= ' flag4 1';
1476
		}
1477
		if (!empty($config['ntpd']['pps']['refid'])) {
1478
			$ntpcfg .= ' refid ';
1479
			$ntpcfg .= $config['ntpd']['pps']['refid'];
1480
		}
1481
		$ntpcfg .= "\n";
1482
	}
1483
	/* End PPS configuration */
1484

    
1485
	/* Add GPS configuration */
1486
	if (!empty($config['ntpd']['gps'])
1487
		&& file_exists('/dev/'.$config['ntpd']['gps']['port'])
1488
		&& system_ntp_setup_gps($config['ntpd']['gps']['port'])) {
1489
		$ntpcfg .= "\n";
1490
		$ntpcfg .= "# GPS Setup\n";
1491
		$ntpcfg .= 'server 127.127.20.0 mode ';
1492
		if (!empty($config['ntpd']['gps']['nmea']) || !empty($config['ntpd']['gps']['speed']) || !empty($config['ntpd']['gps']['subsec'])) {
1493
			if (!empty($config['ntpd']['gps']['nmea'])) {
1494
				$ntpmode = (int) $config['ntpd']['gps']['nmea'];
1495
			}
1496
			if (!empty($config['ntpd']['gps']['speed'])) {
1497
				$ntpmode += (int) $config['ntpd']['gps']['speed'];
1498
			}
1499
			if (!empty($config['ntpd']['gps']['subsec'])) {
1500
				$ntpmode += 128;
1501
			}
1502
			$ntpcfg .= (string) $ntpmode;
1503
		}else{
1504
			$ntpcfg .= '0';
1505
		}
1506
		$ntpcfg .= ' minpoll 4 maxpoll 4';
1507
		if (empty($config['ntpd']['gps']['prefer'])) { /*note: this one works backwards */
1508
			$ntpcfg .= ' prefer'; 
1509
		}
1510
		if (!empty($config['ntpd']['gps']['noselect'])) {
1511
			$ntpcfg .= ' noselect ';
1512
		}
1513
		$ntpcfg .= "\n";
1514
		$ntpcfg .= 'fudge 127.127.20.0';
1515
		if (!empty($config['ntpd']['gps']['fudge1'])) {
1516
			$ntpcfg .= ' time1 ';
1517
			$ntpcfg .= $config['ntpd']['gps']['fudge1'];
1518
		}
1519
		if (!empty($config['ntpd']['gps']['fudge2'])) {
1520
			$ntpcfg .= ' time2 ';
1521
			$ntpcfg .= $config['ntpd']['gps']['fudge2'];
1522
		}
1523
		if (!empty($config['ntpd']['gps']['flag1'])) {
1524
			$ntpcfg .= ' flag1 1';
1525
		}else{
1526
			$ntpcfg .= ' flag1 0';
1527
		}
1528
		if (!empty($config['ntpd']['gps']['flag2'])) {
1529
			$ntpcfg .= ' flag2 1';
1530
		}
1531
		if (!empty($config['ntpd']['gps']['flag3'])) {
1532
			$ntpcfg .= ' flag3 1';
1533
		}else{
1534
			$ntpcfg .= ' flag3 0';
1535
		}
1536
		if (!empty($config['ntpd']['gps']['flag4'])) {
1537
			$ntpcfg .= ' flag4 1';
1538
		}
1539
		if (!empty($config['ntpd']['gps']['refid'])) {
1540
			$ntpcfg .= ' refid ';
1541
			$ntpcfg .= $config['ntpd']['gps']['refid'];
1542
		}
1543
		$ntpcfg .= "\n";
1544
	}elseif (!empty($config['ntpd']['gpsport'])
1545
		&& file_exists('/dev/'.$config['ntpd']['gpsport'])
1546
		&& system_ntp_setup_gps($config['ntpd']['gpsport'])) {
1547
		/* This handles a 2.1 and earlier config */
1548
		$ntpcfg .= "# GPS Setup\n";
1549
		$ntpcfg .= "server 127.127.20.0 mode 0 minpoll 4 maxpoll 4 prefer\n";
1550
		$ntpcfg .= "fudge 127.127.20.0 time1 0.155 time2 0.000 flag1 1 flag2 0 flag3 1\n";
1551
		// Fall back to local clock if GPS is out of sync?
1552
		$ntpcfg .= "server 127.127.1.0\n";
1553
		$ntpcfg .= "fudge 127.127.1.0 stratum 12\n";
1554
	}
1555
	/* End GPS configuration */
1556
	
1557
	$ntpcfg .= "\n\n# Upstream Servers\n";
1558
	/* foreach through ntp servers and write out to ntpd.conf */
1559
	foreach (explode(' ', $config['system']['timeservers']) as $ts) {
1560
		$ntpcfg .= "server {$ts} iburst maxpoll 9";
1561
		if (substr_count($config['ntpd']['prefer'], $ts)) $ntpcfg .= ' prefer';
1562
		if (substr_count($config['ntpd']['noselect'], $ts)) $ntpcfg .= ' noselect';
1563
		$ntpcfg .= "\n";
1564
	}
1565
	unset($ts);
1566

    
1567
	$ntpcfg .= "\n\n";
1568
	$ntpcfg .= "disable monitor\n"; //prevent NTP reflection attack, see https://forum.pfsense.org/index.php/topic,67189.msg389132.html#msg389132
1569
	if (!empty($config['ntpd']['clockstats']) || !empty($config['ntpd']['loopstats']) || !empty($config['ntpd']['peerstats'])) {
1570
		$ntpcfg .= "enable stats\n";
1571
		$ntpcfg .= 'statistics';
1572
		if (!empty($config['ntpd']['clockstats'])) {
1573
			$ntpcfg .= ' clockstats';
1574
		}
1575
		if (!empty($config['ntpd']['loopstats'])) {
1576
			$ntpcfg .= ' loopstats';
1577
		}
1578
		if (!empty($config['ntpd']['peerstats'])) {
1579
			$ntpcfg .= ' peerstats';
1580
		}
1581
		$ntpcfg .= "\n";
1582
	}
1583
	$ntpcfg .= "statsdir {$statsdir}\n";
1584
	$ntpcfg .= 'logconfig =syncall +clockall';
1585
	if (!empty($config['ntpd']['logpeer'])) {
1586
		$ntpcfg .= ' +peerall';
1587
	}
1588
	if (!empty($config['ntpd']['logsys'])) {
1589
		$ntpcfg .= ' +sysall';
1590
	}
1591
	$ntpcfg .= "\n";
1592
	$ntpcfg .= "driftfile {$driftfile}\n";
1593
	/* Access restrictions */
1594
	$ntpcfg .= 'restrict default';
1595
	if (empty($config['ntpd']['kod'])) { /*note: this one works backwards */
1596
		$ntpcfg .= ' kod limited'; 
1597
	}
1598
	if (empty($config['ntpd']['nomodify'])) { /*note: this one works backwards */
1599
		$ntpcfg .= ' nomodify'; 
1600
	}
1601
	if (!empty($config['ntpd']['noquery'])) {
1602
		$ntpcfg .= ' noquery';
1603
	}
1604
	if (empty($config['ntpd']['nopeer'])) { /*note: this one works backwards */
1605
		$ntpcfg .= ' nopeer'; 
1606
	}
1607
	if (empty($config['ntpd']['notrap'])) { /*note: this one works backwards */
1608
		$ntpcfg .= ' notrap'; 
1609
	}
1610
	if (!empty($config['ntpd']['noserve'])) {
1611
		$ntpcfg .= ' noserve';
1612
	}
1613
	$ntpcfg .= "\nrestrict -6 default";
1614
	if (empty($config['ntpd']['kod'])) { /*note: this one works backwards */
1615
		$ntpcfg .= ' kod limited'; 
1616
	}
1617
	if (empty($config['ntpd']['nomodify'])) { /*note: this one works backwards */
1618
		$ntpcfg .= ' nomodify'; 
1619
	}
1620
	if (!empty($config['ntpd']['noquery'])) {
1621
		$ntpcfg .= ' noquery';
1622
	}
1623
	if (empty($config['ntpd']['nopeer'])) { /*note: this one works backwards */
1624
		$ntpcfg .= ' nopeer'; 
1625
	}
1626
	if (!empty($config['ntpd']['noserve'])) {
1627
		$ntpcfg .= ' noserve';
1628
	}
1629
	if (empty($config['ntpd']['notrap'])) { /*note: this one works backwards */
1630
		$ntpcfg .= ' notrap'; 
1631
	}
1632
	$ntpcfg .= "\n";
1633

    
1634
	/* A leapseconds file is really only useful if this clock is stratum 1 */
1635
	$ntpcfg .= "\n";
1636
	if (!empty($config['ntpd']['leapsec'])) {
1637
		$leapsec .= base64_decode($config['ntpd']['leapsec']);
1638
		file_put_contents('/var/db/leap-seconds', $leapsec);
1639
		$ntpcfg .= "leapfile /var/db/leap-seconds\n";
1640
	}
1641
	
1642

    
1643
	if (empty($config['ntpd']['interface']))
1644
		if (is_array($config['installedpackages']['openntpd']) && !empty($config['installedpackages']['openntpd']['config'][0]['interface']))
1645
			$interfaces = explode(",", $config['installedpackages']['openntpd']['config'][0]['interface']);
1646
		else
1647
			$interfaces = array();
1648
	else
1649
		$interfaces = explode(",", $config['ntpd']['interface']);
1650

    
1651
	if (is_array($interfaces) && count($interfaces)) {
1652
		$ntpcfg .= "interface ignore all\n";
1653
		foreach ($interfaces as $interface) {
1654
			if (!is_ipaddr($interface)) {
1655
				$interface = get_real_interface($interface);
1656
			}
1657
			if (!empty($interface))
1658
				$ntpcfg .= "interface listen {$interface}\n";
1659
		}
1660
	}
1661

    
1662
	/* open configuration for wrting or bail */
1663
	if (!@file_put_contents("{$g['varetc_path']}/ntpd.conf", $ntpcfg)) {
1664
		log_error("Could not open {$g['varetc_path']}/ntpd.conf for writing");
1665
		return;
1666
	}
1667

    
1668
	/* At bootup we just want to write out the config. */
1669
	if (!$start_ntpd)
1670
		return;
1671

    
1672
	/* if ntpd is running, kill it */
1673
	while (isvalidpid("{$g['varrun_path']}/ntpd.pid")) {
1674
		killbypid("{$g['varrun_path']}/ntpd.pid");
1675
	}
1676
	@unlink("{$g['varrun_path']}/ntpd.pid");
1677

    
1678
	/* if /var/empty does not exist, create it */
1679
	if(!is_dir("/var/empty"))
1680
		mkdir("/var/empty", 0775, true);
1681

    
1682
	/* start opentpd, set time now and use /var/etc/ntpd.conf */
1683
	mwexec("/usr/local/sbin/ntpd -g -c {$g['varetc_path']}/ntpd.conf -p {$g['varrun_path']}/ntpd.pid", false, true);
1684
	
1685
	// Note that we are starting up
1686
	log_error("NTPD is starting up.");
1687
	return;
1688
}
1689

    
1690
function sync_system_time() {
1691
	global $config, $g;
1692

    
1693
	if ($g['booting'])
1694
		echo gettext("Syncing system time before startup...");
1695

    
1696
	/* foreach through servers and write out to ntpd.conf */
1697
	foreach (explode(' ', $config['system']['timeservers']) as $ts) {
1698
		mwexec("/usr/local/sbin/ntpdate -s $ts");
1699
	}
1700
	
1701
	if ($g['booting'])
1702
		echo gettext("done.") . "\n";
1703
	
1704
}
1705

    
1706
function system_halt() {
1707
	global $g;
1708

    
1709
	system_reboot_cleanup();
1710

    
1711
	mwexec("/usr/bin/nohup /etc/rc.halt > /dev/null 2>&1 &");
1712
}
1713

    
1714
function system_reboot() {
1715
	global $g;
1716

    
1717
	system_reboot_cleanup();
1718

    
1719
	mwexec("nohup /etc/rc.reboot > /dev/null 2>&1 &");
1720
}
1721

    
1722
function system_reboot_sync() {
1723
	global $g;
1724

    
1725
	system_reboot_cleanup();
1726

    
1727
	mwexec("/etc/rc.reboot > /dev/null 2>&1");
1728
}
1729

    
1730
function system_reboot_cleanup() {
1731
	global $config, $cpzone;
1732

    
1733
	mwexec("/usr/local/bin/beep.sh stop");
1734
	require_once("captiveportal.inc");
1735
	if (is_array($config['captiveportal'])) {
1736
		foreach ($config['captiveportal'] as $cpzone=>$cp) {
1737
			captiveportal_radius_stop_all();
1738
			captiveportal_send_server_accounting(true);
1739
		}
1740
	}
1741
	require_once("voucher.inc");
1742
	voucher_save_db_to_config();
1743
	require_once("pkg-utils.inc");
1744
	stop_packages();
1745
}
1746

    
1747
function system_do_shell_commands($early = 0) {
1748
	global $config, $g;
1749
	if(isset($config['system']['developerspew'])) {
1750
		$mt = microtime();
1751
		echo "system_do_shell_commands() being called $mt\n";
1752
	}
1753

    
1754
	if ($early)
1755
		$cmdn = "earlyshellcmd";
1756
	else
1757
		$cmdn = "shellcmd";
1758

    
1759
	if (is_array($config['system'][$cmdn])) {
1760

    
1761
		/* *cmd is an array, loop through */
1762
		foreach ($config['system'][$cmdn] as $cmd) {
1763
			exec($cmd);
1764
		}
1765

    
1766
	} elseif($config['system'][$cmdn] <> "") {
1767

    
1768
		/* execute single item */
1769
		exec($config['system'][$cmdn]);
1770

    
1771
	}
1772
}
1773

    
1774
function system_console_configure() {
1775
	global $config, $g;
1776
	if(isset($config['system']['developerspew'])) {
1777
		$mt = microtime();
1778
		echo "system_console_configure() being called $mt\n";
1779
	}
1780

    
1781
	if (isset($config['system']['disableconsolemenu'])) {
1782
		touch("{$g['varetc_path']}/disableconsole");
1783
	} else {
1784
		unlink_if_exists("{$g['varetc_path']}/disableconsole");
1785
	}
1786
}
1787

    
1788
function system_dmesg_save() {
1789
	global $g;
1790
	if(isset($config['system']['developerspew'])) {
1791
		$mt = microtime();
1792
		echo "system_dmesg_save() being called $mt\n";
1793
	}
1794

    
1795
	$dmesg = "";
1796
	$_gb = exec("/sbin/dmesg", $dmesg);
1797

    
1798
	/* find last copyright line (output from previous boots may be present) */
1799
	$lastcpline = 0;
1800

    
1801
	for ($i = 0; $i < count($dmesg); $i++) {
1802
		if (strstr($dmesg[$i], "Copyright (c) 1992-"))
1803
			$lastcpline = $i;
1804
	}
1805

    
1806
	$fd = fopen("{$g['varlog_path']}/dmesg.boot", "w");
1807
	if (!$fd) {
1808
		printf(gettext("Error: cannot open dmesg.boot in system_dmesg_save().%s"), "\n");
1809
		return 1;
1810
	}
1811

    
1812
	for ($i = $lastcpline; $i < count($dmesg); $i++)
1813
		fwrite($fd, $dmesg[$i] . "\n");
1814

    
1815
	fclose($fd);
1816
	unset($dmesg);
1817

    
1818
	return 0;
1819
}
1820

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

    
1828
	if (isset($config['system']['harddiskstandby'])) {
1829
		if ($g['booting']) {
1830
			echo gettext('Setting hard disk standby... ');
1831
		}
1832

    
1833
		$standby = $config['system']['harddiskstandby'];
1834
		// Check for a numeric value
1835
		if (is_numeric($standby)) {
1836
			// Sync the disk(s)
1837
			pfSense_sync();
1838
			if (set_single_sysctl('hw.ata.standby', (int)$standby)) {
1839
				// Reinitialize ATA-drives
1840
				mwexec('/usr/local/sbin/atareinit');
1841
				if ($g['booting']) {
1842
					echo gettext("done.") . "\n";
1843
				}
1844
			} else if ($g['booting']) {
1845
				echo gettext("failed!") . "\n";
1846
			}
1847
		} else if ($g['booting']) {
1848
			echo gettext("failed!") . "\n";
1849
		}
1850
	}
1851
}
1852

    
1853
function system_setup_sysctl() {
1854
	global $config;
1855
	if(isset($config['system']['developerspew'])) {
1856
		$mt = microtime();
1857
		echo "system_setup_sysctl() being called $mt\n";
1858
	}
1859

    
1860
	activate_sysctls();	
1861

    
1862
	if (isset($config['system']['sharednet'])) {
1863
		system_disable_arp_wrong_if();
1864
	}
1865
}
1866

    
1867
function system_disable_arp_wrong_if() {
1868
	global $config;
1869
	if(isset($config['system']['developerspew'])) {
1870
		$mt = microtime();
1871
		echo "system_disable_arp_wrong_if() being called $mt\n";
1872
	}
1873
	set_sysctl(array(
1874
		"net.link.ether.inet.log_arp_wrong_iface" => "0",
1875
		"net.link.ether.inet.log_arp_movements" => "0"
1876
	));
1877
}
1878

    
1879
function system_enable_arp_wrong_if() {
1880
	global $config;
1881
	if(isset($config['system']['developerspew'])) {
1882
		$mt = microtime();
1883
		echo "system_enable_arp_wrong_if() being called $mt\n";
1884
	}
1885
	set_sysctl(array(
1886
		"net.link.ether.inet.log_arp_wrong_iface" => "1",
1887
		"net.link.ether.inet.log_arp_movements" => "1"
1888
	));
1889
}
1890

    
1891
function enable_watchdog() {
1892
	global $config;
1893
	return;
1894
	$install_watchdog = false;
1895
	$supported_watchdogs = array("Geode");
1896
	$file = file_get_contents("/var/log/dmesg.boot");
1897
	foreach($supported_watchdogs as $sd) {
1898
		if(stristr($file, "Geode")) {
1899
			$install_watchdog = true;
1900
		}
1901
	}
1902
	if($install_watchdog == true) {
1903
		if(is_process_running("watchdogd"))
1904
			mwexec("/usr/bin/killall watchdogd", true);
1905
		exec("/usr/sbin/watchdogd");
1906
	}
1907
}
1908

    
1909
function system_check_reset_button() {
1910
	global $g;
1911
	if($g['platform'] != "nanobsd")
1912
		return 0;
1913

    
1914
	$specplatform = system_identify_specific_platform();
1915

    
1916
	if ($specplatform['name'] != "wrap" && $specplatform['name'] != "alix")
1917
		return 0;
1918

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

    
1921
	if ($retval == 99) {
1922
		/* user has pressed reset button for 2 seconds - 
1923
		   reset to factory defaults */
1924
		echo <<<EOD
1925

    
1926
***********************************************************************
1927
* Reset button pressed - resetting configuration to factory defaults. *
1928
* The system will reboot after this completes.                        *
1929
***********************************************************************
1930

    
1931

    
1932
EOD;
1933
		
1934
		reset_factory_defaults();
1935
		system_reboot_sync();
1936
		exit(0);
1937
	}
1938

    
1939
	return 0;
1940
}
1941

    
1942
/* attempt to identify the specific platform (for embedded systems)
1943
   Returns an array with two elements:
1944
	name => platform string (e.g. 'wrap', 'alix' etc.)
1945
	descr => human-readable description (e.g. "PC Engines WRAP")
1946
*/
1947
function system_identify_specific_platform() {
1948
	global $g;
1949
	
1950
	if ($g['platform'] == 'generic-pc')
1951
		return array('name' => 'generic-pc', 'descr' => gettext("Generic PC"));
1952
	
1953
	if ($g['platform'] == 'generic-pc-cdrom')
1954
		return array('name' => 'generic-pc-cdrom', 'descr' => gettext("Generic PC (CD-ROM)"));
1955
	
1956
	/* the rest of the code only deals with 'embedded' platforms */
1957
	if ($g['platform'] != 'nanobsd')
1958
		return array('name' => $g['platform'], 'descr' => $g['platform']);
1959

    
1960
	$dmesg = get_single_sysctl('hw.model');
1961

    
1962
	if (strpos($dmesg, "PC Engines WRAP") !== false)
1963
		return array('name' => 'wrap', 'descr' => gettext('PC Engines WRAP'));
1964
	
1965
	if (strpos($dmesg, "PC Engines ALIX") !== false)
1966
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
1967

    
1968
	if (preg_match("/Soekris net45../", $dmesg, $matches))
1969
		return array('name' => 'net45xx', 'descr' => $matches[0]);
1970
	
1971
	if (preg_match("/Soekris net48../", $dmesg, $matches))
1972
		return array('name' => 'net48xx', 'descr' => $matches[0]);
1973
		
1974
	if (preg_match("/Soekris net55../", $dmesg, $matches))
1975
		return array('name' => 'net55xx', 'descr' => $matches[0]);
1976
	
1977
	/* unknown embedded platform */
1978
	return array('name' => 'embedded', 'descr' => gettext('embedded (unknown)'));
1979
}
1980

    
1981
function system_get_dmesg_boot() {
1982
	global $g;
1983
		
1984
	return file_get_contents("{$g['varlog_path']}/dmesg.boot");
1985
}
1986

    
1987
function get_possible_listen_ips($include_ipv6_link_local=false) {
1988
	$interfaces = get_configured_interface_with_descr();
1989
	$carplist = get_configured_carp_interface_list();
1990
	$listenips = array();
1991
	foreach ($carplist as $cif => $carpip)
1992
		$interfaces[$cif] = $carpip." (".get_vip_descr($carpip).")";
1993
	$aliaslist = get_configured_ip_aliases_list();
1994
	foreach ($aliaslist as $aliasip => $aliasif)
1995
		$interfaces[$aliasip] = $aliasip." (".get_vip_descr($aliasip).")";
1996
	foreach ($interfaces as $iface => $ifacename) {
1997
		$tmp["name"]  = $ifacename;
1998
		$tmp["value"] = $iface;
1999
		$listenips[] = $tmp;
2000
		if ($include_ipv6_link_local) {
2001
			$llip = find_interface_ipv6_ll(get_real_interface($iface));
2002
			if (!empty($llip)) {
2003
				$tmp["name"]  = "{$ifacename} IPv6 Link-Local";
2004
				$tmp["value"] = $llip;
2005
				$listenips[] = $tmp;
2006
			}
2007
		}
2008
	}
2009
	$tmp["name"]  = "Localhost";
2010
	$tmp["value"] = "lo0";
2011
	$listenips[] = $tmp;
2012
	return $listenips;
2013
}
2014

    
2015
function get_possible_traffic_source_addresses($include_ipv6_link_local=false) {
2016
	global $config;
2017
	$sourceips = get_possible_listen_ips($include_ipv6_link_local);
2018
	foreach (array('server', 'client') as $mode) {
2019
		if (is_array($config['openvpn']["openvpn-{$mode}"])) {
2020
			foreach ($config['openvpn']["openvpn-{$mode}"] as $id => $setting) {
2021
				if (!isset($setting['disable'])) {
2022
					$vpn = array();
2023
					$vpn['value'] = 'ovpn' . substr($mode, 0, 1) . $setting['vpnid'];
2024
					$vpn['name'] = gettext("OpenVPN") . " ".$mode.": ".htmlspecialchars($setting['description']);
2025
					$sourceips[] = $vpn;
2026
				}
2027
			}
2028
		}
2029
	}
2030
	return $sourceips;
2031
}
2032
?>
(53-53/68)