Project

General

Profile

Download (75.9 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
        $now = date("H:i:s");
489
        log_error("Start Configuration upgrade at $now, set execution timeout to 15 minutes");
490
        ini_set("max_execution_time", "900");
491

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

    
507
	// Save off config version
508
	$prev_version = $config['version'];
509

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

    
515
		/* convert DMZ to optional, if necessary */
516
		if (isset($config['interfaces']['dmz'])) {
517

    
518
			$dmzcfg = &$config['interfaces']['dmz'];
519

    
520
			if ($dmzcfg['if']) {
521
				$config['interfaces']['opt' . $opti] = array();
522
				$optcfg = &$config['interfaces']['opt' . $opti];
523

    
524
				$optcfg['enable'] = $dmzcfg['enable'];
525
				$optcfg['descr'] = "DMZ";
526
				$optcfg['if'] = $dmzcfg['if'];
527
				$optcfg['ipaddr'] = $dmzcfg['ipaddr'];
528
				$optcfg['subnet'] = $dmzcfg['subnet'];
529

    
530
				$ifmap['dmz'] = "opt" . $opti;
531
				$opti++;
532
			}
533

    
534
			unset($config['interfaces']['dmz']);
535
		}
536

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

    
540
			if (!$config['interfaces']['wlan' . $i]['if']) {
541
				unset($config['interfaces']['wlan' . $i]);
542
				continue;
543
			}
544

    
545
			$wlancfg = &$config['interfaces']['wlan' . $i];
546
			$config['interfaces']['opt' . $opti] = array();
547
			$optcfg = &$config['interfaces']['opt' . $opti];
548

    
549
			$optcfg['enable'] = $wlancfg['enable'];
550
			$optcfg['descr'] = "WLAN" . $i;
551
			$optcfg['if'] = $wlancfg['if'];
552
			$optcfg['ipaddr'] = $wlancfg['ipaddr'];
553
			$optcfg['subnet'] = $wlancfg['subnet'];
554
			$optcfg['bridge'] = $wlancfg['bridge'];
555

    
556
			$optcfg['wireless'] = array();
557
			$optcfg['wireless']['mode'] = $wlancfg['mode'];
558
			$optcfg['wireless']['ssid'] = $wlancfg['ssid'];
559
			$optcfg['wireless']['channel'] = $wlancfg['channel'];
560
			$optcfg['wireless']['wep'] = $wlancfg['wep'];
561

    
562
			$ifmap['wlan' . $i] = "opt" . $opti;
563

    
564
			unset($config['interfaces']['wlan' . $i]);
565
			$opti++;
566
		}
567

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

    
572
			$fr = &$config['filter']['rule'][$i];
573

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

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

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

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

    
617
			$fr = &$config['pfqueueing']['rule'][$i];
618

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

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

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

    
657
		$config['version'] = "1.1";
658
	}
659

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

    
667
		/* encrypt password */
668
		$config['system']['password'] = crypt($config['system']['password']);
669

    
670
		$config['version'] = "1.2";
671
	}
672

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

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

    
690
		$config['version'] = "1.3";
691
	}
692

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

    
699
			for ($i = 0; isset($config['pfqueueing']['rule'][$i]); $i++) {
700
				$curent = &$config['pfqueueing']['rule'][$i];
701

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

    
710
				$curent['targetpipe'] = $i;
711

    
712
				unset($curent['bandwidth']);
713
				unset($curent['delay']);
714
				unset($curent['mask']);
715
			}
716
		}
717

    
718
		$config['version'] = "1.4";
719
	}
720

    
721
	/* Convert 1.4 -> 1.5 */
722
	if ($config['version'] <= 1.4) {
723

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

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

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

    
741
		$config['version'] = "1.5";
742
	}
743

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

    
757
		$config['version'] = "1.6";
758
	}
759

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

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

    
824
		$config['version'] = "1.9";
825
	}
826

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

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

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

    
888
		$config['cron']['item'][] = $cron_item;
889

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

    
899
		$config['cron']['item'][] = $cron_item;
900

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

    
910
		$config['cron']['item'][] = $cron_item;
911

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

    
921
		$config['cron']['item'][] = $cron_item;
922

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

    
932
		$config['cron']['item'][] = $cron_item;
933

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

    
943
		$config['cron']['item'][] = $cron_item;
944

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

    
954
		$config['cron']['item'][] = $cron_item;
955

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

    
965
		$config['cron']['item'][] = $cron_item;
966

    
967
		/* write crontab entries to file */
968
		configure_cron();
969

    
970
 		$config['version'] = "2.6";
971
	}
972

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

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

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

    
1015
	/* Convert 3.0 -> 4.0 */
1016
	if ($config['version'] <= 3.9) {
1017
		$config['system']['webgui']['auth_method'] = "session";
1018
		$config['system']['webgui']['backing_method'] = "htpasswd";
1019

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

    
1029
			$config['system']['user'] = array();
1030
			$config['system']['user'][0]['name'] = "{$config['system']['username']}";
1031
			$config['system']['user'][0]['fullname'] = "System Administrator";
1032
			$config['system']['user'][0]['scope'] = "system";
1033
			$config['system']['user'][0]['groupname'] = "admins";
1034
			$config['system']['user'][0]['password'] = "{$config['system']['password']}";
1035
			$config['system']['user'][0]['uid'] = "0";
1036

    
1037
			$config['system']['user'][0]['priv'] = array();
1038
			$config['system']['user'][0]['priv'][0]['id'] = "lockwc";
1039
			$config['system']['user'][0]['priv'][0]['name'] = "Lock webConfigurator";
1040
			$config['system']['user'][0]['priv'][0]['descr'] = "Indicates whether this user will lock access to the webConfigurator for other users.";
1041
			$config['system']['user'][0]['priv'][1]['id'] = "lock-ipages";
1042
			$config['system']['user'][0]['priv'][1]['name'] = "Lock individual pages";
1043
			$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).";
1044
			$config['system']['user'][0]['priv'][2]['id'] = "hasshell";
1045
			$config['system']['user'][0]['priv'][2]['name'] = "Has shell access";
1046
			$config['system']['user'][0]['priv'][2]['descr'] = "Indicates whether this user is able to login for example via SSH.";
1047
			$config['system']['user'][0]['priv'][3]['id'] = "copyfiles";
1048
			$config['system']['user'][0]['priv'][3]['name'] = "Is allowed to copy files";
1049
			$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).";
1050
			$config['system']['user'][0]['priv'][4]['id'] = "isroot";
1051
			$config['system']['user'][0]['priv'][4]['name'] = "Is root user";
1052
			$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).";
1053

    
1054
			$config['system']['nextuid'] = "111";
1055
			$config['system']['nextgid'] = "111";
1056

    
1057
			/* wipe previous auth configuration */
1058
			unset ($config['system']['username']);
1059
			unset ($config['system']['password']);
1060
			
1061
			$config['version'] = "4.0";
1062
		}
1063

    
1064
	}
1065
		
1066
	/* Convert 4.0 -> 4.1 */
1067
	if ($config['version'] <= 4.0) {
1068
		if(!$config['sysctl']) {
1069

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

    
1140
			$config['version'] = "4.1";
1141
		}
1142
	}
1143

    
1144
	/* Convert 4.1 -> 4.2 */
1145
	if ($config['version'] <= 4.1) {
1146
		if (isset($config['shaper']))
1147
			unset($config['shaper']);
1148
		if (isset($config['ezshaper']))
1149
			unset($config['ezshaper']);
1150
		$config['version'] = "4.2";
1151
	}
