Project

General

Profile

Download (86 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
 * XXX: Hack around the cvs syntax checks. 
42
 * DISABLE_PHP_LINT_CHECKING
43
 */
44
 
45

    
46
if($g['booting']) echo ".";
47

    
48
/* do not load this file twice. */
49
if($config_inc_loaded == true)
50
	return;
51
else
52
	$config_inc_loaded = true;
53

    
54
/* include globals/utility/XML parser files */
55
require_once("globals.inc");
56
if($g['booting']) echo ".";
57
require_once("util.inc");
58
if($g['booting']) echo ".";
59
require_once("pfsense-utils.inc");
60
if($g['booting']) echo ".";
61
require_once("xmlparse.inc");
62
if($g['booting']) echo ".";
63
require_once("services.inc");
64

    
65
/* read platform */
66
if($g['booting']) echo ".";
67
if (file_exists("{$g['etc_path']}/platform")) {
68
	$g['platform'] = chop(file_get_contents("{$g['etc_path']}/platform"));
69
} else {
70
	$g['platform'] = "unknown";
71
}
72

    
73
/* if /debugging exists, lets set $debugging
74
   so we can output more information */
75
if(file_exists("/debugging")) {
76
	$debugging = true;
77
	$g['debug'] = true;
78
}
79

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

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

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

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

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

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

    
173
*******************************************************************************
174
* FATAL ERROR                                                                 *
175
* The device that contains the configuration file (config.xml) could not be   *
176
* found. {$g['product_name']} cannot continue booting.                                     *
177
*******************************************************************************
178

    
179

    
180
EOD;
181

    
182
				mwexec("/sbin/halt");
183
				exit;
184
			}
185
		}
186

    
187
		/* write device name to a file for rc.firmware */
188
		$fd = fopen("{$g['varetc_path']}/cfdevice", "w");
189
		fwrite($fd, $cfgdevice . "\n");
190
		fclose($fd);
191

    
192
		/* write out an fstab */
193
		$fd = fopen("{$g['etc_path']}/fstab", "w");
194

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

    
198
		fwrite($fd, $fstab);
199
		fclose($fd);
200
	}
201
	if($g['booting']) echo ".";
202
	/* mount all filesystems */
203
	mwexec("/sbin/mount -a");
204
}
205

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

    
273
	/*    override some global configuration parms if they exist
274
	 *    instead of hard coding these checks into the codebase
275
     */
276
	if($config['pptp']['n_pptp_units'])
277
		$g['n_pptp_units'] = $config['pptp']['n_pptp_units'];
278
	if($config['pptp']['pptp_subnet'])
279
		$g['pptp_subnet'] = $config['pptp']['pptp_subnet'];
280

    
281
	if($config['pppoe']['n_pppoe_units'])
282
		$g['n_pppoe_units'] = $config['pppoe']['n_pppoe_units'];
283
	if($config['pppoe']['pppoe_subnet'])
284
		$g['pppoe_subnet'] = $config['pppoe']['pppoe_subnet'];
285

    
286
	return $config;
287
}
288

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

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

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

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

    
391
	if ((float)$config['version'] > (float)$g['latest_config']) {
392
		echo <<<EOD
393

    
394

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

    
403

    
404
EOD;
405
		}
406

    
407
	/* make alias table (for faster lookups) */
408
	alias_make_table($config);
409
	config_unlock();
410
}
411

    
412
/****f* config/conf_mount_rw
413
 * NAME
414
 *   conf_mount_rw - Mount filesystems read/write.
415
 * RESULT
416
 *   null
417
 ******/
418
/* mount flash card read/write */
419
function conf_mount_rw() {
420
	global $g;
421

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

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

    
449
/****f* config/conf_mount_ro
450
 * NAME
451
 *   conf_mount_ro - Mount filesystems readonly.
452
 * RESULT
453
 *   null
454
 ******/
455
function conf_mount_ro() {
456
	global $g;
457

    
458
	if($g['booting'] == true)
459
		return;
460

    
461
	/* firmare upgrade in progress */
462
	if(file_exists($g['varrun_path'] . "/fwup.enabled"))
463
		return;
464

    
465
	/* do not umount if generating ssh keys */
466
	if(file_exists("/tmp/keys_generating"))
467
		return;
468

    
469
	/* do not umount on cdrom or pfSense platforms */
470
	if($g['platform'] == "cdrom" or $g['platform'] == "pfSense")
471
		return;
472

    
473
	/* sync data, then force a remount of /cf */
474
	mwexec("/bin/sync");
475
	mwexec("/sbin/mount -u -r -f {$g['cf_path']}");
476
	mwexec("/sbin/mount -u -r -f /");
477
}
478

    
479
/****f* config/convert_config
480
 * NAME
481
 *   convert_config - Attempt to update config.xml.
482
 * DESCRIPTION
483
 *   convert_config() reads the current global configuration
484
 *   and attempts to convert it to conform to the latest
485
 *   config.xml version. This allows major formatting changes
486
 *   to be made with a minimum of breakage.
487
 * RESULT
488
 *   null
489
 ******/
490
/* convert configuration, if necessary */
491
function convert_config() {
492
	global $config, $g;
493
        $now = date("H:i:s");
494
        log_error("Start Configuration upgrade at $now, set execution timeout to 15 minutes");
495
        ini_set("max_execution_time", "900");
496

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

    
512
	// Save off config version
513
	$prev_version = $config['version'];
514

    
515
	/* convert 1.0 -> 1.1 */
516
	if ($config['version'] <= 1.0) {
517
		$opti = 1;
518
		$ifmap = array('lan' => 'lan', 'wan' => 'wan', 'pptp' => 'pptp');
519

    
520
		/* convert DMZ to optional, if necessary */
521
		if (isset($config['interfaces']['dmz'])) {
522

    
523
			$dmzcfg = &$config['interfaces']['dmz'];
524

    
525
			if ($dmzcfg['if']) {
526
				$config['interfaces']['opt' . $opti] = array();
527
				$optcfg = &$config['interfaces']['opt' . $opti];
528

    
529
				$optcfg['enable'] = $dmzcfg['enable'];
530
				$optcfg['descr'] = "DMZ";
531
				$optcfg['if'] = $dmzcfg['if'];
532
				$optcfg['ipaddr'] = $dmzcfg['ipaddr'];
533
				$optcfg['subnet'] = $dmzcfg['subnet'];
534

    
535
				$ifmap['dmz'] = "opt" . $opti;
536
				$opti++;
537
			}
538

    
539
			unset($config['interfaces']['dmz']);
540
		}
541

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

    
545
			if (!$config['interfaces']['wlan' . $i]['if']) {
546
				unset($config['interfaces']['wlan' . $i]);
547
				continue;
548
			}
549

    
550
			$wlancfg = &$config['interfaces']['wlan' . $i];
551
			$config['interfaces']['opt' . $opti] = array();
552
			$optcfg = &$config['interfaces']['opt' . $opti];
553

    
554
			$optcfg['enable'] = $wlancfg['enable'];
555
			$optcfg['descr'] = "WLAN" . $i;
556
			$optcfg['if'] = $wlancfg['if'];
557
			$optcfg['ipaddr'] = $wlancfg['ipaddr'];
558
			$optcfg['subnet'] = $wlancfg['subnet'];
559
			$optcfg['bridge'] = $wlancfg['bridge'];
560

    
561
			$optcfg['wireless'] = array();
562
			$optcfg['wireless']['mode'] = $wlancfg['mode'];
563
			$optcfg['wireless']['ssid'] = $wlancfg['ssid'];
564
			$optcfg['wireless']['channel'] = $wlancfg['channel'];
565
			$optcfg['wireless']['wep'] = $wlancfg['wep'];
566

    
567
			$ifmap['wlan' . $i] = "opt" . $opti;
568

    
569
			unset($config['interfaces']['wlan' . $i]);
570
			$opti++;
571
		}
572

    
573
		/* convert filter rules */
574
		$n = count($config['filter']['rule']);
575
		for ($i = 0; $i < $n; $i++) {
576

    
577
			$fr = &$config['filter']['rule'][$i];
578

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

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

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

    
617
		/* convert shaper rules */
618
		$n = count($config['pfqueueing']['rule']);
619
		if (is_array($config['pfqueueing']['rule']))
620
			for ($i = 0; $i < $n; $i++) {
621

    
622
			$fr = &$config['pfqueueing']['rule'][$i];
623

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

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

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

    
662
		$config['version'] = "1.1";
663
	}
664

    
665
	/* convert 1.1 -> 1.2 */
666
	if ($config['version'] <= 1.1) {
667
		/* move LAN DHCP server config */
668
		$tmp = $config['dhcpd'];
669
		$config['dhcpd'] = array();
670
		$config['dhcpd']['lan'] = $tmp;
671

    
672
		/* encrypt password */
673
		$config['system']['password'] = crypt($config['system']['password']);
674

    
675
		$config['version'] = "1.2";
676
	}
677

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

    
690
		/* add an explicit type="pass" to all filter rules to make things consistent */
691
		for ($i = 0; isset($config['filter']['rule'][$i]); $i++) {
692
			$config['filter']['rule'][$i]['type'] = "pass";
693
		}
694

    
695
		$config['version'] = "1.3";
696
	}
697

    
698
	/* convert 1.3 -> 1.4 */
699
	if ($config['version'] <= 1.3) {
700
		/* convert shaper rules (make pipes) */
701
		if (is_array($config['pfqueueing']['rule'])) {
702
			$config['pfqueueing']['pipe'] = array();
703

    
704
			for ($i = 0; isset($config['pfqueueing']['rule'][$i]); $i++) {
705
				$curent = &$config['pfqueueing']['rule'][$i];
706

    
707
				/* make new pipe and associate with this rule */
708
				$newpipe = array();
709
				$newpipe['descr'] = $curent['descr'];
710
				$newpipe['bandwidth'] = $curent['bandwidth'];
711
				$newpipe['delay'] = $curent['delay'];
712
				$newpipe['mask'] = $curent['mask'];
713
				$config['pfqueueing']['pipe'][$i] = $newpipe;
714

    
715
				$curent['targetpipe'] = $i;
716

    
717
				unset($curent['bandwidth']);
718
				unset($curent['delay']);
719
				unset($curent['mask']);
720
			}
721
		}
722

    
723
		$config['version'] = "1.4";
724
	}
725

    
726
	/* Convert 1.4 -> 1.5 */
727
	if ($config['version'] <= 1.4) {
728

    
729
		/* Default route moved */
730
		if (isset($config['interfaces']['wan']['gateway']))
731
			if ($config['interfaces']['wan']['gateway'] <> "")
732
				$config['interfaces']['wan']['gateway'] = $config['interfaces']['wan']['gateway'];
733
		unset($config['interfaces']['wan']['gateway']);
734

    
735
                /* Queues are no longer interface specific */
736
                if (isset($config['interfaces']['lan']['schedulertype']))
737
                        unset($config['interfaces']['lan']['schedulertype']);
738
                if (isset($config['interfaces']['wan']['schedulertype']))
739
                        unset($config['interfaces']['wan']['schedulertype']);
740

    
741
                for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
742
                        if(isset($config['interfaces']['opt' . $i]['schedulertype']))
743
                                unset($config['interfaces']['opt' . $i]['schedulertype']);
744
                }
745

    
746
		$config['version'] = "1.5";
747
	}
748

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

    
762
		$config['version'] = "1.6";
763
	}
