Project

General

Profile

Download (11 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
 * Copyright (c) 2004-2016 Electric Sheep Fencing, LLC
7
 * 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
		'depends_on_package', 'disk', 'dnsserver', 'dnsupdate', 'domainoverrides', 'dyndns',
69
		'earlyshellcmd', 'element', 'encryption-algorithm-option',
70
		'field', 'fieldname',
71
		'gateway_item', 'gateway_group', 'gif', 'gre', 'group',
72 f3d9f32b NOYB
		'hash-algorithm-option', 'hosts', 'ifgroupentry', 'igmpentry', 'interface_array', 'item', 'key',
73 79262830 Phil Davis
		'lagg', 'lbaction', 'lbpool', 'l7rules', 'lbprotocol',
74
		'member', 'menu', 'tab', 'mobilekey', 'monitor_type', 'mount',
75 72a8c829 Ermal
		'npt', 'ntpserver',
76 79262830 Phil Davis
		'onetoone', 'openvpn-server', 'openvpn-client', 'openvpn-csc', 'option',
77
		'package', 'passthrumac', 'phase1', 'phase2', 'ppp', 'pppoe', 'priv', 'proxyarpnet', 'pool',
78 72a8c829 Ermal
		'qinqentry', 'queue',
79 79262830 Phil Davis
		'pages', 'pipe', 'radnsserver', 'roll', 'route', 'row', 'rrddatafile', 'rule',
80 72a8c829 Ermal
		'schedule', 'service', 'servernat', 'servers',
81 79262830 Phil Davis
		'serversdisabled', 'shellcmd', 'staticmap', 'subqueue',
82 72a8c829 Ermal
		'timerange', 'tunnel', 'user', 'vip', 'virtual_server', 'vlan',
83
		'winsserver', 'wolentry', 'widget'
84
	);
85 6d84c956 Ermal
	return array_flip($ret);
