Auth_SASL_DigestMD5 Class Reference

Inheritance diagram for Auth_SASL_DigestMD5:

Inheritance graph
[legend]
Collaboration diagram for Auth_SASL_DigestMD5:

Collaboration graph
[legend]
List of all members.

Public Member Functions

 getResponse ($authcid, $pass, $challenge, $hostname, $service, $authzid= '')
 _parseChallenge ($challenge)
 _getResponseValue ($authcid, $pass, $realm, $nonce, $cnonce, $digest_uri, $authzid= '')
 _getCnonce ()
 _HMAC_MD5 ($key, $data)

Detailed Description

Definition at line 48 of file DigestMD5.php.


Member Function Documentation

Auth_SASL_DigestMD5::_getCnonce  ) 
 

Creates the client nonce for the response

Returns:
string The cnonce value private

Definition at line 175 of file DigestMD5.php.

Referenced by getResponse().

00176     {
00177         if (file_exists('/dev/urandom')) {
00178             return base64_encode(fread(fopen('/dev/urandom', 'r'), 32));
00179 
00180         } elseif (file_exists('/dev/random')) {
00181             return base64_encode(fread(fopen('/dev/random', 'r'), 32));
00182 
00183         } else {
00184             $str = '';
00185             mt_srand((double)microtime()*10000000);
00186             for ($i=0; $i<32; $i++) {
00187                 $str .= chr(mt_rand(0, 255));
00188             }
00189             
00190             return base64_encode($str);
00191         }
00192     }

Auth_SASL_DigestMD5::_getResponseValue authcid,
pass,
realm,
nonce,
cnonce,
digest_uri,
authzid = ''
 

Creates the response= part of the digest response

Parameters:
string $authcid Authentication id (username)
string $pass Password
string $realm Realm as provided by the server
string $nonce Nonce as provided by the server
string $cnonce Client nonce
string $digest_uri The digest-uri= value part of the response
string $authzid Authorization id
Returns:
string The response= part of the digest response private

Definition at line 158 of file DigestMD5.php.

Referenced by getResponse().

00159     {
00160         if ($authzid == '') {
00161             $A1 = sprintf('%s:%s:%s', pack('H32', md5(sprintf('%s:%s:%s', $authcid, $realm, $pass))), $nonce, $cnonce);
00162         } else {
00163             $A1 = sprintf('%s:%s:%s:%s', pack('H32', md5(sprintf('%s:%s:%s', $authcid, $realm, $pass))), $nonce, $cnonce, $authzid);
00164         }
00165         $A2 = 'AUTHENTICATE:' . $digest_uri;
00166         return md5(sprintf('%s:%s:00000001:%s:auth:%s', md5($A1), $nonce, $cnonce, md5($A2)));
00167     }

Auth_SASL_Common::_HMAC_MD5 key,
data
[inherited]
 

Function which implements HMAC MD5 digest

Parameters:
string $key The secret key
string $data The data to protect
Returns:
string The HMAC MD5 digest

Definition at line 55 of file Common.php.

Referenced by Auth_SASL_CramMD5::getResponse().

00056     {
00057         if (strlen($key) > 64) {
00058             $key = pack('H32', md5($key));
00059         }
00060 
00061         if (strlen($key) < 64) {
00062             $key = str_pad($key, 64, chr(0));
00063         }
00064 
00065         $k_ipad = substr($key, 0, 64) ^ str_repeat(chr(0x36), 64);
00066         $k_opad = substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64);
00067 
00068         $inner  = pack('H32', md5($k_ipad . $data));
00069         $digest = md5($k_opad . $inner);
00070 
00071         return $digest;
00072     }

Auth_SASL_DigestMD5::_parseChallenge challenge  ) 
 

Parses and verifies the digest challenge*

Parameters:
string $challenge The digest challenge
Returns:
array The parsed challenge as an assoc array in the form "directive => value". private
Defaults and required directives

Definition at line 91 of file DigestMD5.php.

