tomee-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From dblev...@apache.org
Subject svn commit: r644521 - in /openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server: ./ auth/
Date Thu, 03 Apr 2008 21:37:01 GMT
Author: dblevins
Date: Thu Apr  3 14:37:00 2008
New Revision: 644521

URL: http://svn.apache.org/viewvc?rev=644521&view=rev
Log:
Ported thread pooling and host-based authorization code

Added:
    openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/
    openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/ExactIPAddressPermission.java
    openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/ExactIPv6AddressPermission.java
    openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/FactorizedIPAddressPermission.java
    openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/IPAddressPermission.java
    openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/IPAddressPermissionEditor.java
    openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/IPAddressPermissionFactory.java
    openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/NetmaskIPAddressPermission.java
    openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/NetmaskIPv6AddressPermission.java
    openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/PermitAllPermission.java
    openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/StartWithIPAddressPermission.java
Modified:
    openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceAccessController.java
    openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceDaemon.java

Modified: openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceAccessController.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceAccessController.java?rev=644521&r1=644520&r2=644521&view=diff
==============================================================================
--- openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceAccessController.java
(original)
+++ openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceAccessController.java
Thu Apr  3 14:37:00 2008
@@ -16,41 +16,38 @@
  */
 package org.apache.openejb.server;
 
-import java.io.*;
-import java.net.*;
-import java.util.*;
+
+import org.apache.openejb.server.auth.IPAddressPermission;
+import org.apache.openejb.server.auth.ExactIPAddressPermission;
+import org.apache.openejb.server.auth.ExactIPv6AddressPermission;
+import org.apache.openejb.server.auth.IPAddressPermissionFactory;
+import org.apache.openejb.server.auth.PermitAllPermission;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Inet4Address;
+import java.net.InetAddress;
+import java.net.Socket;
+import java.net.UnknownHostException;
+import java.util.LinkedList;
+import java.util.Properties;
+import java.util.StringTokenizer;
 
 /**
- * @version $Rev$ $Date$
  */
 public class ServiceAccessController implements ServerService {
 
-    ServerService next;
-
-    InetAddress[] allowedHosts;
+    private final ServerService next;
+    private IPAddressPermission[] hostPermissions;
 
     public ServiceAccessController(ServerService next) {
         this.next = next;
     }
 
-    public void init(Properties props) throws Exception {
-
-        parseAdminIPs(props);
-
-        next.init(props);
-    }
-
-    public void start() throws ServiceException {
-
-        next.start();
-    }
-
-    public void stop() throws ServiceException {
-
-        next.stop();
-    }
-
     public void service(Socket socket) throws ServiceException, IOException {
+        // Check authorization
+        checkHostsAuthorization(socket.getInetAddress(), socket.getLocalAddress());
 
         next.service(socket);
     }
@@ -59,66 +56,77 @@
         throw new UnsupportedOperationException("service(in,out)");
     }
 
