Issues (51)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

delegate/index-functions.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/**
4
 * This file contains functions called by index-site.php. The index-site.php
5
 * file should include this file with the following statement at the top:
6
 *
7
 * require_once __DIR__ . '/index-functions.php';
8
 */
9
10
use CILogon\Service\Util;
11
use CILogon\Service\Content;
12
use CILogon\Service\PortalCookie;
13
use CILogon\Service\DBService;
14
use CILogon\Service\Loggit;
15
16
/**
17
 * printLogonPage
18
 *
19
 * This function prints out the HTML for the main cilogon.org page.
20
 * Explanatory text is shown as well as a button to log in to an IdP
21
 * and get rerouted to the Shibboleth protected getuser script.
22
 */
23
function printLogonPage()
0 ignored issues
show
The function printLogonPage() has been defined more than once; this definition is ignored, only the first definition in authorize/index-functions.php (L22-52) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
24
{
25
    $log = new Loggit();
26
    $log->info('Welcome page hit.');
27
28
    // Check if this is the first time the user has visited the site from
29
    // the current portal.  We do this by checking the portal cookie's
30
    // lifetime for a positive value.  If the portal cookie has NOT YET been
31
    // set, then check the skin config to see if either initialremember or
32
    // initiallifetime has been set.  We do this here because these two
33
    // values set the portal cookie, which needs to be done before we go
34
    // to the next page (where the cookie is actually read).
35
    $skin = Util::getSkin();
36
    $pc = new PortalCookie();
37
    $portallife = $pc->get('lifetime');
38
39
    if ((strlen($portallife) == 0) || ($portallife == 0)) {
40
        $needtosetcookie = 0;
41
42
        // Try to read the skin's initiallifetime
43
        $initlife = $skin->getConfigOption('delegate', 'initiallifetime');
44
        if ((!is_null($initlife)) && ((int)$initlife > 0)) {
45
            $needtosetcookie = 1;
46
            $initlife = (int)$initlife;
47
        } else { // Set a default lifetime value in case initialremember is set
48
            $initlife = 12;
49
        }
50
51
        // Make sure initiallifetime is within [minlifetime..maxlifetime]
52
        list($minlife, $maxlife) = Util::getMinMaxLifetimes('delegate', 240);
53
        if ($initlife < $minlife) {
54
            $needtosetcookie = 1;
55
            $initlife = $minlife;
56
        } elseif ($initlife > $maxlife) {
57
            $needtosetcookie = 1;
58
            $initlife = $maxlife;
59
        }
60
61
        // Next, try to read the skin's initialremember
62
        $initialremember = $skin->getConfigOption('delegate', 'initialremember');
63
        if ((!is_null($initialremember)) && ((int)$initialremember > 0)) {
64
            $needtosetcookie = 1;
65
            $initialremember = (int)$initialremember;
66
        } else { // Set a default remember value in case initiallifetime is set
67
            $initialremember = 0;
68
        }
69
70
        if ($needtosetcookie) {
71
            $pc->set('remember', $initialremember);
72
            $pc->set('lifetime', $initlife);
73
            $pc->write();
74
        }
75
    }
76
77
    Content::printHeader('Welcome To The CILogon Delegation Service');
78
79
    // If the <hideportalinfo> option is set, do not show the portal info if
80
    // the callback uri is in the portal list.
81
    $showportalinfo = true;
82
    if (
83
        ((int)$skin->getConfigOption('portallistaction', 'hideportalinfo') == 1) &&
84
        ($skin->inPortalList(Util::getSessionVar('callbackuri')))
85
    ) {
86
        $showportalinfo = false;
87
    }
88
89
    if ($showportalinfo) {
90
        printOAuth1Consent();
91
    }
92
93
    Content::printWAYF();
94
    Content::printFooter();
95
}
96
97
/**
98
 * printOAuth1BadTokenPage
99
 *
100
 * This function prints out the HTML for the page when the oauth_token
101
 * (tempcred) or associated OAuth information is missing, bad, or expired.
102
 */
