Subversion Repositories oidplus

Rev

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

Rev Author Line No. Line
139 daniel-mar 1
<?php
2
 
3
/*
4
 * OIDplus 2.0
5
 * Copyright 2019 Daniel Marschall, ViaThinkSoft
6
 *
7
 * Licensed under the Apache License, Version 2.0 (the "License");
8
 * you may not use this file except in compliance with the License.
9
 * You may obtain a copy of the License at
10
 *
11
 *     http://www.apache.org/licenses/LICENSE-2.0
12
 *
13
 * Unless required by applicable law or agreed to in writing, software
14
 * distributed under the License is distributed on an "AS IS" BASIS,
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 * See the License for the specific language governing permissions and
17
 * limitations under the License.
18
 */
19
 
256 daniel-mar 20
class OIDplusPageAdminRegistration extends OIDplusPagePluginAdmin {
139 daniel-mar 21
 
269 daniel-mar 22
        /*private*/ const QUERY_REGISTER_V1 =         '1.3.6.1.4.1.37476.2.5.2.1.1.1';
23
        /*private*/ const QUERY_UNREGISTER_V1 =       '1.3.6.1.4.1.37476.2.5.2.1.2.1';
24
        /*private*/ const QUERY_LISTALLSYSTEMIDS_V1 = '1.3.6.1.4.1.37476.2.5.2.1.3.1';
25
        /*private*/ const QUERY_LIVESTATUS_V1 =       '1.3.6.1.4.1.37476.2.5.2.1.4.1';
256 daniel-mar 26
 
139 daniel-mar 27
        public function action(&$handled) {
28
                // Nothing
29
        }
30
 
31
        public function gui($id, &$out, &$handled) {
141 daniel-mar 32
                if ($id === 'oidplus:srv_registration') {
139 daniel-mar 33
                        $handled = true;
141 daniel-mar 34
                        $out['title'] = 'System registration settings';
241 daniel-mar 35
                        $out['icon'] = file_exists(__DIR__.'/icon_big.png') ? OIDplus::webpath(__DIR__).'icon_big.png' : '';
139 daniel-mar 36
 
37
                        if (!OIDplus::authUtils()::isAdminLoggedIn()) {
38
                                $out['icon'] = 'img/error_big.png';
250 daniel-mar 39
                                $out['text'] = '<p>You need to <a '.OIDplus::gui()->link('oidplus:login').'>log in</a> as administrator.</p>';
281 daniel-mar 40
                                return;
41
                        }
42
 
43
                        $out['text'] = file_get_contents(__DIR__ . '/info.tpl');
44
 
45
                        if (!OIDplus::getPkiStatus()) {
46
                                $out['text'] .= '<p><font color="red">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>';
139 daniel-mar 47
                        } else {
281 daniel-mar 48
                                $out['text'] .= '<p><input type="button" onclick="openOidInPanel(\'oidplus:srvreg_status\');" value="Check status of the registration and collected data"></p>';
277 daniel-mar 49
 
281 daniel-mar 50
                                if (OIDplus::baseConfig()->getValue('REGISTRATION_HIDE_SYSTEM', false)) {
51
                                        $out['text'] .= '<p><font color="red"><b>Attention!</b> <code>REGISTRATION_HIDE_SYSTEM</code> is set in the local configuration file! Therefore, this system will not register itself, despire the settings below.</font></p>';
52
                                }
139 daniel-mar 53
 
281 daniel-mar 54
                                $out['text'] .= '<p>You can adjust your privacy level here:</p><p><select name="reg_privacy" id="reg_privacy">';
227 daniel-mar 55
 
281 daniel-mar 56
                                # ---
139 daniel-mar 57
 
281 daniel-mar 58
                                $out['text'] .= '<option value="0"';
59
                                if (OIDplus::config()->getValue('reg_privacy') == 0) {
60
                                        $out['text'] .= ' selected';
61
                                } else {
62
                                        $out['text'] .= '';
63
                                }
64
                                $out['text'] .= '>0 = Register to directory service and automatically publish RA/OID data at oid-info.com</option>';
139 daniel-mar 65
 
281 daniel-mar 66
                                # ---
139 daniel-mar 67
 
281 daniel-mar 68
                                $out['text'] .= '<option value="1"';
69
                                if (OIDplus::config()->getValue('reg_privacy') == 1) {
70
                                        $out['text'] .= ' selected';
71
                                } else {
72
                                        $out['text'] .= '';
73
                                }
74
                                $out['text'] .= '>1 = Only register to directory service</option>';
139 daniel-mar 75
 
281 daniel-mar 76
                                # ---
139 daniel-mar 77
 
281 daniel-mar 78
                                $out['text'] .= '<option value="2"';
79
                                if (OIDplus::config()->getValue('reg_privacy') == 2) {
80
                                        $out['text'] .= ' selected';
81
                                } else {
82
                                        $out['text'] .= '';
83
                                }
84
                                $out['text'] .= '>2 = Hide system</option>';
139 daniel-mar 85
 
281 daniel-mar 86
                                # ---
139 daniel-mar 87
 
281 daniel-mar 88
                                $out['text'] .= '</select> <input type="button" value="Change" onclick="crudActionRegPrivacyUpdate()"></p>';
139 daniel-mar 89
 
281 daniel-mar 90
                                $out['text'] .= '<p>After clicking "change", your OIDplus installation will contact the ViaThinkSoft server to adjust (add or remove information) your privacy setting. This may take a few minutes.</p>';
139 daniel-mar 91
 
281 daniel-mar 92
                                $out['text'] .= '<p><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>.';
139 daniel-mar 93
                        }
94
                }
141 daniel-mar 95
                if ($id === 'oidplus:srvreg_status') {
96
                        $handled = true;
97
 
256 daniel-mar 98
                        $query = self::QUERY_LIVESTATUS_V1;
141 daniel-mar 99
 
100
                        $payload = array(
101
                                "query" => $query, // we must repeat the query because we want to sign it
227 daniel-mar 102
                                "system_id" => OIDplus::getSystemId(false)
141 daniel-mar 103
                        );
104
 
105
                        $signature = '';
239 daniel-mar 106
                        if (!@openssl_sign(json_encode($payload), $signature, OIDplus::config()->getValue('oidplus_private_key'))) {
250 daniel-mar 107
                                throw new OIDplusException("Signature failed");
239 daniel-mar 108
                        }
141 daniel-mar 109
 
110
                        $data = array(
111
                                "payload" => $payload,
112
                                "signature" => base64_encode($signature)
113
                        );
114
 
115
                        $ch = curl_init();
116
                        curl_setopt($ch, CURLOPT_URL, 'https://oidplus.viathinksoft.com/reg2/query.php');
117
                        curl_setopt($ch, CURLOPT_POST, 1);
118
                        curl_setopt($ch, CURLOPT_POSTFIELDS, "query=$query&data=".base64_encode(json_encode($data)));
119
                        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
120
                        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
121
                        curl_setopt($ch, CURLOPT_AUTOREFERER, true);
239 daniel-mar 122
                        if (!($res = @curl_exec($ch))) {
250 daniel-mar 123
                                throw new OIDplusException("Communication with ViaThinkSoft server failed");
239 daniel-mar 124
                        }
141 daniel-mar 125
                        curl_close($ch);
126
                        // die("RES: $res\n");
127
                        // if ($res == 'OK') ...
128
 
129
                        $out['title'] = 'Registration live status';
250 daniel-mar 130
                        $out['text']  = '<p><a '.OIDplus::gui()->link('oidplus:srv_registration').'><img src="img/arrow_back.png" width="16"> Go back to registration settings</a></p>' .
142 daniel-mar 131
                                        $res;
141 daniel-mar 132
                }
139 daniel-mar 133
        }
134
 
140 daniel-mar 135
        public function sendRegistrationQuery($privacy_level=null) {
136
                if (is_null($privacy_level)) {
137
                        $privacy_level = OIDplus::config()->getValue('reg_privacy');
138
                }
139 daniel-mar 139
 
227 daniel-mar 140
                $system_url = OIDplus::getSystemUrl();
139 daniel-mar 141
 
175 daniel-mar 142
                // It is very important that we set the ping time NOW, because ViaThinkSoft might contact us during the ping,
143
                // and this would cause an endless loop!
144
                OIDplus::config()->setValue('reg_last_ping', time());
277 daniel-mar 145
 
239 daniel-mar 146
                if (!OIDplus::getPkiStatus()) return false;
175 daniel-mar 147
 
139 daniel-mar 148
                if ($privacy_level == 2) {
149
                        // The user wants to unregister
150
                        // but we only unregister if we are registered. Check this "anonymously" (i.e. without revealing our system ID)
256 daniel-mar 151
                        if (in_array(OIDplus::getSystemId(false), explode(';',file_get_contents('https://oidplus.viathinksoft.com/reg2/query.php?query='.self::QUERY_LISTALLSYSTEMIDS_V1)))) {
152
                                $query = self::QUERY_UNREGISTER_V1;
139 daniel-mar 153
 
154
                                $payload = array(
155
                                        "query" => $query, // we must repeat the query because we want to sign it
227 daniel-mar 156
                                        "system_id" => OIDplus::getSystemId(false)
139 daniel-mar 157
                                );
158
 
159
                                $signature = '';
239 daniel-mar 160
                                if (!@openssl_sign(json_encode($payload), $signature, OIDplus::config()->getValue('oidplus_private_key'))) {
250 daniel-mar 161
                                        return false; // throw new OIDplusException("Signature failed");
239 daniel-mar 162
                                }
139 daniel-mar 163
 
164
                                $data = array(
165
                                        "payload" => $payload,
166
                                        "signature" => base64_encode($signature)
167
                                );
168
 
169
                                $ch = curl_init();
170
                                curl_setopt($ch, CURLOPT_URL, 'https://oidplus.viathinksoft.com/reg2/query.php');
171
                                curl_setopt($ch, CURLOPT_POST, 1);
172
                                curl_setopt($ch, CURLOPT_POSTFIELDS, "query=$query&data=".base64_encode(json_encode($data)));
173
                                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
174
                                curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
175
                                curl_setopt($ch, CURLOPT_AUTOREFERER, true);
239 daniel-mar 176
                                if (!($res = @curl_exec($ch))) {
250 daniel-mar 177
                                        return false; // throw new OIDplusException("Communication with ViaThinkSoft server failed");
239 daniel-mar 178
                                }
139 daniel-mar 179
                                curl_close($ch);
180
                                // die("RES: $res\n");
181
                                // if ($res == 'OK') ...
182
                        }
183
                } else {
184
                        if ($privacy_level == 0) {
185
                                if (class_exists('OIDplusPageAdminOIDInfoExport')) {
186
                                        ob_start();
187
                                        OIDplusPageAdminOIDInfoExport::outputXML(false); // no online check, because the query should be short (since the query is done while a visitor waits for the response)
188
                                        $oidinfo_xml = ob_get_contents();
189
                                        ob_end_clean();
190
                                } else {
191
                                        $oidinfo_xml = false;
192
                                }
193
                        } else {
194
                                $oidinfo_xml = false;
195
                        }
196
 
256 daniel-mar 197
                        $query = self::QUERY_REGISTER_V1;
139 daniel-mar 198
 
199
                        $root_oids = array();
227 daniel-mar 200
                        foreach (OIDplus::getEnabledObjectTypes() as $ot) {
139 daniel-mar 201
                                if ($ot::ns() == 'oid') {
261 daniel-mar 202
                                        $res = OIDplus::db()->query("select id from ###objects where " .
139 daniel-mar 203
                                                                    "parent = 'oid:' " .
204
                                                                    "order by ".OIDplus::db()->natOrder('id'));
236 daniel-mar 205
                                        while ($row = $res->fetch_array()) {
139 daniel-mar 206
                                                $root_oids[] = substr($row['id'],strlen('oid:'));
207
                                        }
208
                                }
209
                        }
210
                        $payload = array(
211
                                "query" => $query, // we must repeat the query because we want to sign it
212
                                "privacy_level" => $privacy_level,
227 daniel-mar 213
                                "system_id" => OIDplus::getSystemId(false),
139 daniel-mar 214
                                "public_key" => OIDplus::config()->getValue('oidplus_public_key'),
215
                                "system_url" => $system_url,
216
                                "hide_system_url" => 0,
217
                                "hide_public_key" => 0,
218
                                "admin_email" => OIDplus::config()->getValue('admin_email'),
257 daniel-mar 219
                                "system_title" => OIDplus::config()->getValue('system_title'),
139 daniel-mar 220
                                "oidinfo_xml" => @base64_encode($oidinfo_xml),
170 daniel-mar 221
                                "root_oids" => $root_oids,
222
                                "system_version" => OIDplus::getVersion(),
223
                                "system_install_type" => OIDplus::getInstallType()
139 daniel-mar 224
                        );
225
 
226
                        $signature = '';
239 daniel-mar 227
                        if (!@openssl_sign(json_encode($payload), $signature, OIDplus::config()->getValue('oidplus_private_key'))) {
250 daniel-mar 228
                                        return false; // throw new OIDplusException("Signature failed");
239 daniel-mar 229
                        }
139 daniel-mar 230
 
231
                        $data = array(
232
                                "payload" => $payload,
233
                                "signature" => base64_encode($signature)
234
                        );
235
 
236
                        $ch = curl_init();
237
                        curl_setopt($ch, CURLOPT_URL, 'https://oidplus.viathinksoft.com/reg2/query.php');
238
                        curl_setopt($ch, CURLOPT_POST, 1);
239
                        curl_setopt($ch, CURLOPT_POSTFIELDS, "query=$query&data=".base64_encode(json_encode($data)));
240
                        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
241
                        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
242
                        curl_setopt($ch, CURLOPT_AUTOREFERER, true);
239 daniel-mar 243
                        if (!($res = @curl_exec($ch))) {
250 daniel-mar 244
                                return false; // throw new OIDplusException("Communication with ViaThinkSoft server failed");
239 daniel-mar 245
                        }
139 daniel-mar 246
                        curl_close($ch);
206 daniel-mar 247
 
248
                        if ($res === 'HASH_CONFLICT') {
288 daniel-mar 249
                                OIDplus::logger()->log("[WARN]A!", "Removing SystemID and key pair because there is a hash conflict with another OIDplus system!");
206 daniel-mar 250
 
251
                                // Delete the system ID since we have a conflict with the 31-bit hash!
252
                                OIDplus::config()->setValue('oidplus_private_key', '');
253
                                OIDplus::config()->setValue('oidplus_public_key', '');
254
 
255
                                // Try to generate a new system ID
227 daniel-mar 256
                                OIDplus::getPkiStatus(true);
206 daniel-mar 257
 
258
                                // Enforce a new registration attempt at the next run
259
                                // We will not try again here, because that might lead to an endless loop if the VTS server would always return 'HASH_CONFLCIT'
260
                                OIDplus::config()->setValue('reg_last_ping', 0);
261
                        }
262
 
139 daniel-mar 263
                        // die("RES: $res\n");
264
                        // if ($res == 'OK') ...
265
                }
266
        }
267
 
268
        public function init($html=true) {
263 daniel-mar 269
                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', '0', OIDplusConfig::PROTECTION_EDITABLE, function($value) {
270
                        if (($value != '0') && ($value != '1') && ($value != '2')) {
271
                                throw new OIDplusException("Please enter either 0, 1 or 2.");
272
                        }
273
                        // Now do a recheck and notify the ViaThinkSoft server
274
                        OIDplus::config()->setValue('reg_last_ping', 0);
275
                        $this->sendRegistrationQuery($value);
276
                });
