View Javadoc

1   /****************************************************************
2    * Licensed to the Apache Software Foundation (ASF) under one   *
3    * or more contributor license agreements.  See the NOTICE file *
4    * distributed with this work for additional information        *
5    * regarding copyright ownership.  The ASF licenses this file   *
6    * to you under the Apache License, Version 2.0 (the            *
7    * "License"); you may not use this file except in compliance   *
8    * with the License.  You may obtain a copy of the License at   *
9    *                                                              *
10   *   http://www.apache.org/licenses/LICENSE-2.0                 *
11   *                                                              *
12   * Unless required by applicable law or agreed to in writing,   *
13   * software distributed under the License is distributed on an  *
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
15   * KIND, either express or implied.  See the License for the    *
16   * specific language governing permissions and limitations      *
17   * under the License.                                           *
18   ****************************************************************/
19  
20  package org.apache.james.jspf.terms;
21  
22  import org.apache.james.jspf.core.DNSLookupContinuation;
23  import org.apache.james.jspf.core.MacroExpand;
24  import org.apache.james.jspf.core.MacroExpandEnabled;
25  import org.apache.james.jspf.core.SPFCheckEnabled;
26  import org.apache.james.jspf.core.SPFChecker;
27  import org.apache.james.jspf.core.SPFCheckerExceptionCatcher;
28  import org.apache.james.jspf.core.SPFSession;
29  import org.apache.james.jspf.core.SPFTermsRegexps;
30  import org.apache.james.jspf.core.exceptions.NeutralException;
31  import org.apache.james.jspf.core.exceptions.NoneException;
32  import org.apache.james.jspf.core.exceptions.PermErrorException;
33  import org.apache.james.jspf.core.exceptions.TempErrorException;
34  
35  /**
36   * This class represent the redirect modifier
37   * 
38   */
39  public class RedirectModifier extends GenericModifier implements
40          SPFCheckEnabled, MacroExpandEnabled {
41  
42      private final class ExpandedChecker implements SPFChecker {
43          
44          /**
45           * @see org.apache.james.jspf.core.SPFChecker#checkSPF(org.apache.james.jspf.core.SPFSession)
46           */
47          public DNSLookupContinuation checkSPF(SPFSession spfData)
48                  throws PermErrorException, NoneException,
49                  TempErrorException, NeutralException {
50              String host = getHost();
51  
52              // throws a PermErrorException that we can pass
53              // through
54              host = macroExpand.expand(host, spfData,
55                      MacroExpand.DOMAIN);
56  
57              spfData.setCurrentDomain(host);
58  
59              spfData.pushChecker(spfChecker);
60              return null;
61          }
62      }
63  
64      private final class CleanupChecker implements SPFChecker, SPFCheckerExceptionCatcher {
65        
66          /**
67          * @see org.apache.james.jspf.core.SPFChecker#checkSPF(org.apache.james.jspf.core.SPFSession)
68          */
69          public DNSLookupContinuation checkSPF(SPFSession spfData)
70                  throws PermErrorException, TempErrorException,
71                  NeutralException, NoneException {
72              // After the redirect we should not use the
73              // explanation from the orginal record
74              spfData.setIgnoreExplanation(true);
75              return null;
76          }
77          
78          /**
79           * @see org.apache.james.jspf.core.SPFCheckerExceptionCatcher#onException(java.lang.Exception, org.apache.james.jspf.core.SPFSession)
80           */
81          public void onException(Exception exception, SPFSession session)
82                  throws PermErrorException, NoneException,
83                  TempErrorException, NeutralException {
84              
85              session.setIgnoreExplanation(true);
86  
87              // remove every checker until the initialized one
88              
89              if (exception instanceof NeutralException) {
90                  throw new PermErrorException(
91                  "included checkSPF returned NeutralException");
92  
93              } else if (exception instanceof NoneException) {
94                  // no spf record assigned to the redirect domain
95                  throw new PermErrorException(
96                          "included checkSPF returned NoneException");
97              } else if (exception instanceof PermErrorException){
98                  throw (PermErrorException) exception;
99              } else if (exception instanceof TempErrorException){
100                 throw (TempErrorException) exception;
101             } else if (exception instanceof RuntimeException){
102                 throw (RuntimeException) exception;
103             } else {
104                 throw new IllegalStateException(exception.getMessage());
105             }
106         }
107     }
108 
109     /**
110      * ABNF: redirect = "redirect" "=" domain-spec
111      */
112     public static final String REGEX = "[rR][eE][dD][iI][rR][eE][cC][tT]"
113             + "\\=" + SPFTermsRegexps.DOMAIN_SPEC_REGEX;
114 
115     private SPFChecker spfChecker;
116 
117     private MacroExpand macroExpand;
118 
119     private SPFChecker cleanupChecker = new CleanupChecker();
120 
121     private SPFChecker expandedChecker = new ExpandedChecker();
122 
123     /**
124      * Set the host which should be used for redirection and set it in SPF1Data
125      * so it can be accessed easy later if needed
126      * 
127      * @param spfData
128      *            The SPF1Data which should used
129      * @return the result of this processing
130      * @throws PermErrorException
131      *             if an error is in the redirect modifier
132      * @throws TempErrorException
133      *             if an DNS problem accurred
134      * @throws NoneException
135      * @throws NeutralException
136      */
137     protected DNSLookupContinuation checkSPFLogged(SPFSession spfData)
138             throws PermErrorException, TempErrorException, NeutralException,
139             NoneException {
140         // the redirect modifier is used only when we had no previous matches
141         if (spfData.getCurrentResult() == null) {
142 
143             // update currentDepth
144             spfData.increaseCurrentDepth();
145             
146             spfData.pushChecker(cleanupChecker);
147             
148             spfData.pushChecker(expandedChecker);
149             return macroExpand.checkExpand(getHost(), spfData, MacroExpand.DOMAIN);
150         }
151         return null;
152     }
153 
154     /**
155      * @see java.lang.Object#toString()
156      */
157     public String toString() {
158         return "redirect=" + getHost();
159     }
160 
161     /**
162      * @see org.apache.james.jspf.core.SPFCheckEnabled#enableSPFChecking(org.apache.james.jspf.core.SPFChecker)
163      */
164     public void enableSPFChecking(SPFChecker checker) {
165         this.spfChecker = checker;
166     }
167 
168     /**
169      * @see org.apache.james.jspf.core.MacroExpandEnabled#enableMacroExpand(org.apache.james.jspf.core.MacroExpand)
170      */
171     public void enableMacroExpand(MacroExpand macroExpand) {
172         this.macroExpand = macroExpand;
173     }
174 
175 }