Subversion Repositories oidplus

Rev

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