103
function printOAuth1ErrorPage()
104
{
105
    $log = new Loggit();
106
107
    Content::printHeader('CILogon Delegation Service');
108
    Content::printCollapseBegin(
109
        'oauth1default',
110
        'CILogon OAuth1 Delegation Endpoint',
111
        false
112
    );
113
114
    // CIL-624 If X509 certs are disabled, show a suitable error message
115
    // to the end user.
116
    if ((defined('DISABLE_X509')) && (DISABLE_X509 === true)) {
117
        $log->warn('OAuth1 transaction failed due to DISABLE_X509 set.');
118
        echo '
119
        <div class="card-body px-5">
120
          <div class="card-text my-2">
121
            You have reached the CILogon Delegation Service. This service is
122
            for use by third parties to obtain certificates for their users.
123
            <strong>However, downloading X.509 certificates has been
124
            disabled.</strong>
125
          </div>
126
          <div class="card-text my-2">
127
            Please direct questions to the email address at the bottom of
128
            the page.
129
          </div>
130
        </div> <!-- end card-body -->
131
        ';
132
    } else {
133
        $log->warn('Missing or invalid oauth_token.');
134
        echo '
135
        <div class="card-body px-5">
136
          <div class="card-text my-2">
137
            You have reached the CILogon Delegation Service. This service is
138
            for use by third parties to obtain certificates for their users.
139
            End users should not normally see this page.
140
          </div>
141
          <div class="card-text my-2">
142
          Possible reasons for seeing this page include:
143
          </div>
144
          <div class="card-text my-2">
145
            <ul>
146
              <li>You navigated directly to this page.</li>
147
              <li>You clicked your browser\'s "Back" button.</li>
148
              <li>There was a problem with the delegation process.</li>
149
            </ul>
150
          </div>
151
          <div class="card-text my-2">
152
            Please return to the previous site and try again. If the error
153
            persists, please contact us at the email address at the bottom of
154
            the page.
155
          </div>
156
          <div class="card-text my-2">
157
            If you are an individual wishing to download a certificate to your
158
            local computer, please try the <a target="_blank"
159
            href="https://' , Util::getHN() , '/">CILogon Service</a>.
160
          </div>
161
          <div class="card-text my-2">
162
            <strong>Note:</strong> You must enable cookies in your web
163
            browser to use this site.
164
          </div>
165
        </div> <!-- end card-body -->
166
        ';
167
    }
168
169
    Content::printCollapseEnd();
170
    Content::printFooter();
171
}
172
173
/**
174
 * printMainPage
175
 *
176
 * This function prints out the HTML for the main page where the user
177
 * is presented with the portal information and asked to either allow
178
 * or deny delegation of a certificate to the portal.  We first check
179
 * to see if the 'remember' cookie has been set for this portal. If
180
 * so, then we automatically always approve delegation.  Otherwise,
181
 * we print out the HTML for the <form> buttons.
182
 */
183
function printMainPage()
0 ignored issues
show
The function printMainPage() has been defined more than once; this definition is ignored, only the first definition in authorize/index-functions.php (L126-224) is considered.

This check looks for functions that have already been defined in other files.

Some Codebases, like WordPress, make a practice of defining functions multiple times. This may lead to problems with the detection of function parameters and types. If you really need to do this, you can mark the duplicate definition with the @ignore annotation.

/**
 * @ignore
 */
function getUser() {

}

function getUser($id, $realm) {

}

See also the PhpDoc documentation for @ignore.

Loading history...
184
{
185
    $log = new Loggit();
186
    $log->info('Allow Or Deny Delegation page hit.');
187
188
    $remember = 0;   // Default value for remember checkbox is unchecked
189
    $life = 12;      // Default value for lifetime is 12 hours
190
191
    // Check the skin for forceremember and forcelifetime
192
    $skin = Util::getSkin();
193
    $forceremember = $skin->getConfigOption('delegate', 'forceremember');
194
    if ((!is_null($forceremember)) && ((int)$forceremember == 1)) {
195
        $forceremember = 1;
196
    } else {
197
        $forceremember = 0;
198
    }
199
    $forcelife = $skin->getConfigOption('delegate', 'forcelifetime');
200
    if ((!is_null($forcelife)) && ((int)$forcelife > 0)) {
201
        $forcelife = (int)$forcelife;
202
    } else {
203
        $forcelife = 0;
204
    }
205
206
    // Try to read the portal coookie for the remember and lifetime values.
207
    $pc = new PortalCookie();
208
    $portalremember = $pc->get('remember');
209
    $portallife = $pc->get('lifetime');
210
211
    // If skin's forceremember or portal cookie's remember is set,
212
    // then we bypass the Allow/Deny delegate page.
213
    if (($forceremember == 1) || ($portalremember == 1)) {
214
        $remember = 1;
215
    }
216
217
    // If skin's forcelifetime or portal cookie's lifetime is set,
218
    // set lifetime accordingly and make sure value is between the
219
    // configured minlifetime and maxlifetime.
220
    if ($forcelife > 0) {
221
        $life = $forcelife;
222
    } elseif ($portallife > 0) {
223
        $life = $portallife;
224
    }
225
    list($minlife, $maxlife) = Util::getMinMaxLifetimes('delegate', 240);
226
    if ($life < $minlife) {
227
        $life = $minlife;
228
    } elseif ($life > $maxlife) {
229
        $life = $maxlife;
230
    }
231
232
    // If 'remember' is set, then auto-click the 'OK' button for the user.
233
    if ($remember == 1) {
234
        handleAllowDelegation(true);
235
    } else {
236
        // User did not check 'Remember OK' before, so show the
237
        // HTML to prompt user for OK or Cancel delegation.
238
        Content::printHeader('Confirm Allow Delegation');
239
        printOAuth1Certificate($life, $minlife, $maxlife, $forcelife);
240
        Content::printFooter();
241
    }
242
}
243
244
/**
245
 * printOAuth1Consent
246
 *
247
 * This function prints out the 'consent' block showing the portal name and
248
 * callback uris just above the 'Select an Identity Provider' block.
249
 */
