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.core.filterchain.IoFilter;
    29  import org.apache.mina.core.filterchain.IoFilterAdapter;
    30  import org.apache.mina.core.session.IdleStatus;
    31  import org.apache.mina.core.session.IoSession;
    32  import org.apache.mina.core.write.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 <a href="http://mina.apache.org">Apache MINA Project</a>
    41   * @org.apache.xbean.XBean
    42   */
    43  public class BlacklistFilter extends IoFilterAdapter {
    44      private final List<Subnet> blacklist = new CopyOnWriteArrayList<Subnet>();
    45
    46      private final static Logger LOGGER = LoggerFactory.getLogger(BlacklistFilter.class);
    47
    48      /**
    49       * Sets the addresses to be blacklisted.
    50       *
    51       * NOTE: this call will remove any previously blacklisted addresses.
    52       *
    53       * @param addresses an array of addresses to be blacklisted.
    54       */
    55      public void setBlacklist(InetAddress[] addresses) {
    56          if (addresses == null) {
    57              throw new IllegalArgumentException("addresses");
    58          }
    59          blacklist.clear();
    60          for (int i = 0; i < addresses.length; i++) {
    61              InetAddress addr = addresses[i];
    62              block(addr);
    63          }
    64      }
    65
    66      /**
    67       * Sets the subnets to be blacklisted.
    68       *
    69       * NOTE: this call will remove any previously blacklisted subnets.
    70       *
    71       * @param subnets an array of subnets to be blacklisted.
    72       */
    73      public void setSubnetBlacklist(Subnet[] subnets) {
    74          if (subnets == null) {
    75              throw new IllegalArgumentException("Subnets must not be null");
    76          }
    77          blacklist.clear();
    78          for (Subnet subnet : subnets) {
    79              block(subnet);
    80          }
    81      }
    82
    83      /**
    84       * Sets the addresses to be blacklisted.
    85       *
    86       * NOTE: this call will remove any previously blacklisted addresses.
    87       *
    88       * @param addresses a collection of InetAddress objects representing the
    89       *        addresses to be blacklisted.
    90       * @throws IllegalArgumentException if the specified collections contains
    91       *         non-{@link InetAddress} objects.
    92       */
    93      public void setBlacklist(Iterable<InetAddress> addresses) {
    94          if (addresses == null) {
    95              throw new IllegalArgumentException("addresses");
    96          }
    97
    98          blacklist.clear();
    99
    100         for (InetAddress address : addresses) {
    101             block(address);
    102         }
    103     }
    104
    105     /**
    106      * Sets the subnets to be blacklisted.
    107      *
    108      * NOTE: this call will remove any previously blacklisted subnets.
    109      *
    110      * @param subnets an array of subnets to be blacklisted.
    111      */
    112     public void setSubnetBlacklist(Iterable<Subnet> subnets) {
    113         if (subnets == null) {
    114             throw new IllegalArgumentException("Subnets must not be null");
    115         }
    116         blacklist.clear();
    117         for (Subnet subnet : subnets) {
    118             block(subnet);
    119         }
    120     }
    121
    122     /**
    123      * Blocks the specified endpoint.
    124      */
    125     public void block(InetAddress address) {
    126         if (address == null) {
    127             throw new IllegalArgumentException("Adress to block can not be null");
    128         }
    129
    130         block(new Subnet(address, 32));
    131     }
    132
    133     /**
    134      * Blocks the specified subnet.
    135      */
    136     public void block(Subnet subnet) {
    137         if (subnet == null) {
    138             throw new IllegalArgumentException("Subnet can not be null");
    139         }
    140
    141         blacklist.add(subnet);
    142     }
    143
    144     /**
    145      * Unblocks the specified endpoint.
    146      */
    147     public void unblock(InetAddress address) {
    148         if (address == null) {
    149             throw new IllegalArgumentException("Adress to unblock can not be null");
    150         }
    151
    152         unblock(new Subnet(address, 32));
    153     }
    154
    155     /**
    156      * Unblocks the specified subnet.
    157      */
    158     public void unblock(Subnet subnet) {
    159         if (subnet == null) {
    160             throw new IllegalArgumentException("Subnet can not be null");
    161         }
    162         blacklist.remove(subnet);
    163     }
    164
    165     @Override
    166     public void sessionCreated(NextFilter nextFilter, IoSession session) {
    167         if (!isBlocked(session)) {
    168             // forward if not blocked
    169             nextFilter.sessionCreated(session);
    170         } else {
    171             blockSession(session);
    172         }
    173     }
    174
    175     @Override
    176     public void sessionOpened(NextFilter nextFilter, IoSession session) throws Exception {
    177         if (!isBlocked(session)) {
    178             // forward if not blocked
    179             nextFilter.sessionOpened(session);
    180         } else {
    181             blockSession(session);
    182         }
    183     }
    184
    185     @Override
    186     public void sessionClosed(NextFilter nextFilter, IoSession session) throws Exception {
    187         if (!isBlocked(session)) {
    188             // forward if not blocked
    189             nextFilter.sessionClosed(session);
    190         } else {
    191             blockSession(session);
    192         }
    193     }
    194
    195     @Override
    196     public void sessionIdle(NextFilter nextFilter, IoSession session, IdleStatus status) throws Exception {
    197         if (!isBlocked(session)) {
    198             // forward if not blocked
    199             nextFilter.sessionIdle(session, status);
    200         } else {
    201             blockSession(session);
    202         }
    203     }
    204
    205     @Override
    206     public void messageReceived(NextFilter nextFilter, IoSession session, Object message) {
    207         if (!isBlocked(session)) {
    208             // forward if not blocked
    209             nextFilter.messageReceived(session, message);
    210         } else {
    211             blockSession(session);
    212         }
    213     }
    214
    215     @Override
    216     public void messageSent(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws Exception {
    217         if (!isBlocked(session)) {
    218             // forward if not blocked
    219             nextFilter.messageSent(session, writeRequest);
    220         } else {
    221             blockSession(session);
    222         }
    223     }
    224
    225     private void blockSession(IoSession session) {
    226         LOGGER.warn("Remote address in the blacklist; closing.");
    227         session.close(true);
    228     }
    229
    230     private boolean isBlocked(IoSession session) {
    231         SocketAddress remoteAddress = session.getRemoteAddress();
    232         if (remoteAddress instanceof InetSocketAddress) {
    233             InetAddress address = ((InetSocketAddress) remoteAddress).getAddress();
    234
    235             // check all subnets
    236             for (Subnet subnet : blacklist) {
    237                 if (subnet.inSubnet(address)) {
    238                     return true;
    239                 }
    240             }
    241         }
    242
    243         return false;
    244     }
    245 }