Subversion Repositories oidplus

Rev

Rev 322 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
101 daniel-mar 1
<?php
2
 
3
/*
4
 * OIDplus 2.0
5
 * Copyright 2019 Daniel Marschall, ViaThinkSoft
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
 
180 daniel-mar 24
originHeaders();
101 daniel-mar 25
 
26
// Step 0: Get request parameter
27
 
28
if (php_sapi_name() == 'cli') {
29
        if ($argc != 2) {
30
                echo "Syntax: $argv[0] <query>\n";
31
                exit(2);
32
        }
33
        $query = $argv[1];
34
} else {
35
        if (!isset($_REQUEST['query'])) {
36
                http_response_code(400);
240 daniel-mar 37
                die("<h1>Error</h1><p>Argument 'query' is missing<p>");
101 daniel-mar 38
        }
39
        $query = $_REQUEST['query'];
40
}
41
 
42
$authTokens = explode('$', $query);
43
$query = array_shift($authTokens);
104 daniel-mar 44
 
45
$authToken = trim(OIDplus::config()->getValue('whois_auth_token'));
46
if (empty($authToken)) $authToken = false;
47
 
101 daniel-mar 48
$show_confidential = $authToken && in_array($authToken, $authTokens);
49
 
50
$query = str_replace('oid:.', 'oid:', $query); // allow leading dot
51
 
52
// Step 1: Collect data
53
 
54
$out = array();
55
 
56
$out[] = "query: $query";
57
 
58
$distance = null;
59
$found = null;
60
 
61
try {
62
        $obj = OIDplusObject::findFitting($query);
63
        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
64
} catch (Exception $e) {
65
        $obj = null;
66
}
67
 
68
if (!$obj) {
69
        $found = false;
70
} else {
71
        $query = $obj->nodeId(); // this may sanitize/canonize identifiers
261 daniel-mar 72
        $res = OIDplus::db()->query("select * from ###objects where id = ?", array($obj->nodeId()));
236 daniel-mar 73
        if ($res->num_rows() > 0) {
101 daniel-mar 74
                $found = true;
75
                $distance = 0;
76
        } else {
77
                $found = false;
78
                $objParent = OIDplusObject::parse($query)->getParent();
79
                if ($objParent) {
261 daniel-mar 80
                        $res = OIDplus::db()->query("select * from ###objects where id = ?", array($objParent->nodeId()));
101 daniel-mar 81
                        $distance = $objParent->distance($query);
236 daniel-mar 82
                        assert($res->num_rows() > 0);
101 daniel-mar 83
 
84
                        $query = $objParent->nodeId();
85
                        $obj = $objParent;
86
                }
87
        }
88
}
89
 
90
$continue = null;
91
if (!$found) {
92
        if (!is_null($distance)) {
93
                $out[] = "result: Not found; superior object found";
94
                $out[] = "distance: $distance";
95
                $continue = true;
96
        } else {
97
                $out[] = "result: Not found";
98
                $continue = false;
99
        }
100
} else {
101
        $out[] = "result: Found";
102
        $continue = true;
103
}
104
 
105
if ($continue) {
106
        $out[] = "";
107
        $out[] = "object: $query";
108
        if ($obj->isConfidential() && !$show_confidential) {
109
                $out[] = "status: Confidential";
110
        } else {
125 daniel-mar 111
                $out[] = "status: Information available";
101 daniel-mar 112
 
262 daniel-mar 113
                $row = $res->fetch_object();
114
                assert($row);
101 daniel-mar 115
                $obj = OIDplusObject::parse($row->id);
116
 
117
                if (!empty($row->parent) && (!is_root($row->parent))) {
118
                        $out[] = 'parent: ' . $row->parent . show_asn1_appendix($row->parent);
119
                }
120
                $out[] = 'name: ' . $row->title;
121
 
122
                $cont = $row->description;
123
                $cont = preg_replace('@<a[^>]+href\s*=\s*["\']([^\'"]+)["\'][^>]*>(.+)<\s*/\s*a\s*>@ismU', '\2 (\1)', $cont);
124
                $out[] = 'description: ' . trim(html_entity_decode(strip_tags($cont)));
125
 
