Completed
Push — master ( 1a0f38...3a0846 )
by Terrence
11:43
created

index-functions.php ➔ printOAuth1Consent()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 31

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 31
rs 9.424
c 0
b 0
f 0
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
Best Practice introduced by
The function printLogonPage() has been defined more than once; this definition is ignored, only the first definition in authorize/index-functions.php (L22-54) 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
    Util::setSessionVar('stage', 'logon');
29
30
    // Check if this is the first time the user has visited the site from
31
    // the current portal.  We do this by checking the portal cookie's
32
    // lifetime for a positive value.  If the portal cookie has NOT YET been
33
    // set, then check the skin config to see if either initialremember or
34
    // initiallifetime has been set.  We do this here because these two
35
    // values set the portal cookie, which needs to be done before we go
36
    // to the next page (where the cookie is actually read).
37
    $skin = Util::getSkin();
38
    $pc = new PortalCookie();
39
    $portallife = $pc->get('lifetime');
40
41
    if ((strlen($portallife) == 0) || ($portallife == 0)) {
42
        $needtosetcookie = 0;
43
44
        // Try to read the skin's initiallifetime
45
        $initlife = $skin->getConfigOption('delegate', 'initiallifetime');
46
        if ((!is_null($initlife)) && ((int)$initlife > 0)) {
47
            $needtosetcookie = 1;
48
            $initlife = (int)$initlife;
49
        } else { // Set a default lifetime value in case initialremember is set
50
            $initlife = 12;
51
        }
52
53
        // Make sure initiallifetime is within [minlifetime..maxlifetime]
54
        list($minlife, $maxlife) = Util::getMinMaxLifetimes('delegate', 240);
0 ignored issues
show
Bug introduced by
The method getMinMaxLifetimes() 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...
55
        if ($initlife < $minlife) {
56
            $needtosetcookie = 1;
57
            $initlife = $minlife;
58
        } elseif ($initlife > $maxlife) {
59
            $needtosetcookie = 1;
60
            $initlife = $maxlife;
61
        }
62
63
        // Next, try to read the skin's initialremember
64
        $initialremember = $skin->getConfigOption('delegate', 'initialremember');
65
        if ((!is_null($initialremember)) && ((int)$initialremember > 0)) {
66
            $needtosetcookie = 1;
67
            $initialremember = (int)$initialremember;
68
        } else { // Set a default remember value in case initiallifetime is set
69
            $initialremember = 0;
70
        }
71
72
        if ($needtosetcookie) {
73
            $pc->set('remember', $initialremember);
74
            $pc->set('lifetime', $initlife);
75
            $pc->write();
76
        }
77
    }
78
79
    Content::printHeader('Welcome To The CILogon Delegation Service');
80
81
    // If the <hideportalinfo> option is set, do not show the portal info if
82
    // the callback uri is in the portal list.
83
    $showportalinfo = true;
84
    if (
85
        ((int)$skin->getConfigOption('portallistaction', 'hideportalinfo') == 1) &&
86
        ($skin->inPortalList(Util::getSessionVar('callbackuri')))
87
    ) {
88
        $showportalinfo = false;
89
    }
90
91
    if ($showportalinfo) {
92
        printOAuth1Consent();
93
    }
94
95
    Content::printWAYF();
96
    Content::printFooter();
97
}
98
99
/**
100
 * printOAuth1BadTokenPage
101
 *
102
 * This function prints out the HTML for the page when the oauth_token
103
 * (tempcred) or associated OAuth information is missing, bad, or expired.
104
 */