1152

    
1153
	/* Convert 4.2 -> 4.3 */
1154
	if ($config['version'] <= 4.2) {
1155
		/* migrate old interface gateway to the new gateways config */
1156
		$old_gateways = array();
1157
		$gateways = array();
1158
		$i = 0;
1159
		$old_gateways = get_interfaces_with_gateway();
1160
		foreach($old_gateways as $ifname => $interface) {
1161
			if(is_ipaddr($config['interfaces'][$ifname]['gateway'])) {
1162
				$config['gateways'][$i][$ifname]['gateway'] = $config['interfaces'][$ifname]['gateway'];
1163
				$config['gateways'][$i][$ifname]['interface'] = $ifname;
1164
				$config['gateways'][$i][$ifname]['name'] = $ifname ."-". $config['interfaces'][$ifname]['gateway'];
1165
				if(is_ipaddr($config['interfaces'][$ifname]['use_rrd_gateway'])) {
1166
					$config['gateways'][$i][$ifname]['monitor'] = $config['interfaces'][$ifname]['use_rrd_gateway'];
1167
					unset($config['interfaces'][$ifname]['use_rrd_gateway']);
1168
				}
1169
				$config['interfaces'][$ifname]['gateway'] = $config['gateways'][$i][$ifname]['name'];
1170
				$i++;
1171
			}
1172
		}
1173
		$config['version'] = "4.3";
1174
	}
1175

    
1176
	/* Convert 4.3 -> 4.4 */
1177
	if ($config['version'] <= 4.3) {
1178
		if (isset($config['installedpackages']['openvpnserver']['config'])) {
1179
			$ocfg =& $config['installedpackages']['openvpnserver']['config'];
1180
			if (!isset($config['openvpn']))
1181
				$config['openvpn'] = array();
1182
			if (!isset($config['openvpn']['keys']))
1183
				$config['openvpn']['keys'] = array();
1184
			$ncfg =& $config['openvpn']['keys'];
1185
			foreach ($ocfg as $id => $cfg) {
1186
				if ($cfg['auth_method'] == 'shared_key') {
1187
					$ncfg["converted{$id}"]['shared.key'] = $cfg['shared_key'];
1188
					$ncfg["converted{$id}"]['existing'] = "yes";
1189
					$ncfg["converted{$id}"]['auth_method'] = "shared_key";
1190
					$ocfg['cipher'] = "converted{$id}";
1191
					unset($ocfg['shared_key']);
1192
				} else  {
1193
					if (isset($ocfg['ca_cert']))  {
1194
						$ncfg["converted{$id}"]['ca.crt'] = $ocfg['ca_cert'];
1195
						unset($ocfg['ca_cert']);
1196
					}
1197
					if (isset($ocfg['server_cert']))  {
1198
						$ncfg["converted{$id}"]['server.crt'] = $ocfg['server_cert'];
1199
						unset($ocfg['server_cert']);
1200
					}
1201
					if (isset($ocfg['server_key']))  {
1202
						$ncfg["converted{$id}"]['server.key'] = $ocfg['server_key'];
1203
						unset($ocfg['ca_cert']);
1204
					}
1205
					if (isset($ocfg['dh_params']))  {
1206
						$ncfg["converted{$id}"]['dh_params.dh'] = $ocfg['dh_params'];
1207
						unset($ocfg['dh_params']);
1208
					}
1209
					if (isset($ocfg['crl']))  {
1210
						$ncfg["converted{$id}"]['crl'] = $ocfg['crl'];
1211
						unset($ocfg['crl']);
1212
					}
1213
					$ncfg["converted{$id}"]['existing'] = "yes";
1214
					$ocfg['cipher'] = "converted{$id}";
1215
				}
1216

    
1217
			}
1218
		}
1219
		$config['version'] = "4.4";
1220
	}
1221

    
1222
        /* Convert 4.4 -> 4.5 */
1223
        if ($config['version'] <= 4.4) {
1224
                if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
1225
                        foreach ($config['vlans']['vlan'] as $id => $vlan)
1226
                                $config['vlans']['vlan'][$id]['vlanif'] = "vlan{$id}";
1227
                }
1228
                $config['version'] = "4.5";
1229
        }
1230

    
1231
	/* Upgrade load balancer from slb to relayd */
1232
        /* Convert 4.5 -> 4.6 */
1233
        if ($config['version'] <= 4.5) {
1234
                if (is_array($config['load_balancer']['virtual_server']) && count($config['load_balancer']['virtual_server'])) {
1235
			$vs_a = &$config['load_balancer']['virtual_server'];
1236
			$pool_a = &$config['load_balancer']['lbpool'];
1237
			$pools = array();
1238
			/* Index pools by name */
1239
			if(is_array($pool_a)) {
1240
				for ($i = 0; isset($pool_a[$i]); $i++) {
1241
					if ($pool_a[$i]['type'] == "server") {
1242
						$pools[$pool_a[$i]['name']] = $pool_a[$i];
1243
					}
1244
				}
1245
			}
1246
			/* Convert sitedown entries to pools and re-attach */
1247
			for ($i = 0; isset($vs_a[$i]); $i++) {
1248
				if (isset($vs_a[$i]['sitedown'])) {
1249
					$pool = array();
1250
					$pool['type'] = 'server';
1251
					$pool['behaviour'] = 'balance';
1252
					$pool['name'] = "{$vs_a[$i]['name']}-sitedown";
1253
					$pool['desc'] = "Sitedown pool for VS: {$vs_a[$i]['name']}";
1254
					$pool['port'] = $pools[$vs_a[$i]['pool']]['port'];
1255
					$pool['servers'] = array();
1256
					$pool['servers'][] = $vs_a[$i]['sitedown'];
1257
					$pool['monitor'] = $pools[$vs_a[$i]['pool']]['monitor'];
1258
					$pool_a[] = $pool;
1259
					$vs_a[$i]['sitedown'] = $pool['name'];
1260
				}
1261
			}
1262
                }
1263
                $config['version'] = "4.6";
1264
        }
1265

    
1266
	/* Convert 4.6 -> 4.7 */