250
function printOAuth1Consent()
251
{
252
    Content::printCollapseBegin(
253
        'oauth2consent',
254
        'Consent to Attribute Release',
255
        false
256
    );
257
258
    echo '
259
        <div class="card-body px-5">
260
          <div class="card-row">
261
            "', htmlspecialchars(Util::getSessionVar('portalname')), '"
262
            requests that you select an Identity Provider and click
263
            "', Content::getLogOnButtonText(), '".
264
            If you do not approve this request, do not proceed.
265
          </div>
266
          <div class="card-row">
267
            By proceeding you agree to share your <em>name</em> and
268
            <em>email address</em> with
269
            "', htmlspecialchars(Util::getSessionVar('portalname')), '".
270
          </div>
271
    ';
272
273
    printOAuth1PortalInfo();
274
275
    echo '
276
        </div> <!-- end card-body -->
277
    ';
278
279
    Content::printCollapseEnd();
280
}
281
282
/**
283
 * printOAuth1Certificate
284
 *
285
 * This function prints out the block showing the portal name and callback
286
 * uris, as well as a text input for the user to set the lifetime of the
287
 * certificate to be delegated to the OAuth1 client.
288
 *
289
 * @param int $life The lifetime (in hours) for the delegated certificate.
290
 * @param int $minlife The minimum lifetime for the cert.
291
 * @param int $maxlife The maximum lifetime for the cert.
292
 * @param int $force The forced-set lifetime for the cert.
293
 */
