/serverconfig/nopassword-setdbpass.php
https://bitbucket.org/steinb/nopassword · PHP · 112 lines · 66 code · 12 blank · 34 comment · 18 complexity · 911529e4602d7c570e71a0c2272a463b MD5 · raw file
- <?php
- /* generate passwords for php access to mysql database,
- * write php config file and sql code to set database passwords
- *
- * to be called by nopassword-setdbpass.sh
- */
- // filename of the configuration file containing the database passwords
- // WARNING: this code will try to replace this file!
- $dbpass_fname = dirname(__FILE__) . '/secrets/nopassword-dbpass.php';
- // config file to read required usernames from
- $config_fname = dirname(__FILE__) . '/../inc/nopassword-config.php';
- $config_authuser = array();
- include $config_fname;
- // expect to have loaded an array config_authuser
- if (!isset($config_authuser)) {
- die("Error: Could not read configuration from file $config_fname.");
- }
- unset($nopassword_dbpass);
- foreach($config_authuser as $username) {
- $nopassword_dbpass[$username] = generate_random_password();
- }
- file_put_contents($dbpass_fname, "<?php\nnamespace nopassword;\n\$nopassword_dbpass = " . var_export($nopassword_dbpass, true) . ";\n?>");
- unset($nopassword_dbpass);
- include $dbpass_fname;
- // set passwords (generate mysql code to do so)
- echo "USE $dbname;\n";
- // disable the general query log for this session, to prevent the new passwords to be written to a log
- echo "SET sql_log_off=1;\n";
- foreach($nopassword_dbpass as $username => $password) {
- // sanity check: the password should be a string not shorter than 20 characters
- // (that would be no more than 120 bits of entropy with a base64 password)
- if (strlen($password) < 20) {
- die("ACTION REQUIRED: The password for $username is too short to be secure. This is a FATAL ERROR: Passwords in PHP config file $cfgfname and mysql database are NOW INCONSISTENT.");
- }
-
- echo "SET PASSWORD FOR $username = PASSWORD('$password');\n";
- }
- unset($nopassword_dbpass);
- //
- // generate a random base64-encoded string,
- // defaulting to a length of 27 characters
- // (a maximum of 27*6 = 162 bits of entropy)
- //
- // MySQL uses 41 charcter hashes where the first character is constant,
- // limiting entropy to at most 40*4 = 160 bits. Hence longer passwords
- // would not add security.
- //
- // base64 is a good choice for the encoding of a high-entropy password,
- // as it uses a large charcter set with almost perfect compatibility with any choice of charsets and transmission protocols
- //
- // this code is adapted from the random hash salt generation in a compatibility shim for the php 5.5 password function,
- // found at https://github.com/ircmaxell/password_compat
- //
- // the code attempts to use high-quality random number generators if available (mcrypt, openssl, /dev/urandom),
- // but does not fail if none are available, instead falling back to php's mt_rand() function, a pseudo-random number generator
- //
- // WARNING: On very old versions of PHP (<4.2.0), mt_rand is not (automatically) seeded, causing this code to break.
- // Also, the code has not been tested on PHP <5.4.9.
- //
- function generate_random_password($pw_len = 27) {
- $buffer = '';
- $raw_length = (int) ($pw_len * 3 / 4 + 1);
- $buffer_valid = false;
- if (function_exists('mcrypt_create_iv') && !defined('PHALANGER')) {
- $buffer = mcrypt_create_iv($raw_length, MCRYPT_DEV_URANDOM);
- if ($buffer) {
- $buffer_valid = true;
- }
- }
- if (!$buffer_valid && function_exists('openssl_random_pseudo_bytes')) {
- $buffer = openssl_random_pseudo_bytes($raw_length);
- if ($buffer) {
- $buffer_valid = true;
- }
- }
- if (!$buffer_valid && is_readable('/dev/urandom')) {
- $f = fopen('/dev/urandom', 'r');
- $read = strlen($buffer);
- while ($read < $raw_length) {
- $buffer .= fread($f, $raw_length - $read);
- $read = strlen($buffer);
- }
- fclose($f);
- if ($read >= $raw_length) {
- $buffer_valid = true;
- }
- }
- if (!$buffer_valid || strlen($buffer) < $raw_length) {
- $bl = strlen($buffer);
- for ($i = 0; $i < $raw_length; $i++) {
- if ($i < $bl) {
- $buffer[$i] = $buffer[$i] ^ chr(mt_rand(0, 255));
- } else {
- $buffer .= chr(mt_rand(0, 255));
- }
- }
- }
- $salt = str_replace('+', '.', base64_encode($buffer));
- return substr($salt, 0, $pw_len);
- }
- ?>