diff options
Diffstat (limited to 'mailnews/import/oexpress/nsOESettings.cpp')
-rw-r--r-- | mailnews/import/oexpress/nsOESettings.cpp | 921 |
1 files changed, 921 insertions, 0 deletions
diff --git a/mailnews/import/oexpress/nsOESettings.cpp b/mailnews/import/oexpress/nsOESettings.cpp new file mode 100644 index 000000000..600acf74c --- /dev/null +++ b/mailnews/import/oexpress/nsOESettings.cpp @@ -0,0 +1,921 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +/* + + Outlook Express (Win32) settings + +*/ + +#include "nsOESettings.h" +#include "mozilla/WindowsVersion.h" +#include "nsCOMPtr.h" +#include "nscore.h" +#include "nsMsgUtils.h" +#include "nsOEImport.h" +#include "nsIComponentManager.h" +#include "nsIServiceManager.h" +#include "nsOERegUtil.h" +#include "nsIMsgAccountManager.h" +#include "nsIMsgAccount.h" +#include "nsIImportSettings.h" +#include "nsMsgBaseCID.h" +#include "nsMsgCompCID.h" +#include "nsMsgI18N.h" +#include "nsISmtpService.h" +#include "nsISmtpServer.h" +#include "nsOEStringBundle.h" +#include "OEDebugLog.h" +#include "nsIPop3IncomingServer.h" +#include "nsIImapIncomingServer.h" +#include "nsINntpIncomingServer.h" +#include "stdlib.h" +#include <windows.h> +#include "nsIWindowsRegKey.h" +#include "nsComponentManagerUtils.h" + +#ifdef MOZILLA_INTERNAL_API +#include "nsNativeCharsetUtils.h" +#else +#include "nsMsgI18N.h" +#define NS_CopyNativeToUnicode(source, dest) \ + nsMsgI18NConvertToUnicode(nsMsgI18NFileSystemCharset(), source, dest) +#define NS_CopyUnicodeToNative(source, dest) \ + nsMsgI18NConvertFromUnicode(nsMsgI18NFileSystemCharset(), source, dest) +#endif + +class OESettings { +public: + static nsresult GetDefaultMailAccount(nsAString &aMailAccount); + static nsresult GetCheckMailInterval(uint32_t *aInterval); + static nsresult Find50Key(nsIWindowsRegKey **aKey); + static nsresult Find40Key(nsIWindowsRegKey **aKey); + static nsresult FindAccountsKey(nsIWindowsRegKey **aKey); + + static bool DoImport(nsIMsgAccount **ppAccount); + + static bool DoIMAPServer(nsIMsgAccountManager *aMgr, + nsIWindowsRegKey *aKey, + const nsString &aServerName, + nsIMsgAccount **ppAccount); + static bool DoPOP3Server(nsIMsgAccountManager *aMgr, + nsIWindowsRegKey *aKey, + const nsString &aServerName, + nsIMsgAccount **ppAccount); + static bool DoNNTPServer(nsIMsgAccountManager *aMgr, + nsIWindowsRegKey *aKey, + const nsString &aServerName, + nsIMsgAccount **ppAccount); + + static void SetIncomingServerProperties(nsIMsgIncomingServer *aServer, + nsIWindowsRegKey *aKey, + const nsString &aKeyNamePrefix); + + static void SetIdentities(nsIMsgAccountManager *aMgr, + nsIMsgAccount *aAccount, + nsIWindowsRegKey *aKey, + const nsString &aIncomgUserName, + int32_t authMethodIncoming, bool isNNTP); + static void SetSmtpServer(const nsString &aSmtpServer, + nsIWindowsRegKey *aKey, + nsIMsgIdentity *aId, + const nsString &aIncomgUserName, + int32_t authMethodIncoming); + static nsresult GetAccountName(nsIWindowsRegKey *aKey, + const nsString &aDefaultName, + nsAString &aAccountName); + static bool IsKB933612Applied(); +}; + +static uint32_t checkNewMailTime;// OE global setting, let's default to 30 +static bool checkNewMail; // OE global setting, let's default to false + // This won't cause unwanted autodownloads- + // user can set prefs after import + +//////////////////////////////////////////////////////////////////////// +nsresult nsOESettings::Create(nsIImportSettings** aImport) +{ + NS_PRECONDITION(aImport != nullptr, "null ptr"); + if (! aImport) + return NS_ERROR_NULL_POINTER; + + *aImport = new nsOESettings(); + if (! *aImport) + return NS_ERROR_OUT_OF_MEMORY; + + NS_ADDREF(*aImport); + return NS_OK; +} + +nsOESettings::nsOESettings() +{ +} + +nsOESettings::~nsOESettings() +{ +} + +NS_IMPL_ISUPPORTS(nsOESettings, nsIImportSettings) + +NS_IMETHODIMP nsOESettings::AutoLocate(char16_t **description, nsIFile **location, bool *_retval) +{ + NS_PRECONDITION(description != nullptr, "null ptr"); + NS_PRECONDITION(_retval != nullptr, "null ptr"); + if (!description || !_retval) + return NS_ERROR_NULL_POINTER; + + *description = nsOEStringBundle::GetStringByID(OEIMPORT_NAME); + + if (location) + *location = nullptr; + + *_retval = false; + nsCOMPtr<nsIWindowsRegKey> key; + if (NS_FAILED(OESettings::Find50Key(getter_AddRefs(key))) && + NS_FAILED(OESettings::Find40Key(getter_AddRefs(key)))) + return NS_OK; + + if (NS_SUCCEEDED(OESettings::FindAccountsKey(getter_AddRefs(key)))) + *_retval = true; + + return NS_OK; +} + +NS_IMETHODIMP nsOESettings::SetLocation(nsIFile *location) +{ + return NS_OK; +} + +NS_IMETHODIMP nsOESettings::Import(nsIMsgAccount **localMailAccount, bool *_retval) +{ + NS_PRECONDITION(_retval != nullptr, "null ptr"); + + if (OESettings::DoImport(localMailAccount)) { + *_retval = true; + IMPORT_LOG0("Settings import appears successful\n"); + } + else { + *_retval = false; + IMPORT_LOG0("Settings import returned FALSE\n"); + } + + return NS_OK; +} + +nsresult OESettings::GetDefaultMailAccount(nsAString &aMailAccount) +{ + nsresult rv; + nsCOMPtr<nsIWindowsRegKey> key = + do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv); + NS_ENSURE_SUCCESS(rv, rv); + + nsAutoString userId; + rv = nsOERegUtil::GetDefaultUserId(userId); + // OE has default mail account here when it has been + // set up by transfer or has multiple identities + // look below for orig code that looked in new OE installs + if (NS_SUCCEEDED(rv)) { + nsAutoString path(NS_LITERAL_STRING("Identities\\")); + path.Append(userId); + path.AppendLiteral("\\Software\\Microsoft\\Internet Account Manager"); + rv = key->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER, + path, + nsIWindowsRegKey::ACCESS_QUERY_VALUE); + if (NS_SUCCEEDED(rv)) + key->ReadStringValue(NS_LITERAL_STRING("Default Mail Account"), aMailAccount); + } + + if (!aMailAccount.IsEmpty()) + return NS_OK; + + // else it must be here in original install location from orig code + rv = key->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER, + NS_LITERAL_STRING("Software\\Microsoft\\Outlook Express"), + nsIWindowsRegKey::ACCESS_QUERY_VALUE); + if (NS_FAILED(rv)) + return rv; + + return key->ReadStringValue(NS_LITERAL_STRING("Default Mail Account"), aMailAccount); +} + +nsresult OESettings::GetCheckMailInterval(uint32_t *aInterval) +{ + nsCOMPtr<nsIWindowsRegKey> key; + // 'poll for messages' setting in OE is a global setting + // in OE options general tab and in following global OE + // registry location. + // for all accounts poll interval is a 32 bit value, 0 for + // "don't poll", else milliseconds + nsresult rv = Find50Key(getter_AddRefs(key)); + if (NS_FAILED(rv)) + rv = Find40Key(getter_AddRefs(key)); + + if (NS_FAILED(rv)) + return rv; + + nsCOMPtr<nsIWindowsRegKey> subKey; + rv = key->OpenChild(NS_LITERAL_STRING("Mail"), + nsIWindowsRegKey::ACCESS_QUERY_VALUE, + getter_AddRefs(subKey)); + if (NS_FAILED(rv)) + return rv; + + uint32_t intValue; + rv = subKey->ReadIntValue(NS_LITERAL_STRING("Poll For Mail"), &intValue); + if (NS_SUCCEEDED(rv) && intValue != PR_UINT32_MAX) + *aInterval = intValue / 60000; + + return rv; +} + +nsresult OESettings::FindAccountsKey(nsIWindowsRegKey **aKey) +{ + nsAutoString userId; + nsresult rv = nsOERegUtil::GetDefaultUserId(userId); + if (NS_FAILED(rv)) + return rv; + + nsAutoString path(NS_LITERAL_STRING("Identities\\")); + path.Append(userId); + path.AppendLiteral("\\Software\\Microsoft\\Internet Account Manager\\Accounts"); + + nsCOMPtr<nsIWindowsRegKey> key = + do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv); + NS_ENSURE_SUCCESS(rv, rv); + + rv = key->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER, + path, + nsIWindowsRegKey::ACCESS_QUERY_VALUE | + nsIWindowsRegKey::ACCESS_ENUMERATE_SUB_KEYS); + if (NS_SUCCEEDED(rv)) { + NS_ADDREF(*aKey = key); + return rv; + } + + rv = key->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER, + NS_LITERAL_STRING("Software\\Microsoft\\Internet Account Manager\\Accounts"), + nsIWindowsRegKey::ACCESS_QUERY_VALUE | + nsIWindowsRegKey::ACCESS_ENUMERATE_SUB_KEYS); + NS_IF_ADDREF(*aKey = key); + return rv; +} + +nsresult OESettings::Find50Key(nsIWindowsRegKey **aKey) +{ + nsresult rv; + nsCOMPtr<nsIWindowsRegKey> key = + do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv); + NS_ENSURE_SUCCESS(rv, rv); + + nsAutoString userId; + rv = nsOERegUtil::GetDefaultUserId(userId); + if (NS_FAILED(rv)) + return rv; + + nsAutoString path(NS_LITERAL_STRING("Identities\\")); + path.Append(userId); + path.AppendLiteral("\\Software\\Microsoft\\Outlook Express\\5.0"); + rv = key->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER, + path, + nsIWindowsRegKey::ACCESS_QUERY_VALUE); + NS_IF_ADDREF(*aKey = key); + + return rv; +} + +nsresult OESettings::Find40Key(nsIWindowsRegKey **aKey) +{ + nsresult rv; + nsCOMPtr<nsIWindowsRegKey> key = + do_CreateInstance("@mozilla.org/windows-registry-key;1", &rv); + NS_ENSURE_SUCCESS(rv, rv); + + rv = key->Open(nsIWindowsRegKey::ROOT_KEY_CURRENT_USER, + NS_LITERAL_STRING("Software\\Microsoft\\Outlook Express"), + nsIWindowsRegKey::ACCESS_QUERY_VALUE); + NS_IF_ADDREF(*aKey = key); + + return rv; +} + +bool OESettings::DoImport(nsIMsgAccount **aAccount) +{ + nsCOMPtr<nsIWindowsRegKey> key; + nsresult rv = FindAccountsKey(getter_AddRefs(key)); + if (NS_FAILED(rv)) { + IMPORT_LOG0( "*** Error finding Outlook Express registry account keys\n"); + return false; + } + + nsCOMPtr<nsIMsgAccountManager> accMgr = + do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv); + if (NS_FAILED(rv)) { + IMPORT_LOG0("*** Failed to create a account manager!\n"); + return false; + } + + nsAutoString defMailName; + rv = GetDefaultMailAccount(defMailName); + + checkNewMail = false; + checkNewMailTime = 30; + rv = GetCheckMailInterval(&checkNewMailTime); + if (NS_SUCCEEDED(rv)) + checkNewMail = true; + + // Iterate the accounts looking for POP3 & IMAP accounts... + // Ignore LDAP for now! + uint32_t accounts = 0; + nsAutoString keyComp; + uint32_t childCount = 0; + key->GetChildCount(&childCount); + for (uint32_t i = 0; i < childCount; i++) { + nsAutoString keyName; + key->GetChildName(i, keyName); + + nsCOMPtr<nsIWindowsRegKey> subKey; + rv = key->OpenChild(keyName, + nsIWindowsRegKey::ACCESS_QUERY_VALUE, + getter_AddRefs(subKey)); + if (NS_FAILED(rv)) + continue; + + nsAutoCString nativeKeyName; + NS_CopyUnicodeToNative(keyName, nativeKeyName); + IMPORT_LOG1("Opened Outlook Express account: %s\n", + nativeKeyName.get()); + + nsIMsgAccount *anAccount = nullptr; + nsAutoString value; + rv = subKey->ReadStringValue(NS_LITERAL_STRING("IMAP Server"), value); + if (NS_SUCCEEDED(rv) && DoIMAPServer(accMgr, subKey, value, &anAccount)) + accounts++; + + rv = subKey->ReadStringValue(NS_LITERAL_STRING("NNTP Server"), value); + if (NS_SUCCEEDED(rv) && DoNNTPServer(accMgr, subKey, value, &anAccount)) + accounts++; + + rv = subKey->ReadStringValue(NS_LITERAL_STRING("POP3 Server"), value); + if (NS_SUCCEEDED(rv) && DoPOP3Server(accMgr, subKey, value, &anAccount)) + accounts++; + + if (anAccount) { + // Is this the default account? + keyComp = keyName; + if (keyComp.Equals(defMailName)) + accMgr->SetDefaultAccount(anAccount); + NS_RELEASE(anAccount); + } + } + + // Now save the new acct info to pref file. + rv = accMgr->SaveAccountInfo(); + NS_ASSERTION(NS_SUCCEEDED(rv), "Can't save account info to pref file"); + + return accounts != 0; +} + +nsresult OESettings::GetAccountName(nsIWindowsRegKey *aKey, + const nsString &aDefaultName, + nsAString &aAccountName) +{ + nsresult rv; + rv = aKey->ReadStringValue(NS_LITERAL_STRING("Account Name"), aAccountName); + if (NS_FAILED(rv)) + aAccountName.Assign(aDefaultName); + + return NS_OK; +} + +bool OESettings::DoIMAPServer(nsIMsgAccountManager *aMgr, + nsIWindowsRegKey *aKey, + const nsString &aServerName, + nsIMsgAccount **ppAccount) +{ + if (ppAccount) + *ppAccount = nullptr; + + nsAutoString userName; + nsresult rv; + rv = aKey->ReadStringValue(NS_LITERAL_STRING("IMAP User Name"), userName); + if (NS_FAILED(rv)) + return false; + + nsAutoCString nativeUserName; + NS_CopyUnicodeToNative(userName, nativeUserName); + nsAutoCString nativeServerName; + NS_CopyUnicodeToNative(aServerName, nativeServerName); + // I now have a user name/server name pair, find out if it already exists? + nsCOMPtr<nsIMsgIncomingServer> in; + rv = aMgr->FindServer(nativeUserName, + nativeServerName, + NS_LITERAL_CSTRING("imap"), + getter_AddRefs(in)); + if (NS_SUCCEEDED(rv)) { + // for an existing server we create another identity, + // TB lists under 'manage identities' + nsCOMPtr<nsIMsgAccount> account; + rv = aMgr->FindAccountForServer(in, getter_AddRefs(account)); + if (NS_FAILED(rv)) + return false; + + IMPORT_LOG0("Created an identity and added to existing IMAP incoming server\n"); + // Fiddle with the identities + int32_t authMethod; + in->GetAuthMethod(&authMethod); + SetIdentities(aMgr, account, aKey, userName, authMethod, false); + if (ppAccount) + account->QueryInterface(NS_GET_IID(nsIMsgAccount), + (void **)ppAccount); + return true; + } + + // Create the incoming server and an account for it? + rv = aMgr->CreateIncomingServer(nativeUserName, + nativeServerName, + NS_LITERAL_CSTRING("imap"), + getter_AddRefs(in)); + NS_ENSURE_SUCCESS(rv, false); + + nsAutoString rootFolder; + rv = aKey->ReadStringValue(NS_LITERAL_STRING("IMAP Root Folder"), rootFolder); + if (NS_SUCCEEDED(rv) && !rootFolder.IsEmpty()) { + nsCOMPtr<nsIImapIncomingServer> imapServer = do_QueryInterface(in); + nsAutoCString nativeRootFolder; + NS_CopyUnicodeToNative(rootFolder, nativeRootFolder); + imapServer->SetServerDirectory(nativeRootFolder); + } + + SetIncomingServerProperties(in, aKey, NS_LITERAL_STRING("IMAP ")); + + IMPORT_LOG2("Created IMAP server named: %s, userName: %s\n", + nativeServerName.get(), nativeUserName.get()); + + nsAutoString prettyName; + if (NS_SUCCEEDED(GetAccountName(aKey, aServerName, prettyName))) + rv = in->SetPrettyName(prettyName); + + // We have a server, create an account. + nsCOMPtr<nsIMsgAccount> account; + rv = aMgr->CreateAccount(getter_AddRefs(account)); + if (NS_SUCCEEDED(rv) && account) { + rv = account->SetIncomingServer(in); + + IMPORT_LOG0("Created an account and set the IMAP server as the incoming server\n"); + + // Fiddle with the identities + int32_t authMethod; + in->GetAuthMethod(&authMethod); + SetIdentities(aMgr, account, aKey, userName, authMethod, false); + if (ppAccount) + account->QueryInterface(NS_GET_IID(nsIMsgAccount), (void **)ppAccount); + return true; + } + + return false; +} + +bool OESettings::DoPOP3Server(nsIMsgAccountManager *aMgr, + nsIWindowsRegKey *aKey, + const nsString &aServerName, + nsIMsgAccount **ppAccount) +{ + if (ppAccount) + *ppAccount = nullptr; + + nsAutoString userName; + nsresult rv; + rv = aKey->ReadStringValue(NS_LITERAL_STRING("POP3 User Name"), userName); + if (NS_FAILED(rv)) + return false; + + nsAutoCString nativeUserName; + NS_CopyUnicodeToNative(userName, nativeUserName); + nsAutoCString nativeServerName; + NS_CopyUnicodeToNative(aServerName, nativeServerName); + + // I now have a user name/server name pair, find out if it already exists? + nsCOMPtr<nsIMsgIncomingServer> in; + rv = aMgr->FindServer(nativeUserName, + nativeServerName, + NS_LITERAL_CSTRING("pop3"), + getter_AddRefs(in)); + if (NS_SUCCEEDED(rv)) { + IMPORT_LOG2("Existing POP3 server named: %s, userName: %s\n", + nativeUserName.get(), nativeServerName.get()); + // for an existing server we create another identity, + // TB listed under 'manage identities' + nsCOMPtr<nsIMsgAccount> account; + rv = aMgr->FindAccountForServer(in, getter_AddRefs(account)); + if (NS_SUCCEEDED(rv) && account) { + IMPORT_LOG0("Created identity and added to existing POP3 incoming server.\n"); + // Fiddle with the identities + int32_t authMethod; + in->GetAuthMethod(&authMethod); + SetIdentities(aMgr, account, aKey, userName, authMethod, false); + if (ppAccount) + account->QueryInterface(NS_GET_IID(nsIMsgAccount), (void **)ppAccount); + return true; + } + return false; + } + + // Create the incoming server and an account for it? + rv = aMgr->CreateIncomingServer(nativeUserName, + nativeServerName, + NS_LITERAL_CSTRING("pop3"), + getter_AddRefs( in)); + if (NS_FAILED(rv)) + return false; + + SetIncomingServerProperties(in, aKey, NS_LITERAL_STRING("POP3 ")); + + nsCOMPtr<nsIPop3IncomingServer> pop3Server = do_QueryInterface(in); + if (pop3Server) { + // set local folders as the Inbox to use for this POP3 server + nsCOMPtr<nsIMsgIncomingServer> localFoldersServer; + aMgr->GetLocalFoldersServer(getter_AddRefs(localFoldersServer)); + + if (!localFoldersServer) + { + // If Local Folders does not exist already, create it + + if (NS_FAILED(aMgr->CreateLocalMailAccount())) { + IMPORT_LOG0("*** Failed to create Local Folders!\n"); + return false; + } + + aMgr->GetLocalFoldersServer(getter_AddRefs(localFoldersServer)); + } + + // now get the account for this server + nsCOMPtr<nsIMsgAccount> localFoldersAccount; + aMgr->FindAccountForServer(localFoldersServer, getter_AddRefs(localFoldersAccount)); + if (localFoldersAccount) + { + nsCString localFoldersAcctKey; + localFoldersAccount->GetKey(localFoldersAcctKey); + pop3Server->SetDeferredToAccount(localFoldersAcctKey); + } + + uint32_t intValue; + rv = aKey->ReadIntValue(NS_LITERAL_STRING("POP3 Skip Account"), &intValue); + // OE:0=='Include this account when receiving mail or synchronizing'== + // TB:1==AM:Server:advanced:Include this server when getting new mail + pop3Server->SetDeferGetNewMail(NS_SUCCEEDED(rv) && intValue == 0); + + rv = aKey->ReadIntValue(NS_LITERAL_STRING("Leave Mail On Server"), + &intValue); + pop3Server->SetLeaveMessagesOnServer(NS_SUCCEEDED(rv) && intValue == 1); + + rv = aKey->ReadIntValue(NS_LITERAL_STRING("Remove When Deleted"), + &intValue); + pop3Server->SetDeleteMailLeftOnServer(NS_SUCCEEDED(rv) && intValue == 1); + + rv = aKey->ReadIntValue(NS_LITERAL_STRING("Remove When Expired"), + &intValue); + pop3Server->SetDeleteByAgeFromServer(NS_SUCCEEDED(rv) && intValue == 1); + + rv = aKey->ReadIntValue(NS_LITERAL_STRING("Expire Days"), + &intValue); + if (NS_SUCCEEDED(rv)) + pop3Server->SetNumDaysToLeaveOnServer(static_cast<int32_t>(intValue)); + } + IMPORT_LOG2("Created POP3 server named: %s, userName: %s\n", + nativeServerName.get(), nativeUserName.get()); + nsString prettyName; + if (NS_SUCCEEDED(GetAccountName(aKey, aServerName, prettyName))) + rv = in->SetPrettyName(prettyName); + + // We have a server, create an account. + nsCOMPtr<nsIMsgAccount> account; + rv = aMgr->CreateAccount(getter_AddRefs( account)); + if (NS_SUCCEEDED( rv) && account) { + rv = account->SetIncomingServer(in); + IMPORT_LOG0("Created a new account and set the incoming server to the POP3 server.\n"); + + int32_t authMethod; + in->GetAuthMethod(&authMethod); + // Fiddle with the identities + SetIdentities(aMgr, account, aKey, userName, authMethod, false); + if (ppAccount) + account->QueryInterface(NS_GET_IID(nsIMsgAccount), + (void **)ppAccount); + return true; + } + + return false; +} + +bool OESettings::DoNNTPServer(nsIMsgAccountManager *aMgr, + nsIWindowsRegKey *aKey, + const nsString &aServerName, + nsIMsgAccount **ppAccount) +{ + if (ppAccount) + *ppAccount = nullptr; + + nsAutoString userName; + nsresult rv; + // this only exists if NNTP server requires it or not anon login + rv = aKey->ReadStringValue(NS_LITERAL_STRING("NNTP User Name"), userName); + + bool result = false; + + nsAutoCString nativeServerName; + NS_CopyUnicodeToNative(aServerName, nativeServerName); + // I now have a user name/server name pair, find out if it already exists? + // NNTP can have empty user name. This is wild card in findserver + nsCOMPtr<nsIMsgIncomingServer> in; + rv = aMgr->FindServer(EmptyCString(), + nativeServerName, + NS_LITERAL_CSTRING("nntp"), + getter_AddRefs(in)); + if (NS_FAILED(rv) || (in == nullptr)) { + // Create the incoming server and an account for it? + rv = aMgr->CreateIncomingServer(EmptyCString(), + nativeServerName, + NS_LITERAL_CSTRING("nntp"), + getter_AddRefs(in)); + if (NS_SUCCEEDED(rv) && in) { + uint32_t port = 0; + rv = aKey->ReadIntValue(NS_LITERAL_STRING("NNTP Port"), + &port); + if (NS_SUCCEEDED(rv) && port && port != 119) + in->SetPort(static_cast<int32_t>(port)); + + nsAutoCString nativeUserName; + NS_CopyUnicodeToNative(userName, nativeUserName); + // do nntpincomingserver stuff + nsCOMPtr<nsINntpIncomingServer> nntpServer = do_QueryInterface(in); + if (nntpServer && !userName.IsEmpty()) { + nntpServer->SetPushAuth(true); + in->SetUsername(nativeUserName); + } + + IMPORT_LOG2("Created NNTP server named: %s, userName: %s\n", + nativeServerName.get(), nativeUserName.get()); + + nsString prettyName; + if (NS_SUCCEEDED(GetAccountName(aKey, aServerName, prettyName))) + rv = in->SetPrettyName(prettyName); + + // We have a server, create an account. + nsCOMPtr<nsIMsgAccount> account; + rv = aMgr->CreateAccount(getter_AddRefs(account)); + if (NS_SUCCEEDED(rv) && account) { + rv = account->SetIncomingServer(in); + + IMPORT_LOG0("Created an account and set the NNTP server as the incoming server\n"); + + // Fiddle with the identities + SetIdentities(aMgr, account, aKey, userName, 0, true); + result = true; + if (ppAccount) + account->QueryInterface(NS_GET_IID(nsIMsgAccount), (void **)ppAccount); + } + } + } + else if (NS_SUCCEEDED(rv) && in) { + // for the existing server... + nsCOMPtr<nsIMsgAccount> account; + rv = aMgr->FindAccountForServer(in, getter_AddRefs(account)); + if (NS_SUCCEEDED(rv) && account) { + IMPORT_LOG0("Using existing account and set the NNTP server as the incoming server\n"); + // Fiddle with the identities + SetIdentities(aMgr, account, aKey, userName, 0, true); + if (ppAccount) + account->QueryInterface(NS_GET_IID(nsIMsgAccount), + (void **)ppAccount); + return true; + } + } + else + result = true; + + return result; +} + +void OESettings::SetIncomingServerProperties(nsIMsgIncomingServer *aServer, + nsIWindowsRegKey *aKey, + const nsString &aKeyNamePrefix) +{ + nsresult rv; + uint32_t secureConnection = 0; + nsString keyName(aKeyNamePrefix); + keyName.AppendLiteral("Secure Connection"); + rv = aKey->ReadIntValue(keyName, &secureConnection); + if (NS_SUCCEEDED(rv) && secureConnection == 1) + aServer->SetSocketType(nsMsgSocketType::SSL); + + uint32_t port = 0; + keyName.SetLength(aKeyNamePrefix.Length()); + keyName.AppendLiteral("Port"); + rv = aKey->ReadIntValue(keyName, &port); + if (NS_SUCCEEDED(rv) && port) + aServer->SetPort(static_cast<int32_t>(port)); + + int32_t authMethod; + uint32_t useSicily = 0; + keyName.SetLength(aKeyNamePrefix.Length()); + keyName.AppendLiteral("Use Sicily"); + rv = aKey->ReadIntValue(keyName, &useSicily); + if (NS_SUCCEEDED(rv) && useSicily) + authMethod = nsMsgAuthMethod::secure; + else + authMethod = nsMsgAuthMethod::passwordCleartext; + aServer->SetAuthMethod(authMethod); + + aServer->SetDoBiff(checkNewMail); + aServer->SetBiffMinutes(checkNewMailTime); +} + +void OESettings::SetIdentities(nsIMsgAccountManager *aMgr, + nsIMsgAccount *pAcc, + nsIWindowsRegKey *aKey, + const nsString &aIncomgUserName, + int32_t authMethodIncoming, + bool isNNTP) +{ + // Get the relevant information for an identity + nsresult rv; + nsAutoString name; + rv = aKey->ReadStringValue(isNNTP ? + NS_LITERAL_STRING("NNTP Display Name") : + NS_LITERAL_STRING("SMTP Display Name"), + name); + nsAutoString email; + rv = aKey->ReadStringValue(isNNTP ? + NS_LITERAL_STRING("NNTP Email Address") : + NS_LITERAL_STRING("SMTP Email Address"), + email); + nsAutoString reply; + rv = aKey->ReadStringValue(isNNTP ? + NS_LITERAL_STRING("NNTP Reply To Email Address") : + NS_LITERAL_STRING("SMTP Reply To Email Address"), + reply); + nsAutoString orgName; + rv = aKey->ReadStringValue(isNNTP ? + NS_LITERAL_STRING("NNTP Organization Name") : + NS_LITERAL_STRING("SMTP Organization Name"), + orgName); + + nsCOMPtr<nsIMsgIdentity> id; + rv = aMgr->CreateIdentity(getter_AddRefs(id)); + if (NS_FAILED(rv)) + return; + + id->SetFullName(name); + id->SetOrganization(orgName); + + nsAutoCString nativeEmail; + NS_CopyUnicodeToNative(email, nativeEmail); + id->SetEmail(nativeEmail); + if (!reply.IsEmpty()) { + nsAutoCString nativeReply; + NS_CopyUnicodeToNative(reply, nativeReply); + id->SetReplyTo(nativeReply); + } + + // Outlook Express users are used to top style quoting. + id->SetReplyOnTop(isNNTP ? 0 : 1); + pAcc->AddIdentity(id); + + nsAutoCString nativeName; + NS_CopyUnicodeToNative(name, nativeName); + IMPORT_LOG0("Created identity and added to the account\n"); + IMPORT_LOG1("\tname: %s\n", nativeName.get()); + IMPORT_LOG1("\temail: %s\n", nativeEmail.get()); + + if (isNNTP) // NNTP does not use SMTP in OE or TB + return; + nsAutoString smtpServer; + rv = aKey->ReadStringValue(NS_LITERAL_STRING("SMTP Server"), smtpServer); + SetSmtpServer(smtpServer, aKey, id, aIncomgUserName, authMethodIncoming); +} + +void OESettings::SetSmtpServer(const nsString &aSmtpServer, + nsIWindowsRegKey *aKey, + nsIMsgIdentity *aId, + const nsString &aIncomgUserName, + int32_t authMethodIncoming) +{ + // set the id.smtpserver accordingly + // first we have to calculate the smtp user name which is based on sicily + if (!aKey || !aId || aIncomgUserName.IsEmpty() || aSmtpServer.IsEmpty()) + return; + nsCString smtpServerKey; + // smtp user name depends on sicily which may or not exist + uint32_t useSicily = 0; + nsresult rv = aKey->ReadIntValue(NS_LITERAL_STRING("SMTP Use Sicily"), + &useSicily); + nsAutoString userName; + switch (useSicily) { + case 1: + case 3: + // has to go in whether empty or no + // shouldn't be empty but better safe than sorry + aKey->ReadStringValue(NS_LITERAL_STRING("SMTP User Name"), userName); + break; + case 2: + userName = aIncomgUserName; + break; + default: + break; // initial userName == "" + } + + nsCOMPtr<nsISmtpService> smtpService(do_GetService(NS_SMTPSERVICE_CONTRACTID, &rv)); + if (NS_SUCCEEDED(rv) && smtpService) { + nsCOMPtr<nsISmtpServer> foundServer; + // don't try to make another server + // regardless if username doesn't match + nsAutoCString nativeUserName; + NS_CopyUnicodeToNative(userName, nativeUserName); + nsAutoCString nativeSmtpServer; + NS_CopyUnicodeToNative(aSmtpServer, nativeSmtpServer); + rv = smtpService->FindServer(nativeUserName.get(), + nativeSmtpServer.get(), + getter_AddRefs(foundServer)); + if (NS_SUCCEEDED(rv) && foundServer) { + // set our account keyed to this smptserver key + foundServer->GetKey(getter_Copies(smtpServerKey)); + aId->SetSmtpServerKey(smtpServerKey); + + IMPORT_LOG1("SMTP server already exists: %s\n", + nativeSmtpServer.get()); + } + else { + nsCOMPtr<nsISmtpServer> smtpServer; + rv = smtpService->CreateServer(getter_AddRefs(smtpServer)); + if (NS_SUCCEEDED(rv) && smtpServer) { + uint32_t port = 0; + rv = aKey->ReadIntValue(NS_LITERAL_STRING("SMTP Port"), + &port); + if (NS_SUCCEEDED(rv) && port) + smtpServer->SetPort(static_cast<int32_t>(port)); + + int32_t socketType = nsMsgSocketType::plain; + uint32_t secureConnection = 0; + rv = aKey->ReadIntValue(NS_LITERAL_STRING("SMTP Secure Connection"), + &secureConnection); + if (NS_SUCCEEDED(rv) && secureConnection == 1) { + // Outlook Express does not support STARTTLS without KB933612 fix. + if (IsKB933612Applied() && port != 465) + socketType = nsMsgSocketType::alwaysSTARTTLS; + else + socketType = nsMsgSocketType::SSL; + } + smtpServer->SetSocketType(socketType); + smtpServer->SetUsername(nativeUserName); + switch (useSicily) { + case 1 : + smtpServer->SetAuthMethod(nsMsgAuthMethod::secure); + break; + case 2 : // requires SMTP authentication to use the incoming server settings + smtpServer->SetAuthMethod(authMethodIncoming); + break; + case 3 : + smtpServer->SetAuthMethod(nsMsgAuthMethod::passwordCleartext); + break; + default: + smtpServer->SetAuthMethod(nsMsgAuthMethod::none); + } + + smtpServer->SetHostname(nativeSmtpServer); + + smtpServer->GetKey(getter_Copies(smtpServerKey)); + aId->SetSmtpServerKey(smtpServerKey); + + IMPORT_LOG1("Created new SMTP server: %s\n", + nativeSmtpServer.get()); + } + } + } +} + +bool OESettings::IsKB933612Applied() +{ + // The following versions of Windows include KB933612 fix: + // - Windows 7 and future versions of Windows + // - Windows Vista, SP1 or later + // - Windows Server 2003, SP2 or later + // - Windows XP, SP3 or later + // + // The following versions do not: + // - Windows Vista SP0 + // - Windows Server 2003, SP1 or earlier + // - Windows XP, SP2 or earlier + // + // See http://support.microsoft.com/kb/929123 and + // http://support.microsoft.com/kb/933612 + // + // Note that mozilla::IsWin2003SP2OrLater() will return true for + // Windows Vista and mozilla::IsXPSP3OrLater() will return true + // for Windows Server 2003. + return mozilla::IsVistaSP1OrLater() || + !mozilla::IsWin2003OrLater() && mozilla::IsXPSP3OrLater() || + !mozilla::IsVistaOrLater() && mozilla::IsWin2003SP2OrLater(); +} + |