- if (!defined($ref->{'digest_ha1_hex'}) || $ref->{'digest_ha1_hex'} !~ /^[0-9a-f]{32}$/) {
- # A user that exists but has empty HA1 is a user that's not
- # ready for digest auth, so we hack it and resend 401,
- # only this time without digest auth.
- output_401($r, DigestAuth => 0);
- return undef;
- }
- my $ha1 = $ref->{'digest_ha1_hex'};
- my $ha2 = Digest::MD5::md5_hex($r->method . ':' . $auth{'uri'});
- my $response;
- if (exists($auth{'qop'}) && $auth{'qop'} eq 'auth') {
- unless (exists($auth{'nc'}) && exists($auth{'cnonce'})) {
- output_401($r);
- return undef;
- }
-
- $response = $ha1;
- $response .= ':' . $auth{'nonce'};
- $response .= ':' . $auth{'nc'};
- $response .= ':' . $auth{'cnonce'};
- $response .= ':' . $auth{'qop'};
- $response .= ':' . $ha2;
- } else {
- $response = $ha1;
- $response .= ':' . $auth{'nonce'};
- $response .= ':' . $ha2;
- }
- if ($auth{'response'} ne Digest::MD5::md5_hex($response)) {
- output_401($r);
- return undef;
- }
-
- # OK, everything is good, and there's only one thing we need to check: That the nonce
- # isn't too old. If it is, but everything else is ok, we tell the browser that and it
- # will re-encrypt with the new nonce.
- my $timediff = time - $auth{'opaque'};
- if ($timediff < 0 || $timediff > 300) {
- output_401($r, StaleNonce => 1);
- return undef;
- }
-
- return ($user, $takenby);