Subversion Repositories oidplus

Rev

Rev 830 | Rev 941 | 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
776 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
if (!defined('INSIDE_OIDPLUS')) die();
21
 
22
class OIDplusPageAdminRegistration extends OIDplusPagePluginAdmin {
23
 
24
        /*private*/ const QUERY_REGISTER_V1 =         '1.3.6.1.4.1.37476.2.5.2.1.1.1';
25
        /*private*/ const QUERY_UNREGISTER_V1 =       '1.3.6.1.4.1.37476.2.5.2.1.2.1';
26
        /*private*/ const QUERY_LISTALLSYSTEMIDS_V1 = '1.3.6.1.4.1.37476.2.5.2.1.3.1';
27
        /*private*/ const QUERY_LIVESTATUS_V1 =       '1.3.6.1.4.1.37476.2.5.2.1.4.1';
28
 
29
        public function csrfUnlock($actionID) {
30
                if ($actionID == 'verify_pubkey') return true;
31
                return parent::csrfUnlock($actionID);
32
        }
33
 
34
        public function action($actionID, $params) {
35
                if ($actionID == 'verify_pubkey') {
36
                        _CheckParamExists($params, 'challenge');
37
 
38
                        $payload = 'oidplus-verify-pubkey:'.sha3_512($params['challenge']);
39
 
40
                        $signature = '';
830 daniel-mar 41
                        if (!OIDplus::getPkiStatus() || !@openssl_sign($payload, $signature, OIDplus::getSystemPrivateKey())) {
635 daniel-mar 42
                                throw new OIDplusException(_L('Signature failed'));
43
                        }
44
 
45
                        return array(
46
                                "status" => 0,
47
                                "response" => base64_encode($signature)
48
                        );
49
                } else {
50
                        throw new OIDplusException(_L('Unknown action ID'));
51
                }
52
        }
53
 
54
        public function gui($id, &$out, &$handled) {
55
                if ($id === 'oidplus:srv_registration') {
56
                        $handled = true;
57
                        $out['title'] = _L('System registration settings');
801 daniel-mar 58
                        $out['icon'] = file_exists(__DIR__.'/img/main_icon.png') ? OIDplus::webpath(__DIR__,OIDplus::PATH_RELATIVE).'img/main_icon.png' : '';
635 daniel-mar 59
 
60
                        if (!OIDplus::authUtils()->isAdminLoggedIn()) {
800 daniel-mar 61
                                $out['icon'] = 'img/error.png';
635 daniel-mar 62
                                $out['text'] = '<p>'._L('You need to <a %1>log in</a> as administrator.',OIDplus::gui()->link('oidplus:login$admin')).'</p>';
63
                                return;
64
                        }
65
 
66
                        if (file_exists(__DIR__ . '/info$'.OIDplus::getCurrentLang().'.html')) {
67
                                $info = file_get_contents(__DIR__ . '/info$'.OIDplus::getCurrentLang().'.html');
68
                        } else {
69
                                $info = file_get_contents(__DIR__ . '/info.html');
70
                        }
71
 
72
                        list($html, $js, $css) = extractHtmlContents($info);
73
                        $info = '';
74
                        if (!empty($js))  $info .= "<script>\n$js\n</script>";
75
                        if (!empty($css)) $info .= "<style>\n$css\n</style>";
821 daniel-mar 76
                        $info .= stripHtmlComments($html);
635 daniel-mar 77
 
78
                        $out['text'] = $info;
79
 
80
                        if (!OIDplus::getPkiStatus()) {
81
                                $out['text'] .= '<p><font color="red">'._L('Error: Your system could not generate a private/public key pair. (OpenSSL is probably missing on your system). Therefore, you cannot register/unregister your OIDplus instance.').'</font></p>';
82
                        } else {
83
                                $out['text'] .= '<p><input type="button" onclick="openOidInPanel(\'oidplus:srvreg_status\');" value="'._L('Check status of the registration and collected data').'"></p>';
84
 
85
                                if (OIDplus::baseConfig()->getValue('REGISTRATION_HIDE_SYSTEM', false)) {
86
                                        $out['text'] .= '<p><font color="red"><b>'._L('Attention!').'</b> '._L('<code>REGISTRATION_HIDE_SYSTEM</code> is set in the local configuration file! Therefore, this system will not register itself, despite of the settings below.').'</font></p>';
87
                                }
88
 
89
                                $out['text'] .= '<p>'._L('You can adjust your privacy level here').':</p><p><select name="reg_privacy" id="reg_privacy">';
90
 
91
                                # ---
92
 
93
                                $out['text'] .= '<option value="0"';
94
                                if (OIDplus::config()->getValue('reg_privacy') == 0) {
95
                                        $out['text'] .= ' selected';
96
                                } else {
97
                                        $out['text'] .= '';
98
                                }
99
                                $out['text'] .= '>'._L('0 = Register to directory service and automatically publish RA/OID data at oid-info.com').'</option>';
100
 
101
                                # ---
102
 
103
                                $out['text'] .= '<option value="1"';
104
                                if (OIDplus::config()->getValue('reg_privacy') == 1) {
105
                                        $out['text'] .= ' selected';
106
                                } else {
107
                                        $out['text'] .= '';
108
                                }
109
                                $out['text'] .= '>'._L('1 = Only register to directory service').'</option>';
110
 
111
                                # ---
112
 
113
                                $out['text'] .= '<option value="2"';
114
                                if (OIDplus::config()->getValue('reg_privacy') == 2) {
115
                                        $out['text'] .= ' selected';
116
                                } else {
117
                                        $out['text'] .= '';
118
                                }
119
                                $out['text'] .= '>'._L('2 = Hide system').'</option>';
120
 
121
                                # ---
122
 
123
                                $out['text'] .= '</select> <input type="button" value="'._L('Change').'" onclick="OIDplusPageAdminRegistration.crudActionRegPrivacyUpdate()"></p>';
124
 
125
                                $out['text'] .= '<p>'._L('After clicking "change", your OIDplus system will contact the ViaThinkSoft server to adjust (add or remove information) your privacy setting. This may take a few minutes.').'</p>';
126
 
127
                                $out['text'] .= '<p>'._L('<i>Privacy information:</i> Please note that removing your system from the directory does not automatically delete information about OIDs which are already published at oid-info.com. To remove already submitted OIDs at oid-info.com, please contact the <a href="mailto:admin@oid-info.com">OID Repository Webmaster</a>.').'</p>';
128
                        }
129
                }
130
                if ($id === 'oidplus:srvreg_status') {
131
                        $handled = true;
132
                        $out['title'] = _L('Registration live status');
801 daniel-mar 133
                        $out['icon'] = file_exists(__DIR__.'/img/main_icon.png') ? OIDplus::webpath(__DIR__,OIDplus::PATH_RELATIVE).'img/main_icon.png' : '';
635 daniel-mar 134
 
135
                        if (!OIDplus::authUtils()->isAdminLoggedIn()) {
800 daniel-mar 136
                                $out['icon'] = 'img/error.png';
635 daniel-mar 137
                                $out['text'] = '<p>'._L('You need to <a %1>log in</a> as administrator.',OIDplus::gui()->link('oidplus:login$admin')).'</p>';
138
                                return;
139
                        }
140
 
141
                        $query = self::QUERY_LIVESTATUS_V1;
142
 
143
                        $payload = array(
777 daniel-mar 144
                                "query" => $query, // we must include $query to the playload, because we want to sign it
635 daniel-mar 145
                                "lang" => OIDplus::getCurrentLang(),
146
                                "system_id" => OIDplus::getSystemId(false)
147
                        );
148
 
149
                        $signature = '';
830 daniel-mar 150
                        if (!OIDplus::getPkiStatus() || !@openssl_sign(json_encode($payload), $signature, OIDplus::getSystemPrivateKey())) {
635 daniel-mar 151
                                throw new OIDplusException(_L('Signature failed'));
152
                        }
153
 
154
                        $data = array(
155
                                "payload" => $payload,
156
                                "signature" => base64_encode($signature)
157
                        );
158
 
159
                        if (!function_exists('curl_init')) {
160
                                throw new OIDplusException(_L('The "%1" PHP extension is not installed at your system. Please enable the PHP extension <code>%2</code>.','CURL','php_curl'));
161
                        }
162
 
163
                        $ch = curl_init();
164
                        if (ini_get('curl.cainfo') == '') curl_setopt($ch, CURLOPT_CAINFO, OIDplus::localpath() . 'vendor/cacert.pem');
165
                        curl_setopt($ch, CURLOPT_URL, 'https://oidplus.viathinksoft.com/reg2/query.php');
715 daniel-mar 166
                        curl_setopt($ch, CURLOPT_USERAGENT, 'ViaThinkSoft-OIDplus/2.0');
635 daniel-mar 167
                        curl_setopt($ch, CURLOPT_POST, 1);
168
                        if (function_exists('gzdeflate')) {
169
                                $compressed = "1";
170
                                $data2 = gzdeflate(json_encode($data));
171
                        } else {
172
                                $compressed = "0";
173
                                $data2 = json_encode($data);
174
                        }
175
                        curl_setopt($ch, CURLOPT_POSTFIELDS, "query=".urlencode($query)."&compressed=$compressed&data=".urlencode(base64_encode($data2)));
176
                        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
177
                        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
178
                        curl_setopt($ch, CURLOPT_AUTOREFERER, true);
179
                        if (!($res = @curl_exec($ch))) {
180
                                throw new OIDplusException(_L('Communication with ViaThinkSoft server failed: %1',curl_error($ch)));
181
                        }
182
                        curl_close($ch);
183
 
184
                        $json = @json_decode($res, true);
185
 
186
                        if (!$json) {
800 daniel-mar 187
                                $out['icon'] = 'img/error.png';
635 daniel-mar 188
                                $out['text'] = _L('JSON reply from ViaThinkSoft decoding error: %1',$res);
189
                                return;
190
                        }
191
 
192
                        if (isset($json['error']) || ($json['status'] < 0)) {
800 daniel-mar 193
                                $out['icon'] = 'img/error.png';
635 daniel-mar 194
                                if (isset($json['error'])) {
195
                                        $out['text'] = _L('Received error status code: %1',$json['error']);
196
                                } else {
197
                                        $out['text'] = _L('Received error status code: %1',$json['status']);
198
                                }
199
                                return;
200
                        }
201
 
202
                        $out['text']  = '<p><a '.OIDplus::gui()->link('oidplus:srv_registration').'><img src="img/arrow_back.png" width="16" alt="'._L('Go back').'"> '._L('Go back to registration settings').'</a></p>' .
203
                                        $json['content'];
204
                }
205
        }
206
 
207
        protected function areWeRegistered() {
208
                // To check if we are registered. Check it "anonymously" (i.e. without revealing our system ID)
715 daniel-mar 209
                $res = url_get_contents('https://oidplus.viathinksoft.com/reg2/query.php?query='.self::QUERY_LISTALLSYSTEMIDS_V1);
635 daniel-mar 210
 
211
                $json = @json_decode($res, true);
212
 
213
                if (!$json) {
214
                        return false; // throw new OIDplusException(_L('JSON reply from ViaThinkSoft decoding error: %1',$res));
215
                }
216
 
217
                if (isset($json['error']) || ($json['status'] < 0)) {
218
                        if (isset($json['error'])) {
219
                                return false; // throw new OIDplusException(_L('Received error status code: %1',$json['error']));
220
                        } else {
221
                                return false; // throw new OIDplusException(_L('Received error status code: %1',$json['status']));
222
                        }
223
                }
224
 
225
                $list = $json['list'];
226
 
227
                return in_array(OIDplus::getSystemId(false), $list);
228
        }
229
 
230
        public function sendRegistrationQuery($privacy_level=null) {
231
                if (is_null($privacy_level)) {
232
                        $privacy_level = OIDplus::config()->getValue('reg_privacy');
233
                }
234
 
801 daniel-mar 235
                $system_url = OIDplus::webpath(null,OIDplus::PATH_ABSOLUTE_CANONICAL);
635 daniel-mar 236
 
237
                // It is very important that we set the ping time NOW, because ViaThinkSoft might contact us during the ping,
238
                // and this would cause an endless loop!
239
                OIDplus::config()->setValue('reg_last_ping', time());
240
 
241
                if (!OIDplus::getPkiStatus()) return false;
242
 
243
                if ($privacy_level == 2) {
244
                        // The user wants to unregister,  but we only unregister if we are registered
245
                        if ($this->areWeRegistered()) {
246
                                $query = self::QUERY_UNREGISTER_V1;
247
 
248
                                $payload = array(
777 daniel-mar 249
                                        "query" => $query, // we must include $query to the payload, because we want to sign it
635 daniel-mar 250
                                        "system_id" => OIDplus::getSystemId(false)
251
                                );
252
 
253
                                $signature = '';
830 daniel-mar 254
                                if (!OIDplus::getPkiStatus() || !@openssl_sign(json_encode($payload), $signature, OIDplus::getSystemPrivateKey())) {
635 daniel-mar 255
                                        return false; // throw new OIDplusException(_L('Signature failed'));
256
                                }
257
 
258
                                $data = array(
259
                                        "payload" => $payload,
260
                                        "signature" => base64_encode($signature)
261
                                );
262
 
263
                                if (!function_exists('curl_init')) {
264
                                        return false; // throw new OIDplusException(_L('The "%1" PHP extension is not installed at your system. Please enable the PHP extension <code>%2</code>.','CURL','php_curl'));
265
                                }
266
 
267
                                $ch = curl_init();
268
                                if (ini_get('curl.cainfo') == '') curl_setopt($ch, CURLOPT_CAINFO, OIDplus::localpath() . 'vendor/cacert.pem');
269
                                curl_setopt($ch, CURLOPT_URL, 'https://oidplus.viathinksoft.com/reg2/query.php');
715 daniel-mar 270
                                curl_setopt($ch, CURLOPT_USERAGENT, 'ViaThinkSoft-OIDplus/2.0');
635 daniel-mar 271
                                curl_setopt($ch, CURLOPT_POST, 1);
272
                                if (function_exists('gzdeflate')) {
273
                                        $compressed = "1";
274
                                        $data2 = gzdeflate(json_encode($data));
275
                                } else {
276
                                        $compressed = "0";
277
                                        $data2 = json_encode($data);
278
                                }
279
                                curl_setopt($ch, CURLOPT_POSTFIELDS, "query=".urlencode($query)."&compressed=$compressed&data=".urlencode(base64_encode($data2)));
280
                                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
281
                                curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
282
                                curl_setopt($ch, CURLOPT_AUTOREFERER, true);
283
                                if (!($res = @curl_exec($ch))) {
284
                                        return false; // throw new OIDplusException(_L('Communication with ViaThinkSoft server failed: %1',curl_error($ch)));
285
                                }
286
                                curl_close($ch);
287
 
288
                                $json = @json_decode($res, true);
289
 
290
                                if (!$json) {
291
                                        return false; // throw new OIDplusException(_L('JSON reply from ViaThinkSoft decoding error: %1',$res));
292
                                }
293
 
294
                                if (isset($json['error']) || ($json['status'] < 0)) {
295
                                        if (isset($json['error'])) {
296
                                                return false; // throw new OIDplusException(_L('Received error status code: %1',$json['error']));
297
                                        } else {
298
                                                return false; // throw new OIDplusException(_L('Received error status code: %1',$json['status']));
299
                                        }
300
                                }
301
                        }
302
                } else {
303
                        if ($privacy_level == 0) {
304
                                $adminExportPlugin = OIDplus::getPluginByOid('1.3.6.1.4.1.37476.2.5.2.4.3.400'); // OIDplusPageAdminOIDInfoExport
305
                                if (!is_null($adminExportPlugin)) {
306
                                        ob_start();
307
                                        OIDplusPageAdminOIDInfoExport::outputXML(false); // no online check, because the query should be short (since the query is done while a visitor waits for the response)
308
                                        $oidinfo_xml = ob_get_contents();
309
                                        ob_end_clean();
310
                                } else {
311
                                        $oidinfo_xml = false;
312
                                }
313
                        } else {
314
                                $oidinfo_xml = false;
315
                        }
316
 
317
                        $query = self::QUERY_REGISTER_V1;
318
 
319
                        $root_oids = array();
320
                        foreach (OIDplus::getEnabledObjectTypes() as $ot) {
321
                                if ($ot::ns() == 'oid') {
322
                                        $res = OIDplus::db()->query("select id from ###objects where " .
323
                                                                    "(parent = 'oid:' or " .
324
                                                                    // The following two cases are special cases e.g. if there are multiple PEN or UUID-OIDs, and the system owner decides to use the IANA PEN as root OID, but actually, it is not "his" root then! The OIDs inside the IANA PEN root are his root then!
325
                                                                    "parent in (select oid from ###asn1id where well_known = ?) or " .
326
                                                                    "parent in (select oid from ###iri where well_known = ?)) and " .
327
                                                                    // We assume hereby that RAs of well-known OIDs (e.g. IANA) will not use OIDplus for allocating OIDs:
328
                                                                    "id not in (select oid from ###asn1id where well_known = ?) and " .
329
                                                                    "id not in (select oid from ###iri where well_known = ?) " .
330
                                                                    "order by ".OIDplus::db()->natOrder('id'), array(true, true, true, true));
331
                                        while ($row = $res->fetch_array()) {
332
                                                $root_oids[] = substr($row['id'],strlen('oid:'));
333
                                        }
334
                                }
335
                        }
336
                        $payload = array(
777 daniel-mar 337
                                "query" => $query, // we must include $query to the payload, because we want to sign it
635 daniel-mar 338
                                "privacy_level" => $privacy_level,
339
                                "system_id" => OIDplus::getSystemId(false),
830 daniel-mar 340
                                "public_key" => OIDplus::getSystemPublicKey(),
635 daniel-mar 341
                                "system_url" => $system_url,
342
                                "hide_system_url" => 0,
343
                                "hide_public_key" => 0,
344
                                "admin_email" => OIDplus::config()->getValue('admin_email'),
345
                                "system_title" => OIDplus::config()->getValue('system_title'),
346
                                "oidinfo_xml" => @base64_encode($oidinfo_xml),
347
                                "root_oids" => $root_oids,
348
                                "system_version" => OIDplus::getVersion(),
349
                                "system_install_type" => OIDplus::getInstallType()
350
                        );
351
 
352
                        $signature = '';
830 daniel-mar 353
                        if (!OIDplus::getPkiStatus() || !@openssl_sign(json_encode($payload), $signature, OIDplus::getSystemPrivateKey())) {
635 daniel-mar 354
                                return false; // throw new OIDplusException(_L('Signature failed'));
355
                        }
356
 
357
                        $data = array(
358
                                "payload" => $payload,
359
                                "signature" => base64_encode($signature)
360
                        );
361
 
362
                        if (!function_exists('curl_init')) {
363
                                return false; // throw new OIDplusException(_L('The "%1" PHP extension is not installed at your system. Please enable the PHP extension <code>%2</code>.','CURL','php_curl'));
364
                        }
365
 
366
                        $ch = curl_init();
367
                        if (ini_get('curl.cainfo') == '') curl_setopt($ch, CURLOPT_CAINFO, OIDplus::localpath() . 'vendor/cacert.pem');
368
                        curl_setopt($ch, CURLOPT_URL, 'https://oidplus.viathinksoft.com/reg2/query.php');
715 daniel-mar 369
                        curl_setopt($ch, CURLOPT_USERAGENT, 'ViaThinkSoft-OIDplus/2.0');
635 daniel-mar 370
                        curl_setopt($ch, CURLOPT_POST, 1);
371
                        if (function_exists('gzdeflate')) {
372
                                $compressed = "1";
373
                                $data2 = gzdeflate(json_encode($data));
374
                        } else {
375
                                $compressed = "0";
376
                                $data2 = json_encode($data);
377
                        }
378
                        curl_setopt($ch, CURLOPT_POSTFIELDS, "query=".urlencode($query)."&compressed=$compressed&data=".urlencode(base64_encode($data2)));
379
                        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
380
                        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
381
                        curl_setopt($ch, CURLOPT_AUTOREFERER, true);
382
                        if (!($res = @curl_exec($ch))) {
383
                                return false; // throw new OIDplusException(_L('Communication with ViaThinkSoft server failed: %1',curl_error($ch)));
384
                        }
385
                        curl_close($ch);
386
 
387
                        $json = @json_decode($res, true);
388
 
389
                        if (!$json) {
390
                                return false; // throw new OIDplusException(_L('JSON reply from ViaThinkSoft decoding error: %1',$res));
391
                        }
392
 
393
                        if (isset($json['error']) || ($json['status'] < 0)) {
394
                                if (isset($json['error'])) {
395
                                        return false; // throw new OIDplusException(_L('Received error status code: %1',$json['error']));
396
                                } else {
397
                                        return false; // throw new OIDplusException(_L('Received error status code: %1',$json['status']));
398
                                }
399
                        } else if ($json['status'] == 99/*Hash conflict*/) {
400
                                OIDplus::logger()->log("[WARN]A!", "Removing SystemID and key pair because there is a hash conflict with another OIDplus system!");
401
 
402
                                // Delete the system ID since we have a conflict with the 31-bit hash!
403
                                OIDplus::config()->setValue('oidplus_private_key', '');
404
                                OIDplus::config()->setValue('oidplus_public_key', '');
405
 
406
                                // Try to generate a new system ID
407
                                OIDplus::getPkiStatus(true);
408
 
409
                                // Enforce a new registration attempt at the next page visit
410
                                // We will not try again here, because that might lead to an endless loop if the VTS server would always return 'HASH_CONFLCIT'
411
                                OIDplus::config()->setValue('reg_last_ping', 0);
776 daniel-mar 412
                        } else if ($json['status'] == 0/*OK*/) {
413
                                // Note: whois.viathinksoft.de:43 uses VGWhoIs, which uses these patterns: https://github.com/danielmarschall/vgwhois/blob/master/main/pattern/oid
414
                                // If your system gets acknowledged by ViaThinkSoft, then vts_whois will be filled with that server name whois.viathinksoft.de:43
415
                                if (isset($json['vts_whois'])) OIDplus::config()->setValue('vts_whois', $json['vts_whois']);
416
 
417
                                // ViaThinkSoft certifies the system public key and other system attributes and root objects (requires human verification)
418
                                if (isset($json['vts_cert'])) OIDplus::config()->setValue('vts_cert', $json['vts_cert']);
419
                                if (isset($json['vts_ca'])) OIDplus::config()->setValue('vts_ca', $json['vts_ca']);
635 daniel-mar 420
                        }
421
                }
422
        }
423
 
424
        public function init($html=true) {
699 daniel-mar 425
                if (OIDplus::getEditionInfo()['vendor'] != 'ViaThinkSoft') {
426
                        throw new OIDplusException(_L('This plugin is only available in the ViaThinkSoft edition of OIDplus'));
427
                }
428
 
635 daniel-mar 429
                // Note: It is important that the default value is '2', otherwise, systems which don't have CURL will fail
430
                OIDplus::config()->prepareConfigKey('reg_privacy', '2=Hide your system, 1=Register your system to the ViaThinkSoft directory and oid-info.com, 0=Publish your system to ViaThinkSoft directory and all public contents (RA/OID) to oid-info.com', '2', OIDplusConfig::PROTECTION_EDITABLE, function($value) {
431
                        if (($value != '0') && ($value != '1') && ($value != '2')) {
432
                                throw new OIDplusException(_L('Please enter either 0, 1 or 2.'));
433
                        }
434
                        // Now do a recheck and notify the ViaThinkSoft server
435
                        if (($value == 2) || !OIDplus::baseConfig()->getValue('REGISTRATION_HIDE_SYSTEM', false)) {
436
                                OIDplus::config()->setValue('reg_last_ping', 0);
437
                                $this->sendRegistrationQuery($value);
438
                        }
439
                });
440
                OIDplus::config()->prepareConfigKey('reg_ping_interval', 'Registration ping interval (in seconds)', '3600', OIDplusConfig::PROTECTION_HIDDEN, function($value) {
441
 
442
                });
443
                OIDplus::config()->prepareConfigKey('reg_last_ping', 'Last ping to ViaThinkSoft directory services', '0', OIDplusConfig::PROTECTION_HIDDEN, function($value) {
444
 
445
                });
776 daniel-mar 446
                OIDplus::config()->prepareConfigKey('vts_whois', 'ViaThinkSoft Whois Server (if this system is recognized)', '', OIDplusConfig::PROTECTION_READONLY, function($value) {
447
 
448
                });
449
                OIDplus::config()->prepareConfigKey('vts_cert', 'ViaThinkSoft certificate (requires registration)', '', OIDplusConfig::PROTECTION_HIDDEN, function($value) {
450
 
451
                });
452
                OIDplus::config()->prepareConfigKey('vts_ca', 'ViaThinkSoft certificate root (requires registration)', '', OIDplusConfig::PROTECTION_HIDDEN, function($value) {
453
 
454
                });
635 daniel-mar 455
                OIDplus::config()->prepareConfigKey('oobe_registration_done', '"Out Of Box Experience" wizard for OIDplusPageAdminRegistration done once?', '0', OIDplusConfig::PROTECTION_HIDDEN, function($value) {});
456
 
457
                // Is it time to register / renew the directory entry?
458
                // Note: REGISTRATION_HIDE_SYSTEM is an undocumented constant that can be put in the userdata/baseconfig/config.inc.php files of a test system accessing the same database as the productive system that is registered.
459
                // This avoids that the URL of a productive system is overridden with the URL of a cloned test system (since they use the same database, they also have the same system ID)
460
 
461
                if (OIDplus::config()->getValue('oobe_registration_done') == '1') {
462
                        if (!OIDplus::baseConfig()->getValue('REGISTRATION_HIDE_SYSTEM', false)) {
463
                                $privacy_level = OIDplus::config()->getValue('reg_privacy');
464
 
465
                                if (PHP_SAPI !== 'cli') { // don't register when called from CLI, otherwise the oidinfo XML can't convert relative links into absolute links
786 daniel-mar 466
                                        $last_ping = OIDplus::config()->getValue('reg_last_ping');
467
                                        if (!is_numeric($last_ping)) $last_ping = 0;
468
                                        $last_ping_interval = OIDplus::config()->getValue('reg_ping_interval');
469
                                        if (!is_numeric($last_ping_interval)) $last_ping_interval = 3600;
852 daniel-mar 470
 
471
                                        // Cronjobs get half ping interval, to make sure that a web visitor won't get any delay
472
                                        if (OIDplus::isCronjob()) $last_ping_interval /= 2;
473
 
786 daniel-mar 474
                                        if ((time()-$last_ping >= $last_ping_interval)) {
635 daniel-mar 475
                                                $this->sendRegistrationQuery();
476
                                        }
477
                                }
478
                        }
479
                }
480
        }
481
 
482
        public function tree(&$json, $ra_email=null, $nonjs=false, $req_goto='') {
483
                if (!OIDplus::authUtils()->isAdminLoggedIn()) return false;
484
 
800 daniel-mar 485
                if (file_exists(__DIR__.'/img/main_icon16.png')) {
801 daniel-mar 486
                        $tree_icon = OIDplus::webpath(__DIR__,OIDplus::PATH_RELATIVE).'img/main_icon16.png';
635 daniel-mar 487
                } else {
488
                        $tree_icon = null; // default icon (folder)
489
                }
490
 
491
                $json[] = array(
492
                        'id' => 'oidplus:srv_registration',
493
                        'icon' => $tree_icon,
494
                        'text' => _L('System registration')
495
                );
496
 
497
                return true;
498
        }
499
 
500
        public function tree_search($request) {
501
                return false;
502
        }
503
 
504
        public function implementsFeature($id) {
505
                if (strtolower($id) == '1.3.6.1.4.1.37476.2.5.2.3.1') return true; // oobeEntry, oobeRequested
506
                return false;
507
        }
508
 
509
        public function oobeRequested(): bool {
510
                // Interface 1.3.6.1.4.1.37476.2.5.2.3.1
511
 
512
                return OIDplus::config()->getValue('oobe_registration_done') == '0';
513
        }
514
 
515
        public function oobeEntry($step, $do_edits, &$errors_happened)/*: void*/ {
516
                // Interface 1.3.6.1.4.1.37476.2.5.2.3.1
517
 
518
                echo '<p><u>'._L('Step %1: System registration and automatic publishing (optional)',$step).'</u></p>';
519
 
520
                if (file_exists(__DIR__ . '/info$'.OIDplus::getCurrentLang().'.html')) {
521
                        $info = file_get_contents(__DIR__ . '/info$'.OIDplus::getCurrentLang().'.html');
522
                } else {
523
                        $info = file_get_contents(__DIR__ . '/info.html');
524
                }
525
 
526
                // make sure the program works even if the user provided HTML is not UTF-8
721 daniel-mar 527
                $info = convert_to_utf8_no_bom($info);
635 daniel-mar 528
 
529
                echo $info;
530
 
531
                if (!function_exists('curl_init')) {
532
                        echo '<p><font color="red">';
533
                        echo _L('The "%1" PHP extension is not installed at your system. Please enable the PHP extension <code>%2</code>.','CURL','php_curl').' ';
534
                        echo _L('Therefore, you <b>cannot</b> register your OIDplus instance now.');
535
                        echo '</font></p>';
536
                        if ($do_edits) {
537
                                OIDplus::config()->setValue('oobe_registration_done', '1');
538
                        }
539
                        return;
540
                }
541
 
542
                $testurl = 'https://www.google.com/';
543
                $ch = curl_init();
544
                if (ini_get('curl.cainfo') == '') curl_setopt($ch, CURLOPT_CAINFO, OIDplus::localpath() . 'vendor/cacert.pem');
545
                curl_setopt($ch, CURLOPT_URL, $testurl);
715 daniel-mar 546
                curl_setopt($ch, CURLOPT_USERAGENT, 'ViaThinkSoft-OIDplus/2.0');
635 daniel-mar 547
                curl_setopt($ch, CURLOPT_HEADER, TRUE);
548
                curl_setopt($ch, CURLOPT_NOBODY, TRUE);
549
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
550
                curl_exec($ch);
551
                $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
552
                curl_close($ch);
553
                if (!$httpCode) {
554
                        echo '<p><font color="red">';
555
                        echo _L('The "CURL" PHP extension cannot access HTTPS webpages. Therefore, you cannot use this feature. Please download <a href="https://curl.haxx.se/ca/cacert.pem">cacert.pem</a>, place it somewhere and then adjust the setting <code>curl.cainfo</code> in PHP.ini.').' ';
556
                        echo _L('Therefore, you <b>cannot</b> register your OIDplus instance now.');
557
                        echo '</font></p>';
558
                        if ($do_edits) {
559
                                OIDplus::config()->setValue('oobe_registration_done', '1');
560
                        }
561
                        return;
562
                }
563
 
564
                $pki_status = OIDplus::getPkiStatus();
565
 
566
                if (!$pki_status) {
567
                        echo '<p><font color="red">';
568
                        echo _L('Your system could not generate a private/public key pair. (OpenSSL is probably missing on your system).').' ';
569
                        echo _L('Therefore, you <b>cannot</b> register your OIDplus instance now.');
570
                        echo '</font></p>';
571
                        if ($do_edits) {
572
                                OIDplus::config()->setValue('oobe_registration_done', '1');
573
                        }
574
                        return;
575
                }
576
 
577
                echo '<p>'._L('Privacy level').':</p><select name="reg_privacy" id="reg_privacy">';
578
 
579
                # ---
580
 
581
                echo '<option value="0"';
582
                if (isset($_REQUEST['sent'])) {
583
                        if (isset($_REQUEST['reg_privacy']) && ($_REQUEST['reg_privacy'] == 0)) echo ' selected';
584
                } else {
585
                        if ((OIDplus::config()->getValue('reg_privacy') == 0) || !OIDplus::config()->getValue('oobe_registration_done')) {
586
                                echo ' selected';
587
                        } else {
588
                                echo '';
589
                        }
590
                }
591
                echo '>'._L('0 = Register to directory service and automatically publish RA/OID data at oid-info.com').'</option>';
592
 
593
                # ---
594
 
595
                echo '<option value="1"';
596
                if (isset($_REQUEST['sent'])) {
597
                        if (isset($_REQUEST['reg_privacy']) && ($_REQUEST['reg_privacy'] == 1)) echo ' selected';
598
                } else {
599
                        if ((OIDplus::config()->getValue('reg_privacy') == 1)) {
600
                                echo ' selected';
601
                        } else {
602
                                echo '';
603
                        }
604
                }
605
                echo '>'._L('1 = Only register to directory service').'</option>';
606
 
607
                # ---
608
 
609
                echo '<option value="2"';
610
                if (isset($_REQUEST['sent'])) {
611
                        if (isset($_REQUEST['reg_privacy']) && ($_REQUEST['reg_privacy'] == 2)) echo ' selected';
612
                } else {
613
                        if ((OIDplus::config()->getValue('reg_privacy') == 2)) {
614
                                echo ' selected';
615
                        } else {
616
                                echo '';
617
                        }
618
                }
619
                echo '>'._L('2 = Hide system').'</option>';
620
 
621
                # ---
622
 
623
                echo '</select>';
624
 
625
                $msg = '';
626
                if ($do_edits) {
627
                        try {
628
                                OIDplus::config()->setValue('reg_privacy', isset($_REQUEST['reg_privacy']) ? $_REQUEST['reg_privacy'] : 1);
629
                                OIDplus::config()->setValue('oobe_registration_done', '1');
630
                        } catch (Exception $e) {
631
                                $msg = $e->getMessage();
632
                                $errors_happened = true;
633
                        }
634
                }
635
                echo ' <font color="red"><b>'.$msg.'</b></font>';
636
 
637
                echo '<p>'._L('<i>Privacy information:</i> This setting can always be changed in the administrator login / control panel.').'<br>';
638
                echo _L('<a %1>Click here</a> for more information about privacy related topics.','href="../../../../res/OIDplus/privacy_documentation.html" target="_blank"');
639
                echo '</p>';
640
        }
641
 
642
}