forked from chromium/chromium
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
BUG=147591 Review URL: https://chromiumcodereview.appspot.com/10913238 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@159342 0039d316-1c4b-4281-b951-d872f2087c98
- Loading branch information
piatek@google.com
committed
Sep 28, 2012
1 parent
08c8df6
commit ec44ee0
Showing
14 changed files
with
464 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
168 changes: 168 additions & 0 deletions
168
chrome/browser/net/spdyproxy/http_auth_handler_spdyproxy.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
// Copyright (c) 2012 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#include "chrome/browser/net/spdyproxy/http_auth_handler_spdyproxy.h" | ||
|
||
#include <string> | ||
|
||
#include "base/i18n/icu_string_conversions.h" | ||
#include "base/metrics/histogram.h" | ||
#include "base/string_util.h" | ||
#include "base/utf_string_conversions.h" | ||
#include "net/base/net_errors.h" | ||
#include "net/http/http_auth.h" | ||
#include "net/http/http_request_info.h" | ||
|
||
namespace spdyproxy { | ||
|
||
using net::AuthCredentials; | ||
using net::BoundNetLog; | ||
using net::CompletionCallback; | ||
using net::HttpAuth; | ||
using net::HttpAuthHandler; | ||
using net::HttpAuthHandlerFactory; | ||
using net::HttpRequestInfo; | ||
using net::HttpUtil; | ||
|
||
HttpAuthHandlerSpdyProxy::Factory::Factory( | ||
const GURL& authorized_spdyproxy_origin) | ||
: authorized_spdyproxy_origin_(authorized_spdyproxy_origin) { | ||
} | ||
|
||
HttpAuthHandlerSpdyProxy::Factory::~Factory() { | ||
} | ||
|
||
int HttpAuthHandlerSpdyProxy::Factory::CreateAuthHandler( | ||
HttpAuth::ChallengeTokenizer* challenge, | ||
HttpAuth::Target target, | ||
const GURL& origin, | ||
CreateReason reason, | ||
int digest_nonce_count, | ||
const BoundNetLog& net_log, | ||
scoped_ptr<HttpAuthHandler>* handler) { | ||
// If a spdyproxy auth proxy has not been set, refuse all requests to use this | ||
// auth handler. | ||
if (authorized_spdyproxy_origin_.possibly_invalid_spec().empty()) { | ||
VLOG(1) << "SpdyProxy auth without configuring authorized origin."; | ||
return net::ERR_UNSUPPORTED_AUTH_SCHEME; | ||
} | ||
|
||
// We ensure that this authentication handler is used only with an authorized | ||
// SPDY proxy, since otherwise a user's authentication token can be | ||
// sniffed by a malicious proxy that presents an appropriate challenge. | ||
const GURL origin_origin = origin.GetOrigin(); | ||
if (!(target == HttpAuth::AUTH_PROXY && | ||
origin_origin == authorized_spdyproxy_origin_)) { | ||
UMA_HISTOGRAM_COUNTS("Net.UnexpectedSpdyProxyAuth", 1); | ||
VLOG(1) << "SpdyProxy auth request with an unexpected config." | ||
<< " origin: " << origin_origin.possibly_invalid_spec() | ||
<< " authorized_origin: " | ||
<< authorized_spdyproxy_origin_.possibly_invalid_spec(); | ||
return net::ERR_UNSUPPORTED_AUTH_SCHEME; | ||
} | ||
|
||
scoped_ptr<HttpAuthHandler> tmp_handler( | ||
new HttpAuthHandlerSpdyProxy(authorized_spdyproxy_origin_)); | ||
if (!tmp_handler->InitFromChallenge(challenge, target, origin, net_log)) | ||
return net::ERR_INVALID_RESPONSE; | ||
handler->swap(tmp_handler); | ||
return net::OK; | ||
} | ||
|
||
HttpAuthHandlerSpdyProxy::HttpAuthHandlerSpdyProxy( | ||
const GURL& authorized_spdyproxy_origin) | ||
: HttpAuthHandler(), | ||
authorized_spdyproxy_origin_(authorized_spdyproxy_origin) { | ||
} | ||
|
||
HttpAuth::AuthorizationResult | ||
HttpAuthHandlerSpdyProxy::HandleAnotherChallenge( | ||
HttpAuth::ChallengeTokenizer* challenge) { | ||
// SpdyProxy authentication is always a single round, so any responses | ||
// should be treated as a rejection. | ||
return HttpAuth::AUTHORIZATION_RESULT_REJECT; | ||
} | ||
|
||
bool HttpAuthHandlerSpdyProxy::NeedsIdentity() { | ||
return true; | ||
} | ||
|
||
bool HttpAuthHandlerSpdyProxy::AllowsDefaultCredentials() { | ||
return false; | ||
} | ||
|
||
bool HttpAuthHandlerSpdyProxy::AllowsExplicitCredentials() { | ||
return true; | ||
} | ||
|
||
bool HttpAuthHandlerSpdyProxy::Init( | ||
HttpAuth::ChallengeTokenizer* challenge) { | ||
auth_scheme_ = HttpAuth::AUTH_SCHEME_SPDYPROXY; | ||
score_ = 5; | ||
properties_ = ENCRYPTS_IDENTITY; | ||
return ParseChallenge(challenge); | ||
} | ||
|
||
int HttpAuthHandlerSpdyProxy::GenerateAuthTokenImpl( | ||
const AuthCredentials* credentials, const HttpRequestInfo* request, | ||
const CompletionCallback&, std::string* auth_token) { | ||
DCHECK(credentials); | ||
if (credentials->password().length() == 0) { | ||
DVLOG(1) << "Received a SpdyProxy auth token request without an " | ||
<< "available token."; | ||
return -1; | ||
} | ||
*auth_token = "SpdyProxy ps=\"" + ps_token_ + "\", sid=\"" + | ||
UTF16ToUTF8(credentials->password()) + "\""; | ||
return net::OK; | ||
} | ||
|
||
bool HttpAuthHandlerSpdyProxy::ParseChallenge( | ||
HttpAuth::ChallengeTokenizer* challenge) { | ||
|
||
// Verify the challenge's auth-scheme. | ||
if (!LowerCaseEqualsASCII(challenge->scheme(), "spdyproxy")) { | ||
VLOG(1) << "Parsed challenge without SpdyProxy type"; | ||
return false; | ||
} | ||
|
||
HttpUtil::NameValuePairsIterator parameters = challenge->param_pairs(); | ||
|
||
// Loop through all the properties. | ||
while (parameters.GetNext()) { | ||
// FAIL -- couldn't parse a property. | ||
if (!ParseChallengeProperty(parameters.name(), | ||
parameters.value())) | ||
return false; | ||
} | ||
// Check if tokenizer failed. | ||
if (!parameters.valid()) | ||
return false; | ||
|
||
// Check that the required properties were provided. | ||
if (realm_.empty()) | ||
return false; | ||
|
||
if (ps_token_.empty()) | ||
return false; | ||
|
||
return true; | ||
} | ||
|
||
bool HttpAuthHandlerSpdyProxy::ParseChallengeProperty( | ||
const std::string& name, const std::string& value) { | ||
if (LowerCaseEqualsASCII(name, "realm")) { | ||
std::string realm; | ||
if (!base::ConvertToUtf8AndNormalize(value, base::kCodepageLatin1, &realm)) | ||
return false; | ||
realm_ = realm; | ||
} else if (LowerCaseEqualsASCII(name, "ps")) { | ||
ps_token_ = value; | ||
} else { | ||
VLOG(1) << "Skipping unrecognized SpdyProxy auth property, " << name; | ||
} | ||
return true; | ||
} | ||
|
||
} // namespace spdyproxy |
80 changes: 80 additions & 0 deletions
80
chrome/browser/net/spdyproxy/http_auth_handler_spdyproxy.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
// Copyright (c) 2012 The Chromium Authors. All rights reserved. | ||
// Use of this source code is governed by a BSD-style license that can be | ||
// found in the LICENSE file. | ||
|
||
#ifndef CHROME_BROWSER_NET_SPDYPROXY_HTTP_AUTH_HANDLER_SPDYPROXY_H_ | ||
#define CHROME_BROWSER_NET_SPDYPROXY_HTTP_AUTH_HANDLER_SPDYPROXY_H_ | ||
|
||
#include <string> | ||
|
||
#include "base/gtest_prod_util.h" | ||
#include "net/http/http_auth_handler.h" | ||
#include "net/http/http_auth_handler_factory.h" | ||
|
||
namespace spdyproxy { | ||
|
||
// Code for handling http SpdyProxy authentication. | ||
class HttpAuthHandlerSpdyProxy : public net::HttpAuthHandler { | ||
public: | ||
class Factory : public net::HttpAuthHandlerFactory { | ||
public: | ||
// Constructs a new spdyproxy handler factory which mints handlers that | ||
// respond to challenges only from the given |authorized_spdyproxy_origin|. | ||
explicit Factory(const GURL& authorized_spdyproxy_origin); | ||
virtual ~Factory(); | ||
|
||
virtual int CreateAuthHandler( | ||
net::HttpAuth::ChallengeTokenizer* challenge, | ||
net::HttpAuth::Target target, | ||
const GURL& origin, | ||
CreateReason reason, | ||
int digest_nonce_count, | ||
const net::BoundNetLog& net_log, | ||
scoped_ptr<HttpAuthHandler>* handler) OVERRIDE; | ||
|
||
private: | ||
// The origin for which we will respond to SpdyProxy auth challenges. | ||
GURL authorized_spdyproxy_origin_; | ||
}; | ||
|
||
// Constructs a new spdyproxy handler which responds to challenges | ||
// from the given |authorized_spdyproxy_origin|. | ||
explicit HttpAuthHandlerSpdyProxy( | ||
const GURL& authorized_spdyproxy_origin); | ||
|
||
// Overrides from net::HttpAuthHandler. | ||
virtual net::HttpAuth::AuthorizationResult HandleAnotherChallenge( | ||
net::HttpAuth::ChallengeTokenizer* challenge) OVERRIDE; | ||
virtual bool NeedsIdentity() OVERRIDE; | ||
virtual bool AllowsDefaultCredentials() OVERRIDE; | ||
virtual bool AllowsExplicitCredentials() OVERRIDE; | ||
|
||
private: | ||
FRIEND_TEST_ALL_PREFIXES(HttpAuthHandlerSpdyProxyTest, ParseChallenge); | ||
|
||
virtual ~HttpAuthHandlerSpdyProxy() {} | ||
|
||
virtual bool Init(net::HttpAuth::ChallengeTokenizer* challenge) OVERRIDE; | ||
|
||
virtual int GenerateAuthTokenImpl(const net::AuthCredentials* credentials, | ||
const net::HttpRequestInfo* request, | ||
const net::CompletionCallback& callback, | ||
std::string* auth_token) OVERRIDE; | ||
|
||
bool ParseChallenge(net::HttpAuth::ChallengeTokenizer* challenge); | ||
|
||
bool ParseChallengeProperty(const std::string& name, | ||
const std::string& value); | ||
|
||
// The origin for which we will respond to SpdyProxy auth challenges. | ||
GURL authorized_spdyproxy_origin_; | ||
|
||
// The ps token, encoded as UTF-8. | ||
std::string ps_token_; | ||
|
||
DISALLOW_COPY_AND_ASSIGN(HttpAuthHandlerSpdyProxy); | ||
}; | ||
|
||
} // namespace spdyproxy | ||
|
||
#endif // CHROME_BROWSER_NET_SPDYPROXY_HTTP_AUTH_HANDLER_SPDYPROXY_H_ |
Oops, something went wrong.