Project

General

Profile

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

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

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

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

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

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

    
29
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
30
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
31
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
32
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
33
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
34
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
35
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
36
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
37
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
38
	POSSIBILITY OF SUCH DAMAGE.
39
*/
40
/*
41
 * 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 = "msdosfs";
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/encrypted_configxml
207
 * NAME
208
 *   encrypted_configxml - Checks to see if config.xml is encrypted and if so, prompts to unlock.
209
 * INPUTS
210
 *   None
211
 * RESULT
212
 *   $config 	- rewrites config.xml without encryption
213
 ******/
214
function encrypted_configxml() {
215
	global $g, $config;
216
	if(file_exists($g['conf_path'] . "/config.xml")) {
217
		if($g['booting']) {
218
			$configtxt = file_get_contents($g['conf_path'] . "/config.xml");			
219
			if(tagfile_deformat($configtxt, $configtxt, "config.xml")) {
220
				$fp = fopen('php://stdin', 'r');
221
				$data = "";
222
				echo "\n\n*** Encrypted config.xml detected ***\n";
223
				while($data == "") {
224
					echo "\nEnter the password to decrypt config.xml: ";
225
					$decrypt_password = chop(fgets($fp));
226
					$data = decrypt_data($configtxt, $decrypt_password);
227
					if(!strstr($data, "<pfsense>"))
228
						$data = "";
229
					if($data) {
230
						$fd = fopen($g['conf_path'] . "/config.xml", "w");
231
						fwrite($fd, $data);
232
						fclose($fd);
233
						echo "\nConfig.xml unlocked.\n";
234
						fclose($fp);
235
					} else {
236
						echo "\nInvalid password entered.  Please try again.\n";
237
					}
238
				}
239
			}
240
		}
241
	}
242
}
243

    
244
/****f* config/parse_config
245
 * NAME
246
 *   parse_config - Read in config.cache or config.xml if needed and return $config array
247
 * INPUTS
248
 *   $parse       - boolean to force parse_config() to read config.xml and generate config.cache
249
 * RESULT
250
 *   $config      - array containing all configuration variables
251
 ******/
252
function parse_config($parse = false) {
253
	global $g;
254
	if(filesize("{$g['conf_path']}/config.xml") == 0) {
255
		$last_backup = discover_last_backup();
256
		if($last_backup) {
257
			log_error("No config.xml found, attempting last known config restore.");
258
			file_notice("config.xml", "No config.xml found, attempting last known config restore.", "pfSenseConfigurator", "");
259
			restore_backup("{$g['conf_path']}/backup/{$last_backup}");
260
		} else {
261
			die("Config.xml is corrupted and is 0 bytes.  Could not restore a previous backup.");
262
		}
263
	}
264
	if($g['booting']) echo ".";
265
	config_lock();
266
	// Check for encrypted config.xml
267
	encrypted_configxml();
268
	if(!$parse) {
269
		if(file_exists($g['tmp_path'] . '/config.cache')) {
270
			$config = unserialize(file_get_contents($g['tmp_path'] . '/config.cache'));
271
			if(is_null($config)) {
272
				config_unlock();
273
				parse_config(true);
274
			}
275
		} else {
276
			config_unlock();
277
			if(!file_exists($g['conf_path'] . "/config.xml")) {
278
				log_error("No config.xml found, attempting last known config restore.");
279
				file_notice("config.xml", "No config.xml found, attempting last known config restore.", "pfSenseConfigurator", "");
280
				$last_backup = discover_last_backup();
281
				if ($last_backup)
282
					restore_backup("/cf/conf/backup/{$last_backup}");
283
				else
284
					log_error("Could not restore config.xml.");
285
			}
286
			$config = parse_config(true);
287
		}
288
	} else {
289
		if(!file_exists($g['conf_path'] . "/config.xml")) {
290
			if($g['booting']) echo ".";
291
			log_error("No config.xml found, attempting last known config restore.");
292
			file_notice("config.xml", "No config.xml found, attempting last known config restore.", "pfSenseConfigurator", "");
293
			$last_backup = discover_last_backup();
294
			if ($last_backup)
295
				restore_backup("/cf/conf/backup/{$last_backup}");
296
			else
297
				log_error("Could not restore config.xml.");
298
		}
299
		$config = parse_xml_config($g['conf_path'] . '/config.xml', $g['xml_rootobj']);
300
		if($config == "-1") {
301
			$last_backup = discover_last_backup();
302
			if ($last_backup)
303
				restore_backup("/cf/conf/backup/{$last_backup}");
304
			else
305
				log_error(gettext("Could not restore config.xml."));
306
		}
307
		generate_config_cache($config);
308
	}
309
	if($g['booting']) echo ".";
310
	alias_make_table($config);
311
	config_unlock();
312

    
313
	/* process packager manager custom rules */
314
	if(is_dir("/usr/local/pkg/config_parse/")) {
315
		update_filter_reload_status("Running plugins (config_parse)");
316
		run_plugins("/usr/local/pkg/config_parse/");
317
		update_filter_reload_status("Plugins completed.");
318
	}
319

    
320
	return $config;
321
}
322

    
323
/****f* config/generate_config_cache
324
 * NAME
325
 *   generate_config_cache - Write serialized configuration to cache.
326
 * INPUTS
327
 *   $config	- array containing current firewall configuration
328
 * RESULT
329
 *   boolean	- true on completion
330
 ******/
331
function generate_config_cache($config) {
332
	global $g;
333
	config_lock();
334
	conf_mount_rw();
335
	$configcache = fopen($g['tmp_path'] . '/config.cache', "w");
336
	fwrite($configcache, serialize($config));
337
	fclose($configcache);
338
	mwexec("sync");
339
	conf_mount_ro();
340
	config_unlock();
341
	return true;
342
}
343

    
344
function discover_last_backup() {
345
        $backups = split("\n", `cd /cf/conf/backup && ls -ltr *.xml | awk '{print \$9}'`);
346
		$last_backup = "";
347
        foreach($backups as $backup)
348
        	if($backup)
349
	        	$last_backup = $backup;
350
        return $last_backup;
351
}
352

    
353
function restore_backup($file) {
354
	config_lock();
355
	if(file_exists($file)) {
356
		conf_mount_rw();
357
		copy("$file","/cf/conf/config.xml");
358
		unlink_if_exists("/tmp/config.cache");
359
		log_error("{$g['product_name']} is restoring the configuration $file");
360
		file_notice("config.xml", "{$g['product_name']} is restoring the configuration $file", "pfSenseConfigurator", "");
361
		mwexec("sync");
362
		conf_mount_ro();
363
	}
364
	config_unlock();
365
	reload_all();
366
}
367

    
368
/****f* config/parse_config_bootup
369
 * NAME
370
 *   parse_config_bootup - Bootup-specific configuration checks.
371
 * RESULT
372
 *   null
373
 ******/
374
function parse_config_bootup() {
375
	global $config, $g, $noparseconfig;
376
	if($g['booting']) echo ".";
377
	if (!$noparseconfig) {
378
		if (!file_exists("{$g['conf_path']}/config.xml")) {
379
			config_lock();
380
			if ($g['booting']) {
381
				if (strstr($g['platform'], "cdrom")) {
382
					/* try copying the default config. to the floppy */
383
					echo "Resetting factory defaults...\n";
384
					reset_factory_defaults();
385
					if (file_exists("{$g['conf_path']}/config.xml")) {
386
						/* do nothing, we have a file. */
387
					} else {
388
						echo "No XML configuration file found - using factory defaults.\n";
389
						echo "Make sure that the configuration floppy disk with the conf/config.xml\n";
390
						echo "file is inserted. If it isn't, your configuration changes will be lost\n";
391
						echo "on reboot.\n";
392
					}
393
				} else {
394
					$last_backup = discover_last_backup();
395
					if($last_backup) {
396
						log_error("No config.xml found, attempting last known config restore.");
397
						file_notice("config.xml", "No config.xml found, attempting last known config restore.", "pfSenseConfigurator", "");
398
						restore_backup("/cf/conf/backup/{$last_backup}");
399
					}
400
					if(!file_exists("{$g['conf_path']}/config.xml")) {
401
						echo "XML configuration file not found.  {$g['product_name']} cannot continue booting.\n";
402
						mwexec("/sbin/halt");
403
						exit;
404
					}
405
					log_error("Last known config found and restored.  Please double check your configuration file for accuracy.");
406
					file_notice("config.xml", "Last known config found and restored.  Please double check your configuration file for accuracy.", "pfSenseConfigurator", "");
407
				}
408
			} else {
409
				config_unlock();
410
				exit(0);
411
			}
412
		}
413
	}
414
	if(filesize("{$g['conf_path']}/config.xml") == 0) {
415
		$last_backup = discover_last_backup();
416
		if($last_backup) {
417
			log_error("No config.xml found, attempting last known config restore.");
418
			file_notice("config.xml", "No config.xml found, attempting last known config restore.", "pfSenseConfigurator", "");
419
			restore_backup("{$g['conf_path']}/backup/{$last_backup}");
420
		} else {
421
			die("Config.xml is corrupted and is 0 bytes.  Could not restore a previous backup.");
422
		}
423
	}
424
	parse_config(true);
425

    
426
	if ((float)$config['version'] > (float)$g['latest_config']) {
427
		echo <<<EOD
428

    
429

    
430
*******************************************************************************
431
* WARNING!                                                                    *
432
* The current configuration has been created with a newer version of {$g['product_name']}  *
433
* than this one! This can lead to serious misbehavior and even security       *
434
* holes! You are urged to either upgrade to a newer version of {$g['product_name']} or     *
435
* revert to the default configuration immediately!                            *
436
*******************************************************************************
437

    
438

    
439
EOD;
440
		}
441

    
442
	/* make alias table (for faster lookups) */
443
	alias_make_table($config);
444
	config_unlock();
445
}
446

    
447
/****f* config/conf_mount_rw
448
 * NAME
449
 *   conf_mount_rw - Mount filesystems read/write.
450
 * RESULT
451
 *   null
452
 ******/
453
/* mount flash card read/write */
454
function conf_mount_rw() {
455
	global $g;
456

    
457
	/* do not mount on cdrom platform */
458
	if($g['platform'] == "cdrom" or $g['platform'] == "pfSense")
459
		return;
460
		
461
	$status = mwexec("/sbin/mount -u -w {$g['cf_path']}");
462
	if($status <> 0) {
463
		if($g['booting'])
464
			echo "Disk is dirty.  Running fsck -y\n";
465
		mwexec("/sbin/fsck -y {$g['cf_path']}");
466
		$status = mwexec("/sbin/mount -u -w {$g['cf_path']}");
467
	}
468

    
469
	/*    if the platform is soekris or wrap or pfSense, lets mount the
470
	 *    compact flash cards root.
471
         */
472
	if($g['platform'] == "wrap" or $g['platform'] == "net45xx"
473
	   or $g['platform'] == "embedded") {
474
		$status = mwexec("/sbin/mount -u -w /");
475
		/* we could not mount this correctly.  kick off fsck */
476
		if($status <> 0) {
477
			log_error("File system is dirty.  Launching FSCK for /");
478
			mwexec("/sbin/fsck -y /");
479
			$status = mwexec("/sbin/mount -u -w /");
480
		}
481
	}
482
}
483

    
484
/****f* config/conf_mount_ro
485
 * NAME
486
 *   conf_mount_ro - Mount filesystems readonly.
487
 * RESULT
488
 *   null
489
 ******/
490
function conf_mount_ro() {
491
	global $g;
492

    
493
	if($g['booting'] == true)
494
		return;
495

    
496
	/* firmare upgrade in progress */
497
	if(file_exists($g['varrun_path'] . "/firmware.lock"))
498
		return;
499

    
500
	/* do not umount if generating ssh keys */
501
	if(file_exists("/tmp/keys_generating"))
502
		return;
503

    
504
	/* do not umount on cdrom or pfSense platforms */
505
	if($g['platform'] == "cdrom" or $g['platform'] == "pfSense")
506
		return;
507

    
508
	/* sync data, then force a remount of /cf */
509
	mwexec("/bin/sync");
510
	mwexec("/sbin/mount -u -r -f {$g['cf_path']}");
511
	mwexec("/sbin/mount -u -r -f /");
512
}
513

    
514
/****f* config/convert_config
515
 * NAME
516
 *   convert_config - Attempt to update config.xml.
517
 * DESCRIPTION
518
 *   convert_config() reads the current global configuration
519
 *   and attempts to convert it to conform to the latest
520
 *   config.xml version. This allows major formatting changes
521
 *   to be made with a minimum of breakage.
522
 * RESULT
523
 *   null
524
 ******/
