Project

General

Profile

Download (16.9 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', '3600');
44
ini_set('max_input_time', '3600');
45

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

    
50
function remove_bad_chars($string) {
51
	return preg_replace('/[^a-z|_|0-9]/i','',$string);
52
}
53

    
54
function check_and_returnif_section_exists($section) {
55
	global $config;
56
	if(is_array($config[$section]))
57
		return true;
58
	return false;
59
}
60

    
61
function spit_out_select_items($area, $showall) {
62
	global $config;
63
		
64
	$areas = array("aliases" => "Aliases", 
65
				   "captiveportal" => "Captive Portal",
66
				   "dnsmasq" => "DNS Forwarder",				
67
				   "dhcpd" => "DHCP Server",
68
				   "filter" => "Firewall Rules",
69
				   "interfaces" => "Interfaces",
70
				   "ipsec" => "IPSEC",
71
				   "nat" => "NAT",
72
				   "ovpn" => "OpenVPN",
73
				   "installedpackages" => "Package Manager",
74
				   "pptpd" => "PPTP Server",
75
				   "cron" => "Scheduled Tasks",				
76
				   "syslog" => "Syslog",
77
				   "system" => "System",
78
				   "staticroutes" => "Static routes",
79
				   "sysctl" => "System tunables",
80
				   "snmpd" => "SNMP Server",
81
				   "shaper" => "Traffic Shaper",
82
				   "vlans" => "VLANS",
83
				   "wol" => "Wake on LAN"
84
	);
85

    
86
	$select  = "<select name=\"{$area}\">\n";
87
	$select .= "<option VALUE=\"\">ALL</option>";
88

    
89
	if($showall == true) 
90
		foreach($areas as $area => $areaname)
91
			$select .= "<option value='{$area}'>{$areaname}</option>\n";
92
	else 
93
		foreach($areas as $area => $areaname)
94
			if(check_and_returnif_section_exists($area) == true)
95
				$select .= "<option value='{$area}'>{$areaname}</option>\n";
96

    
97
	$select .= "</select>\n";
98
		
99
	echo $select;
100

    
101
}
102

    
103
if ($_POST) {
104
	unset($input_errors);
105
	if (stristr($_POST['Submit'], "Restore configuration"))
106
		$mode = "restore";
107
	else if (stristr($_POST['Submit'], "Reinstall"))
108
		$mode = "reinstallpackages";
109
	else if (stristr($_POST['Submit'], "Download"))
110
		$mode = "download";
111
	else if (stristr($_POST['Submit'], "Restore version"))
112
		$mode = "restore_ver";
113

    
114
	if ($_POST["nopackages"] <> "")
115
		$options = "nopackages";
116

    
117
	if ($_POST["ver"] <> "")
118
		$ver2restore = $_POST["ver"];
119

    
120
	if ($mode) {
121

    
122
		if ($mode == "download") {
123

    
124
			if ($_POST['encrypt']) {
125
				if(!$_POST['encrypt_password'] || !$_POST['encrypt_passconf'])
126
					$input_errors[] = "You must supply and confirm the password for encryption.";
127
				if($_POST['encrypt_password'] != $_POST['encrypt_passconf'])
128
					$input_errors[] = "The supplied 'Password' and 'Confirm' field values must match.";
129
			}
130

    
131
			if (!$input_errors) {
132

    
133
				config_lock();
134

    
135
				$host = "{$config['system']['hostname']}.{$config['system']['domain']}";
136
				$name = "config-{$host}-".date("YmdHis").".xml";
137
				$data = "";
138

    
139
				if($options == "nopackages") {
140
					$sfn = "/tmp/config.xml.nopkg";
141
					exec("sed '/<installedpackages>/,/<\/installedpackages>/d' /conf/config.xml > {$sfn}");
142
					$data = file_get_contents($sfn);
143
				} else {
144
					if(!$_POST['backuparea']) {
145
						/* backup entire configuration */
146
						$data = file_get_contents("{$g['conf_path']}/config.xml");
147
					} else {
148
						/* backup specific area of configuration */
149
						$data = backup_config_section($_POST['backuparea']);
150
						$name = "{$_POST['backuparea']}-{$name}";
151
					}
152
				}
153

    
154
				if ($_POST['encrypt']) {
155
					$data = encrypt_data($data, $_POST['encrypt_password']);
156
					tagfile_reformat($data, $data, "config.xml");
157
				}
158

    
159
				/* 
160
				 *  Backup RRD Data
161
				 */
162
				if(!$_POST['donotbackuprrd']) {
163
					$data = str_replace("</pfsense>", "\t<rrddata>", $data);
164
					$rrd_files_var_db_rrd = split("\n",`cd /var/db/rrd && ls *.rrd`);
165
					foreach($rrd_files_var_db_rrd as $rrd) {
166
						if($rrd) {
167
							$rrd_data = file_get_contents("{$g['vardb_path']}/rrd/{$rrd}");
168
							if($rrd_data) {
169
								$data .= "\t\t<rrddatafile>\n";
170
								$data .= "\t\t\t<filename>{$rrd}</filename>\n";
171
								$data .= "\t\t\t<data>" . base64_encode($rrd_data) . "</data>\n";
172
								$data .= "\t\t</rrddatafile>\n";
173
							}
174
						}
175
					}
176
					$data .= "\t</rrddata>\n";
177
					$data .= "</pfsense>\n";
178
				}
179
				
180
				$size = strlen($data);
181
				header("Content-Type: application/octet-stream");
182
				header("Content-Disposition: attachment; filename={$name}");
183
				header("Content-Length: $size");
184
				echo $data;
185

    
186
				config_unlock();
187
				exit;
188
			}
189
		}
190

    
191
		if ($mode == "restore") {
192

    
193
			if ($_POST['decrypt']) {
194
				if(!$_POST['decrypt_password'] || !$_POST['decrypt_passconf'])
195
					$input_errors[] = "You must supply and confirm the password for decryption.";
196
				if($_POST['decrypt_password'] != $_POST['decrypt_passconf'])
197
					$input_errors[] = "The supplied 'Password' and 'Confirm' field values must match.";
198
			}
199

    
200
			if (!$input_errors) {
201

    
202
				if (is_uploaded_file($_FILES['conffile']['tmp_name'])) {
203

    
204
					/* read the file contents */
205
					$data = file_get_contents($_FILES['conffile']['tmp_name']);
206
					if(!$data) {
207
						log_error("Warning, could not read file " . $_FILES['conffile']['tmp_name']);
208
						return 1;
209
					}
210

    
211
					if ($_POST['decrypt']) {
212
						if (!tagfile_deformat($data, $data, "config.xml")) {
213
							$input_errors[] = "The uploaded file does not appear to contain an encrypted pfsense configuration.";
214
							return 1;
215
						}
216
						$data = decrypt_data($data, $_POST['decrypt_password']);
217
					}
218

    
219
					if(stristr($data, "m0n0wall")) {
220
						log_error("Upgrading m0n0wall configuration to pfsense.");
221
						/* m0n0wall was found in config.  convert it. */
222
						$data = str_replace("m0n0wall", "pfsense", $data);
223
						$m0n0wall_upgrade = true;
224
					}
225

    
226
					if($_POST['restorearea']) {
227
						/* restore a specific area of the configuration */
228
						if(!stristr($data, $_POST['restorearea'])) {
229
							$input_errors[] = "You have selected to restore a area but we could not locate the correct xml tag.";
230
						} else {
231
							restore_config_section($_POST['restorearea'], $data);
232
							filter_configure();
233
							$savemsg = "The configuration area has been restored.  You may need to reboot the firewall.";
234
						}
235
					} else {
236
						if(!stristr($data, "<pfsense>")) {
237
							$input_errors[] = "You have selected to restore the full configuration but we could not locate a pfsense tag.";
238
						} else {
239
							/* restore the entire configuration */
240
							file_put_contents($_FILES['conffile']['tmp_name'], $data);
241
							if (config_install($_FILES['conffile']['tmp_name']) == 0) {
242
								/* this will be picked up by /index.php */
243
								conf_mount_rw();
244
								if($g['platform'] <> "cdrom")
245
									touch("/needs_package_sync");
246
								$reboot_needed = true;
247
								$savemsg = "The configuration has been restored. The firewall is now rebooting.";
248
								/* remove cache, we will force a config reboot */
249
								if(file_exists("/tmp/config.cache"))
250
									unlink("/tmp/config.cache");
251
								$config = parse_config(true);
252
								/* extract out rrd items, unset from $confgi when done */
253
								if($config['rrddata']) {
254
									foreach($config['rrddata']['rrddatafile'] as $rrd) {
255
										$rrd_fd = fopen("{$g['vardb_path']}/rrd/{$rrd['filename']}", "w");
256
										fwrite($rrd_fd, base64_decode($rrd['data']));
257
										fclose($rrd_fd);
258
									}
259
									unset($config['rrddata']);
260
									unlink_if_exists("/tmp/config.cache");
261
									write_config();
262
									conf_mount_ro();
263
								}
264
								if($m0n0wall_upgrade == true) {
265
									if($config['system']['gateway'] <> "")
266
										$config['interfaces']['wan']['gateway'] = $config['system']['gateway'];
267
									unset($config['shaper']);
268
									/* optional if list */
269
									$ifdescrs = get_configured_interface_list(true, true);
270
									/* remove special characters from interface descriptions */
271
									if(is_array($ifdescrs))
272
										foreach($ifdescrs as $iface)
273
											$config['interfaces'][$iface]['descr'] = remove_bad_chars($config['interfaces'][$iface]['descr']);
274
									unlink_if_exists("/tmp/config.cache");
275
									write_config();
276
									conf_mount_ro();
277
									$savemsg = "The m0n0wall configuration has been restored and upgraded to pfSense.<p>The firewall is now rebooting.";
278
									$reboot_needed = true;
279
								}
280
								if(isset($config['captiveportal']['enable'])) {
281
									/* for some reason ipfw doesn't init correctly except on bootup sequence */
282
									$savemsg = "The configuration has been restored.<p>The firewall is now rebooting.";
283
									$reboot_needed = true;
284
								}
285
								setup_serial_port();
286
								if(is_interface_mismatch() == true) {
287
									touch("/var/run/interface_mismatch_reboot_needed");
288
									$reboot_needed = false;
289
									header("Location: interfaces_assign.php");
290
									exit;
291
								}
292
							} else {
293
								$input_errors[] = "The configuration could not be restored.";
294
							}
295
						}
296
					}
297
				} else {
298
					$input_errors[] = "The configuration could not be restored (file upload error).";
299
				}
300
			}
301
		}
302

    
303
		if ($mode == "reinstallpackages") {
304

    
305
			header("Location: pkg_mgr_install.php?mode=reinstallall");
306
			exit;
307
                } else if ($mode == "restore_ver") {
308
			$input_errors[] = "XXX - this feature may hose your config (do NOT backrev configs!) - billm";
309
			if ($ver2restore <> "") {
310
				$conf_file = "{$g['cf_conf_path']}/bak/config-" . strtotime($ver2restore) . ".xml";
311
                                if (config_install($conf_file) == 0) {
312
									$reboot_needed = true;
313
                                    $savemsg = "The configuration has been restored. The firewall is now rebooting.";
314
                                } else {
315
                                	$input_errors[] = "The configuration could not be restored.";
316
                                }
317
                        } else {
318
                                $input_errors[] = "No version selected.";
319
                        }
320
		}
321
	}
322
}
323

    
324
$id = rand() . '.' . time();
325

    
326
$mth = ini_get('upload_progress_meter.store_method');
327
$dir = ini_get('upload_progress_meter.file.filename_template');
328

    
329
$pgtitle = array("Diagnostics","Backup/restore");
330
include("head.inc");
331

    
332
?>
333

    
334
<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
335
<?php include("fbegin.inc"); ?>
336
<script language="JavaScript">
337
<!--
338

    
339
function encrypt_change() {
340

    
341
	if (!document.iform.encrypt.checked)
342
		document.getElementById("encrypt_opts").style.display="none";
343
	else
344
		document.getElementById("encrypt_opts").style.display="";
345
}
346

    
347
function decrypt_change() {
348

    
349
	if (!document.iform.decrypt.checked)
350
		document.getElementById("decrypt_opts").style.display="none";
351
	else
352
		document.getElementById("decrypt_opts").style.display="";
353
}
354

    
355
//-->
356
</script>
357
<form action="diag_backup.php" method="post" name="iform" enctype="multipart/form-data">
358
<?php if ($input_errors) print_input_errors($input_errors); ?>
359
<?php if ($savemsg) print_info_box($savemsg); ?>
360
<table width="100%" border="0" cellspacing="0" cellpadding="0">
361
	<tr>
362
		<td>
363
<?php
364
		$tab_array = array();
365
		$tab_array[0] = array("Config History", false, "diag_confbak.php");
366
		$tab_array[1] = array("Backup/Restore", true, "diag_backup.php");
367
		display_top_tabs($tab_array);
368
?>
369
		</td>
370
	</tr>
371
	<tr>
372
		<td>
373
			<div id="mainarea">
374
			<table class="tabcont" align="center" width="100%" border="0" cellpadding="6" cellspacing="0">
375
				<tr>
376
					<td colspan="2" class="listtopic">Backup configuration</td>
377
				</tr>
378
				<tr>
379
					<td width="22%" valign="baseline" class="vncell">&nbsp;</td>
380
					<td width="78%" class="vtable">
381
						<p>Click this button to download the system configuration in XML format.<br /><br /> Backup area: <?php spit_out_select_items("backuparea", false); ?></p>
382
						<table>
383
							<tr>
384
								<td>
385
									<input name="nopackages" type="checkbox" class="formcheckbox" id="nopackages">
386
								</td>
387
								<td>
388
									<span class="vexpl">Do not backup package information.</span>
389
								</td>
390
							</tr>
391
						</table>
392
						<table>
393
							<tr>
394
								<td>
395
									<input name="encrypt" type="checkbox" class="formcheckbox" id="nopackages" onClick="encrypt_change()">
396
								</td>
397
								<td>
398
									<span class="vexpl">Encrypt this configuration file.</span>
399
								</td>
400
							</tr>
401
							<tr>
402
								<td>
403
									<input name="donotbackuprrd" type="checkbox" class="formcheckbox" id="dotnotbackuprrd">
404
								</td>
405
								<td>
406
									<span class="vexpl">Do not backup RRD data (NOTE: RRD Data can consume 4+ megabytes of config.xml space!)</span>
407
								</td>
408
							</tr>
409
						</table>
410
						<table id="encrypt_opts">
411
							<tr>
412
								<td>
413
									<span class="vexpl">Password :</span>
414
								</td>
415
								<td>
416
									<input name="encrypt_password" type="password" class="formfld pwd" size="20" value="" />
417
								</td>
418
							</tr>
419
							<tr>
420
								<td>
421
									<span class="vexpl">confirm :</span>
422
								</td>
423
								<td>
424
									<input name="encrypt_passconf" type="password" class="formfld pwd" size="20" value="" />
425
								</td>
426
							</tr>
427
						</table>
428
						<p><input name="Submit" type="submit" class="formbtn" id="download" value="Download configuration"></p>
429
					</td>
430
				</tr>
431
				<tr>
432
					<td colspan="2" class="list" height="12">&nbsp;</td>
433
                </tr>
434
                <tr>
435
					<td colspan="2" class="listtopic">Restore configuration</td>
436
				</tr>
437
				<tr>
438
					<td width="22%" valign="baseline" class="vncell">&nbsp;</td>
439
					<td width="78%" class="vtable">
440
						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); ?>
