Completed
Push — master ( 656de5...ed4cb5 )
by Terrence
13:27
created

Util::getGetOrPostVar()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
dl 0
loc 8
ccs 0
cts 2
cp 0
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
crap 6
1
<?php
2
3
namespace CILogon\Service;
4
5
use CILogon\Service\CSRF;
6
use CILogon\Service\Loggit;
7
use CILogon\Service\IdpList;
8
use CILogon\Service\DBService;
9
use CILogon\Service\SessionMgr;
10
use CILogon\Service\Skin;
11
use CILogon\Service\TimeIt;
12
use CILogon\Service\PortalCookie;
13
use PEAR;
14
use Config;
15
16
// Full path to the php.ini-style config file for the CILogon Service
17
define('CILOGON_INI_FILE', '/var/www/config/cilogon.ini');
18
19
/**
20
 * Util
21
 *
22
 * This class contains a bunch of static (class) utility
23
 * methods, for example getting and setting server environment
24
 * variables and handling cookies. See the header for each function for
25
 * detailed description.
26
 */
27
class Util
28
{
29
    /**
30
     * @var array $ini_array Read the cilogon.ini file into an array
31
     */
32
    public static $ini_array = null;
33
34
    /**
35
     * @var TimeIt $timeit Initialize by calling static::startTiming() in
36
     * init().
37
     */
38
    public static $timeit;
39
40
    /**
41
     * @var IdPList $idplist A 'global' IdpList object since dplist.xml is
42
     *      large and expensive to create multiple times.
43
     */
44
    public static $idplist = null;
45
46
    /**
47
     * @var CSRF $csrf A 'global' CSRF token object to set the CSRF cookie
48
     * and print the hidden CSRF form element. Needs to be set only once
49
     * to keep the same CSRF value through the session.
50
     */
51
    public static $csrf = null;
52
53
    /**
54
     * @var Skin $skin A 'global' Skin object for skin configuration.
55
     */
56
    public static $skin = null;
57
58
    /**
59
     * @var array $oauth2idps An array of OAuth2 Identity Providers.
60
     */
61
    public static $oauth2idps = ['Google', 'GitHub', 'ORCID'];
62
63
64
    /**
65
     * getIdPList
66
     *
67
     * This function initializes the class $idplist object (if not yet
68
     * created) and returns it. This allows for a single 'global'
69
     * $idplist to be used by other classes (since creating an IdPList
70
     * object is expensive).
71
     *
72
     * @return IdPList The class instantiated IdPList object.
73
     **/
74
    public static function getIdpList()
75
    {
76
        if (is_null(static::$idplist)) {
77
            static::$idplist = new IdpList();
78
        }
79
        return static::$idplist;
80
    }
81
82
    /**
83
     * getCsrf
84
     *
85
     * This function initializes the class $csrf object (if not yet
86
     * created) and returns it. This allows for a single 'global'
87
     * $csrf to be used by other classes (since we want the CSRV value
88
     * to be consistent for the current page load).
89
     *
90
     * @return CSRF The class instantiated CSRF object.
91
     */
92
    public static function getCsrf()
93
    {
94
        if (is_null(static::$csrf)) {
95
            static::$csrf = new CSRF();
96
        }
97
        return static::$csrf;
98
    }
99
100
    /**
101
     * getSkin
102
     *
103
     * This function initializes the class $skin object (if not yet
104
     * created) and returns it. This allows for a single 'global'
105
     * $skin to be used by other classes (since loading the skin is
106
     * potentially expensive).
107
     *
108
     * @return The class instantiated Skin object.
109
     */
110
    public static function getSkin()
111
    {
112
        if (is_null(static::$skin)) {
113
            static::$skin = new Skin();
114
        }
115
        return static::$skin;
116
    }
117
118
    /**
119
     * getConfigVar
120
     *
121
     * This function returns a sinle configuration vale from the
122
     * CILOGON_INI_FILE, or empty string if no such configuration
123
     * value is found in the file.
124
     *
125
     * @param string $config The config parameter to read from the
126
     *        cilogon.ini file.
127
     * @return string The value of the config parameter, or empty string
128
     *         if no such parameter found in config.ini.
129
     */
130
    public static function getConfigVar($config)
131
    {
132
        $retval = '';
133
        // Read in the config file into an array
134
        if (is_null(static::$ini_array)) {
135
            static::$ini_array = @parse_ini_file(CILOGON_INI_FILE);
136
        }
137
        if ((is_array(static::$ini_array)) &&
138
            (array_key_exists($config, static::$ini_array))) {
139
            $retval = static::$ini_array[$config];
140
        }
141
        return $retval;
142
    }
143
144
    /**
145
     * startTiming
146
     *
147
     * This function initializes the class variable $timeit which is
148
     * used for timing/benchmarking purposes.
149
     */
150
    public static function startTiming()
151
    {
152
        static::$timeit = new TimeIt(TimeIt::DEFAULTFILENAME, true);
153
    }
154
155
    /**
156
     * getServerVar
157
     *
158
     * This function queries a given $_SERVER variable (which is set
159
     * by the Apache server) and returns the value.
160
     *
161
     * @param string $serv The $_SERVER variable to query.
162
     * @return string The value of the $_SERVER variable or empty string
163
     *         if that variable is not set.
164
     */
165
    public static function getServerVar($serv)
166
    {
167
        $retval = '';
168
        if (isset($_SERVER[$serv])) {
169
            $retval = $_SERVER[$serv];
170
        }
171
        return $retval;
172
    }
173
174
    /**
175
     * getGetVar
176
     *
177
     * This function queries a given $_GET parameter (which is set in
178
     * the URL via a '?parameter=value' parameter) and returns the
179
     * value.
180
     *
181
     * @param string $get The $_GET variable to query.
182
     * @return string The value of the $_GET variable or empty string if
183
     *         that variable is not set.
184
     */
185
    public static function getGetVar($get)
186
    {
187
        $retval = '';
188
        if (isset($_GET[$get])) {
189
            $retval = $_GET[$get];
190
        }
191
        return $retval;
192
    }
193
194
    /**
195
     * getPostVar
196
     *
197
     * This function queries a given $_POST variable (which is set when
198
     * the user submits a form, for example) and returns the value.
199
     *
200
     * @param string $post The $_POST variable to query.
201
     * @return string The value of the $_POST variable or empty string if
202
     *         that variable is not set.
203
     */
204
    public static function getPostVar($post)
205
    {
206
        $retval = '';
207
        if (isset($_POST[$post])) {
208
            $retval = $_POST[$post];
209
        }
210
        return $retval;
211
    }
212
213
    /**
214
     * getGetOrPostVar
215
     *
216
     * This function looks for a $_GET or $_POST variable, with
217
     * preference given to $_GET if both are present.
218
     *
219
     * @param string $var The $_GET or $_POST variable to query.
220
     * @return string The value of the $_GET or $_POST variable
221
     *         if present. Empty string if variable is not set.
222
     */
223
    public static function getGetOrPostVar($var)
224
    {
225
        $retval = static::getGetVar($var);
226
        if (empty($retval)) {
227
            $retval = static::getPostVar($var);
228
        }
229
        return $retval;
230
    }
231
232
    /**
233
     * getCookieVar
234
     *
235
     * This function returns the value of a given cookie.
236
     *
237
     * @param string $cookie he $_COOKIE variable to query.
238
     * @return string The value of the $_COOKIE variable or empty string
239
     *         if that variable is not set.
240
     */
241
    public static function getCookieVar($cookie)
242
    {
243
        $retval = '';
244
        if (isset($_COOKIE[$cookie])) {
245
            $retval = $_COOKIE[$cookie];
246
        }
247
        return $retval;
248
    }
249
250
    /**
251
     * setCookieVar
252
     *
253
     * This function sets a cookie.
254
     *
255
     * @param string $cookie The name of the cookie to set.
256
     * @param string $value (Optional) The value to set for the cookie.
257
     *        Defaults to empty string.
258
     * @param int $exp The future expiration time (in seconds) of the
259
     *        cookie. Defaults to 1 year from now. If set to 0,
260
     *        the cookie expires at the end of the session.
261
     */
262
    public static function setCookieVar($cookie, $value = '', $exp = 31536000)
263
    {
264
        if ($exp > 0) {
265
            $exp += time();
266
        }
267
        setcookie($cookie, $value, $exp, '/', '.'.static::getDN(), true);
268
        $_COOKIE[$cookie] = $value;
269
    }
270
271
    /**
272
     * unsetCookieVar
273
     *
274
     * This function unsets a cookie. Strictly speaking, the cookie is
275
     * not removed, rather it is set to an empty value with an expired
276
     * time.
277
     *
278
     * @param string $cookie The name of the cookie to unset (delete).
279
     */
280
    public static function unsetCookieVar($cookie)
281
    {
282
        setcookie($cookie, '', 1, '/', '.'.static::getDN(), true);
283
        unset($_COOKIE[$cookie]);
284
    }
285
286
    /**
287
     * getPortalOrNormalCookieVar
288
     *
289
     * This is a convenience function which first checks if there is a
290
     * OAuth 1.0a ('delegate') or OIDC ('authorize') session active.
291
     * If so, it attempts to get the requested cookie from the
292
     * associated portalcookie. If there is not an OAuth/OIDC session
293
     * active, it looks for a 'normal' cookie. If you need a
294
     * portalcookie object to do multiple get/set method calls from
295
     * one function, it is probably better NOT to use this method since
296
     * creating the portalcookie object is potentially expensive.
297
     *
298
     * @param string $cookie The name of the cookie to get.
299
     * @return string The cookie value from either the portalcookie
300
     *         (in the case of an active OAuth session) or the
301
     *         'normal' cookie. Return empty string if no matching
302
     *         cookie in either place.
303
     */
304
    public static function getPortalOrNormalCookieVar($cookie)
305
    {
306
        $retval = '';
0 ignored issues
show
Unused Code introduced by
$retval is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
307
        $pc = new PortalCookie();
308
        $pn = $pc->getPortalName();
309
        if (strlen($pn) > 0) {
310
            $retval = $pc->get($cookie);
311
        } else {
312
            $retval = static::getCookieVar($cookie);
313
        }
314
        return $retval;
315
    }
316
317
    /**
318
     * getSessionVar
319
     *
320
     * This function returns the value of a given PHP Session variable.
321
     *
322
     * @param string $sess The $_SESSION variable to query.
323
     * @return string The value of the $_SESSION variable or empty string
324
     *         if that variable is not set.
325
     */
326
    public static function getSessionVar($sess)
327
    {
328
        $retval = '';
329
        if (isset($_SESSION[$sess])) {
330
            $retval = $_SESSION[$sess];
331
        }
332
        return $retval;
333
    }
334
335
    /**
336
     * setSessionVar
337
     *
338
     * This function can set or unset a given PHP session variable.
339
     * The first parameter is the PHP session variable to set/unset.
340
     * If the second parameter is the empty string, then the session
341
     * variable is unset.  Otherwise, the session variable is set to
342
     * the second parameter.  The function returns true if the session
343
     * variable was set to a non-empty value, false otherwise.
344
     * Normally, the return value can be ignored.
345
     *
346
     * @param string $key The name of the PHP session variable to set
347
     *        (or unset).
348
     * @param string $value (Optional) The value of the PHP session variable
349
     *        (to set), or empty string (to unset). Defaults to empty
350
     *        string (implies unset the session variable).
351
     * @return bool True if the PHP session variable was set to a
352
     *         non-empty string, false if variable was unset or if
353
     *         the specified session variable was not previously set.
354
     */
355
    public static function setSessionVar($key, $value = '')
356
    {
357
        $retval = false;  // Assume we want to unset the session variable
358
        if (strlen($key) > 0) {  // Make sure session var name was passed in
359
            if (strlen($value) > 0) {
360
                $_SESSION[$key] = $value;
361
                $retval = true;
362
            } else {
363
                static::unsetSessionVar($key);
364
            }
365
        }
366
        return $retval;
367
    }
368
369
    /**
370
     * unsetSessionVar
371
     *
372
     * This function clears the given PHP session variable by first
373
     * setting it to null and then unsetting it entirely.
374
     *
375
     * @param string $sess The $_SESSION variable to erase.
376
     */
377
    public static function unsetSessionVar($sess)
378
    {
379
        if (isset($_SESSION[$sess])) {
380
            $_SESSION[$sess] = null;
381
            unset($_SESSION[$sess]);
382
        }
383
    }
384
385
    /**
386
     * removeShibCookies
387
     *
388
     * This function removes all '_shib*' cookies currently in the
389
     * user's browser session. In effect, this logs the user out of
390
     * any IdP. Note that you must call this before you output any
391
     * HTML. Strictly speaking, the cookies are not removed, rather
392
     * they are set to empty values with expired times.
393
     */
394
    public static function removeShibCookies()
395
    {
396
        while (list($key, $val) = each($_COOKIE)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $val is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
397
            if (strncmp($key, '_shib', strlen('_shib')) == 0) {
398
                static::unsetCookieVar($key);
399
            }
400
        }
401
    }
402
403
    /**
404
     * startPHPSession
405
     *
406
     * This function starts a secure PHP session and should be called
407
     * at the beginning of each script before any HTML is output.  It
408
     * does a trick of setting a 'lastaccess' time so that the
409
     * $_SESSION variable does not expire without warning.
410
     *
411
     * @param string $storetype (Optional) Storage location of the PHP
412
     *        session data, one of 'file' or 'mysql'. Defaults to null,
413
     *        which means use the value of storage.phpsessions from the
414
     *        cilogon.ini config file, or 'file' if no such
415
     *        parameter configured.
416
     */
417
    public static function startPHPSession($storetype = null)
0 ignored issues
show
Unused Code introduced by
The parameter $storetype is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
418
    {
419
        // No parameter given? Use the value read in from cilogon.ini file.
420
        // If storage.phpsessions == 'mysql', create a sessionmgr().
421
        $storetype = static::getConfigVar('storage.phpsessions');
422
423
        if (preg_match('/^mysql/', $storetype)) {
424
            $sessionmgr = new SessionMgr();
0 ignored issues
show
Unused Code introduced by
$sessionmgr is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
425
        }
426
427
        ini_set('session.cookie_secure', true);
428
        ini_set('session.cookie_domain', '.'.static::getDN());
429
        session_start();
430
        if ((!isset($_SESSION['lastaccess']) ||
431
            (time() - $_SESSION['lastaccess']) > 60)) {
432
            $_SESSION['lastaccess'] = time();
433
        }
434
    }
435
436
    /**
437
     * getScriptDir
438
     *
439
     * This function returns the directory (or full url) of the script
440
     * that is currently running.  The returned directory/url is
441
     * terminated by a '/' character (unless the second parameter is
442
     * set to true). This function is useful for those scripts named
443
     * index.php where we don't want to actually see 'index.php' in the
444
     * address bar (again, unless the second parameter is set to true).
445
     *
446
     * @param bool $prependhttp (Optional) Boolean to prepend 'http(s)://' to
447
     *        the script name. Defaults to false.
448
     * @param bool $stripfile (Optional) Boolean to strip off the trailing
449
     *        filename (e.g. index.php) from the path.
450
     *        Defaults to true (i.e., defaults to directory
451
     *        only without the trailing filename).
452
     * @return string The directory or url of the current script, with or
453
     *         without the trailing .php filename.
454
     */
455
    public static function getScriptDir($prependhttp = false, $stripfile = true)
456
    {
457
        $retval = static::getServerVar('SCRIPT_NAME');
458
        if ($stripfile) {
459
            $retval = dirname($retval);
460
        }
461
        if ($retval == '.') {
462
            $retval = '';
463
        }
464
        if ((strlen($retval) == 0) ||
465
            ($stripfile && ($retval[strlen($retval)-1] != '/'))) {
466
            $retval .= '/';  // Append a slash if necessary
467
        }
468
        if ($prependhttp) {  // Prepend http(s)://hostname
469
            $retval = 'http' .
470
                      ((strtolower(static::getServerVar('HTTPS')) == 'on')?'s':'') .
471
                      '://' . static::getServerVar('HTTP_HOST') . $retval;
472
        }
473
        return $retval;
474
    }
475
476
    /**
477
     * readArrayFromFile
478
     *
479
     * This function reads in the contents of a file into an array. It
480
     * is assumed that the file contains lines of the form:
481
     *     key value
482
     * where 'key' and 'value' are separated by whitespace.  The 'key'
483
     * portion of the string may not contain any whitespace, but the
484
     * 'value' part of the line may contain whitespace. Any empty lines
485
     * or lines starting with '#' (comments, without leading spaces)
486
     * in the file are skipped.  Note that this assumes that each 'key'
487
     * in the file is unique.  If there is any problem reading the
488
     * file, the resulting array will be empty.
489
     *
490
     * @param string $filename The name of the file to read.
491
     * @return array An array containing the contents of the file.
492
     */
493
    public static function readArrayFromFile($filename)
494
    {
495
        $retarray = array();
496
        if (is_readable($filename)) {
497
            $lines = file(
498
                $filename,
499
                FILE_IGNORE_NEW_LINES|FILE_SKIP_EMPTY_LINES
500
            );
501
            foreach ($lines as $line) {
502
                if (substr($line, 0, 1) != '#') { // Skip '#' comment lines
503
                    $values = preg_split('/\s+/', $line, 2);
504
                    $retarray[$values[0]] = @$values[1];
505
                }
506
            }
507
        }
508
509
        return $retarray;
510
    }
511
512
    /**
513
     * writeArrayToFile
514
     *
515
     * This funtion writes an array (with key=>value pairs) to a file,
516
     * each line will be of the form:
517
     *     key value
518
     * The 'key' and 'value' strings are separated by a space. Note
519
     * that a 'key' may not contain any whitespace (e.g. tabs), but a
520
     * 'value' may contain whitespace. To be super safe, the array is
521
     * first written to a temporary file, which is then renamed to the
522
     * final desired filename.
523
     *
524
     * @param string $filename The name of the file to write.
525
     * @param array $thearray The array to be written to the file.
526
     * @return bool True if successfully wrote file, false otherwise.
527
     */
528
    public static function writeArrayToFile($filename, $thearray)
529
    {
530
        $retval = false;  // Assume write failed
531
        $tmpfnmae = tempnam('/tmp', 'ARR');
0 ignored issues
show
Unused Code introduced by
$tmpfnmae is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
532
        if ($fh = fopen($tmpfname, 'w')) {
533
            if (flock($fh, LOCK_EX)) {
534
                foreach ($thearray as $key => $value) {
535
                    fwrite($fh, "$key $value\n");
536
                }
537
                flock($fh, LOCK_UN);
538
            }
539
            fclose($fh);
540
            if (@rename($tmpfname, $filename)) {
541
                $retval = true;
542
            } else {
543
                @unlink($tmpfname);
0 ignored issues
show
Bug introduced by
The variable $tmpfname does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
544
            }
545
        }
546
547
        return $retval;
548
    }
549
550
    /**
551
     * parseGridShibConf
552
     *
553
     * This function parses the gridshib-ca.conf file and returns an
554
     * array containing the various options. It uses the PHP
555
     * PEAR::Config package to parse the config file. The
556
     * gridshib-ca.conf file is MOSTLY an Apache-style config file.
557
     * However, each option has an extra ' = ' prepended, so you will
558
     * need to strip these off each config option. For example, to get
559
     * the 'MaximumCredLifetime' value which is in the 'CA' section,
560
     * you would do the following:
561
     *     $gridshibconf = Util::parseGridShibConf();
562
     *     $life = preg_replace('%^\s*=\s*%','',
563
     *             $gridshibconf['root']['CA']['MaximumCredLifetime']);
564
     *
565
     * @param string $conffile (Optional) Full path location of
566
     *        gridshib-ca.conf file. Defaults to
567
     *        '/usr/local/gridshib-ca/conf/gridshib-ca.conf'.
568
     * @return array An array containing the various configuration
569
     *         parameters in the gridshib-ca.conf file.
570
     */
571
    public static function parseGridShibConf(
572
        $conffile = '/usr/local/gridshib-ca/conf/gridshib-ca.conf'
573
    ) {
574
        $conf = new Config;
575
        $root = $conf->parseConfig($conffile, 'Apache');
576
        $gridshibconf = array();
577
        if (!(PEAR::isError($root))) {
578
            $gridshibconf = $root->toArray();
579
        }
580
        return $gridshibconf;
581
    }
582
583
    /**
584
     * tempDir
585
     *
586
     * This function creates a temporary subdirectory within the
587
     * specified subdirectory. The new directory name is composed of
588
     * 16 hexadecimal letters, plus any prefix if you specify one. The
589
     * full path of the the newly created directory is returned.
590
     *
591
     * @param string $dir The full path to the containing directory.
592
     * @param string $prefix (Optional) A prefix for the new temporary
593
     *        directory. Defaults to empty string.
594
     * @param int $mode (Optional) Access permissions for the new
595
     *        temporary directory. Defaults to 0775.
596
     * @return string Full path to the newly created temporary directory.
597
     */
598
    public static function tempDir($dir, $prefix = '', $mode = 0775)
599
    {
600
        if (substr($dir, -1) != '/') {
601
            $dir .= '/';
602
        }
603
604
        $path = '';
0 ignored issues
show
Unused Code introduced by
$path is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
605
        do {
606
            $path = $dir . $prefix . sprintf("%08X%08X", mt_rand(), mt_rand());
607
        } while (!mkdir($path, $mode, true));
608
609
        return $path;
610
    }
611
612
    /**
613
     * deleteDir
614
     *
615
     * This function deletes a directory and all of its contents.
616
     *
617
     * @param string $dir The (possibly non-empty) directory to delete.
618
     * @param bool $shred (Optional) Shred the file before deleting?
619
     *        Defaults to false.
620
     */
621
    public static function deleteDir($dir, $shred = false)
622
    {
623
        if (is_dir($dir)) {
624
            $objects = scandir($dir);
625
            foreach ($objects as $object) {
626
                if ($object != "." && $object != "..") {
627
                    if (filetype($dir."/".$object) == "dir") {
628
                        static::deleteDir($dir."/".$object);
629
                    } else {
630
                        if ($shred) {
631
                            @exec('/bin/env /usr/bin/shred -u -z '.$dir."/".$object);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
632
                        } else {
633
                            @unlink($dir."/".$object);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
634
                        }
635
                    }
636
                }
637
            }
638
            reset($objects);
639
            @rmdir($dir);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
640
        }
641
    }
642
643
    /**
644
     * htmlent
645
     *
646
     * This method is necessary since htmlentities() does not seem to
647
     * obey the default arguments as documented in the PHP manual, and
648
     * instead encodes accented characters incorrectly. By specifying
649
     * the flags and encoding, the problem is solved.
650
     *
651
     * @param string $str : A string to process with htmlentities().
652
     * @return string The input string processed by htmlentities with
653
     *         specific options.
654
     */
655
    public static function htmlent($str)
656
    {
657
        return htmlentities($str, ENT_COMPAT|ENT_HTML401, 'UTF-8');
658
    }
659
660
    /**
661
     * sendErrorAlert
662
     *
663
     * Use this function to send an error message. The $summary should
664
     * be a short description of the error since it is placed in the
665
     * subject of the email. Put a more verbose description of the
666
     * error in the $detail parameter. Any session variables available
667
     * are appended to the body of the message.
668
     *
669
     * @param string $summary A brief summary of the error (in email subject)
670
     * @param string $detail A detailed description of the error (in the
671
     *        email body)
672
     * @param string $mailto (Optional) The destination email address.
673
     *        Defaults to '[email protected]'.
674
     */
675
    public static function sendErrorAlert(
676
        $summary,
677
        $detail,
678
        $mailto = '[email protected]'
679
    ) {
680
        $sessionvars = array(
681
            'idp'          => 'IdP ID',
682
            'idpname'      => 'IdP Name',
683
            'uid'          => 'Database UID',
684
            'dn'           => 'Cert DN',
685
            'firstname'    => 'First Name',
686
            'lastname'     => 'Last Name',
687
            'displayname'  => 'Display Name',
688
            'ePPN'         => 'ePPN',
689
            'ePTID'        => 'ePTID',
690
            'openID'       => 'OpenID ID',
691
            'oidcID'       => 'OIDC ID',
692
            'loa'          => 'LOA',
693
            'affiliation'  => 'Affiliation',
694
            'ou'           => 'OU',
695
            'memberof'     => 'MemberOf',
696
            'acr'          => 'AuthnContextClassRef',
697
            'entitlement'  => 'Entitlement',
698
            'cilogon_skin' => 'Skin Name',
699
            'twofactor'    => 'Two-Factor',
700
            'authntime'    => 'Authn Time'
701
        );
702
703
        $remoteaddr = static::getServerVar('REMOTE_ADDR');
704
        $remotehost = gethostbyaddr($remoteaddr);
705
        $mailfrom = 'From: [email protected]' . "\r\n" .
706
                    'X-Mailer: PHP/' . phpversion();
707
        $mailsubj = 'CILogon Service on ' . php_uname('n') .
708
                    ' - ' . $summary;
709
        $mailmsg  = '
710
CILogon Service - ' . $summary . '
711
-----------------------------------------------------------
712
' . $detail . '
713
714
Session Variables
715
-----------------
716
Timestamp     = ' . date(DATE_ATOM) . '
717
Server Host   = ' . static::getHN() . '
718
Remote Address= ' . $remoteaddr . '
719
' . (($remotehost !== false) ? "Remote Host   = $remotehost" : '') . '
720
';
721
722
        foreach ($sessionvars as $svar => $sname) {
723
            if (strlen($val = static::getSessionVar($svar)) > 0) {
724
                $mailmsg .= sprintf("%-14s= %s\n", $sname, $val);
725
            }
726
        }
727
728
        mail($mailto, $mailsubj, $mailmsg, $mailfrom);
729
    }
730
731
    /**
732
     * getFirstAndLastName
733
     *
734
     * This function attempts to get the first and last name of a user
735
     * extracted from the 'full name' (displayName) of the user.
736
     * Simply pass in all name info (full, first, and last) and the
737
     * function first tries to break up the full name into first/last.
738
     * If this is not sufficient, the function checks first and last
739
     * name. Finally, if either first or last is blank, the function
740
     * duplicates first <=> last so both names have the same value.
741
     * Note that even with all this, you still need to check if the
742
     * returned (first,last) names are blank.
743
     *
744
     * @param string $full The 'full name' of the user
745
     * @param string $first (Optional) The 'first name' of the user
746
     * @param string $last (Optional) The 'last name' of the user
747
     * @return array An array 'list(firstname,lastname)'
748
     */
749
    public static function getFirstAndLastName($full, $first = '', $last = '')
750
    {
751
        $firstname = '';
752
        $lastname = '';
753
754
        # Try to split the incoming $full name into first and last names
755
        if (strlen($full) > 0) {
756
            $names = preg_split('/\s+/', $full, 2);
757
            $firstname = @$names[0];
758
            $lastname =  @$names[1];
759
        }
760
761
        # If either first or last name blank, then use incoming $first and $last
762
        if (strlen($firstname) == 0) {
763
            $firstname = $first;
764
        }
765
        if (strlen($lastname) == 0) {
766
            $lastname = $last;
767
        }
768
769
        # Finally, if only a single name, copy first name <=> last name
770
        if (strlen($lastname) == 0) {
771
            $lastname = $firstname;
772
        }
773
        if (strlen($firstname) == 0) {
774
            $firstname = $lastname;
775
        }
776
777
        # Return both names as an array (i.e., use list($first,last)=...)
778
        return array($firstname,$lastname);
779
    }
780
781
    /**
782
     * getHN
783
     *
784
     * This function calculates and returns the 'hostname' for the
785
     * server. It first checks HTTP_HOST. If not set, it returns
786
     * 'cilogon.org'. This is needed by command line scripts.
787
     *
788
     * @return string The 'Hostname' for the web server.
789
     */
790
    public static function getHN()
791
    {
792
        $thehostname = static::getServerVar('HTTP_HOST');
793
        if (strlen($thehostname) == 0) {
794
            $thehostname = 'cilogon.org';
795
        }
796
        return $thehostname;
797
    }
798
799
    /**
800
     * getDN
801
     *
802
     * This function calculates and returns the 'domainname' for the
803
     * server. It uses the hostname value calculated by getHN() and
804
     * uses the last two segments.
805
     *
806
     * @return string The 'Domainname' for the web server.
807
     */
808
    public static function getDN()
809
    {
810
        $thedomainname = static::getHN();
811
        if (preg_match('/[^\.]+\.[^\.]+$/', $thedomainname, $matches)) {
812
            $thedomainname = $matches[0];
813
        }
814
        return $thedomainname;
815
    }
816
817
    /**
818
     * getAuthzUrl
819
     *
820
     * This funtion takes in the name of an IdP (e.g., 'Google') and
821
     * returns the assoicated OAuth2 authorization URL.
822
     *
823
     * @param string $idp The name of an OAuth2 Identity Provider.
824
     * @return string The authorization URL for the given IdP.
825
     */
826
    public static function getAuthzUrl($idp)
827
    {
828
        $url = null;
829
        $idptourl = array(
830
            'Google' => 'https://accounts.google.com/o/oauth2/auth',
831
            'GitHub' => 'https://github.com/login/oauth/authorize',
832
            'ORCID'  => 'https://orcid.org/oauth/authorize',
833
        );
834
        if (array_key_exists($idp, $idptourl)) {
835
            $url = $idptourl[$idp];
836
        }
837
        return $url;
838
    }
839
840
    /**
841
     * getAuthzIdP
842
     *
843
     * This function takes in the OAuth2 authorization URL and returns
844
     * the associated pretty-print name of the IdP.
845
     *
846
     * @param string $url The authorization URL of an OAuth2 Identity Provider.
847
     * @return string The name of the IdP.
848
     */
849
    public static function getAuthzIdP($url)
850
    {
851
        $idp = null;
852
        $urltoidp = array(
853
            'https://accounts.google.com/o/oauth2/auth' => 'Google',
854
            'https://github.com/login/oauth/authorize'  => 'GitHub',
855
            'https://orcid.org/oauth/authorize'         => 'ORCID',
856
        );
857
        if (array_key_exists($url, $urltoidp)) {
858
            $idp = $urltoidp[$url];
859
        }
860
        return $idp;
861
    }
862
863
    /**
864
     * saveUserToDataStore
865
     *
866
     * This function is called when a user logs on to save identity
867
     * information to the datastore. As it is used by both Shibboleth
868
     * and OpenID Identity Providers, some parameters passed in may
869
     * be blank (empty string). The function verifies that the minimal
870
     * sets of parameters are valid, the dbservice servlet is called
871
     * to save the user info. Then various session variables are set
872
     * for use by the program later on. In case of error, an email
873
     * alert is sent showing the missing parameters.
874
     *
875
     * @param string $remoteuser The REMOTE_USER from HTTP headers
876
     * @param string $providerId The provider IdP Identifier / URL endpoint
877
     * @param string providerName The pretty print provider IdP name
878
     * @param string $firstname The user's first name
879
     * @param string $lastname The user's last name
880
     * @param string $displayname The user's display name
881
     * @param string $emailaddr The user's email address
882
     * @param string $loa The level of assurance (e.g., openid/basic/silver)
883
     * @param string $eppn (optional) User's ePPN (for SAML IdPs)
884
     * @param string $eptid (optional) User's ePTID (for SAML IdPs)
885
     * @param string $openidid (optional) User's OpenID 2.0 Identifier
886
     * @param string $oidcid (optional) User's OpenID Connect Identifier
887
     * @param string $affiliation (optional) User's affiliation
888
     * @param string $ou (optional) User's organizational unit (OU)
889
     * @param string $memberof (optional) User's isMemberOf group info
890
     * @param string $acr (optional) Authentication Context Class Ref
891
     * @param string $entitlement (optional) User's entitlement
892
     */
893
    public static function saveUserToDataStore(
894
        $remoteuser,
895
        $providerId,
896
        $providerName,
897
        $firstname,
898
        $lastname,
899
        $displayname,
900
        $emailaddr,
901
        $loa,
902
        $eppn = '',
903
        $eptid = '',
904
        $openidid = '',
905
        $oidcid = '',
906
        $affiliation = '',
907
        $ou = '',
908
        $memberof = '',
909
        $acr = '',
910
        $entitlement = ''
911
    ) {
912
        $dbs = new DBService();
913
914
        // Keep original values of providerName and providerId
915
        $databaseProviderName = $providerName;
916
        $databaseProviderId   = $providerId;
917
918
        // Save the passed-in variables to the session for later use
919
        // (e.g., by the error handler in handleGotUser).
920
        static::setSessionVar('firstname', $firstname);
921
        static::setSessionVar('lastname', $lastname);
922
        static::setSessionVar('displayname', $displayname);
923
        static::setSessionvar('emailaddr', $emailaddr);
924
        static::setSessionVar('loa', $loa);
925
        static::setSessionVar('ePPN', $eppn);
926
        static::setSessionVar('ePTID', $eptid);
927
        static::setSessionVar('openidID', $openidid);
928
        static::setSessionVar('oidcID', $oidcid);
929
        static::setSessionVar('affiliation', $affiliation);
930
        static::setSessionVar('ou', $ou);
931
        static::setSessionVar('memberof', $memberof);
932
        static::setSessionVar('acr', $acr);
933
        static::setSessionVar('entitlement', $entitlement);
934
        static::setSessionVar('idp', $providerId); // Enable error message
935
        static::setSessionVar('idpname', $providerName); // Enable check for Google
936
        static::setSessionVar('submit', static::getSessionVar('responsesubmit'));
937
938
        // CACC-238 - Set loa to "silver" if the following are true:
939
        // (1) loa contains  https://refeds.org/assurance/profile/cappuccino
940
        // (2) acr is either https://refeds.org/profile/sfa or
941
        //                   https://refeds.org/profile/mfa
942
        if ((preg_match('%https://refeds.org/assurance/profile/cappuccino%', $loa)) &&
943
            (preg_match('%https://refeds.org/profile/[ms]fa%', $acr))) {
944
            $loa = 'http://incommonfederation.org/assurance/silver';
945
            static::setSessionVar('loa', $loa);
946
        }
947
948
        // Make sure parameters are not empty strings, and email is valid
949
        // Must have at least one of remoteuser/eppn/eptid/openidid/oidcid
950
        if (((strlen($remoteuser) > 0) ||
951
               (strlen($eppn) > 0) ||
952
               (strlen($eptid) > 0) ||
953
               (strlen($openidid) > 0) ||
954
               (strlen($oidcid) > 0)) &&
955
            (strlen($databaseProviderId) > 0) &&
956
            (strlen($databaseProviderName) > 0)  &&
957
            (strlen($firstname) > 0) &&
958
            (strlen($lastname) > 0) &&
959
            (strlen($emailaddr) > 0) &&
960
            (filter_var($emailaddr, FILTER_VALIDATE_EMAIL))) {
961
            // For the new Google OAuth 2.0 endpoint, we want to keep the
962
            // old Google OpenID endpoint URL in the database (so user does
963
            // not get a new certificate subject DN). Change the providerId
964
            // and providerName to the old Google OpenID values.
965
            if (($databaseProviderName == 'Google+') ||
966
                ($databaseProviderId == static::getAuthzUrl('Google'))) {
967
                $databaseProviderName = 'Google';
968
                $databaseProviderId = 'https://www.google.com/accounts/o8/id';
969
            }
970
971
            // In the database, keep a consistent ProviderId format: only
972
            // allow 'http' (not 'https') and remove any 'www.' prefix.
973
            if ($loa == 'openid') {
974
                $databaseProviderId = preg_replace(
975
                    '%^https://(www\.)?%',
976
                    'http://',
977
                    $databaseProviderId
978
                );
979
            }
980
981
            $result = $dbs->getUser(
982
                $remoteuser,
983
                $databaseProviderId,
984
                $databaseProviderName,
985
                $firstname,
986
                $lastname,
987
                $displayname,
988
                $emailaddr,
989
                $eppn,
990
                $eptid,
991
                $openidid,
992
                $oidcid,
993
                $affiliation,
994
                $ou,
995
                $memberof,
996
                $acr,
997
                $entitlement
998
            );
999
            static::setSessionVar('uid', $dbs->user_uid);
1000
            static::setSessionVar('dn', $dbs->distinguished_name);
1001
            static::setSessionVar('twofactor', $dbs->two_factor);
1002
            static::setSessionVar('status', $dbs->status);
1003
            if (!$result) {
1004
                static::sendErrorAlert(
1005
                    'dbService Error',
1006
                    'Error calling dbservice action "getUser" in ' .
1007
                    'saveUserToDatastore() method.'
1008
                );
1009
            }
1010
        } else { // Missing one or more required attributes
1011
            static::setSessionVar(
1012
                'status',
1013
                DBService::$STATUS['STATUS_MISSING_PARAMETER_ERROR']
1014
            );
1015
        }
1016
1017
        // If 'status' is not STATUS_OK*, then send an error email
1018
        $status = static::getSessionVar('status');
1019
        if ($status & 1) { // Bad status codes are odd
1020
            // For missing parameter errors, log an error message
1021
            if ($status ==
1022
                DBService::$STATUS['STATUS_MISSING_PARAMETER_ERROR']) {
1023
                $log = new Loggit();
1024
                $log->error('STATUS_MISSING_PARAMETER_ERROR', true);
1025
            }
1026
1027
            // For other dbservice errors OR for any error involving
1028
            // LIGO (e.g., missing parameter error), send email alert.
1029
            if (($status !=
1030
                    DBService::$STATUS['STATUS_MISSING_PARAMETER_ERROR']) ||
1031
                (preg_match('/ligo\.org/', $databaseProviderId))) {
1032
                $mailto = '[email protected]';
1033
1034
                // Set $disableligoalerts = true to stop LIGO failures
1035
                // from being sent to '[email protected]', but still
1036
                // sent to '[email protected]'.
1037
                $disableligoalerts = false;
1038
1039
                // Fixes CIL-205 - Notify LIGO about IdP login errors
1040
                if (preg_match('/ligo\.org/', $databaseProviderId)) {
1041
                    if ($disableligoalerts) {
1042
                        $mailto = '';
1043
                    }
1044
                    $mailto .= ((strlen($mailto) > 0) ? ',' : '') .
1045
                        '[email protected]';
1046
                }
1047
1048
                static::sendErrorAlert(
1049
                    'Failure in ' .
1050
                        (($loa == 'openid') ? '' : '/secure') . '/getuser/',
1051
                    'Remote_User   = ' . ((strlen($remoteuser) > 0) ?
1052
                        $remoteuser : '<MISSING>') . "\n" .
1053
                    'IdP ID        = ' . ((strlen($databaseProviderId) > 0) ?
1054
                        $databaseProviderId : '<MISSING>') . "\n" .
1055
                    'IdP Name      = ' . ((strlen($databaseProviderName) > 0) ?
1056
                        $databaseProviderName : '<MISSING>') . "\n" .
1057
                    'First Name    = ' . ((strlen($firstname) > 0) ?
1058
                        $firstname : '<MISSING>') . "\n" .
1059
                    'Last Name     = ' . ((strlen($lastname) > 0) ?
1060
                        $lastname : '<MISSING>') . "\n" .
1061
                    'Display Name  = ' . ((strlen($displayname) > 0) ?
1062
                        $displayname : '<MISSING>') . "\n" .
1063
                    'Email Address = ' . ((strlen($emailaddr) > 0) ?
1064
                        $emailaddr : '<MISSING>') . "\n" .
1065
                    'ePPN          = ' . ((strlen($eppn) > 0) ?
1066
                        $eppn : '<MISSING>') . "\n" .
1067
                    'ePTID         = ' . ((strlen($eptid) > 0) ?
1068
                        $eptid : '<MISSING>') . "\n" .
1069
                    'OpenID ID     = ' . ((strlen($openidid) > 0) ?
1070
                        $openidid : '<MISSING>') . "\n" .
1071
                    'OIDC ID       = ' . ((strlen($oidcid) > 0) ?
1072
                        $oidcid : '<MISSING>') . "\n" .
1073
                    'Affiliation   = ' . ((strlen($affiliation) > 0) ?
1074
                        $affiliation : '<MISSING>') . "\n" .
1075
                    'OU            = ' . ((strlen($ou) > 0) ?
1076
                        $ou : '<MISSING>') . "\n" .
1077
                    'MemberOf      = ' . ((strlen($memberof) > 0) ?
1078
                        $memberof : '<MISSING>') . "\n" .
1079
                    'ACR           = ' . ((strlen($acr) > 0) ?
1080
                        $acr : '<MISSING>') . "\n" .
1081
                    'Entitlement   = ' . ((strlen($entitlement) > 0) ?
1082
                        $entitlement : '<MISSING>') . "\n" .
1083
                    'Database UID  = ' . ((strlen(
1084
                        $i = static::getSessionVar('uid')
1085
                    ) > 0) ?  $i : '<MISSING>') . "\n" .
1086
                    'Status Code   = ' . ((strlen(
1087
                        $i = array_search(
1088
                            $status,
1089
                            DBService::$STATUS
1090
                        )
1091
                    ) > 0) ?  $i : '<MISSING>'),
1092
                    $mailto
1093
                );
1094
            }
1095
            static::unsetSessionVar('authntime');
1096
        } else { // status is okay, set authntime
1097
            static::setSessionVar('authntime', time());
1098
        }
1099
1100
        static::unsetSessionVar('responsesubmit');
1101
        static::unsetSessionVar('requestsilver');
1102
1103
        static::getCsrf()->setCookieAndSession();
1104
    }
1105
1106
    /**
1107
     * unsetClientSessionVars
1108
     *
1109
     * This function removes all of the PHP session variables related to
1110
     * the client session.
1111
     */
1112
    public static function unsetClientSessionVars()
1113
    {
1114
        static::unsetSessionVar('submit');
1115
1116
        // Specific to 'Download Certificate' page
1117
        static::unsetSessionVar('activation');
1118
        static::unsetSessionVar('p12');
1119
        static::unsetSessionVar('p12lifetime');
1120
        static::unsetSessionVar('p12multiplier');
1121
1122
        // Specific to OAuth 1.0a flow
1123
        static::unsetSessionVar('portalstatus');
1124
        static::unsetSessionVar('callbackuri');
1125
        static::unsetSessionVar('successuri');
1126
        static::unsetSessionVar('failureuri');
1127
        static::unsetSessionVar('portalname');
1128
        static::unsetSessionVar('tempcred');
1129
1130
        // Specific to OIDC flow
1131
        static::unsetSessionVar('clientparams');
1132
    }
1133
1134
    /**
1135
     * unsetUserSessionVars
1136
     *
1137
     * This function removes all of the PHP session variables related to
1138
     * the user's session.  This will force the user to log on (again)
1139
     * with their IdP and call the 'getuser' script to repopulate the PHP
1140
     * session.
1141
     */
1142
    public static function unsetUserSessionVars()
1143
    {
1144
        // Needed for verifyCurrentUserSession
1145
        static::unsetSessionVar('idp');
1146
        static::unsetSessionVar('idpname');
1147
        static::unsetSessionVar('status');
1148
        static::unsetSessionVar('uid');
1149
        static::unsetSessionVar('dn');
1150
        static::unsetSessionVar('authntime');
1151
1152
        // Specific to 2FA
1153
        static::unsetSessionVar('twofactor');
1154
1155
        // Variables set by getuser
1156
        static::unsetSessionVar('firstname');
1157
        static::unsetSessionVar('lastname');
1158
        static::unsetSessionVar('displayname');
1159
        static::unsetSessionVar('emailaddr');
1160
        static::unsetSessionVar('loa');
1161
        static::unsetSessionVar('ePPN');
1162
        static::unsetSessionVar('ePTID');
1163
        static::unsetSessionVar('openidID');
1164
        static::unsetSessionVar('oidcID');
1165
        static::unsetSessionVar('affiliation');
1166
        static::unsetSessionVar('ou');
1167
        static::unsetSessionVar('memberof');
1168
        static::unsetSessionVar('acr');
1169
        static::unsetSessionVar('entitlement');
1170
1171
        // Current skin
1172
        static::unsetSessionVar('cilogon_skin');
1173
    }
1174
1175
    /**
1176
     * unsetAllUserSessionVars
1177
     *
1178
     * This is a convenience method to clear all session variables related
1179
     * to the client and the user.
1180
     */
1181
    public static function unsetAllUserSessionVars()
1182
    {
1183
        static::unsetClientSessionVars();
1184
        static::unsetUserSessionVars();
1185
    }
1186
1187
    /**
1188
     * verifySessionAndCall
1189
     *
1190
     * This function is a convenience method called by several cases in the
1191
     * main 'switch' call at the top of the index.php file. I noticed
1192
     * a pattern where verifyCurrentUserSession() was called to verify the
1193
     * current user session. Upon success, one or two functions were called
1194
     * to continue program, flow. Upon failure, cookies and session
1195
     * variables were cleared, and the main Logon page was printed. This
1196
     * function encapsulates that pattern. If the user's session is valid,
1197
     * the passed-in $func is called, possibly with parameters passed in as
1198
     * an array. The function returns true if the session is verified, so
1199
     * that other functions may be called upon return.
1200
     *
1201
     * @param function $func The function to call if the current session is
1202
     *        successfully verified.
1203
     * @param array $params (Optional) An array of parameters to pass to the
1204
     8        function. Defaults to empty array, meaning zero parameters.
1205
     */
1206
    public static function verifySessionAndCall($func, $params = array())
1207
    {
1208
        $retval = false;
1209
        if (Content::verifyCurrentUserSession()) { // Verify PHP session is valid
1210
            $retval = true;
1211
            call_user_func_array($func, $params);
1212
        } else {
1213
            printLogonPage(true); // Clear cookies and session vars too
1214
        }
1215
        return $retval;
1216
    }
1217
}
1218