525
/* convert configuration, if necessary */
526
function convert_config() {
527
	global $config, $g;
528
        $now = date("H:i:s");
529
        log_error("Start Configuration upgrade at $now, set execution timeout to 15 minutes");
530
        ini_set("max_execution_time", "900");
531

    
532
	/* special case upgrades */
533
	/* fix every minute crontab bogons entry */
534
	$cron_item_count = count($config['cron']['item']);
535
	for($x=0; $x<$cron_item_count; $x++) {
536
		if(stristr($config['cron']['item'][$x]['command'], "rc.update_bogons.sh")) {
537
			if($config['cron']['item'][$x]['hour'] == "*" ) {
538
		        $config['cron']['item'][$x]['hour'] = "3";
539
		 		write_config("Updated bogon update frequency to 3am");
540
		 		log_error("Updated bogon update frequency to 3am");
541
		 	}       
542
		}
543
	}
544
	if ($config['version'] == $g['latest_config'])
545
		return;		/* already at latest version */
546

    
547
	// Save off config version
548
	$prev_version = $config['version'];
549

    
550
	/* convert 1.0 -> 1.1 */
551
	if ($config['version'] <= 1.0) {
552
		$opti = 1;
553
		$ifmap = array('lan' => 'lan', 'wan' => 'wan', 'pptp' => 'pptp');
554

    
555
		/* convert DMZ to optional, if necessary */
556
		if (isset($config['interfaces']['dmz'])) {
557

    
558
			$dmzcfg = &$config['interfaces']['dmz'];
559

    
560
			if ($dmzcfg['if']) {
561
				$config['interfaces']['opt' . $opti] = array();
562
				$optcfg = &$config['interfaces']['opt' . $opti];
563

    
564
				$optcfg['enable'] = $dmzcfg['enable'];
565
				$optcfg['descr'] = "DMZ";
566
				$optcfg['if'] = $dmzcfg['if'];
567
				$optcfg['ipaddr'] = $dmzcfg['ipaddr'];
568
				$optcfg['subnet'] = $dmzcfg['subnet'];
569

    
570
				$ifmap['dmz'] = "opt" . $opti;
571
				$opti++;
572
			}
573

    
574
			unset($config['interfaces']['dmz']);
575
		}
576

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

    
580
			if (!$config['interfaces']['wlan' . $i]['if']) {
581
				unset($config['interfaces']['wlan' . $i]);
582
				continue;
583
			}
584

    
585
			$wlancfg = &$config['interfaces']['wlan' . $i];
586
			$config['interfaces']['opt' . $opti] = array();
587
			$optcfg = &$config['interfaces']['opt' . $opti];
588

    
589
			$optcfg['enable'] = $wlancfg['enable'];
590
			$optcfg['descr'] = "WLAN" . $i;
591
			$optcfg['if'] = $wlancfg['if'];
592
			$optcfg['ipaddr'] = $wlancfg['ipaddr'];
593
			$optcfg['subnet'] = $wlancfg['subnet'];
594
			$optcfg['bridge'] = $wlancfg['bridge'];
595

    
596
			$optcfg['wireless'] = array();
597
			$optcfg['wireless']['mode'] = $wlancfg['mode'];
598
			$optcfg['wireless']['ssid'] = $wlancfg['ssid'];
599
			$optcfg['wireless']['channel'] = $wlancfg['channel'];
600
			$optcfg['wireless']['wep'] = $wlancfg['wep'];
601

    
602
			$ifmap['wlan' . $i] = "opt" . $opti;
603

    
604
			unset($config['interfaces']['wlan' . $i]);
605
			$opti++;
606
		}
607

    
608
		/* convert filter rules */
609
		$n = count($config['filter']['rule']);
610
		for ($i = 0; $i < $n; $i++) {
611

    
612
			$fr = &$config['filter']['rule'][$i];
613

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

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

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

    
652
		/* convert shaper rules */
653
		$n = count($config['pfqueueing']['rule']);
654
		if (is_array($config['pfqueueing']['rule']))
655
			for ($i = 0; $i < $n; $i++) {
656

    
657
			$fr = &$config['pfqueueing']['rule'][$i];
658

    
659
			/* remap interface */
660
			if (array_key_exists($fr['interface'], $ifmap))
661
				$fr['interface'] = $ifmap[$fr['interface']];
662
			else {
663
				/* remove the rule */
664
				echo "\nWarning: traffic shaper rule removed " .
665
					"(interface '{$fr['interface']}' does not exist anymore).";
666
				unset($config['pfqueueing']['rule'][$i]);
667
				continue;
668
			}
669

    
670
			/* remap source network */
671
			if (isset($fr['source']['network'])) {
672
				if (array_key_exists($fr['source']['network'], $ifmap))
673
					$fr['source']['network'] = $ifmap[$fr['source']['network']];
674
				else {
675
					/* remove the rule */
676
					echo "\nWarning: traffic shaper rule removed " .
677
						"(source network '{$fr['source']['network']}' does not exist anymore).";
678
					unset($config['pfqueueing']['rule'][$i]);
679
					continue;
680
				}
681
			}
682

    
683
			/* remap destination network */
684
			if (isset($fr['destination']['network'])) {
685
				if (array_key_exists($fr['destination']['network'], $ifmap))
686
					$fr['destination']['network'] = $ifmap[$fr['destination']['network']];
687
				else {
688
					/* remove the rule */
689
					echo "\nWarning: traffic shaper rule removed " .
690
						"(destination network '{$fr['destination']['network']}' does not exist anymore).";
691
					unset($config['pfqueueing']['rule'][$i]);
692
					continue;
693
				}
694
			}
695
		}
696

    
697
		$config['version'] = "1.1";
698
	}
699

    
700
	/* convert 1.1 -> 1.2 */
701
	if ($config['version'] <= 1.1) {
702
		/* move LAN DHCP server config */
703
		$tmp = $config['dhcpd'];
704
		$config['dhcpd'] = array();
705
		$config['dhcpd']['lan'] = $tmp;
706

    
707
		/* encrypt password */
708
		$config['system']['password'] = crypt($config['system']['password']);
709

    
710
		$config['version'] = "1.2";
711
	}
712

    
713
	/* convert 1.2 -> 1.3 */
714
	if ($config['version'] <= 1.2) {
715
		/* convert advanced outbound NAT config */
716
		for ($i = 0; isset($config['nat']['advancedoutbound']['rule'][$i]); $i++) {
717
			$curent = &$config['nat']['advancedoutbound']['rule'][$i];
718
			$src = $curent['source'];
719
			$curent['source'] = array();
720
			$curent['source']['network'] = $src;
721
			$curent['destination'] = array();
722
			$curent['destination']['any'] = true;
723
		}
724

    
725
		/* add an explicit type="pass" to all filter rules to make things consistent */
726
		for ($i = 0; isset($config['filter']['rule'][$i]); $i++) {
727
			$config['filter']['rule'][$i]['type'] = "pass";
728
		}
729

    
730
		$config['version'] = "1.3";
731
	}
732

    
733
	/* convert 1.3 -> 1.4 */
734
	if ($config['version'] <= 1.3) {
735
		/* convert shaper rules (make pipes) */
736
		if (is_array($config['pfqueueing']['rule'])) {
737
			$config['pfqueueing']['pipe'] = array();
738

    
739
			for ($i = 0; isset($config['pfqueueing']['rule'][$i]); $i++) {
740
				$curent = &$config['pfqueueing']['rule'][$i];
741

    
742
				/* make new pipe and associate with this rule */
743
				$newpipe = array();
744
				$newpipe['descr'] = $curent['descr'];
745
				$newpipe['bandwidth'] = $curent['bandwidth'];
746
				$newpipe['delay'] = $curent['delay'];
747
				$newpipe['mask'] = $curent['mask'];
748
				$config['pfqueueing']['pipe'][$i] = $newpipe;
749

    
750
				$curent['targetpipe'] = $i;
751

    
752
				unset($curent['bandwidth']);
753
				unset($curent['delay']);
754
				unset($curent['mask']);
755
			}
756
		}
757

    
758
		$config['version'] = "1.4";
759
	}
760

    
761
	/* Convert 1.4 -> 1.5 */
762
	if ($config['version'] <= 1.4) {
763

    
764
		/* Default route moved */
765
		if (isset($config['interfaces']['wan']['gateway']))
766
			if ($config['interfaces']['wan']['gateway'] <> "")
767
				$config['interfaces']['wan']['gateway'] = $config['interfaces']['wan']['gateway'];
768
		unset($config['interfaces']['wan']['gateway']);
769

    
770
                /* Queues are no longer interface specific */
771
                if (isset($config['interfaces']['lan']['schedulertype']))
772
                        unset($config['interfaces']['lan']['schedulertype']);
773
                if (isset($config['interfaces']['wan']['schedulertype']))
774
                        unset($config['interfaces']['wan']['schedulertype']);
775

    
776
                for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
777
                        if(isset($config['interfaces']['opt' . $i]['schedulertype']))
778
                                unset($config['interfaces']['opt' . $i]['schedulertype']);
779
                }
780

    
781
		$config['version'] = "1.5";
782
	}
783

    
784
	/* Convert 1.5 -> 1.6 */
785
	if ($config['version'] <= 1.5) {
786
		/* Alternate firmware URL moved */
787
		if (isset($config['system']['firmwareurl']) && isset($config['system']['firmwarename'])) { // Only convert if *both* are defined.
788
			$config['system']['alt_firmware_url'] = array();
789
			$config['system']['alt_firmware_url']['enabled'] = "";
790
			$config['system']['alt_firmware_url']['firmware_base_url'] = $config['system']['firmwareurl'];
791
			$config['system']['alt_firmware_url']['firmware_filename'] = $config['system']['firmwarename'];
792
			unset($config['system']['firmwareurl'], $config['system']['firmwarename']);
793
		} else {
794
			unset($config['system']['firmwareurl'], $config['system']['firmwarename']);
795
		}
796

    
797
		$config['version'] = "1.6";
798
	}
799

    
800
	/* Convert 1.6 -> 1.7 */
801
	if ($config['version'] <= 1.6) {
802
		/* wipe previous shaper configuration */
803
		unset($config['shaper']['queue']);
804
		unset($config['shaper']['rule']);
805
		unset($config['interfaces']['wan']['bandwidth']);
806
		unset($config['interfaces']['wan']['bandwidthtype']);
807
		unset($config['interfaces']['lan']['bandwidth']);
808
		unset($config['interfaces']['lan']['bandwidthtype']);
809
		$config['shaper']['enable'] = FALSE;
810
		$config['version'] = "1.7";
811
	}
812
	/* Convert 1.7 -> 1.8 */
813
	if ($config['version'] <= 1.7) {
814
		if(isset($config['proxyarp']) && is_array($config['proxyarp']['proxyarpnet'])) {
815
			$proxyarp = &$config['proxyarp']['proxyarpnet'];
816
			foreach($proxyarp as $arpent){
817
				$vip = array();
818
				$vip['mode'] = "proxyarp";
819
				$vip['interface'] = $arpent['interface'];
820
				$vip['descr'] = $arpent['descr'];
821
				if (isset($arpent['range'])) {
822
					$vip['range'] = $arpent['range'];
823
					$vip['type'] = "range";
824
				} else {
825
					$subnet = explode('/', $arpent['network']);
826
					$vip['subnet'] = $subnet[0];
827
					if (isset($subnet[1])) {
828
						$vip['subnet_bits'] = $subnet[1];
829
						$vip['type'] = "network";
830
					} else {
831
						$vip['subnet_bits'] = "32";
832
						$vip['type'] = "single";
833
					}
834
				}
835
				$config['virtualip']['vip'][] = $vip;
836
			}
837
			unset($config['proxyarp']);
838
		}
839
		if(isset($config['installedpackages']) && isset($config['installedpackages']['carp']) && is_array($config['installedpackages']['carp']['config'])) {
840
			$carp = &$config['installedpackages']['carp']['config'];
841
			foreach($carp as $carpent){
842
				$vip = array();
843
				$vip['mode'] = "carp";
844
				$vip['interface'] = "AUTO";
845
				$vip['descr'] = "CARP vhid {$carpent['vhid']}";
846
				$vip['type'] = "single";
847
				$vip['vhid'] = $carpent['vhid'];
848
				$vip['advskew'] = $carpent['advskew'];
849
				$vip['password'] = $carpent['password'];
850
				$vip['subnet'] = $carpent['ipaddress'];
851
				$vip['subnet_bits'] = $carpent['netmask'];
852
				$config['virtualip']['vip'][] = $vip;
853
			}
854
			unset($config['installedpackages']['carp']);
855
		}
856
		/* Server NAT is no longer needed */
857
		unset($config['nat']['servernat']);
858

    
859
		/* enable SSH */
860
		if ($config['version'] == "1.8") {
861
			$config['system']['sshenabled'] = true;
862
		}
863

    
864
		$config['version'] = "1.9";
865
	}
866

    
867
	/* Convert 1.8 -> 1.9 */
868
	if ($config['version'] <= 1.8) {
869
		$config['theme']="metallic";
870
		$config['version'] = "1.9";
871
	}
872
	/* Convert 1.9 -> 2.0 */
873
	if ($config['version'] <= 1.9) {
874
		if(is_array($config['ipsec']['tunnel'])) {
875
			reset($config['ipsec']['tunnel']);
876
			while (list($index, $tunnel) = each($config['ipsec']['tunnel'])) {
877
				/* Sanity check on required variables */
878
				/* This fixes bogus <tunnel> entries - remnant of bug #393 */
879
				if (!isset($tunnel['local-subnet']) && !isset($tunnel['remote-subnet'])) {
880
					unset($config['ipsec']['tunnel'][$tunnel]);
881
				}
882
			}
883
        	}
884
		$config['version'] = "2.0";
885
	}
886
	/* Convert 2.0 -> 2.1 */
887
	if ($config['version'] <= 2.0) {
888
		/* shaper scheduler moved */
889
		if(isset($config['system']['schedulertype'])) {
890
			$config['shaper']['schedulertype'] = $config['system']['schedulertype'];
891
			unset($config['system']['schedulertype']);
892
		}
893
		$config['version'] = "2.1";
894
	}
895
	/* Convert 2.1 -> 2.2 */
896
	if ($config['version'] <= 2.1) {
897
		/* move gateway to wan interface */
898
		$config['interfaces']['wan']['gateway'] = $config['system']['gateway'];
899
		$config['version'] = "2.2";
900
	}
901
	/* Convert 2.2 -> 2.3 */
902
	if ($config['version'] <= 2.2) {
903
		if(isset($config['shaper'])) {
904
			/* wipe previous shaper configuration */
905
			unset($config['shaper']);
906
		}
907
		$config['version'] = "2.3";
908
	}
909

    
910
	/* Convert 2.4 -> 2.5 */
911
	if ($config['version'] <= 2.4) {
912
		$config['interfaces']['wan']['use_rrd_gateway'] = $config['system']['use_rrd_gateway'];
913
		unset($config['system']['use_rrd_gateway']);
914
 		$config['version'] = "2.5";
915
	}
916

    
917
	/* Convert 2.5 -> 2.6 */
918
	if ($config['version'] <= 2.5) {
919
		$cron_item = array();
920
		$cron_item['minute'] = "0";
921
		$cron_item['hour'] = "*";
922
		$cron_item['mday'] = "*";
923
		$cron_item['month'] = "*";
924
		$cron_item['wday'] = "*";
925
		$cron_item['who'] = "root";
926
		$cron_item['command'] = "/usr/bin/nice -n20 newsyslog";
927

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

    
930
		$cron_item = array();
931
		$cron_item['minute'] = "1,31";
932
		$cron_item['hour'] = "0-5";
933
		$cron_item['mday'] = "*";
934
		$cron_item['month'] = "*";
935
		$cron_item['wday'] = "*";
936
		$cron_item['who'] = "root";
937
		$cron_item['command'] = "/usr/bin/nice -n20 adjkerntz -a";
938

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

    
941
		$cron_item = array();
942
		$cron_item['minute'] = "1";
943
		$cron_item['hour'] = "*";
944
		$cron_item['mday'] = "1";
945
		$cron_item['month'] = "*";
946
		$cron_item['wday'] = "*";
947
		$cron_item['who'] = "root";
948
		$cron_item['command'] = "/usr/bin/nice -n20 /etc/rc.update_bogons.sh";
949

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

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

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

    
963
		$cron_item = array();
964
		$cron_item['minute'] = "1";
965
		$cron_item['hour'] = "1";
966
		$cron_item['mday'] = "*";
967
		$cron_item['month'] = "*";
968
		$cron_item['wday'] = "*";
969
		$cron_item['who'] = "root";
970
		$cron_item['command'] = "/usr/bin/nice -n20 /etc/rc.dyndns.update";
971

    
972
		$config['cron']['item'][] = $cron_item;
973

    
974
		$cron_item = array();
975
		$cron_item['minute'] = "*/60";
976
		$cron_item['hour'] = "*";
977
		$cron_item['mday'] = "*";
978
		$cron_item['month'] = "*";
979
		$cron_item['wday'] = "*";
980
		$cron_item['who'] = "root";
981
		$cron_item['command'] = "/usr/bin/nice -n20 /usr/local/sbin/expiretable -v -t 3600 virusprot";
982

    
983
		$config['cron']['item'][] = $cron_item;
984

    
985
		$cron_item = array();
986
		$cron_item['minute'] = "*/60";
987
		$cron_item['hour'] = "*";
988
		$cron_item['mday'] = "*";
989
		$cron_item['month'] = "*";
990
		$cron_item['wday'] = "*";
991
		$cron_item['who'] = "root";
992
		$cron_item['command'] = "/usr/bin/nice -n20 /usr/local/sbin/expiretable -t 1800 snort2c";
993

    
994
		$config['cron']['item'][] = $cron_item;
995

    
996
		$cron_item = array();
997
		$cron_item['minute'] = "*/5";
998
		$cron_item['hour'] = "*";
999
		$cron_item['mday'] = "*";
1000
		$cron_item['month'] = "*";
1001
		$cron_item['wday'] = "*";
1002
		$cron_item['who'] = "root";
1003
		$cron_item['command'] = "/usr/local/bin/checkreload.sh";
1004

    
1005
		$config['cron']['item'][] = $cron_item;
1006

    
1007
		/* write crontab entries to file */
1008
		configure_cron();
1009

    
1010
 		$config['version'] = "2.6";
1011
	}
