1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.james.jspf.policies;
21
22 import org.apache.james.jspf.core.DNSLookupContinuation;
23 import org.apache.james.jspf.core.DNSRequest;
24 import org.apache.james.jspf.core.DNSResponse;
25 import org.apache.james.jspf.core.SPF1Constants;
26 import org.apache.james.jspf.core.SPF1Record;
27 import org.apache.james.jspf.core.SPF1Utils;
28 import org.apache.james.jspf.core.SPFChecker;
29 import org.apache.james.jspf.core.SPFCheckerDNSResponseListener;
30 import org.apache.james.jspf.core.SPFSession;
31 import org.apache.james.jspf.core.exceptions.NeutralException;
32 import org.apache.james.jspf.core.exceptions.NoneException;
33 import org.apache.james.jspf.core.exceptions.PermErrorException;
34 import org.apache.james.jspf.core.exceptions.TempErrorException;
35 import org.apache.james.jspf.core.exceptions.TimeoutException;
36
37 import java.util.Iterator;
38 import java.util.List;
39
40
41
42
43 public class SPFRetriever implements SPFChecker {
44
45 private static final class SPFRecordHandlerDNSResponseListener implements SPFCheckerDNSResponseListener {
46
47
48
49
50 public DNSLookupContinuation onDNSResponse(
51 DNSResponse response, SPFSession session)
52 throws PermErrorException,
53 NoneException, TempErrorException,
54 NeutralException {
55
56 List spfR;
57 try {
58 spfR = response.getResponse();
59 String record = extractSPFRecord(spfR);
60 if (record != null) {
61 session.setAttribute(SPF1Utils.ATTRIBUTE_SPF1_RECORD, new SPF1Record(record));
62 }
63 } catch (TimeoutException e) {
64 throw new TempErrorException("Timeout querying dns");
65 }
66 return null;
67
68 }
69
70 }
71
72 private static final class SPFRetrieverDNSResponseListener implements SPFCheckerDNSResponseListener {
73
74
75
76
77 public DNSLookupContinuation onDNSResponse(
78 DNSResponse response, SPFSession session)
79 throws PermErrorException, NoneException,
80 TempErrorException, NeutralException {
81 try {
82 List spfR = response.getResponse();
83
84 if (spfR == null || spfR.isEmpty()) {
85
86 String currentDomain = session.getCurrentDomain();
87 return new DNSLookupContinuation(new DNSRequest(currentDomain, DNSRequest.TXT), new SPFRecordHandlerDNSResponseListener());
88
89 } else {
90
91 String record = extractSPFRecord(spfR);
92 if (record != null) {
93 session.setAttribute(SPF1Utils.ATTRIBUTE_SPF1_RECORD, new SPF1Record(record));
94 }
95
96 }
97
98 return null;
99
100 } catch (TimeoutException e) {
101 throw new TempErrorException("Timeout querying dns");
102 }
103 }
104
105 }
106
107
108
109
110
111 private static final boolean CHECK_ONLY_TXT_RECORDS = false;
112
113
114
115
116
117
118
119
120
121 protected static String extractSPFRecord(List spfR) throws PermErrorException {
122 if (spfR == null || spfR.isEmpty()) return null;
123
124 String returnValue = null;
125 Iterator all = spfR.iterator();
126
127 while (all.hasNext()) {
128
129 String compare = all.next().toString();
130
131
132 if (compare.toLowerCase().trim().startsWith(SPF1Constants.SPF_VERSION1 + " ") || compare.trim().equalsIgnoreCase(SPF1Constants.SPF_VERSION1)) {
133 if (returnValue == null) {
134 returnValue = compare;
135 } else {
136 throw new PermErrorException(
137 "More than 1 SPF record found");
138 }
139 }
140 }
141
142 return returnValue;
143 }
144
145
146
147
148
149 public DNSLookupContinuation checkSPF(SPFSession spfData)
150 throws PermErrorException, TempErrorException, NeutralException,
151 NoneException {
152 SPF1Record res = (SPF1Record) spfData.getAttribute(SPF1Utils.ATTRIBUTE_SPF1_RECORD);
153 if (res == null) {
154 String currentDomain = spfData.getCurrentDomain();
155 if (CHECK_ONLY_TXT_RECORDS) {
156 return new DNSLookupContinuation(new DNSRequest(currentDomain, DNSRequest.TXT), new SPFRecordHandlerDNSResponseListener());
157 } else {
158 return new DNSLookupContinuation(new DNSRequest(currentDomain, DNSRequest.SPF), new SPFRetrieverDNSResponseListener());
159 }
160
161 }
162 return null;
163 }
164
165 }