Project

General

Profile

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

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

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

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

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

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

    
32
/*
33
	pfSense_BUILDER_BINARIES:	/usr/sbin/powerd	/usr/bin/killall	/sbin/sysctl	/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/bin/ntpd	/usr/sbin/ntpdate
37
	pfSense_BUILDER_BINARIES:	/usr/bin/nohup	/sbin/dmesg	/usr/local/sbin/atareinit	/sbin/kldload
38
	pfSense_MODULE:	utils
39
*/
40

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

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

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

    
59
		mwexec("/usr/sbin/powerd -b $battery_mode -a $ac_mode");
60
	}
61
}
62

    
63
function get_default_sysctl_value($id) {
64
	global $sysctls;
65

    
66
	if (isset($sysctls[$id]))
67
		return $sysctls[$id];
68
}
69

    
70
function activate_sysctls() {
71
	global $config, $g;
72
	if ($g['platform'] == 'jail')
73
		return;
74
	exec("/sbin/sysctl net.enc.out.ipsec_bpf_mask=0x0001");
75
	exec("/sbin/sysctl net.enc.out.ipsec_filter_mask=0x0001");
76
	exec("/sbin/sysctl net.enc.in.ipsec_bpf_mask=0x0002");
77
	exec("/sbin/sysctl net.enc.in.ipsec_filter_mask=0x0002");
78

    
79
	if(is_array($config['sysctl'])) {
80
		foreach($config['sysctl']['item'] as $tunable) {
81
			if($tunable['value'] == "default") {
82
				$value = get_default_sysctl_value($tunable['tunable']);
83
				mwexec("/sbin/sysctl " . $tunable['tunable'] . "=\"" . $value .  "\"");
84
			} else { 
85
				mwexec("/sbin/sysctl " . $tunable['tunable'] . "=\"" . $tunable['value'] .  "\"");
86
			}
87
		}
88
	}
89
}
90

    
91
function system_resolvconf_generate($dynupdate = false) {
92
	global $config, $g;
93

    
94
	if(isset($config['system']['developerspew'])) {
95
		$mt = microtime();
96
		echo "system_resolvconf_generate() being called $mt\n";
97
	}
98

    
99
	$syscfg = $config['system'];
100

    
101
	// Do not create blank domain lines, it breaks tools like dig.
102
	if($syscfg['domain'])
103
		$resolvconf = "domain {$syscfg['domain']}\n";
104

    
105
	if (isset($config['dnsmasq']['enable']) && !isset($config['system']['dnslocalhost']))
106
		$resolvconf .= "nameserver 127.0.0.1\n";
107

    
108
	if (isset($syscfg['dnsallowoverride'])) {
109
		/* get dynamically assigned DNS servers (if any) */
110
		$ns = array_unique(get_searchdomains());
111
		foreach($ns as $searchserver) {
112
			if($searchserver)
113
				$resolvconf .= "search {$searchserver}\n";
114
		}
115
		$ns = array_unique(get_nameservers());
116
		foreach($ns as $nameserver) {
117
			if($nameserver)
118
				$resolvconf .= "nameserver $nameserver\n";
119
		}
120
	}
121
	if (is_array($syscfg['dnsserver'])) {
122
		foreach ($syscfg['dnsserver'] as $ns) {
123
			if ($ns)
124
				$resolvconf .= "nameserver $ns\n";
125
		}
126
	}
127

    
128
	$dnslock = lock('resolvconf', LOCK_EX);
129

    
130
	$fd = fopen("{$g['varetc_path']}/resolv.conf", "w");
131
	if (!$fd) {
132
		printf("Error: cannot open resolv.conf in system_resolvconf_generate().\n");
133
		unlock($dnslock);
134
		return 1;
135
	}
136

    
137
	fwrite($fd, $resolvconf);
138
	fclose($fd);
139

    
140
	if (!$g['booting']) {
141
		/* restart dhcpd (nameservers may have changed) */
142
		if (!$dynupdate)
143
			services_dhcpd_configure();
144
	}
145

    
146
	/* setup static routes for DNS servers. */
147
	for ($dnscounter=1; $dnscounter<5; $dnscounter++) {
148
		/* setup static routes for dns servers */
149
		$dnsgw = "dns{$dnscounter}gw";
150
		if (isset($config['system'][$dnsgw])) {
151
			$gwname = $config['system'][$dnsgw];
152
			if (($gwname <> "") && ($gwname <> "none")) {
153
				$gatewayip = lookup_gateway_ip_by_name($gwname);
154
				if (is_ipaddrv4($gatewayip)) {
155
					/* dns server array starts at 0 */
156
					$dnscountermo = $dnscounter - 1;
157
					mwexec("route change -host " . $syscfg['dnsserver'][$dnscountermo] . " {$gatewayip}");
158
				}
159
				if (is_ipaddrv6($gatewayip)) {
160
					/* dns server array starts at 0 */
161
					$dnscountermo = $dnscounter - 1;
162
					mwexec("route change -host -inet6 " . $syscfg['dnsserver'][$dnscountermo] . " {$gatewayip}");
163
				}
164
			}
165
		}
166
	}
167

    
168
	unlock($dnslock);
169

    
170
	return 0;
171
}
172

    
173
function get_searchdomains() {
174
	global $config, $g;
175

    
176
	$master_list = array();
177
	
178
	// Read in dhclient nameservers
179
	$search_list = glob("/var/etc/searchdomain_*");
180
	if (is_array($search_lists)) {
181
		foreach($search_lists as $fdns) {
182
			$contents = file($fdns, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
183
			if (!is_array($contents))
184
				continue;
185
			foreach ($contents as $dns) {
186
				if(is_hostname($dns)) 
187
					$master_list[] = $dns;
188
			}
189
		}
190
	}
191

    
192
	return $master_list;
193
}
194

    
195
function get_nameservers() {
196
	global $config, $g;
197
	$master_list = array();
198
	
199
	// Read in dhclient nameservers
200
	$dns_lists = glob("/var/etc/nameserver_*");
201
	if (is_array($dns_lists)) {
202
		foreach($dns_lists as $fdns) {
203
			$contents = file($fdns, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
204
			if (!is_array($contents))
205
				continue;
206
			foreach ($contents as $dns) {
207
				if(is_ipaddr($dns)) 
208
					$master_list[] = $dns;
209
			}
210
		}
211
	}
212

    
213
	// Read in any extra nameservers
214
	if(file_exists("/var/etc/nameservers.conf")) {
215
		$dns_s = file("/var/etc/nameservers.conf", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
216
		if(is_array($dns_s)) {
217
			foreach($dns_s as $dns)
218
				if (is_ipaddr($dns))
219
					$master_list[] = $dns;
220
		}
221
	}
222

    
223
	return $master_list;
224
}
225

    
226
function system_hosts_generate() {
227
	global $config, $g;
228
	if(isset($config['system']['developerspew'])) {
229
		$mt = microtime();
230
		echo "system_hosts_generate() being called $mt\n";
231
	}
232

    
233
	$syscfg = $config['system'];
234
	$dnsmasqcfg = $config['dnsmasq'];
235

    
236
	$hosts = "127.0.0.1	localhost localhost.{$syscfg['domain']}\n";
237
	$lhosts = "";
238
	$dhosts = "";
239

    
240
	if ($config['interfaces']['lan']) {
241
		$cfgip = get_interface_ip("lan");
242
		if (is_ipaddr($cfgip))
243
			$hosts .= "{$cfgip}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
244
	} else {
245
		$sysiflist = get_configured_interface_list();
246
		foreach ($sysiflist as $sysif) {
247
			if (!interface_has_gateway($sysif)) {
248
				$cfgip = get_interface_ip($sysif);
249
				if (is_ipaddr($cfgip)) {
250
					$hosts .= "{$cfgip}	{$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}\n";
251
					break;
252
				}
253
			}
254
		}
255
	}
256

    
257
	if (isset($dnsmasqcfg['enable'])) {
258
		if (!is_array($dnsmasqcfg['hosts']))
259
			$dnsmasqcfg['hosts'] = array();
260

    
261
		foreach ($dnsmasqcfg['hosts'] as $host) {
262
			if ($host['host'])
263
				$lhosts .= "{$host['ip']}	{$host['host']}.{$host['domain']} {$host['host']}\n";
264
			else
265
				$lhosts .= "{$host['ip']}	{$host['domain']}\n";
266
			if (!is_array($host['aliases']) || !is_array($host['aliases']['item']))
267
				continue;
268
			foreach ($host['aliases']['item'] as $alias) {
269
				if ($alias['host'])
270
					$lhosts .= "{$host['ip']}	{$alias['host']}.{$alias['domain']} {$alias['host']}\n";
271
				else
272
					$lhosts .= "{$host['ip']}	{$alias['domain']}\n";
273
			}
274
		}
275
		if (isset($dnsmasqcfg['regdhcpstatic']) && is_array($config['dhcpd'])) {
276
			foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf)
277
				if(is_array($dhcpifconf['staticmap']) && isset($dhcpifconf['enable']))
278
						foreach ($dhcpifconf['staticmap'] as $host)
279
							if ($host['ipaddr'] && $host['hostname'])
280
								$dhosts .= "{$host['ipaddr']}	{$host['hostname']}.{$syscfg['domain']} {$host['hostname']}\n";
281
		}
282
		if (isset($dnsmasqcfg['regdhcpstatic']) && is_array($config['dhcpdv6'])) {
283
			foreach ($config['dhcpdv6'] as $dhcpif => $dhcpifconf)
284
				if(is_array($dhcpifconf['staticmap']) && isset($dhcpifconf['enable']))
285
						foreach ($dhcpifconf['staticmap'] as $host)
286
							if ($host['ipaddrv6'] && $host['hostname'])
287
								$dhosts .= "{$host['ipaddrv6']}	{$host['hostname']}.{$syscfg['domain']} {$host['hostname']}\n";
288
		}
289

    
290
		if (isset($dnsmasqcfg['dhcpfirst']))
291
			$hosts .= $dhosts . $lhosts;
292
		else
293
			$hosts .= $lhosts . $dhosts;
294
	}
295

    
296
	/*
297
	 * Do not remove this because dhcpleases monitors with kqueue it needs to be 
298
	 * killed before writing to hosts files.
299
	 */
300
	if (file_exists("{$g['varrun_path']}/dhcpleases.pid")) {
301
		sigkillbypid("{$g['varrun_path']}/dhcpleases.pid", "TERM");
302
		@unlink("{$g['varrun_path']}/dhcpleases.pid");
303
	}
304
	$fd = fopen("{$g['varetc_path']}/hosts", "w");
305
	if (!$fd) {
306
		log_error("Error: cannot open hosts file in system_hosts_generate().\n");
307
		return 1;
308
	}
309
	fwrite($fd, $hosts);
310
	fclose($fd);
311

    
312
	system_dhcpleases_configure();
313

    
314
	return 0;
315
}
316

    
317
function system_dhcpleases_configure() {
318
	global $config, $g;
319
	
320
	if ($g['platform'] == 'jail')
321
		return;
322
	/* Start the monitoring process for dynamic dhcpclients. */
323
	if (isset($config['dnsmasq']['enable']) && isset($config['dnsmasq']['regdhcp'])) {
324
		/* Make sure we do not error out */
325
		mwexec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/db");
326
		if (!file_exists("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases"))
327
			@touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases");
328
		if (isvalidpid("{$g['varrun_path']}/dhcpleases.pid"))
329
			sigkillbypid("{$g['varrun_path']}/dhcpleases.pid", "HUP");
330
		else
331
			mwexec("/usr/local/sbin/dhcpleases -l {$g['dhcpd_chroot_path']}/var/db/dhcpd.leases -d {$config['system']['domain']} -p {$g['varrun_path']}/dnsmasq.pid -h {$g['varetc_path']}/hosts");
332
	} else {
333
		sigkillbypid("{$g['varrun_path']}/dhcpleases.pid", "TERM");
334
		@unlink("{$g['varrun_path']}/dhcpleases.pid");
335
	}
336
}
337

    
338
function system_hostname_configure() {
339
	global $config, $g;
340
	if(isset($config['system']['developerspew'])) {
341
		$mt = microtime();
342
		echo "system_hostname_configure() being called $mt\n";
343
	}
344

    
345
	$syscfg = $config['system'];
346

    
347
	/* set hostname */
348
	$status = mwexec("/bin/hostname " .
349
		escapeshellarg("{$syscfg['hostname']}.{$syscfg['domain']}"));
350

    
351
    /* Setup host GUID ID.  This is used by ZFS. */
352
	mwexec("/etc/rc.d/hostid start");
353

    
354
	return $status;
355
}
356

    
357
function system_routing_configure($interface = "") {
358
	global $config, $g;
359
	if ($g['platform'] == 'jail')
360
		return;
361
	if(isset($config['system']['developerspew'])) {
362
		$mt = microtime();
363
		echo "system_routing_configure() being called $mt\n";
364
	}
365

    
366
	$gatewayip = "";
367
	$interfacegw = "";
368
	$foundgw = false;
369
	$gatewayipv6 = "";
370
	$interfacegwv6 = "";
371
	$foundgwv6 = false;
372
	/* tack on all the hard defined gateways as well */
373
	if (is_array($config['gateways']['gateway_item'])) {
374
		mwexec("/bin/rm -f {$g['tmp_path']}/*_defaultgw {$g['tmp_path']}/*_defaultgwv6", true);
375
		foreach	($config['gateways']['gateway_item'] as $gateway) {
376
			if (isset($gateway['defaultgw'])) {
377
				if ($gateway['ipprotocol'] != "inet6" && (is_ipaddrv4($gateway['gateway']) || $gateway['gateway'] == "dynamic")) {
378
					if(strstr($gateway['gateway'], ":"))
379
						continue;
380
					if ($gateway['gateway'] == "dynamic")
381
						$gateway['gateway'] = get_interface_gateway($gateway['interface']);
382
					$gatewayip = $gateway['gateway'];
383
					$interfacegw = $gateway['interface'];
384
					if (!empty($gateway['interface'])) {
385
						$defaultif = get_real_interface($gateway['interface']);
386
						if ($defaultif)
387
							@file_put_contents("{$g['tmp_path']}/{$defaultif}_defaultgw", $gateway['gateway']);
388
					}
389
					$foundgw = true;
390
				} else if ($gateway['ipprotocol'] == "inet6" && (is_ipaddrv6($gateway['gateway']) || $gateway['gateway'] == "dynamic6")) {
391
					if ($gateway['gateway'] == "dynamic6")
392
						$gateway['gateway'] = get_interface_gateway_v6($gateway['interface']);
393
					$gatewayipv6 = $gateway['gateway'];
394
					$interfacegwv6 = $gateway['interface'];
395
					if (!empty($gateway['interface'])) {
396
						$defaultifv6 = get_real_interface($gateway['interface']);
397
						if ($defaultifv6)
398
							@file_put_contents("{$g['tmp_path']}/{$defaultifv6}_defaultgwv6", $gateway['gateway']);
399
					}
400
					$foundgwv6 = true;
401
				}
402
			}
403
			if ($foundgw === true && $foundgwv6 === true)
404
				break;
405
		}
406
	}
407
	if ($foundgw == false) {
408
		$defaultif = get_real_interface("wan");
409
		$interfacegw = "wan";
410
		$gatewayip = get_interface_gateway("wan");
411
		@touch("{$g['tmp_path']}/{$defaultif}_defaultgw");
412
	}	
413
	if ($foundgwv6 == false) {
414
		$defaultifv6 = get_real_interface("wan");
415
		$interfacegwv6 = "wan";
416
		$gatewayipv6 = get_interface_gateway_v6("wan");
417
		@touch("{$g['tmp_path']}/{$defaultif}_defaultgwv6");
418
	}
419
	$dont_add_route = false;
420
	/* if OLSRD is enabled, allow WAN to house DHCP. */
421
	if (is_array($config['installedpackages']['olsrd'])) {
422
		foreach($config['installedpackages']['olsrd']['config'] as $olsrd) {
423
			if(($olsrd['enabledyngw'] == "on") && ($olsrd['enable'] == "on")) {
424
				$dont_add_route = true;
425
				log_error(sprintf(gettext("Not adding default route because OLSR dynamic gateway is enabled.")));
426
				break;
427
			}
428
		}
429
	}
430

    
431
	if ($dont_add_route == false ) {
432
		if (!empty($interface) && $interface != $interfacegw)
433
			;
434
		else if (($interfacegw <> "bgpd") && (is_ipaddrv4($gatewayip))) {
435
			log_error("ROUTING: setting default route to $gatewayip");
436
			mwexec("/sbin/route change -inet default " . escapeshellarg($gatewayip));
437
		}
438

    
439
		if (!empty($interface) && $interface != $interfacegwv6)
440
			;
441
		else if (($interfacegwv6 <> "bgpd") && (is_ipaddrv6($gatewayipv6))) {
442
			$ifscope = "";
443
			if(is_linklocal($gatewayipv6))
444
				$ifscope = "%{$defaultifv6}";
445
			log_error("ROUTING: setting IPv6 default route to {$gatewayipv6}{$ifscope}");
446
			mwexec("/sbin/route change -inet6 default " . escapeshellarg($gatewayipv6) ."{$ifscope}");
447
		}
448
	}
449

    
450
	$static_routes = get_staticroutes();
451
	if (count($static_routes)) {
452
		$gateways_arr = return_gateways_array(false, true);
453

    
454
		foreach ($static_routes as $rtent) {
455
			$gatewayip = "";
456
			if (empty($gateways_arr[$rtent['gateway']])) {
457
				log_error(sprintf(gettext("Static Routes: Gateway IP could not be found for %s"), $rtent['network']));
458
				continue;
459
			}
460
			$gateway = $gateways_arr[$rtent['gateway']];
461
			if (!empty($interface) && $interface != $gateway['friendlyiface'])
462
				continue;
463

    
464
			/* XXX: This is a bit dangerous in case of routing daemons!? */
465
			if(isset($rtent['disabled'])) {
466
				mwexec("/sbin/route delete " . escapeshellarg($rtent['network']), true);
467
				continue;
468
			}
469

    
470
			$gatewayip = $gateway['gateway'];
471
			$interfacegw = $gateway['interface'];
472

    
473
			$blackhole = "";
474
			if (!strcasecmp("Null", substr($rtent['gateway'], 0, 3)))
475
				$blackhole = "-blackhole";
476

    
477
			if (is_subnetv6($rtent['network'])) {
478
				if (is_ipaddrv6($gatewayip))
479
					mwexec("/sbin/route change -inet6 {$blackhole} " . escapeshellarg($rtent['network']) .
480
						" " . escapeshellarg($gatewayip));
481
				else if (!empty($interfacegw))
482
					mwexec("/sbin/route change -inet6 {$blackhole} " . escapeshellarg($rtent['network']) .
483
						" -iface " . escapeshellarg($interfacegw));
484
			 } else if (is_subnetv4($rtent['network'])) {
485
				if (is_ipaddrv4($gatewayip))
486
					mwexec("/sbin/route change -inet {$blackhole} " . escapeshellarg($rtent['network']) .
487
						" " . escapeshellarg($gatewayip));
488
				else if (!empty($interfacegw))
489
					mwexec("/sbin/route change -inet {$blackhole} " . escapeshellarg($rtent['network']) .
490
						" -iface " . escapeshellarg($interfacegw));
491
			}
492
		}
493
		unset($gateways_arr);
494
	}
495
	unset($static_routes);
496

    
497
	return 0;
498
}
499

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

    
507
	mwexec("/sbin/sysctl net.inet.ip.forwarding=1");
508
	mwexec("/sbin/sysctl net.inet6.ip6.forwarding=1");
509
	return;
510
}
511

    
512
function system_syslogd_fixup_server($server) {
513
	/* If it's an IPv6 IP alone, encase it in brackets */
514
	if (is_ipaddrv6($server))
515
		return "[$server]";
516
	else
517
		return $server;
518
}
519

    
520
function system_syslogd_get_remote_servers($syslogcfg, $facility = "*.*") {
521
	// Rather than repeatedly use the same code, use this function to build a list of remote servers.
522
	$facility .= " ".
523
	$remote_servers = "";
524
	$pad_to  = 56;
525
	$padding = ceil(($pad_to - strlen($facility))/8)+1;
526
	if($syslogcfg['remoteserver'])
527
		$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver']) . "\n";
528
	if($syslogcfg['remoteserver2'])
529
		$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver2']) . "\n";
530
	if($syslogcfg['remoteserver3'])
531
		$remote_servers .= "{$facility}" . str_repeat("\t", $padding) . "@" . system_syslogd_fixup_server($syslogcfg['remoteserver3']) . "\n";
532
	return $remote_servers;
533
}
534

    
535
function system_syslogd_start() {
536
	global $config, $g;
537
	if(isset($config['system']['developerspew'])) {
538
		$mt = microtime();
539
		echo "system_syslogd_start() being called $mt\n";
540
	}
541

    
542
	mwexec("/etc/rc.d/hostid start");
543

    
544
	$syslogcfg = $config['syslog'];
545

    
546
	if ($g['booting'])
547
		echo gettext("Starting syslog...");
548
	else
549
		killbypid("{$g['varrun_path']}/syslog.pid");
550

    
551
	if (is_process_running("syslogd"))
552
		mwexec('/bin/pkill syslogd');
553
	if (is_process_running("fifolog_writer"))
554
		mwexec('/bin/pkill fifolog_writer');
555

    
556
	// Which logging type are we using this week??
557
	if (isset($config['system']['disablesyslogclog'])) {
558
		$log_directive = "";
559
		$log_create_directive = "/usr/bin/touch ";
560
		$log_size = "";
561
	} else if (isset($config['system']['usefifolog'])) {
562
		$log_directive = "|/usr/sbin/fifolog_writer ";
563
		$log_size = "10240";
564
		$log_create_directive = "/usr/sbin/fifolog_create -s ";
565
	} else { // Defaults to CLOG
566
		$log_directive = "%";
567
		$log_size = "10240";
568
		$log_create_directive = "/usr/sbin/clog -i -s ";
569
	}
570
	
571
	if (isset($syslogcfg)) {
572
		$separatelogfacilities = array('ntp','ntpd','ntpdate','racoon','openvpn','pptps','poes','l2tps','relayd','hostapd','dnsmasq','filterdns','unbound','dhcpd','dhcrelay','dhclient','apinger','radvd','routed','olsrd','zebra','ospfd','bgpd','miniupnpd');
573
		$syslogconf = "";
574
		if($config['installedpackages']['package']) {
575
			foreach($config['installedpackages']['package'] as $package) {
576
				if($package['logging']) {
577
					array_push($separatelogfacilities, $package['logging']['facilityname']);
578
					mwexec("{$log_create_directive} {$log_size} {$g['varlog_path']}/{$package['logging']['logfilename']}");
579
					$syslogconf .= "!{$package['logging']['facilityname']}\n*.*\t\t\t\t\t\t {$log_directive}{$g['varlog_path']}/{$package['logging']['logfilename']}\n";
580
				}
581
			}
582
		}
583
		$facilitylist = implode(',', array_unique($separatelogfacilities));
584
		$syslogconf .= "!radvd,routed,olsrd,zebra,ospfd,bgpd,miniupnpd\n";
585
		if (!isset($syslogcfg['disablelocallogging']))
586
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/routing.log\n";
587

    
588
		$syslogconf .= "!ntp,ntpd,ntpdate\n";
589
		if (!isset($syslogcfg['disablelocallogging'])) 
590
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ntpd.log\n";
591

    
592
		$syslogconf .= "!ppp\n";
593
		if (!isset($syslogcfg['disablelocallogging'])) 
594
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ppp.log\n";
595

    
596
		$syslogconf .= "!pptps\n";
597
		if (!isset($syslogcfg['disablelocallogging'])) 
598
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/pptps.log\n";
599

    
600
		$syslogconf .= "!poes\n";
601
		if (!isset($syslogcfg['disablelocallogging'])) 
602
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/poes.log\n";
603

    
604
		$syslogconf .= "!l2tps\n";
605
		if (!isset($syslogcfg['disablelocallogging'])) 
606
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/l2tps.log\n";
607

    
608
		$syslogconf .= "!racoon\n";
609
		if (!isset($syslogcfg['disablelocallogging'])) 
610
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/ipsec.log\n";
611
		if (isset($syslogcfg['vpn']))
612
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
613

    
614
		$syslogconf .= "!openvpn\n";
615
		if (!isset($syslogcfg['disablelocallogging'])) 
616
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/openvpn.log\n";
617
		if (isset($syslogcfg['vpn']))
618
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
619

    
620
		$syslogconf .= "!apinger\n";
621
		if (!isset($syslogcfg['disablelocallogging']))
622
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/gateways.log\n";
623
		if (isset($syslogcfg['apinger']))
624
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
625

    
626
		$syslogconf .= "!dnsmasq,filterdns,unbound\n";
627
		if (!isset($syslogcfg['disablelocallogging']))
628
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/resolver.log\n";
629
		if (isset($syslogcfg['apinger']))
630
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
631

    
632
		$syslogconf .= "!dhcpd,dhcrelay,dhclient\n";
633
		if (!isset($syslogcfg['disablelocallogging']))
634
			$syslogconf .= "*.*								{$log_directive}{$g['varlog_path']}/dhcpd.log\n";
635
		if (isset($syslogcfg['apinger']))
636
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
637

    
638
		$syslogconf .= "!relayd\n";
639
		if (!isset($syslogcfg['disablelocallogging']))
640
			$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/relayd.log\n";
641
		if (isset($syslogcfg['relayd']))
642
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
643

    
644
		$syslogconf .= "!hostapd\n";
645
		if (!isset($syslogcfg['disablelocallogging']))
646
			$syslogconf .= "*.* 								{$log_directive}{$g['varlog_path']}/wireless.log\n";
647
		if (isset($syslogcfg['hostapd']))
648
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
649

    
650
		$syslogconf .= "!-{$facilitylist}\n";
651
		if (!isset($syslogcfg['disablelocallogging'])) 
652
			$syslogconf .= <<<EOD
653
local0.*							{$log_directive}{$g['varlog_path']}/filter.log
654
local3.*							{$log_directive}{$g['varlog_path']}/vpn.log
655
local4.*							{$log_directive}{$g['varlog_path']}/portalauth.log
656
local7.*							{$log_directive}{$g['varlog_path']}/dhcpd.log
657
*.notice;kern.debug;lpr.info;mail.crit;daemon.none;		{$log_directive}{$g['varlog_path']}/system.log
658
news.err;local0.none;local3.none;local4.none;			{$log_directive}{$g['varlog_path']}/system.log
659
local7.none							{$log_directive}{$g['varlog_path']}/system.log
660
security.*							{$log_directive}{$g['varlog_path']}/system.log
661
auth.info;authpriv.info;daemon.info				{$log_directive}{$g['varlog_path']}/system.log
662
auth.info;authpriv.info 					|exec /usr/local/sbin/sshlockout_pf 15
663
*.emerg								*
664

    
665
EOD;
666
		if (isset($syslogcfg['filter']))
667
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local0.*");
668
		if (isset($syslogcfg['vpn']))
669
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local3.*");
670
		if (isset($syslogcfg['portalauth']))
671
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local4.*");
672
		if (isset($syslogcfg['dhcp']))
673
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "local7.*");
674
		if (isset($syslogcfg['system'])) {
675
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.notice;kern.debug;lpr.info;mail.crit;");
676
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "news.err;local0.none;local3.none;local7.none");
677
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "security.*");
678
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "auth.info;authpriv.info;daemon.info");
679
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.emerg");
680
		}
