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
48 private int timeOut = 20;
49
50
51 private Logger log;
52
53
54 private int recordLimit;
55
56 /***
57 * Default Constructor
58 */
59 public DNSServiceXBillImpl(Logger logger) {
60 this.log = logger;
61
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
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:
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
186 log.debug("No "+recordTypeDescription+" Record found for host: " + hostname);
187 records = null;
188 }
189 return records;
190 }
191
192 }