Subversion Repositories oidplus

Rev

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

Rev Author Line No. Line
2 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
 
112 daniel-mar 20
if (!defined('IN_OIDPLUS')) die();
21
 
2 daniel-mar 22
class OIDplus {
61 daniel-mar 23
        private static /*OIDplusPagePlugin[][]*/ $pagePlugins = array();
221 daniel-mar 24
        private static /*OIDplusAuthPlugin[][]*/ $authPlugins = array();
227 daniel-mar 25
        private static /*OIDplusObjectTypePlugin[]*/ $objectTypePlugins = array();
26
        private static /*string[]*/ $enabledObjectTypes = array();
27
        private static /*string[]*/ $disabledObjectTypes = array();
28
        private static /*OIDplusDatabasePlugin[]*/ $dbPlugins = array();
2 daniel-mar 29
 
236 daniel-mar 30
        protected static $html = null;
31
 
2 daniel-mar 32
        private function __construct() {
33
        }
256 daniel-mar 34
 
227 daniel-mar 35
        # --- Singleton classes
2 daniel-mar 36
 
37
        public static function config() {
86 daniel-mar 38
                static $config = null;
39
                if (is_null($config)) {
40
                        $config = new OIDplusConfig();
2 daniel-mar 41
                }
86 daniel-mar 42
                return $config;
2 daniel-mar 43
        }
44
 
45
        public static function gui() {
86 daniel-mar 46
                static $gui = null;
47
                if (is_null($gui)) {
48
                        $gui = new OIDplusGui();
49
                }
50
                return $gui;
2 daniel-mar 51
        }
52
 
53
        public static function authUtils() {
86 daniel-mar 54
                static $authUtils = null;
55
                if (is_null($authUtils)) {
56
                        $authUtils = new OIDplusAuthUtils();
57
                }
58
                return $authUtils;
2 daniel-mar 59
        }
60
 
250 daniel-mar 61
        public static function mailUtils() {
62
                static $mailUtils = null;
63
                if (is_null($mailUtils)) {
64
                        $mailUtils = new OIDplusMailUtils();
65
                }
66
                return $mailUtils;
67
        }
68
 
69
        public static function menuUtils() {
70
                static $menuUtils = null;
71
                if (is_null($menuUtils)) {
72
                        $menuUtils = new OIDplusMenuUtils();
73
                }
74
                return $menuUtils;
75
        }
76
 
115 daniel-mar 77
        public static function logger() {
78
                static $logger = null;
79
                if (is_null($logger)) {
80
                        $logger = new OIDplusLogger();
81
                }
82
                return $logger;
83
        }
84
 
86 daniel-mar 85
        public static function sesHandler() {
86
                static $sesHandler = null;
87
                if (is_null($sesHandler)) {
88
                        $sesHandler = new OIDplusSessionHandler(OIDPLUS_SESSION_SECRET);
89
                }
90
                return $sesHandler;
91
        }
92
 
230 daniel-mar 93
        # --- Database plugin
74 daniel-mar 94
 
227 daniel-mar 95
        private static function registerDatabasePlugin(OIDplusDatabasePlugin $plugin) {
150 daniel-mar 96
                $name = $plugin->name();
97
                if ($name === false) return false;
98
 
99
                self::$dbPlugins[$name] = $plugin;
100
 
101
                return true;
102
        }
103
 
104
        public static function getDatabasePlugins() {
105
                return self::$dbPlugins;
106
        }
107
 
227 daniel-mar 108
        public static function db() {
260 daniel-mar 109
                if (!defined('OIDPLUS_DATABASE_PLUGIN')) {
110
                        throw new OIDplusConfigInitializationException("No database plugin selected in config file");
111
                }
227 daniel-mar 112
                if (!isset(self::$dbPlugins[OIDPLUS_DATABASE_PLUGIN])) {
240 daniel-mar 113
                        throw new OIDplusConfigInitializationException("Database plugin '".OIDPLUS_DATABASE_PLUGIN."' not found");
227 daniel-mar 114
                }
115
                $obj = self::$dbPlugins[OIDPLUS_DATABASE_PLUGIN];
116
                if (!$obj->isConnected()) $obj->connect();
117
                return $obj;
118
        }
119
 
120
        # --- Page plugin
121
 
224 daniel-mar 122
        private static function registerPagePlugin(OIDplusPagePlugin $plugin) {
61 daniel-mar 123
                $type = $plugin->type();
124
                if ($type === false) return false;
125
 
126
                $prio = $plugin->priority();
256 daniel-mar 127
                if (!is_numeric($prio)) throw new OIDplusException('Errornous plugin "'.get_class($plugin).'": Invalid priority');
128
                if ($prio <   0) throw new OIDplusException('Errornous plugin "'.get_class($plugin).'": Invalid priority');
129
                if ($prio > 999) throw new OIDplusException('Errornous plugin "'.get_class($plugin).'": Invalid priority');
61 daniel-mar 130
 
131
                if (!isset(self::$pagePlugins[$type])) self::$pagePlugins[$type] = array();
256 daniel-mar 132
                self::$pagePlugins[$type][str_pad($prio, 3, '0', STR_PAD_LEFT).get_class($plugin)] = $plugin;
61 daniel-mar 133
 
134
                return true;
135
        }
136
 
230 daniel-mar 137
        public static function getPagePlugins($type='*') {
138
                if ($type === '*') {
61 daniel-mar 139
                        $res = array();
140
                        foreach (self::$pagePlugins as $data) {
141
                                $res = array_merge($res, $data);
142
                        }
143
                } else {
230 daniel-mar 144
                        $types = explode(',', $type);
145
                        foreach ($types as $type) {
146
                                $res = isset(self::$pagePlugins[$type]) ? self::$pagePlugins[$type] : array();
147
                        }
61 daniel-mar 148
                }
149
                ksort($res);
150
                return $res;
151
        }
152
 
227 daniel-mar 153
        # --- Auth plugin
154
 
155
        private static function registerAuthPlugin(OIDplusAuthPlugin $plugin) {
156
                self::$authPlugins[] = $plugin;
157
                return true;
158
        }
159
 
221 daniel-mar 160
        public static function getAuthPlugins() {
161
                return self::$authPlugins;
162
        }
163
 
227 daniel-mar 164
        # --- Object type plugin
165
 
166
        private static function registerObjectTypePlugin(OIDplusObjectTypePlugin $plugin) {
167
                self::$objectTypePlugins[] = $plugin;
168
 
169
                $ot = $plugin::getObjectTypeClassName();
170
                self::registerObjectType($ot);
171
 
172
                return true;
173
        }
174
 
224 daniel-mar 175
        private static function registerObjectType($ot) {
66 daniel-mar 176
                $ns = $ot::ns();
177
 
250 daniel-mar 178
                if (empty($ns)) throw new OIDplusException("Attention: Empty NS at $ot\n");
66 daniel-mar 179
 
180
                $ns_found = false;
227 daniel-mar 181
                foreach (array_merge(OIDplus::getEnabledObjectTypes(), OIDplus::getDisabledObjectTypes()) as $test_ot) {
66 daniel-mar 182
                        if ($test_ot::ns() == $ns) {
183
                                $ns_found = true;
184
                                break;
185
                        }
186
                }
187
                if ($ns_found) {
250 daniel-mar 188
                        throw new OIDplusException("Attention: Two objectType plugins use the same namespace \"$ns\"!");
66 daniel-mar 189
                }
190
 
191
                $init = OIDplus::config()->getValue("objecttypes_initialized");
192
                $init_ary = empty($init) ? array() : explode(';', $init);
70 daniel-mar 193
                $init_ary = array_map('trim', $init_ary);
66 daniel-mar 194
 
195
                $enabled = OIDplus::config()->getValue("objecttypes_enabled");
196
                $enabled_ary = empty($enabled) ? array() : explode(';', $enabled);
70 daniel-mar 197
                $enabled_ary = array_map('trim', $enabled_ary);
66 daniel-mar 198
 
79 daniel-mar 199
                $do_enable = false;
200
                if (in_array($ns, $enabled_ary)) {
201
                        $do_enable = true;
202
                } else {
203
                        if (!OIDplus::config()->getValue('registration_done')) {
204
                                $do_enable = $ns == 'oid';
205
                        } else {
206
                                $do_enable = !in_array($ns, $init_ary);
207
                        }
208
                }
209
 
210
                if ($do_enable) {
227 daniel-mar 211
                        self::$enabledObjectTypes[] = $ot;
212
                        usort(self::$enabledObjectTypes, function($a, $b) {
66 daniel-mar 213
                                $enabled = OIDplus::config()->getValue("objecttypes_enabled");
214
                                $enabled_ary = explode(';', $enabled);
215
 
216
                                $idx_a = array_search($a::ns(), $enabled_ary);
217
                                $idx_b = array_search($b::ns(), $enabled_ary);
218
 
219
                                if ($idx_a == $idx_b) {
220
                                    return 0;
221
                                }
222
                                return ($idx_a > $idx_b) ? +1 : -1;
223
                        });
74 daniel-mar 224
                } else {
225
                        self::$disabledObjectTypes[] = $ot;
66 daniel-mar 226
                }
227
 
228
                if (!in_array($ns, $init_ary)) {
229
                        // Was never initialized before, so we add it to the list of enabled object types once
230
 
79 daniel-mar 231
                        if ($do_enable) {
232
                                $enabled_ary[] = $ns;
233
                                OIDplus::config()->setValue("objecttypes_enabled", implode(';', $enabled_ary));
234
                        }
66 daniel-mar 235
 
236
                        $init_ary[] = $ns;
237
                        OIDplus::config()->setValue("objecttypes_initialized", implode(';', $init_ary));
238
                }
61 daniel-mar 239
        }
240
 
227 daniel-mar 241
        public static function getObjectTypePlugins() {
242
                return self::$objectTypePlugins;
61 daniel-mar 243
        }
244
 
227 daniel-mar 245
        public static function getObjectTypePluginsEnabled() {
246
                $res = array();
247
                foreach (self::$objectTypePlugins as $plugin) {
248
                        $ot = $plugin::getObjectTypeClassName();
249
                        if (in_array($ot, self::$enabledObjectTypes)) $res[] = $plugin;
250
                }
251
                return $res;
74 daniel-mar 252
        }
253
 
227 daniel-mar 254
        public static function getObjectTypePluginsDisabled() {
255
                $res = array();
256
                foreach (self::$objectTypePlugins as $plugin) {
257
                        $ot = $plugin::getObjectTypeClassName();
258
                        if (in_array($ot, self::$disabledObjectTypes)) $res[] = $plugin;
74 daniel-mar 259
                }
227 daniel-mar 260
                return $res;
74 daniel-mar 261
        }
262
 
227 daniel-mar 263
        public static function getEnabledObjectTypes() {
264
                return self::$enabledObjectTypes;
265
        }
74 daniel-mar 266
 
227 daniel-mar 267
        public static function getDisabledObjectTypes() {
268
                return self::$disabledObjectTypes;
269
        }
74 daniel-mar 270
 
227 daniel-mar 271
        # --- Initialization of OIDplus
206 daniel-mar 272
 
2 daniel-mar 273
        public static function init($html=true) {
236 daniel-mar 274
                self::$html = $html;
275
 
2 daniel-mar 276
                // Include config file
74 daniel-mar 277
 
2 daniel-mar 278
                if (file_exists(__DIR__ . '/../config.inc.php')) {
279
                        include_once __DIR__ . '/../config.inc.php';
280
                } else {
240 daniel-mar 281
                        if (!is_dir(__DIR__.'/../../setup')) {
282
                                throw new OIDplusConfigInitializationException('File includes/config.inc.php is missing, but setup can\'t be started because its directory missing.');
283
                        } else {
284
                                if ($html) {
285
                                        header('Location:'.OIDplus::getSystemUrl().'setup/');
286
                                        die('Redirecting to setup...');
2 daniel-mar 287
                                } else {
240 daniel-mar 288
                                        // This can be displayed in e.g. ajax.php
289
                                        throw new OIDplusConfigInitializationException('File includes/config.inc.php is missing. Please run setup again.');
2 daniel-mar 290
                                }
291
                        }
292
                }
293
 
230 daniel-mar 294
                // Auto-fill non-existing config values, so that there won't be any PHP errors
295
                // if something would be missing in config.inc.php (which should not happen!)
74 daniel-mar 296
 
2 daniel-mar 297
                if (!defined('OIDPLUS_CONFIG_VERSION'))   define('OIDPLUS_CONFIG_VERSION',   0.0);
298
                if (!defined('OIDPLUS_ADMIN_PASSWORD'))   define('OIDPLUS_ADMIN_PASSWORD',   '');
299
                if (!defined('OIDPLUS_TABLENAME_PREFIX')) define('OIDPLUS_TABLENAME_PREFIX', '');
300
                if (!defined('OIDPLUS_SESSION_SECRET'))   define('OIDPLUS_SESSION_SECRET',   '');
27 daniel-mar 301
                if (!defined('RECAPTCHA_ENABLED'))        define('RECAPTCHA_ENABLED',        false);
302
                if (!defined('RECAPTCHA_PUBLIC'))         define('RECAPTCHA_PUBLIC',         '');
303
                if (!defined('RECAPTCHA_PRIVATE'))        define('RECAPTCHA_PRIVATE',        '');
111 daniel-mar 304
                if (!defined('OIDPLUS_ENFORCE_SSL'))      define('OIDPLUS_ENFORCE_SSL',      2 /* Auto */);
256 daniel-mar 305
 
247 daniel-mar 306
                // Now include a file containing various size/depth limitations of OIDs
307
                // It is important to include it after config.inc.php was included,
308
                // so we can give config.inc.php the chance to override the values
256 daniel-mar 309
                // by defining the constants first.
2 daniel-mar 310
 
256 daniel-mar 311
                include_once __DIR__ . '/../limits.inc.php';
247 daniel-mar 312
 
2 daniel-mar 313
                // Check version of the config file
74 daniel-mar 314
 
76 daniel-mar 315
                if (OIDPLUS_CONFIG_VERSION != 2.0) {
240 daniel-mar 316
                        throw new OIDplusConfigInitializationException("The information located in includes/config.inc.php is outdated.");
2 daniel-mar 317
                }
42 daniel-mar 318
 
150 daniel-mar 319
                // Register database types (highest priority)
320
 
321
                $ary = glob(__DIR__ . '/../../plugins/database/'.'*'.'/plugin.inc.php');
322
                foreach ($ary as $a) include $a;
323
 
224 daniel-mar 324
                foreach (get_declared_classes() as $c) {
246 daniel-mar 325
                        if (is_subclass_of($c, 'OIDplusDatabasePlugin')) {
224 daniel-mar 326
                                self::registerDatabasePlugin(new $c());
327
                        }
328
                }
329
 
237 daniel-mar 330
                foreach (OIDplus::getDatabasePlugins() as $plugin) {
331
                        $plugin->init($html);
332
                }
333
 
42 daniel-mar 334
                // Do redirect stuff etc.
74 daniel-mar 335
 
230 daniel-mar 336
                self::isSslAvailable(); // This function does automatic redirects
61 daniel-mar 337
 
257 daniel-mar 338
                // Construct the configuration manager once
339
                // During the construction, various system settings are prepared if required
66 daniel-mar 340
 
257 daniel-mar 341
                OIDplus::config();
66 daniel-mar 342
 
74 daniel-mar 343
                // Initialize public / private keys
344
 
227 daniel-mar 345
                OIDplus::getPkiStatus(true);
74 daniel-mar 346
 
237 daniel-mar 347
                // Register non-DB plugins
74 daniel-mar 348
 
222 daniel-mar 349
                $ary = glob(__DIR__ . '/../../plugins/objectTypes/'.'*'.'/plugin.inc.php');
150 daniel-mar 350
                foreach ($ary as $a) include $a;
351
 
256 daniel-mar 352
                $ary = glob(__DIR__ . '/../../plugins/*Pages/'.'*'.'/plugin.inc.php');
61 daniel-mar 353
                foreach ($ary as $a) include $a;
74 daniel-mar 354
 
221 daniel-mar 355
                $ary = glob(__DIR__ . '/../../plugins/auth/'.'*'.'/plugin.inc.php');
356
                foreach ($ary as $a) include $a;
357
 
224 daniel-mar 358
                foreach (get_declared_classes() as $c) {
256 daniel-mar 359
                        if (!(new ReflectionClass($c))->isAbstract()) {
360
                                if (is_subclass_of($c, 'OIDplusPagePlugin')) {
361
                                                self::registerPagePlugin(new $c());
362
                                }
363
                                if (is_subclass_of($c, 'OIDplusAuthPlugin')) {
364
                                        self::registerAuthPlugin(new $c());
365
                                }
366
                                if (is_subclass_of($c, 'OIDplusObjectTypePlugin')) {
367
                                        self::registerObjectTypePlugin(new $c());
368
                                }
224 daniel-mar 369
                        }
370
                }
74 daniel-mar 371
 
237 daniel-mar 372
                // Initialize non-DB plugins
224 daniel-mar 373
 
74 daniel-mar 374
                foreach (OIDplus::getPagePlugins('*') as $plugin) {
375
                        $plugin->init($html);
376
                }
230 daniel-mar 377
                foreach (OIDplus::getAuthPlugins() as $plugin) {
378
                        $plugin->init($html);
379
                }
380
                foreach (OIDplus::getObjectTypePlugins() as $plugin) {
381
                        $plugin->init($html);
382
                }
2 daniel-mar 383
        }
42 daniel-mar 384
 
227 daniel-mar 385
        # --- System URL, System ID, PKI, and other functions
386
 
387
        public static function getSystemUrl($relative=false) {
388
                if (!isset($_SERVER["SCRIPT_NAME"])) return false;
389
 
390
                $test_dir = dirname($_SERVER['SCRIPT_FILENAME']);
391
                $c = 0;
392
                while (!file_exists($test_dir.'/oidplus_base.js')) {
393
                        $test_dir = dirname($test_dir);
394
                        $c++;
395
                        if ($c == 1000) return false;
396
                }
397
 
398
                $res = dirname($_SERVER['SCRIPT_NAME'].'xxx');
399
 
400
                for ($i=1; $i<=$c; $i++) {
401
                        $res = dirname($res);
402
                }
403
 
404
                if ($res == '/') $res = '';
405
                $res .= '/';
406
 
407
                if (!$relative) {
228 daniel-mar 408
                        $is_ssl = isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] === 'on');
409
                        $protocol = $is_ssl ? 'https' : 'http';
410
                        $host = $_SERVER['HTTP_HOST'];
411
                        $port = $_SERVER['SERVER_PORT'];
412
                        if ($is_ssl && ($port != 443)) {
413
                                $port_add = ":$port";
414
                        } else if (!$is_ssl && ($port != 80)) {
415
                                $port_add = ":$port";
416
                        } else {
417
                                $port_add = "";
418
                        }
419
                        $res = $protocol.'://'.$host.$port_add.$res;
227 daniel-mar 420
                }