105
function printOAuth1ErrorPage()
106
{
107
    $log = new Loggit();
108
    $log->warn('Missing or invalid oauth_token.');
109
110
    Content::printHeader('CILogon Delegation Service');
111
    Content::printCollapseBegin(
0 ignored issues
show
Bug introduced by
The method printCollapseBegin() does not seem to exist on object<CILogon\Service\Content>.

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...
112
        'oauth1default',
113
        'CILogon OAuth1 Delegation Endpoint',
114
        false
115
    );
116
117
    echo '
118
    <div class="card-body px-5">
119
      <div class="card-text my-2">
120
        You have reached the CILogon Delegation Service.  This service is for
121
        use by third parties to obtain certificates for their users.
122
        End users should not normally see this page.
123
      </div>
124
      <div class="card-text my-2">
125
      Possible reasons for seeing this page include:
126
      </div>
127
      <div class="card-text my-2">
128
        <ul>
129
          <li>You navigated directly to this page.</li>
130
          <li>You clicked your browser\'s "Back" button.</li>
131
          <li>There was a problem with the delegation process.</li>
132
        </ul>
133
      </div>
134
      <div class="card-text my-2">
135
        Please return to the previous site and try again. If the error
136
        persists, please contact us at the email address at the bottom of
137
        the page.
138
      </div>
139
      <div class="card-text my-2">
140
        If you are an individual wishing to download a certificate to your
141
        local computer, please try the <a target="_blank"
142
        href="https://' , Util::getHN() , '/">CILogon Service</a>.
143
      </div>
144
      <div class="card-text my-2">
145
        <strong>Note:</strong> You must enable cookies in your web
146
        browser to use this site.
147
      </div>
148
    </div> <!-- end card-body -->
149
    ';
150
151
    Content::printCollapseEnd();
0 ignored issues
show
Bug introduced by
The method printCollapseEnd() does not seem to exist on object<CILogon\Service\Content>.

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...
152
    Content::printFooter();
153
}
154
155
/**
156
 * printMainPage
157
 *
158
 * This function prints out the HTML for the main page where the user
159
 * is presented with the portal information and asked to either allow
160
 * or deny delegation of a certificate to the portal.  We first check
161
 * to see if the 'remember' cookie has been set for this portal. If
162
 * so, then we automatically always approve delegation.  Otherwise,
163
 * we print out the HTML for the <form> buttons.
164
 */
