ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
HTTP.php
Go to the documentation of this file.
1<?php
2namespace SimpleSAML\Utils;
3
6
12class HTTP
13{
14
27 {
30
31 // get the session ID
32 $session_id = $session->getSessionId();
33 if (is_null($session_id)) {
34 // this is a transient session, it is pointless to continue
35 throw new \SimpleSAML_Error_Exception('Cannot save POST data to a transient session.');
36 }
37
38 // encrypt the session ID and the random ID
39 $info = base64_encode(Crypto::aesEncrypt($session_id.':'.$id));
40
41 $url = Module::getModuleURL('core/postredirect.php', array('RedirInfo' => $info));
42 return preg_replace('#^https:#', 'http:', $url);
43 }
44
45
54 private static function getServerHost()
55 {
56 if (array_key_exists('HTTP_HOST', $_SERVER)) {
57 $current = $_SERVER['HTTP_HOST'];
58 } elseif (array_key_exists('SERVER_NAME', $_SERVER)) {
59 $current = $_SERVER['SERVER_NAME'];
60 } else {
61 // almost certainly not what you want, but...
62 $current = 'localhost';
63 }
64
65 if (strstr($current, ":")) {
66 $decomposed = explode(":", $current);
67 $port = array_pop($decomposed);
68 if (!is_numeric($port)) {
69 array_push($decomposed, $port);
70 }
71 $current = implode($decomposed, ":");
72 }
73 return $current;
74 }
75
76
84 public static function getServerHTTPS()
85 {
86 if (!array_key_exists('HTTPS', $_SERVER)) {
87 // not an https-request
88 return false;
89 }
90
91 if ($_SERVER['HTTPS'] === 'off') {
92 // IIS with HTTPS off
93 return false;
94 }
95
96 // otherwise, HTTPS will be non-empty
97 return !empty($_SERVER['HTTPS']);
98 }
99
100
109 public static function getServerPort()
110 {
111 $port = (isset($_SERVER['SERVER_PORT'])) ? $_SERVER['SERVER_PORT'] : '80';
112 if (self::getServerHTTPS()) {
113 if ($port !== '443') {
114 return ':'.$port;
115 }
116 } else {
117 if ($port !== '80') {
118 return ':'.$port;
119 }
120 }
121 return '';
122 }
123
124
148 private static function redirect($url, $parameters = array())
149 {
150 if (!is_string($url) || empty($url) || !is_array($parameters)) {
151 throw new \InvalidArgumentException('Invalid input parameters.');
152 }
153 if (!empty($parameters)) {
154 $url = self::addURLParameters($url, $parameters);
155 }
156
157 /* Set the HTTP result code. This is either 303 See Other or
158 * 302 Found. HTTP 303 See Other is sent if the HTTP version
159 * is HTTP/1.1 and the request type was a POST request.
160 */
161 if ($_SERVER['SERVER_PROTOCOL'] === 'HTTP/1.1' &&
162 $_SERVER['REQUEST_METHOD'] === 'POST'
163 ) {
164 $code = 303;
165 } else {
166 $code = 302;
167 }
168
169 if (strlen($url) > 2048) {
170 Logger::warning('Redirecting to a URL longer than 2048 bytes.');
171 }
172
173 if (!headers_sent()) {
174 // set the location header
175 header('Location: '.$url, true, $code);
176
177 // disable caching of this response
178 header('Pragma: no-cache');
179 header('Cache-Control: no-cache, no-store, must-revalidate');
180 }
181
182 // show a minimal web page with a clickable link to the URL
183 echo '<?xml version="1.0" encoding="UTF-8"?>'."\n";
184 echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"';
185 echo ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'."\n";
186 echo '<html xmlns="http://www.w3.org/1999/xhtml">'."\n";
187 echo " <head>\n";
188 echo ' <meta http-equiv="content-type" content="text/html; charset=utf-8">'."\n";
189 echo ' <meta http-equiv="refresh" content="0;URL=\''.htmlspecialchars($url).'\'">'."\n";
190 echo " <title>Redirect</title>\n";
191 echo " </head>\n";
192 echo " <body>\n";
193 echo " <h1>Redirect</h1>\n";
194 echo ' <p>You were redirected to: <a id="redirlink" href="'.htmlspecialchars($url).'">';
195 echo htmlspecialchars($url)."</a>\n";
196 echo ' <script type="text/javascript">document.getElementById("redirlink").focus();</script>'."\n";
197 echo " </p>\n";
198 echo " </body>\n";
199 echo '</html>';
200
201 // end script execution
202 exit;
203 }
204
205
218 private static function savePOSTData(\SimpleSAML_Session $session, $destination, $data)
219 {
220 // generate a random ID to avoid replay attacks
221 $id = Random::generateID();
222 $postData = array(
223 'post' => $data,
224 'url' => $destination,
225 );
226
227 // save the post data to the session, tied to the random ID
228 $session->setData('core_postdatalink', $id, $postData);
229
230 return $id;
231 }
232
233
247 public static function addURLParameters($url, $parameters)
248 {
249 if (!is_string($url) || !is_array($parameters)) {
250 throw new \InvalidArgumentException('Invalid input parameters.');
251 }
252
253 $queryStart = strpos($url, '?');
254 if ($queryStart === false) {
255 $oldQuery = array();
256 $url .= '?';
257 } else {
259 $oldQuery = substr($url, $queryStart + 1);
260 if ($oldQuery === false) {
261 $oldQuery = array();
262 } else {
263 $oldQuery = self::parseQueryString($oldQuery);
264 }
265 $url = substr($url, 0, $queryStart + 1);
266 }
267
269 $query = array_merge($oldQuery, $parameters);
270 $url .= http_build_query($query, '', '&');
271
272 return $url;
273 }
274
275
287 public static function checkSessionCookie($retryURL = null)
288 {
289 if (!is_null($retryURL) && !is_string($retryURL)) {
290 throw new \InvalidArgumentException('Invalid input parameters.');
291 }
292
293 $session = \SimpleSAML_Session::getSessionFromRequest();
294 if ($session->hasSessionCookie()) {
295 return;
296 }
297
298 // we didn't have a session cookie. Redirect to the no-cookie page
299
300 $url = Module::getModuleURL('core/no_cookie.php');
301 if ($retryURL !== null) {
302 $url = self::addURLParameters($url, array('retryURL' => $retryURL));
303 }
304 self::redirectTrustedURL($url);
305 }
306
307
322 public static function checkURLAllowed($url, array $trustedSites = null)
323 {
324 if (empty($url)) {
325 return '';
326 }
327 $url = self::normalizeURL($url);
328
329 if (filter_var($url, FILTER_VALIDATE_URL) === false) {
330 throw new \SimpleSAML_Error_Exception('Invalid URL: '.$url);
331 }
332
333 // get the white list of domains
334 if ($trustedSites === null) {
335 $trustedSites = \SimpleSAML_Configuration::getInstance()->getValue('trusted.url.domains', array());
336 }
337
338 // validates the URL's host is among those allowed
339 if (is_array($trustedSites)) {
340 assert(is_array($trustedSites));
341 $components = parse_url($url);
342 $hostname = $components['host'];
343
344 // check for userinfo
345 if ((isset($components['user']) && strpos($components['user'], '\\') !== false) ||
346 (isset($components['pass']) && strpos($components['pass'], '\\') !== false)
347 ) {
348 throw new \SimpleSAML_Error_Exception('Invalid URL: '.$url);
349 }
350
351 // allow URLs with standard ports specified (non-standard ports must then be allowed explicitly)
352 if (isset($components['port']) &&
353 (($components['scheme'] === 'http' && $components['port'] !== 80) ||
354 ($components['scheme'] === 'https' && $components['port'] !== 443))
355 ) {
356 $hostname = $hostname.':'.$components['port'];
357 }
358
359 $self_host = self::getSelfHostWithNonStandardPort();
360
361 $trustedRegex = \SimpleSAML_Configuration::getInstance()->getValue('trusted.url.regex', false);
362
363 $trusted = false;
364 if ($trustedRegex) {
365 // add self host to the white list
366 $trustedSites[] = preg_quote($self_host);
367 foreach ($trustedSites as $regex) {
368 // Add start and end delimiters.
369 $regex = "@^{$regex}$@";
370 if (preg_match($regex, $hostname)) {
371 $trusted = true;
372 break;
373 }
374 }
375 } else {
376 // add self host to the white list
377 $trustedSites[] = $self_host;
378 $trusted = in_array($hostname, $trustedSites, true);
379 }
380
381 // throw exception due to redirection to untrusted site
382 if (!$trusted) {
383 throw new \SimpleSAML_Error_Exception('URL not allowed: '.$url);
384 }
385 }
386 return $url;
387 }
388
389
409 public static function fetch($url, $context = array(), $getHeaders = false)
410 {
411 if (!is_string($url)) {
412 throw new \InvalidArgumentException('Invalid input parameters.');
413 }
414
415 $config = \SimpleSAML_Configuration::getInstance();
416
417 $proxy = $config->getString('proxy', null);
418 if ($proxy !== null) {
419 if (!isset($context['http']['proxy'])) {
420 $context['http']['proxy'] = $proxy;
421 }
422 $proxy_auth = $config->getString('proxy.auth', false);
423 if ($proxy_auth !== false) {
424 $context['http']['header'] = "Proxy-Authorization: Basic".base64_encode($proxy_auth);
425 }
426 if (!isset($context['http']['request_fulluri'])) {
427 $context['http']['request_fulluri'] = true;
428 }
429 /*
430 * If the remote endpoint over HTTPS uses the SNI extension (Server Name Indication RFC 4366), the proxy
431 * could introduce a mismatch between the names in the Host: HTTP header and the SNI_server_name in TLS
432 * negotiation (thanks to Cristiano Valli @ GARR-IDEM to have pointed this problem).
433 * See: https://bugs.php.net/bug.php?id=63519
434 * These controls will force the same value for both fields.
435 * Marco Ferrante (marco@csita.unige.it), Nov 2012
436 */
437 if (preg_match('#^https#i', $url)
438 && defined('OPENSSL_TLSEXT_SERVER_NAME')
439 && OPENSSL_TLSEXT_SERVER_NAME
440 ) {
441 // extract the hostname
442 $hostname = parse_url($url, PHP_URL_HOST);
443 if (!empty($hostname)) {
444 $context['ssl'] = array(
445 'SNI_server_name' => $hostname,
446 'SNI_enabled' => true,
447 );
448 } else {
449 Logger::warning('Invalid URL format or local URL used through a proxy');
450 }
451 }
452 }
453
454 $context = stream_context_create($context);
455 $data = file_get_contents($url, false, $context);
456 if ($data === false) {
457 $error = error_get_last();
458 throw new \SimpleSAML_Error_Exception('Error fetching '.var_export($url, true).':'.
459 (is_array($error) ? $error['message'] : 'no error available'));
460 }
461
462 // data and headers
463 if ($getHeaders) {
464 if (isset($http_response_header)) {
465 $headers = array();
466 foreach ($http_response_header as $h) {
467 if (preg_match('@^HTTP/1\.[01]\s+\d{3}\s+@', $h)) {
468 $headers = array(); // reset
469 $headers[0] = $h;
470 continue;
471 }
472 $bits = explode(':', $h, 2);
473 if (count($bits) === 2) {
474 $headers[strtolower($bits[0])] = trim($bits[1]);
475 }
476 }
477 } else {
478 // no HTTP headers, probably a different protocol, e.g. file
479 $headers = null;
480 }
481 return array($data, $headers);
482 }
483
484 return $data;
485 }
486
487
499 public static function getAcceptLanguage()
500 {
501 if (!array_key_exists('HTTP_ACCEPT_LANGUAGE', $_SERVER)) {
502 // no Accept-Language header, return an empty set
503 return array();
504 }
505
506 $languages = explode(',', strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE']));
507
508 $ret = array();
509
510 foreach ($languages as $l) {
511 $opts = explode(';', $l);
512
513 $l = trim(array_shift($opts)); // the language is the first element
514
515 $q = 1.0;
516
517 // iterate over all options, and check for the quality option
518 foreach ($opts as $o) {
519 $o = explode('=', $o);
520 if (count($o) < 2) {
521 // skip option with no value
522 continue;
523 }
524
525 $name = trim($o[0]);
526 $value = trim($o[1]);
527
528 if ($name === 'q') {
529 $q = (float) $value;
530 }
531 }
532
533 // remove the old key to ensure that the element is added to the end
534 unset($ret[$l]);
535
536 // set the quality in the result
537 $ret[$l] = $q;
538
539 if (strpos($l, '-')) {
540 // the language includes a region part
541
542 // extract the language without the region
543 $l = explode('-', $l);
544 $l = $l[0];
545
546 // add this language to the result (unless it is defined already)
547 if (!array_key_exists($l, $ret)) {
548 $ret[$l] = $q;
549 }
550 }
551 }
552 return $ret;
553 }
554
555
563 public static function guessBasePath()
564 {
565 if (!array_key_exists('REQUEST_URI', $_SERVER) || !array_key_exists('SCRIPT_FILENAME', $_SERVER)) {
566 return '/';
567 }
568 // get the name of the current script
569 $path = explode('/', $_SERVER['SCRIPT_FILENAME']);
570 $script = array_pop($path);
571
572 // get the portion of the URI up to the script, i.e.: /simplesaml/some/directory/script.php
573 if (!preg_match('#^/(?:[^/]+/)*'.$script.'#', $_SERVER['REQUEST_URI'], $matches)) {
574 return '/';
575 }
576 $uri_s = explode('/', $matches[0]);
577 $file_s = explode('/', $_SERVER['SCRIPT_FILENAME']);
578
579 // compare both arrays from the end, popping elements matching out of them
580 while ($uri_s[count($uri_s) - 1] === $file_s[count($file_s) - 1]) {
581 array_pop($uri_s);
582 array_pop($file_s);
583 }
584 // we are now left with the minimum part of the URI that does not match anything in the file system, use it
585 return join('/', $uri_s).'/';
586 }
587
588
598 public static function getBaseURL()
599 {
600 $globalConfig = \SimpleSAML_Configuration::getInstance();
601 $baseURL = $globalConfig->getString('baseurlpath', 'simplesaml/');
602
603 if (preg_match('#^https?://.*/?$#D', $baseURL, $matches)) {
604 // full URL in baseurlpath, override local server values
605 return rtrim($baseURL, '/').'/';
606 } elseif (
607 (preg_match('#^/?([^/]?.*/)$#D', $baseURL, $matches)) ||
608 (preg_match('#^\*(.*)/$#D', $baseURL, $matches)) ||
609 ($baseURL === '')
610 ) {
611 // get server values
612 $protocol = 'http';
613 $protocol .= (self::getServerHTTPS()) ? 's' : '';
614 $protocol .= '://';
615
616 $hostname = self::getServerHost();
617 $port = self::getServerPort();
618 $path = $globalConfig->getBasePath();
619
620 return $protocol.$hostname.$port.$path;
621 } else {
622 /*
623 * Invalid 'baseurlpath'. We cannot recover from this, so throw a critical exception and try to be graceful
624 * with the configuration. Use a guessed base path instead of the one provided.
625 */
626 $c = $globalConfig->toArray();
627 $c['baseurlpath'] = self::guessBasePath();
628 throw new \SimpleSAML\Error\CriticalConfigurationError(
629 'Invalid value for \'baseurlpath\' in config.php. Valid format is in the form: '.
630 '[(http|https)://(hostname|fqdn)[:port]]/[path/to/simplesaml/]. It must end with a \'/\'.',
631 null,
632 $c
633 );
634 }
635 }
636
637
647 public static function getFirstPathElement($trailingslash = true)
648 {
649 if (preg_match('|^/(.*?)/|', $_SERVER['SCRIPT_NAME'], $matches)) {
650 return ($trailingslash ? '/' : '').$matches[1];
651 }
652 return '';
653 }
654
655
668 public static function getPOSTRedirectURL($destination, $data)
669 {
670 if (!is_string($destination) || !is_array($data)) {
671 throw new \InvalidArgumentException('Invalid input parameters.');
672 }
673
674 $config = \SimpleSAML_Configuration::getInstance();
675 $allowed = $config->getBoolean('enable.http_post', false);
676
677 if ($allowed && preg_match("#^http:#", $destination) && self::isHTTPS()) {
678 // we need to post the data to HTTP
679 $url = self::getSecurePOSTRedirectURL($destination, $data);
680 } else { // post the data directly
681 $session = \SimpleSAML_Session::getSessionFromRequest();
682 $id = self::savePOSTData($session, $destination, $data);
683 $url = Module::getModuleURL('core/postredirect.php', array('RedirId' => $id));
684 }
685
686 return $url;
687 }
688
689
699 public static function getSelfHost()
700 {
701 $decomposed = explode(':', self::getSelfHostWithNonStandardPort());
702 return array_shift($decomposed);
703 }
704
717 public static function getSelfHostWithNonStandardPort()
718 {
719 $url = self::getBaseURL();
720
722 $colon = strpos($url, '://');
723 $start = $colon + 3;
724 $length = strcspn($url, '/', $start);
725
726 return substr($url, $start, $length);
727 }
728
738 public static function getSelfHostWithPath()
739 {
740 $baseurl = explode("/", self::getBaseURL());
741 $elements = array_slice($baseurl, 3 - count($baseurl), count($baseurl) - 4);
742 $path = implode("/", $elements);
743 return self::getSelfHostWithNonStandardPort()."/".$path;
744 }
745
746
762 public static function getSelfURL()
763 {
764 $cfg = \SimpleSAML_Configuration::getInstance();
765 $baseDir = $cfg->getBaseDir();
766 $cur_path = realpath($_SERVER['SCRIPT_FILENAME']);
767 // make sure we got a string from realpath()
768 $cur_path = is_string($cur_path) ? $cur_path : '';
769 // find the path to the current script relative to the www/ directory of SimpleSAMLphp
770 $rel_path = str_replace($baseDir.'www'.DIRECTORY_SEPARATOR, '', $cur_path);
771 // convert that relative path to an HTTP query
772 $url_path = str_replace(DIRECTORY_SEPARATOR, '/', $rel_path);
773 // find where the relative path starts in the current request URI
774 $uri_pos = (!empty($url_path)) ? strpos($_SERVER['REQUEST_URI'], $url_path) : false;
775
776 if ($cur_path == $rel_path || $uri_pos === false) {
777 /*
778 * We were accessed from an external script. This can happen in the following cases:
779 *
780 * - $_SERVER['SCRIPT_FILENAME'] points to a script that doesn't exist. E.g. functional testing. In this
781 * case, realpath() returns false and str_replace an empty string, so we compare them loosely.
782 *
783 * - The URI requested does not belong to a script in the www/ directory of SimpleSAMLphp. In that case,
784 * removing SimpleSAMLphp's base dir from the current path yields the same path, so $cur_path and
785 * $rel_path are equal.
786 *
787 * - The request URI does not match the current script. Even if the current script is located in the www/
788 * directory of SimpleSAMLphp, the URI does not contain its relative path, and $uri_pos is false.
789 *
790 * It doesn't matter which one of those cases we have. We just know we can't apply our base URL to the
791 * current URI, so we need to build it back from the PHP environment, unless we have a base URL specified
792 * for this case in the configuration. First, check if that's the case.
793 */
794
796 $appcfg = $cfg->getConfigItem('application', null);
797 $appurl = ($appcfg instanceof \SimpleSAML_Configuration) ? $appcfg->getString('baseURL', '') : '';
798 if (!empty($appurl)) {
799 $protocol = parse_url($appurl, PHP_URL_SCHEME);
800 $hostname = parse_url($appurl, PHP_URL_HOST);
801 $port = parse_url($appurl, PHP_URL_PORT);
802 $port = !empty($port) ? ':'.$port : '';
803
804 } else { // no base URL specified for app, just use the current URL
805 $protocol = 'http';
806 $protocol .= (self::getServerHTTPS()) ? 's' : '';
807 $hostname = self::getServerHost();
808 $port = self::getServerPort();
809 }
810 return $protocol.'://'.$hostname.$port.$_SERVER['REQUEST_URI'];
811 }
812
813 return self::getBaseURL().$rel_path.substr($_SERVER['REQUEST_URI'], $uri_pos + strlen($url_path));
814 }
815
816
826 public static function getSelfURLHost()
827 {
828 $url = self::getSelfURL();
829
831 $colon = strpos($url, '://');
832 $start = $colon + 3;
833 $length = strcspn($url, '/', $start) + $start;
834 return substr($url, 0, $length);
835 }
836
837
846 public static function getSelfURLNoQuery()
847 {
848 $url = self::getSelfURL();
849 $pos = strpos($url, '?');
850 if (!$pos) {
851 return $url;
852 }
853 return substr($url, 0, $pos);
854 }
855
856
865 public static function isHTTPS()
866 {
867 return strpos(self::getSelfURL(), 'https://') === 0;
868 }
869
870
883 public static function normalizeURL($url)
884 {
885 if (!is_string($url)) {
886 throw new \InvalidArgumentException('Invalid input parameters.');
887 }
888
889 $url = self::resolveURL($url, self::getSelfURL());
890
891 // verify that the URL is to a http or https site
892 if (!preg_match('@^https?://@i', $url)) {
893 throw new \InvalidArgumentException('Invalid URL: '.$url);
894 }
895
896 return $url;
897 }
898
899
915 public static function parseQueryString($query_string)
916 {
917 if (!is_string($query_string)) {
918 throw new \InvalidArgumentException('Invalid input parameters.');
919 }
920
921 $res = array();
922 if (empty($query_string)) {
923 return $res;
924 }
925
926 foreach (explode('&', $query_string) as $param) {
927 $param = explode('=', $param);
928 $name = urldecode($param[0]);
929 if (count($param) === 1) {
930 $value = '';
931 } else {
932 $value = urldecode($param[1]);
933 }
934 $res[$name] = $value;
935 }
936 return $res;
937 }
938
939
962 public static function redirectTrustedURL($url, $parameters = array())
963 {
964 if (!is_string($url) || !is_array($parameters)) {
965 throw new \InvalidArgumentException('Invalid input parameters.');
966 }
967
968 $url = self::normalizeURL($url);
969 self::redirect($url, $parameters);
970 }
971
972
994 public static function redirectUntrustedURL($url, $parameters = array())
995 {
996 if (!is_string($url) || !is_array($parameters)) {
997 throw new \InvalidArgumentException('Invalid input parameters.');
998 }
999
1000 $url = self::checkURLAllowed($url);
1001 self::redirect($url, $parameters);
1002 }
1003
1004
1026 public static function resolveURL($url, $base = null)
1027 {
1028 if ($base === null) {
1029 $base = self::getBaseURL();
1030 }
1031
1032 if (!is_string($url) || !is_string($base)) {
1033 throw new \InvalidArgumentException('Invalid input parameters.');
1034 }
1035
1036 if (!preg_match('/^((((\w+:)\/\/[^\/]+)(\/[^?#]*))(?:\?[^#]*)?)(?:#.*)?/', $base, $baseParsed)) {
1037 throw new \InvalidArgumentException('Unable to parse base url: '.$base);
1038 }
1039
1040 $baseDir = dirname($baseParsed[5].'filename');
1041 $baseScheme = $baseParsed[4];
1042 $baseHost = $baseParsed[3];
1043 $basePath = $baseParsed[2];
1044 $baseQuery = $baseParsed[1];
1045
1046 if (preg_match('$^\w+:$', $url)) {
1047 return $url;
1048 }
1049
1050 if (substr($url, 0, 2) === '//') {
1051 return $baseScheme.$url;
1052 }
1053
1054 if ($url[0] === '/') {
1055 return $baseHost.$url;
1056 }
1057 if ($url[0] === '?') {
1058 return $basePath.$url;
1059 }
1060 if ($url[0] === '#') {
1061 return $baseQuery.$url;
1062 }
1063
1064 // we have a relative path. Remove query string/fragment and save it as $tail
1065 $queryPos = strpos($url, '?');
1066 $fragmentPos = strpos($url, '#');
1067 if ($queryPos !== false || $fragmentPos !== false) {
1068 if ($queryPos === false) {
1069 $tailPos = $fragmentPos;
1070 } elseif ($fragmentPos === false) {
1071 $tailPos = $queryPos;
1072 } elseif ($queryPos < $fragmentPos) {
1073 $tailPos = $queryPos;
1074 } else {
1075 $tailPos = $fragmentPos;
1076 }
1077
1078 $tail = substr($url, $tailPos);
1079 $dir = substr($url, 0, $tailPos);
1080 } else {
1081 $dir = $url;
1082 $tail = '';
1083 }
1084
1085 $dir = System::resolvePath($dir, $baseDir);
1086
1087 return $baseHost.$dir.$tail;
1088 }
1089
1090
1107 public static function setCookie($name, $value, $params = null, $throw = true)
1108 {
1109 if (!(is_string($name) && // $name must be a string
1110 (is_string($value) || is_null($value)) && // $value can be a string or null
1111 (is_array($params) || is_null($params)) && // $params can be an array or null
1112 is_bool($throw)) // $throw must be boolean
1113 ) {
1114 throw new \InvalidArgumentException('Invalid input parameters.');
1115 }
1116
1117 $default_params = array(
1118 'lifetime' => 0,
1119 'expire' => null,
1120 'path' => '/',
1121 'domain' => null,
1122 'secure' => false,
1123 'httponly' => true,
1124 'raw' => false,
1125 );
1126
1127 if ($params !== null) {
1128 $params = array_merge($default_params, $params);
1129 } else {
1130 $params = $default_params;
1131 }
1132
1133 // Do not set secure cookie if not on HTTPS
1134 if ($params['secure'] && !self::isHTTPS()) {
1135 if ($throw) {
1136 throw new \SimpleSAML\Error\CannotSetCookie(
1137 'Setting secure cookie on plain HTTP is not allowed.',
1138 \SimpleSAML\Error\CannotSetCookie::SECURE_COOKIE
1139 );
1140 }
1141 Logger::warning('Error setting cookie: setting secure cookie on plain HTTP is not allowed.');
1142 return;
1143 }
1144
1145 if ($value === null) {
1146 $expire = time() - 365 * 24 * 60 * 60;
1147 } elseif (isset($params['expire'])) {
1148 $expire = $params['expire'];
1149 } elseif ($params['lifetime'] === 0) {
1150 $expire = 0;
1151 } else {
1152 $expire = time() + $params['lifetime'];
1153 }
1154
1155 if ($params['raw']) {
1156 $success = @setrawcookie(
1157 $name,
1158 $value,
1159 $expire,
1160 $params['path'],
1161 $params['domain'],
1162 $params['secure'],
1163 $params['httponly']
1164 );
1165 } else {
1166 $success = @setcookie(
1167 $name,
1168 $value,
1169 $expire,
1170 $params['path'],
1171 $params['domain'],
1172 $params['secure'],
1173 $params['httponly']
1174 );
1175 }
1176
1177 if (!$success) {
1178 if ($throw) {
1179 throw new \SimpleSAML\Error\CannotSetCookie(
1180 'Headers already sent.',
1181 \SimpleSAML\Error\CannotSetCookie::HEADERS_SENT
1182 );
1183 }
1184 Logger::warning('Error setting cookie: headers already sent.');
1185 }
1186 }
1187
1188
1205 public static function submitPOSTData($destination, $data)
1206 {
1207 if (!is_string($destination) || !is_array($data)) {
1208 throw new \InvalidArgumentException('Invalid input parameters.');
1209 }
1210
1211 $config = \SimpleSAML_Configuration::getInstance();
1212 $allowed = $config->getBoolean('enable.http_post', false);
1213
1214 if ($allowed && preg_match("#^http:#", $destination) && self::isHTTPS()) {
1215 // we need to post the data to HTTP
1216 self::redirect(self::getSecurePOSTRedirectURL($destination, $data));
1217 }
1218
1219 $p = new \SimpleSAML_XHTML_Template($config, 'post.php');
1220 $p->data['destination'] = $destination;
1221 $p->data['post'] = $data;
1222 $p->show();
1223 exit(0);
1224 }
1225}
An exception for terminatinating execution or to throw for unit testing.
static warning($string)
Definition: Logger.php:179
static getModuleURL($resource, array $parameters=array())
Get absolute URL to a specified module resource.
Definition: Module.php:303
static aesEncrypt($data)
Encrypt data using AES-256-CBC and the system-wide secret salt as key.
Definition: Crypto.php:146
static getSecurePOSTRedirectURL($destination, $data)
Obtain a URL where we can redirect to securely post a form with the given data to a specific destinat...
Definition: HTTP.php:26
static getServerPort()
Retrieve the port number from $_SERVER environment variables.
Definition: HTTP.php:109
static getServerHTTPS()
Retrieve HTTPS status from $_SERVER environment variables.
Definition: HTTP.php:84
static getServerHost()
Retrieve Host value from $_SERVER environment variables.
Definition: HTTP.php:54
static savePOSTData(\SimpleSAML_Session $session, $destination, $data)
Save the given HTTP POST data and the destination where it should be posted to a given session.
Definition: HTTP.php:218
static redirect($url, $parameters=array())
This function redirects the user to the specified address.
Definition: HTTP.php:148
static getSessionFromRequest()
Retrieves the current session.
Definition: Session.php:243
$code
Definition: example_050.php:99
if(!array_key_exists('StateId', $_REQUEST)) $id
$destination
$info
Definition: index.php:5
static http()
Fetches the global http state from ILIAS.
$session
$url
if((!isset($_SERVER['DOCUMENT_ROOT'])) OR(empty($_SERVER['DOCUMENT_ROOT']))) $_SERVER['DOCUMENT_ROOT']