421
 
422
                return $res;
423
        }
424
 
425
        private static $system_id_cache = null;
426
        public static function getSystemId($oid=false) {
427
                if (!is_null(self::$system_id_cache)) {
428
                        $out = self::$system_id_cache;
429
                } else {
430
                        $out = false;
431
 
432
                        if (self::getPkiStatus(true)) {
433
                                $pubKey = OIDplus::config()->getValue('oidplus_public_key');
434
                                if (preg_match('@BEGIN PUBLIC KEY\-+(.+)\-+END PUBLIC KEY@ismU', $pubKey, $m)) {
435
                                        $out = smallhash(base64_decode($m[1]));
436
                                }
437
                        }
438
                        self::$system_id_cache = $out;
439
                }
239 daniel-mar 440
                return ($out ? '1.3.6.1.4.1.37476.30.9.' : '').$out;
227 daniel-mar 441
        }
442
 
443
        public static function getPkiStatus($try_generate=true) {
444
                if (!function_exists('openssl_pkey_new')) return false;
445
 
446
                $privKey = OIDplus::config()->getValue('oidplus_private_key');
447
                $pubKey = OIDplus::config()->getValue('oidplus_public_key');
448
 
449
                if ($try_generate && !verify_private_public_key($privKey, $pubKey)) {
450
                        $config = array(
451
                            "digest_alg" => "sha512",
452
                            "private_key_bits" => 2048,
453
                            "private_key_type" => OPENSSL_KEYTYPE_RSA,
454
                        );
455
 
456
                        // Create the private and public key
457
                        $res = openssl_pkey_new($config);
256 daniel-mar 458
 
239 daniel-mar 459
                        if (!$res) return false;
227 daniel-mar 460
 
461
                        // Extract the private key from $res to $privKey
462
                        openssl_pkey_export($res, $privKey);
463
 
464
                        // Extract the public key from $res to $pubKey
465
                        $pubKey = openssl_pkey_get_details($res)["key"];
466
 
239 daniel-mar 467
                        // Log
468
                        OIDplus::logger()->log("A!", "Generating new SystemID using a new key pair");
469
 
227 daniel-mar 470
                        // Save the key pair to database
471
                        OIDplus::config()->setValue('oidplus_private_key', $privKey);
472
                        OIDplus::config()->setValue('oidplus_public_key', $pubKey);
473
 
474
                        // Log the new system ID
475
                        if (preg_match('@BEGIN PUBLIC KEY\-+(.+)\-+END PUBLIC KEY@ismU', $pubKey, $m)) {
476
                                $system_id = smallhash(base64_decode($m[1]));
477
                                OIDplus::logger()->log("A!", "Your SystemID is now $system_id");
478
                        }
479
                }
480
 
481
                return verify_private_public_key($privKey, $pubKey);
482
        }
