support for APOP, patch by ch.ey@gmx.net, r=bienvenu, sr=mscott 43923

This commit is contained in:
bienvenu%nventure.com 2003-07-20 15:45:31 +00:00
parent af7a2da1c4
commit 5800175d8c
4 changed files with 82 additions and 8 deletions

View File

@ -197,9 +197,10 @@
## @loc None
4030=Mail server does not support secure authentication.
## @name MOVEMAIL_SPOOL_FILE_NOT_FOUND
## @loc None
4031=Unable to locate mail spool file.
+# secure authentication failed and unsure why
+## @name CANNOT_PROCESS_APOP_AUTH
+## @loc None
+4031=Mail server does not support secure authentication or you have entered an incorrect password. Please check your password, or turn off secure authentication in the account settings for your mail server.
## @name MOVEMAIL_SPOOL_FILE_LOCKED
## @loc None
@ -220,3 +221,8 @@
## @name MOVEMAIL_CANT_TRUNCATE_SPOOL_FILE
## @loc None
4036=Unable to truncate spool file %S.
## @name MOVEMAIL_SPOOL_FILE_NOT_FOUND
## @loc None
4037=Unable to locate mail spool file.

View File

@ -87,11 +87,12 @@ private:
#define MOVING_MSGS_STATUS 4028
#define POP3_MESSAGE_FOLDER_BUSY 4029
#define CANNOT_PROCESS_SECURE_AUTH 4030
#define MOVEMAIL_SPOOL_FILE_NOT_FOUND 4031
#define CANNOT_PROCESS_APOP_AUTH 4031
#define MOVEMAIL_SPOOL_FILE_LOCKED 4032
#define MOVEMAIL_CANT_OPEN_SPOOL_FILE 4033
#define MOVEMAIL_CANT_CREATE_LOCK 4034
#define MOVEMAIL_CANT_DELETE_LOCK 4035
#define MOVEMAIL_CANT_TRUNCATE_SPOOL_FILE 4036
#define MOVEMAIL_SPOOL_FILE_NOT_FOUND 4037
#endif /* _nsLocalStringBundle_H__ */

View File