441
						<p><input name="conffile" type="file" class="formfld unknown" id="conffile" size="40"></p>
442
						<table>
443
							<tr>
444
								<td>
445
									<input name="decrypt" type="checkbox" class="formcheckbox" id="nopackages" onClick="decrypt_change()">
446
								</td>
447
								<td>
448
									<span class="vexpl">Configuration file is encrypted.</span>
449
								</td>
450
							</tr>
451
						</table>
452
						<table id="decrypt_opts">
453
							<tr>
454
								<td>
455
									<span class="vexpl">Password :</span>
456
								</td>
457
								<td>
458
									<input name="decrypt_password" type="password" class="formfld pwd" size="20" value="" />
459
								</td>
460
							</tr>
461
							<tr>
462
								<td>
463
									<span class="vexpl">confirm :</span>
464
								</td>
465
								<td>
466
									<input name="decrypt_passconf" type="password" class="formfld pwd" size="20" value="" />
467
								</td>
468
							</tr>
469
						</table>
470
						<p><input name="Submit" type="submit" class="formbtn" id="restore" value="Restore configuration"></p>
471
                      	<p><strong><span class="red">Note:</span></strong><br />The firewall may need a reboot after restoring the configuration.<br /></p>
472
					</td>
473
				</tr>
474
				<?php if($config['installedpackages']['package'] != "") { ?>
475
				<tr>
476
					<td colspan="2" class="list" height="12">&nbsp;</td>
477
				</tr>
478
				<tr>
479
					<td colspan="2" class="listtopic">Reinstall packages</td>
480
				</tr>
481
				<tr>
482
					<td width="22%" valign="baseline" class="vncell">&nbsp;</td>
483
					<td width="78%" class="vtable">
484
						<p>Click this button to reinstall all system packages.  This may take a while. <br /><br />
485
		  				<input name="Submit" type="submit" class="formbtn" id="reinstallpackages" value="Reinstall packages">
486
					</td>
487
				</tr>
488
				<?php } ?>
489
			</table>
490
			</div>
491
		</td>
492
	</tr>
493
</table>
494
</form>
495

    
496
<script language="JavaScript">
497
<!--
498
encrypt_change();
499
decrypt_change();
500
//-->
501
</script>
502

    
503
<?php include("fend.inc"); ?>
504
</body>
505
</html>
506

    
507
<?php
508

    
509
if($reboot_needed == true) {
510
	ob_flush();
511
	flush();
512
	sleep(5);
513
	while(file_exists("{$g['varrun_path']}/config.lock"))
514
		sleep(3);
515
	mwexec("/sbin/shutdown -r now");
516
	exit;
517
}
518

    
519
?>
(5-5/216)