This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
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\DBService; |
||
13 | use CILogon\Service\Loggit; |
||
14 | |||
15 | /** |
||
16 | * printLogonPage |
||
17 | * |
||
18 | * This function prints out the HTML for the main cilogon.org page. |
||
19 | * Explanatory text is shown as well as a button to log in to an IdP |
||
20 | * and get rerouted to the Shibboleth protected getuser script. |
||
21 | */ |
||
22 | function printLogonPage() |
||
23 | { |
||
24 | $log = new Loggit(); |
||
25 | $log->info('Welcome page hit.'); |
||
26 | |||
27 | Content::printHeader( |
||
28 | 'Welcome To The CILogon OpenID Connect Authorization Service' |
||
29 | ); |
||
30 | |||
31 | $clientparams = json_decode(Util::getSessionVar('clientparams'), true); |
||
32 | |||
33 | // If the <hideportalinfo> option is set, do not show the portal info |
||
34 | // if the OIDC redirect_uri or client_id is in the portal list. |
||
35 | $showportalinfo = true; |
||
36 | $skin = Util::getSkin(); |
||
37 | if ( |
||
38 | ((int)$skin->getConfigOption('portallistaction', 'hideportalinfo') == 1) && |
||
39 | ( |
||
40 | ($skin->inPortalList($clientparams['redirect_uri'])) || |
||
41 | ($skin->inPortalList($clientparams['client_id'])) |
||
42 | ) |
||
43 | ) { |
||
44 | $showportalinfo = false; |
||
45 | } |
||
46 | |||
47 | if ($showportalinfo) { |
||
48 | Content::printOIDCConsent(); |
||
0 ignored issues
–
show
|
|||
49 | } |
||
50 | Content::printWAYF(); |
||
51 | Content::printFooter(); |
||
52 | } |
||
53 | |||
54 | /** |
||
55 | * printOIDCErrorPage |
||
56 | * |
||
57 | * This function prints out the HTML for the page when the the various |
||
58 | * OIDC parameters sent by the client are missing or bad. |
||
59 | */ |
||
60 | function printOIDCErrorPage() |
||
61 | { |
||
62 | $log = new Loggit(); |
||
63 | $log->warn('Missing or invalid OIDC parameters.'); |
||
64 | |||
65 | Content::printHeader('CILogon Authorization Endpoint'); |
||
66 | Content::printCollapseBegin('oidcdefault', 'CILogon OIDC Authorization Endpoint', false); |
||
67 | |||
68 | echo ' |
||
69 | <div class="card-body px-5"> |
||
70 | <div class="card-text my-2"> |
||
71 | You have reached the CILogon OAuth2/OpenID Connect (OIDC) |
||
72 | Authorization Endpoint. This service is for use by OAuth2/OIDC |
||
73 | Relying Parties (RPs) to authorize users of the CILogon Service. |
||
74 | End users should not normally see this page. |
||
75 | </div> <!-- end row --> |
||
76 | '; |
||
77 | |||
78 | $client_error_msg = Util::getSessionVar('client_error_msg'); |
||
79 | Util::unsetSessionVar('client_error_msg'); |
||
80 | if (strlen($client_error_msg) > 0) { |
||
81 | echo '<div class="alert alert-danger" role="alert">', $client_error_msg, '</div>'; |
||
82 | } else { |
||
83 | echo ' |
||
84 | <div class="card-text my-2"> |
||
85 | Possible reasons for seeing this page include: |
||
86 | </div> <!-- end row --> |
||
87 | <div class="card-text my-2"> |
||
88 | <ul> |
||
89 | <li>You navigated directly to this page.</li> |
||
90 | <li>You clicked your browser\'s "Back" button.</li> |
||
91 | <li>There was a problem with the OpenID Connect client.</li> |
||
92 | </ul> |
||
93 | </div> <!-- end row --> |
||
94 | '; |
||
95 | } |
||
96 | |||
97 | echo ' |
||
98 | <div class="card-text my-2"> |
||
99 | For assistance, please contact us at the email address at the |
||
100 | bottom of the page. |
||
101 | </div> |
||
102 | <div class="card-text my-2"> |
||
103 | <strong>Note:</strong> You must enable cookies in your web |
||
104 | browser to use this site. |
||
105 | </div> |
||
106 | </div> <!-- end card-body --> |
||
107 | '; |
||
108 | |||
109 | Content::printCollapseEnd(); |
||
110 | Content::printFooter(); |
||
111 | } |
||
112 | |||
113 | /** |
||
114 | * printMainPage |
||
115 | * |
||
116 | * This function is poorly named for the OIDC case, but is called by |
||
117 | * gotUserSuccess, so the name stays. This function is called once the |
||
118 | * user has successfully logged on at the selected IdP. In the OIDC |
||
119 | * case, the user's UID is then paired with the OIDC 'code' and |
||
120 | * 'authntime' in the datastore so that it can be fetched later when |
||
121 | * the OIDC client wants to get userinfo or a certificate. There |
||
122 | * really isn't anything 'printed' to the user here. Control is |
||
123 | * simply redirected to the OIDC client with appropriate success or |
||
124 | * error response. |
||
125 | */ |
||
126 | function printMainPage() |
||
127 | { |
||
128 | $clientparams = json_decode(Util::getSessionVar('clientparams'), true); |
||
129 | $redirect = 'Location: ' . $clientparams['redirect_url']; |
||
130 | |||
131 | $log = new Loggit(); |
||
132 | $log->info('Calling setTransactionState dbService method...'); |
||
133 | |||
134 | $dbs = new DBService(); |
||
135 | if ( |
||
136 | ($dbs->setTransactionState( |
||
137 | $clientparams['code'], |
||
138 | Util::getSessionVar('user_uid'), |
||
139 | Util::getSessionVar('authntime'), |
||
140 | Util::getLOA(), |
||
141 | Util::getSessionVar('myproxyinfo') |
||
142 | )) && (!($dbs->status & 1)) |
||
143 | ) { // STATUS_OK codes are even |
||
144 | // CIL-360 - Check for Response Mode |
||
145 | // http://openid.net/specs/oauth-v2-multiple-response-types-1_0.html#ResponseModes |
||
146 | if (isset($clientparams['response_mode'])) { |
||
147 | $responsemode = $clientparams['response_mode']; |
||
148 | if ($responsemode == 'query') { |
||
149 | // This is the default mode for 'code' response |
||
150 | } elseif ($responsemode == 'fragment') { |
||
151 | // Replace '?' with '#' |
||
152 | $redirect = str_replace('?', '#', $redirect); |
||
153 | } elseif ($responsemode == 'form_post') { |
||
154 | // https://openid.net/specs/oauth-v2-form-post-response-mode-1_0.html |
||
155 | // At this point, $clientparams['redirect_url'] contains |
||
156 | // both the callback uri and all query string parameters |
||
157 | // that should be passed to the callback uri. We need |
||
158 | // to separate the two so we can put the query parameters |
||
159 | // into hidden <input> fields in the output form. |
||
160 | $orig_redirect_uri = $clientparams['redirect_uri']; |
||
161 | $full_redirect_url = $clientparams['redirect_url']; |
||
162 | $queryparams = str_replace( |
||
163 | $orig_redirect_uri . '?', |
||
164 | '', |
||
165 | $full_redirect_url |
||
166 | ); |
||
167 | Util::unsetClientSessionVars(); |
||
168 | // Util::unsetAllUserSessionVars(); |
||
169 | // Get the components of the response (split by '&') |
||
170 | $comps = explode('&', $queryparams); |
||
171 | $outform = '<html> |
||
172 | <head><title>Submit This Form</title></head> |
||
173 | <body onload="javascript:document.forms[0].submit()"> |
||
174 | <form method="post" action="' . $orig_redirect_uri . '"> |
||
175 | '; |
||
176 | foreach ($comps as $value) { |
||
177 | $params = explode('=', $value); |
||
178 | $outform .= '<input type="hidden" name="' . $params[0] . |
||
179 | '" value="' . html_entity_decode($params[1]) . '"/>'; |
||
180 | } |
||
181 | $outform .= ' |
||
182 | </form> |
||
183 | </body> |
||
184 | </html>'; |
||
185 | $log->info( |
||
186 | 'response_mode=form_post; outputting form' . "\n" . |
||
187 | $outform |
||
188 | ); |
||
189 | echo $outform; |
||
190 | exit; // No further processing necessary |
||
191 | } |
||
192 | } |
||
193 | $log->info('setTransactionState succeeded, redirect to ' . $redirect); |
||
194 | // CIL-507 Special log message for XSEDE |
||
195 | $email = Util::getSessionVar('email'); |
||
196 | $clientname = $clientparams['client_name']; |
||
197 | $log->info("USAGE email=\"$email\" client=\"$clientname\""); |
||
198 | 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. ![]() |
|||
199 | } else { // dbservice error |
||
200 | $errstr = ''; |
||
201 | if (!is_null($dbs->status)) { |
||
202 | $errstr = array_search($dbs->status, DBService::$STATUS); |
||
203 | } |
||
204 | $redirect = 'Location: ' . $clientparams['redirect_uri'] . |
||
205 | (preg_match('/\?/', $clientparams['redirect_uri']) ? '&' : '?') . |
||
206 | 'error=server_error&error_description=' . |
||
207 | 'Unable%20to%20associate%20user%20UID%20with%20OIDC%20code' . |
||
208 | ((isset($clientparams['state'])) ? |
||
209 | '&state=' . $clientparams['state'] : ''); |
||
210 | $log->info("setTransactionState failed $errstr, redirect to $redirect"); |
||
211 | Util::sendErrorAlert( |
||
212 | 'dbService Error', |
||
213 | 'Error calling dbservice action "setTransactionState" in ' . |
||
214 | 'OIDC authorization endpoint\'s printMainPage() method. ' . |
||
215 | $errstr . ' Redirected to ' . $redirect |
||
216 | ); |
||
217 | Util::unsetUserSessionVars(); |
||
218 | } |
||
219 | |||
220 | Util::unsetClientSessionVars(); |
||
221 | // Util::unsetAllUserSessionVars(); |
||
222 | header($redirect); |
||
223 | exit; // No further processing necessary |
||
224 | } |
||
225 | |||
226 | /** |
||
227 | * verifyOIDCParams |
||
228 | * |
||
229 | * This function verifies that all of the various OIDC parameters are |
||
230 | * set in the PHP session. First, the function checks if an OIDC |
||
231 | * client has passed appropriate parameters to the authorization |
||
232 | * endpoint. If so, we call the 'real' OA4MP OIDC authorization |
||
233 | * endpoint and let it verify the client parameters. Upon successful |
||
234 | * return, we read the database to get the OIDC client information |
||
235 | * to display to the user. All client parameters (including the ones |
||
236 | * passed in) are saved to the 'clientparams' PHP session variable, |
||
237 | * which is encoded as a JSON token to preserve arrays. If there are |
||
238 | * any errors, false is returned and an email is sent. In some cases |
||
239 | * the session variable 'client_error_msg' is set so it can be |
||
240 | * displayed by the printOIDCErrorPage() function. |
||
241 | * |
||
242 | * @return bool True if the various parameters related to the OIDC |
||
243 | * session are present. False otherwise. |
||
244 | */ |
||
245 | function verifyOIDCParams() |
||
246 | { |
||
247 | $retval = false; // Assume OIDC session info is not valid |
||
248 | |||
249 | // Combine the $_GET and $_POST arrays into a single array which can be |
||
250 | // stored in the 'clientparams' session variable as a JSON object. |
||
251 | $clientparams = array(); |
||
252 | foreach ($_GET as $key => $value) { |
||
253 | $clientparams[$key] = $value; |
||
254 | } |
||
255 | foreach ($_POST as $key => $value) { |
||
256 | $clientparams[$key] = $value; |
||
257 | } |
||
258 | |||
259 | // CIL-624 If X509 certs are disabled, check for 'getcert' scope. |
||
260 | // If found, show an error message. |
||
261 | $scope = Util::getGetVar('scope'); |
||
262 | if ( |
||
263 | (defined('DISABLE_X509')) && |
||
264 | (DISABLE_X509 === true) && |
||
265 | (preg_match('/edu.uiuc.ncsa.myproxy.getcert/', $scope)) |
||
266 | ) { |
||
267 | Util::sendErrorAlert( |
||
268 | 'CILogon OIDC authz endpoint error', |
||
269 | 'The CILogon OIDC authorization endpoint received a request ' . |
||
270 | 'including the "edu.ncsa.uiuc.myproxy.getcert" scope, ' . |
||
271 | 'but the server is configured with DISABLE_X509 to prevent ' . |
||
272 | 'downloading certificates. ' . |
||
273 | "\n\n" . |
||
274 | 'clientparams = ' . print_r($clientparams, true) . |
||
275 | "\n" |
||
276 | ); |
||
277 | Util::setSessionVar( |
||
278 | 'client_error_msg', |
||
279 | 'The CILogon Service is currently configured to prevent ' . |
||
280 | 'downloading X.509 certificates, but the incoming request ' . |
||
281 | 'included the "edu.ncsa.uiuc.myproxy.getcert" scope. ' . |
||
282 | 'CILogon system administrators have been notified.' |
||
283 | ); |
||
284 | $clientparams = array(); |
||
285 | |||
286 | // If the 'redirect_uri' parameter was passed in then let the 'real' |
||
287 | // OA4MP OIDC authz endpoint handle parse the request since it might be |
||
288 | // possible to return an error code to the client. |
||
289 | } elseif (isset($clientparams['redirect_uri'])) { |
||
290 | $ch = curl_init(); |
||
291 | if ($ch !== false) { |
||
292 | $url = OAUTH2_CREATE_TRANSACTION_URL; |
||
293 | if (count($_GET) > 0) { |
||
294 | // CIL-658 Look for double-encoded spaces in 'scope' |
||
295 | if (strlen($scope) > 0) { |
||
296 | $_GET['scope'] = preg_replace('/(\+|%2B)/', ' ', $scope); |
||
297 | } |
||
298 | $url .= (preg_match('/\?/', $url) ? '&' : '?') . |
||
299 | http_build_query($_GET); |
||
300 | } |
||
301 | if (count($_POST) > 0) { |
||
302 | curl_setopt($ch, CURLOPT_POST, true); |
||
303 | curl_setopt($ch, CUROPT_POSTFIELDS, http_build_query($_POST)); |
||
304 | } |
||
305 | curl_setopt($ch, CURLOPT_URL, $url); |
||
306 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); |
||
307 | curl_setopt($ch, CURLOPT_TIMEOUT, 30); |
||
308 | curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false); // Catch redirects |
||
309 | $output = curl_exec($ch); |
||
310 | if (curl_errno($ch)) { // Send alert on curl errors |
||
311 | Util::sendErrorAlert( |
||
312 | 'cUrl Error', |
||
313 | 'cUrl Error = ' . curl_error($ch) . "\n" . |
||
314 | "URL Accessed = $url" . |
||
315 | "\n\n" . |
||
316 | 'clientparams = ' . print_r($clientparams, true) |
||
317 | ); |
||
318 | $clientparams = array(); |
||
319 | } else { |
||
320 | $info = curl_getinfo($ch); |
||
321 | if ($info !== false) { |
||
322 | if ( |
||
323 | (isset($info['http_code'])) && |
||
324 | ($info['http_code'] == 200) |
||
325 | ) { |
||
326 | // The OA4MP OIDC authz endpoint responded with 200 |
||
327 | // (success). The body of the message should be a |
||
328 | // JSON token containing the appropriate parameters |
||
329 | // such as the 'code'. |
||
330 | $json = json_decode($output, true); |
||
331 | if (isset($json['code'])) { |
||
332 | // Got 'code' - save to session and read OIDC |
||
333 | // client info from the database to display |
||
334 | // to the user |
||
335 | $clientparams['redirect_url'] = |
||
336 | $clientparams['redirect_uri'] . |
||
337 | (preg_match('/\?/', $clientparams['redirect_uri']) ? '&' : '?') . |
||
338 | http_build_query($json); |
||
339 | $clientparams['code'] = $json['code']; |
||
340 | // CIL-618 Read OIDC client info from database |
||
341 | if (!Util::getOIDCClientParams($clientparams)) { |
||
342 | Util::sendErrorAlert( |
||
343 | 'getOIDCClientParams Error', |
||
344 | 'Error getting OIDC client parameters ' . |
||
345 | 'in verifyOIDCParams() function for ' . |
||
346 | 'client_id="' . |
||
347 | $clientparams['client_id'] . '".' |
||
348 | ); |
||
349 | $clientparams = array(); |
||
350 | } |
||
351 | } else { |
||
352 | // Either the output returned was not a valid |
||
353 | // JSON token, or there was no 'code' found in |
||
354 | // the returned JSON token. |
||
355 | $errortxt = getErrorStatusText($output, $clientparams); |
||
356 | |||
357 | Util::sendErrorAlert( |
||
358 | 'OA4MP OIDC authz endpoint error', |
||
359 | (!empty($errortxt) ? $errortxt : |
||
360 | 'The OA4MP OIDC authorization endpoint ' . |
||
361 | 'returned an HTTP response 200, but either ' . |
||
362 | 'the output was not a valid JSON token, or ' . |
||
363 | 'there was no "code" in the JSON token. ' . |
||
364 | ((strlen($output) > 0) ? |
||
365 | "\n\nReturned output =\n$output" : '')) . |
||
366 | "\n\n" . |
||
367 | 'curl_getinfo = ' . print_r($info, true) . "\n\n" . |
||
368 | 'clientparams = ' . print_r($clientparams, true) . |
||
369 | "\n" |
||
370 | ); |
||
371 | Util::setSessionVar( |
||
372 | 'client_error_msg', |
||
373 | 'There was an unrecoverable error during the transaction. ' . |
||
374 | 'CILogon system administrators have been notified. ' . |
||
375 | (!empty($errortxt) ? "<p><b>Error message: $errortxt</b><p>" : '') |
||
376 | ); |
||
377 | $clientparams = array(); |
||
378 | } |
||
379 | } elseif ( |
||
380 | (isset($info['http_code'])) && |
||
381 | ($info['http_code'] == 302) |
||
382 | ) { |
||
383 | // The OA4MP OIDC authz endpoint responded with 302 |
||
384 | // (redirect) which indicates an OIDC error was |
||
385 | // detected. We need to check the response for an |
||
386 | // 'error' and simply redirect error to OIDC client. |
||
387 | $redirect_url = ''; |
||
388 | if (isset($info['redirect_url'])) { |
||
389 | $redirect_url = $info['redirect_url']; |
||
390 | $clientparams['redirect_url'] = $redirect_url; |
||
391 | // CIL-407 - In case of two question marks '?' |
||
392 | // in redirect_url (caused by OIDC authz endpoint |
||
393 | // blindly appending "?error=..."), change all |
||
394 | // but the first '?' to '&'. |
||
395 | // https://stackoverflow.com/a/37150213 |
||
396 | if (substr_count($redirect_url, '?') > 1) { |
||
397 | $arr = explode('?', $redirect_url, 2); |
||
398 | $arr[1] = str_replace('?', '&', $arr[1]); |
||
399 | $redirect_url = implode('?', $arr); |
||
400 | } |
||
401 | } |
||
402 | // Get components of redirect_url - need 'query' |
||
403 | $comps = parse_url($redirect_url); |
||
404 | if ($comps !== false) { |
||
405 | // Look for 'error' in query |
||
406 | $query = ''; |
||
407 | if (isset($comps['query'])) { |
||
408 | $query = $comps['query']; |
||
409 | $query = html_entity_decode($query); |
||
410 | } |
||
411 | $queries = explode('&', $query); |
||
412 | $params = array(); |
||
413 | foreach ($queries as $value) { |
||
414 | $x = explode('=', $value); |
||
415 | $params[$x[0]] = $x[1]; |
||
416 | } |
||
417 | if (isset($params['error'])) { |
||
418 | // Got 'error' - simply return to OIDC client |
||
419 | Util::unsetAllUserSessionVars(); |
||
420 | header("Location: $redirect_url"); |
||
421 | exit; // No further processing necessary |
||
422 | } else { // Weird params - Should never get here! |
||
423 | Util::sendErrorAlert( |
||
424 | 'OA4MP OIDC 302 Error', |
||
425 | 'The OA4MP OIDC authz endpoint ' . |
||
426 | 'returned a 302 redirect (error) ' . |
||
427 | 'response, but there was no "error" ' . |
||
428 | "query parameter.\n\n" . |
||
429 | "redirect_url = $redirect_url\n\n" . |
||
430 | 'clientparams = ' . |
||
431 | print_r($clientparams, true) . |
||
432 | "\n" |
||
433 | ); |
||
434 | $clientparams = array(); |
||
435 | } |
||
436 | } else { // parse_url($redirect_url) gave error |
||
437 | Util::sendErrorAlert( |
||
438 | 'parse_url(redirect_url) error', |
||
439 | 'There was an error when attempting to ' . |
||
440 | 'parse the redirect_url. This should never ' . |
||
441 | "happen.\n\n" . |
||
442 | "redirect_url = $redirect_url\n\n" . |
||
443 | 'clientparams = ' . print_r($clientparams, true) . |
||
444 | "\n" |
||
445 | ); |
||
446 | $clientparams = array(); |
||
447 | } |
||
448 | } else { |
||
449 | // An HTTP return code other than 200 (success) or |
||
450 | // 302 (redirect) means that the OA4MP OIDC authz |
||
451 | // endpoint tried to handle an unrecoverable error, |
||
452 | // possibly by outputting HTML. If so, then we |
||
453 | // ignore it and output our own error message to the |
||
454 | // user. |
||
455 | Util::sendErrorAlert( |
||
456 | 'OA4MP OIDC authz endpoint error', |
||
457 | 'The OA4MP OIDC authorization endpoint returned ' . |
||
458 | 'an HTTP response other than 200 or 302. ' . |
||
459 | ((strlen($output) > 0) ? |
||
460 | "\n\nReturned output =\n$output" : '') . |
||
461 | "\n\n" . |
||
462 | 'curl_getinfo = ' . print_r($info, true) . "\n\n" . |
||
463 | 'clientparams = ' . print_r($clientparams, true) . |
||
464 | "\n" |
||
465 | ); |
||
466 | // CIL-423 Better end-user error output for errors. |
||
467 | // Scan output for ServletException message. |
||
468 | $errstr = ''; |
||
469 | if ( |
||
470 | preg_match( |
||
471 | '/javax.servlet.ServletException:\s?(.*)/', |
||
472 | $output, |
||
473 | $matches |
||
474 | ) |
||
475 | ) { |
||
476 | $output = ''; |
||
477 | $errstr = ' |
||
478 | <div> |
||
479 | <p>Error Message: <b>' . |
||
480 | $matches[1] . '</b>.</p> |
||
481 | <ul> |
||
482 | <li>Did you <b>register</b> your OAuth2/OIDC client? If not, go |
||
483 | <b><a target="_blank" href="https://' . |
||
484 | Util::getHN() |
||
485 | . '/oauth2/register">here</a></b> to do so.</li> |
||
486 | <li>Did you receive confirmation that your OAuth2/OIDC client |
||
487 | was <b>approved</b>? If not, please wait up to 48 hours for an |
||
488 | approval email from CILogon administrators.</li> |
||
489 | <li>Did you configure your OAuth2/OIDC client with the |
||
490 | registered <b>client ID and secret</b>?</li> |
||
491 | </ul> |
||
492 | </div>'; |
||
493 | } |
||
494 | Util::setSessionVar( |
||
495 | 'client_error_msg', |
||
496 | 'There was an unrecoverable error during the transaction. ' . |
||
497 | 'CILogon system administrators have been notified.' . |
||
498 | ((strlen($errstr) > 0) ? $errstr : '') . |
||
499 | ((strlen($output) > 0) ? |
||
500 | '<br/><pre>' . |
||
501 | preg_replace('/\+/', ' ', $output) . |
||
502 | '</pre>' : '') |
||
503 | ); |
||
504 | $clientparams = array(); |
||
505 | } |
||
506 | } else { // curl_getinfo() returned false - should not happen |
||
507 | Util::sendErrorAlert( |
||
508 | 'curl_getinfo error', |
||
509 | 'When attempting to talk to the OA4MP OIDC ' . |
||
510 | 'authorization endpoint, curl_getinfo() returned ' . |
||
511 | "false. This should never happen.\n\n" . |
||
512 | 'clientparams = ' . print_r($clientparams, true) . "\n" |
||
513 | ); |
||
514 | $clientparams = array(); |
||
515 | } |
||
516 | } |
||
517 | curl_close($ch); |
||
518 | } else { // curl_init() returned false - should not happen |
||
519 | Util::sendErrorAlert( |
||
520 | 'curl_init error', |
||
521 | 'When attempting to talk to the OA4MP OIDC authorization ' . |
||
522 | 'endpoint, curl_init() returned false. This should never ' . |
||
523 | "happen.\n\n" . |
||
524 | 'clientparams = ' . print_r($clientparams, true) . "\n" |
||
525 | ); |
||
526 | $clientparams = array(); |
||
527 | } |
||
528 | |||
529 | // If redirect_uri was not passed in, but one of the other required OIDC |
||
530 | // parameters WAS passed in, then assume that this was an attempt by an |
||
531 | // OIDC client to use the authz endpoint, and display an error message |
||
532 | // that at least one parameter (redirect_uri) was missing from the |
||
533 | // request. Note that since we don't have a redirect_uri, we cannot |
||
534 | // return code flow back to the OIDC client. |
||
535 | } elseif ( |
||
536 | (isset($clientparams['client_id'])) || |
||
537 | (isset($clientparams['scope'])) || |
||
538 | (isset($clientparams['response_type'])) |
||
539 | ) { |
||
540 | $missing = 'redirect_uri' . |
||
541 | ((isset($clientparams['client_id'])) ? '' : ', client_id') . |
||
542 | ((isset($clientparams['scope'])) ? '' : ', scope') . |
||
543 | ((isset($clientparams['response_type'])) ? '' : ', response_type'); |
||
544 | Util::sendErrorAlert( |
||
545 | 'CILogon OIDC authz endpoint error', |
||
546 | 'The CILogon OIDC authorization endpoint received a request ' . |
||
547 | 'from an OIDC client, but at least one of the required ' . |
||
548 | 'parameters (' . $missing . ') was missing. ' . |
||
549 | "\n\n" . |
||
550 | 'clientparams = ' . print_r($clientparams, true) . |
||
551 | "\n" |
||
552 | ); |
||
553 | Util::setSessionVar( |
||
554 | 'client_error_msg', |
||
555 | 'It appears that an OpenID Connect client attempted to ' . |
||
556 | 'initiate a session with the CILogon Service, but at least ' . |
||
557 | 'one of the requried parameters (' . $missing . ') ' . |
||
558 | 'was missing. CILogon system administrators have been notified.' |
||
559 | ); |
||
560 | $clientparams = array(); |
||
561 | |||
562 | // If none of the required OIDC authz endpoint parameters were passed |
||
563 | // in, then this might be a later step in the authz process. So check |
||
564 | // the session variable array 'clientparams' for the required |
||
565 | // information. |
||
566 | } else { |
||
567 | $clientparams = json_decode(Util::getSessionVar('clientparams'), true); |
||
568 | } |
||
569 | |||
570 | // Now check to verify all variables have data |
||
571 | if ( |
||
572 | (isset($clientparams['redirect_uri'])) && |
||
573 | (isset($clientparams['scope'])) && |
||
574 | (isset($clientparams['response_type'])) && |
||
575 | (isset($clientparams['client_id'])) && |
||
576 | (isset($clientparams['code'])) && |
||
577 | (isset($clientparams['client_name'])) && |
||
578 | (isset($clientparams['client_home_url'])) && |
||
579 | (isset($clientparams['client_callback_uri'])) && |
||
580 | (isset($clientparams['client_scopes'])) && |
||
581 | (isset($clientparams['redirect_url'])) && |
||
582 | (isset($clientparams['clientstatus'])) && |
||
583 | (!($clientparams['clientstatus'] & 1)) |
||
584 | ) { // STATUS_OK* are even |
||
585 | $retval = true; |
||
586 | Util::setSessionVar('clientparams', json_encode($clientparams)); |
||
587 | } |
||
588 | |||
589 | return $retval; |
||
590 | } |
||
591 | |||
592 | /** |
||
593 | * getErrorStatusText |
||
594 | * |
||
595 | * This function is called when the OA4MP OIDC authz endpoint responds with |
||
596 | * a 200 (success), but the returned output was not a valid JSON token, or |
||
597 | * there was no 'code' found in the returned JSON token. So attempt to scan |
||
598 | * the returned $output for error messages that can be returned to the end |
||
599 | * user and added to the alert email sent to admins. |
||
600 | * |
||
601 | * @param string $output The returned text from the OA4MP authz endpoint. |
||
602 | * @param array $clientparams An array of the incoming OIDC client parameters. |
||
603 | * @return string Error text to be displayed to the end user and added to |
||
604 | * the alert email sent to admins. |
||
605 | */ |
||
606 | function getErrorStatusText($output, $clientparams) |
||
607 | { |
||
608 | $errstr = ''; |
||
609 | $errtxt = ''; |
||
610 | |||
611 | // CIL-575 Check the $output for a "status=..." line and convert |
||
612 | // the error number to an error message defined in CILogon\Service\Util. |
||
613 | if (preg_match('/status=(\d+)/', $output, $matches)) { |
||
614 | $errnum = $matches[1]; |
||
615 | $errstr = array_search($errnum, DBService::$STATUS); |
||
616 | $errtxt = @DBService::$STATUS_TEXT[$errstr]; |
||
617 | } |
||
618 | |||
619 | // CIL-831 The OA4MP code returns a STATUS_INTERNAL_ERROR when there is |
||
620 | // weirdness in the incoming client parameters. Look for some special |
||
621 | // error conditions and set the error text appropriately. |
||
622 | if ( |
||
623 | (strlen($errstr) == 0) || |
||
624 | ($errstr == 'STATUS_INTERNAL_ERROR') || |
||
625 | ($errstr == 'STATUS_CREATE_TRANSACTION_FAILED') || |
||
626 | ($errstr == 'STATUS_MISSING_PARAMETER_ERROR') |
||
627 | ) { |
||
628 | $params = [ |
||
629 | 'redirect_uri', |
||
630 | 'scope', |
||
631 | 'response_type', |
||
632 | 'client_id', |
||
633 | 'prompt', |
||
634 | 'response_mode', |
||
635 | ]; |
||
636 | foreach ($params as $value) { |
||
637 | $$value = @$clientparams[$value]; |
||
638 | } |
||
639 | |||
640 | if (empty($scope)) { |
||
0 ignored issues
–
show
The variable
$scope seems to never exist, and therefore empty should always return true . Did you maybe rename this variable?
This check looks for calls to This is most likely caused by the renaming of a variable or the removal of a function/method parameter. ![]() |
|||
641 | $errtxt = "Missing or empty scope parameter."; |
||
642 | } elseif (empty($client_id)) { |
||
0 ignored issues
–
show
The variable
$client_id seems to never exist, and therefore empty should always return true . Did you maybe rename this variable?
This check looks for calls to This is most likely caused by the renaming of a variable or the removal of a function/method parameter. ![]() |
|||
643 | $errtxt = "Missing or empty client_id parameter."; |
||
644 | } elseif (empty($response_type)) { |
||
0 ignored issues
–
show
The variable
$response_type seems to never exist, and therefore empty should always return true . Did you maybe rename this variable?
This check looks for calls to This is most likely caused by the renaming of a variable or the removal of a function/method parameter. ![]() |
|||
645 | $errtxt = "Missing or empty response_type parameter."; |
||
646 | } elseif (preg_match('/[\+%"\']/', $scope)) { |
||
647 | $errtxt = "Invalid characters found in scope parameter, may be URL encoded twice."; |
||
648 | } elseif (preg_match('/[A-Z]/', $scope)) { |
||
649 | $errtxt = "Upper case characters found in scope parameter."; |
||
650 | } elseif ($response_type != 'code') { |
||
651 | $errtxt = "Unsupported response_type parameter. Only code is supported."; |
||
652 | } elseif ((!empty($prompt)) && ($prompt != 'login') && ($prompt != 'select_account')) { |
||
0 ignored issues
–
show
The variable
$prompt seems to never exist, and therefore empty should always return true . Did you maybe rename this variable?
This check looks for calls to This is most likely caused by the renaming of a variable or the removal of a function/method parameter. ![]() |
|||
653 | $errtxt = "Unsupported prompt parameter. Only login and select_account are supported."; |
||
654 | } elseif ( |
||
655 | (!empty($response_mode)) && |
||
0 ignored issues
–
show
The variable
$response_mode seems to never exist, and therefore empty should always return true . Did you maybe rename this variable?
This check looks for calls to This is most likely caused by the renaming of a variable or the removal of a function/method parameter. ![]() |
|||
656 | ($response_mode != 'query') && |
||
657 | ($response_mode != 'fragment') && |
||
658 | ($response_mode != 'form_post') |
||
659 | ) { |
||
660 | $errtxt = "Unsupported response_mode parameter."; |
||
661 | } |
||
662 | |||
663 | // CIL-697 The OA4MP code should eventually return an |
||
664 | // "error_description=..." field that can give detailed error text to |
||
665 | // replace the default text associated with STATUS_INTERNAL_ERROR. |
||
666 | // CIL-909 Use the error_description field only if $errtxt is still |
||
667 | // empty, OR if the $errstr was STATUS_CREATE_TRANSACTION_FAILED |
||
668 | // (i.e., "Failed to initialize OIDC flow."). |
||
669 | if ( |
||
670 | ((strlen($errtxt) == 0) || |
||
671 | ($errstr == 'STATUS_CREATE_TRANSACTION_FAILED')) && |
||
672 | (preg_match('/error_description=([^\r\n]+)/', $output, $matches)) |
||
673 | ) { |
||
674 | $errtxt = urldecode($matches[1]); |
||
675 | } |
||
676 | } |
||
677 | |||
678 | return $errtxt; |
||
679 | } |
||
680 |
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.