126
                if (substr($query,0,4) === 'oid:') {
261 daniel-mar 127
                        $res2 = OIDplus::db()->query("select * from ###asn1id where oid = ?", array($row->id));
236 daniel-mar 128
                        while ($row2 = $res2->fetch_object()) {
101 daniel-mar 129
                                $out[] = 'identifier: ' . $row2->name;
130
                        }
131
 
261 daniel-mar 132
                        $res2 = OIDplus::db()->query("select * from ###asn1id where standardized = ? and oid = ?", array(true, $row->id));
236 daniel-mar 133
                        while ($row2 = $res2->fetch_object()) {
101 daniel-mar 134
                                $out[] = 'standardized-id: ' . $row2->name;
135
                        }
136
 
261 daniel-mar 137
                        $res2 = OIDplus::db()->query("select * from ###iri where oid = ?", array($row->id));
236 daniel-mar 138
                        while ($row2 = $res2->fetch_object()) {
101 daniel-mar 139
                                $out[] = 'unicode-label: ' . $row2->name;
140
                        }
141
 
261 daniel-mar 142
                        $res2 = OIDplus::db()->query("select * from ###iri where longarc = ? and oid = ?", array(true, $row->id));
236 daniel-mar 143
                        while ($row2 = $res2->fetch_object()) {
101 daniel-mar 144
                                $out[] = 'long-arc: ' . $row2->name;
145
                        }
146
                }
322 daniel-mar 147
                foreach (OIDplus::getPagePlugins() as $plugin) {
148
                        if ($plugin->implementsFeature('1.3.6.1.4.1.37476.2.5.2.3.4')) {
149
                                $plugin->whoisObjectAttributes($row->id, $out);
150
                        }
151
                }
101 daniel-mar 152
                $out[] = 'created: ' . $row->created;
153
                $out[] = 'updated: ' . $row->updated;
154
 
261 daniel-mar 155
                $res2 = OIDplus::db()->query("select * from ###objects where parent = ? order by ".OIDplus::db()->natOrder('id'), array($row->id));
236 daniel-mar 156
                if ($res2->num_rows() == 0) {
101 daniel-mar 157
                        // $out[] = 'subordinate: (none)';
158
                }
236 daniel-mar 159
                while ($row2 = $res2->fetch_object()) {
101 daniel-mar 160
                        $out[] = 'subordinate: ' . $row2->id . show_asn1_appendix($row2->id);
161
                }
162
 
163
                $out[] = '';
164
 
261 daniel-mar 165
                $res2 = OIDplus::db()->query("select * from ###ra where email = ?", array($row->ra_email));
236 daniel-mar 166
                if ($row2 = $res2->fetch_object()) {
101 daniel-mar 167
                        $out[] = 'ra: '.(!empty($row2->ra_name) ? $row2->ra_name : $row2->email);
125 daniel-mar 168
                        $out[] = 'ra-status: Information available';
101 daniel-mar 169
                        $out[] = 'ra-name: ' . $row2->ra_name;
170
                        $out[] = 'ra-email: ' . $row->ra_email;
171
                        $out[] = 'ra-personal-name: ' . $row2->personal_name;
172
                        $out[] = 'ra-organization: ' . $row2->organization;
173
                        $out[] = 'ra-office: ' . $row2->office;
174
                        if ($row2->privacy && !$show_confidential) {
175
                                $out[] = 'ra-street: ' . (!empty($row2->street) ? '(redacted)' : '');
176
                                $out[] = 'ra-town: ' . (!empty($row2->zip_town) ? '(redacted)' : '');
177
                                $out[] = 'ra-country: ' . (!empty($row2->country) ? '(redacted)' : '');
178
                                $out[] = 'ra-phone: ' . (!empty($row2->phone) ? '(redacted)' : '');
179
                                $out[] = 'ra-mobile: ' . (!empty($row2->mobile) ? '(redacted)' : '');
180
                                $out[] = 'ra-fax: ' . (!empty($row2->fax) ? '(redacted)' : '');
181
                        } else {
182
                                $out[] = 'ra-street: ' . $row2->street;
330 daniel-mar 183
                                $out[] = 'ra-town: ' . $row2->zip_town;
101 daniel-mar 184
                                $out[] = 'ra-country: ' . $row2->country;
185
                                $out[] = 'ra-phone: ' . $row2->phone;
186
                                $out[] = 'ra-mobile: ' . $row2->mobile;
187
                                $out[] = 'ra-fax: ' . $row2->fax;
188
                        }
322 daniel-mar 189
                        foreach (OIDplus::getPagePlugins() as $plugin) {
190
                                if ($plugin->implementsFeature('1.3.6.1.4.1.37476.2.5.2.3.4')) {
191
                                        $plugin->whoisRaAttributes($row->ra_email, $out);
192
                                }
193
                        }
101 daniel-mar 194
                        $out[] = 'ra-created: ' . $row2->registered;
195
                        $out[] = 'ra-updated: ' . $row2->updated;
196
                } else {
197
                        $out[] = 'ra: '.$row->ra_email;
322 daniel-mar 198
                        foreach (OIDplus::getPagePlugins() as $plugin) {
199
                                if ($plugin->implementsFeature('1.3.6.1.4.1.37476.2.5.2.3.4')) {
200
                                        $plugin->whoisRaAttributes($row->ra_email, $out);
201
                                }
202
                        }
125 daniel-mar 203
                        $out[] = "ra-status: Information unavailable";
101 daniel-mar 204
                }
