Project

General

Profile

Download (61.3 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/****h* pfSense/config
3
 * NAME
4
 *   config.inc - Functions to manipulate config.xml
5
 * DESCRIPTION
6
 *   This include contains various config.xml specific functions.
7
 * HISTORY
8
 * $Id$
9
 ******
10

    
11
	config.inc
12
	Copyright (C) 2004-2006 Scott Ullrich
13
	All rights reserved.
14

    
15
	originally part of m0n0wall (http://m0n0.ch/wall)
16
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
17
	All rights reserved.
18

    
19
	Redistribution and use in source and binary forms, with or without
20
	modification, are permitted provided that the following conditions are met:
21

    
22
	1. Redistributions of source code must retain the above copyright notice,
23
	   this list of conditions and the following disclaimer.
24

    
25
	2. Redistributions in binary form must reproduce the above copyright
26
	   notice, this list of conditions and the following disclaimer in the
27
	   documentation and/or other materials provided with the distribution.
28

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

    
41
if($g['booting']) echo ".";
42

    
43
/* do not load this file twice. */
44
if($config_inc_loaded == true)
45
	return;
46
else
47
	$config_inc_loaded = true;
48

    
49
/* include globals/utility/XML parser files */
50
require_once("globals.inc");
51
if($g['booting']) echo ".";
52
require_once("util.inc");
53
if($g['booting']) echo ".";
54
require_once("pfsense-utils.inc");
55
if($g['booting']) echo ".";
56
require_once("xmlparse.inc");
57
if($g['booting']) echo ".";
58
require_once("services.inc");
59

    
60
/* read platform */
61
if($g['booting']) echo ".";
62
if (file_exists("{$g['etc_path']}/platform")) {
63
	$g['platform'] = chop(file_get_contents("{$g['etc_path']}/platform"));
64
} else {
65
	$g['platform'] = "unknown";
66
}
67

    
68
/* if /debugging exists, lets set $debugging
69
   so we can output more information */
70
if(file_exists("/debugging")) {
71
	$debugging = true;
72
	$g['debug'] = true;
73
}
74

    
75
if($g['booting']) echo ".";
76
if(file_exists("/cf/conf/config.xml")) {
77
	$config_contents = file_get_contents("/cf/conf/config.xml");
78
	if(stristr($config_contents, "<m0n0wall>") == true) {
79
		if($g['booting']) echo ".";
80
		/* user has just upgraded to m0n0wall, replace root xml tags */
81
		log_error("Upgrading m0n0wall configuration to pfSense... ");
82
		$config_contents = str_replace("m0n0wall","pfsense", $config_contents);
83
		if (!config_validate("{$g['conf_path']}/config.xml"))
84
			log_error("ERROR!  Could not convert m0n0wall -> pfsense in config.xml");
85
		conf_mount_rw();
86
		$fd = fopen("/cf/conf/config.xml", "w");
87
		fwrite($fd, $config_contents);
88
		fclose($fd);
89
		mwexec("sync");
90
		conf_mount_ro();
91
	}
92
}
93

    
94
/* if our config file exists bail out, we're already set. */
95
if ($g['booting'] and !file_exists($g['cf_conf_path'] . "/config.xml")  ) {
96
	if($g['booting']) echo ".";
97
	/* find the device where config.xml resides and write out an fstab */
98
	unset($cfgdevice);
99
	if($g['booting']) echo ".";
100
	/* check if there's already an fstab (NFS booting?) */
101
	if (!file_exists("{$g['etc_path']}/fstab")) {
102
		if($g['booting']) echo ".";
103
		if (strstr($g['platform'], "cdrom")) {
104
			/* config is on floppy disk for CD-ROM version */
105
			$cfgdevice = $cfgpartition = "fd0";
106
			$dmesg = `dmesg -a`;
107
			if(ereg("da0", $dmesg) == true) {
108
				$cfgdevice = $cfgpartition = "da0" ;
109
				if (mwexec("/sbin/mount -r /dev/{$cfgdevice} /cf")) {
110
					/* could not mount, fallback to floppy */
111
					$cfgdevice = $cfgpartition = "fd0";
112
				}
113
			}
114
			$cfgfstype = "msdos";
115
			echo "CDROM build\n";
116
			echo "   CFG: {$cfgpartition}\n";
117
			echo "  TYPE: {$cfgfstype}\n";
118
		} else {
119
			if($g['booting']) echo ".";
120
			/* probe kernel known disks until we find one with config.xml */
121
			$disks = explode(" ", trim(preg_replace("/kern.disks: /", "", exec("/sbin/sysctl kern.disks"))));
122
			foreach ($disks as $mountdisk) {
123
				/* skip mfs mounted filesystems */
124
				if (strstr($mountdisk, "md"))
125
					continue;
126
				if (mwexec("/sbin/mount -r /dev/{$mountdisk}a {$g['cf_path']}") == 0) {
127
					if (file_exists("{$g['cf_conf_path']}/config.xml")) {
128
						/* found it */
129
						$cfgdevice = $mountdisk;
130
						$cfgpartition = $cfgdevice . "a";
131
						$cfgfstype = "ufs";
132
						echo "Found configuration on $cfgdevice.\n";
133
					}
134

    
135
					mwexec("/sbin/umount -f {$g['cf_path']}");
136

    
137
					if ($cfgdevice)
138
						break;
139
				}
140
				if (mwexec("/sbin/mount -r /dev/{$mountdisk}d {$g['cf_path']}") == 0) {
141
					if($g['booting']) echo ".";
142
					if (file_exists("{$g['cf_conf_path']}/config.xml")) {
143
						/* found it */
144
						$cfgdevice = $mountdisk;
145
						$cfgpartition = $cfgdevice . "d";
146
						$cfgfstype = "ufs";
147
						echo "Found configuration on $cfgdevice.\n";
148
					}
149

    
150
					mwexec("/sbin/umount -f {$g['cf_path']}");
151

    
152
					if ($cfgdevice)
153
						break;
154
				}
155
			}
156
		}
157
		if($g['booting']) echo ".";
158
		if (!$cfgdevice) {
159
			$last_backup = discover_last_backup();
160
			if($last_backup) {
161
				log_error("No config.xml found, attempting last known config restore.");
162
				file_notice("config.xml", "No config.xml found, attempting last known config restore.", "pfSenseConfigurator", "");
163
				restore_backup("/cf/conf/backup/{$last_backup}");
164
			} else {
165
				/* no device found, print an error and die */
166
				echo <<<EOD
167

    
168
*******************************************************************************
169
* FATAL ERROR                                                                 *
170
* The device that contains the configuration file (config.xml) could not be   *
171
* found. {$g['product_name']} cannot continue booting.                                     *
172
*******************************************************************************
173

    
174

    
175
EOD;
176

    
177
				mwexec("/sbin/halt");
178
				exit;
179
			}
180
		}
181

    
182
		/* write device name to a file for rc.firmware */
183
		$fd = fopen("{$g['varetc_path']}/cfdevice", "w");
184
		fwrite($fd, $cfgdevice . "\n");
185
		fclose($fd);
186

    
187
		/* write out an fstab */
188
		$fd = fopen("{$g['etc_path']}/fstab", "w");
189

    
190
		$fstab = "/dev/{$cfgpartition} {$g['cf_path']} {$cfgfstype} ro 1 1\n";
191
		$fstab .= "proc /proc procfs rw 0 0\n";
192

    
193
		fwrite($fd, $fstab);
194
		fclose($fd);
195
	}
196
	if($g['booting']) echo ".";
197
	/* mount all filesystems */
198
	mwexec("/sbin/mount -a");
199
}
200

    
201
/****f* config/parse_config
202
 * NAME
203
 *   parse_config - Read in config.cache or config.xml if needed and return $config array
204
 * INPUTS
205
 *   $parse       - boolean to force parse_config() to read config.xml and generate config.cache
206
 * RESULT
207
 *   $config      - array containing all configuration variables
208
 ******/
209
function parse_config($parse = false) {
210
	global $g;
211
	if(filesize("{$g['conf_path']}/config.xml") == 0) {
212
		$last_backup = discover_last_backup();
213
		if($last_backup) {
214
			log_error("No config.xml found, attempting last known config restore.");
215
			file_notice("config.xml", "No config.xml found, attempting last known config restore.", "pfSenseConfigurator", "");
216
			restore_backup("{$g['conf_path']}/backup/{$last_backup}");
217
		} else {
218
			die("Config.xml is corrupted and is 0 bytes.  Could not restore a previous backup.");
219
		}
220
	}
221
	if($g['booting']) echo ".";
222
	config_lock();
223
	if(!$parse) {
224
		if(file_exists($g['tmp_path'] . '/config.cache')) {
225
			$config = unserialize(file_get_contents($g['tmp_path'] . '/config.cache'));
226
			if(is_null($config)) {
227
				config_unlock();
228
				parse_config(true);
229
			}
230
		} else {
231
			config_unlock();
232
			if(!file_exists($g['conf_path'] . "/config.xml")) {
233
				log_error("No config.xml found, attempting last known config restore.");
234
				file_notice("config.xml", "No config.xml found, attempting last known config restore.", "pfSenseConfigurator", "");
235
				$last_backup = discover_last_backup();
236
				if ($last_backup)
237
					restore_backup("/cf/conf/backup/{$last_backup}");
238
				else
239
					log_error("Could not restore config.xml.");
240
			}
241
			$config = parse_config(true);
242
		}
243
	} else {
244
		if(!file_exists($g['conf_path'] . "/config.xml")) {
245
			if($g['booting']) echo ".";
246
			log_error("No config.xml found, attempting last known config restore.");
247
			file_notice("config.xml", "No config.xml found, attempting last known config restore.", "pfSenseConfigurator", "");
248
			$last_backup = discover_last_backup();
249
			if ($last_backup)
250
				restore_backup("/cf/conf/backup/{$last_backup}");
251
			else
252
				log_error("Could not restore config.xml.");
253
		}
254
		$config = parse_xml_config($g['conf_path'] . '/config.xml', $g['xml_rootobj']);
255
		if($config == "-1") {
256
			$last_backup = discover_last_backup();
257
			if ($last_backup)
258
				restore_backup("/cf/conf/backup/{$last_backup}");
259
			else
260
				log_error(gettext("Could not restore config.xml."));
261
		}
262
		generate_config_cache($config);
263
	}
264
	if($g['booting']) echo ".";
265
	alias_make_table($config);
266
	config_unlock();
267

    
268
	/*    override some global configuration parms if they exist
269
	 *    instead of hard coding these checks into the codebase
270
     */
271
	if($config['pptp']['n_pptp_units'])
272
		$g['n_pptp_units'] = $config['pptp']['n_pptp_units'];
273
	if($config['pptp']['pptp_subnet'])
274
		$g['pptp_subnet'] = $config['pptp']['pptp_subnet'];
275

    
276
	if($config['pppoe']['n_pppoe_units'])
277
		$g['n_pppoe_units'] = $config['pppoe']['n_pppoe_units'];
278
	if($config['pppoe']['pppoe_subnet'])
279
		$g['pppoe_subnet'] = $config['pppoe']['pppoe_subnet'];
280

    
281
	return $config;
282
}
283

    
284
/****f* config/generate_config_cache
285
 * NAME
286
 *   generate_config_cache - Write serialized configuration to cache.
287
 * INPUTS
288
 *   $config	- array containing current firewall configuration
289
 * RESULT
290
 *   boolean	- true on completion
291
 ******/
292
function generate_config_cache($config) {
293
	global $g;
294
	config_lock();
295
	conf_mount_rw();
296
	$configcache = fopen($g['tmp_path'] . '/config.cache', "w");
297
	fwrite($configcache, serialize($config));
298
	fclose($configcache);
299
	mwexec("sync");
300
	conf_mount_ro();
301
	config_unlock();
302
	return true;
303
}
304

    
305
function discover_last_backup() {
306
        $backups = split("\n", `cd /cf/conf/backup && ls -ltr *.xml | awk '{print \$9}'`);
307
		$last_backup = "";
308
        foreach($backups as $backup)
309
        	if($backup)
310
	        	$last_backup = $backup;
311
        return $last_backup;
312
}
313

    
314
function restore_backup($file) {
315
	config_lock();
316
	if(file_exists($file)) {
317
		conf_mount_rw();
318
		copy("$file","/cf/conf/config.xml");
319
		unlink_if_exists("/tmp/config.cache");
320
		log_error("{$g['product_name']} is restoring the configuration $file");
321
		file_notice("config.xml", "{$g['product_name']} is restoring the configuration $file", "pfSenseConfigurator", "");
322
		mwexec("sync");
323
		conf_mount_ro();
324
	}
325
	config_unlock();
326
}
327

    
328
/****f* config/parse_config_bootup
329
 * NAME
330
 *   parse_config_bootup - Bootup-specific configuration checks.
331
 * RESULT
332
 *   null
333
 ******/
334
function parse_config_bootup() {
335
	global $config, $g, $noparseconfig;
336
	if($g['booting']) echo ".";
337
	if (!$noparseconfig) {
338
		if (!file_exists("{$g['conf_path']}/config.xml")) {
339
			config_lock();
340
			if ($g['booting']) {
341
				if (strstr($g['platform'], "cdrom")) {
342
					/* try copying the default config. to the floppy */
343
					echo "Resetting factory defaults...\n";
344
					reset_factory_defaults();
345
					if (file_exists("{$g['conf_path']}/config.xml")) {
346
						/* do nothing, we have a file. */
347
					} else {
348
						echo "No XML configuration file found - using factory defaults.\n";
349
						echo "Make sure that the configuration floppy disk with the conf/config.xml\n";
350
						echo "file is inserted. If it isn't, your configuration changes will be lost\n";
351
						echo "on reboot.\n";
352
					}
353
				} else {
354
					$last_backup = discover_last_backup();
355
					if($last_backup) {
356
						log_error("No config.xml found, attempting last known config restore.");
357
						file_notice("config.xml", "No config.xml found, attempting last known config restore.", "pfSenseConfigurator", "");
358
						restore_backup("/cf/conf/backup/{$last_backup}");
359
					}
360
					if(!file_exists("{$g['conf_path']}/config.xml")) {
361
						echo "XML configuration file not found.  {$g['product_name']} cannot continue booting.\n";
362
						mwexec("/sbin/halt");
363
						exit;
364
					}
365
					log_error("Last known config found and restored.  Please double check your configuration file for accuracy.");
366
					file_notice("config.xml", "Last known config found and restored.  Please double check your configuration file for accuracy.", "pfSenseConfigurator", "");
367
				}
368
			} else {
369
				config_unlock();
370
				exit(0);
371
			}
372
		}
373
	}
374
	if(filesize("{$g['conf_path']}/config.xml") == 0) {
375
		$last_backup = discover_last_backup();
376
		if($last_backup) {
377
			log_error("No config.xml found, attempting last known config restore.");
378
			file_notice("config.xml", "No config.xml found, attempting last known config restore.", "pfSenseConfigurator", "");
379
			restore_backup("{$g['conf_path']}/backup/{$last_backup}");
380
		} else {
381
			die("Config.xml is corrupted and is 0 bytes.  Could not restore a previous backup.");
382
		}
383
	}
384
	parse_config(true);
385

    
386
	if ((float)$config['version'] > (float)$g['latest_config']) {
387
		echo <<<EOD
388

    
389

    
390
*******************************************************************************
391
* WARNING!                                                                    *
392
* The current configuration has been created with a newer version of {$g['product_name']}  *
393
* than this one! This can lead to serious misbehavior and even security       *
394
* holes! You are urged to either upgrade to a newer version of {$g['product_name']} or     *
395
* revert to the default configuration immediately!                            *
396
*******************************************************************************
397

    
398

    
399
EOD;
400
		}
401

    
402
	/* make alias table (for faster lookups) */
403
	alias_make_table($config);
404
	config_unlock();
405
}
406

    
407
/****f* config/conf_mount_rw
408
 * NAME
409
 *   conf_mount_rw - Mount filesystems read/write.
410
 * RESULT
411
 *   null
412
 ******/
413
/* mount flash card read/write */
414
function conf_mount_rw() {
415
	global $g;
416

    
417
	/* do not mount on cdrom platform */
418
	if($g['platform'] == "cdrom" or $g['platform'] == "pfSense")
419
		return;
420
		
421
	$status = mwexec("/sbin/mount -u -w {$g['cf_path']}");
422
	if($status <> 0) {
423
		if($g['booting'])
424
			echo "Disk is dirty.  Running fsck -y\n";
425
		mwexec("/sbin/fsck -y {$g['cf_path']}");
426
		$status = mwexec("/sbin/mount -u -w {$g['cf_path']}");
427
	}
428

    
429
	/*    if the platform is soekris or wrap or pfSense, lets mount the
430
	 *    compact flash cards root.
431
         */
432
	if($g['platform'] == "wrap" or $g['platform'] == "net45xx"
433
	   or $g['platform'] == "embedded") {
434
		$status = mwexec("/sbin/mount -u -w /");
435
		/* we could not mount this correctly.  kick off fsck */
436
		if($status <> 0) {
437
			log_error("File system is dirty.  Launching FSCK for /");
438
			mwexec("/sbin/fsck -y /");
439
			$status = mwexec("/sbin/mount -u -w /");
440
		}
441
	}
442
}
443

    
444
/****f* config/conf_mount_ro
445
 * NAME
446
 *   conf_mount_ro - Mount filesystems readonly.
447
 * RESULT
448
 *   null
449
 ******/
450
function conf_mount_ro() {
451
	global $g;
452

    
453
	if($g['booting'] == true)
454
		return;
455

    
456
	/* firmare upgrade in progress */
457
	if(file_exists($g['varrun_path'] . "/fwup.enabled"))
458
		return;
459

    
460
	/* do not umount if generating ssh keys */
461
	if(file_exists("/tmp/keys_generating"))
462
		return;
463

    
464
	/* do not umount on cdrom or pfSense platforms */
465
	if($g['platform'] == "cdrom" or $g['platform'] == "pfSense")
466
		return;
467

    
468
	/* sync data, then force a remount of /cf */
469
	mwexec("/bin/sync");
470
	mwexec("/sbin/mount -u -r -f {$g['cf_path']}");
471
	mwexec("/sbin/mount -u -r -f /");
472
}
473

    
474
/****f* config/convert_config
475
 * NAME
476
 *   convert_config - Attempt to update config.xml.
477
 * DESCRIPTION
478
 *   convert_config() reads the current global configuration
479
 *   and attempts to convert it to conform to the latest
480
 *   config.xml version. This allows major formatting changes
481
 *   to be made with a minimum of breakage.
482
 * RESULT
483
 *   null
484
 ******/
485
/* convert configuration, if necessary */
486
function convert_config() {
487
	global $config, $g;
488

    
489
	/* special case upgrades */
490
	/* fix every minute crontab bogons entry */
491
	$cron_item_count = count($config['cron']['item']);
492
	for($x=0; $x<$cron_item_count; $x++) {
493
		if(stristr($config['cron']['item'][$x]['command'], "rc.update_bogons.sh")) {
494
			if($config['cron']['item'][$x]['hour'] == "*" ) {
495
		        $config['cron']['item'][$x]['hour'] = "3";
496
		 		write_config("Updated bogon update frequency to 3am");
497
		 		log_error("Updated bogon update frequency to 3am");
498
		 	}       
499
		}
500
	}
501
	if ($config['version'] == $g['latest_config'])
502
		return;		/* already at latest version */
503

    
504
	// Save off config version
505
	$prev_version = $config['version'];
506

    
507
	/* convert 1.0 -> 1.1 */
508
	if ($config['version'] <= 1.0) {
509
		$opti = 1;
510
		$ifmap = array('lan' => 'lan', 'wan' => 'wan', 'pptp' => 'pptp');
511

    
512
		/* convert DMZ to optional, if necessary */
513
		if (isset($config['interfaces']['dmz'])) {
514

    
515
			$dmzcfg = &$config['interfaces']['dmz'];
516

    
517
			if ($dmzcfg['if']) {
518
				$config['interfaces']['opt' . $opti] = array();
519
				$optcfg = &$config['interfaces']['opt' . $opti];
520

    
521
				$optcfg['enable'] = $dmzcfg['enable'];
522
				$optcfg['descr'] = "DMZ";
523
				$optcfg['if'] = $dmzcfg['if'];
524
				$optcfg['ipaddr'] = $dmzcfg['ipaddr'];
525
				$optcfg['subnet'] = $dmzcfg['subnet'];
526

    
527
				$ifmap['dmz'] = "opt" . $opti;
528
				$opti++;
529
			}
530

    
531
			unset($config['interfaces']['dmz']);
532
		}
533

    
534
		/* convert WLAN1/2 to optional, if necessary */
535
		for ($i = 1; isset($config['interfaces']['wlan' . $i]); $i++) {
536

    
537
			if (!$config['interfaces']['wlan' . $i]['if']) {
538
				unset($config['interfaces']['wlan' . $i]);
539
				continue;
540
			}
541

    
542
			$wlancfg = &$config['interfaces']['wlan' . $i];
543
			$config['interfaces']['opt' . $opti] = array();
544
			$optcfg = &$config['interfaces']['opt' . $opti];
545

    
546
			$optcfg['enable'] = $wlancfg['enable'];
547
			$optcfg['descr'] = "WLAN" . $i;
548
			$optcfg['if'] = $wlancfg['if'];
549
			$optcfg['ipaddr'] = $wlancfg['ipaddr'];
550
			$optcfg['subnet'] = $wlancfg['subnet'];
551
			$optcfg['bridge'] = $wlancfg['bridge'];
552

    
553
			$optcfg['wireless'] = array();
554
			$optcfg['wireless']['mode'] = $wlancfg['mode'];
555
			$optcfg['wireless']['ssid'] = $wlancfg['ssid'];
556
			$optcfg['wireless']['channel'] = $wlancfg['channel'];
557
			$optcfg['wireless']['wep'] = $wlancfg['wep'];
558

    
559
			$ifmap['wlan' . $i] = "opt" . $opti;
560

    
561
			unset($config['interfaces']['wlan' . $i]);
562
			$opti++;
563
		}
564

    
565
		/* convert filter rules */
566
		$n = count($config['filter']['rule']);
567
		for ($i = 0; $i < $n; $i++) {
568

    
569
			$fr = &$config['filter']['rule'][$i];
570

    
571
			/* remap interface */
572
			if (array_key_exists($fr['interface'], $ifmap))
573
				$fr['interface'] = $ifmap[$fr['interface']];
574
			else {
575
				/* remove the rule */
576
				echo "\nWarning: filter rule removed " .
577
					"(interface '{$fr['interface']}' does not exist anymore).";
578
				unset($config['filter']['rule'][$i]);
579
				continue;
580
			}
581

    
582
			/* remap source network */
583
			if (isset($fr['source']['network'])) {
584
				if (array_key_exists($fr['source']['network'], $ifmap))
585
					$fr['source']['network'] = $ifmap[$fr['source']['network']];
586
				else {
587
					/* remove the rule */
588
					echo "\nWarning: filter rule removed " .
589
						"(source network '{$fr['source']['network']}' does not exist anymore).";
590
					unset($config['filter']['rule'][$i]);
591
					continue;
592
				}
593
			}
594

    
595
			/* remap destination network */
596
			if (isset($fr['destination']['network'])) {
597
				if (array_key_exists($fr['destination']['network'], $ifmap))
598
					$fr['destination']['network'] = $ifmap[$fr['destination']['network']];
599
				else {
600
					/* remove the rule */
601
					echo "\nWarning: filter rule removed " .
602
						"(destination network '{$fr['destination']['network']}' does not exist anymore).";
603
					unset($config['filter']['rule'][$i]);
604
					continue;
605
				}
606
			}
607
		}
608

    
609
		/* convert shaper rules */
610
		$n = count($config['pfqueueing']['rule']);
611
		if (is_array($config['pfqueueing']['rule']))
612
			for ($i = 0; $i < $n; $i++) {
613

    
614
			$fr = &$config['pfqueueing']['rule'][$i];
615

    
616
			/* remap interface */
617
			if (array_key_exists($fr['interface'], $ifmap))
618
				$fr['interface'] = $ifmap[$fr['interface']];
619
			else {
620
				/* remove the rule */
621
				echo "\nWarning: traffic shaper rule removed " .
622
					"(interface '{$fr['interface']}' does not exist anymore).";
623
				unset($config['pfqueueing']['rule'][$i]);
624
				continue;
625
			}
626

    
627
			/* remap source network */
628
			if (isset($fr['source']['network'])) {
629
				if (array_key_exists($fr['source']['network'], $ifmap))
630
					$fr['source']['network'] = $ifmap[$fr['source']['network']];
631
				else {
632
					/* remove the rule */
633
					echo "\nWarning: traffic shaper rule removed " .
634
						"(source network '{$fr['source']['network']}' does not exist anymore).";
635
					unset($config['pfqueueing']['rule'][$i]);
636
					continue;
637
				}
638
			}
639

    
640
			/* remap destination network */
641
			if (isset($fr['destination']['network'])) {
642
				if (array_key_exists($fr['destination']['network'], $ifmap))
643
					$fr['destination']['network'] = $ifmap[$fr['destination']['network']];
644
				else {
645
					/* remove the rule */
646
					echo "\nWarning: traffic shaper rule removed " .
647
						"(destination network '{$fr['destination']['network']}' does not exist anymore).";
648
					unset($config['pfqueueing']['rule'][$i]);
649
					continue;
650
				}
651
			}
652
		}
653

    
654
		$config['version'] = "1.1";
655
	}
656

    
657
	/* convert 1.1 -> 1.2 */
658
	if ($config['version'] <= 1.1) {
659
		/* move LAN DHCP server config */
660
		$tmp = $config['dhcpd'];
661
		$config['dhcpd'] = array();
662
		$config['dhcpd']['lan'] = $tmp;
663

    
664
		/* encrypt password */
665
		$config['system']['password'] = crypt($config['system']['password']);
666

    
667
		$config['version'] = "1.2";
668
	}
669

    
670
	/* convert 1.2 -> 1.3 */
671
	if ($config['version'] <= 1.2) {
672
		/* convert advanced outbound NAT config */
673
		for ($i = 0; isset($config['nat']['advancedoutbound']['rule'][$i]); $i++) {
674
			$curent = &$config['nat']['advancedoutbound']['rule'][$i];
675
			$src = $curent['source'];
676
			$curent['source'] = array();
677
			$curent['source']['network'] = $src;
678
			$curent['destination'] = array();
679
			$curent['destination']['any'] = true;
680
		}
681

    
682
		/* add an explicit type="pass" to all filter rules to make things consistent */
683
		for ($i = 0; isset($config['filter']['rule'][$i]); $i++) {
684
			$config['filter']['rule'][$i]['type'] = "pass";
685
		}
686

    
687
		$config['version'] = "1.3";
688
	}
689

    
690
	/* convert 1.3 -> 1.4 */
691
	if ($config['version'] <= 1.3) {
692
		/* convert shaper rules (make pipes) */
693
		if (is_array($config['pfqueueing']['rule'])) {
694
			$config['pfqueueing']['pipe'] = array();
695

    
696
			for ($i = 0; isset($config['pfqueueing']['rule'][$i]); $i++) {
697
				$curent = &$config['pfqueueing']['rule'][$i];
698

    
699
				/* make new pipe and associate with this rule */
700
				$newpipe = array();
701
				$newpipe['descr'] = $curent['descr'];
702
				$newpipe['bandwidth'] = $curent['bandwidth'];
703
				$newpipe['delay'] = $curent['delay'];
704
				$newpipe['mask'] = $curent['mask'];
705
				$config['pfqueueing']['pipe'][$i] = $newpipe;
706

    
707
				$curent['targetpipe'] = $i;
708

    
709
				unset($curent['bandwidth']);
710
				unset($curent['delay']);
711
				unset($curent['mask']);
712
			}
713
		}
714

    
715
		$config['version'] = "1.4";
716
	}
717

    
718
	/* Convert 1.4 -> 1.5 */
719
	if ($config['version'] <= 1.4) {
720

    
721
		/* Default route moved */
722
		if (isset($config['interfaces']['wan']['gateway']))
723
			if ($config['interfaces']['wan']['gateway'] <> "")
724
				$config['interfaces']['wan']['gateway'] = $config['interfaces']['wan']['gateway'];
725
		unset($config['interfaces']['wan']['gateway']);
726

    
727
                /* Queues are no longer interface specific */
728
                if (isset($config['interfaces']['lan']['schedulertype']))
729
                        unset($config['interfaces']['lan']['schedulertype']);
730
                if (isset($config['interfaces']['wan']['schedulertype']))
731
                        unset($config['interfaces']['wan']['schedulertype']);
732

    
733
                for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
734
                        if(isset($config['interfaces']['opt' . $i]['schedulertype']))
735
                                unset($config['interfaces']['opt' . $i]['schedulertype']);
736
                }
737

    
738
		$config['version'] = "1.5";
739
	}
740

    
741
	/* Convert 1.5 -> 1.6 */
742
	if ($config['version'] <= 1.5) {
743
		/* Alternate firmware URL moved */
744
		if (isset($config['system']['firmwareurl']) && isset($config['system']['firmwarename'])) { // Only convert if *both* are defined.
745
			$config['system']['alt_firmware_url'] = array();
746
			$config['system']['alt_firmware_url']['enabled'] = "";
747
			$config['system']['alt_firmware_url']['firmware_base_url'] = $config['system']['firmwareurl'];
748
			$config['system']['alt_firmware_url']['firmware_filename'] = $config['system']['firmwarename'];
749
			unset($config['system']['firmwareurl'], $config['system']['firmwarename']);
750
		} else {
751
			unset($config['system']['firmwareurl'], $config['system']['firmwarename']);
752
		}
753

    
754
		$config['version'] = "1.6";
755
	}
756

    
757
	/* Convert 1.6 -> 1.7 */
758
	if ($config['version'] <= 1.6) {
759
		/* wipe previous shaper configuration */
760
		unset($config['shaper']['queue']);
761
		unset($config['shaper']['rule']);
762
		unset($config['interfaces']['wan']['bandwidth']);
763
		unset($config['interfaces']['wan']['bandwidthtype']);
764
		unset($config['interfaces']['lan']['bandwidth']);
765
		unset($config['interfaces']['lan']['bandwidthtype']);
766
		$config['shaper']['enable'] = FALSE;
767
		$config['version'] = "1.7";
768
	}
769
	/* Convert 1.7 -> 1.8 */
770
	if ($config['version'] <= 1.7) {
771
		if(isset($config['proxyarp']) && is_array($config['proxyarp']['proxyarpnet'])) {
772
			$proxyarp = &$config['proxyarp']['proxyarpnet'];
773
			foreach($proxyarp as $arpent){
774
				$vip = array();
775
				$vip['mode'] = "proxyarp";
776
				$vip['interface'] = $arpent['interface'];
777
				$vip['descr'] = $arpent['descr'];
778
				if (isset($arpent['range'])) {
779
					$vip['range'] = $arpent['range'];
780
					$vip['type'] = "range";
781
				} else {
782
					$subnet = explode('/', $arpent['network']);
783
					$vip['subnet'] = $subnet[0];
784
					if (isset($subnet[1])) {
785
						$vip['subnet_bits'] = $subnet[1];
786
						$vip['type'] = "network";
787
					} else {
788
						$vip['subnet_bits'] = "32";
789
						$vip['type'] = "single";
790
					}
791
				}
792
				$config['virtualip']['vip'][] = $vip;
793
			}
794
			unset($config['proxyarp']);
795
		}
796
		if(isset($config['installedpackages']) && isset($config['installedpackages']['carp']) && is_array($config['installedpackages']['carp']['config'])) {
797
			$carp = &$config['installedpackages']['carp']['config'];
798
			foreach($carp as $carpent){
799
				$vip = array();
800
				$vip['mode'] = "carp";
801
				$vip['interface'] = "AUTO";
802
				$vip['descr'] = "CARP vhid {$carpent['vhid']}";
803
				$vip['type'] = "single";
804
				$vip['vhid'] = $carpent['vhid'];
805
				$vip['advskew'] = $carpent['advskew'];
806
				$vip['password'] = $carpent['password'];
807
				$vip['subnet'] = $carpent['ipaddress'];
808
				$vip['subnet_bits'] = $carpent['netmask'];
809
				$config['virtualip']['vip'][] = $vip;
810
			}
811
			unset($config['installedpackages']['carp']);
812
		}
813
		/* Server NAT is no longer needed */
814
		unset($config['nat']['servernat']);
815

    
816
		/* enable SSH */
817
		if ($config['version'] == "1.8") {
818
			$config['system']['sshenabled'] = true;
819
		}
820

    
821
		$config['version'] = "1.9";
822
	}
823

    
824
	/* Convert 1.8 -> 1.9 */
825
	if ($config['version'] <= 1.8) {
826
		$config['theme']="metallic";
827
		$config['version'] = "1.9";
828
	}
829
	/* Convert 1.9 -> 2.0 */
830
	if ($config['version'] <= 1.9) {
831
		if(is_array($config['ipsec']['tunnel'])) {
832
			reset($config['ipsec']['tunnel']);
833
			while (list($index, $tunnel) = each($config['ipsec']['tunnel'])) {
834
				/* Sanity check on required variables */
835
				/* This fixes bogus <tunnel> entries - remnant of bug #393 */
836
				if (!isset($tunnel['local-subnet']) && !isset($tunnel['remote-subnet'])) {
837
					unset($config['ipsec']['tunnel'][$tunnel]);
838
				}
839
			}
840
        	}
841
		$config['version'] = "2.0";
842
	}
843
	/* Convert 2.0 -> 2.1 */
844
	if ($config['version'] <= 2.0) {
845
		/* shaper scheduler moved */
846
		if(isset($config['system']['schedulertype'])) {
847
			$config['shaper']['schedulertype'] = $config['system']['schedulertype'];
848
			unset($config['system']['schedulertype']);
849
		}
850
		$config['version'] = "2.1";
851
	}
852
	/* Convert 2.1 -> 2.2 */
853
	if ($config['version'] <= 2.1) {
854
		/* move gateway to wan interface */
855
		$config['interfaces']['wan']['gateway'] = $config['system']['gateway'];
856
		$config['version'] = "2.2";
857
	}
858
	/* Convert 2.2 -> 2.3 */
859
	if ($config['version'] <= 2.2) {
860
		if(isset($config['shaper'])) {
861
			/* wipe previous shaper configuration */
862
			unset($config['shaper']);
863
		}
864
		$config['version'] = "2.3";
865
	}
866

    
867
	/* Convert 2.4 -> 2.5 */
868
	if ($config['version'] <= 2.4) {
869
		$config['interfaces']['wan']['use_rrd_gateway'] = $config['system']['use_rrd_gateway'];
870
		unset($config['system']['use_rrd_gateway']);
871
 		$config['version'] = "2.5";
872
	}
873

    
874
	/* Convert 2.5 -> 2.6 */
875
	if ($config['version'] <= 2.5) {
876
		$cron_item = array();
877
		$cron_item['minute'] = "0";
878
		$cron_item['hour'] = "*";
879
		$cron_item['mday'] = "*";
880
		$cron_item['month'] = "*";
881
		$cron_item['wday'] = "*";
882
		$cron_item['who'] = "root";
883
		$cron_item['command'] = "/usr/bin/nice -n20 newsyslog";
884

    
885
		$config['cron']['item'][] = $cron_item;
886

    
887
		$cron_item = array();
888
		$cron_item['minute'] = "1,31";
889
		$cron_item['hour'] = "0-5";
890
		$cron_item['mday'] = "*";
891
		$cron_item['month'] = "*";
892
		$cron_item['wday'] = "*";
893
		$cron_item['who'] = "root";
894
		$cron_item['command'] = "/usr/bin/nice -n20 adjkerntz -a";
895

    
896
		$config['cron']['item'][] = $cron_item;
897

    
898
		$cron_item = array();
899
		$cron_item['minute'] = "1";
900
		$cron_item['hour'] = "*";
901
		$cron_item['mday'] = "1";
902
		$cron_item['month'] = "*";
903
		$cron_item['wday'] = "*";
904
		$cron_item['who'] = "root";
905
		$cron_item['command'] = "/usr/bin/nice -n20 /etc/rc.update_bogons.sh";
906

    
907
		$config['cron']['item'][] = $cron_item;
908

    
909
		$cron_item = array();
910
		$cron_item['minute'] = "*/60";
911
		$cron_item['hour'] = "*";
912
		$cron_item['mday'] = "*";
913
		$cron_item['month'] = "*";
914
		$cron_item['wday'] = "*";
915
		$cron_item['who'] = "root";
916
		$cron_item['command'] = "/usr/bin/nice -n20 /usr/local/sbin/expiretable -v -t 3600 sshlockout";
917

    
918
		$config['cron']['item'][] = $cron_item;
919

    
920
		$cron_item = array();
921
		$cron_item['minute'] = "1";
922
		$cron_item['hour'] = "1";
923
		$cron_item['mday'] = "*";
924
		$cron_item['month'] = "*";
925
		$cron_item['wday'] = "*";
926
		$cron_item['who'] = "root";
927
		$cron_item['command'] = "/usr/bin/nice -n20 /etc/rc.dyndns.update";
928

    
929
		$config['cron']['item'][] = $cron_item;
930

    
931
		$cron_item = array();
932
		$cron_item['minute'] = "*/60";
933
		$cron_item['hour'] = "*";
934
		$cron_item['mday'] = "*";
935
		$cron_item['month'] = "*";
936
		$cron_item['wday'] = "*";
937
		$cron_item['who'] = "root";
938
		$cron_item['command'] = "/usr/bin/nice -n20 /usr/local/sbin/expiretable -v -t 3600 virusprot";
939

    
940
		$config['cron']['item'][] = $cron_item;
941

    
942
		$cron_item = array();
943
		$cron_item['minute'] = "*/60";
944
		$cron_item['hour'] = "*";
945
		$cron_item['mday'] = "*";
946
		$cron_item['month'] = "*";
947
		$cron_item['wday'] = "*";
948
		$cron_item['who'] = "root";
949
		$cron_item['command'] = "/usr/bin/nice -n20 /usr/local/sbin/expiretable -t 1800 snort2c";
950

    
951
		$config['cron']['item'][] = $cron_item;
952

    
953
		$cron_item = array();
954
		$cron_item['minute'] = "*/5";
955
		$cron_item['hour'] = "*";
956
		$cron_item['mday'] = "*";
957
		$cron_item['month'] = "*";
958
		$cron_item['wday'] = "*";
959
		$cron_item['who'] = "root";
960
		$cron_item['command'] = "/usr/local/bin/checkreload.sh";
961

    
962
		$config['cron']['item'][] = $cron_item;
963

    
964
		/* write crontab entries to file */
965
		configure_cron();
966

    
967
 		$config['version'] = "2.6";
968
	}
969

    
970
	/* Convert 2.6 -> 2.7 */
971
	if ($config['version'] <= 2.6) {
972
		$config['interfaces']['wan']['use_rrd_gateway'] = $config['system']['use_rrd_gateway'];
973
		unset($config['system']['use_rrd_gateway']);
974
		$config['version'] = "2.7";
975
	}
976

    
977
	/* Convert 2.7 -> 2.8 */
978
	if ($config['version'] <= 2.7) {
979
		$founditem = false;
980
		foreach($config['cron']['item'] as $cronitem) {
981
			if($cronitem['command'] == "/usr/local/bin/checkreload.sh")
982
				$founditem = true;
983
		}
984
		if($founditem == false) {
985
			$cron_item = array();
986
			$cron_item['minute'] = "*/5";
987
			$cron_item['hour'] = "*";
988
			$cron_item['mday'] = "*";
989
			$cron_item['month'] = "*";
990
			$cron_item['wday'] = "*";
991
			$cron_item['who'] = "root";
992
			$cron_item['command'] = "/usr/local/bin/checkreload.sh";
993
			$config['cron']['item'][] = $cron_item;
994
		}
995
		$config['version'] = "2.8";
996
	}
997

    
998
	/* Convert 2.8 -> 2.9 */
999
	if ($config['version'] <= 2.8) {
1000
		$rule_item = array();
1001
		$a_filter = &$config['filter']['rule'];
1002
		$rule_item['interface'] = "enc0";
1003
		$rule_item['type'] = "pass";
1004
		$rule_item['source']['any'] = true;
1005
		$rule_item['destination']['any'] = true;
1006
		$rule_item['descr'] = "Permit IPsec traffic.";
1007
		$rule_item['statetype'] = "keep state";
1008
		$a_filter[] = $rule_item;
1009
		$config['version'] = "2.9";
1010
	}
1011

    
1012
	/* Convert 2.9 -> 3.0 */
1013
	if ($config['version'] <= 2.9) {
1014
		/* enable the rrd config setting by default */
1015
		$config['rrd']['enable'] = true;
1016
		$config['version'] = "3.0";
1017
	}
1018

    
1019
	/* Convert 3.0 -> 4.0 */
1020
	if ($config['version'] <= 3.9) {
1021
		$config['system']['webgui']['auth_method'] = "session";
1022
		$config['system']['webgui']['backing_method'] = "htpasswd";
1023

    
1024
		if (isset ($config['system']['username'])) {
1025
			$config['system']['group'] = array();
1026
			$config['system']['group'][0]['name'] = "admins";
1027
			$config['system']['group'][0]['description'] = "System Administrators";
1028
			$config['system']['group'][0]['scope'] = "system";
1029
			$config['system']['group'][0]['pages'] = "ANY";
1030
			$config['system']['group'][0]['home'] = "index.php";
1031
			$config['system']['group'][0]['gid'] = "110";
1032

    
1033
			$config['system']['user'] = array();
1034
			$config['system']['user'][0]['name'] = "{$config['system']['username']}";
1035
			$config['system']['user'][0]['fullname'] = "System Administrator";
1036
			$config['system']['user'][0]['scope'] = "system";
1037
			$config['system']['user'][0]['groupname'] = "admins";
1038
			$config['system']['user'][0]['password'] = "{$config['system']['password']}";
1039
			$config['system']['user'][0]['uid'] = "0";
1040

    
1041
			$config['system']['user'][0]['priv'] = array();
1042
			$config['system']['user'][0]['priv'][0]['id'] = "lockwc";
1043
			$config['system']['user'][0]['priv'][0]['name'] = "Lock webConfigurator";
1044
			$config['system']['user'][0]['priv'][0]['descr'] = "Indicates whether this user will lock access to the webConfigurator for other users.";
1045
			$config['system']['user'][0]['priv'][1]['id'] = "lock-ipages";
1046
			$config['system']['user'][0]['priv'][1]['name'] = "Lock individual pages";
1047
			$config['system']['user'][0]['priv'][1]['descr'] = "Indicates whether this user will lock individual HTML pages after having accessed a particular page (the lock will be freed if the user leaves or saves the page form).";
1048
			$config['system']['user'][0]['priv'][2]['id'] = "hasshell";
1049
			$config['system']['user'][0]['priv'][2]['name'] = "Has shell access";
1050
			$config['system']['user'][0]['priv'][2]['descr'] = "Indicates whether this user is able to login for example via SSH.";
1051
			$config['system']['user'][0]['priv'][3]['id'] = "copyfiles";
1052
			$config['system']['user'][0]['priv'][3]['name'] = "Is allowed to copy files";
1053
			$config['system']['user'][0]['priv'][3]['descr'] = "Indicates whether this user is allowed to copy files onto the {$g['product_name']} appliance via SCP/SFTP. If you are going to use this privilege, you must install scponly on the appliance (Hint: pkg_add -r scponly).";
1054
			$config['system']['user'][0]['priv'][4]['id'] = "isroot";
1055
			$config['system']['user'][0]['priv'][4]['name'] = "Is root user";
1056
			$config['system']['user'][0]['priv'][4]['descr'] = "This user is associated with the UNIX root user (you should associate this privilege only with one single user).";
1057

    
1058
			$config['system']['nextuid'] = "111";
1059
			$config['system']['nextgid'] = "111";
1060

    
1061
			/* wipe previous auth configuration */
1062
			unset ($config['system']['username']);
1063
			unset ($config['system']['password']);
1064
			
1065
			$config['version'] = "4.0";
1066
		}
1067

    
1068
	}
1069
		
1070
	/* Convert 4.0 -> 4.1 */
1071
	if ($config['version'] <= 4.0) {
1072
		if(!$config['sysctl']) {
1073

    
1074
			$config['sysctl']['item'] = array();
1075
	
1076
			$config['sysctl']['item'][0]['tunable'] = "net.inet.tcp.blackhole";
1077
			$config['sysctl']['item'][0]['desc'] =    "Drop packets to closed TCP ports without returning a RST";
1078
			$config['sysctl']['item'][0]['value'] =   "2";
1079
	
1080
			$config['sysctl']['item'][1]['tunable'] = "net.inet.udp.blackhole";
1081
			$config['sysctl']['item'][1]['desc'] =    "Do not send ICMP port unreachable messages for closed UDP ports";
1082
			$config['sysctl']['item'][1]['value'] =   "1";
1083
	
1084
			$config['sysctl']['item'][2]['tunable'] = "net.inet.ip.random_id";
1085
			$config['sysctl']['item'][2]['desc'] =    "Randomize the ID field in IP packets (default is 0: sequential IP IDs)";
1086
			$config['sysctl']['item'][2]['value'] =   "1";
1087
	
1088
			$config['sysctl']['item'][3]['tunable'] = "net.inet.tcp.drop_synfin";
1089
			$config['sysctl']['item'][3]['desc'] =    "Drop SYN-FIN packets (breaks RFC1379, but nobody uses it anyway)";
1090
			$config['sysctl']['item'][3]['value'] =   "1";
1091
	
1092
			$config['sysctl']['item'][4]['tunable'] = "net.inet.ip.redirect";
1093
			$config['sysctl']['item'][4]['desc'] =    "Disable sending IPv4 redirects";
1094
			$config['sysctl']['item'][4]['value'] =   "0";
1095
	
1096
			$config['sysctl']['item'][5]['tunable'] = "net.inet6.ip6.redirect";
1097
			$config['sysctl']['item'][5]['desc'] =    "Disable sending IPv6 redirects";
1098
			$config['sysctl']['item'][5]['value'] =   "0";
1099
	
1100
			$config['sysctl']['item'][6]['tunable'] = "net.inet.tcp.syncookies";
1101
			$config['sysctl']['item'][6]['desc'] =    "Generate SYN cookies for outbound SYN-ACK packets";
1102
			$config['sysctl']['item'][6]['value'] =   "1";
1103
	
1104
			$config['sysctl']['item'][7]['tunable'] = "net.inet.tcp.recvspace";
1105
			$config['sysctl']['item'][7]['desc'] =    "Maximum incoming TCP datagram size";
1106
			$config['sysctl']['item'][7]['value'] =   "65228";
1107
	
1108
			$config['sysctl']['item'][8]['tunable'] = "net.inet.tcp.sendspace";
1109
			$config['sysctl']['item'][8]['desc'] =    "Maximum outgoing TCP datagram size";
1110
			$config['sysctl']['item'][8]['value'] =   "65228";
1111
	
1112
			$config['sysctl']['item'][9]['tunable'] = "net.inet.ip.fastforwarding";
1113
			$config['sysctl']['item'][9]['desc'] =    "Fastforwarding (see http://lists.freebsd.org/pipermail/freebsd-net/2004-January/002534.html)";
1114
			$config['sysctl']['item'][9]['value'] =   "1";
1115
	
1116
			$config['sysctl']['item'][10]['tunable'] = "net.inet.tcp.delayed_ack";
1117
			$config['sysctl']['item'][10]['desc'] =    "Do not delay ACK to try and piggyback it onto a data packet";
1118
			$config['sysctl']['item'][10]['value'] =   "0";
1119
	
1120
			$config['sysctl']['item'][11]['tunable'] = "net.inet.udp.maxdgram";
1121
			$config['sysctl']['item'][11]['desc'] =    "Maximum outgoing UDP datagram size";
1122
			$config['sysctl']['item'][11]['value'] =   "57344";
1123
	
1124
			$config['sysctl']['item'][12]['tunable'] = "net.link.bridge.pfil_onlyip";
1125
			$config['sysctl']['item'][12]['desc'] =    "Handling of non-IP packets which are not passed to pfil (see if_bridge(4))";
1126
			$config['sysctl']['item'][12]['value'] =   "0";
1127
	
1128
			$config['sysctl']['item'][13]['tunable'] = "net.link.tap.user_open";
1129
			$config['sysctl']['item'][13]['desc'] =    "Allow unprivileged access to tap(4) device nodes";
1130
			$config['sysctl']['item'][13]['value'] =   "1";
1131
	
1132
			$config['sysctl']['item'][14]['tunable'] = "kern.rndtest.verbose";
1133
			$config['sysctl']['item'][14]['desc'] =    "Verbosity of the rndtest driver (0: do not display results on console)";
1134
			$config['sysctl']['item'][14]['value'] =   "0";
1135
	
1136
			$config['sysctl']['item'][15]['tunable'] = "kern.randompid";
1137
			$config['sysctl']['item'][15]['desc'] =    "Randomize PID's (see src/sys/kern/kern_fork.c: sysctl_kern_randompid())";
1138
			$config['sysctl']['item'][15]['value'] =   "347";
1139
	
1140
			$config['sysctl']['item'][16]['tunable'] = "net.inet.tcp.inflight.enable";
1141
			$config['sysctl']['item'][16]['desc'] =    "The system will attempt to calculate the bandwidth delay product for each connection and limit the amount of data queued to the network to just the amount required to maintain optimum throughput. ";
1142
			$config['sysctl']['item'][16]['value'] =   "3";
1143

    
1144
			$config['version'] = "4.1";
1145
		}
1146
	}
1147

    
1148
	/* Convert 4.1 -> 4.2 */
1149
        if ($config['version'] <= 4.0) {
1150
		if (isset($config['shaper']))
1151
                        unset($config['shaper']);
1152
                if (isset($config['ezshaper']))
1153
                        unset($config['ezshaper']);
1154

    
1155
                $config['version'] = "4.2";
1156
	}
1157
	if ($prev_version != $config['version'])
1158
		write_config("Upgraded config version level from {$prev_version} to {$config['version']}");
1159
}
1160

    
1161
/****f* config/write_config
1162
 * NAME
1163
 *   write_config - Backup and write the firewall configuration.
1164
 * DESCRIPTION
1165
 *   write_config() handles backing up the current configuration,
1166
 *   applying changes, and regenerating the configuration cache.
1167
 * INPUTS
1168
 *   $desc	- string containing the a description of configuration changes
1169
 *   $backup	- boolean: do not back up current configuration if false.
1170
 * RESULT
1171
 *   null
1172
 ******/
