1 /** 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 package org.apache.openejb.server; 18 19 20 import org.apache.openejb.server.auth.IPAddressPermission; 21 import org.apache.openejb.server.auth.ExactIPAddressPermission; 22 import org.apache.openejb.server.auth.ExactIPv6AddressPermission; 23 import org.apache.openejb.server.auth.IPAddressPermissionFactory; 24 import org.apache.openejb.server.auth.PermitAllPermission; 25 26 import java.io.IOException; 27 import java.io.InputStream; 28 import java.io.OutputStream; 29 import java.net.Inet4Address; 30 import java.net.InetAddress; 31 import java.net.Socket; 32 import java.net.UnknownHostException; 33 import java.util.LinkedList; 34 import java.util.Properties; 35 import java.util.StringTokenizer; 36 37 /** 38 */ 39 public class ServiceAccessController implements ServerService { 40 41 private final ServerService next; 42 private IPAddressPermission[] hostPermissions; 43 44 public ServiceAccessController(ServerService next) { 45 this.next = next; 46 } 47 48 public void service(Socket socket) throws ServiceException, IOException { 49 // Check authorization 50 checkHostsAuthorization(socket.getInetAddress(), socket.getLocalAddress()); 51 52 next.service(socket); 53 } 54 55 public void service(InputStream in, OutputStream out) throws ServiceException, IOException { 56 throw new UnsupportedOperationException("service(in,out)"); 57 } 58 59 public void checkHostsAuthorization(InetAddress clientAddress, InetAddress serverAddress) throws SecurityException { 60 // Check the client ip against the server ip. Hosts are 61 // allowed to access themselves, so if these ips 62 // match, the following for loop will be skipped. 63 if (clientAddress.equals(serverAddress)) { 64 return; 65 } 66 67 for (IPAddressPermission host : hostPermissions) { 68 if (host.implies(clientAddress)) { 69 return; 70 } 71 } 72 73 throw new SecurityException("Host " + clientAddress.getHostAddress() + " is not authorized to access this service."); 74 } 75 76 private void parseAdminIPs(Properties props) throws ServiceException { 77 LinkedList<IPAddressPermission> permissions = new LinkedList<IPAddressPermission>(); 78 79 String ipString = props.getProperty("only_from"); 80 81 if (ipString == null) { 82 permissions.add(new PermitAllPermission()); 83 } else { 84 String hostname = "localhost"; 85 addIPAddressPermissions(permissions, hostname); 86 87 StringTokenizer st = new StringTokenizer(ipString, ", \n\t"); 88 while (st.hasMoreTokens()) { 89 String mask = st.nextToken(); 90 try { 91 permissions.add(IPAddressPermissionFactory.getIPAddressMask(mask)); 92 } catch (IllegalArgumentException iae) { 93 // it could be that it is a hostname not ip address 94 addIPAddressPermissions(permissions, mask); 95 } 96 } 97 } 98 99 hostPermissions = (IPAddressPermission[]) permissions.toArray(new IPAddressPermission[permissions.size()]); 100 } 101 102 private void addIPAddressPermissions( 103 LinkedList<IPAddressPermission> permissions, String hostname) 104 throws ServiceException { 105 try { 106 InetAddress[] localIps = InetAddress.getAllByName(hostname); 107 for (int i = 0; i < localIps.length; i++) { 108 if (localIps[i] instanceof Inet4Address) { 109 permissions.add(new ExactIPAddressPermission(localIps[i].getAddress())); 110 } else { 111 permissions.add(new ExactIPv6AddressPermission(localIps[i].getAddress())); 112 } 113 } 114 } catch (UnknownHostException e) { 115 throw new ServiceException("Could not get " + hostname + " inet address", e); 116 } 117 } 118 119 public void init(Properties props) throws Exception { 120 parseAdminIPs(props); 121 next.init(props); 122 } 123 124 public void start() throws ServiceException { 125 next.start(); 126 } 127 128 public void stop() throws ServiceException { 129 next.stop(); 130 } 131 132 public String getName() { 133 return next.getName(); 134 } 135 136 public String getIP() { 137 return next.getIP(); 138 } 139 140 public int getPort() { 141 return next.getPort(); 142 } 143 144 }