681
		if (isset($syslogcfg['logall'])) {
682
			// Make everything mean everything, including facilities excluded above.
683
			$syslogconf .= "!*\n";
684
			$syslogconf .= system_syslogd_get_remote_servers($syslogcfg, "*.*");
685
		}
686

    
687
		if (isset($syslogcfg['zmqserver'])) {
688
				$syslogconf .= <<<EOD
689
*.*								^{$syslogcfg['zmqserver']}
690

    
691
EOD;
692
		}
693
		/* write syslog.conf */		
694
		if (!@file_put_contents("{$g['varetc_path']}/syslog.conf", $syslogconf)) {
695
			printf(gettext("Error: cannot open syslog.conf in system_syslogd_start().%s"), "\n");
696
			unset($syslogconf);
697
			return 1;
698
		}
699
		unset($syslogconf);
700

    
701
		// Ensure that the log directory exists
702
		if (!is_dir("{$g['dhcpd_chroot_path']}/var/run"))
703
			exec("/bin/mkdir -p {$g['dhcpd_chroot_path']}/var/run");
704

    
705
		$retval = mwexec_bg("/usr/sbin/syslogd -s -c -c -l {$g['dhcpd_chroot_path']}/var/run/log -f {$g['varetc_path']}/syslog.conf");
706

    
707
	} else {
708
		$retval = mwexec_bg("/usr/sbin/syslogd -s -c -c -l {$g['dhcpd_chroot_path']}/var/run/log");
709
	}