1173
/* save the system configuration */
1174
function write_config($desc="Unknown", $backup = true) {
1175
	global $config, $g;
1176

    
1177
	if($g['bootup']) 
1178
		log_error("WARNING! Configuration written on bootup.  This can cause stray openvpn and load balancing items in config.xml");
1179

    
1180
	if($backup)
1181
		backup_config();
1182

    
1183
	if (time() > mktime(0, 0, 0, 9, 1, 2004))       /* make sure the clock settings are plausible */
1184
		$changetime = time();
1185

    
1186
	/* Log the running script so it's not entirely unlogged what changed */
1187
    if ($desc == "Unknown")
1188
		$desc = "{$_SERVER['SCRIPT_NAME']} made unknown change";
1189

    
1190
	$config['revision']['description'] = $desc;
1191
	$config['revision']['time'] = $changetime;
1192

    
1193
	config_lock();
1194

    
1195
	/* generate configuration XML */
1196
	$xmlconfig = dump_xml_config($config, $g['xml_rootobj']);
1197

    
1198
	conf_mount_rw();
1199

    
1200
	/* write new configuration */
1201
	$fd = fopen("{$g['cf_conf_path']}/config.xml", "w");
1202
	if (!$fd)
1203
		die("Unable to open {$g['cf_conf_path']}/config.xml for writing in write_config()\n");
1204
	fwrite($fd, $xmlconfig);
1205
	fclose($fd);
1206

    
1207
	if($g['platform'] == "embedded") {
1208
		cleanup_backupcache(5);
1209
	} else {
1210
		cleanup_backupcache(30);
1211
	}
1212

    
1213
	if($g['booting'] <> true) {
1214
		mwexec("sync");
1215
		conf_mount_ro();
1216
	}
1217

    
1218
	/* re-read configuration */
1219
	$config = parse_xml_config("{$g['conf_path']}/config.xml", $g['xml_rootobj']);
1220

    
1221
	/* write config cache */
1222
	$fd = @fopen("{$g['tmp_path']}/config.cache", "wb");
1223
	if ($fd) {
1224
		fwrite($fd, serialize($config));
1225
		fclose($fd);
1226
	}
1227

    
1228
	/* tell kernel to sync fs data */
1229
	mwexec("/bin/sync");
1230

    
1231
	config_unlock();
1232

    
1233
	return $config;
1234
}
1235

    
1236
/****f* config/reset_factory_defaults
1237
 * NAME
1238
 *   reset_factory_defaults - Reset the system to its default configuration.
1239
 * RESULT
1240
 *   integer	- indicates completion
1241
 ******/
