Subversion Repositories oidplus

Rev

Rev 1029 | Rev 1050 | 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) {
1029 daniel-mar 231
 
635 daniel-mar 232
                if (is_null($privacy_level)) {
233
                        $privacy_level = OIDplus::config()->getValue('reg_privacy');
234
                }
235
 
801 daniel-mar 236
                $system_url = OIDplus::webpath(null,OIDplus::PATH_ABSOLUTE_CANONICAL);
635 daniel-mar 237
 
238
                // It is very important that we set the ping time NOW, because ViaThinkSoft might contact us during the ping,
239
                // and this would cause an endless loop!
240
                OIDplus::config()->setValue('reg_last_ping', time());
241
 
242
                if (!OIDplus::getPkiStatus()) return false;
243
 
244
                if ($privacy_level == 2) {
245
                        // The user wants to unregister,  but we only unregister if we are registered
246
                        if ($this->areWeRegistered()) {
247
                                $query = self::QUERY_UNREGISTER_V1;
248
 
249
                                $payload = array(
777 daniel-mar 250
                                        "query" => $query, // we must include $query to the payload, because we want to sign it
635 daniel-mar 251
                                        "system_id" => OIDplus::getSystemId(false)
252
                                );
253
 
254
                                $signature = '';
830 daniel-mar 255
                                if (!OIDplus::getPkiStatus() || !@openssl_sign(json_encode($payload), $signature, OIDplus::getSystemPrivateKey())) {
635 daniel-mar 256
                                        return false; // throw new OIDplusException(_L('Signature failed'));
257
                                }
258
 
259
                                $data = array(
260
                                        "payload" => $payload,
261
                                        "signature" => base64_encode($signature)
262
                                );
263
 
264
                                if (!function_exists('curl_init')) {
265
                                        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'));
266
                                }
267
 
268
                                $ch = curl_init();
269
                                if (ini_get('curl.cainfo') == '') curl_setopt($ch, CURLOPT_CAINFO, OIDplus::localpath() . 'vendor/cacert.pem');
270
                                curl_setopt($ch, CURLOPT_URL, 'https://oidplus.viathinksoft.com/reg2/query.php');
715 daniel-mar 271
                                curl_setopt($ch, CURLOPT_USERAGENT, 'ViaThinkSoft-OIDplus/2.0');
635 daniel-mar 272
                                curl_setopt($ch, CURLOPT_POST, 1);
273
                                if (function_exists('gzdeflate')) {
274
                                        $compressed = "1";
275
                                        $data2 = gzdeflate(json_encode($data));
276
                                } else {
277
                                        $compressed = "0";
278
                                        $data2 = json_encode($data);
279
                                }
280
                                curl_setopt($ch, CURLOPT_POSTFIELDS, "query=".urlencode($query)."&compressed=$compressed&data=".urlencode(base64_encode($data2)));
281
                                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
282
                                curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
283
                                curl_setopt($ch, CURLOPT_AUTOREFERER, true);
284
                                if (!($res = @curl_exec($ch))) {
285
                                        return false; // throw new OIDplusException(_L('Communication with ViaThinkSoft server failed: %1',curl_error($ch)));
286
                                }
287
                                curl_close($ch);
288
 
289
                                $json = @json_decode($res, true);
290
 
291
                                if (!$json) {
292
                                        return false; // throw new OIDplusException(_L('JSON reply from ViaThinkSoft decoding error: %1',$res));
293
                                }
294
 
295
                                if (isset($json['error']) || ($json['status'] < 0)) {
296
                                        if (isset($json['error'])) {
297
                                                return false; // throw new OIDplusException(_L('Received error status code: %1',$json['error']));
298
                                        } else {
299
                                                return false; // throw new OIDplusException(_L('Received error status code: %1',$json['status']));
300
                                        }
301
                                }
302
                        }
303
                } else {
304
                        if ($privacy_level == 0) {
305
                                $adminExportPlugin = OIDplus::getPluginByOid('1.3.6.1.4.1.37476.2.5.2.4.3.400'); // OIDplusPageAdminOIDInfoExport
306
                                if (!is_null($adminExportPlugin)) {
941 daniel-mar 307
                                        list($oidinfo_xml, $dummy_content_type) = OIDplusPageAdminOIDInfoExport::outputXML(false); // no online check, because the query should be short (since the query is done while a visitor waits for the response)
635 daniel-mar 308
                                } else {
309
                                        $oidinfo_xml = false;
310
                                }
311
                        } else {
312
                                $oidinfo_xml = false;
313
                        }
314
 
315
                        $query = self::QUERY_REGISTER_V1;
316
 
317
                        $root_oids = array();
318
                        foreach (OIDplus::getEnabledObjectTypes() as $ot) {
319
                                if ($ot::ns() == 'oid') {
320
                                        $res = OIDplus::db()->query("select id from ###objects where " .
321
                                                                    "(parent = 'oid:' or " .
322
                                                                    // 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!
323
                                                                    "parent in (select oid from ###asn1id where well_known = ?) or " .
324
                                                                    "parent in (select oid from ###iri where well_known = ?)) and " .
325
                                                                    // We assume hereby that RAs of well-known OIDs (e.g. IANA) will not use OIDplus for allocating OIDs:
326
                                                                    "id not in (select oid from ###asn1id where well_known = ?) and " .
327
                                                                    "id not in (select oid from ###iri where well_known = ?) " .
328
                                                                    "order by ".OIDplus::db()->natOrder('id'), array(true, true, true, true));
329
                                        while ($row = $res->fetch_array()) {
330
                                                $root_oids[] = substr($row['id'],strlen('oid:'));
331
                                        }
332
                                }
333
                        }
334
                        $payload = array(
777 daniel-mar 335
                                "query" => $query, // we must include $query to the payload, because we want to sign it
635 daniel-mar 336
                                "privacy_level" => $privacy_level,
337
                                "system_id" => OIDplus::getSystemId(false),
830 daniel-mar 338
                                "public_key" => OIDplus::getSystemPublicKey(),
635 daniel-mar 339
                                "system_url" => $system_url,
340
                                "hide_system_url" => 0,
341
                                "hide_public_key" => 0,
342
                                "admin_email" => OIDplus::config()->getValue('admin_email'),
343
                                "system_title" => OIDplus::config()->getValue('system_title'),
344
                                "oidinfo_xml" => @base64_encode($oidinfo_xml),
345
                                "root_oids" => $root_oids,
346
                                "system_version" => OIDplus::getVersion(),
347
                                "system_install_type" => OIDplus::getInstallType()
348
                        );
349
 
350
                        $signature = '';
830 daniel-mar 351
                        if (!OIDplus::getPkiStatus() || !@openssl_sign(json_encode($payload), $signature, OIDplus::getSystemPrivateKey())) {
635 daniel-mar 352
                                return false; // throw new OIDplusException(_L('Signature failed'));
353
                        }
354
 
355
                        $data = array(
356
                                "payload" => $payload,
357
                                "signature" => base64_encode($signature)
358
                        );
359
 
360
                        if (!function_exists('curl_init')) {
361
                                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'));
362
                        }
363
 
364
                        $ch = curl_init();
365
                        if (ini_get('curl.cainfo') == '') curl_setopt($ch, CURLOPT_CAINFO, OIDplus::localpath() . 'vendor/cacert.pem');
366
                        curl_setopt($ch, CURLOPT_URL, 'https://oidplus.viathinksoft.com/reg2/query.php');
715 daniel-mar 367
                        curl_setopt($ch, CURLOPT_USERAGENT, 'ViaThinkSoft-OIDplus/2.0');
635 daniel-mar 368
                        curl_setopt($ch, CURLOPT_POST, 1);
369
                        if (function_exists('gzdeflate')) {
370
                                $compressed = "1";
371
                                $data2 = gzdeflate(json_encode($data));
372
                        } else {
373
                                $compressed = "0";
374
                                $data2 = json_encode($data);
375
                        }
376
                        curl_setopt($ch, CURLOPT_POSTFIELDS, "query=".urlencode($query)."&compressed=$compressed&data=".urlencode(base64_encode($data2)));
377
                        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
378
                        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
379
                        curl_setopt($ch, CURLOPT_AUTOREFERER, true);
380
                        if (!($res = @curl_exec($ch))) {
381
                                return false; // throw new OIDplusException(_L('Communication with ViaThinkSoft server failed: %1',curl_error($ch)));
382
                        }
383
                        curl_close($ch);
384
 
385
                        $json = @json_decode($res, true);
386
 
387
                        if (!$json) {
388
                                return false; // throw new OIDplusException(_L('JSON reply from ViaThinkSoft decoding error: %1',$res));
389
                        }
390
 
391
                        if (isset($json['error']) || ($json['status'] < 0)) {
392
                                if (isset($json['error'])) {
393
                                        return false; // throw new OIDplusException(_L('Received error status code: %1',$json['error']));
394
                                } else {
395
                                        return false; // throw new OIDplusException(_L('Received error status code: %1',$json['status']));
396
                                }
397
                        } else if ($json['status'] == 99/*Hash conflict*/) {
398
                                OIDplus::logger()->log("[WARN]A!", "Removing SystemID and key pair because there is a hash conflict with another OIDplus system!");
399
 
400
                                // Delete the system ID since we have a conflict with the 31-bit hash!
401
                                OIDplus::config()->setValue('oidplus_private_key', '');
402
                                OIDplus::config()->setValue('oidplus_public_key', '');
403
 
404
                                // Try to generate a new system ID
405
                                OIDplus::getPkiStatus(true);
406
 
407
                                // Enforce a new registration attempt at the next page visit
408
                                // We will not try again here, because that might lead to an endless loop if the VTS server would always return 'HASH_CONFLCIT'
409
                                OIDplus::config()->setValue('reg_last_ping', 0);
776 daniel-mar 410
                        } else if ($json['status'] == 0/*OK*/) {
411
                                // Note: whois.viathinksoft.de:43 uses VGWhoIs, which uses these patterns: https://github.com/danielmarschall/vgwhois/blob/master/main/pattern/oid
412
                                // If your system gets acknowledged by ViaThinkSoft, then vts_whois will be filled with that server name whois.viathinksoft.de:43
413
                                if (isset($json['vts_whois'])) OIDplus::config()->setValue('vts_whois', $json['vts_whois']);
414
 
415
                                // ViaThinkSoft certifies the system public key and other system attributes and root objects (requires human verification)
416
                                if (isset($json['vts_cert'])) OIDplus::config()->setValue('vts_cert', $json['vts_cert']);
417
                                if (isset($json['vts_ca'])) OIDplus::config()->setValue('vts_ca', $json['vts_ca']);
635 daniel-mar 418
                        }
419
                }
420
        }
