Bug 316995 - When migrating from Internet Explorer http auth passwords are not migrated, patch by Michael Wu, r=mconnor

This commit is contained in:
martijn.martijn%gmail.com 2006-07-23 20:11:53 +00:00
parent 8eb18ee78b
commit c54ab46e4e
2 changed files with 87 additions and 11 deletions

View File

@ -78,6 +78,7 @@
#include "nsIGlobalHistory.h" #include "nsIGlobalHistory.h"
#include "nsIRDFRemoteDataSource.h" #include "nsIRDFRemoteDataSource.h"
#include "nsIURI.h" #include "nsIURI.h"
#include "nsIPasswordManager.h"
#include "nsIPasswordManagerInternal.h" #include "nsIPasswordManagerInternal.h"
#include "nsIFormHistory.h" #include "nsIFormHistory.h"
#include "nsIRDFService.h" #include "nsIRDFService.h"
@ -692,7 +693,7 @@ nsIEProfileMigrator::CopyHistory(PRBool aReplace)
// //
// <USER_ID> is a long string that uniquely identifies the current user // <USER_ID> is a long string that uniquely identifies the current user
// <IE_PSS_GUID> is a GUID that identifies a subsection of the Protected Storage // <IE_PSS_GUID> is a GUID that identifies a subsection of the Protected Storage
// System specific to MSIE. This GUID is defined below ("IEPStoreGUID"). // System specific to MSIE. This GUID is defined below ("IEPStoreAutocompGUID").
// //
// Data is stored in the Protected Strage System ("PStore") in the following // Data is stored in the Protected Strage System ("PStore") in the following
// format: // format:
@ -745,12 +746,16 @@ struct SignonData {
char* realm; char* realm;
}; };
// The IEPStore GUID is the registry key under which IE Protected Store data lives. // IE PStore Type GUIDs
// {e161255a-37c3-11d2-bcaa-00c04fd929db} // {e161255a-37c3-11d2-bcaa-00c04fd929db} Autocomplete Password & Form Data
static GUID IEPStoreGUID = { 0xe161255a, 0x37c3, 0x11d2, { 0xbc, 0xaa, 0x00, 0xc0, 0x4f, 0xd9, 0x29, 0xdb } }; // Subtype has same GUID
// {5e7e8100-9138-11d1-945a-00c04fc308ff} HTTP/FTP Auth Login Data
// Subtype has a zero GUID
static GUID IEPStoreAutocompGUID = { 0xe161255a, 0x37c3, 0x11d2, { 0xbc, 0xaa, 0x00, 0xc0, 0x4f, 0xd9, 0x29, 0xdb } };
static GUID IEPStoreSiteAuthGUID = { 0x5e7e8100, 0x9138, 0x11d1, { 0x94, 0x5a, 0x00, 0xc0, 0x4f, 0xc3, 0x08, 0xff } };
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// IMPORTING PASSWORDS // IMPORTING AUTOCOMPLETE PASSWORDS
// //
// This is tricky, and requires 2 passes through the subkeys in IE's PStore // This is tricky, and requires 2 passes through the subkeys in IE's PStore
// section. // section.
@ -822,6 +827,76 @@ nsIEProfileMigrator::CopyPasswords(PRBool aReplace)
if (NS_SUCCEEDED(rv)) if (NS_SUCCEEDED(rv))
ResolveAndMigrateSignons(PStore, &signonsFound); ResolveAndMigrateSignons(PStore, &signonsFound);
MigrateSiteAuthSignons(PStore);
return NS_OK;
}
///////////////////////////////////////////////////////////////////////////////
// IMPORTING SITE AUTHENTICATION PASSWORDS
//
// This is simple and straightforward. We iterate through the part of the
// PStore that matches the type GUID defined in IEPStoreSiteAuthGUID and
// a zero subtype GUID. For each item, we check the data for a ':' that
// separates the username and password parts. If there is no ':', we give up.
// After that, we check to see if the name of the item starts with "DPAPI:".
// We bail out if that's the case, because we can't handle those yet.
// However, if everything is all and well, we convert the itemName to a realm
// string that the password manager can work with and save this login
// via AddUser.
nsresult
nsIEProfileMigrator::MigrateSiteAuthSignons(IPStore* aPStore)
{
HRESULT hr;
NS_ENSURE_ARG_POINTER(aPStore);
nsCOMPtr<nsIPasswordManager> pwmgr(do_GetService("@mozilla.org/passwordmanager;1"));
if (!pwmgr)
return NS_OK;
GUID mtGuid = {0};
IEnumPStoreItemsPtr enumItems = NULL;
hr = aPStore->EnumItems(0, &IEPStoreSiteAuthGUID, &mtGuid, 0, &enumItems);
if (SUCCEEDED(hr) && enumItems != NULL) {
LPWSTR itemName = NULL;
while ((enumItems->Next(1, &itemName, 0) == S_OK) && itemName) {
unsigned long count = 0;
unsigned char* data = NULL;
hr = aPStore->ReadItem(0, &IEPStoreSiteAuthGUID, &mtGuid, itemName, &count, &data, NULL, 0);
if (SUCCEEDED(hr) && data) {
unsigned long i;
unsigned char* password = NULL;
for (i = 0; i < count; i++)
if (data[i] == ':') {
data[i] = '\0';
if (i + 1 < count)
password = &data[i + 1];
break;
}
nsAutoString tmp(itemName);
tmp.Truncate(6);
if (tmp.Equals(NS_LITERAL_STRING("DPAPI:"))) // often FTP logins
password = NULL; // We can't handle these yet
if (password) {
int idx;
nsAutoString realm(itemName);
idx = realm.FindChar('/');
if (idx) {
realm.Replace(idx, 1, NS_LITERAL_STRING(" ("));
realm.Append(NS_LITERAL_STRING(")"));
}
pwmgr->AddUser(NS_ConvertUTF16toUTF8(realm),
NS_ConvertUTF8toUTF16((char *)data),
NS_ConvertUTF8toUTF16((char *)password));
}
::CoTaskMemFree(data);
}
}
}
return NS_OK; return NS_OK;
} }
@ -833,7 +908,7 @@ nsIEProfileMigrator::GetSignonsListFromPStore(IPStore* aPStore, nsVoidArray* aSi
NS_ENSURE_ARG_POINTER(aPStore); NS_ENSURE_ARG_POINTER(aPStore);
IEnumPStoreItemsPtr enumItems = NULL; IEnumPStoreItemsPtr enumItems = NULL;
hr = aPStore->EnumItems(0, &IEPStoreGUID, &IEPStoreGUID, 0, &enumItems); hr = aPStore->EnumItems(0, &IEPStoreAutocompGUID, &IEPStoreAutocompGUID, 0, &enumItems);
if (SUCCEEDED(hr) && enumItems != NULL) { if (SUCCEEDED(hr) && enumItems != NULL) {
LPWSTR itemName = NULL; LPWSTR itemName = NULL;
while ((enumItems->Next(1, &itemName, 0) == S_OK) && itemName) { while ((enumItems->Next(1, &itemName, 0) == S_OK) && itemName) {
@ -842,7 +917,7 @@ nsIEProfileMigrator::GetSignonsListFromPStore(IPStore* aPStore, nsVoidArray* aSi
// We are responsible for freeing |data| using |CoTaskMemFree|!! // We are responsible for freeing |data| using |CoTaskMemFree|!!
// But we don't do it here... // But we don't do it here...
hr = aPStore->ReadItem(0, &IEPStoreGUID, &IEPStoreGUID, itemName, &count, &data, NULL, 0); hr = aPStore->ReadItem(0, &IEPStoreAutocompGUID, &IEPStoreAutocompGUID, itemName, &count, &data, NULL, 0);
if (SUCCEEDED(hr) && data) { if (SUCCEEDED(hr) && data) {
nsAutoString itemNameString(itemName); nsAutoString itemNameString(itemName);
nsAutoString suffix; nsAutoString suffix;
@ -915,14 +990,14 @@ nsIEProfileMigrator::ResolveAndMigrateSignons(IPStore* aPStore, nsVoidArray* aSi
HRESULT hr; HRESULT hr;
IEnumPStoreItemsPtr enumItems = NULL; IEnumPStoreItemsPtr enumItems = NULL;
hr = aPStore->EnumItems(0, &IEPStoreGUID, &IEPStoreGUID, 0, &enumItems); hr = aPStore->EnumItems(0, &IEPStoreAutocompGUID, &IEPStoreAutocompGUID, 0, &enumItems);
if (SUCCEEDED(hr) && enumItems != NULL) { if (SUCCEEDED(hr) && enumItems != NULL) {
LPWSTR itemName = NULL; LPWSTR itemName = NULL;
while ((enumItems->Next(1, &itemName, 0) == S_OK) && itemName) { while ((enumItems->Next(1, &itemName, 0) == S_OK) && itemName) {
unsigned long count = 0; unsigned long count = 0;
unsigned char* data = NULL; unsigned char* data = NULL;
hr = aPStore->ReadItem(0, &IEPStoreGUID, &IEPStoreGUID, itemName, &count, &data, NULL, 0); hr = aPStore->ReadItem(0, &IEPStoreAutocompGUID, &IEPStoreAutocompGUID, itemName, &count, &data, NULL, 0);
if (SUCCEEDED(hr) && data) { if (SUCCEEDED(hr) && data) {
nsAutoString itemNameString(itemName); nsAutoString itemNameString(itemName);
nsAutoString suffix; nsAutoString suffix;
@ -1042,7 +1117,7 @@ nsIEProfileMigrator::CopyFormData(PRBool aReplace)
return NS_OK; return NS_OK;
IEnumPStoreItemsPtr enumItems = NULL; IEnumPStoreItemsPtr enumItems = NULL;
hr = PStore->EnumItems(0, &IEPStoreGUID, &IEPStoreGUID, 0, &enumItems); hr = PStore->EnumItems(0, &IEPStoreAutocompGUID, &IEPStoreAutocompGUID, 0, &enumItems);
if (SUCCEEDED(hr) && enumItems != NULL) { if (SUCCEEDED(hr) && enumItems != NULL) {
LPWSTR itemName = NULL; LPWSTR itemName = NULL;
while ((enumItems->Next(1, &itemName, 0) == S_OK) && itemName) { while ((enumItems->Next(1, &itemName, 0) == S_OK) && itemName) {
@ -1050,7 +1125,7 @@ nsIEProfileMigrator::CopyFormData(PRBool aReplace)
unsigned char* data = NULL; unsigned char* data = NULL;
// We are responsible for freeing |data| using |CoTaskMemFree|!! // We are responsible for freeing |data| using |CoTaskMemFree|!!
hr = PStore->ReadItem(0, &IEPStoreGUID, &IEPStoreGUID, itemName, &count, &data, NULL, 0); hr = PStore->ReadItem(0, &IEPStoreAutocompGUID, &IEPStoreAutocompGUID, itemName, &count, &data, NULL, 0);
if (SUCCEEDED(hr) && data) { if (SUCCEEDED(hr) && data) {
nsAutoString itemNameString(itemName); nsAutoString itemNameString(itemName);
nsAutoString suffix; nsAutoString suffix;

View File

@ -79,6 +79,7 @@ protected:
PRBool KeyIsURI(const nsAString& aKey, char** aRealm); PRBool KeyIsURI(const nsAString& aKey, char** aRealm);
nsresult CopyPasswords(PRBool aReplace); nsresult CopyPasswords(PRBool aReplace);
nsresult MigrateSiteAuthSignons(IPStore* aPStore);
nsresult GetSignonsListFromPStore(IPStore* aPStore, nsVoidArray* aSignonsFound); nsresult GetSignonsListFromPStore(IPStore* aPStore, nsVoidArray* aSignonsFound);
nsresult ResolveAndMigrateSignons(IPStore* aPStore, nsVoidArray* aSignonsFound); nsresult ResolveAndMigrateSignons(IPStore* aPStore, nsVoidArray* aSignonsFound);
void EnumerateUsernames(const nsAString& aKey, PRUnichar* aData, unsigned long aCount, nsVoidArray* aSignonsFound); void EnumerateUsernames(const nsAString& aKey, PRUnichar* aData, unsigned long aCount, nsVoidArray* aSignonsFound);