710

    
711
	if ($g['booting'])
712
		echo gettext("done.") . "\n";
713

    
714
	return $retval;
715
}
716

    
717
function system_pccard_start() {
718
	global $config, $g;
719
	if(isset($config['system']['developerspew'])) {
720
		$mt = microtime();
721
		echo "system_pccard_start() being called $mt\n";
722
	}
723

    
724
	if ($g['booting'])
725
		echo gettext("Initializing PCMCIA...");
726

    
727
	/* kill any running pccardd */
728
	killbypid("{$g['varrun_path']}/pccardd.pid");
729

    
730
	/* fire up pccardd */
731
	$res = mwexec("/usr/sbin/pccardd -z -f {$g['etc_path']}/pccard.conf");
732

    
733
	if ($g['booting']) {
734
		if ($res == 0)
735
			echo gettext("done.") . "\n";
736
		else
737
			echo gettext("failed!") . "\n";
738
	}
739

    
740
	return $res;
741
}
742

    
743

    
744
function system_webgui_start() {
745
	global $config, $g;
746

    
747
	if ($g['booting'])
748
		echo gettext("Starting webConfigurator...");
749

    
750
	chdir($g['www_path']);
751

    
752
	/* defaults */
753
	$portarg = "80";
754
	$crt = "";
755
	$key = "";
756
	$ca = "";
757

    
758
	/* non-standard port? */
759
	if (isset($config['system']['webgui']['port']) && $config['system']['webgui']['port'] <> "")
760
		$portarg = "{$config['system']['webgui']['port']}";
761

    
762
	if ($config['system']['webgui']['protocol'] == "https") {
763
		// Ensure that we have a webConfigurator CERT
764
		$cert =& lookup_cert($config['system']['webgui']['ssl-certref']);
765
		if(!is_array($cert) && !$cert['crt'] && !$cert['prv']) {
766
			if (!is_array($config['ca']))
767
				$config['ca'] = array();
768
			$a_ca =& $config['ca'];
769
			if (!is_array($config['cert']))
770
				$config['cert'] = array();
771
			$a_cert =& $config['cert'];
772
			log_error("Creating SSL Certificate for this host");
773
			$cert = array();
774
			$cert['refid'] = uniqid();
775
			$cert['descr'] = gettext("webConfigurator default");
776
			mwexec("/usr/local/bin/openssl genrsa 1024 > {$g['tmp_path']}/ssl.key");
777
			mwexec("/usr/local/bin/openssl req -new -x509 -nodes -sha256 -days 2000 -key {$g['tmp_path']}/ssl.key > {$g['tmp_path']}/ssl.crt");
778
			$crt = file_get_contents("{$g['tmp_path']}/ssl.crt");
779
			$key = file_get_contents("{$g['tmp_path']}/ssl.key");
780
			unlink("{$g['tmp_path']}/ssl.key");
781
			unlink("{$g['tmp_path']}/ssl.crt");
782
			cert_import($cert, $crt, $key);
783
			$a_cert[] = $cert;
784
			$config['system']['webgui']['ssl-certref'] = $cert['refid'];
785
			write_config(gettext("Importing HTTPS certificate"));
786
			if(!$config['system']['webgui']['port'])
787
				$portarg = "443";
788
			$ca = ca_chain($cert);
789
		} else {
790
			$crt = base64_decode($cert['crt']);
791
			$key = base64_decode($cert['prv']);
792
			if(!$config['system']['webgui']['port'])
793
				$portarg = "443";
794
			$ca = ca_chain($cert);
795
		}
796
	}
797

    
798
	/* generate lighttpd configuration */
799
	system_generate_lighty_config("{$g['varetc_path']}/lighty-webConfigurator.conf",
800
		$crt, $key, $ca, "lighty-webConfigurator.pid", $portarg, "/usr/local/www/",
801
		"cert.pem", "ca.pem");
802

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

    
806
	sleep(1);
807

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

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

    
813
	if ($g['booting']) {
814
		if ($res == 0)
815
			echo gettext("done.") . "\n";
816
		else
817
			echo gettext("failed!") . "\n";
818
	}
819

    
820
	return $res;
821
}
822

    
823
function system_generate_lighty_config($filename,
824
	$cert,
825
	$key,
826
	$ca,
827
	$pid_file,
828
	$port = 80,
829
	$document_root = "/usr/local/www/",
830
	$cert_location = "cert.pem",
831
	$ca_location = "ca.pem",
832
	$captive_portal = false) {
833

    
834
	global $config, $g;
835

    
836
	if(!is_dir("{$g['tmp_path']}/lighttpdcompress"))
837
		mkdir("{$g['tmp_path']}/lighttpdcompress");
838

    
839
	if(isset($config['system']['developerspew'])) {
840
		$mt = microtime();
841
		echo "system_generate_lighty_config() being called $mt\n";
842
	}
843

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

    
848
		$maxprocperip = $config['captiveportal'][$captive_portal]['maxprocperip'];
849
		if (empty($maxprocperip))
850
			$maxprocperip = 10;
851
		$captive_portal_mod_evasive = "evasive.max-conns-per-ip = {$maxprocperip}";
852

    
853
		$server_upload_dirs = "server.upload-dirs = ( \"{$g['tmp_path']}/captiveportal/\" )\n";
854
		exec("mkdir -p {$g['tmp_path']}/captiveportal");
855
		exec("chmod a-w {$g['tmp_path']}/captiveportal");
856
		$server_max_request_size = "server.max-request-size    = 384";
857
		$cgi_config = "";
858
	} else {
859
		$captiveportal = ",\"mod_cgi\"";
860
		$captive_portal_rewrite = "";
861
		$captive_portal_mod_evasive = "";
862
		$server_upload_dirs = "server.upload-dirs = ( \"{$g['upload_path']}/\", \"{$g['tmp_path']}/\", \"/var/\" )\n";
863
		$server_max_request_size = "server.max-request-size    = 2097152";
864
		$cgi_config = "cgi.assign                 = ( \".cgi\" => \"\" )";
865
	}