764

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

    
824
		/* enable SSH */
825
		if ($config['version'] == "1.8") {
826
			$config['system']['sshenabled'] = true;
827
		}
828

    
829
		$config['version'] = "1.9";
830
	}
831

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

    
875
	/* Convert 2.4 -> 2.5 */
876
	if ($config['version'] <= 2.4) {
877
		$config['interfaces']['wan']['use_rrd_gateway'] = $config['system']['use_rrd_gateway'];
878
		unset($config['system']['use_rrd_gateway']);
879
 		$config['version'] = "2.5";
880
	}
881

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

    
893
		$config['cron']['item'][] = $cron_item;
894

    
895
		$cron_item = array();
896
		$cron_item['minute'] = "1,31";
897
		$cron_item['hour'] = "0-5";
898
		$cron_item['mday'] = "*";
899
		$cron_item['month'] = "*";
900
		$cron_item['wday'] = "*";
901
		$cron_item['who'] = "root";
902
		$cron_item['command'] = "/usr/bin/nice -n20 adjkerntz -a";
903

    
904
		$config['cron']['item'][] = $cron_item;
905

    
906
		$cron_item = array();
907
		$cron_item['minute'] = "1";
908
		$cron_item['hour'] = "*";
909
		$cron_item['mday'] = "1";
910
		$cron_item['month'] = "*";
911
		$cron_item['wday'] = "*";
912
		$cron_item['who'] = "root";
913
		$cron_item['command'] = "/usr/bin/nice -n20 /etc/rc.update_bogons.sh";
914

    
915
		$config['cron']['item'][] = $cron_item;
916

    
917
		$cron_item = array();
918
		$cron_item['minute'] = "*/60";
919
		$cron_item['hour'] = "*";
920
		$cron_item['mday'] = "*";
921
		$cron_item['month'] = "*";
922
		$cron_item['wday'] = "*";
923
		$cron_item['who'] = "root";
924
		$cron_item['command'] = "/usr/bin/nice -n20 /usr/local/sbin/expiretable -v -t 3600 sshlockout";
925

    
926
		$config['cron']['item'][] = $cron_item;
927

    
928
		$cron_item = array();
929
		$cron_item['minute'] = "1";
930
		$cron_item['hour'] = "1";
931
		$cron_item['mday'] = "*";
932
		$cron_item['month'] = "*";
933
		$cron_item['wday'] = "*";
934
		$cron_item['who'] = "root";
935
		$cron_item['command'] = "/usr/bin/nice -n20 /etc/rc.dyndns.update";
936

    
937
		$config['cron']['item'][] = $cron_item;
938

    
939
		$cron_item = array();
940
		$cron_item['minute'] = "*/60";
941
		$cron_item['hour'] = "*";
942
		$cron_item['mday'] = "*";
943
		$cron_item['month'] = "*";
944
		$cron_item['wday'] = "*";
945
		$cron_item['who'] = "root";
946
		$cron_item['command'] = "/usr/bin/nice -n20 /usr/local/sbin/expiretable -v -t 3600 virusprot";
947

    
948
		$config['cron']['item'][] = $cron_item;
949

    
950
		$cron_item = array();
951
		$cron_item['minute'] = "*/60";
952
		$cron_item['hour'] = "*";
953
		$cron_item['mday'] = "*";
954
		$cron_item['month'] = "*";
955
		$cron_item['wday'] = "*";
956
		$cron_item['who'] = "root";
957
		$cron_item['command'] = "/usr/bin/nice -n20 /usr/local/sbin/expiretable -t 1800 snort2c";
958

    
959
		$config['cron']['item'][] = $cron_item;
960

    
961
		$cron_item = array();
962
		$cron_item['minute'] = "*/5";
963
		$cron_item['hour'] = "*";
964
		$cron_item['mday'] = "*";
965
		$cron_item['month'] = "*";
966
		$cron_item['wday'] = "*";
967
		$cron_item['who'] = "root";
968
		$cron_item['command'] = "/usr/local/bin/checkreload.sh";
969

    
970
		$config['cron']['item'][] = $cron_item;
971

    
972
		/* write crontab entries to file */
973
		configure_cron();
974

    
975
 		$config['version'] = "2.6";
976
	}
977

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
1181
if(0):
1182

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

    
1224
			}
1225
		}
1226
		$config['version'] = "4.4";
1227
	}
1228

    
1229
endif;
1230

    
1231
	/* Convert 4.4 -> 4.5 */
1232
	if ($config['version'] <= 4.4) {
1233
		if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
1234
			foreach ($config['vlans']['vlan'] as $id => $vlan)
1235
				$config['vlans']['vlan'][$id]['vlanif'] = "vlan{$id}";
1236
		}
1237
		$config['version'] = "4.5";
1238
	}
1239

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

    
1275
	/* Convert 4.6 -> 4.7 */
