smtp: deliver IPv4 address literals directly
Debian Trixie package bundle / packages (push) Successful in 16m1s
Debian Trixie package bundle / packages (push) Successful in 16m1s
This commit is contained in:
+50
-1
@@ -499,6 +499,8 @@ Connection *LookupRemoteMX(RecipStruct *Recipient, char *hostname,
|
||||
XplDns_MxLookup *mx = NULL;
|
||||
XplDns_IpList *list = NULL;
|
||||
Connection *Result=NULL;
|
||||
struct in_addr literalAddress;
|
||||
BOOL addressLiteral = FALSE;
|
||||
|
||||
if (hostname == NULL || hostnameSize == 0 || canonicalHostname == NULL ||
|
||||
canonicalHostnameSize == 0 || nextHopDomain == NULL ||
|
||||
@@ -533,7 +535,13 @@ Connection *LookupRemoteMX(RecipStruct *Recipient, char *hostname,
|
||||
*(Recipient->localPart-1) = '@';
|
||||
return Result;
|
||||
}
|
||||
// FIXME: assumes our DNS routines will accept IP address.
|
||||
if (inet_pton(AF_INET, Host, &literalAddress) != 1) {
|
||||
Recipient->Result = DELIVER_BOGUS_NAME;
|
||||
*end = ']';
|
||||
*(Recipient->localPart-1) = '@';
|
||||
return Result;
|
||||
}
|
||||
addressLiteral = TRUE;
|
||||
*end = ']';
|
||||
} else {
|
||||
size_t hostLength = strlen(Recipient->SortField);
|
||||
@@ -549,6 +557,47 @@ Connection *LookupRemoteMX(RecipStruct *Recipient, char *hostname,
|
||||
/* make sure to reset the SortField as it was previously */
|
||||
*(Recipient->localPart-1) = '@';
|
||||
|
||||
/*
|
||||
* RFC 5321 address literals bypass MX and address lookups. Besides
|
||||
* avoiding a meaningless DNS query, this preserves the literal as the
|
||||
* next-hop identity and prevents DNSSEC state from being inferred for it.
|
||||
*/
|
||||
if (addressLiteral) {
|
||||
int status;
|
||||
|
||||
snprintf(hostname, hostnameSize, "%s", Host);
|
||||
snprintf(canonicalHostname, canonicalHostnameSize, "%s", Host);
|
||||
snprintf(nextHopDomain, nextHopDomainSize, "%s", Host);
|
||||
Result = ConnAlloc(TRUE);
|
||||
if (Result == NULL) {
|
||||
Recipient->Result = DELIVER_INTERNAL_ERROR;
|
||||
goto finish;
|
||||
}
|
||||
Result->socketAddress.sin_addr = literalAddress;
|
||||
Result->socketAddress.sin_family = AF_INET;
|
||||
Result->socketAddress.sin_port = htons(25);
|
||||
status = ConnConnect(Result, NULL, 0, NULL);
|
||||
if (status <= 0) {
|
||||
switch (errno) {
|
||||
case ETIMEDOUT:
|
||||
Recipient->Result = DELIVER_TIMEOUT;
|
||||
break;
|
||||
case ECONNREFUSED:
|
||||
Recipient->Result = DELIVER_REFUSED;
|
||||
break;
|
||||
case ENETUNREACH:
|
||||
Recipient->Result = DELIVER_UNREACHABLE;
|
||||
break;
|
||||
default:
|
||||
Recipient->Result = DELIVER_TRY_LATER;
|
||||
break;
|
||||
}
|
||||
ConnFree(Result);
|
||||
Result = NULL;
|
||||
}
|
||||
goto finish;
|
||||
}
|
||||
|
||||
/* DNS and the normalized SMTP envelope both use the same IDNA2008
|
||||
* A-label. This also validates ASCII domains before lookup. */
|
||||
if (!BongoDomainToASCII(Host, asciiHost, sizeof(asciiHost))) {
|
||||
|
||||
Reference in New Issue
Block a user