Chromium Code Reviews| 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/password_manager/password_store.h" | 5 #include "chrome/browser/password_manager/password_store.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/memory/scoped_ptr.h" | 8 #include "base/memory/scoped_ptr.h" |
| 9 #include "base/message_loop.h" | 9 #include "base/message_loop.h" |
| 10 #include "base/stl_util.h" | 10 #include "base/stl_util.h" |
| 11 #include "chrome/browser/password_manager/password_store_consumer.h" | 11 #include "chrome/browser/password_manager/password_store_consumer.h" |
| 12 #include "content/public/browser/browser_thread.h" | 12 #include "content/public/browser/browser_thread.h" |
| 13 #include "webkit/forms/password_form.h" | 13 #include "webkit/forms/password_form.h" |
| 14 | 14 |
| 15 using content::BrowserThread; | 15 using content::BrowserThread; |
| 16 using std::vector; | 16 using std::vector; |
| 17 using webkit::forms::PasswordForm; | 17 using webkit::forms::PasswordForm; |
| 18 | 18 |
| 19 PasswordStore::GetLoginsRequest::GetLoginsRequest( | 19 PasswordStore::GetLoginsRequest::GetLoginsRequest( |
| 20 const GetLoginsCallback& callback) | 20 const GetLoginsCallback& callback) |
| 21 : CancelableRequest1<GetLoginsCallback, | 21 : CancelableRequest1<GetLoginsCallback, |
| 22 std::vector<PasswordForm*> >(callback) { | 22 std::vector<PasswordForm*> >(callback), |
| 23 ignore_logins_cutoff_(0) { | |
| 24 } | |
| 25 | |
| 26 void PasswordStore::GetLoginsRequest::ApplyIgnoreLoginsCutoff() { | |
| 27 if (ignore_logins_cutoff_ > 0) { | |
| 28 const base::Time cutoff_time = base::Time::FromTimeT(ignore_logins_cutoff_); | |
| 29 // Count down rather than up since we may be deleting elements. | |
| 30 // Note that in principle it could be more efficient to copy the whole array | |
| 31 // since that's worst-case linear time, but we expect that elements will be | |
| 32 // deleted rarely and lists will be small, so this avoids the copies. | |
| 33 for (size_t i = value.size(); i > 0; --i) { | |
| 34 if (value[i - 1]->date_created < cutoff_time) { | |
| 35 delete value[i - 1]; | |
| 36 value.erase(value.begin() + (i - 1)); | |
| 37 } | |
| 38 } | |
| 39 } | |
| 23 } | 40 } |
| 24 | 41 |
| 25 PasswordStore::GetLoginsRequest::~GetLoginsRequest() { | 42 PasswordStore::GetLoginsRequest::~GetLoginsRequest() { |
| 26 if (canceled()) { | 43 if (canceled()) { |
| 27 STLDeleteElements(&value); | 44 STLDeleteElements(&value); |
| 28 } | 45 } |
| 29 } | 46 } |
| 30 | 47 |
| 31 PasswordStore::PasswordStore() { | 48 PasswordStore::PasswordStore() { |
| 32 } | 49 } |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 54 void PasswordStore::RemoveLoginsCreatedBetween(const base::Time& delete_begin, | 71 void PasswordStore::RemoveLoginsCreatedBetween(const base::Time& delete_begin, |
| 55 const base::Time& delete_end) { | 72 const base::Time& delete_end) { |
| 56 ScheduleTask(base::Bind(&PasswordStore::WrapModificationTask, this, | 73 ScheduleTask(base::Bind(&PasswordStore::WrapModificationTask, this, |
| 57 base::Closure( | 74 base::Closure( |
| 58 base::Bind(&PasswordStore::RemoveLoginsCreatedBetweenImpl, this, | 75 base::Bind(&PasswordStore::RemoveLoginsCreatedBetweenImpl, this, |
| 59 delete_begin, delete_end)))); | 76 delete_begin, delete_end)))); |
| 60 } | 77 } |
| 61 | 78 |
| 62 CancelableRequestProvider::Handle PasswordStore::GetLogins( | 79 CancelableRequestProvider::Handle PasswordStore::GetLogins( |
| 63 const PasswordForm& form, PasswordStoreConsumer* consumer) { | 80 const PasswordForm& form, PasswordStoreConsumer* consumer) { |
| 64 return Schedule(&PasswordStore::GetLoginsImpl, consumer, form); | 81 // Per http://crbug.com/121738, we deliberately ignore saved logins for |
| 82 // http*://www.google.com/ that were stored prior to 2012. (Google now uses | |
| 83 // https://accounts.google.com/ for all login forms, so these should be | |
| 84 // unused.) We don't delete them just yet, and they'll still be visible in the | |
| 85 // password manager, but we won't use them to autofill any forms. This is a | |
| 86 // security feature to help minimize damage that can be done by XSS attacks. | |
| 87 // TODO(mdm): actually delete them at some point, say M24 or so. | |
| 88 time_t ignore_logins_cutoff = 0; | |
| 89 if (form.scheme == PasswordForm::SCHEME_HTML && | |
| 90 (form.signon_realm == "http://www.google.com" || | |
| 91 form.signon_realm == "http://www.google.com/" || | |
|
Tom Sepez
2012/04/28 01:04:08
Is slash the only trailing character that could be
Mike Mammarella
2012/04/30 16:09:45
As far as I know, yes.
| |
| 92 form.signon_realm == "https://www.google.com" || | |
| 93 form.signon_realm == "https://www.google.com/")) { | |
| 94 ignore_logins_cutoff = 1325376000; // 00:00 Jan 1 2012 UTC | |
| 95 } | |
| 96 return Schedule(&PasswordStore::GetLoginsImpl, consumer, form, | |
| 97 ignore_logins_cutoff); | |
| 65 } | 98 } |
| 66 | 99 |
| 67 CancelableRequestProvider::Handle PasswordStore::GetAutofillableLogins( | 100 CancelableRequestProvider::Handle PasswordStore::GetAutofillableLogins( |
| 68 PasswordStoreConsumer* consumer) { | 101 PasswordStoreConsumer* consumer) { |
| 69 return Schedule(&PasswordStore::GetAutofillableLoginsImpl, consumer); | 102 return Schedule(&PasswordStore::GetAutofillableLoginsImpl, consumer); |
| 70 } | 103 } |
| 71 | 104 |
| 72 CancelableRequestProvider::Handle PasswordStore::GetBlacklistLogins( | 105 CancelableRequestProvider::Handle PasswordStore::GetBlacklistLogins( |
| 73 PasswordStoreConsumer* consumer) { | 106 PasswordStoreConsumer* consumer) { |
| 74 return Schedule(&PasswordStore::GetBlacklistLoginsImpl, consumer); | 107 return Schedule(&PasswordStore::GetBlacklistLoginsImpl, consumer); |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 91 PasswordStore::GetLoginsRequest* PasswordStore::NewGetLoginsRequest( | 124 PasswordStore::GetLoginsRequest* PasswordStore::NewGetLoginsRequest( |
| 92 const GetLoginsCallback& callback) { | 125 const GetLoginsCallback& callback) { |
| 93 return new GetLoginsRequest(callback); | 126 return new GetLoginsRequest(callback); |
| 94 } | 127 } |
| 95 | 128 |
| 96 void PasswordStore::ScheduleTask(const base::Closure& task) { | 129 void PasswordStore::ScheduleTask(const base::Closure& task) { |
| 97 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, task); | 130 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, task); |
| 98 } | 131 } |
| 99 | 132 |
| 100 void PasswordStore::ForwardLoginsResult(GetLoginsRequest* request) { | 133 void PasswordStore::ForwardLoginsResult(GetLoginsRequest* request) { |
| 134 request->ApplyIgnoreLoginsCutoff(); | |
| 101 request->ForwardResult(request->handle(), request->value); | 135 request->ForwardResult(request->handle(), request->value); |
| 102 } | 136 } |
| 103 | 137 |
| 104 template<typename BackendFunc> | 138 template<typename BackendFunc> |
| 105 CancelableRequestProvider::Handle PasswordStore::Schedule( | 139 CancelableRequestProvider::Handle PasswordStore::Schedule( |
| 106 BackendFunc func, PasswordStoreConsumer* consumer) { | 140 BackendFunc func, PasswordStoreConsumer* consumer) { |
| 107 scoped_refptr<GetLoginsRequest> request(NewGetLoginsRequest( | 141 scoped_refptr<GetLoginsRequest> request(NewGetLoginsRequest( |
| 108 base::Bind(&PasswordStoreConsumer::OnPasswordStoreRequestDone, | 142 base::Bind(&PasswordStoreConsumer::OnPasswordStoreRequestDone, |
| 109 base::Unretained(consumer)))); | 143 base::Unretained(consumer)))); |
| 110 AddRequest(request, consumer->cancelable_consumer()); | 144 AddRequest(request, consumer->cancelable_consumer()); |
| 111 ScheduleTask(base::Bind(func, this, request)); | 145 ScheduleTask(base::Bind(func, this, request)); |
| 112 return request->handle(); | 146 return request->handle(); |
| 113 } | 147 } |
| 114 | 148 |
| 115 template<typename BackendFunc, typename ArgA> | 149 template<typename BackendFunc> |
| 116 CancelableRequestProvider::Handle PasswordStore::Schedule( | 150 CancelableRequestProvider::Handle PasswordStore::Schedule( |
| 117 BackendFunc func, PasswordStoreConsumer* consumer, const ArgA& a) { | 151 BackendFunc func, PasswordStoreConsumer* consumer, |
| 152 const PasswordForm& form, time_t ignore_logins_cutoff) { | |
| 118 scoped_refptr<GetLoginsRequest> request(NewGetLoginsRequest( | 153 scoped_refptr<GetLoginsRequest> request(NewGetLoginsRequest( |
| 119 base::Bind(&PasswordStoreConsumer::OnPasswordStoreRequestDone, | 154 base::Bind(&PasswordStoreConsumer::OnPasswordStoreRequestDone, |
| 120 base::Unretained(consumer)))); | 155 base::Unretained(consumer)))); |
| 156 request->set_ignore_logins_cutoff(ignore_logins_cutoff); | |
| 121 AddRequest(request, consumer->cancelable_consumer()); | 157 AddRequest(request, consumer->cancelable_consumer()); |
| 122 ScheduleTask(base::Bind(func, this, request, a)); | 158 ScheduleTask(base::Bind(func, this, request, form)); |
| 123 return request->handle(); | 159 return request->handle(); |
| 124 } | 160 } |
| 125 | 161 |
| 126 void PasswordStore::WrapModificationTask(base::Closure task) { | 162 void PasswordStore::WrapModificationTask(base::Closure task) { |
| 127 #if !defined(OS_MACOSX) | 163 #if !defined(OS_MACOSX) |
| 128 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 164 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| 129 #endif // !defined(OS_MACOSX) | 165 #endif // !defined(OS_MACOSX) |
| 130 task.Run(); | 166 task.Run(); |
| 131 PostNotifyLoginsChanged(); | 167 PostNotifyLoginsChanged(); |
| 132 } | 168 } |
| 133 | 169 |
| 134 void PasswordStore::PostNotifyLoginsChanged() { | 170 void PasswordStore::PostNotifyLoginsChanged() { |
| 135 #if !defined(OS_MACOSX) | 171 #if !defined(OS_MACOSX) |
| 136 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 172 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
| 137 #endif // !defined(OS_MACOSX) | 173 #endif // !defined(OS_MACOSX) |
| 138 | |
| 139 BrowserThread::PostTask( | 174 BrowserThread::PostTask( |
| 140 BrowserThread::UI, FROM_HERE, | 175 BrowserThread::UI, FROM_HERE, |
| 141 base::Bind(&PasswordStore::NotifyLoginsChanged, this)); | 176 base::Bind(&PasswordStore::NotifyLoginsChanged, this)); |
| 142 } | 177 } |
| 143 | 178 |
| 144 void PasswordStore::NotifyLoginsChanged() { | 179 void PasswordStore::NotifyLoginsChanged() { |
| 145 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 180 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
| 146 FOR_EACH_OBSERVER(Observer, observers_, OnLoginsChanged()); | 181 FOR_EACH_OBSERVER(Observer, observers_, OnLoginsChanged()); |
| 147 } | 182 } |
| OLD | NEW |