165
function printMainPage()
0 ignored issues
show
Best Practice introduced by
The function printMainPage() has been defined more than once; this definition is ignored, only the first definition in authorize/index-functions.php (L128-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...
166
{
167
    $log = new Loggit();
168
    $log->info('Allow Or Deny Delegation page hit.');
169
170
    Util::setSessionVar('stage', 'main');
171
172
    $remember = 0;   // Default value for remember checkbox is unchecked
173
    $life = 12;      // Default value for lifetime is 12 hours
174
175
    // Check the skin for forceremember and forcelifetime
176
    $skin = Util::getSkin();
177
    $forceremember = $skin->getConfigOption('delegate', 'forceremember');
178
    if ((!is_null($forceremember)) && ((int)$forceremember == 1)) {
179
        $forceremember = 1;
180
    } else {
181
        $forceremember = 0;
182
    }
183
    $forcelife = $skin->getConfigOption('delegate', 'forcelifetime');
184
    if ((!is_null($forcelife)) && ((int)$forcelife > 0)) {
185
        $forcelife = (int)$forcelife;
186
    } else {
187
        $forcelife = 0;
188
    }
189
190
    // Try to read the portal coookie for the remember and lifetime values.
191
    $pc = new PortalCookie();
192
    $portalremember = $pc->get('remember');
193
    $portallife = $pc->get('lifetime');
194
195
    // If skin's forceremember or portal cookie's remember is set,
196
    // then we bypass the Allow/Deny delegate page.
197
    if (($forceremember == 1) || ($portalremember == 1)) {
198
        $remember = 1;
199
    }
200
201
    // If skin's forcelifetime or portal cookie's lifetime is set,
202
    // set lifetime accordingly and make sure value is between the
203
    // configured minlifetime and maxlifetime.
204
    if ($forcelife > 0) {
205
        $life = $forcelife;
206
    } elseif ($portallife > 0) {
207
        $life = $portallife;
208
    }
209
    list($minlife, $maxlife) = Util::getMinMaxLifetimes('delegate', 240);
0 ignored issues
show
Bug introduced by
The method getMinMaxLifetimes() 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...
210
    if ($life < $minlife) {
211
        $life = $minlife;
212
    } elseif ($life > $maxlife) {
213
        $life = $maxlife;
214
    }
215
216
    // If 'remember' is set, then auto-click the 'OK' button for the user.
217
    if ($remember == 1) {
218
        handleAllowDelegation(true);
219
    } else {
220
        // User did not check 'Remember OK' before, so show the
221
        // HTML to prompt user for OK or Cancel delegation.
222
        Content::printHeader('Confirm Allow Delegation');
223
        printOAuth1Certificate($life, $minlife, $maxlife, $forcelife);
224
        Content::printFooter();
225
    }
226
}
227
228
/**
229
 * printOAuth1Consent
230
 *
231
 * This function prints out the 'consent' block showing the portal name and
232
 * callback uris just above the 'Select an Identity Provider' block.
233
 */
234
function printOAuth1Consent()
235
{
236
    Content::printCollapseBegin(
0 ignored issues
show
Bug introduced by
The method printCollapseBegin() does not seem to exist on object<CILogon\Service\Content>.

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...
237
        'oauth2consent',
238
        'Consent to Attribute Release',
239
        false
240
    );
241
242
    echo '
243
        <div class="card-body px-5">
244
          <div class="card-row">
245
            "', htmlspecialchars(Util::getSessionVar('portalname')), '"
246
            requests that you select an Identity Provider and click
247
            "', Content::getLogOnButtonText(), '".
248
            If you do not approve this request, do not proceed.
249
          </div>
250
          <div class="card-row">
251
            By proceeding you agree to share your <em>name</em> and
252
            <em>email address</em> with
253
            "', htmlspecialchars(Util::getSessionVar('portalname')), '".
254
          </div>
255
    ';
256
257
    printOAuth1PortalInfo();
258
259
    echo '
260
        </div> <!-- end card-body -->
261
    ';
262
263
    Content::printCollapseEnd();
0 ignored issues
show
Bug introduced by
The method printCollapseEnd() does not seem to exist on object<CILogon\Service\Content>.

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...
264
}
265
266
/**
267
 * printOAuth1Certificate
268
 *
269
 * This function prints out the block showing the portal name and callback
270
 * uris, as well as a text input for the user to set the lifetime of the
271
 * certificate to be delegated to the OAuth1 client.
272
 *
273
 * @param int $life The lifetime (in hours) for the delegated certificate.
274
 * @param int $minlife The minimum lifetime for the cert.
275
 * @param int $maxlife The maximum lifetime for the cert.
276
 * @param int $force The forced-set lifetime for the cert.
277
 */
278
function printOAuth1Certificate($life, $minlife, $maxlife, $force)
279
{
280
    $lifehelp = 'Certificate lifetime range is between ' .
281
        $minlife . ' and ' . $maxlife . ' hours.';
282
    $rememberhelp = "Check this box to automatically approve " .
283
        "certificate issuance to the site on future visits. " .
284
        "The certificate lifetime will be remembered. You will " .
285
        "need to clear your browser's cookies to return here.";
286
287
    Content::printCollapseBegin(
0 ignored issues
show
Bug introduced by
The method printCollapseBegin() does not seem to exist on object<CILogon\Service\Content>.

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...
288
        'oauth1cert',
289
        'Confirm Certificate Delegation',
290
        false
291
    );
292
293
    echo '
294
        <div class="card-body px-5">
295
          <div class="row mb-3">
296
            "', htmlspecialchars(Util::getSessionVar('portalname')) , '"
297
            is requesting a certificate for you. If you approve, then
298
            "OK" the request. Otherwise, "Cancel" the request or
299
            navigate away from this page.
300
          </div>
301
    ';
302
303
    printOAuth1PortalInfo();
304
305
    Content::printFormHead();
306
307
    echo '
308
          <div class="container col-lg-6 offset-lg-3
309
          col-md-8 offset-md-2 col-sm-10 offset-sm-1">
310
            <div class="form-group">
311
              <div class="form-row">
312
                <label for="lifetime">Certificate Lifetime (in hours):</label>
313
                <input type="number" name="lifetime" id="lifetime"
314
                min="', $minlife, '"
315
                max="', $maxlife, '"
316
                value="', $life , '" ' ,
317
                (($force > 0) ? 'disabled="disabled" ' : ' ') , '
318
                class="form-control" required="required"
319
                aria-describedby="lifetime1help" />
320
                <small id="lifetime1help" class="form-text text-muted">',
321
                $lifehelp, '
322
                </small>
323
<!--[if IE]><input type="text" style="display:none;" disabled="disabled" size="1"/><![endif]-->
324
              </div> <!-- end form-row -->
325
            </div> <!-- end form-group -->
326
327
            <div class="form-group">
328
              <div class="form-row align-items-center justify-content-center">
329
                <div class="form-check">
330
                  <input class="form-check-input" type="checkbox"
331
                  name="rememberok" id="rememberok" />
332
                  <label class="form-check-label"
333
                  for="rememberok">Remember my OK for the site</label>
334
                  <a href="#" tabindex="0" data-trigger="hover click"
335
                  class="helpcursor"
336
                  data-toggle="popover" data-html="true"
337
                  data-content="', $rememberhelp, '"><i class="fa
338
                  fa-question-circle"></i></a>
339
                </div> <!-- end form-check -->
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="col-auto">
346
                  <input type="submit" name="submit"
347
                  class="btn btn-primary submit form-control" value="OK" />
348
                </div>
349
                <div class="col-auto">
350
                  <input type="submit" name="submit"
351
                  class="btn btn-primary submit form-control" value="Cancel" />
352
                </div>
353
              </div> <!-- end form-row align-items-center -->
354
            </div> <!-- end form-group -->
355
          </div> <!-- end container -->
356
357
        </form>
358
        </div> <!-- end card-body -->
359
    ';
360
361
    Content::printCollapseEnd();
0 ignored issues
show
Bug introduced by
The method printCollapseEnd() does not seem to exist on object<CILogon\Service\Content>.

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...
362
}
363
364
/**
365
 * printOAuth1PortalInfo
366
 *
367
 * This function prints the portal name, success uri (i.e., the uri to
368
 * redirect to upon successful delegation of the certificate), and the
369
 * callback uri used by the OAuth1 protocol.
370
 */
371
function printOAuth1PortalInfo()
372
{
373
    echo '
374
    <table class="table table-striped table-sm">
375
    <tbody>
376
      <tr>
377
        <th>Site Name:</th>
378
        <td></td>
379
        <td>', htmlspecialchars(Util::getSessionVar('portalname')), '</td>';
380
381
    $helptext = "The location where you will be redirected upon completion.";
382
383
    echo '
384
      </tr>
385
      <tr>
386
        <th>Site URL:</th>
387
        <td><a href="#" tabindex="0" data-trigger="hover click"
388
          class="helpcursor" data-toggle="popover" data-html="true"
389
          data-content="', $helptext, '"><i class="fa
390
          fa-question-circle"></i></a></td>
391
        <td>', htmlspecialchars(Util::getSessionVar('successuri')), '</td>';
392
393
    $helptext = "The location where CILogon " .
394
        "will send a certificate containing your identity information.";
395
396
    echo '
397
      </tr>
398
      <tr>
399
        <th>Service URL:</th>
400
        <td><a href="#" tabindex="0" data-trigger="hover click"
401
          class="helpcursor" data-toggle="popover" data-html="true"
402
          data-content="', $helptext, '"><i class="fa
403
          fa-question-circle"></i></a></td>
404
        <td>', htmlspecialchars(Util::getSessionVar('callbackuri')), '</td>
405
      </tr>
406
    </tbody>
407
    </table>
408
    ';
409
}
410
411
/**
412
 * printOAuth1DelegationDone
413
 *
414
 * This function prints out the block after generation of the certificate.
415
 * The $success parameter indicates if the cert was generated successfully
416
 * or not. If so, the $responseurl will contain the link to redirect the
417
 * user to, and the $certtext will contain the contents of the cert.
418
 *
419
 * @param bool $success True if the certificate was successfully generated
420
 *        and delegated to the OAuth1 client.
421
 * @param string $responseurl The url to redirect the user to. If this is
422
 *        empty, then the PHP session success/failure uris will be used as
423
 *        determined by the $success value.
424
 * @param string $certtext The contents of the generated cert.
425
 */
426
function printOAuth1DelegationDone($success, $responseurl, $certtext)
427
{
428
    Content::printCollapseBegin(
0 ignored issues
show
Bug introduced by
The method printCollapseBegin() does not seem to exist on object<CILogon\Service\Content>.

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...
429
        'oauth1done',
430
        'Certificate Delegation ' . ($success ? 'Success' : 'Failure'),
431
        false
432
    );
433
434
    echo '
435
        <div class="card-body px-5">
436
    ';
437
438
    if ($success) {
439
        echo '
440
          <div class="card-text my-2">
441
            The CILogon Service has issued a certificate to "' ,
442
            htmlspecialchars(Util::getSessionVar('portalname')) , '".
443
            Below is a link to return to
444
            the site to use the issued certificate.
445
          </div>
446
          ';
447
        Content::printCollapseBegin('certdetails', 'Certificate Details');
0 ignored issues
show
Bug introduced by
The method printCollapseBegin() does not seem to exist on object<CILogon\Service\Content>.

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...
448
        echo '<div class="card-body px-5">
449
                <pre>', htmlspecialchars($certtext), '</pre>
450
              </div>
451
        ';
452
        Content::printCollapseEnd();
0 ignored issues
show
Bug introduced by
The method printCollapseEnd() does not seem to exist on object<CILogon\Service\Content>.

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...
453
    } else {
454
        echo '
455
          <div class="card-text my-2">
456
            We were unable to issue a certificate to "' ,
457
            htmlspecialchars(Util::getSessionVar('portalname')) , '".
458
            Below is a link to return to the site.
459
          </div> <!-- end card-text -->';
460
    }
461
462
    echo '
463
          <div class="card-text my-2 text-center">
464
            <a class="btn btn-primary"
465
            href="' , ((strlen($responseurl) > 0) ? $responseurl :
466
            (Util::getSessionVar($success ? 'successuri' : 'failureuri'))),
467
            '">Return to ' ,
468
            htmlspecialchars(Util::getSessionVar('portalname')) , '</a>
469
          </div> <!-- end card-text -->
470
        </div> <!-- end card-body -->';
471
472
    Content::printCollapseEnd();
0 ignored issues
show
Bug introduced by
The method printCollapseEnd() does not seem to exist on object<CILogon\Service\Content>.

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...
473
}
474
475
/**
476
 * printCancelPage
477
 *
478
 * This function prints out the HTML for when the user clicked the
479
 * 'Cancel' button on the 'Allow Delegation' page.  It gives the user a
480
 * link back to the portal via the 'failure URL'.
481
 */