1267
	if ($config['version'] <= 4.7) {
1268

    
1269
		/* Upgrade IPsec from tunnel to phase1/phase2 */
1270

    
1271
		echo "Beginning upgrade to version 4.7\n";
1272

    
1273
        if(is_array($config['ipsec']['tunnel'])) {
1274

    
1275
			$a_phase1 = array();
1276
			$a_phase2 = array();
1277
			$ikeid = 0;
1278

    
1279
			foreach ($config['ipsec']['tunnel'] as $tunnel) {
1280

    
1281
				unset($ph1ent);
1282
				unset($ph2ent);
1283

    
1284
				/*
1285
				 *  attempt to locate an enabled phase1
1286
				 *  entry that matches the peer gateway
1287
				 */
1288

    
1289
				if (!isset($tunnel['disabled'])) {
1290

    
1291
					$remote_gateway = $tunnel['remote-gateway'];
1292

    
1293
					foreach ($a_phase1 as $ph1tmp) {
1294
						if ($ph1tmp['remote-gateway'] == $remote_gateway) {
1295
							$ph1ent = $ph1tmp;
1296
							break;
1297
						}
1298
					}
1299
				}
1300

    
1301
				/* none found, create a new one */
1302

    
1303
				if (!isset( $ph1ent )) {
1304

    
1305
					/* build new phase1 entry */
1306

    
1307
					$ph1ent = array();
1308

    
1309
					$ph1ent['ikeid'] = ++$ikeid;
1310

    
1311
					if (isset($tunnel['disabled']))
1312
						$ph1ent['disabled'] = $tunnel['disabled'];
1313

    
1314
					$ph1ent['interface'] = $tunnel['interface'];
1315
					$ph1ent['remote-gateway'] = $tunnel['remote-gateway'];
1316
					$ph1ent['descr'] = $tunnel['descr'];
1317

    
1318
					$ph1ent['mode'] = $tunnel['p1']['mode'];
1319

    
1320
					if (isset($tunnel['p1']['myident']['myaddress']))
1321
						$ph1ent['myid_type'] = "myaddress";
1322
					if (isset($tunnel['p1']['myident']['address'])) {
1323
						$ph1ent['myid_type'] = "address";
1324
						$ph1ent['myid_data'] = $tunnel['p1']['myident']['address'];
1325
					}
1326
					if (isset($tunnel['p1']['myident']['fqdn'])) {
1327
						$ph1ent['myid_type'] = "fqdn";
1328
						$ph1ent['myid_data'] = $tunnel['p1']['myident']['fqdn'];
1329
					}
1330
					if (isset($tunnel['p1']['myident']['user_fqdn'])) {
1331
						$ph1ent['myid_type'] = "user_fqdn";
1332
						$ph1ent['myid_data'] = $tunnel['p1']['myident']['user_fqdn'];
1333
					}
1334
					if (isset($tunnel['p1']['myident']['asn1dn'])) {
1335
						$ph1ent['myid_type'] = "asn1dn";
1336
						$ph1ent['myid_data'] = $tunnel['p1']['myident']['asn1dn'];
1337
					}
1338
					if (isset($tunnel['p1']['myident']['dyn_dns'])) {
1339
						$ph1ent['myid_type'] = "dyn_dns";
1340
						$ph1ent['myid_data'] = $tunnel['p1']['myident']['dyn_dns'];
1341
					}
1342

    
1343
					$ph1ent['peerid_type'] = "peeraddress";
1344

    
1345
					switch ($tunnel['p1']['encryption-algorithm']) {
1346
					case "des":
1347
						$ph1alg = array( 'name' => 'des' );
1348
						break;
1349
					case "3des":
1350
						$ph1alg = array( 'name' => '3des' );
1351
						break;
1352
					case "blowfish":
1353
						$ph1alg = array( 'name' => 'blowfish', 'keylen' => '128'  );
1354
						break;
1355
					case "cast128":
1356
						$ph1alg = array( 'name' => 'cast128' );
1357
						break;
1358
					case "rijndael":
1359
						$ph1alg = array( 'name' => 'aes', 'keylen' => '128' );
1360
						break;
1361
					case "rijndael 256":
1362
						$ph1alg = array( 'name' => 'aes', 'keylen' => '256' );
1363
						break;
1364
					}
1365

    
1366
					$ph1ent['encryption-algorithm'] = $ph1alg;
1367
					$ph1ent['hash-algorithm'] = $tunnel['p1']['hash-algorithm'];
1368
					$ph1ent['dhgroup'] = $tunnel['p1']['dhgroup'];
1369
					$ph1ent['lifetime'] = $tunnel['p1']['lifetime'];
1370
					$ph1ent['authentication_method'] = $tunnel['p1']['authentication_method'];
1371

    
1372
					if (isset($tunnel['p1']['pre-shared-key']))
1373
						$ph1ent['pre-shared-key'] = $tunnel['p1']['pre-shared-key'];
1374
					if (isset($tunnel['p1']['cert']))
1375
						$ph1ent['cert'] = $tunnel['p1']['cert'];
1376
					if (isset($tunnel['p1']['peercert']))
1377
						$ph1ent['peercert'] = $tunnel['p1']['peercert'];
1378
					if (isset($tunnel['p1']['private-key']))
1379
						$ph1ent['private-key'] = $tunnel['p1']['private-key'];
1380

    
1381
					if (isset($tunnel['pinghost']['pinghost']))
1382
						$ph1ent['pinghost'] = $tunnel['pinghost'];
1383

    
1384
					$ph1ent['nat_traversal'] = "on";
1385
					$ph1ent['dpd_enable'] = 1;
1386
					$ph1ent['dpd_delay'] = 10;
1387
					$ph1ent['dpd_maxfail'] = 5;
1388

    
1389
					$a_phase1[] = $ph1ent;
1390
				}
1391

    
1392
				/* build new phase2 entry */
1393

    
1394
				$ph2ent = array();
1395

    
1396
				$ph2ent['ikeid'] = $ph1ent['ikeid'];
1397

    
1398
				if (isset($tunnel['disabled']))
1399
					$ph1ent['disabled'] = $tunnel['disabled'];
1400

    
1401
				$ph2ent['descr'] = "phase2 for ".$tunnel['descr'];
1402

    
1403
				$type = "lan";
1404
				if ($tunnel['local-subnet']['network'])
1405
					$type = $tunnel['local-subnet']['network'];
1406
				if ($tunnel['local-subnet']['address']) {
1407
					list($address,$netbits) = explode("/",$tunnel['local-subnet']['address']);
1408
					if (is_null($netbits))
1409
						$type = "address";
1410
					else
1411
						$type = "network";
1412
				}
1413
				
1414
				switch ($type) {
1415
					case "address":
1416
						$ph2ent['localid'] = array('type' => $type,'address' => $address);
1417
						break;
1418
					case "network":
1419
						$ph2ent['localid'] = array('type' => $type,'address' => $address,'netbits' => $netbits);
1420
						break;
1421
					default:
1422
						$ph2ent['localid'] = array('type' => $type);
1423
						break;
1424
				}
1425

    
1426
				list($address,$netbits) = explode("/",$tunnel['remote-subnet']);
1427
				$ph2ent['remoteid'] = array('type' => 'network','address' => $address,'netbits' => $netbits);
1428

    
1429
				$ph2ent['protocol'] = $tunnel['p2']['protocol'];
1430

    
1431
				$aes_count = 0;
1432
				foreach( $tunnel['p2']['encryption-algorithm-option'] as $tunalg ) {
1433
					$aes_found = false;
1434
					switch ($tunalg) {
1435
						case "des":
1436
							$ph2alg = array( 'name' => 'des' );
1437
							break;
1438
						case "3des":
1439
							$ph2alg = array( 'name' => '3des' );
1440
							break;
1441
						case "blowfish":
1442
							$ph2alg = array( 'name' => 'blowfish', 'keylen' => 'auto'  );
1443
							break;
1444
						case "cast128":
1445
							$ph2alg = array( 'name' => 'cast128' );
1446
							break;
1447
						case "rijndael":
1448
						case "rijndael 256":
1449
							$ph2alg = array( 'name' => 'aes', 'keylen' => 'auto' );
1450
							$aes_found = true;
1451
							$aes_count++;
1452
							break;
1453
					}
1454

    
1455
					if( !$aes_found || ($aes_count < 2))
1456
						$ph2ent['encryption-algorithm-option'][] = $ph2alg;
1457
				}
1458

    
1459
				$ph2ent['hash-algorithm-option'] = $tunnel['p2']['hash-algorithm-option'];
1460
				$ph2ent['pfsgroup'] = $tunnel['p2']['pfsgroup'];
1461
				$ph2ent['lifetime'] = $tunnel['p2']['lifetime'];
1462

    
1463
				$a_phase2[] = $ph2ent;
1464
			}
1465

    
1466
			unset($config['ipsec']['tunnel']);
1467
			$config['ipsec']['phase1'] = $a_phase1;
1468
			$config['ipsec']['phase2'] = $a_phase2;
1469
		}
1470

    
1471
		$config['version'] = "4.7";
1472
	}
