You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2013/01/04 21:55:34 UTC
svn commit: r1429123 - in /tomcat/trunk:
java/org/apache/tomcat/util/http/parser/HttpParser.java
test/org/apache/tomcat/util/http/parser/TestAuthorizationDigest.java
Author: markt
Date: Fri Jan 4 20:55:34 2013
New Revision: 1429123
URL: http://svn.apache.org/viewvc?rev=1429123&view=rev
Log:
Make HTTP DIGEST authentication header parsing tolerant of known buggy clients.
Modified:
tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java
tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestAuthorizationDigest.java
Modified: tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java?rev=1429123&r1=1429122&r2=1429123&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/http/parser/HttpParser.java Fri Jan 4 20:55:34 2013
@@ -48,6 +48,7 @@ public class HttpParser {
private static final Integer FIELD_TYPE_TOKEN_OR_QUOTED_STRING = Integer.valueOf(2);
private static final Integer FIELD_TYPE_LHEX = Integer.valueOf(3);
private static final Integer FIELD_TYPE_QUOTED_LHEX = Integer.valueOf(4);
+ private static final Integer FIELD_TYPE_QUOTED_TOKEN = Integer.valueOf(5);
private static final Map<String,Integer> fieldTypes = new HashMap<>();
@@ -64,7 +65,7 @@ public class HttpParser {
fieldTypes.put("algorithm", FIELD_TYPE_TOKEN);
fieldTypes.put("cnonce", FIELD_TYPE_QUOTED_STRING);
fieldTypes.put("opaque", FIELD_TYPE_QUOTED_STRING);
- fieldTypes.put("qop", FIELD_TYPE_TOKEN);
+ fieldTypes.put("qop", FIELD_TYPE_QUOTED_TOKEN);
fieldTypes.put("nc", FIELD_TYPE_LHEX);
// Setup the flag arrays
@@ -148,6 +149,10 @@ public class HttpParser {
// FIELD_TYPE_QUOTED_LHEX
value = readQuotedLhex(input);
break;
+ case 5:
+ // FIELD_TYPE_QUOTED_TOKEN
+ value = readQuotedToken(input);
+ break;
default:
// Error
throw new IllegalArgumentException(
@@ -346,6 +351,58 @@ public class HttpParser {
}
/**
+ * This is not defined in any RFC. It is a special case to handle data from
+ * buggy clients (known buggy clients include Microsoft IE 8 & 9, Apple
+ * Safari for OSX and iOS) that add quotes to values that should be tokens.
+ *
+ * @return the token if one was found, null if data other than a token or
+ * quoted token was found or null if the end of data was reached
+ * before a quoted token was terminated
+ */
+ private static String readQuotedToken(StringReader input)
+ throws IOException {
+
+ StringBuilder result = new StringBuilder();
+ boolean quoted = false;
+
+ int c = input.read();
+
+ // Skip lws
+ while (c == 32 || c == 9) {
+ c = input.read();
+ }
+
+ if (c == '"') {
+ quoted = true;
+ } else if (c == -1) {
+ return null;
+ } else {
+ result.append((char) c);
+ }
+ c = input.read();
+
+ while (c != -1 && isToken[c]) {
+ result.append((char) c);
+ c = input.read();
+ }
+
+ if (quoted) {
+ if (c != '"') {
+ return null;
+ }
+ } else {
+ // Skip back so non-token character is available for next read
+ input.skip(-1);
+ }
+
+ if (c != -1 && result.length() == 0) {
+ return null;
+ } else {
+ return result.toString();
+ }
+ }
+
+ /**
* Parses lower case hex but permits upper case hex to be used (converting
* it to lower case before returning).
*
Modified: tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestAuthorizationDigest.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestAuthorizationDigest.java?rev=1429123&r1=1429122&r2=1429123&view=diff
==============================================================================
--- tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestAuthorizationDigest.java (original)
+++ tomcat/trunk/test/org/apache/tomcat/util/http/parser/TestAuthorizationDigest.java Fri Jan 4 20:55:34 2013
@@ -155,4 +155,53 @@ public class TestAuthorizationDigest {
Assert.assertNull(result);
}
+ @Test
+ public void testTokenQop() throws Exception {
+ String header = "Digest qop=auth";
+
+ StringReader input = new StringReader(header);
+
+ Map<String,String> result = HttpParser.parseAuthorizationDigest(input);
+ Assert.assertEquals("auth", result.get("qop"));
+ }
+
+ @Test
+ public void testQuotedTokenQop() throws Exception {
+ String header = "Digest qop=\"auth\"";
+
+ StringReader input = new StringReader(header);
+
+ Map<String,String> result = HttpParser.parseAuthorizationDigest(input);
+ Assert.assertEquals("auth", result.get("qop"));
+ }
+
+ @Test
+ public void testNonTokenQop() throws Exception {
+ String header = "Digest qop=au{th";
+
+ StringReader input = new StringReader(header);
+
+ Map<String,String> result = HttpParser.parseAuthorizationDigest(input);
+ Assert.assertNull(result);
+ }
+
+ @Test
+ public void testQuotedNonTokenQop() throws Exception {
+ String header = "Digest qop=\"au{th\"";
+
+ StringReader input = new StringReader(header);
+
+ Map<String,String> result = HttpParser.parseAuthorizationDigest(input);
+ Assert.assertNull(result);
+ }
+
+ @Test
+ public void testUnclosedQuotedTokenQop() throws Exception {
+ String header = "Digest qop=\"auth";
+
+ StringReader input = new StringReader(header);
+
+ Map<String,String> result = HttpParser.parseAuthorizationDigest(input);
+ Assert.assertNull(result);
+ }
}
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org