add support for IMAP AUTH=NTLM, MSN, sr=mscott 200436

This commit is contained in:
bienvenu%nventure.com 2004-04-13 17:35:52 +00:00
parent 03f96fc967
commit f43477c8f3
10 changed files with 181 additions and 115 deletions

View File

@ -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

View File

@ -44,6 +44,7 @@ REQUIRES = xpcom \
uconv \
unicharutil \
mime \
caps \
pref \
intl \
nkcache \

View File

@ -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

View File

@ -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;
}

View File

@ -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.

View File

@ -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);

View File

@ -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++;

View File

@ -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.

View File

@ -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;

View File

@ -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();