Project

General

Profile

Download (9.52 KB) Statistics
| Branch: | Tag: | Revision:
1 5b237745 Scott Ullrich
<?php
2
/*
3 ac24dc24 Renato Botelho
 * xmlparse.inc
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6 38809d47 Renato Botelho do Couto
 * Copyright (c) 2004-2013 BSD Perimeter
7
 * Copyright (c) 2013-2016 Electric Sheep Fencing
8 0284d79e jim-p
 * Copyright (c) 2014-2020 Rubicon Communications, LLC (Netgate)
9 ac24dc24 Renato Botelho
 * All rights reserved.
10
 *
11
 * originally part of m0n0wall (http://m0n0.ch/wall)
12 c5d81585 Renato Botelho
 * Copyright (c) 2003-2004 Manuel Kasper <mk@neon1.net>.
13 ac24dc24 Renato Botelho
 * All rights reserved.
14
 *
15 b12ea3fb Renato Botelho
 * Licensed under the Apache License, Version 2.0 (the "License");
16
 * you may not use this file except in compliance with the License.
17
 * You may obtain a copy of the License at
18 ac24dc24 Renato Botelho
 *
19 b12ea3fb Renato Botelho
 * http://www.apache.org/licenses/LICENSE-2.0
20 ac24dc24 Renato Botelho
 *
21 b12ea3fb Renato Botelho
 * Unless required by applicable law or agreed to in writing, software
22
 * distributed under the License is distributed on an "AS IS" BASIS,
23
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
24
 * See the License for the specific language governing permissions and
25
 * limitations under the License.
26 ac24dc24 Renato Botelho
 */
