| 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 |