1276
	if ($config['version'] <= 4.7) {
1277

    
1278
		/* Upgrade IPsec from tunnel to phase1/phase2 */
1279

    
1280
        if(is_array($config['ipsec']['tunnel'])) {
1281

    
1282
			$a_phase1 = array();
1283
			$a_phase2 = array();
1284
			$ikeid = 0;
1285

    
1286
			foreach ($config['ipsec']['tunnel'] as $tunnel) {
1287

    
1288
				unset($ph1ent);
1289
				unset($ph2ent);
1290

    
1291
				/*
1292
				 *  attempt to locate an enabled phase1
1293
				 *  entry that matches the peer gateway
1294
				 */
1295

    
1296
				if (!isset($tunnel['disabled'])) {
1297

    
1298
					$remote_gateway = $tunnel['remote-gateway'];
1299

    
1300
					foreach ($a_phase1 as $ph1tmp) {
1301
						if ($ph1tmp['remote-gateway'] == $remote_gateway) {
1302
							$ph1ent = $ph1tmp;
1303
							break;
1304
						}
1305
					}
1306
				}
1307

    
1308
				/* none found, create a new one */
1309

    
1310
				if (!isset( $ph1ent )) {
1311

    
1312
					/* build new phase1 entry */
1313

    
1314
					$ph1ent = array();
1315

    
1316
					$ph1ent['ikeid'] = ++$ikeid;
1317

    
1318
					if (isset($tunnel['disabled']))
1319
						$ph1ent['disabled'] = $tunnel['disabled'];
1320

    
1321
					$ph1ent['interface'] = $tunnel['interface'];
1322
					$ph1ent['remote-gateway'] = $tunnel['remote-gateway'];
1323
					$ph1ent['descr'] = $tunnel['descr'];
1324

    
1325
					$ph1ent['mode'] = $tunnel['p1']['mode'];
1326

    
1327
					if (isset($tunnel['p1']['myident']['myaddress']))
1328
						$ph1ent['myid_type'] = "myaddress";
1329
					if (isset($tunnel['p1']['myident']['address'])) {
1330
						$ph1ent['myid_type'] = "address";
1331
						$ph1ent['myid_data'] = $tunnel['p1']['myident']['address'];
1332
					}
1333
					if (isset($tunnel['p1']['myident']['fqdn'])) {
1334
						$ph1ent['myid_type'] = "fqdn";
1335
						$ph1ent['myid_data'] = $tunnel['p1']['myident']['fqdn'];
1336
					}
1337
					if (isset($tunnel['p1']['myident']['user_fqdn'])) {
1338
						$ph1ent['myid_type'] = "user_fqdn";
1339
						$ph1ent['myid_data'] = $tunnel['p1']['myident']['user_fqdn'];
1340
					}
1341
					if (isset($tunnel['p1']['myident']['asn1dn'])) {
1342
						$ph1ent['myid_type'] = "asn1dn";
1343
						$ph1ent['myid_data'] = $tunnel['p1']['myident']['asn1dn'];
1344
					}
1345
					if (isset($tunnel['p1']['myident']['dyn_dns'])) {
1346
						$ph1ent['myid_type'] = "dyn_dns";
1347
						$ph1ent['myid_data'] = $tunnel['p1']['myident']['dyn_dns'];
1348
					}
1349

    
1350
					$ph1ent['peerid_type'] = "peeraddress";
1351

    
1352
					switch ($tunnel['p1']['encryption-algorithm']) {
1353
					case "des":
1354
						$ph1alg = array( 'name' => 'des' );
1355
						break;
1356
					case "3des":
1357
						$ph1alg = array( 'name' => '3des' );
1358
						break;
1359
					case "blowfish":
1360
						$ph1alg = array( 'name' => 'blowfish', 'keylen' => '128'  );
1361
						break;
1362
					case "cast128":
1363
						$ph1alg = array( 'name' => 'cast128' );
1364
						break;
1365
					case "rijndael":
1366
						$ph1alg = array( 'name' => 'aes', 'keylen' => '128' );
1367
						break;
1368
					case "rijndael 256":
1369
						$ph1alg = array( 'name' => 'aes', 'keylen' => '256' );
1370
						break;
1371
					}
1372

    
1373
					$ph1ent['encryption-algorithm'] = $ph1alg;
1374
					$ph1ent['hash-algorithm'] = $tunnel['p1']['hash-algorithm'];
1375
					$ph1ent['dhgroup'] = $tunnel['p1']['dhgroup'];
1376
					$ph1ent['lifetime'] = $tunnel['p1']['lifetime'];
1377
					$ph1ent['authentication_method'] = $tunnel['p1']['authentication_method'];
1378

    
1379
					if (isset($tunnel['p1']['pre-shared-key']))
1380
						$ph1ent['pre-shared-key'] = $tunnel['p1']['pre-shared-key'];
1381
					if (isset($tunnel['p1']['cert']))
1382
						$ph1ent['cert'] = $tunnel['p1']['cert'];
1383
					if (isset($tunnel['p1']['peercert']))
1384
						$ph1ent['peercert'] = $tunnel['p1']['peercert'];
1385
					if (isset($tunnel['p1']['private-key']))
1386
						$ph1ent['private-key'] = $tunnel['p1']['private-key'];
1387

    
1388
					if (isset($tunnel['pinghost']['pinghost']))
1389
						$ph1ent['pinghost'] = $tunnel['pinghost'];
1390

    
1391
					$ph1ent['nat_traversal'] = "on";
1392
					$ph1ent['dpd_enable'] = 1;
1393
					$ph1ent['dpd_delay'] = 10;
1394
					$ph1ent['dpd_maxfail'] = 5;
1395

    
1396
					$a_phase1[] = $ph1ent;
1397
				}
1398

    
1399
				/* build new phase2 entry */
1400

    
1401
				$ph2ent = array();
1402

    
1403
				$ph2ent['ikeid'] = $ph1ent['ikeid'];
1404

    
1405
				if (isset($tunnel['disabled']))
1406
					$ph1ent['disabled'] = $tunnel['disabled'];
1407

    
1408
				$ph2ent['descr'] = "phase2 for ".$tunnel['descr'];
1409

    
1410
				$type = "lan";
1411
				if ($tunnel['local-subnet']['network'])
1412
					$type = $tunnel['local-subnet']['network'];
1413
				if ($tunnel['local-subnet']['address']) {
1414
					list($address,$netbits) = explode("/",$tunnel['local-subnet']['address']);
1415
					if (is_null($netbits))
1416
						$type = "address";
1417
					else
1418
						$type = "network";
1419
				}
1420
				
1421
				switch ($type) {
1422
					case "address":
1423
						$ph2ent['localid'] = array('type' => $type,'address' => $address);
1424
						break;
1425
					case "network":
1426
						$ph2ent['localid'] = array('type' => $type,'address' => $address,'netbits' => $netbits);
1427
						break;
1428
					default:
1429
						$ph2ent['localid'] = array('type' => $type);
1430
						break;
1431
				}
1432

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

    
1436
				$ph2ent['protocol'] = $tunnel['p2']['protocol'];
1437

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

    
1462
					if( !$aes_found || ($aes_count < 2))
1463
						$ph2ent['encryption-algorithm-option'][] = $ph2alg;
1464
				}
1465

    
1466
				$ph2ent['hash-algorithm-option'] = $tunnel['p2']['hash-algorithm-option'];
1467
				$ph2ent['pfsgroup'] = $tunnel['p2']['pfsgroup'];
1468
				$ph2ent['lifetime'] = $tunnel['p2']['lifetime'];
1469

    
1470
				$a_phase2[] = $ph2ent;
1471
			}
1472

    
1473
			unset($config['ipsec']['tunnel']);
1474
			$config['ipsec']['phase1'] = $a_phase1;
1475
			$config['ipsec']['phase2'] = $a_phase2;
1476
		}
1477

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

    
1544
		$config['version'] = "4.8";
1545
	}
1546

    
1547
	/* Convert 4.8 -> 4.9 */
1548
	if ($config['version'] <= 4.8) {
1549

    
1550
		/* setup new all users group */
1551
		$all = array();
1552
		$all['name'] = "all";
1553
		$all['description'] = "All Users";
1554
		$all['scope'] = "system";
1555
		$all['gid'] = 1998;
1556
		$all['member'] = array();
1557

    
1558
		if (!is_array($config['system']['group']))
1559
			$config['system']['group'] = array();
1560

    
1561
		/* work around broken uid assignments */
1562
		$config['system']['nextuid'] = 2000;
1563
		foreach ($config['system']['user'] as & $user) {
1564
			if (isset($user['uid']) && !$user['uid'])
1565
				continue;
1566
			$user['uid'] = $config['system']['nextuid']++;
1567
		}
1568

    
1569
		/* work around broken gid assignments */
1570
		$config['system']['nextgid'] = 2000;
1571
		foreach ($config['system']['group'] as & $group) {
1572
			if ($group['name'] == $g['admin_group'])
1573
				$group['gid'] = 1999;
1574
			else
1575
				$group['gid'] = $config['system']['nextgid']++;
1576
		}
1577

    
1578
		/* build group membership information */
1579
		foreach ($config['system']['group'] as & $group) {
1580
			$group['member'] = array();
1581
			foreach ($config['system']['user'] as & $user) {
1582
				$groupnames = explode(",", $user['groupname']);
1583
				if (in_array($group['name'],$groupnames))
1584
					$group['member'][] = $user['uid'];
1585
			}
1586
		}
1587

    
1588
		/* reset user group information */
1589
		foreach ($config['system']['user'] as & $user) {
1590
			unset($user['groupname']);
1591
			$all['member'][] = $user['uid'];
1592
		}
1593

    
1594
		/* reset group scope information */
1595
		foreach ($config['system']['group'] as & $group)
1596
			if ($group['name'] != $g['admin_group'])
1597
				$group['scope'] = "user";
1598

    
1599
		/* insert new all group */
1600
		$groups = Array();
1601
		$groups[] = $all;
1602
		$groups = array_merge($config['system']['group'],$groups);
1603
		$config['system']['group'] = $groups;
1604

    
1605
		$config['version'] = "4.9";
1606
	}
1607

    
1608
	/* Convert 4.9 -> 5.0 */
