|
@@ -1494,7 +1494,8 @@ function sm_truncate_string($string, $max_chars, $elipses='',
|
|
function sm_get_user_security_tokens($purge_old=TRUE)
|
|
function sm_get_user_security_tokens($purge_old=TRUE)
|
|
{
|
|
{
|
|
|
|
|
|
- global $data_dir, $username, $max_token_age_days;
|
|
|
|
|
|
+ global $data_dir, $username, $max_token_age_days,
|
|
|
|
+ $use_expiring_security_tokens;
|
|
|
|
|
|
$tokens = getPref($data_dir, $username, 'security_tokens', '');
|
|
$tokens = getPref($data_dir, $username, 'security_tokens', '');
|
|
if (($tokens = unserialize($tokens)) === FALSE || !is_array($tokens))
|
|
if (($tokens = unserialize($tokens)) === FALSE || !is_array($tokens))
|
|
@@ -1521,7 +1522,17 @@ function sm_get_user_security_tokens($purge_old=TRUE)
|
|
/**
|
|
/**
|
|
* Generates a security token that is then stored in
|
|
* Generates a security token that is then stored in
|
|
* the user's preferences with a timestamp for later
|
|
* the user's preferences with a timestamp for later
|
|
- * verification/use.
|
|
|
|
|
|
+ * verification/use (although session-based tokens
|
|
|
|
+ * are not stored in user preferences).
|
|
|
|
+ *
|
|
|
|
+ * NOTE: By default SquirrelMail will use a single session-based
|
|
|
|
+ * token, but if desired, user tokens can have expiration
|
|
|
|
+ * dates associated with them and become invalid even during
|
|
|
|
+ * the same login session. When in that mode, the note
|
|
|
|
+ * immediately below applies, otherwise it is irrelevant.
|
|
|
|
+ * To enable that mode, the administrator must add the
|
|
|
|
+ * following to config/config_local.php:
|
|
|
|
+ * $use_expiring_security_tokens = TRUE;
|
|
*
|
|
*
|
|
* NOTE: The administrator can force SquirrelMail to generate
|
|
* NOTE: The administrator can force SquirrelMail to generate
|
|
* a new token every time one is requested (which may increase
|
|
* a new token every time one is requested (which may increase
|
|
@@ -1552,9 +1563,24 @@ function sm_get_user_security_tokens($purge_old=TRUE)
|
|
function sm_generate_security_token($force_generate_new=FALSE)
|
|
function sm_generate_security_token($force_generate_new=FALSE)
|
|
{
|
|
{
|
|
|
|
|
|
- global $data_dir, $username, $disable_security_tokens, $do_not_use_single_token;
|
|
|
|
|
|
+ global $data_dir, $username, $disable_security_tokens, $do_not_use_single_token,
|
|
|
|
+ $use_expiring_security_tokens;
|
|
$max_generation_tries = 1000;
|
|
$max_generation_tries = 1000;
|
|
|
|
|
|
|
|
+ // if we're using session-based tokens, just return
|
|
|
|
+ // the same one every time (generate it if it's not there)
|
|
|
|
+ //
|
|
|
|
+ if (!$use_expiring_security_tokens)
|
|
|
|
+ {
|
|
|
|
+ if (sqgetGlobalVar('sm_security_token', $token, SQ_SESSION))
|
|
|
|
+ return $token;
|
|
|
|
+
|
|
|
|
+ // create new one since there was none in session
|
|
|
|
+ $token = GenerateRandomString(12, '', 7);
|
|
|
|
+ sqsession_register($token, 'sm_security_token');
|
|
|
|
+ return $token;
|
|
|
|
+ }
|
|
|
|
+
|
|
$tokens = sm_get_user_security_tokens();
|
|
$tokens = sm_get_user_security_tokens();
|
|
|
|
|
|
if (!$force_generate_new && !$do_not_use_single_token && !empty($tokens))
|
|
if (!$force_generate_new && !$do_not_use_single_token && !empty($tokens))
|
|
@@ -1593,6 +1619,9 @@ function sm_generate_security_token($force_generate_new=FALSE)
|
|
* overrides that value using $max_token_age_days in
|
|
* overrides that value using $max_token_age_days in
|
|
* config/config_local.php
|
|
* config/config_local.php
|
|
*
|
|
*
|
|
|
|
+ * Session-based tokens of course are always reused and are
|
|
|
|
+ * valid for the lifetime of the login session.
|
|
|
|
+ *
|
|
* WARNING: If the administrator has turned the token system
|
|
* WARNING: If the administrator has turned the token system
|
|
* off by setting $disable_security_tokens to TRUE in
|
|
* off by setting $disable_security_tokens to TRUE in
|
|
* config/config.php or the configuration tool, this
|
|
* config/config.php or the configuration tool, this
|
|
@@ -1627,12 +1656,33 @@ function sm_validate_security_token($token, $validity_period=0, $show_error=FALS
|
|
{
|
|
{
|
|
|
|
|
|
global $data_dir, $username, $max_token_age_days,
|
|
global $data_dir, $username, $max_token_age_days,
|
|
|
|
+ $use_expiring_security_tokens,
|
|
$disable_security_tokens;
|
|
$disable_security_tokens;
|
|
|
|
|
|
// bypass token validation? CAREFUL!
|
|
// bypass token validation? CAREFUL!
|
|
//
|
|
//
|
|
if ($disable_security_tokens) return TRUE;
|
|
if ($disable_security_tokens) return TRUE;
|
|
|
|
|
|
|
|
+ // if we're using session-based tokens, just compare
|
|
|
|
+ // the same one every time
|
|
|
|
+ //
|
|
|
|
+ if (!$use_expiring_security_tokens)
|
|
|
|
+ {
|
|
|
|
+ if (!sqgetGlobalVar('sm_security_token', $session_token, SQ_SESSION))
|
|
|
|
+ {
|
|
|
|
+ if (!$show_error) return FALSE;
|
|
|
|
+ logout_error(_("Fatal security token error; please log in again"));
|
|
|
|
+ exit;
|
|
|
|
+ }
|
|
|
|
+ if ($token !== $session_token)
|
|
|
|
+ {
|
|
|
|
+ if (!$show_error) return FALSE;
|
|
|
|
+ logout_error(_("The current page request appears to have originated from an untrusted source."));
|
|
|
|
+ exit;
|
|
|
|
+ }
|
|
|
|
+ return TRUE;
|
|
|
|
+ }
|
|
|
|
+
|
|
// don't purge old tokens here because we already
|
|
// don't purge old tokens here because we already
|
|
// do it when generating tokens
|
|
// do it when generating tokens
|
|
//
|
|
//
|