421
 
422
        public function init($html=true) {
699 daniel-mar 423
                if (OIDplus::getEditionInfo()['vendor'] != 'ViaThinkSoft') {
424
                        throw new OIDplusException(_L('This plugin is only available in the ViaThinkSoft edition of OIDplus'));
425
                }
426
 
635 daniel-mar 427
                // Note: It is important that the default value is '2', otherwise, systems which don't have CURL will fail
428
                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) {
429
                        if (($value != '0') && ($value != '1') && ($value != '2')) {
430
                                throw new OIDplusException(_L('Please enter either 0, 1 or 2.'));
431
                        }
432
                        // Now do a recheck and notify the ViaThinkSoft server
433
                        if (($value == 2) || !OIDplus::baseConfig()->getValue('REGISTRATION_HIDE_SYSTEM', false)) {
434
                                OIDplus::config()->setValue('reg_last_ping', 0);
435
                                $this->sendRegistrationQuery($value);
436
                        }
437
                });
438
                OIDplus::config()->prepareConfigKey('reg_ping_interval', 'Registration ping interval (in seconds)', '3600', OIDplusConfig::PROTECTION_HIDDEN, function($value) {
439
 
440
                });
441
                OIDplus::config()->prepareConfigKey('reg_last_ping', 'Last ping to ViaThinkSoft directory services', '0', OIDplusConfig::PROTECTION_HIDDEN, function($value) {
442
 
443
                });
