Subversion Repositories oidplus

Rev

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