* @package Mammut\Auth */ class Digest extends Base { public function __construct(iAuthClient $handler, $realm) { parent::__construct($handler, $realm); } public function isAuthenticated() { if(empty($_SERVER['PHP_AUTH_DIGEST'])) return false; $realm = $this->getRealm(); // Analysieren der Variable PHP_AUTH_DIGEST $digData = $this->parseDigest($_SERVER['PHP_AUTH_DIGEST']); if(empty($digData)) return false; $handler = $this->getHandler(); if(!($passwd = $handler->getUserSecret($digData['username']))) return false; // Erzeugen einer gültigen Antwort $A1 = md5($digData['username'] . ':' . $realm . ':' . $passwd); $A2 = md5($_SERVER['REQUEST_METHOD'] . ':' . $digData['uri']); $accessToken = md5($A1 . ':' . $digData['nonce'] . ':' . $digData['nc'] . ':' . $digData['cnonce'] . ':' . $digData['qop'] . ':' . $A2); if($digData['response'] != $accessToken) return false; return true; } public function getUser() { if(!$this->isAuthenticated()) return NULL; $digData = $this->parseDigest($_SERVER['PHP_AUTH_DIGEST']); $handler = $this->getHandler(); if($handler->getUserSecret($digData['username'])) return $digData['username']; return NULL; } public function authenticate() { if($this->isAuthenticated()) { $_SESSION['logged'] = true; return true; } $realm = $this->getRealm(); $_SESSION['http_auth_id'] = uniqid(); header('WWW-Authenticate: Digest realm="' . $realm . '",qop="auth",nonce="' . $_SESSION['http_auth_id'] . '",opaque="' . md5($realm) . '"'); header('HTTP/1.1 401 Unauthorized'); $_SESSION['logged'] = false; return false; } public function logout() { session_destroy(); session_unset($_SESSION['http_auth_id']); session_unset($_SESSION['logged']); header("Location: .", TRUE, 301); } private function parseDigest($input) { // gegen fehlende Daten schützen $digData = array(); $required = array( 'nonce' => true,'nc' => true,'cnonce' => true,'qop' => true,'username' => true, 'uri' => true,'response' => true); $key = implode('|', array_keys($required)); preg_match_all('@(' . $key . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))@', $input, $match, PREG_SET_ORDER); foreach($match as $m) { $digData[$m[1]] = $m[3] ? $m[3] : $m[4]; unset($required[$m[1]]); } return count($required) > 0 ? false : $digData; } }