482
function printCancelPage()
483
{
484
    $portalname = Util::getSessionVar('portalname');
485
486
    Content::printHeader('Delegation Denied');
487
    Content::printCollapseBegin(
0 ignored issues
show
Bug introduced by
The method printCollapseBegin() does not seem to exist on object<CILogon\Service\Content>.

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...
488
        'oauth1cancel',
489
        'Certificate Delegation Cancelled',
490
        false
491
    );
492
493
    echo '
494
        <div class="card-body px-5">
495
          <div class="card-text my-2">
496
            You have canceled delegation of a certificate to "' ,
497
            htmlspecialchars($portalname) , '".
498
            Below is a link to return to the portal.
499
            This link has been provided by the portal to be used when
500
            delegation of a certificate fails.
501
          </div>
502
          <div class="card-text my-2">
503
            <strong>Note:</strong> If you do not trust the information
504
            provided by the portal, <strong>do not</strong> click on the
505
            link below.  Instead, please contact your portal administrators
506
            or contact us at the email address at the bottom of the page.
507
          </div>
508
          <div class="card-text my-2 text-center">
509
            <a class="btn btn-primary"
510
            href="' , Util::getSessionVar('failureuri') , '">Return to ' ,
511
            htmlspecialchars($portalname) , '</a>
512
          </div>
513
        </div> <!-- end card-body -->
514
    ';
515
516
    Content::printCollapseEnd();
0 ignored issues
show
Bug introduced by
The method printCollapseEnd() does not seem to exist on object<CILogon\Service\Content>.

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...
517
    Content::printFooter();
518
}
519
520
/**
521
 * handleAllowDelegation
522
 *
523
 * This fuction is called when the user clicks the 'OK' button on the
524
 * main page, or when the user had previously checked the 'Remember
525
 * my OK for this portal' checkbox which saved the 'remember' cookie
526
 * for the current portal. It first reads the cookie for the portal and
527
 * updates the 'lifetime' and 'remember' parameters, then (re)saves
528
 * the cookie.  Then it calls out to the 'oauth/authorized' servlet
529
 * in order to do the back-end certificate delegation process. If the
530
 * $always parameter is true, then the user is automatically returned
531
 * to the portal's successuri or failureuri.  Otherwise, the user is
532
 * presented with a page showing the result of the attempted
533
 * certificate delegation as well as a link to 'return to your portal'.
534
 *
535
 * @param bool $always True if the user selected to always allow delegation.
536
 */
