Project

General

Profile

Download (18 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	diag_backup.php
5
	Copyright (C) 2004,2005,2006 Scott Ullrich
6
	All rights reserved.
7

    
8
	originally part of m0n0wall (http://m0n0.ch/wall)
9
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
10
	All rights reserved.
11

    
12
	Redistribution and use in source and binary forms, with or without
13
	modification, are permitted provided that the following conditions are met:
14

    
15
	1. Redistributions of source code must retain the above copyright notice,
16
	   this list of conditions and the following disclaimer.
17

    
18
	2. Redistributions in binary form must reproduce the above copyright
19
	   notice, this list of conditions and the following disclaimer in the
20
	   documentation and/or other materials provided with the distribution.
21

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

    
34
##|+PRIV
35
##|*IDENT=page-diagnostics-backup/restore
36
##|*NAME=Diagnostics: Backup/restore page
37
##|*DESCR=Allow access to the 'Diagnostics: Backup/restore' page.
38
##|*MATCH=diag_backup.php*
39
##|-PRIV
40

    
41

    
42
/* Allow additional execution time 0 = no limit. */
43
ini_set('max_execution_time', '0');
44
ini_set('max_input_time', '0');
45

    
46
/* omit no-cache headers because it confuses IE with file downloads */
47
$omit_nocacheheaders = true;
48
require("guiconfig.inc");
49

    
50
function add_base_packages_menu_items() {
51
	global $g, $config;
52
	$base_packages = split($g['base_packages'], ",");
53
	$modified_config = false;
54
	foreach($base_packages as $bp) {
55
		$basepkg_path = "/usr/local/pkg/";
56
		if(file_exists($basepkg_path . $configfile)) {
57
			$pkg_config = parse_xml_config_pkg($basepkg_path . $bp, "packagegui");
58
			if($pkg_config['menu'] != "") {
59
				if(is_array($pkg_config['menu'])) {
60
					foreach($pkg_config['menu'] as $menu) {
61
						if(is_array($config['installedpackages']['menu']))
62
							foreach($config['installedpackages']['menu'] as $amenu)
63
								if($amenu['name'] == $menu['name'])
64
									continue;
65
						$config['installedpackages']['menu'][] = $menu;
66
						$modified_config = true;
67
					}
68
				}
69
				$static_output .= "done.\n";
70
				update_output_window($static_output);
71
			}
72
		}
73
	}
74
	if($modified_config) {
75
		write_confg("Restored base_package menus after configuration restore.");
76
		$config = parse_config(true);
77
	}
78
}
79

    
80
function remove_bad_chars($string) {
81
	return preg_replace('/[^a-z|_|0-9]/i','',$string);
82
}
83

    
84
function check_and_returnif_section_exists($section) {
85
	global $config;
86
	if(is_array($config[$section]))
87
		return true;
88
	return false;
89
}
90

    
91
function spit_out_select_items($area, $showall) {
92
	global $config;
93
		
94
	$areas = array("aliases" => "Aliases", 
95
				   "captiveportal" => "Captive Portal",
96
				   "dnsmasq" => "DNS Forwarder",				
97
				   "dhcpd" => "DHCP Server",
98
				   "filter" => "Firewall Rules",
99
				   "interfaces" => "Interfaces",
100
				   "ipsec" => "IPSEC",
101
				   "nat" => "NAT",
102
				   "ovpn" => "OpenVPN",
103
				   "installedpackages" => "Package Manager",
104
				   "pptpd" => "PPTP Server",
105
				   "cron" => "Scheduled Tasks",				
106
				   "syslog" => "Syslog",
107
				   "system" => "System",
108
				   "staticroutes" => "Static routes",
109
				   "sysctl" => "System tunables",
110
				   "snmpd" => "SNMP Server",
111
				   "shaper" => "Traffic Shaper",
112
				   "vlans" => "VLANS",
113
				   "wol" => "Wake on LAN"
114
	);
115

    
116
	$select  = "<select name=\"{$area}\">\n";
117
	$select .= "<option VALUE=\"\">ALL</option>";
118

    
119
	if($showall == true) 
120
		foreach($areas as $area => $areaname)
121
			$select .= "<option value='{$area}'>{$areaname}</option>\n";
122
	else 
123
		foreach($areas as $area => $areaname)
124
			if(check_and_returnif_section_exists($area) == true)
125
				$select .= "<option value='{$area}'>{$areaname}</option>\n";
126

    
127
	$select .= "</select>\n";
128
		
129
	echo $select;
130

    
131
}
132

    
133
if ($_POST) {
134
	unset($input_errors);
135
	if (stristr($_POST['Submit'], "Restore configuration"))
136
		$mode = "restore";
137
	else if (stristr($_POST['Submit'], "Reinstall"))
138
		$mode = "reinstallpackages";
139
	else if (stristr($_POST['Submit'], "Download"))
140
		$mode = "download";
141
	else if (stristr($_POST['Submit'], "Restore version"))
142
		$mode = "restore_ver";
143

    
144
	if ($_POST["nopackages"] <> "")
145
		$options = "nopackages";
146

    
147
	if ($_POST["ver"] <> "")
148
		$ver2restore = $_POST["ver"];
149

    
150
	if ($mode) {
151

    
152
		if ($mode == "download") {
153

    
154
			if ($_POST['encrypt']) {
155
				if(!$_POST['encrypt_password'] || !$_POST['encrypt_passconf'])
156
					$input_errors[] = "You must supply and confirm the password for encryption.";
157
				if($_POST['encrypt_password'] != $_POST['encrypt_passconf'])
158
					$input_errors[] = "The supplied 'Password' and 'Confirm' field values must match.";
159
			}
160

    
161
			if (!$input_errors) {
162

    
163
				$lockbckp = lock('config');
164

    
165
				$host = "{$config['system']['hostname']}.{$config['system']['domain']}";
166
				$name = "config-{$host}-".date("YmdHis").".xml";
167
				$data = "";
168

    
169
				if($options == "nopackages") {
170
					$sfn = "/tmp/config.xml.nopkg";
171
					exec("sed '/<installedpackages>/,/<\/installedpackages>/d' /conf/config.xml > {$sfn}");
172
					$data = file_get_contents($sfn);
173
				} else {
174
					if(!$_POST['backuparea']) {
175
						/* backup entire configuration */
176
						$data = file_get_contents("{$g['conf_path']}/config.xml");
177
					} else {
178
						/* backup specific area of configuration */
179
						$data = backup_config_section($_POST['backuparea']);
180
						$name = "{$_POST['backuparea']}-{$name}";
181
					}
182
				}
183

    
184
				if ($_POST['encrypt']) {
185
					$data = encrypt_data($data, $_POST['encrypt_password']);
186
					tagfile_reformat($data, $data, "config.xml");
187
				}
188

    
189
				/* 
190
				 *  Backup RRD Data
191
				 */
192
				if(!$_POST['donotbackuprrd']) {
193
					$data = str_replace("</pfsense>", "\t<rrddata>", $data);
194
					$rrd_files_var_db_rrd = split("\n",`cd /var/db/rrd && ls *.rrd`);
195
					foreach($rrd_files_var_db_rrd as $rrd) {
196
						if($rrd) {
197
							$rrd_data = file_get_contents("{$g['vardb_path']}/rrd/{$rrd}");
198
							if($rrd_data) {
199
								$data .= "\t\t<rrddatafile>\n";
200
								$data .= "\t\t\t<filename>{$rrd}</filename>\n";
201
								$data .= "\t\t\t<data>" . base64_encode($rrd_data) . "</data>\n";
202
								$data .= "\t\t</rrddatafile>\n";
203
							}
204
						}
205
					}
206
					$data .= "\t</rrddata>\n";
207
					$data .= "</pfsense>\n";
208
				}
209
				
210
				$size = strlen($data);
211
				header("Content-Type: application/octet-stream");
212
				header("Content-Disposition: attachment; filename={$name}");
213
				header("Content-Length: $size");
214
				echo $data;
215

    
216
				unlock($lockbckp);
217
				exit;
218
			}
219
		}
220

    
221
		if ($mode == "restore") {
222

    
223
			if ($_POST['decrypt']) {
224
				if(!$_POST['decrypt_password'] || !$_POST['decrypt_passconf'])
225
					$input_errors[] = "You must supply and confirm the password for decryption.";
226
				if($_POST['decrypt_password'] != $_POST['decrypt_passconf'])
227
					$input_errors[] = "The supplied 'Password' and 'Confirm' field values must match.";
228
			}
229

    
230
			if (!$input_errors) {
231

    
232
				if (is_uploaded_file($_FILES['conffile']['tmp_name'])) {
233

    
234
					/* read the file contents */
235
					$data = file_get_contents($_FILES['conffile']['tmp_name']);
236
					if(!$data) {
237
						log_error("Warning, could not read file " . $_FILES['conffile']['tmp_name']);
238
						return 1;
239
					}
240

    
241
					if ($_POST['decrypt']) {
242
						if (!tagfile_deformat($data, $data, "config.xml")) {
243
							$input_errors[] = "The uploaded file does not appear to contain an encrypted pfsense configuration.";
244
							return 1;
245
						}
246
						$data = decrypt_data($data, $_POST['decrypt_password']);
247
					}
248

    
249
					if(stristr($data, "m0n0wall")) {
250
						log_error("Upgrading m0n0wall configuration to pfsense.");
251
						/* m0n0wall was found in config.  convert it. */
252
						$data = str_replace("m0n0wall", "pfsense", $data);
253
						$m0n0wall_upgrade = true;
254
					}
255

    
256
					if($_POST['restorearea']) {
257
						/* restore a specific area of the configuration */
258
						if(!stristr($data, $_POST['restorearea'])) {
259
							$input_errors[] = "You have selected to restore a area but we could not locate the correct xml tag.";
260
						} else {
261
							restore_config_section($_POST['restorearea'], $data);
262
							filter_configure();
263
							$savemsg = "The configuration area has been restored.  You may need to reboot the firewall.";
264
						}
265
					} else {
266
						if(!stristr($data, "<" . $g['xml_rootobj'] . ">")) {
267
							$input_errors[] = "You have selected to restore the full configuration but we could not locate a " . $g['xml_rootobj'] . " tag.";
268
						} else {
269
							/* restore the entire configuration */
270
							file_put_contents($_FILES['conffile']['tmp_name'], $data);
271
							if (config_install($_FILES['conffile']['tmp_name']) == 0) {
272
								/* this will be picked up by /index.php */
273
								conf_mount_rw();
274
								if($g['platform'] <> "cdrom")
275
									touch("/needs_package_sync");
276
								$reboot_needed = true;
277
								$savemsg = "The configuration has been restored. The firewall is now rebooting.";
278
								/* remove cache, we will force a config reboot */
279
								if(file_exists("/tmp/config.cache"))
280
									unlink("/tmp/config.cache");
281
								$config = parse_config(true);
282
								/* extract out rrd items, unset from $confgi when done */
283
								if($config['rrddata']) {
284
									foreach($config['rrddata']['rrddatafile'] as $rrd) {
285
										$rrd_fd = fopen("{$g['vardb_path']}/rrd/{$rrd['filename']}", "w");
286
										fwrite($rrd_fd, base64_decode($rrd['data']));
287
										fclose($rrd_fd);
288
									}
289
									unset($config['rrddata']);
290
									unlink_if_exists("/tmp/config.cache");
291
									write_config();
292
									add_base_packages_menu_items();
293
									convert_config();
294
									conf_mount_ro();
295
								}
296
								if($m0n0wall_upgrade == true) {
297
									if($config['system']['gateway'] <> "")
298
										$config['interfaces']['wan']['gateway'] = $config['system']['gateway'];
299
									unset($config['shaper']);
300
									/* optional if list */
301
									$ifdescrs = get_configured_interface_list(true, true);
302
									/* remove special characters from interface descriptions */
303
									if(is_array($ifdescrs))
304
										foreach($ifdescrs as $iface)
305
											$config['interfaces'][$iface]['descr'] = remove_bad_chars($config['interfaces'][$iface]['descr']);
306
									unlink_if_exists("/tmp/config.cache");
307
									write_config();
308
									add_base_packages_menu_items();									
309
									convert_config();
310
									conf_mount_ro();
311
									$savemsg = "The m0n0wall configuration has been restored and upgraded to pfSense.<p>The firewall is now rebooting.";
312
									$reboot_needed = true;
313
								}
314
								if(isset($config['captiveportal']['enable'])) {
315
									/* for some reason ipfw doesn't init correctly except on bootup sequence */
316
									$savemsg = "The configuration has been restored.<p>The firewall is now rebooting.";
317
									$reboot_needed = true;
318
								}
319
								setup_serial_port();
320
								if(is_interface_mismatch() == true) {
321
									touch("/var/run/interface_mismatch_reboot_needed");
322
									$reboot_needed = false;
323
									header("Location: interfaces_assign.php");
324
									exit;
325
								}
326
							} else {
327
								$input_errors[] = "The configuration could not be restored.";
328
							}
329
						}
330
					}
331
				} else {
332
					$input_errors[] = "The configuration could not be restored (file upload error).";
333
				}
334
			}
335
		}
336

    
337
		if ($mode == "reinstallpackages") {
338

    
339
			header("Location: pkg_mgr_install.php?mode=reinstallall");
340
			exit;
341
                } else if ($mode == "restore_ver") {
342
			$input_errors[] = "XXX - this feature may hose your config (do NOT backrev configs!) - billm";
343
			if ($ver2restore <> "") {
344
				$conf_file = "{$g['cf_conf_path']}/bak/config-" . strtotime($ver2restore) . ".xml";
345
                                if (config_install($conf_file) == 0) {
346
									$reboot_needed = true;
347
                                    $savemsg = "The configuration has been restored. The firewall is now rebooting.";
348
                                } else {
349
                                	$input_errors[] = "The configuration could not be restored.";
350
                                }
351
                        } else {
352
                                $input_errors[] = "No version selected.";
353
                        }
354
		}
355
	}
356
}
357

    
358
$id = rand() . '.' . time();
359

    
360
$mth = ini_get('upload_progress_meter.store_method');
361
$dir = ini_get('upload_progress_meter.file.filename_template');
362

    
363
$pgtitle = array("Diagnostics","Backup/restore");
364
include("head.inc");
365

    
366
?>
367

    
368
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
369
<?php include("fbegin.inc"); ?>
370
<script language="JavaScript">
371
<!--
372

    
373
function encrypt_change() {
374

    
375
	if (!document.iform.encrypt.checked)
376
		document.getElementById("encrypt_opts").style.display="none";
377
	else
378
		document.getElementById("encrypt_opts").style.display="";
379
}
380

    
381
function decrypt_change() {
382

    
383
	if (!document.iform.decrypt.checked)
384
		document.getElementById("decrypt_opts").style.display="none";
385
	else
386
		document.getElementById("decrypt_opts").style.display="";
387
}
388

    
389
//-->
390
</script>
391
<form action="diag_backup.php" method="post" name="iform" enctype="multipart/form-data">
392
<?php if ($input_errors) print_input_errors($input_errors); ?>
393
<?php if ($savemsg) print_info_box($savemsg); ?>
394
<table width="100%" border="0" cellspacing="0" cellpadding="0">
395
	<tr>
396
		<td>
397
<?php
398
		$tab_array = array();
399
		$tab_array[0] = array("Config History", false, "diag_confbak.php");
400
		$tab_array[1] = array("Backup/Restore", true, "diag_backup.php");
401
		display_top_tabs($tab_array);
402
?>
403
		</td>
404
	</tr>
405
	<tr>
406
		<td>
407
			<div id="mainarea">
408
			<table class="tabcont" align="center" width="100%" border="0" cellpadding="6" cellspacing="0">
409
				<tr>
410
					<td colspan="2" class="listtopic">Backup configuration</td>
411
				</tr>
412
				<tr>
413
					<td width="22%" valign="baseline" class="vncell">&nbsp;</td>
414
					<td width="78%" class="vtable">
415
						<p>Click this button to download the system configuration in XML format.<br /><br /> Backup area: <?php spit_out_select_items("backuparea", false); ?></p>
416
						<table>
417
							<tr>
418
								<td>
419
									<input name="nopackages" type="checkbox" class="formcheckbox" id="nopackages">
420
								</td>
421
								<td>
422
									<span class="vexpl">Do not backup package information.</span>
423
								</td>
424
							</tr>
425
						</table>
426
						<table>
427
							<tr>
428
								<td>
429
									<input name="encrypt" type="checkbox" class="formcheckbox" id="nopackages" onClick="encrypt_change()">
430
								</td>
431
								<td>
432
									<span class="vexpl">Encrypt this configuration file.</span>
433
								</td>
434
							</tr>
435
							<tr>
436
								<td>
437
									<input name="donotbackuprrd" type="checkbox" class="formcheckbox" id="dotnotbackuprrd">
438
								</td>
439
								<td>
440
									<span class="vexpl">Do not backup RRD data (NOTE: RRD Data can consume 4+ megabytes of config.xml space!)</span>
441
								</td>
442
							</tr>
443
						</table>
444
						<table id="encrypt_opts">
445
							<tr>
446
								<td>
447
									<span class="vexpl">Password :</span>
448
								</td>
449
								<td>
450
									<input name="encrypt_password" type="password" class="formfld pwd" size="20" value="" />
451
								</td>
452
							</tr>
453
							<tr>
454
								<td>
455
									<span class="vexpl">confirm :</span>
456
								</td>
457
								<td>
458
									<input name="encrypt_passconf" type="password" class="formfld pwd" size="20" value="" />
459
								</td>
460
							</tr>
461
						</table>
462
						<p><input name="Submit" type="submit" class="formbtn" id="download" value="Download configuration"></p>
463
					</td>
464
				</tr>
465
				<tr>
466
					<td colspan="2" class="list" height="12">&nbsp;</td>
467
                </tr>
468
                <tr>
469
					<td colspan="2" class="listtopic">Restore configuration</td>
470
				</tr>
471
				<tr>
472
					<td width="22%" valign="baseline" class="vncell">&nbsp;</td>
473
					<td width="78%" class="vtable">
474
						Open a <?=$g['[product_name']?> configuration XML file and click the button below to restore the configuration. <br /><br /> Restore area: <?php spit_out_select_items("restorearea", true); ?>
475
						<p><input name="conffile" type="file" class="formfld unknown" id="conffile" size="40"></p>
476
						<table>
477
							<tr>
478
								<td>
479
									<input name="decrypt" type="checkbox" class="formcheckbox" id="nopackages" onClick="decrypt_change()">
480
								</td>
481
								<td>
482
									<span class="vexpl">Configuration file is encrypted.</span>
483
								</td>
484
							</tr>
485
						</table>
486
						<table id="decrypt_opts">
487
							<tr>
488
								<td>
489
									<span class="vexpl">Password :</span>
490
								</td>
491
								<td>
492
									<input name="decrypt_password" type="password" class="formfld pwd" size="20" value="" />
493
								</td>
494
							</tr>
495
							<tr>
496
								<td>
497
									<span class="vexpl">confirm :</span>
498
								</td>
499
								<td>
500
									<input name="decrypt_passconf" type="password" class="formfld pwd" size="20" value="" />
501
								</td>
502
							</tr>
503
						</table>
504
						<p><input name="Submit" type="submit" class="formbtn" id="restore" value="Restore configuration"></p>
505
                      	<p><strong><span class="red">Note:</span></strong><br />The firewall may need a reboot after restoring the configuration.<br /></p>
506
					</td>
507
				</tr>
508
				<?php if($config['installedpackages']['package'] != "") { ?>
509
				<tr>
510
					<td colspan="2" class="list" height="12">&nbsp;</td>
511
				</tr>
512
				<tr>
513
					<td colspan="2" class="listtopic">Reinstall packages</td>
514
				</tr>
515
				<tr>
516
					<td width="22%" valign="baseline" class="vncell">&nbsp;</td>
517
					<td width="78%" class="vtable">
518
						<p>Click this button to reinstall all system packages.  This may take a while. <br /><br />
519
		  				<input name="Submit" type="submit" class="formbtn" id="reinstallpackages" value="Reinstall packages">
520
					</td>
521
				</tr>
522
				<?php } ?>
523
			</table>
524
			</div>
525
		</td>
526
	</tr>
527
</table>
528
</form>
529

    
530
<script language="JavaScript">
531
<!--
532
encrypt_change();
533
decrypt_change();
534
//-->
535
</script>
536

    
537
<?php include("fend.inc"); ?>
538
</body>
539
</html>
540

    
541
<?php
542

    
543
if($reboot_needed == true) {
544
	ob_flush();
545
	flush();
546
	sleep(5);
547
	while(file_exists("{$g['varrun_path']}/config.lock"))
548
		sleep(3);
549
	mwexec("/sbin/shutdown -r now");
550
	exit;
551
}
552

    
553
?>
(4-4/218)