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 "components/autofill/browser/autofill_ie_toolbar_import_win.h" | 5 #include "components/autofill/browser/autofill_ie_toolbar_import_win.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 #include <map> | 8 #include <map> |
9 #include <string> | 9 #include <string> |
10 #include <vector> | 10 #include <vector> |
(...skipping 12 matching lines...) Expand all Loading... |
23 #include "components/autofill/browser/personal_data_manager.h" | 23 #include "components/autofill/browser/personal_data_manager.h" |
24 #include "components/autofill/browser/personal_data_manager_observer.h" | 24 #include "components/autofill/browser/personal_data_manager_observer.h" |
25 #include "components/autofill/browser/phone_number.h" | 25 #include "components/autofill/browser/phone_number.h" |
26 #include "components/autofill/browser/phone_number_i18n.h" | 26 #include "components/autofill/browser/phone_number_i18n.h" |
27 #include "sync/util/data_encryption_win.h" | 27 #include "sync/util/data_encryption_win.h" |
28 | 28 |
29 using base::win::RegKey; | 29 using base::win::RegKey; |
30 | 30 |
31 // Forward declaration. This function is not in unnamed namespace as it | 31 // Forward declaration. This function is not in unnamed namespace as it |
32 // is referenced in the unittest. | 32 // is referenced in the unittest. |
33 bool ImportCurrentUserProfiles(std::vector<AutofillProfile>* profiles, | 33 bool ImportCurrentUserProfiles(const std::string& app_locale, |
| 34 std::vector<AutofillProfile>* profiles, |
34 std::vector<CreditCard>* credit_cards); | 35 std::vector<CreditCard>* credit_cards); |
35 namespace { | 36 namespace { |
36 | 37 |
37 const wchar_t* const kProfileKey = | 38 const wchar_t* const kProfileKey = |
38 L"Software\\Google\\Google Toolbar\\4.0\\Autofill\\Profiles"; | 39 L"Software\\Google\\Google Toolbar\\4.0\\Autofill\\Profiles"; |
39 const wchar_t* const kCreditCardKey = | 40 const wchar_t* const kCreditCardKey = |
40 L"Software\\Google\\Google Toolbar\\4.0\\Autofill\\Credit Cards"; | 41 L"Software\\Google\\Google Toolbar\\4.0\\Autofill\\Credit Cards"; |
41 const wchar_t* const kPasswordHashValue = L"password_hash"; | 42 const wchar_t* const kPasswordHashValue = L"password_hash"; |
42 const wchar_t* const kSaltValue = L"salt"; | 43 const wchar_t* const kSaltValue = L"salt"; |
43 | 44 |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
123 }; | 124 }; |
124 | 125 |
125 typedef std::map<std::wstring, AutofillFieldType> RegToFieldMap; | 126 typedef std::map<std::wstring, AutofillFieldType> RegToFieldMap; |
126 | 127 |
127 // Imports address or credit card data from the given registry |key| into the | 128 // Imports address or credit card data from the given registry |key| into the |
128 // given |form_group|, with the help of |reg_to_field|. When importing address | 129 // given |form_group|, with the help of |reg_to_field|. When importing address |
129 // data, writes the phone data into |phone|; otherwise, |phone| should be null. | 130 // data, writes the phone data into |phone|; otherwise, |phone| should be null. |
130 // Returns true if any fields were set, false otherwise. | 131 // Returns true if any fields were set, false otherwise. |
131 bool ImportSingleFormGroup(const RegKey& key, | 132 bool ImportSingleFormGroup(const RegKey& key, |
132 const RegToFieldMap& reg_to_field, | 133 const RegToFieldMap& reg_to_field, |
| 134 const std::string& app_locale, |
133 FormGroup* form_group, | 135 FormGroup* form_group, |
134 PhoneNumber::PhoneCombineHelper* phone) { | 136 PhoneNumber::PhoneCombineHelper* phone) { |
135 if (!key.Valid()) | 137 if (!key.Valid()) |
136 return false; | 138 return false; |
137 | 139 |
138 bool has_non_empty_fields = false; | 140 bool has_non_empty_fields = false; |
139 | 141 |
140 const std::string app_locale = AutofillCountry::ApplicationLocale(); | |
141 for (uint32 i = 0; i < key.GetValueCount(); ++i) { | 142 for (uint32 i = 0; i < key.GetValueCount(); ++i) { |
142 std::wstring value_name; | 143 std::wstring value_name; |
143 if (key.GetValueNameAt(i, &value_name) != ERROR_SUCCESS) | 144 if (key.GetValueNameAt(i, &value_name) != ERROR_SUCCESS) |
144 continue; | 145 continue; |
145 | 146 |
146 RegToFieldMap::const_iterator it = reg_to_field.find(value_name); | 147 RegToFieldMap::const_iterator it = reg_to_field.find(value_name); |
147 if (it == reg_to_field.end()) | 148 if (it == reg_to_field.end()) |
148 continue; // This field is not imported. | 149 continue; // This field is not imported. |
149 | 150 |
150 string16 field_value = ReadAndDecryptValue(key, value_name.c_str()); | 151 string16 field_value = ReadAndDecryptValue(key, value_name.c_str()); |
151 if (!field_value.empty()) { | 152 if (!field_value.empty()) { |
152 if (it->second == CREDIT_CARD_NUMBER) | 153 if (it->second == CREDIT_CARD_NUMBER) |
153 field_value = DecryptCCNumber(field_value); | 154 field_value = DecryptCCNumber(field_value); |
154 | 155 |
155 // Phone numbers are stored piece-by-piece, and then reconstructed from | 156 // Phone numbers are stored piece-by-piece, and then reconstructed from |
156 // the pieces. The rest of the fields are set "as is". | 157 // the pieces. The rest of the fields are set "as is". |
157 if (!phone || !phone->SetInfo(it->second, field_value)) { | 158 if (!phone || !phone->SetInfo(it->second, field_value)) { |
158 has_non_empty_fields = true; | 159 has_non_empty_fields = true; |
159 form_group->SetInfo(it->second, field_value, app_locale); | 160 form_group->SetInfo(it->second, field_value, app_locale); |
160 } | 161 } |
161 } | 162 } |
162 } | 163 } |
163 | 164 |
164 return has_non_empty_fields; | 165 return has_non_empty_fields; |
165 } | 166 } |
166 | 167 |
167 // Imports address data from the given registry |key| into the given |profile|, | 168 // Imports address data from the given registry |key| into the given |profile|, |
168 // with the help of |reg_to_field|. Returns true if any fields were set, false | 169 // with the help of |reg_to_field|. Returns true if any fields were set, false |
169 // otherwise. | 170 // otherwise. |
170 bool ImportSingleProfile(const RegKey& key, | 171 bool ImportSingleProfile(const std::string& app_locale, |
| 172 const RegKey& key, |
171 const RegToFieldMap& reg_to_field, | 173 const RegToFieldMap& reg_to_field, |
172 AutofillProfile* profile) { | 174 AutofillProfile* profile) { |
173 PhoneNumber::PhoneCombineHelper phone; | 175 PhoneNumber::PhoneCombineHelper phone; |
174 bool has_non_empty_fields = | 176 bool has_non_empty_fields = |
175 ImportSingleFormGroup(key, reg_to_field, profile, &phone); | 177 ImportSingleFormGroup(key, reg_to_field, app_locale, profile, &phone); |
176 | 178 |
177 // Now re-construct the phones if needed. | 179 // Now re-construct the phones if needed. |
178 string16 constructed_number; | 180 string16 constructed_number; |
179 const std::string app_locale = AutofillCountry::ApplicationLocale(); | |
180 if (phone.ParseNumber(*profile, app_locale, &constructed_number)) { | 181 if (phone.ParseNumber(*profile, app_locale, &constructed_number)) { |
181 has_non_empty_fields = true; | 182 has_non_empty_fields = true; |
182 profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, constructed_number); | 183 profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, constructed_number); |
183 } | 184 } |
184 | 185 |
185 return has_non_empty_fields; | 186 return has_non_empty_fields; |
186 } | 187 } |
187 | 188 |
188 // Imports profiles from the IE toolbar and stores them. Asynchronous | 189 // Imports profiles from the IE toolbar and stores them. Asynchronous |
189 // if PersonalDataManager has not been loaded yet. Deletes itself on completion. | 190 // if PersonalDataManager has not been loaded yet. Deletes itself on completion. |
190 class AutofillImporter : public PersonalDataManagerObserver { | 191 class AutofillImporter : public PersonalDataManagerObserver { |
191 public: | 192 public: |
192 explicit AutofillImporter(PersonalDataManager* personal_data_manager) | 193 explicit AutofillImporter(PersonalDataManager* personal_data_manager) |
193 : personal_data_manager_(personal_data_manager) { | 194 : personal_data_manager_(personal_data_manager) { |
194 personal_data_manager_->AddObserver(this); | 195 personal_data_manager_->AddObserver(this); |
195 } | 196 } |
196 | 197 |
197 bool ImportProfiles() { | 198 bool ImportProfiles() { |
198 if (!ImportCurrentUserProfiles(&profiles_, &credit_cards_)) { | 199 if (!ImportCurrentUserProfiles(personal_data_manager_->app_locale(), |
| 200 &profiles_, |
| 201 &credit_cards_)) { |
199 delete this; | 202 delete this; |
200 return false; | 203 return false; |
201 } | 204 } |
202 if (personal_data_manager_->IsDataLoaded()) | 205 if (personal_data_manager_->IsDataLoaded()) |
203 OnPersonalDataChanged(); | 206 OnPersonalDataChanged(); |
204 return true; | 207 return true; |
205 } | 208 } |
206 | 209 |
207 // PersonalDataManagerObserver: | 210 // PersonalDataManagerObserver: |
208 virtual void OnPersonalDataChanged() OVERRIDE { | 211 virtual void OnPersonalDataChanged() OVERRIDE { |
(...skipping 16 matching lines...) Expand all Loading... |
225 PersonalDataManager* personal_data_manager_; | 228 PersonalDataManager* personal_data_manager_; |
226 std::vector<AutofillProfile> profiles_; | 229 std::vector<AutofillProfile> profiles_; |
227 std::vector<CreditCard> credit_cards_; | 230 std::vector<CreditCard> credit_cards_; |
228 }; | 231 }; |
229 | 232 |
230 } // namespace | 233 } // namespace |
231 | 234 |
232 // Imports Autofill profiles and credit cards from IE Toolbar if present and not | 235 // Imports Autofill profiles and credit cards from IE Toolbar if present and not |
233 // password protected. Returns true if data is successfully retrieved. False if | 236 // password protected. Returns true if data is successfully retrieved. False if |
234 // there is no data, data is password protected or error occurred. | 237 // there is no data, data is password protected or error occurred. |
235 bool ImportCurrentUserProfiles(std::vector<AutofillProfile>* profiles, | 238 bool ImportCurrentUserProfiles(const std::string& app_locale, |
| 239 std::vector<AutofillProfile>* profiles, |
236 std::vector<CreditCard>* credit_cards) { | 240 std::vector<CreditCard>* credit_cards) { |
237 DCHECK(profiles); | 241 DCHECK(profiles); |
238 DCHECK(credit_cards); | 242 DCHECK(credit_cards); |
239 | 243 |
240 // Create a map of possible fields for a quick access. | 244 // Create a map of possible fields for a quick access. |
241 RegToFieldMap reg_to_field; | 245 RegToFieldMap reg_to_field; |
242 for (size_t i = 0; i < arraysize(profile_reg_values); ++i) { | 246 for (size_t i = 0; i < arraysize(profile_reg_values); ++i) { |
243 reg_to_field[std::wstring(profile_reg_values[i].reg_value_name)] = | 247 reg_to_field[std::wstring(profile_reg_values[i].reg_value_name)] = |
244 profile_reg_values[i].field_type; | 248 profile_reg_values[i].field_type; |
245 } | 249 } |
246 | 250 |
247 base::win::RegistryKeyIterator iterator_profiles(HKEY_CURRENT_USER, | 251 base::win::RegistryKeyIterator iterator_profiles(HKEY_CURRENT_USER, |
248 kProfileKey); | 252 kProfileKey); |
249 for (; iterator_profiles.Valid(); ++iterator_profiles) { | 253 for (; iterator_profiles.Valid(); ++iterator_profiles) { |
250 std::wstring key_name(kProfileKey); | 254 std::wstring key_name(kProfileKey); |
251 key_name.append(L"\\"); | 255 key_name.append(L"\\"); |
252 key_name.append(iterator_profiles.Name()); | 256 key_name.append(iterator_profiles.Name()); |
253 RegKey key(HKEY_CURRENT_USER, key_name.c_str(), KEY_READ); | 257 RegKey key(HKEY_CURRENT_USER, key_name.c_str(), KEY_READ); |
254 AutofillProfile profile; | 258 AutofillProfile profile; |
255 if (ImportSingleProfile(key, reg_to_field, &profile)) { | 259 if (ImportSingleProfile(app_locale, key, reg_to_field, &profile)) { |
256 // Combine phones into whole phone #. | 260 // Combine phones into whole phone #. |
257 profiles->push_back(profile); | 261 profiles->push_back(profile); |
258 } | 262 } |
259 } | 263 } |
260 string16 password_hash; | 264 string16 password_hash; |
261 string16 salt; | 265 string16 salt; |
262 RegKey cc_key(HKEY_CURRENT_USER, kCreditCardKey, KEY_READ); | 266 RegKey cc_key(HKEY_CURRENT_USER, kCreditCardKey, KEY_READ); |
263 if (cc_key.Valid()) { | 267 if (cc_key.Valid()) { |
264 password_hash = ReadAndDecryptValue(cc_key, kPasswordHashValue); | 268 password_hash = ReadAndDecryptValue(cc_key, kPasswordHashValue); |
265 salt = ReadAndDecryptValue(cc_key, kSaltValue); | 269 salt = ReadAndDecryptValue(cc_key, kSaltValue); |
266 } | 270 } |
267 | 271 |
268 // We import CC profiles only if they are not password protected. | 272 // We import CC profiles only if they are not password protected. |
269 if (password_hash.empty() && IsEmptySalt(salt)) { | 273 if (password_hash.empty() && IsEmptySalt(salt)) { |
270 base::win::RegistryKeyIterator iterator_cc(HKEY_CURRENT_USER, | 274 base::win::RegistryKeyIterator iterator_cc(HKEY_CURRENT_USER, |
271 kCreditCardKey); | 275 kCreditCardKey); |
272 for (; iterator_cc.Valid(); ++iterator_cc) { | 276 for (; iterator_cc.Valid(); ++iterator_cc) { |
273 std::wstring key_name(kCreditCardKey); | 277 std::wstring key_name(kCreditCardKey); |
274 key_name.append(L"\\"); | 278 key_name.append(L"\\"); |
275 key_name.append(iterator_cc.Name()); | 279 key_name.append(iterator_cc.Name()); |
276 RegKey key(HKEY_CURRENT_USER, key_name.c_str(), KEY_READ); | 280 RegKey key(HKEY_CURRENT_USER, key_name.c_str(), KEY_READ); |
277 CreditCard credit_card; | 281 CreditCard credit_card; |
278 if (ImportSingleFormGroup(key, reg_to_field, &credit_card, NULL)) { | 282 if (ImportSingleFormGroup( |
| 283 key, reg_to_field, app_locale, &credit_card, NULL)) { |
279 string16 cc_number = credit_card.GetRawInfo(CREDIT_CARD_NUMBER); | 284 string16 cc_number = credit_card.GetRawInfo(CREDIT_CARD_NUMBER); |
280 if (!cc_number.empty()) | 285 if (!cc_number.empty()) |
281 credit_cards->push_back(credit_card); | 286 credit_cards->push_back(credit_card); |
282 } | 287 } |
283 } | 288 } |
284 } | 289 } |
285 return (profiles->size() + credit_cards->size()) > 0; | 290 return (profiles->size() + credit_cards->size()) > 0; |
286 } | 291 } |
287 | 292 |
288 bool ImportAutofillDataWin(PersonalDataManager* pdm) { | 293 bool ImportAutofillDataWin(PersonalDataManager* pdm) { |
289 // In incognito mode we do not have PDM - and we should not import anything. | 294 // In incognito mode we do not have PDM - and we should not import anything. |
290 if (!pdm) | 295 if (!pdm) |
291 return false; | 296 return false; |
292 AutofillImporter *importer = new AutofillImporter(pdm); | 297 AutofillImporter *importer = new AutofillImporter(pdm); |
293 // importer will self delete. | 298 // importer will self delete. |
294 return importer->ImportProfiles(); | 299 return importer->ImportProfiles(); |
295 } | 300 } |
OLD | NEW |