diff options
author | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-31 07:16:59 +0000 |
---|---|---|
committer | jochen@chromium.org <jochen@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-31 07:16:59 +0000 |
commit | 7cc9929276a9a927ef3589109717f0765239e2af (patch) | |
tree | d10cfad399b480359f6cdf517cbc65c7089b2b17 /net | |
parent | 1255b5d9b20f8c23a1980ef270c09bbb07683418 (diff) | |
download | chromium_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.cc | 13 | ||||
-rw-r--r-- | net/http/http_auth_unittest.cc | 76 |
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="; |