1242
function reset_factory_defaults() {
1243
	global $g;
1244

    
1245
	config_lock();
1246
	conf_mount_rw();
1247

    
1248
	/* create conf directory, if necessary */
1249
	safe_mkdir("{$g['cf_conf_path']}");
1250

    
1251
	/* clear out /conf */
1252
	$dh = opendir($g['conf_path']);
1253
	while ($filename = readdir($dh)) {
1254
		if (($filename != ".") && ($filename != "..")) {
1255
			unlink_if_exists($g['conf_path'] . "/" . $filename);
1256
		}
1257
	}
1258
	closedir($dh);
1259

    
1260
	/* copy default configuration */
1261
	copy("{$g['conf_default_path']}/config.xml", "{$g['conf_path']}/config.xml");
1262

    
1263
	/* call the wizard */
1264
	touch("/conf/trigger_initial_wizard");
1265

    
1266
	mwexec("sync");
1267
	conf_mount_ro();
1268
	config_unlock();
1269

    
1270
	return 0;
1271
}
1272

    
1273
function config_restore($conffile) {
1274
	global $config, $g;
1275

    
1276
	if (!file_exists($conffile))
1277
		return 1;
1278

    
1279
    config_lock();
1280
    conf_mount_rw();
1281

    
1282
    backup_config();
1283
    copy($conffile, "{$g['cf_conf_path']}/config.xml");
1284
	$config = parse_config(true);
1285
    write_config("Reverted to " . array_pop(explode("/", $conffile)) . ".", false);
1286

    
1287
	mwexec("sync");
1288
    conf_mount_ro();
1289
    config_unlock();
1290

    
1291
    return 0;
1292
}
1293

    
1294
function config_install($conffile) {
1295
	global $config, $g;
1296

    
1297
	if (!file_exists($conffile))
1298
		return 1;
1299

    
1300
	if (!config_validate("{$g['conf_path']}/config.xml"))
1301
		return 1;
1302

    
1303
	if($g['booting'] == true)
1304
		echo "Installing configuration...\n";
1305

    
1306
    config_lock();
1307
    conf_mount_rw();
1308

    
1309
    copy($conffile, "{$g['conf_path']}/config.xml");
1310

    
1311
	/* unlink cache file if it exists */
1312
	if(file_exists("{$g['tmp_path']}/config.cache"))
1313
		unlink("{$g['tmp_path']}/config.cache");
1314

    
1315
	mwexec("sync");
1316
    conf_mount_ro();
1317
    config_unlock();
1318

    
1319
    return 0;
1320
}
1321

    
1322
function config_validate($conffile) {
1323

    
1324
	global $g, $xmlerr;
1325

    
1326
	$xml_parser = xml_parser_create();
1327

    
1328
	if (!($fp = fopen($conffile, "r"))) {
1329
		$xmlerr = "XML error: unable to open file";
1330
		return false;
1331
	}
1332

    
1333
	while ($data = fread($fp, 4096)) {
1334
		if (!xml_parse($xml_parser, $data, feof($fp))) {
1335
			$xmlerr = sprintf("%s at line %d",
1336
						xml_error_string(xml_get_error_code($xml_parser)),
1337
						xml_get_current_line_number($xml_parser));
1338
			return false;
1339
		}
1340
	}
1341
	xml_parser_free($xml_parser);
1342

    
1343
	fclose($fp);
1344

    
1345
	return true;
1346
}
1347

    
1348
/*   lock configuration file, decide that the lock file
1349
 *   is stale after 10 seconds
1350
 */
