From b8ee522006dc367c8c1e481cdf5cf2874dd74d88 Mon Sep 17 00:00:00 2001 From: Martin Ritchie Date: Mon, 13 Apr 2009 11:55:21 +0000 Subject: QPID-1583: Implement support for comma-seperated lists of networks and hostnames. merged from trunk r743311 git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/0.5-fix@764420 13f79535-47bb-0310-9956-ffa450edef68 --- .../access/plugins/network/FirewallPlugin.java | 76 ++++++++++++++++------ .../apache/qpid/server/protocol/TestIoSession.java | 24 +++++-- .../access/plugins/network/FirewallPluginTest.java | 31 ++++++++- 3 files changed, 100 insertions(+), 31 deletions(-) diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallPlugin.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallPlugin.java index c0089d5e12..cb8b6f6fed 100644 --- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallPlugin.java +++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/network/FirewallPlugin.java @@ -23,6 +23,7 @@ package org.apache.qpid.server.security.access.plugins.network; import java.net.InetAddress; import java.net.InetSocketAddress; import java.net.SocketAddress; +import java.util.List; import java.util.regex.Pattern; import org.apache.commons.configuration.Configuration; @@ -32,8 +33,6 @@ import org.apache.qpid.server.security.access.plugins.AbstractACLPlugin; import org.apache.qpid.server.virtualhost.VirtualHost; import org.apache.qpid.util.NetMatcher; -import sun.net.util.IPAddressUtil; - public class FirewallPlugin extends AbstractACLPlugin { @@ -42,20 +41,54 @@ public class FirewallPlugin extends AbstractACLPlugin private AuthzResult _access; private NetMatcher _network; - private Pattern _hostnamePattern; + private Pattern[] _hostnamePatterns; - public FirewallRule(String access, String network, String hostname) + public FirewallRule(String access, List networks, List hostnames) { _access = (access.equals("allow")) ? AuthzResult.ALLOWED : AuthzResult.DENIED; - _network = (network != null) ? new NetMatcher(new String[]{network}) : null; - _hostnamePattern = (hostname != null) ? Pattern.compile(hostname) : null; + + if (networks != null && networks.size() > 0) + { + String[] networkStrings = objListToStringArray(networks); + _network = new NetMatcher(networkStrings); + } + + if (hostnames != null && hostnames.size() > 0) + { + int i = 0; + _hostnamePatterns = new Pattern[hostnames.size()]; + for (String hostname : objListToStringArray(hostnames)) + { + _hostnamePatterns[i++] = Pattern.compile(hostname); + } + } + + } + + private String[] objListToStringArray(List objList) + { + String[] networkStrings = new String[objList.size()]; + int i = 0; + for (Object network : objList) + { + networkStrings[i++] = (String) network; + } + return networkStrings; } public boolean match(InetAddress remote) { - if (_hostnamePattern != null) + if (_hostnamePatterns != null) { - return _hostnamePattern.matcher(remote.getCanonicalHostName()).matches(); + String hostname = remote.getCanonicalHostName(); + for (Pattern pattern : _hostnamePatterns) + { + if (pattern.matcher(hostname).matches()) + { + return true; + } + } + return false; } else { @@ -78,16 +111,17 @@ public class FirewallPlugin extends AbstractACLPlugin { if (!(session instanceof AMQMinaProtocolSession)) { - return AuthzResult.ABSTAIN; // We only deal with tcp sessions, which mean MINA right now + return AuthzResult.ABSTAIN; // We only deal with tcp sessions, which + // mean MINA right now } InetAddress addr = getInetAdressFromMinaSession((AMQMinaProtocolSession) session); - + if (addr == null) { return AuthzResult.ABSTAIN; // Not an Inet socket on the other end } - + boolean match = false; for (FirewallRule rule : _rules) { @@ -107,7 +141,7 @@ public class FirewallPlugin extends AbstractACLPlugin if (remote instanceof InetSocketAddress) { return ((InetSocketAddress) remote).getAddress(); - } + } else { return null; @@ -119,27 +153,27 @@ public class FirewallPlugin extends AbstractACLPlugin { // Get default action String defaultAction = config.getString("[@default-action]"); - if (defaultAction == null) { + if (defaultAction == null) + { _default = AuthzResult.ABSTAIN; - } + } else if (defaultAction.toLowerCase().equals("allow")) { _default = AuthzResult.ALLOWED; } - else + else { _default = AuthzResult.DENIED; } - + int numRules = config.getList("rule[@access]").size(); // all rules must - // have an access - // attribute + // have an access + // attribute _rules = new FirewallRule[numRules]; for (int i = 0; i < numRules; i++) { - FirewallRule rule = new FirewallRule((String) config.getProperty("rule(" + i + ")[@access]"), - (String) config.getProperty("rule(" + i + ")[@network]"), (String) config.getProperty("rule(" + i - + ")[@hostname]")); + FirewallRule rule = new FirewallRule(config.getString("rule(" + i + ")[@access]"), config.getList("rule(" + + i + ")[@network]"), config.getList("rule(" + i + ")[@hostname]")); _rules[i] = rule; } } diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/TestIoSession.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/TestIoSession.java index c449135bd2..211f491867 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/TestIoSession.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/protocol/TestIoSession.java @@ -20,16 +20,26 @@ */ package org.apache.qpid.server.protocol; -import org.apache.mina.common.*; -import org.apache.mina.transport.socket.nio.SocketAcceptorConfig; -import org.apache.qpid.pool.ReadWriteThreadModel; - -import java.net.InetAddress; -import java.net.SocketAddress; import java.net.InetSocketAddress; +import java.net.SocketAddress; import java.util.Set; -import java.util.concurrent.ConcurrentMap; import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.apache.mina.common.CloseFuture; +import org.apache.mina.common.IdleStatus; +import org.apache.mina.common.IoFilterChain; +import org.apache.mina.common.IoHandler; +import org.apache.mina.common.IoService; +import org.apache.mina.common.IoServiceConfig; +import org.apache.mina.common.IoSession; +import org.apache.mina.common.IoSessionConfig; +import org.apache.mina.common.ThreadModel; +import org.apache.mina.common.TrafficMask; +import org.apache.mina.common.TransportType; +import org.apache.mina.common.WriteFuture; +import org.apache.mina.transport.socket.nio.SocketAcceptorConfig; +import org.apache.qpid.pool.ReadWriteThreadModel; /** * Test implementation of IoSession, which is required for some tests. Methods not being used are not implemented, diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/plugins/network/FirewallPluginTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/plugins/network/FirewallPluginTest.java index 5229146847..8028362979 100644 --- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/plugins/network/FirewallPluginTest.java +++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/plugins/network/FirewallPluginTest.java @@ -25,15 +25,12 @@ import java.io.BufferedWriter; import java.io.File; import java.io.FileWriter; import java.io.IOException; -import java.net.Inet4Address; -import java.net.InetAddress; import java.net.InetSocketAddress; import junit.framework.TestCase; import org.apache.commons.configuration.ConfigurationException; import org.apache.commons.configuration.XMLConfiguration; -import org.apache.mina.common.IoSession; import org.apache.qpid.codec.AMQCodecFactory; import org.apache.qpid.server.protocol.AMQMinaProtocolSession; import org.apache.qpid.server.protocol.TestIoSession; @@ -264,4 +261,32 @@ public class FirewallPluginTest extends TestCase assertEquals(AuthzResult.ALLOWED, plugin.authoriseConnect(_session, _virtualHost)); } + public void testCommaSeperatedNetmask() throws Exception + { + RuleInfo firstRule = new RuleInfo(); + firstRule.setAccess("allow"); + firstRule.setNetwork("10.1.1.1/8, 192.168.23.0/24"); + FirewallPlugin plugin = initialisePlugin("deny", new RuleInfo[]{firstRule}); + + assertEquals(AuthzResult.DENIED, plugin.authoriseConnect(_session, _virtualHost)); + + // Set session IP so that we're connected from the right address + ((TestIoSession) _session.getIOSession()).setAddress("192.168.23.23"); + assertEquals(AuthzResult.ALLOWED, plugin.authoriseConnect(_session, _virtualHost)); + } + + public void testCommaSeperatedHostnames() throws Exception + { + RuleInfo firstRule = new RuleInfo(); + firstRule.setAccess("allow"); + firstRule.setHostname("foo, bar, "+new InetSocketAddress("127.0.0.1", 5672).getHostName()); + FirewallPlugin plugin = initialisePlugin("deny", new RuleInfo[]{firstRule}); + ((TestIoSession) _session.getIOSession()).setAddress("10.0.0.1"); + assertEquals(AuthzResult.DENIED, plugin.authoriseConnect(_session, _virtualHost)); + + // Set session IP so that we're connected from the right address + ((TestIoSession) _session.getIOSession()).setAddress("127.0.0.1"); + assertEquals(AuthzResult.ALLOWED, plugin.authoriseConnect(_session, _virtualHost)); + } + } -- cgit v1.2.1