Subversion Repositories oidplus

Rev

Rev 236 | 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
 
20
if (!defined('IN_OIDPLUS')) die();
21
 
22
define('QUERY_REGISTER_V1',         '1.3.6.1.4.1.37476.2.5.2.1.1.1');
23
define('QUERY_UNREGISTER_V1',       '1.3.6.1.4.1.37476.2.5.2.1.2.1');
24
define('QUERY_LISTALLSYSTEMIDS_V1', '1.3.6.1.4.1.37476.2.5.2.1.3.1');
141 daniel-mar 25
define('QUERY_LIVESTATUS_V1',       '1.3.6.1.4.1.37476.2.5.2.1.4.1');
139 daniel-mar 26
 
148 daniel-mar 27
class OIDplusPageAdminRegistration extends OIDplusPagePlugin {
222 daniel-mar 28
        public static function getPluginInformation() {
29
                $out = array();
30
                $out['name'] = 'System registration';
31
                $out['author'] = 'ViaThinkSoft';
32
                $out['version'] = null;
33
                $out['descriptionHTML'] = null;
34
                return $out;
35
        }
36
 
139 daniel-mar 37
        public function type() {
38
                return 'admin';
39
        }
40
 
41
        public function priority() {
42
                return 120;
43
        }
44
 
45
        public function action(&$handled) {
46
                // Nothing
47
        }
48
 
49
        public function cfgSetValue($name, $value) {
50
                if ($name == 'reg_privacy') {
51
                        if (($value != '0') && ($value != '1') && ($value != '2')) {
52
                                throw new Exception("Please enter either 0, 1 or 2.");
53
                        }
140 daniel-mar 54
                        // Now do a recheck and notify the ViaThinkSoft server
55
                        OIDplus::config()->setValue('reg_last_ping', 0);
56
                        $this->sendRegistrationQuery($value);
139 daniel-mar 57
                }
58
        }
59
 
60
        public function gui($id, &$out, &$handled) {
141 daniel-mar 61
                if ($id === 'oidplus:srv_registration') {
139 daniel-mar 62
                        $handled = true;
141 daniel-mar 63
                        $out['title'] = 'System registration settings';
148 daniel-mar 64
                        $out['icon'] = file_exists(__DIR__.'/icon_big.png') ? 'plugins/'.basename(dirname(__DIR__)).'/'.basename(__DIR__).'/icon_big.png' : '';
139 daniel-mar 65
 
66
                        if (!OIDplus::authUtils()::isAdminLoggedIn()) {
67
                                $out['icon'] = 'img/error_big.png';
153 daniel-mar 68
                                $out['text'] = '<p>You need to <a '.oidplus_link('oidplus:login').'>log in</a> as administrator.</p>';
139 daniel-mar 69
                        } else {
239 daniel-mar 70
                                $out['text'] = file_get_contents(__DIR__ . '/info.tpl');
71
 
72
                                if (!OIDplus::getPkiStatus()) {
73
                                        $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>';
74
                                } else {
75
                                        $out['text'] .= '<p><input type="button" onclick="openOidInPanel(\'oidplus:srvreg_status\');" value="Check status of the registration and collected data"></p>';
139 daniel-mar 76
 
239 daniel-mar 77
                                        if (defined('REGISTRATION_HIDE_SYSTEM') && REGISTRATION_HIDE_SYSTEM) {
78
                                                $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>';
79
                                        }
227 daniel-mar 80
 
139 daniel-mar 81
                                        $out['text'] .= '<p>You can adjust your privacy level here:</p><p><select name="reg_privacy" id="reg_privacy">';
82
 
83
                                        # ---
84
 
85
                                        $out['text'] .= '<option value="0"';
86
                                        if (OIDplus::config()->getValue('reg_privacy') == 0) {
87
                                                $out['text'] .= ' selected';
88
                                        } else {
89
                                                $out['text'] .= '';
90
                                        }
91
                                        $out['text'] .= '>0 = Register to directory service and automatically publish RA/OID data at oid-info.com</option>';
92
 
93
                                        # ---
94
 
95
                                        $out['text'] .= '<option value="1"';
96
                                        if (OIDplus::config()->getValue('reg_privacy') == 1) {
97
                                                $out['text'] .= ' selected';
98
                                        } else {
99
                                                $out['text'] .= '';
100
                                        }
101
                                        $out['text'] .= '>1 = Only register to directory service</option>';
102
 
103
                                        # ---
104
 
105
                                        $out['text'] .= '<option value="2"';
106
                                        if (OIDplus::config()->getValue('reg_privacy') == 2) {
107
                                                $out['text'] .= ' selected';
108
                                        } else {
109
                                                $out['text'] .= '';
110
                                        }
111
                                        $out['text'] .= '>2 = Hide system</option>';
112
 
113
                                        # ---
114
 
115
                                        $out['text'] .= '</select> <input type="button" value="Change" onclick="crudActionRegPrivacyUpdate()"></p>';
116
 
117
                                        $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>';
239 daniel-mar 118
 
119
                                        $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 120
                                }
121
                        }
122
                }
141 daniel-mar 123
                if ($id === 'oidplus:srvreg_status') {
124
                        $handled = true;
125
 
126
                        $query = QUERY_LIVESTATUS_V1;
127
 
128
                        $payload = array(
129
                                "query" => $query, // we must repeat the query because we want to sign it
227 daniel-mar 130
                                "system_id" => OIDplus::getSystemId(false)
141 daniel-mar 131
                        );
132
 
133
                        $signature = '';
239 daniel-mar 134
                        if (!@openssl_sign(json_encode($payload), $signature, OIDplus::config()->getValue('oidplus_private_key'))) {
135
                                throw new Exception("Signature failed");
136
                        }
141 daniel-mar 137
 
138
                        $data = array(
139
                                "payload" => $payload,
140
                                "signature" => base64_encode($signature)
141
                        );
142
 
143
                        $ch = curl_init();
144
                        curl_setopt($ch, CURLOPT_URL, 'https://oidplus.viathinksoft.com/reg2/query.php');
145
                        curl_setopt($ch, CURLOPT_POST, 1);
146
                        curl_setopt($ch, CURLOPT_POSTFIELDS, "query=$query&data=".base64_encode(json_encode($data)));
147
                        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
148
                        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
149
                        curl_setopt($ch, CURLOPT_AUTOREFERER, true);
239 daniel-mar 150
                        if (!($res = @curl_exec($ch))) {
151
                                throw new Exception("Communication with ViaThinkSoft server failed");
152
                        }
141 daniel-mar 153
                        curl_close($ch);
154
                        // die("RES: $res\n");
155
                        // if ($res == 'OK') ...
156
 
157
                        $out['title'] = 'Registration live status';
142 daniel-mar 158
                        $out['text']  = '<p><a '.oidplus_link('oidplus:srv_registration').'><img src="img/arrow_back.png" width="16"> Go back to registration settings</a></p>' .
159
                                        $res;
141 daniel-mar 160
                }
139 daniel-mar 161
        }
162
 
140 daniel-mar 163
        public function sendRegistrationQuery($privacy_level=null) {
164
                if (is_null($privacy_level)) {
165
                        $privacy_level = OIDplus::config()->getValue('reg_privacy');
166
                }
139 daniel-mar 167
 
227 daniel-mar 168
                $system_url = OIDplus::getSystemUrl();
139 daniel-mar 169
 
175 daniel-mar 170
                // It is very important that we set the ping time NOW, because ViaThinkSoft might contact us during the ping,
171
                // and this would cause an endless loop!
172
                OIDplus::config()->setValue('reg_last_ping', time());
239 daniel-mar 173
 
174
                if (!OIDplus::getPkiStatus()) return false;
175 daniel-mar 175
 
139 daniel-mar 176
                if ($privacy_level == 2) {
177
                        // The user wants to unregister
178
                        // but we only unregister if we are registered. Check this "anonymously" (i.e. without revealing our system ID)
227 daniel-mar 179
                        if (in_array(OIDplus::getSystemId(false), explode(';',file_get_contents('https://oidplus.viathinksoft.com/reg2/query.php?query='.QUERY_LISTALLSYSTEMIDS_V1)))) {
139 daniel-mar 180
                                $query = QUERY_UNREGISTER_V1;
181
 
182
                                $payload = array(
183
                                        "query" => $query, // we must repeat the query because we want to sign it
227 daniel-mar 184
                                        "system_id" => OIDplus::getSystemId(false)
139 daniel-mar 185
                                );
186
 
187
                                $signature = '';
239 daniel-mar 188
                                if (!@openssl_sign(json_encode($payload), $signature, OIDplus::config()->getValue('oidplus_private_key'))) {
189
                                        return false; // throw new Exception("Signature failed");
190
                                }
139 daniel-mar 191
 
192
                                $data = array(
193
                                        "payload" => $payload,
194
                                        "signature" => base64_encode($signature)
195
                                );
196
 
197
                                $ch = curl_init();
198
                                curl_setopt($ch, CURLOPT_URL, 'https://oidplus.viathinksoft.com/reg2/query.php');
199
                                curl_setopt($ch, CURLOPT_POST, 1);
200
                                curl_setopt($ch, CURLOPT_POSTFIELDS, "query=$query&data=".base64_encode(json_encode($data)));
201
                                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
202
                                curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
203
                                curl_setopt($ch, CURLOPT_AUTOREFERER, true);
239 daniel-mar 204
                                if (!($res = @curl_exec($ch))) {
205
                                        return false; // throw new Exception("Communication with ViaThinkSoft server failed");
206
                                }
139 daniel-mar 207
                                curl_close($ch);
208
                                // die("RES: $res\n");
209
                                // if ($res == 'OK') ...
210
                        }
211
                } else {
212
                        if ($privacy_level == 0) {
213
                                if (class_exists('OIDplusPageAdminOIDInfoExport')) {
214
                                        ob_start();
215
                                        OIDplusPageAdminOIDInfoExport::outputXML(false); // no online check, because the query should be short (since the query is done while a visitor waits for the response)
216
                                        $oidinfo_xml = ob_get_contents();
217
                                        ob_end_clean();
218
                                } else {
219
                                        $oidinfo_xml = false;
220
                                }
221
                        } else {
222
                                $oidinfo_xml = false;
223
                        }
224
 
225
                        $query = QUERY_REGISTER_V1;
226
 
227
                        $root_oids = array();
227 daniel-mar 228
                        foreach (OIDplus::getEnabledObjectTypes() as $ot) {
139 daniel-mar 229
                                if ($ot::ns() == 'oid') {
230
                                        $res = OIDplus::db()->query("select id from ".OIDPLUS_TABLENAME_PREFIX."objects where " .
231
                                                                    "parent = 'oid:' " .
232
                                                                    "order by ".OIDplus::db()->natOrder('id'));
236 daniel-mar 233
                                        while ($row = $res->fetch_array()) {
139 daniel-mar 234
                                                $root_oids[] = substr($row['id'],strlen('oid:'));
235
                                        }
236
                                }
237
                        }
238
                        $payload = array(
239
                                "query" => $query, // we must repeat the query because we want to sign it
240
                                "privacy_level" => $privacy_level,
227 daniel-mar 241
                                "system_id" => OIDplus::getSystemId(false),
139 daniel-mar 242
                                "public_key" => OIDplus::config()->getValue('oidplus_public_key'),
243
                                "system_url" => $system_url,
244
                                "hide_system_url" => 0,
245
                                "hide_public_key" => 0,
246
                                "admin_email" => OIDplus::config()->getValue('admin_email'),
247
                                "system_title" => OIDplus::config()->systemTitle(),
248
                                "oidinfo_xml" => @base64_encode($oidinfo_xml),
170 daniel-mar 249
                                "root_oids" => $root_oids,
250
                                "system_version" => OIDplus::getVersion(),
251
                                "system_install_type" => OIDplus::getInstallType()
139 daniel-mar 252
                        );
253
 
254
                        $signature = '';
239 daniel-mar 255
                        if (!@openssl_sign(json_encode($payload), $signature, OIDplus::config()->getValue('oidplus_private_key'))) {
256
                                        return false; // throw new Exception("Signature failed");
257
                        }
139 daniel-mar 258
 
259
                        $data = array(
260
                                "payload" => $payload,
261
                                "signature" => base64_encode($signature)
262
                        );
263
 
264
                        $ch = curl_init();
265
                        curl_setopt($ch, CURLOPT_URL, 'https://oidplus.viathinksoft.com/reg2/query.php');
266
                        curl_setopt($ch, CURLOPT_POST, 1);
267
                        curl_setopt($ch, CURLOPT_POSTFIELDS, "query=$query&data=".base64_encode(json_encode($data)));
268
                        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
269
                        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
270
                        curl_setopt($ch, CURLOPT_AUTOREFERER, true);
239 daniel-mar 271
                        if (!($res = @curl_exec($ch))) {
272
                                return false; // throw new Exception("Communication with ViaThinkSoft server failed");
273
                        }
139 daniel-mar 274
                        curl_close($ch);
206 daniel-mar 275
 
276
                        if ($res === 'HASH_CONFLICT') {
277
                                OIDplus::logger()->log("A!", "Removing SystemID and key pair because there is a hash conflict with another OIDplus system!");
278
 
279
                                // Delete the system ID since we have a conflict with the 31-bit hash!
280
                                OIDplus::config()->setValue('oidplus_private_key', '');
281
                                OIDplus::config()->setValue('oidplus_public_key', '');
282
 
283
                                // Try to generate a new system ID
227 daniel-mar 284
                                OIDplus::getPkiStatus(true);
206 daniel-mar 285
 
286
                                // Enforce a new registration attempt at the next run
287
                                // We will not try again here, because that might lead to an endless loop if the VTS server would always return 'HASH_CONFLCIT'
288
                                OIDplus::config()->setValue('reg_last_ping', 0);
289
                        }
290
 
139 daniel-mar 291
                        // die("RES: $res\n");
292
                        // if ($res == 'OK') ...
293
                }
294
        }
295
 
296
        public function init($html=true) {
297
                OIDplus::config()->prepareConfigKey('reg_wizard_done', 'Registration wizard done once?', '0', 1, 0);
298
                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', 0, 1);
299
                OIDplus::config()->prepareConfigKey('reg_ping_interval', 'Registration ping interval (in seconds)', '3600', 0, 0);
300
                OIDplus::config()->prepareConfigKey('reg_last_ping', 'Last ping to ViaThinkSoft directory services', '0', 1, 0);
239 daniel-mar 301
 
302
                $oobe_done = OIDplus::config()->getValue('reg_wizard_done') == '1';
303
 
304
                if (!$oobe_done) {
305
                        // Show registration/configuration wizard once
306
                        if ($html) {
139 daniel-mar 307
                                if (basename($_SERVER['SCRIPT_NAME']) != 'registration.php') {
227 daniel-mar 308
                                        if ($system_url = OIDplus::getSystemUrl()) {
148 daniel-mar 309
                                                header('Location:'.$system_url.'plugins/'.basename(dirname(__DIR__)).'/'.basename(__DIR__).'/registration.php');
139 daniel-mar 310
                                        } else {
148 daniel-mar 311
                                                header('Location:plugins/'.basename(dirname(__DIR__)).'/'.basename(__DIR__).'/registration.php');
139 daniel-mar 312
                                        }
313
                                        die();
314
                                }
315
                        }
239 daniel-mar 316
                } else {
317
                        // Is it time to register / renew the directory entry?
318
                        // 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.
319
                        // 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)
139 daniel-mar 320
 
239 daniel-mar 321
                        if (!defined('REGISTRATION_HIDE_SYSTEM') || !REGISTRATION_HIDE_SYSTEM) {
139 daniel-mar 322
                                $privacy_level = OIDplus::config()->getValue('reg_privacy');
323
 
183 daniel-mar 324
                                if (php_sapi_name() !== 'cli') { // don't register when called from CLI, otherweise the oidinfo XML can't convert relative links into absolute links
325
                                        if ((time()-OIDplus::config()->getValue('reg_last_ping') >= OIDplus::config()->getValue('reg_ping_interval'))) {
326
                                                $this->sendRegistrationQuery();
327
                                        }
139 daniel-mar 328
                                }
329
                        }
330
                }
331
        }
332
 
333
        public function tree(&$json, $ra_email=null, $nonjs=false, $req_goto='') {
334
                if (file_exists(__DIR__.'/treeicon.png')) {
148 daniel-mar 335
                        $tree_icon = 'plugins/'.basename(dirname(__DIR__)).'/'.basename(__DIR__).'/treeicon.png';
139 daniel-mar 336
                } else {
337
                        $tree_icon = null; // default icon (folder)
338
                }
339
 
340
                $json[] = array(
141 daniel-mar 341
                        'id' => 'oidplus:srv_registration',
139 daniel-mar 342
                        'icon' => $tree_icon,
206 daniel-mar 343
                        'text' => 'System registration'
139 daniel-mar 344
                );
345
 
346
                return true;
347
        }
348
 
349
        public function tree_search($request) {
350
                return false;
351
        }
352
}