1351
function config_lock() {
1352
	global $g, $process_lock;
1353

    
1354
	/* No need to continue if we're the ones holding the lock */
1355
	if ($process_lock)
1356
		return;
1357

    
1358
	$lockfile = "{$g['varrun_path']}/config.lock";
1359

    
1360
	$n = 0;
1361
	while ($n < 10) {
1362
		/* open the lock file in append mode to avoid race condition */
1363
		if ($fd = @fopen($lockfile, "x")) {
1364
			/* succeeded */
1365
			$process_lock = true;
1366
			fclose($fd);
1367
			return;
1368
		} else {
1369
			/* file locked, wait and try again */
1370
			$process_lock = false;
1371
			sleep(1);
1372
			$n++;
1373
		}
1374
	}
1375
}
1376

    
1377
/* unlock configuration file */
1378
function config_unlock() {
1379
	global $g, $process_lock;
1380

    
1381
	$lockfile = "{$g['varrun_path']}/config.lock";
1382
	$process_lock = false;
1383

    
1384
	unlink_if_exists($lockfile);
1385
}
1386

    
1387
function set_networking_interfaces_ports() {
1388
	global $noreboot;
1389
	global $config;
1390
	global $g;
1391
	global $fp;
1392

    
1393
	$fp = fopen('php://stdin', 'r');
1394

    
1395
	$memory = get_memory();
1396
	$avail = $memory[0];
1397

    
1398
	if($avail < $g['minimum_ram_warning']) {
1399
		echo "\n\n\n";
1400
		echo "DANGER!  WARNING!  ACHTUNG!\n\n";
1401
		echo "{$g['product_name']} requires *AT LEAST* {$g['minimum_ram_warning_text']} ram to function correctly.\n";
1402
		echo "Only ({$avail}) megs of ram has been detected.\n";
1403
		echo "\nPress ENTER to continue. ";
1404
		fgets($fp);
1405
		echo "\n";
1406
	}
1407

    
1408
	$iflist = get_interface_list();
1409

    
1410
	echo <<<EOD
1411

    
1412
Valid interfaces are:
1413

    
1414

    
1415
EOD;
1416

    
1417
	if(!is_array($iflist)) {
1418
		echo "No interfaces found!\n";
1419
	} else {
1420
		foreach ($iflist as $iface => $ifa) {
1421
			echo sprintf("% -8s%s%s\n", $iface, $ifa['mac'],
1422
				$ifa['up'] ? "   (up)" : "");
1423
		}
1424
	}
1425

    
1426
	echo <<<EOD
1427

    
1428
Do you want to set up VLANs first?
1429
If you are not going to use VLANs, or only for optional interfaces, you should
1430
say no here and use the webConfigurator to configure VLANs later, if required.
1431

    
1432
Do you want to set up VLANs now [y|n]?
1433
EOD;
1434

    
1435
	if (strcasecmp(chop(fgets($fp)), "y") == 0)
1436
		vlan_setup();
1437

    
1438
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
1439

    
1440
		echo "\n\nVLAN interfaces:\n\n";
1441
		$i = 0;
1442
		foreach ($config['vlans']['vlan'] as $vlan) {
1443

    
1444
			echo sprintf("% -8s%s\n", "vlan{$i}",
1445
				"VLAN tag {$vlan['tag']}, interface {$vlan['if']}");
1446

    
1447
			$iflist['vlan' . $i] = array();
1448
			$i++;
1449
		}
1450
	}
