Project

General

Profile

Download (11.1 KB) Statistics
| Branch: | Tag: | Revision:
1 5b237745 Scott Ullrich
<?php
2
/*
3 8acd654a Renato Botelho
 * xmlparse.inc
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6 2a2396a6 Renato Botelho
 * Copyright (c) 2004-2016 Rubicon Communications, LLC (Netgate)
7 8acd654a Renato Botelho
 * All rights reserved.
8
 *
9
 * originally part of m0n0wall (http://m0n0.ch/wall)
10 aaec5634 Renato Botelho
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
11 8acd654a Renato Botelho
 * All rights reserved.
12
 *
13
 * Redistribution and use in source and binary forms, with or without
14
 * modification, are permitted provided that the following conditions are met:
15
 *
16
 * 1. Redistributions of source code must retain the above copyright notice,
17
 *    this list of conditions and the following disclaimer.
18
 *
19
 * 2. Redistributions in binary form must reproduce the above copyright
20
 *    notice, this list of conditions and the following disclaimer in
21
 *    the documentation and/or other materials provided with the
22
 *    distribution.
23
 *
24
 * 3. All advertising materials mentioning features or use of this software
25
 *    must display the following acknowledgment:
26
 *    "This product includes software developed by the pfSense Project
27
 *    for use in the pfSense® software distribution. (http://www.pfsense.org/).
28
 *
29
 * 4. The names "pfSense" and "pfSense Project" must not be used to
30
 *    endorse or promote products derived from this software without
31
 *    prior written permission. For written permission, please contact
32
 *    coreteam@pfsense.org.
33
 *
34
 * 5. Products derived from this software may not be called "pfSense"
35
 *    nor may "pfSense" appear in their names without prior written
36
 *    permission of the Electric Sheep Fencing, LLC.
37
 *
38
 * 6. Redistributions of any form whatsoever must retain the following
39
 *    acknowledgment:
40
 *
41
 * "This product includes software developed by the pfSense Project
42
 * for use in the pfSense software distribution (http://www.pfsense.org/).
43
 *
44
 * THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
45
 * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
47
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE pfSense PROJECT OR
48
 * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
49
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
50
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
51
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
52
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
53
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
54
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
55
 * OF THE POSSIBILITY OF SUCH DAMAGE.
56
 */