866
	
867
	if (empty($port))
868
		$lighty_port = "80";
869
	else
870
		$lighty_port = $port;
871

    
872
	$memory = get_memory();
873
	$avail = $memory[1];
874

    
875
	// Determine web GUI process settings and take into account low memory systems
876
	if ($avail < 255)
877
		$max_procs = 1;
878
	else
879
		$max_procs = ($config['system']['webgui']['max_procs']) ? $config['system']['webgui']['max_procs'] : 2;
880

    
881
	// Ramp up captive portal max procs, assuming each PHP process can consume up to 64MB RAM 
882
	if ($captive_portal !== false)  {
883
		if ($avail > 135 and $avail < 256) {
884
			$max_procs += 1; // 2 worker processes
885
		} else if ($avail > 255 and $avail < 513) {
886
			$max_procs += 2; // 3 worker processes
887
		} else if ($avail > 512) {
888
			$max_procs += 4; // 6 worker processes
889
		}
890
		if ($max_procs > 1)
891
			$max_php_children = intval($max_procs/2);
892
		else
893
			$max_php_children = 1;
894

    
895
	} else {
896
		if ($avail < 78)
897
			$max_php_children = 0;
898
		else
899
			$max_php_children = 1;
900
	}
901

    
902
	if ($captive_portal !== false)