Referenced by getResponse().

00092     {
00093         $tokens = array();
00094         while (preg_match('/^([a-z-]+)=("[^"]+(?<!\\\)"|[^,]+)/i', $challenge, $matches)) {
00095 
00096             // Ignore these as per rfc2831
00097             if ($matches[1] == 'opaque' OR $matches[1] == 'domain') {
00098                 $challenge = substr($challenge, strlen($matches[0]) + 1);
00099                 continue;
00100             }
00101 
00102             // Allowed multiple "realm" and "auth-param"
00103             if (!empty($tokens[$matches[1]]) AND ($matches[1] == 'realm' OR $matches[1] == 'auth-param')) {
00104                 if (is_array($tokens[$matches[1]])) {
00105                     $tokens[$matches[1]][] = preg_replace('/^"(.*)"$/', '\\1', $matches[2]);
00106                 } else {
00107                     $tokens[$matches[1]] = array($tokens[$matches[1]], preg_replace('/^"(.*)"$/', '\\1', $matches[2]));
00108                 }
00109 
00110             // Any other multiple instance = failure
00111             } elseif (!empty($tokens[$matches[1]])) {
00112                 $tokens = array();
00113                 break;
00114 
00115             } else {
00116                 $tokens[$matches[1]] = preg_replace('/^"(.*)"$/', '\\1', $matches[2]);
00117             }
00118 
00119             // Remove the just parsed directive from the challenge
00120             $challenge = substr($challenge, strlen($matches[0]) + 1);
00121         }
00122 
00126         // Realm
00127         if (empty($tokens['realm'])) {
00128             $uname = posix_uname();
00129             $tokens['realm'] = $uname['nodename'];
00130         }
00131         
00132         // Maxbuf
00133         if (empty($tokens['maxbuf'])) {
00134             $tokens['maxbuf'] = 65536;
00135         }
00136         
00137         // Required: nonce, algorithm
00138         if (empty($tokens['nonce']) OR empty($tokens['algorithm'])) {
00139             return array();
00140         }
00141         
00142         return $tokens;
00143     }

Auth_SASL_DigestMD5::getResponse authcid,
pass,
challenge,
hostname,
service,
authzid = ''
 

Provides the (main) client response for DIGEST-MD5 requires a few extra parameters than the other mechanisms, which are unavoidable.

Parameters:
string $authcid Authentication id (username)
string $pass Password
string $challenge The digest challenge sent by the server
string $hostname The hostname of the machine you're connecting to
string $service The servicename (eg. imap, pop, acap etc)
string $authzid Authorization id (username to proxy as)
Returns:
string The digest response (NOT base64 encoded) public

Definition at line 64 of file DigestMD5.php.

References _getCnonce(), _getResponseValue(), _parseChallenge(), and PEAR::raiseError().

00065     {
00066         $challenge = $this->_parseChallenge($challenge);
00067         $authzid_string = '';
00068         if ($authzid != '') {
00069             $authzid_string = ',authzid="' . $authzid . '"'; 
00070         }
00071 
00072         if (!empty($challenge)) {
00073             $cnonce         = $this->_getCnonce();
00074             $digest_uri     = sprintf('%s/%s', $service, $hostname);
00075             $response_value = $this->_getResponseValue($authcid, $pass, $challenge['realm'], $challenge['nonce'], $cnonce, $digest_uri, $authzid);
00076 
00077             return sprintf('username="%s",realm="%s"' . $authzid_string  . ',nonce="%s",cnonce="%s",nc="00000001",qop=auth,digest-uri="%s",response=%s,%d', $authcid, $challenge['realm'], $challenge['nonce'], $cnonce, $digest_uri, $response_value, $challenge['maxbuf']);
00078         } else {
00079             return PEAR::raiseError('Invalid digest challenge');
00080         }
00081     }


The documentation for this class was generated from the following file:
Generated on Fri Mar 17 14:50:35 2006 for CRE Loaded 6.2 Pro by  doxygen 1.4.4