Author: ngn
Date: Wed Mar 12 15:19:27 2008
New Revision: 636538

URL: http://svn.apache.org/viewvc?rev=636538&view=rev
Log:
Adding support for blocking IP ranges in the BlacklistFilter

Added:
    
mina/trunk/core/src/main/java/org/apache/mina/filter/firewall/InetAddressRange.java
    
mina/trunk/core/src/test/java/org/apache/mina/filter/firewall/InetAddressRangeTest.java
Modified:
    
mina/trunk/core/src/main/java/org/apache/mina/filter/firewall/BlacklistFilter.java

Modified: 
mina/trunk/core/src/main/java/org/apache/mina/filter/firewall/BlacklistFilter.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/filter/firewall/BlacklistFilter.java?rev=636538&r1=636537&r2=636538&view=diff
==============================================================================
--- 
mina/trunk/core/src/main/java/org/apache/mina/filter/firewall/BlacklistFilter.java
 (original)
+++ 
mina/trunk/core/src/main/java/org/apache/mina/filter/firewall/BlacklistFilter.java
 Wed Mar 12 15:19:27 2008
@@ -41,7 +41,8 @@
  * @version $Rev$, $Date$
  */
 public class BlacklistFilter extends IoFilterAdapter {
-    private final List<InetAddress> blacklist = new 
CopyOnWriteArrayList<InetAddress>();
+       private final List<InetAddress> blacklist = new 
CopyOnWriteArrayList<InetAddress>();
+    private final List<InetAddressRange> rangeBlacklist = new 
CopyOnWriteArrayList<InetAddressRange>();
 
     private final Logger logger = LoggerFactory.getLogger(getClass());
     /**
@@ -63,6 +64,23 @@
     }
 
     /**
+     * Sets the address ranges to be blacklisted.
+     *
+     * NOTE: this call will remove any previously blacklisted ranges.
+     *
+     * @param ranges an array of address ranges to be blacklisted.
+     */
+    public void setRangeBlacklist(InetAddressRange[] ranges) {
+        if (ranges == null) {
+            throw new NullPointerException("Ranges must not be null");
+        }
+        rangeBlacklist.clear();
+        for (InetAddressRange range : ranges) {
+            block(range);
+        }
+    }
+    
+    /**
      * Sets the addresses to be blacklisted.
      *
      * NOTE: this call will remove any previously blacklisted addresses.
@@ -85,6 +103,23 @@
     }
 
     /**
+     * Sets the address ranges to be blacklisted.
+     *
+     * NOTE: this call will remove any previously blacklisted ranges.
+     *
+     * @param ranges an array of address ranges to be blacklisted.
+     */
+    public void setRangeBlacklist(Iterable<InetAddressRange> ranges) {
+        if (ranges == null) {
+            throw new NullPointerException("Ranges must not be null");
+        }
+        rangeBlacklist.clear();
+        for (InetAddressRange range : ranges) {
+            block(range);
+        }
+    }
+    
+    /**
      * Blocks the specified endpoint.
      */
     public void block(InetAddress address, String error_string) {
@@ -98,17 +133,38 @@
      * Blocks the specified endpoint.
      */
     public void block(InetAddress address) {
-        block(address, "address");
+       block(address, "address");
     }
 
     /**
+     * Blocks the specified range.
+     */
+    public void block(InetAddressRange range) {
+       if(range == null) {
+               throw new NullPointerException("Range can not be null");
+       }
+       
+        rangeBlacklist.add(range);
+    }
+    
+    /**
      * Unblocks the specified endpoint.
      */
     public void unblock(InetAddress address) {
-        if (address == null) {
-            throw new NullPointerException("address");
+       if (address == null) {
+               throw new NullPointerException("address");
+       }
+       blacklist.remove(address);
+    }
+
+    /**
+     * Unblocks the specified range.
+     */
+    public void unblock(InetAddressRange range) {
+        if (range == null) {
+            throw new NullPointerException("Range can not be null");
         }
-        blacklist.remove(address);
+        rangeBlacklist.remove(range);
     }
 
     @Override
@@ -184,9 +240,16 @@
     private boolean isBlocked(IoSession session) {
         SocketAddress remoteAddress = session.getRemoteAddress();
         if (remoteAddress instanceof InetSocketAddress) {
-            if (blacklist.contains(((InetSocketAddress) remoteAddress)
-                    .getAddress())) {
+               InetAddress address = ((InetSocketAddress) 
remoteAddress).getAddress(); 
+            if (blacklist.contains(address)) {
                 return true;
+            } 
+            
+            // check all ranges
+            for(InetAddressRange range : rangeBlacklist) {
+               if(range.contains(address)) {
+                       return true;
+               }
             }
         }
 

Added: 
mina/trunk/core/src/main/java/org/apache/mina/filter/firewall/InetAddressRange.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/filter/firewall/InetAddressRange.java?rev=636538&view=auto
==============================================================================
--- 
mina/trunk/core/src/main/java/org/apache/mina/filter/firewall/InetAddressRange.java
 (added)
+++ 
mina/trunk/core/src/main/java/org/apache/mina/filter/firewall/InetAddressRange.java
 Wed Mar 12 15:19:27 2008
@@ -0,0 +1,121 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+
+package org.apache.mina.filter.firewall;
+
+import java.net.Inet4Address;
+import java.net.Inet6Address;
+import java.net.InetAddress;
+
+/**
+ * Represents a range of IP4 or IP6 addresses.
+ *
+ *
+ * @author The Apache MINA Project ([EMAIL PROTECTED])
+ * @version $Rev: 616100 $, $Date: 2008-01-28 23:58:32 +0100 (Mon, 28 Jan 
2008) $
+ */
+public class InetAddressRange {
+
+       private InetAddress lower;
+       private InetAddress upper;
+
+       /**
+        * Construct an IP range
+        * @param lower The lower [EMAIL PROTECTED] InetAddress}, must be an 
[EMAIL PROTECTED] Inet4Address} or [EMAIL PROTECTED] Inet6Address}
+        * @param upper The upper [EMAIL PROTECTED] InetAddress}, must be an 
[EMAIL PROTECTED] Inet4Address} or [EMAIL PROTECTED] Inet6Address}
+        * @throws IllegalArgumentException If the lower [EMAIL PROTECTED] 
InetAddress} is larger than the upper [EMAIL PROTECTED] InetAddress}
+        * @throws IllegalArgumentException Is not a [EMAIL PROTECTED] 
Inet4Address} or [EMAIL PROTECTED] Inet6Address}
+        * @throws IllegalArgumentException If lower and upper are of different 
types
+        * @throws NullPointerException If the lower or upper [EMAIL PROTECTED] 
InetAddress} is null
+        */
+       public InetAddressRange(InetAddress lower, InetAddress upper) {
+               if(lower == null) {
+                       throw new NullPointerException("Lower IP can not be 
null");
+               }
+               if(upper == null) {
+                       throw new NullPointerException("Upper IP can not be 
null");
+               }
+               if(!(lower instanceof Inet4Address || lower instanceof 
Inet6Address)) {
+                       throw new IllegalArgumentException("Lower address must 
be a Inet4Address or Inet6Address");
+               }
+               if(!(upper instanceof Inet4Address || upper instanceof 
Inet6Address)) {
+                       throw new IllegalArgumentException("Upper address must 
be a Inet4Address or Inet6Address");
+               }
+               if(!upper.getClass().equals(lower.getClass())) {
+                       throw new IllegalArgumentException("Lower and upper 
address must be of the same type");
+               }
+               
+               this.lower = lower;
+               this.upper = upper;
+
+               if (compare(lower, upper) > 0) {
+                       throw new IllegalArgumentException("Lower must be lower 
than upper");
+               }
+       }
+       
+       private int compare(InetAddress a1, InetAddress a2) {
+               byte[] b1 = a1.getAddress();
+               byte[] b2 = a2.getAddress();
+               
+               for (int i = 0; i < b1.length; i++) {
+                       if (b1[i] != b2[i]) {
+                               return (b1[i] & 0xff) - (b2[i] & 0xff);
+                       }
+               }
+               return 0;
+               
+       }
+
+       /**
+        * Get the lower IP of this range
+        * @return A [EMAIL PROTECTED] Inet4Address} or [EMAIL PROTECTED] 
Inet6Address}
+        */
+       public InetAddress getLower() {
+               return lower;
+       }
+
+       /**
+        * Get the upper IP of this range
+        * @return A [EMAIL PROTECTED] Inet4Address} or [EMAIL PROTECTED] 
Inet6Address}
+        */
+       public InetAddress getUpper() {
+               return upper;
+       }
+
+       /**
+        * Check if the [EMAIL PROTECTED] InetAddress} is within the range
+        * @param address The address to be checked against the range
+        * @return true if the address is within the range (inclusive)
+        * @throws NullPointerException If address is null
+        * @throws IllegalArgumentException If the address type differs from 
the range
+        */
+       public boolean contains(InetAddress address) {
+               if(address == null) {
+                       throw new NullPointerException("Address can not be 
null");
+               }
+               if(!address.getClass().equals(lower.getClass())) {
+                       throw new IllegalArgumentException("Address is not of 
the same InetAddress type as the range");
+               }
+               
+               
+               return compare(lower, address) <= 0 && compare(address, upper) 
<=0; 
+       }
+
+}

Added: 
mina/trunk/core/src/test/java/org/apache/mina/filter/firewall/InetAddressRangeTest.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/core/src/test/java/org/apache/mina/filter/firewall/InetAddressRangeTest.java?rev=636538&view=auto
==============================================================================
--- 
mina/trunk/core/src/test/java/org/apache/mina/filter/firewall/InetAddressRangeTest.java
 (added)
+++ 
mina/trunk/core/src/test/java/org/apache/mina/filter/firewall/InetAddressRangeTest.java
 Wed Mar 12 15:19:27 2008
@@ -0,0 +1,85 @@
+/*
+ *  Licensed to the Apache Software Foundation (ASF) under one
+ *  or more contributor license agreements.  See the NOTICE file
+ *  distributed with this work for additional information
+ *  regarding copyright ownership.  The ASF licenses this file
+ *  to you under the Apache License, Version 2.0 (the
+ *  "License"); you may not use this file except in compliance
+ *  with the License.  You may obtain a copy of the License at
+ *
+ *    http://www.apache.org/licenses/LICENSE-2.0
+ *
+ *  Unless required by applicable law or agreed to in writing,
+ *  software distributed under the License is distributed on an
+ *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ *  KIND, either express or implied.  See the License for the
+ *  specific language governing permissions and limitations
+ *  under the License.
+ *
+ */
+
+package org.apache.mina.filter.firewall;
+
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+import junit.framework.TestCase;
+
+
+public class InetAddressRangeTest extends TestCase {
+
+       public void testContainsInRangeIp4() throws UnknownHostException {
+               Inet4Address lower = (Inet4Address) 
InetAddress.getByName("1.2.2.4");
+               Inet4Address middle = (Inet4Address) 
InetAddress.getByName("1.2.3.5");
+               Inet4Address upper = (Inet4Address) 
InetAddress.getByName("1.2.4.6");
+               Inet4Address toSmall = (Inet4Address) 
InetAddress.getByName("1.2.1.6");
+               Inet4Address toLarge = (Inet4Address) 
InetAddress.getByName("1.2.155.6");
+               
+               InetAddressRange range = new InetAddressRange(lower, upper);
+               
+               assertTrue(range.contains(lower));
+               assertTrue(range.contains(middle));
+               assertTrue(range.contains(upper));
+               assertFalse(range.contains(toSmall));
+               assertFalse(range.contains(toLarge));
+       }
+
+       public void testContainsInRangeIpp() throws UnknownHostException {
+               InetAddress lower = 
InetAddress.getByName("2001:0db8:85a3:08d3:1319:8a2e:0370:7344");
+               InetAddress middle = 
InetAddress.getByName("2001:0db8:85a3:08d3:1319:8a2e:0470:1234");
+               InetAddress upper = 
InetAddress.getByName("2001:0db8:85a3:08d3:1319:9a2e:0370:7344");
+               InetAddress toSmall = 
InetAddress.getByName("1001:0db8:85a3:08d3:1319:8a2e:0370:7344");
+               InetAddress toLarge = 
InetAddress.getByName("2001:0db8:85b3:08d3:1319:8a2e:0370:7344");
+               
+               InetAddressRange range = new InetAddressRange(lower, upper);
+               
+               assertTrue(range.contains(lower));
+               assertTrue(range.contains(middle));
+               assertTrue(range.contains(upper));
+               assertFalse(range.contains(toSmall));
+               assertFalse(range.contains(toLarge));
+       }
+
+       public void testLowerEqualToUpper() throws UnknownHostException {
+               Inet4Address lower = (Inet4Address) 
InetAddress.getByName("1.2.3.4");
+               Inet4Address upper = (Inet4Address) 
InetAddress.getByName("1.2.3.4");
+               
+               InetAddressRange range = new InetAddressRange(lower, upper);
+               
+               assertTrue(range.contains(lower));
+               assertTrue(range.contains(upper));
+       }
+       
+       public void testLowerLargerThanUpper() throws UnknownHostException {
+               Inet4Address lower = (Inet4Address) 
InetAddress.getByName("1.2.3.5");
+               Inet4Address upper = (Inet4Address) 
InetAddress.getByName("1.2.3.4");
+               
+               try {
+                       new InetAddressRange(lower, upper);
+                       fail("Must throw IllegalArgumentException");
+               } catch(IllegalArgumentException e) {
+                       // OK
+               }
+       }
+}


Reply via email to