зеркало из https://github.com/mozilla/pjs.git
add support for IMAP AUTH=NTLM, MSN, sr=mscott 200436
This commit is contained in:
Родитель
fdef38b20b
Коммит
804ad832e0
|
@ -56,7 +56,7 @@ interface nsIImapProtocol : nsISupports {
|
|||
// I think. Imap happens to be the only case where we need to push back
|
||||
// a thread safe object to our test app.
|
||||
///////////////////////////////////////////////////////////////////////// */
|
||||
void LoadUrl(in nsIURI aUrl, in nsISupports aConsumer);
|
||||
void LoadImapUrl(in nsIURI aUrl, in nsISupports aConsumer);
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// IsBusy returns true if the connection is currently processing a url
|
||||
|
|
|
@ -44,6 +44,7 @@ REQUIRES = xpcom \
|
|||
uconv \
|
||||
unicharutil \
|
||||
mime \
|
||||
caps \
|
||||
pref \
|
||||
intl \
|
||||
nkcache \
|
||||
|
|
|
@ -134,7 +134,9 @@ typedef enum {
|
|||
kHasLanguageCapability = 0x00010000, /* language extensions */
|
||||
kHasCRAMCapability = 0x00020000, /* CRAM auth extension */
|
||||
kQuotaCapability = 0x00040000, /* RFC 2087 quota extension */
|
||||
kHasIdleCapability = 0x00080000 /* RFC 2177 idle extension */
|
||||
kHasIdleCapability = 0x00080000, /* RFC 2177 idle extension */
|
||||
kHasAuthNTLMCapability = 0x00100000, /* AUTH NTLM extension */
|
||||
kHasAuthMSNCapability = 0x00200000, /* AUTH MSN extension */
|
||||
} eIMAPCapabilityFlag;
|
||||
|
||||
// this used to be part of the connection object class - maybe we should move it into
|
||||
|
|
|
@ -90,6 +90,7 @@
|
|||
#include "nsIMsgProtocolInfo.h"
|
||||
#include "nsIMsgMailSession.h"
|
||||
#include "nsIMAPNamespace.h"
|
||||
#include "nsISignatureVerifier.h"
|
||||
|
||||
#include "nsITimer.h"
|
||||
#include "nsMsgUtils.h"
|
||||
|
@ -439,14 +440,14 @@ nsImapIncomingServer::GetImapConnectionAndLoadUrl(nsIEventQueue * aClientEventQu
|
|||
nsCOMPtr<nsIMsgMailNewsUrl> mailnewsurl = do_QueryInterface(aImapUrl, &rv);
|
||||
if (aProtocol)
|
||||
{
|
||||
rv = aProtocol->LoadUrl(mailnewsurl, aConsumer);
|
||||
rv = aProtocol->LoadImapUrl(mailnewsurl, aConsumer);
|
||||
// *** jt - in case of the time out situation or the connection gets
|
||||
// terminated by some unforseen problems let's give it a second chance
|
||||
// to run the url
|
||||
if (NS_FAILED(rv))
|
||||
{
|
||||
NS_ASSERTION(PR_FALSE, "shouldn't get an error loading url");
|
||||
rv = aProtocol->LoadUrl(mailnewsurl, aConsumer);
|
||||
rv = aProtocol->LoadImapUrl(mailnewsurl, aConsumer);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -508,7 +509,7 @@ nsImapIncomingServer::LoadNextQueuedUrl(nsIImapProtocol *aProtocol, PRBool *aRes
|
|||
if (NS_SUCCEEDED(rv) && url)
|
||||
{
|
||||
nsImapProtocol::LogImapUrl("playing queued url", aImapUrl);
|
||||
rv = protocolInstance->LoadUrl(url, aConsumer);
|
||||
rv = protocolInstance->LoadImapUrl(url, aConsumer);
|
||||
NS_ASSERTION(NS_SUCCEEDED(rv), "failed running queued url");
|
||||
urlRun = PR_TRUE;
|
||||
removeUrlFromQueue = PR_TRUE;
|
||||
|
@ -846,8 +847,18 @@ nsImapIncomingServer::CreateProtocolInstance(nsIEventQueue *aEventQueue,
|
|||
// create a new connection and add it to the connection cache
|
||||
// we may need to flag the protocol connection as busy so we don't get
|
||||
// a race condition where someone else goes through this code
|
||||
|
||||
PRBool useSecAuth;
|
||||
GetUseSecAuth(&useSecAuth);
|
||||
nsresult rv;
|
||||
// pre-flight that we have nss - on the ui thread
|
||||
if (useSecAuth)
|
||||
{
|
||||
nsCOMPtr<nsISignatureVerifier> verifier = do_GetService(SIGNATURE_VERIFIER_CONTRACTID, &rv);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
nsIImapProtocol * protocolInstance = nsnull;
|
||||
nsresult rv = nsComponentManager::CreateInstance(kImapProtocolCID, nsnull,
|
||||
rv = nsComponentManager::CreateInstance(kImapProtocolCID, nsnull,
|
||||
NS_GET_IID(nsIImapProtocol),
|
||||
(void **) &protocolInstance);
|
||||
if (NS_SUCCEEDED(rv) && protocolInstance)
|
||||
|
@ -1794,15 +1805,15 @@ NS_IMETHODIMP nsImapIncomingServer::DiscoveryDone()
|
|||
currentImapFolder->GetIsNamespace(&isNamespace);
|
||||
if (!isNamespace) // don't list namespaces explicitly
|
||||
{
|
||||
// If there are no subfolders and this is unverified, we don't want to run
|
||||
// this url. That is, we want to undiscover the folder.
|
||||
// If there are subfolders and no descendants are verified, we want to
|
||||
// undiscover all of the folders.
|
||||
// Only if there are subfolders and at least one of them is verified do we want
|
||||
// to refresh that folder's flags, because it won't be going away.
|
||||
currentImapFolder->SetExplicitlyVerify(PR_FALSE);
|
||||
currentImapFolder->List();
|
||||
}
|
||||
// If there are no subfolders and this is unverified, we don't want to run
|
||||
// this url. That is, we want to undiscover the folder.
|
||||
// If there are subfolders and no descendants are verified, we want to
|
||||
// undiscover all of the folders.
|
||||
// Only if there are subfolders and at least one of them is verified do we want
|
||||
// to refresh that folder's flags, because it won't be going away.
|
||||
currentImapFolder->SetExplicitlyVerify(PR_FALSE);
|
||||
currentImapFolder->List();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1989,6 +2000,7 @@ nsresult nsImapIncomingServer::DeleteNonVerifiedFolders(nsIMsgFolder *curFolder)
|
|||
return rv;
|
||||
}
|
||||
|
||||
|
||||
PRBool nsImapIncomingServer::NoDescendentsAreVerified(nsIMsgFolder *parentFolder)
|
||||
{
|
||||
PRBool nobodyIsVerified = PR_TRUE;
|
||||
|
@ -2708,7 +2720,7 @@ NS_IMETHODIMP nsImapIncomingServer::OnLogonRedirectionReply(const PRUnichar *pHo
|
|||
nsCOMPtr<nsIURI> url = do_QueryInterface(aImapUrl, &rv);
|
||||
if (NS_SUCCEEDED(rv) && url)
|
||||
{
|
||||
rv = protocolInstance->LoadUrl(url, aConsumer);
|
||||
rv = protocolInstance->LoadImapUrl(url, aConsumer);
|
||||
urlRun = PR_TRUE;
|
||||
}
|
||||
|
||||
|
|
|
@ -854,7 +854,7 @@ NS_IMETHODIMP nsImapMailFolder::CreateClientSubfolderInfo(const char *folderName
|
|||
if (NS_FAILED(rv)) return rv;
|
||||
nsCAutoString leafnameC;
|
||||
leafnameC.AssignWithConversion(leafName);
|
||||
return parentFolder->CreateClientSubfolderInfo(leafnameC.get(), hierarchyDelimiter,flags, suppressNotification);
|
||||
return parentFolder->CreateClientSubfolderInfo(leafnameC.get(), hierarchyDelimiter,flags, suppressNotification);
|
||||
}
|
||||
|
||||
// if we get here, it's really a leaf, and "this" is the parent.
|
||||
|
@ -876,7 +876,10 @@ NS_IMETHODIMP nsImapMailFolder::CreateClientSubfolderInfo(const char *folderName
|
|||
rv = CreateFileSpecForDB(folderName, path, getter_AddRefs(dbFileSpec));
|
||||
NS_ENSURE_SUCCESS(rv,rv);
|
||||
|
||||
rv = mailDBFactory->Open(dbFileSpec, PR_TRUE, PR_TRUE, (nsIMsgDatabase **) getter_AddRefs(unusedDB));
|
||||
//Now let's create the actual new folder
|
||||
rv = AddSubfolderWithPath(folderNameStr, dbFileSpec, getter_AddRefs(child));
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
rv = mailDBFactory->OpenFolderDB(child, PR_TRUE, PR_TRUE, (nsIMsgDatabase **) getter_AddRefs(unusedDB));
|
||||
|
||||
if (NS_SUCCEEDED(rv) && unusedDB)
|
||||
{
|
||||
|
@ -889,11 +892,6 @@ NS_IMETHODIMP nsImapMailFolder::CreateClientSubfolderInfo(const char *folderName
|
|||
// folderInfo->SetMailboxName(&folderNameStr);
|
||||
// }
|
||||
|
||||
//Now let's create the actual new folder
|
||||
rv = AddSubfolderWithPath(folderNameStr, dbFileSpec, getter_AddRefs(child));
|
||||
// if (NS_SUCCEEDED(rv) && child)
|
||||
// child->SetPath(dbFileSpec);
|
||||
|
||||
nsCOMPtr <nsIMsgImapMailFolder> imapFolder = do_QueryInterface(child);
|
||||
if (imapFolder)
|
||||
{
|
||||
|
@ -4618,21 +4616,20 @@ nsImapMailFolder::OnStopRunningUrl(nsIURI *aUrl, nsresult aExitCode)
|
|||
}
|
||||
break;
|
||||
case nsIImapUrl::nsImapListFolder:
|
||||
// check if folder is now verified - if not,
|
||||
// we should remove it?
|
||||
if (NS_SUCCEEDED(aExitCode) && !m_verifiedAsOnlineFolder)
|
||||
{
|
||||
nsCOMPtr<nsIMsgFolder> parent;
|
||||
rv = GetParent(getter_AddRefs(parent));
|
||||
|
||||
|
||||
if (NS_SUCCEEDED(rv) && parent)
|
||||
// check if folder is now verified - if not,
|
||||
// we should remove it?
|
||||
if (NS_SUCCEEDED(aExitCode) && !m_verifiedAsOnlineFolder)
|
||||
{
|
||||
nsCOMPtr<nsIMsgImapMailFolder> imapParent = do_QueryInterface(parent);
|
||||
if (imapParent)
|
||||
imapParent->RemoveSubFolder(this);
|
||||
nsCOMPtr<nsIMsgFolder> parent;
|
||||
rv = GetParent(getter_AddRefs(parent));
|
||||
|
||||
if (NS_SUCCEEDED(rv) && parent)
|
||||
{
|
||||
nsCOMPtr<nsIMsgImapMailFolder> imapParent = do_QueryInterface(parent);
|
||||
if (imapParent)
|
||||
imapParent->RemoveSubFolder(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case nsIImapUrl::nsImapRefreshFolderUrls:
|
||||
// we finished getting an admin url for the folder.
|
||||
|
|
|
@ -112,7 +112,7 @@ nsImapOfflineSync::OnStopRunningUrl(nsIURI* url, nsresult exitCode)
|
|||
nsCOMPtr<nsIImapUrl> imapUrl = do_QueryInterface(url);
|
||||
|
||||
if (imapUrl)
|
||||
nsImapProtocol::LogImapUrl(NS_SUCCEEDED(rv) ? "offline imap url succeeded:" : "offline imap url failed:", imapUrl);
|
||||
nsImapProtocol::LogImapUrl(NS_SUCCEEDED(rv) ? "offline imap url succeeded " : "offline imap url failed ", imapUrl);
|
||||
// NS_BINDING_ABORTED is used for the user pressing stop, which
|
||||
// should cause us to abort the offline process. Other errors
|
||||
// should allow us to continue.
|
||||
|
@ -140,6 +140,8 @@ nsresult nsImapOfflineSync::AdvanceToNextServer()
|
|||
|
||||
if (!m_allServers)
|
||||
{
|
||||
NS_ASSERTION(!m_currentServer, "this shouldn't be set");
|
||||
m_currentServer = nsnull;
|
||||
nsCOMPtr<nsIMsgAccountManager> accountManager =
|
||||
do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
|
||||
NS_ASSERTION(accountManager && NS_SUCCEEDED(rv), "couldn't get account mgr");
|
||||
|
@ -206,7 +208,6 @@ nsresult nsImapOfflineSync::AdvanceToNextFolder()
|
|||
|
||||
if (NS_SUCCEEDED(rv) && m_serverEnumerator)
|
||||
{
|
||||
// ### argh, this doesn't go into sub-folders of each folder.
|
||||
nsCOMPtr <nsISupports> supports;
|
||||
rv = m_serverEnumerator->CurrentItem(getter_AddRefs(supports));
|
||||
m_currentFolder = do_QueryInterface(supports);
|
||||
|
|
|
@ -294,8 +294,9 @@ NS_IMETHODIMP nsMsgImapLineDownloadCache::GetMsgHdrs(const char **aMsgHdrs)
|
|||
}
|
||||
|
||||
/* the following macros actually implement addref, release and query interface for our component. */
|
||||
NS_IMPL_THREADSAFE_ADDREF(nsImapProtocol)
|
||||
NS_IMPL_THREADSAFE_RELEASE(nsImapProtocol)
|
||||
|
||||
NS_IMPL_ADDREF_INHERITED(nsImapProtocol, nsMsgProtocol)
|
||||
NS_IMPL_RELEASE_INHERITED(nsImapProtocol, nsMsgProtocol )
|
||||
|
||||
NS_INTERFACE_MAP_BEGIN(nsImapProtocol)
|
||||
NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIImapProtocol)
|
||||
|
@ -349,12 +350,10 @@ nsresult nsImapProtocol::GlobalInitialization()
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
nsImapProtocol::nsImapProtocol() :
|
||||
nsImapProtocol::nsImapProtocol() : nsMsgProtocol(nsnull),
|
||||
m_parser(*this)
|
||||
{
|
||||
m_flags = 0;
|
||||
m_urlInProgress = PR_FALSE;
|
||||
m_socketIsOpen = PR_FALSE;
|
||||
m_idle = PR_FALSE;
|
||||
m_useIdle = PR_TRUE; // by default, use it
|
||||
m_ignoreExpunges = PR_FALSE;
|
||||
|
@ -1182,7 +1181,7 @@ nsImapProtocol::ImapThreadMainLoop()
|
|||
break;
|
||||
#ifdef DEBUG_bienvenu
|
||||
else
|
||||
printf("read to run but no url and not idle\n");
|
||||
printf("ready to run but no url and not idle\n");
|
||||
#endif
|
||||
}
|
||||
m_imapThreadIsRunning = PR_FALSE;
|
||||
|
@ -1546,12 +1545,20 @@ nsresult nsImapProtocol::SendData(const char * dataBuffer, PRBool aSuppressLoggi
|
|||
// Begin protocol state machine functions...
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// LoadUrl takes a url, initializes all of our url specific data by calling SetupUrl.
|
||||
// ProcessProtocolState - we override this only so we'll link - it should never get called.
|
||||
|
||||
nsresult nsImapProtocol::ProcessProtocolState(nsIURI * url, nsIInputStream * inputStream,
|
||||
PRUint32 sourceOffset, PRUint32 length)
|
||||
{
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
// LoadImapUrl takes a url, initializes all of our url specific data by calling SetupUrl.
|
||||
// If we don't have a connection yet, we open the connection. Finally, we signal the
|
||||
// url to run monitor to let the imap main thread loop process the current url (it is waiting
|
||||
// on this monitor). There is a contract that the imap thread has already been started b4 we
|
||||
// attempt to load a url....
|
||||
nsresult nsImapProtocol::LoadUrl(nsIURI * aURL, nsISupports * aConsumer)
|
||||
NS_IMETHODIMP nsImapProtocol::LoadImapUrl(nsIURI * aURL, nsISupports * aConsumer)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
if (aURL)
|
||||
|
@ -4578,7 +4585,7 @@ void
|
|||
nsImapProtocol::Store(const char * messageList, const char * messageData,
|
||||
PRBool idsAreUid)
|
||||
{
|
||||
|
||||
|
||||
// turn messageList back into key array and then back into a message id list,
|
||||
// but use the flag state to handle ranges correctly.
|
||||
nsCString messageIdList;
|
||||
|
@ -4598,46 +4605,46 @@ nsImapProtocol::Store(const char * messageList, const char * messageData,
|
|||
msgCountLeft -= msgsToHandle;
|
||||
|
||||
IncrementCommandTagNumber();
|
||||
const char *formatString;
|
||||
if (idsAreUid)
|
||||
formatString = "%s uid store %s %s\015\012";
|
||||
else
|
||||
formatString = "%s store %s %s\015\012";
|
||||
const char *formatString;
|
||||
if (idsAreUid)
|
||||
formatString = "%s uid store %s %s\015\012";
|
||||
else
|
||||
formatString = "%s store %s %s\015\012";
|
||||
|
||||
// we might need to close this mailbox after this
|
||||
m_closeNeededBeforeSelect = GetDeleteIsMoveToTrash() &&
|
||||
m_closeNeededBeforeSelect = GetDeleteIsMoveToTrash() &&
|
||||
(PL_strcasestr(messageData, "\\Deleted"));
|
||||
|
||||
const char *commandTag = GetServerCommandTag();
|
||||
int protocolStringSize = PL_strlen(formatString) +
|
||||
PL_strlen(messageList) + PL_strlen(messageData) +
|
||||
PL_strlen(commandTag) + 1;
|
||||
char *protocolString = (char *) PR_CALLOC( protocolStringSize );
|
||||
const char *commandTag = GetServerCommandTag();
|
||||
int protocolStringSize = PL_strlen(formatString) +
|
||||
PL_strlen(messageList) + PL_strlen(messageData) +
|
||||
PL_strlen(commandTag) + 1;
|
||||
char *protocolString = (char *) PR_CALLOC( protocolStringSize );
|
||||
|
||||
if (protocolString)
|
||||
{
|
||||
PR_snprintf(protocolString, // string to create
|
||||
protocolStringSize, // max size
|
||||
formatString, // format string
|
||||
commandTag, // command tag
|
||||
idString.get(),
|
||||
messageData);
|
||||
|
||||
nsresult rv = SendData(protocolString);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
if (protocolString)
|
||||
{
|
||||
m_flagChangeCount++;
|
||||
ParseIMAPandCheckForNewMail(protocolString);
|
||||
if (GetServerStateParser().LastCommandSuccessful() && CheckNeeded())
|
||||
Check();
|
||||
PR_snprintf(protocolString, // string to create
|
||||
protocolStringSize, // max size
|
||||
formatString, // format string
|
||||
commandTag, // command tag
|
||||
idString.get(),
|
||||
messageData);
|
||||
|
||||
nsresult rv = SendData(protocolString);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
m_flagChangeCount++;
|
||||
ParseIMAPandCheckForNewMail(protocolString);
|
||||
if (GetServerStateParser().LastCommandSuccessful() && CheckNeeded())
|
||||
Check();
|
||||
}
|
||||
PR_Free(protocolString);
|
||||
}
|
||||
PR_Free(protocolString);
|
||||
}
|
||||
else
|
||||
HandleMemoryFailure();
|
||||
else
|
||||
HandleMemoryFailure();
|
||||
}
|
||||
while (msgCountLeft > 0 && !DeathSignalReceived());
|
||||
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -4853,8 +4860,6 @@ void nsImapProtocol::AuthLogin(const char *userName, const char *password, eIMAP
|
|||
|
||||
if (flag & kHasCRAMCapability)
|
||||
{
|
||||
nsresult rv;
|
||||
char *digest;
|
||||
// inform the server that we want to begin a CRAM authentication procedure...
|
||||
nsCAutoString command (GetServerCommandTag());
|
||||
command.Append(" authenticate CRAM-MD5" CRLF);
|
||||
|
@ -4862,7 +4867,8 @@ void nsImapProtocol::AuthLogin(const char *userName, const char *password, eIMAP
|
|||
ParseIMAPandCheckForNewMail();
|
||||
if (GetServerStateParser().LastCommandSuccessful())
|
||||
{
|
||||
char *cramDigest = GetServerStateParser().fCRAMDigest;
|
||||
char *digest = nsnull;
|
||||
char *cramDigest = GetServerStateParser().fAuthChallenge;
|
||||
char * decodedChallenge = PL_Base64Decode(cramDigest,
|
||||
strlen(cramDigest), nsnull);
|
||||
if (m_imapServerSink)
|
||||
|
@ -4884,17 +4890,54 @@ void nsImapProtocol::AuthLogin(const char *userName, const char *password, eIMAP
|
|||
char *base64Str = PL_Base64Encode(m_dataOutputBuf, nsCRT::strlen(m_dataOutputBuf), nsnull);
|
||||
PR_snprintf(m_dataOutputBuf, OUTPUT_BUFFER_SIZE, "%s" CRLF, base64Str);
|
||||
PR_Free(base64Str);
|
||||
PR_Free(digest);
|
||||
rv = SendData(m_dataOutputBuf);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
ParseIMAPandCheckForNewMail(command.get());
|
||||
if (GetServerStateParser().LastCommandSuccessful())
|
||||
return;
|
||||
PR_Free(digest);
|
||||
GetServerStateParser().SetCapabilityFlag(GetServerStateParser().GetCapabilityFlag() & ~kHasCRAMCapability);
|
||||
|
||||
}
|
||||
}
|
||||
} // if CRAM response was received
|
||||
else
|
||||
if (flag & kHasAuthPlainCapability)
|
||||
else if (flag & (kHasAuthNTLMCapability|kHasAuthMSNCapability))
|
||||
{
|
||||
nsCAutoString command (GetServerCommandTag());
|
||||
command.Append((flag & kHasAuthNTLMCapability) ? " authenticate NTLM" CRLF
|
||||
: " authenticate MSN" CRLF);
|
||||
rv = SendData(command.get());
|
||||
ParseIMAPandCheckForNewMail("AUTH NTLM"); // this just waits for ntlm step 1
|
||||
if (GetServerStateParser().LastCommandSuccessful())
|
||||
{
|
||||
nsCAutoString cmd;
|
||||
rv = DoNtlmStep1(userName, password, cmd);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
cmd += CRLF;
|
||||
rv = SendData(cmd.get());
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
ParseIMAPandCheckForNewMail(command.get());
|
||||
if (GetServerStateParser().LastCommandSuccessful())
|
||||
{
|
||||
nsCString challengeStr(GetServerStateParser().fAuthChallenge);
|
||||
nsCString response;
|
||||
rv = DoNtlmStep2(challengeStr, response);
|
||||
if (NS_SUCCEEDED(rv))
|
||||
{
|
||||
response += CRLF;
|
||||
rv = SendData(response.get());
|
||||
ParseIMAPandCheckForNewMail(command.get());
|
||||
if (!GetServerStateParser().LastCommandSuccessful())
|
||||
GetServerStateParser().SetCapabilityFlag(GetServerStateParser().GetCapabilityFlag() & ~(kHasAuthNTLMCapability|kHasAuthMSNCapability));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (flag & kHasAuthPlainCapability)
|
||||
{
|
||||
PR_snprintf(m_dataOutputBuf, OUTPUT_BUFFER_SIZE, "%s authenticate plain" CRLF, GetServerCommandTag());
|
||||
rv = SendData(m_dataOutputBuf);
|
||||
|
@ -7175,7 +7218,8 @@ PRBool nsImapProtocol::TryToLogon()
|
|||
// If secure auth is configured, don't proceed unless the server
|
||||
// supports it. This avoids fallback to insecure login in case
|
||||
// authentication fails.
|
||||
if(m_useSecAuth && !(GetServerStateParser().GetCapabilityFlag() & kHasCRAMCapability))
|
||||
if(m_useSecAuth && !(GetServerStateParser().GetCapabilityFlag()
|
||||
& (kHasCRAMCapability|kHasAuthNTLMCapability|kHasAuthMSNCapability)))
|
||||
{
|
||||
AlertUserEventUsingId(IMAP_AUTH_SECURE_NOTSUPPORTED);
|
||||
break;
|
||||
|
@ -7193,7 +7237,7 @@ PRBool nsImapProtocol::TryToLogon()
|
|||
break;
|
||||
}
|
||||
|
||||
// Use CRAM only if secure auth is enabled. This is for servers that
|
||||
// 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() & kHasCRAMCapability)
|
||||
|
@ -7201,8 +7245,17 @@ PRBool nsImapProtocol::TryToLogon()
|
|||
AuthLogin (userName, password, kHasCRAMCapability);
|
||||
logonTries++;
|
||||
}
|
||||
else
|
||||
if (GetServerStateParser().GetCapabilityFlag() & kHasAuthPlainCapability)
|
||||
else if (m_useSecAuth && GetServerStateParser().GetCapabilityFlag() & kHasAuthNTLMCapability)
|
||||
{
|
||||
AuthLogin (userName, password, kHasAuthNTLMCapability);
|
||||
logonTries++;
|
||||
}
|
||||
else if (m_useSecAuth && GetServerStateParser().GetCapabilityFlag() & kHasAuthMSNCapability)
|
||||
{
|
||||
AuthLogin (userName, password, kHasAuthMSNCapability);
|
||||
logonTries++;
|
||||
}
|
||||
else if (GetServerStateParser().GetCapabilityFlag() & kHasAuthPlainCapability)
|
||||
{
|
||||
AuthLogin (userName, password, kHasAuthPlainCapability);
|
||||
logonTries++;
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
#include "nsIImapProtocol.h"
|
||||
#include "nsIImapUrl.h"
|
||||
|
||||
#include "nsMsgProtocol.h"
|
||||
#include "nsIEventQueue.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIOutputStream.h"
|
||||
|
@ -149,7 +150,7 @@ public:
|
|||
#define IMAP_CLEAN_UP_URL_STATE 0x00000010 // processing clean up url state
|
||||
#define IMAP_ISSUED_LANGUAGE_REQUEST 0x00000020 // make sure we only issue the language request once per connection...
|
||||
|
||||
class nsImapProtocol : public nsIImapProtocol, public nsIRunnable, public nsIInputStreamCallback
|
||||
class nsImapProtocol : public nsIImapProtocol, public nsIRunnable, public nsIInputStreamCallback, public nsMsgProtocol
|
||||
{
|
||||
public:
|
||||
|
||||
|
@ -158,13 +159,16 @@ public:
|
|||
nsImapProtocol();
|
||||
virtual ~nsImapProtocol();
|
||||
|
||||
virtual nsresult ProcessProtocolState(nsIURI * url, nsIInputStream * inputStream,
|
||||
PRUint32 sourceOffset, PRUint32 length);
|
||||
|
||||
// nsIRunnable method
|
||||
NS_IMETHOD Run();
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
// we support the nsIImapProtocol interface
|
||||
//////////////////////////////////////////////////////////////////////////////////
|
||||
NS_IMETHOD LoadUrl(nsIURI * aURL, nsISupports * aConsumer);
|
||||
NS_IMETHOD LoadImapUrl(nsIURI * aURL, nsISupports * aConsumer);
|
||||
NS_IMETHOD IsBusy(PRBool * aIsConnectionBusy, PRBool *isInboxConnection);
|
||||
NS_IMETHOD CanHandleUrl(nsIImapUrl * aImapUrl, PRBool * aCanRunUrl,
|
||||
PRBool * hasToWait);
|
||||
|
@ -204,11 +208,6 @@ public:
|
|||
// End of nsIStreamListenerSupport
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// Flag manipulators
|
||||
PRBool TestFlag (PRUint32 flag) {return flag & m_flags;}
|
||||
void SetFlag (PRUint32 flag) { m_flags |= flag; }
|
||||
void ClearFlag (PRUint32 flag) { m_flags &= ~flag; }
|
||||
|
||||
// message id string utilities.
|
||||
PRUint32 CountMessagesInIdString(const char *idString);
|
||||
static PRBool HandlingMultipleMessages(const char *messageIdString);
|
||||
|
@ -367,9 +366,7 @@ private:
|
|||
// the following flag is used to determine when a url is currently being run. It is cleared when we
|
||||
// finish processng a url and it is set whenever we call Load on a url
|
||||
PRBool m_urlInProgress;
|
||||
PRBool m_socketIsOpen;
|
||||
PRBool m_gotFEEventCompletion;
|
||||
PRUint32 m_flags; // used to store flag information
|
||||
nsCOMPtr<nsIImapUrl> m_runningUrl; // the nsIImapURL that is currently running
|
||||
nsImapAction m_imapAction; // current imap action associated with this connnection...
|
||||
|
||||
|
@ -385,13 +382,9 @@ private:
|
|||
|
||||
// Ouput stream for writing commands to the socket
|
||||
nsCOMPtr<nsISocketTransport> m_transport;
|
||||
nsCOMPtr<nsIOutputStream> m_outputStream; // this will be obtained from the transport interface
|
||||
nsCOMPtr<nsIInputStream> m_inputStream;
|
||||
|
||||
nsCOMPtr<nsIInputStream> m_channelInputStream;
|
||||
nsCOMPtr<nsIOutputStream> m_channelOutputStream;
|
||||
nsCOMPtr<nsIStreamListener> m_channelListener; // if we are displaying an article this is the rfc-822 display sink...
|
||||
nsCOMPtr<nsISupports> m_channelContext;
|
||||
nsCOMPtr<nsIImapMockChannel> m_mockChannel; // this is the channel we should forward to people
|
||||
//nsCOMPtr<nsIRequest> mAsyncReadRequest; // we're going to cancel this when we're done with the conn.
|
||||
|
||||
|
|
|
@ -91,7 +91,7 @@ nsImapServerResponseParser::nsImapServerResponseParser(nsImapProtocol &imapProto
|
|||
fDownloadingHeaders = PR_FALSE;
|
||||
fGotPermanentFlags = PR_FALSE;
|
||||
fFolderUIDValidity = 0;
|
||||
fCRAMDigest = nsnull;
|
||||
fAuthChallenge = nsnull;
|
||||
fStatusUnseenMessages = 0;
|
||||
fStatusRecentMessages = 0;
|
||||
fStatusNextUID = nsMsgKey_None;
|
||||
|
@ -110,7 +110,7 @@ nsImapServerResponseParser::~nsImapServerResponseParser()
|
|||
PR_Free( fManageListsUrl );
|
||||
PR_Free( fManageFiltersUrl );
|
||||
PR_Free( fSelectedMailboxName );
|
||||
PR_Free(fCRAMDigest);
|
||||
PR_Free(fAuthChallenge);
|
||||
|
||||
NS_IF_RELEASE (fHostSessionList);
|
||||
fCopyResponseKeyArray.RemoveAll();
|
||||
|
@ -189,8 +189,7 @@ void nsImapServerResponseParser::ParseIMAPServerResponse(const char *currentComm
|
|||
{
|
||||
|
||||
NS_ASSERTION(currentCommand && *currentCommand != '\r' &&
|
||||
*currentCommand != '\n' && *currentCommand != ' ',
|
||||
"Invailid command string");
|
||||
*currentCommand != '\n' && *currentCommand != ' ', "Invailid command string");
|
||||
PRBool sendingIdleDone = !strcmp(currentCommand, "DONE"CRLF);
|
||||
if (sendingIdleDone)
|
||||
fWaitingForMoreClientInput = PR_FALSE;
|
||||
|
@ -226,7 +225,7 @@ void nsImapServerResponseParser::ParseIMAPServerResponse(const char *currentComm
|
|||
fCurrentCommandTag = PL_strdup(tagToken);
|
||||
if (!fCurrentCommandTag)
|
||||
HandleMemoryFailure();
|
||||
inIdle = !strcmp(commandToken, "IDLE");
|
||||
inIdle = commandToken && !strcmp(commandToken, "IDLE");
|
||||
}
|
||||
|
||||
if (commandToken && ContinueParse())
|
||||
|
@ -251,10 +250,12 @@ void nsImapServerResponseParser::ParseIMAPServerResponse(const char *currentComm
|
|||
" didn't get the number of tagged responses we expected");
|
||||
numberOfTaggedResponsesReceived = fNumberOfTaggedResponsesExpected;
|
||||
if (commandToken && !nsCRT::strcasecmp(commandToken, "authenticate") && placeInTokenString &&
|
||||
!nsCRT::strncasecmp(placeInTokenString, "CRAM-MD5", strlen("CRAM-MD5")))
|
||||
(!nsCRT::strncasecmp(placeInTokenString, "CRAM-MD5", strlen("CRAM-MD5"))
|
||||
|| !nsCRT::strncasecmp(placeInTokenString, "NTLM", strlen("NTLM"))
|
||||
|| !nsCRT::strncasecmp(placeInTokenString, "MSN", strlen("MSN"))))
|
||||
{
|
||||
// we need to store the digest from the server if we are using CRAM-MD5.
|
||||
cramResponse_data();
|
||||
// we need to store the challenge from the server if we are using CRAM-MD5 or NTLM.
|
||||
authChallengeResponse_data();
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -2131,6 +2132,10 @@ void nsImapServerResponseParser::capability_data()
|
|||
fCapabilityFlag |= kHasAuthPlainCapability;
|
||||
else if (! PL_strcasecmp(fNextToken, "AUTH=CRAM-MD5"))
|
||||
fCapabilityFlag |= kHasCRAMCapability;
|
||||
else if (! PL_strcasecmp(fNextToken, "AUTH=NTLM"))
|
||||
fCapabilityFlag |= kHasAuthNTLMCapability;
|
||||
else if (! PL_strcasecmp(fNextToken, "AUTH=MSN"))
|
||||
fCapabilityFlag |= kHasAuthMSNCapability;
|
||||
else if (! PL_strcasecmp(fNextToken, "X-NETSCAPE"))
|
||||
fCapabilityFlag |= kHasXNetscapeCapability;
|
||||
else if (! PL_strcasecmp(fNextToken, "XSENDER"))
|
||||
|
@ -2248,18 +2253,19 @@ void nsImapServerResponseParser::language_data()
|
|||
} while (fNextToken && !at_end_of_line() && ContinueParse());
|
||||
}
|
||||
|
||||
// cram response data ::= "+" SPACE digest/challenge CRLF
|
||||
// the server expects more client data after issuing it's challenge
|
||||
// cram/auth response data ::= "+" SPACE challenge CRLF
|
||||
// the server expects more client data after issuing its challenge
|
||||
|
||||
void nsImapServerResponseParser::cramResponse_data()
|
||||
void nsImapServerResponseParser::authChallengeResponse_data()
|
||||
{
|
||||
fNextToken = GetNextToken();
|
||||
fCRAMDigest = nsCRT::strdup(fNextToken);
|
||||
fAuthChallenge = nsCRT::strdup(fNextToken);
|
||||
fWaitingForMoreClientInput = PR_TRUE;
|
||||
|
||||
skip_to_CRLF();
|
||||
}
|
||||
|
||||
|
||||
void nsImapServerResponseParser::namespace_data()
|
||||
{
|
||||
EIMAPNamespaceType namespaceType = kPersonalNamespace;
|
||||
|
|
|
@ -152,7 +152,8 @@ public:
|
|||
void UseCachedShell(nsIMAPBodyShell *cachedShell);
|
||||
void SetHostSessionList(nsIImapHostSessionList *aHostSession);
|
||||
nsIImapHostSessionList *GetHostSessionList();
|
||||
char *fCRAMDigest; // the digest returned by the server in response to authenticate using CRAM-MD5...
|
||||
char *fAuthChallenge; // the challenge returned by the server in
|
||||
//response to authenticate using CRAM-MD5 or NTLM
|
||||
|
||||
protected:
|
||||
virtual void flags();
|
||||
|
@ -169,7 +170,7 @@ protected:
|
|||
virtual void text();
|
||||
virtual void parse_folder_flags();
|
||||
virtual void language_data();
|
||||
virtual void cramResponse_data();
|
||||
virtual void authChallengeResponse_data();
|
||||
virtual void resp_text_code();
|
||||
virtual void response_done();
|
||||
virtual void response_tagged();
|
||||
|
|
Загрузка…
Ссылка в новой задаче