1012

    
1013
	/* Convert 2.7 -> 2.8 */
1014
	if ($config['version'] <= 2.7) {
1015
		$founditem = false;
1016
		foreach($config['cron']['item'] as $cronitem) {
1017
			if($cronitem['command'] == "/usr/local/bin/checkreload.sh")
1018
				$founditem = true;
1019
		}
1020
		if($founditem == false) {
1021
			$cron_item = array();
1022
			$cron_item['minute'] = "*/5";
1023
			$cron_item['hour'] = "*";
1024
			$cron_item['mday'] = "*";
1025
			$cron_item['month'] = "*";
1026
			$cron_item['wday'] = "*";
1027
			$cron_item['who'] = "root";
1028
			$cron_item['command'] = "/usr/local/bin/checkreload.sh";
1029
			$config['cron']['item'][] = $cron_item;
1030
		}
1031
		$config['version'] = "2.8";
1032
	}
1033

    
1034
	/* Convert 2.8 -> 2.9 */
1035
	if ($config['version'] <= 2.8) {
1036
		$rule_item = array();
1037
		$a_filter = &$config['filter']['rule'];
1038
		$rule_item['interface'] = "enc0";
1039
		$rule_item['type'] = "pass";
1040
		$rule_item['source']['any'] = true;
1041
		$rule_item['destination']['any'] = true;
1042
		$rule_item['descr'] = "Permit IPsec traffic.";
1043
		$rule_item['statetype'] = "keep state";
1044
		$a_filter[] = $rule_item;
1045
		$config['version'] = "2.9";
1046
	}
1047

    
1048
	/* Convert 2.9 -> 3.0 */
1049
	if ($config['version'] <= 2.9) {
1050
		/* enable the rrd config setting by default */
1051
		$config['rrd']['enable'] = true;
1052
		$config['version'] = "3.0";
1053
	}
1054

    
1055
	/* Convert 3.0 -> 4.0 */
1056
	if ($config['version'] <= 3.9) {
1057
		$config['system']['webgui']['auth_method'] = "session";
1058
		$config['system']['webgui']['backing_method'] = "htpasswd";
1059

    
1060
		if (isset ($config['system']['username'])) {
1061
			$config['system']['group'] = array();
1062
			$config['system']['group'][0]['name'] = "admins";
1063
			$config['system']['group'][0]['description'] = "System Administrators";
1064
			$config['system']['group'][0]['scope'] = "system";
1065
			$config['system']['group'][0]['pages'] = "ANY";
1066
			$config['system']['group'][0]['home'] = "index.php";
1067
			$config['system']['group'][0]['gid'] = "110";
1068

    
1069
			$config['system']['user'] = array();
1070
			$config['system']['user'][0]['name'] = "{$config['system']['username']}";
1071
			$config['system']['user'][0]['fullname'] = "System Administrator";
1072
			$config['system']['user'][0]['scope'] = "system";
1073
			$config['system']['user'][0]['groupname'] = "admins";
1074
			$config['system']['user'][0]['password'] = "{$config['system']['password']}";
1075
			$config['system']['user'][0]['uid'] = "0";
1076

    
1077
			$config['system']['user'][0]['priv'] = array();
1078
			$config['system']['user'][0]['priv'][0]['id'] = "lockwc";
1079
			$config['system']['user'][0]['priv'][0]['name'] = "Lock webConfigurator";
1080
			$config['system']['user'][0]['priv'][0]['descr'] = "Indicates whether this user will lock access to the webConfigurator for other users.";
1081
			$config['system']['user'][0]['priv'][1]['id'] = "lock-ipages";
1082
			$config['system']['user'][0]['priv'][1]['name'] = "Lock individual pages";
1083
			$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).";
1084
			$config['system']['user'][0]['priv'][2]['id'] = "hasshell";
1085
			$config['system']['user'][0]['priv'][2]['name'] = "Has shell access";
1086
			$config['system']['user'][0]['priv'][2]['descr'] = "Indicates whether this user is able to login for example via SSH.";
1087
			$config['system']['user'][0]['priv'][3]['id'] = "copyfiles";
1088
			$config['system']['user'][0]['priv'][3]['name'] = "Is allowed to copy files";
1089
			$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).";
1090
			$config['system']['user'][0]['priv'][4]['id'] = "isroot";
1091
			$config['system']['user'][0]['priv'][4]['name'] = "Is root user";
1092
			$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).";
1093

    
1094
			$config['system']['nextuid'] = "111";
1095
			$config['system']['nextgid'] = "111";
1096

    
1097
			/* wipe previous auth configuration */
1098
			unset ($config['system']['username']);
1099
			unset ($config['system']['password']);
1100
			
1101
			$config['version'] = "4.0";
1102
		}
1103

    
1104
	}
1105
		
1106
	/* Convert 4.0 -> 4.1 */
1107
	if ($config['version'] <= 4.0) {
1108
		if(!$config['sysctl']) {
1109

    
1110
			$config['sysctl']['item'] = array();
1111
	
1112
			$config['sysctl']['item'][0]['tunable'] = "net.inet.tcp.blackhole";
1113
			$config['sysctl']['item'][0]['desc'] =    "Drop packets to closed TCP ports without returning a RST";
1114
			$config['sysctl']['item'][0]['value'] =   "2";
1115
	
1116
			$config['sysctl']['item'][1]['tunable'] = "net.inet.udp.blackhole";
1117
			$config['sysctl']['item'][1]['desc'] =    "Do not send ICMP port unreachable messages for closed UDP ports";
1118
			$config['sysctl']['item'][1]['value'] =   "1";
1119
	
1120
			$config['sysctl']['item'][2]['tunable'] = "net.inet.ip.random_id";
1121
			$config['sysctl']['item'][2]['desc'] =    "Randomize the ID field in IP packets (default is 0: sequential IP IDs)";
1122
			$config['sysctl']['item'][2]['value'] =   "1";
1123
	
1124
			$config['sysctl']['item'][3]['tunable'] = "net.inet.tcp.drop_synfin";
1125
			$config['sysctl']['item'][3]['desc'] =    "Drop SYN-FIN packets (breaks RFC1379, but nobody uses it anyway)";
1126
			$config['sysctl']['item'][3]['value'] =   "1";
1127
	
1128
			$config['sysctl']['item'][4]['tunable'] = "net.inet.ip.redirect";
1129
			$config['sysctl']['item'][4]['desc'] =    "Disable sending IPv4 redirects";
1130
			$config['sysctl']['item'][4]['value'] =   "0";
1131
	
1132
			$config['sysctl']['item'][5]['tunable'] = "net.inet6.ip6.redirect";
1133
			$config['sysctl']['item'][5]['desc'] =    "Disable sending IPv6 redirects";
1134
			$config['sysctl']['item'][5]['value'] =   "0";
1135
	
1136
			$config['sysctl']['item'][6]['tunable'] = "net.inet.tcp.syncookies";
1137
			$config['sysctl']['item'][6]['desc'] =    "Generate SYN cookies for outbound SYN-ACK packets";
1138
			$config['sysctl']['item'][6]['value'] =   "1";
1139
	
1140
			$config['sysctl']['item'][7]['tunable'] = "net.inet.tcp.recvspace";
1141
			$config['sysctl']['item'][7]['desc'] =    "Maximum incoming TCP datagram size";
1142
			$config['sysctl']['item'][7]['value'] =   "65228";
1143
	
1144
			$config['sysctl']['item'][8]['tunable'] = "net.inet.tcp.sendspace";
1145
			$config['sysctl']['item'][8]['desc'] =    "Maximum outgoing TCP datagram size";
1146
			$config['sysctl']['item'][8]['value'] =   "65228";
1147
	
1148
			$config['sysctl']['item'][9]['tunable'] = "net.inet.ip.fastforwarding";
1149
			$config['sysctl']['item'][9]['desc'] =    "Fastforwarding (see http://lists.freebsd.org/pipermail/freebsd-net/2004-January/002534.html)";
1150
			$config['sysctl']['item'][9]['value'] =   "1";
1151
	
1152
			$config['sysctl']['item'][10]['tunable'] = "net.inet.tcp.delayed_ack";
1153
			$config['sysctl']['item'][10]['desc'] =    "Do not delay ACK to try and piggyback it onto a data packet";
1154
			$config['sysctl']['item'][10]['value'] =   "0";
1155
	
1156
			$config['sysctl']['item'][11]['tunable'] = "net.inet.udp.maxdgram";
1157
			$config['sysctl']['item'][11]['desc'] =    "Maximum outgoing UDP datagram size";
1158
			$config['sysctl']['item'][11]['value'] =   "57344";
1159
	
1160
			$config['sysctl']['item'][12]['tunable'] = "net.link.bridge.pfil_onlyip";
1161
			$config['sysctl']['item'][12]['desc'] =    "Handling of non-IP packets which are not passed to pfil (see if_bridge(4))";
1162
			$config['sysctl']['item'][12]['value'] =   "0";
1163
	
1164
			$config['sysctl']['item'][13]['tunable'] = "net.link.tap.user_open";
1165
			$config['sysctl']['item'][13]['desc'] =    "Allow unprivileged access to tap(4) device nodes";
1166
			$config['sysctl']['item'][13]['value'] =   "1";
1167
	
1168
			$config['sysctl']['item'][14]['tunable'] = "kern.rndtest.verbose";
1169
			$config['sysctl']['item'][14]['desc'] =    "Verbosity of the rndtest driver (0: do not display results on console)";
1170
			$config['sysctl']['item'][14]['value'] =   "0";
1171
	
1172
			$config['sysctl']['item'][15]['tunable'] = "kern.randompid";
1173
			$config['sysctl']['item'][15]['desc'] =    "Randomize PID's (see src/sys/kern/kern_fork.c: sysctl_kern_randompid())";
1174
			$config['sysctl']['item'][15]['value'] =   "347";
1175
	
1176
			$config['sysctl']['item'][16]['tunable'] = "net.inet.tcp.inflight.enable";
1177
			$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. ";
1178
			$config['sysctl']['item'][16]['value'] =   "1";
1179

    
1180
			$config['sysctl']['item'][17]['tunable'] = "net.inet.icmp.icmplim";
1181
			$config['sysctl']['item'][17]['desc'] =    "Set ICMP Limits";
1182
			$config['sysctl']['item'][17]['value'] =   "750";
1183

    
1184
			$config['sysctl']['item'][18]['tunable'] = "net.inet.tcp.tso";
1185
			$config['sysctl']['item'][18]['desc'] =    "TCP Offload engine";
1186
			$config['sysctl']['item'][18]['value'] =   "0";
1187

    
1188
			$config['sysctl']['item'][19]['tunable'] = "hw.bce.tso_enable";
1189
			$config['sysctl']['item'][19]['desc'] =    "TCP Offload engine - BCE";
1190
			$config['sysctl']['item'][19]['value'] =   "0";
1191

    
1192
			$config['version'] = "4.1";
1193
		}
1194
	}
1195

    
1196
	/* Convert 4.1 -> 4.2 */
1197
	if ($config['version'] <= 4.1) {
1198
		if (isset($config['shaper']))
1199
			unset($config['shaper']);
1200
		if (isset($config['ezshaper']))
1201
			unset($config['ezshaper']);
1202
		$config['version'] = "4.2";
1203
	}
1204

    
1205
	/* Convert 4.2 -> 4.3 */
1206
	if ($config['version'] <= 4.2) {
1207
		/* migrate old interface gateway to the new gateways config */
1208
		$old_gateways = array();
1209
		$gateways = array();
1210
		$i = 0;
1211
		$old_gateways = get_interfaces_with_gateway();
1212
		foreach($old_gateways as $ifname => $interface) {
1213
			if(is_ipaddr($config['interfaces'][$ifname]['gateway'])) {
1214
				$config['gateways'][$i][$ifname]['gateway'] = $config['interfaces'][$ifname]['gateway'];
1215
				$config['gateways'][$i][$ifname]['interface'] = $ifname;
1216
				$config['gateways'][$i][$ifname]['name'] = $ifname ."-". $config['interfaces'][$ifname]['gateway'];
1217
				if(is_ipaddr($config['interfaces'][$ifname]['use_rrd_gateway'])) {
1218
					$config['gateways'][$i][$ifname]['monitor'] = $config['interfaces'][$ifname]['use_rrd_gateway'];
1219
					unset($config['interfaces'][$ifname]['use_rrd_gateway']);
1220
				}
1221
				$config['interfaces'][$ifname]['gateway'] = $config['gateways'][$i][$ifname]['name'];
1222
				$i++;
1223
			}
1224
		}
1225
		$config['version'] = "4.3";
1226
	}
1227

    
1228
if(0):
1229

    
1230
	/* Convert 4.3 -> 4.4 */
1231
	if ($config['version'] <= 4.3) {
1232
		if (isset($config['installedpackages']['openvpnserver']['config'])) {
1233
			$ocfg =& $config['installedpackages']['openvpnserver']['config'];
1234
			if (!isset($config['openvpn']))
1235
				$config['openvpn'] = array();
1236
			if (!isset($config['openvpn']['keys']))
1237
				$config['openvpn']['keys'] = array();
1238
			$ncfg =& $config['openvpn']['keys'];
1239
			foreach ($ocfg as $id => &$cfg) {
1240
				if ($cfg['auth_method'] == 'shared_key') {
1241
					$ncfg["converted{$id}"]['shared.key'] = $cfg['shared_key'];
1242
					$ncfg["converted{$id}"]['existing'] = "yes";
1243
					$ncfg["converted{$id}"]['auth_method'] = "shared_key";
1244
					$cfg['cipher'] = "converted{$id}";
1245
					unset($cfg['shared_key']);
1246
				} else  {
1247
					if (isset($cfg['ca_cert']))  {
1248
						$ncfg["converted{$id}"]['ca.crt'] = $cfg['ca_cert'];
1249
						unset($cfg['ca_cert']);
1250
					}
1251
					if (isset($cfg['server_cert']))  {
1252
						$ncfg["converted{$id}"]['server.crt'] = $cfg['server_cert'];
1253
						unset($cfg['server_cert']);
1254
					}
1255
					if (isset($cfg['server_key']))  {
1256
						$ncfg["converted{$id}"]['server.key'] = $cfg['server_key'];
1257
						unset($cfg['ca_cert']);
1258
					}
1259
					if (isset($cfg['dh_params']))  {
1260
						$ncfg["converted{$id}"]['dh_params.dh'] = $cfg['dh_params'];
1261
						unset($cfg['dh_params']);
1262
					}
1263
					if (isset($cfg['crl']))  {
1264
						$ncfg["converted{$id}"]['crl'] = $cfg['crl'];
1265
						unset($cfg['crl']);
1266
					}
1267
					$ncfg["converted{$id}"]['existing'] = "yes";
1268
					$cfg['cipher'] = "converted{$id}";
1269
				}
1270

    
1271
			}
1272
		}
1273
		$config['version'] = "4.4";
1274
	}
