Project

General

Profile

Download (87.7 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['sysctl']['item'][17]['tunable'] = "net.inet.icmp.icmplim";
1146
			$config['sysctl']['item'][17]['desc'] =    "Set ICMP Limits";
1147
			$config['sysctl']['item'][17]['value'] =   "500";
1148

    
1149
			$config['version'] = "4.1";
1150
		}
1151
	}
1152

    
1153
	/* Convert 4.1 -> 4.2 */
1154
	if ($config['version'] <= 4.1) {
1155
		if (isset($config['shaper']))
1156
			unset($config['shaper']);
1157
		if (isset($config['ezshaper']))
1158
			unset($config['ezshaper']);
1159
		$config['version'] = "4.2";
1160
	}
1161

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

    
1185
if(0):
1186

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

    
1228
			}
1229
		}
1230
		$config['version'] = "4.4";
1231
	}
1232

    
1233
endif;
1234

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

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

    
1279
	/* Convert 4.6 -> 4.7 */
1280
	if ($config['version'] <= 4.6) {
1281

    
1282
		/* Upgrade IPsec from tunnel to phase1/phase2 */
1283

    
1284
        if(is_array($config['ipsec']['tunnel'])) {
1285

    
1286
			$a_phase1 = array();
1287
			$a_phase2 = array();
1288
			$ikeid = 0;
1289

    
1290
			foreach ($config['ipsec']['tunnel'] as $tunnel) {
1291

    
1292
				unset($ph1ent);
1293
				unset($ph2ent);
1294

    
1295
				/*
1296
				 *  attempt to locate an enabled phase1
1297
				 *  entry that matches the peer gateway
1298
				 */
1299

    
1300
				if (!isset($tunnel['disabled'])) {
1301

    
1302
					$remote_gateway = $tunnel['remote-gateway'];
1303

    
1304
					foreach ($a_phase1 as $ph1tmp) {
1305
						if ($ph1tmp['remote-gateway'] == $remote_gateway) {
1306
							$ph1ent = $ph1tmp;
1307
							break;
1308
						}
1309
					}
1310
				}
1311

    
1312
				/* none found, create a new one */
1313

    
1314
				if (!isset( $ph1ent )) {
1315

    
1316
					/* build new phase1 entry */
1317

    
1318
					$ph1ent = array();
1319

    
1320
					$ph1ent['ikeid'] = ++$ikeid;
1321

    
1322
					if (isset($tunnel['disabled']))
1323
						$ph1ent['disabled'] = $tunnel['disabled'];
1324

    
1325
					$ph1ent['interface'] = $tunnel['interface'];
1326
					$ph1ent['remote-gateway'] = $tunnel['remote-gateway'];
1327
					$ph1ent['descr'] = $tunnel['descr'];
1328

    
1329
					$ph1ent['mode'] = $tunnel['p1']['mode'];
1330

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

    
1354
					$ph1ent['peerid_type'] = "peeraddress";
1355

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

    
1377
					$ph1ent['encryption-algorithm'] = $ph1alg;
1378
					$ph1ent['hash-algorithm'] = $tunnel['p1']['hash-algorithm'];
1379
					$ph1ent['dhgroup'] = $tunnel['p1']['dhgroup'];
1380
					$ph1ent['lifetime'] = $tunnel['p1']['lifetime'];
1381
					$ph1ent['authentication_method'] = $tunnel['p1']['authentication_method'];
1382

    
1383
					if (isset($tunnel['p1']['pre-shared-key']))
1384
						$ph1ent['pre-shared-key'] = $tunnel['p1']['pre-shared-key'];
1385
					if (isset($tunnel['p1']['cert']))
1386
						$ph1ent['cert'] = $tunnel['p1']['cert'];
1387
					if (isset($tunnel['p1']['peercert']))
1388
						$ph1ent['peercert'] = $tunnel['p1']['peercert'];
1389
					if (isset($tunnel['p1']['private-key']))
1390
						$ph1ent['private-key'] = $tunnel['p1']['private-key'];
1391

    
1392
					if (isset($tunnel['pinghost']['pinghost']))
1393
						$ph1ent['pinghost'] = $tunnel['pinghost'];
1394

    
1395
					$ph1ent['nat_traversal'] = "on";
1396
					$ph1ent['dpd_enable'] = 1;
1397
					$ph1ent['dpd_delay'] = 10;
1398
					$ph1ent['dpd_maxfail'] = 5;
1399

    
1400
					$a_phase1[] = $ph1ent;
1401
				}
1402

    
1403
				/* build new phase2 entry */
1404

    
1405
				$ph2ent = array();
1406

    
1407
				$ph2ent['ikeid'] = $ph1ent['ikeid'];
1408

    
1409
				if (isset($tunnel['disabled']))
1410
					$ph1ent['disabled'] = $tunnel['disabled'];
1411

    
1412
				$ph2ent['descr'] = "phase2 for ".$tunnel['descr'];
1413

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

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

    
1440
				$ph2ent['protocol'] = $tunnel['p2']['protocol'];
1441

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

    
1466
					if( !$aes_found || ($aes_count < 2))
1467
						$ph2ent['encryption-algorithm-option'][] = $ph2alg;
1468
				}
1469

    
1470
				$ph2ent['hash-algorithm-option'] = $tunnel['p2']['hash-algorithm-option'];
1471
				$ph2ent['pfsgroup'] = $tunnel['p2']['pfsgroup'];
1472
				$ph2ent['lifetime'] = $tunnel['p2']['lifetime'];
1473

    
1474
				$a_phase2[] = $ph2ent;
1475
			}
1476

    
1477
			unset($config['ipsec']['tunnel']);
1478
			$config['ipsec']['phase1'] = $a_phase1;
1479
			$config['ipsec']['phase2'] = $a_phase2;
1480
		}
1481

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

    
1548
		$config['version'] = "4.8";
1549
	}
1550

    
1551
	/* Convert 4.8 -> 4.9 */
