| OLD | NEW |
| 1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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 "chrome/browser/importer/firefox_importer_utils.h" | 5 #include "chrome/browser/importer/nss_decryptor_win.h" |
| 6 | |
| 7 #include <shlobj.h> | |
| 8 | |
| 9 #include "base/file_util.h" | 6 #include "base/file_util.h" |
| 10 #include "base/registry.h" | 7 #include "base/sys_string_conversions.h" |
| 11 | 8 |
| 12 namespace { | 9 namespace { |
| 13 | 10 |
| 14 typedef BOOL (WINAPI* SetDllDirectoryFunc)(LPCTSTR lpPathName); | 11 typedef BOOL (WINAPI* SetDllDirectoryFunc)(LPCTSTR lpPathName); |
| 15 | 12 |
| 16 // A helper class whose destructor calls SetDllDirectory(NULL) to undo the | 13 // A helper class whose destructor calls SetDllDirectory(NULL) to undo the |
| 17 // effects of a previous SetDllDirectory call. | 14 // effects of a previous SetDllDirectory call. |
| 18 class SetDllDirectoryCaller { | 15 class SetDllDirectoryCaller { |
| 19 public: | 16 public: |
| 20 explicit SetDllDirectoryCaller() : func_(NULL) { } | 17 explicit SetDllDirectoryCaller() : func_(NULL) { } |
| 21 | 18 |
| 22 ~SetDllDirectoryCaller() { | 19 ~SetDllDirectoryCaller() { |
| 23 if (func_) | 20 if (func_) |
| 24 func_(NULL); | 21 func_(NULL); |
| 25 } | 22 } |
| 26 | 23 |
| 27 // Sets the SetDllDirectory function pointer to activates this object. | 24 // Sets the SetDllDirectory function pointer to activates this object. |
| 28 void set_func(SetDllDirectoryFunc func) { func_ = func; } | 25 void set_func(SetDllDirectoryFunc func) { func_ = func; } |
| 29 | 26 |
| 30 private: | 27 private: |
| 31 SetDllDirectoryFunc func_; | 28 SetDllDirectoryFunc func_; |
| 32 }; | 29 }; |
| 33 | 30 |
| 34 } // namespace | 31 } // namespace |
| 35 | 32 |
| 36 // NOTE: Keep these in order since we need test all those paths according | |
| 37 // to priority. For example. One machine has multiple users. One non-admin | |
| 38 // user installs Firefox 2, which causes there is a Firefox2 entry under HKCU. | |
| 39 // One admin user installs Firefox 3, which causes there is a Firefox 3 entry | |
| 40 // under HKLM. So when the non-admin user log in, we should deal with Firefox 2 | |
| 41 // related data instead of Firefox 3. | |
| 42 static const HKEY kFireFoxRegistryPaths[] = { | |
| 43 HKEY_CURRENT_USER, | |
| 44 HKEY_LOCAL_MACHINE | |
| 45 }; | |
| 46 | |
| 47 int GetCurrentFirefoxMajorVersionFromRegistry() { | |
| 48 TCHAR ver_buffer[128]; | |
| 49 DWORD ver_buffer_length = sizeof(ver_buffer); | |
| 50 int highest_version = 0; | |
| 51 // When installing Firefox with admin account, the product keys will be | |
| 52 // written under HKLM\Mozilla. Otherwise it the keys will be written under | |
| 53 // HKCU\Mozilla. | |
| 54 for (int i = 0; i < arraysize(kFireFoxRegistryPaths); ++i) { | |
| 55 bool result = ReadFromRegistry(kFireFoxRegistryPaths[i], | |
| 56 L"Software\\Mozilla\\Mozilla Firefox", | |
| 57 L"CurrentVersion", ver_buffer, &ver_buffer_length); | |
| 58 if (!result) | |
| 59 continue; | |
| 60 highest_version = std::max(highest_version, _wtoi(ver_buffer)); | |
| 61 } | |
| 62 return highest_version; | |
| 63 } | |
| 64 | |
| 65 std::wstring GetFirefoxInstallPathFromRegistry() { | |
| 66 // Detects the path that Firefox is installed in. | |
| 67 std::wstring registry_path = L"Software\\Mozilla\\Mozilla Firefox"; | |
| 68 TCHAR buffer[MAX_PATH]; | |
| 69 DWORD buffer_length = sizeof(buffer); | |
| 70 bool result; | |
| 71 result = ReadFromRegistry(HKEY_LOCAL_MACHINE, registry_path.c_str(), | |
| 72 L"CurrentVersion", buffer, &buffer_length); | |
| 73 if (!result) | |
| 74 return std::wstring(); | |
| 75 registry_path += L"\\" + std::wstring(buffer) + L"\\Main"; | |
| 76 buffer_length = sizeof(buffer); | |
| 77 result = ReadFromRegistry(HKEY_LOCAL_MACHINE, registry_path.c_str(), | |
| 78 L"Install Directory", buffer, &buffer_length); | |
| 79 if (!result) | |
| 80 return std::wstring(); | |
| 81 return buffer; | |
| 82 } | |
| 83 | |
| 84 FilePath GetProfilesINI() { | |
| 85 FilePath ini_file; | |
| 86 // The default location of the profile folder containing user data is | |
| 87 // under the "Application Data" folder in Windows XP. | |
| 88 wchar_t buffer[MAX_PATH] = {0}; | |
| 89 if (SUCCEEDED(SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, | |
| 90 SHGFP_TYPE_CURRENT, buffer))) { | |
| 91 ini_file = FilePath(buffer).Append(L"Mozilla\\Firefox\\profiles.ini"); | |
| 92 } | |
| 93 if (file_util::PathExists(ini_file)) | |
| 94 return ini_file; | |
| 95 | |
| 96 return FilePath(); | |
| 97 } | |
| 98 | |
| 99 // static | 33 // static |
| 100 const wchar_t NSSDecryptor::kNSS3Library[] = L"nss3.dll"; | 34 const wchar_t NSSDecryptor::kNSS3Library[] = L"nss3.dll"; |
| 101 const wchar_t NSSDecryptor::kSoftokn3Library[] = L"softokn3.dll"; | 35 const wchar_t NSSDecryptor::kSoftokn3Library[] = L"softokn3.dll"; |
| 102 const wchar_t NSSDecryptor::kPLDS4Library[] = L"plds4.dll"; | 36 const wchar_t NSSDecryptor::kPLDS4Library[] = L"plds4.dll"; |
| 103 const wchar_t NSSDecryptor::kNSPR4Library[] = L"nspr4.dll"; | 37 const wchar_t NSSDecryptor::kNSPR4Library[] = L"nspr4.dll"; |
| 104 | 38 |
| 105 bool NSSDecryptor::Init(const std::wstring& dll_path, | 39 bool NSSDecryptor::Init(const std::wstring& dll_path, |
| 106 const std::wstring& db_path) { | 40 const std::wstring& db_path) { |
| 107 // We call SetDllDirectory to work around a Purify bug (GetModuleHandle | 41 // We call SetDllDirectory to work around a Purify bug (GetModuleHandle |
| 108 // fails inside Purify under certain conditions). SetDllDirectory only | 42 // fails inside Purify under certain conditions). SetDllDirectory only |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 if (softokn3_dll_ == NULL) { | 83 if (softokn3_dll_ == NULL) { |
| 150 Free(); | 84 Free(); |
| 151 return false; | 85 return false; |
| 152 } | 86 } |
| 153 } | 87 } |
| 154 HMODULE plds4_dll = GetModuleHandle(kPLDS4Library); | 88 HMODULE plds4_dll = GetModuleHandle(kPLDS4Library); |
| 155 HMODULE nspr4_dll = GetModuleHandle(kNSPR4Library); | 89 HMODULE nspr4_dll = GetModuleHandle(kNSPR4Library); |
| 156 | 90 |
| 157 return InitNSS(db_path, plds4_dll, nspr4_dll); | 91 return InitNSS(db_path, plds4_dll, nspr4_dll); |
| 158 } | 92 } |
| 93 |
| 94 NSSDecryptor::NSSDecryptor() |
| 95 : NSS_Init(NULL), NSS_Shutdown(NULL), PK11_GetInternalKeySlot(NULL), |
| 96 PK11_CheckUserPassword(NULL), PK11_FreeSlot(NULL), |
| 97 PK11_Authenticate(NULL), PK11SDR_Decrypt(NULL), SECITEM_FreeItem(NULL), |
| 98 PL_ArenaFinish(NULL), PR_Cleanup(NULL), |
| 99 nss3_dll_(NULL), softokn3_dll_(NULL), |
| 100 is_nss_initialized_(false) { |
| 101 } |
| 102 |
| 103 NSSDecryptor::~NSSDecryptor() { |
| 104 Free(); |
| 105 } |
| 106 |
| 107 bool NSSDecryptor::InitNSS(const std::wstring& db_path, |
| 108 base::NativeLibrary plds4_dll, |
| 109 base::NativeLibrary nspr4_dll) { |
| 110 // NSPR DLLs are already loaded now. |
| 111 if (plds4_dll == NULL || nspr4_dll == NULL) { |
| 112 Free(); |
| 113 return false; |
| 114 } |
| 115 |
| 116 // Gets the function address. |
| 117 NSS_Init = (NSSInitFunc) |
| 118 base::GetFunctionPointerFromNativeLibrary(nss3_dll_, "NSS_Init"); |
| 119 NSS_Shutdown = (NSSShutdownFunc) |
| 120 base::GetFunctionPointerFromNativeLibrary(nss3_dll_, "NSS_Shutdown"); |
| 121 PK11_GetInternalKeySlot = (PK11GetInternalKeySlotFunc) |
| 122 base::GetFunctionPointerFromNativeLibrary(nss3_dll_, |
| 123 "PK11_GetInternalKeySlot"); |
| 124 PK11_FreeSlot = (PK11FreeSlotFunc) |
| 125 base::GetFunctionPointerFromNativeLibrary(nss3_dll_, "PK11_FreeSlot"); |
| 126 PK11_Authenticate = (PK11AuthenticateFunc) |
| 127 base::GetFunctionPointerFromNativeLibrary(nss3_dll_, "PK11_Authenticate"); |
| 128 PK11SDR_Decrypt = (PK11SDRDecryptFunc) |
| 129 base::GetFunctionPointerFromNativeLibrary(nss3_dll_, "PK11SDR_Decrypt"); |
| 130 SECITEM_FreeItem = (SECITEMFreeItemFunc) |
| 131 base::GetFunctionPointerFromNativeLibrary(nss3_dll_, "SECITEM_FreeItem"); |
| 132 PL_ArenaFinish = (PLArenaFinishFunc) |
| 133 base::GetFunctionPointerFromNativeLibrary(plds4_dll, "PL_ArenaFinish"); |
| 134 PR_Cleanup = (PRCleanupFunc) |
| 135 base::GetFunctionPointerFromNativeLibrary(nspr4_dll, "PR_Cleanup"); |
| 136 |
| 137 if (NSS_Init == NULL || NSS_Shutdown == NULL || |
| 138 PK11_GetInternalKeySlot == NULL || PK11_FreeSlot == NULL || |
| 139 PK11_Authenticate == NULL || PK11SDR_Decrypt == NULL || |
| 140 SECITEM_FreeItem == NULL || PL_ArenaFinish == NULL || |
| 141 PR_Cleanup == NULL) { |
| 142 Free(); |
| 143 return false; |
| 144 } |
| 145 |
| 146 SECStatus result = NSS_Init(base::SysWideToNativeMB(db_path).c_str()); |
| 147 if (result != SECSuccess) { |
| 148 Free(); |
| 149 return false; |
| 150 } |
| 151 |
| 152 is_nss_initialized_ = true; |
| 153 return true; |
| 154 } |
| 155 |
| 156 void NSSDecryptor::Free() { |
| 157 if (is_nss_initialized_) { |
| 158 NSS_Shutdown(); |
| 159 PL_ArenaFinish(); |
| 160 PR_Cleanup(); |
| 161 is_nss_initialized_ = false; |
| 162 } |
| 163 if (softokn3_dll_ != NULL) |
| 164 base::UnloadNativeLibrary(softokn3_dll_); |
| 165 if (nss3_dll_ != NULL) |
| 166 base::UnloadNativeLibrary(nss3_dll_); |
| 167 NSS_Init = NULL; |
| 168 NSS_Shutdown = NULL; |
| 169 PK11_GetInternalKeySlot = NULL; |
| 170 PK11_FreeSlot = NULL; |
| 171 PK11_Authenticate = NULL; |
| 172 PK11SDR_Decrypt = NULL; |
| 173 SECITEM_FreeItem = NULL; |
| 174 PL_ArenaFinish = NULL; |
| 175 PR_Cleanup = NULL; |
| 176 nss3_dll_ = NULL; |
| 177 softokn3_dll_ = NULL; |
| 178 } |
| OLD | NEW |