summaryrefslogtreecommitdiff
path: root/includes/common.inc
diff options
context:
space:
mode:
authorDries Buytaert <dries@buytaert.net>2008-03-31 20:50:05 +0000
committerDries Buytaert <dries@buytaert.net>2008-03-31 20:50:05 +0000
commited59911f9ee542da87ae7cddcb2d50da0e785079 (patch)
tree8b7f873dd371ae19d1f678e26ad548c47ff1b0ad /includes/common.inc
parent763298455f88e26f286749b5f7ff6c9471742012 (diff)
downloadbrdo-ed59911f9ee542da87ae7cddcb2d50da0e785079.tar.gz
brdo-ed59911f9ee542da87ae7cddcb2d50da0e785079.tar.bz2
- Patch #29706 by pwolanin, solardiz, et al: more secure password hashing.
This is a big and important patch for Drupal's security. We are switching to much stronger password hashes that are also compatible with the Portable PHP password hashing framework. The new password hashes defeat a number of attacks, including: - The ability to try candidate passwords against multiple hashes at once. - The ability to use pre-hashed lists of candidate passwords. - The ability to determine whether two users have the same (or different) password without actually having to guess one of the passwords. Also implemented a pluggable password hashing API (similar to how an alternate cache mechanism can be used) to allow developers to readily substitute an alternative hashing and authentication scheme. Thanks all!
Diffstat (limited to 'includes/common.inc')
-rw-r--r--includes/common.inc40
1 files changed, 39 insertions, 1 deletions
diff --git a/includes/common.inc b/includes/common.inc
index 52d8babd8..a77479e1f 100644
--- a/includes/common.inc
+++ b/includes/common.inc
@@ -2308,6 +2308,44 @@ function drupal_urlencode($text) {
}
/**
+ * Returns a string of highly randomized bytes (over the full 8-bit range).
+ *
+ * This function is better than simply calling mt_rand() or any other built-in
+ * PHP function because it can return a long string of bytes (compared to < 4
+ * bytes normally from mt_rand()) and uses the best available pseudo-random source.
+ *
+ * @param $count
+ * The number of characters (bytes) to return in the string.
+ */
+function drupal_random_bytes($count) {
+ static $random_state;
+ // We initialize with the somewhat random PHP process ID on the first call.
+ if (empty($random_state)) {
+ $random_state = getmypid();
+ }
+ $output = '';
+ // /dev/urandom is available on many *nix systems and is considered the best
+ // commonly available pseudo-random source.
+ if ($fh = @fopen('/dev/urandom', 'rb')) {
+ $output = fread($fh, $count);
+ fclose($fh);
+ }
+ // If /dev/urandom is not available or returns no bytes, this loop will
+ // generate a good set of pseudo-random bytes on any system.
+ // Note that it may be important that our $random_state is passed
+ // through md5() prior to being rolled into $output, that the two md5()
+ // invocations are different, and that the extra input into the first one -
+ // the microtime() - is prepended rather than appended. This is to avoid
+ // directly leaking $random_state via the $output stream, which could
+ // allow for trivial prediction of further "random" numbers.
+ while (strlen($output) < $count) {
+ $random_state = md5(microtime() . mt_rand() . $random_state);
+ $output .= md5(mt_rand() . $random_state, TRUE);
+ }
+ return substr($output, 0, $count);
+}
+
+/**
* Ensure the private key variable used to generate tokens is set.
*
* @return
@@ -2315,7 +2353,7 @@ function drupal_urlencode($text) {
*/
function drupal_get_private_key() {
if (!($key = variable_get('drupal_private_key', 0))) {
- $key = md5(uniqid(mt_rand(), true)) . md5(uniqid(mt_rand(), true));
+ $key = md5(drupal_random_bytes(64));
variable_set('drupal_private_key', $key);
}
return $key;