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++] = (String) network;
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((AMQMinaProtocolSession) session);
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 ((InetSocketAddress) remote).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 }
|