1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 /*
7   Windows Live Mail (Win32) settings
8 */
9 
10 #include "nsCOMPtr.h"
11 #include "nscore.h"
12 #include "nsString.h"
13 #include "nsMsgUtils.h"
14 #include "nsWMImport.h"
15 #include "nsIMsgAccountManager.h"
16 #include "nsIMsgAccount.h"
17 #include "nsIImportSettings.h"
18 #include "nsWMSettings.h"
19 #include "nsMsgBaseCID.h"
20 #include "nsMsgCompCID.h"
21 #include "nsMsgI18N.h"
22 #include "nsISmtpService.h"
23 #include "nsISmtpServer.h"
24 #include "nsWMStringBundle.h"
25 #include "ImportDebug.h"
26 #include "nsIPop3IncomingServer.h"
27 #include "nsIImapIncomingServer.h"
28 #include "nsINntpIncomingServer.h"
29 #include "stdlib.h"
30 #include "mozilla/dom/Document.h"
31 #include "nsIFile.h"
32 #include "nsNetUtil.h"
33 #include "nsTArray.h"
34 #include <windows.h>
35 #include "nsIWindowsRegKey.h"
36 #include "nsCOMArray.h"
37 #include "nsWMUtils.h"
38 
39 class WMSettings {
40  public:
41   static bool DoImport(nsIMsgAccount** ppAccount);
42   static bool DoIMAPServer(nsIMsgAccountManager* pMgr,
43                            mozilla::dom::Document* xmlDoc,
44                            const nsString& serverName,
45                            nsIMsgAccount** ppAccount);
46   static bool DoPOP3Server(nsIMsgAccountManager* pMgr,
47                            mozilla::dom::Document* xmlDoc,
48                            const nsString& serverName,
49                            nsIMsgAccount** ppAccount);
50   static bool DoNNTPServer(nsIMsgAccountManager* pMgr,
51                            mozilla::dom::Document* xmlDoc,
52                            const nsString& serverName,
53                            nsIMsgAccount** ppAccount);
54   static void SetIdentities(nsIMsgAccountManager* pMgr, nsIMsgAccount* pAcc,
55                             mozilla::dom::Document* xmlDoc,
56                             nsAutoString& userName, int32_t authMethodIncoming,
57                             bool isNNTP);
58   static void SetSmtpServer(mozilla::dom::Document* xmlDoc, nsIMsgIdentity* id,
59                             nsAutoString& inUserName,
60                             int32_t authMethodIncoming);
61 };
62 
63 static int32_t checkNewMailTime;  // WM global setting, let's default to 30
64 static bool checkNewMail;         // WM global setting, let's default to false
65                                   // This won't cause unwanted autodownloads-
66                                   // user can set prefs after import
67 
68 ////////////////////////////////////////////////////////////////////////
Create(nsIImportSettings ** aImport)69 nsresult nsWMSettings::Create(nsIImportSettings** aImport) {
70   NS_ENSURE_ARG_POINTER(aImport);
71   NS_ADDREF(*aImport = new nsWMSettings());
72   return NS_OK;
73 }
74 
nsWMSettings()75 nsWMSettings::nsWMSettings() {}
76 
~nsWMSettings()77 nsWMSettings::~nsWMSettings() {}
78 
NS_IMPL_ISUPPORTS(nsWMSettings,nsIImportSettings)79 NS_IMPL_ISUPPORTS(nsWMSettings, nsIImportSettings)
80 
81 NS_IMETHODIMP nsWMSettings::AutoLocate(char16_t** description,
82                                        nsIFile** location, bool* _retval) {
83   NS_ASSERTION(description != nullptr, "null ptr");
84   NS_ASSERTION(_retval != nullptr, "null ptr");
85   if (!description || !_retval) return NS_ERROR_NULL_POINTER;
86 
87   *description = nsWMStringBundle::GetStringByID(WMIMPORT_NAME);
88   *_retval = false;
89 
90   if (location) *location = nullptr;
91   nsCOMPtr<nsIWindowsRegKey> key;
92   if (NS_SUCCEEDED(nsWMUtils::FindWMKey(getter_AddRefs(key)))) *_retval = true;
93 
94   return NS_OK;
95 }
96 
SetLocation(nsIFile * location)97 NS_IMETHODIMP nsWMSettings::SetLocation(nsIFile* location) { return NS_OK; }
98 
Import(nsIMsgAccount ** localMailAccount,bool * _retval)99 NS_IMETHODIMP nsWMSettings::Import(nsIMsgAccount** localMailAccount,
100                                    bool* _retval) {
101   NS_ASSERTION(_retval != nullptr, "null ptr");
102 
103   if (WMSettings::DoImport(localMailAccount)) {
104     *_retval = true;
105     IMPORT_LOG0("Settings import appears successful\n");
106   } else {
107     *_retval = false;
108     IMPORT_LOG0("Settings import returned FALSE\n");
109   }
110 
111   return NS_OK;
112 }
113 
DoImport(nsIMsgAccount ** ppAccount)114 bool WMSettings::DoImport(nsIMsgAccount** ppAccount) {
115   // do the windows registry stuff first
116   nsCOMPtr<nsIWindowsRegKey> key;
117   if (NS_FAILED(nsWMUtils::FindWMKey(getter_AddRefs(key)))) {
118     IMPORT_LOG0("*** Error finding Windows Live Mail registry account keys\n");
119     return false;
120   }
121   // 'poll for messages' setting in WM is a global setting-Like OE
122   // for all accounts dword ==0xffffffff for don't poll else 1/60000 = minutes
123   checkNewMailTime = 30;
124   checkNewMail = false;
125 
126   nsresult rv;
127   nsCOMPtr<nsIWindowsRegKey> subKey;
128   if (NS_SUCCEEDED(key->OpenChild(u"mail"_ns,
129                                   nsIWindowsRegKey::ACCESS_QUERY_VALUE,
130                                   getter_AddRefs(subKey)))) {
131     uint32_t dwordResult = -1;
132     rv = subKey->ReadIntValue(u"Poll For Mail"_ns,
133                               &dwordResult);  // reg_dword
134     subKey->Close();
135     if (NS_SUCCEEDED(rv) && dwordResult != -1) {
136       checkNewMail = true;
137       checkNewMailTime = dwordResult / 60000;
138     }
139   }
140   // these are in main windowsmail key and if they don't exist-not to worry
141   // (less than 64 chars) e.g.
142   // account{4A18B81E-83CA-472A-8D7F-5301C0B97B8D}.oeaccount
143   nsAutoString defMailAcct, defNewsAcct;
144   key->ReadStringValue(u"Default Mail Account"_ns,
145                        defMailAcct);  // ref_sz
146   key->ReadStringValue(u"Default News Account"_ns,
147                        defNewsAcct);  // ref_sz
148 
149   nsCOMPtr<nsIMsgAccountManager> accMgr =
150       do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
151   if (NS_FAILED(rv)) {
152     IMPORT_LOG0("*** Failed to create an account manager!\n");
153     return false;
154   }
155 
156   nsCOMArray<nsIFile> fileArray;
157   if (NS_FAILED(nsWMUtils::GetOEAccountFiles(fileArray))) {
158     IMPORT_LOG0("*** Failed to get .oeaccount file!\n");
159     return false;
160   }
161 
162   // Loop through *.oeaccounts files looking for POP3 & IMAP & NNTP accounts
163   // Ignore LDAP for now!
164   int accounts = 0;
165   nsCOMPtr<mozilla::dom::Document> xmlDoc;
166 
167   for (int32_t i = fileArray.Count() - 1; i >= 0; i--) {
168     nsWMUtils::MakeXMLdoc(getter_AddRefs(xmlDoc), fileArray[i]);
169 
170     nsAutoCString name;
171     fileArray[i]->GetNativeLeafName(name);
172     nsAutoString value;
173     nsCOMPtr<nsIMsgAccount> anAccount;
174     if (NS_SUCCEEDED(nsWMUtils::GetValueForTag(xmlDoc, "IMAP_Server", value)))
175       if (DoIMAPServer(accMgr, xmlDoc, value, getter_AddRefs(anAccount)))
176         accounts++;
177     if (NS_SUCCEEDED(nsWMUtils::GetValueForTag(xmlDoc, "NNTP_Server", value)))
178       if (DoNNTPServer(accMgr, xmlDoc, value, getter_AddRefs(anAccount)))
179         accounts++;
180     if (NS_SUCCEEDED(nsWMUtils::GetValueForTag(xmlDoc, "POP3_Server", value)))
181       if (DoPOP3Server(accMgr, xmlDoc, value, getter_AddRefs(anAccount)))
182         accounts++;
183 
184     if (anAccount) {
185       nsString name;
186       // Is this the default account?
187       fileArray[i]->GetLeafName(name);
188       if (defMailAcct.Equals(name)) accMgr->SetDefaultAccount(anAccount);
189     }
190   }
191 
192   // Now save the new acct info to pref file.
193   rv = accMgr->SaveAccountInfo();
194   NS_ASSERTION(NS_SUCCEEDED(rv), "Can't save account info to pref file");
195 
196   return accounts != 0;
197 }
198 
DoIMAPServer(nsIMsgAccountManager * pMgr,mozilla::dom::Document * xmlDoc,const nsString & serverName,nsIMsgAccount ** ppAccount)199 bool WMSettings::DoIMAPServer(nsIMsgAccountManager* pMgr,
200                               mozilla::dom::Document* xmlDoc,
201                               const nsString& serverName,
202                               nsIMsgAccount** ppAccount) {
203   int32_t authMethod;  // Secure Password Authentication (SPA)
204   nsresult errorCode;
205   if (ppAccount) *ppAccount = nullptr;
206 
207   nsAutoString userName, value;
208   if (NS_FAILED(nsWMUtils::GetValueForTag(xmlDoc, "IMAP_User_Name", userName)))
209     return false;
210   bool result = false;
211   // I now have a user name/server name pair, find out if it already exists?
212   nsCOMPtr<nsIMsgIncomingServer> in;
213   nsresult rv = pMgr->FindServer(NS_ConvertUTF16toUTF8(userName),
214                                  NS_ConvertUTF16toUTF8(serverName), "imap"_ns,
215                                  getter_AddRefs(in));
216   if (NS_FAILED(rv) || (in == nullptr)) {
217     // Create the incoming server and an account for it?
218     rv = pMgr->CreateIncomingServer(NS_ConvertUTF16toUTF8(userName),
219                                     NS_ConvertUTF16toUTF8(serverName),
220                                     "imap"_ns, getter_AddRefs(in));
221     if (NS_SUCCEEDED(rv) && in) {
222       nsCOMPtr<nsIImapIncomingServer> imapServer = do_QueryInterface(in);
223       if (!imapServer) {
224         IMPORT_LOG1("*** Failed to create nsIImapIncomingServer for %S!\n",
225                     serverName.get());
226         return false;
227       }
228       if (NS_SUCCEEDED(
229               nsWMUtils::GetValueForTag(xmlDoc, "IMAP_Root_Folder", value))) {
230         imapServer->SetServerDirectory(NS_ConvertUTF16toUTF8(value));
231       }
232       if (NS_SUCCEEDED(nsWMUtils::GetValueForTag(
233               xmlDoc, "IMAP_Secure_Connection", value))) {
234         if (value.ToInteger(&errorCode, 16))
235           in->SetSocketType(nsMsgSocketType::SSL);
236       }
237       if (NS_SUCCEEDED(
238               nsWMUtils::GetValueForTag(xmlDoc, "IMAP_Use_Sicily", value))) {
239         bool secAuth = (bool)value.ToInteger(&errorCode, 16);
240         authMethod = secAuth ? nsMsgAuthMethod::secure
241                              : nsMsgAuthMethod::passwordCleartext;
242         in->SetAuthMethod(authMethod);
243       }
244 
245       if (NS_SUCCEEDED(nsWMUtils::GetValueForTag(xmlDoc, "IMAP_Port", value))) {
246         in->SetPort(value.ToInteger(&errorCode, 16));
247       }
248       if (NS_SUCCEEDED(
249               nsWMUtils::GetValueForTag(xmlDoc, "Account_Name", value))) {
250         rv = in->SetPrettyName(value);
251       }
252       in->SetDoBiff(checkNewMail);
253       in->SetBiffMinutes(checkNewMailTime);
254 
255       IMPORT_LOG2("Created IMAP server named: %S, userName: %S\n",
256                   serverName.get(), userName.get());
257 
258       // We have a server, create an account.
259       nsCOMPtr<nsIMsgAccount> account;
260       rv = pMgr->CreateAccount(getter_AddRefs(account));
261       if (NS_SUCCEEDED(rv) && account) {
262         rv = account->SetIncomingServer(in);
263 
264         IMPORT_LOG0(
265             "Created an account and set the IMAP server "
266             "as the incoming server\n");
267 
268         // Fiddle with the identities
269         SetIdentities(pMgr, account, xmlDoc, userName, authMethod, false);
270         result = true;
271         if (ppAccount) account.forget(ppAccount);
272       }
273     }
274   } else if (NS_SUCCEEDED(rv) && in) {
275     // for an existing server we create another identity,
276     //  TB lists under 'manage identities'
277     nsCOMPtr<nsIMsgAccount> account;
278     rv = pMgr->FindAccountForServer(in, getter_AddRefs(account));
279     if (NS_SUCCEEDED(rv) && account) {
280       IMPORT_LOG0(
281           "Created an identity and added to existing "
282           "IMAP incoming server\n");
283       // Fiddle with the identities
284       in->GetAuthMethod(&authMethod);
285       SetIdentities(pMgr, account, xmlDoc, userName, authMethod, false);
286       result = true;
287       if (ppAccount) account.forget(ppAccount);
288     }
289   } else
290     result = true;
291   return result;
292 }
293 
DoPOP3Server(nsIMsgAccountManager * pMgr,mozilla::dom::Document * xmlDoc,const nsString & serverName,nsIMsgAccount ** ppAccount)294 bool WMSettings::DoPOP3Server(nsIMsgAccountManager* pMgr,
295                               mozilla::dom::Document* xmlDoc,
296                               const nsString& serverName,
297                               nsIMsgAccount** ppAccount) {
298   int32_t authMethod;  // Secure Password Authentication (SPA)
299   nsresult errorCode;
300   if (ppAccount) *ppAccount = nullptr;
301 
302   nsAutoString userName, value;
303   if (NS_FAILED(nsWMUtils::GetValueForTag(xmlDoc, "POP3_User_Name", userName)))
304     return false;
305   bool result = false;
306   // I now have a user name/server name pair, find out if it already exists?
307   nsCOMPtr<nsIMsgIncomingServer> in;
308   nsresult rv = pMgr->FindServer(NS_ConvertUTF16toUTF8(userName),
309                                  NS_ConvertUTF16toUTF8(serverName), "pop3"_ns,
310                                  getter_AddRefs(in));
311   if (NS_FAILED(rv) || (in == nullptr)) {
312     // Create the incoming server and an account for it?
313     rv = pMgr->CreateIncomingServer(NS_ConvertUTF16toUTF8(userName),
314                                     NS_ConvertUTF16toUTF8(serverName),
315                                     "pop3"_ns, getter_AddRefs(in));
316     if (NS_SUCCEEDED(rv) && in) {
317       nsCOMPtr<nsIPop3IncomingServer> pop3Server = do_QueryInterface(in);
318       if (!pop3Server) {
319         IMPORT_LOG1("*** Failed to create nsIPop3IncomingServer for %S!\n",
320                     serverName.get());
321         return false;
322       }
323 
324       if (NS_SUCCEEDED(nsWMUtils::GetValueForTag(
325               xmlDoc, "POP3_Secure_Connection", value)) &&
326           value.ToInteger(&errorCode, 16)) {
327         in->SetSocketType(nsMsgSocketType::SSL);
328       }
329       if (NS_SUCCEEDED(
330               nsWMUtils::GetValueForTag(xmlDoc, "POP3_Use_Sicily", value))) {
331         bool secAuth = (bool)value.ToInteger(&errorCode, 16);
332         authMethod = secAuth ? nsMsgAuthMethod::secure
333                              : nsMsgAuthMethod::passwordCleartext;
334         in->SetAuthMethod(authMethod);
335       }
336       if (NS_SUCCEEDED(nsWMUtils::GetValueForTag(xmlDoc, "POP3_Port", value))) {
337         in->SetPort(value.ToInteger(&errorCode, 16));
338       }
339       if (NS_SUCCEEDED(
340               nsWMUtils::GetValueForTag(xmlDoc, "POP3_Skip_Account", value))) {
341         if (!value.IsEmpty())
342           // OE:0=='Include this account when receiving mail or synchronizing'==
343           // TB:1==ActMgr:Server:advanced:Include this server when getting new
344           // mail
345           pop3Server->SetDeferGetNewMail(value.ToInteger(&errorCode, 16) == 0);
346         else
347           pop3Server->SetDeferGetNewMail(false);
348       }
349       if (NS_SUCCEEDED(nsWMUtils::GetValueForTag(xmlDoc, "Leave_Mail_On_Server",
350                                                  value))) {
351         pop3Server->SetLeaveMessagesOnServer(
352             (bool)value.ToInteger(&errorCode, 16));
353       }
354       if (NS_SUCCEEDED(nsWMUtils::GetValueForTag(xmlDoc, "Remove_When_Deleted",
355                                                  value))) {
356         pop3Server->SetDeleteMailLeftOnServer(
357             (bool)value.ToInteger(&errorCode, 16));
358       }
359       if (NS_SUCCEEDED(nsWMUtils::GetValueForTag(xmlDoc, "Remove_When_Expired",
360                                                  value))) {
361         pop3Server->SetDeleteByAgeFromServer(
362             (bool)value.ToInteger(&errorCode, 16));
363       }
364       if (NS_SUCCEEDED(
365               nsWMUtils::GetValueForTag(xmlDoc, "Expire_Days", value))) {
366         pop3Server->SetNumDaysToLeaveOnServer(value.ToInteger(&errorCode, 16));
367       }
368       if (NS_SUCCEEDED(
369               nsWMUtils::GetValueForTag(xmlDoc, "Account_Name", value))) {
370         rv = in->SetPrettyName(value);
371       }
372 
373       in->SetDoBiff(checkNewMail);
374       in->SetBiffMinutes(checkNewMailTime);
375 
376       // set local folders as the Inbox to use for this POP3 server
377       nsCOMPtr<nsIMsgIncomingServer> localFoldersServer;
378       pMgr->GetLocalFoldersServer(getter_AddRefs(localFoldersServer));
379       if (!localFoldersServer) {
380         // XXX: We may need to move this local folder creation
381         // code to the generic nsImportSettings code
382         // if the other import modules end up needing to do this too.
383         // if Local Folders does not exist already, create it
384         rv = pMgr->CreateLocalMailAccount();
385         if (NS_FAILED(rv)) {
386           IMPORT_LOG0("*** Failed to create Local Folders!\n");
387           return false;
388         }
389         pMgr->GetLocalFoldersServer(getter_AddRefs(localFoldersServer));
390       }
391 
392       // now get the account for this server
393       nsCOMPtr<nsIMsgAccount> localFoldersAccount;
394       pMgr->FindAccountForServer(localFoldersServer,
395                                  getter_AddRefs(localFoldersAccount));
396       if (localFoldersAccount) {
397         nsCString localFoldersAcctKey;
398         localFoldersAccount->GetKey(localFoldersAcctKey);
399         pop3Server->SetDeferredToAccount(localFoldersAcctKey);
400       }
401 
402       IMPORT_LOG2("Created POP3 server named: %S, userName: %S\n",
403                   serverName.get(), userName.get());
404 
405       // We have a server, create an account.
406       nsCOMPtr<nsIMsgAccount> account;
407       rv = pMgr->CreateAccount(getter_AddRefs(account));
408       if (NS_SUCCEEDED(rv) && account) {
409         rv = account->SetIncomingServer(in);
410         IMPORT_LOG0(
411             "Created a new account and set the incoming "
412             "server to the POP3 server.\n");
413 
414         // Fiddle with the identities
415         SetIdentities(pMgr, account, xmlDoc, userName, authMethod, false);
416         result = true;
417         if (ppAccount) account.forget(ppAccount);
418       }
419     }
420   } else if (NS_SUCCEEDED(rv) && in) {
421     IMPORT_LOG2("Existing POP3 server named: %S, userName: %S\n",
422                 serverName.get(), userName.get());
423     // for an existing server we create another identity,
424     // TB listed under 'manage identities'
425     nsCOMPtr<nsIMsgAccount> account;
426     rv = pMgr->FindAccountForServer(in, getter_AddRefs(account));
427     if (NS_SUCCEEDED(rv) && account) {
428       IMPORT_LOG0(
429           "Created identity and added to existing POP3 incoming server.\n");
430       // Fiddle with the identities
431       in->GetAuthMethod(&authMethod);
432       SetIdentities(pMgr, account, xmlDoc, userName, authMethod, false);
433       result = true;
434       if (ppAccount) account.forget(ppAccount);
435     }
436   } else
437     result = true;
438   return result;
439 }
440 
DoNNTPServer(nsIMsgAccountManager * pMgr,mozilla::dom::Document * xmlDoc,const nsString & serverName,nsIMsgAccount ** ppAccount)441 bool WMSettings::DoNNTPServer(nsIMsgAccountManager* pMgr,
442                               mozilla::dom::Document* xmlDoc,
443                               const nsString& serverName,
444                               nsIMsgAccount** ppAccount) {
445   int32_t authMethod;
446   nsresult errorCode;
447   if (ppAccount) *ppAccount = nullptr;
448 
449   nsAutoString userName, value;
450   // this only exists if NNTP server requires it or not, anonymous login
451   nsWMUtils::GetValueForTag(xmlDoc, "NNTP_User_Name", userName);
452   bool result = false;
453 
454   // I now have a user name/server name pair, find out if it already exists?
455   // NNTP can have empty user name.  This is wild card in findserver
456   nsCOMPtr<nsIMsgIncomingServer> in;
457   nsresult rv =
458       pMgr->FindServer(EmptyCString(), NS_ConvertUTF16toUTF8(serverName),
459                        "nntp"_ns, getter_AddRefs(in));
460   if (NS_FAILED(rv) || (in == nullptr)) {
461     // Create the incoming server and an account for it?
462     rv = pMgr->CreateIncomingServer(nsDependentCString(""),
463                                     NS_ConvertUTF16toUTF8(serverName),
464                                     "nntp"_ns, getter_AddRefs(in));
465     if (NS_SUCCEEDED(rv) && in) {
466       nsCOMPtr<nsINntpIncomingServer> nntpServer = do_QueryInterface(in);
467       if (!nntpServer) {
468         IMPORT_LOG1("*** Failed to create nsINnntpIncomingServer for %S!\n",
469                     serverName.get());
470         return false;
471       }
472       if (!userName.IsEmpty()) {  // if username req'd then auth req'd
473         nntpServer->SetPushAuth(true);
474         in->SetUsername(NS_ConvertUTF16toUTF8(userName));
475       }
476 
477       nsAutoString value;
478       if (NS_SUCCEEDED(nsWMUtils::GetValueForTag(xmlDoc, "NNTP_Port", value))) {
479         in->SetPort(value.ToInteger(&errorCode, 16));
480       }
481 
482       if (NS_SUCCEEDED(
483               nsWMUtils::GetValueForTag(xmlDoc, "Account_Name", value))) {
484         in->SetPrettyName(value);
485       }
486 
487       if (NS_SUCCEEDED(
488               nsWMUtils::GetValueForTag(xmlDoc, "NNTP_Use_Sicily", value))) {
489         bool secAuth = (bool)value.ToInteger(&errorCode, 16);
490         authMethod = secAuth ? nsMsgAuthMethod::secure
491                              : nsMsgAuthMethod::passwordCleartext;
492         in->SetAuthMethod(authMethod);
493       }
494 
495       IMPORT_LOG2("Created NNTP server named: %S, userName: %S\n",
496                   serverName.get(), userName.get());
497 
498       // We have a server, create an account.
499       nsCOMPtr<nsIMsgAccount> account;
500       rv = pMgr->CreateAccount(getter_AddRefs(account));
501       if (NS_SUCCEEDED(rv) && account) {
502         rv = account->SetIncomingServer(in);
503 
504         IMPORT_LOG0(
505             "Created an account and set the NNTP server "
506             "as the incoming server\n");
507 
508         // Fiddle with the identities
509         SetIdentities(pMgr, account, xmlDoc, userName, authMethod, true);
510         result = true;
511         if (ppAccount) account.forget(ppAccount);
512       }
513     }
514   } else if (NS_SUCCEEDED(rv) && in) {
515     // for the existing server...
516     nsCOMPtr<nsIMsgAccount> account;
517     rv = pMgr->FindAccountForServer(in, getter_AddRefs(account));
518     if (NS_SUCCEEDED(rv) && account) {
519       IMPORT_LOG0(
520           "Using existing account and set the "
521           "NNTP server as the incoming server\n");
522       // Fiddle with the identities
523       in->GetAuthMethod(&authMethod);
524       SetIdentities(pMgr, account, xmlDoc, userName, authMethod, true);
525       result = true;
526       if (ppAccount) account.forget(ppAccount);
527     }
528   } else
529     result = true;
530   return result;
531 }
532 
SetIdentities(nsIMsgAccountManager * pMgr,nsIMsgAccount * pAcc,mozilla::dom::Document * xmlDoc,nsAutoString & inUserName,int32_t authMethodIncoming,bool isNNTP)533 void WMSettings::SetIdentities(nsIMsgAccountManager* pMgr, nsIMsgAccount* pAcc,
534                                mozilla::dom::Document* xmlDoc,
535                                nsAutoString& inUserName,
536                                int32_t authMethodIncoming, bool isNNTP) {
537   // Get the relevant information for an identity
538   nsresult rv;
539   nsAutoString value;
540 
541   nsCOMPtr<nsIMsgIdentity> id;
542   rv = pMgr->CreateIdentity(getter_AddRefs(id));
543   if (id) {
544     IMPORT_LOG0("Created identity and added to the account\n");
545     if (NS_SUCCEEDED(nsWMUtils::GetValueForTag(
546             xmlDoc, isNNTP ? "NNTP_Display_Name" : "SMTP_Display_Name",
547             value))) {
548       id->SetFullName(value);
549       IMPORT_LOG1("\tname: %S\n", value.get());
550     }
551 
552     if (NS_SUCCEEDED(nsWMUtils::GetValueForTag(
553             xmlDoc,
554             isNNTP ? "NNTP_Organization_Name" : "SMTP_Organization_Name",
555             value))) {
556       id->SetOrganization(value);
557     }
558 
559     if (NS_SUCCEEDED(nsWMUtils::GetValueForTag(
560             xmlDoc, isNNTP ? "NNTP_Email_Address" : "SMTP_Email_Address",
561             value))) {
562       id->SetEmail(NS_ConvertUTF16toUTF8(value));
563       IMPORT_LOG1("\temail: %S\n", value.get());
564     }
565 
566     if (NS_SUCCEEDED(
567             nsWMUtils::GetValueForTag(xmlDoc,
568                                       isNNTP ? "NNTP_Reply_To_Email_Address"
569                                              : "SMTP_Reply_To_Email_Address",
570                                       value))) {
571       id->SetReplyTo(NS_ConvertUTF16toUTF8(value));
572     }
573 
574     // Windows users are used to top style quoting.
575     id->SetReplyOnTop(isNNTP ? 0 : 1);
576     pAcc->AddIdentity(id);
577   }
578 
579   if (!isNNTP)  // NNTP does not use SMTP in OE or TB
580     SetSmtpServer(xmlDoc, id, inUserName, authMethodIncoming);
581 }
582 
SetSmtpServer(mozilla::dom::Document * xmlDoc,nsIMsgIdentity * id,nsAutoString & inUserName,int32_t authMethodIncoming)583 void WMSettings::SetSmtpServer(mozilla::dom::Document* xmlDoc,
584                                nsIMsgIdentity* id, nsAutoString& inUserName,
585                                int32_t authMethodIncoming) {
586   nsresult errorCode;
587 
588   // set the id.smtpserver accordingly
589   if (!id) return;
590   nsCString smtpServerKey, userName;
591   nsAutoString value, smtpName;
592   if (NS_FAILED(nsWMUtils::GetValueForTag(xmlDoc, "SMTP_Server", smtpName)))
593     return;
594 
595   // first we have to calculate the smtp user name which is based on sicily
596   // smtp user name depends on sicily which may or not exist
597   int32_t useSicily = 0;
598   if (NS_SUCCEEDED(
599           nsWMUtils::GetValueForTag(xmlDoc, "SMTP_Use_Sicily", value))) {
600     useSicily = (int32_t)value.ToInteger(&errorCode, 16);
601   }
602   switch (useSicily) {
603     case 1:
604     case 3:
605       if (NS_SUCCEEDED(
606               nsWMUtils::GetValueForTag(xmlDoc, "SMTP_User_Name", value))) {
607         CopyUTF16toUTF8(value, userName);
608       } else {
609         CopyUTF16toUTF8(inUserName, userName);
610       }
611       break;
612     case 2:
613       CopyUTF16toUTF8(inUserName, userName);
614       break;
615     default:
616       break;  // initial userName == ""
617   }
618 
619   nsresult rv;
620   nsCOMPtr<nsISmtpService> smtpService(
621       do_GetService(NS_SMTPSERVICE_CONTRACTID, &rv));
622   if (NS_SUCCEEDED(rv) && smtpService) {
623     nsCOMPtr<nsISmtpServer> extgServer;
624     // don't try to make another server
625     // regardless if username doesn't match
626     rv = smtpService->FindServer(userName.get(),
627                                  NS_ConvertUTF16toUTF8(smtpName).get(),
628                                  getter_AddRefs(extgServer));
629     if (NS_SUCCEEDED(rv) && extgServer) {
630       // set our account keyed to this smptserver key
631       extgServer->GetKey(getter_Copies(smtpServerKey));
632       id->SetSmtpServerKey(smtpServerKey);
633 
634       IMPORT_LOG1("SMTP server already exists: %s\n",
635                   NS_ConvertUTF16toUTF8(smtpName).get());
636     } else {
637       nsCOMPtr<nsISmtpServer> smtpServer;
638       rv = smtpService->CreateServer(getter_AddRefs(smtpServer));
639       if (NS_SUCCEEDED(rv) && smtpServer) {
640         if (NS_SUCCEEDED(
641                 nsWMUtils::GetValueForTag(xmlDoc, "SMTP_Port", value))) {
642           smtpServer->SetPort(value.ToInteger(&errorCode, 16));
643         }
644 
645         if (NS_SUCCEEDED(nsWMUtils::GetValueForTag(
646                 xmlDoc, "SMTP_Secure_Connection", value))) {
647           if (value.ToInteger(&errorCode, 16) == 1)
648             smtpServer->SetSocketType(nsMsgSocketType::SSL);
649           else
650             smtpServer->SetSocketType(nsMsgSocketType::plain);
651         }
652         smtpServer->SetUsername(userName);
653         switch (useSicily) {
654           case 1:
655             smtpServer->SetAuthMethod(nsMsgAuthMethod::secure);
656             break;
657           case 2:  // requires SMTP authentication to use the incoming server
658                    // settings
659             smtpServer->SetAuthMethod(authMethodIncoming);
660             break;
661           case 3:
662             smtpServer->SetAuthMethod(nsMsgAuthMethod::passwordCleartext);
663             break;
664           default:
665             smtpServer->SetAuthMethod(nsMsgAuthMethod::none);
666         }
667 
668         smtpServer->SetHostname(NS_ConvertUTF16toUTF8(smtpName));
669 
670         smtpServer->GetKey(getter_Copies(smtpServerKey));
671         id->SetSmtpServerKey(smtpServerKey);
672 
673         IMPORT_LOG1("Created new SMTP server: %s\n",
674                     NS_ConvertUTF16toUTF8(smtpName).get());
675       }
676     }
677   }
678 }
679