1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.james.smtpserver.core.filter.fastfail;
21
22 import java.net.UnknownHostException;
23 import java.util.ArrayList;
24 import java.util.Collection;
25 import java.util.Iterator;
26
27
28 import org.apache.avalon.framework.configuration.Configuration;
29 import org.apache.avalon.framework.configuration.ConfigurationException;
30 import org.apache.avalon.framework.service.ServiceException;
31 import org.apache.avalon.framework.service.ServiceManager;
32 import org.apache.avalon.framework.service.Serviceable;
33 import org.apache.james.api.dnsservice.DNSService;
34 import org.apache.james.api.dnsservice.TemporaryResolutionException;
35 import org.apache.james.api.dnsservice.util.NetMatcher;
36 import org.apache.james.dsn.DSNStatus;
37 import org.apache.james.smtpserver.CommandHandler;
38 import org.apache.james.smtpserver.SMTPSession;
39 import org.apache.mailet.MailAddress;
40
41
42
43
44
45 public class ValidRcptMX extends AbstractJunkHandler implements CommandHandler,
46 Serviceable {
47
48 private DNSService dnsServer = null;
49
50 private static final String LOCALHOST = "localhost";
51
52 private NetMatcher bNetwork = null;
53
54
55
56
57 public void configure(Configuration arg0) throws ConfigurationException {
58
59 Configuration[] badMX = arg0.getChildren("invalidMXNetworks");
60
61 if (badMX.length != 0) {
62
63 Collection bannedNetworks = new ArrayList();
64
65 for (int i = 0; i < badMX.length; i++) {
66 String network = badMX[i].getValue(null);
67
68 if (network != null) {
69 bannedNetworks.add(network);
70 }
71 }
72
73 setBannedNetworks(bannedNetworks, dnsServer);
74
75 getLogger().info("Invalid MX Networks: " + bNetwork.toString());
76
77 } else {
78 throw new ConfigurationException(
79 "Please configure at least on invalid MX network");
80 }
81
82 super.configure(arg0);
83 }
84
85
86
87
88
89
90
91 public void setBannedNetworks(Collection networks, DNSService dnsServer) {
92 bNetwork = new NetMatcher(networks, dnsServer) {
93 protected void log(String s) {
94 getLogger().debug(s);
95 }
96
97 };
98 }
99
100
101
102
103 public void service(ServiceManager arg0) throws ServiceException {
104 setDNSServer((DNSService) arg0.lookup(DNSService.ROLE));
105 }
106
107
108
109
110 public Collection getImplCommands() {
111 Collection c = new ArrayList();
112 c.add("RCPT");
113 return c;
114 }
115
116
117
118
119 public void onCommand(SMTPSession session) {
120 doProcessing(session);
121 }
122
123
124
125
126
127
128
129 public void setDNSServer(DNSService dnsServer) {
130 this.dnsServer = dnsServer;
131 }
132
133
134
135
136 protected boolean check(SMTPSession session) {
137 MailAddress rcpt = (MailAddress) session.getState().get(SMTPSession.CURRENT_RECIPIENT);
138
139 String domain = rcpt.getHost();
140
141
142 if (domain.equals(LOCALHOST)) return false;
143
144 Iterator mx = null;
145 try {
146 mx = dnsServer.findMXRecords(domain).iterator();
147 } catch (TemporaryResolutionException e1) {
148
149 }
150
151 if (mx != null && mx.hasNext()) {
152 while (mx.hasNext()) {
153 String mxRec = mx.next().toString();
154
155 try {
156 String ip = dnsServer.getByName(mxRec).getHostAddress();
157
158
159 if (bNetwork.matchInetNetwork(ip)) {
160 return true;
161 }
162 } catch (UnknownHostException e) {
163
164 }
165 }
166 }
167 return false;
168 }
169
170
171
172
173 public JunkHandlerData getJunkHandlerData(SMTPSession session) {
174 MailAddress rcpt = (MailAddress) session.getState().get(SMTPSession.CURRENT_RECIPIENT);
175 JunkHandlerData data = new JunkHandlerData();
176
177 data.setRejectResponseString("530" + DSNStatus.getStatus(DSNStatus.PERMANENT, DSNStatus.SECURITY_AUTH) + " Invalid MX " + session.getRemoteIPAddress()
178 + " for domain " + rcpt.getHost() + ". Reject email");
179
180 data.setJunkScoreLogString("Invalid MX " + session.getRemoteIPAddress() + " for domain " + rcpt.getHost() + ". Add JunkScore: " + getScore());
181 data.setRejectLogString("Invalid MX " + session.getRemoteIPAddress() + " for domain " + rcpt.getHost() + ". Reject email");
182 data.setScoreName("ValidRcptMXCheck");
183 return data;
184 }
185 }