/**
  * 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');
 }
Exemple #2
0
 /**
  * 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'));
 }