Subversion Repositories oidplus

Rev

Rev 251 | 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
 
251 daniel-mar 113
                assert($row = $res->fetch_object());
101 daniel-mar 114
                $obj = OIDplusObject::parse($row->id);
115
 
116
                if (!empty($row->parent) && (!is_root($row->parent))) {
117
                        $out[] = 'parent: ' . $row->parent . show_asn1_appendix($row->parent);
118
                }
119
                $out[] = 'name: ' . $row->title;
120
 
121
                $cont = $row->description;
122
                $cont = preg_replace('@<a[^>]+href\s*=\s*["\']([^\'"]+)["\'][^>]*>(.+)<\s*/\s*a\s*>@ismU', '\2 (\1)', $cont);
123
                $out[] = 'description: ' . trim(html_entity_decode(strip_tags($cont)));
124
 
125
                if (substr($query,0,4) === 'oid:') {
261 daniel-mar 126
                        $res2 = OIDplus::db()->query("select * from ###asn1id where oid = ?", array($row->id));
236 daniel-mar 127
                        while ($row2 = $res2->fetch_object()) {
101 daniel-mar 128
                                $out[] = 'identifier: ' . $row2->name;
129
                        }
130
 
261 daniel-mar 131
                        $res2 = OIDplus::db()->query("select * from ###asn1id where standardized = ? and oid = ?", array(true, $row->id));
236 daniel-mar 132
                        while ($row2 = $res2->fetch_object()) {
101 daniel-mar 133
                                $out[] = 'standardized-id: ' . $row2->name;
134
                        }
135
 
261 daniel-mar 136
                        $res2 = OIDplus::db()->query("select * from ###iri where oid = ?", array($row->id));
236 daniel-mar 137
                        while ($row2 = $res2->fetch_object()) {
101 daniel-mar 138
                                $out[] = 'unicode-label: ' . $row2->name;
139
                        }
140
 
261 daniel-mar 141
                        $res2 = OIDplus::db()->query("select * from ###iri where longarc = ? and oid = ?", array(true, $row->id));
236 daniel-mar 142
                        while ($row2 = $res2->fetch_object()) {
101 daniel-mar 143
                                $out[] = 'long-arc: ' . $row2->name;
144
                        }
145
                }
146
 
147
                $out[] = 'created: ' . $row->created;
148
                $out[] = 'updated: ' . $row->updated;
149
 
261 daniel-mar 150
                $res2 = OIDplus::db()->query("select * from ###objects where parent = ? order by ".OIDplus::db()->natOrder('id'), array($row->id));
236 daniel-mar 151
                if ($res2->num_rows() == 0) {
101 daniel-mar 152
                        // $out[] = 'subordinate: (none)';
153
                }
236 daniel-mar 154
                while ($row2 = $res2->fetch_object()) {
101 daniel-mar 155
                        $out[] = 'subordinate: ' . $row2->id . show_asn1_appendix($row2->id);
156
                }
157
 
158
                $out[] = '';
159
 
261 daniel-mar 160
                $res2 = OIDplus::db()->query("select * from ###ra where email = ?", array($row->ra_email));
236 daniel-mar 161
                if ($row2 = $res2->fetch_object()) {
101 daniel-mar 162
                        $out[] = 'ra: '.(!empty($row2->ra_name) ? $row2->ra_name : $row2->email);
125 daniel-mar 163
                        $out[] = 'ra-status: Information available';
101 daniel-mar 164
                        $out[] = 'ra-name: ' . $row2->ra_name;
165
                        $out[] = 'ra-email: ' . $row->ra_email;
166
                        $out[] = 'ra-personal-name: ' . $row2->personal_name;
167
                        $out[] = 'ra-organization: ' . $row2->organization;
168
                        $out[] = 'ra-office: ' . $row2->office;
169
                        if ($row2->privacy && !$show_confidential) {
170
                                $out[] = 'ra-street: ' . (!empty($row2->street) ? '(redacted)' : '');
171
                                $out[] = 'ra-town: ' . (!empty($row2->zip_town) ? '(redacted)' : '');
172
                                $out[] = 'ra-country: ' . (!empty($row2->country) ? '(redacted)' : '');
173
                                $out[] = 'ra-phone: ' . (!empty($row2->phone) ? '(redacted)' : '');
174
                                $out[] = 'ra-mobile: ' . (!empty($row2->mobile) ? '(redacted)' : '');
175
                                $out[] = 'ra-fax: ' . (!empty($row2->fax) ? '(redacted)' : '');
176
                        } else {
177
                                $out[] = 'ra-street: ' . $row2->street;
178
                                $out[] = 'ra-zip_town: ' . $row2->zip_town;
179
                                $out[] = 'ra-country: ' . $row2->country;
180
                                $out[] = 'ra-phone: ' . $row2->phone;
181
                                $out[] = 'ra-mobile: ' . $row2->mobile;
182
                                $out[] = 'ra-fax: ' . $row2->fax;
183
                        }
184
                        $out[] = 'ra-created: ' . $row2->registered;
185
                        $out[] = 'ra-updated: ' . $row2->updated;
186
                } else {
187
                        $out[] = 'ra: '.$row->ra_email;
125 daniel-mar 188
                        $out[] = "ra-status: Information unavailable";
101 daniel-mar 189
                }
190
        }
191
}
192
 
193
// Step 2: Format output
194
 
195
ob_start();
196
 
201 daniel-mar 197
$format = isset($_REQUEST['format']) ? $_REQUEST['format'] : 'txt';
101 daniel-mar 198
 