903
		$fast_cgi_path = "{$g['tmp_path']}/php-fastcgi-{$captive_portal}.socket";
904
	else
905
		$fast_cgi_path = "{$g['tmp_path']}/php-fastcgi.socket";
906

    
907
	$fastcgi_config = <<<EOD
908
#### fastcgi module
909
## read fastcgi.txt for more info
910
fastcgi.server = ( ".php" =>
911
	( "localhost" =>
912
		(
913
			"socket" => "{$fast_cgi_path}",
914
			"max-procs" => {$max_procs},
915
			"bin-environment" => (
916
				"PHP_FCGI_CHILDREN" => "{$max_php_children}",
917
				"PHP_FCGI_MAX_REQUESTS" => "500"
918
			),
919
			"bin-path" => "/usr/local/bin/php"
920
		)
921
	)
922
)
923

    
924
EOD;
925

    
926
	$lighty_config = <<<EOD
927
#
928
# lighttpd configuration file
929
#
930
# use a it as base for lighttpd 1.0.0 and above
931
#
932
############ Options you really have to take care of ####################
933

    
934
## FreeBSD!
935
server.event-handler	= "freebsd-kqueue"
936
server.network-backend 	= "writev"
937
#server.use-ipv6 = "enable"
938

    
939
## modules to load
940
server.modules              =   ( "mod_access", "mod_expire", "mod_compress", "mod_redirect",
941
	{$captiveportal}, "mod_fastcgi"
942
)
943

    
944
server.max-keep-alive-requests = 15
945
server.max-keep-alive-idle = 30
946

    
947
## a static document-root, for virtual-hosting take look at the
948
## server.virtual-* options
949
server.document-root        = "{$document_root}"
950
{$captive_portal_rewrite}
951

    
952
# Maximum idle time with nothing being written (php downloading)
953
server.max-write-idle = 999
954

    
955
## where to send error-messages to
956
server.errorlog-use-syslog="enable"
957

    
958
# files to check for if .../ is requested
959
server.indexfiles           = ( "index.php", "index.html",
960
                                "index.htm", "default.htm" )
961

    
962
# mimetype mapping
963
mimetype.assign             = (
964
  ".pdf"          =>      "application/pdf",
965
  ".sig"          =>      "application/pgp-signature",
966
  ".spl"          =>      "application/futuresplash",
967
  ".class"        =>      "application/octet-stream",
968
  ".ps"           =>      "application/postscript",
969
  ".torrent"      =>      "application/x-bittorrent",
970
  ".dvi"          =>      "application/x-dvi",
971
  ".gz"           =>      "application/x-gzip",
972
  ".pac"          =>      "application/x-ns-proxy-autoconfig",
973
  ".swf"          =>      "application/x-shockwave-flash",
974
  ".tar.gz"       =>      "application/x-tgz",
975
  ".tgz"          =>      "application/x-tgz",
976
  ".tar"          =>      "application/x-tar",
977
  ".zip"          =>      "application/zip",
978
  ".mp3"          =>      "audio/mpeg",
979
  ".m3u"          =>      "audio/x-mpegurl",
980
  ".wma"          =>      "audio/x-ms-wma",
981
  ".wax"          =>      "audio/x-ms-wax",
982
  ".ogg"          =>      "audio/x-wav",
983
  ".wav"          =>      "audio/x-wav",
984
  ".gif"          =>      "image/gif",
985
  ".jpg"          =>      "image/jpeg",
986
  ".jpeg"         =>      "image/jpeg",
987
  ".png"          =>      "image/png",
988
  ".xbm"          =>      "image/x-xbitmap",
989
  ".xpm"          =>      "image/x-xpixmap",
990
  ".xwd"          =>      "image/x-xwindowdump",
991
  ".css"          =>      "text/css",
992
  ".html"         =>      "text/html",
993
  ".htm"          =>      "text/html",
994
  ".js"           =>      "text/javascript",
995
  ".asc"          =>      "text/plain",
996
  ".c"            =>      "text/plain",
997
  ".conf"         =>      "text/plain",
998
  ".text"         =>      "text/plain",
999
  ".txt"          =>      "text/plain",
1000
  ".dtd"          =>      "text/xml",
1001
  ".xml"          =>      "text/xml",
1002
  ".mpeg"         =>      "video/mpeg",
1003
  ".mpg"          =>      "video/mpeg",
1004
  ".mov"          =>      "video/quicktime",
1005
  ".qt"           =>      "video/quicktime",
1006
  ".avi"          =>      "video/x-msvideo",
1007
  ".asf"          =>      "video/x-ms-asf",
1008
  ".asx"          =>      "video/x-ms-asf",
1009
  ".wmv"          =>      "video/x-ms-wmv",
1010
  ".bz2"          =>      "application/x-bzip",
1011
  ".tbz"          =>      "application/x-bzip-compressed-tar",
1012
  ".tar.bz2"      =>      "application/x-bzip-compressed-tar"
1013
 )
1014

    
1015
# Use the "Content-Type" extended attribute to obtain mime type if possible
1016
#mimetypes.use-xattr        = "enable"
1017

    
1018
## deny access the file-extensions
1019
#
1020
# ~    is for backupfiles from vi, emacs, joe, ...
1021
# .inc is often used for code includes which should in general not be part
1022
#      of the document-root
1023
url.access-deny             = ( "~", ".inc" )
1024

    
1025

    
1026
######### Options that are good to be but not neccesary to be changed #######
1027

    
1028
## bind to port (default: 80)
1029

    
1030
EOD;
1031

    
1032
	$lighty_config .= "server.bind  = \"0.0.0.0\"\n";
1033
	$lighty_config .= "server.port  = {$lighty_port}\n";
1034
	$lighty_config .= "\$SERVER[\"socket\"]  == \"0.0.0.0:{$lighty_port}\" { }\n";
1035
	$lighty_config .= "\$SERVER[\"socket\"]  == \"[::]:{$lighty_port}\" { \n";