1552
	if ($config['version'] <= 4.8) {
1553

    
1554
		/* setup new all users group */
1555
		$all = array();
1556
		$all['name'] = "all";
1557
		$all['description'] = "All Users";
1558
		$all['scope'] = "system";
1559
		$all['gid'] = 1998;
1560
		$all['member'] = array();
1561

    
1562
		if (!is_array($config['system']['group']))
1563
			$config['system']['group'] = array();
1564

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

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

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

    
1592
		/* reset user group information */
1593
		foreach ($config['system']['user'] as & $user) {
1594
			unset($user['groupname']);
1595
			$all['member'][] = $user['uid'];
1596
		}
1597

    
1598
		/* reset group scope information */
1599
		foreach ($config['system']['group'] as & $group)
1600
			if ($group['name'] != $g['admin_group'])
1601
				$group['scope'] = "user";
1602

    
1603
		/* insert new all group */
1604
		$groups = Array();
1605
		$groups[] = $all;
1606
		$groups = array_merge($config['system']['group'],$groups);
1607
		$config['system']['group'] = $groups;
1608

    
1609
		$config['version'] = "4.9";
1610
	}
1611

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

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

    
1651
		/* sync all local account information */
1652
		local_sync_accounts();
1653

    
1654
		$config['version'] = "5.0";
1655
	}
1656

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

    
1670
		unset($config['bridge']);
1671

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

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

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

    
1707
		$vpnid = 1;
1708

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

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

    
1716
				if (!is_array($server))
1717
					continue;
1718

    
1719
				if ($server['auth_method'] == "pki") {
1720

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

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

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

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

    
1747
					$index++;
1748
				}
1749

    
1750
				/* determine operational mode */
1751
				if ($server['auth_method'] == 'pki') {
1752
					if($server['nopool'])
1753
						$server['mode'] = "p2p_tls";
1754
					else
1755
						$server['mode'] = "server_tls";
1756
				} else
1757
					$server['mode'] = "p2p_shared_key";
1758
				unset($server['auth_method']);
1759

    
1760
				/* modify configuration values */
1761
				$server['dh_length'] = 1024;
1762
				unset($server['dh_params']);
1763
				if (!$server['interface'])
1764
					$server['interface'] = 'wan';
1765
				$server['tunnel_network'] = $server['addresspool'];
1766
				unset($server['addresspool']);
1767
				$server['compress'] = $server['use_lzo'];
1768
				unset($server['use_lzo']);
1769
				if ($server['nopool'])
1770
					$server['pool_enable'] = false;
1771
				else
1772
					$server['pool_enable'] = "yes";
1773
				unset($server['nopool']);
1774
				$server['dns_domain'] = $server['dhcp_domainname'];
1775
				unset($server['dhcp_domainname']);
1776
				$server['dns_server1'] = $server['dhcp_dns'];
1777
				unset($server['dhcp_dns']);
1778
				$server['ntp_server1'] = $server['dhcp_ntp'];
1779
				unset($server['dhcp_ntp']);
1780
				if ($server['dhcp_nbtdisable'])
1781
					$server['netbios_enable'] = false;
1782
				else
1783
					$server['netbios_enable'] = "yes";
1784
				unset($server['dhcp_nbtdisable']);
1785
				$server['netbios_ntype'] = $server['dhcp_nbttype'];
1786
				unset($server['dhcp_nbttype']);
1787
				$server['netbios_scope'] = $server['dhcp_nbtscope'];
1788
				unset($server['dhcp_nbtscope']);
1789
				$server['nbdd_server1'] = $server['dhcp_nbdd'];
1790
				unset($server['dhcp_nbdd']);
1791
				$server['wins_server1'] = $server['dhcp_wins'];
1792
				unset($server['dhcp_wins']);
1793

    
1794
				/* allocate vpnid */
1795
				$server['vpnid'] = $vpnid++;
1796

    
1797
				$config['openvpn']['openvpn-server'][] = $server;
1798
			}
1799
			unset($config['installedpackages']['openvpnserver']);
1800
		}
1801

    
1802
		/* openvpn client configurations */
1803
		if (is_array($config['installedpackages']['openvpnclient'])) {
1804
			$config['openvpn']['openvpn-client'] = array();
1805

    
1806
			$index = 1;
1807
			foreach($config['installedpackages']['openvpnclient']['config'] as $client) {
1808

    
1809
				if (!is_array($client))
1810
					continue;
1811

    
1812
				if ($client['auth_method'] == "pki") {
1813

    
1814
					/* create ca entry */
1815
					$ca = array();
1816
					$ca['refid'] = uniqid();
1817
					$ca['name'] = "OpenVPN Client CA #{$index}";
1818
					$ca['crt'] = $client['ca_cert'];
1819
					$ca['crl'] = $client['crl'];
1820
					$config['system']['ca'][] = $ca;
1821

    
1822
					/* create ca reference */
1823
					unset($client['ca_cert']);
1824
					unset($client['crl']);
1825
					$client['caref'] = $ca['refid'];
1826

    
1827
					/* create cert entry */
1828
					$cert = array();
1829
					$cert['refid'] = uniqid();
1830
					$cert['name'] = "OpenVPN Client Certificate #{$index}";
1831
					$cert['crt'] = $client['client_cert'];
1832
					$cert['prv'] = $client['client_key'];
1833
					$config['system']['cert'][] = $cert;
1834

    
1835
					/* create cert reference */
1836
					unset($client['client_cert']);
1837
					unset($client['client_key']);
1838
					$client['certref'] = $cert['refid'];
1839

    
1840
					$index++;
1841
				}
1842

    
1843
				/* determine operational mode */
1844
				if ($client['auth_method'] == 'pki')
1845
					$client['mode'] = "p2p_tls";
1846
				else
1847
					$client['mode'] = "p2p_shared_key";
1848
				unset($client['auth_method']);
1849

    
1850
				/* modify configuration values */
1851
				if (!$client['interface'])
1852
					$client['interface'] = 'wan';
1853
				$client['tunnel_network'] = $client['interface_ip'];
1854
				unset($client['interface_ip']);
1855
				$client['server_addr'] = $client['serveraddr'];
1856
				unset($client['serveraddr']);
1857
				$client['server_port'] = $client['serverport'];
1858
				unset($client['serverport']);
1859
				$client['proxy_addr'] = $client['poxy_hostname'];
1860
				unset($client['proxy_addr']);
1861
				$client['compress'] = $client['use_lzo'];
1862
				unset($client['use_lzo']);
1863
				$client['resolve_retry'] = $client['infiniteresolvretry'];
1864
				unset($client['infiniteresolvretry']);
1865

    
1866
				/* allocate vpnid */
1867
				$client['vpnid'] = $vpnid++;
1868

    
1869
				$config['openvpn']['openvpn-client'][] = $client;
1870
			}
1871

    
1872
			unset($config['installedpackages']['openvpnclient']);
1873
		}
