Closed Bug 312593 Opened 19 years ago Closed 7 years ago

thunderbird says the password/login failed when using symbols (unicode characters) in passwords

Categories

(Thunderbird :: Security, defect)

defect
Not set
major

Tracking

(thunderbird_esr52 wontfix, thunderbird57 fixed, thunderbird58 fixed)

RESOLVED FIXED
Thunderbird 58.0
Tracking Status
thunderbird_esr52 --- wontfix
thunderbird57 --- fixed
thunderbird58 --- fixed

People

(Reporter: michaeleaton, Assigned: jorgk-bmo)

References

(Blocks 1 open bug)

Details

(Keywords: intl)

Attachments

(2 files, 6 obsolete files)

User-Agent:       Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; .NET CLR 1.1.4322)
Build Identifier: 

When i add/import/use an account within thunderbird that contains any wierd 
symbols ( copyright symbol ©, trademark symbol ™).. 

I've created a test account for you here:


Mail Server: mail.merito.co.uk (both smtp/pop3)
Username: thunderbirdbug@merito.co.uk
Password: ©password™    
(incase it doesnt show here, its a copyright symbol first, alt + 0169, the 
word 'password' then, the TM symbol alt + 0153)

Reproducible: Always

Steps to Reproduce:
1. add an email account
2. enter username/password details with a symbol like: ©/™ (c)(tm)(r)
3. click get mail :)

Actual Results:  
login failed/incorrect password, tried both current stable release of 
thunderbird, and also beta2.

Expected Results:  
it should of polled the mail server as normal.
Just thought i'd show mail logs from thunderbird and then outlook express..


####Thunderbird#####

Oct 16 01:15:22 tuscan cpanelpop[30249]: Connection from host=84.9.*.* to 
ip=85.92.*.*
Oct 16 01:15:22 tuscan cpanelpop[30249]: Password failure for 
user=thunderbirdbug homedir=/home/merito passwd=/home/merito/etc/*****/shadow
Oct 16 01:15:22 tuscan cpanelpop[30249]: Session Closed host=84.9.*.* ip= 
user=root realuser= totalxfer=181

####Outlook Express#####

Oct 16 01:18:31 tuscan cpanelpop[31015]: Connection from host=84.9.*.* to 
ip=85.92.*.*
Oct 16 01:18:31 tuscan cpanelpop[31015]: Login host=84.9.*.* ip= 
user=thunderbirdbug@merito.co.uk realuser=thunderbirdbug@merito.co.uk
Oct 16 01:18:32 tuscan cpanelpop[31015]: Session Closed host=84.9.*.* ip= 
user=thunderbirdbug@merito.co.uk realuser=thunderbirdbug@merito.co.uk 
totalxfer=1589
thx for the test account; I'll try it out.
Confirming

Thunderbird 20051017
Windows XP
Status: UNCONFIRMED → NEW
Ever confirmed: true
Ugh, the problem is that the wallet interfaces use unicode passwords, and wallet
stores them internally as utf8. But when we get the unicode password back, we do
a lossy convert to ascii. It's called lossy for a reason, I guess :-( jshin, is
there any hope here? I think we just want to effectively treat the passwords as
8-bit ascii throughout...
I have to check whether SMTP auth and POP3 support non-ASCII password and how if
they do. 

Reporter, do you know any mail client that works with your password? 

This is the only thing thats stopping me from switching to mozilla world! I 
hope this helps with the motivation.. 


I've only tried Outlook Express and Outlook.. they both work..


Hope this helps.
We originally had problems with international passwords on SMTP and IMAP, so working through all the dang password code to use UTF8 fixed the issue on Windows and Linux.  In a rush generating patches, so please let me know if there are any issues.
Attachment #233086 - Flags: review?(mscott)
Comment on attachment 233086 [details] [diff] [review]
This patch uses pure utf8 for all password handling