1036
	if($cert <> "" and $key <> "") {
1037
		$lighty_config .= "\n";
1038
		$lighty_config .= "## ssl configuration\n";
1039
		$lighty_config .= "ssl.engine = \"enable\"\n";
1040
		$lighty_config .= "ssl.pemfile = \"{$g['varetc_path']}/{$cert_location}\"\n\n";
1041
		if($ca <> "")
1042
			$lighty_config .= "ssl.ca-file = \"{$g['varetc_path']}/{$ca_location}\"\n\n";
1043
	}
1044
	$lighty_config .= " }\n";
1045

    
1046

    
1047
	$lighty_config .= <<<EOD
1048

    
1049
## error-handler for status 404
1050
#server.error-handler-404   = "/error-handler.html"
1051
#server.error-handler-404   = "/error-handler.php"
1052

    
1053
## to help the rc.scripts
1054
server.pid-file            = "{$g['varrun_path']}/{$pid_file}"
1055

    
1056
## virtual directory listings
1057
server.dir-listing         = "disable"
1058

    
1059
## enable debugging
1060
debug.log-request-header   = "disable"
1061
debug.log-response-header  = "disable"
1062
debug.log-request-handling = "disable"
1063
debug.log-file-not-found   = "disable"
1064

    
1065
# gzip compression
1066
compress.cache-dir = "{$g['tmp_path']}/lighttpdcompress/"
1067
compress.filetype  = ("text/plain","text/css", "text/xml", "text/javascript" )
1068

    
1069
{$server_upload_dirs}
1070

    
1071
{$server_max_request_size}
1072

    
1073
{$fastcgi_config}
1074

    
1075
{$cgi_config}
1076

    
1077
{$captive_portal_mod_evasive}
1078

    
1079
expire.url = (
1080
				"" => "access 50 hours",	
1081
        )
1082

    
1083
EOD;
1084

    
1085
	$cert = str_replace("\r", "", $cert);
1086
	$key = str_replace("\r", "", $key);
1087
	$ca = str_replace("\r", "", $ca);
1088

    
1089
	$cert = str_replace("\n\n", "\n", $cert);
1090
	$key = str_replace("\n\n", "\n", $key);
1091
	$ca = str_replace("\n\n", "\n", $ca);
1092

    
1093
	if($cert <> "" and $key <> "") {
1094
		$fd = fopen("{$g['varetc_path']}/{$cert_location}", "w");
1095
		if (!$fd) {
1096
			printf(gettext("Error: cannot open cert.pem in system_webgui_start().%s"), "\n");
1097
			return 1;
1098
		}
1099
		chmod("{$g['varetc_path']}/{$cert_location}", 0600);
1100
		fwrite($fd, $cert);
1101
		fwrite($fd, "\n");
1102
		fwrite($fd, $key);
1103
		fclose($fd);
1104
		if(!(empty($ca) || (strlen(trim($ca)) == 0))) {
1105
			$fd = fopen("{$g['varetc_path']}/{$ca_location}", "w");
1106
			if (!$fd) {
1107
				printf(gettext("Error: cannot open ca.pem in system_webgui_start().%s"), "\n");
1108
				return 1;
1109
			}
1110
			chmod("{$g['varetc_path']}/{$ca_location}", 0600);
1111
			fwrite($fd, $ca);
1112
			fclose($fd);
1113
		}
1114
		$lighty_config .= "\n";
1115
		$lighty_config .= "## " . gettext("ssl configuration") . "\n";
1116
		$lighty_config .= "ssl.engine = \"enable\"\n";
1117
		$lighty_config .= "ssl.pemfile = \"{$g['varetc_path']}/{$cert_location}\"\n\n";
1118

    
1119
		// Harden SSL a bit for PCI conformance testing
1120
		$lighty_config .= "ssl.use-sslv2 = \"disable\"\n";
1121
		$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";
1122

    
1123
		if(!(empty($ca) || (strlen(trim($ca)) == 0)))
1124
			$lighty_config .= "ssl.ca-file = \"{$g['varetc_path']}/{$ca_location}\"\n\n";
1125
	}
1126

    
1127
	// Add HTTP to HTTPS redirect	
1128
	if ($captive_portal === false && $config['system']['webgui']['protocol'] == "https" && !isset($config['system']['webgui']['disablehttpredirect'])) {
1129
		if($lighty_port != "443") 
1130
			$redirectport = ":{$lighty_port}";
1131
		$lighty_config .= <<<EOD
1132
\$SERVER["socket"] == ":80" {
1133
	\$HTTP["host"] =~ "(.*)" {
1134
		url.redirect = ( "^/(.*)" => "https://%1{$redirectport}/$1" )
1135
	}
1136
}
1137
EOD;
1138
	}
1139

    
1140
	$fd = fopen("{$filename}", "w");
1141
	if (!$fd) {
1142
		printf(gettext("Error: cannot open %s in system_generate_lighty_config().%s"), $filename, "\n");
1143
		return 1;
1144
	}
1145
	fwrite($fd, $lighty_config);
1146
	fclose($fd);
1147

    
1148
	return 0;