+    public void checkHostsAuthorization(InetAddress clientAddress, InetAddress serverAddress)
throws SecurityException {
+        // Check the client ip against the server ip. Hosts are
+        // allowed to access themselves, so if these ips
+        // match, the following for loop will be skipped.
+        if (clientAddress.equals(serverAddress)) {
+            return;
+        }
 
-    public String getName() {
-        return next.getName();
-    }
-
-    public String getIP() {
-        return next.getIP();
-    }
+        for (IPAddressPermission host : hostPermissions) {
+            if (host.implies(clientAddress)) {
+                return;
+            }
+        }
 
-    public int getPort() {
-        return next.getPort();
+        throw new SecurityException("Host " + clientAddress.getHostAddress() + " is not authorized
to access this service.");
     }
 
-    public void checkHostsAuthorization(InetAddress client, InetAddress server) throws SecurityException
{
+    private void parseAdminIPs(Properties props) throws ServiceException {
+        LinkedList<IPAddressPermission> permissions = new LinkedList<IPAddressPermission>();
 
-        boolean authorized = false;
+        String ipString = props.getProperty("only_from");
 
-        authorized = client.equals(server);
+        if (ipString == null) {
+            permissions.add(new PermitAllPermission());
+        } else {
+            try {
+                InetAddress[] localIps = InetAddress.getAllByName("localhost");
+                for (int i = 0; i < localIps.length; i++) {
+                    if (localIps[i] instanceof Inet4Address) {
+                        permissions.add(new ExactIPAddressPermission(localIps[i].getAddress()));
+                    } else {
+                        permissions.add(new ExactIPv6AddressPermission(localIps[i].getAddress()));
+                    }
+                }
+            } catch (UnknownHostException e) {
+                throw new ServiceException("Could not get localhost inet address", e);
+            }
 
-        for (int i = 0; i < allowedHosts.length && !authorized; i++) {
-            authorized = allowedHosts[i].equals(client);
+            StringTokenizer st = new StringTokenizer(ipString, " ");
+            while (st.hasMoreTokens()) {
+                String mask = st.nextToken();
+                permissions.add(IPAddressPermissionFactory.getIPAddressMask(mask));
+            }
         }
 
-        if (!authorized) {
-            throw new SecurityException("Host " + client.getHostAddress() + " is not authorized
to access this service.");
-        }
+        hostPermissions = (IPAddressPermission[]) permissions.toArray(new IPAddressPermission[permissions.size()]);
     }
 
-    private void parseAdminIPs(Properties props) {
-        try {
-
-            Vector addresses = new Vector();
-
-            InetAddress[] localIps = InetAddress.getAllByName("localhost");
-            for (int i = 0; i < localIps.length; i++) {
-                addresses.add(localIps[i]);
-            }
+    public void init(Properties props) throws Exception {
+        parseAdminIPs(props);
+        next.init(props);
+    }
 
-            String ipString = props.getProperty("only_from");
-            if (ipString != null) {
-                StringTokenizer st = new StringTokenizer(ipString, ",");
-                while (st.hasMoreTokens()) {
-                    String address = null;
-                    InetAddress ip = null;
-                    try {
-                        address = st.nextToken();
-                        ip = InetAddress.getByName(address);
-                        addresses.add(ip);
-                    } catch (Exception e) {
+    public void start() throws ServiceException {
+        next.start();
+    }
 
-                    }
-                }
-            }
+    public void stop() throws ServiceException {
+        next.stop();
+    }
 
-            allowedHosts = new InetAddress[ addresses.size() ];
-            addresses.copyInto(allowedHosts);
+    public String getName() {
+        return next.getName();
+    }
 
-        } catch (Exception e) {
+    public String getIP() {
+        return next.getIP();
+    }
 
-        }
+    public int getPort() {
+        return next.getPort();
     }
 
 }

Modified: openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceDaemon.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceDaemon.java?rev=644521&r1=644520&r2=644521&view=diff
==============================================================================
--- openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceDaemon.java
(original)
+++ openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceDaemon.java
Thu Apr  3 14:37:00 2008
@@ -16,25 +16,36 @@
  */
 package org.apache.openejb.server;
 
+import org.apache.openejb.util.Logger;
+import org.apache.openejb.util.LogCategory;
+
 import java.io.*;
 import java.net.*;
 import java.util.*;
 
 /**
- * @version $Rev$ $Date$
  */
-public class ServiceDaemon implements ServerService, Runnable {
+public class ServiceDaemon implements ServerService {
+
+    private static final Logger log = Logger.getInstance(LogCategory.OPENEJB_SERVER, ServiceDaemon.class);
+
+    private ServerService next;
+
+    private SocketListener socketListener;
+
+    private int timeout;
 
-    ServerService next;
+    private InetAddress address;
 
-    Properties props;
-    String ip;
-    int port;
+    private int port;
 
-    ServerSocket serverSocket;
+    private String name;
 
     boolean stop = true;
+
     private int backlog;
+    private String ip;
+
 
     public ServiceDaemon(ServerService next) {
         this.next = next;
@@ -43,9 +54,18 @@
     public ServiceDaemon(ServerService next, int port, String ip) {
         this.port = port;
         this.ip = ip;
+        this.address = getAddress(ip);
         this.next = next;
     }
 
+    private static InetAddress getAddress(String host){
+        try {
+            return InetAddress.getByName(host);
+        } catch (UnknownHostException e) {
+            throw new IllegalArgumentException(host);
+        }
+    }
+
     public static int getInt(Properties p, String property, int defaultValue){
         String value = p.getProperty(property);
         try {
@@ -56,12 +76,32 @@
         }
     }
 
-    public void init(Properties props) throws Exception {
+   public void setSoTimeout(int timeout) throws SocketException {
+        this.timeout = timeout;
+        if (socketListener != null) {
+            socketListener.setSoTimeout(timeout);
+        }
+    }
 
-        this.props = props;
+    public int getSoTimeout() throws IOException {
+        if (socketListener == null) return 0;
+        return socketListener.getSoTimeout();
+    }
+
+    /**
+     * Gets the inetAddress number that the
+     * daemon is listening on.
+     */
+    public InetAddress getAddress() {
+        return address;
+    }
+
+    public void init(Properties props) throws Exception {
 
         ip = props.getProperty("bind");
 
+        address = getAddress(ip);
+
         port = getInt(props, "port", 0);
 
         int threads = getInt(props, "threads", 100);
@@ -73,108 +113,119 @@
 
     public void start() throws ServiceException {
         synchronized (this) {
-
-            if (!stop)
+            // Don't bother if we are already started/starting
+            if (socketListener != null) {
                 return;
+            }
 
-            stop = false;
+            next.start();
 
+            ServerSocket serverSocket;
             try {
-                InetAddress address = InetAddress.getByName(ip);
                 serverSocket = new ServerSocket(port, backlog, address);
-//                serverSocket = new ServerSocket(port, 20);
                 port = serverSocket.getLocalPort();
-                ip = serverSocket.getInetAddress().getHostAddress();
-
-                Thread d = new Thread(this);
-                d.setName("service." + next.getName() + "@" + d.hashCode());
-                d.setDaemon(true);
-                d.start();
+                serverSocket.setSoTimeout(timeout);
             } catch (Exception e) {
-                throw new ServiceException("Service failed to start.", e);
-
+                throw new ServiceException("Service failed to open socket", e);
             }
 
-            next.start();
+            socketListener = new SocketListener(next, serverSocket);
+            Thread thread = new Thread(socketListener);
+            thread.setName("service." + name + "@" + socketListener.hashCode());
+            thread.setDaemon(true);
+            thread.start();
+
         }
     }
 
     public void stop() throws ServiceException {
 
         synchronized (this) {
-
-            if (stop)
-                return;
-
-            stop = true;
-            try {
-                this.notifyAll();
-            } catch (Throwable t) {
-                t.printStackTrace();
-
-                // Received exception: "+t.getClass().getName()+" :
-                // "+t.getMessage());
+            if (socketListener != null) {
+                socketListener.stop();
+                socketListener = null;
             }
-
             next.stop();
         }
     }
 
-    public void service(InputStream in, OutputStream out) throws ServiceException, IOException
{
-        throw new UnsupportedOperationException("service(in,out)");
+    public String getIP() {
+        return ip;
     }
 
-    public synchronized void service(final Socket socket)
-            throws ServiceException, IOException {
-        Thread d = new Thread(new Runnable() {
-            public void run() {
-                try {
-                    next.service(socket);
-                } catch (SecurityException e) {
-
-                } catch (Throwable e) {
+    /**
+     * Gets the port number that the
+     * daemon is listening on.
+     */
+    public int getPort() {
+        return port;
+    }
 
-                } finally {
-                    try {
-                        if (socket != null)
-                            socket.close();
-                    } catch (Throwable t) {
+    public void service(Socket socket) throws ServiceException, IOException {
+    }
 
-                        // connection with client: "+t.getMessage());
-                    }
-                }
-            }
-        });
-        d.setDaemon(true);
-        d.start();
+    public void service(InputStream in, OutputStream out) throws ServiceException, IOException
{
     }
 
     public String getName() {
         return next.getName();
     }
 
-    public String getIP() {
-        return ip;
-    }
-
-    public int getPort() {
-        return port;
-    }
+    private static class SocketListener implements Runnable {
+        private ServerService serverService;
+        private ServerSocket serverSocket;
+        private boolean stopped;
+
+        public SocketListener(ServerService serverService, ServerSocket serverSocket) {
+            this.serverService = serverService;
+            this.serverSocket = serverSocket;
+            stopped = false;
+        }
 
-    public void run() {
+        public synchronized void stop() {
+            stopped = true;
+        }
 
-        Socket socket = null;
+        private synchronized boolean shouldStop() {
+            return stopped;
+        }
 
-        while (!stop) {
-            try {
-                socket = serverSocket.accept();
-                socket.setTcpNoDelay(true);
-                if (!stop) service(socket);
-            } catch (SecurityException e) {
+        public void run() {
+            while (!shouldStop()) {
+                Socket socket = null;
+                try {
+                    socket = serverSocket.accept();
+                    socket.setTcpNoDelay(true);
+                    if (!shouldStop()) {
+                        // the server service is responsible
+                        // for closing the socket.
+                        serverService.service(socket);
+                    }
+                } catch (SocketTimeoutException e) {
+                    // we don't really care
+                    // log.debug("Socket timed-out",e);
+                } catch (Throwable e) {
+                    log.error("Unexpected error", e);
+                }
+            }
 
-            } catch (Throwable e) {
-                e.printStackTrace();
+            if (serverSocket != null) {
+                try {
+                    serverSocket.close();
+                } catch (IOException ioException) {
+                    log.debug("Error cleaning up socked", ioException);
+                }
+                serverSocket = null;
             }
+            serverService = null;
+        }
+
+        public void setSoTimeout(int timeout) throws SocketException {
+            serverSocket.setSoTimeout(timeout);
+        }
+
+        public int getSoTimeout() throws IOException {
+            return serverSocket.getSoTimeout();
         }
     }
 }

Added: openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/ExactIPAddressPermission.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/ExactIPAddressPermission.java?rev=644521&view=auto
==============================================================================
--- openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/ExactIPAddressPermission.java
(added)
+++ openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/ExactIPAddressPermission.java
Thu Apr  3 14:37:00 2008
@@ -0,0 +1,72 @@
+/**
+ *
+ * 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.openejb.server.auth;
+
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import java.net.InetAddress;
+import java.net.Inet4Address;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public class ExactIPAddressPermission implements IPAddressPermission {
+    private static final Pattern MASK_VALIDATOR = Pattern.compile("^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})$");
+
+    public static boolean canSupport(String mask) {
+        Matcher matcher = MASK_VALIDATOR.matcher(mask);
+        return matcher.matches();
+    }
+
+    private final byte[] bytes;
+
+    public ExactIPAddressPermission(byte[] bytes) {
+        this.bytes = bytes;
+    }
+
+    public ExactIPAddressPermission(String mask) {
+        Matcher matcher = MASK_VALIDATOR.matcher(mask);
+        if (false == matcher.matches()) {
+            throw new IllegalArgumentException("Mask " + mask + " does not match pattern
" + MASK_VALIDATOR.pattern());
+        }
+
+        bytes = new byte[4];
+        for (int i = 0; i < 4; i++) {
+            String group = matcher.group(i + 1);
+            int value = Integer.parseInt(group);
+            if (value < 0 || 255 < value) {
+                throw new IllegalArgumentException("byte #" + i + " is not valid.");
+            }
+            bytes[i] = (byte) value;
+        }
+    }
+
+    public boolean implies(InetAddress address) {
+        if (false == address instanceof Inet4Address) {
+            return false;
+        }
+
+        byte[] byteAddress = address.getAddress();
+        for (int i = 0; i < 4; i++) {
+            if (byteAddress[i] != bytes[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+}

Added: openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/ExactIPv6AddressPermission.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/ExactIPv6AddressPermission.java?rev=644521&view=auto
==============================================================================
--- openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/ExactIPv6AddressPermission.java
(added)
+++ openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/ExactIPv6AddressPermission.java
Thu Apr  3 14:37:00 2008
@@ -0,0 +1,73 @@
+/**
+ *
+ * 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.openejb.server.auth;
+
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import java.util.StringTokenizer;
+import java.net.InetAddress;
+import java.net.Inet6Address;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public class ExactIPv6AddressPermission implements IPAddressPermission {
+    private static final Pattern MASK_VALIDATOR = Pattern.compile("^(([a-fA-F0-9]{1,4}:){7})([a-fA-F0-9]{1,4})$");
+
+    public static boolean canSupport(String mask) {
+        Matcher matcher = MASK_VALIDATOR.matcher(mask);
+        return matcher.matches();
+    }
+
+    private final byte[] bytes;
+
+    public ExactIPv6AddressPermission(byte[] bytes) {
+        this.bytes = bytes;
+    }
+
+    public ExactIPv6AddressPermission(String mask) {
+        Matcher matcher = MASK_VALIDATOR.matcher(mask);
+        if (false == matcher.matches()) {
+            throw new IllegalArgumentException("Mask " + mask + " does not match pattern
" + MASK_VALIDATOR.pattern());
+        }
+
+        bytes = new byte[16];
+        int pos = 0;
+        StringTokenizer tokenizer = new StringTokenizer(mask, ":");
+        while (tokenizer.hasMoreTokens()) {
+            String token = tokenizer.nextToken();
+            int value = Integer.parseInt(token, 16);
+            bytes[pos++] = (byte) ((value & 0xff00) >> 8);
+            bytes[pos++] = (byte) value;
+        }
+    }
+
+    public boolean implies(InetAddress address) {
+        if (false == address instanceof Inet6Address) {
+            return false;
+        }
+
+        byte[] byteAddress = address.getAddress();
+        for (int i = 0; i < 16; i++) {
+            if (byteAddress[i] != bytes[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+}

Added: openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/FactorizedIPAddressPermission.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/FactorizedIPAddressPermission.java?rev=644521&view=auto
==============================================================================
--- openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/FactorizedIPAddressPermission.java
(added)
+++ openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/FactorizedIPAddressPermission.java
Thu Apr  3 14:37:00 2008
@@ -0,0 +1,104 @@
+/**
+ *
+ * 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.openejb.server.auth;
+
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import java.util.StringTokenizer;
+import java.net.InetAddress;
+import java.net.Inet4Address;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public class FactorizedIPAddressPermission implements IPAddressPermission {
+    private static final Pattern MASK_VALIDATOR = Pattern.compile("^((\\d{1,3}){1}(\\.\\d{1,3}){0,2}\\.)?\\{(\\d{1,3}){1}((,\\d{1,3})*)\\}$");
+
+    public static boolean canSupport(String mask) {
+        Matcher matcher = MASK_VALIDATOR.matcher(mask);
+        return matcher.matches();
+    }
+
+    private final byte[] prefixBytes;
+    private final byte[] suffixBytes;
+
+    public FactorizedIPAddressPermission(String mask) {
+        Matcher matcher = MASK_VALIDATOR.matcher(mask);
+        if (false == matcher.matches()) {
+            throw new IllegalArgumentException("Mask " + mask + " does not match pattern
" + MASK_VALIDATOR.pattern());
+        }
+
+        // group 1 is the factorized IP part.
+        // e.g. group 1 in "1.2.3.{4,5,6}" is "1.2.3."
+        String prefix = matcher.group(1);
+        StringTokenizer tokenizer = new StringTokenizer(prefix, ".");
+        prefixBytes = new byte[tokenizer.countTokens()];
+        for (int i = 0; i < prefixBytes.length; i++) {
+            String token = tokenizer.nextToken();
+            int value = Integer.parseInt(token);
+            if (value < 0 || 255 < value) {
+                throw new IllegalArgumentException("byte #" + i + " is not valid.");
+            }
+            prefixBytes[i] = (byte) value;
+        }
+
+        // group 5 is a comma separated list of optional suffixes.
+        // e.g. group 5 in "1.2.3.{4,5,6}" is ",5,6"
+        String suffix = matcher.group(5);
+        tokenizer = new StringTokenizer(suffix, ",");
+        suffixBytes = new byte[1 + tokenizer.countTokens()];
+
+        // group 4 is the compulsory and first suffix.
+        // e.g. group 4 in "1.2.3.{4,5,6}" is "4"
+        int value = Integer.parseInt(matcher.group(4));
+        int i = 0;
+        if (value < 0 || 255 < value) {
+            throw new IllegalArgumentException("suffix " + i + " is not valid.");
+        }
+        suffixBytes[i++] = (byte) value;
+
+        for (; i < suffixBytes.length; i++) {
+            String token = tokenizer.nextToken();
+            value = Integer.parseInt(token);
+            if (value < 0 || 255 < value) {
+                throw new IllegalArgumentException("byte #" + i + " is not valid.");
+            }
+            suffixBytes[i] = (byte) value;
+        }
+    }
+
+    public boolean implies(InetAddress address) {
+        if (false == address instanceof Inet4Address) {
+            return false;
+        }
+
+        byte[] byteAddress = address.getAddress();
+        for (int i = 0; i < prefixBytes.length; i++) {
+            if (byteAddress[i] != prefixBytes[i]) {
+                return false;
+            }
+        }
+        byte lastByte = byteAddress[prefixBytes.length];
+        for (int i = 0; i < suffixBytes.length; i++) {
+            if (lastByte == suffixBytes[i]) {
+                return true;
+            }
+        }
+        return false;
+    }
+}

Added: openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/IPAddressPermission.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/IPAddressPermission.java?rev=644521&view=auto
==============================================================================
--- openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/IPAddressPermission.java
(added)
+++ openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/IPAddressPermission.java
Thu Apr  3 14:37:00 2008
@@ -0,0 +1,28 @@
+/**
+ *
+ * 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.openejb.server.auth;
+
+import java.io.Serializable;
+import java.net.InetAddress;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public interface IPAddressPermission {
+    public boolean implies(InetAddress address);
+}

Added: openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/IPAddressPermissionEditor.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/IPAddressPermissionEditor.java?rev=644521&view=auto
==============================================================================
--- openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/IPAddressPermissionEditor.java
(added)
+++ openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/IPAddressPermissionEditor.java
Thu Apr  3 14:37:00 2008
@@ -0,0 +1,35 @@
+/**
+ *
+ * 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.openejb.server.auth;
+
+import java.beans.PropertyEditorSupport;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public class IPAddressPermissionEditor extends PropertyEditorSupport {
+    private IPAddressPermission addressMask;
+
+    public void setAsText(String text) throws IllegalArgumentException {
+        addressMask = IPAddressPermissionFactory.getIPAddressMask(text);
+    }
+
+    public Object getValue() {
+        return addressMask;
+    }
+}

Added: openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/IPAddressPermissionFactory.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/IPAddressPermissionFactory.java?rev=644521&view=auto
==============================================================================
--- openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/IPAddressPermissionFactory.java
(added)
+++ openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/IPAddressPermissionFactory.java
Thu Apr  3 14:37:00 2008
@@ -0,0 +1,41 @@
+/**
+ *
+ * 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.openejb.server.auth;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public class IPAddressPermissionFactory {
+
+    public static IPAddressPermission getIPAddressMask(String mask) {
+        if (StartWithIPAddressPermission.canSupport(mask)) {
+            return new StartWithIPAddressPermission(mask);
+        } else if (ExactIPAddressPermission.canSupport(mask)) {
+            return new ExactIPAddressPermission(mask);
+        } else if (FactorizedIPAddressPermission.canSupport(mask)) {
+            return new FactorizedIPAddressPermission(mask);
+        } else if (NetmaskIPAddressPermission.canSupport(mask)) {
+            return new NetmaskIPAddressPermission(mask);
+        } else if (ExactIPv6AddressPermission.canSupport(mask)) {
+            return new ExactIPv6AddressPermission(mask);
+        } else if (NetmaskIPv6AddressPermission.canSupport(mask)) {
+            return new NetmaskIPv6AddressPermission(mask);
+        }
+        throw new IllegalArgumentException("Mask " + mask + " is not supported.");
+    }
+}

Added: openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/NetmaskIPAddressPermission.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/NetmaskIPAddressPermission.java?rev=644521&view=auto
==============================================================================
--- openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/NetmaskIPAddressPermission.java
(added)
+++ openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/NetmaskIPAddressPermission.java
Thu Apr  3 14:37:00 2008
@@ -0,0 +1,90 @@
+/**
+ *
+ * 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.openejb.server.auth;
+
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import java.net.InetAddress;
+import java.net.Inet4Address;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public class NetmaskIPAddressPermission implements IPAddressPermission {
+    private static final Pattern MASK_VALIDATOR = Pattern.compile("^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})/((\\d{1,2})|(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3}))$");
+
+    public static boolean canSupport(String mask) {
+        Matcher matcher = MASK_VALIDATOR.matcher(mask);
+        return matcher.matches();
+    }
+
+    private final byte[] networkAddressBytes;
+    private final byte[] netmaskBytes;
+
+    public NetmaskIPAddressPermission(String mask) {
+        Matcher matcher = MASK_VALIDATOR.matcher(mask);
+        if (false == matcher.matches()) {
+            throw new IllegalArgumentException("Mask " + mask + " does not match pattern
" + MASK_VALIDATOR.pattern());
+        }
+
+        networkAddressBytes = new byte[4];
+        for (int i = 0; i < 4; i++) {
+            String group = matcher.group(i + 1);
+            int value = Integer.parseInt(group);
+            if (value < 0 || 255 < value) {
+                throw new IllegalArgumentException("byte #" + i + " is not valid.");
+            }
+            networkAddressBytes[i] = (byte) value;
+        }
+
+        netmaskBytes = new byte[4];
+        String netmask = matcher.group(6);
+        if (null != netmask) {
+            int value = Integer.parseInt(netmask);
+            int pos = value / 8;
+            int shift = 8 - value % 8;
+            for (int i = 0; i < pos; i++) {
+                netmaskBytes[i] = (byte) 0xff;
+            }
+            netmaskBytes[pos] = (byte) (0xff << shift);
+        } else {
+            for (int i = 0; i < 4; i++) {
+                String group = matcher.group(i + 7);
+                int value = Integer.parseInt(group);
+                if (value < 0 || 255 < value) {
+                    throw new IllegalArgumentException("byte #" + i + " is not valid.");
+                }
+                netmaskBytes[i] = (byte) value;
+            }
+        }
+    }
+
+    public boolean implies(InetAddress address) {
+        if (false == address instanceof Inet4Address) {
+            return false;
+        }
+
+        byte[] byteAddress = address.getAddress();
+        for (int i = 0; i < 4; i++) {
+            if ((netmaskBytes[i] & byteAddress[i]) != networkAddressBytes[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+}

Added: openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/NetmaskIPv6AddressPermission.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/NetmaskIPv6AddressPermission.java?rev=644521&view=auto
==============================================================================
--- openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/NetmaskIPv6AddressPermission.java
(added)
+++ openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/NetmaskIPv6AddressPermission.java
Thu Apr  3 14:37:00 2008
@@ -0,0 +1,91 @@
+/**
+ *
+ * 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.openejb.server.auth;
+
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import java.util.StringTokenizer;
+import java.net.InetAddress;
+import java.net.Inet6Address;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public class NetmaskIPv6AddressPermission implements IPAddressPermission {
+    private static final Pattern MASK_VALIDATOR = Pattern.compile("^(([a-fA-F0-9]{1,4}:){7}[a-fA-F0-9]{1,4})/((\\d{1,3})|(([a-fA-F0-9]{1,4}:){7}[a-fA-F0-9]{1,4}))$");
+
+    public static boolean canSupport(String mask) {
+        Matcher matcher = MASK_VALIDATOR.matcher(mask);
+        return matcher.matches();
+    }
+
+    private final byte[] networkAddressBytes;
+    private final byte[] netmaskBytes;
+
+    public NetmaskIPv6AddressPermission(String mask) {
+        Matcher matcher = MASK_VALIDATOR.matcher(mask);
+        if (false == matcher.matches()) {
+            throw new IllegalArgumentException("Mask " + mask + " does not match pattern
" + MASK_VALIDATOR.pattern());
+        }
+
+        networkAddressBytes = new byte[16];
+        int pos = 0;
+        StringTokenizer tokenizer = new StringTokenizer(matcher.group(1), ":");
+        while (tokenizer.hasMoreTokens()) {
+            String token = tokenizer.nextToken();
+            int value = Integer.parseInt(token, 16);
+            networkAddressBytes[pos++] = (byte) ((value & 0xff00) >> 8);
+            networkAddressBytes[pos++] = (byte) value;
+        }
+
+        netmaskBytes = new byte[16];
+        String netmask = matcher.group(4);
+        if (null != netmask) {
+            int value = Integer.parseInt(netmask);
+            pos = value / 8;
+            int shift = 8 - value % 8;
+            for (int i = 0; i < pos; i++) {
+                netmaskBytes[i] = (byte) 0xff;
+            }
+            netmaskBytes[pos] = (byte) (0xff << shift);
+        } else {
+            pos = 0;
+            tokenizer = new StringTokenizer(matcher.group(5), ":");
+            while (tokenizer.hasMoreTokens()) {
+                String token = tokenizer.nextToken();
+                int value = Integer.parseInt(token, 16);
+                netmaskBytes[pos++] = (byte) ((value & 0xff00) >> 8);
+                netmaskBytes[pos++] = (byte) value;
+            }
+        }
+    }
+
+    public boolean implies(InetAddress address) {
+        if (false == address instanceof Inet6Address) {
+            return false;
+        }
+
+        byte[] byteAddress = address.getAddress();
+        for (int i = 0; i < 16; i++) {
+            if ((netmaskBytes[i] & byteAddress[i]) != networkAddressBytes[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+}

Added: openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/PermitAllPermission.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/PermitAllPermission.java?rev=644521&view=auto
==============================================================================
--- openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/PermitAllPermission.java
(added)
+++ openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/PermitAllPermission.java
Thu Apr  3 14:37:00 2008
@@ -0,0 +1,28 @@
+/**
+ * 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.openejb.server.auth;
+
+import java.net.InetAddress;
+
+/**
+ * @version $Rev$ $Date$
+ */
+public class PermitAllPermission implements IPAddressPermission {
+    public boolean implies(InetAddress address) {
+        return true;
+    }
+}

Added: openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/StartWithIPAddressPermission.java
URL: http://svn.apache.org/viewvc/openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/StartWithIPAddressPermission.java?rev=644521&view=auto
==============================================================================
--- openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/StartWithIPAddressPermission.java
(added)
+++ openejb/trunk/openejb3/server/openejb-server/src/main/java/org/apache/openejb/server/auth/StartWithIPAddressPermission.java
Thu Apr  3 14:37:00 2008
@@ -0,0 +1,82 @@
+/**
+ *
+ * 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.openejb.server.auth;
+
+import java.util.regex.Pattern;
+import java.util.regex.Matcher;
+import java.net.InetAddress;
+import java.net.Inet4Address;
+
+/**
+ * @version $Revision$ $Date$
+ */
+public class StartWithIPAddressPermission implements IPAddressPermission {
+    private static final Pattern MASK_VALIDATOR = Pattern.compile("^(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.0$");
+
+    public static boolean canSupport(String mask) {
+        Matcher matcher = MASK_VALIDATOR.matcher(mask);
+        return matcher.matches();
+    }
+
+    private final byte[] bytes;
+
+    public StartWithIPAddressPermission(String mask) {
+        Matcher matcher = MASK_VALIDATOR.matcher(mask);
+        if (false == matcher.matches()) {
+            throw new IllegalArgumentException("Mask " + mask + " does not match pattern
" + MASK_VALIDATOR.pattern());
+        }
+
+        Byte[] tmpBytes = new Byte[4];
+        boolean isWildCard = false;
+        int size = 0;
+        for (int i = 0; i < 3; i++) {
+            String group = matcher.group(i + 1);
+            if (group.equals("0")) {
+                isWildCard = true;
+            } else if (isWildCard) {
+                throw new IllegalArgumentException("0 at position " + size + " in mask");
+            } else {
+                int value = Integer.parseInt(group);
+                if (value < 0 || 255 < value) {
+                    throw new IllegalArgumentException("byte #" + i + " is not valid.");
+                }
+                tmpBytes[i] = new Byte((byte) value);
+                size++;
+            }
+        }
+
+        bytes = new byte[size];
+        for (int i = 0; i < bytes.length; i++) {
+            bytes[i] = tmpBytes[i].byteValue();
+        }
+    }
+
+    public boolean implies(InetAddress address) {
+        if (false == address instanceof Inet4Address) {
+            return false;
+        }
+
+        byte[] byteAddress = address.getAddress();
+        for (int i = 0; i < bytes.length; i++) {
+            if (byteAddress[i] != bytes[i]) {
+                return false;
+            }
+        }
+        return true;
+    }
+}



Mime
View raw message