1874

    
1875
		/* openvpn client specific configurations */
1876
		if (is_array($config['installedpackages']['openvpncsc'])) {
1877
			$config['openvpn']['openvpn-csc'] = array();
1878

    
1879
			foreach($config['installedpackages']['openvpncsc']['config'] as $csc) {
1880

    
1881
				if (!is_array($csc))
1882
					continue;
1883

    
1884
				/* modify configuration values */
1885
				$csc['common_name'] = $csc['commonname'];
1886
				unset($csc['commonname']);
1887
				$csc['tunnel_network'] = $csc['ifconfig_push'];
1888
				unset($csc['ifconfig_push']);
1889
				$csc['dns_domain'] = $csc['dhcp_domainname'];
1890
				unset($csc['dhcp_domainname']);
1891
				$csc['dns_server1'] = $csc['dhcp_dns'];
1892
				unset($csc['dhcp_dns']);
1893
				$csc['ntp_server1'] = $csc['dhcp_ntp'];
1894
				unset($csc['dhcp_ntp']);
1895
				if ($csc['dhcp_nbtdisable'])
1896
					$csc['netbios_enable'] = false;
1897
				else
1898
					$csc['netbios_enable'] = "yes";
1899
				unset($csc['dhcp_nbtdisable']);
1900
				$csc['netbios_ntype'] = $csc['dhcp_nbttype'];
1901
				unset($csc['dhcp_nbttype']);
1902
				$csc['netbios_scope'] = $csc['dhcp_nbtscope'];
1903
				unset($csc['dhcp_nbtscope']);
1904
				$csc['nbdd_server1'] = $csc['dhcp_nbdd'];
1905
				unset($csc['dhcp_nbdd']);
1906
				$csc['wins_server1'] = $csc['dhcp_wins'];
1907
				unset($csc['dhcp_wins']);
1908

    
1909
				$config['openvpn']['openvpn-csc'][] = $csc;
1910
			}
1911

    
1912
			unset($config['installedpackages']['openvpncsc']);
1913
		}
1914

    
1915
		/*
1916
		 * FIXME: hack to keep things working with no installedpackages
1917
		 * or carp array in the configuration data.
1918
		 */
1919
		if (!is_array($config['installedpackages']))
1920
			$config['installedpackages'] = array();
1921
		if (!is_array($config['installedpackages']['carp']))
1922
			$config['installedpackages']['carp'] = array();
1923

    
1924
		/* reconfigure openvpn services */
1925
		openvpn_resync_all();
1926

    
1927
		$config['version'] = "5.2";
1928
	}
1929

    
1930
	/* Convert 5.2 -> 5.3 */
1931
	if ($config['version'] <= 5.2) {
1932

    
1933
		if (!is_array($config['system']['ca']))
1934
			$config['system']['ca'] = array();
1935
		if (!is_array($config['system']['cert']))
1936
			$config['system']['cert'] = array();
1937

    
1938
		/* migrate advanced admin page webui ssl to certifcate mngr */
1939
		if ($config['system']['webgui']['certificate'] &&
1940
			$config['system']['webgui']['private-key']) {
1941

    
1942
			/* create cert entry */
1943
			$cert = array();
1944
			$cert['refid'] = uniqid();
1945
			$cert['name'] = "webConfigurator SSL Certificate";
1946
			$cert['crt'] = $config['system']['webgui']['certificate'];
1947
			$cert['prv'] = $config['system']['webgui']['private-key'];
1948
			$config['system']['cert'][] = $cert;
1949

    
1950
			/* create cert reference */
1951
			unset($config['system']['webgui']['certificate']);
1952
			unset($config['system']['webgui']['private-key']);
1953
			$config['system']['webgui']['ssl-certref'] = $cert['refid'];
1954
		}
1955

    
1956
		/* migrate advanced admin page ssh keys to user manager */
1957
		if ($config['system']['ssh']['authorizedkeys']) {
1958
			$admin_user =& getUserEntryByUID(0);
1959
			$admin_user['authorizedkeys'] = $config['system']['ssh']['authorizedkeys'];
1960
			unset($config['system']['ssh']['authorizedkeys']);
1961
		}
1962

    
1963
		$config['version'] = "5.3";
1964
	}
1965

    
1966
	$now = date("H:i:s");
1967
	log_error("Ended Configuration upgrade at $now");
1968

    
1969
	if ($prev_version != $config['version'])
1970
		write_config("Upgraded config version level from {$prev_version} to {$config['version']}");
1971
}
1972

    
1973
/****f* config/write_config
1974
 * NAME
1975
 *   write_config - Backup and write the firewall configuration.
1976
 * DESCRIPTION
1977
 *   write_config() handles backing up the current configuration,
1978
 *   applying changes, and regenerating the configuration cache.
1979
 * INPUTS
1980
 *   $desc	- string containing the a description of configuration changes
1981
 *   $backup	- boolean: do not back up current configuration if false.
1982
 * RESULT
1983
 *   null
1984
 ******/
1985
/* save the system configuration */
1986
function write_config($desc="Unknown", $backup = true) {
1987
	global $config, $g;
1988

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

    
1992
	if($backup)
1993
		backup_config();
1994

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

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

    
2002
	$config['revision']['description'] = $desc;
2003
	$config['revision']['time'] = $changetime;
2004

    
2005
	config_lock();
2006

    
2007
	/* generate configuration XML */
2008
	$xmlconfig = dump_xml_config($config, $g['xml_rootobj']);
2009

    
2010
	conf_mount_rw();
2011

    
2012
	/* write new configuration */
2013
	if (!safe_write_file("{$g['cf_conf_path']}/config.xml", $xmlconfig, false)) {
2014
		die("Unable to open {$g['cf_conf_path']}/config.xml for writing in write_config()\n");
2015
	}
2016

    
2017
	if($g['platform'] == "embedded") {
2018
		cleanup_backupcache(5);
2019
	} else {
2020
		cleanup_backupcache(30);
2021
	}
2022

    
2023
	if($g['booting'] <> true) {
2024
		mwexec("sync");
2025
		conf_mount_ro();
2026
	}
2027

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

    
2031
	/* write config cache */
2032
	safe_write_file("{$g['tmp_path']}/config.cache", serialize($config), true);
2033

    
2034
	/* tell kernel to sync fs data */
2035
	mwexec("/bin/sync");
2036

    
2037
	config_unlock();
2038

    
2039
	return $config;
2040
}
2041

    
2042
/****f* config/reset_factory_defaults
2043
 * NAME
2044
 *   reset_factory_defaults - Reset the system to its default configuration.
2045
 * RESULT
2046
 *   integer	- indicates completion
2047
 ******/
