diff --git a/cake/libs/http/digest_authentication.php b/cake/libs/http/digest_authentication.php index b25c6c971..ba146e2fc 100644 --- a/cake/libs/http/digest_authentication.php +++ b/cake/libs/http/digest_authentication.php @@ -30,16 +30,17 @@ class DigestAuthentication { * Authentication * * @param HttpSocket $http + * @param array $authInfo * @return void * @throws Exception * @link http://www.ietf.org/rfc/rfc2617.txt */ - public static function authentication(HttpSocket $http) { - if (isset($http->request['auth']['user'], $http->request['auth']['pass'])) { - if (!isset($http->config['request']['auth']['realm']) && !self::_getServerInformation($http)) { + public static function authentication(HttpSocket $http, &$authInfo) { + if (isset($authInfo['user'], $authInfo['pass'])) { + if (!isset($authInfo['realm']) && !self::_getServerInformation($http, $authInfo)) { return; } - $http->request['header']['Authorization'] = self::_generateHeader($http); + $http->request['header']['Authorization'] = self::_generateHeader($http, $authInfo); } } @@ -47,23 +48,25 @@ class DigestAuthentication { * Retrive information about the authetication * * @param HttpSocket $http + * @parma array $authInfo * @return boolean */ - protected static function _getServerInformation(HttpSocket $http) { + protected static function _getServerInformation(HttpSocket $http, &$authInfo) { $originalRequest = $http->request; - $http->request['auth'] = array('method' => false); + $http->setAuthConfig(false); $http->request($http->request); $http->request = $originalRequest; + $http->setAuthConfig('Digest', $authInfo); if (empty($http->response['header']['WWW-Authenticate'])) { return false; } preg_match_all('@(\w+)=(?:(?:")([^"]+)"|([^\s,$]+))@', $http->response['header']['WWW-Authenticate'], $matches, PREG_SET_ORDER); foreach ($matches as $match) { - $http->config['request']['auth'][$match[1]] = $match[2]; + $authInfo[$match[1]] = $match[2]; } - if (!empty($http->config['request']['auth']['qop']) && empty($http->config['request']['auth']['nc'])) { - $http->config['request']['auth']['nc'] = 1; + if (!empty($authInfo['qop']) && empty($authInfo['nc'])) { + $authInfo['nc'] = 1; } return true; } @@ -72,31 +75,32 @@ class DigestAuthentication { * Generate the header Authorization * * @param HttpSocket $http + * @param array $authInfo * @return string */ - protected static function _generateHeader(HttpSocket $http) { - $a1 = md5($http->request['auth']['user'] . ':' . $http->config['request']['auth']['realm'] . ':' . $http->request['auth']['pass']); + protected static function _generateHeader(HttpSocket $http, &$authInfo) { + $a1 = md5($authInfo['user'] . ':' . $authInfo['realm'] . ':' . $authInfo['pass']); $a2 = md5($http->request['method'] . ':' . $http->request['uri']['path']); - if (empty($http->config['request']['auth']['qop'])) { - $response = md5($a1 . ':' . $http->config['request']['auth']['nonce'] . ':' . $a2); + if (empty($authInfo['qop'])) { + $response = md5($a1 . ':' . $authInfo['nonce'] . ':' . $a2); } else { - $http->config['request']['auth']['cnonce'] = uniqid(); - $nc = sprintf('%08x', $http->config['request']['auth']['nc']++); - $response = md5($a1 . ':' . $http->config['request']['auth']['nonce'] . ':' . $nc . ':' . $http->config['request']['auth']['cnonce'] . ':auth:' . $a2); + $authInfo['cnonce'] = uniqid(); + $nc = sprintf('%08x', $authInfo['nc']++); + $response = md5($a1 . ':' . $authInfo['nonce'] . ':' . $nc . ':' . $authInfo['cnonce'] . ':auth:' . $a2); } $authHeader = 'Digest '; - $authHeader .= 'username="' . str_replace(array('\\', '"'), array('\\\\', '\\"'), $http->request['auth']['user']) . '", '; - $authHeader .= 'realm="' . $http->config['request']['auth']['realm'] . '", '; - $authHeader .= 'nonce="' . $http->config['request']['auth']['nonce'] . '", '; + $authHeader .= 'username="' . str_replace(array('\\', '"'), array('\\\\', '\\"'), $authInfo['user']) . '", '; + $authHeader .= 'realm="' . $authInfo['realm'] . '", '; + $authHeader .= 'nonce="' . $authInfo['nonce'] . '", '; $authHeader .= 'uri="' . $http->request['uri']['path'] . '", '; $authHeader .= 'response="' . $response . '"'; - if (!empty($http->config['request']['auth']['opaque'])) { - $authHeader .= ', opaque="' . $http->config['request']['auth']['opaque'] . '"'; + if (!empty($authInfo['opaque'])) { + $authHeader .= ', opaque="' . $authInfo['opaque'] . '"'; } - if (!empty($http->config['request']['auth']['qop'])) { - $authHeader .= ', qop="auth", nc=' . $nc . ', cnonce="' . $http->config['request']['auth']['cnonce'] . '"'; + if (!empty($authInfo['qop'])) { + $authHeader .= ', qop="auth", nc=' . $nc . ', cnonce="' . $authInfo['cnonce'] . '"'; } return $authHeader; } diff --git a/cake/tests/cases/libs/http/digest_authentication.test.php b/cake/tests/cases/libs/http/digest_authentication.test.php index 75e98595e..2166aee24 100644 --- a/cake/tests/cases/libs/http/digest_authentication.test.php +++ b/cake/tests/cases/libs/http/digest_authentication.test.php @@ -72,11 +72,6 @@ class DigestAuthenticationTest extends CakeTestCase { $this->HttpSocket = new DigestHttpSocket(); $this->HttpSocket->request['method'] = 'GET'; $this->HttpSocket->request['uri']['path'] = '/'; - $this->HttpSocket->request['auth'] = array( - 'method' => 'Digest', - 'user' => 'admin', - 'pass' => '1234' - ); } /** @@ -95,12 +90,13 @@ class DigestAuthenticationTest extends CakeTestCase { */ public function testBasic() { $this->HttpSocket->nextHeader = 'Digest realm="The batcave",nonce="4cded326c6c51"'; - $this->HttpSocket->config['request']['auth'] = array(); $this->assertFalse(isset($this->HttpSocket->request['header']['Authorization'])); - DigestAuthentication::authentication($this->HttpSocket); + + $auth = array('user' => 'admin', 'pass' => '1234'); + DigestAuthentication::authentication($this->HttpSocket, $auth); $this->assertTrue(isset($this->HttpSocket->request['header']['Authorization'])); - $this->assertEqual($this->HttpSocket->config['request']['auth']['realm'], 'The batcave'); - $this->assertEqual($this->HttpSocket->config['request']['auth']['nonce'], '4cded326c6c51'); + $this->assertEqual($auth['realm'], 'The batcave'); + $this->assertEqual($auth['nonce'], '4cded326c6c51'); } /** @@ -110,20 +106,20 @@ class DigestAuthenticationTest extends CakeTestCase { */ public function testQop() { $this->HttpSocket->nextHeader = 'Digest realm="The batcave",nonce="4cded326c6c51"'; - $this->HttpSocket->config['request']['auth'] = array(); - DigestAuthentication::authentication($this->HttpSocket); + $auth = array('user' => 'admin', 'pass' => '1234'); + DigestAuthentication::authentication($this->HttpSocket, $auth); $expected = 'Digest username="admin", realm="The batcave", nonce="4cded326c6c51", uri="/", response="da7e2a46b471d77f70a9bb3698c8902b"'; $this->assertEqual($expected, $this->HttpSocket->request['header']['Authorization']); - $this->assertFalse(isset($this->HttpSocket->config['request']['auth']['qop'])); - $this->assertFalse(isset($this->HttpSocket->config['request']['auth']['nc'])); + $this->assertFalse(isset($auth['qop'])); + $this->assertFalse(isset($auth['nc'])); $this->HttpSocket->nextHeader = 'Digest realm="The batcave",nonce="4cded326c6c51",qop="auth"'; - $this->HttpSocket->config['request']['auth'] = array(); - DigestAuthentication::authentication($this->HttpSocket); + $auth = array('user' => 'admin', 'pass' => '1234'); + DigestAuthentication::authentication($this->HttpSocket, $auth); $expected = '@Digest username="admin", realm="The batcave", nonce="4cded326c6c51", uri="/", response="[a-z0-9]{32}", qop="auth", nc=00000001, cnonce="[a-z0-9]+"@'; $this->assertPattern($expected, $this->HttpSocket->request['header']['Authorization']); - $this->assertEqual($this->HttpSocket->config['request']['auth']['qop'], 'auth'); - $this->assertEqual($this->HttpSocket->config['request']['auth']['nc'], 2); + $this->assertEqual($auth['qop'], 'auth'); + $this->assertEqual($auth['nc'], 2); } /** @@ -133,13 +129,13 @@ class DigestAuthenticationTest extends CakeTestCase { */ public function testOpaque() { $this->HttpSocket->nextHeader = 'Digest realm="The batcave",nonce="4cded326c6c51"'; - $this->HttpSocket->config['request']['auth'] = array(); - DigestAuthentication::authentication($this->HttpSocket); + $auth = array('user' => 'admin', 'pass' => '1234'); + DigestAuthentication::authentication($this->HttpSocket, $auth); $this->assertFalse(strpos($this->HttpSocket->request['header']['Authorization'], 'opaque="d8ea7aa61a1693024c4cc3a516f49b3c"')); $this->HttpSocket->nextHeader = 'Digest realm="The batcave",nonce="4cded326c6c51",opaque="d8ea7aa61a1693024c4cc3a516f49b3c"'; - $this->HttpSocket->config['request']['auth'] = array(); - DigestAuthentication::authentication($this->HttpSocket); + $auth = array('user' => 'admin', 'pass' => '1234'); + DigestAuthentication::authentication($this->HttpSocket, $auth); $this->assertTrue(strpos($this->HttpSocket->request['header']['Authorization'], 'opaque="d8ea7aa61a1693024c4cc3a516f49b3c"') > 0); } @@ -150,21 +146,21 @@ class DigestAuthenticationTest extends CakeTestCase { */ public function testMultipleRequest() { $this->HttpSocket->nextHeader = 'Digest realm="The batcave",nonce="4cded326c6c51",qop="auth"'; - $this->HttpSocket->config['request']['auth'] = array(); - DigestAuthentication::authentication($this->HttpSocket); + $auth = array('user' => 'admin', 'pass' => '1234'); + DigestAuthentication::authentication($this->HttpSocket, $auth); $this->assertTrue(strpos($this->HttpSocket->request['header']['Authorization'], 'nc=00000001') > 0); - $this->assertEqual($this->HttpSocket->config['request']['auth']['nc'], 2); + $this->assertEqual($auth['nc'], 2); - DigestAuthentication::authentication($this->HttpSocket); + DigestAuthentication::authentication($this->HttpSocket, $auth); $this->assertTrue(strpos($this->HttpSocket->request['header']['Authorization'], 'nc=00000002') > 0); - $this->assertEqual($this->HttpSocket->config['request']['auth']['nc'], 3); + $this->assertEqual($auth['nc'], 3); $responsePos = strpos($this->HttpSocket->request['header']['Authorization'], 'response='); $response = substr($this->HttpSocket->request['header']['Authorization'], $responsePos + 10, 32); $this->HttpSocket->nextHeader = ''; - DigestAuthentication::authentication($this->HttpSocket); + DigestAuthentication::authentication($this->HttpSocket, $auth); $this->assertTrue(strpos($this->HttpSocket->request['header']['Authorization'], 'nc=00000003') > 0); - $this->assertEqual($this->HttpSocket->config['request']['auth']['nc'], 4); + $this->assertEqual($auth['nc'], 4); $responsePos = strpos($this->HttpSocket->request['header']['Authorization'], 'response='); $response2 = substr($this->HttpSocket->request['header']['Authorization'], $responsePos + 10, 32); $this->assertNotEqual($response, $response2); @@ -178,8 +174,8 @@ class DigestAuthenticationTest extends CakeTestCase { public function testPathChanged() { $this->HttpSocket->nextHeader = 'Digest realm="The batcave",nonce="4cded326c6c51"'; $this->HttpSocket->request['uri']['path'] = '/admin'; - $this->HttpSocket->config['request']['auth'] = array(); - DigestAuthentication::authentication($this->HttpSocket); + $auth = array('user' => 'admin', 'pass' => '1234'); + DigestAuthentication::authentication($this->HttpSocket, $auth); $responsePos = strpos($this->HttpSocket->request['header']['Authorization'], 'response='); $response = substr($this->HttpSocket->request['header']['Authorization'], $responsePos + 10, 32); $this->assertNotEqual($response, 'da7e2a46b471d77f70a9bb3698c8902b'); @@ -193,8 +189,8 @@ class DigestAuthenticationTest extends CakeTestCase { public function testNoDigestResponse() { $this->HttpSocket->nextHeader = false; $this->HttpSocket->request['uri']['path'] = '/admin'; - $this->HttpSocket->config['request']['auth'] = array(); - DigestAuthentication::authentication($this->HttpSocket); + $auth = array('user' => 'admin', 'pass' => '1234'); + DigestAuthentication::authentication($this->HttpSocket, $auth); $this->assertFalse(isset($this->HttpSocket->request['header']['Authorization'])); }