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
parent f8d1b7c1d0
commit 7d6d82ab51
5 changed files with 73 additions and 28 deletions

View File

@ -65,6 +65,7 @@
#include "prprf.h"
#include "prmem.h"
#include "plbase64.h"
#include "prnetdb.h"
#include "nsEscape.h"
#include "nsMsgUtils.h"
#include "nsIPipe.h"
@ -347,28 +348,34 @@ void nsSmtpProtocol::Initialize(nsIURI * aURL)
return;
}
const char * nsSmtpProtocol::GetUserDomainName()
void nsSmtpProtocol::GetUserDomainName(nsACString& aResult)
{
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;
rv = m_runningURL->GetSenderIdentity(getter_AddRefs(senderIdentity));
if (NS_FAILED(rv) || !senderIdentity)
return nsnull;
rv = senderIdentity->GetEmail(getter_Copies(m_mailAddr));
if (NS_FAILED(rv) || !((const char *)m_mailAddr))
return nsnull;
const char *atSignMarker = nsnull;
atSignMarker = PL_strchr(m_mailAddr, '@');
return atSignMarker ? atSignMarker+1 : (const char *) m_mailAddr; // return const ptr into buffer in running url...
// turn it into a string
char ipAddressString[64];
if (PR_NetAddrToString(&iaddr, ipAddressString, sizeof(ipAddressString)) == PR_SUCCESS)
{
NS_ASSERTION(PR_IsNetAddrType(&iaddr, PR_IpAddrV4Mapped) == PR_FALSE,
"unexpected IPv4-mapped IPv6 address");
if (iaddr.raw.family == PR_AF_INET6) // IPv6 style address?
aResult.Assign(NS_LITERAL_CSTRING("[IPv6:"));
else
aResult.Assign(NS_LITERAL_CSTRING("["));
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);
}
buffer += GetUserDomainName();
nsCAutoString domainName;
GetUserDomainName(domainName);
buffer += domainName;
buffer += CRLF;
nsCOMPtr<nsIURI> url = do_QueryInterface(m_runningURL);
@ -632,7 +642,10 @@ PRInt32 nsSmtpProtocol::SendEhloResponse(nsIInputStream * inputStream, PRUint32
}
buffer = "HELO ";
buffer += GetUserDomainName();
nsCAutoString domainName;
GetUserDomainName(domainName);
buffer += domainName;
buffer += CRLF;
status = SendData(url, buffer.get());
}
@ -1001,7 +1014,7 @@ PRInt32 nsSmtpProtocol::AuthLoginStep1()
if (TestFlag(SMTP_AUTH_LOGIN_ENABLED))
{
base64Str = PL_Base64Encode((const char *)username,
strlen((const char*)username), nsnull);
strlen((const char*)username), nsnull);
PR_snprintf(buffer, sizeof(buffer), "%.256s" CRLF, base64Str);
}
else

View File

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

View File

@ -48,7 +48,7 @@ native PRNetAddr(union PRNetAddr);
* NOTE: This is a free-threaded interface, meaning that the methods on
* 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
{
/**
@ -62,10 +62,16 @@ interface nsISocketTransport : nsITransport
readonly attribute long port;
/**
* Returns the IP address for the underlying socket connection. This
* attribute is only defined once a connection has been established.
* Returns the IP address of the socket connection peer. This
* 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

View File

@ -1671,7 +1671,7 @@ nsSocketTransport::GetPort(PRInt32 *port)
}
NS_IMETHODIMP
nsSocketTransport::GetAddress(PRNetAddr *addr)
nsSocketTransport::GetPeerAddr(PRNetAddr *addr)
{
// once we are in the connected state, mNetAddr will not change.
// so if we can verify that we are in the connected state, then
@ -1684,6 +1684,33 @@ nsSocketTransport::GetAddress(PRNetAddr *addr)
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
nsSocketTransport::OnLookupComplete(nsIDNSRequest *request,
nsIDNSRecord *rec,

View File

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