1451

    
1452
	echo <<<EOD
1453

    
1454
*NOTE*  {$g['product_name']} requires {$g['minimum_nic_count_text']} assigned interfaces to function.
1455
        If you do not have {$g['minimum_nic_count_text']} interfaces you CANNOT continue. 
1456

    
1457
        If you do not have at least {$g['minimum_nic_count']} *REAL* network interface cards
1458
        or one interface with multiple VLANs then {$g['product_name']}
1459
        *WILL NOT* function correctly.
1460

    
1461
If you do not know the names of your interfaces, you may choose to use
1462
auto-detection. In that case, disconnect all interfaces now before
1463
hitting 'a' to initiate auto detection.
1464

    
1465
EOD;
1466

    
1467
	do {
1468
		echo "\nEnter the WAN interface name or 'a' for auto-detection: ";
1469
		$wanif = chop(fgets($fp));
1470
		if ($wanif === "") {
1471
			return;
1472
		}
1473
		if ($wanif === "a")
1474
			$wanif = autodetect_interface("WAN", $fp);
1475
		else if (!array_key_exists($wanif, $iflist)) {
1476
			echo "\nInvalid interface name '{$wanif}'\n";
1477
			unset($wanif);
1478
			continue;
1479
		}
1480
	} while (!$wanif);