86 eeb6c16e Bill Marquette
}
87
88 79262830 Phil Davis
/* Package XML tags that should be treated as a list not as a traditional array */
89 eeb6c16e Bill Marquette
function listtags_pkg() {
90 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');
91 eeb6c16e Bill Marquette
92 1c62178a Ermal
	return array_flip($ret);
93 eeb6c16e Bill Marquette
}
94
95 26433cb8 Scott Ullrich
function startElement($parser, $name, $attrs) {
96 1fb064e8 Erik Fonnesbeck
	global $parsedcfg, $depth, $curpath, $havedata, $listtags;
97 528ae96e Scott Ullrich
98 26433cb8 Scott Ullrich
	array_push($curpath, strtolower($name));
99
100
	$ptr =& $parsedcfg;
101
	foreach ($curpath as $path) {
102
		$ptr =& $ptr[$path];
103
	}
104
105
	/* is it an element that belongs to a list? */
106 6d84c956 Ermal
	if (isset($listtags[strtolower($name)])) {
107 26433cb8 Scott Ullrich
108
		/* is there an array already? */
109
		if (!is_array($ptr)) {
110
			/* make an array */
111
			$ptr = array();
112
		}
113
114
		array_push($curpath, count($ptr));
115
116
	} else if (isset($ptr)) {
117
		/* multiple entries not allowed for this element, bail out */
118 addc0439 Renato Botelho
		die(sprintf(gettext('XML error: %1$s at line %2$d cannot occur more than once') . "\n",
119 79262830 Phil Davis
		    $name,
120
		    xml_get_current_line_number($parser)));
121 26433cb8 Scott Ullrich
	}
122
123
	$depth++;
124
	$havedata = $depth;
125
}
126
127
function endElement($parser, $name) {
128
	global $depth, $curpath, $parsedcfg, $havedata, $listtags;
129
130
	if ($havedata == $depth) {
131
		$ptr =& $parsedcfg;
132
		foreach ($curpath as $path) {
133
			$ptr =& $ptr[$path];
134
		}
135
		$ptr = "";
136
	}
137
138
	array_pop($curpath);
139
140 79262830 Phil Davis
	if (isset($listtags[strtolower($name)])) {
141 26433cb8 Scott Ullrich
		array_pop($curpath);
142 79262830 Phil Davis
	}
143 26433cb8 Scott Ullrich
144
	$depth--;
145
}
146
147
function cData($parser, $data) {
148
	global $depth, $curpath, $parsedcfg, $havedata;
149
150
	$data = trim($data, "\t\n\r");
151
152
	if ($data != "") {
153
		$ptr =& $parsedcfg;
154
		foreach ($curpath as $path) {
155
			$ptr =& $ptr[$path];
156
		}
157
158
		if (is_string($ptr)) {
159 2e6a43a1 Ermal
			$ptr .= html_entity_decode($data);
160 26433cb8 Scott Ullrich
		} else {
161
			if (trim($data, " ") != "") {
162 2e6a43a1 Ermal
				$ptr = html_entity_decode($data);
163 26433cb8 Scott Ullrich
				$havedata++;
164
			}
165
		}
166
	}
167 5b237745 Scott Ullrich
}
168
169 48ca2dc9 Colin Smith
function parse_xml_config($cffile, $rootobj, $isstring = "false") {
170 cb980a2f Colin Smith
	global $listtags;
171 eeb6c16e Bill Marquette
	$listtags = listtags();
172 79262830 Phil Davis
	if (isset($GLOBALS['custom_listtags'])) {
173
		foreach ($GLOBALS['custom_listtags'] as $tag) {
174
			$listtags[$tag] = $tag;
175
		}
176
	}
177 26433cb8 Scott Ullrich
	return parse_xml_config_raw($cffile, $rootobj, $isstring);
178 cb980a2f Colin Smith
}
179
180 48ca2dc9 Colin Smith
function parse_xml_config_pkg($cffile, $rootobj, $isstring = "false") {
181 cb980a2f Colin Smith
	global $listtags;
182 eeb6c16e Bill Marquette
	$listtags = listtags_pkg();
183 79262830 Phil Davis
	if (isset($GLOBALS['custom_listtags_pkg'])) {
184
		foreach ($GLOBALS['custom_listtags_pkg'] as $tag) {
185
			$listtags[$tag] = $tag;
186
		}
187
	}
188 bef6cb99 Ermal
	$cfg =parse_xml_config_raw($cffile, $rootobj, $isstring);
189 79262830 Phil Davis
	if ($cfg == -1) {
190 187ce62b Ermal
		return array();
191 79262830 Phil Davis
	}
192
193 bef6cb99 Ermal
	return $cfg;
194 cb980a2f Colin Smith
}
195
196 48ca2dc9 Colin Smith
function parse_xml_config_raw($cffile, $rootobj, $isstring = "false") {
197 5b237745 Scott Ullrich
198 26433cb8 Scott Ullrich
	global $depth, $curpath, $parsedcfg, $havedata, $listtags;
199 08c3872d Colin Smith
	$parsedcfg = array();
200 26433cb8 Scott Ullrich
	$curpath = array();
201
	$depth = 0;
202
	$havedata = 0;
203
204
	$xml_parser = xml_parser_create();
205
206
	xml_set_element_handler($xml_parser, "startElement", "endElement");
207
	xml_set_character_data_handler($xml_parser, "cdata");
208 086cf944 Phil Davis
	xml_parser_set_option($xml_parser, XML_OPTION_SKIP_WHITE, 1);
209 26433cb8 Scott Ullrich
210
	if (!($fp = fopen($cffile, "r"))) {
211 ada992bd Renato Botelho
		log_error(gettext("Error: could not open XML input") . "\n");
212 541989d5 Ermal
		return -1;
213 26433cb8 Scott Ullrich
	}
214 d7b6c842 Ermal Lu?i
215 26433cb8 Scott Ullrich
	while ($data = fread($fp, 4096)) {
216
		if (!xml_parse($xml_parser, $data, feof($fp))) {
217 c92ccac7 Vinicius Coque
			log_error(sprintf(gettext('XML error: %1$s at line %2$d in %3$s') . "\n",
218 79262830 Phil Davis
				xml_error_string(xml_get_error_code($xml_parser)),
219
				xml_get_current_line_number($xml_parser),
220
				$cffile));
221 26433cb8 Scott Ullrich
			return -1;
222
		}
223
	}
224
	xml_parser_free($xml_parser);
225
226 428c289f Darren Embry
	if ($rootobj) {
227 79262830 Phil Davis
		if (!is_array($rootobj)) {
228 428c289f Darren Embry
			$rootobj = array($rootobj);
229 79262830 Phil Davis
		}
230
		foreach ($rootobj as $rootobj_name) {
231
			if ($parsedcfg[$rootobj_name]) {
232 428c289f Darren Embry
				break;
233 79262830 Phil Davis
			}
234
		}
235
236 428c289f Darren Embry
		if (!$parsedcfg[$rootobj_name]) {
237
			log_error(sprintf(gettext("XML error: no %s object found!") . "\n", implode(" or ", $rootobj)));
238
			return -1;
239
		}
240
		return $parsedcfg[$rootobj_name];
241
	} else {
242
		return $parsedcfg;
243 26433cb8 Scott Ullrich
	}
244 5b237745 Scott Ullrich
}
245
246
function dump_xml_config_sub($arr, $indent) {
247
248
	global $listtags;
249 528ae96e Scott Ullrich
250 5b237745 Scott Ullrich
	$xmlconfig = "";
251
252
	foreach ($arr as $ent => $val) {
253
		if (is_array($val)) {
254
			/* is it just a list of multiple values? */
255 6d84c956 Ermal
			if (isset($listtags[strtolower($ent)])) {
256 5b237745 Scott Ullrich
				foreach ($val as $cval) {
257
					if (is_array($cval)) {
258 70d6b5c4 Ermal
						if (empty($cval)) {
259
							$xmlconfig .= str_repeat("\t", $indent);
260
							$xmlconfig .= "<$ent/>\n";
261
						} else {
262
							$xmlconfig .= str_repeat("\t", $indent);
263
							$xmlconfig .= "<$ent>\n";
264
							$xmlconfig .= dump_xml_config_sub($cval, $indent + 1);
265
							$xmlconfig .= str_repeat("\t", $indent);
266
							$xmlconfig .= "</$ent>\n";
267
						}
268 5b237745 Scott Ullrich
					} else {
269 79262830 Phil Davis
						if ($cval === false) {
270
							continue;
271
						}
272 70d6b5c4 Ermal
						$xmlconfig .= str_repeat("\t", $indent);
273 79262830 Phil Davis
						if ((is_bool($cval) && $cval == true) || ($cval === "")) {
274 5b237745 Scott Ullrich
							$xmlconfig .= "<$ent/>\n";
275 79262830 Phil Davis
						} else if ((substr($ent, 0, 5) == "descr") ||
276
						    (substr($ent, 0, 6) == "detail") ||
277
						    (substr($ent, 0, 12) == "login_banner") ||
278
						    (substr($ent, 0, 9) == "ldap_attr") ||
279
						    (substr($ent, 0, 9) == "ldap_bind") ||
280
						    (substr($ent, 0, 11) == "ldap_basedn") ||
281
						    (substr($ent, 0, 18) == "ldap_authcn") ||
282
						    (substr($ent, 0, 19) == "ldap_extended_query")) {
283 02611466 Ermal
							$xmlconfig .= "<$ent><![CDATA[" . htmlentities($cval) . "]]></$ent>\n";
284 0d57f5f3 Scott Ullrich
						} else {
285 2e6a43a1 Ermal
							$xmlconfig .= "<$ent>" . htmlentities($cval) . "</$ent>\n";
286 70d6b5c4 Ermal
						}
287 5b237745 Scott Ullrich
					}
288
				}
289 78dd5020 Ermal Lu?i
			} else if (empty($val)) {
290
				$xmlconfig .= str_repeat("\t", $indent);
291
				$xmlconfig .= "<$ent/>\n";
292 5b237745 Scott Ullrich
			} else {
293
				/* it's an array */
294
				$xmlconfig .= str_repeat("\t", $indent);
295
				$xmlconfig .= "<$ent>\n";
296
				$xmlconfig .= dump_xml_config_sub($val, $indent + 1);
297
				$xmlconfig .= str_repeat("\t", $indent);
298
				$xmlconfig .= "</$ent>\n";
299
			}
300
		} else {
301
			if ((is_bool($val) && ($val == true)) || ($val === "")) {
302
				$xmlconfig .= str_repeat("\t", $indent);
303
				$xmlconfig .= "<$ent/>\n";
304
			} else if (!is_bool($val)) {
305
				$xmlconfig .= str_repeat("\t", $indent);
306 79262830 Phil Davis
				if ((substr($ent, 0, 5) == "descr") ||
307
				    (substr($ent, 0, 6) == "detail") ||
308
				    (substr($ent, 0, 12) == "login_banner") ||
309
				    (substr($ent, 0, 9) == "ldap_attr") ||
310
				    (substr($ent, 0, 9) == "ldap_bind") ||
311
				    (substr($ent, 0, 11) == "ldap_basedn") ||
312
				    (substr($ent, 0, 18) == "ldap_authcn") ||
313 5887788f Stephen Beaver
				    (substr($ent, 0, 19) == "ldap_extended_query") ||
314
				    (substr($ent, 0, 5) == "text")) {
315 02611466 Ermal
					$xmlconfig .= "<$ent><![CDATA[" . htmlentities($val) . "]]></$ent>\n";
316 086cf944 Phil Davis
				} else {
317 2e6a43a1 Ermal
					$xmlconfig .= "<$ent>" . htmlentities($val) . "</$ent>\n";
318 79262830 Phil Davis
				}
319 5b237745 Scott Ullrich
			}
320
		}
321
	}
322 528ae96e Scott Ullrich
323 5b237745 Scott Ullrich
	return $xmlconfig;
324
}
325
326
function dump_xml_config($arr, $rootobj) {
327 ba6882bf Colin Smith
	global $listtags;
328 eeb6c16e Bill Marquette
	$listtags = listtags();
329 79262830 Phil Davis
	if (isset($GLOBALS['custom_listtags'])) {
330
		foreach ($GLOBALS['custom_listtags'] as $tag) {
331
			$listtags[$tag] = $tag;
332
		}
333
	}
334 ba6882bf Colin Smith
	return dump_xml_config_raw($arr, $rootobj);
335
}
336
337
function dump_xml_config_pkg($arr, $rootobj) {
338
	global $listtags;
339 eeb6c16e Bill Marquette
	$listtags = listtags_pkg();
340 79262830 Phil Davis
	if (isset($GLOBALS['custom_listtags_pkg'])) {
341
		foreach ($GLOBALS['custom_listtags_pkg'] as $tag) {
342
			$listtags[$tag] = $tag;
343
		}
344
	}
345 ba6882bf Colin Smith
	return dump_xml_config_raw($arr, $rootobj);
346
}
347
348
function dump_xml_config_raw($arr, $rootobj) {
349 5b237745 Scott Ullrich
350
	$xmlconfig = "<?xml version=\"1.0\"?" . ">\n";
351
	$xmlconfig .= "<$rootobj>\n";
352 528ae96e Scott Ullrich
353 5b237745 Scott Ullrich
	$xmlconfig .= dump_xml_config_sub($arr, 1);
354 528ae96e Scott Ullrich
355 5b237745 Scott Ullrich
	$xmlconfig .= "</$rootobj>\n";
356 528ae96e Scott Ullrich
357 5b237745 Scott Ullrich
	return $xmlconfig;
358
}
359
360 187ce62b Ermal
?>