2048
function reset_factory_defaults() {
2049
	global $g;
2050

    
2051
	config_lock();
2052
	conf_mount_rw();
2053

    
2054
	/* create conf directory, if necessary */
2055
	safe_mkdir("{$g['cf_conf_path']}");
2056

    
2057
	/* clear out /conf */
2058
	$dh = opendir($g['conf_path']);
2059
	while ($filename = readdir($dh)) {
2060
		if (($filename != ".") && ($filename != "..")) {
2061
			unlink_if_exists($g['conf_path'] . "/" . $filename);
2062
		}
2063
	}
2064
	closedir($dh);
2065

    
2066
	/* copy default configuration */
2067
	copy("{$g['conf_default_path']}/config.xml", "{$g['conf_path']}/config.xml");
2068

    
2069
	/* call the wizard */
2070
	touch("/conf/trigger_initial_wizard");
2071

    
2072
	mwexec("sync");
2073
	conf_mount_ro();
2074
	config_unlock();
2075

    
2076
	return 0;
2077
}
2078

    
2079
function config_restore($conffile) {
2080
	global $config, $g;
2081

    
2082
	if (!file_exists($conffile))
2083
		return 1;
2084

    
2085
    config_lock();
2086
    conf_mount_rw();
2087

    
2088
    backup_config();
2089
    copy($conffile, "{$g['cf_conf_path']}/config.xml");
2090
	$config = parse_config(true);
2091
    write_config("Reverted to " . array_pop(explode("/", $conffile)) . ".", false);
2092

    
2093
	mwexec("sync");
2094
    conf_mount_ro();
2095
    config_unlock();
2096

    
2097
    return 0;
2098
}
2099

    
2100
function config_install($conffile) {
2101
	global $config, $g;
2102

    
2103
	if (!file_exists($conffile))
2104
		return 1;
2105

    
2106
	if (!config_validate("{$g['conf_path']}/config.xml"))
2107
		return 1;
2108

    
2109
	if($g['booting'] == true)
2110
		echo "Installing configuration...\n";
2111

    
2112
    config_lock();
2113
    conf_mount_rw();
2114

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

    
2117
	/* unlink cache file if it exists */
2118
	if(file_exists("{$g['tmp_path']}/config.cache"))
2119
		unlink("{$g['tmp_path']}/config.cache");
2120

    
2121
	mwexec("sync");
2122
    conf_mount_ro();
2123
    config_unlock();
2124

    
2125
    return 0;
2126
}
2127

    
2128
function config_validate($conffile) {
2129

    
2130
	global $g, $xmlerr;
2131

    
2132
	$xml_parser = xml_parser_create();
2133

    
2134
	if (!($fp = fopen($conffile, "r"))) {
2135
		$xmlerr = "XML error: unable to open file";
2136
		return false;
2137
	}
2138

    
2139
	while ($data = fread($fp, 4096)) {
2140
		if (!xml_parse($xml_parser, $data, feof($fp))) {
2141
			$xmlerr = sprintf("%s at line %d",
2142
						xml_error_string(xml_get_error_code($xml_parser)),
2143
						xml_get_current_line_number($xml_parser));
2144
			return false;
2145
		}
2146
	}
2147
	xml_parser_free($xml_parser);
2148

    
2149
	fclose($fp);
2150

    
2151
	return true;
2152
}
2153

    
2154
/*   lock configuration file, decide that the lock file
2155
 *   is stale after 10 seconds
2156
 */
2157
function config_lock($reason = "") {
2158
	global $g, $process_lock;
2159

    
2160
	/* No need to continue if we're the ones holding the lock */
2161
	if ($process_lock)
2162
		return;
2163

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

    
2166
	$n = 0;
2167
	while ($n < 10) {
2168
		/* open the lock file in append mode to avoid race condition */
2169
		if ($fd = @fopen($lockfile, "x")) {
2170
			/* succeeded */
2171
			fwrite($fd, $reason);
2172
			$process_lock = true;
2173
			fclose($fd);
2174
			return;
2175
		} else {
2176
			/* file locked, wait and try again */
2177
			$process_lock = false;
2178
			sleep(1);
2179
			$n++;
2180
		}
2181
	}
2182
}
2183

    
2184
/* unlock configuration file */
2185
function config_unlock() {
2186
	global $g, $process_lock;
2187

    
2188
	$lockfile = "{$g['varrun_path']}/config.lock";
2189
	$process_lock = false;
2190

    
2191
	unlink_if_exists($lockfile);
2192
}
2193

    
2194
function set_networking_interfaces_ports() {
2195
	global $noreboot;
2196
	global $config;
2197
	global $g;
2198
	global $fp;
2199

    
2200
	$fp = fopen('php://stdin', 'r');
2201

    
2202
	$memory = get_memory();
2203
	$avail = $memory[0];
2204

    
2205
	if($avail < $g['minimum_ram_warning']) {
2206
		echo "\n\n\n";
2207
		echo "DANGER!  WARNING!  ACHTUNG!\n\n";
2208
		echo "{$g['product_name']} requires *AT LEAST* {$g['minimum_ram_warning_text']} ram to function correctly.\n";
2209
		echo "Only ({$avail}) megs of ram has been detected.\n";
2210
		echo "\nPress ENTER to continue. ";
2211
		fgets($fp);
2212
		echo "\n";
2213
	}
2214

    
2215
	$iflist = get_interface_list();
2216

    
2217
	echo <<<EOD
2218

    
2219
Valid interfaces are:
2220

    
2221

    
2222
EOD;
2223

    
2224
	if(!is_array($iflist)) {
2225
		echo "No interfaces found!\n";
2226
	} else {
2227
		foreach ($iflist as $iface => $ifa) {
2228
			echo sprintf("% -8s%s%s\n", $iface, $ifa['mac'],
2229
				$ifa['up'] ? "   (up)" : "");
2230
		}
2231
	}
2232

    
2233
	echo <<<EOD
2234

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

    
2239
Do you want to set up VLANs now [y|n]?
2240
EOD;
2241

    
2242
	if (strcasecmp(chop(fgets($fp)), "y") == 0)
2243
		vlan_setup();
2244

    
2245
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
2246

    
2247
		echo "\n\nVLAN interfaces:\n\n";
2248
		$i = 0;
2249
		foreach ($config['vlans']['vlan'] as $vlan) {
2250

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

    
2254
			$iflist['vlan' . $i] = array();
2255
			$i++;
2256
		}
2257
	}
