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.impl;
21  
22  import java.net.InetAddress;
23  import java.net.UnknownHostException;
24  import java.util.ArrayList;
25  import java.util.List;
26  
27  import org.apache.james.jspf.core.DNSService;
28  import org.apache.james.jspf.core.IPAddr;
29  import org.apache.james.jspf.core.Logger;
30  import org.xbill.DNS.AAAARecord;
31  import org.xbill.DNS.ARecord;
32  import org.xbill.DNS.Lookup;
33  import org.xbill.DNS.MXRecord;
34  import org.xbill.DNS.PTRRecord;
35  import org.xbill.DNS.Record;
36  import org.xbill.DNS.SPFRecord;
37  import org.xbill.DNS.TXTRecord;
38  import org.xbill.DNS.TextParseException;
39  import org.xbill.DNS.Type;
40  
41  /***
42   * This class contains helper to get all neccassary DNS infos that are needed
43   * for SPF
44   */
45  public class DNSServiceXBillImpl implements DNSService {
46  
47      // Set seconds after which we return and TempError
48      private int timeOut = 20;
49  
50      // The logger
51      private Logger log;
52      
53      // The record limit for lookups
54      private int recordLimit;
55      
56      /***
57       * Default Constructor
58       */
59      public DNSServiceXBillImpl(Logger logger) {
60          this.log = logger;
61          // Default record limit is 10
62          this.recordLimit = 10;
63      }
64  
65      /***
66       * @see org.apache.james.jspf.core.DNSService#setTimeOut(int)
67       */
68      public synchronized void setTimeOut(int timeOut) {
69          this.timeOut = timeOut;
70      }
71  
72      /***
73       * @see org.apache.james.jspf.core.DNSService#getLocalDomainNames();
74       */
75      public List getLocalDomainNames() {
76          List names = new ArrayList();
77  
78          log.debug("Start Local ipaddress lookup");
79          try {
80              InetAddress ia[] = InetAddress.getAllByName(InetAddress
81                      .getLocalHost().getHostName());
82  
83              for (int i = 0; i < ia.length; i++) {
84                  String host = ia[i].getHostName();
85                  names.add(host);
86  
87                  log.debug("Add hostname " + host + " to list");
88              }
89          } catch (UnknownHostException e) {
90              // just ignore this..
91          }
92          return names;
93  
94      }
95  
96      /***
97       * @return the current record limit
98       */
99      public int getRecordLimit() {
100         return recordLimit;
101     }
102 
103     /***
104      * Set a new limit for the number of records for MX and PTR lookups.
105      * @param recordLimit
106      */
107     public void setRecordLimit(int recordLimit) {
108         this.recordLimit = recordLimit;
109     }
110     
111     /***
112      * @see org.apache.james.jspf.core.DNSService#getRecords(java.lang.String, int)
113      */
114     public List getRecords(String hostname, int recordType)
115             throws TimeoutException {
116         String recordTypeDescription;
117         int dnsJavaType;
118         int recordCount = 0;
119         switch (recordType) {
120             case A: recordTypeDescription = "A"; dnsJavaType = Type.A; break;
121             case AAAA: recordTypeDescription = "AAAA"; dnsJavaType = Type.AAAA; break;
122             case MX: recordTypeDescription = "MX"; dnsJavaType = Type.MX; break;
123             case PTR: recordTypeDescription = "PTR"; dnsJavaType = Type.PTR; break;
124             case TXT: recordTypeDescription = "TXT"; dnsJavaType = Type.TXT; break;
125             case SPF: recordTypeDescription= "SPF"; dnsJavaType = Type.SPF; break;
126             default: // TODO fail!
127                 return null;
128         }
129         List records;
130         try {
131 
132             log.debug("Start "+recordTypeDescription+"-Record lookup for : " + hostname);
133 
134             Lookup.getDefaultResolver().setTimeout(timeOut);
135             Lookup query = new Lookup(hostname, dnsJavaType);
136 
137             Record[] rr = query.run();
138             int queryResult = query.getResult();
139 
140             if (queryResult == Lookup.TRY_AGAIN) {
141                 throw new TimeoutException();
142             }
143             
144             if (rr != null && rr.length > 0) {
145                 records = new ArrayList();
146                 for (int i = 0; i < rr.length; i++) {
147                     String res;
148                     switch (recordType) {
149                         case A:
150                             ARecord a = (ARecord) rr[i];
151                             res = a.getAddress().getHostAddress();
152                             break;
153                         case AAAA:
154                             AAAARecord aaaa = (AAAARecord) rr[i];
155                             res = aaaa.getAddress().getHostAddress();
156                             break;
157                         case MX:
158                             MXRecord mx = (MXRecord) rr[i];
159                             res = mx.getTarget().toString();
160                             break;
161                         case PTR:
162                             PTRRecord ptr = (PTRRecord) rr[i];
163                             res = IPAddr.stripDot(ptr.getTarget().toString());
164                             break;
165                         case TXT:
166                             TXTRecord txt = (TXTRecord) rr[i];
167                             res = txt.rdataToString();
168                             break;
169                         case SPF:
170                             SPFRecord spf = (SPFRecord) rr[i];
171                             res = spf.rdataToString();
172                             break;
173                         default:
174                             return null;
175                     }
176                     records.add(res);
177                 }
178                 recordCount = rr.length;
179             } else {
180                 records = null;
181             }
182             
183             log.debug("Found " + recordCount + " "+recordTypeDescription+"-Records");
184         } catch (TextParseException e) {
185             // i think this is the best we could do
186             log.debug("No "+recordTypeDescription+" Record found for host: " + hostname);
187             records = null;
188         }
189         return records;
190     }
191 
192 }