1275

    
1276
endif;
1277

    
1278
	/* Convert 4.4 -> 4.5 */
1279
	if ($config['version'] <= 4.4) {
1280
		if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
1281
			foreach ($config['vlans']['vlan'] as $id => &$vlan)
1282
				$vlan['vlanif'] = "vlan{$tag}";
1283
		}
1284
		$config['version'] = "4.5";
1285
	}
1286

    
1287
	/* Upgrade load balancer from slb to relayd */
1288
        /* Convert 4.5 -> 4.6 */
1289
        if ($config['version'] <= 4.5) {
1290
                if (is_array($config['load_balancer']['virtual_server']) && count($config['load_balancer']['virtual_server'])) {
1291
			$vs_a = &$config['load_balancer']['virtual_server'];
1292
			$pool_a = &$config['load_balancer']['lbpool'];
1293
			$pools = array();
1294
			/* Index pools by name */
1295
			if(is_array($pool_a)) {
1296
				for ($i = 0; isset($pool_a[$i]); $i++) {
1297
					if ($pool_a[$i]['type'] == "server") {
1298
						$pools[$pool_a[$i]['name']] = $pool_a[$i];
1299
					}
1300
				}
1301
			}
1302
			/* Convert sitedown entries to pools and re-attach */
1303
			for ($i = 0; isset($vs_a[$i]); $i++) {
1304
				if (isset($vs_a[$i]['sitedown'])) {
1305
					$pool = array();
1306
					$pool['type'] = 'server';
1307
					$pool['behaviour'] = 'balance';
1308
					$pool['name'] = "{$vs_a[$i]['name']}-sitedown";
1309
					$pool['desc'] = "Sitedown pool for VS: {$vs_a[$i]['name']}";
1310
					$pool['port'] = $pools[$vs_a[$i]['pool']]['port'];
1311
					$pool['servers'] = array();
1312
					$pool['servers'][] = $vs_a[$i]['sitedown'];
1313
					$pool['monitor'] = $pools[$vs_a[$i]['pool']]['monitor'];
1314
					$pool_a[] = $pool;
1315
					$vs_a[$i]['sitedown'] = $pool['name'];
1316
				}
1317
			}
1318
                }
1319
                $config['version'] = "4.6";
1320
        }
1321

    
1322
	/* Convert 4.6 -> 4.7 */
1323
	if ($config['version'] <= 4.6) {
1324

    
1325
		/* Upgrade IPsec from tunnel to phase1/phase2 */
1326

    
1327
        if(is_array($config['ipsec']['tunnel'])) {
1328

    
1329
			$a_phase1 = array();
1330
			$a_phase2 = array();
1331
			$ikeid = 0;
1332

    
1333
			foreach ($config['ipsec']['tunnel'] as $tunnel) {
1334

    
1335
				unset($ph1ent);
1336
				unset($ph2ent);
1337

    
1338
				/*
1339
				 *  attempt to locate an enabled phase1
1340
				 *  entry that matches the peer gateway
1341
				 */
1342

    
1343
				if (!isset($tunnel['disabled'])) {
1344

    
1345
					$remote_gateway = $tunnel['remote-gateway'];
1346

    
1347
					foreach ($a_phase1 as $ph1tmp) {
1348
						if ($ph1tmp['remote-gateway'] == $remote_gateway) {
1349
							$ph1ent = $ph1tmp;
1350
							break;
1351
						}
1352
					}
1353
				}
1354

    
1355
				/* none found, create a new one */
1356

    
1357
				if (!isset( $ph1ent )) {
1358

    
1359
					/* build new phase1 entry */
1360

    
1361
					$ph1ent = array();
1362

    
1363
					$ph1ent['ikeid'] = ++$ikeid;
1364

    
1365
					if (isset($tunnel['disabled']))
1366
						$ph1ent['disabled'] = $tunnel['disabled'];
1367

    
1368
					$ph1ent['interface'] = $tunnel['interface'];
1369
					$ph1ent['remote-gateway'] = $tunnel['remote-gateway'];
1370
					$ph1ent['descr'] = $tunnel['descr'];
1371

    
1372
					$ph1ent['mode'] = $tunnel['p1']['mode'];
1373

    
1374
					if (isset($tunnel['p1']['myident']['myaddress']))
1375
						$ph1ent['myid_type'] = "myaddress";
1376
					if (isset($tunnel['p1']['myident']['address'])) {
1377
						$ph1ent['myid_type'] = "address";
1378
						$ph1ent['myid_data'] = $tunnel['p1']['myident']['address'];
1379
					}
1380
					if (isset($tunnel['p1']['myident']['fqdn'])) {
1381
						$ph1ent['myid_type'] = "fqdn";
1382
						$ph1ent['myid_data'] = $tunnel['p1']['myident']['fqdn'];
1383
					}
1384
					if (isset($tunnel['p1']['myident']['user_fqdn'])) {
1385
						$ph1ent['myid_type'] = "user_fqdn";
1386
						$ph1ent['myid_data'] = $tunnel['p1']['myident']['user_fqdn'];
1387
					}
1388
					if (isset($tunnel['p1']['myident']['asn1dn'])) {
1389
						$ph1ent['myid_type'] = "asn1dn";
1390
						$ph1ent['myid_data'] = $tunnel['p1']['myident']['asn1dn'];
1391
					}
1392
					if (isset($tunnel['p1']['myident']['dyn_dns'])) {
1393
						$ph1ent['myid_type'] = "dyn_dns";
1394
						$ph1ent['myid_data'] = $tunnel['p1']['myident']['dyn_dns'];
1395
					}
1396

    
1397
					$ph1ent['peerid_type'] = "peeraddress";
1398

    
1399
					switch ($tunnel['p1']['encryption-algorithm']) {
1400
					case "des":
1401
						$ph1alg = array( 'name' => 'des' );
1402
						break;
1403
					case "3des":
1404
						$ph1alg = array( 'name' => '3des' );
1405
						break;
1406
					case "blowfish":
1407
						$ph1alg = array( 'name' => 'blowfish', 'keylen' => '128'  );
1408
						break;
1409
					case "cast128":
1410
						$ph1alg = array( 'name' => 'cast128' );
1411
						break;
1412
					case "rijndael":
1413
						$ph1alg = array( 'name' => 'aes', 'keylen' => '128' );
1414
						break;
1415
					case "rijndael 256":
1416
						$ph1alg = array( 'name' => 'aes', 'keylen' => '256' );
1417
						break;
1418
					}
1419

    
1420
					$ph1ent['encryption-algorithm'] = $ph1alg;
1421
					$ph1ent['hash-algorithm'] = $tunnel['p1']['hash-algorithm'];
1422
					$ph1ent['dhgroup'] = $tunnel['p1']['dhgroup'];
1423
					$ph1ent['lifetime'] = $tunnel['p1']['lifetime'];
1424
					$ph1ent['authentication_method'] = $tunnel['p1']['authentication_method'];
1425

    
1426
					if (isset($tunnel['p1']['pre-shared-key']))
1427
						$ph1ent['pre-shared-key'] = $tunnel['p1']['pre-shared-key'];
1428
					if (isset($tunnel['p1']['cert']))
1429
						$ph1ent['cert'] = $tunnel['p1']['cert'];
1430
					if (isset($tunnel['p1']['peercert']))
1431
						$ph1ent['peercert'] = $tunnel['p1']['peercert'];
1432
					if (isset($tunnel['p1']['private-key']))
1433
						$ph1ent['private-key'] = $tunnel['p1']['private-key'];
1434

    
1435
					if (isset($tunnel['pinghost']['pinghost']))
1436
						$ph1ent['pinghost'] = $tunnel['pinghost'];
1437

    
1438
					$ph1ent['nat_traversal'] = "on";
1439
					$ph1ent['dpd_enable'] = 1;
1440
					$ph1ent['dpd_delay'] = 10;
1441
					$ph1ent['dpd_maxfail'] = 5;
1442

    
1443
					$a_phase1[] = $ph1ent;
1444
				}
1445

    
1446
				/* build new phase2 entry */
1447

    
1448
				$ph2ent = array();
1449

    
1450
				$ph2ent['ikeid'] = $ph1ent['ikeid'];
1451

    
1452
				if (isset($tunnel['disabled']))
1453
					$ph1ent['disabled'] = $tunnel['disabled'];
1454

    
1455
				$ph2ent['descr'] = "phase2 for ".$tunnel['descr'];
1456

    
1457
				$type = "lan";
1458
				if ($tunnel['local-subnet']['network'])
1459
					$type = $tunnel['local-subnet']['network'];
1460
				if ($tunnel['local-subnet']['address']) {
1461
					list($address,$netbits) = explode("/",$tunnel['local-subnet']['address']);
1462
					if (is_null($netbits))
1463
						$type = "address";
1464
					else
1465
						$type = "network";
1466
				}
1467
				
1468
				switch ($type) {
1469
					case "address":
1470
						$ph2ent['localid'] = array('type' => $type,'address' => $address);
1471
						break;
1472
					case "network":
1473
						$ph2ent['localid'] = array('type' => $type,'address' => $address,'netbits' => $netbits);
1474
						break;
1475
					default:
1476
						$ph2ent['localid'] = array('type' => $type);
1477
						break;
1478
				}
1479

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

    
1483
				$ph2ent['protocol'] = $tunnel['p2']['protocol'];
1484

    
1485
				$aes_count = 0;
1486
				foreach( $tunnel['p2']['encryption-algorithm-option'] as $tunalg ) {
1487
					$aes_found = false;
1488
					switch ($tunalg) {
1489
						case "des":
1490
							$ph2alg = array( 'name' => 'des' );
1491
							break;
1492
						case "3des":
1493
							$ph2alg = array( 'name' => '3des' );
1494
							break;
1495
						case "blowfish":
1496
							$ph2alg = array( 'name' => 'blowfish', 'keylen' => 'auto'  );
1497
							break;
1498
						case "cast128":
1499
							$ph2alg = array( 'name' => 'cast128' );
1500
							break;
1501
						case "rijndael":
1502
						case "rijndael 256":
1503
							$ph2alg = array( 'name' => 'aes', 'keylen' => 'auto' );
1504
							$aes_found = true;
1505
							$aes_count++;
1506
							break;
1507
					}
1508

    
1509
					if( !$aes_found || ($aes_count < 2))
1510
						$ph2ent['encryption-algorithm-option'][] = $ph2alg;
1511
				}
1512

    
1513
				$ph2ent['hash-algorithm-option'] = $tunnel['p2']['hash-algorithm-option'];
1514
				$ph2ent['pfsgroup'] = $tunnel['p2']['pfsgroup'];
1515
				$ph2ent['lifetime'] = $tunnel['p2']['lifetime'];
1516

    
1517
				$a_phase2[] = $ph2ent;
1518
			}
1519

    
1520
			unset($config['ipsec']['tunnel']);
1521
			$config['ipsec']['phase1'] = $a_phase1;
1522
			$config['ipsec']['phase2'] = $a_phase2;
1523
		}
1524

    
1525
		$config['version'] = "4.7";
1526
	}
1527
	
1528
	/* Convert 4.7 -> 4.8 */
1529
	if ($config['version'] <= 4.7) {
1530
		$config['dyndnses']['dyndns'] = array();
1531
		if (isset($config['dyndns']['enable'])) {
1532
			$tempdyn = array();
1533
			$tempdyn['enable'] = isset($config['dyndns']['enable']);
1534
			$tempdyn['type'] = $config['dyndns']['type'];
1535
			$tempdyn['wildcard'] = isset($config['dyndns']['wildcard']);
1536
			$tempdyn['usernamefld'] = $config['dyndns']['username'];
1537
			$tempdyn['passwordfld'] = $config['dyndns']['password'];
1538
			$tempdyn['host'] = $config['dyndns']['host'];
1539
			$tempdyn['mx'] = $config['dyndns']['mx'];		
1540
			$config['dyndnses']['dyndns'][] = $tempdyn;
1541
			unset($config['dyndns']);
1542
		}		
1543
		$config['dnsupdates']['dnsupdate'] = array();
1544
		if (isset($config['dnsupdate']['enable'])) {
1545
			$pconfig = array();
1546
			$pconfig['dnsupdate_enable'] = isset($config['dnsupdate']['enable']);
1547
			$pconfig['dnsupdate_host'] = $config['dnsupdate']['host'];
1548
			$pconfig['dnsupdate_ttl'] = $config['dnsupdate']['ttl'];
1549
			if (!$pconfig['dnsupdate_ttl'])
1550
				$pconfig['dnsupdate_ttl'] = 60;
1551
			$pconfig['dnsupdate_keydata'] = $config['dnsupdate']['keydata'];
1552
			$pconfig['dnsupdate_keyname'] = $config['dnsupdate']['keyname'];
1553
			$pconfig['dnsupdate_keytype'] = $config['dnsupdate']['keytype'];
1554
			if (!$pconfig['dnsupdate_keytype'])
1555
				$pconfig['dnsupdate_keytype'] = "zone";
1556
			$pconfig['dnsupdate_server'] = $config['dnsupdate']['server'];
1557
			$pconfig['dnsupdate_usetcp'] = isset($config['dnsupdate']['usetcp']);
1558
			$config['dnsupdates']['dnsupdate'][] = $pconfig;
1559
			unset($config['dnsupdate']);
1560
		}
1561
	
1562
		if (is_array($config['pppoe'])) {
1563
			$pconfig = array();
1564
			$pconfig['username'] = $config['pppoe']['username'];
1565
			$pconfig['password'] = $config['pppoe']['password'];
1566
			$pconfig['provider'] = $config['pppoe']['provider'];
1567
			$pconfig['ondemand'] = isset($config['pppoe']['ondemand']);
1568
			$pconfig['timeout'] = $config['pppoe']['timeout'];
1569
			unset($config['pppoe']);
1570
			$config['interfaces']['wan']['pppoe_username'] = $pconfig['username'];
1571
			$config['interfaces']['wan']['pppoe_password'] = $pconfig['password'];
1572
			$config['interfaces']['wan']['provider'] = $pconfig['provider'];
1573
			$config['interfaces']['wan']['ondemand'] = isset($pconfig['ondemand']);
1574
			$config['interfaces']['wan']['timeout'] = $pconfig['timeout'];
1575
		}
1576
		if (is_array($config['pptp'])) {
1577
			$pconfig = array();
1578
			$pconfig['username'] = $config['pptp']['username'];
1579
			$pconfig['password'] = $config['pptp']['password'];
1580
			$pconfig['provider'] = $config['pptp']['provider'];
1581
			$pconfig['ondemand'] = isset($config['pptp']['ondemand']);
1582
			$pconfig['timeout'] = $config['pptp']['timeout'];
1583
			unset($config['pptp']);
1584
			$config['interfaces']['wan']['pptp_username'] = $pconfig['username'];
1585
			$config['interfaces']['wan']['pptp_password'] = $pconfig['password'];
1586
			$config['interfaces']['wan']['provider'] = $pconfig['provider'];
1587
			$config['interfaces']['wan']['ondemand'] = isset($pconfig['ondemand'] );
1588
			$config['interfaces']['wan']['timeout'] = $pconfig['timeout'];
1589
		}
1590

    
1591
		$config['version'] = "4.8";
1592
	}