1481

    
1482
	do {
1483
		echo "\nEnter the LAN interface name or 'a' for auto-detection \n" .
1484
			"(or nothing if finished): ";
1485
		$lanif = chop(fgets($fp));
1486
		
1487
		if($lanif == "exit") {
1488
			exit;
1489
		}
1490
		
1491
		if($lanif == "") {
1492
			if($g['minimum_nic_count'] < 2) {
1493
				unset($config['interfaces']['lan']);
1494
				break;	
1495
			} else {
1496
				fclose($fp);
1497
				return;
1498
			}
1499
		}
1500

    
1501
		if ($lanif === "a")
1502
			$lanif = autodetect_interface("LAN", $fp);
1503
		else if (!array_key_exists($lanif, $iflist)) {
1504
			echo "\nInvalid interface name '{$lanif}'\n";
1505
			unset($lanif);
1506
			continue;
1507
		}
1508
	} while (!$lanif);
1509

    
1510
	/* optional interfaces */
1511
	$i = 0;
1512
	$optif = array();
1513

    
1514
	while (1) {
1515
		if ($optif[$i])
1516
			$i++;
1517
		$i1 = $i + 1;
1518

    
1519
		if($config['interfaces']['opt' . $i1]['descr'])
1520
			echo "\nOptional interface {$i1} description found: {$config['interfaces']['opt' . $i1]['descr']}";
1521

    
1522
		echo "\nEnter the Optional {$i1} interface name or 'a' for auto-detection\n" .
1523
			"(or nothing if finished): ";
1524

    
1525
		$optif[$i] = chop(fgets($fp));
1526

    
1527
		if ($optif[$i]) {
1528
			if ($optif[$i] === "a") {
1529
				$ad = autodetect_interface("Optional " . $i1, $fp);
1530
				if ($ad)
1531
					$optif[$i] = $ad;
1532
				else
1533
					unset($optif[$i]);
1534
			} else if (!array_key_exists($optif[$i], $iflist)) {
1535
				echo "\nInvalid interface name '{$optif[$i]}'\n";
1536
				unset($optif[$i]);
1537
				continue;
1538
			}
1539
		} else {
1540
			unset($optif[$i]);
1541
			break;
1542
		}
1543
	}