1473
	
1474
	/* Convert 4.7 -> 4.8 */
1475
        if ($config['version'] <= 4.7) {
1476
		$config['dyndnses']['dyndns'] = array();
1477
		if (isset($config['dyndns']['enable'])) {
1478
			$tempdyn = array();
1479
			$tempdyn['enable'] = isset($config['dyndns']['enable']);
1480
			$tempdyn['type'] = $config['dyndns']['type'];
1481
			$tempdyn['wildcard'] = isset($config['dyndns']['wildcard']);
1482
			$tempdyn['usernamefld'] = $config['dyndns']['username'];
1483
			$tempdyn['passwordfld'] = $config['dyndns']['password'];
1484
			$tempdyn['host'] = $config['dyndns']['host'];
1485
			$tempdyn['mx'] = $config['dyndns']['mx'];		
1486
			$config['dyndnses']['dyndns'][] = $tempdyn;
1487
			unset($config['dyndns']);
1488
		}		
1489
		$config['dnsupdates']['dnsupdate'] = array();
1490
		if (isset($config['dnsupdate']['enable'])) {
1491
			$pconfig = array();
1492
			$pconfig['dnsupdate_enable'] = isset($config['dnsupdate']['enable']);
1493
			$pconfig['dnsupdate_host'] = $config['dnsupdate']['host'];
1494
			$pconfig['dnsupdate_ttl'] = $config['dnsupdate']['ttl'];
1495
			if (!$pconfig['dnsupdate_ttl'])
1496
				$pconfig['dnsupdate_ttl'] = 60;
1497
			$pconfig['dnsupdate_keydata'] = $config['dnsupdate']['keydata'];
1498
			$pconfig['dnsupdate_keyname'] = $config['dnsupdate']['keyname'];
1499
			$pconfig['dnsupdate_keytype'] = $config['dnsupdate']['keytype'];
1500
			if (!$pconfig['dnsupdate_keytype'])
1501
				$pconfig['dnsupdate_keytype'] = "zone";
1502
			$pconfig['dnsupdate_server'] = $config['dnsupdate']['server'];
1503
			$pconfig['dnsupdate_usetcp'] = isset($config['dnsupdate']['usetcp']);
1504
			$config['dnsupdates']['dnsupdate'][] = $pconfig;
1505
			unset($config['dnsupdate']);
1506
		}
1507
		
1508
		if (is_array($config['pppoe'])) {
1509
			$pconfig = array();
1510
			$pconfig['username'] = $config['pppoe']['username'];
1511
			$pconfig['password'] = $config['pppoe']['password'];
1512
			$pconfig['provider'] = $config['pppoe']['provider'];
1513
			$pconfig['ondemand'] = isset($config['pppoe']['ondemand']);
1514
			$pconfig['timeout'] = $config['pppoe']['timeout'];
1515
			unset($config['pppoe']);
1516
			$config['interfaces']['wan']['username'] = $pconfig['username'];
1517
			$config['interfaces']['wan']['password'] = $pconfig['password'];
1518
			$config['interfaces']['wan']['provider'] = $pconfig['provider'];
1519
			$config['interfaces']['wan']['username'] = isset($pconfig['ondemand']);
1520
			$config['interfaces']['wan']['timeout'] = $pconfig['timeout'];
1521
		}
1522
		if (is_array($config['pptp'])) {
1523
                        $pconfig = array();
1524
                        $pconfig['username'] = $config['pptp']['username'];
1525
                        $pconfig['password'] = $config['pptp']['password'];
1526
                        $pconfig['provider'] = $config['pptp']['provider'];
1527
                        $pconfig['ondemand'] = isset($config['pptp']['ondemand']);
1528
                        $pconfig['timeout'] = $config['pptp']['timeout'];
1529
                        unset($config['pptp']);
1530
                        $config['interfaces']['wan']['username'] = $pconfig['username'];
1531
                        $config['interfaces']['wan']['password'] = $pconfig['password'];
1532
                        $config['interfaces']['wan']['provider'] = $pconfig['provider'];
1533
                        $config['interfaces']['wan']['username'] = isset($pconfig['ondemand']
1534
);
1535
                        $config['interfaces']['wan']['timeout'] = $pconfig['timeout'];
1536
                }
1537

    
1538
		$config['version'] = 4.8;
1539
	}
1540

    
1541
	$now = date("H:i:s");
1542
	log_error("Ended Configuration upgrade at $now");
1543

    
1544
//	if ($prev_version != $config['version'])
1545
		write_config("Upgraded config version level from {$prev_version} to {$config['version']}");
1546
}
1547

    
1548
/****f* config/write_config
1549
 * NAME
1550
 *   write_config - Backup and write the firewall configuration.
1551
 * DESCRIPTION
1552
 *   write_config() handles backing up the current configuration,
1553
 *   applying changes, and regenerating the configuration cache.
1554
 * INPUTS
1555
 *   $desc	- string containing the a description of configuration changes
1556
 *   $backup	- boolean: do not back up current configuration if false.
1557
 * RESULT
1558
 *   null
1559
 ******/
1560
/* save the system configuration */
1561
function write_config($desc="Unknown", $backup = true) {
1562
	global $config, $g;
1563

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

    
1567
	if($backup)
1568
		backup_config();
1569

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

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

    
1577
	$config['revision']['description'] = $desc;
1578
	$config['revision']['time'] = $changetime;
1579

    
1580
	config_lock();
1581

    
1582
	/* generate configuration XML */
1583
	$xmlconfig = dump_xml_config($config, $g['xml_rootobj']);
1584

    
1585
	conf_mount_rw();
1586

    
1587
	/* write new configuration */
1588
	if (!safe_write_file("{$g['cf_conf_path']}/config.xml", $xmlconfig, false)) {
1589
		die("Unable to open {$g['cf_conf_path']}/config.xml for writing in write_config()\n");
1590
	}
1591

    
1592
	if($g['platform'] == "embedded") {
1593
		cleanup_backupcache(5);
1594
	} else {
1595
		cleanup_backupcache(30);
1596
	}
1597

    
1598
	if($g['booting'] <> true) {
1599
		mwexec("sync");
1600
		conf_mount_ro();
1601
	}
1602

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

    
1606
	/* write config cache */
1607
	safe_write_file("{$g['tmp_path']}/config.cache", serialize($config), true);
1608

    
1609
	/* tell kernel to sync fs data */
1610
	mwexec("/bin/sync");
1611

    
1612
	config_unlock();
1613

    
1614
	return $config;
1615
}
1616

    
1617
/****f* config/reset_factory_defaults
1618
 * NAME
1619
 *   reset_factory_defaults - Reset the system to its default configuration.
1620
 * RESULT
1621
 *   integer	- indicates completion
1622
 ******/
