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 63e7f8de2d82e687e5fd3073d0533a112e4451f6 Author: Quan Tran <[email protected]> AuthorDate: Tue Nov 3 14:28:06 2026 +0700 [FIX] SPFSession: expand %{v} from the client address it checks The session checks the client address trimmed, and IPv4 when it is IPv4-mapped, but computed %{v} from the address as given: - for ::ffff:1.2.3.4, %{i} was 1.2.3.4 but %{v} "ip6", so "v=spf1 exists:%{v}.example.com -all" failed a client it passes as 1.2.3.4; - for " 1.2.3.4 ", the spaces made the address invalid, so every check was a permerror. Compute %{v} from the address checked: "in-addr" for an IPv4 client, which an IPv4-mapped one is (RFC 7208 5, 7.3). The test asserting "ip6" for ::ffff:192.168.1.1 now asserts "in-addr". --- .../main/java/org/apache/james/jspf/core/SPFSession.java | 4 ++-- .../java/org/apache/james/jspf/SPFExecutorBaseTest.java | 16 ++++++++++++++++ .../java/org/apache/james/jspf/core/SPFSessionTest.java | 15 +++++++++++++++ 3 files changed, 33 insertions(+), 2 deletions(-) diff --git a/resolver/src/main/java/org/apache/james/jspf/core/SPFSession.java b/resolver/src/main/java/org/apache/james/jspf/core/SPFSession.java index 7173852..97d8381 100644 --- a/resolver/src/main/java/org/apache/james/jspf/core/SPFSession.java +++ b/resolver/src/main/java/org/apache/james/jspf/core/SPFSession.java @@ -99,8 +99,8 @@ public class SPFSession implements MacroData { try { this.ipAddress = IPAddr.getProperIpAddress(clientIP.trim()); - // get the in Address - this.inAddress = IPAddr.getInAddress(clientIP); + // get the in Address, of the address checked: trimmed, and IPv4 when IPv4-mapped + this.inAddress = IPAddr.getInAddress(this.ipAddress); } catch (PermErrorException e) { // ip was not rfc conform this.setCurrentResultExpanded(e.getResult()); 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 b972144..d21f49a 100644 --- a/resolver/src/test/java/org/apache/james/jspf/SPFExecutorBaseTest.java +++ b/resolver/src/test/java/org/apache/james/jspf/SPFExecutorBaseTest.java @@ -559,6 +559,22 @@ public abstract class SPFExecutorBaseTest { assertEquals(SPFErrorConstants.PASS_CONV, result.getResult()); } + @Test(timeout = 10000) + public void inAddressShouldBeThatOfAnIpv4MappedClient() throws IOException { + String hostname = "ipv4MappedInAddress.spfexecutor.fake"; + FakeResolver fakeResolver = new FakeResolver(); + fakeResolver.addRecord(new TXTRecord(Name.fromString(hostname + "."), DClass.IN, 30L, + "v=spf1 exists:%{v}." + hostname + " -all")); + fakeResolver.addRecord(new ARecord(Name.fromString("in-addr." + hostname + "."), DClass.IN, 30L, + InetAddress.getByName("127.0.0.2"))); + + SPF spf = createCustomSPF(new DNSServiceXBillImpl(fakeResolver)); + SPFResult result = spf.checkSPF("::ffff:1.2.3.4", "a_user@" + hostname, hostname); + + // RFC 7208 7.3: %{v} is "in-addr" for an IPv4 client, which an IPv4-mapped one is (RFC 7208 5) + assertEquals(SPFErrorConstants.PASS_CONV, result.getResult()); + } + @Test(timeout = 10000) public void shouldReturnPermErrorOnAIp4CidrOverflowingAnInt() throws IOException { SPFResult result = checkRecord("aIp4CidrOverflow.spfexecutor.fake", "v=spf1 a/4294967296 -all", "1.2.3.4"); diff --git a/resolver/src/test/java/org/apache/james/jspf/core/SPFSessionTest.java b/resolver/src/test/java/org/apache/james/jspf/core/SPFSessionTest.java index bf28c09..7f91325 100644 --- a/resolver/src/test/java/org/apache/james/jspf/core/SPFSessionTest.java +++ b/resolver/src/test/java/org/apache/james/jspf/core/SPFSessionTest.java @@ -22,6 +22,7 @@ package org.apache.james.jspf.core; import org.junit.Test; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNull; public class SPFSessionTest { @Test @@ -54,6 +55,20 @@ public class SPFSessionTest { @Test public void shouldReturnIPv4Mapped() { SPFSession spfSession = new SPFSession("", "", "::ffff:192.168.1.1"); + assertEquals("in-addr", spfSession.getInAddress()); + } + + @Test + public void shouldReturnIPv4OfAnAddressWithSpaces() { + SPFSession spfSession = new SPFSession("", "", " 192.168.1.1 "); + assertNull(spfSession.getCurrentResultExpanded()); + assertEquals("in-addr", spfSession.getInAddress()); + } + + @Test + public void shouldReturnValidIP6OfAnAddressWithSpaces() { + SPFSession spfSession = new SPFSession("", "", " 2001:db8::1 "); + assertNull(spfSession.getCurrentResultExpanded()); assertEquals("ip6", spfSession.getInAddress()); } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
