Author: frm
Date: Wed Sep 14 11:43:26 2016
New Revision: 1760673

URL: http://svn.apache.org/viewvc?rev=1760673&view=rev
Log:
OAK-4801 - Test the behaviour of DNS resolution in ClientIpFilter

Contribution by Andrei Dulceanu.

Added:
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/AddressResolver.java
   (with props)
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/InetAddressResolver.java
   (with props)
    
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/server/ClientIPFilterHostnameTest.java
   (with props)
Modified:
    
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/ClientIpFilter.java

Added: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/AddressResolver.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/AddressResolver.java?rev=1760673&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/AddressResolver.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/AddressResolver.java
 Wed Sep 14 11:43:26 2016
@@ -0,0 +1,26 @@
+/*
+ * 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.jackrabbit.oak.segment.standby.server;
+
+import java.net.InetAddress;
+
+interface AddressResolver {
+
+    InetAddress resolve(String host);
+
+}

Propchange: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/AddressResolver.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/ClientIpFilter.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/ClientIpFilter.java?rev=1760673&r1=1760672&r2=1760673&view=diff
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/ClientIpFilter.java
 (original)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/ClientIpFilter.java
 Wed Sep 14 11:43:26 2016
@@ -20,22 +20,20 @@ package org.apache.jackrabbit.oak.segmen
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.SocketAddress;
-import java.net.UnknownHostException;
 import java.util.Arrays;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
+import java.util.regex.Pattern;
 
 /**
  * A white list for IP addresses. A filter can be a single IP address, a single
  * host name or a range of IP addresses.
- * <p>
- * Known issue: if a host name is provided as a filter and that host name
- * contains a dash ("-"), it will be interpreted as an IP range.
  */
 class ClientIpFilter implements ClientFilter {
 
-    private static final Logger log = 
LoggerFactory.getLogger(ClientIpFilter.class);
+    private static final Pattern LETTERS = Pattern.compile("[a-zA-Z]+");
+
+    private static boolean containsLetters(String s) {
+        return LETTERS.matcher(s).matches();
+    }
 
     private static boolean areAddressesEqual(InetAddress a, InetAddress b) {
         return Arrays.equals(a.getAddress(), b.getAddress());
@@ -78,35 +76,21 @@ class ClientIpFilter implements ClientFi
         return compare(leftBytes, addressBytes) <= 0 && compare(addressBytes, 
rightBytes) <= 0;
     }
 
-    private static boolean isAllowed(InetAddress client, String left, String 
right) {
-        InetAddress leftAddress;
-
-        try {
-            leftAddress = InetAddress.getByName(left);
-        } catch (UnknownHostException e) {
-            log.warn("Unable to resolve address or invalid IP literal " + 
left, e);
-            return false;
-        }
+    private static boolean isAllowed(InetAddress client, AddressResolver 
addressResolver, String left, String right) {
+        InetAddress leftAddress = addressResolver.resolve(left);
+        InetAddress rightAddress = addressResolver.resolve(right);
 
-        InetAddress rightAddress;
-
-        try {
-            rightAddress = InetAddress.getByName(right);
-        } catch (UnknownHostException e) {
-            log.warn("Unable to resolve address or invalid IP literal " + 
right, e);
+        if (leftAddress == null || rightAddress == null) {
             return false;
         }
 
         return isAddressInRange(client, leftAddress, rightAddress);
     }
 
-    private static boolean isAllowed(InetAddress client, String match) {
-        InetAddress matchAddress;
+    private static boolean isAllowed(InetAddress client, AddressResolver 
addressResolver, String match) {
+        InetAddress matchAddress = addressResolver.resolve(match);
 
-        try {
-            matchAddress = InetAddress.getByName(match);
-        } catch (UnknownHostException e) {
-            log.warn("Unable to resolve address or invalid IP literal " + 
match, e);
+        if (matchAddress == null) {
             return false;
         }
 
@@ -115,13 +99,28 @@ class ClientIpFilter implements ClientFi
 
     private final String[] allowedIpRanges;
 
+    private final AddressResolver addressResolver;
+
     /**
-     * Create a new white list based on the provided filters.
+     * Create a new white list based on the provided filters and the default
+     * {@link InetAddressResolver}.
      *
      * @param filters A list of filters.
      */
     ClientIpFilter(String[] filters) {
+        this(filters, new InetAddressResolver());
+    }
+
+    /**
+     * Create a new white list based on the provided filters.
+     *
+     * @param filters         An array of filters.
+     * @param addressResolver The resolver to be used for resolving IP
+     *                        addresses.
+     */
+    ClientIpFilter(String[] filters, AddressResolver addressResolver) {
         this.allowedIpRanges = filters;
+        this.addressResolver = addressResolver;
     }
 
     @Override
@@ -139,14 +138,14 @@ class ClientIpFilter implements ClientFi
         }
 
         for (String s : this.allowedIpRanges) {
-            int i = s.indexOf('-');
+            String[] parts = s.split("-");
 
-            if (i > 0) {
-                if (isAllowed(address, s.substring(0, i).trim(), s.substring(i 
+ 1).trim())) {
+            if (parts.length == 2 && !containsLetters(parts[0]) && 
!containsLetters(parts[1])) {
+                if (isAllowed(address, addressResolver, parts[0].trim(), 
parts[1].trim())) {
                     return true;
                 }
             } else {
-                if (isAllowed(address, s.trim())) {
+                if (isAllowed(address, addressResolver, s.trim())) {
                     return true;
                 }
             }

Added: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/InetAddressResolver.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/InetAddressResolver.java?rev=1760673&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/InetAddressResolver.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/InetAddressResolver.java
 Wed Sep 14 11:43:26 2016
@@ -0,0 +1,48 @@
+/*
+ * 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.jackrabbit.oak.segment.standby.server;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A simple implementation of {@link AddressResolver} making use of
+ * {@link InetAddress#getByName(String)} to resolve hosts to IP addresses.
+ */
+class InetAddressResolver implements AddressResolver {
+
+    private static final Logger log = 
LoggerFactory.getLogger(InetAddressResolver.class);
+
+    @Override
+    public InetAddress resolve(String host) {
+        InetAddress address;
+
+        try {
+            address = InetAddress.getByName(host);
+        } catch (UnknownHostException e) {
+            log.warn("Unable to resolve address or invalid IP literal " + 
host, e);
+            address = null;
+        }
+
+        return address;
+    }
+
+}

Propchange: 
jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/InetAddressResolver.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: 
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/server/ClientIPFilterHostnameTest.java
URL: 
http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/server/ClientIPFilterHostnameTest.java?rev=1760673&view=auto
==============================================================================
--- 
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/server/ClientIPFilterHostnameTest.java
 (added)
+++ 
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/server/ClientIPFilterHostnameTest.java
 Wed Sep 14 11:43:26 2016
@@ -0,0 +1,100 @@
+/*
+ * 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.jackrabbit.oak.segment.standby.server;
+
+import static org.junit.Assert.assertEquals;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.net.UnknownHostException;
+
+import org.junit.Test;
+
+public class ClientIPFilterHostnameTest {
+
+    @Test
+    public void testInvalidHostname() throws Exception {
+        String[] filters = new String[] {"foobar"};
+
+        AddressResolver dummyAddressResolver = new AddressResolver() {
+
+            @Override
+            public InetAddress resolve(String host) {
+                return null;
+            }
+        };
+
+        ClientFilter clientFilter = new ClientIpFilter(filters, 
dummyAddressResolver);
+        InetSocketAddress address = new InetSocketAddress("localhost", 8080);
+        assertEquals(false, clientFilter.isAllowed(address));
+    }
+
+    @Test
+    public void testHostnameWithDash() {
+        String[] filters = new String[] {"foo-bar"};
+
+        AddressResolver anythingToLocalhostResolver = new AddressResolver() {
+
+            @Override
+            public InetAddress resolve(String host) {
+                InetAddress address = null;
+
+                try {
+                    if (host.equals("foo-bar")) {
+                        address = InetAddress.getByName("localhost");
+                    }
+                } catch (UnknownHostException e) {
+                    // ignore
+                }
+
+                return address;
+            }
+        };
+
+        ClientFilter clientFilter = new ClientIpFilter(filters, 
anythingToLocalhostResolver);
+        InetSocketAddress address = new InetSocketAddress("localhost", 8080);
+        assertEquals(true, clientFilter.isAllowed(address));
+    }
+
+    @Test
+    public void testHostnameWithMultipleDashes() {
+        String[] filters = new String[] {"foo-bar-baz"};
+
+        AddressResolver anythingToLocalhostResolver = new AddressResolver() {
+
+            @Override
+            public InetAddress resolve(String host) {
+                InetAddress address = null;
+
+                try {
+                    if (host.equals("foo-bar-baz")) {
+                        address = InetAddress.getByName("localhost");
+                    }
+                } catch (UnknownHostException e) {
+                    // ignore
+                }
+
+                return address;
+            }
+        };
+
+        ClientFilter clientFilter = new ClientIpFilter(filters, 
anythingToLocalhostResolver);
+        InetSocketAddress address = new InetSocketAddress("localhost", 8080);
+        assertEquals(true, clientFilter.isAllowed(address));
+    }
+}

Propchange: 
jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/server/ClientIPFilterHostnameTest.java
------------------------------------------------------------------------------
    svn:eol-style = native


Reply via email to