1609
	if ($config['version'] <= 5.0) {
1610
		
1611
		/* update user privileges */
1612
		foreach ($config['system']['user'] as & $user) {
1613
			$privs = array();
1614
			if (!is_array($user['priv'])) {
1615
				unset($user['priv']);
1616
				continue;
1617
			}
1618
			foreach ($user['priv'] as $priv) {
1619
				switch($priv['id']) {
1620
					case "lockwc":
1621
						$privs[] = "user-lock-webcfg";
1622
						break;
1623
					case "lock-ipages":
1624
						$privs[] = "user-lock-ipages";
1625
						break;
1626
					case "hasshell":
1627
						$privs[] = "user-shell-access";
1628
						break;
1629
					case "copyfiles":
1630
						$privs[] = "user-copy-files";
1631
						break;
1632
				}
1633
			}
1634
			$user['priv'] = $privs;
1635
		}
1636

    
1637
		/* update group privileges */
1638
		foreach ($config['system']['group'] as & $group) {
1639
			$privs = array();
1640
			if (!is_array($group['pages'])) {
1641
				unset($group['pages']);
1642
				continue;
1643
			}
1644
			foreach ($group['pages'] as $page) {
1645
				$priv = map_page_privname($page);
1646
				if ($priv)
1647
					$privs[] = $priv;
1648
			}
1649
			unset($group['pages']);
1650
			$group['priv'] = $privs;
1651
		}
1652

    
1653
		/* sync all local account information */
1654
		local_sync_accounts();
1655

    
1656
		$config['version'] = "5.0";
1657
	}
1658

    
1659
	/* Convert 5.0 -> 5.1 */
1660
	if ($config['version'] <= 5.1) {
1661
		$pconfig = array();
1662
		$pconfig['desc'] = "Set to 0 to disable filtering on the incoming and outgoing member interfaces.";
1663
		$pconfig['tunable'] = "net.link.bridge.pfil_member";
1664
		$pconfig['value'] = "1";
1665
		$config['sysctl']['item'][] = $pconfig;
1666
		$pconfig = array();
1667
		$pconfig['desc'] = "Set to 1 to enable filtering on the bridge interface";
1668
		$pconfig['tunable'] = "net.link.bridge.pfil_bridge";
1669
		$pconfig['value'] = "0";
1670
		$config['sysctl']['item'][] = $pconfig;
1671

    
1672
		unset($config['bridge']);
1673

    
1674
		$convert_bridges = false;
1675
		foreach($config['interfaces'] as $intf) {
1676
			if (isset($intf['bridge']) && $intf['bridge'] <> "") {
1677
				$config['bridges'] = array();
1678
				$config['bridges']['bridged'] = array();
1679
				$convert_bridges = true;
1680
				break;
1681
			}
1682
		}
1683
		if ($convert_bridges == true) {
1684
			$i = 0;
1685
			foreach ($config['interfaces'] as $ifr => &$intf) {
1686
				if (isset($intf['bridge']) && $intf['bridge'] <> "") {
1687
					$nbridge = array();
1688
					$nbridge['members'] = "{$ifr},{$intf['bridge']}";
1689
					$nbridge['descr'] = "Converted bridged {$ifr}";
1690
					$nbridge['bridgeif'] = "bridge{$i}";
1691
					$config['bridges']['bridged'][] = $nbridge;
1692
					unset($intf['bridge']);
1693
					$i++;
1694
				}
1695
			}
1696
		}
1697
		$config['version'] = "5.1";
1698
	}
1699

    
1700
	/* Convert 5.1 -> 5.2 */
1701
	if ($config['version'] <= 5.1) {
1702

    
1703
		$config['openvpn'] = array();
1704
		if (!is_array($config['system']['ca']))
1705
			$config['system']['ca'] = array();
1706
		if (!is_array($config['system']['cert']))
1707
			$config['system']['cert'] = array();
1708

    
1709
		$vpnid = 1;
1710

    
1711
		/* openvpn server configurations */
1712
		if (is_array($config['installedpackages']['openvpnserver']['config'])) {
1713
			$config['openvpn']['openvpn-server'] = array();
1714

    
1715
			$index = 1;
1716
			foreach($config['installedpackages']['openvpnserver']['config'] as $server) {
1717

    
1718
				if (!is_array($server))
1719
					continue;
1720

    
1721
				if ($server['auth_method'] == "pki") {
1722

    
1723
					/* create ca entry */
1724
					$ca = array();
1725
					$ca['refid'] = uniqid();
1726
					$ca['name'] = "OpenVPN Server CA #{$index}";
1727
					$ca['crt'] = $server['ca_cert'];
1728
					$ca['crl'] = $server['crl'];
1729
					$config['system']['ca'][] = $ca;
1730

    
1731
					/* create ca reference */
1732
					unset($server['ca_cert']);
1733
					unset($server['crl']);
1734
					$server['caref'] = $ca['refid'];
1735

    
1736
					/* create cert entry */
1737
					$cert = array();
1738
					$cert['refid'] = uniqid();
1739
					$cert['name'] = "OpenVPN Server Certificate #{$index}";
1740
					$cert['crt'] = $server['server_cert'];
1741
					$cert['prv'] = $server['server_key'];
1742
					$config['system']['cert'][] = $cert;
1743

    
1744
					/* create cert reference */
1745
					unset($server['server_cert']);
1746
					unset($server['server_key']);
1747
					$server['certref'] = $cert['refid'];
1748

    
1749
					$index++;
1750
				}
1751

    
1752
				/* modify configuration values */
1753
				unset($server['dh_params']);
1754
				if (!$server['interface'])
1755
					$server['interface'] = 'wan';
1756
				$server['tunnel_network'] = $server['addresspool'];
1757
				unset($server['addresspool']);
1758
				$server['compress'] = $server['use_lzo'];
1759
				unset($server['use_lzo']);
1760
				if ($server['nopool'])
1761
					$server['pool_enable'] = false;
1762
				else
1763
					$server['pool_enable'] = "yes";
1764
				unset($server['nopool']);
1765
				$server['dns_domain'] = $server['dhcp_domainname'];
1766
				unset($server['dhcp_domainname']);
1767
				$server['dns_server1'] = $server['dhcp_dns'];
1768
				unset($server['dhcp_dns']);
1769
				$server['ntp_server1'] = $server['dhcp_ntp'];
1770
				unset($server['dhcp_ntp']);
1771
				if ($server['dhcp_nbtdisable'])
1772
					$server['netbios_enable'] = false;
1773
				else
1774
					$server['netbios_enable'] = "yes";
1775
				unset($server['dhcp_nbtdisable']);
1776
				$server['netbios_ntype'] = $server['dhcp_nbttype'];
1777
				unset($server['dhcp_nbttype']);
1778
				$server['netbios_scope'] = $server['dhcp_nbtscope'];
1779
				unset($server['dhcp_nbtscope']);
1780
				$server['nbdd_server1'] = $server['dhcp_nbdd'];
1781
				unset($server['dhcp_nbdd']);
1782
				$server['wins_server1'] = $server['dhcp_wins'];
1783
				unset($server['dhcp_wins']);
1784

    
1785
				/* allocate vpnid */
1786
				$server['vpnid'] = $vpnid++;
1787

    
1788
				$config['openvpn']['openvpn-server'][] = $server;
1789
			}
1790
			unset($config['installedpackages']['openvpnserver']);
1791
		}
1792

    
1793
		/* openvpn client configurations */
1794
		if (is_array($config['installedpackages']['openvpnclient']['config'])) {
1795
			$config['openvpn']['openvpn-client'] = array();
1796

    
1797
			$index = 1;
1798
			foreach($config['installedpackages']['openvpnclient']['config'] as $client) {
1799

    
1800
				if (!is_array($client))
1801
					continue;
1802

    
1803
				if ($client['auth_method'] == "pki") {
1804

    
1805
					/* create ca entry */
1806
					$ca = array();
1807
					$ca['refid'] = uniqid();
1808
					$ca['name'] = "OpenVPN Client CA #{$index}";
1809
					$ca['crt'] = $client['ca_cert'];
1810
					$ca['crl'] = $client['crl'];
1811
					$config['system']['ca'][] = $ca;
1812

    
1813
					/* create ca reference */
1814
					unset($client['ca_cert']);
1815
					unset($client['crl']);
1816
					$client['caref'] = $ca['refid'];
1817

    
1818
					/* create cert entry */
1819
					$cert = array();
1820
					$cert['refid'] = uniqid();
1821
					$cert['name'] = "OpenVPN Client Certificate #{$index}";
1822
					$cert['crt'] = $client['client_cert'];
1823
					$cert['prv'] = $client['client_key'];
1824
					$config['system']['cert'][] = $cert;
1825

    
1826
					/* create cert reference */
1827
					unset($client['client_cert']);
1828
					unset($client['client_key']);
1829
					$client['certref'] = $cert['refid'];
1830

    
1831
					$index++;
1832
				}
1833

    
1834
				/* modify configuration values */
1835
				if (!$client['interface'])
1836
					$client['interface'] = 'wan';
1837
				$client['tunnel_network'] = $client['interface_ip'];
1838
				unset($client['interface_ip']);
1839
				$client['server_addr'] = $client['serveraddr'];
1840
				unset($client['serveraddr']);
1841
				$client['server_port'] = $client['serverport'];
1842
				unset($client['serverport']);
1843
				$client['proxy_addr'] = $client['poxy_hostname'];
1844
				unset($client['proxy_addr']);
1845
				$client['compress'] = $client['use_lzo'];
1846
				unset($client['use_lzo']);
1847
				$client['resolve_retry'] = $client['infiniteresolvretry'];
1848
				unset($client['infiniteresolvretry']);
1849

    
1850
				/* allocate vpnid */
1851
				$client['vpnid'] = $vpnid++;
1852

    
1853
				$config['openvpn']['openvpn-client'][] = $client;
1854
			}
1855

    
1856
			unset($config['installedpackages']['openvpnclient']);
1857
		}
1858

    
1859
		/* openvpn client specific configurations */
1860
		if (is_array($config['installedpackages']['openvpncsc']['config'])) {
1861
			$config['openvpn']['openvpn-csc'] = array();
1862

    
1863
			foreach($config['installedpackages']['openvpncsc']['config'] as $csc) {
1864

    
1865
				if (!is_array($csc))
1866
					continue;
1867

    
1868
				/* modify configuration values */
1869
				$csc['common_name'] = $csc['commonname'];
1870
				unset($csc['commonname']);
1871
				$csc['tunnel_network'] = $csc['ifconfig_push'];
1872
				unset($csc['ifconfig_push']);
1873
				$csc['dns_domain'] = $csc['dhcp_domainname'];
1874
				unset($csc['dhcp_domainname']);
1875
				$csc['dns_server1'] = $csc['dhcp_dns'];
1876
				unset($csc['dhcp_dns']);
1877
				$csc['ntp_server1'] = $csc['dhcp_ntp'];
1878
				unset($csc['dhcp_ntp']);
1879
				if ($csc['dhcp_nbtdisable'])
1880
					$csc['netbios_enable'] = false;
1881
				else
1882
					$csc['netbios_enable'] = "yes";
1883
				unset($csc['dhcp_nbtdisable']);
1884
				$csc['netbios_ntype'] = $csc['dhcp_nbttype'];
1885
				unset($csc['dhcp_nbttype']);
1886
				$csc['netbios_scope'] = $csc['dhcp_nbtscope'];
1887
				unset($csc['dhcp_nbtscope']);
1888
				$csc['nbdd_server1'] = $csc['dhcp_nbdd'];
1889
				unset($csc['dhcp_nbdd']);
1890
				$csc['wins_server1'] = $csc['dhcp_wins'];
1891
				unset($csc['dhcp_wins']);
1892

    
1893
				$config['openvpn']['openvpn-csc'][] = $csc;
1894
			}
1895

    
1896
			unset($config['installedpackages']['openvpncsc']);
1897
		}
1898

    
1899
		/*
1900
		 * FIXME: hack to keep things working with no installedpackages
1901
		 * or carp array in the configuration data.
1902
		 */
1903
		if (!is_array($config['installedpackages']))
1904
			$config['installedpackages'] = array();
1905
		if (!is_array($config['installedpackages']['carp']))
1906
			$config['installedpackages']['carp'] = array();
1907

    
1908
		/* reconfigure openvpn services */
1909
		openvpn_resync_all();
1910

    
1911
		$config['version'] = "5.2";
1912
	}
