| 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 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 60 // Empty salt in IE Toolbar is \x1\x2...\x14 | 60 // Empty salt in IE Toolbar is \x1\x2...\x14 |
| 61 if (salt.length() != 20) | 61 if (salt.length() != 20) |
| 62 return false; | 62 return false; |
| 63 for (size_t i = 0; i < salt.length(); ++i) { | 63 for (size_t i = 0; i < salt.length(); ++i) { |
| 64 if (salt[i] != i + 1) | 64 if (salt[i] != i + 1) |
| 65 return false; | 65 return false; |
| 66 } | 66 } |
| 67 return true; | 67 return true; |
| 68 } | 68 } |
| 69 | 69 |
| 70 string16 ReadAndDecryptValue(const RegKey& key, const wchar_t* value_name) { | 70 base::string16 ReadAndDecryptValue(const RegKey& key, |
| 71 const wchar_t* value_name) { |
| 71 DWORD data_type = REG_BINARY; | 72 DWORD data_type = REG_BINARY; |
| 72 DWORD data_size = 0; | 73 DWORD data_size = 0; |
| 73 LONG result = key.ReadValue(value_name, NULL, &data_size, &data_type); | 74 LONG result = key.ReadValue(value_name, NULL, &data_size, &data_type); |
| 74 if ((result != ERROR_SUCCESS) || !data_size || data_type != REG_BINARY) | 75 if ((result != ERROR_SUCCESS) || !data_size || data_type != REG_BINARY) |
| 75 return string16(); | 76 return base::string16(); |
| 76 std::vector<uint8> data; | 77 std::vector<uint8> data; |
| 77 data.resize(data_size); | 78 data.resize(data_size); |
| 78 result = key.ReadValue(value_name, &(data[0]), &data_size, &data_type); | 79 result = key.ReadValue(value_name, &(data[0]), &data_size, &data_type); |
| 79 if (result == ERROR_SUCCESS) { | 80 if (result == ERROR_SUCCESS) { |
| 80 std::string out_data; | 81 std::string out_data; |
| 81 if (syncer::DecryptData(data, &out_data)) { | 82 if (syncer::DecryptData(data, &out_data)) { |
| 82 // The actual data is in UTF16 already. | 83 // The actual data is in UTF16 already. |
| 83 if (!(out_data.size() & 1) && (out_data.size() > 2) && | 84 if (!(out_data.size() & 1) && (out_data.size() > 2) && |
| 84 !out_data[out_data.size() - 1] && !out_data[out_data.size() - 2]) { | 85 !out_data[out_data.size() - 1] && !out_data[out_data.size() - 2]) { |
| 85 return string16( | 86 return base::string16( |
| 86 reinterpret_cast<const wchar_t *>(out_data.c_str())); | 87 reinterpret_cast<const wchar_t *>(out_data.c_str())); |
| 87 } | 88 } |
| 88 } | 89 } |
| 89 } | 90 } |
| 90 return string16(); | 91 return base::string16(); |
| 91 } | 92 } |
| 92 | 93 |
| 93 struct { | 94 struct { |
| 94 AutofillFieldType field_type; | 95 AutofillFieldType field_type; |
| 95 const wchar_t *reg_value_name; | 96 const wchar_t *reg_value_name; |
| 96 } profile_reg_values[] = { | 97 } profile_reg_values[] = { |
| 97 { NAME_FIRST, L"name_first" }, | 98 { NAME_FIRST, L"name_first" }, |
| 98 { NAME_MIDDLE, L"name_middle" }, | 99 { NAME_MIDDLE, L"name_middle" }, |
| 99 { NAME_LAST, L"name_last" }, | 100 { NAME_LAST, L"name_last" }, |
| 100 { NAME_SUFFIX, L"name_suffix" }, | 101 { NAME_SUFFIX, L"name_suffix" }, |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 | 142 |
| 142 for (uint32 i = 0; i < key.GetValueCount(); ++i) { | 143 for (uint32 i = 0; i < key.GetValueCount(); ++i) { |
| 143 std::wstring value_name; | 144 std::wstring value_name; |
| 144 if (key.GetValueNameAt(i, &value_name) != ERROR_SUCCESS) | 145 if (key.GetValueNameAt(i, &value_name) != ERROR_SUCCESS) |
| 145 continue; | 146 continue; |
| 146 | 147 |
| 147 RegToFieldMap::const_iterator it = reg_to_field.find(value_name); | 148 RegToFieldMap::const_iterator it = reg_to_field.find(value_name); |
| 148 if (it == reg_to_field.end()) | 149 if (it == reg_to_field.end()) |
| 149 continue; // This field is not imported. | 150 continue; // This field is not imported. |
| 150 | 151 |
| 151 string16 field_value = ReadAndDecryptValue(key, value_name.c_str()); | 152 base::string16 field_value = ReadAndDecryptValue(key, value_name.c_str()); |
| 152 if (!field_value.empty()) { | 153 if (!field_value.empty()) { |
| 153 if (it->second == CREDIT_CARD_NUMBER) | 154 if (it->second == CREDIT_CARD_NUMBER) |
| 154 field_value = DecryptCCNumber(field_value); | 155 field_value = DecryptCCNumber(field_value); |
| 155 | 156 |
| 156 // Phone numbers are stored piece-by-piece, and then reconstructed from | 157 // Phone numbers are stored piece-by-piece, and then reconstructed from |
| 157 // the pieces. The rest of the fields are set "as is". | 158 // the pieces. The rest of the fields are set "as is". |
| 158 if (!phone || !phone->SetInfo(it->second, field_value)) { | 159 if (!phone || !phone->SetInfo(it->second, field_value)) { |
| 159 has_non_empty_fields = true; | 160 has_non_empty_fields = true; |
| 160 form_group->SetInfo(it->second, field_value, app_locale); | 161 form_group->SetInfo(it->second, field_value, app_locale); |
| 161 } | 162 } |
| 162 } | 163 } |
| 163 } | 164 } |
| 164 | 165 |
| 165 return has_non_empty_fields; | 166 return has_non_empty_fields; |
| 166 } | 167 } |
| 167 | 168 |
| 168 // Imports address data from the given registry |key| into the given |profile|, | 169 // Imports address data from the given registry |key| into the given |profile|, |
| 169 // with the help of |reg_to_field|. Returns true if any fields were set, false | 170 // with the help of |reg_to_field|. Returns true if any fields were set, false |
| 170 // otherwise. | 171 // otherwise. |
| 171 bool ImportSingleProfile(const std::string& app_locale, | 172 bool ImportSingleProfile(const std::string& app_locale, |
| 172 const RegKey& key, | 173 const RegKey& key, |
| 173 const RegToFieldMap& reg_to_field, | 174 const RegToFieldMap& reg_to_field, |
| 174 AutofillProfile* profile) { | 175 AutofillProfile* profile) { |
| 175 PhoneNumber::PhoneCombineHelper phone; | 176 PhoneNumber::PhoneCombineHelper phone; |
| 176 bool has_non_empty_fields = | 177 bool has_non_empty_fields = |
| 177 ImportSingleFormGroup(key, reg_to_field, app_locale, profile, &phone); | 178 ImportSingleFormGroup(key, reg_to_field, app_locale, profile, &phone); |
| 178 | 179 |
| 179 // Now re-construct the phones if needed. | 180 // Now re-construct the phones if needed. |
| 180 string16 constructed_number; | 181 base::string16 constructed_number; |
| 181 if (phone.ParseNumber(*profile, app_locale, &constructed_number)) { | 182 if (phone.ParseNumber(*profile, app_locale, &constructed_number)) { |
| 182 has_non_empty_fields = true; | 183 has_non_empty_fields = true; |
| 183 profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, constructed_number); | 184 profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, constructed_number); |
| 184 } | 185 } |
| 185 | 186 |
| 186 return has_non_empty_fields; | 187 return has_non_empty_fields; |
| 187 } | 188 } |
| 188 | 189 |
| 189 // Imports profiles from the IE toolbar and stores them. Asynchronous | 190 // Imports profiles from the IE toolbar and stores them. Asynchronous |
| 190 // if PersonalDataManager has not been loaded yet. Deletes itself on completion. | 191 // if PersonalDataManager has not been loaded yet. Deletes itself on completion. |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 254 std::wstring key_name(kProfileKey); | 255 std::wstring key_name(kProfileKey); |
| 255 key_name.append(L"\\"); | 256 key_name.append(L"\\"); |
| 256 key_name.append(iterator_profiles.Name()); | 257 key_name.append(iterator_profiles.Name()); |
| 257 RegKey key(HKEY_CURRENT_USER, key_name.c_str(), KEY_READ); | 258 RegKey key(HKEY_CURRENT_USER, key_name.c_str(), KEY_READ); |
| 258 AutofillProfile profile; | 259 AutofillProfile profile; |
| 259 if (ImportSingleProfile(app_locale, key, reg_to_field, &profile)) { | 260 if (ImportSingleProfile(app_locale, key, reg_to_field, &profile)) { |
| 260 // Combine phones into whole phone #. | 261 // Combine phones into whole phone #. |
| 261 profiles->push_back(profile); | 262 profiles->push_back(profile); |
| 262 } | 263 } |
| 263 } | 264 } |
| 264 string16 password_hash; | 265 base::string16 password_hash; |
| 265 string16 salt; | 266 base::string16 salt; |
| 266 RegKey cc_key(HKEY_CURRENT_USER, kCreditCardKey, KEY_READ); | 267 RegKey cc_key(HKEY_CURRENT_USER, kCreditCardKey, KEY_READ); |
| 267 if (cc_key.Valid()) { | 268 if (cc_key.Valid()) { |
| 268 password_hash = ReadAndDecryptValue(cc_key, kPasswordHashValue); | 269 password_hash = ReadAndDecryptValue(cc_key, kPasswordHashValue); |
| 269 salt = ReadAndDecryptValue(cc_key, kSaltValue); | 270 salt = ReadAndDecryptValue(cc_key, kSaltValue); |
| 270 } | 271 } |
| 271 | 272 |
| 272 // We import CC profiles only if they are not password protected. | 273 // We import CC profiles only if they are not password protected. |
| 273 if (password_hash.empty() && IsEmptySalt(salt)) { | 274 if (password_hash.empty() && IsEmptySalt(salt)) { |
| 274 base::win::RegistryKeyIterator iterator_cc(HKEY_CURRENT_USER, | 275 base::win::RegistryKeyIterator iterator_cc(HKEY_CURRENT_USER, |
| 275 kCreditCardKey); | 276 kCreditCardKey); |
| 276 for (; iterator_cc.Valid(); ++iterator_cc) { | 277 for (; iterator_cc.Valid(); ++iterator_cc) { |
| 277 std::wstring key_name(kCreditCardKey); | 278 std::wstring key_name(kCreditCardKey); |
| 278 key_name.append(L"\\"); | 279 key_name.append(L"\\"); |
| 279 key_name.append(iterator_cc.Name()); | 280 key_name.append(iterator_cc.Name()); |
| 280 RegKey key(HKEY_CURRENT_USER, key_name.c_str(), KEY_READ); | 281 RegKey key(HKEY_CURRENT_USER, key_name.c_str(), KEY_READ); |
| 281 CreditCard credit_card; | 282 CreditCard credit_card; |
| 282 if (ImportSingleFormGroup( | 283 if (ImportSingleFormGroup( |
| 283 key, reg_to_field, app_locale, &credit_card, NULL)) { | 284 key, reg_to_field, app_locale, &credit_card, NULL)) { |
| 284 string16 cc_number = credit_card.GetRawInfo(CREDIT_CARD_NUMBER); | 285 base::string16 cc_number = credit_card.GetRawInfo(CREDIT_CARD_NUMBER); |
| 285 if (!cc_number.empty()) | 286 if (!cc_number.empty()) |
| 286 credit_cards->push_back(credit_card); | 287 credit_cards->push_back(credit_card); |
| 287 } | 288 } |
| 288 } | 289 } |
| 289 } | 290 } |
| 290 return (profiles->size() + credit_cards->size()) > 0; | 291 return (profiles->size() + credit_cards->size()) > 0; |
| 291 } | 292 } |
| 292 | 293 |
| 293 bool ImportAutofillDataWin(PersonalDataManager* pdm) { | 294 bool ImportAutofillDataWin(PersonalDataManager* pdm) { |
| 294 // In incognito mode we do not have PDM - and we should not import anything. | 295 // In incognito mode we do not have PDM - and we should not import anything. |
| 295 if (!pdm) | 296 if (!pdm) |
| 296 return false; | 297 return false; |
| 297 AutofillImporter *importer = new AutofillImporter(pdm); | 298 AutofillImporter *importer = new AutofillImporter(pdm); |
| 298 // importer will self delete. | 299 // importer will self delete. |
| 299 return importer->ImportProfiles(); | 300 return importer->ImportProfiles(); |
| 300 } | 301 } |
| OLD | NEW |