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 time_t ignore_logins_cutoff = 0; | |
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 ignore_logins_cutoff = 1325376000; // 00:00 Jan 1 2012 UTC | |
Ilya Sherman
2012/05/07 07:15:10
nit: Please use base::Time::FromUTCExploded() -- b
Mike Mammarella
2012/05/07 15:48:13
I thought about that, but it's both less concise a
Ilya Sherman
2012/05/07 20:12:02
The TimeT functions are documented as deprecated:
| |
93 } | |
94 return Schedule(&PasswordStore::GetLoginsImpl, consumer, form, | |
95 base::Time::FromTimeT(ignore_logins_cutoff)); | |
65 } | 96 } |
66 | 97 |
67 CancelableRequestProvider::Handle PasswordStore::GetAutofillableLogins( | 98 CancelableRequestProvider::Handle PasswordStore::GetAutofillableLogins( |
68 PasswordStoreConsumer* consumer) { | 99 PasswordStoreConsumer* consumer) { |
69 return Schedule(&PasswordStore::GetAutofillableLoginsImpl, consumer); | 100 return Schedule(&PasswordStore::GetAutofillableLoginsImpl, consumer); |
70 } | 101 } |
71 | 102 |
72 CancelableRequestProvider::Handle PasswordStore::GetBlacklistLogins( | 103 CancelableRequestProvider::Handle PasswordStore::GetBlacklistLogins( |
73 PasswordStoreConsumer* consumer) { | 104 PasswordStoreConsumer* consumer) { |
74 return Schedule(&PasswordStore::GetBlacklistLoginsImpl, consumer); | 105 return Schedule(&PasswordStore::GetBlacklistLoginsImpl, consumer); |
(...skipping 16 matching lines...) Expand all Loading... | |
91 PasswordStore::GetLoginsRequest* PasswordStore::NewGetLoginsRequest( | 122 PasswordStore::GetLoginsRequest* PasswordStore::NewGetLoginsRequest( |
92 const GetLoginsCallback& callback) { | 123 const GetLoginsCallback& callback) { |
93 return new GetLoginsRequest(callback); | 124 return new GetLoginsRequest(callback); |
94 } | 125 } |
95 | 126 |
96 void PasswordStore::ScheduleTask(const base::Closure& task) { | 127 void PasswordStore::ScheduleTask(const base::Closure& task) { |
97 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, task); | 128 BrowserThread::PostTask(BrowserThread::DB, FROM_HERE, task); |
98 } | 129 } |
99 | 130 |
100 void PasswordStore::ForwardLoginsResult(GetLoginsRequest* request) { | 131 void PasswordStore::ForwardLoginsResult(GetLoginsRequest* request) { |
132 request->ApplyIgnoreLoginsCutoff(); | |
101 request->ForwardResult(request->handle(), request->value); | 133 request->ForwardResult(request->handle(), request->value); |
102 } | 134 } |
103 | 135 |
104 template<typename BackendFunc> | 136 template<typename BackendFunc> |
105 CancelableRequestProvider::Handle PasswordStore::Schedule( | 137 CancelableRequestProvider::Handle PasswordStore::Schedule( |
106 BackendFunc func, PasswordStoreConsumer* consumer) { | 138 BackendFunc func, PasswordStoreConsumer* consumer) { |
107 scoped_refptr<GetLoginsRequest> request(NewGetLoginsRequest( | 139 scoped_refptr<GetLoginsRequest> request(NewGetLoginsRequest( |
108 base::Bind(&PasswordStoreConsumer::OnPasswordStoreRequestDone, | 140 base::Bind(&PasswordStoreConsumer::OnPasswordStoreRequestDone, |
109 base::Unretained(consumer)))); | 141 base::Unretained(consumer)))); |
110 AddRequest(request, consumer->cancelable_consumer()); | 142 AddRequest(request, consumer->cancelable_consumer()); |
111 ScheduleTask(base::Bind(func, this, request)); | 143 ScheduleTask(base::Bind(func, this, request)); |
112 return request->handle(); | 144 return request->handle(); |
113 } | 145 } |
114 | 146 |
115 template<typename BackendFunc, typename ArgA> | 147 template<typename BackendFunc> |
116 CancelableRequestProvider::Handle PasswordStore::Schedule( | 148 CancelableRequestProvider::Handle PasswordStore::Schedule( |
117 BackendFunc func, PasswordStoreConsumer* consumer, const ArgA& a) { | 149 BackendFunc func, PasswordStoreConsumer* consumer, |
150 const PasswordForm& form, const base::Time& ignore_logins_cutoff) { | |
118 scoped_refptr<GetLoginsRequest> request(NewGetLoginsRequest( | 151 scoped_refptr<GetLoginsRequest> request(NewGetLoginsRequest( |
119 base::Bind(&PasswordStoreConsumer::OnPasswordStoreRequestDone, | 152 base::Bind(&PasswordStoreConsumer::OnPasswordStoreRequestDone, |
120 base::Unretained(consumer)))); | 153 base::Unretained(consumer)))); |
154 request->set_ignore_logins_cutoff(ignore_logins_cutoff); | |
121 AddRequest(request, consumer->cancelable_consumer()); | 155 AddRequest(request, consumer->cancelable_consumer()); |
122 ScheduleTask(base::Bind(func, this, request, a)); | 156 ScheduleTask(base::Bind(func, this, request, form)); |
123 return request->handle(); | 157 return request->handle(); |
124 } | 158 } |
125 | 159 |
126 void PasswordStore::WrapModificationTask(base::Closure task) { | 160 void PasswordStore::WrapModificationTask(base::Closure task) { |
127 #if !defined(OS_MACOSX) | 161 #if !defined(OS_MACOSX) |
128 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 162 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
129 #endif // !defined(OS_MACOSX) | 163 #endif // !defined(OS_MACOSX) |
130 task.Run(); | 164 task.Run(); |
131 PostNotifyLoginsChanged(); | 165 PostNotifyLoginsChanged(); |
132 } | 166 } |
133 | 167 |
134 void PasswordStore::PostNotifyLoginsChanged() { | 168 void PasswordStore::PostNotifyLoginsChanged() { |
135 #if !defined(OS_MACOSX) | 169 #if !defined(OS_MACOSX) |
136 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); | 170 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::DB)); |
137 #endif // !defined(OS_MACOSX) | 171 #endif // !defined(OS_MACOSX) |
138 | |
139 BrowserThread::PostTask( | 172 BrowserThread::PostTask( |
140 BrowserThread::UI, FROM_HERE, | 173 BrowserThread::UI, FROM_HERE, |
141 base::Bind(&PasswordStore::NotifyLoginsChanged, this)); | 174 base::Bind(&PasswordStore::NotifyLoginsChanged, this)); |
142 } | 175 } |
143 | 176 |
144 void PasswordStore::NotifyLoginsChanged() { | 177 void PasswordStore::NotifyLoginsChanged() { |
145 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 178 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); |
146 FOR_EACH_OBSERVER(Observer, observers_, OnLoginsChanged()); | 179 FOR_EACH_OBSERVER(Observer, observers_, OnLoginsChanged()); |
147 } | 180 } |
OLD | NEW |