Multiple authkeys patch

Marty Vance <[email protected]> Wed, 12 Mar 2008 16:55:15 -0600
Newsgroups gmane.comp.cms.xaraya.patches
Organization Xaraya
Message-ID <[email protected]>
This is a multi-part message in MIME format.
--------------000203070206090100050701
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

The changes are localized to includes/xarSecurity.php and 
includes/xarSession.php.

Xaraya doesn't actually store the authid, it stores a random value which 
is used to compare against a returned authid (one way cipher, like 
password handling).  The changes I made now store an array of random 
values, each associated with a timestamp.  The format is 
[timestamp]-[random value], ie 1204762826-1784614311

The security file has changes to xarSecGenAuthKey() and 
xarSecConfirmAuthKey().

Every call to xarSecGenAuthKey adds another index to the array of stored 
values.

A key is removed when it's age is greater than the session activity timeout.

In order to prevent session data overflow, only the most recent 64 keys 
are maintained.  This should allow for a decent amount of activity.  (I 
expect some crazy module somewhere calls for a new key for each item in 
an item list... keeping 64 keys should avoid a complete recycling of the 
values).

The session file was modified only to change the value stored when the 
session is initialized, mainly as a failsafe, since every call to 
generate a key add another one... the initial value is unlikely to ever 
be used.

--------------000203070206090100050701
Content-Type: text/plain;
 name="ajax_authkeys.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="ajax_authkeys.patch"

#
# old_revision [56a7b0dd9bed1ff5c039d76ec8b736a4898e9ae7]
#
# patch "html/includes/xarSecurity.php"
#  from [262c983f5ddf72f7b0e0a95dcada45ec7b123108]
#    to [7eae753224ac3bcf8423d6feeb1b53d34346b361]
# 
# patch "html/includes/xarSession.php"
#  from [6ba333e753cfc4ec9f06274c44ab868315649437]
#    to [c404ff0302a6a88b80cf63fd70149b1dfaa4b33d]
#
============================================================
--- html/includes/xarSecurity.php	262c983f5ddf72f7b0e0a95dcada45ec7b123108
+++ html/includes/xarSecurity.php	7eae753224ac3bcf8423d6feeb1b53d34346b361
@@ -636,9 +636,28 @@ function xarSecGenAuthKey($modName = NUL
         list($modName) = xarRequestGetInfo();
     }
 
+    $rands = xarSessionGetVar('rand');
+    $now = time();
+
+    // convert single rand to array
+    if(!is_array($rands)){
+        $rands = array();
+    }
+
+    // always make a new rand value
+    // format is timestamp-rand
+    srand((double)microtime()*1000000);
+    $rnd = rand();
+    $rands[] = $now . '-' . $rnd;
+
+    // session integrity: only keep most recent 64 values
+    $rands = array_slice($rands, -64);
+
+    xarSessionSetVar('rand', $rands);
+
     // Date gives extra security but leave it out for now
     // $key = xarSessionGetVar('rand') . $modName . date ('YmdGi');
-    $key = xarSessionGetVar('rand') . strtolower($modName);
+    $key = $rnd . strtolower($modName);
 
     // Encrypt key
     $authid = md5($key);
@@ -667,9 +686,38 @@ function xarSecConfirmAuthKey($modName =
     if(!isset($modName)) list($modName) = xarRequestGetInfo();
     $authid = xarRequestGetVar($authIdVarName);
 
-    // Regenerate static part of key
-    $partkey = xarSessionGetVar('rand') . strtolower($modName);
+    $rands = xarSessionGetVar('rand');
+    $now = time();
 
+    srand((double)microtime()*1000000);
+
+    // convert single rand to array of "timestamp-rand()" strings
+    if(!is_array($rands)){
+        $rands = array();
+
+        // session integrity: only keep most recent 64 values
+        $rands = array_slice($rands, -64);
+
+        xarSessionSetVar('rand', $rands);
+    }
+
+    // needed in foreach to expire old rand values
+    $age = xarConfigGetVar('Site.Session.InactivityTimeout') * 60; // convert minutes to seconds
+
+    // loop through the rands array to find a match
+    foreach($rands as $r => $rnd){
+
+        list($timestamp, $rndval) = explode('-', $rnd, 2);
+
+        // ignore and get rid of random values older than session activity timeout
+        if($now - $age > $timestamp){
+            unset($rands[$r]);
+            continue;
+        }
+
+        // Regenerate static part of key
+        $partkey = $rndval . strtolower($modName);
+
 // Not using time-sensitive keys for the moment
 //    // Key life is 5 minutes, so search backwards and forwards 5
 //    // minutes to see if there is a match anywhere
@@ -688,13 +736,20 @@ function xarSecConfirmAuthKey($modName =
 //            return true;
 //        }
 //    }
-    if ((md5($partkey)) == $authid) {
-        // Match - generate new random number for next key and leave happy
-        srand((double)microtime()*1000000);
-        xarSessionSetVar('rand', rand());
 
-        return true;
+        if ((md5($partkey)) == $authid) {
+            // Match - get rid of it and leave happy
+            unset($rands[$r]);
+
+            // session integrity: only keep most recent 64 values
+            $rands = array_slice($rands, -64);
+
+            xarSessionSetVar('rand', $rands);
+
+            return true;
+        }
     }
+
     // Not found, assume invalid
     xarErrorSet(XAR_USER_EXCEPTION, 'FORBIDDEN_OPERATION',
                    new DefaultUserException());
============================================================
--- html/includes/xarSession.php	6ba333e753cfc4ec9f06274c44ab868315649437
+++ html/includes/xarSession.php	c404ff0302a6a88b80cf63fd70149b1dfaa4b33d
@@ -411,7 +411,7 @@ function xarSession__new($sessionId, $ip
     // Generate a random number, used for
     // some authentication
     srand((double) microtime() * 1000000);
-    xarSessionSetVar('rand', rand());
+    xarSessionSetVar('rand', array(time() . '-' . rand()));
 
     // Congratulations. We have created a new session
     xarEvt_trigger('SessionCreate');

--------------000203070206090100050701
Content-Type: text/plain; charset="us-ascii"
MIME-Version: 1.0
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

_______________________________________________
Xaraya_patches mailing list
[email protected]
http://xaraya.com/mailman/listinfo/xaraya_patches

--------------000203070206090100050701--