776 daniel-mar 444
                OIDplus::config()->prepareConfigKey('vts_whois', 'ViaThinkSoft Whois Server (if this system is recognized)', '', OIDplusConfig::PROTECTION_READONLY, function($value) {
445
 
446
                });
447
                OIDplus::config()->prepareConfigKey('vts_cert', 'ViaThinkSoft certificate (requires registration)', '', OIDplusConfig::PROTECTION_HIDDEN, function($value) {
448
 
449
                });
450
                OIDplus::config()->prepareConfigKey('vts_ca', 'ViaThinkSoft certificate root (requires registration)', '', OIDplusConfig::PROTECTION_HIDDEN, function($value) {
451
 
452
                });
635 daniel-mar 453
                OIDplus::config()->prepareConfigKey('oobe_registration_done', '"Out Of Box Experience" wizard for OIDplusPageAdminRegistration done once?', '0', OIDplusConfig::PROTECTION_HIDDEN, function($value) {});
454
 
455
                // Is it time to register / renew the directory entry?
456
                // 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.
457
                // 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)
458
 
459
                if (OIDplus::config()->getValue('oobe_registration_done') == '1') {
460
                        if (!OIDplus::baseConfig()->getValue('REGISTRATION_HIDE_SYSTEM', false)) {
461
                                $privacy_level = OIDplus::config()->getValue('reg_privacy');
462
 
463
                                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 464
                                        $last_ping = OIDplus::config()->getValue('reg_last_ping');
465
                                        if (!is_numeric($last_ping)) $last_ping = 0;
466
                                        $last_ping_interval = OIDplus::config()->getValue('reg_ping_interval');
467
                                        if (!is_numeric($last_ping_interval)) $last_ping_interval = 3600;
852 daniel-mar 468
 
469
                                        // Cronjobs get half ping interval, to make sure that a web visitor won't get any delay
470
                                        if (OIDplus::isCronjob()) $last_ping_interval /= 2;
471
 
786 daniel-mar 472
                                        if ((time()-$last_ping >= $last_ping_interval)) {
635 daniel-mar 473
                                                $this->sendRegistrationQuery();
474
                                        }
475
                                }
476
                        }