277
                OIDplus::config()->prepareConfigKey('reg_ping_interval', 'Registration ping interval (in seconds)', '3600', OIDplusConfig::PROTECTION_HIDDEN, function($value) {
277 daniel-mar 278
 
263 daniel-mar 279
                });
280
                OIDplus::config()->prepareConfigKey('reg_last_ping', 'Last ping to ViaThinkSoft directory services', '0', OIDplusConfig::PROTECTION_HIDDEN, function($value) {
277 daniel-mar 281
 
263 daniel-mar 282
                });
277 daniel-mar 283
 
292 daniel-mar 284
                // Is it time to register / renew the directory entry?
285
                // Note: REGISTRATION_HIDE_SYSTEM is an undocumented constant that can be put in the config.inc.php files of a test system accessing the same database as the productive system that is registered.
286
                // 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)
277 daniel-mar 287
 
292 daniel-mar 288
                if (!OIDplus::baseConfig()->getValue('REGISTRATION_HIDE_SYSTEM', false)) {
289
                        $privacy_level = OIDplus::config()->getValue('reg_privacy');
139 daniel-mar 290
 
292 daniel-mar 291
                        if (php_sapi_name() !== 'cli') { // don't register when called from CLI, otherweise the oidinfo XML can't convert relative links into absolute links
292
                                if ((time()-OIDplus::config()->getValue('reg_last_ping') >= OIDplus::config()->getValue('reg_ping_interval'))) {
293
                                        $this->sendRegistrationQuery();
139 daniel-mar 294
                                }
295
                        }
296
                }