294
function printOAuth1Certificate($life, $minlife, $maxlife, $force)
295
{
296
    $lifehelp = 'Certificate lifetime range is between ' .
297
        $minlife . ' and ' . $maxlife . ' hours.';
298
    $rememberhelp = "Check this box to automatically approve " .
299
        "certificate issuance to the site on future visits. " .
300
        "The certificate lifetime will be remembered. You will " .
301
        "need to clear your browser's cookies to return here.";
302
303
    Content::printCollapseBegin(
304
        'oauth1cert',
305
        'Confirm Certificate Delegation',
306
        false
307
    );
308
309
    echo '
310
        <div class="card-body px-5">
311
          <div class="row mb-3">
312
            "', htmlspecialchars(Util::getSessionVar('portalname')) , '"
313
            is requesting a certificate for you. If you approve, then
314
            "OK" the request. Otherwise, "Cancel" the request or
315
            navigate away from this page.
316
          </div>
317
    ';
318
319
    printOAuth1PortalInfo();
320
321
    Content::printFormHead();
322
323
    echo '
324
          <div class="container col-lg-6 offset-lg-3
325
          col-md-8 offset-md-2 col-sm-10 offset-sm-1">
326
            <div class="form-group">
327
              <div class="form-row">
328
                <label for="lifetime">Certificate Lifetime (in hours):</label>
329
                <input type="number" name="lifetime" id="lifetime"
330
                min="', $minlife, '"
331
                max="', $maxlife, '"
332
                value="', $life , '" ' ,
333
                (($force > 0) ? 'disabled="disabled" ' : ' ') , '
334
                class="form-control" required="required"
335
                aria-describedby="lifetime1help" />
336
                <small id="lifetime1help" class="form-text text-muted">',
337
                $lifehelp, '
338
                </small>
339
<!--[if IE]><input type="text" style="display:none;" disabled="disabled" size="1"/><![endif]-->
340
              </div> <!-- end form-row -->
341
            </div> <!-- end form-group -->
342
343
            <div class="form-group">
344
              <div class="form-row align-items-center justify-content-center">
345
                <div class="form-check">
346
                  <input class="form-check-input" type="checkbox"
347
                  name="rememberok" id="rememberok" />
348
                  <label class="form-check-label"
349
                  for="rememberok">Remember my OK for the site</label>
350
                  <a href="#" tabindex="0" data-trigger="hover click"
351
                  class="helpcursor"
352
                  data-toggle="popover" data-html="true"
353
                  data-content="', $rememberhelp, '"><i class="fa
354
                  fa-question-circle"></i></a>
355
                </div> <!-- end form-check -->
356
              </div> <!-- end form-row -->
357
            </div> <!-- end form-group -->
358
359
            <div class="form-group">
360
              <div class="form-row align-items-center justify-content-center">
361
                <div class="col-auto">
362
                  <input type="submit" name="submit"
363
                  class="btn btn-primary submit form-control" value="OK" />
364
                </div>
365
                <div class="col-auto">
366
                  <input type="submit" name="submit"
367
                  class="btn btn-primary submit form-control" value="Cancel" />
368
                </div>
369
              </div> <!-- end form-row align-items-center -->
370
            </div> <!-- end form-group -->
371
          </div> <!-- end container -->
372
373
        </form>
374
        </div> <!-- end card-body -->
375
    ';
376
377
    Content::printCollapseEnd();
378
}
379
380
/**
381
 * printOAuth1PortalInfo
382
 *
383
 * This function prints the portal name, success uri (i.e., the uri to
384
 * redirect to upon successful delegation of the certificate), and the
385
 * callback uri used by the OAuth1 protocol.
386
 */
387
function printOAuth1PortalInfo()
388
{
389
    echo '
390
    <table class="table table-striped table-sm">
391
    <tbody>
392
      <tr>
393
        <th>Site Name:</th>
394
        <td></td>
395
        <td>', htmlspecialchars(Util::getSessionVar('portalname')), '</td>';
396
397
    $helptext = "The location where you will be redirected upon completion.";
398
399
    echo '
400
      </tr>
401
      <tr>
402
        <th>Site URL:</th>
403
        <td><a href="#" tabindex="0" data-trigger="hover click"
404
          class="helpcursor" data-toggle="popover" data-html="true"
405
          data-content="', $helptext, '"><i class="fa
406
          fa-question-circle"></i></a></td>
407
        <td>', htmlspecialchars(Util::getSessionVar('successuri')), '</td>';
408
409
    $helptext = "The location where CILogon " .
410
        "will send a certificate containing your identity information.";
411
412
    echo '
413
      </tr>
414
      <tr>
415
        <th>Service URL:</th>
416
        <td><a href="#" tabindex="0" data-trigger="hover click"
417
          class="helpcursor" data-toggle="popover" data-html="true"
418
          data-content="', $helptext, '"><i class="fa
419
          fa-question-circle"></i></a></td>
420
        <td>', htmlspecialchars(Util::getSessionVar('callbackuri')), '</td>
421
      </tr>
422
    </tbody>
423
    </table>
424
    ';
425
}
426
427
/**
428
 * printOAuth1DelegationDone
429
 *
430
 * This function prints out the block after generation of the certificate.
431
 * The $success parameter indicates if the cert was generated successfully
432
 * or not. If so, the $responseurl will contain the link to redirect the
433
 * user to, and the $certtext will contain the contents of the cert.
434
 *
435
 * @param bool $success True if the certificate was successfully generated
436
 *        and delegated to the OAuth1 client.
437
 * @param string $responseurl The url to redirect the user to. If this is
438
 *        empty, then the PHP session success/failure uris will be used as
439
 *        determined by the $success value.
440
 * @param string $certtext The contents of the generated cert.
441
 */
