summaryrefslogtreecommitdiff
path: root/mailnews
diff options
context:
space:
mode:
authorGaming4JC <g4jc@hyperbola.info>2019-12-30 09:24:51 -0500
committerGaming4JC <g4jc@hyperbola.info>2019-12-30 20:29:25 -0500
commita4ab8fd190102e4773ec3399b5281e8eeef04eae (patch)
tree25a0e01562e2a85295214e49a19a043034ec58f6 /mailnews
parent0395a076c826ffed7f9a83f8b8f5d49730f773ba (diff)
downloaduxp-a4ab8fd190102e4773ec3399b5281e8eeef04eae.tar.gz
Bug 1453643 - Enable proper retry on oauth2 authenication failure.
This prevents mail applications from attempting to use an unauthenticated connection to mailbox(s) and avoid unexpected deletion of local mbox files and subsequent re-download of mailbox content over imap.
Diffstat (limited to 'mailnews')
-rw-r--r--mailnews/imap/src/nsImapProtocol.cpp59
-rw-r--r--mailnews/imap/src/nsImapProtocol.h1
2 files changed, 34 insertions, 26 deletions
diff --git a/mailnews/imap/src/nsImapProtocol.cpp b/mailnews/imap/src/nsImapProtocol.cpp
index c8e3ceb67f..940d87cbd1 100644
--- a/mailnews/imap/src/nsImapProtocol.cpp
+++ b/mailnews/imap/src/nsImapProtocol.cpp
@@ -5714,6 +5714,36 @@ void nsImapProtocol::ResetAuthMethods()
m_failedAuthMethods = 0;
}
+nsresult nsImapProtocol::SendDataParseIMAPandCheckForNewMail(const char *aData, const char *aCommand)
+{
+ nsresult rv;
+ bool isResend = false;
+ while (true)
+ {
+ // Send authentication string (true: suppress logging the string).
+ rv = SendData(aData, true);
+ if (NS_FAILED(rv))
+ break;
+ ParseIMAPandCheckForNewMail(aCommand);
+ if (!GetServerStateParser().WaitingForMoreClientInput())
+ break;
+
+ // The server is asking for the authentication string again. So we send
+ // the same string again although we know that it might be rejected again.
+ // We do that to get a firm authentication failure instead of a resend
+ // request. That keeps things in order before failing authentication and
+ // trying another method if capable.
+ if (isResend)
+ {
+ rv = NS_ERROR_FAILURE;
+ break;
+ }
+ isResend = true;
+ }
+
+ return rv;
+}
+
nsresult nsImapProtocol::AuthLogin(const char *userName, const nsCString &password, eIMAPCapabilityFlag flag)
{
ProgressEventFunctionUsingName("imapStatusSendingAuthLogin");
@@ -5880,29 +5910,7 @@ nsresult nsImapProtocol::AuthLogin(const char *userName, const nsCString &passwo
PR_snprintf(m_dataOutputBuf, OUTPUT_BUFFER_SIZE, "%s" CRLF, base64Str);
PR_Free(base64Str);
- bool isResend = false;
- while (true)
- {
- // Send authentication string (true: suppress logging the string).
- rv = SendData(m_dataOutputBuf, true);
- if (NS_FAILED(rv))
- break;
- ParseIMAPandCheckForNewMail(currentCommand);
- if (!GetServerStateParser().WaitingForMoreClientInput())
- break;
-
- // Server is asking for authentication string again. So we send the
- // same string again although we already know that it will be
- // rejected again. We do that to get a firm authentication failure
- // instead of a resend request. That keeps things in order before
- // failing "authenticate PLAIN" and trying another method if capable.
- if (isResend)
- {
- rv = NS_ERROR_FAILURE;
- break;
- }
- isResend = true;
- }
+ rv = SendDataParseIMAPandCheckForNewMail(m_dataOutputBuf, currentCommand);
} // if the last command succeeded
} // if auth plain capability
else if (flag & kHasAuthLoginCapability)
@@ -5953,9 +5961,8 @@ nsresult nsImapProtocol::AuthLogin(const char *userName, const nsCString &passwo
EscapeUserNamePasswordString(password.get(), &correctedPassword);
command.Append(correctedPassword);
command.Append("\"" CRLF);
- rv = SendData(command.get(), true /* suppress logging */);
- NS_ENSURE_SUCCESS(rv, rv);
- ParseIMAPandCheckForNewMail();
+
+ rv = SendDataParseIMAPandCheckForNewMail(command.get(), nullptr);
}
#ifdef MOZ_MAILNEWS_OAUTH2
else if (flag & kHasXOAuth2Capability)
diff --git a/mailnews/imap/src/nsImapProtocol.h b/mailnews/imap/src/nsImapProtocol.h
index ba2594c894..8cee4f4fb6 100644
--- a/mailnews/imap/src/nsImapProtocol.h
+++ b/mailnews/imap/src/nsImapProtocol.h
@@ -485,6 +485,7 @@ private:
void Namespace();
void InsecureLogin(const char *userName, const nsCString &password);
nsresult AuthLogin(const char *userName, const nsCString &password, eIMAPCapabilityFlag flag);
+ nsresult SendDataParseIMAPandCheckForNewMail(const char *data, const char *command);
void ProcessAuthenticatedStateURL();
void ProcessAfterAuthenticated();
void ProcessSelectedStateURL();