477
                }
478
        }
479
 
480
        public function tree(&$json, $ra_email=null, $nonjs=false, $req_goto='') {
481
                if (!OIDplus::authUtils()->isAdminLoggedIn()) return false;
482
 
800 daniel-mar 483
                if (file_exists(__DIR__.'/img/main_icon16.png')) {
801 daniel-mar 484
                        $tree_icon = OIDplus::webpath(__DIR__,OIDplus::PATH_RELATIVE).'img/main_icon16.png';
635 daniel-mar 485
                } else {
486
                        $tree_icon = null; // default icon (folder)
487
                }
488
 
489
                $json[] = array(
490
                        'id' => 'oidplus:srv_registration',
491
                        'icon' => $tree_icon,
492
                        'text' => _L('System registration')
493
                );
494
 
495
                return true;
496
        }
497
 
498
        public function tree_search($request) {
499
                return false;
500
        }
501
 
502
        public function implementsFeature($id) {
503
                if (strtolower($id) == '1.3.6.1.4.1.37476.2.5.2.3.1') return true; // oobeEntry, oobeRequested
1000 daniel-mar 504
                if (strtolower($id) == '1.3.6.1.4.1.37476.2.5.2.3.8') return true; // getNotifications()
635 daniel-mar 505
                return false;
506
        }
507
 
508
        public function oobeRequested(): bool {
509
                // Interface 1.3.6.1.4.1.37476.2.5.2.3.1
510
 
511
                return OIDplus::config()->getValue('oobe_registration_done') == '0';
512
        }
513
 
