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 } | 23 } |
| 24 | 24 |
| 25 void PasswordStore::GetLoginsRequest::ApplyIgnoreLoginsCutoff() { | |
| 26 if (!ignore_logins_cutoff_.is_null()) { | |
| 27 // Count down rather than up since we may be deleting elements. | |
| 28 // Note that in principle it could be more efficient to copy the whole array | |
| 29 // since that's worst-case linear time, but we expect that elements will be | |
| 30 // deleted rarely and lists will be small, so this avoids the copies. | |
| 31 for (size_t i = value.size(); i > 0; --i) { | |
| 32 if (value[i - 1]->date_created < ignore_logins_cutoff_) { | |
| 33 delete value[i - 1]; | |
| 34 value.erase(value.begin() + (i - 1)); | |
| 35 } | |
| 36 } | |
| 37 } | |
| 38 } | |
| 39 | |
| 25 PasswordStore::GetLoginsRequest::~GetLoginsRequest() { | 40 PasswordStore::GetLoginsRequest::~GetLoginsRequest() { |
| 26 if (canceled()) { | 41 if (canceled()) { |
| 27 STLDeleteElements(&value); | 42 STLDeleteElements(&value); |
| 28 } | 43 } |
| 29 } | 44 } |
| 30 | 45 |
| 31 PasswordStore::PasswordStore() { | 46 PasswordStore::PasswordStore() { |
| 32 } | 47 } |
| 33 | 48 |
| 34 bool PasswordStore::Init() { | 49 bool PasswordStore::Init() { |
| (...skipping 19 matching lines...) Expand all Loading... | |
| 54 void PasswordStore::RemoveLoginsCreatedBetween(const base::Time& delete_begin, | 69 void PasswordStore::RemoveLoginsCreatedBetween(const base::Time& delete_begin, |
| 55 const base::Time& delete_end) { | 70 const base::Time& delete_end) { |
| 56 ScheduleTask(base::Bind(&PasswordStore::WrapModificationTask, this, | 71 ScheduleTask(base::Bind(&PasswordStore::WrapModificationTask, this, |
| 57 base::Closure( | 72 base::Closure( |
| 58 base::Bind(&PasswordStore::RemoveLoginsCreatedBetweenImpl, this, | 73 base::Bind(&PasswordStore::RemoveLoginsCreatedBetweenImpl, this, |
| 59 delete_begin, delete_end)))); | 74 delete_begin, delete_end)))); |
| 60 } | 75 } |
| 61 | 76 |
| 62 CancelableRequestProvider::Handle PasswordStore::GetLogins( | 77 CancelableRequestProvider::Handle PasswordStore::GetLogins( |
| 63 const PasswordForm& form, PasswordStoreConsumer* consumer) { | 78 const PasswordForm& form, PasswordStoreConsumer* consumer) { |
| 64 return Schedule(&PasswordStore::GetLoginsImpl, consumer, form); | 79 // Per http://crbug.com/121738, we deliberately ignore saved logins for |
| 80 // http*://www.google.com/ that were stored prior to 2012. (Google now uses | |
| 81 // https://accounts.google.com/ for all login forms, so these should be | |
| 82 // unused.) We don't delete them just yet, and they'll still be visible in the | |
| 83 // password manager, but we won't use them to autofill any forms. This is a | |
| 84 // security feature to help minimize damage that can be done by XSS attacks. | |
| 85 // TODO(mdm): actually delete them at some point, say M24 or so. | |
| 86 base::Time ignore_logins_cutoff; // the null time | |
| 87 if (form.scheme == PasswordForm::SCHEME_HTML && | |
| 88 (form.signon_realm == "http://www.google.com" || | |
| 89 form.signon_realm == "http://www.google.com/" || | |
| 90 form.signon_realm == "https://www.google.com" || | |
| 91 form.signon_realm == "https://www.google.com/")) { | |
| 92 static const base::Time::Exploded exploded_cutoff = | |
| 93 { 2012, 1, 0, 1, 0, 0, 0, 0 }; // 00:00 Jan 1 2012 | |
|
Mike Mammarella
2012/05/08 20:28:19
Hmm. This isn't actually as self-documenting as I
| |
| 94 ignore_logins_cutoff = base::Time::FromUTCExploded(exploded_cutoff); | |
| 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, const base::Time& 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 |