View Javadoc

1   package org.apache.james.jspf.policies;
2   
3   import org.apache.james.jspf.core.DNSService;
4   import org.apache.james.jspf.core.SPF1Constants;
5   import org.apache.james.jspf.core.SPF1Record;
6   import org.apache.james.jspf.exceptions.NeutralException;
7   import org.apache.james.jspf.exceptions.NoneException;
8   import org.apache.james.jspf.exceptions.PermErrorException;
9   import org.apache.james.jspf.exceptions.TempErrorException;
10  
11  import java.util.Iterator;
12  import java.util.List;
13  
14  /***
15   * Get the raw dns txt or spf entry which contains a spf entry
16   */
17  public class SPFRetriever implements Policy {
18      /***
19       * dns service
20       */
21      private final DNSService dns;
22  
23  
24      /***
25       * A new instance of the SPFRetriever
26       * 
27       * @param dns the dns service
28       */
29      public SPFRetriever(DNSService dns) {
30          this.dns = dns;
31      }
32  
33  
34      /***
35       * @see org.apache.james.jspf.policies.Policy#getSPFRecord(java.lang.String)
36       */
37      public SPF1Record getSPFRecord(String currentDomain) throws PermErrorException, TempErrorException, NoneException, NeutralException {
38          // retrieve the SPFRecord
39          String spfDnsEntry = retrieveSpfRecord(currentDomain);
40          if (spfDnsEntry != null) {
41              return new SPF1Record(spfDnsEntry);
42          } else {
43              return null;
44          }
45      }
46  
47      /***
48       * Get the SPF-Record for a server
49       * 
50       * @param dns
51       *            The dns service to query
52       * @param hostname
53       *            The hostname for which we want to retrieve the SPF-Record
54       * @param spfVersion
55       *            The SPF-Version which should used.
56       * @return The SPF-Record if one is found.
57       * @throws PermErrorException
58       *             if more then one SPF-Record was found.
59       * @throws TempErrorException
60       *             if the lookup result was "TRY_AGAIN"
61       */
62      protected String retrieveSpfRecord(String hostname)
63              throws PermErrorException, TempErrorException {
64  
65          try {
66              // first check for SPF-Type records
67              List spfR = dns.getRecords(hostname, DNSService.SPF);
68              
69              if (spfR == null || spfR.isEmpty()) {
70                  // do DNS lookup for TXT
71                  spfR = dns.getRecords(hostname, DNSService.TXT);
72              }
73      
74              // process returned records
75              if (spfR != null && !spfR.isEmpty()) {
76                  return extractSPFRecord(spfR);
77              } else {
78                  return null;
79              }
80          } catch (DNSService.TimeoutException e) {
81              throw new TempErrorException("Timeout querying dns");
82          }
83      }
84      
85      /***
86       * Return the extracted SPF-Record 
87       *  
88       * @param spfR the List which holds TXT/SPF - Records
89       * @return returnValue the extracted SPF-Record
90       * @throws PermErrorException if more then one SPF - Record was found in the 
91       *                            given List.
92       */
93      protected String extractSPFRecord(List spfR) throws PermErrorException {
94         String returnValue = null;
95          Iterator all = spfR.iterator();
96             
97          while (all.hasNext()) {
98              // DO NOT trim the result!
99              String compare = all.next().toString();
100 
101             // TODO is this correct? we remove the first and last char if the
102             // result has an initial " 
103             // remove '"'
104             if (compare.charAt(0)=='"') {
105                 compare = compare.toLowerCase().substring(1,
106                         compare.length() - 1);
107             }
108 
109             // We trim the compare value only for the comparison
110             if (compare.toLowerCase().trim().startsWith(SPF1Constants.SPF_VERSION + " ") || compare.trim().equalsIgnoreCase(SPF1Constants.SPF_VERSION)) {
111                 if (returnValue == null) {
112                     returnValue = compare;
113                 } else {
114                     throw new PermErrorException(
115                             "More than 1 SPF record found");
116                 }
117             }
118         }
119         
120         return returnValue;
121     }
122     
123 
124     /***
125      * Return the DNSService
126      * 
127      * @return the dns
128      */
129     protected DNSService getDNSService() {
130         return dns;
131     }
132 
133 
134 }