297
        }
298
 
299
        public function tree(&$json, $ra_email=null, $nonjs=false, $req_goto='') {
281 daniel-mar 300
                if (!OIDplus::authUtils()::isAdminLoggedIn()) return false;
292 daniel-mar 301
 
139 daniel-mar 302
                if (file_exists(__DIR__.'/treeicon.png')) {
241 daniel-mar 303
                        $tree_icon = OIDplus::webpath(__DIR__).'treeicon.png';
139 daniel-mar 304
                } else {
305
                        $tree_icon = null; // default icon (folder)
306
                }
307
 
308
                $json[] = array(
141 daniel-mar 309
                        'id' => 'oidplus:srv_registration',
139 daniel-mar 310
                        'icon' => $tree_icon,
206 daniel-mar 311
                        'text' => 'System registration'
139 daniel-mar 312
                );
313
 
314
                return true;
315
        }
316
 
317
        public function tree_search($request) {
318
                return false;
319
        }
292 daniel-mar 320
 
321
        public function implementsFeature($id) {
322
                if (strtolower($id) == '1.3.6.1.4.1.37476.2.5.2.3.1') return true; // oobeEntry
323
                return false;
324
        }
325
 
326
        public function oobeEntry($step, $do_edits, &$errors_happened)/*: void*/ {
327
                // Interface 1.3.6.1.4.1.37476.2.5.2.3.1
328
 
329
                echo "<p><u>Step $step: System registration and automatic publishing</u> (optional)</p>";
330
 
331
                echo file_get_contents(__DIR__ . '/info.tpl');
332
 
333
                $pki_status = OIDplus::getPkiStatus();
334
 
335
                if (!$pki_status) {
336
                        echo '<p>Note: Your system could not generate a private/public key pair. (OpenSSL is probably missing on your system). Therefore, you <b>cannot</b> register your OIDplus instance at the moment.</p>';
337
                } else {
338
 
339
                        echo '<p>Privacy level:</p><select name="reg_privacy" id="reg_privacy">';
340
 
341
                        # ---
342
 
343
                        echo '<option value="0"';
344
                        if (isset($_REQUEST['sent'])) {
345
                                if (isset($_REQUEST['reg_privacy']) && ($_REQUEST['reg_privacy'] == 0)) echo ' selected';
346
                        } else {
347
                                if ((OIDplus::config()->getValue('reg_privacy') == 0) || !OIDplus::config()->getValue('reg_wizard_done')) {
348
                                        echo ' selected';
349
                                } else {
350
                                        echo '';
351
                                }
352
                        }
353
                        echo '>0 = Register to directory service and automatically publish RA/OID data at oid-info.com</option>';
354
 
355
                        # ---
356
 
357
                        echo '<option value="1"';
358
                        if (isset($_REQUEST['sent'])) {
359
                                if (isset($_REQUEST['reg_privacy']) && ($_REQUEST['reg_privacy'] == 1)) echo ' selected';
360
                        } else {
361
                                if ((OIDplus::config()->getValue('reg_privacy') == 1)) {
362
                                        echo ' selected';
363
                                } else {
364
                                        echo '';
365
                                }
366
                        }
367
                        echo '>1 = Only register to directory service</option>';
368
 
369
                        # ---
370
 
371
                        echo '<option value="2"';
372
                        if (isset($_REQUEST['sent'])) {
373
                                if (isset($_REQUEST['reg_privacy']) && ($_REQUEST['reg_privacy'] == 2)) echo ' selected';
374
                        } else {
375
                                if ((OIDplus::config()->getValue('reg_privacy') == 2)) {
376
                                        echo ' selected';
377
                                } else {
378
                                        echo '';
379
                                }
380
                        }
381
                        echo '>2 = Hide system</option>';
382
 
383
                        # ---
384
 
385
                        echo '</select>';
386
 
387
                        $msg = '';
388
                        if ($do_edits) {
389
                                try {
390
                                        OIDplus::config()->setValue('reg_privacy', $_REQUEST['reg_privacy']);
391
                                } catch (Exception $e) {
392
                                        $msg = $e->getMessage();
393
                                        $errors_happened = true;
394
                                }
395
                        }
396
                        echo ' <font color="red"><b>'.$msg.'</b></font>';
397
 
398
                        echo '<p><i>Privacy information:</i> This setting can always be changed in the administrator login / control panel.<br>
399
                        <a href="../../../res/OIDplus/privacy_documentation.html" target="_blank">Click here</a> for more information about privacy related topics.</p>';
400
                }
401
        }
402
 
139 daniel-mar 403
}