/* ------------------------------------------------------------ */ private int checkNonce(String nonce, Request request) { try { byte[] n = B64Code.decode(nonce.toCharArray()); if (n.length != 24) { return -1; } long ts = 0; long sk = _nonceSecret; byte[] n2 = new byte[16]; System.arraycopy(n, 0, n2, 0, 8); for (int i = 0; i < 8; i++) { n2[8 + i] = (byte) (sk & 0xff); sk = sk >> 8; ts = (ts << 8) + (0xff & (long) n[7 - i]); } long age = request.getTimeStamp() - ts; if (Log.isDebugEnabled()) { Log.debug("age=" + age); } byte[] hash = null; try { MessageDigest md = MessageDigest.getInstance("MD5"); md.reset(); md.update(n2, 0, 16); hash = md.digest(); } catch (Exception e) { Log.warn(e); } for (int i = 0; i < 16; i++) { if (n[i + 8] != hash[i]) { return -1; } } if (_maxNonceAge > 0 && (age < 0 || age > _maxNonceAge)) { return 0; // stale } return 1; } catch (Exception e) { Log.ignore(e); } return -1; }
public Authentication validateRequest(ServletRequest req, ServletResponse res, boolean mandatory) throws ServerAuthException { if (!mandatory) { return _deferred; } HttpServletRequest request = (HttpServletRequest) req; HttpServletResponse response = (HttpServletResponse) res; String credentials = request.getHeader(HttpHeaders.AUTHORIZATION); try { boolean stale = false; if (credentials != null) { if (Log.isDebugEnabled()) { Log.debug("Credentials: " + credentials); } QuotedStringTokenizer tokenizer = new QuotedStringTokenizer(credentials, "=, ", true, false); final Digest digest = new Digest(request.getMethod()); String last = null; String name = null; while (tokenizer.hasMoreTokens()) { String tok = tokenizer.nextToken(); char c = (tok.length() == 1) ? tok.charAt(0) : '\0'; switch (c) { case '=': name = last; last = tok; break; case ',': name = null; case ' ': break; default: last = tok; if (name != null) { if ("username".equalsIgnoreCase(name)) { digest.username = tok; } else if ("realm".equalsIgnoreCase(name)) { digest.realm = tok; } else if ("nonce".equalsIgnoreCase(name)) { digest.nonce = tok; } else if ("nc".equalsIgnoreCase(name)) { digest.nc = tok; } else if ("cnonce".equalsIgnoreCase(name)) { digest.cnonce = tok; } else if ("qop".equalsIgnoreCase(name)) { digest.qop = tok; } else if ("uri".equalsIgnoreCase(name)) { digest.uri = tok; } else if ("response".equalsIgnoreCase(name)) { digest.response = tok; } break; } } } int n = checkNonce(digest.nonce, (Request) request); if (n > 0) { UserIdentity user = _loginService.login(digest.username, digest); if (user != null) { return new UserAuthentication(getAuthMethod(), user); } } else if (n == 0) { stale = true; } } if (!_deferred.isDeferred(response)) { String domain = request.getContextPath(); if (domain == null) { domain = "/"; } response.setHeader( HttpHeaders.WWW_AUTHENTICATE, "Digest realm=\"" + _loginService.getName() + "\", domain=\"" + domain + "\", nonce=\"" + newNonce((Request) request) + "\", algorithm=MD5, qop=\"auth\"" + (_useStale ? (" stale=" + stale) : "")); response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); return Authentication.SEND_CONTINUE; } return Authentication.UNAUTHENTICATED; } catch (Exception e) { throw new ServerAuthException(e); } }