@ -800,6 +800,30 @@ nsPop3Protocol::WaitForStartOfConnectionResponse(nsIInputStream* aInputStream,
else
m_commandResponse = line;
if (m_useSecAuth)
{
PRInt32 endMark = m_commandResponse.FindChar('>');
PRInt32 startMark = m_commandResponse.FindChar('<');
PRInt32 at = m_commandResponse.FindChar('@');
if (!(endMark == -1 || startMark == -1 || at == -1 ||
endMark < startMark || at > endMark || at < startMark))
{
nsresult rv;
nsCOMPtr<nsISignatureVerifier> verifier = do_GetService(SIGNATURE_VERIFIER_CONTRACTID, &rv);
// this checks if psm is installed...
if (NS_SUCCEEDED(rv))
{
m_ApopTimestamp = Substring(m_commandResponse, startMark, endMark - startMark + 1);
SetCapFlag(POP3_HAS_AUTH_APOP);
}
}
}
else
ClearCapFlag(POP3_HAS_AUTH_APOP);
m_pop3Server->SetPop3CapabilityFlags(m_pop3ConData->capability_flags);
m_pop3ConData->next_state = POP3_PROCESS_AUTH;
m_pop3ConData->pause_for_read = PR_FALSE; /* don't pause */
}
@ -1027,6 +1051,9 @@ PRInt32 nsPop3Protocol::ProcessAuth()
if (TestCapFlag(POP3_HAS_AUTH_CRAM_MD5))
m_pop3ConData->next_state = POP3_SEND_USERNAME;
else
if (TestCapFlag(POP3_HAS_AUTH_APOP))
m_pop3ConData->next_state = POP3_SEND_PASSWORD;
else
return(Error(CANNOT_PROCESS_SECURE_AUTH));
}
else
@ -1060,12 +1087,16 @@ 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 CRAM-MD5 enabled, remove it
// if CRAM-MD5 enabled, disable it
ClearCapFlag(POP3_HAS_AUTH_CRAM_MD5);
else
if (TestCapFlag(POP3_HAS_AUTH_APOP))
// if APOP enabled, disable it
ClearCapFlag(POP3_HAS_AUTH_APOP);
else
if(TestCapFlag(POP3_HAS_AUTH_LOGIN | POP3_HAS_AUTH_USER))
// if LOGIN or USER enabled,
// it was the username which was wrong
// it was the username which was wrong -
// no fallback but return error
return(Error(POP3_USERNAME_FAILURE));
@ -1157,6 +1188,9 @@ PRInt32 nsPop3Protocol::SendUsername()
PRInt32 nsPop3Protocol::SendPassword()
{
if (m_username.IsEmpty())
return(Error(POP3_USERNAME_UNDEFINED));
nsXPIDLCString password;
PRBool okayValue = PR_TRUE;
nsresult rv = GetPassword(getter_Copies(password), &okayValue);
@ -1207,6 +1241,32 @@ PRInt32 nsPop3Protocol::SendPassword()
if (NS_FAILED(rv))
ClearFlag(POP3_HAS_AUTH_CRAM_MD5);
}
else
if (TestCapFlag(POP3_HAS_AUTH_APOP))
{
char buffer[512];
unsigned char digest[DIGEST_LENGTH];
rv = MSGApopMD5(m_ApopTimestamp.get(), m_ApopTimestamp.Length(), password.get(), password.Length(), digest);
if (NS_SUCCEEDED(rv) && digest)
{
nsCAutoString encodedDigest;
char hexVal[8];
for (PRUint32 j=0; j<16; j++)
{
PR_snprintf (hexVal,8, "%.2x", 0x0ff & (unsigned short)digest[j]);
encodedDigest.Append(hexVal);
}
PR_snprintf(buffer, sizeof(buffer), "APOP %s %s", m_username.get(), encodedDigest.get());
cmd = buffer;
}
if (NS_FAILED(rv))
ClearFlag(POP3_HAS_AUTH_APOP);
}
}
else
{
@ -1245,6 +1305,12 @@ PRInt32 nsPop3Protocol::SendStatOrGurl(PRBool sendStat)
if(TestFlag(POP3_STOPLOGIN))
return(Error(POP3_PASSWORD_FAILURE));
if(!TestCapFlag(POP3_HAS_AUTH_CRAM_MD5) &&
TestCapFlag(POP3_HAS_AUTH_APOP))
// unsure because APOP failed and we can't determine why
Error(CANNOT_PROCESS_APOP_AUTH);
else
Error(POP3_PASSWORD_FAILURE);
/* The password failed.
Sever the connection and go back to the `read password' state,
@ -1254,7 +1320,6 @@ PRInt32 nsPop3Protocol::SendStatOrGurl(PRBool sendStat)
But if we're just checking for new mail (biff) then don't bother
prompting the user for a password: just fail silently. */
Error(POP3_PASSWORD_FAILURE);
SetFlag(POP3_PASSWORD_FAILED);

View File

@ -101,7 +101,8 @@ enum Pop3CapabilityEnum {
POP3_TOP_UNDEFINED = 0x00000400,
POP3_HAS_TOP = 0x00000800,
POP3_HAS_AUTH_USER = 0x00001000,
POP3_HAS_AUTH_CRAM_MD5 = 0x00002000
POP3_HAS_AUTH_CRAM_MD5 = 0x00002000,
POP3_HAS_AUTH_APOP = 0x00004000
};
enum Pop3StatesEnum {
@ -281,6 +282,7 @@ public:
virtual PRInt32 HandleLine(char *line, PRUint32 line_length);
private:
nsCString m_ApopTimestamp;
nsCOMPtr<nsIMsgStringService> mStringService;
nsCString m_username;