зеркало из https://github.com/mozilla/gecko-dev.git
fixed bug 18293 - My ISP complains about not receiving a HELO command first; r=bienvenu
This commit is contained in:
Родитель
70d6c978e4
Коммит
ca0f8937e3
|
@ -62,9 +62,9 @@ public:
|
|||
virtual nsresult SetUrl(nsIURI * aURL); // sometimes we want to set the url before we load it
|
||||
|
||||
// Flag manipulators
|
||||
PRBool TestFlag (PRUint32 flag) {return flag & m_flags;}
|
||||
void SetFlag (PRUint32 flag) { m_flags |= flag; }
|
||||
void ClearFlag (PRUint32 flag) { m_flags &= ~flag; }
|
||||
virtual PRBool TestFlag (PRUint32 flag) {return flag & m_flags;}
|
||||
virtual void SetFlag (PRUint32 flag) { m_flags |= flag; }
|
||||
virtual void ClearFlag (PRUint32 flag) { m_flags &= ~flag; }
|
||||
|
||||
protected:
|
||||
// methods for opening and closing a socket with core netlib....
|
||||
|
|
|
@ -24,6 +24,18 @@ interface nsIPrompt;
|
|||
|
||||
[scriptable, uuid(6a0b35ce-54e4-11d3-81df-006008948010)]
|
||||
interface nsISmtpServer : nsISupports {
|
||||
|
||||
const unsigned long cap_undefined = 0x80000000;
|
||||
|
||||
const unsigned long cap_smtp_server = 0x10000000;
|
||||
const unsigned long cap_esmtp_server = 0x20000000;
|
||||
|
||||
const unsigned long cap_dsn = 0x00000002;
|
||||
const unsigned long cap_auth_login = 0x00000004;
|
||||
const unsigned long cap_auth_plain = 0x00000008;
|
||||
const unsigned long cap_auth_external = 0x00000010;
|
||||
const unsigned long cap_auth_starttls = 0x00000020;
|
||||
|
||||
attribute string key; // unique identifier
|
||||
|
||||
attribute string hostname;
|
||||
|
@ -33,6 +45,8 @@ interface nsISmtpServer : nsISupports {
|
|||
/* what kind of logon redirector to use for this server, if any */
|
||||
attribute string redirectorType;
|
||||
|
||||
attribute unsigned long capability;
|
||||
|
||||
attribute long authMethod;
|
||||
attribute long trySSL;
|
||||
|
||||
|
|
|
@ -270,8 +270,10 @@ void nsSmtpProtocol::Initialize(nsIURI * aURL)
|
|||
NS_PRECONDITION(aURL, "invalid URL passed into Smtp Protocol");
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
m_flags = 0;
|
||||
m_flags = nsISmtpServer::cap_undefined;
|
||||
m_prefAuthMethod = PREF_AUTH_NONE;
|
||||
m_port = SMTP_PORT;
|
||||
m_tlsInitiated = PR_FALSE;
|
||||
|
||||
m_urlErrorState = NS_ERROR_FAILURE;
|
||||
|
||||
|
@ -311,9 +313,10 @@ void nsSmtpProtocol::Initialize(nsIURI * aURL)
|
|||
nsCOMPtr<nsISmtpServer> smtpServer;
|
||||
m_runningURL->GetSmtpServer(getter_AddRefs(smtpServer));
|
||||
if (smtpServer)
|
||||
{
|
||||
smtpServer->GetAuthMethod(&m_prefAuthMethod);
|
||||
else
|
||||
m_prefAuthMethod = PREF_AUTH_NONE;
|
||||
smtpServer->GetCapability(&m_flags);
|
||||
}
|
||||
|
||||
rv = RequestOverrideInfo(smtpServer);
|
||||
// if we aren't waiting for a login override, then go ahead an
|
||||
|
@ -504,6 +507,32 @@ PRInt32 nsSmtpProtocol::SmtpResponse(nsIInputStream * inputStream, PRUint32 leng
|
|||
m_responseText += line+4;
|
||||
}
|
||||
|
||||
if (m_responseCode == 220)
|
||||
{ // fisrt time we connect to the server; check for the greeting if it is a
|
||||
// ESMTP server set capability accordingly
|
||||
if (m_responseText && nsCRT::strlen(m_responseText))
|
||||
{
|
||||
if (TestFlag(nsISmtpServer::cap_undefined) && m_runningURL)
|
||||
{
|
||||
nsCOMPtr<nsISmtpServer> smtpServer;
|
||||
m_runningURL->GetSmtpServer(getter_AddRefs(smtpServer));
|
||||
if (smtpServer)
|
||||
{
|
||||
if (m_responseText.Find("ESMTP", PR_TRUE) != -1)
|
||||
{
|
||||
smtpServer->SetCapability(nsISmtpServer::cap_esmtp_server);
|
||||
m_nextStateAfterResponse = SMTP_EXTN_LOGIN_RESPONSE;
|
||||
}
|
||||
else
|
||||
{
|
||||
smtpServer->SetCapability(nsISmtpServer::cap_smtp_server);
|
||||
m_nextStateAfterResponse = SMTP_LOGIN_RESPONSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(m_continuationResponse == -1) /* all done with this response? */
|
||||
{
|
||||
m_nextState = m_nextStateAfterResponse;
|
||||
|
@ -714,6 +743,15 @@ PRInt32 nsSmtpProtocol::SendEhloResponse(nsIInputStream * inputStream, PRUint32
|
|||
if (PL_strcasestr(m_responseText, "EXTERNAL") != 0)
|
||||
SetFlag(SMTP_AUTH_EXTERNAL_ENABLED);
|
||||
}
|
||||
m_nextState = SMTP_AUTH_PROCESS_STATE;
|
||||
return status;
|
||||
}
|
||||
|
||||
PRInt32 nsSmtpProtocol::ProcessAuth()
|
||||
{
|
||||
PRInt32 status = 0;
|
||||
nsCAutoString buffer;
|
||||
nsCOMPtr<nsIURI> url = do_QueryInterface(m_runningURL);
|
||||
|
||||
if (!m_tlsEnabled)
|
||||
{
|
||||
|
@ -728,7 +766,9 @@ PRInt32 nsSmtpProtocol::SendEhloResponse(nsIInputStream * inputStream, PRUint32
|
|||
|
||||
status = SendData(url, buffer);
|
||||
|
||||
m_flags = 0; // resetting the flags
|
||||
m_flags = nsISmtpServer::cap_esmtp_server; // resetting the flags
|
||||
m_tlsInitiated = PR_TRUE;
|
||||
|
||||
m_nextState = SMTP_RESPONSE;
|
||||
m_nextStateAfterResponse = SMTP_TLS_RESPONSE;
|
||||
SetFlag(SMTP_PAUSE_FOR_READ);
|
||||
|
@ -1265,7 +1305,12 @@ nsresult nsSmtpProtocol::LoadUrl(nsIURI * aURL, nsISupports * aConsumer )
|
|||
char *addrs1 = 0;
|
||||
char *addrs2 = 0;
|
||||
m_nextState = SMTP_RESPONSE;
|
||||
m_nextStateAfterResponse = SMTP_EXTN_LOGIN_RESPONSE;
|
||||
if (TestFlag(nsISmtpServer::cap_undefined))
|
||||
m_nextStateAfterResponse = SMTP_EXTN_LOGIN_RESPONSE;
|
||||
else if (TestFlag(nsISmtpServer::cap_esmtp_server))
|
||||
m_nextStateAfterResponse = SMTP_AUTH_PROCESS_STATE;
|
||||
else
|
||||
m_nextStateAfterResponse = SMTP_SEND_HELO_RESPONSE;
|
||||
|
||||
/* Remove duplicates from the list, to prevent people from getting
|
||||
more than one copy (the SMTP host may do this too, or it may not.)
|
||||
|
@ -1340,7 +1385,12 @@ nsresult nsSmtpProtocol::ProcessProtocolState(nsIURI * url, nsIInputStream * inp
|
|||
case SMTP_START_CONNECT:
|
||||
SetFlag(SMTP_PAUSE_FOR_READ);
|
||||
m_nextState = SMTP_RESPONSE;
|
||||
m_nextStateAfterResponse = SMTP_EXTN_LOGIN_RESPONSE;
|
||||
if (TestFlag(nsISmtpServer::cap_undefined))
|
||||
m_nextStateAfterResponse = SMTP_EXTN_LOGIN_RESPONSE;
|
||||
else if (TestFlag(nsISmtpServer::cap_esmtp_server))
|
||||
m_nextStateAfterResponse = SMTP_AUTH_PROCESS_STATE;
|
||||
else
|
||||
m_nextStateAfterResponse = SMTP_SEND_HELO_RESPONSE;
|
||||
break;
|
||||
case SMTP_FINISH_CONNECT:
|
||||
SetFlag(SMTP_PAUSE_FOR_READ);
|
||||
|
@ -1370,7 +1420,9 @@ nsresult nsSmtpProtocol::ProcessProtocolState(nsIURI * url, nsIInputStream * inp
|
|||
else
|
||||
status = SendEhloResponse(inputStream, length);
|
||||
break;
|
||||
|
||||
case SMTP_AUTH_PROCESS_STATE:
|
||||
status = ProcessAuth();
|
||||
break;
|
||||
case SMTP_AUTH_LOGIN_RESPONSE:
|
||||
if (inputStream == nsnull)
|
||||
SetFlag(SMTP_PAUSE_FOR_READ);
|
||||
|
@ -1682,4 +1734,37 @@ NS_IMETHODIMP nsSmtpProtocol::OnLogonRedirectionReply(const PRUnichar * aHost, u
|
|||
return rv;
|
||||
}
|
||||
|
||||
static PRUint32 capFlags = (nsISmtpServer::cap_auth_login |
|
||||
nsISmtpServer::cap_dsn |
|
||||
nsISmtpServer::cap_auth_plain |
|
||||
nsISmtpServer::cap_auth_external |
|
||||
nsISmtpServer::cap_auth_starttls);
|
||||
|
||||
void
|
||||
nsSmtpProtocol::SetFlag(PRUint32 flag)
|
||||
{
|
||||
nsMsgProtocol::SetFlag(flag);
|
||||
if (!m_tlsInitiated && flag & capFlags)
|
||||
{
|
||||
nsCOMPtr<nsISmtpServer> smtpServer;
|
||||
m_runningURL->GetSmtpServer(getter_AddRefs(smtpServer));
|
||||
if (! smtpServer) return;
|
||||
smtpServer->SetCapability(nsISmtpServer::cap_esmtp_server |
|
||||
(m_flags & capFlags));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nsSmtpProtocol::ClearFlag(PRUint32 flag)
|
||||
{
|
||||
nsMsgProtocol::ClearFlag(flag);
|
||||
if (!m_tlsInitiated && flag & capFlags)
|
||||
{
|
||||
nsCOMPtr<nsISmtpServer> smtpServer;
|
||||
m_runningURL->GetSmtpServer(getter_AddRefs(smtpServer));
|
||||
if (! smtpServer) return;
|
||||
smtpServer->SetCapability((m_flags & capFlags) |
|
||||
nsISmtpServer::cap_esmtp_server);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -56,18 +56,24 @@ SMTP_SEND_AUTH_LOGIN_USERNAME, // 16
|
|||
SMTP_SEND_AUTH_LOGIN_PASSWORD, // 17
|
||||
SMTP_AUTH_LOGIN_RESPONSE, // 18
|
||||
SMTP_TLS_RESPONSE, // 19
|
||||
SMTP_AUTH_EXTERNAL_RESPONSE // 20
|
||||
SMTP_AUTH_EXTERNAL_RESPONSE, // 20
|
||||
SMTP_AUTH_PROCESS_STATE // 21
|
||||
} SmtpState;
|
||||
|
||||
// State Flags (Note, I use the word state in terms of storing
|
||||
// state information about the connection (authentication, have we sent
|
||||
// commands, etc. I do not intend it to refer to protocol state)
|
||||
#define SMTP_PAUSE_FOR_READ 0x00000001 /* should we pause for the next read */
|
||||
#define SMTP_PAUSE_FOR_READ 0x00000001 /* should we pause for the
|
||||
/* next read */
|
||||
// *** don't change the following value; they are in sync with the capability
|
||||
// *** flags defined in nsISmtpServer.idl
|
||||
|
||||
#define SMTP_EHLO_DSN_ENABLED 0x00000002
|
||||
#define SMTP_AUTH_LOGIN_ENABLED 0x00000004
|
||||
#define SMTP_AUTH_PLAIN_ENABLED 0x00000008
|
||||
#define SMTP_AUTH_EXTERNAL_ENABLED 0x00000010
|
||||
#define SMTP_EHLO_STARTTLS_ENABLED 0x00000020
|
||||
|
||||
// if we are using a login redirection
|
||||
// and we are waiting for it to give us the
|
||||
// host and port to connect to, then this flag
|
||||
|
@ -110,6 +116,9 @@ public:
|
|||
virtual nsresult LoadUrl(nsIURI * aURL, nsISupports * aConsumer = nsnull);
|
||||
virtual PRInt32 SendData(nsIURI * aURL, const char * dataBuffer);
|
||||
|
||||
virtual void SetFlag (PRUint32 flag);
|
||||
virtual void ClearFlag (PRUint32 flag);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// we suppport the nsIStreamListener interface
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -157,6 +166,8 @@ private:
|
|||
// multiple smtp servers
|
||||
PRInt32 m_prefAuthMethod;
|
||||
PRBool m_tlsEnabled;
|
||||
|
||||
PRBool m_tlsInitiated;
|
||||
|
||||
// message specific information
|
||||
PRInt32 m_totalAmountWritten;
|
||||
|
@ -205,7 +216,7 @@ private:
|
|||
PRInt32 SendPostData();
|
||||
PRInt32 SendMessageResponse();
|
||||
|
||||
PRInt32 CheckAuthResponse();
|
||||
PRInt32 ProcessAuth();
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -41,6 +41,7 @@ NS_INTERFACE_MAP_END
|
|||
nsSmtpServer::nsSmtpServer()
|
||||
{
|
||||
NS_INIT_REFCNT();
|
||||
m_capability = nsISmtpServer::cap_undefined;
|
||||
}
|
||||
|
||||
nsSmtpServer::~nsSmtpServer()
|
||||
|
@ -324,3 +325,18 @@ nsSmtpServer::GetRedirectorType(char **aResult)
|
|||
if (NS_FAILED(rv)) *aResult=nsnull;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSmtpServer::SetCapability(PRUint32 capability)
|
||||
{
|
||||
m_capability = capability;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsSmtpServer::GetCapability(PRUint32 *capability)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(capability);
|
||||
*capability = m_capability;
|
||||
return NS_OK;
|
||||
}
|
||||
|
|
|
@ -43,6 +43,7 @@ private:
|
|||
|
||||
nsresult getPrefString(const char *pref, nsCAutoString& result);
|
||||
nsCString m_password;
|
||||
PRUint32 m_capability;
|
||||
};
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче