Bug #68877 --> use the IP address of the host for the smtp connection as the domain name for HELO/EHLO instead

of just using the domain name of the sender.

Patch by Christian Eyrich
r=darin
sr=mscott
This commit is contained in:
scott%scott-macgregor.org 2004-04-29 23:07:05 +00:00
Родитель b1966faa9d
Коммит f7f37b70ef
5 изменённых файлов: 73 добавлений и 28 удалений

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

@ -65,6 +65,7 @@
#include "prprf.h" #include "prprf.h"
#include "prmem.h" #include "prmem.h"
#include "plbase64.h" #include "plbase64.h"
#include "prnetdb.h"
#include "nsEscape.h" #include "nsEscape.h"
#include "nsMsgUtils.h" #include "nsMsgUtils.h"
#include "nsIPipe.h" #include "nsIPipe.h"
@ -347,28 +348,34 @@ void nsSmtpProtocol::Initialize(nsIURI * aURL)
return; return;
} }
const char * nsSmtpProtocol::GetUserDomainName() void nsSmtpProtocol::GetUserDomainName(nsACString& aResult)
{ {
nsresult rv; nsresult rv;
NS_PRECONDITION(m_runningURL, "we must be running a url in order to get the user's domain...");
if (m_runningURL) PRNetAddr iaddr; // IP address for this connection
// our transport is always a nsISocketTransport
nsCOMPtr<nsISocketTransport> socketTransport = do_QueryInterface(m_transport);
// should return the interface ip of the SMTP connection
// minimum case - see bug 68877 and RFC 2821, chapter 4.1.1.1
rv = socketTransport->GetSelfAddr(&iaddr);
if (NS_SUCCEEDED(rv))
{ {
nsCOMPtr <nsIMsgIdentity> senderIdentity; // turn it into a string
rv = m_runningURL->GetSenderIdentity(getter_AddRefs(senderIdentity)); char ipAddressString[64];
if (NS_FAILED(rv) || !senderIdentity) if (PR_NetAddrToString(&iaddr, ipAddressString, sizeof(ipAddressString)) == PR_SUCCESS)
return nsnull; {
NS_ASSERTION(PR_IsNetAddrType(&iaddr, PR_IpAddrV4Mapped) == PR_FALSE,
rv = senderIdentity->GetEmail(getter_Copies(m_mailAddr)); "unexpected IPv4-mapped IPv6 address");
if (NS_FAILED(rv) || !((const char *)m_mailAddr))
return nsnull; if (iaddr.raw.family == PR_AF_INET6) // IPv6 style address?
aResult.Assign(NS_LITERAL_CSTRING("[IPv6:"));
const char *atSignMarker = nsnull; else
atSignMarker = PL_strchr(m_mailAddr, '@'); aResult.Assign(NS_LITERAL_CSTRING("["));
return atSignMarker ? atSignMarker+1 : (const char *) m_mailAddr; // return const ptr into buffer in running url...
aResult.Append(nsDependentCString(ipAddressString) + NS_LITERAL_CSTRING("]"));
}
} }
return nsnull;
} }
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
@ -497,7 +504,10 @@ PRInt32 nsSmtpProtocol::ExtensionLoginResponse(nsIInputStream * inputStream, PRU
return(NS_ERROR_COULD_NOT_LOGIN_TO_SMTP_SERVER); return(NS_ERROR_COULD_NOT_LOGIN_TO_SMTP_SERVER);
} }
buffer += GetUserDomainName(); nsCAutoString domainName;
GetUserDomainName(domainName);
buffer += domainName;
buffer += CRLF; buffer += CRLF;
nsCOMPtr<nsIURI> url = do_QueryInterface(m_runningURL); nsCOMPtr<nsIURI> url = do_QueryInterface(m_runningURL);
@ -632,7 +642,10 @@ PRInt32 nsSmtpProtocol::SendEhloResponse(nsIInputStream * inputStream, PRUint32
} }
buffer = "HELO "; buffer = "HELO ";
buffer += GetUserDomainName(); nsCAutoString domainName;
GetUserDomainName(domainName);
buffer += domainName;
buffer += CRLF; buffer += CRLF;
status = SendData(url, buffer.get()); status = SendData(url, buffer.get());
} }
@ -1001,7 +1014,7 @@ PRInt32 nsSmtpProtocol::AuthLoginStep1()
if (TestFlag(SMTP_AUTH_LOGIN_ENABLED)) if (TestFlag(SMTP_AUTH_LOGIN_ENABLED))
{ {
base64Str = PL_Base64Encode((const char *)username, base64Str = PL_Base64Encode((const char *)username,
strlen((const char*)username), nsnull); strlen((const char*)username), nsnull);
PR_snprintf(buffer, sizeof(buffer), "%.256s" CRLF, base64Str); PR_snprintf(buffer, sizeof(buffer), "%.256s" CRLF, base64Str);
} }
else else

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

