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 |