483
 
170 daniel-mar 484
        public static function getInstallType() {
485
                if (!file_exists(__DIR__ . '/../../oidplus_version.txt') && !is_dir(__DIR__ . '/../../.svn')) {
486
                        return 'unknown';
487
                }
488
                if (file_exists(__DIR__ . '/../../oidplus_version.txt') && is_dir(__DIR__ . '/../../.svn')) {
489
                        return 'ambigous';
490
                }
491
                if (is_dir(__DIR__ . '/../../.svn')) {
492
                        return 'svn-wc';
493
                }
494
                if (file_exists(__DIR__ . '/../../oidplus_version.txt')) {
495
                        return 'svn-snapshot';
496
                }
497
        }
498
 
111 daniel-mar 499
        public static function getVersion() {
162 daniel-mar 500
                if (file_exists(__DIR__ . '/../../oidplus_version.txt') && is_dir(__DIR__ . '/../../.svn')) {
239 daniel-mar 501
                        return false; // version is ambigous
111 daniel-mar 502
                }
162 daniel-mar 503
 
504
                if (is_dir(__DIR__ . '/../../.svn')) {
505
                        // Try to find out the SVN version using the shell
239 daniel-mar 506
                        // TODO: das müllt die log files voll!
162 daniel-mar 507
                        $status = @shell_exec('svnversion '.realpath(__FILE__));
508
                        if (preg_match('/\d+/', $status, $match)) {
239 daniel-mar 509
                                return 'svn-'.$match[0];
162 daniel-mar 510
                        }
511
 
512
                        // If that failed, try to get the version via SQLite3
239 daniel-mar 513
                        if (class_exists('SQLite3')) {
162 daniel-mar 514
                                $db = new SQLite3(__DIR__ . '/../../.svn/wc.db');
515
                                $results = $db->query('SELECT MIN(revision) AS rev FROM NODES_BASE');
516
                                while ($row = $results->fetchArray()) {
239 daniel-mar 517
                                        return 'svn-'.$row['rev'];
162 daniel-mar 518
                                }
519
                        }
520
                }
521
 
522
                if (file_exists(__DIR__ . '/../../oidplus_version.txt')) {
523
                        $cont = file_get_contents(__DIR__ . '/../../oidplus_version.txt');
239 daniel-mar 524
                        if (preg_match('@Revision (\d+)@', $cont, $m))
525
                                return 'svn-'.$m[1];
162 daniel-mar 526
                }
527
 
239 daniel-mar 528
                return false;
111 daniel-mar 529
        }
