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.mina.filter.firewall;
21  
22  import java.net.InetAddress;
23  import java.net.InetSocketAddress;
24  import java.net.SocketAddress;
25  import java.util.List;
26  import java.util.concurrent.CopyOnWriteArrayList;
27  
28  import org.apache.mina.common.IdleStatus;
29  import org.apache.mina.common.IoFilter;
30  import org.apache.mina.common.IoFilterAdapter;
31  import org.apache.mina.common.IoSession;
32  import org.apache.mina.common.WriteRequest;
33  import org.slf4j.Logger;
34  import org.slf4j.LoggerFactory;
35  
36  /**
37   * A {@link IoFilter} which blocks connections from blacklisted remote
38   * address.
39   *
40   * @author The Apache MINA Project (dev@mina.apache.org)
41   * @version $Rev: 616100 $, $Date: 2008-01-28 15:58:32 -0700 (Mon, 28 Jan 2008) $
42   */
43  public class BlacklistFilter extends IoFilterAdapter {
44      private final List<InetAddress> blacklist = new CopyOnWriteArrayList<InetAddress>();
45  
46      private final Logger logger = LoggerFactory.getLogger(getClass());
47      /**
48       * Sets the addresses to be blacklisted.
49       *
50       * NOTE: this call will remove any previously blacklisted addresses.
51       *
52       * @param addresses an array of addresses to be blacklisted.
53       */
54      public void setBlacklist(InetAddress[] addresses) {
55          if (addresses == null) {
56              throw new NullPointerException("addresses");
57          }
58          blacklist.clear();
59          for (int i = 0; i < addresses.length; i++) {
60              InetAddress addr = addresses[i];
61              block(addr, "addresses[" + i + ']');
62          }
63      }
64  
65      /**
66       * Sets the addresses to be blacklisted.
67       *
68       * NOTE: this call will remove any previously blacklisted addresses.
69       *
70       * @param addresses a collection of InetAddress objects representing the
71       *        addresses to be blacklisted.
72       * @throws IllegalArgumentException if the specified collections contains
73       *         non-{@link InetAddress} objects.
74       */
75      public void setBlacklist(Iterable<InetAddress> addresses) {
76          if (addresses == null) {
77              throw new NullPointerException("addresses");
78          }
79  
80          blacklist.clear();
81          
82          for( InetAddress address : addresses ){
83              block( address, address.getHostName() );
84          }
85      }
86  
87      /**
88       * Blocks the specified endpoint.
89       */
90      public void block(InetAddress address, String error_string) {
91          if (address == null) {
92              throw new NullPointerException(error_string);
93          }
94          blacklist.add(address);
95      }
96  
97      /**
98       * Blocks the specified endpoint.
99       */
100     public void block(InetAddress address) {
101         block(address, "address");
102     }
103 
104     /**
105      * Unblocks the specified endpoint.
106      */
107     public void unblock(InetAddress address) {
108         if (address == null) {
109             throw new NullPointerException("address");
110         }
111         blacklist.remove(address);
112     }
113 
114     @Override
115     public void sessionCreated(NextFilter nextFilter, IoSession session) {
116         if (!isBlocked(session)) {
117             // forward if not blocked
118             nextFilter.sessionCreated(session);
119         } else {
120             blockSession(session);
121         }
122     }
123 
124     @Override
125     public void sessionOpened(NextFilter nextFilter, IoSession session)
126             throws Exception {
127         if (!isBlocked(session)) {
128             // forward if not blocked
129             nextFilter.sessionOpened(session);
130         } else {
131             blockSession(session);
132         }
133     }
134 
135     @Override
136     public void sessionClosed(NextFilter nextFilter, IoSession session)
137             throws Exception {
138         if (!isBlocked(session)) {
139             // forward if not blocked
140             nextFilter.sessionClosed(session);
141         } else {
142             blockSession(session);
143         }
144     }
145 
146     @Override
147     public void sessionIdle(NextFilter nextFilter, IoSession session,
148             IdleStatus status) throws Exception {
149         if (!isBlocked(session)) {
150             // forward if not blocked
151             nextFilter.sessionIdle(session, status);
152         } else {
153             blockSession(session);
154         }
155     }
156 
157     @Override
158     public void messageReceived(NextFilter nextFilter, IoSession session,
159             Object message) {
160         if (!isBlocked(session)) {
161             // forward if not blocked
162             nextFilter.messageReceived(session, message);
163         } else {
164             blockSession(session);
165         }
166     }
167 
168     @Override
169     public void messageSent(NextFilter nextFilter, IoSession session,
170             WriteRequest writeRequest) throws Exception {
171         if (!isBlocked(session)) {
172             // forward if not blocked
173             nextFilter.messageSent(session, writeRequest);
174         } else {
175             blockSession(session);
176         }
177     }
178 
179     private void blockSession(IoSession session) {
180         logger.warn("Remote address in the blacklist; closing.");
181         session.close();
182     }
183 
184     private boolean isBlocked(IoSession session) {
185         SocketAddress remoteAddress = session.getRemoteAddress();
186         if (remoteAddress instanceof InetSocketAddress) {
187             if (blacklist.contains(((InetSocketAddress) remoteAddress)
188                     .getAddress())) {
189                 return true;
190             }
191         }
192 
193         return false;
194     }
195 }