201 daniel-mar 199
if ($format == 'txt') {
200
        header('Content-Type:text/plain; charset=UTF-8');
101 daniel-mar 201
 
201 daniel-mar 202
        $longest_key = 0;
203
        foreach ($out as $line) {
204
                $longest_key = max($longest_key, strlen(trim(explode(':',$line,2)[0])));
101 daniel-mar 205
        }
206
 
261 daniel-mar 207
        echo '% ' . str_repeat('*', OIDplus::config()->getValue('webwhois_output_format_max_line_length', 80)-2)."\n";
101 daniel-mar 208
 
201 daniel-mar 209
        foreach ($out as $line) {
210
                if (trim($line) == '') {
211
                        echo "\n";
212
                        continue;
213
                }
101 daniel-mar 214
 
201 daniel-mar 215
                $ary = explode(':', $line, 2);
101 daniel-mar 216
 
201 daniel-mar 217
                $key = trim($ary[0]);
218
 
219
                $value = trim($ary[1]);
261 daniel-mar 220
                $value = wordwrap($value, OIDplus::config()->getValue('webwhois_output_format_max_line_length', 80) - $longest_key - strlen(':') - OIDplus::config()->getValue('webwhois_output_format_spacer', 2));
221
                $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 222
 
261 daniel-mar 223
                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 224
        }
225
 
261 daniel-mar 226
        echo '% ' . str_repeat('*', OIDplus::config()->getValue('webwhois_output_format_max_line_length', 80)-2)."\n";
201 daniel-mar 227
 
228
        $cont = ob_get_contents();
229
        ob_end_clean();
230
 
231
        echo $cont;
232
 
227 daniel-mar 233
        if (OIDplus::getPkiStatus(true)) {
201 daniel-mar 234
                $signature = '';
239 daniel-mar 235
                if (@openssl_sign($cont, $signature, OIDplus::config()->getValue('oidplus_private_key'))) {
201 daniel-mar 236
                        $signature = base64_encode($signature);
237
                        $signature = wordwrap($signature, 80, "\n", true);
238
 
239
                        $signature = "-----BEGIN RSA SIGNATURE-----\n".
240
                                     "$signature\n".
241
                                     "-----END RSA SIGNATURE-----\n";
242
                        echo $signature;
243
                }
244
        }
101 daniel-mar 245
}
246
 
201 daniel-mar 247
if ($format == 'json') {
248
        $ary = array();
101 daniel-mar 249
 
201 daniel-mar 250
        $current_section = array();
251
        $ary[] = &$current_section;
101 daniel-mar 252
 
201 daniel-mar 253
        foreach ($out as $line) {
254
                if ($line == '') {
255
                        unset($current_section);
256
                        $current_section = array();
257
                        $ary[] = &$current_section;
258
                } else {
259
                        list($key,$val) = explode(':', $line, 2);
260
                        $val = trim($val);
261
                        if (!isset($current_section[$key])) {
262
                                $current_section[$key] = $val;
263
                        } elseif (is_array($current_section[$key])) {
264
                                $current_section[$key][] = $val;
265
                        } else {
266
                                $current_section[$key] = array($current_section[$key], $val);
267
                        }
268
                }
269
        }
270
        $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 271
 
227 daniel-mar 272
        if (OIDplus::getPkiStatus(true)) {
201 daniel-mar 273
                $cont = json_encode($ary);
274
                $signature = '';
239 daniel-mar 275
                if (@openssl_sign($cont, $signature, OIDplus::config()->getValue('oidplus_private_key'))) {
201 daniel-mar 276
                        $signature = base64_encode($signature);
277
                        $ary['signature'] = array('content' => $cont, 'signature' => $signature);
278
                }
279
        }
280
        header('Content-Type:application/json; charset=UTF-8');
281
        echo json_encode($ary);
282
}
101 daniel-mar 283
 
201 daniel-mar 284
if ($format == 'xml') {
285
        $xml = '<whois><section>';
286
        foreach ($out as $line) {
287
                if ($line == '') {
288
                        $xml .= '</section><section>';
289
                } else {
290
                        list($key,$val) = explode(':', $line, 2);
291
                        $val = trim($val);
292
                        $xml .= "<$key>".htmlspecialchars($val)."</$key>";
293
                }
294
        }
295
        $xml .= '</section></whois>';
101 daniel-mar 296
 
227 daniel-mar 297
        if (OIDplus::getPkiStatus(true)) {
201 daniel-mar 298
                $cont = $xml;
299
                $signature = '';
239 daniel-mar 300
                if (@openssl_sign($cont, $signature, OIDplus::config()->getValue('oidplus_private_key'))) {
201 daniel-mar 301
                        $signature = base64_encode($signature);
302
                        $xml .= "<signature><content>".htmlspecialchars($cont)."</content><signature>".htmlspecialchars($signature)."</signature></signature>";
303
                }
101 daniel-mar 304
        }
201 daniel-mar 305
 
306
        header('Content-Type:application/xml; charset=UTF-8');
307
        echo '<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>';
308
        echo '<root>'.$xml.'</root>';
101 daniel-mar 309
}
310
 
311
# ---
312
 
313
function show_asn1_appendix($id) {
314
        if (substr($id,0,4) === 'oid:') {
315
                $appendix_asn1ids = array();
261 daniel-mar 316
                $res3 = OIDplus::db()->query("select * from ###asn1id where oid = ?", array($id));
236 daniel-mar 317
                while ($row3 = $res3->fetch_object()) {
101 daniel-mar 318
                        $appendix_asn1ids[] = $row3->name;
319
                }
320
 
321
                $appendix = implode(', ', $appendix_asn1ids);
322
                if (!empty($appendix)) $appendix = " ($appendix)";
323
        } else {
324
                $appendix = '';
325
        }
326
        return $appendix;
327
}
328
 
329
function is_root($id) {
330
        return empty(explode(':',$id,2)[1]);
331
}