summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorjochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-31 07:16:59 +0000
committerjochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-03-31 07:16:59 +0000
commit7cc9929276a9a927ef3589109717f0765239e2af (patch)
treed10cfad399b480359f6cdf517cbc65c7089b2b17 /net
parent1255b5d9b20f8c23a1980ef270c09bbb07683418 (diff)
downloadchromium_src-7cc9929276a9a927ef3589109717f0765239e2af.zip
chromium_src-7cc9929276a9a927ef3589109717f0765239e2af.tar.gz
chromium_src-7cc9929276a9a927ef3589109717f0765239e2af.tar.bz2
Gracefully recover from malformed auth challenge.
BUG=39836 TEST=try to log in to an allnet webcam Review URL: http://codereview.chromium.org/1567008 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@43182 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net')
-rw-r--r--net/http/http_auth.cc13
-rw-r--r--net/http/http_auth_unittest.cc76
2 files changed, 84 insertions, 5 deletions
diff --git a/net/http/http_auth.cc b/net/http/http_auth.cc
index 83da9ad..540edf9 100644
--- a/net/http/http_auth.cc
+++ b/net/http/http_auth.cc
@@ -84,6 +84,9 @@ void HttpAuth::ChallengeTokenizer::Init(std::string::const_iterator begin,
// name="value"
// name=value
// name=
+// Due to buggy implementations found in some embedded devices, we also
+// accept values with missing close quotemark (http://crbug.com/39836):
+// name="value
bool HttpAuth::ChallengeTokenizer::GetNext() {
if (!props_.GetNext())
return false;
@@ -123,13 +126,13 @@ bool HttpAuth::ChallengeTokenizer::GetNext() {
name_end_ = equals;
value_begin_ = equals + 1;
+ value_is_quoted_ = false;
if (value_begin_ != value_end_ && HttpUtil::IsQuote(*value_begin_)) {
// Trim surrounding quotemarks off the value
- if (*value_begin_ != *(value_end_ - 1))
- return valid_ = false; // Malformed -- mismatching quotes.
- value_is_quoted_ = true;
- } else {
- value_is_quoted_ = false;
+ if (*value_begin_ != *(value_end_ - 1) || value_begin_ + 1 == value_end_)
+ value_begin_ = equals + 2; // Gracefully recover from mismatching quotes.
+ else
+ value_is_quoted_ = true;
}
return true;
}
diff --git a/net/http/http_auth_unittest.cc b/net/http/http_auth_unittest.cc
index 8522cca..799dcec 100644
--- a/net/http/http_auth_unittest.cc
+++ b/net/http/http_auth_unittest.cc
@@ -401,6 +401,82 @@ TEST(HttpAuthTest, ChallengeTokenizerNoQuotes) {
EXPECT_FALSE(challenge.GetNext());
}
+// Use a name=value property with mismatching quote marks.
+TEST(HttpAuthTest, ChallengeTokenizerMismatchedQuotes) {
+ std::string challenge_str = "Basic realm=\"foobar@baz.com";
+ HttpAuth::ChallengeTokenizer challenge(challenge_str.begin(),
+ challenge_str.end());
+ EXPECT_TRUE(challenge.valid());
+ EXPECT_EQ(std::string("Basic"), challenge.scheme());
+ EXPECT_TRUE(challenge.GetNext());
+ EXPECT_TRUE(challenge.valid());
+ EXPECT_EQ(std::string("realm"), challenge.name());
+ EXPECT_EQ(std::string("foobar@baz.com"), challenge.value());
+ EXPECT_EQ(std::string("foobar@baz.com"), challenge.unquoted_value());
+ EXPECT_FALSE(challenge.value_is_quoted());
+ EXPECT_FALSE(challenge.GetNext());
+}
+
+// Use a name= property without a value and with mismatching quote marks.
+TEST(HttpAuthTest, ChallengeTokenizerMismatchedQuotesNoValue) {
+ std::string challenge_str = "Basic realm=\"";
+ HttpAuth::ChallengeTokenizer challenge(challenge_str.begin(),
+ challenge_str.end());
+ EXPECT_TRUE(challenge.valid());
+ EXPECT_EQ(std::string("Basic"), challenge.scheme());
+ EXPECT_TRUE(challenge.GetNext());
+ EXPECT_TRUE(challenge.valid());
+ EXPECT_EQ(std::string("realm"), challenge.name());
+ EXPECT_EQ(std::string(""), challenge.value());
+ EXPECT_FALSE(challenge.value_is_quoted());
+ EXPECT_FALSE(challenge.GetNext());
+}
+
+// Use a name=value property with mismatching quote marks and spaces in the
+// value.
+TEST(HttpAuthTest, ChallengeTokenizerMismatchedQuotesSpaces) {
+ std::string challenge_str = "Basic realm=\"foo bar";
+ HttpAuth::ChallengeTokenizer challenge(challenge_str.begin(),
+ challenge_str.end());
+ EXPECT_TRUE(challenge.valid());
+ EXPECT_EQ(std::string("Basic"), challenge.scheme());
+ EXPECT_TRUE(challenge.GetNext());
+ EXPECT_TRUE(challenge.valid());
+ EXPECT_EQ(std::string("realm"), challenge.name());
+ EXPECT_EQ(std::string("foo bar"), challenge.value());
+ EXPECT_EQ(std::string("foo bar"), challenge.unquoted_value());
+ EXPECT_FALSE(challenge.value_is_quoted());
+ EXPECT_FALSE(challenge.GetNext());
+}
+
+// Use multiple name=value properties with mismatching quote marks in the last
+// value.
+TEST(HttpAuthTest, ChallengeTokenizerMismatchedQuotesMultiple) {
+ std::string challenge_str = "Digest qop=, algorithm=md5, realm=\"foo";
+ HttpAuth::ChallengeTokenizer challenge(challenge_str.begin(),
+ challenge_str.end());
+ EXPECT_TRUE(challenge.valid());
+ EXPECT_EQ(std::string("Digest"), challenge.scheme());
+ EXPECT_TRUE(challenge.GetNext());
+ EXPECT_TRUE(challenge.valid());
+ EXPECT_EQ(std::string("qop"), challenge.name());
+ EXPECT_EQ(std::string(""), challenge.value());
+ EXPECT_FALSE(challenge.value_is_quoted());
+ EXPECT_TRUE(challenge.GetNext());
+ EXPECT_TRUE(challenge.valid());
+ EXPECT_EQ(std::string("algorithm"), challenge.name());
+ EXPECT_EQ(std::string("md5"), challenge.value());
+ EXPECT_EQ(std::string("md5"), challenge.unquoted_value());
+ EXPECT_FALSE(challenge.value_is_quoted());
+ EXPECT_TRUE(challenge.GetNext());
+ EXPECT_TRUE(challenge.valid());
+ EXPECT_EQ(std::string("realm"), challenge.name());
+ EXPECT_EQ(std::string("foo"), challenge.value());
+ EXPECT_EQ(std::string("foo"), challenge.unquoted_value());
+ EXPECT_FALSE(challenge.value_is_quoted());
+ EXPECT_FALSE(challenge.GetNext());
+}
+
// Use a name= property which has no value.
TEST(HttpAuthTest, ChallengeTokenizerNoValue) {
std::string challenge_str = "Digest qop=";