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.LogEnabled;
25 import org.apache.james.jspf.core.Logger;
26 import org.apache.james.jspf.core.MacroExpand;
27 import org.apache.james.jspf.core.MacroExpandEnabled;
28 import org.apache.james.jspf.core.SPF1Constants;
29 import org.apache.james.jspf.core.SPFCheckEnabled;
30 import org.apache.james.jspf.core.SPFChecker;
31 import org.apache.james.jspf.core.SPFCheckerExceptionCatcher;
32 import org.apache.james.jspf.core.SPFSession;
33 import org.apache.james.jspf.core.SPFTermsRegexps;
34 import org.apache.james.jspf.core.exceptions.NeutralException;
35 import org.apache.james.jspf.core.exceptions.NoneException;
36 import org.apache.james.jspf.core.exceptions.PermErrorException;
37 import org.apache.james.jspf.core.exceptions.TempErrorException;
38
39
40
41
42
43 public class IncludeMechanism implements Mechanism, ConfigurationEnabled, LogEnabled, SPFCheckEnabled, MacroExpandEnabled {
44
45 private final class ExpandedChecker implements SPFChecker {
46
47
48
49
50 public DNSLookupContinuation checkSPF(SPFSession spfData) throws PermErrorException,
51 TempErrorException {
52
53
54 String host = macroExpand.expand(getHost(), spfData, MacroExpand.DOMAIN);
55
56 spfData.setCurrentDomain(host);
57
58
59 spfData.setIgnoreExplanation(true);
60
61 spfData.setCurrentResult(null);
62 spfData.setCurrentResultExpanded(null);
63
64 spfData.pushChecker(spfChecker);
65
66 return null;
67 }
68 }
69
70 private final class CleanupAndResultChecker implements SPFChecker, SPFCheckerExceptionCatcher {
71 private String previousResult;
72 private String previousResultExpanded;
73 private String previousDomain;
74
75 private void restoreSession(SPFSession spfData) {
76 spfData.setIgnoreExplanation(false);
77 spfData.setCurrentDomain(previousDomain);
78 spfData.setCurrentResult(previousResult);
79 spfData.setCurrentResultExpanded(previousResultExpanded);
80 }
81
82
83
84
85 public DNSLookupContinuation checkSPF(SPFSession spfData) throws PermErrorException,
86 TempErrorException, NeutralException, NoneException {
87
88 String currentResult = spfData.getCurrentResult();
89
90 restoreSession(spfData);
91
92 if (currentResult == null) {
93 throw new TempErrorException("included checkSPF returned null");
94 } else if (currentResult.equals(SPF1Constants.PASS)) {
95
96 spfData.setAttribute(Directive.ATTRIBUTE_MECHANISM_RESULT, Boolean.TRUE);
97 } else if (currentResult.equals(SPF1Constants.FAIL) || currentResult.equals(SPF1Constants.SOFTFAIL) || currentResult.equals(SPF1Constants.NEUTRAL)) {
98
99 spfData.setAttribute(Directive.ATTRIBUTE_MECHANISM_RESULT, Boolean.FALSE);
100 } else {
101 throw new TempErrorException("included checkSPF returned an Illegal result");
102 }
103
104 return null;
105 }
106
107
108
109
110 public void onException(Exception exception, SPFSession session)
111 throws PermErrorException, NoneException,
112 TempErrorException, NeutralException {
113
114 restoreSession(session);
115
116 if (exception instanceof NeutralException) {
117 throw new PermErrorException("included checkSPF returned NeutralException");
118 } else if (exception instanceof NoneException) {
119 throw new PermErrorException("included checkSPF returned NoneException");
120 } else if (exception instanceof PermErrorException){
121 throw (PermErrorException) exception;
122 } else if (exception instanceof TempErrorException){
123 throw (TempErrorException) exception;
124 } else if (exception instanceof RuntimeException){
125 throw (RuntimeException) exception;
126 } else {
127 throw new IllegalStateException(exception.getMessage());
128 }
129 }
130
131 public SPFChecker init(SPFSession spfSession) {
132
133
134
135
136 this.previousResult = spfSession.getCurrentResult();
137 this.previousDomain = spfSession.getCurrentDomain();
138 this.previousResultExpanded = spfSession.getCurrentResultExpanded();
139 return this;
140 }
141 }
142
143
144
145
146 public static final String REGEX = "[iI][nN][cC][lL][uU][dD][eE]" + "\\:"
147 + SPFTermsRegexps.DOMAIN_SPEC_REGEX;
148
149 protected String host;
150
151 protected Logger log;
152
153 private SPFChecker spfChecker;
154
155 private MacroExpand macroExpand;
156
157
158
159
160 public DNSLookupContinuation checkSPF(SPFSession spfData) throws PermErrorException, TempErrorException, NoneException, NeutralException {
161
162 spfData.increaseCurrentDepth();
163
164 SPFChecker cleanupAndResultHandler = new CleanupAndResultChecker().init(spfData);
165 spfData.pushChecker(cleanupAndResultHandler);
166
167 spfData.pushChecker(new ExpandedChecker());
168 return macroExpand.checkExpand(getHost(), spfData, MacroExpand.DOMAIN);
169 }
170
171
172
173
174 public synchronized void config(Configuration params) throws PermErrorException {
175 if (params.groupCount() == 0) {
176 throw new PermErrorException("Include mechanism without an host");
177 }
178 host = params.group(1);
179 }
180
181
182
183
184 protected synchronized String getHost() {
185 return host;
186 }
187
188
189
190
191 public void enableLogging(Logger logger) {
192 this.log = logger;
193 }
194
195
196
197
198 public String toString() {
199 return "include:"+getHost();
200 }
201
202
203
204
205 public void enableSPFChecking(SPFChecker checker) {
206 this.spfChecker = checker;
207 }
208
209
210
211
212 public void enableMacroExpand(MacroExpand macroExpand) {
213 this.macroExpand = macroExpand;
214 }
215 }