530
 
230 daniel-mar 531
        private static $sslAvailableCache = null;
532
        public static function isSslAvailable() {
533
                if (!is_null(self::$sslAvailableCache)) return self::$sslAvailableCache;
256 daniel-mar 534
 
230 daniel-mar 535
                if (php_sapi_name() == 'cli') {
536
                        self::$sslAvailableCache = false;
537
                        return false;
538
                }
539
 
49 daniel-mar 540
                $timeout = 2;
80 daniel-mar 541
                $already_ssl = isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == "on");
542
                $ssl_port = 443;
227 daniel-mar 543
                $cookie_path = OIDplus::getSystemUrl(true);
83 daniel-mar 544
                if (empty($cookie_path)) $cookie_path = '/';
42 daniel-mar 545
 
80 daniel-mar 546
                if (OIDPLUS_ENFORCE_SSL == 0) {
547
                        // No SSL available
230 daniel-mar 548
                        self::$sslAvailableCache = $already_ssl;
80 daniel-mar 549
                        return $already_ssl;
550
                }
551
 
552
                if (OIDPLUS_ENFORCE_SSL == 1) {
553
                        // Force SSL
554
                        if ($already_ssl) {
230 daniel-mar 555
                                self::$sslAvailableCache = true;
80 daniel-mar 556
                                return true;
42 daniel-mar 557
                        } else {
80 daniel-mar 558
                                $location = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
559
                                header('Location:'.$location);
240 daniel-mar 560
                                die('Redirecting to HTTPS...');
230 daniel-mar 561
                                self::$sslAvailableCache = true;
80 daniel-mar 562
                                return true;
563
                        }
564
                }