1149

    
1150
}
1151

    
1152
function system_timezone_configure() {
1153
	global $config, $g;
1154
	if(isset($config['system']['developerspew'])) {
1155
		$mt = microtime();
1156
		echo "system_timezone_configure() being called $mt\n";
1157
	}
1158

    
1159
	$syscfg = $config['system'];
1160

    
1161
	if ($g['booting'])
1162
		echo gettext("Setting timezone...");
1163

    
1164
	/* extract appropriate timezone file */
1165
	$timezone = $syscfg['timezone'];
1166
	if (!$timezone)
1167
		$timezone = "Etc/UTC";
1168

    
1169
	conf_mount_rw();
1170

    
1171
	exec("LANG=C /usr/bin/tar xzfO /usr/share/zoneinfo.tgz " .
1172
		escapeshellarg($timezone) . " > /etc/localtime");
1173

    
1174
	mwexec("sync");
1175
	conf_mount_ro();
1176

    
1177
	if ($g['booting'])
1178
		echo gettext("done.") . "\n";
1179
}
1180

    
1181
function system_ntp_setup_gps($serialport) {
1182
	$gps_device = '/dev/gps0';
1183
	$serialport = '/dev/'.$serialport;
1184

    
1185
	if (!file_exists($serialport))
1186
		return false;
1187

    
1188
	conf_mount_rw();
1189
	// Create symlink that ntpd requires
1190
	unlink_if_exists($gps_device);
1191
	symlink($serialport, $gps_device);
1192

    
1193
	/* Send the following to the GPS port to initialize the GPS */
1194
	$gps_init = <<<EOF
1195
\$PUBX,40,GSV,0,0,0,0*59
1196
\$PUBX,40,GLL,0,0,0,0*5C
1197
\$PUBX,40,ZDA,0,0,0,0*44
1198
\$PUBX,40,VTG,0,0,0,0*5E
1199
\$PUBX,40,GSV,0,0,0,0*59
1200
\$PUBX,40,GSA,0,0,0,0*4E
1201
\$PUBX,40,GGA,0,0,0,0
1202
\$PUBX,40,TXT,0,0,0,0
1203
\$PUBX,40,RMC,0,0,0,0*46
1204
\$PUBX,41,1,0007,0003,4800,0
1205
\$PUBX,40,ZDA,1,1,1,1
1206
EOF;
1207
	file_put_contents("/tmp/gps.init", $gps_init);
1208
	`cat /tmp/gps.init > $serialport`;
1209

    
1210
	/* Add /etc/remote entry in case we need to read from the GPS with tip */
1211
	if (intval(`grep -c '^gps0' /etc/remote`) == 0)
1212
		`echo "gps0:dv={$serialport}:br#4800:pa=none:" >> /etc/remote`;
1213

    
1214
	conf_mount_ro();
1215

    
1216
	return true;
1217
}
1218

    
1219
function system_ntp_configure($start_ntpd=true) {
1220
	global $config, $g;
1221
	$driftfile = "/var/db/ntpd.drift";
1222
	$statsdir = "/var/log/ntp";
1223
	$gps_device = '/dev/gps0';
1224

    
1225
	if ($g['platform'] == 'jail')
1226
		return;
1227

    
1228
	safe_mkdir($statsdir);
1229

    
1230
	$ntpcfg = "# \n";
1231
	$ntpcfg .= "# pfSense ntp configuration file \n";
1232
	$ntpcfg .= "# \n\n";
1233
	$ntpcfg .= "tinker panic 0 \n";
1234

    
1235
	if (!empty($config['ntpd']['gpsport'])
1236
		&& file_exists('/dev/'.$config['ntpd']['gpsport'])
1237
		&& system_ntp_setup_gps($config['ntpd']['gpsport'])) {
1238
		$ntpcfg .= "# GPS Setup\n";
1239
		$ntpcfg .= "server 127.127.20.0 mode 0 minpoll 4 maxpoll 4 prefer\n";
1240
		$ntpcfg .= "fudge 127.127.20.0 time1 0.155 time2 0.000 flag1 1 flag2 0 flag3 1\n";
1241
		// Fall back to local clock if GPS is out of sync?
1242
		$ntpcfg .= "server 127.127.1.0\n";
1243
		$ntpcfg .= "fudge 127.127.1.0 stratum 12\n";
1244
	}
1245

    
1246
	$ntpcfg .= "\n\n# Upstream Servers\n";
1247
	/* foreach through servers and write out to ntpd.conf */
1248
	foreach (explode(' ', $config['system']['timeservers']) as $ts)
1249
		$ntpcfg .= "server {$ts} iburst maxpoll 9\n";
1250

    
1251
	$ntpcfg .= "enable monitor\n";
1252
	$ntpcfg .= "enable stats\n";
1253
	$ntpcfg .= "statistics clockstats\n";
1254
	$ntpcfg .= "statsdir {$statsdir}\n";
1255
	$ntpcfg .= "logconfig =syncall +clockall\n";
1256
	$ntpcfg .= "driftfile {$driftfile}\n";
1257
	$ntpcfg .= "restrict default kod nomodify notrap nopeer\n";
1258
	$ntpcfg .= "restrict -6 default kod nomodify notrap nopeer\n";
1259

    
1260
	if (empty($config['ntpd']['interface']))
1261
		if (is_array($config['installedpackages']['openntpd']) && !empty($config['installedpackages']['openntpd']['config'][0]['interface']))
1262
			$interfaces = explode(",", $config['installedpackages']['openntpd']['config'][0]['interface']);
1263
		else
1264
			$interfaces = array();
1265
	else
1266
		$interfaces = explode(",", $config['ntpd']['interface']);
1267

    
1268
	if (is_array($interfaces) && count($interfaces)) {
1269
		$ntpcfg .= "interface ignore all\n";
1270
		foreach ($interfaces as $interface) {
1271
			if (!is_ipaddr($interface)) {
1272
				$interface = get_real_interface($interface);
1273
			}
1274
			$ntpcfg .= "interface listen {$interface}\n";
1275
		}
1276
	}
1277

    
1278
	/* open configuration for wrting or bail */
1279
	if (!@file_put_contents("{$g['varetc_path']}/ntpd.conf", $ntpcfg)) {
1280
		log_error("Could not open {$g['varetc_path']}/ntpd.conf for writing");
1281
		return;
1282
	}
1283

    
1284
	/* At bootup we just want to write out the config. */
1285
	if (!$start_ntpd)
1286
		return;
1287

    
1288
	/* if ntpd is running, kill it */
1289
	while (isvalidpid("{$g['varrun_path']}/ntpd.pid")) {
1290
		killbypid("{$g['varrun_path']}/ntpd.pid");
1291
	}
1292
	@unlink("{$g['varrun_path']}/ntpd.pid");
1293

    
1294
	/* if /var/empty does not exist, create it */
1295
	if(!is_dir("/var/empty"))
1296
		exec("/bin/mkdir -p /var/empty && chmod ug+rw /var/empty/.");
1297

    
1298
	/* start opentpd, set time now and use /var/etc/ntpd.conf */
1299
	mwexec("/usr/local/bin/ntpd -g -c {$g['varetc_path']}/ntpd.conf -p {$g['varrun_path']}/ntpd.pid", false, true);
1300
	
1301
	// Note that we are starting up
1302
	log_error("NTPD is starting up.");
1303
	return;
1304
}
1305

    
1306
function sync_system_time() {
1307
	global $config, $g;
1308

    
1309
	if ($g['booting'])
1310
		echo gettext("Syncing system time before startup...");
1311

    
1312
	/* foreach through servers and write out to ntpd.conf */
1313
	foreach (explode(' ', $config['system']['timeservers']) as $ts) {
1314
		mwexec("/usr/sbin/ntpdate -s $ts");
1315
	}
1316
	
1317
	if ($g['booting'])
1318
		echo gettext("done.") . "\n";
1319
	
1320
}
1321

    
1322
function system_halt() {
1323
	global $g;
1324

    
1325
	system_reboot_cleanup();
1326

    
1327
	mwexec("/usr/bin/nohup /etc/rc.halt > /dev/null 2>&1 &");
1328
}
1329

    
1330
function system_reboot() {
1331
	global $g;
1332

    
1333
	system_reboot_cleanup();
1334

    
1335
	mwexec("nohup /etc/rc.reboot > /dev/null 2>&1 &");
1336
}
1337

    
1338
function system_reboot_sync() {
1339
	global $g;
1340

    
1341
	system_reboot_cleanup();
1342

    
1343
	mwexec("/etc/rc.reboot > /dev/null 2>&1");
1344
}
1345

    
1346
function system_reboot_cleanup() {
1347
	global $config, $cpzone;
1348

    
1349
	mwexec("/usr/local/bin/beep.sh stop");
1350
	require_once("captiveportal.inc");
1351
	if (is_array($config['captiveportal'])) {
1352
		foreach ($config['captiveportal'] as $cpzone=>$cp) {
1353
			captiveportal_radius_stop_all();
1354
			captiveportal_send_server_accounting(true);
1355
		}
1356
	}
1357
	require_once("voucher.inc");
1358
	voucher_save_db_to_config();
1359
	require_once("pkg-utils.inc");
1360
	stop_packages();
1361
}
1362

    
1363
function system_do_shell_commands($early = 0) {
1364
	global $config, $g;
1365
	if(isset($config['system']['developerspew'])) {
1366
		$mt = microtime();
1367
		echo "system_do_shell_commands() being called $mt\n";
1368
	}
1369

    
1370
	if ($early)
1371
		$cmdn = "earlyshellcmd";
1372
	else
1373
		$cmdn = "shellcmd";
1374

    
1375
	if (is_array($config['system'][$cmdn])) {
1376

    
1377
		/* *cmd is an array, loop through */
1378
		foreach ($config['system'][$cmdn] as $cmd) {
1379
			exec($cmd);
1380
		}
1381

    
1382
	} elseif($config['system'][$cmdn] <> "") {
1383

    
1384
		/* execute single item */
1385
		exec($config['system'][$cmdn]);
1386

    
1387
	}
1388
}
1389

    
1390
function system_console_configure() {
1391
	global $config, $g;
1392
	if(isset($config['system']['developerspew'])) {
1393
		$mt = microtime();
1394
		echo "system_console_configure() being called $mt\n";
1395
	}
1396

    
1397
	if (isset($config['system']['disableconsolemenu'])) {
1398
		touch("{$g['varetc_path']}/disableconsole");
1399
	} else {
1400
		unlink_if_exists("{$g['varetc_path']}/disableconsole");
1401
	}
1402
}
1403

    
1404
function system_dmesg_save() {
1405
	global $g;
1406
	if(isset($config['system']['developerspew'])) {
1407
		$mt = microtime();
1408
		echo "system_dmesg_save() being called $mt\n";
1409
	}
1410

    
1411
	$dmesg = "";
1412
	exec("/sbin/dmesg", $dmesg);
1413

    
1414
	/* find last copyright line (output from previous boots may be present) */
1415
	$lastcpline = 0;
1416

    
1417
	for ($i = 0; $i < count($dmesg); $i++) {
1418
		if (strstr($dmesg[$i], "Copyright (c) 1992-"))
1419
			$lastcpline = $i;
1420
	}
1421

    
1422
	$fd = fopen("{$g['varlog_path']}/dmesg.boot", "w");
1423
	if (!$fd) {
1424
		printf(gettext("Error: cannot open dmesg.boot in system_dmesg_save().%s"), "\n");
1425
		return 1;
1426
	}
1427

    
1428
	for ($i = $lastcpline; $i < count($dmesg); $i++)
1429
		fwrite($fd, $dmesg[$i] . "\n");
1430

    
1431
	fclose($fd);
1432

    
1433
	return 0;
1434
}
1435

    
1436
function system_set_harddisk_standby() {
1437
	global $g, $config;
1438
	if(isset($config['system']['developerspew'])) {
1439
		$mt = microtime();
1440
		echo "system_set_harddisk_standby() being called $mt\n";
1441
	}
1442

    
1443
	if (isset($config['system']['harddiskstandby'])) {
1444
		if ($g['booting']) {
1445
			echo gettext('Setting hard disk standby... ');
1446
		}
1447

    
1448
		$standby = $config['system']['harddiskstandby'];
1449
		// Check for a numeric value
1450
		if (is_numeric($standby)) {
1451
			// Sync the disk(s)
1452
			pfSense_sync();
1453
			if (!mwexec('/sbin/sysctl hw.ata.standby=' . ((int)$standby))) {
1454
				// Reinitialize ATA-drives
1455
				mwexec('/usr/local/sbin/atareinit');
1456
				if ($g['booting']) {
1457
					echo gettext("done.") . "\n";
1458
				}
1459
			} else if ($g['booting']) {
1460
				echo gettext("failed!") . "\n";
1461
			}
1462
		} else if ($g['booting']) {
1463
			echo gettext("failed!") . "\n";
1464
		}
1465
	}
1466
}
1467

    
1468
function system_setup_sysctl() {
1469
	global $config;
1470
	if(isset($config['system']['developerspew'])) {
1471
		$mt = microtime();
1472
		echo "system_setup_sysctl() being called $mt\n";
1473
	}
1474

    
1475
	activate_sysctls();	
1476

    
1477
	if (isset($config['system']['sharednet'])) {
1478
		system_disable_arp_wrong_if();
1479
	}
1480
}
1481

    
1482
function system_disable_arp_wrong_if() {
1483
	global $config;
1484
	if(isset($config['system']['developerspew'])) {
1485
		$mt = microtime();
1486
		echo "system_disable_arp_wrong_if() being called $mt\n";
1487
	}
1488
	mwexec("/sbin/sysctl -n net.link.ether.inet.log_arp_wrong_iface=0");
1489
	mwexec("/sbin/sysctl -n net.link.ether.inet.log_arp_movements=0");
1490
}
1491

    
1492
function system_enable_arp_wrong_if() {
1493
	global $config;
1494
	if(isset($config['system']['developerspew'])) {
1495
		$mt = microtime();
1496
		echo "system_enable_arp_wrong_if() being called $mt\n";
1497
	}
1498
	mwexec("/sbin/sysctl -n net.link.ether.inet.log_arp_wrong_iface=1");
1499
	mwexec("/sbin/sysctl -n net.link.ether.inet.log_arp_movements=1");
1500
}
1501

    
1502
function enable_watchdog() {
1503
	global $config;
1504
	return;
1505
	$install_watchdog = false;
1506
	$supported_watchdogs = array("Geode");
1507
	$file = file_get_contents("/var/log/dmesg.boot");
1508
	foreach($supported_watchdogs as $sd) {
1509
		if(stristr($file, "Geode")) {
1510
			$install_watchdog = true;
1511
		}
1512
	}
1513
	if($install_watchdog == true) {
1514
		if(is_process_running("watchdogd"))
1515
			mwexec("/usr/bin/killall watchdogd", true);
1516
		exec("/usr/sbin/watchdogd");
1517
	}
1518
}
1519

    
1520
function system_check_reset_button() {
1521
	global $g;
1522
	if($g['platform'] != "nanobsd")
1523
		return 0;
1524

    
1525
	$specplatform = system_identify_specific_platform();
1526

    
1527
	if ($specplatform['name'] != "wrap" && $specplatform['name'] != "alix")
1528
		return 0;
1529

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

    
1532
	if ($retval == 99) {
1533
		/* user has pressed reset button for 2 seconds - 
1534
		   reset to factory defaults */
1535
		echo <<<EOD
1536

    
1537
***********************************************************************
1538
* Reset button pressed - resetting configuration to factory defaults. *
1539
* The system will reboot after this completes.                        *
1540
***********************************************************************
1541

    
1542

    
1543
EOD;
1544
		
1545
		reset_factory_defaults();
1546
		system_reboot_sync();
1547
		exit(0);
1548
	}
1549

    
1550
	return 0;
1551
}
1552

    
1553
/* attempt to identify the specific platform (for embedded systems)
1554
   Returns an array with two elements:
1555
	name => platform string (e.g. 'wrap', 'alix' etc.)
1556
	descr => human-readable description (e.g. "PC Engines WRAP")
1557
*/
1558
function system_identify_specific_platform() {
1559
	global $g;
1560
	
1561
	if ($g['platform'] == 'generic-pc')
1562
		return array('name' => 'generic-pc', 'descr' => gettext("Generic PC"));
1563
	
1564
	if ($g['platform'] == 'generic-pc-cdrom')
1565
		return array('name' => 'generic-pc-cdrom', 'descr' => gettext("Generic PC (CD-ROM)"));
1566
	
1567
	/* the rest of the code only deals with 'embedded' platforms */
1568
	if ($g['platform'] != 'nanobsd')
1569
		return array('name' => $g['platform'], 'descr' => $g['platform']);
1570
	
1571
	$dmesg = system_get_dmesg_boot();
1572
	
1573
	if (strpos($dmesg, "PC Engines WRAP") !== false)
1574
		return array('name' => 'wrap', 'descr' => gettext('PC Engines WRAP'));
1575
	
1576
	if (strpos($dmesg, "PC Engines ALIX") !== false)
1577
		return array('name' => 'alix', 'descr' => gettext('PC Engines ALIX'));
1578

    
1579
	if (preg_match("/Soekris net45../", $dmesg, $matches))
1580
		return array('name' => 'net45xx', 'descr' => $matches[0]);
1581
	
1582
	if (preg_match("/Soekris net48../", $dmesg, $matches))
1583
		return array('name' => 'net48xx', 'descr' => $matches[0]);
1584
		
1585
	if (preg_match("/Soekris net55../", $dmesg, $matches))
1586
		return array('name' => 'net55xx', 'descr' => $matches[0]);
1587
	
1588
	/* unknown embedded platform */
1589
	return array('name' => 'embedded', 'descr' => gettext('embedded (unknown)'));
1590
}
1591

    
1592
function system_get_dmesg_boot() {
1593
	global $g;
1594
		
1595
	return file_get_contents("{$g['varlog_path']}/dmesg.boot");
1596
}
1597

    
1598
function get_possible_listen_ips($include_ipv6_link_local=false) {
1599
	$interfaces = get_configured_interface_with_descr();
1600
	$carplist = get_configured_carp_interface_list();
1601
	$listenips = array();
1602
	foreach ($carplist as $cif => $carpip)
1603
		$interfaces[$cif] = $carpip." (".get_vip_descr($carpip).")";
1604
	$aliaslist = get_configured_ip_aliases_list();
1605
	foreach ($aliaslist as $aliasip => $aliasif)
1606
		$interfaces[$aliasip] = $aliasip." (".get_vip_descr($aliasip).")";
1607
	foreach ($interfaces as $iface => $ifacename) {
1608
		$tmp["name"]  = $ifacename;
1609
		$tmp["value"] = $iface;
1610
		$listenips[] = $tmp;
1611
		if ($include_ipv6_link_local) {
1612
			$llip = find_interface_ipv6_ll(get_real_interface($iface));
1613
			if (!empty($llip)) {
1614
				$tmp["name"]  = "{$ifacename} IPv6 Link-Local";
1615
				$tmp["value"] = $llip;
1616
				$listenips[] = $tmp;
1617
			}
1618
		}
1619
	}
1620
	$tmp["name"]  = "Localhost";
1621
	$tmp["value"] = "lo0";
1622
	$listenips[] = $tmp;
1623
	return $listenips;
1624
}
1625

    
1626
function get_possible_traffic_source_addresses($include_ipv6_link_local=false) {
1627
	global $config;
1628
	$sourceips = get_possible_listen_ips($include_ipv6_link_local);
1629
	foreach (array('server', 'client') as $mode) {
1630
		if (is_array($config['openvpn']["openvpn-{$mode}"])) {
1631
			foreach ($config['openvpn']["openvpn-{$mode}"] as $id => $setting) {
1632
				if (!isset($setting['disable'])) {
1633
					$vpn = array();
1634
					$vpn['value'] = 'ovpn' . substr($mode, 0, 1) . $setting['vpnid'];
1635
					$vpn['name'] = gettext("OpenVPN") . " ".$mode.": ".htmlspecialchars($setting['description']);
1636
					$sourceips[] = $vpn;
1637
				}
1638
			}
1639
		}
1640
	}
1641
	return $sourceips;
1642
}
1643
?>
(52-52/66)