537
function handleAllowDelegation($always = false)
538
{
539
    // The 'authorized' servlet may return a response URL to be used
540
    // instead of the success / failure URLs.
541
    $responseurl = '';
542
543
    $log = new Loggit();
544
    $log->info('Attempting to delegate a certificate to a portal...');
545
546
    $life = 0;
547
    // Check the skin's forcelifetime and use it if it is configured.
548
    $forcelife = Util::getSkin()->getConfigOption('delegate', 'forcelifetime');
549
    if ((!is_null($forcelife)) && ((int)$forcelife > 0)) {
550
        $life = (int)$forcelife;
551
    }
552
553
    // Next, try to get the certificate lifetime from a submitted <form>
554
    if ($life == 0) {
555
        $life = (int)(trim(Util::getPostVar('lifetime')));
556
    }
557
558
    // If we couldn't get lifetime from the <form>, try the cookie
559
    $pc = new PortalCookie();
560
    if ($life == 0) {
561
        $life = (int)($pc->get('lifetime'));
562
    }
563
564
    // Default lifetime to 12 hours. And then make sure lifetime is in
565
    // acceptable range.
566
    if ($life == 0) {
567
        $life = 12;
568
    }
569
    list($minlife, $maxlife) = Util::getMinMaxLifetimes('delegate', 240);
0 ignored issues
show
Bug introduced by
The method getMinMaxLifetimes() 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...
570
    if ($life < $minlife) {
571
        $life = $minlife;
572
    } elseif ($life > $maxlife) {
573
        $life = $maxlife;
574
    }
575
576
    $pc->set('remember', (int)$always);
577
    $pc->set('lifetime', $life);
578
    $pc->write();
579
580
    $success = false;  // Assume delegation of certificate failed
581
    $certtext = '';    // Output of 'openssl x509 -noout -text -in cert.pem'
582
    $myproxyinfo = Util::getSessionVar('myproxyinfo');
583
584
    // Now call out to the 'oauth/authorized' servlet to execute
585
    // the delegation the credential to the portal.
586
    $ch = curl_init();
587
    if ($ch !== false) {
588
        $tempcred = Util::getSessionVar('tempcred');
589
        $url = OAUTH1_AUTHORIZED_URL . '?' .
590
               'oauth_token=' . urlencode($tempcred) . '&' .
591
               'cilogon_lifetime=' . $life . '&' .
592
               'cilogon_loa=' . urlencode(Util::getSessionVar('loa')) . '&' .
593
               'cilogon_uid=' . urlencode(Util::getSessionVar('uid')) .
594
               ((strlen($myproxyinfo) > 0) ?
595
                   ('&cilogon_info=' . urlencode($myproxyinfo)) : '');
596
        curl_setopt($ch, CURLOPT_URL, $url);
597
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
598
        curl_setopt($ch, CURLOPT_TIMEOUT, 35);
599
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
600
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
601
        $output = curl_exec($ch);
602
        if (curl_errno($ch)) { // Send alert on curl errors
603
            Util::sendErrorAlert(
604
                'cUrl Error',
605
                'cUrl Error    = ' . curl_error($ch) . "\n" .
606
                "URL Accessed  = $url"
607
            );
608
        }
609
        if (!empty($output)) {
610
            $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
611
            if ($httpcode == 200) {
612
                // Check body of curl query for cilogon_status=ok
613
                if (preg_match('/cilogon_status=ok/', $output)) {
614
                    $success = true;
615
                    // Also check if the cert was returned as base64
616
                    // encoded PEM certificate.  If so, get info about it.
617
                    if (
618
                        preg_match(
619
                            '/cilogon_cert=([^\s]+)/',
620
                            $output,
621
                            $matches
622
                        )
623
                    ) {
624
                        $b64cert = $matches[1];
625
                        $cert = base64_decode($b64cert);
626
                        if ($cert !== false) {
627
                            // Run 'openssl x509' command for cert info
628
                            exec(
629
                                '/bin/env RANDFILE=/tmp/.rnd ' .
630
                                '/usr/bin/openssl x509 -text ' .
631
                                '<<< ' . escapeshellarg($cert) . ' 2>&1',
632
                                $x509out,
633
                                $retcode
634
                            );
635
                            if ($retcode === 0) {
636
                                $certtext = implode("\n", $x509out);
637
                            } else {
638
                                $certtext = $cert;
639
                            }
640
                        }
641
                    }
642
                }
643
                // Check for an alternate response URL to be used
644
                // in place of success / failure URLs.
645
                if (
646
                    preg_match(
647
                        '/cilogon_response_url=([^\s]+)/',
648
                        $output,
649
                        $matches
650
                    )
651
                ) {
652
                    $responseurl = $matches[1];
653
                }
654
            }
655
        }
656
        curl_close($ch);
657
    }
658
659
    $log = new Loggit();
660
    $log->info('Delegation of certificate to portal ' .
661
               ($success ? 'succeeded.' : 'failed.'));
662
    //CIL-507 Special log message for XSEDE
663
    $log->info('USAGE email="' . Util::getSessionVar('emailaddr') .
664
               '" client="' . Util::getSessionVar('portalname') . '"');
665
666
667
    // Depending on the result (success or failure), output appropriate
668
    // HTML to allow the user to return to the portal, or if $always
669
    // was set, then automatically return the user to the successuri,
670
    // failureuri, or cilogon_reponse_url if supplied by authorized servlet.
671
    if ($always) {
672
        $log->info("Automatically returning to portal's " .
673
            ($success ? 'success' : 'failure') . ' url.');
674
        $location = 'Location: ' . ((strlen($responseurl) > 0) ? $responseurl :
675
            (Util::getSessionVar($success ? 'successuri' : 'failureuri')));
676
        if ($success) {
677
            Util::unsetClientSessionVars();
678
            /// Util::unsetAllUserSessionVars();
679
        } else {
680
            Util::unsetAllUserSessionVars();
681
        }
682
        header($location);
683
        exit; // No further processing necessary
684
    } else {
685
        Content::printHeader('Delegation ' . ($success ? 'Successful' : 'Failed'));
686
        printOAuth1DelegationDone($success, $responseurl, $certtext);
687
        Content::printFooter();
688
        if ($success) {
689
            Util::unsetClientSessionVars();
690
        } else {
691
            Util::unsetAllUserSessionVars();
692
        }
693
    }
694
}
695
696
/**
697
 * verifyOAuthToken
698
 *
699
 * This function verifies that all of the various PortalParameters
700
 * have been set in the PHP session.  If the first parameter is passed
701
 * in, it first attempts to call CILogon::getPortalParameters() and
702
 * populates the PHP session with the associated values.
703
 *
704
 * @param string $token (Optional) The temporary credential passed from a
705
 *        Community Portal to the 'delegate' script as 'oauth_token' in the
706
 *        URL (as a $_GET variable). Defaults to empty string.
707
 * @return bool True if the various parameters related to the OAuth
708
 *         token (callbackuri, failureuri, successuri, portalname,
709
 *         and tempcred) are in the PHP session, false otherwise.
710
 */