2258

    
2259
	echo <<<EOD
2260

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

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

    
2268
If you do not know the names of your interfaces, you may choose to use
2269
auto-detection. In that case, disconnect all interfaces now before
2270
hitting 'a' to initiate auto detection.
2271

    
2272
EOD;
2273

    
2274
	do {
2275
		echo "\nEnter the WAN interface name or 'a' for auto-detection: ";
2276
		$wanif = chop(fgets($fp));
2277
		if ($wanif === "") {
2278
			return;
2279
		}
2280
		if ($wanif === "a")
2281
			$wanif = autodetect_interface("WAN", $fp);
2282
		else if (!array_key_exists($wanif, $iflist)) {
2283
			echo "\nInvalid interface name '{$wanif}'\n";
2284
			unset($wanif);
2285
			continue;
2286
		}
2287
	} while (!$wanif);
2288

    
2289
	do {
2290
		echo "\nEnter the LAN interface name or 'a' for auto-detection \n" .
2291
			"(or nothing if finished): ";
2292
		$lanif = chop(fgets($fp));
2293
		
2294
		if($lanif == "exit") {
2295
			exit;
2296
		}
2297
		
2298
		if($lanif == "") {
2299
			if($g['minimum_nic_count'] < 2) {
2300
				break;	
2301
			} else {
2302
				fclose($fp);
2303
				return;
2304
			}
2305
		}
2306

    
2307
		if ($lanif === "a")
2308
			$lanif = autodetect_interface("LAN", $fp);
2309
		else if (!array_key_exists($lanif, $iflist)) {
2310
			echo "\nInvalid interface name '{$lanif}'\n";
2311
			unset($lanif);
2312
			continue;
2313
		}
2314
	} while (!$lanif);
2315

    
2316
	/* optional interfaces */
2317
	$i = 0;
2318
	$optif = array();
2319

    
2320
	if($lanif <> "") {
2321
		while (1) {
2322
			if ($optif[$i])
2323
				$i++;
2324
			$i1 = $i + 1;
2325
	
2326
			if($config['interfaces']['opt' . $i1]['descr'])
2327
				echo "\nOptional interface {$i1} description found: {$config['interfaces']['opt' . $i1]['descr']}";
2328

    
2329
			echo "\nEnter the Optional {$i1} interface name or 'a' for auto-detection\n" .
2330
				"(or nothing if finished): ";
2331
	
2332
			$optif[$i] = chop(fgets($fp));
2333
	
2334
			if ($optif[$i]) {
2335
				if ($optif[$i] === "a") {
2336
					$ad = autodetect_interface("Optional " . $i1, $fp);
2337
					if ($ad)
2338
						$optif[$i] = $ad;
2339
					else
2340
						unset($optif[$i]);
2341
				} else if (!array_key_exists($optif[$i], $iflist)) {
2342
					echo "\nInvalid interface name '{$optif[$i]}'\n";
2343
					unset($optif[$i]);
2344
					continue;
2345
				}
2346
			} else {
2347
				unset($optif[$i]);
2348
				break;
2349
			}
2350
		}
2351
	}
2352
	
2353
	/* check for double assignments */
2354
	$ifarr = array_merge(array($lanif, $wanif), $optif);
2355
	
2356
	for ($i = 0; $i < (count($ifarr)-1); $i++) {
2357
	for ($j = ($i+1); $j < count($ifarr); $j++) {
2358
		if ($ifarr[$i] == $ifarr[$j]) {
2359
			echo <<<EOD
2360

    
2361
Error: you cannot assign the same interface name twice!
2362

    
2363
EOD;
2364
				fclose($fp);
2365
				return;
2366
			}
2367
		}
2368
	}
2369

    
2370
	echo "The interfaces will be assigned as follows: \n\n";
2371

    
2372
	if ($lanif != "")
2373
		echo "LAN  ->" . $lanif . "\n";
2374
	echo "WAN  ->" . $wanif . "\n";
2375
	for ($i = 0; $i < count($optif); $i++) {
2376
		echo "OPT" . ($i+1) . " -> " . $optif[$i] . "\n";
2377
	}