1913

    
1914
	$now = date("H:i:s");
1915
	log_error("Ended Configuration upgrade at $now");
1916

    
1917
	if ($prev_version != $config['version'])
1918
		write_config("Upgraded config version level from {$prev_version} to {$config['version']}");
1919
}
1920

    
1921
/****f* config/write_config
1922
 * NAME
1923
 *   write_config - Backup and write the firewall configuration.
1924
 * DESCRIPTION
1925
 *   write_config() handles backing up the current configuration,
1926
 *   applying changes, and regenerating the configuration cache.
1927
 * INPUTS
1928
 *   $desc	- string containing the a description of configuration changes
1929
 *   $backup	- boolean: do not back up current configuration if false.
1930
 * RESULT
1931
 *   null
1932
 ******/
1933
/* save the system configuration */
1934
function write_config($desc="Unknown", $backup = true) {
1935
	global $config, $g;
1936

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

    
1940
	if($backup)
1941
		backup_config();
1942

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

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

    
1950
	$config['revision']['description'] = $desc;
1951
	$config['revision']['time'] = $changetime;
1952

    
1953
	config_lock();
1954

    
1955
	/* generate configuration XML */
1956
	$xmlconfig = dump_xml_config($config, $g['xml_rootobj']);
1957

    
1958
	conf_mount_rw();
1959

    
1960
	/* write new configuration */
1961
	if (!safe_write_file("{$g['cf_conf_path']}/config.xml", $xmlconfig, false)) {
1962
		die("Unable to open {$g['cf_conf_path']}/config.xml for writing in write_config()\n");
1963
	}
1964

    
1965
	if($g['platform'] == "embedded") {
1966
		cleanup_backupcache(5);
1967
	} else {
1968
		cleanup_backupcache(30);
1969
	}
1970

    
1971
	if($g['booting'] <> true) {
1972
		mwexec("sync");
1973
		conf_mount_ro();
1974
	}
1975

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

    
1979
	/* write config cache */
1980
	safe_write_file("{$g['tmp_path']}/config.cache", serialize($config), true);
1981

    
1982
	/* tell kernel to sync fs data */
1983
	mwexec("/bin/sync");
1984

    
1985
	config_unlock();
1986

    
1987
	return $config;
1988
}
1989

    
1990
/****f* config/reset_factory_defaults
1991
 * NAME
1992
 *   reset_factory_defaults - Reset the system to its default configuration.
1993
 * RESULT
1994
 *   integer	- indicates completion
1995
 ******/
1996
function reset_factory_defaults() {
1997
	global $g;
1998

    
1999
	config_lock();
2000
	conf_mount_rw();
2001

    
2002
	/* create conf directory, if necessary */
2003
	safe_mkdir("{$g['cf_conf_path']}");
2004

    
2005
	/* clear out /conf */
2006
	$dh = opendir($g['conf_path']);
2007
	while ($filename = readdir($dh)) {
2008
		if (($filename != ".") && ($filename != "..")) {
2009
			unlink_if_exists($g['conf_path'] . "/" . $filename);
2010
		}
2011
	}
2012
	closedir($dh);
2013

    
2014
	/* copy default configuration */
2015
	copy("{$g['conf_default_path']}/config.xml", "{$g['conf_path']}/config.xml");
2016

    
2017
	/* call the wizard */
2018
	touch("/conf/trigger_initial_wizard");
2019

    
2020
	mwexec("sync");
2021
	conf_mount_ro();
2022
	config_unlock();
2023

    
2024
	return 0;
2025
}
2026

    
2027
function config_restore($conffile) {
2028
	global $config, $g;
2029

    
2030
	if (!file_exists($conffile))
2031
		return 1;
2032

    
2033
    config_lock();
2034
    conf_mount_rw();
2035

    
2036
    backup_config();
2037
    copy($conffile, "{$g['cf_conf_path']}/config.xml");
2038
	$config = parse_config(true);
2039
    write_config("Reverted to " . array_pop(explode("/", $conffile)) . ".", false);
2040

    
2041
	mwexec("sync");
2042
    conf_mount_ro();
2043
    config_unlock();
2044

    
2045
    return 0;
2046
}
2047

    
2048
function config_install($conffile) {
2049
	global $config, $g;
2050

    
2051
	if (!file_exists($conffile))
2052
		return 1;
2053

    
2054
	if (!config_validate("{$g['conf_path']}/config.xml"))
2055
		return 1;
2056

    
2057
	if($g['booting'] == true)
2058
		echo "Installing configuration...\n";
2059

    
2060
    config_lock();
2061
    conf_mount_rw();
2062

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

    
2065
	/* unlink cache file if it exists */
2066
	if(file_exists("{$g['tmp_path']}/config.cache"))
2067
		unlink("{$g['tmp_path']}/config.cache");
2068

    
2069
	mwexec("sync");
2070
    conf_mount_ro();
2071
    config_unlock();
2072

    
2073
    return 0;
2074
}
2075

    
2076
function config_validate($conffile) {
2077

    
2078
	global $g, $xmlerr;
2079

    
2080
	$xml_parser = xml_parser_create();
2081

    
2082
	if (!($fp = fopen($conffile, "r"))) {
2083
		$xmlerr = "XML error: unable to open file";
2084
		return false;
2085
	}
2086

    
2087
	while ($data = fread($fp, 4096)) {
2088
		if (!xml_parse($xml_parser, $data, feof($fp))) {
2089
			$xmlerr = sprintf("%s at line %d",
2090
						xml_error_string(xml_get_error_code($xml_parser)),
2091
						xml_get_current_line_number($xml_parser));
2092
			return false;
2093
		}
2094
	}
2095
	xml_parser_free($xml_parser);
2096

    
2097
	fclose($fp);
2098

    
2099
	return true;
2100
}
2101

    
2102
/*   lock configuration file, decide that the lock file
2103
 *   is stale after 10 seconds
2104
 */
