fixed bug 18293 - My ISP complains about not receiving a HELO command first; r=bienvenu

This commit is contained in:
jefft%netscape.com 2000-06-22 13:56:07 +00:00
Родитель 70d6c978e4
Коммит ca0f8937e3
6 изменённых файлов: 140 добавлений и 13 удалений

Просмотреть файл

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