1623
function reset_factory_defaults() {
1624
	global $g;
1625

    
1626
	config_lock();
1627
	conf_mount_rw();
1628

    
1629
	/* create conf directory, if necessary */
1630
	safe_mkdir("{$g['cf_conf_path']}");
1631

    
1632
	/* clear out /conf */
1633
	$dh = opendir($g['conf_path']);
1634
	while ($filename = readdir($dh)) {
1635
		if (($filename != ".") && ($filename != "..")) {
1636
			unlink_if_exists($g['conf_path'] . "/" . $filename);
1637
		}
1638
	}
1639
	closedir($dh);
1640

    
1641
	/* copy default configuration */
1642
	copy("{$g['conf_default_path']}/config.xml", "{$g['conf_path']}/config.xml");
1643

    
1644
	/* call the wizard */
1645
	touch("/conf/trigger_initial_wizard");
1646

    
1647
	mwexec("sync");
1648
	conf_mount_ro();
1649
	config_unlock();
1650

    
1651
	return 0;
1652
}
1653

    
1654
function config_restore($conffile) {
1655
	global $config, $g;
1656

    
1657
	if (!file_exists($conffile))
1658
		return 1;
1659

    
1660
    config_lock();
1661
    conf_mount_rw();
1662

    
1663
    backup_config();
1664
    copy($conffile, "{$g['cf_conf_path']}/config.xml");
1665
	$config = parse_config(true);
1666
    write_config("Reverted to " . array_pop(explode("/", $conffile)) . ".", false);
1667

    
1668
	mwexec("sync");
1669
    conf_mount_ro();
1670
    config_unlock();
1671

    
1672
    return 0;
1673
}
1674

    
1675
function config_install($conffile) {
1676
	global $config, $g;
1677

    
1678
	if (!file_exists($conffile))
1679
		return 1;
1680

    
1681
	if (!config_validate("{$g['conf_path']}/config.xml"))
1682
		return 1;
1683

    
1684
	if($g['booting'] == true)
1685
		echo "Installing configuration...\n";
1686

    
1687
    config_lock();
1688
    conf_mount_rw();
1689

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

    
1692
	/* unlink cache file if it exists */
1693
	if(file_exists("{$g['tmp_path']}/config.cache"))
1694
		unlink("{$g['tmp_path']}/config.cache");
1695

    
1696
	mwexec("sync");
1697
    conf_mount_ro();
1698
    config_unlock();
1699

    
1700
    return 0;
1701
}
1702

    
1703
function config_validate($conffile) {
1704

    
1705
	global $g, $xmlerr;
1706

    
1707
	$xml_parser = xml_parser_create();
1708

    
1709
	if (!($fp = fopen($conffile, "r"))) {
1710
		$xmlerr = "XML error: unable to open file";
1711
		return false;
1712
	}
1713

    
1714
	while ($data = fread($fp, 4096)) {
1715
		if (!xml_parse($xml_parser, $data, feof($fp))) {
1716
			$xmlerr = sprintf("%s at line %d",
1717
						xml_error_string(xml_get_error_code($xml_parser)),
1718
						xml_get_current_line_number($xml_parser));
1719
			return false;
1720
		}
1721
	}
1722
	xml_parser_free($xml_parser);
1723

    
1724
	fclose($fp);
1725

    
1726
	return true;
1727
}
1728

    
1729
/*   lock configuration file, decide that the lock file
1730
 *   is stale after 10 seconds
1731
 */
1732
function config_lock($reason = "") {
1733
	global $g, $process_lock;
1734

    
1735
	/* No need to continue if we're the ones holding the lock */
1736
	if ($process_lock)
1737
		return;
1738

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

    
1741
	$n = 0;
1742
	while ($n < 10) {
1743
		/* open the lock file in append mode to avoid race condition */
1744
		if ($fd = @fopen($lockfile, "x")) {
1745
			/* succeeded */
1746
			fwrite($fd, $reason);
1747
			$process_lock = true;
1748
			fclose($fd);
1749
			return;
1750
		} else {
1751
			/* file locked, wait and try again */
1752
			$process_lock = false;
1753
			sleep(1);
1754
			$n++;
1755
		}
1756
	}
1757
}
1758

    
1759
/* unlock configuration file */
1760
function config_unlock() {
1761
	global $g, $process_lock;
1762

    
1763
	$lockfile = "{$g['varrun_path']}/config.lock";
1764
	$process_lock = false;
1765

    
1766
	unlink_if_exists($lockfile);
1767
}
1768

    
1769
function set_networking_interfaces_ports() {
1770
	global $noreboot;
1771
	global $config;
1772
	global $g;
1773
	global $fp;
1774

    
1775
	$fp = fopen('php://stdin', 'r');
1776

    
1777
	$memory = get_memory();
1778
	$avail = $memory[0];
1779

    
1780
	if($avail < $g['minimum_ram_warning']) {
1781
		echo "\n\n\n";
1782
		echo "DANGER!  WARNING!  ACHTUNG!\n\n";
1783
		echo "{$g['product_name']} requires *AT LEAST* {$g['minimum_ram_warning_text']} ram to function correctly.\n";
1784
		echo "Only ({$avail}) megs of ram has been detected.\n";
1785
		echo "\nPress ENTER to continue. ";
1786
		fgets($fp);
1787
		echo "\n";
1788
	}
1789

    
1790
	$iflist = get_interface_list();
1791

    
1792
	echo <<<EOD
1793

    
1794
Valid interfaces are:
1795

    
1796

    
1797
EOD;
1798

    
1799
	if(!is_array($iflist)) {
1800
		echo "No interfaces found!\n";
1801
	} else {
1802
		foreach ($iflist as $iface => $ifa) {
1803
			echo sprintf("% -8s%s%s\n", $iface, $ifa['mac'],
1804
				$ifa['up'] ? "   (up)" : "");
1805
		}
1806
	}
1807

    
1808
	echo <<<EOD
1809

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

    
1814
Do you want to set up VLANs now [y|n]?
1815
EOD;
1816

    
1817
	if (strcasecmp(chop(fgets($fp)), "y") == 0)
1818
		vlan_setup();
1819

    
1820
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
1821

    
1822
		echo "\n\nVLAN interfaces:\n\n";
1823
		$i = 0;
1824
		foreach ($config['vlans']['vlan'] as $vlan) {
1825

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

    
1829
			$iflist['vlan' . $i] = array();
1830
			$i++;
1831
		}
1832
	}
1833

    
1834
	echo <<<EOD
1835

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

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

    
1843
If you do not know the names of your interfaces, you may choose to use
1844
auto-detection. In that case, disconnect all interfaces now before
1845
hitting 'a' to initiate auto detection.
1846

    
1847
EOD;
1848

    
1849
	do {
1850
		echo "\nEnter the WAN interface name or 'a' for auto-detection: ";
1851
		$wanif = chop(fgets($fp));
1852
		if ($wanif === "") {
1853
			return;
1854
		}
1855
		if ($wanif === "a")
1856
			$wanif = autodetect_interface("WAN", $fp);
1857
		else if (!array_key_exists($wanif, $iflist)) {
1858
			echo "\nInvalid interface name '{$wanif}'\n";
1859
			unset($wanif);
1860
			continue;
1861
		}
1862
	} while (!$wanif);
1863

    
1864
	do {
1865
		echo "\nEnter the LAN interface name or 'a' for auto-detection \n" .
1866
			"(or nothing if finished): ";
1867
		$lanif = chop(fgets($fp));
1868
		
1869
		if($lanif == "exit") {
1870
			exit;
1871
		}
1872
		
1873
		if($lanif == "") {
1874
			if($g['minimum_nic_count'] < 2) {
1875
				break;	
1876
			} else {
1877
				fclose($fp);
1878
				return;
1879
			}
1880
		}
1881

    
1882
		if ($lanif === "a")
1883
			$lanif = autodetect_interface("LAN", $fp);
1884
		else if (!array_key_exists($lanif, $iflist)) {
1885
			echo "\nInvalid interface name '{$lanif}'\n";
1886
			unset($lanif);
1887
			continue;
1888
		}
1889
	} while (!$lanif);
1890

    
1891
	/* optional interfaces */
1892
	$i = 0;
1893
	$optif = array();
