Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F13203136
D7650.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
3 KB
Referenced Files
None
Subscribers
None
D7650.diff
View Options
Index: src/filesystem/Filesystem.php
===================================================================
--- src/filesystem/Filesystem.php
+++ src/filesystem/Filesystem.php
@@ -390,18 +390,47 @@
* @task file
*/
public static function readRandomBytes($number_of_bytes) {
+ $number_of_bytes = (int)$number_of_bytes;
+ if ($number_of_bytes < 1) {
+ throw new Exception(pht("You must generate at least 1 byte of entropy."));
+ }
+
+ // Try to use `openssl_random_psuedo_bytes()` if it's available. This source
+ // is the most widely available source, and works on Windows/Linux/OSX/etc.
if (function_exists('openssl_random_pseudo_bytes')) {
$strong = true;
$data = openssl_random_pseudo_bytes($number_of_bytes, $strong);
- } else {
- $urandom = @fopen('/dev/urandom', 'rb');
- if (!$urandom) {
- throw new FilesystemException(
- '/dev/urandom',
- 'Failed to open /dev/urandom for reading!');
+
+ if (!$strong) {
+ // NOTE: This indicates we're using a weak random source. This is
+ // probably OK, but maybe we should be more strict here.
+ }
+
+ if ($data === false) {
+ throw new Exception(
+ pht('openssl_random_pseudo_bytes() failed to generate entropy!'));
}
+ if (strlen($data) != $number_of_bytes) {
+ throw new Exception(
+ pht(
+ 'openssl_random_pseudo_bytes() returned an unexpected number of '.
+ 'bytes (got %d, expected %d)!',
+ strlen($data),
+ $number_of_bytes));
+ }
+
+ return $data;
+ }
+
+
+ // Try to use `/dev/urandom` if it's available. This is usually available
+ // on non-Windows systems, but some PHP config (open_basedir) and chrooting
+ // may limit our access to it.
+
+ $urandom = @fopen('/dev/urandom', 'rb');
+ if ($urandom) {
$data = @fread($urandom, $number_of_bytes);
@fclose($urandom);
if (strlen($data) != $number_of_bytes) {
@@ -409,15 +438,30 @@
'/dev/urandom',
'Failed to read random bytes!');
}
+ return $data;
}
- if (strlen($data) != $number_of_bytes) {
+ // (We might be able to try to generate entropy here from a weaker source
+ // if neither of the above sources panned out, see some discussion in
+ // T4153.)
+
+ // We've failed to find any valid entropy source. Try to fail in the most
+ // useful way we can, based on the platform.
+
+ if (phutil_is_windows()) {
throw new Exception(
- 'Filesystem::readRandomBytes() requires at least PHP 5.3 or '.
- '/dev/urandom');
+ pht(
+ 'Filesystem::readRandomBytes() requires the PHP OpenSSL extension '.
+ 'to be installed and enabled to access an entropy source. On '.
+ 'Windows, this extension is usually installed but not enabled by '.
+ 'default. Enable it in your "php.ini".'));
}
- return $data;
+ throw new Exception(
+ pht(
+ 'Filesystem::readRandomBytes() requires the PHP OpenSSL extension '.
+ 'or access to "/dev/urandom". Install or enable the OpenSSL '.
+ 'extension, or make sure "/dev/urandom" is accessible.'));
}
Index: src/filesystem/__tests__/FilesystemTestCase.php
===================================================================
--- src/filesystem/__tests__/FilesystemTestCase.php
+++ src/filesystem/__tests__/FilesystemTestCase.php
@@ -64,6 +64,19 @@
$number_of_bytes = 1024;
$data = Filesystem::readRandomBytes($number_of_bytes);
$this->assertEqual(true, (strlen($data) == $number_of_bytes));
+
+ $data1 = Filesystem::readRandomBytes(128);
+ $data2 = Filesystem::readRandomBytes(128);
+ $this->assertEqual(false, $data1 == $data2);
+
+ $caught = null;
+ try {
+ Filesystem::readRandomBytes(0);
+ } catch (Exception $ex) {
+ $caught = $ex;
+ }
+ $this->assertEqual(true, ($caught instanceof Exception));
+
}
}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Wed, May 15, 11:30 PM (2 w, 4 d ago)
Storage Engine
blob
Storage Format
Encrypted (AES-256-CBC)
Storage Handle
6290173
Default Alt Text
D7650.diff (3 KB)
Attached To
Mode
D7650: Improve error messages from Filesystem::readRandomBytes()
Attached
Detach File
Event Timeline
Log In to Comment