This is an automated email from the ASF dual-hosted git repository. chibenwa pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-jspf.git
commit 6266c12f6bfff635f41be7a9af1bc3245f0a8d7d Author: Quan Tran <[email protected]> AuthorDate: Wed Nov 4 22:37:59 2026 +0700 [FIX] DNSServiceXBillImpl: look up the names as fully qualified getRecords gave dnsjava's Lookup the name as relative, so after an NXDOMAIN Lookup looked it up again under each domain of the search path of the host: a sender domain x.example.com that does not exist was checked with the record of x.example.com.corp.local, when the host searches corp.local. The domains of SPF are fully qualified (RFC 7208 4.3, and 4.8: "a fully qualified DNS name"), and the asynchronous lookup, of a session without search path, did not do it. Look up the names as fully qualified, in both getRecords and getRecordsAsync. --- .../apache/james/jspf/impl/DNSServiceXBillImpl.java | 5 +++-- .../org/apache/james/jspf/SPFExecutorBaseTest.java | 20 ++++++++++++++++++++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/resolver/src/main/java/org/apache/james/jspf/impl/DNSServiceXBillImpl.java b/resolver/src/main/java/org/apache/james/jspf/impl/DNSServiceXBillImpl.java index da95454..a0614cd 100644 --- a/resolver/src/main/java/org/apache/james/jspf/impl/DNSServiceXBillImpl.java +++ b/resolver/src/main/java/org/apache/james/jspf/impl/DNSServiceXBillImpl.java @@ -305,7 +305,8 @@ public class DNSServiceXBillImpl implements DNSService { LOGGER.debug("Start {}-Record lookup for : {}", recordTypeDescription, request.getHostname()); - Lookup query = new Lookup(request.getHostname(), dnsJavaType); + // RFC 7208 4.3: a fully qualified name, not looked up under the search path of the host + Lookup query = new Lookup(Name.fromString(request.getHostname(), Name.root), dnsJavaType); query.setResolver(resolver); Record[] rr = query.run(); @@ -345,7 +346,7 @@ public class DNSServiceXBillImpl implements DNSService { final LookupSession lookupSession = LookupSession.defaultBuilder().resolver(new BoundedResolver(this.resolver)).build(); try { - return lookupSession.lookupAsync(Name.fromString(request.getHostname()), dnsJavaType) + return lookupSession.lookupAsync(Name.fromString(request.getHostname(), Name.root), dnsJavaType) .thenApply(result -> convertRecordsToList(ofType(result.getRecords().toArray(new Record[0]), dnsJavaType))); } catch (TextParseException e) { // no record, as getRecords answers diff --git a/resolver/src/test/java/org/apache/james/jspf/SPFExecutorBaseTest.java b/resolver/src/test/java/org/apache/james/jspf/SPFExecutorBaseTest.java index b7736cd..45626d4 100644 --- a/resolver/src/test/java/org/apache/james/jspf/SPFExecutorBaseTest.java +++ b/resolver/src/test/java/org/apache/james/jspf/SPFExecutorBaseTest.java @@ -960,6 +960,26 @@ public abstract class SPFExecutorBaseTest { result.getHeader()); } + @Test(timeout = 10000) + public void shouldNotLookUpTheDomainUnderTheSearchPath() throws IOException { + String hostname = "searchPath.spfexecutor.fake"; + FakeResolver fakeResolver = new FakeResolver(AnsweringResolver.withRcode(Rcode.NXDOMAIN)); + // the domain under a search path of the host, of a record that would pass + fakeResolver.addRecord(new TXTRecord(Name.fromString(hostname + ".search.fake."), DClass.IN, 30L, "v=spf1 +all")); + List<Name> searchPath = Lookup.getDefaultSearchPath(); + Lookup.setDefaultSearchPath(Name.fromString("search.fake.")); + try { + SPF spf = createCustomSPF(new DNSServiceXBillImpl(fakeResolver)); + + SPFResult result = spf.checkSPF("192.0.2.10", "a_user@" + hostname, hostname); + + // RFC 7208 4.3: the domain is fully qualified, and does not exist + assertEquals(SPFErrorConstants.NONE_CONV, result.getResult()); + } finally { + Lookup.setDefaultSearchPath(searchPath); + } + } + @Test(timeout = 10000) public void shouldReturnPermErrorOnAIp4CidrOverflowingAnInt() throws IOException { SPFResult result = checkRecord("aIp4CidrOverflow.spfexecutor.fake", "v=spf1 a/4294967296 -all", "1.2.3.4"); --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