1894

    
1895
	if($lanif <> "") {
1896
		while (1) {
1897
			if ($optif[$i])
1898
				$i++;
1899
			$i1 = $i + 1;
1900
	
1901
			if($config['interfaces']['opt' . $i1]['descr'])
1902
				echo "\nOptional interface {$i1} description found: {$config['interfaces']['opt' . $i1]['descr']}";
1903
	
1904
			echo "\nEnter the Optional {$i1} interface name or 'a' for auto-detection\n" .
1905
				"(or nothing if finished): ";
1906
	
1907
			$optif[$i] = chop(fgets($fp));
1908
	
1909
			if ($optif[$i]) {
1910
				if ($optif[$i] === "a") {
1911
					$ad = autodetect_interface("Optional " . $i1, $fp);
1912
					if ($ad)
1913
						$optif[$i] = $ad;
1914
					else
1915
						unset($optif[$i]);
1916
				} else if (!array_key_exists($optif[$i], $iflist)) {
1917
					echo "\nInvalid interface name '{$optif[$i]}'\n";
1918
					unset($optif[$i]);
1919
					continue;
1920
				}
1921
			} else {
1922
				unset($optif[$i]);
1923
				break;
1924
			}
1925
		}
1926
	}
1927
	
1928
	/* check for double assignments */
1929
	$ifarr = array_merge(array($lanif, $wanif), $optif);
1930
	
1931
	for ($i = 0; $i < (count($ifarr)-1); $i++) {
1932
	for ($j = ($i+1); $j < count($ifarr); $j++) {
1933
		if ($ifarr[$i] == $ifarr[$j]) {
1934
			echo <<<EOD
1935

    
1936
Error: you cannot assign the same interface name twice!
1937

    
1938
EOD;
1939
				fclose($fp);
1940
				return;
1941
			}
1942
		}
1943
	}
1944

    
1945
	echo "The interfaces will be assigned as follows: \n\n";
1946

    
1947
	if ($lanif != "")
1948
		echo "LAN  ->" . $lanif . "\n";
1949
	echo "WAN  ->" . $wanif . "\n";
1950
	for ($i = 0; $i < count($optif); $i++) {
1951
		echo "OPT" . ($i+1) . " -> " . $optif[$i] . "\n";
1952
	}
1953

    
1954
echo <<<EOD
1955

    
1956
Do you want to proceed [y|n]?
1957
EOD;
1958

    
1959
	if (strcasecmp(chop(fgets($fp)), "y") == 0) {
1960
		if($lanif) {
1961
			$config['interfaces']['lan']['if'] = $lanif;
1962
		} elseif (!$g['booting']) {
1963

    
1964
echo <<<EODD
1965

    
1966
You have chosen to remove the LAN interface.
1967

    
1968
Would you like to remove the LAN IP address and
1969
unload the interface now? [y|n]? 
1970
EODD;
1971

    
1972
				if (strcasecmp(chop(fgets($fp)), "y") == 0) {
1973
					if($config['interfaces']['lan']['if'])
1974
						mwexec("/sbin/ifconfig delete " . $config['interfaces']['lan']['if']);
1975
				}
1976
				if(isset($config['interfaces']['lan']))
1977
					unset($config['interfaces']['lan']);
1978
				if(isset($config['dhcpd']['lan']))
1979
					unset($config['dhcpd']['lan']);
1980
				if(isset($config['interfaces']['lan']['if']))
1981
					unset($config['interfaces']['lan']['if']);
1982
				if(isset($config['interfaces']['wan']['blockpriv']))
1983
					unset($config['interfaces']['wan']['blockpriv']);
1984
				if(isset($config['shaper']))
1985
					unset($config['shaper']);
1986
				if(isset($config['ezshaper']))
1987
					unset($config['ezshaper']);
1988
				if(isset($config['nat']))
1989
					unset($config['nat']);				
1990
		} else {
1991
			if(isset($config['interfaces']['lan']['if']))
1992
				mwexec("/sbin/ifconfig delete " . $config['interfaces']['lan']['if']);
1993
			if(isset($config['interfaces']['lan']))
1994
				unset($config['interfaces']['lan']);
1995
			if(isset($config['dhcpd']['lan']))
1996
				unset($config['dhcpd']['lan']);
1997
			if(isset($config['interfaces']['lan']['if']))
1998
				unset($config['interfaces']['lan']['if']);
1999
			if(isset($config['interfaces']['wan']['blockpriv']))
2000
				unset($config['interfaces']['wan']['blockpriv']);
2001
			if(isset($config['shaper']))
2002
				unset($config['shaper']);
2003
			if(isset($config['ezshaper']))
2004
				unset($config['ezshaper']);
2005
			if(isset($config['nat']))
2006
				unset($config['nat']);				
2007
		}
2008
		if (preg_match($g['wireless_regex'], $lanif)) {
2009
			if (!is_array($config['interfaces']['lan']['wireless']))
2010
				$config['interfaces']['lan']['wireless'] = array();
2011
		} else {
2012
			unset($config['interfaces']['lan']['wireless']);
2013
		}
2014

    
2015
		$config['interfaces']['wan']['if'] = $wanif;
2016
		if (preg_match($g['wireless_regex'], $wanif)) {
2017
			if (!is_array($config['interfaces']['wan']['wireless']))
2018
				$config['interfaces']['wan']['wireless'] = array();
2019
		} else {
2020
			unset($config['interfaces']['wan']['wireless']);
2021
		}
2022

    
2023
		for ($i = 0; $i < count($optif); $i++) {
2024
			if (!is_array($config['interfaces']['opt' . ($i+1)]))
2025
				$config['interfaces']['opt' . ($i+1)] = array();
2026

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

    
2029
			/* wireless interface? */
2030
			if (preg_match($g['wireless_regex'], $optif[$i])) {
2031
				if (!is_array($config['interfaces']['opt' . ($i+1)]['wireless']))
2032
					$config['interfaces']['opt' . ($i+1)]['wireless'] = array();
2033
			} else {
2034
				unset($config['interfaces']['opt' . ($i+1)]['wireless']);
2035
			}
2036

    
2037
			unset($config['interfaces']['opt' . ($i+1)]['enable']);
2038
			$config['interfaces']['opt' . ($i+1)]['descr'] = "OPT" . ($i+1);
2039
		}
2040

    
2041
		/* remove all other (old) optional interfaces */
2042
		for (; isset($config['interfaces']['opt' . ($i+1)]); $i++)
2043
			unset($config['interfaces']['opt' . ($i+1)]);
2044

    
2045
		echo "\nWriting configuration...";
2046
		write_config();
2047
		echo "done.\n";
2048

    
2049
		echo <<<EOD
2050

    
2051

    
2052

    
2053
EOD;
2054

    
2055
		fclose($fp);
2056
		if($g['booting'])
2057
			return;
2058

    
2059
		echo "One moment while we reload the settings...";
2060

    
2061
		$g['booting'] = false;
2062

    
2063
		/* resync everything */
2064
		reload_all_sync();
2065

    
2066
		echo " done!\n";
2067

    
2068
		touch("{$g['tmp_path']}/assign_complete");
2069

    
2070
	}
