зеркало из https://github.com/mozilla/pjs.git
add gssapi auth to imap,pop3, and smtp, patch by simon@sxw.org.uk, 303160, sr=mscott, r=bienvenu
This commit is contained in:
Родитель
0d6859d92d
Коммит
fcc3069434
|
@ -718,6 +718,10 @@ PRInt32 nsSmtpProtocol::SendEhloResponse(nsIInputStream * inputStream, PRUint32
|
|||
|
||||
if(m_prefTrySecAuth)
|
||||
{
|
||||
|
||||
if (responseLine.Find("GSSAPI", PR_TRUE, 5) >= 0)
|
||||
SetFlag(SMTP_AUTH_GSSAPI_ENABLED);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsISignatureVerifier> verifier = do_GetService(SIGNATURE_VERIFIER_CONTRACTID, &rv);
|
||||
// this checks if psm is installed...
|
||||
|
@ -856,7 +860,9 @@ PRInt32 nsSmtpProtocol::ProcessAuth()
|
|||
else
|
||||
if (m_prefAuthMethod == PREF_AUTH_ANY)
|
||||
{
|
||||
if (TestFlag(SMTP_AUTH_CRAM_MD5_ENABLED) ||
|
||||
if (TestFlag(SMTP_AUTH_GSSAPI_ENABLED))
|
||||
m_nextState = SMTP_SEND_AUTH_GSSAPI_FIRST;
|
||||
else if (TestFlag(SMTP_AUTH_CRAM_MD5_ENABLED) ||
|
||||
TestFlag(SMTP_AUTH_NTLM_ENABLED) ||
|
||||
TestFlag(SMTP_AUTH_PLAIN_ENABLED))
|
||||
m_nextState = SMTP_SEND_AUTH_LOGIN_STEP1;
|
||||
|
@ -904,7 +910,9 @@ PRInt32 nsSmtpProtocol::AuthLoginResponse(nsIInputStream * stream, PRUint32 leng
|
|||
{
|
||||
// If one authentication failed, we're going to
|
||||
// fall back on a less secure login method.
|
||||
if(TestFlag(SMTP_AUTH_DIGEST_MD5_ENABLED))
|
||||
if(TestFlag(SMTP_AUTH_GSSAPI_ENABLED))
|
||||
ClearFlag(SMTP_AUTH_GSSAPI_ENABLED);
|
||||
else if(TestFlag(SMTP_AUTH_DIGEST_MD5_ENABLED))
|
||||
// if DIGEST-MD5 enabled, clear it if we failed.
|
||||
ClearFlag(SMTP_AUTH_DIGEST_MD5_ENABLED);
|
||||
else if(TestFlag(SMTP_AUTH_CRAM_MD5_ENABLED))
|
||||
|
@ -946,6 +954,64 @@ PRInt32 nsSmtpProtocol::AuthLoginResponse(nsIInputStream * stream, PRUint32 leng
|
|||
return (status);
|
||||
}
|
||||
|
||||
// GSSAPI may consist of multiple round trips
|
||||
|
||||
PRInt32 nsSmtpProtocol::AuthGSSAPIFirst()
|
||||
{
|
||||
nsCAutoString command("AUTH GSSAPI ");
|
||||
nsCAutoString resp;
|
||||
nsCAutoString service("smtp@");
|
||||
nsXPIDLCString hostName;
|
||||
nsXPIDLCString userName;
|
||||
nsresult rv;
|
||||
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 (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
rv = smtpServer->GetHostname(getter_Copies(hostName));
|
||||
if (NS_FAILED(rv)) return NS_ERROR_FAILURE;
|
||||
|
||||
service.Append(hostName);
|
||||
rv = DoGSSAPIStep1(service.get(), userName, resp);
|
||||
if (NS_FAILED(rv))
|
||||
command.Append("*");
|
||||
else
|
||||
command.Append(resp);
|
||||
command.Append(CRLF);
|
||||
m_nextState = SMTP_RESPONSE;
|
||||
m_nextStateAfterResponse = SMTP_SEND_AUTH_GSSAPI_STEP;
|
||||
SetFlag(SMTP_PAUSE_FOR_READ);
|
||||
nsCOMPtr<nsIURI> url = do_QueryInterface(m_runningURL);
|
||||
return SendData(url, command.get());
|
||||
}
|
||||
|
||||
PRInt32 nsSmtpProtocol::AuthGSSAPIStep()
|
||||
{
|
||||
nsresult rv;
|
||||
nsCAutoString cmd;
|
||||
|
||||
// Check to see what the server said
|
||||
if (m_responseCode / 100 != 3) {
|
||||
m_nextState = SMTP_AUTH_LOGIN_RESPONSE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
rv = DoGSSAPIStep2(m_responseText, cmd);
|
||||
if (NS_FAILED(rv))
|
||||
cmd = "*";
|
||||
cmd += CRLF;
|
||||
|
||||
m_nextStateAfterResponse = (rv == NS_SUCCESS_AUTH_FINISHED)?SMTP_AUTH_LOGIN_RESPONSE:SMTP_SEND_AUTH_GSSAPI_STEP;
|
||||
m_nextState = SMTP_RESPONSE;
|
||||
SetFlag(SMTP_PAUSE_FOR_READ);
|
||||
|
||||
nsCOMPtr<nsIURI> url = do_QueryInterface(m_runningURL);
|
||||
return SendData(url, cmd.get());
|
||||
}
|
||||
|
||||
|
||||
// LOGIN and MSN consist of three steps (MSN not through the mechanism
|
||||
// but by non-RFC2821 compliant implementation in M$ servers) not two as
|
||||
// PLAIN or CRAM-MD5, so we've to start here and continue with AuthStep1
|
||||
|
@ -1543,6 +1609,14 @@ nsresult nsSmtpProtocol::LoadUrl(nsIURI * aURL, nsISupports * aConsumer )
|
|||
status = ProcessAuth();
|
||||
break;
|
||||
|
||||
case SMTP_SEND_AUTH_GSSAPI_FIRST:
|
||||
status = AuthGSSAPIFirst();
|
||||
break;
|
||||
|
||||
case SMTP_SEND_AUTH_GSSAPI_STEP:
|
||||
status = AuthGSSAPIStep();
|
||||
break;
|
||||
|
||||
case SMTP_SEND_AUTH_LOGIN_STEP0:
|
||||
status = AuthLoginStep0();
|
||||
break;
|
||||
|
|
|
@ -76,7 +76,9 @@ SMTP_AUTH_LOGIN_RESPONSE, // 19
|
|||
SMTP_TLS_RESPONSE, // 20
|
||||
SMTP_AUTH_EXTERNAL_RESPONSE, // 21
|
||||
SMTP_AUTH_PROCESS_STATE, // 22
|
||||
SMTP_AUTH_CRAM_MD5_CHALLENGE_RESPONSE // 23
|
||||
SMTP_AUTH_CRAM_MD5_CHALLENGE_RESPONSE, // 23
|
||||
SMTP_SEND_AUTH_GSSAPI_FIRST, // 24
|
||||
SMTP_SEND_AUTH_GSSAPI_STEP // 25
|
||||
} SmtpState;
|
||||
|
||||
// State Flags (Note, I use the word state in terms of storing
|
||||
|
@ -107,8 +109,9 @@ SMTP_AUTH_CRAM_MD5_CHALLENGE_RESPONSE // 23
|
|||
#define SMTP_AUTH_DIGEST_MD5_ENABLED 0x00000800
|
||||
#define SMTP_AUTH_NTLM_ENABLED 0x00001000
|
||||
#define SMTP_AUTH_MSN_ENABLED 0x00002000
|
||||
#define SMTP_AUTH_ANY_ENABLED 0x00003C1C
|
||||
#define SMTP_AUTH_ANY_ENABLED 0x0000BC1C
|
||||
#define SMTP_EHLO_SIZE_ENABLED 0x00004000
|
||||
#define SMTP_AUTH_GSSAPI_ENABLED 0x00008000
|
||||
|
||||
typedef enum _PrefAuthMethod {
|
||||
PREF_AUTH_NONE = 0,
|
||||
|
@ -228,6 +231,8 @@ private:
|
|||
PRInt32 SendHeloResponse(nsIInputStream * inputStream, PRUint32 length);
|
||||
PRInt32 SendEhloResponse(nsIInputStream * inputStream, PRUint32 length);
|
||||
|
||||
PRInt32 AuthGSSAPIFirst();
|
||||
PRInt32 AuthGSSAPIStep();
|
||||
PRInt32 AuthLoginStep0();
|
||||
PRInt32 AuthLoginStep0Response();
|
||||
PRInt32 AuthLoginStep1();
|
||||
|
|
|
@ -138,7 +138,8 @@ typedef enum {
|
|||
kHasAuthNTLMCapability = 0x00100000, /* AUTH NTLM extension */
|
||||
kHasAuthMSNCapability = 0x00200000, /* AUTH MSN extension */
|
||||
kHasStartTLSCapability = 0x00400000, /* STARTTLS support */
|
||||
kLoginDisabled = 0x00800000 /* login disabled */
|
||||
kLoginDisabled = 0x00800000, /* login disabled */
|
||||
kHasAuthGssApiCapability = 0x01000000
|
||||
} eIMAPCapabilityFlag;
|
||||
|
||||
// this used to be part of the connection object class - maybe we should move it into
|
||||
|
|
|
@ -4973,7 +4973,7 @@ void nsImapProtocol::InsecureLogin(const char *userName, const char *password)
|
|||
ParseIMAPandCheckForNewMail();
|
||||
}
|
||||
|
||||
void nsImapProtocol::AuthLogin(const char *userName, const char *password, eIMAPCapabilityFlag flag)
|
||||
nsresult nsImapProtocol::AuthLogin(const char *userName, const char *password, eIMAPCapabilityFlag flag)
|
||||
{
|
||||
ProgressEventFunctionUsingId (IMAP_STATUS_SENDING_AUTH_LOGIN);
|
||||
IncrementCommandTagNumber();
|
||||
|
@ -5018,12 +5018,61 @@ void nsImapProtocol::AuthLogin(const char *userName, const char *password, eIMAP
|
|||
if (NS_SUCCEEDED(rv))
|
||||
ParseIMAPandCheckForNewMail(command.get());
|
||||
if (GetServerStateParser().LastCommandSuccessful())
|
||||
return;
|
||||
return NS_OK;
|
||||
GetServerStateParser().SetCapabilityFlag(GetServerStateParser().GetCapabilityFlag() & ~kHasCRAMCapability);
|
||||
|
||||
}
|
||||
}
|
||||
} // if CRAM response was received
|
||||
else if (flag & kHasAuthGssApiCapability)
|
||||
{
|
||||
// Only try GSSAPI once - if it fails, its going to be because we don't
|
||||
// have valid credentials
|
||||
GetServerStateParser().SetCapabilityFlag(GetServerStateParser().GetCapabilityFlag() & ~(kHasAuthGssApiCapability));
|
||||
|
||||
// We do step1 first, so we don't try GSSAPI against a server which
|
||||
// we can't get credentials for.
|
||||
nsCAutoString response;
|
||||
nsresult gssrv;
|
||||
|
||||
nsCAutoString service("imap@");
|
||||
service.Append(GetImapHostName());
|
||||
gssrv = DoGSSAPIStep1(service.get(), userName, response);
|
||||
NS_ENSURE_SUCCESS(gssrv, gssrv);
|
||||
|
||||
nsCAutoString command (GetServerCommandTag());
|
||||
command.Append(" authenticate GSSAPI" CRLF);
|
||||
rv = SendData(command.get());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
ParseIMAPandCheckForNewMail("AUTH GSSAPI");
|
||||
if (GetServerStateParser().LastCommandSuccessful())
|
||||
{
|
||||
response += CRLF;
|
||||
rv = SendData(response.get());
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
ParseIMAPandCheckForNewMail(command.get());
|
||||
|
||||
while (GetServerStateParser().LastCommandSuccessful() &&
|
||||
NS_SUCCEEDED(gssrv) && gssrv != NS_SUCCESS_AUTH_FINISHED)
|
||||
{
|
||||
nsCString challengeStr(GetServerStateParser().fAuthChallenge);
|
||||
gssrv = DoGSSAPIStep2(challengeStr, response);
|
||||
if (NS_SUCCEEDED(gssrv))
|
||||
{
|
||||
response += CRLF;
|
||||
rv = SendData(response.get());
|
||||
}
|
||||
else
|
||||
rv = SendData("*" CRLF);
|
||||
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
ParseIMAPandCheckForNewMail(command.get());
|
||||
}
|
||||
rv = gssrv;
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
else if (flag & (kHasAuthNTLMCapability|kHasAuthMSNCapability))
|
||||
{
|
||||
nsCAutoString command (GetServerCommandTag());
|
||||
|
@ -5064,7 +5113,7 @@ void nsImapProtocol::AuthLogin(const char *userName, const char *password, eIMAP
|
|||
{
|
||||
PR_snprintf(m_dataOutputBuf, OUTPUT_BUFFER_SIZE, "%s authenticate plain" CRLF, GetServerCommandTag());
|
||||
rv = SendData(m_dataOutputBuf);
|
||||
if (NS_FAILED(rv)) return;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
currentCommand = PL_strdup(m_dataOutputBuf); /* StrAllocCopy(currentCommand, GetOutputBuffer()); */
|
||||
ParseIMAPandCheckForNewMail();
|
||||
if (GetServerStateParser().LastCommandSuccessful())
|
||||
|
@ -5089,7 +5138,7 @@ void nsImapProtocol::AuthLogin(const char *userName, const char *password, eIMAP
|
|||
if (GetServerStateParser().LastCommandSuccessful())
|
||||
{
|
||||
PR_Free(currentCommand);
|
||||
return;
|
||||
return NS_OK;
|
||||
} // if the last command succeeded
|
||||
} // if we got a base 64 encoded string
|
||||
} // if the last command succeeded
|
||||
|
@ -5099,7 +5148,7 @@ void nsImapProtocol::AuthLogin(const char *userName, const char *password, eIMAP
|
|||
{
|
||||
PR_snprintf(m_dataOutputBuf, OUTPUT_BUFFER_SIZE, "%s authenticate login" CRLF, GetServerCommandTag());
|
||||
rv = SendData(m_dataOutputBuf);
|
||||
if (NS_FAILED(rv)) return;
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
currentCommand = PL_strdup(m_dataOutputBuf);
|
||||
ParseIMAPandCheckForNewMail();
|
||||
|
||||
|
@ -5125,7 +5174,7 @@ void nsImapProtocol::AuthLogin(const char *userName, const char *password, eIMAP
|
|||
if (GetServerStateParser().LastCommandSuccessful())
|
||||
{
|
||||
PR_Free(currentCommand);
|
||||
return;
|
||||
return NS_OK;
|
||||
}
|
||||
} // if last command successful
|
||||
} // if last command successful
|
||||
|
@ -5136,6 +5185,7 @@ void nsImapProtocol::AuthLogin(const char *userName, const char *password, eIMAP
|
|||
InsecureLogin(userName, password);
|
||||
|
||||
PR_Free(currentCommand);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void nsImapProtocol::OnLSubFolders()
|
||||
|
@ -7406,6 +7456,7 @@ PRBool nsImapProtocol::TryToLogon()
|
|||
{
|
||||
PRInt32 logonTries = 0;
|
||||
PRBool loginSucceeded = PR_FALSE;
|
||||
PRBool clientSucceeded = PR_TRUE;
|
||||
nsXPIDLCString password;
|
||||
char * userName = nsnull;
|
||||
nsresult rv = NS_OK;
|
||||
|
@ -7450,7 +7501,7 @@ PRBool nsImapProtocol::TryToLogon()
|
|||
// supports it. This avoids fallback to insecure login in case
|
||||
// authentication fails.
|
||||
if(m_useSecAuth && !(GetServerStateParser().GetCapabilityFlag()
|
||||
& (kHasCRAMCapability|kHasAuthNTLMCapability|kHasAuthMSNCapability)))
|
||||
& (kHasCRAMCapability|kHasAuthNTLMCapability|kHasAuthMSNCapability|kHasAuthGssApiCapability)))
|
||||
{
|
||||
AlertUserEventUsingId(IMAP_AUTH_SECURE_NOTSUPPORTED);
|
||||
break;
|
||||
|
@ -7463,7 +7514,8 @@ PRBool nsImapProtocol::TryToLogon()
|
|||
m_hostSessionList->SetCapabilityForHost(GetImapServerKey(), kCapabilityUndefined);
|
||||
break;
|
||||
}
|
||||
if (password.IsEmpty() && m_imapServerSink)
|
||||
if (password.IsEmpty() && m_imapServerSink &&
|
||||
!(m_useSecAuth && GetServerStateParser().GetCapabilityFlag() & kHasAuthGssApiCapability))
|
||||
{
|
||||
if (!aMsgWindow)
|
||||
{
|
||||
|
@ -7475,10 +7527,15 @@ PRBool nsImapProtocol::TryToLogon()
|
|||
break;
|
||||
}
|
||||
|
||||
clientSucceeded = PR_TRUE;
|
||||
// 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)
|
||||
if (m_useSecAuth && GetServerStateParser().GetCapabilityFlag() & kHasAuthGssApiCapability)
|
||||
{
|
||||
clientSucceeded = NS_SUCCEEDED(AuthLogin(userName, password, kHasAuthGssApiCapability));
|
||||
}
|
||||
else if (m_useSecAuth && GetServerStateParser().GetCapabilityFlag() & kHasCRAMCapability)
|
||||
{
|
||||
AuthLogin (userName, password, kHasCRAMCapability);
|
||||
logonTries++;
|
||||
|
@ -7509,14 +7566,15 @@ PRBool nsImapProtocol::TryToLogon()
|
|||
else if (! (GetServerStateParser().GetCapabilityFlag() & kLoginDisabled))
|
||||
InsecureLogin(userName, password);
|
||||
|
||||
if (!GetServerStateParser().LastCommandSuccessful())
|
||||
if (!clientSucceeded || !GetServerStateParser().LastCommandSuccessful())
|
||||
{
|
||||
// login failed!
|
||||
// if we failed because of an interrupt, then do not bother the user
|
||||
if (m_imapServerSink && !DeathSignalReceived())
|
||||
// similarly - if we failed due to a local error, don't bug them
|
||||
if (m_imapServerSink && !DeathSignalReceived() && clientSucceeded)
|
||||
rv = m_imapServerSink->ForgetPassword();
|
||||
|
||||
if (!DeathSignalReceived())
|
||||
if (!DeathSignalReceived() && clientSucceeded)
|
||||
{
|
||||
AlertUserEventUsingId(IMAP_LOGIN_FAILED);
|
||||
m_hostSessionList->SetPasswordForHost(GetImapServerKey(), nsnull);
|
||||
|
|
|
@ -459,7 +459,7 @@ private:
|
|||
void Language(); // set the language on the server if it supports it
|
||||
void Namespace();
|
||||
void InsecureLogin(const char *userName, const char *password);
|
||||
void AuthLogin(const char *userName, const char *password, eIMAPCapabilityFlag flag);
|
||||
nsresult AuthLogin(const char *userName, const char *password, eIMAPCapabilityFlag flag);
|
||||
void ProcessAuthenticatedStateURL();
|
||||
void ProcessAfterAuthenticated();
|
||||
void ProcessSelectedStateURL();
|
||||
|
|
|
@ -254,6 +254,7 @@ void nsImapServerResponseParser::ParseIMAPServerResponse(const char *currentComm
|
|||
if (commandToken && !nsCRT::strcasecmp(commandToken, "authenticate") && placeInTokenString &&
|
||||
(!nsCRT::strncasecmp(placeInTokenString, "CRAM-MD5", strlen("CRAM-MD5"))
|
||||
|| !nsCRT::strncasecmp(placeInTokenString, "NTLM", strlen("NTLM"))
|
||||
|| !nsCRT::strncasecmp(placeInTokenString, "GSSAPI", strlen("GSSAPI"))
|
||||
|| !nsCRT::strncasecmp(placeInTokenString, "MSN", strlen("MSN"))))
|
||||
{
|
||||
// we need to store the challenge from the server if we are using CRAM-MD5 or NTLM.
|
||||
|
@ -2134,6 +2135,8 @@ void nsImapServerResponseParser::capability_data()
|
|||
fCapabilityFlag |= kHasCRAMCapability;
|
||||
else if (! PL_strcasecmp(fNextToken, "AUTH=NTLM"))
|
||||
fCapabilityFlag |= kHasAuthNTLMCapability;
|
||||
else if (! PL_strcasecmp(fNextToken, "AUTH=GSSAPI"))
|
||||
fCapabilityFlag |= kHasAuthGssApiCapability;
|
||||
else if (! PL_strcasecmp(fNextToken, "AUTH=MSN"))
|
||||
fCapabilityFlag |= kHasAuthMSNCapability;
|
||||
else if (! PL_strcasecmp(fNextToken, "STARTTLS"))
|
||||
|
|
|
@ -1203,6 +1203,8 @@ PRInt32 nsPop3Protocol::AuthResponse(nsIInputStream* inputStream,
|
|||
if (NS_SUCCEEDED(rv))
|
||||
SetCapFlag(POP3_HAS_AUTH_NTLM|POP3_HAS_AUTH_MSN);
|
||||
}
|
||||
else if (!PL_strcasecmp (line, "GSSAPI"))
|
||||
SetCapFlag(POP3_HAS_AUTH_GSSAPI);
|
||||
else if (!PL_strcasecmp (line, "PLAIN"))
|
||||
SetCapFlag(POP3_HAS_AUTH_PLAIN);
|
||||
else if (!PL_strcasecmp (line, "LOGIN"))
|
||||
|
@ -1311,6 +1313,9 @@ PRInt32 nsPop3Protocol::CapaResponse(nsIInputStream* inputStream,
|
|||
if (responseLine.Find("LOGIN", PR_TRUE) >= 0)
|
||||
SetCapFlag(POP3_HAS_AUTH_LOGIN);
|
||||
|
||||
if (responseLine.Find("GSSAPI", PR_TRUE) >= 0)
|
||||
SetCapFlag(POP3_HAS_AUTH_GSSAPI);
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsISignatureVerifier> verifier = do_GetService(SIGNATURE_VERIFIER_CONTRACTID, &rv);
|
||||
// this checks if psm is installed...
|
||||
|
@ -1404,7 +1409,9 @@ PRInt32 nsPop3Protocol::ProcessAuth()
|
|||
|
||||
if(m_useSecAuth)
|
||||
{
|
||||
if (TestCapFlag(POP3_HAS_AUTH_CRAM_MD5))
|
||||
if (TestCapFlag(POP3_HAS_AUTH_GSSAPI))
|
||||
m_pop3ConData->next_state = POP3_AUTH_GSSAPI;
|
||||
else if (TestCapFlag(POP3_HAS_AUTH_CRAM_MD5))
|
||||
m_pop3ConData->next_state = POP3_SEND_USERNAME;
|
||||
else
|
||||
if (TestCapFlag(POP3_HAS_AUTH_NTLM))
|
||||
|
@ -1488,7 +1495,9 @@ PRInt32 nsPop3Protocol::AuthFallback()
|
|||
{
|
||||
// If one authentication failed, we're going to
|
||||
// fall back on a less secure login method.
|
||||
if (TestCapFlag(POP3_HAS_AUTH_CRAM_MD5))
|
||||
if (TestCapFlag(POP3_HAS_AUTH_GSSAPI))
|
||||
ClearCapFlag(POP3_HAS_AUTH_GSSAPI);
|
||||
else if (TestCapFlag(POP3_HAS_AUTH_CRAM_MD5))
|
||||
// if CRAM-MD5 enabled, disable it
|
||||
ClearCapFlag(POP3_HAS_AUTH_CRAM_MD5);
|
||||
else if (TestCapFlag(POP3_HAS_AUTH_NTLM))
|
||||
|
@ -1638,6 +1647,70 @@ PRInt32 nsPop3Protocol::AuthNtlmResponse()
|
|||
return 0;
|
||||
}
|
||||
|
||||
PRInt32 nsPop3Protocol::AuthGSSAPI()
|
||||
{
|
||||
nsCOMPtr<nsIMsgIncomingServer> server = do_QueryInterface(m_pop3Server);
|
||||
if (server) {
|
||||
nsCAutoString cmd;
|
||||
nsCAutoString service("pop@");
|
||||
nsXPIDLCString hostName;
|
||||
nsresult rv;
|
||||
|
||||
server->GetRealHostName(getter_Copies(hostName));
|
||||
service.Append(hostName);
|
||||
rv = DoGSSAPIStep1(service.get(), m_username.get(), cmd);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
m_GSSAPICache.Assign(cmd);
|
||||
m_pop3ConData->next_state_after_response = POP3_AUTH_GSSAPI_FIRST;
|
||||
m_pop3ConData->pause_for_read = PR_TRUE;
|
||||
return SendData(m_url, "AUTH GSSAPI" CRLF);
|
||||
}
|
||||
}
|
||||
|
||||
ClearCapFlag(POP3_HAS_AUTH_GSSAPI);
|
||||
m_pop3ConData->next_state = POP3_PROCESS_AUTH;
|
||||
m_pop3ConData->pause_for_read = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
PRInt32 nsPop3Protocol::AuthGSSAPIResponse(PRBool first)
|
||||
{
|
||||
if (!m_pop3ConData->command_succeeded)
|
||||
{
|
||||
if (first)
|
||||
m_GSSAPICache.Truncate();
|
||||
ClearCapFlag(POP3_HAS_AUTH_GSSAPI);
|
||||
m_pop3ConData->next_state = POP3_PROCESS_AUTH;
|
||||
m_pop3ConData->pause_for_read = PR_FALSE;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult rv;
|
||||
|
||||
m_pop3ConData->next_state_after_response = POP3_AUTH_GSSAPI_STEP;
|
||||
m_pop3ConData->pause_for_read = PR_TRUE;
|
||||
|
||||
if (first) {
|
||||
m_GSSAPICache += CRLF;
|
||||
rv = SendData(m_url, m_GSSAPICache.get());
|
||||
m_GSSAPICache.Truncate();
|
||||
}
|
||||
else {
|
||||
nsCAutoString cmd;
|
||||
rv = DoGSSAPIStep2(m_commandResponse, cmd);
|
||||
if (NS_FAILED(rv))
|
||||
cmd = "*";
|
||||
if (rv == NS_SUCCESS_AUTH_FINISHED) {
|
||||
m_pop3ConData->next_state_after_response = POP3_AUTH_FALLBACK;
|
||||
m_password_already_sent = PR_TRUE;
|
||||
}
|
||||
cmd += CRLF;
|
||||
rv = SendData(m_url, cmd.get());
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
PRInt32 nsPop3Protocol::SendUsername()
|
||||
{
|
||||
if(m_username.IsEmpty())
|
||||
|
@ -3622,6 +3695,19 @@ nsresult nsPop3Protocol::ProcessProtocolState(nsIURI * url, nsIInputStream * aIn
|
|||
status = AuthNtlmResponse();
|
||||
break;
|
||||
|
||||
case POP3_AUTH_GSSAPI:
|
||||
status = AuthGSSAPI();
|
||||
break;
|
||||
|
||||
case POP3_AUTH_GSSAPI_FIRST:
|
||||
UpdateStatus(POP3_CONNECT_HOST_CONTACTED_SENDING_LOGIN_INFORMATION);
|
||||
status = AuthGSSAPIResponse(true);
|
||||
break;
|
||||
|
||||
case POP3_AUTH_GSSAPI_STEP:
|
||||
status = AuthGSSAPIResponse(false);
|
||||
break;
|
||||
|
||||
case POP3_SEND_USERNAME:
|
||||
UpdateStatus(POP3_CONNECT_HOST_CONTACTED_SENDING_LOGIN_INFORMATION);
|
||||
status = SendUsername();
|
||||
|
|
|
@ -110,11 +110,12 @@ enum Pop3CapabilityEnum {
|
|||
POP3_HAS_AUTH_MSN = 0x00010000,
|
||||
POP3_HAS_RESP_CODES = 0x00020000,
|
||||
POP3_HAS_AUTH_RESP_CODE = 0x00040000,
|
||||
POP3_HAS_STLS = 0x00080000
|
||||
POP3_HAS_STLS = 0x00080000,
|
||||
POP3_HAS_AUTH_GSSAPI = 0x00100000
|
||||
};
|
||||
|
||||
#define POP3_HAS_AUTH_ANY 0x00001C00
|
||||
#define POP3_HAS_AUTH_ANY_SEC 0x0001E000
|
||||
#define POP3_HAS_AUTH_ANY_SEC 0x0011E000
|
||||
|
||||
enum Pop3StatesEnum {
|
||||
POP3_READ_PASSWORD, // 0
|
||||
|
@ -171,7 +172,11 @@ enum Pop3StatesEnum {
|
|||
POP3_GURL_RESPONSE, // 42
|
||||
POP3_QUIT_RESPONSE, // 43
|
||||
POP3_INTERRUPTED, // 44
|
||||
POP3_TLS_RESPONSE // 45
|
||||
POP3_TLS_RESPONSE, // 45
|
||||
|
||||
POP3_AUTH_GSSAPI, // 46
|
||||
POP3_AUTH_GSSAPI_FIRST, // 47
|
||||
POP3_AUTH_GSSAPI_STEP // 48
|
||||
};
|
||||
|
||||
|
||||
|
@ -319,6 +324,7 @@ private:
|
|||
nsCString m_senderInfo;
|
||||
nsCString m_commandResponse;
|
||||
nsCOMPtr<nsIMsgStatusFeedback> m_statusFeedback;
|
||||
nsCString m_GSSAPICache;
|
||||
|
||||
// progress state information
|
||||
void UpdateProgressPercent (PRUint32 totalDone, PRUint32 total);
|
||||
|
@ -383,6 +389,8 @@ private:
|
|||
PRInt32 AuthLoginResponse();
|
||||
PRInt32 AuthNtlm();
|
||||
PRInt32 AuthNtlmResponse();
|
||||
PRInt32 AuthGSSAPI();
|
||||
PRInt32 AuthGSSAPIResponse(PRBool first);
|
||||
PRInt32 SendUsername();
|
||||
PRInt32 SendPassword();
|
||||
PRInt32 SendStatOrGurl(PRBool sendStat);
|
||||
|
|
Загрузка…
Ссылка в новой задаче