| Newsgroups |
gmane.comp.jakarta.james.devel |
| Message-ID |
<[email protected]> |
This is an automated email from the ASF dual-hosted git repository.
btellier pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/james-jspf.git
commit 530227acacd5018a752f7aad887793309768cfa2
Author: Emerson Pinter <[email protected]>
AuthorDate: Fri Jan 24 15:53:53 2025 -0300
Add more tests
---
.../org/apache/james/jspf/SPFExecutorBaseTest.java | 193 +++++++++++++++++++++
.../dnszones/SPFExecutorIntegrationTest-1.zone | 12 ++
2 files changed, 205 insertions(+)
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 ae1c296..acdc376 100644
--- a/resolver/src/test/java/org/apache/james/jspf/SPFExecutorBaseTest.java
+++ b/resolver/src/test/java/org/apache/james/jspf/SPFExecutorBaseTest.java
@@ -1,22 +1,33 @@
package org.apache.james.jspf;
import org.apache.james.jspf.core.DNSService;
+import org.apache.james.jspf.core.exceptions.SPFErrorConstants;
import org.apache.james.jspf.executor.SPFResult;
+import org.apache.james.jspf.helpers.FakeResolver;
import org.apache.james.jspf.impl.DNSServiceXBillImpl;
import org.apache.james.jspf.impl.SPF;
import org.junit.Before;
import org.junit.Test;
import org.xbill.DNS.DClass;
import org.xbill.DNS.Lookup;
+import org.xbill.DNS.Name;
import org.xbill.DNS.Resolver;
+import org.xbill.DNS.SPFRecord;
import org.xbill.DNS.SimpleResolver;
+import org.xbill.DNS.TXTRecord;
+import org.xbill.DNS.TextParseException;
+import java.io.IOException;
import java.net.UnknownHostException;
+import java.nio.file.Paths;
import java.util.concurrent.ThreadLocalRandom;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
import static org.junit.Assert.assertEquals;
public abstract class SPFExecutorBaseTest {
+ protected final String zonesDir = "src/test/resources/dnszones";
protected abstract SPF createSPF();
@@ -27,6 +38,10 @@ public abstract class SPFExecutorBaseTest {
Lookup.getDefaultCache(DClass.IN).clearCache();
}
+ public String getZonePath(String zoneFile) {
+ return Paths.get(zonesDir, zoneFile).toAbsolutePath().toString();
+ }
+
@Test
public void test() {
SPF spf = createSPF();
@@ -68,4 +83,182 @@ public abstract class SPFExecutorBaseTest {
assertEquals("Received-SPF: temperror (spfCheck: Error in retrieving data from DNS) client-ip=207.54.72.202; envelope-from=do_not_reply@reyifglerifwukfvbdjhrkbvebvekvfulervkerkeruerbeb.de; helo=reyifglerifwukfvbdjhrkbvebvekvfulervkerkeruerbeb.de;",
result.getHeader());
}
+
+ @Test
+ public void shouldReturnPassIfJustOneTxtSpf1Record() throws IOException {
+ String testDomain = "spfexecutor.fake";
+ String hostname = "shouldReturnPassIfJustOneTxtSpf1Record." + testDomain;
+ String ip = "192.0.2.127";
+
+ //setup resolver
+ FakeResolver fakeResolver = new FakeResolver();
+ fakeResolver.fromZoneFile(testDomain, getZonePath("SPFExecutorIntegrationTest-1.zone"));
+ fakeResolver.addRecords(FakeResolver.genNRandomTXTRecords(hostname + ".", 300));
+
+ SPF spf = createCustomSPF(new DNSServiceXBillImpl(fakeResolver));
+ SPFResult result = spf.checkSPF(ip, "a_user@" + hostname, hostname);
+ assertEquals(String.format(
+ "Received-SPF: %3$s (spfCheck: domain of %2$s designates %1$s as permitted sender) client-ip=%1$s; envelope-from=a_user@%2$s; helo=%2$s;",
+ ip, hostname, SPFErrorConstants.PASS_CONV),
+ result.getHeader());
+ assertEquals(SPFErrorConstants.PASS_CONV, result.getResult());
+ }
+
+ @Test
+ public void shouldReturnErrorIfMoreThanOneTxtSpf1Record() throws IOException {
+ String testDomain = "spfexecutor.fake";
+ String hostname = "shouldReturnErrorIfMoreThanOneTxtSpf1Record." + testDomain;
+ String ip = "192.0.2.127";
+
+ //setup resolver
+ FakeResolver fakeResolver = new FakeResolver();
+ fakeResolver.fromZoneFile(testDomain, getZonePath("SPFExecutorIntegrationTest-1.zone"));
+
+ SPF spf = createCustomSPF(new DNSServiceXBillImpl(fakeResolver));
+ SPFResult result = spf.checkSPF(ip, "a_user@" + hostname, hostname);
+ assertEquals(String.format(
+ "Received-SPF: %3$s (spfCheck: Error in processing SPF Record) client-ip=%1$s; envelope-from=a_user@%2$s; helo=%2$s;",
+ ip, hostname, SPFErrorConstants.PERM_ERROR_CONV),
+ result.getHeader());
+ assertEquals(SPFErrorConstants.PERM_ERROR_CONV, result.getResult());
+ }
+
+ @Test
+ public void shouldReturnErrorIfMoreThanOneSpfRecord() throws IOException {
+ String testDomain = "spfexecutor.fake";
+ String hostname = "shouldReturnErrorIfMoreThanOneSpfRecord." + testDomain;
+ String ip = "192.0.2.127";
+
+ //setup resolver
+ FakeResolver fakeResolver = new FakeResolver();
+ fakeResolver.setRecords(FakeResolver.genNRandomTXTRecords(hostname + ".", 300));
+ fakeResolver.addRecord(new SPFRecord(
+ Name.fromString(hostname + "."), DClass.IN, 30L, String.format("v=spf1 ip4:%s ip4:1.1.1.1 -all", ip)));
+ fakeResolver.addRecord(new SPFRecord(
+ Name.fromString(hostname + "."), DClass.IN, 30L, String.format("v=spf1 ip4:%s -all", ip)));
+
+ SPF spf = createCustomSPF(new DNSServiceXBillImpl(fakeResolver));
+ SPFResult result = spf.checkSPF(ip, "a_user@" + hostname, hostname);
+ assertEquals(String.format(
+ "Received-SPF: %3$s (spfCheck: Error in processing SPF Record) client-ip=%1$s; envelope-from=a_user@%2$s; helo=%2$s;",
+ ip, hostname, SPFErrorConstants.PERM_ERROR_CONV),
+ result.getHeader());
+ assertEquals(SPFErrorConstants.PERM_ERROR_CONV, result.getResult());
+ }
+
+ /*
+ * Test the limit described in RFC7208 section "4.6.4. DNS Lookup Limits"
+ */
+ @Test
+ public void shouldReturnErrorIfDepthMoreThan10() throws IOException {
+ String testDomain = "spfexecutor.fake";
+ String hostname = "shouldReturnErrorIfDepthMoreThan10." + testDomain;
+ String ip = "192.0.2.127";
+
+ //setup resolver
+ FakeResolver fakeResolver = new FakeResolver();
+ fakeResolver.addRecord(new TXTRecord(Name.fromString(hostname + "."),
+ DClass.IN, 30L, String.format("v=spf1 ip4:4.3.2.1 include:depth0.%s -all", hostname)));
+
+ fakeResolver.addRecords(IntStream.range(0, 10).mapToObj(
+ i -> {
+ try {
+ String txt = String.format("v=spf1 ip4:4.3.2.2 include:depth%s.%s -all", i + 1, hostname);
+ return new TXTRecord(
+ Name.fromString(String.format("depth%s.%s.", i, hostname), Name.fromString(testDomain)),
+ DClass.IN, 30L, txt);
+ } catch (TextParseException e) {
+ throw new RuntimeException(e);
+ }
+ }).collect(Collectors.toList()));
+
+
+ SPF spf = createCustomSPF(new DNSServiceXBillImpl(fakeResolver));
+ SPFResult result = spf.checkSPF(ip, "a_user@" + hostname, hostname);
+ assertEquals(String.format(
+ "Received-SPF: %3$s (spfCheck: Error in processing SPF Record) client-ip=%1$s; envelope-from=a_user@%2$s; helo=%2$s;",
+ ip, hostname, SPFErrorConstants.PERM_ERROR_CONV),
+ result.getHeader());
+ assertEquals(SPFErrorConstants.PERM_ERROR_CONV, result.getResult());
+ }
+
+ /*
+ * Test the limit described in RFC7208 section "4.6.4. DNS Lookup Limits"
+ */
+ @Test
+ public void shouldReturnPassIfDepth10orLess() throws IOException {
+ String testDomain = "spfexecutor.fake";
+ String hostname = "shouldReturnPassIfDepth10OrLess." + testDomain;
+ String ip = "192.0.2.127";
+
+ //setup resolver
+ FakeResolver fakeResolver = new FakeResolver();
+ fakeResolver.addRecord(new TXTRecord(Name.fromString(hostname + "."),
+ DClass.IN, 30L, String.format("v=spf1 ip4:4.3.2.1 include:depth0.%s -all", hostname)));
+
+ int count = 10;
+ fakeResolver.addRecords(IntStream.range(0, count).mapToObj(
+ i -> {
+ try {
+ String txt;
+ if (i == count - 1) {
+ txt = String.format("v=spf1 ip4:4.3.2.2 ip4:%s -all", ip);
+ } else {
+ txt = String.format("v=spf1 ip4:4.3.2.2 include:depth%s.%s -all", i + 1, hostname);
+ }
+ return new TXTRecord(
+ Name.fromString(String.format("depth%s.%s.", i, hostname), Name.fromString(testDomain)),
+ DClass.IN, 30L, txt);
+ } catch (TextParseException e) {
+ throw new RuntimeException(e);
+ }
+ }).collect(Collectors.toList()));
+
+
+ SPF spf = createCustomSPF(new DNSServiceXBillImpl(fakeResolver));
+ SPFResult result = spf.checkSPF(ip, "a_user@" + hostname, hostname);
+ assertEquals(String.format(
+ "Received-SPF: %3$s (spfCheck: domain of %2$s designates %1$s as permitted sender) client-ip=%1$s; envelope-from=a_user@%2$s; helo=%2$s;",
+ ip, hostname, SPFErrorConstants.PASS_CONV),
+ result.getHeader());
+ assertEquals(SPFErrorConstants.PASS_CONV, result.getResult());
+ }
+
+ @Test
+ public void shouldReturnPermErrorIfIncludeDomainNotFound() throws IOException {
+ String testDomain = "spfexecutor.fake";
+ String hostname = "shouldReturnPermErrorIfIncludeDomainNotFound." + testDomain;
+ String ip = "192.0.2.127";
+
+ //setup resolver
+ FakeResolver fakeResolver = new FakeResolver();
+ fakeResolver.fromZoneFile(testDomain, getZonePath("SPFExecutorIntegrationTest-1.zone"));
+
+ SPF spf = createCustomSPF(new DNSServiceXBillImpl(fakeResolver));
+ SPFResult result = spf.checkSPF(ip, "a_user@" + hostname, hostname);
+ assertEquals(String.format(
+ "Received-SPF: %3$s (spfCheck: Error in processing SPF Record) client-ip=%1$s; envelope-from=a_user@%2$s; helo=%2$s;",
+ ip, hostname, SPFErrorConstants.PERM_ERROR_CONV),
+ result.getHeader());
+ assertEquals(SPFErrorConstants.PERM_ERROR_CONV, result.getResult());
+ }
+
+ @Test
+ public void shouldHandleMultipleStrings() throws IOException {
+ String testDomain = "spfexecutor.fake";
+ String hostname = "shouldReturnPassIfMultipleStrings." + testDomain;
+ String ip = "192.0.2.127";
+
+ //setup resolver
+ FakeResolver fakeResolver = new FakeResolver();
+ fakeResolver.fromZoneFile(testDomain, getZonePath("SPFExecutorIntegrationTest-1.zone"));
+
+ SPF spf = createCustomSPF(new DNSServiceXBillImpl(fakeResolver));
+ SPFResult result = spf.checkSPF(ip, "a_user@" + hostname, hostname);
+ assertEquals(String.format(
+ "Received-SPF: %3$s (spfCheck: domain of %2$s designates %1$s as permitted sender) client-ip=%1$s; envelope-from=a_user@%2$s; helo=%2$s;",
+ ip, hostname, SPFErrorConstants.PASS_CONV),
+ result.getHeader());
+ assertEquals(SPFErrorConstants.PASS_CONV, result.getResult());
+ }
}
diff --git a/resolver/src/test/resources/dnszones/SPFExecutorIntegrationTest-1.zone b/resolver/src/test/resources/dnszones/SPFExecutorIntegrationTest-1.zone
new file mode 100644
index 0000000..8898bee
--- /dev/null
+++ b/resolver/src/test/resources/dnszones/SPFExecutorIntegrationTest-1.zone
@@ -0,0 +1,12 @@
+$TTL 30
+@ 30 IN SOA ns1.fakeresolver.apache. hostmaster.fakeresolver.apache. 1 30 30 30 30
+@ 30 IN NS ns1
+
+shouldReturnErrorIfMoreThanOneTxtSpf1Record IN TXT "v=spf1 ip4:192.0.2.162 -all"
+shouldReturnErrorIfMoreThanOneTxtSpf1Record IN TXT "v=spf1 ip4:192.0.2.127 ip4:1.1.1.1 -all"
+
+shouldReturnPassIfJustOneTxtSpf1Record IN TXT "v=spf1 include:_spf.google.com include:spf.protection.outlook.com ip4:2.3.4.5 ip4:192.0.2.127 -all"
+
+shouldReturnPermErrorIfIncludeDomainNotFound IN TXT "v=spf1 ip4:4.3.2.1 include:unknownDomain.fake -all"
+
+shouldReturnPassIfMultipleStrings IN TXT "v=spf1 mx a ip4:192.0.2.127 ip4:4.3.2.1 ip4:4.3.2.1 ip4:4.3.2.1 ip4:4.3.2.1 ip4:4.3.2.1 ip4:4.3.2.1 ip4:4.3.2.1 ip4:4.3.2.1 ip4:4.3.2.1 ip4:4.3.2.1 ip4:4.3.2.1 ip4:4.3.2.1 ip4:4.3.2.1 ip4:4.3.2.1 ip4:4.3.2.1 ip4:4.3.2.1 ip4:4.3.2.1 ip4:4.3.2.1" " ip4:4.3.2.1 -all"