2378

    
2379
echo <<<EOD
2380

    
2381
Do you want to proceed [y|n]?
2382
EOD;
2383

    
2384
	if (strcasecmp(chop(fgets($fp)), "y") == 0) {
2385
		if($lanif) {
2386
			$config['interfaces']['lan']['if'] = $lanif;
2387
		} elseif (!$g['booting']) {
2388

    
2389
echo <<<EODD
2390

    
2391
You have chosen to remove the LAN interface.
2392

    
2393
Would you like to remove the LAN IP address and
2394
unload the interface now? [y|n]? 
2395
EODD;
2396

    
2397
				if (strcasecmp(chop(fgets($fp)), "y") == 0) {
2398
					if($config['interfaces']['lan']['if'])
2399
						mwexec("/sbin/ifconfig delete " . $config['interfaces']['lan']['if']);
2400
				}
2401
				if(isset($config['interfaces']['lan']))
2402
					unset($config['interfaces']['lan']);
2403
				if(isset($config['dhcpd']['lan']))
2404
					unset($config['dhcpd']['lan']);
2405
				if(isset($config['interfaces']['lan']['if']))
2406
					unset($config['interfaces']['lan']['if']);
2407
				if(isset($config['interfaces']['wan']['blockpriv']))
2408
					unset($config['interfaces']['wan']['blockpriv']);
2409
				if(isset($config['shaper']))
2410
					unset($config['shaper']);
2411
				if(isset($config['ezshaper']))
2412
					unset($config['ezshaper']);
2413
				if(isset($config['nat']))
2414
					unset($config['nat']);				
2415
		} else {
2416
			if(isset($config['interfaces']['lan']['if']))
2417
				mwexec("/sbin/ifconfig delete " . $config['interfaces']['lan']['if']);
2418
			if(isset($config['interfaces']['lan']))
2419
				unset($config['interfaces']['lan']);
2420
			if(isset($config['dhcpd']['lan']))
2421
				unset($config['dhcpd']['lan']);
2422
			if(isset($config['interfaces']['lan']['if']))
2423
				unset($config['interfaces']['lan']['if']);
2424
			if(isset($config['interfaces']['wan']['blockpriv']))
2425
				unset($config['interfaces']['wan']['blockpriv']);
2426
			if(isset($config['shaper']))
2427
				unset($config['shaper']);
2428
			if(isset($config['ezshaper']))
2429
				unset($config['ezshaper']);
2430
			if(isset($config['nat']))
2431
				unset($config['nat']);				
2432
		}
2433
		if (preg_match($g['wireless_regex'], $lanif)) {
2434
			if (!is_array($config['interfaces']['lan']['wireless']))
2435
				$config['interfaces']['lan']['wireless'] = array();
2436
		} else {
2437
			unset($config['interfaces']['lan']['wireless']);
2438
		}
2439

    
2440
		$config['interfaces']['wan']['if'] = $wanif;
2441
		if (preg_match($g['wireless_regex'], $wanif)) {
2442
			if (!is_array($config['interfaces']['wan']['wireless']))
2443
				$config['interfaces']['wan']['wireless'] = array();
2444
		} else {
2445
			unset($config['interfaces']['wan']['wireless']);
2446
		}
2447

    
2448
		for ($i = 0; $i < count($optif); $i++) {
2449
			if (!is_array($config['interfaces']['opt' . ($i+1)]))
2450
				$config['interfaces']['opt' . ($i+1)] = array();
2451

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

    
2454
			/* wireless interface? */
2455
			if (preg_match($g['wireless_regex'], $optif[$i])) {
2456
				if (!is_array($config['interfaces']['opt' . ($i+1)]['wireless']))
2457
					$config['interfaces']['opt' . ($i+1)]['wireless'] = array();
2458
			} else {
2459
				unset($config['interfaces']['opt' . ($i+1)]['wireless']);
2460
			}
2461

    
2462
			unset($config['interfaces']['opt' . ($i+1)]['enable']);
2463
			$config['interfaces']['opt' . ($i+1)]['descr'] = "OPT" . ($i+1);
2464
		}
2465

    
2466
		/* remove all other (old) optional interfaces */
2467
		for (; isset($config['interfaces']['opt' . ($i+1)]); $i++)
2468
			unset($config['interfaces']['opt' . ($i+1)]);
2469

    
2470
		echo "\nWriting configuration...";
2471
		write_config();
2472
		echo "done.\n";
2473

    
2474
		echo <<<EOD
2475

    
2476

    
2477

    
2478
EOD;
2479

    
2480
		fclose($fp);
2481
		if($g['booting'])
2482
			return;
2483

    
2484
		echo "One moment while we reload the settings...";
2485

    
2486
		$g['booting'] = false;
2487

    
2488
		/* resync everything */
2489
		reload_all_sync();
2490

    
2491
		echo " done!\n";
2492

    
2493
		touch("{$g['tmp_path']}/assign_complete");
2494

    
2495
	}
2496
}
2497

    
2498
function autodetect_interface($ifname, $fp) {
2499
	$iflist_prev = get_interface_list("media");
2500
	echo <<<EOD
2501

    
2502
Connect the {$ifname} interface now and make sure that the link is up.
2503
Then press ENTER to continue.
2504

    
2505
EOD;
2506
	fgets($fp);
2507
	$iflist = get_interface_list("media");
2508

    
2509
	foreach ($iflist_prev as $ifn => $ifa) {
2510
		if (!$ifa['up'] && $iflist[$ifn]['up']) {
2511
			echo "Detected link-up on interface {$ifn}.\n";
2512
			return $ifn;
2513
		}
2514
	}
2515

    
2516
	echo "No link-up detected.\n";
2517

    
2518
	return null;
2519
}
2520

    
2521
function vlan_setup() {
2522
	global $iflist, $config, $g, $fp;
2523

    
2524
	$iflist = get_interface_list();
2525

    
2526
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
2527

    
2528
	echo <<<EOD
2529

    
2530
WARNING: all existing VLANs will be cleared if you proceed!
2531

    
2532
Do you want to proceed [y|n]?
2533
EOD;
2534

    
2535
	if (strcasecmp(chop(fgets($fp)), "y") != 0)
2536
		return;
2537
	}
2538

    
2539
	$config['vlans']['vlan'] = array();
2540
	echo "\n";
2541

    
2542
	while (1) {
2543
		$vlan = array();
2544

    
2545
		echo "\n\nVLAN Capable interfaces:\n\n";
2546
		if(!is_array($iflist)) {
2547
			echo "No interfaces found!\n";
2548
		} else {
2549
			$vlan_capable=0;
2550
			foreach ($iflist as $iface => $ifa) {
2551
				if (is_jumbo_capable($iface)) {
2552
					echo sprintf("% -8s%s%s\n", $iface, $ifa['mac'],
2553
						$ifa['up'] ? "   (up)" : "");
2554
					$vlan_capable++;
2555
				}
2556
			}
2557
		}
2558

    
2559
		if($vlan_capable == 0) {
2560
			echo "No VLAN capable interfaces detected.\n";
2561
			return;
2562
		}
2563

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

    
2567
		if ($vlan['if']) {
2568
			if (!array_key_exists($vlan['if'], $iflist) or
2569
			    !is_jumbo_capable($vlan['if'])) {
2570
				echo "\nInvalid interface name '{$vlan['if']}'\n";
2571
				continue;
2572
			}
2573
		} else {
2574
			break;
2575
		}
2576

    
2577
		echo "Enter the VLAN tag (1-4094): ";
2578
		$vlan['tag'] = chop(fgets($fp));
2579

    
2580
		if (!is_numericint($vlan['tag']) || ($vlan['tag'] < 1) || ($vlan['tag'] > 4094)) {
2581
			echo "\nInvalid VLAN tag '{$vlan['tag']}'\n";
2582
			continue;
2583
		}
2584
		
2585
		$config['vlans']['vlan'][] = $vlan;
2586
	}
