FirewallPlugin.java
001 /*
002  *
003  * Licensed to the Apache Software Foundation (ASF) under one
004  * or more contributor license agreements.  See the NOTICE file
005  * distributed with this work for additional information
006  * regarding copyright ownership.  The ASF licenses this file
007  * to you under the Apache License, Version 2.0 (the
008  * "License"); you may not use this file except in compliance
009  * with the License.  You may obtain a copy of the License at
010  *
011  *   http://www.apache.org/licenses/LICENSE-2.0
012  *
013  * Unless required by applicable law or agreed to in writing,
014  * software distributed under the License is distributed on an
015  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
016  * KIND, either express or implied.  See the License for the
017  * specific language governing permissions and limitations
018  * under the License.
019  *
020  */
021 package org.apache.qpid.server.security.access.plugins.network;
022 
023 import java.net.InetAddress;
024 import java.net.InetSocketAddress;
025 import java.net.SocketAddress;
026 import java.util.List;
027 import java.util.regex.Pattern;
028 
029 import org.apache.commons.configuration.Configuration;
030 import org.apache.qpid.server.protocol.AMQMinaProtocolSession;
031 import org.apache.qpid.server.protocol.AMQProtocolSession;
032 import org.apache.qpid.server.security.access.plugins.AbstractACLPlugin;
033 import org.apache.qpid.server.virtualhost.VirtualHost;
034 import org.apache.qpid.util.NetMatcher;
035 
036 public class FirewallPlugin extends AbstractACLPlugin
037 {
038 
039     public class FirewallRule
040     {
041 
042         private AuthzResult _access;
043         private NetMatcher _network;
044         private Pattern[] _hostnamePatterns;
045 
046         public FirewallRule(String access, List networks, List hostnames)
047         {
048             _access = (access.equals("allow")) ? AuthzResult.ALLOWED : AuthzResult.DENIED;
049             
050             if (networks != null && networks.size() 0)
051             {
052                 String[] networkStrings = objListToStringArray(networks);
053                 _network = new NetMatcher(networkStrings);
054             }
055             
056             if (hostnames != null && hostnames.size() 0)
057             {
058                 int i = 0;
059                 _hostnamePatterns = new Pattern[hostnames.size()];
060                 for (String hostname : objListToStringArray(hostnames))
061                 {
062                     _hostnamePatterns[i++= Pattern.compile(hostname);
063                 }
064             }
065             
066         }
067 
068         private String[] objListToStringArray(List objList)
069         {
070             String[] networkStrings = new String[objList.size()];
071             int i = 0;
072             for (Object network : objList)
073             {
074                 networkStrings[i++(Stringnetwork;
075             }
076             return networkStrings;
077         }
078 
079         public boolean match(InetAddress remote)
080         {
081             if (_hostnamePatterns != null)
082             {
083                 String hostname = remote.getCanonicalHostName();
084                 for (Pattern pattern : _hostnamePatterns)
085                 {
086                     if (pattern.matcher(hostname).matches())
087                     {
088                         return true;
089                     }
090                 }
091                 return false;
092             }
093             else
094             {
095                 return _network.matchInetNetwork(remote);
096             }
097         }
098 
099         public AuthzResult getAccess()
100         {
101             return _access;
102         }
103 
104     }
105 
106     private AuthzResult _default = AuthzResult.ABSTAIN;
107     private FirewallRule[] _rules;
108 
109     @Override
110     public AuthzResult authoriseConnect(AMQProtocolSession session, VirtualHost virtualHost)
111     {
112         if (!(session instanceof AMQMinaProtocolSession))
113         {
114             return AuthzResult.ABSTAIN; // We only deal with tcp sessions, which
115                                         // mean MINA right now
116         }
117 
118         InetAddress addr = getInetAdressFromMinaSession((AMQMinaProtocolSessionsession);
119 
120         if (addr == null)
121         {
122             return AuthzResult.ABSTAIN; // Not an Inet socket on the other end
123         }
124 
125         boolean match = false;
126         for (FirewallRule rule : _rules)
127         {
128             match = rule.match(addr);
129             if (match)
130             {
131                 return rule.getAccess();
132             }
133         }
134         return _default;
135 
136     }
137 
138     private InetAddress getInetAdressFromMinaSession(AMQMinaProtocolSession session)
139     {
140         SocketAddress remote = session.getIOSession().getRemoteAddress();
141         if (remote instanceof InetSocketAddress)
142         {
143             return ((InetSocketAddressremote).getAddress();
144         }
145         else
146         {
147             return null;
148         }
149     }
150 
151     @Override
152     public void setConfiguration(Configuration config)
153     {
154         // Get default action
155         String defaultAction = config.getString("[@default-action]");
156         if (defaultAction == null)
157         {
158             _default = AuthzResult.ABSTAIN;
159         }
160         else if (defaultAction.toLowerCase().equals("allow"))
161         {
162             _default = AuthzResult.ALLOWED;
163         }
164         else
165         {
166             _default = AuthzResult.DENIED;
167         }
168 
169         int numRules = config.getList("rule[@access]").size()// all rules must
170         // have an access
171         // attribute
172         _rules = new FirewallRule[numRules];
173         for (int i = 0; i < numRules; i++)
174         {
175             FirewallRule rule = new FirewallRule(config.getString("rule(" + i + ")[@access]"), config.getList("rule("
176                     + i + ")[@network]"), config.getList("rule(" + i + ")[@hostname]"));
177             _rules[i= rule;
178         }
179     }
180 }