You are viewing a plain text version of this content. The canonical link for it is here.
Posted to oak-commits@jackrabbit.apache.org by fr...@apache.org on 2016/09/09 11:28:34 UTC

svn commit: r1759985 - in /jackrabbit/oak/trunk/oak-segment-tar/src: main/java/org/apache/jackrabbit/oak/segment/standby/server/ test/java/org/apache/jackrabbit/oak/segment/standby/server/

Author: frm
Date: Fri Sep  9 11:28:34 2016
New Revision: 1759985

URL: http://svn.apache.org/viewvc?rev=1759985&view=rev
Log:
OAK-4738 - Extract IP white list from the StandbyServerHandler

Added:
    jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/IpAddressFilter.java   (with props)
    jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/server/
    jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/server/IpAddressFilterTest.java   (with props)
Modified:
    jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/StandbyServerHandler.java

Added: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/IpAddressFilter.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/IpAddressFilter.java?rev=1759985&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/IpAddressFilter.java (added)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/IpAddressFilter.java Fri Sep  9 11:28:34 2016
@@ -0,0 +1,132 @@
+/*
+ * 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 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 IpAddressFilter {
+
+    private static final Logger log = LoggerFactory.getLogger(IpAddressFilter.class);
+
+    private static long ipToLong(InetAddress ip) {
+        byte[] octets = ip.getAddress();
+
+        long result = 0;
+
+        for (byte octet : octets) {
+            result = (result << 8) | (octet & 0xff);
+        }
+
+        return result;
+    }
+
+    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;
+        }
+
+        InetAddress rightAddress;
+
+        try {
+            rightAddress = InetAddress.getByName(right);
+        } catch (UnknownHostException e) {
+            log.warn("Unable to resolve address or invalid IP literal " + right, e);
+            return false;
+        }
+
+        return isAllowed(ipToLong(client), ipToLong(leftAddress), ipToLong(rightAddress));
+    }
+
+    private static boolean isAllowed(InetAddress client, String match) {
+        InetAddress matchAddress;
+
+        try {
+            matchAddress = InetAddress.getByName(match);
+        } catch (UnknownHostException e) {
+            log.warn("Unable to resolve address or invalid IP literal " + match, e);
+            return false;
+        }
+
+        return ipToLong(client) == ipToLong(matchAddress);
+    }
+
+    private static boolean isAllowed(long address, long left, long right) {
+        return left <= address && address <= right;
+    }
+
+    private final String[] allowedIpRanges;
+
+    /**
+     * Create a new white list based on the provided filters.
+     *
+     * @param filters A list of filters.
+     */
+    IpAddressFilter(String[] filters) {
+        this.allowedIpRanges = filters;
+    }
+
+    /**
+     * Check if the provided IP address is allowed by this white list.
+     *
+     * @param address the address to verify.
+     * @return {@code true} if the address is valid according to this white
+     * list, {@code false} otherwise.
+     */
+    boolean isAllowed(InetAddress address) {
+        if (allowedIpRanges == null) {
+            return true;
+        }
+
+        if (allowedIpRanges.length == 0) {
+            return true;
+        }
+
+        for (String s : this.allowedIpRanges) {
+            int i = s.indexOf('-');
+
+            if (i > 0) {
+                if (isAllowed(address, s.substring(0, i).trim(), s.substring(i + 1).trim())) {
+                    return true;
+                }
+            } else {
+                if (isAllowed(address, s.trim())) {
+                    return true;
+                }
+            }
+        }
+
+        return false;
+    }
+
+}

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

Modified: jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/StandbyServerHandler.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/StandbyServerHandler.java?rev=1759985&r1=1759984&r2=1759985&view=diff
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/StandbyServerHandler.java (original)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/main/java/org/apache/jackrabbit/oak/segment/standby/server/StandbyServerHandler.java Fri Sep  9 11:28:34 2016
@@ -19,9 +19,7 @@
 
 package org.apache.jackrabbit.oak.segment.standby.server;
 
-import java.net.InetAddress;
 import java.net.InetSocketAddress;
-import java.net.UnknownHostException;
 import java.util.UUID;
 import java.util.concurrent.TimeUnit;
 
@@ -34,11 +32,9 @@ import org.apache.jackrabbit.oak.api.Ill
 import org.apache.jackrabbit.oak.plugins.blob.BlobStoreBlob;
 import org.apache.jackrabbit.oak.segment.RecordId;
 import org.apache.jackrabbit.oak.segment.Segment;
-import org.apache.jackrabbit.oak.segment.SegmentId;
 import org.apache.jackrabbit.oak.segment.file.FileStore;
 import org.apache.jackrabbit.oak.segment.standby.codec.Messages;
 import org.apache.jackrabbit.oak.segment.standby.store.CommunicationObserver;