2587
}
2588

    
2589
function system_start_ftp_helpers() {
2590
	require_once("interfaces.inc");
2591
	global $config, $g;
2592

    
2593
	mwexec("/usr/bin/killall ftpsesame");
2594

    
2595
	/* if list */
2596
	$iflist = get_configured_interface_list();
2597

    
2598
	/* loop through all interfaces and handle ftp-proxy */
2599
	$interface_counter = 0;
2600
	foreach ($iflist as $ifent => $ifname) {
2601
		/* XXX: needed?! */
2602
		if ($ifent == "wan")
2603
			continue;
2604

    
2605
		/*    if the ftp proxy is disabled for this interface then kill ftp-proxy
2606
		 *    instance and continue. note that the helpers for port forwards are
2607
		 *    launched in a  different sequence so we are filtering them out
2608
	         *    here by not including -c {$port} -g 8021 first.
2609
		 */
2610

    
2611
		/* Get the ftp queue for this interface */
2612
		if (isset($config['shaper'][$ifname]['ftpqueue']))
2613
			$shaper_queue = $config['interfaces'][$ifname]['ftpqueue'];
2614

    
2615
		$port = 8021 + $interface_counter;
2616
		if(isset($config['interfaces'][$ifname]['disableftpproxy'])) {
2617
			/*    item is disabled.  lets ++ the interface counter and
2618
			 *    keep processing interfaces. kill ftp-proxy if already
2619
			 *    running for this instance.
2620
			 */
2621
			$helpers = exec("/bin/ps awux | grep \"/usr/local/sbin/ftp-proxy {$shaper_queue} -p {$port}\" | grep -v grep | sed \"s/  */ /g\" | cut -f2 -d\" \"");
2622
			if($helpers)
2623
				mwexec("/bin/kill {$helpers}");
2624
			$interface_counter++;
2625
		} else {
2626
			/* grab the current interface IP address */
2627
			$int = convert_friendly_interface_to_real_interface_name($ifname);
2628
			$ip = find_interface_ip($int);
2629
			/* are we in routed mode? no source nat rules and not a outside interface? */
2630
			/* If we have advanced outbound nat we skip the FTP proxy, we use ftpsesame */
2631
			if((isset($config['nat']['advancedoutbound']['enable'])) && (! interface_has_gateway($ifname))) {
2632
				$sourcenat = 0;
2633
				/* we are using advanced outbound nat, are we in routing mode? */
2634
				/* if the interface address lies within a outbound NAT source network we should skip */
2635
				if(! empty($config['nat']['advancedoutbound']['rule'])) {
2636
					foreach($config['nat']['advancedoutbound']['rule'] as $natnetwork) {
2637
						if(ip_in_subnet($ip, $natnetwork['source']['network'])) {
2638
							/* if the interface address is matched in the AON Rule we need the ftp proxy */
2639
							if(is_ipaddr($natnetwork['target']) && ($natnetwork['interface'] == "wan")) {
2640
								$pftpxsourceaddr = "-a {$natnetwork['target']}";
2641
								if($g['debug'])
2642
									log_error("Config: AON: using the external ip source {$pftpxsourceaddr} for the ftp proxy");
2643
							}
2644
							$sourcenat++;
2645
						}
2646
					}
2647
				}
2648
				if($sourcenat == 0) {
2649
					if($g['debug'])
2650
						log_error("Config: No AON rule matched for interface {$ifname} - not using FTP proxy");
2651
					mwexec("/usr/local/sbin/ftpsesame -i $int");
2652
					$interface_counter++;
2653
					continue;
2654
				} else {
2655
					if($g['debug'])
2656
						log_error("Config: AON rule matched for interface {$ifname} - using FTP proxy");
2657
				}
2658
			}
2659
			/* if ftp-proxy is already running then do not launch it again */
2660
			$helpers = exec("/bin/ps awux | grep \"/usr/local/sbin/ftp-proxy {$shaper_queue} -p {$port}\" | grep -v grep | sed \"s/  */ /g\"");
2661
			if(!$helpers && $ip)
2662
 				mwexec("/usr/local/sbin/ftp-proxy {$shaper_queue} -p {$port} {$pftpxsourceaddr} {$ip}");
2663
			if(!$ip)
2664
				mwexec("/usr/local/sbin/ftpsesame {$shaper_queue} -i $int");
2665
			$interface_counter++;
2666
		}
2667
	}
2668
	/* support bridged interfaces.  even they need ftp mojo */
2669
	if (is_array($config['bridges']['bridged']))
2670
		foreach($config['bridges']['bridged'] as $bridge) 
2671
			mwexec("/usr/local/sbin/ftpsesame {$shaper_queue} -i {$bridge['bridgeif']}");
2672
}
2673

    
2674
function cleanup_backupcache($revisions = 30) {
2675
	global $g;
2676
	$i = false;
2677
	config_lock();
2678
	if(file_exists($g['cf_conf_path'] . '/backup/backup.cache')) {
2679
		conf_mount_rw();
2680
		$backups = get_backups();
2681
		$newbaks = array();
2682
		$bakfiles = glob($g['cf_conf_path'] . "/backup/config-*");
2683
		$baktimes = $backups['versions'];
2684
		$tocache = array();
2685
		unset($backups['versions']);
2686
   		foreach($bakfiles as $backup) { // Check for backups in the directory not represented in the cache.
2687
   			if(filesize($backup) == 0) {
2688
   				unlink($backup);
2689
   				continue;
2690
   			}
2691
			$tocheck = array_shift(explode('.', array_pop(explode('-', $backup))));
2692
            if(!in_array($tocheck, $baktimes)) {
2693
				$i = true;
2694
				if($g['booting'])
2695
					echo ".";
2696
				$newxml = parse_xml_config($backup, $g['xml_rootobj']);
2697
				if($newxml == "-1") {
2698
					log_error("The backup cache file $backup is corrupted.  Unlinking.");
2699
					unlink($backup);
2700
					log_error("The backup cache file $backup is corrupted.  Unlinking.");
2701
					continue;
2702
				}
2703
				if($newxml['revision']['description'] == "")
2704
					$newxml['revision']['description'] = "Unknown";
2705
				$tocache[$tocheck] = array('description' => $newxml['revision']['description']);
2706
			}
2707
    	}
2708
		foreach($backups as $checkbak) {
2709

    
2710
			if(count(preg_grep('/' . $checkbak['time'] . '/i', $bakfiles)) != 0) {
2711
				$newbaks[] = $checkbak;
2712
			} else {
2713
				$i = true;
2714
				if($g['booting']) print " " . $tocheck . "r";
2715
			}
2716
		}
2717
		foreach($newbaks as $todo) $tocache[$todo['time']] = array('description' => $todo['description']);
2718
		if(is_int($revisions) and (count($tocache) > $revisions)) {
2719
			$toslice = array_slice(array_keys($tocache), 0, $revisions);
2720
			foreach($toslice as $sliced)
2721
				$newcache[$sliced] = $tocache[$sliced];
2722
			foreach($tocache as $version => $versioninfo) {
2723
				if(!in_array($version, array_keys($newcache))) {
2724
					unlink_if_exists($g['conf_path'] . '/backup/config-' . $version . '.xml');
2725
					if($g['booting']) print " " . $tocheck . "d";
2726
				}
2727
			}
2728
			$tocache = $newcache;
2729
		}
2730
		$bakout = fopen($g['cf_conf_path'] . '/backup/backup.cache', "w");
2731
        fwrite($bakout, serialize($tocache));
2732
		fclose($bakout);
2733
		mwexec("sync");
2734
		conf_mount_ro();
2735
	}
2736
	if($g['booting']) {
2737
		if($i) {
2738
			print "done.\n";
2739
		}
2740
	}
2741
	config_unlock();
2742
}
2743

    
2744
function get_backups() {
2745
	global $g;
2746
	if(file_exists("{$g['cf_conf_path']}/backup/backup.cache")) {
2747
		$confvers = unserialize(file_get_contents("{$g['cf_conf_path']}/backup/backup.cache"));
2748
		$bakvers = array_keys($confvers);
2749
		$toreturn = array();
2750
		sort($bakvers);
2751
		// 	$bakvers = array_reverse($bakvers);
2752
		foreach(array_reverse($bakvers) as $bakver)
2753
			$toreturn[] = array('time' => $bakver, 'description' => $confvers[$bakver]['description']);
2754
	} else {
2755
		return false;
2756
	}
2757
	$toreturn['versions'] = $bakvers;
2758
	return $toreturn;
2759
}
2760

    
2761
function backup_config() {
2762
	global $config, $g;
2763

    
2764
	if($g['platform'] == "cdrom")
2765
		return;
2766

    
2767
	conf_mount_rw();
2768

    
2769
	/* Create backup directory if needed */
2770
	safe_mkdir("{$g['cf_conf_path']}/backup");
2771

    
2772
    if($config['revision']['time'] == "") {
2773
            $baktime = 0;
2774
    } else {
2775
            $baktime = $config['revision']['time'];
2776
    }
2777
    if($config['revision']['description'] == "") {
2778
            $bakdesc = "Unknown";
2779
    } else {
2780
            $bakdesc = $config['revision']['description'];
2781
    }
2782
    copy($g['cf_conf_path'] . '/config.xml', $g['cf_conf_path'] . '/backup/config-' . $baktime . '.xml');
2783
    if(file_exists($g['cf_conf_path'] . '/backup/backup.cache')) {
2784
            $backupcache = unserialize(file_get_contents($g['cf_conf_path'] . '/backup/backup.cache'));
2785
    } else {
2786
            $backupcache = array();
2787
    }
2788
    $backupcache[$baktime] = array('description' => $bakdesc);
2789
    $bakout = fopen($g['cf_conf_path'] . '/backup/backup.cache', "w");
2790
    fwrite($bakout, serialize($backupcache));
2791
    fclose($bakout);
2792

    
2793
	mwexec("sync");
2794
	conf_mount_ro();
2795

    
2796
	return true;
2797
}
2798

    
2799
function mute_kernel_msgs() {
2800
	return;
2801
	exec("/sbin/conscontrol mute on");
2802
}
2803

    
2804
function unmute_kernel_msgs() {
2805
	exec("/sbin/conscontrol mute off");
2806
}
2807

    
2808
function start_devd() {
2809
	exec("/sbin/devd");
2810
	sleep(1);
2811
	if(file_exists("/tmp/rc.linkup"))
2812
		unlink("/tmp/rc.linkup");
2813
}
2814

    
2815
function is_interface_mismatch() {
2816
	global $config, $g;
2817
	if(!$config['interfaces']['lan']) 	
2818
		return false;
2819
	if($config['interfaces']['wan']['ipaddr'] == "carpdev-dhcp")
2820
		return false;		
2821
	$lan_if = $config['interfaces']['lan']['if'];
2822
	$wan_if = get_real_wan_interface();
2823
	$do_assign = 0;
2824
	/* we need to ignore the vlan interface checks) */
2825
	if (stristr($lan_if, "vlan") == false and stristr($wan_if, "vlan") == false) {
2826
		if (does_interface_exist($lan_if) == false)
2827
			if($g['minimum_nic_count'] > 1)
2828
				$do_assign = 1;
2829
		if ($config['interfaces']['wan']['ipaddr'] <> "pppoe" && $config['interfaces']['wan']['ipaddr'] <> "pptp" && $do_assign == 0)
2830
			if (does_interface_exist($wan_if) == false)
2831
				$do_assign = 1;
2832
	}
2833
	/* XXX: enumerate OPT interfaces looking for mismatches */
2834
	if (file_exists("{$g['tmp_path']}/assign_complete"))
2835
		return false;
2836
	if ($do_assign == 1)
2837
		return true;
2838
	else
2839
		return false;
2840
}
2841

    
2842
function set_device_perms() {
2843
	$devices = array(
2844
		'pf'	=> array(	'user'	=> 'proxy',
2845
					'group'	=> 'proxy',
2846
					'mode'	=> 0660),
2847
		);
2848

    
2849
	foreach ($devices as $name => $attr) {
2850
		$path = "/dev/$name";
2851
		if (file_exists($path)) {
2852
			chown($path, $attr['user']);
2853
			chgrp($path, $attr['group']);
2854
			chmod($path, $attr['mode']);
2855
		}
2856
	}
2857
}
2858

    
2859
if($g['booting']) echo ".";
2860
$config = parse_config();
2861

    
2862
?>
(8-8/37)