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  
21  
22  package org.apache.james.smtpserver.core.filter.fastfail;
23  
24  import java.util.ArrayList;
25  import java.util.Collection;
26  
27  import org.apache.avalon.framework.configuration.Configurable;
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.dsn.DSNStatus;
36  import org.apache.james.smtpserver.CommandHandler;
37  import org.apache.james.smtpserver.SMTPSession;
38  import org.apache.mailet.MailAddress;
39  
40  public class ValidSenderDomainHandler
41      extends AbstractJunkHandler
42      implements CommandHandler, Configurable, Serviceable {
43      
44      private boolean checkAuthClients = false;
45      
46      private DNSService dnsServer = null;
47  
48      
49      /**
50       * @see org.apache.avalon.framework.configuration.Configurable#configure(Configuration)
51       */
52      public void configure(Configuration handlerConfiguration) throws ConfigurationException {
53          
54          Configuration configRelay = handlerConfiguration.getChild("checkAuthClients",false);
55          if(configRelay != null) {
56              setCheckAuthClients(configRelay.getValueAsBoolean(false));
57          }
58          
59          super.configure(handlerConfiguration);
60      }
61      
62      /**
63       * @see org.apache.avalon.framework.service.Serviceable#service(ServiceManager)
64       */
65      public void service(ServiceManager serviceMan) throws ServiceException {
66          setDnsServer((DNSService) serviceMan.lookup(DNSService.ROLE));
67      }
68      
69      /**
70       * Set the DnsServer
71       * 
72       * @param dnsServer The DnsServer
73       */
74      public void setDnsServer(DNSService dnsServer) {
75          this.dnsServer = dnsServer;
76      }
77      
78      /**
79       * Enable checking of authorized clients
80       * 
81       * @param checkAuthClients Set to true to enable
82       */
83      public void setCheckAuthClients(boolean checkAuthClients) {
84          this.checkAuthClients = checkAuthClients;
85      }
86      
87      /**
88       * @see org.apache.james.smtpserver.CommandHandler#onCommand(SMTPSession)
89       */
90      public void onCommand(SMTPSession session) {
91          doProcessing(session);
92      }
93      
94      /**
95       * @see org.apache.james.smtpserver.core.filter.fastfail.AbstractJunkHandler#check(org.apache.james.smtpserver.SMTPSession)
96       */
97      protected boolean check(SMTPSession session) {
98          MailAddress senderAddress = (MailAddress) session.getState().get(SMTPSession.SENDER);
99              
100         // null sender so return
101         if (senderAddress == null) return false;
102             
103         /**
104          * don't check if the ip address is allowed to relay. Only check if it is set in the config. 
105          */
106         if (checkAuthClients || !session.isRelayingAllowed()) {
107             Collection records = null;
108             
109                 
110             // try to resolv the provided domain in the senderaddress. If it can not resolved do not accept it.
111             try {
112                 records = dnsServer.findMXRecords(senderAddress.getHost());
113             } catch (TemporaryResolutionException e) {
114                 // TODO: Should we reject temporary ?
115             }
116         
117             if (records == null || records.size() == 0) {
118                 session.getState().remove(SMTPSession.SENDER);
119                 return true;
120             }
121         }
122         return false;
123     }
124     
125     /**
126      * @see org.apache.james.smtpserver.CommandHandler#getImplCommands()
127      */
128     public Collection getImplCommands() {
129         Collection implCommands = new ArrayList();
130         implCommands.add("MAIL");
131         
132         return implCommands;
133     }
134     
135     /**
136      * @see org.apache.james.smtpserver.core.filter.fastfail.AbstractJunkHandler#getJunkHandlerData(org.apache.james.smtpserver.SMTPSession)
137      */
138     public JunkHandlerData getJunkHandlerData(SMTPSession session) {
139         MailAddress senderAddress = (MailAddress) session.getState().get(SMTPSession.SENDER);
140         JunkHandlerData data = new JunkHandlerData();
141     
142         data.setRejectResponseString("501 "+DSNStatus.getStatus(DSNStatus.PERMANENT,DSNStatus.ADDRESS_SYNTAX_SENDER)+ " sender " + senderAddress + " contains a domain with no valid MX records");
143         data.setJunkScoreLogString("Sender " + senderAddress + " contains a domain with no valid MX records. Add Junkscore: " + getScore());
144         data.setRejectLogString("Sender " + senderAddress + " contains a domain with no valid MX records");
145         data.setScoreName("ValidSenderDomainCheck");
146         return data;
147     }
148 }