/** * Attempt to log in using the given username and password. * * On a successful login, this function should return the username as 'uid' attribute, * and merged attributes from the configuration file. * On failure, it should throw an exception. A SimpleSAML_Error_Error('WRONGUSERPASS') * should be thrown in case of a wrong username OR a wrong password, to prevent the * enumeration of usernames. * * @param string $username The username the user wrote. * @param string $password The password the user wrote. * @return array Associative array with the users attributes. */ protected function login($username, $password) { assert('is_string($username)'); assert('is_string($password)'); foreach ($this->users as $userpass) { $matches = explode(':', $userpass, 2); if ($matches[0] == $username) { $crypted = $matches[1]; // This is about the only attribute we can add $attributes = array_merge(array('uid' => array($username)), $this->attributes); // Traditional crypt(3) if (crypt($password, $crypted) == $crypted) { SimpleSAML_Logger::debug('User ' . $username . ' authenticated successfully'); return $attributes; } // Apache's custom MD5 if (APR1_MD5::check($crypted, $password)) { SimpleSAML_Logger::debug('User ' . $username . ' authenticated successfully'); return $attributes; } // SHA1 or plain-text if (SimpleSAML\Utils\Crypto::pwValid($crypted, $password)) { SimpleSAML_Logger::debug('User ' . $username . ' authenticated successfully'); return $attributes; } throw new SimpleSAML_Error_Error('WRONGUSERPASS'); } } throw new SimpleSAML_Error_Error('WRONGUSERPASS'); }
/** * Middleware callback used to check the HTTP authentication is OK. * Credentials are read from file named auth.htpasswd in the root directory. * It is not intended that you call this function yourself. * * @throws \SameAsLite\AuthException An exception is thrown if the credentials file cannot be opened */ public function callbackCheckAuth() { // do we have credentials to validate? $authorized = false; if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) { // parse the auth.htpasswd file for username/password $filename = dirname($_SERVER['DOCUMENT_ROOT'] . $_SERVER['PHP_SELF']) . '/auth.htpasswd'; $credentials = @file($filename, FILE_SKIP_EMPTY_LINES | FILE_IGNORE_NEW_LINES); if ($credentials === false || count($credentials) === 0) { // auth.htpasswd could not be loaded throw new Exception\AuthException('Failed to load valid authorization credentials from ' . $filename); } foreach ($credentials as $line) { $line = trim($line); if ($line === '' || strpos($line, ':') === false) { continue; } list($u, $p) = explode(':', $line, 2); // salt check if (strpos($p, '$') === false) { // no salt present in password // password must be invalid continue; } // Check plaintext password against an APR1-MD5 hash // TODO: get rid of the WhiteHat101 package if (true === \WhiteHat101\Crypt\APR1_MD5::check($_SERVER['PHP_AUTH_PW'], $p)) { $authorized = true; break; } } } // missing or invalid credentials if (!$authorized) { $this->outputError401(); } }
public function testSaltRamdomness() { $this->assertNotEquals(APR1_MD5::salt(), APR1_MD5::salt()); }
public function testHash_null_nullSalt() { $hash = APR1_MD5::hash(null); $this->assertEquals(37, strlen($hash)); }
public function testHash_ChangeMe1() { $this->assertTrue(APR1_MD5::check('ChangeMe1', '$apr1$PVWlTz/5$SNkIVyogockgH65nMLn.W1')); }