/** * Authenticate a user * * @param string user * @param string pass * @return bool * @throws security.auth.AuthenticatorException */ public function authenticate($user, $pass) { if (!($crypt = $this->lookup($user))) { return FALSE; } return UnixCrypt::matches($crypt, $pass); }
/** * Authenticate a user * * @param string user * @param string pass * @return bool */ public function authenticate($user, $pass) { try { $r = $this->lc->search($this->basedn, '(uid=' . $user . ')'); } catch (LDAPException $e) { throw new AuthenticatorException(sprintf('Authentication failed (#%d: "%s")', $e->getErrorCode(), $e->getMessage()), $e); } catch (ConnectException $e) { throw new AuthenticatorException(sprintf('Authentication failed (<connect>: "%s")', $e->getMessage()), $e); } // Check return, we must find a distinct user if (1 != $r->numEntries()) { return FALSE; } $entry = $r->getNextEntry(); return UnixCrypt::matches($entry->getAttribute('userpassword', 0), $pass); }
static function __static() { $builtin = version_compare(PHP_VERSION, '5.3.0', 'ge'); if (!CRYPT_STD_DES) { self::$STANDARD = new CryptNotImplemented('STD_DES'); } else { self::$STANDARD = new NativeCryptImpl(); // Before 5.3.2, PHP's crypt() function returned incorrect values // when given salt characters outside of the alphabet "./0-9A-Za-z". // No real workaround, so throw an exception - this is inconsistent // with XP on newer PHP versions which yields the correct results. // On systems >= 5.3.2, check for usage of libc crypt() which also // allows salts which are too short and unsafe characters \n and : if (version_compare(PHP_VERSION, '5.3.2', 'lt')) { self::$STANDARD = newinstance('security.crypto.NativeCryptImpl', array(), '{ public function crypt($plain, $salt) { if (!preg_match("#^[./0-9A-Za-z]{2}#", $salt)) { throw new CryptoException("Malformed salt"); } return parent::crypt($plain, $salt); } public function toString() { return "security.crypto.NativeCryptImpl+std:salt-alphabet-constraint"; } }'); } else { if (':' === substr(crypt('', ':'), 0, 1)) { self::$STANDARD = newinstance('security.crypto.NativeCryptImpl', array(), '{ public function crypt($plain, $salt) { if (strlen($salt) < 1 || strcspn($salt, "\\n:") < 2) { throw new CryptoException("Malformed salt"); } return parent::crypt($plain, $salt); } public function toString() { return "security.crypto.NativeCryptImpl+std:salt-unsafe-check"; } }'); } } } if (!CRYPT_BLOWFISH) { self::$BLOWFISH = new CryptNotImplemented('BLOWFISH'); } else { self::$BLOWFISH = new NativeCryptImpl(); // The blowfish method has a bug between PHP 5.3.0 and 5.3.2 which // returns a bogus result instead of failing when the cost parameter // is incorrect. For *any* builtin implementation, recognition is // broken as the "__" in "$2a$__$" for example makes PHP not jump // into the blowfish branch but fall back to the else branch, and thus // to standard DES. See line 247 and following in ext/standard/crypt.c if ($builtin) { self::$BLOWFISH = newinstance('security.crypto.NativeCryptImpl', array(), '{ public function crypt($plain, $salt) { if (1 !== sscanf($salt, "$2a$%02d$", $cost)) { throw new CryptoException("Malformed cost parameter"); } if ($cost < 4 || $cost > 31) { throw new CryptoException("Cost parameter must be between 04 and 31"); } return parent::crypt($plain, $salt); } public function toString() { return "security.crypto.NativeCryptImpl+blowfish:cost-param-check"; } }'); } } if (!CRYPT_EXT_DES) { self::$EXTENDED = new CryptNotImplemented('EXT_DES'); } else { // PHP's crypt() function crashes if the salt is too short due to PHP // using its own DES implementations as 5.3 - these don't check the // return value correctly. See Bug #51059, which was fixed in PHP 5.3.2 // Debian only recognizes EXT_DES if the salt is 9 characters long, see // notes in PHP Bug #51254. As there is no reliable way to detect whether // the patch (referenced in this bug) is applied, always use the check // and strip off rest of crypted when matching. self::$EXTENDED = newinstance('security.crypto.NativeCryptImpl', array(), '{ public function crypt($plain, $salt) { if (strlen($salt) < 9) { throw new CryptoException("Extended DES: Salt too short"); } return parent::crypt($plain, $salt); } public function matches($encrypted, $entered) { return ($encrypted === $this->crypt($entered, substr($encrypted, 0, 9))); } public function toString() { return "security.crypto.NativeCryptImpl+ext:recognition-fix"; } }'); } if (!CRYPT_MD5) { self::$MD5 = XPClass::forName('security.crypto.MD5CryptImpl')->newInstance(); } else { self::$MD5 = new NativeCryptImpl(); // In PHP version between 5.3.0 and 5.3.5, this fails for situations when // the salt is too short, too long or does not end with "$". 5.3.6 only // breaks when the salt is too short. 5.3.7 is the first version to get it // right, except: In PHP Bug #55439, crypt() returns just the salt for MD5 // on Un*x systems. This bug first occurred in PHP 5.3.7 RC6 and was shipped // with PHP 5.3.7, and fixed in the release thereafter. if ($builtin && version_compare(PHP_VERSION, '5.3.7', 'lt')) { self::$MD5 = XPClass::forName('security.crypto.MD5CryptImpl')->newInstance(); } else { if (0 === strpos(PHP_VERSION, '5.3.7')) { if ('$1$' === crypt('', '$1$')) { self::$MD5 = XPClass::forName('security.crypto.MD5CryptImpl')->newInstance(); } } } } self::$DEFAULT = self::$MD5; }