57 5b237745 Scott Ullrich
58 2e5ebf5d Scott Ullrich
/* The following items will be treated as arrays in config.xml */
59 eeb6c16e Bill Marquette
function listtags() {
60 72a8c829 Ermal
	/*
61
	 * Please keep this list alpha sorted and no longer than 80 characters
62
	 * I know it's a pain, but it's a pain to find stuff too if it's not
63
	 */
64
	$ret = array(
65 79262830 Phil Davis
		'acls', 'alias', 'aliasurl', 'allowedip', 'allowedhostname', 'authserver',
66
		'bridged', 'build_port_path',
67
		'ca', 'cacert', 'cert', 'crl', 'clone', 'config', 'container', 'columnitem',
68 b89bc607 Phil Davis
		'checkipservice',
69 79262830 Phil Davis
		'depends_on_package', 'disk', 'dnsserver', 'dnsupdate', 'domainoverrides', 'dyndns',
70
		'earlyshellcmd', 'element', 'encryption-algorithm-option',
71
		'field', 'fieldname',
72
		'gateway_item', 'gateway_group', 'gif', 'gre', 'group',
73 f3d9f32b NOYB
		'hash-algorithm-option', 'hosts', 'ifgroupentry', 'igmpentry', 'interface_array', 'item', 'key',
74 79262830 Phil Davis
		'lagg', 'lbaction', 'lbpool', 'l7rules', 'lbprotocol',
75
		'member', 'menu', 'tab', 'mobilekey', 'monitor_type', 'mount',
76 72a8c829 Ermal
		'npt', 'ntpserver',
77 79262830 Phil Davis
		'onetoone', 'openvpn-server', 'openvpn-client', 'openvpn-csc', 'option',
78
		'package', 'passthrumac', 'phase1', 'phase2', 'ppp', 'pppoe', 'priv', 'proxyarpnet', 'pool',
79 72a8c829 Ermal
		'qinqentry', 'queue',
80 79262830 Phil Davis
		'pages', 'pipe', 'radnsserver', 'roll', 'route', 'row', 'rrddatafile', 'rule',
81 72a8c829 Ermal
		'schedule', 'service', 'servernat', 'servers',
82 79262830 Phil Davis
		'serversdisabled', 'shellcmd', 'staticmap', 'subqueue',
83 72a8c829 Ermal
		'timerange', 'tunnel', 'user', 'vip', 'virtual_server', 'vlan',
84
		'winsserver', 'wolentry', 'widget'
85
	);
86 6d84c956 Ermal
	return array_flip($ret);
87 eeb6c16e Bill Marquette
}
88
89 79262830 Phil Davis
/* Package XML tags that should be treated as a list not as a traditional array */
90 eeb6c16e Bill Marquette
function listtags_pkg() {
91 72a8c829 Ermal
	$ret = array('build_port_path', 'depends_on_package', 'onetoone', 'queue', 'rule', 'servernat', 'alias', 'additional_files_needed', 'tab', 'template', 'menu', 'rowhelperfield', 'service', 'step', 'package', 'columnitem', 'option', 'item', 'field', 'package', 'file');
92 eeb6c16e Bill Marquette
93 1c62178a Ermal
	return array_flip($ret);
94 eeb6c16e Bill Marquette
}
95
96 26433cb8 Scott Ullrich
function startElement($parser, $name, $attrs) {
97 1fb064e8 Erik Fonnesbeck
	global $parsedcfg, $depth, $curpath, $havedata, $listtags;
98 528ae96e Scott Ullrich
99 26433cb8 Scott Ullrich
	array_push($curpath, strtolower($name));
100
101
	$ptr =& $parsedcfg;
102
	foreach ($curpath as $path) {
103
		$ptr =& $ptr[$path];
104
	}
105
106
	/* is it an element that belongs to a list? */
107 6d84c956 Ermal
	if (isset($listtags[strtolower($name)])) {
108 26433cb8 Scott Ullrich
109
		/* is there an array already? */
110
		if (!is_array($ptr)) {
111
			/* make an array */
112
			$ptr = array();
113
		}
114
115
		array_push($curpath, count($ptr));
116
117
	} else if (isset($ptr)) {
118
		/* multiple entries not allowed for this element, bail out */
119 addc0439 Renato Botelho
		die(sprintf(gettext('XML error: %1$s at line %2$d cannot occur more than once') . "\n",
120 79262830 Phil Davis
		    $name,
121
		    xml_get_current_line_number($parser)));
122 26433cb8 Scott Ullrich
	}
123
124
	$depth++;
125
	$havedata = $depth;
126
}
127
128
function endElement($parser, $name) {
129
	global $depth, $curpath, $parsedcfg, $havedata, $listtags;
130
131
	if ($havedata == $depth) {
132
		$ptr =& $parsedcfg;
133
		foreach ($curpath as $path) {
134
			$ptr =& $ptr[$path];
135
		}
136
		$ptr = "";
137
	}
138
139
	array_pop($curpath);
140
141 79262830 Phil Davis
	if (isset($listtags[strtolower($name)])) {
142 26433cb8 Scott Ullrich
		array_pop($curpath);
143 79262830 Phil Davis
	}
144 26433cb8 Scott Ullrich
145
	$depth--;
146
}
147
148
function cData($parser, $data) {
149
	global $depth, $curpath, $parsedcfg, $havedata;
150
151
	$data = trim($data, "\t\n\r");
152
153
	if ($data != "") {
154
		$ptr =& $parsedcfg;
155
		foreach ($curpath as $path) {
156
			$ptr =& $ptr[$path];
157
		}
158
159
		if (is_string($ptr)) {
160 2e6a43a1 Ermal
			$ptr .= html_entity_decode($data);
161 26433cb8 Scott Ullrich
		} else {
162
			if (trim($data, " ") != "") {
163 2e6a43a1 Ermal
				$ptr = html_entity_decode($data);
164 26433cb8 Scott Ullrich
				$havedata++;
165
			}
166
		}
167
	}
168 5b237745 Scott Ullrich
}
169
170 48ca2dc9 Colin Smith
function parse_xml_config($cffile, $rootobj, $isstring = "false") {
171 cb980a2f Colin Smith
	global $listtags;
172 eeb6c16e Bill Marquette
	$listtags = listtags();
173 79262830 Phil Davis
	if (isset($GLOBALS['custom_listtags'])) {
174
		foreach ($GLOBALS['custom_listtags'] as $tag) {
175
			$listtags[$tag] = $tag;
176
		}
177
	}
178 26433cb8 Scott Ullrich
	return parse_xml_config_raw($cffile, $rootobj, $isstring);
179 cb980a2f Colin Smith
}
180
181 48ca2dc9 Colin Smith
function parse_xml_config_pkg($cffile, $rootobj, $isstring = "false") {
182 cb980a2f Colin Smith
	global $listtags;
183 eeb6c16e Bill Marquette
	$listtags = listtags_pkg();
184 79262830 Phil Davis
	if (isset($GLOBALS['custom_listtags_pkg'])) {
185
		foreach ($GLOBALS['custom_listtags_pkg'] as $tag) {
186
			$listtags[$tag] = $tag;
187
		}
188
	}
189 bef6cb99 Ermal
	$cfg =parse_xml_config_raw($cffile, $rootobj, $isstring);
190 79262830 Phil Davis
	if ($cfg == -1) {
191 187ce62b Ermal
		return array();
192 79262830 Phil Davis
	}
193
194 bef6cb99 Ermal
	return $cfg;
195 cb980a2f Colin Smith
}
196
197 48ca2dc9 Colin Smith
function parse_xml_config_raw($cffile, $rootobj, $isstring = "false") {
198 5b237745 Scott Ullrich
199 26433cb8 Scott Ullrich
	global $depth, $curpath, $parsedcfg, $havedata, $listtags;
200 08c3872d Colin Smith
	$parsedcfg = array();
201 26433cb8 Scott Ullrich
	$curpath = array();
202
	$depth = 0;
203
	$havedata = 0;
204
205
	$xml_parser = xml_parser_create();
206
207
	xml_set_element_handler($xml_parser, "startElement", "endElement");
208
	xml_set_character_data_handler($xml_parser, "cdata");
209 086cf944 Phil Davis
	xml_parser_set_option($xml_parser, XML_OPTION_SKIP_WHITE, 1);
210 26433cb8 Scott Ullrich
211
	if (!($fp = fopen($cffile, "r"))) {
212 ada992bd Renato Botelho
		log_error(gettext("Error: could not open XML input") . "\n");
213 541989d5 Ermal
		return -1;
214 26433cb8 Scott Ullrich
	}
215 d7b6c842 Ermal Lu?i
216 26433cb8 Scott Ullrich
	while ($data = fread($fp, 4096)) {
217
		if (!xml_parse($xml_parser, $data, feof($fp))) {
218 c92ccac7 Vinicius Coque
			log_error(sprintf(gettext('XML error: %1$s at line %2$d in %3$s') . "\n",
219 79262830 Phil Davis
				xml_error_string(xml_get_error_code($xml_parser)),
220
				xml_get_current_line_number($xml_parser),
221
				$cffile));
222 26433cb8 Scott Ullrich
			return -1;
223
		}
224
	}
225
	xml_parser_free($xml_parser);
226
227 428c289f Darren Embry
	if ($rootobj) {
228 79262830 Phil Davis
		if (!is_array($rootobj)) {
229 428c289f Darren Embry
			$rootobj = array($rootobj);
230 79262830 Phil Davis
		}
231
		foreach ($rootobj as $rootobj_name) {
232
			if ($parsedcfg[$rootobj_name]) {
233 428c289f Darren Embry
				break;
234 79262830 Phil Davis
			}
235
		}
236
237 428c289f Darren Embry
		if (!$parsedcfg[$rootobj_name]) {
238
			log_error(sprintf(gettext("XML error: no %s object found!") . "\n", implode(" or ", $rootobj)));
239
			return -1;
240
		}
241
		return $parsedcfg[$rootobj_name];
242
	} else {
243
		return $parsedcfg;
244 26433cb8 Scott Ullrich
	}
245 5b237745 Scott Ullrich
}
246
247
function dump_xml_config_sub($arr, $indent) {
248
249
	global $listtags;
250 528ae96e Scott Ullrich
251 5b237745 Scott Ullrich
	$xmlconfig = "";
252
253
	foreach ($arr as $ent => $val) {
254
		if (is_array($val)) {
255
			/* is it just a list of multiple values? */
256 6d84c956 Ermal
			if (isset($listtags[strtolower($ent)])) {
257 5b237745 Scott Ullrich
				foreach ($val as $cval) {
258
					if (is_array($cval)) {
259 70d6b5c4 Ermal
						if (empty($cval)) {
260
							$xmlconfig .= str_repeat("\t", $indent);
261 e5f9360f Steve Beaver
							$xmlconfig .= "<$ent></$ent>\n";
262 70d6b5c4 Ermal
						} else {
263
							$xmlconfig .= str_repeat("\t", $indent);
264
							$xmlconfig .= "<$ent>\n";
265
							$xmlconfig .= dump_xml_config_sub($cval, $indent + 1);
266
							$xmlconfig .= str_repeat("\t", $indent);
267
							$xmlconfig .= "</$ent>\n";
268
						}
269 5b237745 Scott Ullrich
					} else {
270 79262830 Phil Davis
						if ($cval === false) {
271
							continue;
272
						}
273 70d6b5c4 Ermal
						$xmlconfig .= str_repeat("\t", $indent);
274 79262830 Phil Davis
						if ((is_bool($cval) && $cval == true) || ($cval === "")) {
275 e5f9360f Steve Beaver
							$xmlconfig .= "<$ent></$ent>\n";
276 79262830 Phil Davis
						} else if ((substr($ent, 0, 5) == "descr") ||
277
						    (substr($ent, 0, 6) == "detail") ||
278
						    (substr($ent, 0, 12) == "login_banner") ||
279
						    (substr($ent, 0, 9) == "ldap_attr") ||
280
						    (substr($ent, 0, 9) == "ldap_bind") ||
281
						    (substr($ent, 0, 11) == "ldap_basedn") ||
282
						    (substr($ent, 0, 18) == "ldap_authcn") ||
283
						    (substr($ent, 0, 19) == "ldap_extended_query")) {
284 02611466 Ermal
							$xmlconfig .= "<$ent><![CDATA[" . htmlentities($cval) . "]]></$ent>\n";
285 0d57f5f3 Scott Ullrich
						} else {
286 2e6a43a1 Ermal
							$xmlconfig .= "<$ent>" . htmlentities($cval) . "</$ent>\n";
287 70d6b5c4 Ermal
						}
288 5b237745 Scott Ullrich
					}
289
				}
290 78dd5020 Ermal Lu?i
			} else if (empty($val)) {
291
				$xmlconfig .= str_repeat("\t", $indent);
292 e5f9360f Steve Beaver
				$xmlconfig .= "<$ent></$ent>\n";
293 5b237745 Scott Ullrich
			} else {
294
				/* it's an array */
295
				$xmlconfig .= str_repeat("\t", $indent);
296
				$xmlconfig .= "<$ent>\n";
297
				$xmlconfig .= dump_xml_config_sub($val, $indent + 1);
298
				$xmlconfig .= str_repeat("\t", $indent);
299
				$xmlconfig .= "</$ent>\n";
300
			}
301
		} else {
302
			if ((is_bool($val) && ($val == true)) || ($val === "")) {
303
				$xmlconfig .= str_repeat("\t", $indent);
304 e5f9360f Steve Beaver
				$xmlconfig .= "<$ent></$ent>\n";
305 5b237745 Scott Ullrich
			} else if (!is_bool($val)) {
306
				$xmlconfig .= str_repeat("\t", $indent);
307 79262830 Phil Davis
				if ((substr($ent, 0, 5) == "descr") ||
308
				    (substr($ent, 0, 6) == "detail") ||
309
				    (substr($ent, 0, 12) == "login_banner") ||
310
				    (substr($ent, 0, 9) == "ldap_attr") ||
311
				    (substr($ent, 0, 9) == "ldap_bind") ||
312
				    (substr($ent, 0, 11) == "ldap_basedn") ||
313
				    (substr($ent, 0, 18) == "ldap_authcn") ||
314 5887788f Stephen Beaver
				    (substr($ent, 0, 19) == "ldap_extended_query") ||
315
				    (substr($ent, 0, 5) == "text")) {
316 02611466 Ermal
					$xmlconfig .= "<$ent><![CDATA[" . htmlentities($val) . "]]></$ent>\n";
317 086cf944 Phil Davis
				} else {
318 2e6a43a1 Ermal
					$xmlconfig .= "<$ent>" . htmlentities($val) . "</$ent>\n";
319 79262830 Phil Davis
				}
320 5b237745 Scott Ullrich
			}
321
		}
322
	}
323 528ae96e Scott Ullrich
324 5b237745 Scott Ullrich
	return $xmlconfig;
325
}
326
327
function dump_xml_config($arr, $rootobj) {
328 ba6882bf Colin Smith
	global $listtags;
329 eeb6c16e Bill Marquette
	$listtags = listtags();
330 79262830 Phil Davis
	if (isset($GLOBALS['custom_listtags'])) {
331
		foreach ($GLOBALS['custom_listtags'] as $tag) {
332
			$listtags[$tag] = $tag;
333
		}
334
	}
335 ba6882bf Colin Smith
	return dump_xml_config_raw($arr, $rootobj);
336
}
337
338
function dump_xml_config_pkg($arr, $rootobj) {
339
	global $listtags;
340 eeb6c16e Bill Marquette
	$listtags = listtags_pkg();
341 79262830 Phil Davis
	if (isset($GLOBALS['custom_listtags_pkg'])) {
342
		foreach ($GLOBALS['custom_listtags_pkg'] as $tag) {
343
			$listtags[$tag] = $tag;
344
		}
345
	}
346 ba6882bf Colin Smith
	return dump_xml_config_raw($arr, $rootobj);
347
}
348
349
function dump_xml_config_raw($arr, $rootobj) {
350 5b237745 Scott Ullrich
351
	$xmlconfig = "<?xml version=\"1.0\"?" . ">\n";
352
	$xmlconfig .= "<$rootobj>\n";
353 528ae96e Scott Ullrich
354 5b237745 Scott Ullrich
	$xmlconfig .= dump_xml_config_sub($arr, 1);
355 528ae96e Scott Ullrich
356 5b237745 Scott Ullrich
	$xmlconfig .= "</$rootobj>\n";
357 528ae96e Scott Ullrich
358 5b237745 Scott Ullrich
	return $xmlconfig;
359
}
360
361 187ce62b Ermal
?>