514
        public function oobeEntry($step, $do_edits, &$errors_happened)/*: void*/ {
515
                // Interface 1.3.6.1.4.1.37476.2.5.2.3.1
516
 
517
                echo '<p><u>'._L('Step %1: System registration and automatic publishing (optional)',$step).'</u></p>';
518
 
519
                if (file_exists(__DIR__ . '/info$'.OIDplus::getCurrentLang().'.html')) {
520
                        $info = file_get_contents(__DIR__ . '/info$'.OIDplus::getCurrentLang().'.html');
521
                } else {
522
                        $info = file_get_contents(__DIR__ . '/info.html');
523
                }
524
 
525
                // make sure the program works even if the user provided HTML is not UTF-8
721 daniel-mar 526
                $info = convert_to_utf8_no_bom($info);
635 daniel-mar 527
 
528
                echo $info;
529
 
530
                if (!function_exists('curl_init')) {
531
                        echo '<p><font color="red">';
532
                        echo _L('The "%1" PHP extension is not installed at your system. Please enable the PHP extension <code>%2</code>.','CURL','php_curl').' ';
533
                        echo _L('Therefore, you <b>cannot</b> register your OIDplus instance now.');
534
                        echo '</font></p>';
535
                        if ($do_edits) {
536
                                OIDplus::config()->setValue('oobe_registration_done', '1');
537
                        }
538
                        return;
539
                }
540
 
541
                $pki_status = OIDplus::getPkiStatus();
542
 
543
                if (!$pki_status) {
544
                        echo '<p><font color="red">';
545
                        echo _L('Your system could not generate a private/public key pair. (OpenSSL is probably missing on your system).').' ';
546
                        echo _L('Therefore, you <b>cannot</b> register your OIDplus instance now.');
547
                        echo '</font></p>';
548
                        if ($do_edits) {
549
                                OIDplus::config()->setValue('oobe_registration_done', '1');
550
                        }
551
                        return;
552
                }
553
 
554
                echo '<p>'._L('Privacy level').':</p><select name="reg_privacy" id="reg_privacy">';
555
 
556
                # ---
557
 
558
                echo '<option value="0"';
1033 daniel-mar 559
                if (isset($_POST['sent'])) {
560
                        if (isset($_POST['reg_privacy']) && ($_POST['reg_privacy'] == 0)) echo ' selected';
635 daniel-mar 561
                } else {
562
                        if ((OIDplus::config()->getValue('reg_privacy') == 0) || !OIDplus::config()->getValue('oobe_registration_done')) {
563
                                echo ' selected';
564
                        } else {
565
                                echo '';
566
                        }
567
                }
568
                echo '>'._L('0 = Register to directory service and automatically publish RA/OID data at oid-info.com').'</option>';
569
 
570
                # ---
571
 
572
                echo '<option value="1"';
1033 daniel-mar 573
                if (isset($_POST['sent'])) {
574
                        if (isset($_POST['reg_privacy']) && ($_POST['reg_privacy'] == 1)) echo ' selected';
635 daniel-mar 575
                } else {
576
                        if ((OIDplus::config()->getValue('reg_privacy') == 1)) {
577
                                echo ' selected';
578
                        } else {
579
                                echo '';
580
                        }
581
                }
582
                echo '>'._L('1 = Only register to directory service').'</option>';
583
 
584
                # ---
585
 
586
                echo '<option value="2"';
1033 daniel-mar 587
                if (isset($_POST['sent'])) {
588
                        if (isset($_POST['reg_privacy']) && ($_POST['reg_privacy'] == 2)) echo ' selected';
635 daniel-mar 589
                } else {
590
                        if ((OIDplus::config()->getValue('reg_privacy') == 2)) {
591
                                echo ' selected';
592
                        } else {
593
                                echo '';
594
                        }
595
                }
596
                echo '>'._L('2 = Hide system').'</option>';
597
 
598
                # ---
599
 
600
                echo '</select>';
601
 
602
                $msg = '';
603
                if ($do_edits) {
604
                        try {
1033 daniel-mar 605
                                OIDplus::config()->setValue('reg_privacy', isset($_POST['reg_privacy']) ? $_POST['reg_privacy'] : 1);
635 daniel-mar 606
                                OIDplus::config()->setValue('oobe_registration_done', '1');
607
                        } catch (Exception $e) {
608
                                $msg = $e->getMessage();
609
                                $errors_happened = true;
610
                        }
611
                }
1029 daniel-mar 612
                if (!empty($msg)) echo ' <font color="red"><b>'.$msg.'</b></font>';
635 daniel-mar 613
 
614
                echo '<p>'._L('<i>Privacy information:</i> This setting can always be changed in the administrator login / control panel.').'<br>';
615
                echo _L('<a %1>Click here</a> for more information about privacy related topics.','href="../../../../res/OIDplus/privacy_documentation.html" target="_blank"');
616
                echo '</p>';
617
        }
618
 
1000 daniel-mar 619
        public function getNotifications($user=null): array {
620
                // Interface 1.3.6.1.4.1.37476.2.5.2.3.8
621
                $notifications = array();
622
                if ((!$user || ($user == 'admin')) && OIDplus::authUtils()->isAdminLoggedIn()) {
623
                        if (!function_exists('curl_init')) {
624
                                $title = _L('System registration');
1008 daniel-mar 625
                                $notifications[] = array('ERR', _L('OIDplus plugin "%1" is enabled, but the required PHP extension "%2" is not installed.', '<a '.OIDplus::gui()->link('oidplus:srv_registration').'>'.htmlentities($title).'</a>', 'php_curl'));
1000 daniel-mar 626
                        }
627
                }
628
                return $notifications;
629
        }
630
 
635 daniel-mar 631
}