diff --git a/java/org/apache/catalina/authenticator/DigestAuthenticator.java b/java/org/apache/catalina/authenticator/DigestAuthenticator.java index 92e660e..9728b53 100644 --- a/java/org/apache/catalina/authenticator/DigestAuthenticator.java +++ b/java/org/apache/catalina/authenticator/DigestAuthenticator.java @@ -26,6 +26,8 @@ import java.security.Principal; import java.util.LinkedHashMap; import java.util.Map; import java.util.StringTokenizer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -55,6 +57,10 @@ public class DigestAuthenticator extends AuthenticatorBase { private static final Log log = LogFactory.getLog(DigestAuthenticator.class); + /** Pattern for parsing tokens in Authorization header. + * + */ + private static final Pattern TOKEN_PATTERN = Pattern.compile("\\s*([a-zA-Z]+)\\s*=\\s*((?:[^\", ]+)|(?:\"(?:[^\"\\\\]|(?:\\\\.))*\"))\\s*,?"); // -------------------------------------------------------------- Constants @@ -357,7 +363,21 @@ public class DigestAuthenticator extends AuthenticatorBase { !quotesRequired) { return quotedString; } else if (quotedString.length() > 2) { - return quotedString.substring(1, quotedString.length() - 1); + String string = quotedString.substring(1, quotedString.length() - 1); + if (string.indexOf('\\') != -1) { + // The string contains quoted characters + StringBuilder buffer = new StringBuilder(string); + int pos = 0; + while (pos < buffer.length()) { + int index = buffer.indexOf("\\", pos); + if (index == -1) + break; + buffer.deleteCharAt(index); + pos = index+1; + } + string = buffer.toString(); + } + return string; } else { return ""; } @@ -543,24 +563,18 @@ public class DigestAuthenticator extends AuthenticatorBase { } authorization = authorization.substring(7).trim(); - // Bugzilla 37132: http://issues.apache.org/bugzilla/show_bug.cgi?id=37132 - String[] tokens = authorization.split(",(?=(?:[^\"]*\"[^\"]*\")+$)"); - method = request.getMethod(); - for (int i = 0; i < tokens.length; i++) { - String currentToken = tokens[i]; - if (currentToken.length() == 0) - continue; - - int equalSign = currentToken.indexOf('='); - if (equalSign < 0) { + Matcher matcher = TOKEN_PATTERN.matcher(authorization); + while (matcher.regionStart() < authorization.length()) { + if (!matcher.lookingAt()) { + // have unmatched text + log.warn("Unmatched text in Authorization: "+authorization.substring(matcher.regionStart())); return false; } - String currentTokenName = - currentToken.substring(0, equalSign).trim(); - String currentTokenValue = - currentToken.substring(equalSign + 1).trim(); + String currentTokenName = matcher.group(1); + String currentTokenValue = matcher.group(2); + matcher.region(matcher.end(), authorization.length()); if ("username".equals(currentTokenName)) userName = removeQuotes(currentTokenValue); if ("realm".equals(currentTokenName))