442
function printOAuth1DelegationDone($success, $responseurl, $certtext)
443
{
444
    Content::printCollapseBegin(
445
        'oauth1done',
446
        'Certificate Delegation ' . ($success ? 'Success' : 'Failure'),
447
        false
448
    );
449
450
    echo '
451
        <div class="card-body px-5">
452
    ';
453
454
    if ($success) {
455
        echo '
456
          <div class="card-text my-2">
457
            The CILogon Service has issued a certificate to "' ,
458
            htmlspecialchars(Util::getSessionVar('portalname')) , '".
459
            Below is a link to return to
460
            the site to use the issued certificate.
461
          </div>
462
          ';
463
        Content::printCollapseBegin('certdetails', 'Certificate Details');
464
        echo '<div class="card-body px-5">
465
                <pre>', htmlspecialchars($certtext), '</pre>
466
              </div>
467
        ';
468
        Content::printCollapseEnd();
469
    } else {
470
        echo '
471
          <div class="card-text my-2">
472
            We were unable to issue a certificate to "' ,
473
            htmlspecialchars(Util::getSessionVar('portalname')) , '".
474
            Below is a link to return to the site.
475
          </div> <!-- end card-text -->';
476
    }
477
478
    echo '
479
          <div class="card-text my-2 text-center">
480
            <a class="btn btn-primary"
481
            href="' , ((strlen($responseurl) > 0) ? $responseurl :
482
            (Util::getSessionVar($success ? 'successuri' : 'failureuri'))),
483
            '">Return to ' ,
484
            htmlspecialchars(Util::getSessionVar('portalname')) , '</a>
485
          </div> <!-- end card-text -->
486
        </div> <!-- end card-body -->';
487
488
    Content::printCollapseEnd();
489
}
490
491
/**
492
 * printCancelPage
493
 *
494
 * This function prints out the HTML for when the user clicked the
495
 * 'Cancel' button on the 'Allow Delegation' page.  It gives the user a
496
 * link back to the portal via the 'failure URL'.
497
 */
498
function printCancelPage()
499
{
500
    $portalname = Util::getSessionVar('portalname');
501
502
    Content::printHeader('Delegation Denied');
503
    Content::printCollapseBegin(
504
        'oauth1cancel',
505
        'Certificate Delegation Cancelled',
506
        false
507
    );
508
509
    echo '
510
        <div class="card-body px-5">
511
          <div class="card-text my-2">
512
            You have canceled delegation of a certificate to "' ,
513
            htmlspecialchars($portalname) , '".
514
            Below is a link to return to the portal.
515
            This link has been provided by the portal to be used when
516
            delegation of a certificate fails.
517
          </div>
518
          <div class="card-text my-2">
519
            <strong>Note:</strong> If you do not trust the information
520
            provided by the portal, <strong>do not</strong> click on the
521
            link below.  Instead, please contact your portal administrators
522
            or contact us at the email address at the bottom of the page.
523
          </div>
524
          <div class="card-text my-2 text-center">
525
            <a class="btn btn-primary"
526
            href="' , Util::getSessionVar('failureuri') , '">Return to ' ,
527
            htmlspecialchars($portalname) , '</a>
528
          </div>
529
        </div> <!-- end card-body -->
530
    ';
531
532
    Content::printCollapseEnd();
533
    Content::printFooter();
534
}
535
536
/**
537
 * handleAllowDelegation
538
 *
539
 * This fuction is called when the user clicks the 'OK' button on the
540
 * main page, or when the user had previously checked the 'Remember
541
 * my OK for this portal' checkbox which saved the 'remember' cookie
542
 * for the current portal. It first reads the cookie for the portal and
543
 * updates the 'lifetime' and 'remember' parameters, then (re)saves
544
 * the cookie.  Then it calls out to the 'oauth/authorized' servlet
545
 * in order to do the back-end certificate delegation process. If the
546
 * $always parameter is true, then the user is automatically returned
547
 * to the portal's successuri or failureuri.  Otherwise, the user is
548
 * presented with a page showing the result of the attempted
549
 * certificate delegation as well as a link to 'return to your portal'.
550
 *
551
 * @param bool $always True if the user selected to always allow delegation.
552
 */
