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 64df226ed59f3c8116c802d362259ce41ddaad9b
Author: Quan Tran <[email protected]>
AuthorDate: Thu Nov 5 11:26:37 2026 +0700

    [FIX] ptr mechanism: check the first 10 names, not 9
    
    Of more than 10 PTR names of the client address, the ptr mechanism
    kept the first getRecordLimit() - 1, so 9 with the default limit of
    10, and none with a limit of 1: when the 10th name was the one
    validating the client, the mechanism did not match where it matches.
    RFC 7208 4.6.4: "all records other than the first 10 MUST be ignored".
    
    Keep the first getRecordLimit() names.
---
 .../org/apache/james/jspf/terms/PTRMechanism.java  |  6 ++--
 .../org/apache/james/jspf/SPFExecutorBaseTest.java | 35 ++++++++++++++++++++++
 2 files changed, 38 insertions(+), 3 deletions(-)

diff --git 
a/resolver/src/main/java/org/apache/james/jspf/terms/PTRMechanism.java 
b/resolver/src/main/java/org/apache/james/jspf/terms/PTRMechanism.java
index 0a0dfb2..374d799 100644
--- a/resolver/src/main/java/org/apache/james/jspf/terms/PTRMechanism.java
+++ b/resolver/src/main/java/org/apache/james/jspf/terms/PTRMechanism.java
@@ -156,9 +156,9 @@ public class PTRMechanism extends GenericMechanism 
implements DNSServiceEnabled,
         
                 // check if the maximum lookup count is reached
                 if (dnsService.getRecordLimit() > 0 && domainList.size() > 
dnsService.getRecordLimit()) {
-                    // Truncate the PTR list to getRecordLimit.
-                    // See #ptr-limit rfc4408 test
-                    domainList = domainList.subList(0, 
dnsService.getRecordLimit()-1);
+                    // Truncate the PTR list to getRecordLimit: RFC 7208 
4.6.4, "all records other than the
+                    // first 10 MUST be ignored". See #ptr-limit rfc4408 test
+                    domainList = domainList.subList(0, 
dnsService.getRecordLimit());
                     // throw new PermErrorException("Maximum PTR lookup count 
reached");
                 }
                 
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 b5d6f3c..f678e92 100644
--- a/resolver/src/test/java/org/apache/james/jspf/SPFExecutorBaseTest.java
+++ b/resolver/src/test/java/org/apache/james/jspf/SPFExecutorBaseTest.java
@@ -83,6 +83,20 @@ public abstract class SPFExecutorBaseTest {
         return fakeResolver;
     }
 
+    // hostname has "v=spf1 ptr -all", and 1.2.3.4 the 11 PTR names 
name<i>.<hostname>, of which only name<validated> has
+    // the address 1.2.3.4
+    private static FakeResolver elevenPtrNamesOfTheClient(String hostname, int 
validated) throws IOException {
+        FakeResolver fakeResolver = new FakeResolver();
+        fakeResolver.addRecord(new TXTRecord(Name.fromString(hostname + "."), 
DClass.IN, 30L, "v=spf1 ptr -all"));
+        for (int i = 1; i <= 11; i++) {
+            fakeResolver.addRecord(new 
PTRRecord(Name.fromString("4.3.2.1.in-addr.arpa."), DClass.IN, 30L,
+                Name.fromString("name" + i + "." + hostname + ".")));
+        }
+        fakeResolver.addRecord(new ARecord(Name.fromString("name" + validated 
+ "." + hostname + "."), DClass.IN, 30L,
+            InetAddress.getByName("1.2.3.4")));
+        return fakeResolver;
+    }
+
     // a server publishing the record, failing the lookups of the given 
DNSRequest type
     private static DNSService dnsFailing(int failedType, Record record) throws 
IOException {
         FakeResolver fakeResolver = new FakeResolver();
@@ -716,6 +730,27 @@ public abstract class SPFExecutorBaseTest {
         assertEquals(SPFErrorConstants.PASS_CONV, result.getResult());
     }
 
+    @Test(timeout = 10000)
+    public void ptrShouldCheckTheTenthOfMoreThanTenNames() throws IOException {
+        String hostname = "ptrlimit.spfexecutor.fake";
+        SPF spf = createCustomSPF(new 
DNSServiceXBillImpl(elevenPtrNamesOfTheClient(hostname, 10)));
+
+        SPFResult result = spf.checkSPF("1.2.3.4", "a_user@" + hostname, 
hostname);
+
+        // RFC 7208 4.6.4: "all records other than the first 10 MUST be 
ignored"
+        assertEquals(SPFErrorConstants.PASS_CONV, result.getResult());
+    }
+
+    @Test(timeout = 10000)
+    public void ptrShouldIgnoreTheEleventhOfMoreThanTenNames() throws 
IOException {
+        String hostname = "ptrlimit11.spfexecutor.fake";
+        SPF spf = createCustomSPF(new 
DNSServiceXBillImpl(elevenPtrNamesOfTheClient(hostname, 11)));
+
+        SPFResult result = spf.checkSPF("1.2.3.4", "a_user@" + hostname, 
hostname);
+
+        assertEquals(SPFErrorConstants.FAIL_CONV, result.getResult());
+    }
+
     @Test(timeout = 10000)
     public void ptrShouldNotMatchALabelHoldingADotAsASubdomain() throws 
IOException {
         String hostname = "ptrlabel.spfexecutor.fake";


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to