Author: ngn
Date: Wed Mar 19 01:48:28 2008
New Revision: 638749

URL: http://svn.apache.org/viewvc?rev=638749&view=rev
Log:
Replacing range blocking with subnet blocking (DIRMINA-556)

Added:
    mina/trunk/core/src/main/java/org/apache/mina/filter/firewall/Subnet.java
    
mina/trunk/core/src/test/java/org/apache/mina/filter/firewall/SubnetIPv4Test.java
    
mina/trunk/core/src/test/java/org/apache/mina/filter/firewall/SubnetIPv6Test.java
Removed:
    
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=638749&r1=638748&r2=638749&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 19 01:48:28 2008
@@ -41,8 +41,7 @@
  * @version $Rev$, $Date$
  */
 public class BlacklistFilter extends IoFilterAdapter {
-       private final List<InetAddress> blacklist = new 
CopyOnWriteArrayList<InetAddress>();
-    private final List<InetAddressRange> rangeBlacklist = new 
CopyOnWriteArrayList<InetAddressRange>();
+    private final List<Subnet> blacklist = new CopyOnWriteArrayList<Subnet>();
 
     private final Logger logger = LoggerFactory.getLogger(getClass());
     /**
@@ -59,24 +58,24 @@
         blacklist.clear();
         for (int i = 0; i < addresses.length; i++) {
             InetAddress addr = addresses[i];
-            block(addr, "addresses[" + i + ']');
+            block(addr);
         }
     }
 
     /**
-     * Sets the address ranges to be blacklisted.
+     * Sets the subnets to be blacklisted.
      *
-     * NOTE: this call will remove any previously blacklisted ranges.
+     * NOTE: this call will remove any previously blacklisted subnets.
      *
-     * @param ranges an array of address ranges to be blacklisted.
+     * @param subnets an array of subnets to be blacklisted.
      */
-    public void setRangeBlacklist(InetAddressRange[] ranges) {
-        if (ranges == null) {
-            throw new NullPointerException("Ranges must not be null");
+    public void setSubnetBlacklist(Subnet[] subnets) {
+        if (subnets == null) {
+            throw new NullPointerException("Subnets must not be null");
         }
-        rangeBlacklist.clear();
-        for (InetAddressRange range : ranges) {
-            block(range);
+        blacklist.clear();
+        for (Subnet subnet : subnets) {
+            block(subnet);
         }
     }
     
@@ -98,53 +97,47 @@
         blacklist.clear();
         
         for( InetAddress address : addresses ){
-            block( address, address.getHostName() );
+            block(address);
         }
     }
 
     /**
-     * Sets the address ranges to be blacklisted.
+     * Sets the subnets to be blacklisted.
      *
-     * NOTE: this call will remove any previously blacklisted ranges.
+     * NOTE: this call will remove any previously blacklisted subnets.
      *
-     * @param ranges an array of address ranges to be blacklisted.
+     * @param subnets an array of subnets 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);
+    public void setSubnetBlacklist(Iterable<Subnet> subnets) {
+        if (subnets == null) {
+            throw new NullPointerException("Subnets must not be null");
         }
-    }
-    
-    /**
-     * Blocks the specified endpoint.
-     */
-    public void block(InetAddress address, String error_string) {
-        if (address == null) {
-            throw new NullPointerException(error_string);
+        blacklist.clear();
+        for (Subnet subnet : subnets) {
+            block(subnet);
         }
-        blacklist.add(address);
     }
 
     /**
      * Blocks the specified endpoint.
      */
     public void block(InetAddress address) {
-       block(address, "address");
+       if (address == null) {
+               throw new NullPointerException("Adress to block can not be 
null");
+       }
+
+       block(new Subnet(address, 32));
     }
 
     /**
-     * Blocks the specified range.
+     * Blocks the specified subnet.
      */
-    public void block(InetAddressRange range) {
-       if(range == null) {
-               throw new NullPointerException("Range can not be null");
+    public void block(Subnet subnet) {
+       if(subnet == null) {
+               throw new NullPointerException("Subnet can not be null");
        }
        
-        rangeBlacklist.add(range);
+        blacklist.add(subnet);
     }
     
     /**
@@ -152,19 +145,20 @@
      */
     public void unblock(InetAddress address) {
        if (address == null) {
-               throw new NullPointerException("address");
+               throw new NullPointerException("Adress to unblock can not be 
null");
        }
-       blacklist.remove(address);
+       
+       unblock(new Subnet(address, 32));
     }
 
     /**
-     * Unblocks the specified range.
+     * Unblocks the specified subnet.
      */
-    public void unblock(InetAddressRange range) {
-        if (range == null) {
-            throw new NullPointerException("Range can not be null");
+    public void unblock(Subnet subnet) {
+        if (subnet == null) {
+            throw new NullPointerException("Subnet can not be null");
         }
-        rangeBlacklist.remove(range);
+        blacklist.remove(subnet);
     }
 
     @Override
@@ -241,13 +235,10 @@
         SocketAddress remoteAddress = session.getRemoteAddress();
         if (remoteAddress instanceof InetSocketAddress) {
                InetAddress address = ((InetSocketAddress) 
remoteAddress).getAddress(); 
-            if (blacklist.contains(address)) {
-                return true;
-            } 
             
-            // check all ranges
-            for(InetAddressRange range : rangeBlacklist) {
-               if(range.contains(address)) {
+            // check all subnets
+            for(Subnet subnet : blacklist) {
+               if(subnet.inSubnet(address)) {
                        return true;
                }
             }

Added: mina/trunk/core/src/main/java/org/apache/mina/filter/firewall/Subnet.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/core/src/main/java/org/apache/mina/filter/firewall/Subnet.java?rev=638749&view=auto
==============================================================================
--- mina/trunk/core/src/main/java/org/apache/mina/filter/firewall/Subnet.java 
(added)
+++ mina/trunk/core/src/main/java/org/apache/mina/filter/firewall/Subnet.java 
Wed Mar 19 01:48:28 2008
@@ -0,0 +1,122 @@
+/*
+ *  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;
+
+/**
+ * A IP subnet using the CIDR notation. Currently, only IP version 4
+ * address are supported.
+ *
+ * @author The Apache MINA Project ([EMAIL PROTECTED])
+ * @version $Rev: 636538 $, $Date: 2008-03-12 22:19:27 +0000 (Wed, 12 Mar 
2008) $
+ */
+public class Subnet {
+
+       private static final int IP_MASK = 0x80000000;
+       private static final int BYTE_MASK = 0xFF;
+
+       private InetAddress subnet;
+       private int subnetInt;
+       private int subnetMask;
+       private int suffix;
+
+       /**
+        * Creates a subnet from CIDR notation. For example, the subnet
+        * 192.168.0.0/24 would be created using the [EMAIL PROTECTED] 
InetAddress}  
+        * 192.168.0.0 and the mask 24.
+        * @param subnet The [EMAIL PROTECTED] InetAddress} of the subnet
+        * @param mask The mask
+        */
+       public Subnet(InetAddress subnet, int mask) {
+               if(subnet == null) {
+                       throw new NullPointerException("Subnet address can not 
be null");
+               }
+               if(!(subnet instanceof Inet4Address)) {
+                       throw new IllegalArgumentException("Only IPv4 
supported");
+               }
+
+               if(mask < 0 || mask > 32) {
+                       throw new IllegalArgumentException("Mask has to be an 
integer between 0 and 32");
+               }
+               
+               this.subnet = subnet;
+               this.subnetInt = toInt(subnet);
+               this.suffix = mask;
+               
+               // binary mask for this subnet
+               this.subnetMask = IP_MASK >> (mask - 1);
+       }
+
+       /** 
+        * Converts an IP address into an integer
+        */ 
+       private int toInt(InetAddress inetAddress) {
+               byte[] address = inetAddress.getAddress();
+               int result = 0;
+               for (int i = 0; i < address.length; i++) {
+                       result <<= 8;
+                       result |= address[i] & BYTE_MASK;
+               }
+               return result;
+       }
+
+       /**
+        * Converts an IP address to a subnet using the provided 
+        * mask
+        * @param address The address to convert into a subnet
+        * @return The subnet as an integer
+        */
+       private int toSubnet(InetAddress address) {
+               return toInt(address) & subnetMask;
+       }
+       
+       /**
+        * Checks if the [EMAIL PROTECTED] InetAddress} is within this subnet
+        * @param address The [EMAIL PROTECTED] InetAddress} to check
+        * @return True if the address is within this subnet, false otherwise
+        */
+       public boolean inSubnet(InetAddress address) {
+               return toSubnet(address) == subnetInt;
+       }
+
+       /**
+        * @see Object#toString()
+        */
+       @Override
+       public String toString() {
+               return subnet.getHostAddress() + "/" + suffix;
+       }
+
+       @Override
+       public boolean equals(Object obj) {
+               if(!(obj instanceof Subnet)) {
+                       return false;
+               }
+               
+               Subnet other = (Subnet) obj;
+               
+               return other.subnetInt == subnetInt && other.suffix == suffix;
+       }
+
+       
+}

Added: 
mina/trunk/core/src/test/java/org/apache/mina/filter/firewall/SubnetIPv4Test.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/core/src/test/java/org/apache/mina/filter/firewall/SubnetIPv4Test.java?rev=638749&view=auto
==============================================================================
--- 
mina/trunk/core/src/test/java/org/apache/mina/filter/firewall/SubnetIPv4Test.java
 (added)
+++ 
mina/trunk/core/src/test/java/org/apache/mina/filter/firewall/SubnetIPv4Test.java
 Wed Mar 19 01:48:28 2008
@@ -0,0 +1,98 @@
+/*
+ *  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.InetAddress;
+import java.net.UnknownHostException;
+
+import junit.framework.TestCase;
+
+public class SubnetIPv4Test extends TestCase {
+
+       public void test24() throws UnknownHostException {
+               InetAddress a = InetAddress.getByName("127.2.3.0");
+               InetAddress b = InetAddress.getByName("127.2.3.4");
+               InetAddress c = InetAddress.getByName("127.2.3.255");
+               InetAddress d = InetAddress.getByName("127.2.4.4");
+               
+               Subnet mask = new Subnet(a, 24);
+               
+               assertTrue(mask.inSubnet(a));
+               assertTrue(mask.inSubnet(b));
+               assertTrue(mask.inSubnet(c));
+               assertFalse(mask.inSubnet(d));
+       }
+
+       public void test16() throws UnknownHostException {
+               InetAddress a = InetAddress.getByName("127.2.0.0");
+               InetAddress b = InetAddress.getByName("127.2.3.4");
+               InetAddress c = InetAddress.getByName("127.2.129.255");
+               InetAddress d = InetAddress.getByName("127.3.4.4");
+               
+               Subnet mask = new Subnet(a, 16);
+               
+               assertTrue(mask.inSubnet(a));
+               assertTrue(mask.inSubnet(b));
+               assertTrue(mask.inSubnet(c));
+               assertFalse(mask.inSubnet(d));
+       }
+       
+       public void testSingleIp() throws UnknownHostException {
+               InetAddress a = InetAddress.getByName("127.2.3.4");
+               InetAddress b = InetAddress.getByName("127.2.3.3");
+               InetAddress c = InetAddress.getByName("127.2.3.255");
+               InetAddress d = InetAddress.getByName("127.2.3.0");
+               
+               Subnet mask = new Subnet(a, 32);
+               
+               assertTrue(mask.inSubnet(a));
+               assertFalse(mask.inSubnet(b));
+               assertFalse(mask.inSubnet(c));
+               assertFalse(mask.inSubnet(d));
+       }
+       
+       public void testToString() throws UnknownHostException {
+               InetAddress a = InetAddress.getByName("127.2.3.0");
+               Subnet mask = new Subnet(a, 24);
+               
+               assertEquals("127.2.3.0/24", mask.toString());
+       }
+
+       public void testToStringLiteral() throws UnknownHostException {
+               InetAddress a = InetAddress.getByName("localhost");
+               Subnet mask = new Subnet(a, 32);
+               
+               assertEquals("127.0.0.1/32", mask.toString());
+       }
+       
+       
+       public void testEquals() throws UnknownHostException {
+               Subnet a = new Subnet(InetAddress.getByName("127.2.3.4"), 32);
+               Subnet b = new Subnet(InetAddress.getByName("127.2.3.4"), 32);
+               Subnet c = new Subnet(InetAddress.getByName("127.2.3.5"), 32);
+               Subnet d = new Subnet(InetAddress.getByName("127.2.3.5"), 24);
+               
+               assertTrue(a.equals(b));
+               assertFalse(a.equals(c));
+               assertFalse(a.equals(d));
+               assertFalse(a.equals(null));
+       }
+}

Added: 
mina/trunk/core/src/test/java/org/apache/mina/filter/firewall/SubnetIPv6Test.java
URL: 
http://svn.apache.org/viewvc/mina/trunk/core/src/test/java/org/apache/mina/filter/firewall/SubnetIPv6Test.java?rev=638749&view=auto
==============================================================================
--- 
mina/trunk/core/src/test/java/org/apache/mina/filter/firewall/SubnetIPv6Test.java
 (added)
+++ 
mina/trunk/core/src/test/java/org/apache/mina/filter/firewall/SubnetIPv6Test.java
 Wed Mar 19 01:48:28 2008
@@ -0,0 +1,42 @@
+/*
+ *  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.Inet6Address;
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+import junit.framework.TestCase;
+
+public class SubnetIPv6Test extends TestCase {
+
+       public void testIPv6() throws UnknownHostException {
+               InetAddress a = 
InetAddress.getByName("1080:0:0:0:8:800:200C:417A");
+               
+               assertTrue(a instanceof Inet6Address);
+               try {
+                       new Subnet(a, 24);
+                       fail("IPv6 not supported");
+               } catch(IllegalArgumentException e) {
+                       // OK
+               }
+       }
+}


Reply via email to