@ -251,8 +251,7 @@ private:
PRInt32 SendMessageInFile(); PRInt32 SendMessageInFile();
// extract domain name from userName field in the url... void GetUserDomainName(nsACString& domainName);
const char * GetUserDomainName();
nsresult GetPassword(char **aPassword); nsresult GetPassword(char **aPassword);
nsresult GetUsernamePassword(char **aUsername, char **aPassword); nsresult GetUsernamePassword(char **aUsername, char **aPassword);
nsresult PromptForPassword(nsISmtpServer *aSmtpServer, nsISmtpUrl *aSmtpUrl, const PRUnichar **formatStrings, char **aPassword); nsresult PromptForPassword(nsISmtpServer *aSmtpServer, nsISmtpUrl *aSmtpUrl, const PRUnichar **formatStrings, char **aPassword);

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

@ -48,7 +48,7 @@ native PRNetAddr(union PRNetAddr);
* NOTE: This is a free-threaded interface, meaning that the methods on * NOTE: This is a free-threaded interface, meaning that the methods on
* this interface may be called from any thread. * this interface may be called from any thread.
*/ */
[scriptable, uuid(1e372001-ca12-4507-8405-3267d4e0c1fd)] [scriptable, uuid(ee783990-c87c-4ace-87ca-54e5fcc477b0)]
interface nsISocketTransport : nsITransport interface nsISocketTransport : nsITransport
{ {
/** /**
@ -62,10 +62,16 @@ interface nsISocketTransport : nsITransport
readonly attribute long port; readonly attribute long port;
/** /**
* Returns the IP address for the underlying socket connection. This * Returns the IP address of the socket connection peer. This
* attribute is only defined once a connection has been established. * attribute is defined only once a connection has been established.
*/ */
[noscript] PRNetAddr getAddress(); [noscript] PRNetAddr getPeerAddr();
/**
* Returns the IP address of the initiating end. This attribute
* is defined only once a connection has been established.
*/
[noscript] PRNetAddr getSelfAddr();
/** /**
* Security info object returned from the secure socket provider. This * Security info object returned from the secure socket provider. This

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

@ -1671,7 +1671,7 @@ nsSocketTransport::GetPort(PRInt32 *port)
} }
NS_IMETHODIMP NS_IMETHODIMP
nsSocketTransport::GetAddress(PRNetAddr *addr) nsSocketTransport::GetPeerAddr(PRNetAddr *addr)
{ {
// once we are in the connected state, mNetAddr will not change. // once we are in the connected state, mNetAddr will not change.
// so if we can verify that we are in the connected state, then // so if we can verify that we are in the connected state, then
@ -1684,6 +1684,33 @@ nsSocketTransport::GetAddress(PRNetAddr *addr)
return NS_OK; return NS_OK;
} }
NS_IMETHODIMP
nsSocketTransport::GetSelfAddr(PRNetAddr *addr)
{
// we must not call any PR methods on our file descriptor
// while holding mLock since those methods might re-enter
// socket transport code.
PRFileDesc *fd;
{
nsAutoLock lock(mLock);
fd = GetFD_Locked();
}
if (!fd)
return NS_ERROR_NOT_CONNECTED;
nsresult rv =
(PR_GetSockName(fd, addr) == PR_SUCCESS) ? NS_OK : NS_ERROR_FAILURE;
{
nsAutoLock lock(mLock);
ReleaseFD_Locked(fd);
}
return rv;
}
NS_IMETHODIMP NS_IMETHODIMP
nsSocketTransport::OnLookupComplete(nsIDNSRequest *request, nsSocketTransport::OnLookupComplete(nsIDNSRequest *request,
nsIDNSRecord *rec, nsIDNSRecord *rec,

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

@ -1641,7 +1641,7 @@ nsFtpState::S_pasv() {
if (sTrans) { if (sTrans) {
PRNetAddr addr; PRNetAddr addr;
rv = sTrans->GetAddress(&addr); rv = sTrans->GetPeerAddr(&addr);
if (NS_SUCCEEDED(rv)) { if (NS_SUCCEEDED(rv)) {
if (addr.raw.family == PR_AF_INET6 && !PR_IsNetAddrType(&addr, PR_IpAddrV4Mapped)) { if (addr.raw.family == PR_AF_INET6 && !PR_IsNetAddrType(&addr, PR_IpAddrV4Mapped)) {
mIPv6ServerAddress = (char *) nsMemory::Alloc(100); mIPv6ServerAddress = (char *) nsMemory::Alloc(100);