1 | <?php |
||
2 | /* For licensing terms, see /license.txt */ |
||
3 | /** |
||
4 | * @package chamilo.webservices |
||
5 | */ |
||
6 | $realm = 'The batcave'; |
||
7 | |||
8 | // Just a random id |
||
9 | $nonce = uniqid(); |
||
10 | |||
11 | // Get the digest from the http header |
||
12 | $digest = getDigest(); |
||
13 | |||
14 | // If there was no digest, show login |
||
15 | if (is_null($digest)) { |
||
16 | requireLogin($realm, $nonce); |
||
17 | } |
||
18 | |||
19 | $digestParts = digestParse($digest); |
||
20 | |||
21 | $validUser = 'admin'; |
||
22 | $validPass = 'admin'; |
||
23 | |||
24 | // Based on all the info we gathered we can figure out what the response should be |
||
25 | $A1 = md5("{$digestParts['username']}:{$realm}:{$validPass}"); |
||
26 | $A2 = md5("{$_SERVER['REQUEST_METHOD']}:{$digestParts['uri']}"); |
||
27 | |||
28 | $validResponse = md5("{$A1}:{$digestParts['nonce']}:{$digestParts['nc']}:{$digestParts['cnonce']}:{$digestParts['qop']}:{$A2}"); |
||
29 | |||
30 | if ($digestParts['response'] != $validResponse) { |
||
31 | requireLogin($realm, $nonce); |
||
32 | } else { |
||
33 | // We're in! |
||
34 | echo 'a7532ae474e5e66a0c16eddab02e02a7'; |
||
35 | exit(); |
||
36 | } |
||
37 | |||
38 | // This function returns the digest string |
||
39 | function getDigest() |
||
40 | { |
||
41 | // mod_php |
||
42 | if (isset($_SERVER['PHP_AUTH_DIGEST'])) { |
||
43 | $digest = $_SERVER['PHP_AUTH_DIGEST']; |
||
44 | // most other servers |
||
45 | } elseif (isset($_SERVER['HTTP_AUTHENTICATION'])) { |
||
46 | if (strpos( |
||
47 | strtolower($_SERVER['HTTP_AUTHENTICATION']), |
||
48 | 'digest' |
||
49 | ) === 0) { |
||
50 | $digest = substr($_SERVER['HTTP_AUTHORIZATION'], 7); |
||
51 | } |
||
52 | } elseif (isset($_SERVER['HTTP_WWW_AUTHENTICATE'])) { |
||
53 | $digest = $_SERVER['HTTP_WWW_AUTHENTICATE']; |
||
54 | } |
||
55 | |||
56 | return $digest; |
||
57 | } |
||
58 | |||
59 | // This function forces a login prompt |
||
60 | function requireLogin($realm, $nonce) |
||
61 | { |
||
62 | header('WWW-Authenticate: Digest realm="'.$realm.'",qop="auth",nonce="'.$nonce.'",opaque="'.md5($realm).'"'); |
||
63 | header('HTTP/1.1 401'); |
||
64 | echo 'Authentication Canceled'; |
||
65 | exit(); |
||
0 ignored issues
–
show
|
|||
66 | } |
||
67 | |||
68 | // This function extracts the separate values from the digest string |
||
69 | function digestParse($digest) |
||
70 | { |
||
71 | // protect against missing data |
||
72 | $needed_parts = ['nonce' => 1, 'nc' => 1, 'cnonce' => 1, 'qop' => 1, 'username' => 1, 'uri' => 1, 'response' => 1]; |
||
73 | $data = []; |
||
74 | |||
75 | preg_match_all('@(\w+)=(?:(?:")([^"]+)"|([^\s,$]+))@', $digest, $matches, PREG_SET_ORDER); |
||
76 | |||
77 | foreach ($matches as $m) { |
||
78 | $data[$m[1]] = $m[2] ? $m[2] : $m[3]; |
||
79 | unset($needed_parts[$m[1]]); |
||
80 | } |
||
81 | |||
82 | return $needed_parts ? false : $data; |
||
0 ignored issues
–
show
|
|||
83 | } |
||
84 |
In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.