1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.apache.james.jspf.terms;
22
23 import org.apache.james.jspf.core.DNSLookupContinuation;
24 import org.apache.james.jspf.core.DNSRequest;
25 import org.apache.james.jspf.core.DNSResponse;
26 import org.apache.james.jspf.core.IPAddr;
27 import org.apache.james.jspf.core.MacroExpand;
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.SPFTermsRegexps;
32 import org.apache.james.jspf.core.exceptions.NeutralException;
33 import org.apache.james.jspf.core.exceptions.NoneException;
34 import org.apache.james.jspf.core.exceptions.PermErrorException;
35 import org.apache.james.jspf.core.exceptions.TempErrorException;
36 import org.apache.james.jspf.core.exceptions.TimeoutException;
37
38 import java.util.ArrayList;
39 import java.util.List;
40
41
42
43
44
45 public class MXMechanism extends AMechanism implements SPFCheckerDNSResponseListener {
46
47 private final class ExpandedChecker implements SPFChecker {
48
49
50
51
52 public DNSLookupContinuation checkSPF(SPFSession spfData) throws PermErrorException,
53 TempErrorException, NeutralException, NoneException {
54
55
56 String host = expandHost(spfData);
57
58 return new DNSLookupContinuation(new DNSRequest(host, DNSRequest.MX), MXMechanism.this);
59 }
60 }
61
62 private static final String ATTRIBUTE_MX_RECORDS = "MXMechanism.mxRecords";
63 private static final String ATTRIBUTE_CHECK_RECORDS = "MXMechanism.checkRecords";
64
65
66
67 public static final String REGEX = "[mM][xX]" + "(?:\\:"
68 + SPFTermsRegexps.DOMAIN_SPEC_REGEX + ")?" + "(?:"
69 + DUAL_CIDR_LENGTH_REGEX + ")?";
70
71 private SPFChecker expandedChecker = new ExpandedChecker();
72
73
74
75
76 public DNSLookupContinuation checkSPF(SPFSession spfData) throws PermErrorException,
77 TempErrorException, NeutralException, NoneException{
78
79
80 spfData.increaseCurrentDepth();
81
82 spfData.pushChecker(expandedChecker);
83 return macroExpand.checkExpand(getDomain(), spfData, MacroExpand.DOMAIN);
84 }
85
86
87
88
89 public DNSLookupContinuation onDNSResponse(DNSResponse response, SPFSession spfSession)
90 throws PermErrorException, TempErrorException, NoneException, NeutralException {
91 try {
92
93 List records = (List) spfSession.getAttribute(ATTRIBUTE_CHECK_RECORDS);
94 List mxR = (List) spfSession.getAttribute(ATTRIBUTE_MX_RECORDS);
95
96 if (records == null) {
97
98 records = response.getResponse();
99
100 if (records == null) {
101
102 spfSession.setAttribute(Directive.ATTRIBUTE_MECHANISM_RESULT, Boolean.FALSE);
103 return null;
104 }
105
106 spfSession.setAttribute(ATTRIBUTE_CHECK_RECORDS, records);
107
108 } else {
109
110 List res = response.getResponse();
111
112 if (res != null) {
113 if (mxR == null) {
114 mxR = new ArrayList();
115 spfSession.setAttribute(ATTRIBUTE_MX_RECORDS, mxR);
116 }
117 mxR.addAll(res);
118 }
119
120 }
121
122
123 boolean isIPv6 = IPAddr.isIPV6(spfSession.getIpAddress());
124
125 String mx;
126 while (records.size() > 0 && (mx = (String) records.remove(0)) != null && mx.length() > 0) {
127 log.debug("Add MX-Record " + mx + " to list");
128
129 return new DNSLookupContinuation(new DNSRequest(mx, isIPv6 ? DNSRequest.AAAA : DNSRequest.A), MXMechanism.this);
130
131 }
132
133
134 if (mxR == null || mxR.size() == 0) {
135 spfSession.setAttribute(Directive.ATTRIBUTE_MECHANISM_RESULT, Boolean.FALSE);
136 return null;
137 }
138
139
140 IPAddr checkAddress;
141 checkAddress = IPAddr.getAddress(spfSession.getIpAddress(), isIPv6 ? getIp6cidr() : getIp4cidr());
142
143
144 spfSession.removeAttribute(ATTRIBUTE_CHECK_RECORDS);
145 spfSession.removeAttribute(ATTRIBUTE_MX_RECORDS);
146 spfSession.setAttribute(Directive.ATTRIBUTE_MECHANISM_RESULT, Boolean.valueOf(checkAddressList(checkAddress, mxR, getIp4cidr())));
147 return null;
148
149 } catch (TimeoutException e) {
150 spfSession.setAttribute(ATTRIBUTE_CHECK_RECORDS, null);
151 spfSession.setAttribute(ATTRIBUTE_MX_RECORDS, null);
152 throw new TempErrorException("Timeout querying the dns server");
153 }
154 }
155
156
157
158
159 public String toString() {
160 return super.toString("mx");
161 }
162
163 }