2105
function config_lock($reason = "") {
2106
	global $g, $process_lock;
2107

    
2108
	/* No need to continue if we're the ones holding the lock */
2109
	if ($process_lock)
2110
		return;
2111

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

    
2114
	$n = 0;
2115
	while ($n < 10) {
2116
		/* open the lock file in append mode to avoid race condition */
2117
		if ($fd = @fopen($lockfile, "x")) {
2118
			/* succeeded */
2119
			fwrite($fd, $reason);
2120
			$process_lock = true;
2121
			fclose($fd);
2122
			return;
2123
		} else {
2124
			/* file locked, wait and try again */
2125
			$process_lock = false;
2126
			sleep(1);
2127
			$n++;
2128
		}
2129
	}
2130
}
2131

    
2132
/* unlock configuration file */
2133
function config_unlock() {
2134
	global $g, $process_lock;
2135

    
2136
	$lockfile = "{$g['varrun_path']}/config.lock";
2137
	$process_lock = false;
2138

    
2139
	unlink_if_exists($lockfile);
2140
}
2141

    
2142
function set_networking_interfaces_ports() {
2143
	global $noreboot;
2144
	global $config;
2145
	global $g;
2146
	global $fp;
2147

    
2148
	$fp = fopen('php://stdin', 'r');
2149

    
2150
	$memory = get_memory();
2151
	$avail = $memory[0];
2152

    
2153
	if($avail < $g['minimum_ram_warning']) {
2154
		echo "\n\n\n";
2155
		echo "DANGER!  WARNING!  ACHTUNG!\n\n";
2156
		echo "{$g['product_name']} requires *AT LEAST* {$g['minimum_ram_warning_text']} ram to function correctly.\n";
2157
		echo "Only ({$avail}) megs of ram has been detected.\n";
2158
		echo "\nPress ENTER to continue. ";
2159
		fgets($fp);
2160
		echo "\n";
2161
	}
2162

    
2163
	$iflist = get_interface_list();
2164

    
2165
	echo <<<EOD
2166

    
2167
Valid interfaces are:
2168

    
2169

    
2170
EOD;
2171

    
2172
	if(!is_array($iflist)) {
2173
		echo "No interfaces found!\n";
2174
	} else {
2175
		foreach ($iflist as $iface => $ifa) {
2176
			echo sprintf("% -8s%s%s\n", $iface, $ifa['mac'],
2177
				$ifa['up'] ? "   (up)" : "");
2178
		}
2179
	}
2180

    
2181
	echo <<<EOD
2182

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

    
2187
Do you want to set up VLANs now [y|n]?
2188
EOD;
2189

    
2190
	if (strcasecmp(chop(fgets($fp)), "y") == 0)
2191
		vlan_setup();
2192

    
2193
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
2194

    
2195
		echo "\n\nVLAN interfaces:\n\n";
2196
		$i = 0;
2197
		foreach ($config['vlans']['vlan'] as $vlan) {
2198

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

    
2202
			$iflist['vlan' . $i] = array();
2203
			$i++;
2204
		}
2205
	}
2206

    
2207
	echo <<<EOD
2208

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

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

    
2216
If you do not know the names of your interfaces, you may choose to use
2217
auto-detection. In that case, disconnect all interfaces now before
2218
hitting 'a' to initiate auto detection.
2219

    
2220
EOD;
2221

    
2222
	do {
2223
		echo "\nEnter the WAN interface name or 'a' for auto-detection: ";
2224
		$wanif = chop(fgets($fp));
2225
		if ($wanif === "") {
2226
			return;
2227
		}
2228
		if ($wanif === "a")
2229
			$wanif = autodetect_interface("WAN", $fp);
2230
		else if (!array_key_exists($wanif, $iflist)) {
2231
			echo "\nInvalid interface name '{$wanif}'\n";
2232
			unset($wanif);
2233
			continue;
2234
		}
2235
	} while (!$wanif);
2236

    
2237
	do {
2238
		echo "\nEnter the LAN interface name or 'a' for auto-detection \n" .
2239
			"(or nothing if finished): ";
2240
		$lanif = chop(fgets($fp));
2241
		
2242
		if($lanif == "exit") {
2243
			exit;
2244
		}
2245
		
2246
		if($lanif == "") {
2247
			if($g['minimum_nic_count'] < 2) {
2248
				break;	
2249
			} else {
2250
				fclose($fp);
2251
				return;
2252
			}
2253
		}
2254

    
2255
		if ($lanif === "a")
2256
			$lanif = autodetect_interface("LAN", $fp);
2257
		else if (!array_key_exists($lanif, $iflist)) {
2258
			echo "\nInvalid interface name '{$lanif}'\n";
2259
			unset($lanif);
2260
			continue;
2261
		}
2262
	} while (!$lanif);
2263

    
2264
	/* optional interfaces */
2265
	$i = 0;
2266
	$optif = array();
2267

    
2268
	if($lanif <> "") {
2269
		while (1) {
2270
			if ($optif[$i])
2271
				$i++;
2272
			$i1 = $i + 1;
2273
	
2274
			if($config['interfaces']['opt' . $i1]['descr'])
2275
				echo "\nOptional interface {$i1} description found: {$config['interfaces']['opt' . $i1]['descr']}";
2276
	
2277
			echo "\nEnter the Optional {$i1} interface name or 'a' for auto-detection\n" .
2278
				"(or nothing if finished): ";
2279
	
2280
			$optif[$i] = chop(fgets($fp));
2281
	
2282
			if ($optif[$i]) {
2283
				if ($optif[$i] === "a") {
2284
					$ad = autodetect_interface("Optional " . $i1, $fp);
2285
					if ($ad)
2286
						$optif[$i] = $ad;
2287
					else
2288
						unset($optif[$i]);
2289
				} else if (!array_key_exists($optif[$i], $iflist)) {
2290
					echo "\nInvalid interface name '{$optif[$i]}'\n";
2291
					unset($optif[$i]);
2292
					continue;
2293
				}
2294
			} else {
2295
				unset($optif[$i]);
2296
				break;
2297
			}
2298
		}
2299
	}
2300
	
2301
	/* check for double assignments */
2302
	$ifarr = array_merge(array($lanif, $wanif), $optif);
2303
	
2304
	for ($i = 0; $i < (count($ifarr)-1); $i++) {
2305
	for ($j = ($i+1); $j < count($ifarr); $j++) {
2306
		if ($ifarr[$i] == $ifarr[$j]) {
2307
			echo <<<EOD
2308

    
2309
Error: you cannot assign the same interface name twice!
2310

    
2311
EOD;
2312
				fclose($fp);
2313
				return;
2314
			}
2315
		}
2316
	}
2317

    
2318
	echo "The interfaces will be assigned as follows: \n\n";
2319

    
2320
	if ($lanif != "")
2321
		echo "LAN  ->" . $lanif . "\n";
2322
	echo "WAN  ->" . $wanif . "\n";
2323
	for ($i = 0; $i < count($optif); $i++) {
2324
		echo "OPT" . ($i+1) . " -> " . $optif[$i] . "\n";
2325
	}
