diff --git a/lib/SimpleSAML/Auth/Simple.php b/lib/SimpleSAML/Auth/Simple.php index 33fc4e552aa71074c4ebf217e754c73be47eb71b..cc61e937b78bde3cfae3b1170e073c39cc0c9576 100644 --- a/lib/SimpleSAML/Auth/Simple.php +++ b/lib/SimpleSAML/Auth/Simple.php @@ -114,7 +114,7 @@ class SimpleSAML_Auth_Simple { } if (is_string($returnTo) && $keepPost && $_SERVER['REQUEST_METHOD'] === 'POST') { - $returnTo = SimpleSAML_Utilities::createPostRedirectLink($returnTo, $_POST); + $returnTo = \SimpleSAML\Utils\HTTP::getPOSTRedirectURL($returnTo, $_POST); } if (array_key_exists('ErrorURL', $params)) { diff --git a/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php b/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php index d992aba6d6506e485e0489edb7408ea93c2b0d30..86feff9eb5e19c32231850134e37c1a898c34763 100644 --- a/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php +++ b/lib/SimpleSAML/Bindings/Shib13/HTTPPost.php @@ -80,7 +80,7 @@ class SimpleSAML_Bindings_Shib13_HTTPPost { SimpleSAML_Utilities::debugMessage($response, 'out'); - SimpleSAML_Utilities::postRedirect($shire, array( + \SimpleSAML\Utils\HTTP::submitPOSTData($shire, array( 'TARGET' => $relayState, 'SAMLResponse' => base64_encode($response), )); diff --git a/lib/SimpleSAML/Utilities.php b/lib/SimpleSAML/Utilities.php index 303b5777c76286b23d3ba4483b3e1d15d2f98139..410730202132e137e3541332817753acae6b8d74 100644 --- a/lib/SimpleSAML/Utilities.php +++ b/lib/SimpleSAML/Utilities.php @@ -675,72 +675,22 @@ class SimpleSAML_Utilities { /** - * Do a POST redirect to a page. - * - * This function never returns. - * - * @param string $destination The destination URL. - * @param array $post An array of name-value pairs which will be posted. + * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\HTTP::submitPOSTData() instead. */ public static function postRedirect($destination, $post) { - assert('is_string($destination)'); - assert('is_array($post)'); - - $config = SimpleSAML_Configuration::getInstance(); - $httpRedirect = $config->getBoolean('enable.http_post', FALSE); - - if ($httpRedirect && preg_match("#^http:#", $destination) && self::isHTTPS()) { - $url = self::createHttpPostRedirectLink($destination, $post); - self::redirect($url); - assert('FALSE'); - } - - $p = new SimpleSAML_XHTML_Template($config, 'post.php'); - $p->data['destination'] = $destination; - $p->data['post'] = $post; - $p->show(); - exit(0); + \SimpleSAML\Utils\HTTP::submitPOSTData($destination, $post); } /** - * Create a link which will POST data. - * - * @param string $destination The destination URL. - * @param array $post The name-value pairs which will be posted to the destination. - * @return string A URL which can be accessed to post the data. + * @deprecated This method will be removed in SSP 2.0. PLease use SimpleSAML\Utils\HTTP::getPOSTRedirectURL() instead. */ public static function createPostRedirectLink($destination, $post) { - assert('is_string($destination)'); - assert('is_array($post)'); - - $config = SimpleSAML_Configuration::getInstance(); - $httpRedirect = $config->getBoolean('enable.http_post', FALSE); - - if ($httpRedirect && preg_match("#^http:#", $destination) && self::isHTTPS()) { - $url = self::createHttpPostRedirectLink($destination, $post); - } else { - $postId = SimpleSAML\Utils\Random::generateID(); - $postData = array( - 'post' => $post, - 'url' => $destination, - ); - - $session = SimpleSAML_Session::getSessionFromRequest(); - $session->setData('core_postdatalink', $postId, $postData); - - $url = SimpleSAML_Module::getModuleURL('core/postredirect.php', array('RedirId' => $postId)); - } - - return $url; + return \SimpleSAML\Utils\HTTP::getPOSTRedirectURL($destination, $post); } /** - * Create a link which will POST data to HTTP in a secure way. - * - * @param string $destination The destination URL. - * @param array $post The name-value pairs which will be posted to the destination. - * @return string A URL which can be accessed to post the data. + * @deprecated This method will be removed in SSP 2.0. Please use SimpleSAML\Utils\HTTP::getPOSTRedirectURL() instead. */ public static function createHttpPostRedirectLink($destination, $post) { assert('is_string($destination)'); diff --git a/lib/SimpleSAML/Utils/HTTP.php b/lib/SimpleSAML/Utils/HTTP.php index 56e5ebe4fa6118fde287b4499d61583cc6c3387d..59be933008ca450259b3b428d084e45129a4370d 100644 --- a/lib/SimpleSAML/Utils/HTTP.php +++ b/lib/SimpleSAML/Utils/HTTP.php @@ -10,6 +10,29 @@ namespace SimpleSAML\Utils; class HTTP { + /** + * Obtain a URL where we can redirect to securely post a form with the given data to a specific destination. + * + * @param string $destination The destination URL. + * @param array $data An associative array containing the data to be posted to $destination. + * + * @return string A URL which allows to securely post a form to $destination. + * + * @author Jaime Perez, UNINETT AS <jaime.perez@uninett.no> + */ + private static function getSecurePOSTRedirectURL($destination, $data) + { + $session = \SimpleSAML_Session::getSessionFromRequest(); + $id = self::savePOSTData($session, $destination, $data); + + // encrypt the session ID and the random ID + $info = base64_encode(Crypto::aesEncrypt($session->getSessionId().':'.$id)); + + $url = \SimpleSAML_Module::getModuleURL('core/postredirect.php', array('RedirInfo' => $info)); + return preg_replace('#^https:#', 'http:', $url); + } + + /** * Retrieve Host value from $_SERVER environment variables. * @@ -167,6 +190,34 @@ class HTTP } + /** + * Save the given HTTP POST data and the destination where it should be posted to a given session. + * + * @param \SimpleSAML_Session $session The session where to temporarily store the data. + * @param string $destination The destination URL where the form should be posted. + * @param array $data An associative array with the data to be posted to $destination. + * + * @return string A random identifier that can be used to retrieve the data from the current session. + * + * @author Andjelko Horvat + * @author Jaime Perez, UNINETT AS <jaime.perez@uninett.no> + */ + private static function savePOSTData(\SimpleSAML_Session $session, $destination, $data) + { + // generate a random ID to avoid replay attacks + $id = Random::generateID(); + $postData = array( + 'post' => $data, + 'url' => $destination, + ); + + // save the post data to the session, tied to the random ID + $session->setData('core_postdatalink', $id, $postData); + + return $id; + } + + /** * Add one or more query parameters to the given URL. * @@ -424,6 +475,40 @@ class HTTP } + /** + * Create a link which will POST data. + * + * @param string $destination The destination URL. + * @param array $data The name-value pairs which will be posted to the destination. + * + * @return string A URL which can be accessed to post the data. + * @throws \SimpleSAML_Error_Exception If $destination is not a string or $data is not an array. + * + * @author Andjelko Horvat + * @author Jaime Perez, UNINETT AS <jaime.perez@uninett.no> + */ + public static function getPOSTRedirectURL($destination, $data) + { + if (!is_string($destination) || !is_array($data)) { + throw new \SimpleSAML_Error_Exception('Invalid input parameters.'); + } + + $config = \SimpleSAML_Configuration::getInstance(); + $allowed = $config->getBoolean('enable.http_post', false); + + if ($allowed && preg_match("#^http:#", $destination) && self::isHTTPS()) { + // we need to post the data to HTTP + $url = self::getSecurePOSTRedirectURL($destination, $data); + } else { // post the data directly + $session = \SimpleSAML_Session::getSessionFromRequest(); + $id = self::savePOSTData($session, $destination, $data); + $url = \SimpleSAML_Module::getModuleURL('core/postredirect.php', array('RedirId' => $id)); + } + + return $url; + } + + /** * Retrieve our own host. * @@ -735,4 +820,40 @@ class HTTP return $baseHost.$dir.$tail; } + + + /** + * Submit a POST form to a specific destination. + * + * This function never returns. + * + * @param string $destination The destination URL. + * @param array $data An associative array with the data to be posted to $destination. + * + * @throws \SimpleSAML_Error_Exception If $destination is not a string or $data is not an array. + * + * @author Olav Morken, UNINETT AS <olav.morken@uninett.no> + * @author Andjelko Horvat + * @author Jaime Perez, UNINETT AS <jaime.perez@uninett.no> + */ + public static function submitPOSTData($destination, $data) + { + if (!is_string($destination) || !is_array($data)) { + throw new \SimpleSAML_Error_Exception('Invalid input parameters.'); + } + + $config = \SimpleSAML_Configuration::getInstance(); + $allowed = $config->getBoolean('enable.http_post', false); + + if ($allowed && preg_match("#^http:#", $destination) && self::isHTTPS()) { + // we need to post the data to HTTP + self::redirect(self::getSecurePOSTRedirectURL($destination, $data)); + } + + $p = new \SimpleSAML_XHTML_Template($config, 'post.php'); + $p->data['destination'] = $destination; + $p->data['post'] = $data; + $p->show(); + exit(0); + } } \ No newline at end of file diff --git a/modules/cdc/lib/Server.php b/modules/cdc/lib/Server.php index 8c2798fd71031a6809b1868cedae1ce2e138f598..41cffb927ebc51d274c1801bdacd989d6b2932ce 100644 --- a/modules/cdc/lib/Server.php +++ b/modules/cdc/lib/Server.php @@ -328,7 +328,7 @@ class sspmod_cdc_Server { if (strlen($url) < 2048) { SimpleSAML_Utilities::redirectTrustedURL($url); } else { - SimpleSAML_Utilities::postRedirect($to, $params); + \SimpleSAML\Utils\HTTP::submitPOSTData($to, $params); } }