553
function handleAllowDelegation($always = false)
554
{
555
    // The 'authorized' servlet may return a response URL to be used
556
    // instead of the success / failure URLs.
557
    $responseurl = '';
558
559
    $log = new Loggit();
560
    $log->info('Attempting to delegate a certificate to a portal...');
561
562
    $life = 0;
563
    // Check the skin's forcelifetime and use it if it is configured.
564
    $forcelife = Util::getSkin()->getConfigOption('delegate', 'forcelifetime');
565
    if ((!is_null($forcelife)) && ((int)$forcelife > 0)) {
566
        $life = (int)$forcelife;
567
    }
568
569
    // Next, try to get the certificate lifetime from a submitted <form>
570
    if ($life == 0) {
571
        $life = (int)(trim(Util::getPostVar('lifetime')));
572
    }
573
574
    // If we couldn't get lifetime from the <form>, try the cookie
575
    $pc = new PortalCookie();
576
    if ($life == 0) {
577
        $life = (int)($pc->get('lifetime'));
578
    }
579
580
    // Default lifetime to 12 hours. And then make sure lifetime is in
581
    // acceptable range.
582
    if ($life == 0) {
583
        $life = 12;
584
    }
585
    list($minlife, $maxlife) = Util::getMinMaxLifetimes('delegate', 240);
586
    if ($life < $minlife) {
587
        $life = $minlife;
588
    } elseif ($life > $maxlife) {
589
        $life = $maxlife;
590
    }
591
592
    $pc->set('remember', (int)$always);
593
    $pc->set('lifetime', $life);
594
    $pc->write();
595
596
    $success = false;  // Assume delegation of certificate failed
597
    $certtext = '';    // Output of 'openssl x509 -noout -text -in cert.pem'
598
    $myproxyinfo = Util::getSessionVar('myproxyinfo');
599
600
    // Now call out to the 'oauth/authorized' servlet to execute
601
    // the delegation the credential to the portal.
602
    $ch = curl_init();
603
    if ($ch !== false) {
604
        $tempcred = Util::getSessionVar('tempcred');
605
        $url = OAUTH1_AUTHORIZED_URL . '?' .
606
               'oauth_token=' . urlencode($tempcred) . '&' .
607
               'cilogon_lifetime=' . $life . '&' .
608
               'cilogon_loa=' . urlencode(Util::getLOA()) . '&' .
609
               'cilogon_uid=' . urlencode(Util::getSessionVar('user_uid')) .
610
               ((strlen($myproxyinfo) > 0) ?
611
                   ('&cilogon_info=' . urlencode($myproxyinfo)) : '');
612
        curl_setopt($ch, CURLOPT_URL, $url);
613
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
614
        curl_setopt($ch, CURLOPT_TIMEOUT, 35);
615
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
616
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
617
        $output = curl_exec($ch);
618
        if (curl_errno($ch)) { // Send alert on curl errors
619
            Util::sendErrorAlert(
620
                'cUrl Error',
621
                'cUrl Error    = ' . curl_error($ch) . "\n" .
622
                "URL Accessed  = $url"
623
            );
624
        }
625
        if (!empty($output)) {
626
            $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
627
            if ($httpcode == 200) {
628
                // Check body of curl query for cilogon_status=ok
629
                if (preg_match('/cilogon_status=ok/', $output)) {
630
                    $success = true;
631
                    // Also check if the cert was returned as base64
632
                    // encoded PEM certificate.  If so, get info about it.
633
                    if (
634
                        preg_match(
635
                            '/cilogon_cert=([^\s]+)/',
636
                            $output,
637
                            $matches
638
                        )
639
                    ) {
640
                        $b64cert = $matches[1];
641
                        $cert = base64_decode($b64cert);
642
                        if ($cert !== false) {
643
                            // Run 'openssl x509' command for cert info
644
                            exec(
645
                                '/bin/env RANDFILE=/tmp/.rnd ' .
646
                                '/usr/bin/openssl x509 -text ' .
647
                                '<<< ' . escapeshellarg($cert) . ' 2>&1',
648
                                $x509out,
649
                                $retcode
650
                            );
651
                            if ($retcode === 0) {
652
                                $certtext = implode("\n", $x509out);
653
                            } else {
654
                                $certtext = $cert;
655
                            }
656
                        }
657
                    }
658
                }
659
                // Check for an alternate response URL to be used
660
                // in place of success / failure URLs.
661
                if (
662
                    preg_match(
663
                        '/cilogon_response_url=([^\s]+)/',
664
                        $output,
665
                        $matches
666
                    )
667
                ) {
668
                    $responseurl = $matches[1];
669
                }
670
            }
671
        }
672
        curl_close($ch);
673
    }
674
675
    $log = new Loggit();
676
    $log->info('Delegation of certificate to portal ' .
677
               ($success ? 'succeeded.' : 'failed.'));
678
    //CIL-507 Special log message for XSEDE
679
    $email = Util::getSessionVar('email');
680
    $clientname = Util::getSessionVar('portalname');
681
    $log->info("USAGE email=\"$email\" client=\"$clientname\"");
682
    Util::logXSEDEUsage($clientname, $email);
0 ignored issues
show
The method logXSEDEUsage() does not seem to exist on object<CILogon\Service\Util>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
683
684
    // Depending on the result (success or failure), output appropriate
685
    // HTML to allow the user to return to the portal, or if $always
686
    // was set, then automatically return the user to the successuri,
687
    // failureuri, or cilogon_reponse_url if supplied by authorized servlet.
688
    if ($always) {
689
        $log->info("Automatically returning to portal's " .
690
            ($success ? 'success' : 'failure') . ' url.');
691
        $location = 'Location: ' . ((strlen($responseurl) > 0) ? $responseurl :
692
            (Util::getSessionVar($success ? 'successuri' : 'failureuri')));
693
        if ($success) {
694
            Util::unsetClientSessionVars();
695
            /// Util::unsetAllUserSessionVars();
696
        } else {
697
            Util::unsetAllUserSessionVars();
698
        }
699
        header($location);
700
        exit; // No further processing necessary
701
    } else {
702
        Content::printHeader('Delegation ' . ($success ? 'Successful' : 'Failed'));
703
        printOAuth1DelegationDone($success, $responseurl, $certtext);
704
        Content::printFooter();
705
        if ($success) {
706
            Util::unsetClientSessionVars();
707
        } else {
708
            Util::unsetAllUserSessionVars();
709
        }
710
    }
711
}
712
713
/**
714
 * verifyOAuthToken
715
 *
716
 * This function verifies that all of the various PortalParameters
717
 * have been set in the PHP session.  If the first parameter is passed
718
 * in, it first attempts to call CILogon::getPortalParameters() and
719
 * populates the PHP session with the associated values.
720
 *
721
 * @param string $token (Optional) The temporary credential passed from a
722
 *        Community Portal to the 'delegate' script as 'oauth_token' in the
723
 *        URL (as a $_GET variable). Defaults to empty string.
724
 * @return bool True if the various parameters related to the OAuth
725
 *         token (callbackuri, failureuri, successuri, portalname,
726
 *         and tempcred) are in the PHP session, false otherwise.
727
 */