1544

    
1545
	/* check for double assignments */
1546
	$ifarr = array_merge(array($lanif, $wanif), $optif);
1547

    
1548
	for ($i = 0; $i < (count($ifarr)-1); $i++) {
1549
		for ($j = ($i+1); $j < count($ifarr); $j++) {
1550
			if ($ifarr[$i] == $ifarr[$j]) {
1551
				echo <<<EOD
1552

    
1553
Error: you cannot assign the same interface name twice!
1554

    
1555
EOD;
1556
				fclose($fp);
1557
				return;
1558
			}
1559
		}
1560
	}
1561

    
1562
	echo "The interfaces will be assigned as follows: \n\n";
1563

    
1564
	if ($lanif != "")
1565
		echo "LAN  ->" . $lanif . "\n";
1566
	echo "WAN  ->" . $wanif . "\n";
1567
	for ($i = 0; $i < count($optif); $i++) {
1568
		echo "OPT" . ($i+1) . " -> " . $optif[$i] . "\n";
1569
	}
1570

    
1571
echo <<<EOD
1572

    
1573
Do you want to proceed [y|n]?
1574
EOD;
1575

    
1576
	if (strcasecmp(chop(fgets($fp)), "y") == 0) {
1577

    
1578
		$config['interfaces']['lan']['if'] = $lanif;
1579
		if (preg_match($g['wireless_regex'], $lanif)) {
1580
			if (!is_array($config['interfaces']['lan']['wireless']))
1581
				$config['interfaces']['lan']['wireless'] = array();
1582
		} else {
1583
			unset($config['interfaces']['lan']['wireless']);
1584
		}
1585

    
1586
		$config['interfaces']['wan']['if'] = $wanif;
1587
		if (preg_match($g['wireless_regex'], $wanif)) {
1588
			if (!is_array($config['interfaces']['wan']['wireless']))
1589
				$config['interfaces']['wan']['wireless'] = array();
1590
		} else {
1591
			unset($config['interfaces']['wan']['wireless']);
1592
		}
1593

    
1594
		for ($i = 0; $i < count($optif); $i++) {
1595
			if (!is_array($config['interfaces']['opt' . ($i+1)]))
1596
				$config['interfaces']['opt' . ($i+1)] = array();
1597

    
1598
			$config['interfaces']['opt' . ($i+1)]['if'] = $optif[$i];
1599

    
1600
			/* wireless interface? */
1601
			if (preg_match($g['wireless_regex'], $optif[$i])) {
1602
				if (!is_array($config['interfaces']['opt' . ($i+1)]['wireless']))
1603
					$config['interfaces']['opt' . ($i+1)]['wireless'] = array();
1604
			} else {
1605
				unset($config['interfaces']['opt' . ($i+1)]['wireless']);
1606
			}
1607

    
1608
			unset($config['interfaces']['opt' . ($i+1)]['enable']);
1609
			$config['interfaces']['opt' . ($i+1)]['descr'] = "OPT" . ($i+1);
1610
		}
1611

    
1612
		/* remove all other (old) optional interfaces */
1613
		for (; isset($config['interfaces']['opt' . ($i+1)]); $i++)
1614
			unset($config['interfaces']['opt' . ($i+1)]);
1615

    
1616
		write_config();
1617

    
1618
		echo <<<EOD
1619

    
1620

    
1621

    
1622
EOD;
1623

    
1624
		fclose($fp);
1625
		if($g['booting'])
1626
			return;
1627

    
1628
		echo "One moment while we reload the settings...";
1629

    
1630
		$g['booting'] = false;
1631

    
1632
		/* resync everything */
1633
		reload_all_sync();
1634

    
1635
		echo " done!\n";
1636

    
1637
		touch("{$g['tmp_path']}/assign_complete");
1638

    
1639
	}
1640
}
1641

    
1642
function autodetect_interface($ifname, $fp) {
1643
	$iflist_prev = get_interface_list("media");
1644
	echo <<<EOD
1645

    
1646
Connect the {$ifname} interface now and make sure that the link is up.
1647
Then press ENTER to continue.
1648

    
1649
EOD;
1650
	fgets($fp);
1651
	$iflist = get_interface_list("media");
1652

    
1653
	foreach ($iflist_prev as $ifn => $ifa) {
1654
		if (!$ifa['up'] && $iflist[$ifn]['up']) {
1655
			echo "Detected link-up on interface {$ifn}.\n";
1656
			return $ifn;
1657
		}
1658
	}
1659

    
1660
	echo "No link-up detected.\n";
1661

    
1662
	return null;
1663
}
1664

    
1665
function vlan_setup() {
1666
	global $iflist, $config, $g, $fp;
1667

    
1668
	$iflist = get_interface_list();
1669

    
1670
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
1671

    
1672
	echo <<<EOD
1673

    
1674
WARNING: all existing VLANs will be cleared if you proceed!
1675

    
1676
Do you want to proceed [y|n]?
1677
EOD;
1678

    
1679
	if (strcasecmp(chop(fgets($fp)), "y") != 0)
1680
		return;
1681
	}
1682

    
1683
	$config['vlans']['vlan'] = array();
1684
	echo "\n";
1685

    
1686
	while (1) {
1687
		$vlan = array();
1688

    
1689
		echo "\n\nVLAN Capable interfaces:\n\n";
1690
		if(!is_array($iflist)) {
1691
			echo "No interfaces found!\n";
1692
		} else {
1693
			$vlan_capable=0;
1694
			foreach ($iflist as $iface => $ifa) {
1695
				if (is_jumbo_capable($iface)) {
1696
					echo sprintf("% -8s%s%s\n", $iface, $ifa['mac'],
1697
						$ifa['up'] ? "   (up)" : "");
1698
					$vlan_capable++;
1699
				}
1700
			}
1701
		}
1702

    
1703
		if($vlan_capable == 0) {
1704
			echo "No VLAN capable interfaces detected.\n";
1705
			return;
1706
		}
1707

    
1708
		echo "\nEnter the parent interface name for the new VLAN (or nothing if finished): ";
1709
		$vlan['if'] = chop(fgets($fp));
1710

    
1711
		if ($vlan['if']) {
1712
			if (!array_key_exists($vlan['if'], $iflist) or
1713
			    !is_jumbo_capable($vlan['if'])) {
1714
				echo "\nInvalid interface name '{$vlan['if']}'\n";
1715
				continue;
1716
			}
1717
		} else {
1718
			break;
1719
		}
1720

    
1721
		echo "Enter the VLAN tag (1-4094): ";
1722
		$vlan['tag'] = chop(fgets($fp));
1723

    
1724
		if (!is_numericint($vlan['tag']) || ($vlan['tag'] < 1) || ($vlan['tag'] > 4094)) {
1725
			echo "\nInvalid VLAN tag '{$vlan['tag']}'\n";
1726
			continue;
1727
		}
1728

    
1729
		$config['vlans']['vlan'][] = $vlan;
1730
	}
1731
}
1732

    
1733
function system_start_ftp_helpers() {
1734
	require_once("interfaces.inc");
1735
	global $config, $g;
1736

    
1737
	mwexec("/usr/bin/killall ftpsesame");
1738

    
1739
	/* build an array of interfaces to work with */
1740
	$iflist = array("lan" => "lan");
1741
	for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++)
1742
		$iflist['opt' . $i] = "opt{$i}";
1743

    
1744
	/* loop through all interfaces and handle ftp-proxy */
1745
	$interface_counter = 0;