1593

    
1594
	/* Convert 4.8 -> 4.9 */
1595
	if ($config['version'] <= 4.8) {
1596

    
1597
		/* setup new all users group */
1598
		$all = array();
1599
		$all['name'] = "all";
1600
		$all['description'] = "All Users";
1601
		$all['scope'] = "system";
1602
		$all['gid'] = 1998;
1603
		$all['member'] = array();
1604

    
1605
		if (!is_array($config['system']['group']))
1606
			$config['system']['group'] = array();
1607

    
1608
		/* work around broken uid assignments */
1609
		$config['system']['nextuid'] = 2000;
1610
		foreach ($config['system']['user'] as & $user) {
1611
			if (isset($user['uid']) && !$user['uid'])
1612
				continue;
1613
			$user['uid'] = $config['system']['nextuid']++;
1614
		}
1615

    
1616
		/* work around broken gid assignments */
1617
		$config['system']['nextgid'] = 2000;
1618
		foreach ($config['system']['group'] as & $group) {
1619
			if ($group['name'] == $g['admin_group'])
1620
				$group['gid'] = 1999;
1621
			else
1622
				$group['gid'] = $config['system']['nextgid']++;
1623
		}
1624

    
1625
		/* build group membership information */
1626
		foreach ($config['system']['group'] as & $group) {
1627
			$group['member'] = array();
1628
			foreach ($config['system']['user'] as & $user) {
1629
				$groupnames = explode(",", $user['groupname']);
1630
				if (in_array($group['name'],$groupnames))
1631
					$group['member'][] = $user['uid'];
1632
			}
1633
		}
1634

    
1635
		/* reset user group information */
1636
		foreach ($config['system']['user'] as & $user) {
1637
			unset($user['groupname']);
1638
			$all['member'][] = $user['uid'];
1639
		}
1640

    
1641
		/* reset group scope information */
1642
		foreach ($config['system']['group'] as & $group)
1643
			if ($group['name'] != $g['admin_group'])
1644
				$group['scope'] = "user";
1645

    
1646
		/* insert new all group */
1647
		$groups = Array();
1648
		$groups[] = $all;
1649
		$groups = array_merge($config['system']['group'],$groups);
1650
		$config['system']['group'] = $groups;
1651

    
1652
		$config['version'] = "4.9";
1653
	}
1654

    
1655
	/* Convert 4.9 -> 5.0 */
1656
	if ($config['version'] <= 5.0) {
1657
		
1658
		/* update user privileges */
1659
		foreach ($config['system']['user'] as & $user) {
1660
			$privs = array();
1661
			if (!is_array($user['priv'])) {
1662
				unset($user['priv']);
1663
				continue;
1664
			}
1665
			foreach ($user['priv'] as $priv) {
1666
				switch($priv['id']) {
1667
					case "hasshell":
1668
						$privs[] = "user-shell-access";
1669
						break;
1670
					case "copyfiles":
1671
						$privs[] = "user-copy-files";
1672
						break;
1673
				}
1674
			}
1675
			$user['priv'] = $privs;
1676
		}
1677

    
1678
		/* update group privileges */
1679
		foreach ($config['system']['group'] as & $group) {
1680
			$privs = array();
1681
			if (!is_array($group['pages'])) {
1682
				unset($group['pages']);
1683
				continue;
1684
			}
1685
			foreach ($group['pages'] as $page) {
1686
				$priv = map_page_privname($page);
1687
				if ($priv)
1688
					$privs[] = $priv;
1689
			}
1690
			unset($group['pages']);
1691
			$group['priv'] = $privs;
1692
		}
1693

    
1694
		/* sync all local account information */
1695
		local_sync_accounts();
1696

    
1697
		$config['version'] = "5.0";
1698
	}
1699

    
1700
	/* Convert 5.0 -> 5.1 */
1701
	if ($config['version'] <= 5.1) {
1702
		$pconfig = array();
1703
		$pconfig['desc'] = "Set to 0 to disable filtering on the incoming and outgoing member interfaces.";
1704
		$pconfig['tunable'] = "net.link.bridge.pfil_member";
1705
		$pconfig['value'] = "1";
1706
		$config['sysctl']['item'][] = $pconfig;
1707
		$pconfig = array();
1708
		$pconfig['desc'] = "Set to 1 to enable filtering on the bridge interface";
1709
		$pconfig['tunable'] = "net.link.bridge.pfil_bridge";
1710
		$pconfig['value'] = "0";
1711
		$config['sysctl']['item'][] = $pconfig;
1712

    
1713
		unset($config['bridge']);
1714

    
1715
		$convert_bridges = false;
1716
		foreach($config['interfaces'] as $intf) {
1717
			if (isset($intf['bridge']) && $intf['bridge'] <> "") {
1718
				$config['bridges'] = array();
1719
				$config['bridges']['bridged'] = array();
1720
				$convert_bridges = true;
1721
				break;
1722
			}
1723
		}
1724
		if ($convert_bridges == true) {
1725
			$i = 0;
1726
			foreach ($config['interfaces'] as $ifr => &$intf) {
1727
				if (isset($intf['bridge']) && $intf['bridge'] <> "") {
1728
					$nbridge = array();
1729
					$nbridge['members'] = "{$ifr},{$intf['bridge']}";
1730
					$nbridge['descr'] = "Converted bridged {$ifr}";
1731
					$nbridge['bridgeif'] = "bridge{$i}";
1732
					$config['bridges']['bridged'][] = $nbridge;
1733
					unset($intf['bridge']);
1734
					$i++;
1735
				}
1736
			}
1737
		}
1738
		$config['version'] = "5.1";
1739
	}
1740

    
1741
	/* Convert 5.1 -> 5.2 */
1742
	if ($config['version'] <= 5.1) {
1743

    
1744
		$config['openvpn'] = array();
1745
		if (!is_array($config['system']['ca']))
1746
			$config['system']['ca'] = array();
1747
		if (!is_array($config['system']['cert']))
1748
			$config['system']['cert'] = array();
1749

    
1750
		$vpnid = 1;
1751

    
1752
		/* openvpn server configurations */
1753
		if (is_array($config['installedpackages']['openvpnserver'])) {
1754
			$config['openvpn']['openvpn-server'] = array();
1755

    
1756
			$index = 1;
1757
			foreach($config['installedpackages']['openvpnserver']['config'] as $server) {
1758

    
1759
				if (!is_array($server))
1760
					continue;
1761

    
1762
				if ($server['auth_method'] == "pki") {
1763

    
1764
					/* create ca entry */
1765
					$ca = array();
1766
					$ca['refid'] = uniqid();
1767
					$ca['name'] = "OpenVPN Server CA #{$index}";
1768
					$ca['crt'] = $server['ca_cert'];
1769
					$ca['crl'] = $server['crl'];
1770
					$config['system']['ca'][] = $ca;
1771

    
1772
					/* create ca reference */
1773
					unset($server['ca_cert']);
1774
					unset($server['crl']);
1775
					$server['caref'] = $ca['refid'];
1776

    
1777
					/* create cert entry */
1778
					$cert = array();
1779
					$cert['refid'] = uniqid();
1780
					$cert['name'] = "OpenVPN Server Certificate #{$index}";
1781
					$cert['crt'] = $server['server_cert'];
1782
					$cert['prv'] = $server['server_key'];
1783
					$config['system']['cert'][] = $cert;
1784

    
1785
					/* create cert reference */
1786
					unset($server['server_cert']);
1787
					unset($server['server_key']);
1788
					$server['certref'] = $cert['refid'];
1789

    
1790
					$index++;
1791
				}
1792

    
1793
				/* determine operational mode */
1794
				if ($server['auth_method'] == 'pki') {
1795
					if($server['nopool'])
1796
						$server['mode'] = "p2p_tls";
1797
					else
1798
						$server['mode'] = "server_tls";
1799
				} else
1800
					$server['mode'] = "p2p_shared_key";
1801
				unset($server['auth_method']);
1802

    
1803
				/* modify configuration values */
1804
				$server['dh_length'] = 1024;
1805
				unset($server['dh_params']);
1806
				if (!$server['interface'])
1807
					$server['interface'] = 'wan';
1808
				$server['tunnel_network'] = $server['addresspool'];
1809
				unset($server['addresspool']);
1810
				$server['compress'] = $server['use_lzo'];
1811
				unset($server['use_lzo']);
1812
				if ($server['nopool'])
1813
					$server['pool_enable'] = false;
1814
				else
1815
					$server['pool_enable'] = "yes";
1816
				unset($server['nopool']);
1817
				$server['dns_domain'] = $server['dhcp_domainname'];
1818
				unset($server['dhcp_domainname']);
1819
				$server['dns_server1'] = $server['dhcp_dns'];
1820
				unset($server['dhcp_dns']);
1821
				$server['ntp_server1'] = $server['dhcp_ntp'];
1822
				unset($server['dhcp_ntp']);
1823
				if ($server['dhcp_nbtdisable'])
1824
					$server['netbios_enable'] = false;
1825
				else
1826
					$server['netbios_enable'] = "yes";
1827
				unset($server['dhcp_nbtdisable']);
1828
				$server['netbios_ntype'] = $server['dhcp_nbttype'];
1829
				unset($server['dhcp_nbttype']);
1830
				$server['netbios_scope'] = $server['dhcp_nbtscope'];
1831
				unset($server['dhcp_nbtscope']);
1832
				$server['nbdd_server1'] = $server['dhcp_nbdd'];
1833
				unset($server['dhcp_nbdd']);
1834
				$server['wins_server1'] = $server['dhcp_wins'];
1835
				unset($server['dhcp_wins']);
1836

    
1837
				/* allocate vpnid */
1838
				$server['vpnid'] = $vpnid++;
1839

    
1840
				$config['openvpn']['openvpn-server'][] = $server;
1841
			}
1842
			unset($config['installedpackages']['openvpnserver']);
1843
		}
1844

    
1845
		/* openvpn client configurations */
1846
		if (is_array($config['installedpackages']['openvpnclient'])) {
1847
			$config['openvpn']['openvpn-client'] = array();
1848

    
1849
			$index = 1;
1850
			foreach($config['installedpackages']['openvpnclient']['config'] as $client) {
1851

    
1852
				if (!is_array($client))
1853
					continue;
1854

    
1855
				if ($client['auth_method'] == "pki") {
1856

    
1857
					/* create ca entry */
1858
					$ca = array();
1859
					$ca['refid'] = uniqid();
1860
					$ca['name'] = "OpenVPN Client CA #{$index}";
1861
					$ca['crt'] = $client['ca_cert'];
1862
					$ca['crl'] = $client['crl'];
1863
					$config['system']['ca'][] = $ca;
1864

    
1865
					/* create ca reference */
1866
					unset($client['ca_cert']);
1867
					unset($client['crl']);
1868
					$client['caref'] = $ca['refid'];
1869

    
1870
					/* create cert entry */
1871
					$cert = array();
1872
					$cert['refid'] = uniqid();
1873
					$cert['name'] = "OpenVPN Client Certificate #{$index}";
1874
					$cert['crt'] = $client['client_cert'];
1875
					$cert['prv'] = $client['client_key'];
1876
					$config['system']['cert'][] = $cert;
1877

    
1878
					/* create cert reference */
1879
					unset($client['client_cert']);
1880
					unset($client['client_key']);
1881
					$client['certref'] = $cert['refid'];
1882

    
1883
					$index++;
1884
				}
1885

    
1886
				/* determine operational mode */
1887
				if ($client['auth_method'] == 'pki')
1888
					$client['mode'] = "p2p_tls";
1889
				else
1890
					$client['mode'] = "p2p_shared_key";
1891
				unset($client['auth_method']);
1892

    
1893
				/* modify configuration values */
1894
				if (!$client['interface'])
1895
					$client['interface'] = 'wan';
1896
				$client['tunnel_network'] = $client['interface_ip'];
1897
				unset($client['interface_ip']);
1898
				$client['server_addr'] = $client['serveraddr'];
1899
				unset($client['serveraddr']);
1900
				$client['server_port'] = $client['serverport'];
1901
				unset($client['serverport']);
1902
				$client['proxy_addr'] = $client['poxy_hostname'];
1903
				unset($client['proxy_addr']);
1904
				$client['compress'] = $client['use_lzo'];
1905
				unset($client['use_lzo']);
1906
				$client['resolve_retry'] = $client['infiniteresolvretry'];
1907
				unset($client['infiniteresolvretry']);
1908

    
1909
				/* allocate vpnid */
1910
				$client['vpnid'] = $vpnid++;
1911

    
1912
				$config['openvpn']['openvpn-client'][] = $client;
1913
			}
1914

    
1915
			unset($config['installedpackages']['openvpnclient']);
1916
		}
1917

    
1918
		/* openvpn client specific configurations */
1919
		if (is_array($config['installedpackages']['openvpncsc'])) {
1920
			$config['openvpn']['openvpn-csc'] = array();
1921

    
1922
			foreach($config['installedpackages']['openvpncsc']['config'] as $csc) {
1923

    
1924
				if (!is_array($csc))
1925
					continue;
1926

    
1927
				/* modify configuration values */
1928
				$csc['common_name'] = $csc['commonname'];
1929
				unset($csc['commonname']);
1930
				$csc['tunnel_network'] = $csc['ifconfig_push'];
1931
				unset($csc['ifconfig_push']);
1932
				$csc['dns_domain'] = $csc['dhcp_domainname'];
1933
				unset($csc['dhcp_domainname']);
1934
				$csc['dns_server1'] = $csc['dhcp_dns'];
1935
				unset($csc['dhcp_dns']);
1936
				$csc['ntp_server1'] = $csc['dhcp_ntp'];
1937
				unset($csc['dhcp_ntp']);
1938
				if ($csc['dhcp_nbtdisable'])
1939
					$csc['netbios_enable'] = false;
1940
				else
1941
					$csc['netbios_enable'] = "yes";
1942
				unset($csc['dhcp_nbtdisable']);
1943
				$csc['netbios_ntype'] = $csc['dhcp_nbttype'];
1944
				unset($csc['dhcp_nbttype']);
1945
				$csc['netbios_scope'] = $csc['dhcp_nbtscope'];
1946
				unset($csc['dhcp_nbtscope']);
1947
				$csc['nbdd_server1'] = $csc['dhcp_nbdd'];
1948
				unset($csc['dhcp_nbdd']);
1949
				$csc['wins_server1'] = $csc['dhcp_wins'];
1950
				unset($csc['dhcp_wins']);
1951

    
1952
				$config['openvpn']['openvpn-csc'][] = $csc;
1953
			}
1954

    
1955
			unset($config['installedpackages']['openvpncsc']);
1956
		}
1957

    
1958
		/*
1959
		 * FIXME: hack to keep things working with no installedpackages
1960
		 * or carp array in the configuration data.
1961
		 */
1962
		if (!is_array($config['installedpackages']))
1963
			$config['installedpackages'] = array();
1964
		if (!is_array($config['installedpackages']['carp']))
1965
			$config['installedpackages']['carp'] = array();
1966

    
1967
		/* reconfigure openvpn services */
1968
		openvpn_resync_all();
1969

    
1970
		$config['version'] = "5.2";
1971
	}
