Rev 731 | Rev 760 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
635 | daniel-mar | 1 | <?php |
2 | |||
3 | /* |
||
4 | * OIDplus 2.0 |
||
758 | daniel-mar | 5 | * Copyright 2019 - 2022 Daniel Marschall, ViaThinkSoft |
635 | daniel-mar | 6 | * |
7 | * Licensed under the Apache License, Version 2.0 (the "License"); |
||
8 | * you may not use this file except in compliance with the License. |
||
9 | * You may obtain a copy of the License at |
||
10 | * |
||
11 | * http://www.apache.org/licenses/LICENSE-2.0 |
||
12 | * |
||
13 | * Unless required by applicable law or agreed to in writing, software |
||
14 | * distributed under the License is distributed on an "AS IS" BASIS, |
||
15 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||
16 | * See the License for the specific language governing permissions and |
||
17 | * limitations under the License. |
||
18 | */ |
||
19 | |||
20 | require_once __DIR__ . '/../../../../../includes/oidplus.inc.php'; |
||
21 | |||
22 | OIDplus::init(true); |
||
23 | set_exception_handler(array('OIDplusGui', 'html_exception_handler')); |
||
24 | |||
25 | if (OIDplus::baseConfig()->getValue('DISABLE_PLUGIN_OIDplusPagePublicWhois', false)) { |
||
26 | throw new OIDplusException(_L('This plugin was disabled by the system administrator!')); |
||
27 | } |
||
28 | |||
29 | originHeaders(); |
||
30 | |||
31 | // Step 0: Get request parameter |
||
32 | |||
33 | if (PHP_SAPI == 'cli') { |
||
34 | if ($_SERVER['argc'] != 2) { |
||
35 | echo _L('Syntax').': '.$_SERVER['argv'][0].' <query>'."\n"; |
||
36 | exit(2); |
||
37 | } |
||
38 | $query = $_SERVER['argv'][1]; |
||
39 | } else { |
||
40 | if (!isset($_REQUEST['query'])) { |
||
41 | http_response_code(400); |
||
42 | die('<h1>'._L('Error').'</h1><p>'._L('Argument "%1" is missing','query').'<p>'); |
||
43 | } |
||
44 | $query = $_REQUEST['query']; |
||
45 | } |
||
46 | |||
47 | // Split input into query, authTokens and serverCommands |
||
48 | $tokens = explode('$', $query); |
||
49 | $query = array_shift($tokens); |
||
50 | $authTokens[] = array(); |
||
51 | $serverCommands = array(); |
||
52 | foreach ($tokens as $token) { |
||
53 | if (strpos($token,'=') !== false) { |
||
54 | $tmp = explode('=',$token,2); |
||
55 | $serverCommands[strtolower($tmp[0])] = $tmp[1]; |
||
56 | } else { |
||
57 | $authTokens[] = $token; |
||
58 | } |
||
59 | } |
||
60 | |||
61 | $query = str_replace('oid:.', 'oid:', $query); // allow leading dot |
||
62 | |||
63 | // Step 1: Collect data |
||
64 | |||
65 | $out = array(); |
||
66 | |||
67 | $out[] = "query: $query"; |
||
68 | |||
69 | $distance = null; |
||
70 | $found = null; |
||
71 | |||
72 | try { |
||
73 | $obj = OIDplusObject::findFitting($query); |
||
74 | if (!$obj) $obj = OIDplusObject::parse($query); // in case we didn't find anything fitting, we take it as it is and later use getParent() to find something else |
||
75 | $query = $obj->nodeId(); |
||
76 | } catch (Exception $e) { |
||
77 | $obj = null; |
||
78 | } |
||
79 | |||
80 | $only_wellknown_ids_found = false; |
||
81 | $continue = false; |
||
82 | |||
83 | if (!$obj) { |
||
84 | $out[] = "result: Not found"; // DO NOT TRANSLATE! |
||
85 | $continue = false; |
||
86 | $res = null; |
||
87 | } else { |
||
88 | $obj = null; |
||
89 | $distance = 0; |
||
90 | |||
91 | $init_query = $query; |
||
92 | while (true) { |
||
93 | $res = OIDplus::db()->query("select * from ###objects where id = ?", array($query)); |
||
94 | if ($res->num_rows() > 0) { |
||
95 | $obj = OIDplusObject::parse($query); |
||
96 | if ($distance > 0) { |
||
97 | $out[] = "result: Not found; superior object found"; // DO NOT TRANSLATE! |
||
98 | $out[] = "distance: $distance"; // DO NOT TRANSLATE |
||
99 | } else { |
||
100 | $out[] = "result: Found"; // DO NOT TRANSLATE! |
||
101 | } |
||
102 | $continue = true; |
||
103 | break; |
||
104 | } |
||
105 | |||
106 | if (substr($query,0,4) === 'oid:') { |
||
107 | $query_prev = $query; |
||
108 | $query = 'oid:'.oid_up(explode(':',$query,2)[1]); |
||
109 | if ($query == $query_prev) break; |
||
110 | $distance++; |
||
111 | } else { |
||
713 | daniel-mar | 112 | // getParent() will find the parent which DOES exist in the DB. |
113 | // It does not need to be the direct parent (like ->one_up() does) |
||
635 | daniel-mar | 114 | $obj = OIDplusObject::parse($query)->getParent(); // For objects, we assume that they are parents of each other |
115 | if ($obj) { |
||
116 | $res = OIDplus::db()->query("select * from ###objects where id = ?", array($obj->nodeId())); |
||
117 | $distance = $obj->distance($query); |
||
118 | assert($res->num_rows() > 0); |
||
119 | |||
120 | $query = $obj->nodeId(); |
||
121 | } |
||
713 | daniel-mar | 122 | |
123 | if ($distance > 0) { |
||
124 | $out[] = "result: Not found; superior object found"; // DO NOT TRANSLATE! |
||
125 | $out[] = "distance: $distance"; // DO NOT TRANSLATE |
||
126 | } |
||
127 | $continue = true; |
||
128 | |||
635 | daniel-mar | 129 | break; |
130 | } |
||
131 | } |
||
132 | |||
133 | if ((substr($query,0,4) === 'oid:') && (!$obj)) { |
||
134 | $query = $init_query; |
||
135 | $distance = 0; |
||
136 | while (true) { |
||
137 | $res = OIDplus::db()->query("select * from ###asn1id where oid = ? union select * from ###iri where oid = ?", array($query, $query)); |
||
138 | if ($res->num_rows() > 0) { |
||
139 | $obj = OIDplusObject::parse($query); |
||
140 | $res = null; |
||
141 | if ($distance > 0) { |
||
142 | $out[] = "result: Not found; superior object found"; // DO NOT TRANSLATE! |
||
143 | $out[] = "distance: $distance"; // DO NOT TRANSLATE |
||
144 | } else { |
||
145 | $out[] = "result: Found"; // DO NOT TRANSLATE! |
||
146 | } |
||
147 | $only_wellknown_ids_found = true; // Information partially available |
||
148 | $continue = true; |
||
149 | break; |
||
150 | } |
||
151 | $query_prev = $query; |
||
152 | $query = 'oid:'.oid_up(explode(':',$query,2)[1]); |
||
153 | if ($query == $query_prev) break; |
||
154 | $distance++; |
||
155 | } |
||
156 | } |
||
157 | |||
158 | if (!$obj) { |
||
159 | $out[] = "result: Not found"; // DO NOT TRANSLATE! |
||
160 | $continue = false; |
||
161 | } |
||
162 | |||
163 | $found = $distance == 0; |
||
164 | } |
||
165 | |||
166 | if ($continue) { |
||
167 | $out[] = ""; |
||
168 | $out[] = "object: $query"; // DO NOT TRANSLATE! |
||
169 | if (!allowObjectView($obj, $authTokens)) { |
||
170 | $out[] = "status: Information unavailable"; // DO NOT TRANSLATE! |
||
171 | $out[] = "attribute: confidential"; // DO NOT TRANSLATE! |
||
172 | } else { |
||
173 | if ($only_wellknown_ids_found) { |
||
174 | $out[] = "status: Information partially available"; // DO NOT TRANSLATE! |
||
175 | } else { |
||
176 | $out[] = "status: Information available"; // DO NOT TRANSLATE! |
||
177 | } |
||
178 | |||
179 | $row = $res ? $res->fetch_object() : null; |
||
180 | |||
758 | daniel-mar | 181 | if (!is_null($row)) { |
182 | $out[] = 'name: ' . $row->title; // DO NOT TRANSLATE! |
||
635 | daniel-mar | 183 | |
184 | $cont = $row->description; |
||
185 | $cont = preg_replace('@<a[^>]+href\s*=\s*["\']([^\'"]+)["\'][^>]*>(.+)<\s*/\s*a\s*>@ismU', '\2 (\1)', $cont); |
||
186 | $cont = preg_replace('@<br.*>@', "\n", $cont); |
||
187 | $cont = preg_replace('@\\n+@', "\n", $cont); |
||
188 | $out[] = 'description: ' . trim(html_entity_decode(strip_tags($cont))); // DO NOT TRANSLATE! |
||
189 | } |
||
190 | |||
191 | if (substr($query,0,4) === 'oid:') { |
||
192 | $out[] = 'asn1-notation: ' . $obj->getAsn1Notation(false); // DO NOT TRANSLATE! |
||
193 | $out[] = 'iri-notation: ' . $obj->getIriNotation(false); // DO NOT TRANSLATE! |
||
194 | |||
195 | $res2 = OIDplus::db()->query("select * from ###asn1id where oid = ?", array($obj->nodeId())); |
||
196 | while ($row2 = $res2->fetch_object()) { |
||
197 | $out[] = 'identifier: ' . $row2->name; // DO NOT TRANSLATE! |
||
198 | } |
||
199 | |||
200 | $res2 = OIDplus::db()->query("select * from ###asn1id where standardized = ? and oid = ?", array(true, $obj->nodeId())); |
||
201 | while ($row2 = $res2->fetch_object()) { |
||
202 | $out[] = 'standardized-id: ' . $row2->name; // DO NOT TRANSLATE! |
||
203 | } |
||
204 | |||
205 | $res2 = OIDplus::db()->query("select * from ###iri where oid = ?", array($obj->nodeId())); |
||
206 | while ($row2 = $res2->fetch_object()) { |
||
207 | $out[] = 'unicode-label: ' . $row2->name; // DO NOT TRANSLATE! |
||
208 | } |
||
209 | |||
210 | $res2 = OIDplus::db()->query("select * from ###iri where longarc = ? and oid = ?", array(true, $obj->nodeId())); |
||
211 | while ($row2 = $res2->fetch_object()) { |
||
212 | $out[] = 'long-arc: ' . $row2->name; // DO NOT TRANSLATE! |
||
213 | } |
||
214 | } |
||
215 | |||
216 | if ($obj->isConfidential()) { // yes, we use isConfidential() instead of allowObjectView()! |
||
678 | daniel-mar | 217 | $out[] = 'attribute: confidential'; // DO NOT TRANSLATE! |
635 | daniel-mar | 218 | } |
219 | |||
730 | daniel-mar | 220 | if ($obj->implementsFeature('1.3.6.1.4.1.37476.2.5.2.3.4')) { |
221 | // Also ask $obj for extra attributes: |
||
222 | // This way we could add various additional information, e.g. IPv4/6 range analysis, interpretation of GUID, etc. (TODO) |
||
223 | $obj->whoisObjectAttributes($obj->nodeId(), $out); |
||
224 | } |
||
225 | |||
635 | daniel-mar | 226 | foreach (OIDplus::getPagePlugins() as $plugin) { |
227 | if ($plugin->implementsFeature('1.3.6.1.4.1.37476.2.5.2.3.4')) { |
||
228 | $plugin->whoisObjectAttributes($obj->nodeId(), $out); |
||
229 | } |
||
230 | } |
||
231 | |||
232 | if (substr($query,0,4) === 'oid:') { |
||
233 | $sParent = 'oid:'.oid_up(explode(':',$query,2)[1]); |
||
234 | |||
235 | $objTest = OIDplusObject::parse($sParent); |
||
236 | if (allowObjectView($objTest, $authTokens)) { |
||
237 | $out[] = 'parent: ' . $sParent . show_asn1_appendix($sParent); // DO NOT TRANSLATE! |
||
238 | } else { |
||
239 | $out[] = 'parent: ' . $sParent; // DO NOT TRANSLATE! |
||
240 | } |
||
241 | } else if (!is_null($row) && !empty($row->parent) && (!is_root($row->parent))) { |
||
242 | $sParent = $row->parent; |
||
243 | $out[] = 'parent: ' . $row->parent; // DO NOT TRANSLATE! |
||
244 | } |
||
245 | |||
246 | $res2 = OIDplus::db()->query("select * from ###objects where parent = ? order by ".OIDplus::db()->natOrder('id'), array($obj->nodeId())); |
||
247 | while ($row2 = $res2->fetch_object()) { |
||
248 | $objTest = OIDplusObject::parse($row2->id); |
||
249 | if (allowObjectView($objTest, $authTokens)) { |
||
250 | $out[] = 'subordinate: ' . $row2->id . show_asn1_appendix($row2->id); // DO NOT TRANSLATE! |
||
251 | } else { |
||
252 | $out[] = 'subordinate: ' . $row2->id; // DO NOT TRANSLATE! |
||
253 | } |
||
254 | } |
||
255 | |||
256 | if (!is_null($row)) { |
||
257 | if ($row->created) $out[] = 'created: ' . date('Y-m-d H:i:s', strtotime($row->created)); // DO NOT TRANSLATE! |
||
258 | if ($row->updated) $out[] = 'updated: ' . date('Y-m-d H:i:s', strtotime($row->updated)); // DO NOT TRANSLATE! |
||
259 | } |
||
260 | |||
261 | $out[] = ''; |
||
262 | |||
263 | $res2 = OIDplus::db()->query("select * from ###ra where email = ?", array(is_null($row) ? '' : $row->ra_email)); |
||
264 | if ($row2 = $res2->fetch_object()) { |
||
265 | $out[] = 'ra: '.(!empty($row2->ra_name) ? $row2->ra_name : (!empty($row2->email) ? $row2->email : _L('Unknown'))); // DO NOT TRANSLATE! |
||
266 | $out[] = 'ra-status: Information available'; // DO NOT TRANSLATE! |
||
267 | |||
268 | $tmp = array(); |
||
269 | if (!empty($row2->office)) $tmp[] = $row2->office; |
||
270 | if (!empty($row2->organization)) $tmp[] = $row2->organization; |
||
271 | $tmp = implode(', ', $tmp); |
||
272 | |||
273 | $out[] = 'ra-contact-name: ' . $row2->personal_name.(!empty($tmp) ? " ($tmp)" : ''); // DO NOT TRANSLATE! |
||
274 | if (!allowRAView($row2, $authTokens)) { |
||
275 | if (!empty($row2->street) || !empty($row2->zip_town) || !empty($row2->country)) { |
||
276 | $out[] = 'ra-address: '._L('(redacted)'); // DO NOT TRANSLATE! |
||
277 | } |
||
278 | $out[] = 'ra-phone: ' . (!empty($row2->phone) ? _L('(redacted)') : ''); // DO NOT TRANSLATE! |
||
279 | $out[] = 'ra-mobile: ' . (!empty($row2->mobile) ? _L('(redacted)') : ''); // DO NOT TRANSLATE! |
||
280 | $out[] = 'ra-fax: ' . (!empty($row2->fax) ? _L('(redacted)') : ''); // DO NOT TRANSLATE! |
||
281 | } else { |
||
282 | if (!empty($row2->street)) $out[] = 'ra-address: ' . $row2->street; // DO NOT TRANSLATE! |
||
283 | if (!empty($row2->zip_town)) $out[] = 'ra-address: ' . $row2->zip_town; // DO NOT TRANSLATE! |
||
284 | if (!empty($row2->country)) $out[] = 'ra-address: ' . $row2->country; // DO NOT TRANSLATE! |
||
285 | $out[] = 'ra-phone: ' . $row2->phone; // DO NOT TRANSLATE! |
||
286 | $out[] = 'ra-mobile: ' . $row2->mobile; // DO NOT TRANSLATE! |
||
287 | $out[] = 'ra-fax: ' . $row2->fax; // DO NOT TRANSLATE! |
||
288 | } |
||
289 | $out[] = 'ra-email: ' . $row->ra_email; // DO NOT TRANSLATE! |
||
730 | daniel-mar | 290 | |
291 | $ra = new OIDplusRA($row->ra_email); |
||
292 | if ($ra->implementsFeature('1.3.6.1.4.1.37476.2.5.2.3.4')) { |
||
731 | daniel-mar | 293 | $ra->whoisRaAttributes($row->ra_email, $out); /** @phpstan-ignore-line */ |
730 | daniel-mar | 294 | } |
295 | |||
635 | daniel-mar | 296 | foreach (OIDplus::getPagePlugins() as $plugin) { |
297 | if ($plugin->implementsFeature('1.3.6.1.4.1.37476.2.5.2.3.4')) { |
||
298 | $plugin->whoisRaAttributes($row->ra_email, $out); |
||
299 | } |
||
300 | } |
||
301 | |||
302 | if ($row2->privacy) { // yes, we use row2->privacy() instead of allowRAView()! |
||
678 | daniel-mar | 303 | $out[] = 'ra-attribute: confidential'; // DO NOT TRANSLATE! |
635 | daniel-mar | 304 | } |
305 | |||
306 | if ($row2->registered) $out[] = 'ra-created: ' . date('Y-m-d H:i:s', strtotime($row2->registered)); // DO NOT TRANSLATE! |
||
307 | if ($row2->updated) $out[] = 'ra-updated: ' . date('Y-m-d H:i:s', strtotime($row2->updated)); // DO NOT TRANSLATE! |
||
308 | } else { |
||
309 | $out[] = 'ra: '.(!is_null($row) && !empty($row->ra_email) ? $row->ra_email : _L('Unknown')); // DO NOT TRANSLATE! |
||
310 | if (!is_null($row)) { |
||
311 | foreach (OIDplus::getPagePlugins() as $plugin) { |
||
312 | if ($plugin->implementsFeature('1.3.6.1.4.1.37476.2.5.2.3.4')) { |
||
313 | $plugin->whoisRaAttributes($row->ra_email, $out); |
||
314 | } |
||
315 | } |
||
316 | } |
||
317 | $out[] = "ra-status: Information unavailable"; // DO NOT TRANSLATE! |
||
318 | } |
||
319 | } |
||
320 | } |
||
321 | |||
322 | // Step 2: Format output |
||
323 | |||
324 | if (isset($_REQUEST['format'])) { |
||
325 | $format = $_REQUEST['format']; |
||
326 | } else if (isset($serverCommands['format'])) { |
||
327 | $format = $serverCommands['format']; |
||
328 | } else { |
||
656 | daniel-mar | 329 | $format = 'text'; // default |
635 | daniel-mar | 330 | } |
331 | |||
758 | daniel-mar | 332 | if (($format != 'txt') && ($format != 'text') && ($format != 'json') && ($format != 'xml') && ($format != 'html')) { |
656 | daniel-mar | 333 | $format = 'text'; // default |
635 | daniel-mar | 334 | } |
335 | |||
656 | daniel-mar | 336 | if (($format == 'text') || ($format == 'txt')) { |
635 | daniel-mar | 337 | header('Content-Type:text/plain; charset=UTF-8'); |
338 | |||
339 | $longest_key = 0; |
||
340 | foreach ($out as $line) { |
||
341 | $longest_key = max($longest_key, strlen(trim(explode(':',$line,2)[0]))); |
||
342 | } |
||
343 | |||
344 | ob_start(); |
||
345 | |||
346 | //echo '% ' . str_repeat('*', OIDplus::config()->getValue('webwhois_output_format_max_line_length', 80)-2)."\r\n"; |
||
347 | |||
348 | foreach ($out as $line) { |
||
349 | if (trim($line) == '') { |
||
350 | echo "\r\n"; |
||
351 | continue; |
||
352 | } |
||
353 | |||
354 | $ary = explode(':', $line, 2); |
||
355 | |||
356 | $key = trim($ary[0]); |
||
357 | |||
358 | $value = isset($ary[1]) ? trim($ary[1]) : ''; |
||
674 | daniel-mar | 359 | |
360 | // Normalize line-breaks to \r\n, otherwise mb_wordwrap won't work correctly |
||
361 | $value = str_replace("\r\n", "\n", $value); |
||
362 | $value = str_replace("\r", "\n", $value); |
||
363 | $value = str_replace("\n", "\r\n", $value); |
||
364 | |||
635 | daniel-mar | 365 | $value = mb_wordwrap($value, OIDplus::config()->getValue('webwhois_output_format_max_line_length', 80) - $longest_key - strlen(':') - OIDplus::config()->getValue('webwhois_output_format_spacer', 2), "\r\n"); |
366 | $value = str_replace("\r\n", "\r\n$key:".str_repeat(' ', $longest_key-strlen($key)) . str_repeat(' ', OIDplus::config()->getValue('webwhois_output_format_spacer', 2)), $value); |
||
367 | |||
368 | if (!empty($value)) { |
||
369 | echo $key.':' . str_repeat(' ', $longest_key-strlen($key)) . str_repeat(' ', OIDplus::config()->getValue('webwhois_output_format_spacer', 2)) . $value . "\r\n"; |
||
370 | } |
||
371 | } |
||
372 | |||
373 | //echo '% ' . str_repeat('*', OIDplus::config()->getValue('webwhois_output_format_max_line_length', 80)-2)."\r\n"; |
||
374 | |||
375 | $cont = ob_get_contents(); |
||
376 | ob_end_clean(); |
||
377 | |||
378 | echo $cont; |
||
379 | |||
380 | if (OIDplus::getPkiStatus()) { |
||
381 | $signature = ''; |
||
382 | if (@openssl_sign($cont, $signature, OIDplus::config()->getValue('oidplus_private_key'))) { |
||
383 | $signature = base64_encode($signature); |
||
384 | $signature = mb_wordwrap($signature, OIDplus::config()->getValue('webwhois_output_format_max_line_length', 80) - strlen('% '), "\r\n", true); |
||
385 | $signature = "% -----BEGIN RSA SIGNATURE-----\r\n". |
||
386 | preg_replace('/^/m', '% ', $signature)."\r\n". |
||
387 | "% -----END RSA SIGNATURE-----\r\n"; |
||
388 | echo $signature; |
||
389 | } |
||
390 | } |
||
391 | } |
||
392 | |||
393 | if ($format == 'json') { |
||
394 | $ary = array(); |
||
395 | |||
396 | $current_section = array(); |
||
397 | $ary[] = &$current_section; |
||
398 | |||
399 | foreach ($out as $line) { |
||
400 | if ($line == '') { |
||
401 | unset($current_section); |
||
402 | $current_section = array(); |
||
403 | $ary[] = &$current_section; |
||
404 | } else { |
||
405 | list($key,$val) = explode(':', $line, 2); |
||
406 | $val = trim($val); |
||
407 | if (!empty($val)) { |
||
408 | if (!isset($current_section[$key])) { |
||
409 | $current_section[$key] = $val; |
||
410 | } elseif (is_array($current_section[$key])) { |
||
411 | $current_section[$key][] = $val; |
||
412 | } else { |
||
413 | $current_section[$key] = array($current_section[$key], $val); |
||
414 | } |
||
415 | } |
||
416 | } |
||
417 | } |
||
418 | $ary = array( |
||
419 | // https://code.visualstudio.com/docs/languages/json#_mapping-in-the-json |
||
420 | // Note that this syntax is VS Code-specific and not part of the JSON Schema specification. |
||
421 | //'$schema' => 'https://oidplus.viathinksoft.com/oidplus/plugins/publicPages/100_whois/whois/json_schema.json', |
||
644 | daniel-mar | 422 | '$schema' => OIDplus::webpath(__DIR__,true).'json_schema.json', |
635 | daniel-mar | 423 | |
424 | // we need this NAMED root, otherwise PHP will name the sections "0", "1", "2" if the array is not sequencial (e.g. because "signature" is added) |
||
758 | daniel-mar | 425 | 'oidip' => $ary |
635 | daniel-mar | 426 | ); |
427 | |||
428 | if (OIDplus::getPkiStatus()) { |
||
429 | $cont = json_encode($ary); |
||
430 | $signature = ''; |
||
431 | if (@openssl_sign($cont, $signature, OIDplus::config()->getValue('oidplus_private_key'))) { |
||
432 | $signature = base64_encode($signature); |
||
433 | $ary['signature'] = array('content' => $cont, 'signature' => $signature); |
||
434 | } |
||
435 | } |
||
436 | |||
437 | // Good JSON schema validator here: https://www.jsonschemavalidator.net |
||
438 | header('Content-Type:application/json; charset=UTF-8'); |
||
439 | echo json_encode($ary); |
||
440 | } |
||
441 | |||
442 | if ($format == 'xml') { |
||
758 | daniel-mar | 443 | $xml = '<oidip><section>'; |
635 | daniel-mar | 444 | foreach ($out as $line) { |
445 | if ($line == '') { |
||
446 | $xml .= '</section><section>'; |
||
447 | } else { |
||
448 | list($key,$val) = explode(':', $line, 2); |
||
449 | $val = trim($val); |
||
450 | if (!empty($val)) { |
||
451 | $xml .= "<$key>".htmlspecialchars($val)."</$key>"; |
||
452 | } |
||
453 | } |
||
454 | } |
||
758 | daniel-mar | 455 | $xml .= '</section></oidip>'; |
635 | daniel-mar | 456 | |
457 | $xml = preg_replace('@<section><(.+)>(.+)</section>@ismU', '<\\1Section><\\1>\\2</\\1Section>', $xml); |
||
458 | |||
459 | if (OIDplus::getPkiStatus()) { |
||
460 | $cont = $xml; |
||
461 | $signature = ''; |
||
462 | if (@openssl_sign($cont, $signature, OIDplus::config()->getValue('oidplus_private_key'))) { |
||
463 | $signature = base64_encode($signature); |
||
464 | $xml .= "<signature><content>".htmlspecialchars($cont)."</content><signature>".htmlspecialchars($signature)."</signature></signature>"; |
||
465 | } |
||
466 | } |
||
467 | |||
468 | // Good XSD validator here: https://www.liquid-technologies.com/online-xsd-validator |
||
469 | header('Content-Type:application/xml; charset=UTF-8'); |
||
470 | echo '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>'; |
||
471 | echo '<root xmlns="urn:oid:1.3.6.1.4.1.37476.2.5.2.5.1.1"'; |
||
472 | echo ' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"'; |
||
473 | //echo ' xsi:schemaLocation="urn:oid:1.3.6.1.4.1.37476.2.5.2.5.1.1 https://oidplus.viathinksoft.com/oidplus/plugins/publicPages/100_whois/whois/xml_schema.xsd">'; |
||
644 | daniel-mar | 474 | echo ' xsi:schemaLocation="urn:oid:1.3.6.1.4.1.37476.2.5.2.5.1.1 '.OIDplus::webpath(__DIR__,true).'xml_schema.xsd">'; |
635 | daniel-mar | 475 | echo $xml; |
476 | echo '</root>'; |
||
477 | } |
||
478 | |||
758 | daniel-mar | 479 | if ($format == 'html') { |
480 | // TODO |
||
481 | throw new OIDplusException(_L('The output format "%1" has not yet been implemented!')); |
||
482 | } |
||
483 | |||
635 | daniel-mar | 484 | # --- |
485 | |||
486 | function show_asn1_appendix($id) { |
||
487 | if (substr($id,0,4) === 'oid:') { |
||
488 | $appendix_asn1ids = array(); |
||
489 | $res3 = OIDplus::db()->query("select * from ###asn1id where oid = ?", array($id)); |
||
490 | while ($row3 = $res3->fetch_object()) { |
||
491 | $appendix_asn1ids[] = $row3->name; |
||
492 | } |
||
493 | |||
494 | $appendix = implode(', ', $appendix_asn1ids); |
||
495 | if (!empty($appendix)) $appendix = " ($appendix)"; |
||
496 | } else { |
||
497 | $appendix = ''; |
||
498 | } |
||
499 | return $appendix; |
||
500 | } |
||
501 | |||
502 | function is_root($id) { |
||
503 | return empty(explode(':',$id,2)[1]); |
||
504 | } |
||
505 | |||
506 | function authTokenAccepted($content, $authTokens) { |
||
507 | foreach ($authTokens as $token) { |
||
508 | if (OIDplusPagePublicWhois::genWhoisAuthToken($content) == $token) return true; |
||
509 | } |
||
510 | return false; |
||
511 | } |
||
512 | |||
513 | function allowObjectView($obj, $authTokens) { |
||
514 | // Master auth token |
||
515 | $authToken = trim(OIDplus::config()->getValue('whois_auth_token')); |
||
516 | if (empty($authToken)) $authToken = false; |
||
517 | if ($authToken && in_array($authToken, $authTokens)) return true; |
||
518 | |||
519 | // Per-OID auth tokens |
||
520 | $curid = $obj->nodeId(); |
||
521 | while (($res = OIDplus::db()->query("select parent, confidential from ###objects where id = ?", array($curid)))->num_rows() > 0) { |
||
522 | $row = $res->fetch_array(); |
||
523 | // Example: You have an auth Token for 2.999.1.2.3 |
||
524 | // This allows you to view 2.999.1.2.3 and all of its children, |
||
525 | // as long as they are not confidential (then you need their auth token). |
||
526 | // 2, 2.999, 2.999.1 and 2.999.1.2 are visible, |
||
527 | // (because their existence is now obvious). |
||
528 | if ($row['confidential'] && !authTokenAccepted($curid, $authTokens)) return false; |
||
529 | $curid = $row['parent']; |
||
530 | } |
||
531 | |||
532 | // Allow |
||
533 | return true; |
||
534 | } |
||
535 | |||
536 | function allowRAView($row, $authTokens) { |
||
537 | // Master auth token |
||
538 | $authToken = trim(OIDplus::config()->getValue('whois_auth_token')); |
||
539 | if (empty($authToken)) $authToken = false; |
||
540 | if ($authToken && in_array($authToken, $authTokens)) return true; |
||
541 | |||
542 | // Per-RA auth tokens |
||
543 | if ($row->privacy && !authTokenAccepted('ra:'.$row->ra_name, $authTokens)) return false; |
||
544 | |||
545 | // Allow |
||
546 | return true; |
||
547 | } |