2071
}
2072

    
2073
function autodetect_interface($ifname, $fp) {
2074
	$iflist_prev = get_interface_list("media");
2075
	echo <<<EOD
2076

    
2077
Connect the {$ifname} interface now and make sure that the link is up.
2078
Then press ENTER to continue.
2079

    
2080
EOD;
2081
	fgets($fp);
2082
	$iflist = get_interface_list("media");
2083

    
2084
	foreach ($iflist_prev as $ifn => $ifa) {
2085
		if (!$ifa['up'] && $iflist[$ifn]['up']) {
2086
			echo "Detected link-up on interface {$ifn}.\n";
2087
			return $ifn;
2088
		}
2089
	}
2090

    
2091
	echo "No link-up detected.\n";
2092

    
2093
	return null;
2094
}
2095

    
2096
function vlan_setup() {
2097
	global $iflist, $config, $g, $fp;
2098

    
2099
	$iflist = get_interface_list();
2100

    
2101
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
2102

    
2103
	echo <<<EOD
2104

    
2105
WARNING: all existing VLANs will be cleared if you proceed!
2106

    
2107
Do you want to proceed [y|n]?
2108
EOD;
2109

    
2110
	if (strcasecmp(chop(fgets($fp)), "y") != 0)
2111
		return;
2112
	}
2113

    
2114
	$config['vlans']['vlan'] = array();
2115
	echo "\n";
2116

    
2117
	while (1) {
2118
		$vlan = array();
2119

    
2120
		echo "\n\nVLAN Capable interfaces:\n\n";
2121
		if(!is_array($iflist)) {
2122
			echo "No interfaces found!\n";
2123
		} else {
2124
			$vlan_capable=0;
2125
			foreach ($iflist as $iface => $ifa) {
2126
				if (is_jumbo_capable($iface)) {
2127
					echo sprintf("% -8s%s%s\n", $iface, $ifa['mac'],
2128
						$ifa['up'] ? "   (up)" : "");
2129
					$vlan_capable++;
2130
				}
2131
			}
2132
		}
2133

    
2134
		if($vlan_capable == 0) {
2135
			echo "No VLAN capable interfaces detected.\n";
2136
			return;
2137
		}
2138

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

    
2142
		if ($vlan['if']) {
2143
			if (!array_key_exists($vlan['if'], $iflist) or
2144
			    !is_jumbo_capable($vlan['if'])) {
2145
				echo "\nInvalid interface name '{$vlan['if']}'\n";
2146
				continue;
2147
			}
2148
		} else {
2149
			break;
2150
		}
2151

    
2152
		echo "Enter the VLAN tag (1-4094): ";
2153
		$vlan['tag'] = chop(fgets($fp));
2154

    
2155
		if (!is_numericint($vlan['tag']) || ($vlan['tag'] < 1) || ($vlan['tag'] > 4094)) {
2156
			echo "\nInvalid VLAN tag '{$vlan['tag']}'\n";
2157
			continue;
2158
		}
2159

    
2160
		$config['vlans']['vlan'][] = $vlan;
2161
	}