1972

    
1973
	/* Convert 5.2 -> 5.3 */
1974
	if ($config['version'] <= 5.2) {
1975

    
1976
		if (!is_array($config['system']['ca']))
1977
			$config['system']['ca'] = array();
1978
		if (!is_array($config['system']['cert']))
1979
			$config['system']['cert'] = array();
1980

    
1981
		/* migrate advanced admin page webui ssl to certifcate mngr */
1982
		if ($config['system']['webgui']['certificate'] &&
1983
			$config['system']['webgui']['private-key']) {
1984

    
1985
			/* create cert entry */
1986
			$cert = array();
1987
			$cert['refid'] = uniqid();
1988
			$cert['name'] = "webConfigurator SSL Certificate";
1989
			$cert['crt'] = $config['system']['webgui']['certificate'];
1990
			$cert['prv'] = $config['system']['webgui']['private-key'];
1991
			$config['system']['cert'][] = $cert;
1992

    
1993
			/* create cert reference */
1994
			unset($config['system']['webgui']['certificate']);
1995
			unset($config['system']['webgui']['private-key']);
1996
			$config['system']['webgui']['ssl-certref'] = $cert['refid'];
1997
		}
1998

    
1999
		/* migrate advanced admin page ssh keys to user manager */
2000
		if ($config['system']['ssh']['authorizedkeys']) {
2001
			$admin_user =& getUserEntryByUID(0);
2002
			$admin_user['authorizedkeys'] = $config['system']['ssh']['authorizedkeys'];
2003
			unset($config['system']['ssh']['authorizedkeys']);
2004
		}
2005

    
2006
		$config['version'] = "5.3";
2007
	}
2008
	
2009
	/* Convert 5.3 -> 5.4 */
2010
	if ($config['version'] <= 5.3) {
2011
		if(is_array($config['loadbalancer']['lbpool'])) {
2012
			$lbpool_arr = $config['loadbalancer']['lbpool'];
2013
			$lbpool_srv_arr = array();
2014
			$gateway_group_arr = array();
2015
			foreach($lbpool_arr as $lbpool) {
2016
					if($lbpool['type'] == "gateway") {
2017
					$gateway_group['name'] = $lbpool['name'];
2018
					$gateway_group['descr'] = $lbpool['desc'];
2019
					$gateway_group['trigger'] = "down";
2020
					$gateway_group['item'] = array();
2021
					$i=0;
2022
					foreach($lbpool['servers'] as $member) {
2023
						$split = split("\|", $member);
2024
						$interface = $split[0];
2025
						$monitor = $split[1];
2026
						if($lbpool['behaviour'] == "failover") { $i++; }
2027
						$gateway_group['item'][] = "$interface|$i";
2028
						$config['interfaces'][$interface]['monitorip'] = "$monitor";
2029
					}
2030
					$gateway_group_arr[] = $gateway_group;
2031
				} else {
2032
					$lbpool_srv_arr[] = $lbpool;
2033
				}
2034
			}
2035
			$config['loadbalancer']['lbpool'] = $lbpool_srv_arr;
2036
			$config['gateways']['gateway_group'] = $gateway_group_arr;
2037
		}
2038
		// Unset lbpool if we no longer have any server pools
2039
		if (count($lbpool_srv_arr) == 0) {
2040
			unset($config['load_balancer']['lbpool']);
2041
		} else {
2042
			$config['load_balancer']['lbpool'] = $lbpool_srv_arr;
2043
		}
2044
		// Only set the gateway group array if we converted any
2045
		if (count($gateway_group_arr) != 0) {
2046
			$config['gateways']['gateway_group'] = $gateway_group_arr;
2047
		}
2048
		$config['version'] = "5.4";
2049
	}
2050

    
2051
	/* Convert 5.4 -> 5.5 */
2052
	if ($config['version'] <= 5.4) {
2053
		/* RRD files changed for quality, traffic and packets graphs */
2054
		ini_set("max_execution_time", "1800");
2055
		/* convert traffic RRD file */
2056
		global $parsedcfg, $listtags;
2057
		$listtags = array("ds", "v", "rra", "row");
2058

    
2059
		$rrddbpath = "/var/db/rrd/";
2060
		$rrdtool = "/usr/bin/nice -n20 /usr/local/bin/rrdtool";
2061

    
2062
		$rrdinterval = 60;
2063
		$valid = $rrdinterval * 2;
2064

    
2065
		/* Asume GigE for now */
2066
		$downstream = 125000000;
2067
		$upstream = 125000000;
2068

    
2069
		/* build a list of quality databases */
2070
		/* roundtrip has become delay */
2071
		function divide_delay($delayval) {
2072
			$delayval = floatval($delayval);
2073
			$delayval = ($delayval / 1000);
2074
			$delayval = " ". sprintf("%1.10e", $delayval) ." ";
2075
			return $delayval;
2076
		}
2077
		/* the roundtrip times need to be divided by 1000 to get seconds, really */
2078
		$databases = array();
2079
		exec("cd $rrddbpath;/usr/bin/find *-quality.rrd", $databases);
2080
		rsort($databases);
2081
		foreach($databases as $database) {
2082
			$xmldump = "{$database}.old.xml";
2083
			$xmldumpnew = "{$database}.new.xml";
2084

    
2085
			echo "Migrate RRD database {$database} to new format \n";
2086
			mwexec("$rrdtool tune {$rrddbpath}{$database} -r roundtrip:delay 2>&1");
2087

    
2088
			dump_rrd_to_xml("{$rrddbpath}/{$database}", "{$g['tmp_path']}/{$xmldump}");
2089
			$rrdold = parse_xml_config_raw("{$g['tmp_path']}/{$xmldump}", "rrd");
2090

    
2091
			$i = 0;
2092
			foreach($rrdold['rra'] as $rra) {
2093
				$l = 0;
2094
				foreach($rra['database']['row'] as $row) {
2095
					$vnew = divide_delay($row['v'][1]);
2096
					$rrdold['rra'][$i]['database']['row'][$l]['v'][1] = $vnew;
2097
					$l++;
2098
				}
2099
				$i++;
2100
			}
2101

    
2102
			$rrdxml = dump_xml_config_raw($rrdold, "rrd");
2103
			file_put_contents("{$g['tmp_path']}/{$xmldumpnew}", $rrdxml);
2104
			mwexec("$rrdtool restore -f {$g['tmp_path']}/{$xmldumpnew} {$rrddbpath}/{$database} 2>&1");
2105

    
2106
		}
2107
		/* let apinger recreate required files */
2108
		setup_gateways_monitor();
2109

    
2110
		/* build a list of traffic and packets databases */
2111
		$databases = array();
2112
		exec("cd $rrddbpath;/usr/bin/find *-traffic.rrd *-packets.rrd", $databases);
2113
		rsort($databases);
2114
		foreach($databases as $database) {
2115
			$databasetmp = "{$database}.tmp";
2116
			$xmldump = "{$database}.old.xml";
2117
			$xmldumptmp = "{$database}.tmp.xml";
2118
			$xmldumpnew = "{$database}.new.xml";
2119

    
2120
			echo "Migrate RRD database {$database} to new format \n";
2121
			/* rename DS source */
2122
			mwexec("$rrdtool tune {$rrddbpath}/{$database} -r in:inpass 2>&1");
2123
			mwexec("$rrdtool tune {$rrddbpath}/{$database} -r out:outpass 2>71");
2124

    
2125
			/* dump contents to xml and move database out of the way */
2126
			dump_rrd_to_xml("{$rrddbpath}/{$database}", "{$g['tmp_path']}/{$xmldump}");
2127

    
2128
			/* create new rrd database file */
2129
			$rrdcreate = "$rrdtool create {$g['tmp_path']}/{$databasetmp} --step $rrdinterval ";
2130
			$rrdcreate .= "DS:inpass:COUNTER:$valid:0:$downstream ";
2131
			$rrdcreate .= "DS:outpass:COUNTER:$valid:0:$upstream ";
2132
			$rrdcreate .= "DS:inblock:COUNTER:$valid:0:$downstream ";
2133
			$rrdcreate .= "DS:outblock:COUNTER:$valid:0:$upstream ";
2134
			$rrdcreate .= "RRA:AVERAGE:0.5:1:1000 ";
2135
			$rrdcreate .= "RRA:AVERAGE:0.5:5:1000 ";
2136
			$rrdcreate .= "RRA:AVERAGE:0.5:60:1000 ";
2137
			$rrdcreate .= "RRA:AVERAGE:0.5:720:3000 ";
2138

    
2139
			create_new_rrd("$rrdcreate");
2140
			/* create temporary xml from new RRD */
2141
			dump_rrd_to_xml("{$g['tmp_path']}/{$databasetmp}", "{$g['tmp_path']}/{$xmldumptmp}");
2142

    
2143
			$rrdold = parse_xml_config_raw("{$g['tmp_path']}/{$xmldump}", "rrd");
2144
			$rrdnew = parse_xml_config_raw("{$g['tmp_path']}/{$xmldumptmp}", "rrd");
2145

    
2146
			/* remove any MAX RRA's. Not needed for traffic. */
2147
			$i = 0;
2148
			foreach ($rrdold['rra'] as $rra) {
2149
				if(trim($rra['cf']) == "MAX") {
2150
					unset($rrdold['rra'][$i]);
2151
				}
2152
				$i++;
2153
			}
2154

    
2155
			$rrdxmlarray = migrate_rrd_format($rrdold, $rrdnew);
2156
			$rrdxml = dump_xml_config_raw($rrdxmlarray, "rrd");
2157
			file_put_contents("{$g['tmp_path']}/{$xmldumpnew}", $rrdxml);
2158
			mwexec("$rrdtool restore -f {$g['tmp_path']}/{$xmldumpnew} {$rrddbpath}/{$database} 2>&1");
2159
			// mwexec("$rrdtool resize {$rrddbpath}/{$database} 3 GROW 3000 2>&1");
2160

    
2161
		}
2162
		enable_rrd_graphing();
2163
		$config['version'] = "5.5";
2164
	}
2165

    
2166
	/* Convert 5.5 -> 5.6 */
2167
	if ($config['version'] <= 5.5) {
2168

    
2169
		/* migrate ipsec ca's to cert manager */
2170
		if (!is_array($config['system']['ca']))
2171
			$config['system']['ca'] = array();
2172
		if (!is_array($config['system']['cert']))
2173
			$config['system']['cert'] = array();
2174
		if (is_array($config['ipsec']['cacert'])) {
2175
			foreach($config['ipsec']['cacert'], & $cacert) {
2176
				$ca = new array();
2177
				$ca['crt'] = $cacert['cert'];
2178
				$ca['name'] = $cacert['ident'];
2179
				$config['system']['ca'][] = $ca;
2180
			}
2181
			unset($config['ipsec']['cacert']);
2182
		}
2183

    
2184
		/* migrate phase1 certificates to cert manager */
2185
		if (is_array($config['ipsec']['phase1'])) {
2186
			foreach($config['ipsec']['phase1'], & $ph1ent) {
2187
				if($ph1ent['cert'] && $ph1ent['private-key']) {
2188
					$cert = new array();
2189
					$cert['name'] = "IPsec Peer {$ph1ent['remote-gateway']} Certificate";
2190
					$cert['crt'] = $ph1ent['cert'];
2191
					$cert['prv'] = $ph1ent['private-key'];
2192
					$config['system']['cert'][] = $cert;
2193
				}
2194
				if($ph1ent['cert'])
2195
					unset($ph1ent['cert']);
2196
				if($ph1ent['private-key'])
2197
					unset($ph1ent['private-key']);
2198
				if($ph1ent['peercert'])
2199
					unset($ph1ent['peercert']);
2200
			}
2201
		}
2202

    
2203
		$config['version'] = "5.6";
2204
	}
2205

    
2206
	$now = date("H:i:s");
2207
	log_error("Ended Configuration upgrade at $now");
2208

    
2209
	if ($prev_version != $config['version'])
2210
		write_config("Upgraded config version level from {$prev_version} to {$config['version']}");
2211
}
2212

    
2213
/****f* config/write_config
2214
 * NAME
2215
 *   write_config - Backup and write the firewall configuration.
2216
 * DESCRIPTION
2217
 *   write_config() handles backing up the current configuration,
2218
 *   applying changes, and regenerating the configuration cache.
2219
 * INPUTS
2220
 *   $desc	- string containing the a description of configuration changes
2221
 *   $backup	- boolean: do not back up current configuration if false.
2222
 * RESULT
2223
 *   null
2224
 ******/
2225
/* save the system configuration */
2226
function write_config($desc="Unknown", $backup = true) {
2227
	global $config, $g;
2228

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

    
2232
	if($backup)
2233
		backup_config();
2234

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

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

    
2242
	$config['revision']['description'] = $desc;
2243
	$config['revision']['time'] = $changetime;
2244

    
2245
	config_lock();
2246

    
2247
	/* generate configuration XML */
2248
	$xmlconfig = dump_xml_config($config, $g['xml_rootobj']);
2249

    
2250
	conf_mount_rw();
2251

    
2252
	/* write new configuration */
2253
	if (!safe_write_file("{$g['cf_conf_path']}/config.xml", $xmlconfig, false)) {
2254
		die("Unable to open {$g['cf_conf_path']}/config.xml for writing in write_config()\n");
2255
	}
2256

    
2257
	if($g['platform'] == "embedded") {
2258
		cleanup_backupcache(5);
2259
	} else {
2260
		cleanup_backupcache(30);
2261
	}
2262

    
2263
	if($g['booting'] <> true) {
2264
		mwexec("sync");
2265
		conf_mount_ro();
2266
	}
2267

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

    
2271
	/* write config cache */
2272
	safe_write_file("{$g['tmp_path']}/config.cache", serialize($config), true);
2273

    
2274
	/* tell kernel to sync fs data */
2275
	mwexec("/bin/sync");
2276

    
2277
	config_unlock();
2278

    
2279
	if(is_dir("/usr/local/pkg/write_config/")) {
2280
		/* process packager manager custom rules */
2281
		update_filter_reload_status("Running plugins");
2282
		run_plugins("/usr/local/pkg/write_config/");
2283
		update_filter_reload_status("Plugins completed.");
2284
	}
2285

    
2286
	return $config;
2287
}
2288

    
2289
/****f* config/reset_factory_defaults
2290
 * NAME
2291
 *   reset_factory_defaults - Reset the system to its default configuration.
2292
 * RESULT
2293
 *   integer	- indicates completion
2294
 ******/