27 5b237745 Scott Ullrich
28 2e5ebf5d Scott Ullrich
/* The following items will be treated as arrays in config.xml */
29 eeb6c16e Bill Marquette
function listtags() {
30 72a8c829 Ermal
	/*
31
	 * Please keep this list alpha sorted and no longer than 80 characters
32
	 * I know it's a pain, but it's a pain to find stuff too if it's not
33
	 */
34
	$ret = array(
35 79262830 Phil Davis
		'acls', 'alias', 'aliasurl', 'allowedip', 'allowedhostname', 'authserver',
36
		'bridged', 'build_port_path',
37
		'ca', 'cacert', 'cert', 'crl', 'clone', 'config', 'container', 'columnitem',
38 39d2f39d NOYB
		'checkipservice',
39 79262830 Phil Davis
		'depends_on_package', 'disk', 'dnsserver', 'dnsupdate', 'domainoverrides', 'dyndns',
40
		'earlyshellcmd', 'element', 'encryption-algorithm-option',
41
		'field', 'fieldname',
42
		'gateway_item', 'gateway_group', 'gif', 'gre', 'group',
43 40d7e4be NOYB
		'hash-algorithm-option', 'hosts', 'ifgroupentry', 'igmpentry', 'interface_array', 'item', 'key',
44 79262830 Phil Davis
		'lagg', 'lbaction', 'lbpool', 'l7rules', 'lbprotocol',
45
		'member', 'menu', 'tab', 'mobilekey', 'monitor_type', 'mount',
46 72a8c829 Ermal
		'npt', 'ntpserver',
47 79262830 Phil Davis
		'onetoone', 'openvpn-server', 'openvpn-client', 'openvpn-csc', 'option',
48
		'package', 'passthrumac', 'phase1', 'phase2', 'ppp', 'pppoe', 'priv', 'proxyarpnet', 'pool',
49 72a8c829 Ermal
		'qinqentry', 'queue',
50 79262830 Phil Davis
		'pages', 'pipe', 'radnsserver', 'roll', 'route', 'row', 'rrddatafile', 'rule',
51 72a8c829 Ermal
		'schedule', 'service', 'servernat', 'servers',
52 1328b154 Luiz Souza
		'serversdisabled', 'shellcmd', 'staticmap', 'subqueue', 'switch', 'swport',
53
		'timerange', 'tunnel', 'user', 'vip', 'virtual_server', 'vlan', 'vlangroup',
54 72a8c829 Ermal
		'winsserver', 'wolentry', 'widget'
55
	);
56 6d84c956 Ermal
	return array_flip($ret);
57 eeb6c16e Bill Marquette
}
58
59 79262830 Phil Davis
/* Package XML tags that should be treated as a list not as a traditional array */
60 eeb6c16e Bill Marquette
function listtags_pkg() {
61 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');
62 eeb6c16e Bill Marquette
63 1c62178a Ermal
	return array_flip($ret);
64 eeb6c16e Bill Marquette
}
65
66 26433cb8 Scott Ullrich
function startElement($parser, $name, $attrs) {
67 1fb064e8 Erik Fonnesbeck
	global $parsedcfg, $depth, $curpath, $havedata, $listtags;
68 528ae96e Scott Ullrich
69 26433cb8 Scott Ullrich
	array_push($curpath, strtolower($name));
70
71
	$ptr =& $parsedcfg;
72
	foreach ($curpath as $path) {
73
		$ptr =& $ptr[$path];
74
	}
75
76
	/* is it an element that belongs to a list? */
77 6d84c956 Ermal
	if (isset($listtags[strtolower($name)])) {
78 26433cb8 Scott Ullrich
79
		/* is there an array already? */
80
		if (!is_array($ptr)) {
81
			/* make an array */
82
			$ptr = array();
83
		}
84
85
		array_push($curpath, count($ptr));
86
87
	} else if (isset($ptr)) {
88
		/* multiple entries not allowed for this element, bail out */
89 6153d668 PiBa-NL
		throw new Exception(
90
		    sprintf(gettext('XML error: %1$s at line %2$d cannot occur more than once') . "\n",
91 79262830 Phil Davis
		    $name,
92
		    xml_get_current_line_number($parser)));
93 26433cb8 Scott Ullrich
	}
94
95
	$depth++;
96
	$havedata = $depth;
97
}
98
99
function endElement($parser, $name) {
100
	global $depth, $curpath, $parsedcfg, $havedata, $listtags;
101
102
	if ($havedata == $depth) {
103
		$ptr =& $parsedcfg;
104
		foreach ($curpath as $path) {
105
			$ptr =& $ptr[$path];
106
		}
107
		$ptr = "";
108
	}
109
110
	array_pop($curpath);
111
112 79262830 Phil Davis
	if (isset($listtags[strtolower($name)])) {
113 26433cb8 Scott Ullrich
		array_pop($curpath);
114 79262830 Phil Davis
	}
115 26433cb8 Scott Ullrich
116
	$depth--;
117
}
118
119
function cData($parser, $data) {
120
	global $depth, $curpath, $parsedcfg, $havedata;
121
122
	$data = trim($data, "\t\n\r");
123
124
	if ($data != "") {
125
		$ptr =& $parsedcfg;
126
		foreach ($curpath as $path) {
127
			$ptr =& $ptr[$path];
128
		}
129
130
		if (is_string($ptr)) {
131 2e6a43a1 Ermal
			$ptr .= html_entity_decode($data);
132 26433cb8 Scott Ullrich
		} else {
133
			if (trim($data, " ") != "") {
134 2e6a43a1 Ermal
				$ptr = html_entity_decode($data);
135 26433cb8 Scott Ullrich
				$havedata++;
136
			}
137
		}
138
	}
139 5b237745 Scott Ullrich
}
140
141 48ca2dc9 Colin Smith
function parse_xml_config($cffile, $rootobj, $isstring = "false") {
142 cb980a2f Colin Smith
	global $listtags;
143 eeb6c16e Bill Marquette
	$listtags = listtags();
144 79262830 Phil Davis
	if (isset($GLOBALS['custom_listtags'])) {
145
		foreach ($GLOBALS['custom_listtags'] as $tag) {
146
			$listtags[$tag] = $tag;
147
		}
148
	}
149 26433cb8 Scott Ullrich
	return parse_xml_config_raw($cffile, $rootobj, $isstring);
150 cb980a2f Colin Smith
}
151
152 48ca2dc9 Colin Smith
function parse_xml_config_pkg($cffile, $rootobj, $isstring = "false") {
153 cb980a2f Colin Smith
	global $listtags;
154 eeb6c16e Bill Marquette
	$listtags = listtags_pkg();
155 79262830 Phil Davis
	if (isset($GLOBALS['custom_listtags_pkg'])) {
156
		foreach ($GLOBALS['custom_listtags_pkg'] as $tag) {
157
			$listtags[$tag] = $tag;
158
		}
159
	}
160 bef6cb99 Ermal
	$cfg =parse_xml_config_raw($cffile, $rootobj, $isstring);
161 79262830 Phil Davis
	if ($cfg == -1) {
162 187ce62b Ermal
		return array();
163 79262830 Phil Davis
	}
164
165 bef6cb99 Ermal
	return $cfg;
166 cb980a2f Colin Smith
}
167
168 48ca2dc9 Colin Smith
function parse_xml_config_raw($cffile, $rootobj, $isstring = "false") {
169 5b237745 Scott Ullrich
170 26433cb8 Scott Ullrich
	global $depth, $curpath, $parsedcfg, $havedata, $listtags;
171 08c3872d Colin Smith
	$parsedcfg = array();
172 26433cb8 Scott Ullrich
	$curpath = array();
173
	$depth = 0;
174
	$havedata = 0;
175
176
	$xml_parser = xml_parser_create();
177
178
	xml_set_element_handler($xml_parser, "startElement", "endElement");
179
	xml_set_character_data_handler($xml_parser, "cdata");
180 086cf944 Phil Davis
	xml_parser_set_option($xml_parser, XML_OPTION_SKIP_WHITE, 1);
181 26433cb8 Scott Ullrich
182
	if (!($fp = fopen($cffile, "r"))) {
183 ada992bd Renato Botelho
		log_error(gettext("Error: could not open XML input") . "\n");
184 541989d5 Ermal
		return -1;
185 26433cb8 Scott Ullrich
	}
186 d7b6c842 Ermal Lu?i
187 26433cb8 Scott Ullrich
	while ($data = fread($fp, 4096)) {
188
		if (!xml_parse($xml_parser, $data, feof($fp))) {
189 c92ccac7 Vinicius Coque
			log_error(sprintf(gettext('XML error: %1$s at line %2$d in %3$s') . "\n",
190 79262830 Phil Davis
				xml_error_string(xml_get_error_code($xml_parser)),
191
				xml_get_current_line_number($xml_parser),
192
				$cffile));
193 26433cb8 Scott Ullrich
			return -1;
194
		}
195
	}
196
	xml_parser_free($xml_parser);
197
198 428c289f Darren Embry
	if ($rootobj) {
199 79262830 Phil Davis
		if (!is_array($rootobj)) {
200 428c289f Darren Embry
			$rootobj = array($rootobj);
201 79262830 Phil Davis
		}
202
		foreach ($rootobj as $rootobj_name) {
203
			if ($parsedcfg[$rootobj_name]) {
204 428c289f Darren Embry
				break;
205 79262830 Phil Davis
			}
206
		}
207
208 428c289f Darren Embry
		if (!$parsedcfg[$rootobj_name]) {
209
			log_error(sprintf(gettext("XML error: no %s object found!") . "\n", implode(" or ", $rootobj)));
210
			return -1;
211
		}
212
		return $parsedcfg[$rootobj_name];
213
	} else {
214
		return $parsedcfg;
215 26433cb8 Scott Ullrich
	}
216 5b237745 Scott Ullrich
}
217
218 7a97d81d jim-p
/* Return true if a field should be cdata encoded */
219
function is_cdata_entity($ent) {
220
	$cdata_fields = array(
221 008c1545 Viktor G
		'auth_pass', 'auth_prompt', 'auth_user', 'certca', 'certname', 'city', 'common_name',
222 9d4ace0b jim-p
		'descr', 'detail', 'email', 'encryption_password', 'ldap_attr',
223 f14c9058 Viktor Gurov
		'ldap_authcn', 'ldap_basedn', 'ldap_basedomain', 'ldap_bind', 'ldapbinddn',
224
		'ldapbindpass', 'ldap_extended_query', 'ldap_filter', 'ldap_pass', 'ldap_user',
225
		'login_banner', 'organization', 'password', 'rangedescr', 'state', 'text',
226
		'username', 'varusersusername', 'varuserspassword'
227 7a97d81d jim-p
	);
228
229
	/* Check if the entity name starts with any of the strings above */
230
	return preg_match('/(^' . implode('|^', $cdata_fields) . ')/', $ent) === 1;
231
}
232
233 5b237745 Scott Ullrich
function dump_xml_config_sub($arr, $indent) {
234
235
	global $listtags;
236 528ae96e Scott Ullrich
237 40caec85 jim-p
	if (!is_array($arr)) {
238
		return null;
239
	}
240
241 5b237745 Scott Ullrich
	$xmlconfig = "";
242
243
	foreach ($arr as $ent => $val) {
244
		if (is_array($val)) {
245
			/* is it just a list of multiple values? */
246 6d84c956 Ermal
			if (isset($listtags[strtolower($ent)])) {
247 5b237745 Scott Ullrich
				foreach ($val as $cval) {
248
					if (is_array($cval)) {
249 70d6b5c4 Ermal
						if (empty($cval)) {
250
							$xmlconfig .= str_repeat("\t", $indent);
251 da7054b7 Steve Beaver
							$xmlconfig .= "<$ent></$ent>\n";
252 70d6b5c4 Ermal
						} else {
253
							$xmlconfig .= str_repeat("\t", $indent);
254
							$xmlconfig .= "<$ent>\n";
255
							$xmlconfig .= dump_xml_config_sub($cval, $indent + 1);
256
							$xmlconfig .= str_repeat("\t", $indent);
257
							$xmlconfig .= "</$ent>\n";
258
						}
259 5b237745 Scott Ullrich
					} else {
260 79262830 Phil Davis
						if ($cval === false) {
261
							continue;
262
						}
263 70d6b5c4 Ermal
						$xmlconfig .= str_repeat("\t", $indent);
264 79262830 Phil Davis
						if ((is_bool($cval) && $cval == true) || ($cval === "")) {
265 da7054b7 Steve Beaver
							$xmlconfig .= "<$ent></$ent>\n";
266 7a97d81d jim-p
						} else if (is_cdata_entity($ent)) {
267 02611466 Ermal
							$xmlconfig .= "<$ent><![CDATA[" . htmlentities($cval) . "]]></$ent>\n";
268 0d57f5f3 Scott Ullrich
						} else {
269 2e6a43a1 Ermal
							$xmlconfig .= "<$ent>" . htmlentities($cval) . "</$ent>\n";
270 70d6b5c4 Ermal
						}
271 5b237745 Scott Ullrich
					}
272
				}
273 78dd5020 Ermal Lu?i
			} else if (empty($val)) {
274
				$xmlconfig .= str_repeat("\t", $indent);
275 da7054b7 Steve Beaver
				$xmlconfig .= "<$ent></$ent>\n";
276 5b237745 Scott Ullrich
			} else {
277
				/* it's an array */
278
				$xmlconfig .= str_repeat("\t", $indent);
279
				$xmlconfig .= "<$ent>\n";
280
				$xmlconfig .= dump_xml_config_sub($val, $indent + 1);
281
				$xmlconfig .= str_repeat("\t", $indent);
282
				$xmlconfig .= "</$ent>\n";
283
			}
284
		} else {
285
			if ((is_bool($val) && ($val == true)) || ($val === "")) {
286
				$xmlconfig .= str_repeat("\t", $indent);
287 da7054b7 Steve Beaver
				$xmlconfig .= "<$ent></$ent>\n";
288 5b237745 Scott Ullrich
			} else if (!is_bool($val)) {
289
				$xmlconfig .= str_repeat("\t", $indent);
290 7a97d81d jim-p
				if (is_cdata_entity($ent)) {
291 02611466 Ermal
					$xmlconfig .= "<$ent><![CDATA[" . htmlentities($val) . "]]></$ent>\n";
292 086cf944 Phil Davis
				} else {
293 2e6a43a1 Ermal
					$xmlconfig .= "<$ent>" . htmlentities($val) . "</$ent>\n";
294 79262830 Phil Davis
				}
295 5b237745 Scott Ullrich
			}
296
		}
297
	}
298 528ae96e Scott Ullrich
299 5b237745 Scott Ullrich
	return $xmlconfig;
300
}
301
302
function dump_xml_config($arr, $rootobj) {
303 ba6882bf Colin Smith
	global $listtags;
304 eeb6c16e Bill Marquette
	$listtags = listtags();
305 79262830 Phil Davis
	if (isset($GLOBALS['custom_listtags'])) {
306
		foreach ($GLOBALS['custom_listtags'] as $tag) {
307
			$listtags[$tag] = $tag;
308
		}
309
	}
310 ba6882bf Colin Smith
	return dump_xml_config_raw($arr, $rootobj);
311
}
312
313
function dump_xml_config_pkg($arr, $rootobj) {
314
	global $listtags;
315 eeb6c16e Bill Marquette
	$listtags = listtags_pkg();
316 79262830 Phil Davis
	if (isset($GLOBALS['custom_listtags_pkg'])) {
317
		foreach ($GLOBALS['custom_listtags_pkg'] as $tag) {
318
			$listtags[$tag] = $tag;
319
		}
320
	}
321 ba6882bf Colin Smith
	return dump_xml_config_raw($arr, $rootobj);
322
}
323
324
function dump_xml_config_raw($arr, $rootobj) {
325 5b237745 Scott Ullrich
326
	$xmlconfig = "<?xml version=\"1.0\"?" . ">\n";
327
	$xmlconfig .= "<$rootobj>\n";
328 528ae96e Scott Ullrich
329 5b237745 Scott Ullrich
	$xmlconfig .= dump_xml_config_sub($arr, 1);
330 528ae96e Scott Ullrich
331 5b237745 Scott Ullrich
	$xmlconfig .= "</$rootobj>\n";
332 528ae96e Scott Ullrich
333 5b237745 Scott Ullrich
	return $xmlconfig;
334
}
335
336 187ce62b Ermal
?>