Created
August 14, 2014 19:41
-
-
Save gabrysiak/ecc4999fc7a8869d7421 to your computer and use it in GitHub Desktop.
PHP - Digest Auth
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function getDigest() { | |
// mod_php | |
if (isset($_SERVER['PHP_AUTH_DIGEST'])) { | |
$digest = $_SERVER['PHP_AUTH_DIGEST']; | |
// most other servers | |
} elseif (isset($_SERVER['HTTP_AUTHENTICATION'])) { | |
if (strpos(strtolower($_SERVER['HTTP_AUTHENTICATION']),'digest')===0) | |
$digest = substr($_SERVER['HTTP_AUTHORIZATION'], 7); | |
} | |
if( !isset($digest) ) return false; | |
return $digest; | |
} | |
// This function forces a login prompt | |
function requireLogin($realm,$nonce) { | |
header('WWW-Authenticate: Digest realm="' . $realm . '",qop="auth",nonce="' . $nonce . '",opaque="' . md5($realm) . '"'); | |
header('HTTP/1.0 401 Unauthorized'); | |
echo 'Text to send if user hits Cancel button'; | |
die(); | |
} | |
// This function extracts the separate values from the digest string | |
function digestParse($digest) { | |
// protect against missing data | |
$needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1); | |
$data = array(); | |
preg_match_all('@(\w+)=(?:(?:")([^"]+)"|([^\s,$]+))@', $digest, $matches, PREG_SET_ORDER); | |
foreach ($matches as $m) { | |
$data[$m[1]] = $m[2] ? $m[2] : $m[3]; | |
unset($needed_parts[$m[1]]); | |
} | |
return $needed_parts ? false : $data; | |
} | |
$realm = 'The batcave'; | |
// Just a random id | |
$nonce = uniqid(); | |
// Get the digest from the http header | |
$digest = getDigest(); | |
// If there was no digest, show login | |
if (!$digest) requireLogin($realm,$nonce); | |
$digestParts = digestParse($digest); | |
$validUser = 'admin'; | |
$validPass = '1234'; | |
// Based on all the info we gathered we can figure out what the response should be | |
$A1 = md5("{$validUser}:{$realm}:{$validPass}"); | |
$A2 = md5("{$_SERVER['REQUEST_METHOD']}:{$digestParts['uri']}"); | |
$validResponse = md5("{$A1}:{$digestParts['nonce']}:{$digestParts['nc']}:{$digestParts['cnonce']}:{$digestParts['qop']}:{$A2}"); | |
if ($digestParts['response']!=$validResponse) requireLogin($realm,$nonce); | |
// We're in! | |
echo 'Well done sir, you made it all the way through the login!'; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment