Uploaded image for project: 'Moodle'
  1. Moodle
  2. MDL-42715

provide bcrypt for external database auth

    XMLWordPrintable

    Details

    • Type: Improvement
    • Status: Closed
    • Priority: Minor
    • Resolution: Duplicate
    • Affects Version/s: 3.3.3, 3.4
    • Fix Version/s: None
    • Component/s: Authentication
    • Labels:
    • Affected Branches:
      MOODLE_33_STABLE, MOODLE_34_STABLE

      Description

      since there is no support for bcrypt in the external database auth plugin i made this patch:

      diff -Naur standardmoodle/auth/db/auth.php mymoodle/auth/db/auth.php
      --- standardmoodle/auth/db/auth.php	2013-11-05 10:53:03.899250152 +0100
      +++ mymoodle/auth/db/auth.php	2013-11-05 10:36:35.614349512 +0100
      @@ -105,30 +105,58 @@
       
       			$authdb = $this->db_init();
       
      -			if ($this->config->passtype === 'md5') {   // Re-format password accordingly.
      -				$extpassword = md5($extpassword);
      -			} else if ($this->config->passtype === 'sha1') {
      -				$extpassword = sha1($extpassword);
      -			}
      -
      -			$rs = $authdb->Execute("SELECT *
      -									  FROM {$this->config->table}
      -									 WHERE {$this->config->fielduser} = '".$this->ext_addslashes($extusername)."'
      -										   AND {$this->config->fieldpass} = '".$this->ext_addslashes($extpassword)."'");
      -			if (!$rs) {
      -				$authdb->Close();
      -				debugging(get_string('auth_dbcantconnect','auth_db'));
      -				return false;
      -			}
      -
      -			if (!$rs->EOF) {
      -				$rs->Close();
      -				$authdb->Close();
      -				return true;
      -			} else {
      +			if ($this->config->passtype === 'bcrypt') {
      +				
      +				$rs = $authdb->Execute("SELECT {$this->config->fieldpass} FROM {$this->config->table}
      +									WHERE {$this->config->fielduser} = '" . $this->ext_addslashes($extusername) . "'");
      +							
      +				if (!$rs) {
      +					$authdb->Close();
      +					debugging(get_string('auth_dbcantconnect', 'auth_db'));
      +					return false;
      +				}
      +				
      +				
      +				if (!$rs->EOF) {
      +					$userdata = $rs->FetchObj();
      +					if (!is_null($userdata->{$this->config->fieldpass}) && !($this->bcrypt_is_legacy_hash($userdata->{$this->config->fieldpass}))) {
      +						if ($this->bcrypt_check($extpassword, $userdata->{$this->config->fieldpass})) {
      +							return true;
      +						}
      +					}
      +				}
      +				
       				$rs->Close();
       				$authdb->Close();
       				return false;
      +				
      +			} else {
      +
      +				if ($this->config->passtype === 'md5') {   // Re-format password accordingly.
      +					$extpassword = md5($extpassword);
      +				} else if ($this->config->passtype === 'sha1') {
      +					$extpassword = sha1($extpassword);
      +				}
      +
      +				$rs = $authdb->Execute("SELECT *
      +										  FROM {$this->config->table}
      +										 WHERE {$this->config->fielduser} = '".$this->ext_addslashes($extusername)."'
      +											   AND {$this->config->fieldpass} = '".$this->ext_addslashes($extpassword)."'");
      +				if (!$rs) {
      +					$authdb->Close();
      +					debugging(get_string('auth_dbcantconnect','auth_db'));
      +					return false;
      +				}
      +
      +				if (!$rs->EOF) {
      +					$rs->Close();
      +					$authdb->Close();
      +					return true;
      +				} else {
      +					$rs->Close();
      +					$authdb->Close();
      +					return false;
      +				}
       			}
       		}
       	}
      @@ -779,4 +807,38 @@
       			$text = str_replace("'", "''", $text);
       		}
       		return $text;
       	}
      +
      +	function bcrypt_hash($password, $work_factor = 8) {
      +		if (version_compare(PHP_VERSION, '5.3') < 0) throw new Exception('Bcrypt requires PHP 5.3 or above');
      +
      +		if (! function_exists('openssl_random_pseudo_bytes')) {
      +			throw new Exception('Bcrypt requires openssl PHP extension');
      +		}
      +
      +		if ($work_factor < 4 || $work_factor > 31) $work_factor = 8;
      +		$salt =
      +			'$2a$' . str_pad($work_factor, 2, '0', STR_PAD_LEFT) . '$' .
      +			substr(
      +				strtr(base64_encode(openssl_random_pseudo_bytes(16)), '+', '.'),
      +				0, 22
      +			)
      +		;
      +		return crypt($password, $salt);
      +	}
      +
      +	function bcrypt_check($password, $stored_hash, $legacy_handler = NULL) {
      +		if (version_compare(PHP_VERSION, '5.3') < 0) throw new Exception('Bcrypt requires PHP 5.3 or above');
      +
      +		if ($this->bcrypt_is_legacy_hash($stored_hash)) {
      +			if ($legacy_handler) return call_user_func($legacy_handler, $password, $stored_hash);
      +			else throw new Exception('Unsupported hash format');
      +		}
      +
      +		return crypt($password, $stored_hash) == $stored_hash;
      +	}
      +
      +	function bcrypt_is_legacy_hash($hash) { return substr($hash, 0, 4) != '$2a$'; }
      +}
      +
      +
      diff -Naur standardmoodle/auth/db/config.html mymoodle/auth/db/config.html
      --- standardmoodle/auth/db/config.html	2013-11-05 10:52:17.099018082 +0100
      +++ mymoodle/auth/db/config.html	2013-11-05 10:38:47.623004107 +0100
      @@ -192,6 +192,11 @@
               $passtype["md5"]       = get_string("md5", "auth");
               $passtype["sha1"]      = get_string("sha1", "auth");
               $passtype["internal"]  = get_string("internal", "auth");
      +
      +        if (version_compare(PHP_VERSION, '5.3') > 0) {
      +            $passtype["bcrypt"]     = get_string("bcrypt", "auth");
      +        }
      +
               echo html_writer::select($passtype, "passtype", $config->passtype, false);
       
               ?>
      diff -Naur standardmoodle/lang/en/auth.php mymoodle/lang/en/auth.php
      --- standardmoodle/lang/en/auth.php	2013-11-05 10:51:39.334830820 +0100
      +++ mymoodle/lang/en/auth.php	2013-11-05 10:42:20.028057367 +0100
      @@ -59,6 +59,7 @@
       $string['auth_user_creation'] = 'New (anonymous) users can create user accounts on the external authentication source and confirmed via email. If you enable this , remember to also configure module-specific options for user creation.';
       $string['auth_usernameexists'] = 'Selected username already exists. Please choose a new one.';
       $string['auto_add_remote_users'] = 'Auto add remote users';
      +$string['bcrypt'] = 'Bcrypt';
       $string['createpasswordifneeded'] = 'Create password if needed';
       $string['emailchangecancel'] = 'Cancel email change';
       $string['emailchangepending'] = 'Change pending. Open the link sent to you at {$a->preference_newemail}.';
      

        Attachments

          Issue Links

            Activity

              People

              • Votes:
                1 Vote for this issue
                Watchers:
                7 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: