| Index: components/autofill/browser/autofill_ie_toolbar_import_win.cc
|
| diff --git a/components/autofill/browser/autofill_ie_toolbar_import_win.cc b/components/autofill/browser/autofill_ie_toolbar_import_win.cc
|
| deleted file mode 100644
|
| index 0020eb34b3656d67e5621bb261dc76255d8befde..0000000000000000000000000000000000000000
|
| --- a/components/autofill/browser/autofill_ie_toolbar_import_win.cc
|
| +++ /dev/null
|
| @@ -1,312 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -#include "components/autofill/browser/autofill_ie_toolbar_import_win.h"
|
| -
|
| -#include <stddef.h>
|
| -#include <map>
|
| -#include <string>
|
| -#include <vector>
|
| -
|
| -#include "base/basictypes.h"
|
| -#include "base/compiler_specific.h"
|
| -#include "base/logging.h"
|
| -#include "base/strings/string16.h"
|
| -#include "base/win/registry.h"
|
| -#include "components/autofill/browser/autofill_country.h"
|
| -#include "components/autofill/browser/autofill_profile.h"
|
| -#include "components/autofill/browser/credit_card.h"
|
| -#include "components/autofill/browser/crypto/rc4_decryptor.h"
|
| -#include "components/autofill/browser/field_types.h"
|
| -#include "components/autofill/browser/form_group.h"
|
| -#include "components/autofill/browser/personal_data_manager.h"
|
| -#include "components/autofill/browser/personal_data_manager_observer.h"
|
| -#include "components/autofill/browser/phone_number.h"
|
| -#include "components/autofill/browser/phone_number_i18n.h"
|
| -#include "sync/util/data_encryption_win.h"
|
| -
|
| -using base::win::RegKey;
|
| -
|
| -namespace autofill {
|
| -
|
| -// Forward declaration. This function is not in unnamed namespace as it
|
| -// is referenced in the unittest.
|
| -bool ImportCurrentUserProfiles(const std::string& app_locale,
|
| - std::vector<AutofillProfile>* profiles,
|
| - std::vector<CreditCard>* credit_cards);
|
| -namespace {
|
| -
|
| -const wchar_t* const kProfileKey =
|
| - L"Software\\Google\\Google Toolbar\\4.0\\Autofill\\Profiles";
|
| -const wchar_t* const kCreditCardKey =
|
| - L"Software\\Google\\Google Toolbar\\4.0\\Autofill\\Credit Cards";
|
| -const wchar_t* const kPasswordHashValue = L"password_hash";
|
| -const wchar_t* const kSaltValue = L"salt";
|
| -
|
| -// This string is stored along with saved addresses and credit cards in the
|
| -// WebDB, and hence should not be modified, so that it remains consistent over
|
| -// time.
|
| -const char kIEToolbarImportOrigin[] = "Imported from Internet Explorer";
|
| -
|
| -// This is RC4 decryption for Toolbar credit card data. This is necessary
|
| -// because it is not standard, so Crypto API cannot be used.
|
| -std::wstring DecryptCCNumber(const std::wstring& data) {
|
| - const wchar_t* kEmptyKey =
|
| - L"\x3605\xCEE5\xCE49\x44F7\xCF4E\xF6CC\x604B\xFCBE\xC70A\x08FD";
|
| - const size_t kMacLen = 10;
|
| -
|
| - if (data.length() <= kMacLen)
|
| - return std::wstring();
|
| -
|
| - RC4Decryptor rc4_algorithm(kEmptyKey);
|
| - return rc4_algorithm.Run(data.substr(kMacLen));
|
| -}
|
| -
|
| -bool IsEmptySalt(std::wstring const& salt) {
|
| - // Empty salt in IE Toolbar is \x1\x2...\x14
|
| - if (salt.length() != 20)
|
| - return false;
|
| - for (size_t i = 0; i < salt.length(); ++i) {
|
| - if (salt[i] != i + 1)
|
| - return false;
|
| - }
|
| - return true;
|
| -}
|
| -
|
| -base::string16 ReadAndDecryptValue(const RegKey& key,
|
| - const wchar_t* value_name) {
|
| - DWORD data_type = REG_BINARY;
|
| - DWORD data_size = 0;
|
| - LONG result = key.ReadValue(value_name, NULL, &data_size, &data_type);
|
| - if ((result != ERROR_SUCCESS) || !data_size || data_type != REG_BINARY)
|
| - return base::string16();
|
| - std::vector<uint8> data;
|
| - data.resize(data_size);
|
| - result = key.ReadValue(value_name, &(data[0]), &data_size, &data_type);
|
| - if (result == ERROR_SUCCESS) {
|
| - std::string out_data;
|
| - if (syncer::DecryptData(data, &out_data)) {
|
| - // The actual data is in UTF16 already.
|
| - if (!(out_data.size() & 1) && (out_data.size() > 2) &&
|
| - !out_data[out_data.size() - 1] && !out_data[out_data.size() - 2]) {
|
| - return base::string16(
|
| - reinterpret_cast<const wchar_t *>(out_data.c_str()));
|
| - }
|
| - }
|
| - }
|
| - return base::string16();
|
| -}
|
| -
|
| -struct {
|
| - AutofillFieldType field_type;
|
| - const wchar_t *reg_value_name;
|
| -} profile_reg_values[] = {
|
| - { NAME_FIRST, L"name_first" },
|
| - { NAME_MIDDLE, L"name_middle" },
|
| - { NAME_LAST, L"name_last" },
|
| - { NAME_SUFFIX, L"name_suffix" },
|
| - { EMAIL_ADDRESS, L"email" },
|
| - { COMPANY_NAME, L"company_name" },
|
| - { PHONE_HOME_NUMBER, L"phone_home_number" },
|
| - { PHONE_HOME_CITY_CODE, L"phone_home_city_code" },
|
| - { PHONE_HOME_COUNTRY_CODE, L"phone_home_country_code" },
|
| - { ADDRESS_HOME_LINE1, L"address_home_line1" },
|
| - { ADDRESS_HOME_LINE2, L"address_home_line2" },
|
| - { ADDRESS_HOME_CITY, L"address_home_city" },
|
| - { ADDRESS_HOME_STATE, L"address_home_state" },
|
| - { ADDRESS_HOME_ZIP, L"address_home_zip" },
|
| - { ADDRESS_HOME_COUNTRY, L"address_home_country" },
|
| - { ADDRESS_BILLING_LINE1, L"address_billing_line1" },
|
| - { ADDRESS_BILLING_LINE2, L"address_billing_line2" },
|
| - { ADDRESS_BILLING_CITY, L"address_billing_city" },
|
| - { ADDRESS_BILLING_STATE, L"address_billing_state" },
|
| - { ADDRESS_BILLING_ZIP, L"address_billing_zip" },
|
| - { ADDRESS_BILLING_COUNTRY, L"address_billing_country" },
|
| - { CREDIT_CARD_NAME, L"credit_card_name" },
|
| - { CREDIT_CARD_NUMBER, L"credit_card_number" },
|
| - { CREDIT_CARD_EXP_MONTH, L"credit_card_exp_month" },
|
| - { CREDIT_CARD_EXP_4_DIGIT_YEAR, L"credit_card_exp_4_digit_year" },
|
| - { CREDIT_CARD_TYPE, L"credit_card_type" },
|
| - // We do not import verification code.
|
| -};
|
| -
|
| -typedef std::map<std::wstring, AutofillFieldType> RegToFieldMap;
|
| -
|
| -// Imports address or credit card data from the given registry |key| into the
|
| -// given |form_group|, with the help of |reg_to_field|. When importing address
|
| -// data, writes the phone data into |phone|; otherwise, |phone| should be null.
|
| -// Returns true if any fields were set, false otherwise.
|
| -bool ImportSingleFormGroup(const RegKey& key,
|
| - const RegToFieldMap& reg_to_field,
|
| - const std::string& app_locale,
|
| - FormGroup* form_group,
|
| - PhoneNumber::PhoneCombineHelper* phone) {
|
| - if (!key.Valid())
|
| - return false;
|
| -
|
| - bool has_non_empty_fields = false;
|
| -
|
| - for (uint32 i = 0; i < key.GetValueCount(); ++i) {
|
| - std::wstring value_name;
|
| - if (key.GetValueNameAt(i, &value_name) != ERROR_SUCCESS)
|
| - continue;
|
| -
|
| - RegToFieldMap::const_iterator it = reg_to_field.find(value_name);
|
| - if (it == reg_to_field.end())
|
| - continue; // This field is not imported.
|
| -
|
| - base::string16 field_value = ReadAndDecryptValue(key, value_name.c_str());
|
| - if (!field_value.empty()) {
|
| - if (it->second == CREDIT_CARD_NUMBER)
|
| - field_value = DecryptCCNumber(field_value);
|
| -
|
| - // Phone numbers are stored piece-by-piece, and then reconstructed from
|
| - // the pieces. The rest of the fields are set "as is".
|
| - if (!phone || !phone->SetInfo(it->second, field_value)) {
|
| - has_non_empty_fields = true;
|
| - form_group->SetInfo(it->second, field_value, app_locale);
|
| - }
|
| - }
|
| - }
|
| -
|
| - return has_non_empty_fields;
|
| -}
|
| -
|
| -// Imports address data from the given registry |key| into the given |profile|,
|
| -// with the help of |reg_to_field|. Returns true if any fields were set, false
|
| -// otherwise.
|
| -bool ImportSingleProfile(const std::string& app_locale,
|
| - const RegKey& key,
|
| - const RegToFieldMap& reg_to_field,
|
| - AutofillProfile* profile) {
|
| - PhoneNumber::PhoneCombineHelper phone;
|
| - bool has_non_empty_fields =
|
| - ImportSingleFormGroup(key, reg_to_field, app_locale, profile, &phone);
|
| -
|
| - // Now re-construct the phones if needed.
|
| - base::string16 constructed_number;
|
| - if (phone.ParseNumber(*profile, app_locale, &constructed_number)) {
|
| - has_non_empty_fields = true;
|
| - profile->SetRawInfo(PHONE_HOME_WHOLE_NUMBER, constructed_number);
|
| - }
|
| -
|
| - return has_non_empty_fields;
|
| -}
|
| -
|
| -// Imports profiles from the IE toolbar and stores them. Asynchronous
|
| -// if PersonalDataManager has not been loaded yet. Deletes itself on completion.
|
| -class AutofillImporter : public PersonalDataManagerObserver {
|
| - public:
|
| - explicit AutofillImporter(PersonalDataManager* personal_data_manager)
|
| - : personal_data_manager_(personal_data_manager) {
|
| - personal_data_manager_->AddObserver(this);
|
| - }
|
| -
|
| - bool ImportProfiles() {
|
| - if (!ImportCurrentUserProfiles(personal_data_manager_->app_locale(),
|
| - &profiles_,
|
| - &credit_cards_)) {
|
| - delete this;
|
| - return false;
|
| - }
|
| - if (personal_data_manager_->IsDataLoaded())
|
| - OnPersonalDataChanged();
|
| - return true;
|
| - }
|
| -
|
| - // PersonalDataManagerObserver:
|
| - virtual void OnPersonalDataChanged() OVERRIDE {
|
| - for (std::vector<AutofillProfile>::const_iterator iter = profiles_.begin();
|
| - iter != profiles_.end(); ++iter) {
|
| - personal_data_manager_->AddProfile(*iter);
|
| - }
|
| - for (std::vector<CreditCard>::const_iterator iter = credit_cards_.begin();
|
| - iter != credit_cards_.end(); ++iter) {
|
| - personal_data_manager_->AddCreditCard(*iter);
|
| - }
|
| - delete this;
|
| - }
|
| -
|
| - private:
|
| - ~AutofillImporter() {
|
| - personal_data_manager_->RemoveObserver(this);
|
| - }
|
| -
|
| - PersonalDataManager* personal_data_manager_;
|
| - std::vector<AutofillProfile> profiles_;
|
| - std::vector<CreditCard> credit_cards_;
|
| -};
|
| -
|
| -} // namespace
|
| -
|
| -// Imports Autofill profiles and credit cards from IE Toolbar if present and not
|
| -// password protected. Returns true if data is successfully retrieved. False if
|
| -// there is no data, data is password protected or error occurred.
|
| -bool ImportCurrentUserProfiles(const std::string& app_locale,
|
| - std::vector<AutofillProfile>* profiles,
|
| - std::vector<CreditCard>* credit_cards) {
|
| - DCHECK(profiles);
|
| - DCHECK(credit_cards);
|
| -
|
| - // Create a map of possible fields for a quick access.
|
| - RegToFieldMap reg_to_field;
|
| - for (size_t i = 0; i < arraysize(profile_reg_values); ++i) {
|
| - reg_to_field[std::wstring(profile_reg_values[i].reg_value_name)] =
|
| - profile_reg_values[i].field_type;
|
| - }
|
| -
|
| - base::win::RegistryKeyIterator iterator_profiles(HKEY_CURRENT_USER,
|
| - kProfileKey);
|
| - for (; iterator_profiles.Valid(); ++iterator_profiles) {
|
| - std::wstring key_name(kProfileKey);
|
| - key_name.append(L"\\");
|
| - key_name.append(iterator_profiles.Name());
|
| - RegKey key(HKEY_CURRENT_USER, key_name.c_str(), KEY_READ);
|
| - AutofillProfile profile;
|
| - profile.set_origin(kIEToolbarImportOrigin);
|
| - if (ImportSingleProfile(app_locale, key, reg_to_field, &profile)) {
|
| - // Combine phones into whole phone #.
|
| - profiles->push_back(profile);
|
| - }
|
| - }
|
| - base::string16 password_hash;
|
| - base::string16 salt;
|
| - RegKey cc_key(HKEY_CURRENT_USER, kCreditCardKey, KEY_READ);
|
| - if (cc_key.Valid()) {
|
| - password_hash = ReadAndDecryptValue(cc_key, kPasswordHashValue);
|
| - salt = ReadAndDecryptValue(cc_key, kSaltValue);
|
| - }
|
| -
|
| - // We import CC profiles only if they are not password protected.
|
| - if (password_hash.empty() && IsEmptySalt(salt)) {
|
| - base::win::RegistryKeyIterator iterator_cc(HKEY_CURRENT_USER,
|
| - kCreditCardKey);
|
| - for (; iterator_cc.Valid(); ++iterator_cc) {
|
| - std::wstring key_name(kCreditCardKey);
|
| - key_name.append(L"\\");
|
| - key_name.append(iterator_cc.Name());
|
| - RegKey key(HKEY_CURRENT_USER, key_name.c_str(), KEY_READ);
|
| - CreditCard credit_card;
|
| - credit_card.set_origin(kIEToolbarImportOrigin);
|
| - if (ImportSingleFormGroup(
|
| - key, reg_to_field, app_locale, &credit_card, NULL)) {
|
| - base::string16 cc_number = credit_card.GetRawInfo(CREDIT_CARD_NUMBER);
|
| - if (!cc_number.empty())
|
| - credit_cards->push_back(credit_card);
|
| - }
|
| - }
|
| - }
|
| - return (profiles->size() + credit_cards->size()) > 0;
|
| -}
|
| -
|
| -bool ImportAutofillDataWin(PersonalDataManager* pdm) {
|
| - // In incognito mode we do not have PDM - and we should not import anything.
|
| - if (!pdm)
|
| - return false;
|
| - AutofillImporter *importer = new AutofillImporter(pdm);
|
| - // importer will self delete.
|
| - return importer->ImportProfiles();
|
| -}
|
| -
|
| -} // namespace autofill
|
|
|