You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tomee.apache.org by db...@apache.org on 2008/04/04 23:04:26 UTC

svn commit: r644923 - in /openejb/branches/openejb-3.0/server/openejb-server/src/main/java/org/apache/openejb/server: ./ auth/

Author: dblevins
Date: Fri Apr  4 14:04:24 2008
New Revision: 644923

URL: http://svn.apache.org/viewvc?rev=644923&view=rev
Log:
Merging r644521 - http://svn.apache.org/viewvc?rev=644521&view=rev

svn merge -r 644520:644521 https://svn.apache.org/repos/asf/openejb/trunk/openejb3 .

------------------------------------------------------------------------
r644521 | dblevins | 2008-04-03 14:37:00 -0700 (Thu, 03 Apr 2008) | 2 lines

Ported thread pooling and host-based authorization code

------------------------------------------------------------------------

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

Modified: openejb/branches/openejb-3.0/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceAccessController.java
URL: http://svn.apache.org/viewvc/openejb/branches/openejb-3.0/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceAccessController.java?rev=644923&r1=644922&r2=644923&view=diff
==============================================================================
--- openejb/branches/openejb-3.0/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceAccessController.java (original)
+++ openejb/branches/openejb-3.0/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceAccessController.java Fri Apr  4 14:04:24 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/branches/openejb-3.0/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceDaemon.java
URL: http://svn.apache.org/viewvc/openejb/branches/openejb-3.0/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceDaemon.java?rev=644923&r1=644922&r2=644923&view=diff
==============================================================================
--- openejb/branches/openejb-3.0/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceDaemon.java (original)
+++ openejb/branches/openejb-3.0/server/openejb-server/src/main/java/org/apache/openejb/server/ServiceDaemon.java Fri Apr  4 14:04:24 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();
         }
     }
 }