205
        }
206
}
207
 
208
// Step 2: Format output
209
 
210
ob_start();
211
 
201 daniel-mar 212
$format = isset($_REQUEST['format']) ? $_REQUEST['format'] : 'txt';
101 daniel-mar 213
 
201 daniel-mar 214
if ($format == 'txt') {
215
        header('Content-Type:text/plain; charset=UTF-8');
101 daniel-mar 216
 
201 daniel-mar 217
        $longest_key = 0;
218
        foreach ($out as $line) {
219
                $longest_key = max($longest_key, strlen(trim(explode(':',$line,2)[0])));
101 daniel-mar 220
        }
221
 
261 daniel-mar 222
        echo '% ' . str_repeat('*', OIDplus::config()->getValue('webwhois_output_format_max_line_length', 80)-2)."\n";
101 daniel-mar 223
 
201 daniel-mar 224
        foreach ($out as $line) {
225
                if (trim($line) == '') {
226
                        echo "\n";
227
                        continue;
228
                }
101 daniel-mar 229
 
201 daniel-mar 230
                $ary = explode(':', $line, 2);
101 daniel-mar 231
 
201 daniel-mar 232
                $key = trim($ary[0]);
233
 
322 daniel-mar 234
                $value = isset($ary[1]) ? trim($ary[1]) : '';
261 daniel-mar 235
                $value = wordwrap($value, OIDplus::config()->getValue('webwhois_output_format_max_line_length', 80) - $longest_key - strlen(':') - OIDplus::config()->getValue('webwhois_output_format_spacer', 2));
236
                $value = str_replace("\n", "\n$key:".str_repeat(' ', $longest_key-strlen($key)) . str_repeat(' ', OIDplus::config()->getValue('webwhois_output_format_spacer', 2)), $value);
201 daniel-mar 237
 
261 daniel-mar 238
                echo $key.':' . str_repeat(' ', $longest_key-strlen($key)) . str_repeat(' ', OIDplus::config()->getValue('webwhois_output_format_spacer', 2)) . (!empty($value) ? $value : '.') . "\n";
201 daniel-mar 239
        }
240
 
261 daniel-mar 241
        echo '% ' . str_repeat('*', OIDplus::config()->getValue('webwhois_output_format_max_line_length', 80)-2)."\n";
201 daniel-mar 242
 
243
        $cont = ob_get_contents();
244
        ob_end_clean();
245
 
246
        echo $cont;
247
 
227 daniel-mar 248
        if (OIDplus::getPkiStatus(true)) {
201 daniel-mar 249
                $signature = '';
239 daniel-mar 250
                if (@openssl_sign($cont, $signature, OIDplus::config()->getValue('oidplus_private_key'))) {
201 daniel-mar 251
                        $signature = base64_encode($signature);
252
                        $signature = wordwrap($signature, 80, "\n", true);
253
 
254
                        $signature = "-----BEGIN RSA SIGNATURE-----\n".
255
                                     "$signature\n".
256
                                     "-----END RSA SIGNATURE-----\n";
257
                        echo $signature;
258
                }
259
        }
101 daniel-mar 260
}
261
 