565
 
566
                if (OIDPLUS_ENFORCE_SSL == 2) {
567
                        // Automatic SSL detection
568
 
569
                        if ($already_ssl) {
570
                                // we are already on HTTPS
83 daniel-mar 571
                                setcookie('SSL_CHECK', '1', 0, $cookie_path, '', false, true);
230 daniel-mar 572
                                self::$sslAvailableCache = true;
80 daniel-mar 573
                                return true;
574
                        } else {
575
                                if (isset($_COOKIE['SSL_CHECK'])) {
576
                                        // We already had the HTTPS detection done before.
577
                                        if ($_COOKIE['SSL_CHECK']) {
578
                                                // HTTPS was detected before, but we are HTTP. Redirect now
579
                                                $location = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
580
                                                header('Location:'.$location);
240 daniel-mar 581
                                                die('Redirecting to HTTPS...');
230 daniel-mar 582
                                                self::$sslAvailableCache = true;
80 daniel-mar 583
                                                return true;
584
                                        } else {
585
                                                // No HTTPS available. Do nothing.
230 daniel-mar 586
                                                self::$sslAvailableCache = false;
80 daniel-mar 587
                                                return false;
588
                                        }
49 daniel-mar 589
                                } else {
80 daniel-mar 590
                                        // This is our first check (or the browser didn't accept the SSL_CHECK cookie)
591
                                        if (@fsockopen($_SERVER['HTTP_HOST'], $ssl_port, $errno, $errstr, $timeout)) {
592
                                                // HTTPS detected. Redirect now, and remember that we had detected HTTPS
83 daniel-mar 593
                                                setcookie('SSL_CHECK', '1', 0, $cookie_path, '', false, true);
80 daniel-mar 594
                                                $location = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'];
595
                                                header('Location:'.$location);
240 daniel-mar 596
                                                die('Redirecting to HTTPS...');
230 daniel-mar 597
                                                self::$sslAvailableCache = true;
80 daniel-mar 598
                                                return true;
599
                                        } else {
600
                                                // No HTTPS detected. Do nothing, and next time, don't try to detect HTTPS again.
83 daniel-mar 601
                                                setcookie('SSL_CHECK', '0', 0, $cookie_path, '', false, true);
230 daniel-mar 602
                                                self::$sslAvailableCache = false;
80 daniel-mar 603
                                                return false;
604
                                        }
49 daniel-mar 605
                                }
42 daniel-mar 606
                        }
607
                }
608
        }
241 daniel-mar 609
 
610
        public static function webpath($target) {
611
                $dir = __DIR__;
612
                $dir = dirname($dir);
613
                $dir = dirname($dir);
614
                $target = substr($target, strlen($dir)+1, strlen($target)-strlen($dir)-1);
615
                if ($target != '') {
616
                        $target = str_replace('\\','/',$target).'/';
617
                }
618
                return $target;
619
        }
2 daniel-mar 620
}