fsf changes, meant to be rebased on upstream
[squirrelmail.git] / functions / global.php
index 652c8bef01c10df55bcef28680552f805aae46a7..0e2dfa0bec063b5aa6aad7861c0ac38c7f1f2f2c 100644 (file)
@@ -7,7 +7,7 @@
  * It also has some session register functions that work across various
  * php versions.
  *
- * @copyright 1999-2013 The SquirrelMail Project Team
+ * @copyright 1999-2021 The SquirrelMail Project Team
  * @license http://opensource.org/licenses/gpl-license.php GNU Public License
  * @version $Id$
  * @package squirrelmail
@@ -491,7 +491,8 @@ function sqsession_destroy() {
     global $base_uri, $_COOKIE, $_SESSION;
 
     if (isset($_COOKIE[session_name()]) && session_name()) {
-        sqsetcookie(session_name(), $_COOKIE[session_name()], 1, $base_uri);
+        // sqsetcookie(session_name(), $_COOKIE[session_name()], 1, $base_uri);
+        sqsetcookie(session_name(), 'SQMTRASH', 1, $base_uri);
 
         /*
          * Make sure to kill /src and /src/ cookies, just in case there are
@@ -502,8 +503,10 @@ function sqsession_destroy() {
          *     or fixate the $base_uri cookie, so we don't worry about
          *     trying to delete all of them here.
          */
-        sqsetcookie(session_name(), $_COOKIE[session_name()], 1, $base_uri . 'src');
-        sqsetcookie(session_name(), $_COOKIE[session_name()], 1, $base_uri . 'src/');
+        // sqsetcookie(session_name(), $_COOKIE[session_name()], 1, $base_uri . 'src');
+        // sqsetcookie(session_name(), $_COOKIE[session_name()], 1, $base_uri . 'src/');
+        sqsetcookie(session_name(), 'SQMTRASH', 1, $base_uri . 'src');
+        sqsetcookie(session_name(), 'SQMTRASH', 1, $base_uri . 'src/');
     }
 
     if (isset($_COOKIE['key']) && $_COOKIE['key']) sqsetcookie('key','SQMTRASH',1,$base_uri);
@@ -580,6 +583,16 @@ function sqsession_start() {
  *                           transmitted over a secure HTTPS connection.
  * @param boolean $bHttpOnly Disallow JS to access the cookie (IE6 only)
  * @param boolean $bReplace  Replace previous cookies with same name?
+ * @param string  $sSameSite Optional override of the default SameSite
+ *                           cookie policy detemined from the global
+ *                           configuration item $same_site_cookies
+ *                           (which can be set in config/config_local.php)
+ *                           (should be NULL to accept the configured global
+ *                           default or one of "Lax" "Strict" or "None"
+ *                           but "None" will not work if $bSecure is FALSE.
+ *                           Can also be set set to an empty string in order
+ *                           to NOT specify the SameSite cookie attribute at
+ *                           all and accept whatever the browser default is)
  *
  * @return void
  *
@@ -587,8 +600,23 @@ function sqsession_start() {
  *
  */
 function sqsetcookie($sName, $sValue='deleted', $iExpire=0, $sPath="", $sDomain="",
-                     $bSecure=false, $bHttpOnly=true, $bReplace=false) {
+                     $bSecure=false, $bHttpOnly=true, $bReplace=false, $sSameSite=NULL) {
  
+    // some environments can get overwhelmed by an excessive
+    // setting of the same cookie over and over (e.g., many
+    // calls to this function via sqsession_is_active() result
+    // in repeated setting of the session cookie when $bReplace
+    // is FALSE, but something odd happens (during login only)
+    // if we change that to default TRUE) ... so we keep our own
+    // naive per-request name/value cache and only set the cookie
+    // if its value is changing (or never seen before)
+    static $cookies = array();
+    if (isset($cookies[$sName]) && $cookies[$sName] === $sValue)
+        return;
+    else
+        $cookies[$sName] = $sValue;
+
+
     // if we have a secure connection then limit the cookies to https only.
     global $is_secure_connection;
     if ($sName && $is_secure_connection)
@@ -599,6 +627,21 @@ function sqsetcookie($sName, $sValue='deleted', $iExpire=0, $sPath="", $sDomain=
     if (!$only_secure_cookies)
         $bSecure = false;
 
+    // use global SameSite setting, but allow override
+    // The global $same_site_cookies (for which an override value
+    // can be specified in config/config_local.php) defaults to
+    // "Strict" when it is NULL (when not given in the config file),
+    // or can be manually set to "Lax" "Strict" or "None" if desired
+    // or can be set to an empty string in order to not specify
+    // SameSite at all and use the browser default
+    if (is_null($sSameSite)) {
+        global $same_site_cookies;
+        if (is_null($same_site_cookies))
+           $sSameSite = 'Strict';
+        else
+           $sSameSite = $same_site_cookies;
+    }
+
     if (false && check_php_version(5,2)) {
        // php 5 supports the httponly attribute in setcookie, but because setcookie seems a bit
        // broken we use the header function for php 5.2 as well. We might change that later.
@@ -619,7 +662,8 @@ function sqsetcookie($sName, $sValue='deleted', $iExpire=0, $sPath="", $sDomain=
                             . (empty($sPath) ? '' : '; path=' . $sPath)
                             . (empty($sDomain) ? '' : '; domain=' . $sDomain)
                             . (!$bSecure ? '' : '; secure')
-                            . (!$bHttpOnly ? '' : '; HttpOnly'), $bReplace);
+                            . (!$bHttpOnly ? '' : '; HttpOnly')
+                            . (empty($sSameSite) ? '' : '; SameSite=' . $sSameSite), $bReplace);
     }
 }
 
@@ -682,9 +726,11 @@ if (!function_exists('session_regenerate_id')) {
  * @return string The path, filename and any arguments for the
  *                current script
  */
-function php_self() {
+function php_self($with_query_string=TRUE) {
 
-    $request_uri = '';
+    static $request_uri = '';
+    if (!empty($request_uri))
+        return ($with_query_string ? $request_uri : (strpos($request_uri, '?') !== FALSE ? substr($request_uri, 0, strpos($request_uri, '?')) : $request_uri));
 
     // first try $_SERVER['PHP_SELF'], which seems most reliable
     // (albeit it usually won't include the query string)
@@ -718,7 +764,10 @@ function php_self() {
         $request_uri .= '?' . $query_string;
     }   
 
-    return $request_uri;
+    global $php_self_pattern, $php_self_replacement;
+    if (!empty($php_self_pattern))
+        $request_uri = preg_replace($php_self_pattern, $php_self_replacement, $request_uri);
+    return ($with_query_string ? $request_uri : (strpos($request_uri, '?') !== FALSE ? substr($request_uri, 0, strpos($request_uri, '?')) : $request_uri));
 
 }