diff options
Diffstat (limited to 'chromium/components/autofill/core/browser/autofill_ie_toolbar_import_win.cc')
-rw-r--r-- | chromium/components/autofill/core/browser/autofill_ie_toolbar_import_win.cc | 312 |
1 files changed, 0 insertions, 312 deletions
diff --git a/chromium/components/autofill/core/browser/autofill_ie_toolbar_import_win.cc b/chromium/components/autofill/core/browser/autofill_ie_toolbar_import_win.cc deleted file mode 100644 index 388e079f3ef..00000000000 --- a/chromium/components/autofill/core/browser/autofill_ie_toolbar_import_win.cc +++ /dev/null @@ -1,312 +0,0 @@ -// Copyright 2013 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/core/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/core/browser/autofill_country.h" -#include "components/autofill/core/browser/autofill_profile.h" -#include "components/autofill/core/browser/credit_card.h" -#include "components/autofill/core/browser/crypto/rc4_decryptor.h" -#include "components/autofill/core/browser/field_types.h" -#include "components/autofill/core/browser/form_group.h" -#include "components/autofill/core/browser/personal_data_manager.h" -#include "components/autofill/core/browser/personal_data_manager_observer.h" -#include "components/autofill/core/browser/phone_number.h" -#include "components/autofill/core/browser/phone_number_i18n.h" -#include "components/webdata/encryptor/encryptor.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::string 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 (Encryptor::DecryptString(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 { - ServerFieldType 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, ServerFieldType> 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(AutofillType(it->second), field_value)) { - has_non_empty_fields = true; - form_group->SetInfo(AutofillType(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 |