2162
}
2163

    
2164
function system_start_ftp_helpers() {
2165
	require_once("interfaces.inc");
2166
	global $config, $g;
2167

    
2168
	mwexec("/usr/bin/killall ftpsesame");
2169

    
2170
	/* if list */
2171
	$iflist = get_configured_interface_list();
2172

    
2173
	/* loop through all interfaces and handle ftp-proxy */
2174
	$interface_counter = 0;
2175
	foreach ($iflist as $ifent => $ifname) {
2176
		/* XXX: needed?! */
2177
		if ($ifent == "wan")
2178
			continue;
2179

    
2180
		/*    if the ftp proxy is disabled for this interface then kill ftp-proxy
2181
		 *    instance and continue. note that the helpers for port forwards are
2182
		 *    launched in a  different sequence so we are filtering them out
2183
	         *    here by not including -c {$port} -g 8021 first.
2184
		 */
2185

    
2186
		/* Get the ftp queue for this interface */
2187
		if (isset($config['shaper'][$ifname]['ftpqueue']))
2188
			$shaper_queue = $config['interfaces'][$ifname]['ftpqueue'];
2189

    
2190
		$port = 8021 + $interface_counter;
2191
		if(isset($config['interfaces'][$ifname]['disableftpproxy'])) {
2192
			/*    item is disabled.  lets ++ the interface counter and
2193
			 *    keep processing interfaces. kill ftp-proxy if already
2194
			 *    running for this instance.
2195
			 */
2196
			$helpers = exec("/bin/ps awux | grep \"/usr/local/sbin/ftp-proxy {$shaper_queue} -p {$port}\" | grep -v grep | sed \"s/  */ /g\" | cut -f2 -d\" \"");
2197
			if($helpers)
2198
				mwexec("/bin/kill {$helpers}");
2199
			$interface_counter++;
2200
		} else {
2201
			/* grab the current interface IP address */
2202
			$int = convert_friendly_interface_to_real_interface_name($ifname);
2203
			$ip = find_interface_ip($int);
2204
			/* are we in routed mode? no source nat rules and not a outside interface? */
2205
			/* If we have advanced outbound nat we skip the FTP proxy, we use ftpsesame */
2206
			if((isset($config['nat']['advancedoutbound']['enable'])) && (! interface_has_gateway($ifname))) {
2207
				$sourcenat = 0;
2208
				/* we are using advanced outbound nat, are we in routing mode? */
2209
				/* if the interface address lies within a outbound NAT source network we should skip */
2210
				if(! empty($config['nat']['advancedoutbound']['rule'])) {
2211
					foreach($config['nat']['advancedoutbound']['rule'] as $natnetwork) {
2212
						if(ip_in_subnet($ip, $natnetwork['source']['network'])) {
2213
							/* if the interface address is matched in the AON Rule we need the ftp proxy */
2214
							if(is_ipaddr($natnetwork['target']) && ($natnetwork['interface'] == "wan")) {
2215
								$pftpxsourceaddr = "-a {$natnetwork['target']}";
2216
								if($g['debug'])
2217
									log_error("Config: AON: using the external ip source {$pftpxsourceaddr} for the ftp proxy");
2218
							}
2219
							$sourcenat++;
2220
						}
2221
					}
2222
				}
2223
				if($sourcenat == 0) {
2224
					if($g['debug'])
2225
						log_error("Config: No AON rule matched for interface {$ifname} - not using FTP proxy");
2226
					mwexec("/usr/local/sbin/ftpsesame -i $int");
2227
					$interface_counter++;
2228
					continue;
2229
				} else {
2230
					if($g['debug'])
2231
						log_error("Config: AON rule matched for interface {$ifname} - using FTP proxy");
2232
				}
2233
			}
2234
			/* if ftp-proxy is already running then do not launch it again */
2235
			$helpers = exec("/bin/ps awux | grep \"/usr/local/sbin/ftp-proxy {$shaper_queue} -p {$port}\" | grep -v grep | sed \"s/  */ /g\"");
2236
			if(!$helpers && $ip)
2237
 				mwexec("/usr/local/sbin/ftp-proxy {$shaper_queue} -p {$port} {$pftpxsourceaddr} {$ip}");
2238
			if(!$ip)
2239
				mwexec("/usr/local/sbin/ftpsesame {$shaper_queue} -i $int");
2240
			$interface_counter++;
2241
		}
2242
	}
2243
	/* support bridged interfaces.  even they need ftp mojo */
2244
	$num_bridges = find_number_of_created_bridges();
2245
	$num_bridges++;
2246
	for($x=0; $x<$num_bridges; $x++) {
2247
		mwexec("/usr/local/sbin/ftpsesame {$shaper_queue} -i bridge{$x}");
2248
	}
2249
}
2250

    
2251
function cleanup_backupcache($revisions = 30) {
2252
	global $g;
2253
	$i = false;
2254
	config_lock();
2255
	if(file_exists($g['cf_conf_path'] . '/backup/backup.cache')) {
2256
		conf_mount_rw();
2257
		$backups = get_backups();
2258
		$newbaks = array();
2259
		$bakfiles = glob($g['cf_conf_path'] . "/backup/config-*");
2260
		$baktimes = $backups['versions'];
2261
		$tocache = array();
2262
		unset($backups['versions']);
2263
   		foreach($bakfiles as $backup) { // Check for backups in the directory not represented in the cache.
2264
   			if(filesize($backup) == 0) {
2265
   				unlink($backup);
2266
   				continue;
2267
   			}
2268
			$tocheck = array_shift(explode('.', array_pop(explode('-', $backup))));
2269
            if(!in_array($tocheck, $baktimes)) {
2270
				$i = true;
2271
				if($g['booting'])
2272
					print " " . $tocheck . "a";
2273
				$newxml = parse_xml_config($backup, $g['xml_rootobj']);
2274
				if($newxml == "-1") {
2275
					log_error("The backup cache file $backup is corrupted.  Unlinking.");
2276
					unlink($backup);
2277
					log_error("The backup cache file $backup is corrupted.  Unlinking.");
2278
					continue;
2279
				}
2280
				if($newxml['revision']['description'] == "")
2281
					$newxml['revision']['description'] = "Unknown";
2282
				$tocache[$tocheck] = array('description' => $newxml['revision']['description']);
2283
			}
2284
    	}
2285
		foreach($backups as $checkbak) {
2286

    
2287
			if(count(preg_grep('/' . $checkbak['time'] . '/i', $bakfiles)) != 0) {
2288
				$newbaks[] = $checkbak;
2289
			} else {
2290
				$i = true;
2291
				if($g['booting']) print " " . $tocheck . "r";
2292
			}
2293
		}
2294
		foreach($newbaks as $todo) $tocache[$todo['time']] = array('description' => $todo['description']);
2295
		if(is_int($revisions) and (count($tocache) > $revisions)) {
2296
			$toslice = array_slice(array_keys($tocache), 0, $revisions);
2297
			foreach($toslice as $sliced)
2298
				$newcache[$sliced] = $tocache[$sliced];
2299
			foreach($tocache as $version => $versioninfo) {
2300
				if(!in_array($version, array_keys($newcache))) {
2301
					unlink_if_exists($g['conf_path'] . '/backup/config-' . $version . '.xml');
2302
					if($g['booting']) print " " . $tocheck . "d";
2303
				}
2304
			}
2305
			$tocache = $newcache;
2306
		}
2307
		$bakout = fopen($g['cf_conf_path'] . '/backup/backup.cache', "w");
2308
        fwrite($bakout, serialize($tocache));
2309
		fclose($bakout);
2310
		mwexec("sync");
2311
		conf_mount_ro();
2312
	}
2313
	if($g['booting']) {
2314
		if($i) {
2315
			print "done.\n";
2316
		}
2317
	}
2318
	config_unlock();
2319
}
2320

    
2321
function get_backups() {
2322
	global $g;
2323
	if(file_exists("{$g['cf_conf_path']}/backup/backup.cache")) {
2324
		$confvers = unserialize(file_get_contents("{$g['cf_conf_path']}/backup/backup.cache"));
2325
		$bakvers = array_keys($confvers);
2326
		$toreturn = array();
2327
		sort($bakvers);
2328
		// 	$bakvers = array_reverse($bakvers);
2329
		foreach(array_reverse($bakvers) as $bakver)
2330
			$toreturn[] = array('time' => $bakver, 'description' => $confvers[$bakver]['description']);
2331
	} else {
2332
		return false;
2333
	}
2334
	$toreturn['versions'] = $bakvers;
2335
	return $toreturn;
2336
}
2337

    
2338
function backup_config() {
2339
	global $config, $g;
2340

    
2341
	if($g['platform'] == "cdrom")
2342
		return;
2343

    
2344
	conf_mount_rw();
2345

    
2346
	/* Create backup directory if needed */
2347
	safe_mkdir("{$g['cf_conf_path']}/backup");
2348

    
2349
    if($config['revision']['time'] == "") {
2350
            $baktime = 0;
2351
    } else {
2352
            $baktime = $config['revision']['time'];
2353
    }
2354
    if($config['revision']['description'] == "") {
2355
            $bakdesc = "Unknown";
2356
    } else {
2357
            $bakdesc = $config['revision']['description'];
2358
    }
2359
    copy($g['cf_conf_path'] . '/config.xml', $g['cf_conf_path'] . '/backup/config-' . $baktime . '.xml');
2360
    if(file_exists($g['cf_conf_path'] . '/backup/backup.cache')) {
2361
            $backupcache = unserialize(file_get_contents($g['cf_conf_path'] . '/backup/backup.cache'));
2362
    } else {
2363
            $backupcache = array();
2364
    }
2365
    $backupcache[$baktime] = array('description' => $bakdesc);
2366
    $bakout = fopen($g['cf_conf_path'] . '/backup/backup.cache', "w");
2367
    fwrite($bakout, serialize($backupcache));
2368
    fclose($bakout);
2369

    
2370
	mwexec("sync");
2371
	conf_mount_ro();
2372

    
2373
	return true;
2374
}
2375

    
2376
function mute_kernel_msgs() {
2377
	return;
2378
	exec("/sbin/conscontrol mute on");
2379
}
2380

    
2381
function unmute_kernel_msgs() {
2382
	exec("/sbin/conscontrol mute off");
2383
}
2384

    
2385
function start_devd() {
2386
	exec("/sbin/devd");
2387
	sleep(1);
2388
	if(file_exists("/tmp/rc.linkup"))
2389
		unlink("/tmp/rc.linkup");
2390
}
2391

    
2392
function is_interface_mismatch() {
2393
	global $config, $g;
2394
	if(!$config['interfaces']['lan']) 	
2395
		return false;
2396
	if($config['interfaces']['wan']['ipaddr'] == "carpdev-dhcp")
2397
		return false;		
2398
	$lan_if = $config['interfaces']['lan']['if'];
2399
	$wan_if = get_real_wan_interface();
2400
	$do_assign = 0;
2401
	/* we need to ignore the vlan interface checks) */
2402
	if (stristr($lan_if, "vlan") == false and stristr($wan_if, "vlan") == false) {
2403
		if (does_interface_exist($lan_if) == false)
2404
			if($g['minimum_nic_count'] > 1)
2405
				$do_assign = 1;
2406
		if ($config['interfaces']['wan']['ipaddr'] <> "pppoe" && $config['interfaces']['wan']['ipaddr'] <> "pptp" && $do_assign == 0)
2407
			if (does_interface_exist($wan_if) == false)
2408
				$do_assign = 1;
2409
	}
2410
	/* XXX: enumerate OPT interfaces looking for mismatches */
2411
	if (file_exists("{$g['tmp_path']}/assign_complete"))
2412
		return false;
2413
	if ($do_assign == 1)
2414
		return true;
2415
	else
2416
		return false;
2417
}
2418

    
2419
function set_device_perms() {
2420
	$devices = array(
2421
		'pf'	=> array(	'user'	=> 'proxy',
2422
					'group'	=> 'proxy',
2423
					'mode'	=> 0660),
2424
		);
2425

    
2426
	foreach ($devices as $name => $attr) {
2427
		$path = "/dev/$name";
2428
		if (file_exists($path)) {
2429
			chown($path, $attr['user']);
2430
			chgrp($path, $attr['group']);
2431
			chmod($path, $attr['mode']);
2432
		}
2433
	}
2434
}
2435

    
2436
if($g['booting']) echo ".";
2437
$config = parse_config();
2438

    
2439
?>
(7-7/31)