From 60fcb921bc3b549535aa35b8a545adb3130d0a76 Mon Sep 17 00:00:00 2001 From: Olav Morken <olav.morken@uninett.no> Date: Wed, 7 Jul 2010 08:22:27 +0000 Subject: [PATCH] session: New/unified cookie handling options. Adds options to control the various session cookie parameters, and changes users of setcookie to use those options instead. git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@2381 44740490-163a-0410-bde0-09ae8108e29a --- config-templates/config.php | 32 +++++++++++++++- lib/SimpleSAML/AuthMemCookie.php | 3 +- lib/SimpleSAML/SessionHandler.php | 51 ++++++++++++++++++++++++- lib/SimpleSAML/SessionHandlerCookie.php | 4 +- lib/SimpleSAML/SessionHandlerPHP.php | 43 +++++++++++++++++---- www/authmemcookie.php | 4 +- 6 files changed, 122 insertions(+), 15 deletions(-) diff --git a/config-templates/config.php b/config-templates/config.php index f4105766f..d16b2beed 100644 --- a/config-templates/config.php +++ b/config-templates/config.php @@ -145,6 +145,36 @@ $config = array ( 'session.datastore.timeout' => (4*60*60), // 4 hours + /* + * Expiration time for the session cookie, in seconds. + * + * Defaults to 0, which means that the cookie expires when the browser is closed. + * + * Example: + * 'session.cookie.lifetime' => 30*60, + */ + 'session.cookie.lifetime' => 0, + + /* + * Limit the path of the cookies. + * + * Can be used to limit the path of the cookies to a specific subdirectory. + * + * Example: + * 'session.cookie.path' => '/simplesaml/', + */ + 'session.cookie.path' => '/', + + /* + * Cookie domain. + * + * Can be used to make the session cookie available to several domains. + * + * Example: + * 'session.cookie.domain' => '.example.org', + */ + 'session.cookie.domain' => NULL, + /* * Set the secure flag in the cookie. * @@ -158,8 +188,8 @@ $config = array ( * Options to override the default settings for php sessions. */ 'session.phpsession.cookiename' => null, - 'session.phpsession.limitedpath' => false, 'session.phpsession.savepath' => null, + 'session.phpsession.httponly' => FALSE, /* * Languages available and what language is default diff --git a/lib/SimpleSAML/AuthMemCookie.php b/lib/SimpleSAML/AuthMemCookie.php index db3ac9cf3..46b70fa8a 100644 --- a/lib/SimpleSAML/AuthMemCookie.php +++ b/lib/SimpleSAML/AuthMemCookie.php @@ -153,7 +153,8 @@ class SimpleSAML_AuthMemCookie { $memcache->delete($sessionID); /* Delete the session cookie. */ - setcookie($cookieName, '', 1, '/', NULL, SimpleSAML_Utilities::isHTTPS(), TRUE); + $sessionHandler = SimpleSAML_SessionHandler::getSessionHandler(); + $sessionHandler->setCookie($cookieName, NULL); } diff --git a/lib/SimpleSAML/SessionHandler.php b/lib/SimpleSAML/SessionHandler.php index 562fed2b9..59d1a2541 100644 --- a/lib/SimpleSAML/SessionHandler.php +++ b/lib/SimpleSAML/SessionHandler.php @@ -129,6 +129,53 @@ abstract class SimpleSAML_SessionHandler { return TRUE; } -} -?> \ No newline at end of file + /** + * Get the cookie parameters that should be used for session cookies. + * + * @return array + * @link http://www.php.net/manual/en/function.session-get-cookie-params.php + */ + public function getCookieParams() { + + $config = SimpleSAML_Configuration::getInstance(); + + return array( + 'lifetime' => $config->getInteger('session.cookie.lifetime', 0), + 'path' => $config->getString('session.cookie.path', '/'), + 'domain' => $config->getString('session.cookie.domain', NULL), + 'secure' => $config->getBoolean('session.cookie.secure', FALSE), + 'httponly' => TRUE, + ); + } + + + /** + * Set a session cookie. + * + * @param string $name The name of the session cookie. + * @param string|NULL $value The value of the cookie. Set to NULL to delete the cookie. + */ + public function setCookie($name, $value) { + assert('is_string($name)'); + assert('is_string($value) || is_null($value)'); + + $params = $this->getCookieParams(); + + if ($value === NULL) { + $expire = time() - 365*24*60*60; + } elseif ($params['lifetime'] === 0) { + $expire = 0; + } else { + $expire = time() + $params['lifetime'];; + } + + $version = explode('.', PHP_VERSION); + if ((int)$version[0] === 5 && (int)$version[1] < 2) { + setcookie($name, $value, $expire, $params['path'], $params['domain'], $params['secure']); + } else { + setcookie($name, $value, $expire, $params['path'], $params['domain'], $params['secure'], $params['httponly']); + } + } + +} diff --git a/lib/SimpleSAML/SessionHandlerCookie.php b/lib/SimpleSAML/SessionHandlerCookie.php index 040483a7e..16be64fb9 100644 --- a/lib/SimpleSAML/SessionHandlerCookie.php +++ b/lib/SimpleSAML/SessionHandlerCookie.php @@ -51,9 +51,7 @@ extends SimpleSAML_SessionHandler { /* We don't have a valid session. Create a new session id. */ $this->session_id = self::createSessionID(); - $config = SimpleSAML_Configuration::getInstance(); - $secureFlag = $config->getBoolean('session.cookie.secure', FALSE); - setcookie('SimpleSAMLSessionID', $this->session_id, 0, '/', NULL, $secureFlag); + $this->setCookie('SimpleSAMLSessionID', $this->session_id); } diff --git a/lib/SimpleSAML/SessionHandlerPHP.php b/lib/SimpleSAML/SessionHandlerPHP.php index 5d1b05315..6faea09bf 100644 --- a/lib/SimpleSAML/SessionHandlerPHP.php +++ b/lib/SimpleSAML/SessionHandlerPHP.php @@ -32,11 +32,16 @@ class SimpleSAML_SessionHandlerPHP extends SimpleSAML_SessionHandler { */ if(session_id() === '') { $config = SimpleSAML_Configuration::getInstance(); - - $cookiepath = ($config->getBoolean('session.phpsession.limitedpath', FALSE) ? '/' . $config->getBaseURL() : '/'); - $secureFlag = $config->getBoolean('session.cookie.secure', FALSE); - session_set_cookie_params(0, $cookiepath, NULL, $secureFlag); - + + $params = $this->getCookieParams(); + + $version = explode('.', PHP_VERSION); + if ((int)$version[0] === 5 && (int)$version[1] < 2) { + session_set_cookie_params($params['lifetime'], $params['path'], $params['domain'], $params['secure']); + } else { + session_set_cookie_params($params['lifetime'], $params['path'], $params['domain'], $params['secure'], $params['httponly']); + } + $cookiename = $config->getString('session.phpsession.cookiename', NULL); if (!empty($cookiename)) session_name($cookiename); @@ -114,6 +119,30 @@ class SimpleSAML_SessionHandlerPHP extends SimpleSAML_SessionHandler { return array_key_exists($cookieName, $_COOKIE); } -} -?> \ No newline at end of file + /** + * Get the cookie parameters that should be used for session cookies. + * + * This function contains some adjustments from the default to provide backwards-compatibility. + * + * @return array + * @link http://www.php.net/manual/en/function.session-get-cookie-params.php + */ + public function getCookieParams() { + + $config = SimpleSAML_Configuration::getInstance(); + + $ret = parent::getCookieParams(); + + if ($config->hasValue('session.phpsession.limitedpath') && $config->hasValue('session.cookie.path')) { + throw new SimpleSAML_Error_Exception('You cannot set both the session.phpsession.limitedpath and session.cookie.path options.'); + } elseif ($config->hasValue('session.phpsession.limitedpath')) { + $ret['path'] = $config->getBoolean('session.phpsession.limitedpath', FALSE) ? '/' . $config->getBaseURL() : '/'; + } + + $ret['httponly'] = $config->getBoolean('session.phpsession.httponly', FALSE); + + return $ret; + } + +} diff --git a/www/authmemcookie.php b/www/authmemcookie.php index dac9a362c..5cb5b1e27 100644 --- a/www/authmemcookie.php +++ b/www/authmemcookie.php @@ -60,7 +60,9 @@ try { $sessionID = SimpleSAML_Utilities::generateID(); $cookieName = $amc->getCookieName(); - setcookie($cookieName, $sessionID, 0, '/', NULL, SimpleSAML_Utilities::isHTTPS(), TRUE); + + $sessionHandler = SimpleSAML_SessionHandler::getSessionHandler(); + $sessionHandler->setCookie($cookieName, $sessionID); /* Generate the authentication information. */ -- GitLab