Project

General

Profile

Download (10.3 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	edit.php
4
*/
5
/* ====================================================================
6
 *	Copyright (c)  2004-2015  Electric Sheep Fencing, LLC. All rights reserved.
7
 *
8
 *	Redistribution and use in source and binary forms, with or without modification,
9
 *	are permitted provided that the following conditions are met:
10
 *
11
 *	1. Redistributions of source code must retain the above copyright notice,
12
 *		this list of conditions and the following disclaimer.
13
 *
14
 *	2. Redistributions in binary form must reproduce the above copyright
15
 *		notice, this list of conditions and the following disclaimer in
16
 *		the documentation and/or other materials provided with the
17
 *		distribution.
18
 *
19
 *	3. All advertising materials mentioning features or use of this software
20
 *		must display the following acknowledgment:
21
 *		"This product includes software developed by the pfSense Project
22
 *		 for use in the pfSense software distribution. (http://www.pfsense.org/).
23
 *
24
 *	4. The names "pfSense" and "pfSense Project" must not be used to
25
 *		 endorse or promote products derived from this software without
26
 *		 prior written permission. For written permission, please contact
27
 *		 coreteam@pfsense.org.
28
 *
29
 *	5. Products derived from this software may not be called "pfSense"
30
 *		nor may "pfSense" appear in their names without prior written
31
 *		permission of the Electric Sheep Fencing, LLC.
32
 *
33
 *	6. Redistributions of any form whatsoever must retain the following
34
 *		acknowledgment:
35
 *
36
 *	"This product includes software developed by the pfSense Project
37
 *	for use in the pfSense software distribution (http://www.pfsense.org/).
38
 *
39
 *	THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
40
 *	EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41
 *	IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
42
 *	PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
43
 *	ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
44
 *	SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
45
 *	NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
46
 *	LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
47
 *	HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
48
 *	STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
49
 *	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
50
 *	OF THE POSSIBILITY OF SUCH DAMAGE.
51
 *
52
 *	====================================================================
53
 *
54
 */
55

    
56
##|+PRIV
57
##|*IDENT=page-diagnostics-edit
58
##|*NAME=Diagnostics: Edit File
59
##|*DESCR=Allow access to the 'Diagnostics: Edit File' page.
60
##|*MATCH=edit.php*
61
##|*MATCH=browser.php*
62
##|*MATCH=filebrowser/browser.php*
63
##|-PRIV
64

    
65
$pgtitle = array(gettext("Diagnostics"), gettext("Edit file"));
66
require("guiconfig.inc");
67

    
68
if ($_POST['action']) {
69
	switch ($_POST['action']) {
70
		case 'load':
71
			if (strlen($_POST['file']) < 1) {
72
				print('|5|' . '<div class="alert alert-danger" role="alert">'.gettext("No file name specified").'</div>' . '|');
73
			} elseif (is_dir($_POST['file'])) {
74
				print('|4|' . '<div class="alert alert-danger" role="alert">' . gettext("Loading a directory is not supported") .'</div>' . '|');
75
			} elseif (!is_file($_POST['file'])) {
76
				print('|3|' . '<div class="alert alert-danger" role="alert">' . gettext("File does not exist or is not a regular file") . '</div>' . '|');
77
			} else {
78
				$data = file_get_contents(urldecode($_POST['file']));
79
				if ($data === false) {
80
					print('|1|' . '<div class="alert alert-danger" role="alert">' . gettext("Failed to read file") . '</div>' . '|');
81
				} else {
82
					$data = base64_encode($data);
83
					print("|0|{$_POST['file']}|{$data}|");
84
				}
85
			}
86
			exit;
87

    
88
		case 'save':
89
			if (strlen($_POST['file']) < 1) {
90
				print('|' . '<div class="alert alert-danger" role="alert">'.gettext("No file name specified").'</div>' . '|');
91
			} else {
92
				conf_mount_rw();
93
				$_POST['data'] = str_replace("\r", "", base64_decode($_POST['data']));
94
				$ret = file_put_contents($_POST['file'], $_POST['data']);
95
				conf_mount_ro();
96
				if ($_POST['file'] == "/conf/config.xml" || $_POST['file'] == "/cf/conf/config.xml") {
97
					if (file_exists("/tmp/config.cache")) {
98
						unlink("/tmp/config.cache");
99
					}
100
					disable_security_checks();
101
				}
102
				if ($ret === false) {
103
					print('|' . '<div class="alert alert-danger" role="alert">' . gettext("Failed to write file") . '</div>' . '|');
104
				} elseif ($ret != strlen($_POST['data'])) {
105
					print('|' . '<div class="alert alert-danger" role="alert">' . gettext("Error while writing file") . '</div>' . '|');
106
				} else {
107
					print('|' . '<div class="alert alert-success" role="alert">' . gettext("File saved successfully") . '</div>' . '|');
108
				}
109
			}
110
			exit;
111
	}
112
	exit;
113
}
114

    
115
require("head.inc");
116
?>
117
<!-- file status box -->
118
<div style="display:none; background:#eeeeee;" id="fileStatusBox">
119
		<strong id="fileStatus"></strong>
120
</div>
121

    
122
<div class="panel panel-default">
123
	<div class="panel-heading"><h2 class="panel-title"><?=gettext("Save / Load a file from the filesystem")?></h2></div>
124
	<div class="panel-body">
125
		<div class="content">
126
			<form>
127
				<input type="text" class="form-control" id="fbTarget"/>
128
				<input type="button" class="btn btn-default btn-sm"	  onclick="loadFile();" value="<?=gettext('Load')?>" />
129
				<input type="button" class="btn btn-default btn-sm"	  id="fbOpen"		   value="<?=gettext('Browse')?>" />
130
				<input type="button" class="btn btn-default btn-sm"	  onclick="saveFile();" value="<?=gettext('Save')?>" />
131
			</form>
132

    
133
			<div id="fbBrowser" style="display:none; border:1px dashed gray; width:98%;"></div>
134

    
135
			<div style="background:#eeeeee;" id="fileOutput">
136
				<script type="text/javascript">
137
				//<![CDATA[
138
				window.onload=function() {
139
					document.getElementById("fileContent").wrap='off';
140
				}
141
				//]]>
142
				</script>
143
				<textarea id="fileContent" name="fileContent" class="form-control" rows="30" cols=""></textarea>
144
			</div>
145
		</div>
146
	</div>
147
</div>
148

    
149
<script type="text/javascript">
150
//<![CDATA[
151
	function loadFile() {
152
		jQuery("#fileStatus").html("");
153
		jQuery("#fileStatusBox").show(500);
154
		jQuery.ajax(
155
			"<?=$_SERVER['SCRIPT_NAME']?>", {
156
				type: "post",
157
				data: "action=load&file=" + jQuery("#fbTarget").val(),
158
				complete: loadComplete
159
			}
160
		);
161
	}
162

    
163
	function loadComplete(req) {
164
		jQuery("#fileContent").show(1000);
165
		var values = req.responseText.split("|");
166
		values.shift(); values.pop();
167

    
168
		if (values.shift() == "0") {
169
			var file = values.shift();
170
			var fileContent = window.atob(values.join("|"));
171

    
172
			jQuery("#fileContent").val(fileContent);
173
		} else {
174
			jQuery("#fileStatus").html(values[0]);
175
			jQuery("#fileContent").val("");
176
		}
177

    
178
		jQuery("#fileContent").show(1000);
179
	}
180

    
181
	function saveFile(file) {
182
		jQuery("#fileStatus").html("");
183
		jQuery("#fileStatusBox").show(500);
184

    
185
		var fileContent = Base64.encode(jQuery("#fileContent").val());
186
		fileContent = fileContent.replace(/\+/g, "%2B");
187

    
188
		jQuery.ajax(
189
			"<?=$_SERVER['SCRIPT_NAME']?>", {
190
				type: "post",
191
				data: "action=save&file=" + jQuery("#fbTarget").val() +
192
							"&data=" + fileContent,
193
				complete: function(req) {
194
					var values = req.responseText.split("|");
195
					jQuery("#fileStatus").html(values[1]);
196
				}
197
			}
198
		);
199
	}
200

    
201
/**
202
 *
203
 *	Base64 encode / decode
204
 *	http://www.webtoolkit.info/
205
 *	http://www.webtoolkit.info/licence
206
 **/
207

    
208
var Base64 = {
209

    
210
	// private property
211
	_keyStr : "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
212

    
213
	// public method for encoding
214
	encode : function (input) {
215
		var output = "";
216
		var chr1, chr2, chr3, enc1, enc2, enc3, enc4;
217
		var i = 0;
218

    
219
		input = Base64._utf8_encode(input);
220

    
221
		while (i < input.length) {
222

    
223
			chr1 = input.charCodeAt(i++);
224
			chr2 = input.charCodeAt(i++);
225
			chr3 = input.charCodeAt(i++);
226

    
227
			enc1 = chr1 >> 2;
228
			enc2 = ((chr1 & 3) << 4) | (chr2 >> 4);
229
			enc3 = ((chr2 & 15) << 2) | (chr3 >> 6);
230
			enc4 = chr3 & 63;
231

    
232
			if (isNaN(chr2)) {
233
				enc3 = enc4 = 64;
234
			} else if (isNaN(chr3)) {
235
				enc4 = 64;
236
			}
237

    
238
			output = output +
239
			this._keyStr.charAt(enc1) + this._keyStr.charAt(enc2) +
240
			this._keyStr.charAt(enc3) + this._keyStr.charAt(enc4);
241

    
242
		}
243

    
244
		return output;
245
	},
246

    
247
	// public method for decoding
248
	decode : function (input) {
249
		var output = "";
250
		var chr1, chr2, chr3;
251
		var enc1, enc2, enc3, enc4;
252
		var i = 0;
253

    
254
		input = input.replace(/[^A-Za-z0-9\+\/\=]/g, "");
255

    
256
		while (i < input.length) {
257

    
258
			enc1 = this._keyStr.indexOf(input.charAt(i++));
259
			enc2 = this._keyStr.indexOf(input.charAt(i++));
260
			enc3 = this._keyStr.indexOf(input.charAt(i++));
261
			enc4 = this._keyStr.indexOf(input.charAt(i++));
262

    
263
			chr1 = (enc1 << 2) | (enc2 >> 4);
264
			chr2 = ((enc2 & 15) << 4) | (enc3 >> 2);
265
			chr3 = ((enc3 & 3) << 6) | enc4;
266

    
267
			output = output + String.fromCharCode(chr1);
268

    
269
			if (enc3 != 64) {
270
				output = output + String.fromCharCode(chr2);
271
			}
272
			if (enc4 != 64) {
273
				output = output + String.fromCharCode(chr3);
274
			}
275

    
276
		}
277

    
278
		output = Base64._utf8_decode(output);
279

    
280
		return output;
281

    
282
	},
283

    
284
	// private method for UTF-8 encoding
285
	_utf8_encode : function (string) {
286
		string = string.replace(/\r\n/g,"\n");
287
		var utftext = "";
288

    
289
		for (var n = 0; n < string.length; n++) {
290

    
291
			var c = string.charCodeAt(n);
292

    
293
			if (c < 128) {
294
				utftext += String.fromCharCode(c);
295
			} else if ((c > 127) && (c < 2048)) {
296
				utftext += String.fromCharCode((c >> 6) | 192);
297
				utftext += String.fromCharCode((c & 63) | 128);
298
			} else {
299
				utftext += String.fromCharCode((c >> 12) | 224);
300
				utftext += String.fromCharCode(((c >> 6) & 63) | 128);
301
				utftext += String.fromCharCode((c & 63) | 128);
302
			}
303

    
304
		}
305

    
306
		return utftext;
307
	},
308

    
309
	// private method for UTF-8 decoding
310
	_utf8_decode : function (utftext) {
311
		var string = "";
312
		var i = 0;
313
		var c = c1 = c2 = 0;
314

    
315
		while (i < utftext.length) {
316

    
317
			c = utftext.charCodeAt(i);
318

    
319
			if (c < 128) {
320
				string += String.fromCharCode(c);
321
				i++;
322
			} else if ((c > 191) && (c < 224)) {
323
				c2 = utftext.charCodeAt(i+1);
324
				string += String.fromCharCode(((c & 31) << 6) | (c2 & 63));
325
				i += 2;
326
			} else {
327
				c2 = utftext.charCodeAt(i+1);
328
				c3 = utftext.charCodeAt(i+2);
329
				string += String.fromCharCode(((c & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63));
330
				i += 3;
331
			}
332

    
333
		}
334

    
335
		return string;
336
	}
337

    
338
};
339

    
340
	<?php if ($_GET['action'] == "load"): ?>
341
		events.push(function() {
342
			jQuery("#fbTarget").val("<?=htmlspecialchars($_GET['path'])?>");
343
			loadFile();
344
		});
345
	<?php endif; ?>
346
//]]>
347
</script>
348

    
349
<?php include("foot.inc");
350

    
351
outputJavaScriptFileInline("filebrowser/browser.js");
(33-33/229)