>? utf8passwordPatch.diff
>? imap/src/nsImapProtocol.diff
>Index: base/public/nsIMsgIncomingServer.idl
>===================================================================
>RCS file: /cvsroot/mozilla/mailnews/base/public/nsIMsgIncomingServer.idl,v
>retrieving revision 1.100
>diff -u -8 -p -r1.100 nsIMsgIncomingServer.idl
>--- base/public/nsIMsgIncomingServer.idl	18 May 2006 18:03:17 -0000	1.100
>+++ base/public/nsIMsgIncomingServer.idl	10 Aug 2006 15:05:33 -0000
>@@ -116,20 +116,20 @@ interface nsIMsgIncomingServer : nsISupp
> 
>   // Perform specific tasks (reset flags, remove files, etc) for account user/server name changes.
>   void OnUserOrHostNameChanged(in string oldName, in string newName);
>   
>   /* should we remember the password? */
>   attribute boolean rememberPassword;
> 
>   /* cleartext version of the password */
>-  attribute string password;
>+  attribute AUTF8String password;
> 
>   /* prompt the user for a password */
>-  string getPasswordWithUI(in wstring aPromptString, in wstring aPromptTitle, in nsIMsgWindow aMsgWindow, out boolean okayValue);
>+  AUTF8String getPasswordWithUI(in wstring aPromptString, in wstring aPromptTitle, in nsIMsgWindow aMsgWindow, out boolean okayValue);
> 
>   /* forget the password in memory and in single signon database */
>   void forgetPassword();
> 
>   /**
>    * logon succeeded - persist password, if user chooses.
>    */
>   void storePassword(); 
>Index: base/src/nsMessengerMigrator.cpp
>===================================================================
>RCS file: /cvsroot/mozilla/mailnews/base/src/nsMessengerMigrator.cpp,v
>retrieving revision 1.118
>diff -u -8 -p -r1.118 nsMessengerMigrator.cpp
>--- base/src/nsMessengerMigrator.cpp	8 Nov 2005 09:20:11 -0000	1.118
>+++ base/src/nsMessengerMigrator.cpp	10 Aug 2006 15:07:33 -0000
>@@ -1597,17 +1597,17 @@ nsMessengerMigrator::MigrateOldMailPrefs
> {
>   nsresult rv;
> 
>   // don't migrate the remember password pref.  see bug #42216 
>   //MIGRATE_SIMPLE_BOOL_PREF(PREF_4X_MAIL_REMEMBER_PASSWORD,server,SetRememberPassword)
>   rv = server->SetRememberPassword(PR_FALSE);
>   if (NS_FAILED(rv)) return rv;
>   
>-  rv = server->SetPassword(nsnull);
>+  rv = server->SetPassword(NS_LITERAL_CSTRING(""));
>   if (NS_FAILED(rv)) return rv;
> 
>   MIGRATE_SIMPLE_BOOL_PREF(PREF_4X_MAIL_CHECK_NEW_MAIL,server,SetDoBiff)
>   MIGRATE_SIMPLE_INT_PREF(PREF_4X_MAIL_CHECK_TIME,server,SetBiffMinutes)
>   MIGRATE_SIMPLE_BOOL_PREF(PREF_4X_MAIL_POP3_GETS_NEW_MAIL,server,SetDownloadOnBiff)
> 
>   nsCOMPtr<nsIPop3IncomingServer> popServer;
>   popServer = do_QueryInterface(server, &rv);
>@@ -1860,17 +1860,17 @@ nsMessengerMigrator::MigrateOldImapPrefs
>   if (NS_FAILED(rv)) return rv;
> 
>   // upgrade the msg incoming server prefs
>   // don't migrate the remember password pref.  see bug #42216 
>   //MIGRATE_BOOL_PREF("mail.imap.server.%s.remember_password",hostAndPort,server,SetRememberPassword)
>   rv = server->SetRememberPassword(PR_FALSE);
>   if (NS_FAILED(rv)) return rv;
> 
>-  rv = server->SetPassword(nsnull);
>+  rv = server->SetPassword(NS_LITERAL_CSTRING(""));
>   if (NS_FAILED(rv)) return rv;
> 
>   // upgrade the imap incoming server specific prefs
>   MIGRATE_BOOL_PREF("mail.imap.server.%s.check_new_mail",hostAndPort,server,SetDoBiff)
>   MIGRATE_INT_PREF("mail.imap.server.%s.check_time",hostAndPort,server,SetBiffMinutes)
>   // "mail.imap.new_mail_get_headers" was a global pref across all imap servers in 4.x
>   // in 5.0, it's per server
>   MIGRATE_BOOL_PREF("%s","mail.imap.new_mail_get_headers",server,SetDownloadOnBiff)
>Index: base/src/nsMsgAccountManager.cpp
>===================================================================
>RCS file: /cvsroot/mozilla/mailnews/base/src/nsMsgAccountManager.cpp,v
>retrieving revision 1.312
>diff -u -8 -p -r1.312 nsMsgAccountManager.cpp
>--- base/src/nsMsgAccountManager.cpp	9 Aug 2006 01:25:10 -0000	1.312
>+++ base/src/nsMsgAccountManager.cpp	10 Aug 2006 15:10:01 -0000
>@@ -1033,27 +1033,26 @@ PRBool PR_CALLBACK nsMsgAccountManager::
>     nsXPIDLCString type;
>     server->GetType(getter_Copies(type));
>     if (root)
>     {
>       nsCOMPtr<nsIMsgFolder> folder;
>       folder = do_QueryInterface(root);
>       if (folder)
>       {
>-         nsXPIDLCString passwd;
>+         nsCString passwd;
>          PRBool serverRequiresPasswordForAuthentication = PR_TRUE;
>          PRBool isImap = (type ? PL_strcmp(type, "imap") == 0 :
>                           PR_FALSE);
>          if (isImap)
>          {
>            server->GetServerRequiresPasswordForBiff(&serverRequiresPasswordForAuthentication);
>-           server->GetPassword(getter_Copies(passwd));
>+           server->GetPassword(passwd);
>          }
>-         if (!isImap || (isImap && (!serverRequiresPasswordForAuthentication || (passwd && 
>-                        strlen((const char*) passwd)))))
>+         if (!isImap || (isImap && (!serverRequiresPasswordForAuthentication || passwd.Length())))
>          {
>            nsCOMPtr<nsIUrlListener> urlListener;
>            nsCOMPtr<nsIMsgAccountManager> accountManager = 
>                     do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
>            if (NS_FAILED(rv)) return rv;
>            if (isImap)
>              urlListener = do_QueryInterface(accountManager, &rv);
>                     
>Index: base/util/nsMsgDBFolder.cpp
>===================================================================
>RCS file: /cvsroot/mozilla/mailnews/base/util/nsMsgDBFolder.cpp,v
>retrieving revision 1.280
>diff -u -8 -p -r1.280 nsMsgDBFolder.cpp
>--- base/util/nsMsgDBFolder.cpp	18 Jul 2006 00:44:40 -0000	1.280
>+++ base/util/nsMsgDBFolder.cpp	10 Aug 2006 15:12:41 -0000
>@@ -2067,17 +2067,17 @@ nsresult nsMsgDBFolder::PromptForCachePa
>   PRBool userDidntCancel;
>   passwordCorrect = PR_FALSE;
>   nsCOMPtr <nsIStringBundle> bundle;
>   nsresult rv = GetBaseStringBundle(getter_AddRefs(bundle));
>   NS_ENSURE_SUCCESS(rv, rv);
>   nsXPIDLCString hostName;
>   nsXPIDLCString userName;
>   nsXPIDLString passwordTemplate;
>-  nsXPIDLCString password;
>+  nsCString password;
>   nsXPIDLString passwordTitle;
>   nsXPIDLString passwordPromptString;
> 
>   server->GetRealHostName(getter_Copies(hostName));
>   server->GetRealUsername(getter_Copies(userName));
>   bundle->GetStringFromName(NS_LITERAL_STRING("passwordTitle").get(), getter_Copies(passwordTitle));
>   bundle->GetStringFromName(NS_LITERAL_STRING("passwordPrompt").get(), getter_Copies(passwordTemplate));
> 
>@@ -2092,17 +2092,17 @@ nsresult nsMsgDBFolder::PromptForCachePa
>   NS_ENSURE_SUCCESS(rv, rv);
> 
>   do
>   {
>     rv = server->GetPasswordWithUI(passwordPromptString,
>                                    passwordTitle, 
>                                    aWindow,
>                                    &userDidntCancel,
>-                                   getter_Copies(password));
>+                                   password);
>     if (rv != NS_MSG_PASSWORD_PROMPT_CANCELLED && !password.IsEmpty()) 
>     {
>       nsCOMPtr <nsIPasswordManagerInternal> passwordMgrInt = do_GetService(NS_PASSWORDMANAGER_CONTRACTID, &rv);
>       if(passwordMgrInt) 
>       {
> 
>         // Get the current server URI
>         nsXPIDLCString currServerUri;
>@@ -2119,19 +2119,19 @@ nsresult nsMsgDBFolder::PromptForCachePa
>         // Get password entry corresponding to the host URI we are passing in.
>         rv = passwordMgrInt->FindPasswordEntry(currServerUri, empty, empty,
>                                                hostFound, userNameFound,
>                                                passwordFound);
>         if (NS_FAILED(rv)) 
>           break;
>         // compare the user-entered password with the saved password with
>         // the munged uri.
>-        passwordCorrect = password.Equals(NS_ConvertUTF16toUTF8(passwordFound).get());
>+        passwordCorrect = password == NS_ConvertUTF16toUTF8(passwordFound);
>         if (!passwordCorrect)
>-          server->SetPassword("");
>+          server->SetPassword(NS_LITERAL_CSTRING(""));
>         else
>         {
>           nsCOMPtr<nsIMsgAccountManager> accountManager = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID);
>           if (accountManager)
>             accountManager->SetUserNeedsToAuthenticate(PR_FALSE);
>         }
>       }
>     }
>Index: base/util/nsMsgIncomingServer.cpp
>===================================================================
>RCS file: /cvsroot/mozilla/mailnews/base/util/nsMsgIncomingServer.cpp,v
>retrieving revision 1.238
>diff -u -8 -p -r1.238 nsMsgIncomingServer.cpp
>--- base/util/nsMsgIncomingServer.cpp	23 May 2006 17:16:01 -0000	1.238
>+++ base/util/nsMsgIncomingServer.cpp	10 Aug 2006 15:21:01 -0000
>@@ -771,17 +771,17 @@ nsMsgIncomingServer::ToString(PRUnichar*
>   *aResult = ToNewUnicode(NS_LITERAL_STRING("[nsIMsgIncomingServer: ") +
>                           NS_ConvertASCIItoUTF16(m_serverKey) +
>                           NS_LITERAL_STRING("]"));
>   NS_ASSERTION(*aResult, "no server name!");
>   return NS_OK;
> }
>   
> 
>-NS_IMETHODIMP nsMsgIncomingServer::SetPassword(const char * aPassword)
>+NS_IMETHODIMP nsMsgIncomingServer::SetPassword(const nsACString &aPassword)
> {
>   m_password = aPassword;
>   
>   nsresult rv;
>   PRBool rememberPassword = PR_FALSE;
>   
>   rv = GetRememberPassword(&rememberPassword);
>   if (NS_FAILED(rv)) return rv;
>@@ -790,40 +790,38 @@ NS_IMETHODIMP nsMsgIncomingServer::SetPa
>   {
>     rv = StorePassword();
>     if (NS_FAILED(rv)) return rv;
>   }
>   
>   return NS_OK;
> }
> 
>-NS_IMETHODIMP nsMsgIncomingServer::GetPassword(char ** aPassword)
>+NS_IMETHODIMP nsMsgIncomingServer::GetPassword(nsACString &aPassword)
> {
>-  NS_ENSURE_ARG_POINTER(aPassword);
>-  *aPassword = ToNewCString(m_password);
>+  aPassword = m_password;
>   return NS_OK;
> }
> 
> NS_IMETHODIMP nsMsgIncomingServer::GetServerRequiresPasswordForBiff(PRBool *aServerRequiresPasswordForBiff)
> {
>   NS_ENSURE_ARG_POINTER(aServerRequiresPasswordForBiff);
>   *aServerRequiresPasswordForBiff = PR_TRUE;
>   return NS_OK;
> }
> 
> NS_IMETHODIMP
> nsMsgIncomingServer::GetPasswordWithUI(const PRUnichar * aPromptMessage, const
>                                        PRUnichar *aPromptTitle, 
>                                        nsIMsgWindow* aMsgWindow,
>                                        PRBool *okayValue,
>-                                       char **aPassword) 
>+                                       nsACString &aPassword) 
> {
>   nsresult rv = NS_OK;
>   
>-  NS_ENSURE_ARG_POINTER(aPassword);
>   NS_ENSURE_ARG_POINTER(okayValue);
>   
>   if (m_password.IsEmpty()) 
>   {
>     // let's see if we have the password in the password manager and  
>     // can avoid this prompting thing. This makes it easier to get embedders
>     // to get up and running w/o a password prompting UI. We already depend on
>     // nsIPasswordManagerInternal so this doesn't introduce a new dependency.
>@@ -890,24 +888,24 @@ nsMsgIncomingServer::GetPasswordWithUI(c
>         NS_ConvertASCIItoUTF16(serverUri).get(), savePasswordType,
>         &uniPassword, okayValue);
>       nsAutoString uniPasswordAdopted;
>       uniPasswordAdopted.Adopt(uniPassword);
>       if (NS_FAILED(rv)) return rv;
>       
>       if (!*okayValue) // if the user pressed cancel, just return NULL;
>       {
>-        *aPassword = nsnull;
>+        aPassword = NS_LITERAL_CSTRING("");
>         return NS_MSG_PASSWORD_PROMPT_CANCELLED;
>       }
>       
>       // we got a password back...so remember it
>       nsCString aCStr; 
>-      aCStr.AssignWithConversion(uniPasswordAdopted); 
>-      rv = SetPassword(aCStr.get());
>+      aCStr = NS_ConvertUTF16toUTF8(uniPasswordAdopted); 
>+      rv = SetPassword(aCStr);
>       if (NS_FAILED(rv)) return rv;
>     } // if we got a prompt dialog
>   } // if the password is empty
>   
>   return GetPassword(aPassword);
> }
> 
> NS_IMETHODIMP
>@@ -916,18 +914,18 @@ nsMsgIncomingServer::StorePassword()
>     nsresult rv;
> 
>     // we only need to store this if we're password protecting the local cache.
>     // Otherwise, the password manager handles storing the password if the user 
>     // checks the "remember password" box.
>     if (!PasswordProtectLocalCache())
>       return NS_OK;
> 
>-    nsXPIDLCString pwd;
>-    rv = GetPassword(getter_Copies(pwd));
>+    nsCString pwd;
>+    rv = GetPassword(pwd);
>     if (NS_FAILED(rv)) return rv;
> 
>     nsCOMPtr<nsIObserverService> observerService = do_GetService("@mozilla.org/observer-service;1", &rv);
>     NS_ENSURE_SUCCESS(rv,rv);
> 
>     nsXPIDLCString serverSpec;
>     rv = GetServerURI(getter_Copies(serverSpec));
>     if (NS_FAILED(rv)) return rv;
>@@ -968,17 +966,17 @@ nsMsgIncomingServer::ForgetPassword()
> 
>     //this is need to make sure wallet service has been created
>     rv = CreateServicesForPasswordManager();
>     NS_ENSURE_SUCCESS(rv, rv);
> 
>     rv = observerService->NotifyObservers(uri, "login-failed", nsnull);
>     NS_ENSURE_SUCCESS(rv,rv);
> 
>-    rv = SetPassword("");
>+    rv = SetPassword(NS_LITERAL_CSTRING(""));
>     return rv;
> }
> 
> NS_IMETHODIMP
> nsMsgIncomingServer::ForgetSessionPassword()
> {
>     m_password.Truncate(0);
>     return NS_OK;
>@@ -1889,19 +1887,19 @@ nsMsgIncomingServer::GetPasswordPromptRe
>       if (!passwordFound.IsEmpty()) 
>       {
>         if (PasswordProtectLocalCache()) // hmm, shouldn't be in here, so remove it.
>         {
>           ForgetPassword();
>         }
>         else
>         {
>-          nsCAutoString cStrPassword;
>-          cStrPassword.AssignWithConversion(passwordFound);
>-          rv = SetPassword(cStrPassword.get());
>+          nsCString cStrPassword;
>+          cStrPassword = NS_ConvertUTF16toUTF8(passwordFound);
>+          rv = SetPassword(cStrPassword);
>           NS_ENSURE_SUCCESS(rv, rv);
>         }
>       }
>     }
>   }
>   *aPasswordIsRequired = m_password.IsEmpty();
>   return rv;
> }
>Index: compose/public/nsISmtpServer.idl
>===================================================================
>RCS file: /cvsroot/mozilla/mailnews/compose/public/nsISmtpServer.idl,v
>retrieving revision 1.15
>diff -u -8 -p -r1.15 nsISmtpServer.idl
>--- compose/public/nsISmtpServer.idl	3 Mar 2005 18:08:46 -0000	1.15
>+++ compose/public/nsISmtpServer.idl	10 Aug 2006 15:22:13 -0000
>@@ -44,27 +44,27 @@ interface nsIAuthPrompt;
> interface nsISmtpServer : nsISupports {
>     
>     attribute string key;       // unique identifier
>     
>     attribute AUTF8String description; // user provided description for the server
>     attribute string hostname;
>     attribute PRInt32 port;
>     attribute string username;
>-    attribute string password;
>+    attribute AUTF8String password;
>     readonly attribute string displayname;
> 
>     /* what kind of logon redirector to use for this server, if any */
>     attribute string redirectorType;   
> 
>     attribute long authMethod;
>     readonly attribute boolean trySecAuth;
>     attribute long trySSL;
> 
>     readonly attribute string serverURI;
>-    string getPasswordWithUI(in wstring promptString, in wstring promptTitle,
>+    AUTF8String getPasswordWithUI(in wstring promptString, in wstring promptTitle,
>                              in nsIAuthPrompt netPrompt);
>     void getUsernamePasswordWithUI(in wstring promptString, in wstring promptTitle,
>-                             in nsIAuthPrompt netPrompt, out string userid, out string password);
>+                             in nsIAuthPrompt netPrompt, out string userid, out AUTF8String password);
>     void forgetPassword();
> 
> 	void clearAllValues();
> };
>Index: compose/public/nsISmtpService.idl
>===================================================================
>RCS file: /cvsroot/mozilla/mailnews/compose/public/nsISmtpService.idl,v
>retrieving revision 1.20
>diff -u -8 -p -r1.20 nsISmtpService.idl
>--- compose/public/nsISmtpService.idl	17 Apr 2004 18:32:22 -0000	1.20
>+++ compose/public/nsISmtpService.idl	10 Aug 2006 15:22:44 -0000
>@@ -67,17 +67,17 @@ interface nsISmtpService : nsISupports {
>   // a dialog to popup if the password is needed for a secure transmission
>   //
>   // The server associate to the Sender Identity will be used or the default
>   // server.
>   //////////////////////////////////////////////////////////////////////////
> 
>   void SendMailMessage(in nsIFileSpec aFilePath, in string aRecipients, 
>                        in nsIMsgIdentity aSenderIdentity,
>-                       in string aPassword,
>+                       in AUTF8String aPassword,
>                        in nsIUrlListener aUrlListener, 
> 					             in nsIMsgStatusFeedback aStatusListener, 
>                        in nsIInterfaceRequestor aNotificationCallbacks,
>                        out nsIURI aURL,
> 					             out nsIRequest aRequest);
> 
>   /**
>    * Return the SMTP server that is associated with an identity.
>Index: compose/src/nsMsgSend.cpp
>===================================================================
>RCS file: /cvsroot/mozilla/mailnews/compose/src/nsMsgSend.cpp,v
>retrieving revision 1.381
>diff -u -8 -p -r1.381 nsMsgSend.cpp
>--- compose/src/nsMsgSend.cpp	18 Jun 2006 17:46:46 -0000	1.381
>+++ compose/src/nsMsgSend.cpp	10 Aug 2006 15:24:43 -0000
>@@ -3609,17 +3609,17 @@ nsMsgComposeAndSend::DeliverFileAsMail()
>     mComposeBundle->GetStringByID(NS_MSG_SENDING_MESSAGE, getter_Copies(msg));
>     SetStatusMessage( msg );
>     nsCOMPtr<nsIMsgStatusFeedback> msgStatus (do_QueryInterface(mSendProgress));
>     // if the sendProgress isn't set, let's use the member variable.
>     if (!msgStatus)
>       msgStatus = do_QueryInterface(mStatusFeedback);
> 
>     rv = smtpService->SendMailMessage(aFileSpec, buf, mUserIdentity,
>-                                      mSmtpPassword.get(), uriListener, msgStatus,
>+                                      mSmtpPassword, uriListener, msgStatus,
>                                       callbacks, nsnull, getter_AddRefs(mRunningRequest));
>   }
>   
>   PR_FREEIF(buf); // free the buf because we are done with it....
>   return rv;
> }
> 
> nsresult
>Index: compose/src/nsSmtpProtocol.cpp
>===================================================================
>RCS file: /cvsroot/mozilla/mailnews/compose/src/nsSmtpProtocol.cpp,v
>retrieving revision 1.180
>diff -u -8 -p -r1.180 nsSmtpProtocol.cpp
>--- compose/src/nsSmtpProtocol.cpp	13 Jul 2006 20:14:07 -0000	1.180
>+++ compose/src/nsSmtpProtocol.cpp	10 Aug 2006 15:32:14 -0000
>@@ -1065,34 +1065,34 @@ PRInt32 nsSmtpProtocol::AuthLoginStep0Re
> 
> PRInt32 nsSmtpProtocol::AuthLoginStep1()
> {
>   char buffer[512];
>   nsresult rv;
>   PRInt32 status = 0;
>   nsXPIDLCString username;
>   char *base64Str = nsnull;
>-  nsXPIDLCString origPassword;
>+  nsCString origPassword;
>   nsCAutoString password;
>   nsCOMPtr<nsISmtpServer> smtpServer;
>   rv = m_runningURL->GetSmtpServer(getter_AddRefs(smtpServer));
>   if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
>   
>   rv = smtpServer->GetUsername(getter_Copies(username));
>   
>   if (username.IsEmpty()) {
>-    rv = GetUsernamePassword(getter_Copies(username), getter_Copies(origPassword));
>+    rv = GetUsernamePassword(getter_Copies(username), origPassword);
>     m_usernamePrompted = PR_TRUE;
>     password.Assign(origPassword);
>     if (username.IsEmpty() || password.IsEmpty())
>       return NS_ERROR_SMTP_PASSWORD_UNDEFINED;
>   }
>   else if (!TestFlag(SMTP_USE_LOGIN_REDIRECTION))
>   {
>-    rv = GetPassword(getter_Copies(origPassword));
>+    rv = GetPassword(origPassword);
>     password.Assign(origPassword);
>     if (password.IsEmpty())
>       return NS_ERROR_SMTP_PASSWORD_UNDEFINED;
>   }
>   else
>     password.Assign(mLogonCookie);
>   
>   if (TestFlag(SMTP_AUTH_CRAM_MD5_ENABLED))
>@@ -1147,26 +1147,25 @@ PRInt32 nsSmtpProtocol::AuthLoginStep2()
>   
>   /* use cached smtp password first
>   * if not then use cached pop password
>   * if pop password undefined 
>   * sync with smtp password
>   */
>   PRInt32 status = 0;
>   nsresult rv;
>-  nsXPIDLCString origPassword;
>+  nsCString origPassword;
>   nsCAutoString password;
>   
>   if (!TestFlag(SMTP_USE_LOGIN_REDIRECTION))
>   {
>-    rv = GetPassword(getter_Copies(origPassword));
>-    PRInt32 passwordLength = strlen((const char *) origPassword);
>-    if (!(const char*) origPassword || passwordLength == 0)
>+    rv = GetPassword(origPassword);
>+    if(origPassword.IsEmpty())
>       return NS_ERROR_SMTP_PASSWORD_UNDEFINED;
>-    password.Assign((const char*) origPassword);
>+    password.Assign(origPassword);
>   }
>   else
>     password.Assign(mLogonCookie);
>   
>   if (!password.IsEmpty()) 
>   {
>     char buffer[512];
>     if (TestFlag(SMTP_AUTH_CRAM_MD5_ENABLED))
>@@ -1743,37 +1742,33 @@ nsresult nsSmtpProtocol::LoadUrl(nsIURI 
>       ClearFlag(SMTP_PAUSE_FOR_READ);
>     }
>   } /* while(!SMTP_PAUSE_FOR_READ) */
> 
>   return NS_OK;
> }
> 
> nsresult
>-nsSmtpProtocol::GetPassword(char **aPassword)
>+nsSmtpProtocol::GetPassword(nsACString &aPassword)
> {
>     NS_ENSURE_ARG_POINTER(aPassword);
> 
>     nsresult rv;
>     nsCOMPtr<nsISmtpUrl> smtpUrl = do_QueryInterface(m_runningURL, &rv);
>     NS_ENSURE_SUCCESS(rv,rv); 
>    
>     nsCOMPtr<nsISmtpServer> smtpServer;
>     rv = smtpUrl->GetSmtpServer(getter_AddRefs(smtpServer));
>     NS_ENSURE_SUCCESS(rv,rv);
>     
>     rv = smtpServer->GetPassword(aPassword);
>     NS_ENSURE_SUCCESS(rv,rv); 
> 
>-    if (*aPassword && **aPassword)
>+    if (!aPassword.IsEmpty())
>         return rv;
>-    // empty password
>-
>-    nsCRT::free(*aPassword);
>-    *aPassword = 0;
> 
>     nsXPIDLCString redirectorType; 
>     rv = smtpServer->GetRedirectorType(getter_Copies(redirectorType));
>     NS_ENSURE_SUCCESS(rv,rv);
>       
>     nsCAutoString prefName("smtp.");
>     prefName.Append(redirectorType);
>     prefName.Append(".hide_hostname_for_password");
>@@ -1810,17 +1805,17 @@ nsSmtpProtocol::GetPassword(char **aPass
>       formatStrings[1] = hostnameUTF16.get();
>     }
>     rv = PromptForPassword(smtpServer, smtpUrl, formatStrings, aPassword);
>     NS_ENSURE_SUCCESS(rv,rv);
>     return rv;
> }
> 
> nsresult
>-nsSmtpProtocol::PromptForPassword(nsISmtpServer *aSmtpServer, nsISmtpUrl *aSmtpUrl, const PRUnichar **formatStrings, char **aPassword)
>+nsSmtpProtocol::PromptForPassword(nsISmtpServer *aSmtpServer, nsISmtpUrl *aSmtpUrl, const PRUnichar **formatStrings, nsACString &aPassword)
> {
>   nsresult rv;
>   nsCOMPtr<nsIStringBundleService> stringService = do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
>   NS_ENSURE_SUCCESS(rv,rv);
>   
>   nsCOMPtr<nsIStringBundle> composeStringBundle;
>   rv = stringService->CreateBundle("chrome://messenger/locale/messengercompose/composeMsgs.properties", getter_AddRefs(composeStringBundle));
>   NS_ENSURE_SUCCESS(rv,rv);
>@@ -1846,47 +1841,45 @@ nsSmtpProtocol::PromptForPassword(nsISmt
>   
>   rv = aSmtpServer->GetPasswordWithUI(passwordPromptString.get(), passwordTitle,
>     netPrompt, aPassword);
>   NS_ENSURE_SUCCESS(rv,rv);
>   return rv;
> }
> 
> nsresult
>-nsSmtpProtocol::GetUsernamePassword(char **aUsername, char **aPassword)
>+nsSmtpProtocol::GetUsernamePassword(char **aUsername, nsACString &aPassword)
> {
>     NS_ENSURE_ARG_POINTER(aUsername);
>     NS_ENSURE_ARG_POINTER(aPassword);
> 
>     nsresult rv;
>     nsCOMPtr<nsISmtpUrl> smtpUrl = do_QueryInterface(m_runningURL, &rv);
>     NS_ENSURE_SUCCESS(rv,rv);
>     
>     nsCOMPtr<nsISmtpServer> smtpServer;
>     rv = smtpUrl->GetSmtpServer(getter_AddRefs(smtpServer));
>     NS_ENSURE_SUCCESS(rv,rv);
>     
>     rv = smtpServer->GetPassword(aPassword);
>     NS_ENSURE_SUCCESS(rv,rv);
> 
>-    if (*aPassword && **aPassword) {
>+    if (!aPassword.IsEmpty()) {
>         rv = smtpServer->GetUsername(aUsername);
>         NS_ENSURE_SUCCESS(rv,rv);
> 
>         if (*aUsername && **aUsername)
>             return rv;
>         
>         // empty username
>         nsCRT::free(*aUsername);
>         *aUsername = 0;
>     }
>-    // empty password
> 
>-    nsCRT::free(*aPassword);
>-    *aPassword = 0;
>+    aPassword = NS_LITERAL_CSTRING("");
> 
>     nsXPIDLCString hostname;      
>     rv = smtpServer->GetHostname(getter_Copies(hostname));
>     NS_ENSURE_SUCCESS(rv, rv);
> 
>     const PRUnichar *formatStrings[] =
>     {
>       NS_ConvertASCIItoUTF16(hostname).get(),
>@@ -1916,28 +1909,28 @@ nsresult nsSmtpProtocol::RequestOverride
>     return NS_OK;
> 
> 	contractID.Append('/');
> 	contractID.Append(redirectionTypeStr);
> 
> 	m_logonRedirector = do_GetService(contractID.get(), &rv);
> 	if (m_logonRedirector && NS_SUCCEEDED(rv))
> 	{
>-		nsXPIDLCString password;
>+		nsCString password;
> 		nsXPIDLCString userName;
>     PRBool requiresPassword = PR_TRUE;
> 
> 		aSmtpServer->GetUsername(getter_Copies(userName));
>     m_logonRedirector->RequiresPassword(userName, redirectionTypeStr.get(), &requiresPassword);
>     if (requiresPassword)
>-		  GetPassword(getter_Copies(password));
>+		  GetPassword(password);
> 
>     nsCOMPtr<nsIPrompt> prompter;
>     m_runningURL->GetPrompt(getter_AddRefs(prompter));
>-		rv = m_logonRedirector->Logon(userName, password, redirectionType, prompter, NS_STATIC_CAST(nsIMsgLogonRedirectionRequester *, this), nsMsgLogonRedirectionServiceIDs::Smtp);
>+		rv = m_logonRedirector->Logon(userName, password.get(), redirectionType, prompter, NS_STATIC_CAST(nsIMsgLogonRedirectionRequester *, this), nsMsgLogonRedirectionServiceIDs::Smtp);
> 	}
> 
>   // this protocol instance now needs to wait until
>   // we receive the login redirection information so set the appropriate state
>   // flag
>   SetFlag(SMTP_WAIT_FOR_REDIRECTION);
>   SetFlag(SMTP_USE_LOGIN_REDIRECTION);
>   
>Index: compose/src/nsSmtpProtocol.h
>===================================================================
>RCS file: /cvsroot/mozilla/mailnews/compose/src/nsSmtpProtocol.h,v
>retrieving revision 1.56
>diff -u -8 -p -r1.56 nsSmtpProtocol.h
>--- compose/src/nsSmtpProtocol.h	19 Aug 2005 17:27:55 -0000	1.56
>+++ compose/src/nsSmtpProtocol.h	10 Aug 2006 15:33:21 -0000
>@@ -252,18 +252,18 @@ private:
> 
>     ////////////////////////////////////////////////////////////////////////////////////////
>     // End of Protocol Methods
>     ////////////////////////////////////////////////////////////////////////////////////////
> 
>     PRInt32 SendMessageInFile();
> 
>     void GetUserDomainName(nsACString& domainName);
>-    nsresult GetPassword(char **aPassword);
>-    nsresult GetUsernamePassword(char **aUsername, char **aPassword);
>-    nsresult PromptForPassword(nsISmtpServer *aSmtpServer, nsISmtpUrl *aSmtpUrl, const PRUnichar **formatStrings, char **aPassword);
>+    nsresult GetPassword(nsACString &aPassword);
>+    nsresult GetUsernamePassword(char **aUsername, nsACString &aPassword);
>+    nsresult PromptForPassword(nsISmtpServer *aSmtpServer, nsISmtpUrl *aSmtpUrl, const PRUnichar **formatStrings, nsACString &aPassword);
> 
>     void BackupAuthFlags();
>     void RestoreAuthFlags();
>     PRInt32 m_origAuthFlags;
> };
> 
> #endif  // nsSmtpProtocol_h___
>Index: compose/src/nsSmtpServer.cpp
>===================================================================
>RCS file: /cvsroot/mozilla/mailnews/compose/src/nsSmtpServer.cpp,v
>retrieving revision 1.52
>diff -u -8 -p -r1.52 nsSmtpServer.cpp
>--- compose/src/nsSmtpServer.cpp	3 Feb 2006 14:18:18 -0000	1.52
>+++ compose/src/nsSmtpServer.cpp	10 Aug 2006 15:38:20 -0000
>@@ -277,19 +277,18 @@ nsSmtpServer::SetUsername(const char * a
>     if (aUsername)
>         return mPrefBranch->SetCharPref("username", aUsername);
>     else
>         mPrefBranch->ClearUserPref("username");
>     return NS_OK;
> }
> 
> NS_IMETHODIMP
>-nsSmtpServer::GetPassword(char * *aPassword)
>+nsSmtpServer::GetPassword(nsACString &aPassword)
> {
>-    NS_ENSURE_ARG_POINTER(aPassword);
>     if (m_password.IsEmpty() && !m_logonFailed)
>     {
>       // try to avoid prompting the user for another password. If the user has set
>       // the appropriate pref, we'll use the password from an incoming server, if 
>       // the user has already logged onto that server.
> 
>       // if this is set, we'll only use this, and not the other prefs
>       // user_pref("mail.smtpserver.smtp1.incomingAccount", "server1");
>@@ -371,37 +370,35 @@ nsSmtpServer::GetPassword(char * *aPassw
>             }
>           }
>         }
>       }
>       if (incomingServerToUse)
>         return incomingServerToUse->GetPassword(aPassword);
> 
>     }
>-    *aPassword = ToNewCString(m_password);
>+    aPassword = m_password;
>     return NS_OK;
> }
> 
> NS_IMETHODIMP
>-nsSmtpServer::SetPassword(const char * aPassword)
>+nsSmtpServer::SetPassword(const nsACString &aPassword)
> {
>     m_password = aPassword;
>     return NS_OK;
> }
> 
> NS_IMETHODIMP
> nsSmtpServer::GetPasswordWithUI(const PRUnichar * aPromptMessage, const
>                                 PRUnichar *aPromptTitle, 
>                                 nsIAuthPrompt* aDialog,
>-                                char **aPassword) 
>+                                nsACString &aPassword) 
> {
>     nsresult rv = NS_OK;
> 
>-    NS_ENSURE_ARG_POINTER(aPassword);
>-
>     if (m_password.IsEmpty())
>     {
>         NS_ENSURE_ARG_POINTER(aDialog);
> 
>         // prompt the user for the password
>         if (NS_SUCCEEDED(rv))
>         {
>             nsXPIDLString uniPassword;
>@@ -419,44 +416,41 @@ nsSmtpServer::GetPasswordWithUI(const PR
>             rv = aDialog->PromptPassword(aPromptTitle, aPromptMessage, 
>                     NS_ConvertASCIItoUTF16(serverUri).get(), savePasswordType,
>                     getter_Copies(uniPassword), &okayValue);
>             if (NS_FAILED(rv))
>                 return rv;
> 
>             if (!okayValue) // if the user pressed cancel, just return NULL;
>             {
>-                *aPassword = nsnull;
>+                aPassword = NS_LITERAL_CSTRING("");
>                 return rv;
>             }
> 
>             // we got a password back...so remember it
>-            nsCString aCStr; aCStr.AssignWithConversion(uniPassword); 
>-
>-            rv = SetPassword(aCStr.get());
>+            rv = SetPassword(NS_ConvertUTF16toUTF8(uniPassword));
>             if (NS_FAILED(rv))
>                 return rv;
>         } // if we got a prompt dialog
>     } // if the password is empty
> 
>     rv = GetPassword(aPassword);
>     return rv;
> }
> 
> NS_IMETHODIMP
> nsSmtpServer::GetUsernamePasswordWithUI(const PRUnichar * aPromptMessage, const
>                                 PRUnichar *aPromptTitle, 
>                                 nsIAuthPrompt* aDialog,
>                                 char **aUsername,
>-                                char **aPassword) 
>+                                nsACString &aPassword) 
> {
>     nsresult rv = NS_OK;
> 
>     NS_ENSURE_ARG_POINTER(aUsername);
>-    NS_ENSURE_ARG_POINTER(aPassword);
> 
>     if (m_password.IsEmpty()) {
>         NS_ENSURE_ARG_POINTER(aDialog);
>         // prompt the user for the password
>         if (NS_SUCCEEDED(rv))
>         {
>             nsXPIDLString uniUsername;
>             nsXPIDLString uniPassword;
>@@ -469,30 +463,29 @@ nsSmtpServer::GetUsernamePasswordWithUI(
>                                          NS_ConvertASCIItoUTF16(serverUri).get(), nsIAuthPrompt::SAVE_PASSWORD_PERMANENTLY,
>                                          getter_Copies(uniUsername), getter_Copies(uniPassword), &okayValue);
>             if (NS_FAILED(rv))
>                 return rv;
> 				
>             if (!okayValue) // if the user pressed cancel, just return NULL;
>             {
>                 *aUsername = nsnull;
>-                *aPassword = nsnull;
>+                aPassword = NS_LITERAL_CSTRING("");
>                 return rv;
>             }
> 
>             // we got a userid and password back...so remember it
>             nsCString aCStr; 
> 
>             aCStr.AssignWithConversion(uniUsername); 
>             rv = SetUsername(aCStr.get());
>             if (NS_FAILED(rv))
>                 return rv;
> 
>-            aCStr.AssignWithConversion(uniPassword); 
>-            rv = SetPassword(aCStr.get());
>+            rv = SetPassword(NS_ConvertUTF16toUTF8(uniPassword));
>             if (NS_FAILED(rv))
>                 return rv;
>         } // if we got a prompt dialog
>     } // if the password is empty
> 
>     rv = GetUsername(aUsername);
>     if (NS_FAILED(rv))
>         return rv;
>@@ -517,17 +510,17 @@ nsSmtpServer::ForgetPassword()
> 
>     //this is need to make sure wallet service has been created
>     rv = CreateServicesForPasswordManager();
>     NS_ENSURE_SUCCESS(rv, rv);
> 
>     rv = observerService->NotifyObservers(uri, "login-failed", nsnull);
>     NS_ENSURE_SUCCESS(rv,rv);
> 
>-    rv = SetPassword("");
>+    rv = SetPassword(NS_LITERAL_CSTRING(""));
>     m_logonFailed = PR_TRUE;
>     return rv;
> }
> 
> NS_IMETHODIMP
> nsSmtpServer::GetServerURI(char **aResult)
> {
>     NS_ENSURE_ARG_POINTER(aResult);
>Index: compose/src/nsSmtpService.cpp
>===================================================================
>RCS file: /cvsroot/mozilla/mailnews/compose/src/nsSmtpService.cpp,v
>retrieving revision 1.137
>diff -u -8 -p -r1.137 nsSmtpService.cpp
>--- compose/src/nsSmtpService.cpp	18 Dec 2005 01:50:39 -0000	1.137
>+++ compose/src/nsSmtpService.cpp	10 Aug 2006 15:39:18 -0000
>@@ -113,32 +113,32 @@ nsSmtpService::~nsSmtpService()
> }
> 
> NS_IMPL_ISUPPORTS2(nsSmtpService, nsISmtpService, nsIProtocolHandler)
> 
> 
> nsresult nsSmtpService::SendMailMessage(nsIFileSpec * aFilePath,
>                                         const char * aRecipients, 
>                                         nsIMsgIdentity * aSenderIdentity,
>-                                        const char * aPassword,
>+                                        const nsACString &aPassword,
>                                         nsIUrlListener * aUrlListener, 
>                                         nsIMsgStatusFeedback *aStatusFeedback,
>                                         nsIInterfaceRequestor* aNotificationCallbacks,
>                                         nsIURI ** aURL,
>                                         nsIRequest ** aRequest)
> {
>   nsIURI * urlToRun = nsnull;
>   nsresult rv = NS_OK;
> 
>   nsCOMPtr<nsISmtpServer> smtpServer;
>   rv = GetSmtpServerByIdentity(aSenderIdentity, getter_AddRefs(smtpServer));
> 
>   if (NS_SUCCEEDED(rv) && smtpServer)
>   {
>-    if (aPassword && *aPassword)
>+    if (!aPassword.IsEmpty())
>       smtpServer->SetPassword(aPassword);
> 
>     nsXPIDLCString smtpHostName;
>     nsXPIDLCString smtpUserName;
>     PRInt32 smtpPort;
>     PRInt32 trySSL;
> 
>     smtpServer->GetHostname(getter_Copies(smtpHostName));
>Index: extensions/mdn/src/nsMsgMdnGenerator.cpp
>===================================================================
>RCS file: /cvsroot/mozilla/mailnews/extensions/mdn/src/nsMsgMdnGenerator.cpp,v
>retrieving revision 1.17
>diff -u -8 -p -r1.17 nsMsgMdnGenerator.cpp
>--- extensions/mdn/src/nsMsgMdnGenerator.cpp	3 Feb 2006 14:18:19 -0000	1.17
>+++ extensions/mdn/src/nsMsgMdnGenerator.cpp	10 Aug 2006 15:59:44 -0000
>@@ -879,17 +879,17 @@ nsresult nsMsgMdnGenerator::SendMdnMsg()
> {
>     DEBUG_MDN("nsMsgMdnGenerator::SendMdnMsg");
>     nsresult rv;
>     nsCOMPtr<nsISmtpService> smtpService = do_GetService(NS_SMTPSERVICE_CONTRACTID, &rv);
>     NS_ENSURE_SUCCESS(rv,rv);
> 
>     nsCOMPtr<nsIRequest> aRequest;
>     smtpService->SendMailMessage(m_fileSpec, m_dntRrt, m_identity,
>-                                     nsnull, this, nsnull, nsnull, nsnull,
>+                                     NS_LITERAL_CSTRING(""), this, nsnull, nsnull, nsnull,
>                                      getter_AddRefs(aRequest));
>     
>     return NS_OK;
> }
> 
> nsresult nsMsgMdnGenerator::WriteString( const char *str )
> {
>   NS_ENSURE_ARG (str);
>Index: imap/public/nsIImapServerSink.idl
>===================================================================
>RCS file: /cvsroot/mozilla/mailnews/imap/public/nsIImapServerSink.idl,v
>retrieving revision 1.35
>diff -u -8 -p -r1.35 nsIImapServerSink.idl
>--- imap/public/nsIImapServerSink.idl	12 Sep 2004 21:29:24 -0000	1.35
>+++ imap/public/nsIImapServerSink.idl	10 Aug 2006 15:40:11 -0000
>@@ -63,17 +63,17 @@ interface nsIImapServerSink : nsISupport
>   void retryUrl(in nsIImapUrl aImapUrl);
>   // if previous url failed, this gives server chance to abort urls with same mock channel
>   void abortQueuedUrls(); 
>   void getImapStringByID(in long aMsgId, out wstring aString);
>   void formatStringWithHostNameByID(in long aMsgId, out wstring aString);
>   void fEAlert(in wstring aString, in nsIMsgWindow aMsgWindow);
>   void fEAlertFromServer(in string aString, in nsIMsgWindow aMsgWindow);
>   void commitNamespaces();
>-  void promptForPassword(out string aString, in nsIMsgWindow aMsgWindow);
>+  void promptForPassword(out AUTF8String aString, in nsIMsgWindow aMsgWindow);
>   attribute boolean userAuthenticated;
>   void setMailServerUrls(in string manageMailAccount, in string manageLists, in string manageFilters);
>   
>   /* this is a bogus method on this interface but i need it until misc. sink is scriptable.. */
>   void RemoveChannelFromUrl(in nsIMsgMailNewsUrl aUrl, in unsigned long statusCode);
>   readonly attribute string arbitraryHeaders;
>   void forgetPassword();
> 
>Index: imap/src/nsImapIncomingServer.cpp
>===================================================================
>RCS file: /cvsroot/mozilla/mailnews/imap/src/nsImapIncomingServer.cpp,v
>retrieving revision 1.357
>diff -u -8 -p -r1.357 nsImapIncomingServer.cpp
>--- imap/src/nsImapIncomingServer.cpp	18 Jul 2006 02:42:07 -0000	1.357
>+++ imap/src/nsImapIncomingServer.cpp	10 Aug 2006 15:43:25 -0000
>@@ -979,21 +979,21 @@ NS_IMETHODIMP nsImapIncomingServer::Rese
> 
>     PR_CExitMonitor(this);
>     return rv;
> }
> 
> NS_IMETHODIMP 
> nsImapIncomingServer::PerformExpand(nsIMsgWindow *aMsgWindow)
> {
>-    nsXPIDLCString password;
>+    nsCString password;
>     nsresult rv;
> 
>     
>-    rv = GetPassword(getter_Copies(password));
>+    rv = GetPassword(password);
>     if (NS_FAILED(rv)) return rv;
>     if (password.IsEmpty())
>         return NS_OK;
> 
>     rv = ResetFoldersToUnverified(nsnull);
>     
>     nsCOMPtr<nsIMsgFolder> rootMsgFolder;
>     rv = GetRootFolder(getter_AddRefs(rootMsgFolder));
>@@ -2306,17 +2306,17 @@ NS_IMETHODIMP nsImapIncomingServer::GetS
> }
> 
> NS_IMETHODIMP nsImapIncomingServer::ForgetPassword()
> {
>   return nsMsgIncomingServer::ForgetPassword();
> }
> 
> 
>-NS_IMETHODIMP nsImapIncomingServer::PromptForPassword(char ** aPassword,
>+NS_IMETHODIMP nsImapIncomingServer::PromptForPassword(nsACString &aPassword,
>                                                       nsIMsgWindow * aMsgWindow)
> {
>     nsXPIDLString passwordTitle; 
>     IMAPGetStringByID(IMAP_ENTER_PASSWORD_PROMPT_TITLE, getter_Copies(passwordTitle));
>     nsXPIDLCString userName;
>     PRBool okayValue;
>     GetRealUsername(getter_Copies(userName));
> 
>@@ -2474,29 +2474,29 @@ nsresult nsImapIncomingServer::RequestOv
>   
>   m_logonRedirector = do_GetService(contractID.get(), &rv);
>   if (m_logonRedirector && NS_SUCCEEDED(rv))
>   {
>     nsCOMPtr <nsIMsgLogonRedirectionRequester> logonRedirectorRequester;
>     rv = QueryInterface(NS_GET_IID(nsIMsgLogonRedirectionRequester), getter_AddRefs(logonRedirectorRequester));
>     if (NS_SUCCEEDED(rv))
>     {
>-      nsXPIDLCString password;
>+      nsCString password;
>       nsXPIDLCString userName;
>       PRBool requiresPassword = PR_TRUE;
>       
>       GetRealUsername(getter_Copies(userName));
>       m_logonRedirector->RequiresPassword(userName, redirectorType.get(), &requiresPassword);
>       
>       if (requiresPassword)
>       {
>-        GetPassword(getter_Copies(password));
>+        GetPassword(password);
>         
>         if (password.IsEmpty())
>-          PromptForPassword(getter_Copies(password), aMsgWindow);
>+          PromptForPassword(password, aMsgWindow);
>         
>         if (password.IsEmpty())  // if still empty then the user canceld out of the password dialog
>         {
>           // be sure to clear the waiting for connection info flag because we aren't waiting
>           // anymore for a connection...
>           m_waitingForConnectionInfo = PR_FALSE;
>           return NS_OK;
>         }
>@@ -2504,17 +2504,17 @@ nsresult nsImapIncomingServer::RequestOv
>       else
>       {
>         SetUserAuthenticated(PR_TRUE);  // we are already authenicated
>       }
>       
>       nsCOMPtr<nsIPrompt> dialogPrompter;
>       if (aMsgWindow)
>         aMsgWindow->GetPromptDialog(getter_AddRefs(dialogPrompter));
>-      rv = m_logonRedirector->Logon(userName, password, redirectorType, dialogPrompter, logonRedirectorRequester, nsMsgLogonRedirectionServiceIDs::Imap);
>+      rv = m_logonRedirector->Logon(userName, password.get(), redirectorType, dialogPrompter, logonRedirectorRequester, nsMsgLogonRedirectionServiceIDs::Imap);
>       if (NS_FAILED(rv)) 
>         return OnLogonRedirectionError(nsnull, PR_TRUE);
>     }
>   }
>   
>   return rv;
> }
> 
>Index: imap/src/nsImapProtocol.cpp
>===================================================================
>RCS file: /cvsroot/mozilla/mailnews/imap/src/nsImapProtocol.cpp,v
>retrieving revision 1.631
>diff -u -8 -p -r1.631 nsImapProtocol.cpp
>--- imap/src/nsImapProtocol.cpp	18 Jul 2006 02:42:07 -0000	1.631
>+++ imap/src/nsImapProtocol.cpp	10 Aug 2006 15:49:53 -0000
>@@ -7575,30 +7575,30 @@ nsresult nsImapProtocol::GetMsgWindow(ns
>     return rv;
> }
> 
> PRBool nsImapProtocol::TryToLogon()
> {
>   PRInt32 logonTries = 0;
>   PRBool loginSucceeded = PR_FALSE;
>   PRBool clientSucceeded = PR_TRUE;
>-  nsXPIDLCString password;
>+  nsCString password;
>   char * userName = nsnull;
>   nsresult rv = NS_OK;
> 
>   // get the password and user name for the current incoming server...
>   nsCOMPtr<nsIMsgIncomingServer> server = do_QueryReferent(m_server);
>   if (server)
>   {
>     // we are in the imap thread so *NEVER* try to extract the password with UI
>     // if logon redirection has changed the password, use the cookie as the password
>     if (m_overRideUrlConnectionInfo)
>       password.Assign(m_logonCookie);
>     else
>-      rv = server->GetPassword(getter_Copies(password));
>+      rv = server->GetPassword(password);
>     rv = server->GetRealUsername(&userName);
>     
>   }
>       
>   nsCOMPtr<nsIMsgWindow> aMsgWindow;
> 
>   do
>   {
>@@ -7643,64 +7643,63 @@ PRBool nsImapProtocol::TryToLogon()
>         if (password.IsEmpty() && m_imapServerSink &&
>             !(m_useSecAuth && GetServerStateParser().GetCapabilityFlag() & kHasAuthGssApiCapability))
>         {
>           if (!aMsgWindow)
>           {
>               rv = GetMsgWindow(getter_AddRefs(aMsgWindow));
>               if (NS_FAILED(rv)) return rv;
>           }
>-          char *pPassword = ToNewCString(m_lastPasswordSent);
>-          char *savePassword = pPassword;
>-          rv = m_imapServerSink->PromptForPassword(&pPassword, aMsgWindow);
>-          PR_Free(savePassword);
>+          nsCString pPassword = m_lastPasswordSent;
>+          nsCString savePassword = pPassword;
>+          rv = m_imapServerSink->PromptForPassword(pPassword, aMsgWindow);
>           if (rv == NS_MSG_PASSWORD_PROMPT_CANCELLED)
>             break;
>           password.Adopt(pPassword);
>          }
> 
>         clientSucceeded = PR_TRUE;
>         m_lastPasswordSent = password;
>         // Use CRAM/NTLM/MSN only if secure auth is enabled. This is for servers that
>         // say they support CRAM but are so badly broken that trying it causes
>         // all subsequent login attempts to fail (bug 231303, bug 227560)
>         if (m_useSecAuth && GetServerStateParser().GetCapabilityFlag() & kHasAuthGssApiCapability)
>         {
>           clientSucceeded = NS_SUCCEEDED(AuthLogin(userName, password, kHasAuthGssApiCapability));
>         }
>         else if (m_useSecAuth && GetServerStateParser().GetCapabilityFlag() & kHasCRAMCapability)
>         {
>-          AuthLogin (userName, password, kHasCRAMCapability);
>+          AuthLogin (userName, password.get(), kHasCRAMCapability);
>           logonTries++;
>         }
>         else if (m_useSecAuth && GetServerStateParser().GetCapabilityFlag() & kHasAuthNTLMCapability)
>         {
>-          AuthLogin (userName, password, kHasAuthNTLMCapability);
>+          AuthLogin (userName, password.get(), kHasAuthNTLMCapability);
>           logonTries++;
>         }
>         else if (m_useSecAuth && GetServerStateParser().GetCapabilityFlag() & kHasAuthMSNCapability)
>         {
>-          AuthLogin (userName, password, kHasAuthMSNCapability);
>+          AuthLogin (userName, password.get(), kHasAuthMSNCapability);
>           logonTries++;
>         }
>         else if (GetServerStateParser().GetCapabilityFlag() & kHasAuthPlainCapability)
>         {
>-          AuthLogin (userName, password, kHasAuthPlainCapability);
>+          AuthLogin (userName, password.get(), kHasAuthPlainCapability);
>           logonTries++;
>         }
>         else if (GetServerStateParser().GetCapabilityFlag() & kHasAuthLoginCapability)
>         {
>-          AuthLogin (userName, password,  kHasAuthLoginCapability); 
>+          AuthLogin (userName, password.get(),  kHasAuthLoginCapability); 
>           logonTries++; // This counts as a logon try for most servers
>         }
>         else if (! (GetServerStateParser().GetCapabilityFlag() & kLoginDisabled))
>-          InsecureLogin(userName, password);
>+          InsecureLogin(userName, password.get());
>       }
>       else if (! (GetServerStateParser().GetCapabilityFlag() & kLoginDisabled))
>-        InsecureLogin(userName, password);
>+        InsecureLogin(userName, password.get());
> 
>       if (!clientSucceeded || !GetServerStateParser().LastCommandSuccessful())
>       {
>           // login failed!
>           // if we failed because of an interrupt, then do not bother the user
>           // similarly - if we failed due to a local error, don't bug them
>           if (m_imapServerSink && !DeathSignalReceived() && clientSucceeded)
>             rv = m_imapServerSink->ForgetPassword();
>@@ -7712,17 +7711,17 @@ PRBool nsImapProtocol::TryToLogon()
>             m_currentBiffState = nsIMsgFolder::nsMsgBiffState_Unknown;
>             SendSetBiffIndicatorEvent(m_currentBiffState);
>             password.Truncate();
>         } // if we didn't receive the death signal...
>       } // if login failed
>       else  // login succeeded
>       {
>         PRBool passwordAlreadyVerified;
>-        rv = m_hostSessionList->SetPasswordForHost(GetImapServerKey(), password);
>+        rv = m_hostSessionList->SetPasswordForHost(GetImapServerKey(), password.get());
>         rv = m_hostSessionList->GetPasswordVerifiedOnline(GetImapServerKey(), passwordAlreadyVerified);
>         if (NS_SUCCEEDED(rv) && !passwordAlreadyVerified)
>           m_hostSessionList->SetPasswordVerifiedOnline(GetImapServerKey());
>         imapPasswordIsNew = !passwordAlreadyVerified;
>         if (imapPasswordIsNew) 
>         {
>           if (m_currentBiffState == nsIMsgFolder::nsMsgBiffState_Unknown)
>           {
>Index: local/src/nsPop3Protocol.cpp
>===================================================================
>RCS file: /cvsroot/mozilla/mailnews/local/src/nsPop3Protocol.cpp,v
>retrieving revision 1.252
>diff -u -8 -p -r1.252 nsPop3Protocol.cpp
>--- local/src/nsPop3Protocol.cpp	23 May 2006 17:16:15 -0000	1.252
>+++ local/src/nsPop3Protocol.cpp	10 Aug 2006 15:56:30 -0000
>@@ -677,38 +677,38 @@ void nsPop3Protocol::UpdateProgressPerce
> // do not pass in an escaped string
> void nsPop3Protocol::SetUsername(const char* name)
> {
>   NS_ASSERTION(name, "no name specified!");
>     if (name) 
>       m_username = name;
> }
> 
>-nsresult nsPop3Protocol::GetPassword(char ** aPassword, PRBool *okayValue)
>+nsresult nsPop3Protocol::GetPassword(nsACString &aPassword, PRBool *okayValue)
> {
>   nsresult rv = NS_OK;
>   nsCOMPtr<nsIMsgIncomingServer> server = do_QueryInterface(m_pop3Server);
>   
>   if (server)
>   {
>     PRBool isAuthenticated;
>     m_nsIPop3Sink->GetUserAuthenticated(&isAuthenticated);
> 
>     // pass the failed password into the password prompt so that
>     // it will be pre-filled, in case it failed because of a
>     // server problem and not because it was wrong.
>     if (!m_lastPasswordSent.IsEmpty())
>-      *aPassword = ToNewCString(m_lastPasswordSent);
>+      aPassword = m_lastPasswordSent;
> 
>     // clear the password if the last one failed
>     if (TestFlag(POP3_PASSWORD_FAILED))
>     {
>       // if we've already gotten a password and it wasn't correct..clear
>       // out the password and try again.
>-      rv = server->SetPassword("");
>+      rv = server->SetPassword(NS_LITERAL_CSTRING(""));
>     }
>     
>     // first, figure out the correct prompt text to use...
>     nsXPIDLCString hostName;
>     nsXPIDLCString userName;
>     PRUnichar *passwordPromptString =nsnull;
>     
>     server->GetRealHostName(getter_Copies(hostName));
>@@ -1717,26 +1717,26 @@ PRInt32 nsPop3Protocol::AuthGSSAPIRespon
>     return rv;
> }
> 
> PRInt32 nsPop3Protocol::SendUsername()
> {
>     if(m_username.IsEmpty())
>         return(Error(POP3_USERNAME_UNDEFINED));
> 
>-    nsXPIDLCString password;
>+    nsCString password;
>     PRBool okayValue = PR_TRUE;
>-    nsresult rv = GetPassword(getter_Copies(password), &okayValue);
>+    nsresult rv = GetPassword(password, &okayValue);
>     if (NS_SUCCEEDED(rv) && !okayValue)
>     {
>         // user has canceled the password prompt
>         m_pop3ConData->next_state = POP3_ERROR_DONE;
>         return NS_ERROR_ABORT;
>     }
>-    else if (NS_FAILED(rv) || !password)
>+    else if (NS_FAILED(rv) || password.IsEmpty())
>     {
>       return Error(POP3_PASSWORD_UNDEFINED);
>     }
> 
>     nsCAutoString cmd;
> 
>     if (m_useSecAuth)
>     {
>@@ -1770,26 +1770,26 @@ PRInt32 nsPop3Protocol::SendUsername()
>     return SendData(m_url, cmd.get());
> }
> 
> PRInt32 nsPop3Protocol::SendPassword()
> {
>     if (m_username.IsEmpty())
>         return(Error(POP3_USERNAME_UNDEFINED));
> 
>-    nsXPIDLCString password;
>+    nsCString password;
>     PRBool okayValue = PR_TRUE;
>-    nsresult rv = GetPassword(getter_Copies(password), &okayValue);
>+    nsresult rv = GetPassword(password, &okayValue);
>     if (NS_SUCCEEDED(rv) && !okayValue)
>     {
>         // user has canceled the password prompt
>         m_pop3ConData->next_state = POP3_ERROR_DONE;
>         return NS_ERROR_ABORT;
>     }
>-    else if (NS_FAILED(rv) || !password)
>+    else if (NS_FAILED(rv) || password.IsEmpty())
>     {
>       return Error(POP3_PASSWORD_UNDEFINED);
>     }
> 
>     nsCAutoString cmd;
>     if (m_useSecAuth)
>     {
>         if (TestCapFlag(POP3_HAS_AUTH_CRAM_MD5))
>@@ -1885,17 +1885,17 @@ PRInt32 nsPop3Protocol::SendPassword()
> 
>             char *base64Str = PL_Base64Encode(plain_string, len, nsnull);
>             cmd = base64Str;
>             PR_Free(base64Str);
>         }
>         else if (TestCapFlag(POP3_HAS_AUTH_LOGIN)) 
>         {
>             char * base64Str = 
>-                PL_Base64Encode(password, PL_strlen(password), nsnull);
>+                PL_Base64Encode(password.get(), password.Length(), nsnull);
>             cmd = base64Str;
>             PR_Free(base64Str);
>         }
>         else
>         {
>             cmd = "PASS ";
>             cmd += password;    
>         }
>@@ -3569,33 +3569,32 @@ nsresult nsPop3Protocol::ProcessProtocol
>     user to type in a password while we don't actually have
>     a connection to the pop server open; this saves us from
>     having to worry about the server timing out on us while
>       we wait for user input. */
>       {
>       /* If we're just checking for new mail (biff) then don't
>       prompt the user for a password; just tell him we don't
>         know whether he has new mail. */
>-        nsXPIDLCString password;
>+        nsCString password;
>         PRBool okayValue;
>-        GetPassword(getter_Copies(password), &okayValue);
>-        const char * pwd = (const char *) password;
>-        if (!password || m_username.IsEmpty())
>+        GetPassword(password, &okayValue);
>+        if (password.IsEmpty() || m_username.IsEmpty())
>         {
>           status = MK_POP3_PASSWORD_UNDEFINED;
>           m_pop3ConData->biffstate = nsIMsgFolder::nsMsgBiffState_Unknown;
>           m_nsIPop3Sink->SetBiffStateAndUpdateFE(m_pop3ConData->biffstate, 0, PR_FALSE);	
>           
>           /* update old style biff */
>           m_pop3ConData->next_state = POP3_FREE;
>           m_pop3ConData->pause_for_read = PR_FALSE;
>           break;
>         }
>         
>-        if (m_username.IsEmpty() || !pwd)
>+        if (m_username.IsEmpty() || password.IsEmpty())
>         {
>           m_pop3ConData->next_state = POP3_ERROR_DONE;
>           m_pop3ConData->pause_for_read = PR_FALSE;
>         }
>         else
>         {
>           // we are already connected so just go on and send the username
>           PRBool prefBool = PR_FALSE; 
>Index: local/src/nsPop3Protocol.h
>===================================================================
>RCS file: /cvsroot/mozilla/mailnews/local/src/nsPop3Protocol.h,v
>retrieving revision 1.73
>diff -u -8 -p -r1.73 nsPop3Protocol.h
>--- local/src/nsPop3Protocol.h	19 Aug 2005 17:29:13 -0000	1.73
>+++ local/src/nsPop3Protocol.h	10 Aug 2006 15:57:45 -0000
>@@ -299,17 +299,17 @@ public:
>   NS_DECL_NSIPOP3PROTOCOL
> 
>   nsresult Initialize(nsIURI * aURL);
>   virtual nsresult LoadUrl(nsIURI *aURL, nsISupports * aConsumer = nsnull);
> 
>   const char* GetUsername() { return m_username.get(); };
>   void SetUsername(const char* name);
> 
>-  nsresult GetPassword(char ** aPassword, PRBool *okayValue);
>+  nsresult GetPassword(nsACString &aPassword, PRBool *okayValue);
> 
>   NS_IMETHOD OnTransportStatus(nsITransport *transport, nsresult status, PRUint32 progress, PRUint32 progressMax);
>   NS_IMETHOD OnStopRequest(nsIRequest *request, nsISupports * aContext, nsresult aStatus);
>   NS_IMETHOD Cancel(nsresult status);
> 
>   static void MarkMsgInHashTable(PLHashTable *hashTable, const Pop3UidlEntry *uidl, 
>                                   PRBool *changed);
>
(In reply to comment #7)
> Created an attachment (id=233086) [edit]
> This patch uses pure utf8 for all password handling

this would be a nice security improvement.
Michael, you need to request review - see http://www.mozilla.org/hacking/life-cycle.html
Dan, thoughts? (I think the patch might have bit-rotted)
Comment on attachment 233086 [details] [diff] [review]
This patch uses pure utf8 for all password handling

We should definitely try and update / land this.  Gary, what makes you say this may have bit-rotted?
Attachment #233086 - Flags: superreview?(dmose)
Attachment #233086 - Flags: review?(mscott)
Attachment #233086 - Flags: review?(bugzilla)
Well, the patch was for a cvs checkout in Aug 2006, the file nsMessengerMigrator.cpp (from the patch) doesn't exist anymore in the trunk, amidst a host of other small changes, the patch doesn't apply cleanly to my current trunk checkout either.
Mike: if you could generate an up-to-date patch, I'll figure out how we can get it reviewed and landed sooner rather than later.  Is something you'd have bandwidth for?
Attachment #233086 - Flags: superreview?(dmose)
Attachment #233086 - Flags: review?(bugzilla)
(In reply to comment #13)
> Mike: if you could generate an up-to-date patch, I'll figure out how we can get
> it reviewed and landed sooner rather than later.  Is something you'd have
> bandwidth for?
> 

No response, so I'm putting on this on the radar and taking. This would be a good patch to do post (or possibly pre) password manager switch.
Assignee: mscott → bugzilla
Depends on: 239131
Flags: blocking-thunderbird3?
Flags: blocking-thunderbird3? → blocking-thunderbird3+
(In reply to comment #5)
> I have to check whether SMTP auth and POP3 support non-ASCII password and how
> if
> they do. 

POP claims it's an ASCII protocol; the SASL docs say it's Unicode with mechanisms specifying format (noting that the ones it uses are UTF-8 encoded). I just found a draft RFC updating POP (dates in 2008, so it's recent) which affirms that it's strictly ASCII, although a command is presented that upgrades it to UTF-8. See 
http://www.ietf.org/internet-drafts/draft-ietf-eai-pop-03.txt. What this amounts to in practice, I don't know.

I don't know about IMAP or SMTP, but I suspect similar things (officially ASCII, probably UTF-8 in practice). I do know, however, that NNTP is UTF-8.
Priority: -- → P3
Target Milestone: --- → Thunderbird 3.0b3
Status: NEW → ASSIGNED
Whiteboard: [need protocol investigations (can they support it?)]
Whiteboard: [need protocol investigations (can they support it?)] → [need protocol investigations (can they support it?)][m4]
We'd very much like for this to be in Thunderbird 3, however we've decided it won't actually block the release as it is not something that is a really major issue. Updated patches are very much welcome though.
Assignee: bugzilla → nobody
Flags: wanted-thunderbird3+
Flags: blocking-thunderbird3-
Flags: blocking-thunderbird3+
Keywords: helpwanted
Whiteboard: [need protocol investigations (can they support it?)][m4]
Status: ASSIGNED → NEW
OS: Windows XP → All
Hardware: x86 → All
Whiteboard: [patchlove]
Component: General → Security
QA Contact: general → thunderbird
Whiteboard: [patchlove] → [patchlove][needs owner]
Whiteboard: [patchlove][needs owner] → [patchlove]
Comment on attachment 233086 [details] [diff] [review]
This patch uses pure utf8 for all password handling

Patch has unfortunately bitrotted:

$ patch -p1 --dry-run < ~/Desktop/utf8passwordPatch.diff 
(Stripping trailing CRs from patch.)
patching file public/nsIMsgIncomingServer.idl
Hunk #1 FAILED at 116.
1 out of 1 hunk FAILED -- saving rejects to file public/nsIMsgIncomingServer.idl.rej
(Stripping trailing CRs from patch.)
can't find file to patch at input line 40
Perhaps you used the wrong -p or --strip option?
The text leading up to this was:
--------------------------
|Index: base/src/nsMessengerMigrator.cpp
|===================================================================
|RCS file: /cvsroot/mozilla/mailnews/base/src/nsMessengerMigrator.cpp,v
|retrieving revision 1.118
|diff -u -8 -p -r1.118 nsMessengerMigrator.cpp
|--- base/src/nsMessengerMigrator.cpp   8 Nov 2005 09:20:11 -0000       1.118
|+++ base/src/nsMessengerMigrator.cpp   10 Aug 2006 15:07:33 -0000
--------------------------
File to patch:
Attachment #233086 - Attachment is obsolete: true
Michael, any chance of an updated patch?
(In reply to comment #15)
> I don't know about IMAP or SMTP, but I suspect similar things (officially
> ASCII, probably UTF-8 in practice). I do know, however, that NNTP is UTF-8.

With some new-found wisdom over the past year, I should say correctly that official specifications and practical results can often differ, especially in the realm of charsets. Usenet servers and IMAP particularly have a problem in this regard.

I'm not sure defaulting to UTF-8 would be that safe--there should be some preference somewhere to choose the charset to use. I know that NNTP already has such a preference, but I don't know about IMAP, NNTP, or SMTP.
I tried to install my account on Ubuntu 10.04 LTS (TB 3.0.7). No matter what I did TB always complained that my password is incorrect.

I tried changing my password and that solved it. 

Conclusion: TB does not allow letter å (Swedish a with circle on top). Changing the password to contain a instead of å solved it.

I'm using the finnish locale with utf-8. My password with å works on all other clients (Evolution, Horde) so this is not a server issue.
One way to allow non-ASCII passwords that will interoperate is to look for the SASL PLAIN mechanism. If SASL PLAIN is present, then there's a standards requirement (dating back to 1999) that the underlying character set for usernames and passwords in SASL PLAIN is UTF-8.

So if a username/password contains non-7-bit-ASCII, then use of SASL PLAIN (instead of POP3 user/pass or IMAP login) with UTF-8 will interoperate with all standards-compliant servers.

Both POP3 user/pass (RFC 1939) and IMAP LOGIN (RFC 3501) are 7-bit protocols. If a client sends anything with the 8th bit set, the GIGO principle applies and there is no guarantee of interoperability. The server is free to always fail the authentication or to require UTF-8 or to do whatever else it wants. If a client sends non-7-bit and non-UTF-8 to these commands (as I gather Thunderbird does), the client is badly broken not only because it won't interoperate, but also because it may result in a dead-end deployment where password hashes are based on a non-interoperable charset and can't support the interoperable standard for non-ASCII passwords that's been around since 1999 (RFC 2595).
Chris, thanks for the comments.  Does your thinking in comment 22 account for the thoughts in comment 20?

possible dupes per Chris: Bug 382905, Bug 123880
Keywords: helpwantedintl
Priority: P3 → --
Whiteboard: [patchlove] → [patchlove][has draft patch]
Target Milestone: Thunderbird 3.0b3 → ---
Yes, but it depends on implementation details and the will of the Thunderbird community.

I suggest there are 5 goals here:
1. Make it possible for correct clients and servers to always interoperate on non-ASCII usernames/passwords without requiring coordinated manual configuration on both the server and client.
2. Make Thunderbird blameless for interoperability problems.
3. Do not break standards-compliant server deployments.
4. Break as few deployments where the servers are not standards-compliant as possible.
5. Make sure server admins with exceptionally non-compliant servers have a way to muddle through.

My proposal:
If the server advertises AUTH=PLAIN and the username/password contains non-ASCII characters, then preferentially use the AUTHENTICATE PLAIN command instead of the LOGIN command. This immediately achieves goals 1-3. It does this because the IMAP standard (RFC 3501) requires implementation of AUTH=PLAIN.

When AUTH=PLAIN is not advertised by the server, then retain the present Thunderbird behavior. This achieves goal 4.

Goal 5 applies in the case where an exceptionally broken server advertises AUTH=PLAIN, allowed non-ASCII username/password to be provisioned, but does not accept UTF-8 in AUTH=PLAIN and convert it to the correct charset for the back-end authentication database it uses (e.g., LDAP requires UTF-8 per RFC 4511). Such a server has been in violation of the SASL PLAIN standard since 1999. However, we still want to allow admins operating such servers to upgrade Thunderbird. The first workaround such admins have with this approach is to disable AUTH=PLAIN on the server (this can even be done with an IMAP proxy) to revert Thunderbird to legacy behavior. But if Thunderbird wants to help admins with a server so broken that it advertises AUTH=PLAIN, violates the 1999 standard and can't disable AUTH=PLAIN, then a boolean option to turn off the above described behavior could be provided in Thunderbird.

I think that covers all the cases. Comments?
(In reply to Chris Newman from comment #24)
> If the server advertises AUTH=PLAIN and the username/password contains
> non-ASCII characters, then preferentially use the AUTHENTICATE PLAIN command
> instead of the LOGIN command. This immediately achieves goals 1-3. It does
> this because the IMAP standard (RFC 3501) requires implementation of
> AUTH=PLAIN.

We already have a full fallback list of preferred methods and LOGIN is at the very bottom.

> When AUTH=PLAIN is not advertised by the server, then retain the present
> Thunderbird behavior. This achieves goal 4.

Doing two different behaviors based on the server configuration is nontrivial. The lossy conversion of the password happens in a place shared for IMAP and POP (NNTP uses a different routine for various reasons, and SMTP is naturally completely different), and we shoehorn the password from UTF-16 to a char* as fast as possible.

On the other hand, changing it from NS_LossyConvertUTF16toASCII to NS_ConvertUTF16toUTF8 probably would help more than it would break (I think legacy charsets are a bigger concern in NNTP, but we have explicit server charset information available there, so it shouldn't be an issue). I don't trust myself to make this call, though.
Joshua,

With my server implementer hat on, your proposal would be ideal. It would immediately make Thunderbird interoperate with current releases of Oracle (formerly iPlanet/Sun) Messaging Server for non-ASCII username/password in POP, IMAP and SMTP submission. Thunderbird presently does not interoperate because we reject authentication attempts that use a non-ASCII charset other than UTF-8 (we internally translate IMAP LOGIN and POP USER/PASS to SASL PLAIN to minimize authentication code paths, which explains this behavior). Thunderbird's present behavior is a harmful standards violation so the interoperability failure is Thunderbird's fault.

I can't speak for other server implementers and server admins. But UTF-8 does have the particularly nice property that a UTF-8 validation routine is almost always successful at distinguishing UTF-8 from other legacy 8-bit character sets. So that means other servers can implement support for your simpler proposal and probably retain backwards compatibility with any legacy behavior.

So I'm personally fine with either of the two proposals. And as long as your IMAP authentication logic prefers SASL PLAIN over IMAP LOGIN or SASL LOGIN mechanisms, Thunderbird can claim IMAP standards compliance once you make your proposed simpler change. Your proposal is less conservative for existing deployments than mine is, but as an open source product, Thunderbird can get away with less conservative changes as long as it can claim standards compliance and blame the server.

So I have no objection to either change proposal, but the Thunderbird status-quo is badly broken.
code-wise, I think I would change the incoming server password code to return a unicode string, and let the protocol code figure out how it wants to do the conversion.
Attached patch proposed fix (obsolete) — Splinter Review
This passes the 16 bit password to the protocols, which allows them to decide how they want to convert them before sending them out on the wire. This gives us a lot of flexibility to deal with different auth mechanisms and different servers, perhaps by adding a per-server pref to control the utf8-encoding, if we really need to.

I also removed the logon redirection from imap, since that's not used anymore, and reworked the pop3passwordfailure.js test to use the async test stuff since the test was a bit fragile (that change is not needed but I made it anyway).

I'll generate a try server build with this change and see if anyone can verify that it helps.
Assignee: nobody → dbienvenu
Attachment #637513 - Flags: superreview?(neil)
Attachment #637513 - Flags: review?(mbanner)
Whiteboard: [patchlove][has draft patch]
(In reply to David :Bienvenu from comment #29)
> Created attachment 637513 [details] [diff] [review]
> proposed fix

What, no test that the passwords work correctly with fakeserver for imapd.js?
(In reply to Joshua Cranmer [:jcranmer] from comment #30)
> (In reply to David :Bienvenu from comment #29)
> > Created attachment 637513 [details] [diff] [review]
> > proposed fix
> 
> What, no test that the passwords work correctly with fakeserver for imapd.js?

we have test_imapPasswordFailure.js, which tests the basic password mechanism, I believe.
Oh, I should say, I made all the imap auth logins use utf8 password, and old LOGIN use the previous lossy converted passwords. This is a just a starting point; we'll have to see what the real world looks like.
Thanks for working on this! It's much appreciated.

Although I'm not familiar with the Thunderbird code, I did review the code deltas. From what I can see, the only place where it uses UTF-8 instead of "lossy convert" (which I presume means ISO-8859-1 which is what you get when Unicode's 20-bit code points are truncated to 8 bits) is for IMAP "AUTHENTICATE PLAIN". In order for Thunderbird to be standards-compliant-enough to interoperate with standards-compliant servers, it should use UTF-8 for the SASL PLAIN mechanism regardless of the underlying protocol (IMAP, POP and SMTP). That includes the POP3 "AUTH PLAIN" command and the SMTP "AUTH PLAIN" command.
(In reply to Chris Newman from comment #34)
> Thanks for working on this! It's much appreciated.
> 
ah, you're right I didn't fix POP. I've fixed that locally. I didn't deal with SMTP at all, but I can do that now.
Attachment #637513 - Attachment is obsolete: true
Attachment #637513 - Flags: superreview?(neil)
Attachment #637513 - Flags: review?(mbanner)
Comment on attachment 637666 [details] [diff] [review]
change smtp to unicode passwords, make pop3 auth=plain use utf8

>-      rv = SetPassword(NS_LossyConvertUTF16toASCII(uniPasswordAdopted));
>+      rv = SetPassword(nsDependentString(uniPassword));
rv = SetPassword(uniPasswordAdopted);

>-    rv = DoNtlmStep1(username.get(), password.get(), response);
>+    rv = DoNtlmStep1(username.get(), asciiPassword.get(), response);
Eek! Ntlm actually wants Unicode (ideally for username too!). Perhaps this would be good to go in a followup bug.

>-nsSmtpServer::GetPassword(nsACString& aPassword)
>+nsSmtpServer::GetPassword(nsAString& aPassword)
...
>-        return incomingServerToUse->GetPassword(aPassword);
Surely you don't need to change this, because the incoming server is now using unicode passwords too?

>-  nsString uniPassword;
> 
>   rv = aDialog->PromptPassword(aPromptTitle, aPromptMessage,
>                                NS_ConvertASCIItoUTF16(serverUri).get(),
>                                nsIAuthPrompt::SAVE_PASSWORD_PERMANENTLY,
>-                               getter_Copies(uniPassword), &okayValue);
>+                               getter_Copies(aPassword), &okayValue);
Please revert these changes, getter_Copies(nsAString) isn't external-API safe.

>@@ -95,7 +95,7 @@ NS_IMETHODIMP nsSmtpService::SendMailMes
>   if (NS_SUCCEEDED(rv) && smtpServer)
>   {
>     if (aPassword && *aPassword)
>-      smtpServer->SetPassword(nsDependentCString(aPassword));
>+      smtpServer->SetPassword(NS_ConvertASCIItoUTF16(nsDependentCString(aPassword)));
Change the signature of SendMailMessage perhaps? (Not sure where the caller is, and why they don't have a unicode password?)

>-  void OverrideConnectionInfo(in wstring pHost, in unsigned short pPort, in string pCookieData);
Unrelated change?

> NS_IMETHODIMP
> nsImapIncomingServer::PromptPassword(nsIMsgWindow *aMsgWindow,
>-                                  nsACString &aPassword)
>+                                     nsAString &aPassword)
:-)

>+  nsCString password;
>+  password.Assign(NS_ConvertUTF16toUTF8(aPassword));
NS_ConvertUTF16toUTF8 password(aPassword);

>-  // these settings allow clients to override various pieces of the connection info from the url
>-  bool m_overRideUrlConnectionInfo;
>+  nsString mAcceptLanguages;
> 
>-  nsCString m_logonHost;
>-  nsCString m_logonCookie;
>-  PRInt16 m_logonPort;
>-  
>-  nsString mAcceptLanguages;
>-  
You confused diff by deleting the whitespace on the last line ;-)
Assignee: dbienvenu → nobody
Neil, this addresses your comments. I fixed the ntlm passwords while I was at it.

The change that looked like an unrelated change was removing of dead code which I would have had to change to make it compile with the interface changes, so I thought it better to simply remove it. It had to do with a bizarro auth mechanism the old aol imap servers required us to use in the Netscape/AOL days.
Assignee: nobody → mozilla
Attachment #637666 - Attachment is obsolete: true
Attachment #641656 - Flags: superreview?(mbanner)
Attachment #641656 - Flags: review?(neil)
Comment on attachment 641656 [details] [diff] [review]
fix addressing Neil's comments

Review of attachment 641656 [details] [diff] [review]:
-----------------------------------------------------------------

sr=me with the comments fixed or in follow-ups.

::: mailnews/base/util/nsMsgIncomingServer.cpp
@@ +804,4 @@
>        }
>  
>        // we got a password back...so remember it
> +      rv = SetPassword(nsDependentString(uniPassword));

You need to free uniPassword after this - it was being adopted previously, but isn't now.

::: mailnews/base/util/nsMsgProtocol.h
@@ +123,4 @@
>  
>    virtual nsresult InitFromURI(nsIURI *aUrl);
>  
> +  nsresult DoNtlmStep1(const char *username, const  PRUnichar *password, nsCString &response);

All the callers to this are doing .get(), I think we should just pass a const ns(C)String & and do a .get() in this function.

::: mailnews/compose/public/nsISmtpService.idl
@@ +54,4 @@
>     */
>    void sendMailMessage(in nsIFile aFilePath, in string aRecipients, 
>                         in nsIMsgIdentity aSenderIdentity,
> +                       in AString aPassword,

This file needs a uuid bump I think
Attachment #641656 - Flags: superreview?(mbanner) → superreview+
Hi,

I experienced the same problem with the username on SASL PLAIN.

I couldnt login with user with "üöä"

ich captured the base64 string from wireshark and after iconv the string from ISO- to UTF8 and put it back to base64,
I could successfully login on telnet.
Blocks: 123880
Neil review ping.
Neil, are you OK to review patch as is? Or do you want patch updated first?
Flags: needinfo?(neil)
Comment on attachment 641656 [details] [diff] [review]
fix addressing Neil's comments

Sorry, I must have overlooked the review request for some reason.

>-      nsAutoString uniPasswordAdopted;
>-      uniPasswordAdopted.Adopt(uniPassword);
As Standard8 mentioned, you need to keep this...

>-      rv = SetPassword(NS_LossyConvertUTF16toASCII(uniPasswordAdopted));
>+      rv = SetPassword(nsDependentString(uniPassword));
... and you still need to change this to SetPassword(uniPasswordAdopted).

>+  nsresult DoNtlmStep1(const char *username, const  PRUnichar *password, nsCString &response);
Nit: spacing issue. (There are others.)

>-            password, EmptyCString(), nsnull);
>+            EmptyString(), EmptyCString(), nsnull);
Whoops. I think this password needs to be switched to AString too.

>+  nsCString asciiPassword;
>+  asciiPassword.Assign(NS_ConvertUTF16toUTF8(password));
NS_ConvertUTF16toUTF8 asciiPassword(password);
[perhaps you should use password and uniPassword?]

>   nsCAutoString password;
>+  nsAutoString uniPassword;
> 
>-  GetPassword(password);
>-  if (password.IsEmpty())
>+  GetPassword(uniPassword);
>+  if (uniPassword.IsEmpty())
>   {
>     m_urlErrorState = NS_ERROR_SMTP_PASSWORD_UNDEFINED;
>     return NS_ERROR_SMTP_PASSWORD_UNDEFINED;
>   }
>+  CopyUTF16toUTF8(uniPassword, password);
NS_ConvertUTF16toUTF8 password(uniPassword);

>-  NS_LossyConvertUTF16toASCII password(uniPassword);
>-
>-  rv = SetPassword(password);
>+  aPassword = uniPassword;
>+  rv = SetPassword(aPassword);
>   NS_ENSURE_SUCCESS(rv, rv);
> 
>-  aPassword = password;
>   return NS_OK;
Would be better to prompt password directly into aPassword like you do for GetUsernamePasswordWithUI.

>-  void OverrideConnectionInfo(in wstring pHost, in unsigned short pPort, in string pCookieData);
Need to look at this more closely because I didn't check last time.

>-        (void) DoNtlmStep1(m_username.get(), m_passwordResult.get(), cmd);
>+        (void) DoNtlmStep1(m_username.get(),
>+                           m_passwordResult.get(),
>+                           cmd);
???

>       rv = MSGCramMD5(decodedChallenge, strlen(decodedChallenge),
>-                      m_passwordResult.get(), m_passwordResult.Length(), digest);
>+                      NS_LossyConvertUTF16toASCII(m_passwordResult).get(),
>+                      m_passwordResult.Length(), digest);
Shouldn't this be UTF8 too?

>     rv = MSGApopMD5(m_ApopTimestamp.get(), m_ApopTimestamp.Length(),
>-                    m_passwordResult.get(), m_passwordResult.Length(), digest);
>+                    NS_LossyConvertUTF16toASCII(m_passwordResult).get(),
>+                    m_passwordResult.Length(), digest);
[Can't work out whether APOP uses UTF8 or not]

>     PR_snprintf(&plain_string[1], 510, "%s", m_username.get());
>     len += m_username.Length();
>     len++; /* second <NUL> char */
>-    PR_snprintf(&plain_string[len], 511-len, "%s", m_passwordResult.get());
>+    PR_snprintf(&plain_string[len], 511-len, "%s",
>+                NS_ConvertUTF16toUTF8(m_passwordResult).get());
>     len += m_passwordResult.Length();
This is wrong, it needs to use the UTF8 length. (But this code section probably needs a rewrite to use some sane sort of string concatenation.)

>+        PL_Base64Encode(NS_LossyConvertUTF16toASCII(m_passwordResult).get(),
>+                        m_passwordResult.Length(), nsnull);
[This looks OK because it's lossy conversion so the length is the same]
Flags: needinfo?(neil)
Comment on attachment 641656 [details] [diff] [review]
fix addressing Neil's comments

r- because of the previous comments.

However the IMAP changes look fine apart from this one nit:
-  NS_ENSURE_TRUE(m_imapServerSink, NS_ERROR_NULL_POINTER);
+ NS_ENSURE_TRUE(m_imapServerSink, NS_ERROR_NULL_POINTER);
Attachment #641656 - Flags: review?(neil) → review-
Whiteboard: [patchlove]
It seems as (after 10+ years) Mozilla experts still is not able correct this bug.
Althougt my system (Linux Fedora 19 i386) is using UTF-8 and I use UTF-8 as mail messages encoding, TB and SM still sent users credentials (contrary to RFC 2595, 4616) badly (seems as some 8859-1 or what).

Squirrelmail webmail and Claws Mail has this implemented fine and works well. From Claws mail migt Mozilla developers inspire - unlimited number of addresses for contact in addressbook, can write contacts to LDAP addressbook, clean design and no UI somersaults are things that I miss in Mozilla TB.
Andrew, could you finish the needed revisions and drive in a final patch?
Assignee: mozilla → nobody
Flags: needinfo?(wanderer)
Not sure, but I'll look into it. I may be a bit slow in getting to it, though; my non-Mozilla schedule is sometimes erratic.
Flags: needinfo?(wanderer)
See Also: → 1102196
I might have a clue where this bug comes from.

I bet the dev of this feature was using MS exchange Server to test.

there is a bug in exchange server that you have to use ISO_8859-1 encoding inside the base64.

discovered this bug while implementing a small mail client, which now does a fallback from utf8 to ISO_8859-1 if login fails, which is needed to login to exchange with SASL-PLAIN
(In reply to matthias.lay from comment #49)
> I might have a clue where this bug comes from.
> 
> I bet the dev of this feature was using MS exchange Server to test.
> 
> there is a bug in exchange server that you have to use ISO_8859-1 encoding
> inside the base64.
> 
> discovered this bug while implementing a small mail client, which now does a
> fallback from utf8 to ISO_8859-1 if login fails, which is needed to login to
> exchange with SASL-PLAIN

I very much doubt this may be the case. 
I'm experiencing this bug by using TB as client and my mail provider is a centOS server. I'm not sure what's the POP server software, but i don't think it would be anything from M$. 

Had to change my pass in order to be able to use TB as mail client, BTW.
Oh... i understand now, you meant "they used Exchange when created the code, that's the reason this is happening, they're surelly forcing iso-8859-1". My bad.
yup. that´s my guess how this TB SASL-PLAIN code was going live

the RFC says it should be utf8. 
and utf8 works with every mailserver I tested

...... EXCEPT M$ Exchange, where the login fails with utf8
This bug is STILL occuring in TB 38.3.0 (on Windows 10 64 bit) !!!

Seriously guys ! 

I have a password with a £ symbol in it.

I can login via Webmail ... no problems
I can login on iPhone .... no problem
I can login on OS X Mail ... no problem

But try it on Windows 10 ... no go.
I am able to reproduce this as well with Thunderbird 45.2.0. The interesting thing is that I hit this problem via SMTP auth only - IMAP works with my long and complex password.

These are the characters I have in my password:
   a-zA-Z
   0-9
   |
   =
   #
   §
   ~
   @
   +
   %
It is 30 characters long.

I hope someone is able to finally solve this. Maybe it helps to look into the part of the code that deals with IMAP AUTH where things seem to be working quite well.

I started my report here: https://support.mozilla.org/en-US/questions/1129468

Feel free to reach out to me if I can help with testing or any other stuff.
(In reply to Phillip from comment #54)

> These are the characters I have in my password:
>    a-zA-Z
>    0-9
>    |
>    =
>    #
>    §
>    ~
>    @
>    +
>    %
> It is 30 characters long.
> 

if your passwords is just out of ASCII like these examples, this might be the wrong bug for you. problem here is utf-8 and this doesnt work in imap neither.
It does work in IMAP.

@ Matthias, could you please make a suggestion which would be the right bug in case I have a password which works via IMAP but not via SMTP?

Just in case you didn't read my initial report I linked here (https://support.mozilla.org/en-US/questions/1129468) - I have tested SMTP access with telnet and used my long complex password with all of the characters above, and it works fine.

Also I might have to remark that Thunderbird worked fine with my SMTP server month and years before. I was also able to change my password back to a shorter less complex one which then works again for Thunderbird.

I was so bored today that I tried all character one at a time:

It is the § sign which brakes SMTP AUTH only - IMAP works well with password containing this char.

Please fix this.
(In reply to Phillip from comment #56)

> @ Matthias, could you please make a suggestion which would be the right bug
> in case I have a password which works via IMAP but not via SMTP?

I dont know the right place. but if you check the age of this ticket (11 years now) and you are looking for a fast solution this might be the wrong place anyway.

I would suggest claws-mail a nice small mail client that honors RFCs, or just dont use "§".



> 
> Please fix this.

this is always very helpful in tickets
How does the age of a ticket affect how fast it is worked on or gets solved when a new comment is added which might help finding the root cause?

What do you suggest to get "a fast solution"?
Just for your notice, I never asked for a fast solution, but now you raised my interest ;)

How does switching to another mail client or omitting certain characters fix the problem in Thunderbird?
@Matthias : The section sign (§) is not part of the ASCII code but is actually part of the extend ASCII code - it's part of ISO 8859-1  and UTF and therefore it's the right bug report.

@Phillip
But calling it a bug is probably a bit missing the point - Thunderbird is just not supporting the RFC standards (what's a bit weird for a client application that's communicating with a server that is actually using the those standards). Anyway, Mozilla decided along time ago to let Thunderbird slowly die and why should the Thunderbird developer still bother to ensure standard compliancy for a more or less dead project?
Blocks: 663814
Summary: thunderbird says the password/login failed when using symbols in passwords → thunderbird says the password/login failed when using symbols (unicode characters) in passwords
Perhaps it is easy to prompt the user, that his password will not work, if it contains symbols that are out of ASCII range, if fixing the root cause is not worth the effort.
Given that this is an ancient old bug which even has a patch that almost passed review, I think we should address the root cause. I'll look into it over the next few weeks. Hopefully we can ship a fix in the next ESR release TB 59.
(In reply to kk from comment #69)
> Perhaps it is easy to prompt the user, that his password will not work, if
> it contains symbols that are out of ASCII range, if fixing the root cause is
> not worth the effort.

Or we could only accept 0 to 9 to log in.
(In reply to David VANTYGHEM from comment #71)

> (In reply to kk from comment #69)
> > Perhaps it is easy to prompt the user, that his password will not work, if
> > it contains symbols that are out of ASCII range, if fixing the root cause is
> > not worth the effort.
> 
> Or we could only accept 0 to 9 to log in.

Neither of those comments are realistic. In many environments password must meet some complexity requirements, and that means characters from european or asian languages.

For example, in Active Directory environments: https://technet.microsoft.com/en-us/library/hh994562(v=ws.11).aspx
(In reply to David VANTYGHEM from comment #71)
> (In reply to kk from comment #69)
> > Perhaps it is easy to prompt the user, that his password will not work, if
> > it contains symbols that are out of ASCII range, if fixing the root cause is
> > not worth the effort.
> 
Or we could use no password.
I think we had enough unhelpful comments here. I'm in the process of refreshing the patch. Then I will address the issues from comment #39, comment #43 and comment #44 and get this landed.
Restrict Comments: true
This refreshes the five y/o patch to the current code base.
The modified test test_pop3PasswordFailure.js passes.

Now I need to address comment #39, comment #43 and comment #44 and get this landed.
Assignee: nobody → jorgk
Status: NEW → ASSIGNED
This addresses comment #39.
Attachment #8911425 - Attachment is obsolete: true
This addresses comment #43 and comment #44. I reverted all the UUID changes since they are no longer necessary.

https://treeherder.mozilla.org/#/jobs?repo=try-comm-central&revision=8d44e804efc9d61fcf1c1689bc6d1086e889dff2
Attachment #8911437 - Attachment is obsolete: true
Attachment #8911439 - Flags: review+
Seven test failures:
TEST-UNEXPECTED-FAIL | mailnews/compose/test/unit/test_sendMessageLater2.js | xpcshell return code: 1 [log…]
TEST-UNEXPECTED-FAIL | mailnews/compose/test/unit/test_sendMessageLater.js | xpcshell return code: 1 [log…]
TEST-UNEXPECTED-FAIL | mailnews/compose/test/unit/test_sendMessageFile.js | xpcshell return code: 1 [log…]
TEST-UNEXPECTED-FAIL | mailnews/compose/test/unit/test_sendMailAddressIDN.js | xpcshell return code: 1 [log…]
TEST-UNEXPECTED-FAIL | mailnews/compose/test/unit/test_sendMessageLater3.js | xpcshell return code: 1 [log…]
TEST-UNEXPECTED-FAIL | mailnews/compose/test/unit/test_bug474774.js | xpcshell return code: 1 [log…]
TEST-UNEXPECTED-FAIL | mailnews/compose/test/unit/test_sendBackground.js | xpcshell return code: 1 [log…]

All with a crash:
PROCESS-CRASH | mailnews/compose/test/unit/test_sendMessageLater2.js | application crashed [@ nsTDependentString<char16_t>::nsTDependentString<char16_t>(char16_t const *)] [log…]

That shouldn't be too hard to fix.
Whiteboard: [patchlove]
Pushed by mozilla@jorgk.com:
https://hg.mozilla.org/comm-central/rev/23725f858c42
Allow unicode in passwords. r=neil,standard8,jorgk
Status: ASSIGNED → RESOLVED
Closed: 7 years ago
Resolution: --- → FIXED
Target Milestone: --- → Thunderbird 58.0
No longer blocks: 663814
Beta (TB 57):
https://hg.mozilla.org/releases/comm-beta/rev/3ba5ab1a84a582c9a4b674eb7c54460d46e15990

That's been on Daily for a while, so to get some real world feedback, this needed to be uplifted.
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: