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.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.SPF1Record;
26  import org.apache.james.jspf.core.SPF1Utils;
27  import org.apache.james.jspf.core.SPFCheckerDNSResponseListener;
28  import org.apache.james.jspf.core.SPFSession;
29  import org.apache.james.jspf.core.exceptions.NeutralException;
30  import org.apache.james.jspf.core.exceptions.NoneException;
31  import org.apache.james.jspf.core.exceptions.PermErrorException;
32  import org.apache.james.jspf.core.exceptions.TempErrorException;
33  import org.apache.james.jspf.core.exceptions.TimeoutException;
34  
35  import java.util.List;
36  
37  /**
38   * Get the raw dns txt or spf entry which contains a spf entry. If a domain
39   * publish both, and both are not equals it throws a PermError
40   */
41  public class SPFStrictCheckerRetriever extends SPFRetriever {
42  
43  
44      private static final String ATTRIBUTE_SPFSTRICT_CHECK_SPFRECORDS = "SPFStrictCheck.SPFRecords";
45      
46      private static final class SPFStrictSPFRecordsDNSResponseListener implements SPFCheckerDNSResponseListener {
47  
48          /**
49           * @see org.apache.james.jspf.core.SPFCheckerDNSResponseListener#onDNSResponse(org.apache.james.jspf.core.DNSResponse, org.apache.james.jspf.core.SPFSession)
50           */
51          public DNSLookupContinuation onDNSResponse(
52                  DNSResponse response, SPFSession session)
53                  throws PermErrorException,
54                  NoneException, TempErrorException,
55                  NeutralException {
56              
57              List spfR = (List) session.getAttribute(ATTRIBUTE_SPFSTRICT_CHECK_SPFRECORDS);
58              List spfTxtR = null;
59              try {
60                  spfTxtR = response.getResponse();
61              } catch (TimeoutException e) {
62                  throw new TempErrorException("Timeout querying dns");
63              }
64  
65              String record = calculateSpfRecord(spfR, spfTxtR);
66              if (record != null) {
67                  session.setAttribute(SPF1Utils.ATTRIBUTE_SPF1_RECORD, new SPF1Record(record));
68              }
69  
70              return null;
71              
72          }
73          
74      }
75      
76      
77      private static final class SPFStrictCheckDNSResponseListener implements SPFCheckerDNSResponseListener {
78  
79          /**
80           * @see org.apache.james.jspf.core.SPFCheckerDNSResponseListener#onDNSResponse(org.apache.james.jspf.core.DNSResponse, org.apache.james.jspf.core.SPFSession)
81           */
82          public DNSLookupContinuation onDNSResponse(
83                  DNSResponse response, SPFSession session)
84                  throws PermErrorException, NoneException,
85                  TempErrorException, NeutralException {
86              try {
87                  List spfR = response.getResponse();
88                  
89                  session.setAttribute(ATTRIBUTE_SPFSTRICT_CHECK_SPFRECORDS, spfR);
90                  
91                  String currentDomain = session.getCurrentDomain();
92                  return new DNSLookupContinuation(new DNSRequest(currentDomain, DNSRequest.TXT), new SPFStrictSPFRecordsDNSResponseListener());
93                      
94              } catch (TimeoutException e) {
95                  throw new TempErrorException("Timeout querying dns");
96              }
97          }
98          
99          
100     }
101 
102 
103     /**
104      * @see org.apache.james.jspf.policies.SPFRetriever#checkSPF(org.apache.james.jspf.core.SPFSession)
105      */
106     public DNSLookupContinuation checkSPF(SPFSession spfData)
107             throws PermErrorException, TempErrorException, NeutralException,
108             NoneException {
109         SPF1Record res = (SPF1Record) spfData.getAttribute(SPF1Utils.ATTRIBUTE_SPF1_RECORD);
110         if (res == null) {
111             String currentDomain = spfData.getCurrentDomain();
112 
113             return new DNSLookupContinuation(new DNSRequest(currentDomain, DNSRequest.SPF), new SPFStrictCheckDNSResponseListener());
114             
115         }
116         return null;
117     }
118 
119 
120     private static String calculateSpfRecord(List spfR, List spfTxtR)
121             throws PermErrorException {
122         String spfR1 = null;
123         String spfR2 = null;
124         if (spfR != null) spfR1 = extractSPFRecord(spfR);
125         if (spfTxtR != null) spfR2 = extractSPFRecord(spfTxtR);
126         
127         if (spfR1 != null && spfR2 == null) {
128             return spfR1;
129         } else if (spfR1 == null && spfR2 != null) {
130             return spfR2;
131         } else if (spfR1 != null && spfR2 != null) {
132             if (spfR1.toLowerCase().equals(spfR2.toLowerCase()) == false) {
133                 throw new PermErrorException("Published SPF records not equals");
134             } else {
135                 return spfR1;
136             }
137         } else {
138             return null;
139         }
140     }
141 }