-import org.apache.jackrabbit.oak.segment.standby.store.StandbyStore;
 import org.apache.jackrabbit.oak.spi.blob.BlobStore;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -46,18 +42,20 @@ import org.slf4j.LoggerFactory;
 @Sharable
 public class StandbyServerHandler extends SimpleChannelInboundHandler<String> {
 
-    private static final Logger log = LoggerFactory
-            .getLogger(StandbyServerHandler.class);
+    private static final Logger log = LoggerFactory.getLogger(StandbyServerHandler.class);
 
     private final FileStore store;
+
     private final CommunicationObserver observer;
-    private final String[] allowedIPRanges;
+
+    private final IpAddressFilter allowedIPRanges;
+
     public String state;
 
     public StandbyServerHandler(FileStore store, CommunicationObserver observer, String[] allowedIPRanges) {
         this.store = store;
         this.observer = observer;
-        this.allowedIPRanges = allowedIPRanges;
+        this.allowedIPRanges = new IpAddressFilter(allowedIPRanges);
     }
 
     private RecordId headId() {
@@ -67,41 +65,8 @@ public class StandbyServerHandler extend
         return null;
     }
 
-    private static long ipToLong(InetAddress ip) {
-        byte[] octets = ip.getAddress();
-        long result = 0;
-        for (byte octet : octets) {
-            result <<= 8;
-            result |= octet & 0xff;
-        }
-        return result;
-    }
-
     private boolean clientAllowed(InetSocketAddress client) {
-        if (this.allowedIPRanges != null && this.allowedIPRanges.length > 0) {
-            for (String s : this.allowedIPRanges) {
-                try {
-                    if (ipToLong(InetAddress.getByName(s)) == ipToLong(client.getAddress())) {
-                        return true;
-                    }
-                }
-                catch (UnknownHostException ignored) { /* it's an ip range */ }
-                int i = s.indexOf('-');
-                if (i > 0) {
-                    try {
-                        long startIPRange = ipToLong(InetAddress.getByName(s.substring(0, i).trim()));
-                        long endIPRange = ipToLong(InetAddress.getByName(s.substring(i + 1).trim()));
-                        long ipl = ipToLong(client.getAddress());
-                        if (startIPRange <= ipl && ipl <= endIPRange) return true;
-                    }
-                    catch (Exception e) {
-                        log.warn("invalid IP-range format: " + s);
-                    }
-                }
-            }
-            return false;
-        }
-        return true;
+        return allowedIPRanges.isAllowed(client.getAddress());
     }
 
     @Override

Added: jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/server/IpAddressFilterTest.java
URL: http://svn.apache.org/viewvc/jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/server/IpAddressFilterTest.java?rev=1759985&view=auto
==============================================================================
--- jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/server/IpAddressFilterTest.java (added)
+++ jackrabbit/oak/trunk/oak-segment-tar/src/test/java/org/apache/jackrabbit/oak/segment/standby/server/IpAddressFilterTest.java Fri Sep  9 11:28:34 2016
@@ -0,0 +1,81 @@
+/*
+ * 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 org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class IpAddressFilterTest {
+
+    @Parameters(name = "filters={0}, address={1}, matches={2}")
+    public static Object[] parameters() {
+        return new Object[][] {
+                {null, "127.0.0.1", true},
+                {"", "127.0.0.1", true},
+                {"127.0.0.1", "127.0.0.1", true},
+                {"127.0.0.2", "127.0.0.1", false},
+                {"::1", "::1", true},
+                {"::2", "::1", false},
+                {"localhost", "127.0.0.1", true},
+                {"foobar", "127.0.0.1", false},
+                {"127.0.0.1-127.0.0.2", "127.0.0.1", true},
+                {"127.0.0.0-127.0.0.1", "127.0.0.1", true},
+                {"127.0.0.0-127.0.0.2", "127.0.0.1", true},
+                {"127.0.0.2-127.0.0.1", "127.0.0.1", false},
+                {"foobar, 127-128, 126.0.0.1, 127.0.0.0-127.255.255.255", "127.0.0.1", true},
+                {"foobar, 122-126, ::1, 126.0.0.1, 127.0.0.0-127.255.255.255", "127.0.0.1", true},
+                {"foobar, 126.0.0.1, ::2, 128.0.0.1-255.255.255.255, 128.0.0.0-127.255.255.255", "127.0.0.1", false},
+                {"foobar, 127-128, 0:0:0:0:0:0:0:1, 126.0.0.1, 127.0.0.0-127.255.255.255", "::1", true},
+                {"foobar, 122-126, ::1, 126.0.0.1, 127.0.0.0-127.255.255.255", "::1", true},
+                {"foobar, 126.0.0.1, ::2, 128.0.0.1-255.255.255.255, 128.0.0.0-127.255.255.255", "::1", false},
+        };
+    }
+
+    private final String addresses;
+
+    private final String client;
+
+    private final boolean match;
+
+    public IpAddressFilterTest(String addresses, String client, boolean match) {
+        this.addresses = addresses;
+        this.client = client;
+        this.match = match;
+    }
+
+    @Test
+    public void test() throws Exception {
+        assertEquals(match, new IpAddressFilter(parseFilters()).isAllowed(InetAddress.getByName(client)));
+    }
+
+    private String[] parseFilters() {
+        if (addresses == null) {
+            return null;
+        }
+
+        return addresses.split(",");
+    }
+
+}

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