includes/sessions.php
changeset 32 4d87aad3c4c0
parent 31 dc8741857bde
child 42 45ebe475ff75
equal deleted inserted replaced
31:dc8741857bde 32:4d87aad3c4c0
   710         $code = $plugins->setHook('login_success');
   710         $code = $plugins->setHook('login_success');
   711         foreach ( $code as $cmd )
   711         foreach ( $code as $cmd )
   712         {
   712         {
   713           eval($cmd);
   713           eval($cmd);
   714         }
   714         }
       
   715         
   715         return 'success';
   716         return 'success';
   716       }
   717       }
   717       else
   718       else
   718         return 'Your login credentials were correct, but an internal error occured while registering the session key in the database.';
   719         return 'Your login credentials were correct, but an internal error occured while registering the session key in the database.';
   719     }
   720     }
   769    * @return bool
   770    * @return bool
   770    */
   771    */
   771    
   772    
   772   function register_session($user_id, $username, $password, $level = USER_LEVEL_MEMBER)
   773   function register_session($user_id, $username, $password, $level = USER_LEVEL_MEMBER)
   773   {
   774   {
       
   775     // Random key identifier
   774     $salt = md5(microtime() . mt_rand());
   776     $salt = md5(microtime() . mt_rand());
       
   777     
       
   778     // SHA1 hash of password, stored in the key
   775     $passha1 = sha1($password);
   779     $passha1 = sha1($password);
       
   780     
       
   781     // Unencrypted session key
   776     $session_key = "u=$username;p=$passha1;s=$salt";
   782     $session_key = "u=$username;p=$passha1;s=$salt";
       
   783     
       
   784     // Encrypt the key
   777     $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE);
   785     $aes = new AESCrypt(AES_BITS, AES_BLOCKSIZE);
   778     $session_key = $aes->encrypt($session_key, $this->private_key, ENC_HEX);
   786     $session_key = $aes->encrypt($session_key, $this->private_key, ENC_HEX);
       
   787     
       
   788     // If we're registering an elevated-privilege key, it needs to be on GET
   779     if($level > USER_LEVEL_MEMBER)
   789     if($level > USER_LEVEL_MEMBER)
   780     {
   790     {
       
   791       // Reverse it - cosmetic only ;-)
   781       $hexkey = strrev($session_key);
   792       $hexkey = strrev($session_key);
   782       $this->sid_super = $hexkey;
   793       $this->sid_super = $hexkey;
   783       $_GET['auth'] = $hexkey;
   794       $_GET['auth'] = $hexkey;
   784     }
   795     }
   785     else
   796     else
   786     {
   797     {
       
   798       // Stash it in a cookie
       
   799       // For now, make the cookie last forever, we can change this in 1.1.x
   787       setcookie( 'sid', $session_key, time()+315360000, scriptPath.'/' );
   800       setcookie( 'sid', $session_key, time()+315360000, scriptPath.'/' );
   788       $_COOKIE['sid'] = $session_key;
   801       $_COOKIE['sid'] = $session_key;
   789     }
   802     }
       
   803     // $keyhash is stored in the database, this is for compatibility with the older DB structure
   790     $keyhash = md5($session_key);
   804     $keyhash = md5($session_key);
       
   805     // Record the user's IP
   791     $ip = ip2hex($_SERVER['REMOTE_ADDR']);
   806     $ip = ip2hex($_SERVER['REMOTE_ADDR']);
   792     if(!$ip)
   807     if(!$ip)
   793       die('$session->register_session: Remote-Addr was spoofed');
   808       die('$session->register_session: Remote-Addr was spoofed');
       
   809     // The time needs to be stashed to enforce the 15-minute limit on elevated session keys
   794     $time = time();
   810     $time = time();
       
   811     
       
   812     // Sanity check
   795     if(!is_int($user_id))
   813     if(!is_int($user_id))
   796       die('Somehow an SQL injection attempt crawled into our session registrar! (1)');
   814       die('Somehow an SQL injection attempt crawled into our session registrar! (1)');
   797     if(!is_int($level))
   815     if(!is_int($level))
   798       die('Somehow an SQL injection attempt crawled into our session registrar! (2)');
   816       die('Somehow an SQL injection attempt crawled into our session registrar! (2)');
   799     
   817     
       
   818     // All done!
   800     $query = $this->sql('INSERT INTO '.table_prefix.'session_keys(session_key, salt, user_id, auth_level, source_ip, time) VALUES(\''.$keyhash.'\', \''.$salt.'\', '.$user_id.', '.$level.', \''.$ip.'\', '.$time.');');
   819     $query = $this->sql('INSERT INTO '.table_prefix.'session_keys(session_key, salt, user_id, auth_level, source_ip, time) VALUES(\''.$keyhash.'\', \''.$salt.'\', '.$user_id.', '.$level.', \''.$ip.'\', '.$time.');');
   801     return true;
   820     return true;
   802   }
   821   }
   803   
   822   
   804   /**
   823   /**
  1562     {
  1581     {
  1563       $q = $this->sql('SELECT user_id,username,email FROM '.table_prefix.'users WHERE user_id='.$user.';'); // This is SAFE! This is only called if $user is an integer
  1582       $q = $this->sql('SELECT user_id,username,email FROM '.table_prefix.'users WHERE user_id='.$user.';'); // This is SAFE! This is only called if $user is an integer
  1564     }
  1583     }
  1565     elseif(is_string($user))
  1584     elseif(is_string($user))
  1566     {
  1585     {
  1567       $q = $this->sql('SELECT user_id,username,email FROM '.table_prefix.'users WHERE username=\''.$db->escape($user).'\';');
  1586       $q = $this->sql('SELECT user_id,username,email FROM '.table_prefix.'users WHERE lcase(username)=lcase(\''.$db->escape($user).'\');');
  1568     }
  1587     }
  1569     else
  1588     else
  1570     {
  1589     {
  1571       return false;
  1590       return false;
  1572     }
  1591     }
  1662   }
  1681   }
  1663   
  1682   
  1664   /**
  1683   /**
  1665    * For a given user level identifier (USER_LEVEL_*), returns a string describing that user level.
  1684    * For a given user level identifier (USER_LEVEL_*), returns a string describing that user level.
  1666    * @param int User level
  1685    * @param int User level
       
  1686    * @param bool If true, returns a shorter string. Optional.
  1667    * @return string
  1687    * @return string
  1668    */
  1688    */
  1669   
  1689   
  1670   function userlevel_to_string($user_level)
  1690   function userlevel_to_string($user_level, $short = false)
  1671   {
  1691   {
  1672     switch ( $user_level )
  1692     if ( $short )
  1673     {
  1693     {
  1674       case USER_LEVEL_GUEST:
  1694       switch ( $user_level )
  1675         return 'Low - guest privileges';
  1695       {
  1676       case USER_LEVEL_MEMBER:
  1696         case USER_LEVEL_GUEST:
  1677         return 'Standard - normal member level';
  1697           return 'Guest';
  1678       case USER_LEVEL_CHPREF:
  1698         case USER_LEVEL_MEMBER:
  1679         return 'Medium - user can change his/her own e-mail address and password';
  1699           return 'Member';
  1680       case USER_LEVEL_MOD:
  1700         case USER_LEVEL_CHPREF:
  1681         return 'High - moderator privileges';
  1701           return 'Sensitive preferences changeable';
  1682       case USER_LEVEL_ADMIN:
  1702         case USER_LEVEL_MOD:
  1683         return 'Highest - administrative privileges';
  1703           return 'Moderator';
  1684       default:
  1704         case USER_LEVEL_ADMIN:
  1685         return "Unknown ($user_level)";
  1705           return 'Administrative';
       
  1706         default:
       
  1707           return "Level $user_level";
       
  1708       }
       
  1709     }
       
  1710     else
       
  1711     {
       
  1712       switch ( $user_level )
       
  1713       {
       
  1714         case USER_LEVEL_GUEST:
       
  1715           return 'Low - guest privileges';
       
  1716         case USER_LEVEL_MEMBER:
       
  1717           return 'Standard - normal member level';
       
  1718         case USER_LEVEL_CHPREF:
       
  1719           return 'Medium - user can change his/her own e-mail address and password';
       
  1720         case USER_LEVEL_MOD:
       
  1721           return 'High - moderator privileges';
       
  1722         case USER_LEVEL_ADMIN:
       
  1723           return 'Highest - administrative privileges';
       
  1724         default:
       
  1725           return "Unknown ($user_level)";
       
  1726       }
  1686     }
  1727     }
  1687   }
  1728   }
  1688   
  1729   
  1689   /**
  1730   /**
  1690    * Updates a user's information in the database. Note that any of the values except $user_id can be false if you want to preserve the old values.
  1731    * Updates a user's information in the database. Note that any of the values except $user_id can be false if you want to preserve the old values.
  1782       }
  1823       }
  1783       // E-mail addy
  1824       // E-mail addy
  1784       if(is_string($email))
  1825       if(is_string($email))
  1785       {
  1826       {
  1786         // I didn't write this regex.
  1827         // I didn't write this regex.
  1787         if(!preg_match('/^(?:[\w\d]+\.?)+@(?:(?:[\w\d]\-?)+\.)+\w{2,4}$/', $email))
  1828         if(!preg_match('/^(?:[\w\d]+\.?)+@((?:(?:[\w\d]\-?)+\.)+\w{2,4}|localhost)$/', $email))
  1788           $errors[] = 'The e-mail address you entered is invalid.';
  1829           $errors[] = 'The e-mail address you entered is invalid.';
  1789         $strs[] = 'email=\''.$db->escape($email).'\'';
  1830         $strs[] = 'email=\''.$db->escape($email).'\'';
  1790       }
  1831       }
  1791     }
  1832     }
  1792     // Real name
  1833     // Real name
  2338               if ( frm._login ) frm._login.disabled = true;
  2379               if ( frm._login ) frm._login.disabled = true;
  2339               len = ( typeof cryptkey == \'string\' || typeof cryptkey == \'object\' ) ? \'\\nLen: \'+cryptkey.length : \'\';
  2380               len = ( typeof cryptkey == \'string\' || typeof cryptkey == \'object\' ) ? \'\\nLen: \'+cryptkey.length : \'\';
  2340               alert(\'The key is messed up\\nType: \'+typeof(cryptkey)+len);
  2381               alert(\'The key is messed up\\nType: \'+typeof(cryptkey)+len);
  2341             }
  2382             }
  2342           }
  2383           }
  2343           if(frm.username) frm.username.focus();
       
  2344           function runEncryption()
  2384           function runEncryption()
  2345           {
  2385           {
  2346             if(testpassed)
  2386             if(testpassed)
  2347             {
  2387             {
  2348               pass = frm.'.$pw_field.'.value;
  2388               pass = frm.'.$pw_field.'.value;