OLD | NEW |
---|---|
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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 "chrome/browser/chromeos/login/profile_auth_data.h" | 5 #include "chrome/browser/chromeos/login/profile_auth_data.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/bind_helpers.h" | 10 #include "base/bind_helpers.h" |
11 #include "base/callback.h" | 11 #include "base/callback.h" |
12 #include "base/location.h" | 12 #include "base/location.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/memory/ref_counted.h" | 14 #include "base/memory/ref_counted.h" |
15 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
16 #include "base/time/time.h" | |
16 #include "content/public/browser/browser_context.h" | 17 #include "content/public/browser/browser_context.h" |
17 #include "content/public/browser/browser_thread.h" | 18 #include "content/public/browser/browser_thread.h" |
18 #include "net/cookies/canonical_cookie.h" | 19 #include "net/cookies/canonical_cookie.h" |
19 #include "net/cookies/cookie_monster.h" | 20 #include "net/cookies/cookie_monster.h" |
20 #include "net/cookies/cookie_store.h" | 21 #include "net/cookies/cookie_store.h" |
21 #include "net/http/http_auth_cache.h" | 22 #include "net/http/http_auth_cache.h" |
22 #include "net/http/http_network_session.h" | 23 #include "net/http/http_network_session.h" |
23 #include "net/http/http_transaction_factory.h" | 24 #include "net/http/http_transaction_factory.h" |
24 #include "net/ssl/channel_id_service.h" | 25 #include "net/ssl/channel_id_service.h" |
25 #include "net/ssl/channel_id_store.h" | 26 #include "net/ssl/channel_id_store.h" |
26 #include "net/url_request/url_request_context.h" | 27 #include "net/url_request/url_request_context.h" |
27 #include "net/url_request/url_request_context_getter.h" | 28 #include "net/url_request/url_request_context_getter.h" |
28 #include "url/gurl.h" | 29 #include "url/gurl.h" |
29 | 30 |
30 using content::BrowserThread; | 31 using content::BrowserThread; |
31 | 32 |
32 namespace chromeos { | 33 namespace chromeos { |
33 | 34 |
34 namespace { | 35 namespace { |
35 | 36 |
36 // Given a |cookie| set during login, returns true if the cookie may have been | 37 const char kSAMLStartCookie[] = "google-accounts-saml-start"; |
37 // set by GAIA. While GAIA can set cookies for many different domains, the | 38 const char kSAMLEndCookie[] = "google-accounts-saml-end"; |
38 // domain names it sets cookies for during Chrome OS login will always contain | |
39 // the strings "google" or "youtube". | |
40 bool IsGAIACookie(const net::CanonicalCookie& cookie) { | |
41 const std::string& domain = cookie.Domain(); | |
42 return domain.find("google") != std::string::npos || | |
43 domain.find("youtube") != std::string::npos; | |
44 } | |
45 | 39 |
46 class ProfileAuthDataTransferer { | 40 class ProfileAuthDataTransferer { |
47 public: | 41 public: |
48 ProfileAuthDataTransferer( | 42 ProfileAuthDataTransferer( |
49 content::BrowserContext* from_context, | 43 content::BrowserContext* from_context, |
50 content::BrowserContext* to_context, | 44 content::BrowserContext* to_context, |
51 bool transfer_auth_cookies_and_channel_ids_on_first_login, | 45 bool transfer_auth_cookies_and_channel_ids_on_first_login, |
52 bool transfer_saml_auth_cookies_on_subsequent_login, | 46 bool transfer_saml_auth_cookies_on_subsequent_login, |
53 const base::Closure& completion_callback); | 47 const base::Closure& completion_callback); |
54 | 48 |
(...skipping 24 matching lines...) Expand all Loading... | |
79 | 73 |
80 // Retrieve |from_context_|'s channel IDs. When the retrieval finishes, | 74 // Retrieve |from_context_|'s channel IDs. When the retrieval finishes, |
81 // OnChannelIDsToTransferRetrieved will be called with the result. | 75 // OnChannelIDsToTransferRetrieved will be called with the result. |
82 void RetrieveChannelIDsToTransfer(); | 76 void RetrieveChannelIDsToTransfer(); |
83 | 77 |
84 // Callback that receives |from_context_|'s channel IDs. Calls | 78 // Callback that receives |from_context_|'s channel IDs. Calls |
85 // MaybeTransferCookiesAndChannelIDs() to try and perform the transfer. | 79 // MaybeTransferCookiesAndChannelIDs() to try and perform the transfer. |
86 void OnChannelIDsToTransferRetrieved( | 80 void OnChannelIDsToTransferRetrieved( |
87 const net::ChannelIDStore::ChannelIDList& channel_ids_to_transfer); | 81 const net::ChannelIDStore::ChannelIDList& channel_ids_to_transfer); |
88 | 82 |
83 // Given a |cookie| set during login, returns true if the cookie may have been | |
84 // set by GAIA. The main criterion is the |cookie|'s creation date. The points | |
85 // in time at which redirects from GAIA to SAML IdP and back occur are stored | |
86 // in |saml_start_time_| and |saml_end_time_|. If the cookie was set between | |
87 // these two times, it was created by the SAML IdP. Otherwise, it was created | |
88 // by GAIA. | |
89 // As an additional precaution, the cookie's domain is checked. If the domain | |
90 // contains "google" or "youtube", the cookie is considered to have been set | |
91 // by GAIA as well. | |
92 bool IsGAIACookie(const net::CanonicalCookie& cookie); | |
93 | |
89 // If all data to be transferred has been retrieved already, transfer it to | 94 // If all data to be transferred has been retrieved already, transfer it to |
90 // |to_context_| and call Finish(). | 95 // |to_context_| and call Finish(). |
91 void MaybeTransferCookiesAndChannelIDs(); | 96 void MaybeTransferCookiesAndChannelIDs(); |
92 | 97 |
93 // Post the |completion_callback_| to the UI thread and schedule destruction | 98 // Post the |completion_callback_| to the UI thread and schedule destruction |
94 // of |this|. | 99 // of |this|. |
95 void Finish(); | 100 void Finish(); |
96 | 101 |
97 scoped_refptr<net::URLRequestContextGetter> from_context_; | 102 scoped_refptr<net::URLRequestContextGetter> from_context_; |
98 scoped_refptr<net::URLRequestContextGetter> to_context_; | 103 scoped_refptr<net::URLRequestContextGetter> to_context_; |
99 bool transfer_auth_cookies_and_channel_ids_on_first_login_; | 104 bool transfer_auth_cookies_and_channel_ids_on_first_login_; |
100 bool transfer_saml_auth_cookies_on_subsequent_login_; | 105 bool transfer_saml_auth_cookies_on_subsequent_login_; |
101 base::Closure completion_callback_; | 106 base::Closure completion_callback_; |
102 | 107 |
103 net::CookieList cookies_to_transfer_; | 108 net::CookieList cookies_to_transfer_; |
104 net::ChannelIDStore::ChannelIDList channel_ids_to_transfer_; | 109 net::ChannelIDStore::ChannelIDList channel_ids_to_transfer_; |
105 | 110 |
111 // The time at which a redirect from GAIA to a SAML IdP occurred. | |
112 base::Time saml_start_time_; | |
113 // The time at which a redirect from a SAML IdP back to GAIA occurred. | |
114 base::Time saml_end_time_; | |
115 | |
106 bool first_login_; | 116 bool first_login_; |
107 bool waiting_for_auth_cookies_; | 117 bool waiting_for_auth_cookies_; |
108 bool waiting_for_channel_ids_; | 118 bool waiting_for_channel_ids_; |
109 }; | 119 }; |
110 | 120 |
111 ProfileAuthDataTransferer::ProfileAuthDataTransferer( | 121 ProfileAuthDataTransferer::ProfileAuthDataTransferer( |
112 content::BrowserContext* from_context, | 122 content::BrowserContext* from_context, |
113 content::BrowserContext* to_context, | 123 content::BrowserContext* to_context, |
114 bool transfer_auth_cookies_and_channel_ids_on_first_login, | 124 bool transfer_auth_cookies_and_channel_ids_on_first_login, |
115 bool transfer_saml_auth_cookies_on_subsequent_login, | 125 bool transfer_saml_auth_cookies_on_subsequent_login, |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
207 from_monster->GetAllCookiesAsync( | 217 from_monster->GetAllCookiesAsync( |
208 base::Bind(&ProfileAuthDataTransferer::OnCookiesToTransferRetrieved, | 218 base::Bind(&ProfileAuthDataTransferer::OnCookiesToTransferRetrieved, |
209 base::Unretained(this))); | 219 base::Unretained(this))); |
210 } | 220 } |
211 | 221 |
212 void ProfileAuthDataTransferer::OnCookiesToTransferRetrieved( | 222 void ProfileAuthDataTransferer::OnCookiesToTransferRetrieved( |
213 const net::CookieList& cookies_to_transfer) { | 223 const net::CookieList& cookies_to_transfer) { |
214 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 224 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
215 waiting_for_auth_cookies_ = false; | 225 waiting_for_auth_cookies_ = false; |
216 cookies_to_transfer_ = cookies_to_transfer; | 226 cookies_to_transfer_ = cookies_to_transfer; |
227 | |
228 // Look for cookies indicating the points in time at which redirects from GAIA | |
229 // to SAML IdP and back occurred. These cookies are synthesized by | |
230 // chrome/browser/resources/gaia_auth/background.js. If the cookies are found, | |
231 // their creation times are stored in |saml_start_time_| and | |
232 // |cookies_to_transfer_| and the cookies are deleted. | |
233 for (net::CookieList::iterator it = cookies_to_transfer_.begin(); | |
234 it != cookies_to_transfer_.end(); ) { | |
235 if (it->Name() == kSAMLStartCookie) { | |
236 saml_start_time_ = it->CreationDate(); | |
237 it = cookies_to_transfer_.erase(it); | |
238 } else if (it->Name() == kSAMLEndCookie) { | |
239 saml_end_time_ = it->CreationDate(); | |
240 it = cookies_to_transfer_.erase(it); | |
241 } else { | |
242 ++it; | |
243 } | |
244 } | |
245 | |
217 MaybeTransferCookiesAndChannelIDs(); | 246 MaybeTransferCookiesAndChannelIDs(); |
218 } | 247 } |
219 | 248 |
220 void ProfileAuthDataTransferer::RetrieveChannelIDsToTransfer() { | 249 void ProfileAuthDataTransferer::RetrieveChannelIDsToTransfer() { |
221 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 250 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
222 net::ChannelIDService* from_service = | 251 net::ChannelIDService* from_service = |
223 from_context_->GetURLRequestContext()->channel_id_service(); | 252 from_context_->GetURLRequestContext()->channel_id_service(); |
224 from_service->GetChannelIDStore()->GetAllChannelIDs( | 253 from_service->GetChannelIDStore()->GetAllChannelIDs( |
225 base::Bind( | 254 base::Bind( |
226 &ProfileAuthDataTransferer::OnChannelIDsToTransferRetrieved, | 255 &ProfileAuthDataTransferer::OnChannelIDsToTransferRetrieved, |
227 base::Unretained(this))); | 256 base::Unretained(this))); |
228 } | 257 } |
229 | 258 |
230 void ProfileAuthDataTransferer::OnChannelIDsToTransferRetrieved( | 259 void ProfileAuthDataTransferer::OnChannelIDsToTransferRetrieved( |
231 const net::ChannelIDStore::ChannelIDList& channel_ids_to_transfer) { | 260 const net::ChannelIDStore::ChannelIDList& channel_ids_to_transfer) { |
232 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 261 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
233 channel_ids_to_transfer_ = channel_ids_to_transfer; | 262 channel_ids_to_transfer_ = channel_ids_to_transfer; |
234 waiting_for_channel_ids_ = false; | 263 waiting_for_channel_ids_ = false; |
235 MaybeTransferCookiesAndChannelIDs(); | 264 MaybeTransferCookiesAndChannelIDs(); |
236 } | 265 } |
237 | 266 |
267 bool ProfileAuthDataTransferer::IsGAIACookie( | |
268 const net::CanonicalCookie& cookie) { | |
269 const base::Time& creation_date = cookie.CreationDate(); | |
270 if (creation_date < saml_start_time_) | |
271 return true; | |
272 if (!saml_end_time_.is_null() && creation_date > saml_end_time_) | |
273 return true; | |
274 | |
dzhioev (left Google)
2014/08/07 09:17:44
I can't understand how does this change help to tr
bartfab (slow)
2014/08/07 11:59:45
Done - I replied to this directly and Pavel was ha
| |
275 const std::string& domain = cookie.Domain(); | |
276 return domain.find("google") != std::string::npos || | |
277 domain.find("youtube") != std::string::npos; | |
278 } | |
279 | |
238 void ProfileAuthDataTransferer::MaybeTransferCookiesAndChannelIDs() { | 280 void ProfileAuthDataTransferer::MaybeTransferCookiesAndChannelIDs() { |
239 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | 281 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); |
240 if (waiting_for_auth_cookies_ || waiting_for_channel_ids_) | 282 if (waiting_for_auth_cookies_ || waiting_for_channel_ids_) |
241 return; | 283 return; |
242 | 284 |
243 net::CookieStore* to_store = | 285 net::CookieStore* to_store = |
244 to_context_->GetURLRequestContext()->cookie_store(); | 286 to_context_->GetURLRequestContext()->cookie_store(); |
245 net::CookieMonster* to_monster = to_store->GetCookieMonster(); | 287 net::CookieMonster* to_monster = to_store->GetCookieMonster(); |
246 if (first_login_) { | 288 if (first_login_) { |
247 to_monster->InitializeFrom(cookies_to_transfer_); | 289 to_monster->InitializeFrom(cookies_to_transfer_); |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
292 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 334 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
293 (new ProfileAuthDataTransferer( | 335 (new ProfileAuthDataTransferer( |
294 from_context, | 336 from_context, |
295 to_context, | 337 to_context, |
296 transfer_auth_cookies_and_channel_ids_on_first_login, | 338 transfer_auth_cookies_and_channel_ids_on_first_login, |
297 transfer_saml_auth_cookies_on_subsequent_login, | 339 transfer_saml_auth_cookies_on_subsequent_login, |
298 completion_callback))->BeginTransfer(); | 340 completion_callback))->BeginTransfer(); |
299 } | 341 } |
300 | 342 |
301 } // namespace chromeos | 343 } // namespace chromeos |
OLD | NEW |