728
function verifyOAuthToken($token = '')
729
{
730
    $retval = false; // Assume OAuth session info is not valid
731
732
    // CIL-624 If X509 certs are disabled, prevent the OAuth1 endpoint
733
    // from running since OAuth1 always generates an X.509 cert.
734
    if ((defined('DISABLE_X509')) && (DISABLE_X509 === true)) {
735
        return false;
736
    }
737
738
    // If passing in the OAuth $token, try to get the associated info
739
    // from the persistent store and put it into the PHP session.
740
    if (strlen($token) > 0) {
741
        $dbs = new DBService();
742
        $dbs->getPortalParameters($token);
743
        $status = $dbs->status;
744
        Util::setSessionVar('portalstatus', $status);
745
        if (!($status & 1)) {  // STATUS_OK* codes are even-numbered
746
            Util::setSessionVar('callbackuri', $dbs->cilogon_callback);
747
            Util::setSessionVar('failureuri', $dbs->cilogon_failure);
748
            Util::setSessionVar('successuri', $dbs->cilogon_success);
749
            Util::setSessionVar('portalname', $dbs->cilogon_portal_name);
750
            Util::setSessionVar('tempcred', $dbs->oauth_token);
751
        }
752
    }
753
754
    // Now check to verify all session variables have data
755
    if (
756
        (strlen(Util::getSessionVar('callbackuri')) > 0) &&
757
        (strlen(Util::getSessionVar('failureuri')) > 0) &&
758
        (strlen(Util::getSessionVar('successuri')) > 0) &&
759
        (strlen(Util::getSessionVar('portalname')) > 0) &&
760
        (strlen(Util::getSessionVar('tempcred')) > 0) &&
761
        (!(Util::getSessionVar('portalstatus') & 1))
762
    ) { // STATUS_OK* are even
763
        $retval = true;
764
    }
765
766
    // As a final check, see if this portal requires a forced skin
767
    if ($retval) {
768
        Util::getSkin()->init();
769
    }
770
771
    return $retval;
772
}
773