711
function verifyOAuthToken($token = '')
712
{
713
    $retval = false; // Assume OAuth session info is not valid
714
715
    // If passing in the OAuth $token, try to get the associated info
716
    // from the persistent store and put it into the PHP session.
717
    if (strlen($token) > 0) {
718
        $dbs = new DBService();
719
        $dbs->getPortalParameters($token);
720
        $status = $dbs->status;
721
        Util::setSessionVar('portalstatus', $status);
722
        if (!($status & 1)) {  // STATUS_OK* codes are even-numbered
723
            Util::setSessionVar('callbackuri', $dbs->cilogon_callback);
724
            Util::setSessionVar('failureuri', $dbs->cilogon_failure);
725
            Util::setSessionVar('successuri', $dbs->cilogon_success);
726
            Util::setSessionVar('portalname', $dbs->cilogon_portal_name);
727
            Util::setSessionVar('tempcred', $dbs->oauth_token);
728
        }
729
    }
730
731
    // Now check to verify all session variables have data
732
    if (
733
        (strlen(Util::getSessionVar('callbackuri')) > 0) &&
734
        (strlen(Util::getSessionVar('failureuri')) > 0) &&
735
        (strlen(Util::getSessionVar('successuri')) > 0) &&
736
        (strlen(Util::getSessionVar('portalname')) > 0) &&
737
        (strlen(Util::getSessionVar('tempcred')) > 0) &&
738
        (!(Util::getSessionVar('portalstatus') & 1))
739
    ) { // STATUS_OK* are even
740
        $retval = true;
741
    }
742
743
    // As a final check, see if this portal requires a forced skin
744
    if ($retval) {
745
        Util::getSkin()->init();
746
    }
747
748
    return $retval;
749
}
750