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 |