2295
function reset_factory_defaults() {
2296
	global $g;
2297

    
2298
	config_lock();
2299
	conf_mount_rw();
2300

    
2301
	/* create conf directory, if necessary */
2302
	safe_mkdir("{$g['cf_conf_path']}");
2303

    
2304
	/* clear out /conf */
2305
	$dh = opendir($g['conf_path']);
2306
	while ($filename = readdir($dh)) {
2307
		if (($filename != ".") && ($filename != "..")) {
2308
			unlink_if_exists($g['conf_path'] . "/" . $filename);
2309
		}
2310
	}
2311
	closedir($dh);
2312

    
2313
	/* copy default configuration */
2314
	copy("{$g['conf_default_path']}/config.xml", "{$g['conf_path']}/config.xml");
2315

    
2316
	/* call the wizard */
2317
	touch("/conf/trigger_initial_wizard");
2318

    
2319
	mwexec("sync");
2320
	conf_mount_ro();
2321
	config_unlock();
2322

    
2323
	return 0;
2324
}
2325

    
2326
function config_restore($conffile) {
2327
	global $config, $g;
2328

    
2329
	if (!file_exists($conffile))
2330
		return 1;
2331

    
2332
    config_lock();
2333
    conf_mount_rw();
2334

    
2335
    backup_config();
2336
    copy($conffile, "{$g['cf_conf_path']}/config.xml");
2337
	$config = parse_config(true);
2338
    write_config("Reverted to " . array_pop(explode("/", $conffile)) . ".", false);
2339

    
2340
	mwexec("sync");
2341
    conf_mount_ro();
2342
    config_unlock();
2343

    
2344
    return 0;
2345
}
2346

    
2347
function config_install($conffile) {
2348
	global $config, $g;
2349

    
2350
	if (!file_exists($conffile))
2351
		return 1;
2352

    
2353
	if (!config_validate("{$g['conf_path']}/config.xml"))
2354
		return 1;
2355

    
2356
	if($g['booting'] == true)
2357
		echo "Installing configuration...\n";
2358

    
2359
    config_lock();
2360
    conf_mount_rw();
2361

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

    
2364
	/* unlink cache file if it exists */
2365
	if(file_exists("{$g['tmp_path']}/config.cache"))
2366
		unlink("{$g['tmp_path']}/config.cache");
2367

    
2368
	mwexec("sync");
2369
    conf_mount_ro();
2370
    config_unlock();
2371

    
2372
    return 0;
2373
}
2374

    
2375
function config_validate($conffile) {
2376

    
2377
	global $g, $xmlerr;
2378

    
2379
	$xml_parser = xml_parser_create();
2380

    
2381
	if (!($fp = fopen($conffile, "r"))) {
2382
		$xmlerr = "XML error: unable to open file";
2383
		return false;
2384
	}
2385

    
2386
	while ($data = fread($fp, 4096)) {
2387
		if (!xml_parse($xml_parser, $data, feof($fp))) {
2388
			$xmlerr = sprintf("%s at line %d",
2389
						xml_error_string(xml_get_error_code($xml_parser)),
2390
						xml_get_current_line_number($xml_parser));
2391
			return false;
2392
		}
2393
	}
2394
	xml_parser_free($xml_parser);
2395

    
2396
	fclose($fp);
2397

    
2398
	return true;
2399
}
2400

    
2401
/*   lock configuration file, decide that the lock file
2402
 *   is stale after 10 seconds
2403
 */
2404
function config_lock($reason = "") {
2405
	global $g, $process_lock;
2406

    
2407
	/* No need to continue if we're the ones holding the lock */
2408
	if ($process_lock)
2409
		return;
2410

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

    
2413
	$n = 0;
2414
	while ($n < 10) {
2415
		/* open the lock file in append mode to avoid race condition */
2416
		if ($fd = @fopen($lockfile, "x")) {
2417
			/* succeeded */
2418
			fwrite($fd, $reason);
2419
			$process_lock = true;
2420
			fclose($fd);
2421
			return;
2422
		} else {
2423
			/* file locked, wait and try again */
2424
			$process_lock = false;
2425
			sleep(1);
2426
			$n++;
2427
		}
2428
	}
2429
}
2430

    
2431
/* unlock configuration file */
2432
function config_unlock() {
2433
	global $g, $process_lock;
2434

    
2435
	$lockfile = "{$g['varrun_path']}/config.lock";
2436
	$process_lock = false;
2437

    
2438
	unlink_if_exists($lockfile);
2439
}
2440

    
2441
function set_networking_interfaces_ports() {
2442
	global $noreboot;
2443
	global $config;
2444
	global $g;
2445
	global $fp;
2446

    
2447
	$fp = fopen('php://stdin', 'r');
2448

    
2449
	$memory = get_memory();
2450
	$avail = $memory[0];
2451

    
2452
	if($avail < $g['minimum_ram_warning']) {
2453
		echo "\n\n\n";
2454
		echo "DANGER!  WARNING!  ACHTUNG!\n\n";
2455
		echo "{$g['product_name']} requires *AT LEAST* {$g['minimum_ram_warning_text']} ram to function correctly.\n";
2456
		echo "Only ({$avail}) megs of ram has been detected.\n";
2457
		echo "\nPress ENTER to continue. ";
2458
		fgets($fp);
2459
		echo "\n";
2460
	}
2461

    
2462
	$iflist = get_interface_list();
2463

    
2464
	echo <<<EOD
2465

    
2466
Valid interfaces are:
2467

    
2468

    
2469
EOD;
2470

    
2471
	if(!is_array($iflist)) {
2472
		echo "No interfaces found!\n";
2473
	} else {
2474
		foreach ($iflist as $iface => $ifa) {
2475
			echo sprintf("% -8s%s%s\t%s\n", $iface, $ifa['mac'],
2476
				$ifa['up'] ? "   (up)" : "   (down)", $ifa['dmesg']);
2477
		}
2478
	}
2479

    
2480
	echo <<<EOD
2481

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

    
2486
Do you want to set up VLANs now [y|n]?
2487
EOD;
2488

    
2489
	if (strcasecmp(chop(fgets($fp)), "y") == 0)
2490
		vlan_setup();
2491

    
2492
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
2493

    
2494
		echo "\n\nVLAN interfaces:\n\n";
2495
		$i = 0;
2496
		foreach ($config['vlans']['vlan'] as $vlan) {
2497

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

    
2501
			$iflist['vlan' . $i] = array();
2502
			$i++;
2503
		}
2504
	}
2505

    
2506
	echo <<<EOD
2507

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

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

    
2515
If you do not know the names of your interfaces, you may choose to use
2516
auto-detection. In that case, disconnect all interfaces now before
2517
hitting 'a' to initiate auto detection.
2518

    
2519
EOD;
2520

    
2521
	do {
2522
		echo "\nEnter the WAN interface name or 'a' for auto-detection: ";
2523
		$wanif = chop(fgets($fp));
2524
		if ($wanif === "") {
2525
			return;
2526
		}
2527
		if ($wanif === "a")
2528
			$wanif = autodetect_interface("WAN", $fp);
2529
		else if (!array_key_exists($wanif, $iflist)) {
2530
			echo "\nInvalid interface name '{$wanif}'\n";
2531
			unset($wanif);
2532
			continue;
2533
		}
2534
	} while (!$wanif);
2535

    
2536
	do {
2537
		echo "\nEnter the LAN interface name or 'a' for auto-detection \n" .
2538
		    "NOTE: this enables full Firewalling/NAT mode.\n" .
2539
			"(or nothing if finished): ";
2540

    
2541
		$lanif = chop(fgets($fp));
2542
		
2543
		if($lanif == "exit") {
2544
			exit;
2545
		}
2546
		
2547
		if($lanif == "") {
2548
			if($g['minimum_nic_count'] < 2) {
2549
				break;	
2550
			} else {
2551
				fclose($fp);
2552
				return;
2553
			}
2554
		}
2555

    
2556
		if ($lanif === "a")
2557
			$lanif = autodetect_interface("LAN", $fp);
2558
		else if (!array_key_exists($lanif, $iflist)) {
2559
			echo "\nInvalid interface name '{$lanif}'\n";
2560
			unset($lanif);
2561
			continue;
2562
		}
2563
	} while (!$lanif);
2564

    
2565
	/* optional interfaces */
2566
	$i = 0;
2567
	$optif = array();
2568

    
2569
	if($lanif <> "") {
2570
		while (1) {
2571
			if ($optif[$i])
2572
				$i++;
2573
			$i1 = $i + 1;
2574
	
2575
			if($config['interfaces']['opt' . $i1]['descr'])
2576
				echo "\nOptional interface {$i1} description found: {$config['interfaces']['opt' . $i1]['descr']}";
2577

    
2578
			echo "\nEnter the Optional {$i1} interface name or 'a' for auto-detection\n" .
2579
				"(or nothing if finished): ";
2580
	
2581
			$optif[$i] = chop(fgets($fp));
2582
	
2583
			if ($optif[$i]) {
2584
				if ($optif[$i] === "a") {
2585
					$ad = autodetect_interface("Optional " . $i1, $fp);
2586
					if ($ad)
2587
						$optif[$i] = $ad;
2588
					else
2589
						unset($optif[$i]);
2590
				} else if (!array_key_exists($optif[$i], $iflist)) {
2591
					echo "\nInvalid interface name '{$optif[$i]}'\n";
2592
					unset($optif[$i]);
2593
					continue;
2594
				}
2595
			} else {
2596
				unset($optif[$i]);
2597
				break;
2598
			}
2599
		}
2600
	}
2601
	
2602
	/* check for double assignments */
2603
	$ifarr = array_merge(array($lanif, $wanif), $optif);
2604
	
2605
	for ($i = 0; $i < (count($ifarr)-1); $i++) {
2606
	for ($j = ($i+1); $j < count($ifarr); $j++) {
2607
		if ($ifarr[$i] == $ifarr[$j]) {
2608
			echo <<<EOD
2609

    
2610
Error: you cannot assign the same interface name twice!
2611

    
2612
EOD;
2613
				fclose($fp);
2614
				return;
2615
			}
2616
		}
2617
	}
2618

    
2619
	echo "\nThe interfaces will be assigned as follows: \n\n";
2620

    
2621
	if ($lanif != "")
2622
		echo "LAN  ->" . $lanif . "\n";
2623
	echo "WAN  ->" . $wanif . "\n";
2624
	for ($i = 0; $i < count($optif); $i++) {
2625
		echo "OPT" . ($i+1) . " -> " . $optif[$i] . "\n";
2626
	}
2627

    
2628
echo <<<EOD
2629

    
2630
Do you want to proceed [y|n]?
2631
EOD;
2632

    
2633
	if (strcasecmp(chop(fgets($fp)), "y") == 0) {
2634
		if($lanif) {
2635
			$config['interfaces']['lan']['if'] = $lanif;
2636
		} elseif (!$g['booting']) {
2637

    
2638
echo <<<EODD
2639

    
2640
You have chosen to remove the LAN interface.
2641

    
2642
Would you like to remove the LAN IP address and
2643
unload the interface now? [y|n]? 
2644
EODD;
2645

    
2646
				if (strcasecmp(chop(fgets($fp)), "y") == 0) {
2647
					if($config['interfaces']['lan']['if'])
2648
						mwexec("/sbin/ifconfig delete " . $config['interfaces']['lan']['if']);
2649
				}
2650
				if(isset($config['interfaces']['lan']))
2651
					unset($config['interfaces']['lan']);
2652
				if(isset($config['dhcpd']['lan']))
2653
					unset($config['dhcpd']['lan']);
2654
				if(isset($config['interfaces']['lan']['if']))
2655
					unset($config['interfaces']['lan']['if']);
2656
				if(isset($config['interfaces']['wan']['blockpriv']))
2657
					unset($config['interfaces']['wan']['blockpriv']);
2658
				if(isset($config['shaper']))
2659
					unset($config['shaper']);
2660
				if(isset($config['ezshaper']))
2661
					unset($config['ezshaper']);
2662
				if(isset($config['nat']))
2663
					unset($config['nat']);				
2664
		} else {
2665
			if(isset($config['interfaces']['lan']['if']))
2666
				mwexec("/sbin/ifconfig delete " . $config['interfaces']['lan']['if']);
2667
			if(isset($config['interfaces']['lan']))
2668
				unset($config['interfaces']['lan']);
2669
			if(isset($config['dhcpd']['lan']))
2670
				unset($config['dhcpd']['lan']);
2671
			if(isset($config['interfaces']['lan']['if']))
2672
				unset($config['interfaces']['lan']['if']);
2673
			if(isset($config['interfaces']['wan']['blockpriv']))
2674
				unset($config['interfaces']['wan']['blockpriv']);
2675
			if(isset($config['shaper']))
2676
				unset($config['shaper']);
2677
			if(isset($config['ezshaper']))
2678
				unset($config['ezshaper']);
2679
			if(isset($config['nat']))
2680
				unset($config['nat']);				
2681
		}
2682
		if (preg_match($g['wireless_regex'], $lanif)) {
2683
			if (!is_array($config['interfaces']['lan']['wireless']))
2684
				$config['interfaces']['lan']['wireless'] = array();
2685
		} else {
2686
			unset($config['interfaces']['lan']['wireless']);
2687
		}
2688

    
2689
		$config['interfaces']['wan']['if'] = $wanif;
2690
		if (preg_match($g['wireless_regex'], $wanif)) {
2691
			if (!is_array($config['interfaces']['wan']['wireless']))
2692
				$config['interfaces']['wan']['wireless'] = array();
2693
		} else {
2694
			unset($config['interfaces']['wan']['wireless']);
2695
		}
2696

    
2697
		for ($i = 0; $i < count($optif); $i++) {
2698
			if (!is_array($config['interfaces']['opt' . ($i+1)]))
2699
				$config['interfaces']['opt' . ($i+1)] = array();
2700

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

    
2703
			/* wireless interface? */
2704
			if (preg_match($g['wireless_regex'], $optif[$i])) {
2705
				if (!is_array($config['interfaces']['opt' . ($i+1)]['wireless']))
2706
					$config['interfaces']['opt' . ($i+1)]['wireless'] = array();
2707
			} else {
2708
				unset($config['interfaces']['opt' . ($i+1)]['wireless']);
2709
			}
2710

    
2711
			unset($config['interfaces']['opt' . ($i+1)]['enable']);
2712
			$config['interfaces']['opt' . ($i+1)]['descr'] = "OPT" . ($i+1);
2713
		}
2714

    
2715
		/* remove all other (old) optional interfaces */
2716
		for (; isset($config['interfaces']['opt' . ($i+1)]); $i++)
2717
			unset($config['interfaces']['opt' . ($i+1)]);
2718

    
2719
		echo "\nWriting configuration...";
2720
		write_config();
2721
		echo "done.\n";
2722

    
2723
		echo <<<EOD
2724

    
2725

    
2726

    
2727
EOD;
2728

    
2729
		fclose($fp);
2730
		if($g['booting'])
2731
			return;
2732

    
2733
		echo "One moment while we reload the settings...";
2734

    
2735
		$g['booting'] = false;
2736

    
2737
		/* resync everything */
2738
		reload_all_sync();
2739

    
2740
		echo " done!\n";
2741

    
2742
		touch("{$g['tmp_path']}/assign_complete");
2743

    
2744
	}
2745
}
2746

    
2747
function autodetect_interface($ifname, $fp) {
2748
	$iflist_prev = get_interface_list("media");
2749
	echo <<<EOD
2750

    
2751
Connect the {$ifname} interface now and make sure that the link is up.
2752
Then press ENTER to continue.
2753

    
2754
EOD;
2755
	fgets($fp);
2756
	$iflist = get_interface_list("media");
2757

    
2758
	foreach ($iflist_prev as $ifn => $ifa) {
2759
		if (!$ifa['up'] && $iflist[$ifn]['up']) {
2760
			echo "Detected link-up on interface {$ifn}.\n";
2761
			return $ifn;
2762
		}
2763
	}
2764

    
2765
	echo "No link-up detected.\n";
2766

    
2767
	return null;
2768
}
2769

    
2770
function vlan_setup() {
2771
	global $iflist, $config, $g, $fp;
2772

    
2773
	$iflist = get_interface_list();
2774

    
2775
	if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
2776

    
2777
	echo <<<EOD
2778

    
2779
WARNING: all existing VLANs will be cleared if you proceed!
2780

    
2781
Do you want to proceed [y|n]?
2782
EOD;
2783

    
2784
	if (strcasecmp(chop(fgets($fp)), "y") != 0)
2785
		return;
2786
	}