201 daniel-mar 262
if ($format == 'json') {
263
        $ary = array();
101 daniel-mar 264
 
201 daniel-mar 265
        $current_section = array();
266
        $ary[] = &$current_section;
101 daniel-mar 267
 
201 daniel-mar 268
        foreach ($out as $line) {
269
                if ($line == '') {
270
                        unset($current_section);
271
                        $current_section = array();
272
                        $ary[] = &$current_section;
273
                } else {
274
                        list($key,$val) = explode(':', $line, 2);
275
                        $val = trim($val);
276
                        if (!isset($current_section[$key])) {
277
                                $current_section[$key] = $val;
278
                        } elseif (is_array($current_section[$key])) {
279
                                $current_section[$key][] = $val;
280
                        } else {
281
                                $current_section[$key] = array($current_section[$key], $val);
282
                        }
283
                }
284
        }
285
        $ary = array('whois' => $ary); // 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)
101 daniel-mar 286
 
227 daniel-mar 287
        if (OIDplus::getPkiStatus(true)) {
201 daniel-mar 288
                $cont = json_encode($ary);
289
                $signature = '';
239 daniel-mar 290
                if (@openssl_sign($cont, $signature, OIDplus::config()->getValue('oidplus_private_key'))) {
201 daniel-mar 291
                        $signature = base64_encode($signature);
292
                        $ary['signature'] = array('content' => $cont, 'signature' => $signature);
293
                }
294
        }
295
        header('Content-Type:application/json; charset=UTF-8');
296
        echo json_encode($ary);
297
}
101 daniel-mar 298
 
201 daniel-mar 299
if ($format == 'xml') {
300
        $xml = '<whois><section>';
301
        foreach ($out as $line) {
302
                if ($line == '') {
303
                        $xml .= '</section><section>';
304
                } else {
305
                        list($key,$val) = explode(':', $line, 2);
306
                        $val = trim($val);
307
                        $xml .= "<$key>".htmlspecialchars($val)."</$key>";
308
                }
309
        }
310
        $xml .= '</section></whois>';
101 daniel-mar 311
 
227 daniel-mar 312
        if (OIDplus::getPkiStatus(true)) {
201 daniel-mar 313
                $cont = $xml;
314
                $signature = '';
239 daniel-mar 315
                if (@openssl_sign($cont, $signature, OIDplus::config()->getValue('oidplus_private_key'))) {
201 daniel-mar 316
                        $signature = base64_encode($signature);
317
                        $xml .= "<signature><content>".htmlspecialchars($cont)."</content><signature>".htmlspecialchars($signature)."</signature></signature>";
318
                }
101 daniel-mar 319
        }
201 daniel-mar 320
 
321
        header('Content-Type:application/xml; charset=UTF-8');
322
        echo '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>';
330 daniel-mar 323
        echo '<root xmlns="https://oidplus.viathinksoft.com"';
324
        echo '      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"';
325
        echo '      xsi:schemaLocation="https://oidplus.viathinksoft.com/oidplus/plugins/publicPages/100_whois/whois/xml_schema.xsd">';
326
        echo $xml;
327
        echo '</root>';
101 daniel-mar 328
}
329
 
330
# ---
331
 
332
function show_asn1_appendix($id) {
333
        if (substr($id,0,4) === 'oid:') {
334
                $appendix_asn1ids = array();
261 daniel-mar 335
                $res3 = OIDplus::db()->query("select * from ###asn1id where oid = ?", array($id));
236 daniel-mar 336
                while ($row3 = $res3->fetch_object()) {
101 daniel-mar 337
                        $appendix_asn1ids[] = $row3->name;
338
                }
339
 
340
                $appendix = implode(', ', $appendix_asn1ids);
341
                if (!empty($appendix)) $appendix = " ($appendix)";
342
        } else {
343
                $appendix = '';
344
        }
345
        return $appendix;
346
}
347
 
348
function is_root($id) {
349
        return empty(explode(':',$id,2)[1]);
350
}