2326

    
2327
echo <<<EOD
2328

    
2329
Do you want to proceed [y|n]?
2330
EOD;
2331

    
2332
	if (strcasecmp(chop(fgets($fp)), "y") == 0) {
2333
		if($lanif) {
2334
			$config['interfaces']['lan']['if'] = $lanif;
2335
		} elseif (!$g['booting']) {
2336

    
2337
echo <<<EODD
2338

    
2339
You have chosen to remove the LAN interface.
2340

    
2341
Would you like to remove the LAN IP address and
2342
unload the interface now? [y|n]? 
2343
EODD;
2344

    
2345
				if (strcasecmp(chop(fgets($fp)), "y") == 0) {
2346
					if($config['interfaces']['lan']['if'])
2347
						mwexec("/sbin/ifconfig delete " . $config['interfaces']['lan']['if']);
2348
				}
2349
				if(isset($config['interfaces']['lan']))
2350
					unset($config['interfaces']['lan']);
2351
				if(isset($config['dhcpd']['lan']))
2352
					unset($config['dhcpd']['lan']);
2353
				if(isset($config['interfaces']['lan']['if']))
2354
					unset($config['interfaces']['lan']['if']);
2355
				if(isset($config['interfaces']['wan']['blockpriv']))
2356
					unset($config['interfaces']['wan']['blockpriv']);
2357
				if(isset($config['shaper']))
2358
					unset($config['shaper']);
2359
				if(isset($config['ezshaper']))
2360
					unset($config['ezshaper']);
2361
				if(isset($config['nat']))
2362
					unset($config['nat']);				
2363
		} else {
2364
			if(isset($config['interfaces']['lan']['if']))
2365
				mwexec("/sbin/ifconfig delete " . $config['interfaces']['lan']['if']);
2366
			if(isset($config['interfaces']['lan']))
2367
				unset($config['interfaces']['lan']);
2368
			if(isset($config['dhcpd']['lan']))
2369
				unset($config['dhcpd']['lan']);
2370
			if(isset($config['interfaces']['lan']['if']))
2371
				unset($config['interfaces']['lan']['if']);
2372
			if(isset($config['interfaces']['wan']['blockpriv']))
2373
				unset($config['interfaces']['wan']['blockpriv']);
2374
			if(isset($config['shaper']))
2375
				unset($config['shaper']);
2376
			if(isset($config['ezshaper']))
2377
				unset($config['ezshaper']);
2378
			if(isset($config['nat']))
2379
				unset($config['nat']);				
2380
		}
2381
		if (preg_match($g['wireless_regex'], $lanif)) {
2382
			if (!is_array($config['interfaces']['lan']['wireless']))
2383
				$config['interfaces']['lan']['wireless'] = array();
2384
		} else {
2385
			unset($config['interfaces']['lan']['wireless']);
2386
		}
2387

    
2388
		$config['interfaces']['wan']['if'] = $wanif;
2389
		if (preg_match($g['wireless_regex'], $wanif)) {
2390
			if (!is_array($config['interfaces']['wan']['wireless']))
2391
				$config['interfaces']['wan']['wireless'] = array();
2392
		} else {
2393
			unset($config['interfaces']['wan']['wireless']);
2394
		}
2395

    
2396
		for ($i = 0; $i < count($optif); $i++) {
2397
			if (!is_array($config['interfaces']['opt' . ($i+1)]))
2398
				$config['interfaces']['opt' . ($i+1)] = array();
2399

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

    
2402
			/* wireless interface? */
2403
			if (preg_match($g['wireless_regex'], $optif[$i])) {
2404
				if (!is_array($config['interfaces']['opt' . ($i+1)]['wireless']))
2405
					$config['interfaces']['opt' . ($i+1)]['wireless'] = array();
2406
			} else {
2407
				unset($config['interfaces']['opt' . ($i+1)]['wireless']);
2408
			}
2409

    
2410
			unset($config['interfaces']['opt' . ($i+1)]['enable']);
2411
			$config['interfaces']['opt' . ($i+1)]['descr'] = "OPT" . ($i+1);
2412
		}
2413

    
2414
		/* remove all other (old) optional interfaces */
2415
		for (; isset($config['interfaces']['opt' . ($i+1)]); $i++)
2416
			unset($config['interfaces']['opt' . ($i+1)]);
2417

    
2418
		echo "\nWriting configuration...";
2419
		write_config();
2420
		echo "done.\n";
2421

    
2422
		echo <<<EOD
2423

    
2424

    
2425

    
2426
EOD;
2427

    
2428
		fclose($fp);
2429
		if($g['booting'])
2430
			return;
2431

    
2432
		echo "One moment while we reload the settings...";
2433

    
2434
		$g['booting'] = false;
2435

    
2436
		/* resync everything */
2437
		reload_all_sync();
2438

    
2439
		echo " done!\n";
2440

    
2441
		touch("{$g['tmp_path']}/assign_complete");
2442

    
2443
	}
2444
}
2445

    
2446
function autodetect_interface($ifname, $fp) {
2447
	$iflist_prev = get_interface_list("media");
2448
	echo <<<EOD
2449

    
2450
Connect the {$ifname} interface now and make sure that the link is up.
2451
Then press ENTER to continue.
2452

    
2453
EOD;
2454
	fgets($fp);
2455
	$iflist = get_interface_list("media");
2456

    
2457
	foreach ($iflist_prev as $ifn => $ifa) {
2458
		if (!$ifa['up'] && $iflist[$ifn]['up']) {
2459
			echo "Detected link-up on interface {$ifn}.\n";
2460
			return $ifn;
2461
		}
2462
	}
2463

    
2464
	echo "No link-up detected.\n";
2465

    
2466
	return null;
2467
}
2468

    
2469
function vlan_setup() {
2470
	global $iflist, $config, $g, $fp;
2471

    
2472
	$iflist = get_interface_list();
2473

    
2474
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
2475

    
2476
	echo <<<EOD
2477

    
2478
WARNING: all existing VLANs will be cleared if you proceed!
2479

    
2480
Do you want to proceed [y|n]?
2481
EOD;
2482

    
2483
	if (strcasecmp(chop(fgets($fp)), "y") != 0)
2484
		return;
2485
	}
2486

    
2487
	$config['vlans']['vlan'] = array();
2488
	echo "\n";
2489

    
2490
	while (1) {
2491
		$vlan = array();
2492

    
2493
		echo "\n\nVLAN Capable interfaces:\n\n";
2494
		if(!is_array($iflist)) {
2495
			echo "No interfaces found!\n";
2496
		} else {
2497
			$vlan_capable=0;
2498
			foreach ($iflist as $iface => $ifa) {
2499
				if (is_jumbo_capable($iface)) {
2500
					echo sprintf("% -8s%s%s\n", $iface, $ifa['mac'],
2501
						$ifa['up'] ? "   (up)" : "");
2502
					$vlan_capable++;
2503
				}
2504
			}
2505
		}
2506

    
2507
		if($vlan_capable == 0) {
2508
			echo "No VLAN capable interfaces detected.\n";
2509
			return;
2510
		}
2511

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

    
2515
		if ($vlan['if']) {
2516
			if (!array_key_exists($vlan['if'], $iflist) or
2517
			    !is_jumbo_capable($vlan['if'])) {
2518
				echo "\nInvalid interface name '{$vlan['if']}'\n";
2519
				continue;
2520
			}
2521
		} else {
2522
			break;
2523
		}
2524

    
2525
		echo "Enter the VLAN tag (1-4094): ";
2526
		$vlan['tag'] = chop(fgets($fp));
2527

    
2528
		if (!is_numericint($vlan['tag']) || ($vlan['tag'] < 1) || ($vlan['tag'] > 4094)) {
2529
			echo "\nInvalid VLAN tag '{$vlan['tag']}'\n";
2530
			continue;
2531
		}
2532

    
2533
		$config['vlans']['vlan'][] = $vlan;
2534
	}
