Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(380)

Side by Side Diff: net/http/http_network_transaction.cc

Issue 28144: Implement the NTLM authentication scheme by porting... (Closed) Base URL: svn://chrome-svn/chrome/trunk/src/
Patch Set: Final upload before checkin Created 11 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/http/http_auth_unittest.cc ('k') | net/http/http_network_transaction_unittest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/http/http_network_transaction.h" 5 #include "net/http/http_network_transaction.h"
6 6
7 #include "base/scoped_ptr.h" 7 #include "base/scoped_ptr.h"
8 #include "base/compiler_specific.h" 8 #include "base/compiler_specific.h"
9 #include "base/string_util.h" 9 #include "base/string_util.h"
10 #include "base/trace_event.h" 10 #include "base/trace_event.h"
(...skipping 105 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 } 116 }
117 117
118 void HttpNetworkTransaction::PrepareForAuthRestart(HttpAuth::Target target) { 118 void HttpNetworkTransaction::PrepareForAuthRestart(HttpAuth::Target target) {
119 DCHECK(HaveAuth(target)); 119 DCHECK(HaveAuth(target));
120 DCHECK(auth_identity_[target].source != HttpAuth::IDENT_SRC_PATH_LOOKUP); 120 DCHECK(auth_identity_[target].source != HttpAuth::IDENT_SRC_PATH_LOOKUP);
121 121
122 // Add the auth entry to the cache before restarting. We don't know whether 122 // Add the auth entry to the cache before restarting. We don't know whether
123 // the identity is valid yet, but if it is valid we want other transactions 123 // the identity is valid yet, but if it is valid we want other transactions
124 // to know about it. If an entry for (origin, handler->realm()) already 124 // to know about it. If an entry for (origin, handler->realm()) already
125 // exists, we update it. 125 // exists, we update it.
126 session_->auth_cache()->Add(AuthOrigin(target), auth_handler_[target], 126 //
127 auth_identity_[target].username, auth_identity_[target].password, 127 // If auth_identity_[target].source is HttpAuth::IDENT_SRC_NONE,
128 AuthPath(target)); 128 // auth_identity_[target] contains no identity because identity is not
129 // required yet.
130 if (auth_identity_[target].source != HttpAuth::IDENT_SRC_NONE) {
131 session_->auth_cache()->Add(AuthOrigin(target), auth_handler_[target],
132 auth_identity_[target].username, auth_identity_[target].password,
133 AuthPath(target));
134 }
129 135
130 bool keep_alive = false; 136 bool keep_alive = false;
131 if (response_.headers->IsKeepAlive()) { 137 if (response_.headers->IsKeepAlive()) {
132 // If there is a response body of known length, we need to drain it first. 138 // If there is a response body of known length, we need to drain it first.
133 if (content_length_ > 0 || chunked_decoder_.get()) { 139 if (content_length_ > 0 || chunked_decoder_.get()) {
134 next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART; 140 next_state_ = STATE_DRAIN_BODY_FOR_AUTH_RESTART;
135 read_buf_ = new IOBuffer(kDrainBodyBufferSize); // A bit bucket 141 read_buf_ = new IOBuffer(kDrainBodyBufferSize); // A bit bucket
136 read_buf_len_ = kDrainBodyBufferSize; 142 read_buf_len_ = kDrainBodyBufferSize;
137 return; 143 return;
138 } 144 }
(...skipping 1116 matching lines...) Expand 10 before | Expand all | Expand 10 after
1255 return false; 1261 return false;
1256 1262
1257 // SelectPreemptiveAuth() is on the critical path for each request, so it 1263 // SelectPreemptiveAuth() is on the critical path for each request, so it
1258 // is expected to be fast. LookupByPath() is fast in the common case, since 1264 // is expected to be fast. LookupByPath() is fast in the common case, since
1259 // the number of http auth cache entries is expected to be very small. 1265 // the number of http auth cache entries is expected to be very small.
1260 // (For most users in fact, it will be 0.) 1266 // (For most users in fact, it will be 0.)
1261 1267
1262 HttpAuthCache::Entry* entry = session_->auth_cache()->LookupByPath( 1268 HttpAuthCache::Entry* entry = session_->auth_cache()->LookupByPath(
1263 AuthOrigin(target), AuthPath(target)); 1269 AuthOrigin(target), AuthPath(target));
1264 1270
1265 if (entry) { 1271 // We don't support preemptive authentication for connection-based
1272 // authentication schemes because they can't reuse entry->handler().
1273 // Hopefully we can remove this limitation in the future.
1274 if (entry && !entry->handler()->is_connection_based()) {
1266 auth_identity_[target].source = HttpAuth::IDENT_SRC_PATH_LOOKUP; 1275 auth_identity_[target].source = HttpAuth::IDENT_SRC_PATH_LOOKUP;
1267 auth_identity_[target].invalid = false; 1276 auth_identity_[target].invalid = false;
1268 auth_identity_[target].username = entry->username(); 1277 auth_identity_[target].username = entry->username();
1269 auth_identity_[target].password = entry->password(); 1278 auth_identity_[target].password = entry->password();
1270 auth_handler_[target] = entry->handler(); 1279 auth_handler_[target] = entry->handler();
1271 return true; 1280 return true;
1272 } 1281 }
1273 return false; 1282 return false;
1274 } 1283 }
1275 1284
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1332 int status = response_.headers->response_code(); 1341 int status = response_.headers->response_code();
1333 if (status != 401 && status != 407) 1342 if (status != 401 && status != 407)
1334 return OK; 1343 return OK;
1335 HttpAuth::Target target = status == 407 ? 1344 HttpAuth::Target target = status == 407 ?
1336 HttpAuth::AUTH_PROXY : HttpAuth::AUTH_SERVER; 1345 HttpAuth::AUTH_PROXY : HttpAuth::AUTH_SERVER;
1337 1346
1338 if (target == HttpAuth::AUTH_PROXY && proxy_info_.is_direct()) 1347 if (target == HttpAuth::AUTH_PROXY && proxy_info_.is_direct())
1339 return ERR_UNEXPECTED_PROXY_AUTH; 1348 return ERR_UNEXPECTED_PROXY_AUTH;
1340 1349
1341 // The auth we tried just failed, hence it can't be valid. Remove it from 1350 // The auth we tried just failed, hence it can't be valid. Remove it from
1342 // the cache so it won't be used again. 1351 // the cache so it won't be used again, unless it's a null identity.
1343 if (HaveAuth(target)) 1352 if (HaveAuth(target) &&
1353 auth_identity_[target].source != HttpAuth::IDENT_SRC_NONE)
1344 InvalidateRejectedAuthFromCache(target); 1354 InvalidateRejectedAuthFromCache(target);
1345 1355
1346 auth_identity_[target].invalid = true; 1356 auth_identity_[target].invalid = true;
1347 1357
1348 // Find the best authentication challenge that we support. 1358 // Find the best authentication challenge that we support.
1349 HttpAuth::ChooseBestChallenge(response_.headers.get(), 1359 HttpAuth::ChooseBestChallenge(response_.headers.get(),
1350 target, 1360 target,
1351 &auth_handler_[target]); 1361 &auth_handler_[target]);
1352 1362
1353 if (!auth_handler_[target]) { 1363 if (!auth_handler_[target]) {
1354 if (establishing_tunnel_) { 1364 if (establishing_tunnel_) {
1355 // We are establishing a tunnel, we can't show the error page because an 1365 // We are establishing a tunnel, we can't show the error page because an
1356 // active network attacker could control its contents. Instead, we just 1366 // active network attacker could control its contents. Instead, we just
1357 // fail to establish the tunnel. 1367 // fail to establish the tunnel.
1358 return ERR_PROXY_AUTH_REQUESTED; 1368 return ERR_PROXY_AUTH_REQUESTED;
1359 } 1369 }
1360 // We found no supported challenge -- let the transaction continue 1370 // We found no supported challenge -- let the transaction continue
1361 // so we end up displaying the error page. 1371 // so we end up displaying the error page.
1362 return OK; 1372 return OK;
1363 } 1373 }
1364 1374
1365 // Pick a new auth identity to try, by looking to the URL and auth cache. 1375 bool has_identity_to_try;
1366 // If an identity to try is found, it is saved to auth_identity_[target]. 1376 if (auth_handler_[target]->NeedsIdentity()) {
1367 bool has_identity_to_try = SelectNextAuthIdentityToTry(target); 1377 // Pick a new auth identity to try, by looking to the URL and auth cache.
1378 // If an identity to try is found, it is saved to auth_identity_[target].
1379 has_identity_to_try = SelectNextAuthIdentityToTry(target);
1380 } else {
1381 // Proceed with a null identity.
1382 //
1383 // TODO(wtc): Add a safeguard against infinite transaction restarts, if
1384 // the server keeps returning "NTLM".
1385 auth_identity_[target].source = HttpAuth::IDENT_SRC_NONE;
1386 auth_identity_[target].invalid = false;
1387 auth_identity_[target].username.clear();
1388 auth_identity_[target].password.clear();
1389 has_identity_to_try = true;
1390 }
1368 DCHECK(has_identity_to_try == !auth_identity_[target].invalid); 1391 DCHECK(has_identity_to_try == !auth_identity_[target].invalid);
1369 1392
1370 if (has_identity_to_try) { 1393 if (has_identity_to_try) {
1371 DCHECK(user_callback_); 1394 DCHECK(user_callback_);
1372 PrepareForAuthRestart(target); 1395 PrepareForAuthRestart(target);
1373 return WILL_RESTART_TRANSACTION; 1396 return WILL_RESTART_TRANSACTION;
1374 } 1397 }
1375 1398
1376 // We have exhausted all identity possibilities, all we can do now is 1399 // We have exhausted all identity possibilities, all we can do now is
1377 // pass the challenge information back to the client. 1400 // pass the challenge information back to the client.
(...skipping 13 matching lines...) Expand all
1391 if (target == HttpAuth::AUTH_PROXY) { 1414 if (target == HttpAuth::AUTH_PROXY) {
1392 auth_info->host = ASCIIToWide(proxy_info_.proxy_server().host_and_port()); 1415 auth_info->host = ASCIIToWide(proxy_info_.proxy_server().host_and_port());
1393 } else { 1416 } else {
1394 DCHECK(target == HttpAuth::AUTH_SERVER); 1417 DCHECK(target == HttpAuth::AUTH_SERVER);
1395 auth_info->host = ASCIIToWide(request_->url.host()); 1418 auth_info->host = ASCIIToWide(request_->url.host());
1396 } 1419 }
1397 response_.auth_challenge = auth_info; 1420 response_.auth_challenge = auth_info;
1398 } 1421 }
1399 1422
1400 } // namespace net 1423 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_auth_unittest.cc ('k') | net/http/http_network_transaction_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698