2787

    
2788
	$config['vlans']['vlan'] = array();
2789
	echo "\n";
2790

    
2791
	$vlanif = 0;
2792

    
2793
	while (1) {
2794
		$vlan = array();
2795

    
2796
		echo "\n\nVLAN Capable interfaces:\n\n";
2797
		if(!is_array($iflist)) {
2798
			echo "No interfaces found!\n";
2799
		} else {
2800
			$vlan_capable=0;
2801
			foreach ($iflist as $iface => $ifa) {
2802
				if (is_jumbo_capable($iface)) {
2803
					echo sprintf("% -8s%s%s\n", $iface, $ifa['mac'],
2804
						$ifa['up'] ? "   (up)" : "");
2805
					$vlan_capable++;
2806
				}
2807
			}
2808
		}
2809

    
2810
		if($vlan_capable == 0) {
2811
			echo "No VLAN capable interfaces detected.\n";
2812
			return;
2813
		}
2814

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

    
2818
		if ($vlan['if']) {
2819
			if (!array_key_exists($vlan['if'], $iflist) or
2820
			    !is_jumbo_capable($vlan['if'])) {
2821
				echo "\nInvalid interface name '{$vlan['if']}'\n";
2822
				continue;
2823
			}
2824
		} else {
2825
			break;
2826
		}
2827

    
2828
		echo "Enter the VLAN tag (1-4094): ";
2829
		$vlan['tag'] = chop(fgets($fp));
2830
		$vlan['vlanif'] = "vlan{$vlan['tag']}";
2831
		if (!is_numericint($vlan['tag']) || ($vlan['tag'] < 1) || ($vlan['tag'] > 4094)) {
2832
			echo "\nInvalid VLAN tag '{$vlan['tag']}'\n";
2833
			continue;
2834
		}
2835
		
2836
		$config['vlans']['vlan'][] = $vlan;
2837
		$vlanif++;
2838
	}
2839
}
2840

    
2841
function system_start_ftp_helpers() {
2842
	require_once("interfaces.inc");
2843
	global $config, $g;
2844

    
2845
	mwexec("/usr/bin/killall ftpsesame", true);
2846

    
2847
	/* if list */
2848
	$iflist = get_configured_interface_list();
2849

    
2850
	/* loop through all interfaces and handle ftp-proxy */
2851
	$interface_counter = 0;
2852
	foreach ($iflist as $ifent => $ifname) {
2853

    
2854
		if(interface_has_gateway($ifname)) {
2855
			$interface_counter++;
2856
			continue;
2857
		}
2858
		/*    if the ftp proxy is disabled for this interface then kill ftp-proxy
2859
		 *    instance and continue. note that the helpers for port forwards are
2860
		 *    launched in a  different sequence so we are filtering them out
2861
	         *    here by not including -c {$port} -g 8021 first.
2862
		 */
2863

    
2864
		/* Get the ftp queue for this interface */
2865
		if (isset($config['shaper'][$ifname]['ftpqueue']))
2866
			$shaper_queue = $config['interfaces'][$ifname]['ftpqueue'];
2867

    
2868
		$port = 8021 + $interface_counter;
2869
		if(isset($config['interfaces'][$ifname]['disableftpproxy'])) {
2870
			/*    item is disabled.  lets ++ the interface counter and
2871
			 *    keep processing interfaces. kill ftp-proxy if already
2872
			 *    running for this instance.
2873
			 */
2874
			if($g['debug'])
2875
				log_error("Config: FTP proxy disabled for interface {$ifent}");
2876

    
2877
			$helpers = array(); 
2878
			exec("/bin/ps awwux | /usr/bin/grep \"[/]ftp-proxy\" | /usr/bin/grep  \"{$port}\" | /usr/bin/awk '{ print $2 }'", $helpers);
2879
			if(count($helpers > 0)) {
2880
				mwexec("/bin/kill {$helpers[0]}");
2881
			}
2882
			$interface_counter++;
2883
		} else {
2884
			/* grab the current interface IP address */
2885
			$int = convert_friendly_interface_to_real_interface_name($ifname);
2886
			$ip = find_interface_ip($int);
2887
			/* are we in routed mode? no source nat rules and not a outside interface? */
2888
			/* If we have advanced outbound nat we skip the FTP proxy, we use ftpsesame */
2889
			if((isset($config['nat']['advancedoutbound']['enable'])) && (! interface_has_gateway($ifname))) {
2890
				$sourcenat = 0;
2891
				/* we are using advanced outbound nat, are we in routing mode? */
2892
				/* if the interface address lies within a outbound NAT source network we should skip */
2893
				if(! empty($config['nat']['advancedoutbound']['rule'])) {
2894
					foreach($config['nat']['advancedoutbound']['rule'] as $natnetwork) {
2895
						if(ip_in_subnet($ip, $natnetwork['source']['network'])) {
2896
							/* if the interface address is matched in the AON Rule we need the ftp proxy */
2897
							if(is_ipaddr($natnetwork['target']) && ($natnetwork['interface'] == "wan")) {
2898
								$pftpxsourceaddr = "-a {$natnetwork['target']}";
2899
								if($g['debug'])
2900
									log_error("Config: AON: using the external ip source {$pftpxsourceaddr} for the ftp proxy");
2901
							}
2902
							$sourcenat++;
2903
						}
2904
					}
2905
				}
2906
				if($sourcenat == 0) {
2907
					if($g['debug'])
2908
						log_error("Config: No AON rule matched for interface {$ifname} - not using FTP proxy");
2909
					mwexec("/usr/local/sbin/ftpsesame -i $int");
2910
					$interface_counter++;
2911
					continue;
2912
				} else {
2913
					if($g['debug'])
2914
						log_error("Config: AON rule matched for interface {$ifname} - using FTP proxy");
2915
				}
2916
			}
2917
			/* if ftp-proxy is already running then do not launch it again */
2918
			if($g['debug']) {
2919
				log_error("Config: FTP proxy port ($port) enabled for interface {$ifname}");
2920
			}
2921
			$helpers = array();
2922
			exec("/bin/ps awwux | /usr/bin/grep \"[/]ftp-proxy\" | /usr/bin/grep \"{$port}\" | /usr/bin/grep \"{$pftpxsourceaddr}\" | /usr/bin/awk '{ print $2 }'", $helpers);
2923
			if(!$helpers && $ip)
2924
 				mwexec("/usr/local/sbin/ftp-proxy {$shaper_queue} -p {$port} {$pftpxsourceaddr} {$ip} -T PFFTPPROXY");
2925
			if(!$ip)
2926
				mwexec("/usr/local/sbin/ftpsesame {$shaper_queue} -i $int");
2927
			$interface_counter++;
2928
		}
2929
	}
2930
	/* support bridged interfaces.  even they need ftp mojo */
2931
	if (is_array($config['bridges']['bridged']))
2932
		foreach($config['bridges']['bridged'] as $bridge) 
2933
			mwexec("/usr/local/sbin/ftpsesame {$shaper_queue} -i {$bridge['bridgeif']}");
2934
}
2935

    
2936
function cleanup_backupcache($revisions = 30) {
2937
	global $g;
2938
	$i = false;
2939
	config_lock();
2940
	if(file_exists($g['cf_conf_path'] . '/backup/backup.cache')) {
2941
		conf_mount_rw();
2942
		$backups = get_backups();
2943
		$newbaks = array();
2944
		$bakfiles = glob($g['cf_conf_path'] . "/backup/config-*");
2945
		$baktimes = $backups['versions'];
2946
		$tocache = array();
2947
		unset($backups['versions']);
2948
   		foreach($bakfiles as $backup) { // Check for backups in the directory not represented in the cache.
2949
   			if(filesize($backup) == 0) {
2950
   				unlink($backup);
2951
   				continue;
2952
   			}
2953
			$tocheck = array_shift(explode('.', array_pop(explode('-', $backup))));
2954
            if(!in_array($tocheck, $baktimes)) {
2955
				$i = true;
2956
				if($g['booting'])
2957
					echo ".";
2958
				$newxml = parse_xml_config($backup, $g['xml_rootobj']);
2959
				if($newxml == "-1") {
2960
					log_error("The backup cache file $backup is corrupted.  Unlinking.");
2961
					unlink($backup);
2962
					log_error("The backup cache file $backup is corrupted.  Unlinking.");
2963
					continue;
2964
				}
2965
				if($newxml['revision']['description'] == "")
2966
					$newxml['revision']['description'] = "Unknown";
2967
				$tocache[$tocheck] = array('description' => $newxml['revision']['description']);
2968
			}
2969
    	}
2970
		foreach($backups as $checkbak) {
2971

    
2972
			if(count(preg_grep('/' . $checkbak['time'] . '/i', $bakfiles)) != 0) {
2973
				$newbaks[] = $checkbak;
2974
			} else {
2975
				$i = true;
2976
				if($g['booting']) print " " . $tocheck . "r";
2977
			}
2978
		}
2979
		foreach($newbaks as $todo) $tocache[$todo['time']] = array('description' => $todo['description']);
2980
		if(is_int($revisions) and (count($tocache) > $revisions)) {
2981
			$toslice = array_slice(array_keys($tocache), 0, $revisions);
2982
			foreach($toslice as $sliced)
2983
				$newcache[$sliced] = $tocache[$sliced];
2984
			foreach($tocache as $version => $versioninfo) {
2985
				if(!in_array($version, array_keys($newcache))) {
2986
					unlink_if_exists($g['conf_path'] . '/backup/config-' . $version . '.xml');
2987
					if($g['booting']) print " " . $tocheck . "d";
2988
				}
2989
			}
2990
			$tocache = $newcache;
2991
		}
2992
		$bakout = fopen($g['cf_conf_path'] . '/backup/backup.cache', "w");
2993
        fwrite($bakout, serialize($tocache));
2994
		fclose($bakout);
2995
		mwexec("sync");
2996
		conf_mount_ro();
2997
	}
2998
	if($g['booting']) {
2999
		if($i) {
3000
			print "done.\n";
3001
		}
3002
	}
3003
	config_unlock();
3004
}
3005

    
3006
function get_backups() {
3007
	global $g;
3008
	if(file_exists("{$g['cf_conf_path']}/backup/backup.cache")) {
3009
		$confvers = unserialize(file_get_contents("{$g['cf_conf_path']}/backup/backup.cache"));
3010
		$bakvers = array_keys($confvers);
3011
		$toreturn = array();
3012
		sort($bakvers);
3013
		// 	$bakvers = array_reverse($bakvers);
3014
		foreach(array_reverse($bakvers) as $bakver)
3015
			$toreturn[] = array('time' => $bakver, 'description' => $confvers[$bakver]['description']);
3016
	} else {
3017
		return false;
3018
	}
3019
	$toreturn['versions'] = $bakvers;
3020
	return $toreturn;
3021
}
3022

    
3023
function backup_config() {
3024
	global $config, $g;
3025

    
3026
	if($g['platform'] == "cdrom")
3027
		return;
3028

    
3029
	conf_mount_rw();
3030

    
3031
	/* Create backup directory if needed */
3032
	safe_mkdir("{$g['cf_conf_path']}/backup");
3033

    
3034
    if($config['revision']['time'] == "") {
3035
            $baktime = 0;
3036
    } else {
3037
            $baktime = $config['revision']['time'];
3038
    }
3039
    if($config['revision']['description'] == "") {
3040
            $bakdesc = "Unknown";
3041
    } else {
3042
            $bakdesc = $config['revision']['description'];
3043
    }
3044
    copy($g['cf_conf_path'] . '/config.xml', $g['cf_conf_path'] . '/backup/config-' . $baktime . '.xml');
3045
    if(file_exists($g['cf_conf_path'] . '/backup/backup.cache')) {
3046
            $backupcache = unserialize(file_get_contents($g['cf_conf_path'] . '/backup/backup.cache'));
3047
    } else {
3048
            $backupcache = array();
3049
    }
3050
    $backupcache[$baktime] = array('description' => $bakdesc);
3051
    $bakout = fopen($g['cf_conf_path'] . '/backup/backup.cache', "w");
3052
    fwrite($bakout, serialize($backupcache));
3053
    fclose($bakout);
3054

    
3055
	mwexec("sync");
3056
	conf_mount_ro();
3057

    
3058
	return true;
3059
}
3060

    
3061
function mute_kernel_msgs() {
3062
	return;
3063
	exec("/sbin/conscontrol mute on");
3064
}
3065

    
3066
function unmute_kernel_msgs() {
3067
	exec("/sbin/conscontrol mute off");
3068
}
3069

    
3070
function start_devd() {
3071
	exec("/sbin/devd");
3072
	sleep(1);
3073
	if(file_exists("/tmp/rc.linkup"))
3074
		unlink("/tmp/rc.linkup");
3075
}
3076

    
3077
function is_interface_mismatch() {
3078
	global $config, $g;
3079

    
3080
	/* XXX: Should we process only enabled interfaces?! */
3081
	$do_assign = false;
3082
	$i = 0;
3083
	foreach ($config['interfaces'] as $ifname => $ifcfg) {
3084
		if (preg_match("/^enc|^tun|^ppp|^pptp|^pppoe|^ovpn|^gif|^gre|^lagg|^bridge|^vlan/i", $ifcfg['if'])) {
3085
			$i++;	
3086
		}
3087
		else if (does_interface_exist($ifcfg['if']) == false) {
3088
			file_notice("interfaces", "{$ifcfg['if']} is not present anymore on the system, you need to reassign interfaces or take appropriate actions.", "System", "", 2);
3089
			$do_assign = true;
3090
		} else 
3091
			$i++;
3092
	}
3093
	
3094
	if ($g['minimum_nic_count'] > $i) {
3095
		file_notice("interfaces", "Minimum allowed interfaces is set to {$g['minimum_nic_count']} but system has only {$i} interfaces!", "", "System", 2);
3096
		$do_assign = true;
3097
	} else if (file_exists("{$g['tmp_path']}/assign_complete"))
3098
		$do_assign = false;
3099

    
3100
	return $do_assign;
3101
}
3102

    
3103
function set_device_perms() {
3104
	$devices = array(
3105
		'pf'	=> array(	'user'	=> 'proxy',
3106
					'group'	=> 'proxy',
3107
					'mode'	=> 0660),
3108
		);
3109

    
3110
	foreach ($devices as $name => $attr) {
3111
		$path = "/dev/$name";
3112
		if (file_exists($path)) {
3113
			chown($path, $attr['user']);
3114
			chgrp($path, $attr['group']);
3115
			chmod($path, $attr['mode']);
3116
		}
3117
	}
3118
}
3119

    
3120
if($g['booting']) echo ".";
3121
$config = parse_config();
3122

    
3123
?>
(9-9/39)