2535
}
2536

    
2537
function system_start_ftp_helpers() {
2538
	require_once("interfaces.inc");
2539
	global $config, $g;
2540

    
2541
	mwexec("/usr/bin/killall ftpsesame");
2542

    
2543
	/* if list */
2544
	$iflist = get_configured_interface_list();
2545

    
2546
	/* loop through all interfaces and handle ftp-proxy */
2547
	$interface_counter = 0;
2548
	foreach ($iflist as $ifent => $ifname) {
2549
		/* XXX: needed?! */
2550
		if ($ifent == "wan")
2551
			continue;
2552

    
2553
		/*    if the ftp proxy is disabled for this interface then kill ftp-proxy
2554
		 *    instance and continue. note that the helpers for port forwards are
2555
		 *    launched in a  different sequence so we are filtering them out
2556
	         *    here by not including -c {$port} -g 8021 first.
2557
		 */
2558

    
2559
		/* Get the ftp queue for this interface */
2560
		if (isset($config['shaper'][$ifname]['ftpqueue']))
2561
			$shaper_queue = $config['interfaces'][$ifname]['ftpqueue'];
2562

    
2563
		$port = 8021 + $interface_counter;
2564
		if(isset($config['interfaces'][$ifname]['disableftpproxy'])) {
2565
			/*    item is disabled.  lets ++ the interface counter and
2566
			 *    keep processing interfaces. kill ftp-proxy if already
2567
			 *    running for this instance.
2568
			 */
2569
			$helpers = exec("/bin/ps awux | grep \"/usr/local/sbin/ftp-proxy {$shaper_queue} -p {$port}\" | grep -v grep | sed \"s/  */ /g\" | cut -f2 -d\" \"");
2570
			if($helpers)
2571
				mwexec("/bin/kill {$helpers}");
2572
			$interface_counter++;
2573
		} else {
2574
			/* grab the current interface IP address */
2575
			$int = convert_friendly_interface_to_real_interface_name($ifname);
2576
			$ip = find_interface_ip($int);
2577
			/* are we in routed mode? no source nat rules and not a outside interface? */
2578
			/* If we have advanced outbound nat we skip the FTP proxy, we use ftpsesame */
2579
			if((isset($config['nat']['advancedoutbound']['enable'])) && (! interface_has_gateway($ifname))) {
2580
				$sourcenat = 0;
2581
				/* we are using advanced outbound nat, are we in routing mode? */
2582
				/* if the interface address lies within a outbound NAT source network we should skip */
2583
				if(! empty($config['nat']['advancedoutbound']['rule'])) {
2584
					foreach($config['nat']['advancedoutbound']['rule'] as $natnetwork) {
2585
						if(ip_in_subnet($ip, $natnetwork['source']['network'])) {
2586
							/* if the interface address is matched in the AON Rule we need the ftp proxy */
2587
							if(is_ipaddr($natnetwork['target']) && ($natnetwork['interface'] == "wan")) {
2588
								$pftpxsourceaddr = "-a {$natnetwork['target']}";
2589
								if($g['debug'])
2590
									log_error("Config: AON: using the external ip source {$pftpxsourceaddr} for the ftp proxy");
2591
							}
2592
							$sourcenat++;
2593
						}
2594
					}
2595
				}
2596
				if($sourcenat == 0) {
2597
					if($g['debug'])
2598
						log_error("Config: No AON rule matched for interface {$ifname} - not using FTP proxy");
2599
					mwexec("/usr/local/sbin/ftpsesame -i $int");
2600
					$interface_counter++;
2601
					continue;
2602
				} else {
2603
					if($g['debug'])
2604
						log_error("Config: AON rule matched for interface {$ifname} - using FTP proxy");
2605
				}
2606
			}
2607
			/* if ftp-proxy is already running then do not launch it again */
2608
			$helpers = exec("/bin/ps awux | grep \"/usr/local/sbin/ftp-proxy {$shaper_queue} -p {$port}\" | grep -v grep | sed \"s/  */ /g\"");
2609
			if(!$helpers && $ip)
2610
 				mwexec("/usr/local/sbin/ftp-proxy {$shaper_queue} -p {$port} {$pftpxsourceaddr} {$ip}");
2611
			if(!$ip)
2612
				mwexec("/usr/local/sbin/ftpsesame {$shaper_queue} -i $int");
2613
			$interface_counter++;
2614
		}
2615
	}
2616
	/* support bridged interfaces.  even they need ftp mojo */
2617
	if (is_array($config['bridges']['bridged']))
2618
		foreach($config['bridges']['bridged'] as $bridge) 
2619
			mwexec("/usr/local/sbin/ftpsesame {$shaper_queue} -i {$bridge['bridgeif']}");
2620
}
2621

    
2622
function cleanup_backupcache($revisions = 30) {
2623
	global $g;
2624
	$i = false;
2625
	config_lock();
2626
	if(file_exists($g['cf_conf_path'] . '/backup/backup.cache')) {
2627
		conf_mount_rw();
2628
		$backups = get_backups();
2629
		$newbaks = array();
2630
		$bakfiles = glob($g['cf_conf_path'] . "/backup/config-*");
2631
		$baktimes = $backups['versions'];
2632
		$tocache = array();
2633
		unset($backups['versions']);
2634
   		foreach($bakfiles as $backup) { // Check for backups in the directory not represented in the cache.
2635
   			if(filesize($backup) == 0) {
2636
   				unlink($backup);
2637
   				continue;
2638
   			}
2639
			$tocheck = array_shift(explode('.', array_pop(explode('-', $backup))));
2640
            if(!in_array($tocheck, $baktimes)) {
2641
				$i = true;
2642
				if($g['booting'])
2643
					echo ".";
2644
				$newxml = parse_xml_config($backup, $g['xml_rootobj']);
2645
				if($newxml == "-1") {
2646
					log_error("The backup cache file $backup is corrupted.  Unlinking.");
2647
					unlink($backup);
2648
					log_error("The backup cache file $backup is corrupted.  Unlinking.");
2649
					continue;
2650
				}
2651
				if($newxml['revision']['description'] == "")
2652
					$newxml['revision']['description'] = "Unknown";
2653
				$tocache[$tocheck] = array('description' => $newxml['revision']['description']);
2654
			}
2655
    	}
2656
		foreach($backups as $checkbak) {
2657

    
2658
			if(count(preg_grep('/' . $checkbak['time'] . '/i', $bakfiles)) != 0) {
2659
				$newbaks[] = $checkbak;
2660
			} else {
2661
				$i = true;
2662
				if($g['booting']) print " " . $tocheck . "r";
2663
			}
2664
		}
2665
		foreach($newbaks as $todo) $tocache[$todo['time']] = array('description' => $todo['description']);
2666
		if(is_int($revisions) and (count($tocache) > $revisions)) {
2667
			$toslice = array_slice(array_keys($tocache), 0, $revisions);
2668
			foreach($toslice as $sliced)
2669
				$newcache[$sliced] = $tocache[$sliced];
2670
			foreach($tocache as $version => $versioninfo) {
2671
				if(!in_array($version, array_keys($newcache))) {
2672
					unlink_if_exists($g['conf_path'] . '/backup/config-' . $version . '.xml');
2673
					if($g['booting']) print " " . $tocheck . "d";
2674
				}
2675
			}
2676
			$tocache = $newcache;
2677
		}
2678
		$bakout = fopen($g['cf_conf_path'] . '/backup/backup.cache', "w");
2679
        fwrite($bakout, serialize($tocache));
2680
		fclose($bakout);
2681
		mwexec("sync");
2682
		conf_mount_ro();
2683
	}
2684
	if($g['booting']) {
2685
		if($i) {
2686
			print "done.\n";
2687
		}
2688
	}
2689
	config_unlock();
2690
}
2691

    
2692
function get_backups() {
2693
	global $g;
2694
	if(file_exists("{$g['cf_conf_path']}/backup/backup.cache")) {
2695
		$confvers = unserialize(file_get_contents("{$g['cf_conf_path']}/backup/backup.cache"));
2696
		$bakvers = array_keys($confvers);
2697
		$toreturn = array();
2698
		sort($bakvers);
2699
		// 	$bakvers = array_reverse($bakvers);
2700
		foreach(array_reverse($bakvers) as $bakver)
2701
			$toreturn[] = array('time' => $bakver, 'description' => $confvers[$bakver]['description']);
2702
	} else {
2703
		return false;
2704
	}
2705
	$toreturn['versions'] = $bakvers;
2706
	return $toreturn;
2707
}
2708

    
2709
function backup_config() {
2710
	global $config, $g;
2711

    
2712
	if($g['platform'] == "cdrom")
2713
		return;
2714

    
2715
	conf_mount_rw();
2716

    
2717
	/* Create backup directory if needed */
2718
	safe_mkdir("{$g['cf_conf_path']}/backup");
2719

    
2720
    if($config['revision']['time'] == "") {
2721
            $baktime = 0;
2722
    } else {
2723
            $baktime = $config['revision']['time'];
2724
    }
2725
    if($config['revision']['description'] == "") {
2726
            $bakdesc = "Unknown";
2727
    } else {
2728
            $bakdesc = $config['revision']['description'];
2729
    }
2730
    copy($g['cf_conf_path'] . '/config.xml', $g['cf_conf_path'] . '/backup/config-' . $baktime . '.xml');
2731
    if(file_exists($g['cf_conf_path'] . '/backup/backup.cache')) {
2732
            $backupcache = unserialize(file_get_contents($g['cf_conf_path'] . '/backup/backup.cache'));
2733
    } else {
2734
            $backupcache = array();
2735
    }
2736
    $backupcache[$baktime] = array('description' => $bakdesc);
2737
    $bakout = fopen($g['cf_conf_path'] . '/backup/backup.cache', "w");
2738
    fwrite($bakout, serialize($backupcache));
2739
    fclose($bakout);
2740

    
2741
	mwexec("sync");
2742
	conf_mount_ro();
2743

    
2744
	return true;
2745
}
2746

    
2747
function mute_kernel_msgs() {
2748
	return;
2749
	exec("/sbin/conscontrol mute on");
2750
}
2751

    
2752
function unmute_kernel_msgs() {
2753
	exec("/sbin/conscontrol mute off");
2754
}
2755

    
2756
function start_devd() {
2757
	exec("/sbin/devd");
2758
	sleep(1);
2759
	if(file_exists("/tmp/rc.linkup"))
2760
		unlink("/tmp/rc.linkup");
2761
}
2762

    
2763
function is_interface_mismatch() {
2764
	global $config, $g;
2765
	if(!$config['interfaces']['lan']) 	
2766
		return false;
2767
	if($config['interfaces']['wan']['ipaddr'] == "carpdev-dhcp")
2768
		return false;		
2769
	$lan_if = $config['interfaces']['lan']['if'];
2770
	$wan_if = get_real_wan_interface();
2771
	$do_assign = 0;
2772
	/* we need to ignore the vlan interface checks) */
2773
	if (stristr($lan_if, "vlan") == false and stristr($wan_if, "vlan") == false) {
2774
		if (does_interface_exist($lan_if) == false)
2775
			if($g['minimum_nic_count'] > 1)
2776
				$do_assign = 1;
2777
		if ($config['interfaces']['wan']['ipaddr'] <> "pppoe" && $config['interfaces']['wan']['ipaddr'] <> "pptp" && $do_assign == 0)
2778
			if (does_interface_exist($wan_if) == false)
2779
				$do_assign = 1;
2780
	}
2781
	/* XXX: enumerate OPT interfaces looking for mismatches */
2782
	if (file_exists("{$g['tmp_path']}/assign_complete"))
2783
		return false;
2784
	if ($do_assign == 1)
2785
		return true;
2786
	else
2787
		return false;
2788
}
2789

    
2790
function set_device_perms() {
2791
	$devices = array(
2792
		'pf'	=> array(	'user'	=> 'proxy',
2793
					'group'	=> 'proxy',
2794
					'mode'	=> 0660),
2795
		);
2796

    
2797
	foreach ($devices as $name => $attr) {
2798
		$path = "/dev/$name";
2799
		if (file_exists($path)) {
2800
			chown($path, $attr['user']);
2801
			chgrp($path, $attr['group']);
2802
			chmod($path, $attr['mode']);
2803
		}
2804
	}
2805
}
2806

    
2807
if($g['booting']) echo ".";
2808
$config = parse_config();
2809

    
2810
?>
(8-8/36)