1746
	foreach ($iflist as $ifent => $ifname) {
1747
		/*    if the ftp proxy is disabled for this interface then kill ftp-proxy
1748
		 *    instance and continue. note that the helpers for port forwards are
1749
		 *    launched in a  different sequence so we are filtering them out
1750
	         *    here by not including -c {$port} -g 8021 first.
1751
		 */
1752
		 /* only install a ftp helper for enabled interfaces. wan and lan are always enabled. */
1753
		if(stristr($ifname, "opt") <> false)
1754
			if(!isset($config['interfaces'][strtolower($ifname)]['enable']))
1755
				continue;
1756

    
1757
		/* Get the ftp queue for this interface */
1758
		if (isset($config['shaper'][$ifname]['ftpqueue']))
1759
			$shaper_queue = $config['interfaces'][$ifname]['ftpqueue'];
1760

    
1761
		$port = 8021 + $interface_counter;
1762
		if(isset($config['interfaces'][$ifname]['disableftpproxy'])) {
1763
			/*    item is disabled.  lets ++ the interface counter and
1764
			 *    keep processing interfaces. kill ftp-proxy if already
1765
			 *    running for this instance.
1766
			 */
1767
			$helpers = exec("/bin/ps awux | grep \"/usr/local/sbin/ftp-proxy {$shaper_queue} -p {$port}\" | grep -v grep | sed \"s/  */ /g\" | cut -f2 -d\" \"");
1768
			if($helpers)
1769
				mwexec("/bin/kill {$helpers}");
1770
			$interface_counter++;
1771
		} else {
1772
			/* grab the current interface IP address */
1773
			$int = convert_friendly_interface_to_real_interface_name($ifname);
1774
			$ip = find_interface_ip($int);
1775
			/* are we in routed mode? no source nat rules and not a outside interface? */
1776
			/* If we have advanced outbound nat we skip the FTP proxy, we use ftpsesame */
1777
			if((isset($config['nat']['advancedoutbound']['enable'])) && (! interface_has_gateway($ifname))) {
1778
				$sourcenat = 0;
1779
				/* we are using advanced outbound nat, are we in routing mode? */
1780
				/* if the interface address lies within a outbound NAT source network we should skip */
1781
				if(! empty($config['nat']['advancedoutbound']['rule'])) {
1782
					foreach($config['nat']['advancedoutbound']['rule'] as $natnetwork) {
1783
						if(ip_in_subnet($ip, $natnetwork['source']['network'])) {
1784
							/* if the interface address is matched in the AON Rule we need the ftp proxy */
1785
							if(is_ipaddr($natnetwork['target']) && ($natnetwork['interface'] == "wan")) {
1786
								$pftpxsourceaddr = "-a {$natnetwork['target']}";
1787
								if($g['debug'])
1788
									log_error("Config: AON: using the external ip source {$pftpxsourceaddr} for the ftp proxy");
1789
							}
1790
							$sourcenat++;
1791
						}
1792
					}
1793
				}
1794
				if($sourcenat == 0) {
1795
					if($g['debug'])
1796
						log_error("Config: No AON rule matched for interface {$ifname} - not using FTP proxy");
1797
					mwexec("/usr/local/sbin/ftpsesame -i $int");
1798
					$interface_counter++;
1799
					continue;
1800
				} else {
1801
					if($g['debug'])
1802
						log_error("Config: AON rule matched for interface {$ifname} - using FTP proxy");
1803
				}
1804
			}
1805
			/* if ftp-proxy is already running then do not launch it again */
1806
			$helpers = exec("/bin/ps awux | grep \"/usr/local/sbin/ftp-proxy {$shaper_queue} -p {$port}\" | grep -v grep | sed \"s/  */ /g\"");
1807
			if(!$helpers && $ip)
1808
 				mwexec("/usr/local/sbin/ftp-proxy {$shaper_queue} -p {$port} {$pftpxsourceaddr} {$ip}");
1809
			if(!$ip)
1810
				mwexec("/usr/local/sbin/ftpsesame {$shaper_queue} -i $int");
1811
			$interface_counter++;
1812
		}
1813
	}
1814
	/* support bridged interfaces.  even they need ftp mojo */
1815
	$num_bridges = find_number_of_created_bridges();
1816
	$num_bridges++;
1817
	for($x=0; $x<$num_bridges; $x++) {
1818
		mwexec("/usr/local/sbin/ftpsesame {$shaper_queue}-i bridge{$x}");
1819
	}
1820
}
1821

    
1822
function cleanup_backupcache($revisions = 30) {
1823
	global $g;
1824
	$i = false;
1825
	config_lock();
1826
	if(file_exists($g['cf_conf_path'] . '/backup/backup.cache')) {
1827
		conf_mount_rw();
1828
		$backups = get_backups();
1829
		$newbaks = array();
1830
		$bakfiles = glob($g['cf_conf_path'] . "/backup/config-*");
1831
		$baktimes = $backups['versions'];
1832
		$tocache = array();
1833
		unset($backups['versions']);
1834
   		foreach($bakfiles as $backup) { // Check for backups in the directory not represented in the cache.
1835
   			if(filesize($backup) == 0) {
1836
   				unlink($backup);
1837
   				continue;
1838
   			}
1839
			$tocheck = array_shift(explode('.', array_pop(explode('-', $backup))));
1840
            if(!in_array($tocheck, $baktimes)) {
1841
				$i = true;
1842
				if($g['booting'])
1843
					print " " . $tocheck . "a";
1844
				$newxml = parse_xml_config($backup, $g['xml_rootobj']);
1845
				if($newxml == "-1") {
1846
					log_error("The backup cache file $backup is corrupted.  Unlinking.");
1847
					unlink($backup);
1848
					log_error("The backup cache file $backup is corrupted.  Unlinking.");
1849
					continue;
1850
				}
1851
				if($newxml['revision']['description'] == "")
1852
					$newxml['revision']['description'] = "Unknown";
1853
				$tocache[$tocheck] = array('description' => $newxml['revision']['description']);
1854
			}
1855
    	}
1856
		foreach($backups as $checkbak) {
1857

    
1858
			if(count(preg_grep('/' . $checkbak['time'] . '/i', $bakfiles)) != 0) {
1859
				$newbaks[] = $checkbak;
1860
			} else {
1861
				$i = true;
1862
				if($g['booting']) print " " . $tocheck . "r";
1863
			}
1864
		}
1865
		foreach($newbaks as $todo) $tocache[$todo['time']] = array('description' => $todo['description']);
1866
		if(is_int($revisions) and (count($tocache) > $revisions)) {
1867
			$toslice = array_slice(array_keys($tocache), 0, $revisions);
1868
			foreach($toslice as $sliced)
1869
				$newcache[$sliced] = $tocache[$sliced];
1870
			foreach($tocache as $version => $versioninfo) {
1871
				if(!in_array($version, array_keys($newcache))) {
1872
					unlink_if_exists($g['conf_path'] . '/backup/config-' . $version . '.xml');
1873
					if($g['booting']) print " " . $tocheck . "d";
1874
				}
1875
			}
1876
			$tocache = $newcache;
1877
		}
1878
		$bakout = fopen($g['cf_conf_path'] . '/backup/backup.cache', "w");
1879
        fwrite($bakout, serialize($tocache));
1880
		fclose($bakout);
1881
		mwexec("sync");
1882
		conf_mount_ro();
1883
	}
1884
	if($g['booting']) {
1885
		if($i) {
1886
			print "done.\n";
1887
		}
1888
	}
1889
	config_unlock();
1890
}
1891

    
1892
function get_backups() {
1893
	global $g;
1894
	if(file_exists("{$g['cf_conf_path']}/backup/backup.cache")) {
1895
		$confvers = unserialize(file_get_contents("{$g['cf_conf_path']}/backup/backup.cache"));
1896
		$bakvers = array_keys($confvers);
1897
		$toreturn = array();
1898
		sort($bakvers);
1899
		// 	$bakvers = array_reverse($bakvers);
1900
		foreach(array_reverse($bakvers) as $bakver)
1901
			$toreturn[] = array('time' => $bakver, 'description' => $confvers[$bakver]['description']);
1902
	} else {
1903
		return false;
1904
	}
1905
	$toreturn['versions'] = $bakvers;
1906
	return $toreturn;
1907
}
1908

    
1909
function backup_config() {
1910
	global $config, $g;
1911

    
1912
	if($g['platform'] == "cdrom")
1913
		return;
1914

    
1915
	conf_mount_rw();
1916

    
1917
	/* Create backup directory if needed */
1918
	safe_mkdir("{$g['cf_conf_path']}/backup");
1919

    
1920
    if($config['revision']['time'] == "") {
1921
            $baktime = 0;
1922
    } else {
1923
            $baktime = $config['revision']['time'];
1924
    }
1925
    if($config['revision']['description'] == "") {
1926
            $bakdesc = "Unknown";
1927
    } else {
1928
            $bakdesc = $config['revision']['description'];
1929
    }
1930
    copy($g['cf_conf_path'] . '/config.xml', $g['cf_conf_path'] . '/backup/config-' . $baktime . '.xml');
1931
    if(file_exists($g['cf_conf_path'] . '/backup/backup.cache')) {
1932
            $backupcache = unserialize(file_get_contents($g['cf_conf_path'] . '/backup/backup.cache'));
1933
    } else {
1934
            $backupcache = array();
1935
    }
1936
    $backupcache[$baktime] = array('description' => $bakdesc);
1937
    $bakout = fopen($g['cf_conf_path'] . '/backup/backup.cache', "w");
1938
    fwrite($bakout, serialize($backupcache));
1939
    fclose($bakout);
1940

    
1941
	mwexec("sync");
1942
	conf_mount_ro();
1943

    
1944
	return true;
1945
}
1946

    
1947
function mute_kernel_msgs() {
1948
	exec("/sbin/conscontrol mute on");
1949
}
1950

    
1951
function unmute_kernel_msgs() {
1952
	exec("/sbin/conscontrol mute off");
1953
}
1954

    
1955
function start_devd() {
1956
	exec("/sbin/devd");
1957
	sleep(1);
1958
	if(file_exists("/tmp/rc.linkup"))
1959
		unlink("/tmp/rc.linkup");
1960
}
1961

    
1962
function is_interface_mismatch() {
1963
	global $config, $g;
1964
	if(!$config['interfaces']['lan']) 	
1965
		return false;
1966
	$lan_if = $config['interfaces']['lan']['if'];
1967
	$wan_if = get_real_wan_interface();
1968
	$do_assign = 0;
1969
	/* we need to ignore the vlan interface checks) */
1970
	if (stristr($lan_if, "vlan") == false and stristr($wan_if, "vlan") == false) {
1971
		if (does_interface_exist($lan_if) == false)
1972
			if($g['minimum_nic_count'] > 1)
1973
				$do_assign = 1;
1974
		if ($config['interfaces']['wan']['ipaddr'] <> "pppoe" && $config['interfaces']['wan']['ipaddr'] <> "pptp" && $do_assign == 0)
1975
			if (does_interface_exist($wan_if) == false)
1976
				$do_assign = 1;
1977
	}
1978
	/* XXX: enumerate OPT interfaces looking for mismatches */
1979
	if (file_exists("{$g['tmp_path']}/assign_complete"))
1980
		return false;
1981
	if ($do_assign == 1)
1982
		return true;
1983
	else
1984
		return false;
1985
}
1986

    
1987
function set_device_perms() {
1988
	$devices = array(
1989
		'pf'	=> array(	'user'	=> 'proxy',
1990
					'group'	=> 'proxy',
1991
					'mode'	=> 0660),
1992
		);
1993

    
1994
	foreach ($devices as $name => $attr) {
1995
		$path = "/dev/$name";
1996
		if (file_exists($path)) {
1997
			chown($path, $attr['user']);
1998
			chgrp($path, $attr['group']);
1999
			chmod($path, $attr['mode']);
2000
		}
2001
	}
2002
}
2003

    
2004
if($g['booting']) echo ".";
2005
$config = parse_config();
2006

    
2007
?>
(6-6/29)