summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
authorKeith Wall <kwall@apache.org>2012-09-28 12:46:06 +0000
committerKeith Wall <kwall@apache.org>2012-09-28 12:46:06 +0000
commit7cd3770948fa5f39d7ba5655051c0fada76a8614 (patch)
tree37e8e3217462ae6cd53b5c37d0e278b6027ff44e /java
parent203d6d4c76fbb7f52c507318ef0e92b8d4dba0bf (diff)
downloadqpid-python-7cd3770948fa5f39d7ba5655051c0fada76a8614.tar.gz
QPID-4334: removed the firewall plugin and moved its functionality into the Access Control plugin.
Applied patch from Philip Harvey <phil@philharveyonline.com>. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1391430 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java')
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AbstractConfiguration.java3
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclAction.java102
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclRulePredicates.java99
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Action.java61
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ClientAction.java88
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/PlainConfiguration.java32
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Rule.java24
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java54
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/AccessControlFirewallException.java (renamed from java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/config/FirewallException.java)17
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/FirewallRule.java26
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/FirewallRuleFactory.java (renamed from java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/FirewallActivator.java)26
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/HostnameFirewallRule.java156
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/InetNetwork.java (renamed from java/common/src/main/java/org/apache/qpid/util/NetMatcher.java)155
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/NetworkFirewallRule.java117
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/logging/AccessControl_logmessages.properties2
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java38
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclActionTest.java66
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclRulePredicatesTest.java87
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/ClientActionTest.java79
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/RuleTest.java53
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/firewall/HostnameFirewallRuleTest.java99
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/firewall/NetworkFirewallRuleTest.java115
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/AccessControlTest.java52
-rw-r--r--java/broker-plugins/firewall/MANIFEST.MF34
-rw-r--r--java/broker-plugins/firewall/build.xml34
-rw-r--r--java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/config/FirewallRule.java136
-rw-r--r--java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/Firewall.java137
-rw-r--r--java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/FirewallConfiguration.java103
-rw-r--r--java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java322
-rw-r--r--java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallPluginTest.java294
-rw-r--r--java/broker/etc/broker_example.acl17
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java206
-rw-r--r--java/ivy.nexus.xml6
-rw-r--r--java/systests/etc/config-systests-firewall-2.xml83
-rw-r--r--java/systests/etc/config-systests-firewall-3.xml85
-rw-r--r--java/systests/etc/config-systests-firewall-settings.xml30
-rw-r--r--java/systests/etc/config-systests-firewall.xml30
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java29
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/security/firewall/FirewallConfigTest.java283
39 files changed, 1439 insertions, 1941 deletions
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AbstractConfiguration.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AbstractConfiguration.java
index f04dd38aca..44c48523e2 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AbstractConfiguration.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AbstractConfiguration.java
@@ -23,12 +23,9 @@ package org.apache.qpid.server.security.access.config;
import java.io.File;
import org.apache.commons.configuration.ConfigurationException;
-import org.apache.log4j.Logger;
public abstract class AbstractConfiguration implements ConfigurationFile
{
- private static final Logger _logger = Logger.getLogger(ConfigurationFile.class);
-
private File _file;
private RuleSet _config;
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclAction.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclAction.java
new file mode 100644
index 0000000000..e4bf21a082
--- /dev/null
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclAction.java
@@ -0,0 +1,102 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.server.security.access.config;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.qpid.server.security.access.ObjectType;
+import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.security.access.firewall.FirewallRule;
+
+public class AclAction
+{
+ private Action _action;
+ private FirewallRule _firewallRule;
+
+ public AclAction(Operation operation, ObjectType object, AclRulePredicates predicates)
+ {
+ _action = new Action(operation, object, predicates.getObjectProperties());
+ _firewallRule = predicates.getFirewallRule();
+ }
+
+ public AclAction(Operation operation)
+ {
+ _action = new Action(operation);
+ }
+
+ public AclAction(Operation operation, ObjectType object, ObjectProperties properties)
+ {
+ _action = new Action(operation, object, properties);
+ }
+
+ public FirewallRule getFirewallRule()
+ {
+ return _firewallRule;
+ }
+
+ public Action getAction()
+ {
+ return _action;
+ }
+
+ public boolean isAllowed()
+ {
+ return _action.isAllowed();
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return new HashCodeBuilder()
+ .append(_action)
+ .append(_firewallRule).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == null)
+ {
+ return false;
+ }
+ if (obj == this)
+ {
+ return true;
+ }
+ if (obj.getClass() != getClass())
+ {
+ return false;
+ }
+ AclAction rhs = (AclAction) obj;
+ return new EqualsBuilder()
+ .append(_action, rhs._action)
+ .append(_firewallRule, rhs._firewallRule).isEquals();
+ }
+
+ @Override
+ public String toString()
+ {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+ .append(_action)
+ .append(_firewallRule).toString();
+ }
+}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclRulePredicates.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclRulePredicates.java
new file mode 100644
index 0000000000..0ea6b2fc9c
--- /dev/null
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/AclRulePredicates.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.server.security.access.config;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.qpid.server.security.access.ObjectProperties.Property;
+import org.apache.qpid.server.security.access.firewall.FirewallRule;
+import org.apache.qpid.server.security.access.firewall.FirewallRuleFactory;
+
+/**
+ * Represents the predicates on an ACL rule by combining predicates relating to the object being operated on
+ * (e.g. name=foo) with firewall rules.
+ */
+public class AclRulePredicates
+{
+ private static final Logger _logger = Logger.getLogger(AclRulePredicates.class);
+
+ private static final String SEPARATOR = ",";
+
+ private ObjectProperties _properties = new ObjectProperties();
+
+ private FirewallRule _firewallRule;
+
+ private FirewallRuleFactory _firewallRuleFactory = new FirewallRuleFactory();
+
+ public void parse(String key, String value)
+ {
+ ObjectProperties.Property property = ObjectProperties.Property.parse(key);
+
+ if(property == Property.FROM_HOSTNAME)
+ {
+ checkFirewallRuleNotAlreadyDefined(key, value);
+ _firewallRule = _firewallRuleFactory.createForHostname(value.split(SEPARATOR));
+ }
+ else if(property == Property.FROM_NETWORK)
+ {
+ checkFirewallRuleNotAlreadyDefined(key, value);
+ _firewallRule = _firewallRuleFactory.createForNetwork(value.split(SEPARATOR));
+ }
+ else
+ {
+ _properties.put(property, value);
+ }
+
+ _logger.debug("Parsed " + property + " with value " + value);
+ }
+
+ private void checkFirewallRuleNotAlreadyDefined(String key, String value)
+ {
+ if(_firewallRule != null)
+ {
+ throw new IllegalStateException(
+ "Cannot parse " + key + "=" + value
+ + " because firewall rule " + _firewallRule + " has already been defined");
+ }
+ }
+
+ @Override
+ public String toString()
+ {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+ .append(_properties)
+ .append(_firewallRule).toString();
+ }
+
+ public FirewallRule getFirewallRule()
+ {
+ return _firewallRule;
+ }
+
+ public ObjectProperties getObjectProperties()
+ {
+ return _properties;
+ }
+
+ void setFirewallRuleFactory(FirewallRuleFactory firewallRuleFactory)
+ {
+ _firewallRuleFactory = firewallRuleFactory;
+ }
+}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Action.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Action.java
index b887d1e079..d244af480a 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Action.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Action.java
@@ -20,8 +20,6 @@
*/
package org.apache.qpid.server.security.access.config;
-import java.util.Comparator;
-
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
@@ -32,7 +30,7 @@ import org.apache.qpid.server.security.access.Operation;
/**
* An access control v2 rule action.
- *
+ *
* An action consists of an {@link Operation} on an {@link ObjectType} with certain properties, stored in a {@link java.util.Map}.
* The operation and object should be an allowable combination, based on the {@link ObjectType#isAllowed(Operation)}
* method of the object, which is exposed as the {@link #isAllowed()} method here. The internal {@link #propertiesMatch(Map)}
@@ -48,29 +46,29 @@ public class Action
private Operation _operation;
private ObjectType _object;
private ObjectProperties _properties;
-
+
public Action(Operation operation)
{
this(operation, ObjectType.ALL);
}
-
+
public Action(Operation operation, ObjectType object, String name)
{
this(operation, object, new ObjectProperties(name));
}
-
+
public Action(Operation operation, ObjectType object)
{
this(operation, object, ObjectProperties.EMPTY);
}
-
+
public Action(Operation operation, ObjectType object, ObjectProperties properties)
{
setOperation(operation);
setObjectType(object);
setProperties(properties);
}
-
+
public Operation getOperation()
{
return _operation;
@@ -95,12 +93,12 @@ public class Action
{
return _properties;
}
-
+
public void setProperties(ObjectProperties properties)
{
_properties = properties;
}
-
+
public boolean isAllowed()
{
return _object.isAllowed(_operation);
@@ -109,40 +107,13 @@ public class Action
/** @see Comparable#compareTo(Object) */
public boolean matches(Action a)
{
- return ((Operation.ALL == a.getOperation() || getOperation() == a.getOperation())
- && (ObjectType.ALL == a.getObjectType() || getObjectType() == a.getObjectType())
- && _properties.matches(a.getProperties()));
- }
+ boolean operationMatches = Operation.ALL == a.getOperation() || getOperation() == a.getOperation();
+ boolean objectTypeMatches = ObjectType.ALL == a.getObjectType() || getObjectType() == a.getObjectType();
+ boolean propertiesMatch = _properties.matches(a.getProperties());
- /**
- * An ordering based on specificity
- *
- * @see Comparator#compare(Object, Object)
- */
- public class Specificity implements Comparator<Action>
- {
- public int compare(Action a, Action b)
- {
- if (a.getOperation() == Operation.ALL && b.getOperation() != Operation.ALL)
- {
- return 1; // B is more specific
- }
- else if (b.getOperation() == Operation.ALL && a.getOperation() != Operation.ALL)
- {
- return 1; // A is more specific
- }
- else if (a.getOperation() == b.getOperation())
- {
- return 1; // b is more specific
- }
- else // Different operations
- {
- return a.getOperation().compareTo(b.getOperation()); // Arbitrary
- }
- }
+ return (operationMatches && objectTypeMatches && propertiesMatch);
}
- /** @see Object#equals(Object) */
@Override
public boolean equals(Object o)
{
@@ -151,26 +122,24 @@ public class Action
return false;
}
Action a = (Action) o;
-
+
return new EqualsBuilder()
.append(_operation, a.getOperation())
.append(_object, a.getObjectType())
- .appendSuper(_properties.equals(a.getProperties()))
+ .append(_properties, a.getProperties())
.isEquals();
}
- /** @see Object#hashCode() */
@Override
public int hashCode()
{
return new HashCodeBuilder()
.append(_operation)
- .append(_operation)
+ .append(_object)
.append(_properties)
.toHashCode();
}
- /** @see Object#toString() */
@Override
public String toString()
{
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ClientAction.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ClientAction.java
new file mode 100644
index 0000000000..fed20a56c8
--- /dev/null
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/ClientAction.java
@@ -0,0 +1,88 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.server.security.access.config;
+
+import java.net.InetAddress;
+
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.qpid.server.security.access.ObjectType;
+import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.security.access.firewall.FirewallRule;
+
+/**
+ * I represent an {@link Action} taken by a client from a known address. The address is used to
+ * determine if I match an {@link AclAction}, which may contain firewall rules.
+ */
+public class ClientAction
+{
+ private Action _clientAction;
+
+ public ClientAction(Action clientAction)
+ {
+ _clientAction = clientAction;
+ }
+
+ public ClientAction(Operation operation, ObjectType objectType, ObjectProperties properties)
+ {
+ _clientAction = new Action(operation, objectType, properties);
+ }
+
+ public boolean matches(AclAction ruleAction, InetAddress addressOfClient)
+ {
+ return _clientAction.matches(ruleAction.getAction())
+ && addressOfClientMatches(ruleAction, addressOfClient);
+ }
+
+ private boolean addressOfClientMatches(AclAction ruleAction, InetAddress addressOfClient)
+ {
+ FirewallRule firewallRule = ruleAction.getFirewallRule();
+ if(firewallRule == null || addressOfClient == null)
+ {
+ return true;
+ }
+ else
+ {
+ return firewallRule.matches(addressOfClient);
+ }
+ }
+
+ public Operation getOperation()
+ {
+ return _clientAction.getOperation();
+ }
+
+ public ObjectType getObjectType()
+ {
+ return _clientAction.getObjectType();
+ }
+
+ public ObjectProperties getProperties()
+ {
+ return _clientAction.getProperties();
+ }
+
+ @Override
+ public String toString()
+ {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+ .append(_clientAction).toString();
+ }
+}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/PlainConfiguration.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/PlainConfiguration.java
index afaece6138..9f56b05e0f 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/PlainConfiguration.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/PlainConfiguration.java
@@ -34,13 +34,15 @@ import java.util.Stack;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.commons.lang.StringUtils;
-import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.log4j.Logger;
import org.apache.qpid.server.security.access.ObjectType;
import org.apache.qpid.server.security.access.Operation;
import org.apache.qpid.server.security.access.Permission;
public class PlainConfiguration extends AbstractConfiguration
{
+ private static final Logger _logger = Logger.getLogger(PlainConfiguration.class);
+
public static final Character COMMENT = '#';
public static final Character CONTINUATION = '\\';
@@ -74,9 +76,16 @@ public class PlainConfiguration extends AbstractConfiguration
{
RuleSet ruleSet = super.load();
+ File file = getFile();
+
try
{
- _st = new StreamTokenizer(new BufferedReader(new FileReader(getFile())));
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("About to load ACL file " + file);
+ }
+
+ _st = new StreamTokenizer(new BufferedReader(new FileReader(file)));
_st.resetSyntax(); // setup the tokenizer
_st.commentChar(COMMENT); // single line comments
@@ -195,11 +204,11 @@ public class PlainConfiguration extends AbstractConfiguration
}
catch (FileNotFoundException fnfe)
{
- throw new ConfigurationException(String.format(CONFIG_NOT_FOUND_MSG, getFile().getName()), fnfe);
+ throw new ConfigurationException(String.format(CONFIG_NOT_FOUND_MSG, file.getName()), fnfe);
}
catch (IOException ioe)
{
- throw new ConfigurationException(String.format(CANNOT_LOAD_MSG, getFile().getName()), ioe);
+ throw new ConfigurationException(String.format(CANNOT_LOAD_MSG, file.getName()), ioe);
}
return ruleSet;
@@ -228,9 +237,9 @@ public class PlainConfiguration extends AbstractConfiguration
else
{
ObjectType object = ObjectType.parse(args.get(3));
- ObjectProperties properties = toObjectProperties(args.subList(4, args.size()));
+ AclRulePredicates predicates = toRulePredicates(args.subList(4, args.size()));
- getConfiguration().grant(number, identity, permission, operation, object, properties);
+ getConfiguration().grant(number, identity, permission, operation, object, predicates);
}
}
@@ -246,10 +255,9 @@ public class PlainConfiguration extends AbstractConfiguration
getConfiguration().configure(properties);
}
- /** Converts a {@link List} of "name", "=", "value" tokens into a {@link Map}. */
- protected ObjectProperties toObjectProperties(List<String> args) throws ConfigurationException
+ private AclRulePredicates toRulePredicates(List<String> args) throws ConfigurationException
{
- ObjectProperties properties = new ObjectProperties();
+ AclRulePredicates predicates = new AclRulePredicates();
Iterator<String> i = args.iterator();
while (i.hasNext())
{
@@ -268,11 +276,9 @@ public class PlainConfiguration extends AbstractConfiguration
}
String value = i.next();
- // parse property key
- ObjectProperties.Property property = ObjectProperties.Property.parse(key);
- properties.put(property, value);
+ predicates.parse(key, value);
}
- return properties;
+ return predicates;
}
/** Converts a {@link List} of "name", "=", "value" tokens into a {@link Map}. */
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Rule.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Rule.java
index 5e98e0bd1b..cef9a8696b 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Rule.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/Rule.java
@@ -41,10 +41,10 @@ public class Rule implements Comparable<Rule>
private Integer _number;
private Boolean _enabled = Boolean.TRUE;
private String _identity;
- private Action _action;
+ private AclAction _action;
private Permission _permission;
- public Rule(Integer number, String identity, Action action, Permission permission)
+ public Rule(Integer number, String identity, AclAction action, Permission permission)
{
setNumber(number);
setIdentity(identity);
@@ -52,7 +52,7 @@ public class Rule implements Comparable<Rule>
setPermission(permission);
}
- public Rule(String identity, Action action, Permission permission)
+ public Rule(String identity, AclAction action, Permission permission)
{
this(null, identity, action, permission);
}
@@ -99,10 +99,15 @@ public class Rule implements Comparable<Rule>
public Action getAction()
{
+ return _action.getAction();
+ }
+
+ public AclAction getAclAction()
+ {
return _action;
}
- public void setAction(Action action)
+ public void setAction(AclAction action)
{
_action = action;
}
@@ -117,7 +122,7 @@ public class Rule implements Comparable<Rule>
_permission = permission;
}
- /** @see Comparable#compareTo(Object) */
+ @Override
public int compareTo(Rule r)
{
return new CompareToBuilder()
@@ -127,7 +132,6 @@ public class Rule implements Comparable<Rule>
.toComparison();
}
- /** @see Object#equals(Object) */
@Override
public boolean equals(Object o)
{
@@ -139,30 +143,28 @@ public class Rule implements Comparable<Rule>
return new EqualsBuilder()
.append(getIdentity(), r.getIdentity())
- .append(getAction(), r.getAction())
+ .append(getAclAction(), r.getAclAction())
.append(getPermission(), r.getPermission())
.isEquals();
}
- /** @see Object#hashCode() */
@Override
public int hashCode()
{
return new HashCodeBuilder()
.append(getIdentity())
- .append(getAction())
+ .append(getAclAction())
.append(getPermission())
.toHashCode();
}
- /** @see Object#toString() */
@Override
public String toString()
{
return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
.append("#", getNumber())
.append("identity", getIdentity())
- .append("action", getAction())
+ .append("action", getAclAction())
.append("permission", getPermission())
.append("enabled", isEnabled())
.toString();
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java
index 2477455de4..e61370fced 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java
@@ -18,6 +18,7 @@
*/
package org.apache.qpid.server.security.access.config;
+import java.net.InetAddress;
import java.security.Principal;
import java.util.Arrays;
import java.util.Collections;
@@ -53,7 +54,7 @@ import org.apache.qpid.server.security.access.logging.AccessControlMessages;
*/
public class RuleSet
{
- public static final Logger _logger = Logger.getLogger(RuleSet.class);
+ private static final Logger _logger = Logger.getLogger(RuleSet.class);
private static final String AT = "@";
private static final String SLASH = "/";
@@ -154,21 +155,27 @@ public class RuleSet
public void grant(Integer number, String identity, Permission permission, Operation operation)
{
- Action action = new Action(operation);
+ AclAction action = new AclAction(operation);
addRule(number, identity, permission, action);
}
public void grant(Integer number, String identity, Permission permission, Operation operation, ObjectType object, ObjectProperties properties)
{
- Action action = new Action(operation, object, properties);
+ AclAction action = new AclAction(operation, object, properties);
addRule(number, identity, permission, action);
}
- public boolean ruleExists(String identity, Action action)
+ public void grant(Integer number, String identity, Permission permission, Operation operation, ObjectType object, AclRulePredicates predicates)
+ {
+ AclAction aclAction = new AclAction(operation, object, predicates);
+ addRule(number, identity, permission, aclAction);
+ }
+
+ public boolean ruleExists(String identity, AclAction action)
{
for (Rule rule : _rules.values())
{
- if (rule.getIdentity().equals(identity) && rule.getAction().equals(action))
+ if (rule.getIdentity().equals(identity) && rule.getAclAction().equals(action))
{
return true;
}
@@ -176,8 +183,7 @@ public class RuleSet
return false;
}
- // TODO make this work when group membership is not known at file parse time
- public void addRule(Integer number, String identity, Permission permission, Action action)
+ public void addRule(Integer number, String identity, Permission permission, AclAction action)
{
_cache.clear();
@@ -263,6 +269,16 @@ public class RuleSet
}
/**
+ * Checks for the case when the client's address is not known.
+ *
+ * @see #check(Subject, Operation, ObjectType, ObjectProperties, InetAddress)
+ */
+ public Result check(Subject subject, Operation operation, ObjectType objectType, ObjectProperties properties)
+ {
+ return check(subject, operation, objectType, properties, null);
+ }
+
+ /**
* Check the authorisation granted to a particular identity for an operation on an object type with
* specific properties.
*
@@ -271,10 +287,9 @@ public class RuleSet
* the first match found, or denies access if there are no matching rules. Normally, it would be expected
* to have a default deny or allow rule at the end of an access configuration however.
*/
- public Result check(Subject subject, Operation operation, ObjectType objectType, ObjectProperties properties)
+ public Result check(Subject subject, Operation operation, ObjectType objectType, ObjectProperties properties, InetAddress addressOfClient)
{
- // Create the action to check
- Action action = new Action(operation, objectType, properties);
+ ClientAction action = new ClientAction(operation, objectType, properties);
if(_logger.isDebugEnabled())
{
@@ -293,27 +308,31 @@ public class RuleSet
}
// Iterate through a filtered set of rules dealing with this identity and operation
- for (Rule current : rules)
+ for (Rule rule : rules)
{
if(_logger.isDebugEnabled())
{
- _logger.debug("Checking against rule: " + current);
+ _logger.debug("Checking against rule: " + rule);
}
- // Check if action matches
- if (action.matches(current.getAction()))
+
+ if (action.matches(rule.getAclAction(), addressOfClient))
{
- Permission permission = current.getPermission();
+ Permission permission = rule.getPermission();
switch (permission)
{
case ALLOW_LOG:
CurrentActor.get().message(AccessControlMessages.ALLOWED(
- action.getOperation().toString(), action.getObjectType().toString(), action.getProperties().toString()));
+ action.getOperation().toString(),
+ action.getObjectType().toString(),
+ action.getProperties().toString()));
case ALLOW:
return Result.ALLOWED;
case DENY_LOG:
CurrentActor.get().message(AccessControlMessages.DENIED(
- action.getOperation().toString(), action.getObjectType().toString(), action.getProperties().toString()));
+ action.getOperation().toString(),
+ action.getObjectType().toString(),
+ action.getProperties().toString()));
case DENY:
return Result.DENIED;
}
@@ -419,5 +438,4 @@ public class RuleSet
}
return objects;
}
-
}
diff --git a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/config/FirewallException.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/AccessControlFirewallException.java
index a9e3fdc242..efae7f5653 100644
--- a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/config/FirewallException.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/AccessControlFirewallException.java
@@ -18,29 +18,26 @@
* under the License.
*
*/
-package org.apache.qpid.server.security.access.config;
+package org.apache.qpid.server.security.access.firewall;
-/**
- * Firewall plugin exception.
- */
-public class FirewallException extends Exception
+public class AccessControlFirewallException extends RuntimeException
{
/** serialVersionUID */
private static final long serialVersionUID = 4526157149690917805L;
-
- public FirewallException() {
+
+ public AccessControlFirewallException() {
super();
}
- public FirewallException(String message) {
+ public AccessControlFirewallException(String message) {
super(message);
}
- public FirewallException(String message, Throwable cause) {
+ public AccessControlFirewallException(String message, Throwable cause) {
super(message, cause);
}
- public FirewallException(Throwable cause) {
+ public AccessControlFirewallException(Throwable cause) {
super(cause);
}
} \ No newline at end of file
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/FirewallRule.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/FirewallRule.java
new file mode 100644
index 0000000000..482a795693
--- /dev/null
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/FirewallRule.java
@@ -0,0 +1,26 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.server.security.access.firewall;
+
+import java.net.InetAddress;
+
+public interface FirewallRule
+{
+ boolean matches(InetAddress addressOfClient);
+}
diff --git a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/FirewallActivator.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/FirewallRuleFactory.java
index 1669352085..64be26c209 100644
--- a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/FirewallActivator.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/FirewallRuleFactory.java
@@ -1,5 +1,4 @@
/*
- *
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
@@ -7,35 +6,28 @@
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
- *
+ *
* http://www.apache.org/licenses/LICENSE-2.0
- *
+ *
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
- *
*/
-package org.apache.qpid.server.security.access.plugins;
+package org.apache.qpid.server.security.access.firewall;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
-import org.apache.qpid.server.security.SecurityPluginActivator;
-import org.apache.qpid.server.security.SecurityPluginFactory;
-
-/**
- * The OSGi {@link org.osgi.framework.BundleActivator} for {@link Firewall}.
- */
-public class FirewallActivator extends SecurityPluginActivator
+public class FirewallRuleFactory
{
- public SecurityPluginFactory getFactory()
+ public FirewallRule createForHostname(String[] hostnames)
{
- return Firewall.FACTORY;
+ return new HostnameFirewallRule(hostnames);
}
- public ConfigurationPluginFactory getConfigurationFactory()
+ public FirewallRule createForNetwork(String[] networks)
{
- return FirewallConfiguration.FACTORY;
+ return new NetworkFirewallRule(networks);
}
+
}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/HostnameFirewallRule.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/HostnameFirewallRule.java
new file mode 100644
index 0000000000..9d60c6d745
--- /dev/null
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/HostnameFirewallRule.java
@@ -0,0 +1,156 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.server.security.access.firewall;
+
+import java.net.InetAddress;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.FutureTask;
+import java.util.concurrent.TimeUnit;
+import java.util.regex.Pattern;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.apache.log4j.Logger;
+
+public class HostnameFirewallRule implements FirewallRule
+{
+ private static final Logger _logger = Logger.getLogger(HostnameFirewallRule.class);
+
+ private static final long DNS_TIMEOUT = 30000;
+ private static final ExecutorService DNS_LOOKUP = Executors.newCachedThreadPool();
+
+ private Pattern[] _hostnamePatterns;
+ private String[] _hostnames;
+
+ public HostnameFirewallRule(String... hostnames)
+ {
+ _hostnames = hostnames;
+
+ int i = 0;
+ _hostnamePatterns = new Pattern[hostnames.length];
+ for (String hostname : hostnames)
+ {
+ _hostnamePatterns[i++] = Pattern.compile(hostname);
+ }
+
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Created " + this);
+ }
+ }
+
+ @Override
+ public boolean matches(InetAddress remote)
+ {
+ String hostname = getHostname(remote);
+ if (hostname == null)
+ {
+ throw new AccessControlFirewallException("DNS lookup failed");
+ }
+ for (Pattern pattern : _hostnamePatterns)
+ {
+ boolean hostnameMatches = pattern.matcher(hostname).matches();
+
+
+ if (hostnameMatches)
+ {
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Hostname " + hostname + " matches rule " + pattern.toString());
+ }
+ return true;
+ }
+ }
+
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Hostname " + hostname + " matches no configured hostname patterns");
+ }
+
+ return false;
+ }
+
+
+ /**
+ * @param remote
+ * the InetAddress to look up
+ * @return the hostname, null if not found, takes longer than
+ * {@value #DNS_LOOKUP} to find or otherwise fails
+ */
+ private String getHostname(final InetAddress remote) throws AccessControlFirewallException
+ {
+ FutureTask<String> lookup = new FutureTask<String>(new Callable<String>()
+ {
+ public String call()
+ {
+ return remote.getCanonicalHostName();
+ }
+ });
+ DNS_LOOKUP.execute(lookup);
+
+ try
+ {
+ return lookup.get(DNS_TIMEOUT, TimeUnit.MILLISECONDS);
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+ finally
+ {
+ lookup.cancel(true);
+ }
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return new HashCodeBuilder().append(_hostnames).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == null)
+ {
+ return false;
+ }
+ if (obj == this)
+ {
+ return true;
+ }
+ if (obj.getClass() != getClass())
+ {
+ return false;
+ }
+ HostnameFirewallRule rhs = (HostnameFirewallRule) obj;
+ return new EqualsBuilder().append(_hostnames, rhs._hostnames).isEquals();
+ }
+
+ @Override
+ public String toString()
+ {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+ .append(_hostnames).toString();
+ }
+}
diff --git a/java/common/src/main/java/org/apache/qpid/util/NetMatcher.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/InetNetwork.java
index 971dd3fe2a..52516af84c 100644
--- a/java/common/src/main/java/org/apache/qpid/util/NetMatcher.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/InetNetwork.java
@@ -1,131 +1,24 @@
-/***********************************************************************
- * Copyright (c) 2000-2006 The Apache Software Foundation. *
- * All rights reserved. *
- * ------------------------------------------------------------------- *
- * Licensed under the Apache License, Version 2.0 (the "License"); you *
- * may not use this file except in compliance with the License. You *
- * may obtain a copy of the License at: *
- * *
- * http://www.apache.org/licenses/LICENSE-2.0 *
- * *
- * Unless required by applicable law or agreed to in writing, software *
- * distributed under the License is distributed on an "AS IS" BASIS, *
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or *
- * implied. See the License for the specific language governing *
- * permissions and limitations under the License. *
- ***********************************************************************/
-
-package org.apache.qpid.util;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.server.security.access.firewall;
import java.net.InetAddress;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Iterator;
-
-public class NetMatcher
-{
- private ArrayList networks;
-
- public void initInetNetworks(final Collection nets)
- {
- networks = new ArrayList();
- for (Iterator iter = nets.iterator(); iter.hasNext(); )
- {
- try
- {
- InetNetwork net = InetNetwork.getFromString((String) iter.next());
- if (!networks.contains(net))
- {
- networks.add(net);
- }
- }
- catch (java.net.UnknownHostException uhe)
- {
- log("Cannot resolve address: " + uhe.getMessage());
- }
- }
- networks.trimToSize();
- }
-
- public void initInetNetworks(final String[] nets)
- {
- networks = new ArrayList();
- for (int i = 0; i < nets.length; i++)
- {
- try
- {
- InetNetwork net = InetNetwork.getFromString(nets[i]);
- if (!networks.contains(net))
- {
- networks.add(net);
- }
- }
- catch (java.net.UnknownHostException uhe)
- {
- log("Cannot resolve address: " + uhe.getMessage());
- }
- }
- networks.trimToSize();
- }
-
- public boolean matchInetNetwork(final String hostIP)
- {
- InetAddress ip = null;
-
- try
- {
- ip = InetAddress.getByName(hostIP);
- }
- catch (java.net.UnknownHostException uhe)
- {
- log("Cannot resolve address for " + hostIP + ": " + uhe.getMessage());
- }
-
- boolean sameNet = false;
-
- if (ip != null)
- {
- for (Iterator iter = networks.iterator(); (!sameNet) && iter.hasNext(); )
- {
- InetNetwork network = (InetNetwork) iter.next();
- sameNet = network.contains(ip);
- }
- }
- return sameNet;
- }
-
- public boolean matchInetNetwork(final InetAddress ip)
- {
- boolean sameNet = false;
-
- for (Iterator iter = networks.iterator(); (!sameNet) && iter.hasNext(); )
- {
- InetNetwork network = (InetNetwork) iter.next();
- sameNet = network.contains(ip);
- }
- return sameNet;
- }
-
- public NetMatcher()
- {
- }
-
- public NetMatcher(final String[] nets)
- {
- initInetNetworks(nets);
- }
-
- public NetMatcher(final Collection nets)
- {
- initInetNetworks(nets);
- }
-
- public String toString() {
- return networks.toString();
- }
-
- protected void log(String s) { }
-}
class InetNetwork
{
@@ -218,7 +111,7 @@ class InetNetwork
/*
* This converts from an uncommon "wildcard" CIDR format
* to "address + mask" format:
- *
+ *
* * => 000.000.000.0/000.000.000.0
* xxx.* => xxx.000.000.0/255.000.000.0
* xxx.xxx.* => xxx.xxx.000.0/255.255.000.0
@@ -227,7 +120,7 @@ class InetNetwork
static private String normalizeFromAsterisk(final String netspec)
{
String[] masks = { "0.0.0.0/0.0.0.0", "0.0.0/255.0.0.0", "0.0/255.255.0.0", "0/255.255.255.0" };
- char[] srcb = netspec.toCharArray();
+ char[] srcb = netspec.toCharArray();
int octets = 0;
for (int i = 1; i < netspec.length(); i++)
{
@@ -261,8 +154,8 @@ class InetNetwork
static {
try {
- Class inetAddressClass = Class.forName("java.net.InetAddress");
- Class[] parameterTypes = { byte[].class };
+ Class<?> inetAddressClass = Class.forName("java.net.InetAddress");
+ Class<?>[] parameterTypes = { byte[].class };
getByAddress = inetAddressClass.getMethod("getByAddress", parameterTypes);
} catch (Exception e) {
getByAddress = null;
@@ -297,4 +190,4 @@ class InetNetwork
}
return addr;
}
-}
+} \ No newline at end of file
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/NetworkFirewallRule.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/NetworkFirewallRule.java
new file mode 100644
index 0000000000..ad619a0e0b
--- /dev/null
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/firewall/NetworkFirewallRule.java
@@ -0,0 +1,117 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.server.security.access.firewall;
+
+import java.net.InetAddress;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.commons.lang.builder.HashCodeBuilder;
+import org.apache.commons.lang.builder.ToStringBuilder;
+import org.apache.commons.lang.builder.ToStringStyle;
+import org.apache.log4j.Logger;
+
+public class NetworkFirewallRule implements FirewallRule
+{
+ private static final Logger _logger = Logger.getLogger(NetworkFirewallRule.class);
+
+ private List<InetNetwork> _networks;
+
+ public NetworkFirewallRule(String... networks)
+ {
+ _networks = new ArrayList<InetNetwork>();
+ for (int i = 0; i < networks.length; i++)
+ {
+ String network = networks[i];
+ try
+ {
+ InetNetwork inetNetwork = InetNetwork.getFromString(network);
+ if (!_networks.contains(inetNetwork))
+ {
+ _networks.add(inetNetwork);
+ }
+ }
+ catch (java.net.UnknownHostException uhe)
+ {
+ _logger.error("Cannot resolve address: " + network, uhe);
+ }
+ }
+
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Created " + this);
+ }
+ }
+
+ @Override
+ public boolean matches(InetAddress ip)
+ {
+ for (InetNetwork network : _networks)
+ {
+ if (network.contains(ip))
+ {
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Client address " + ip + " matches configured network " + network);
+ }
+ return true;
+ }
+ }
+
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Client address " + ip + " does not match any configured networks");
+ }
+
+ return false;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ return new HashCodeBuilder().append(_networks).toHashCode();
+ }
+
+ @Override
+ public boolean equals(Object obj)
+ {
+ if (obj == null)
+ {
+ return false;
+ }
+ if (obj == this)
+ {
+ return true;
+ }
+ if (obj.getClass() != getClass())
+ {
+ return false;
+ }
+ NetworkFirewallRule rhs = (NetworkFirewallRule) obj;
+ return new EqualsBuilder().append(_networks, rhs._networks).isEquals();
+ }
+
+ @Override
+ public String toString()
+ {
+ return new ToStringBuilder(this, ToStringStyle.SHORT_PREFIX_STYLE)
+ .append(_networks).toString();
+ }
+}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/logging/AccessControl_logmessages.properties b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/logging/AccessControl_logmessages.properties
index bf80df3722..2a5eb7b3be 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/logging/AccessControl_logmessages.properties
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/logging/AccessControl_logmessages.properties
@@ -25,4 +25,4 @@
ALLOWED = ACL-1001 : Allowed : {0} {1} {2}
# 'deny-log' rule message
-DENIED = ACL-1002 : Denied : {0} {1} {2} \ No newline at end of file
+DENIED = ACL-1002 : Denied : {0} {1} {2}
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java
index d36ae810c6..d94948237f 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java
@@ -20,9 +20,13 @@
*/
package org.apache.qpid.server.security.access.plugins;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+
import javax.security.auth.Subject;
import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.lang.ObjectUtils;
import org.apache.log4j.Logger;
import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
import org.apache.qpid.server.security.AbstractPlugin;
@@ -39,7 +43,7 @@ import org.apache.qpid.server.security.access.config.RuleSet;
*/
public class AccessControl extends AbstractPlugin
{
- public static final Logger _logger = Logger.getLogger(AccessControl.class);
+ private static final Logger _logger = Logger.getLogger(AccessControl.class);
private RuleSet _ruleSet;
@@ -82,9 +86,16 @@ public class AccessControl extends AbstractPlugin
* Delegate to the {@link #authorise(Operation, ObjectType, ObjectProperties)} method, with
* the operation set to ACCESS and no object properties.
*/
- public Result access(ObjectType objectType, Object instance)
+ public Result access(ObjectType objectType, Object inetSocketAddress)
{
- return authorise(Operation.ACCESS, objectType, ObjectProperties.EMPTY);
+ InetAddress addressOfClient = null;
+
+ if(inetSocketAddress != null)
+ {
+ addressOfClient = ((InetSocketAddress) inetSocketAddress).getAddress();
+ }
+
+ return authoriseFromAddress(Operation.ACCESS, objectType, ObjectProperties.EMPTY, addressOfClient);
}
/**
@@ -94,6 +105,11 @@ public class AccessControl extends AbstractPlugin
*/
public Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties)
{
+ return authoriseFromAddress(operation, objectType, properties, null);
+ }
+
+ public Result authoriseFromAddress(Operation operation, ObjectType objectType, ObjectProperties properties, InetAddress addressOfClient)
+ {
final Subject subject = SecurityManager.getThreadSubject();
// Abstain if there is no subject/principal associated with this thread
if (subject == null || subject.getPrincipals().size() == 0)
@@ -101,8 +117,20 @@ public class AccessControl extends AbstractPlugin
return Result.ABSTAIN;
}
- _logger.debug("Checking " + operation + " " + objectType);
- return _ruleSet.check(subject, operation, objectType, properties);
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Checking " + operation + " " + objectType + " " + ObjectUtils.defaultIfNull(addressOfClient, ""));
+ }
+
+ try
+ {
+ return _ruleSet.check(subject, operation, objectType, properties, addressOfClient);
+ }
+ catch(Exception e)
+ {
+ _logger.error("Unable to check " + operation + " " + objectType + " " + ObjectUtils.defaultIfNull(addressOfClient, ""), e);
+ return Result.DENIED;
+ }
}
public void configure(ConfigurationPlugin config)
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclActionTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclActionTest.java
new file mode 100644
index 0000000000..14620cff70
--- /dev/null
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclActionTest.java
@@ -0,0 +1,66 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.server.security.access.config;
+
+import static org.mockito.Mockito.*;
+
+import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.qpid.server.security.access.ObjectType;
+import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.security.access.firewall.FirewallRule;
+
+import junit.framework.TestCase;
+
+public class AclActionTest extends TestCase
+{
+ public void testEqualsAndHashCode()
+ {
+ AclRulePredicates predicates = createAclRulePredicates();
+ ObjectType objectType = ObjectType.EXCHANGE;
+ Operation operation = Operation.ACCESS;
+
+ AclAction aclAction = new AclAction(operation, objectType, predicates);
+ AclAction equalAclAction = new AclAction(operation, objectType, predicates);
+
+ assertTrue(aclAction.equals(aclAction));
+ assertTrue(aclAction.equals(equalAclAction));
+ assertTrue(equalAclAction.equals(aclAction));
+
+ assertTrue(aclAction.hashCode() == equalAclAction.hashCode());
+
+ assertFalse("Different operation should cause aclActions to be unequal",
+ aclAction.equals(new AclAction(Operation.BIND, objectType, predicates)));
+
+ assertFalse("Different operation type should cause aclActions to be unequal",
+ aclAction.equals(new AclAction(operation, ObjectType.GROUP, predicates)));
+
+ assertFalse("Different predicates should cause aclActions to be unequal",
+ aclAction.equals(new AclAction(operation, objectType, createAclRulePredicates())));
+
+ }
+
+ private AclRulePredicates createAclRulePredicates()
+ {
+ AclRulePredicates predicates = mock(AclRulePredicates.class);
+ when(predicates.getFirewallRule()).thenReturn(mock(FirewallRule.class));
+ when(predicates.getObjectProperties()).thenReturn(mock(ObjectProperties.class));
+ return predicates;
+ }
+
+}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclRulePredicatesTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclRulePredicatesTest.java
new file mode 100644
index 0000000000..93b765d0fb
--- /dev/null
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/AclRulePredicatesTest.java
@@ -0,0 +1,87 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.server.security.access.config;
+
+import static org.apache.qpid.server.security.access.ObjectProperties.Property.*;
+
+import org.apache.qpid.server.security.access.firewall.FirewallRule;
+import org.apache.qpid.server.security.access.firewall.FirewallRuleFactory;
+
+import static org.mockito.Mockito.*;
+
+import junit.framework.TestCase;
+
+public class AclRulePredicatesTest extends TestCase
+{
+ private AclRulePredicates _aclRulePredicates = new AclRulePredicates();
+ private FirewallRuleFactory _firewallRuleFactory = mock(FirewallRuleFactory.class);
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ _aclRulePredicates.setFirewallRuleFactory(_firewallRuleFactory);
+
+ when(_firewallRuleFactory.createForHostname((String[]) any())).thenReturn(mock(FirewallRule.class));
+ when(_firewallRuleFactory.createForNetwork((String[]) any())).thenReturn(mock(FirewallRule.class));
+ }
+
+ public void testParse()
+ {
+ String name = "name";
+ String className = "class";
+
+ _aclRulePredicates.parse(NAME.name(), name);
+ _aclRulePredicates.parse(CLASS.name(), className);
+
+ assertEquals(name, _aclRulePredicates.getObjectProperties().get(NAME));
+ assertEquals(className, _aclRulePredicates.getObjectProperties().get(CLASS));
+ }
+
+ public void testParseHostnameFirewallRule()
+ {
+ String hostname = "hostname1,hostname2";
+ _aclRulePredicates.parse(FROM_HOSTNAME.name(), hostname);
+
+ verify(_firewallRuleFactory).createForHostname(new String[] {"hostname1", "hostname2"});
+ }
+
+ public void testParseNetworkFirewallRule()
+ {
+ _aclRulePredicates.setFirewallRuleFactory(_firewallRuleFactory);
+
+ String networks = "network1,network2";
+ _aclRulePredicates.parse(FROM_NETWORK.name(), networks);
+
+ verify(_firewallRuleFactory).createForNetwork(new String[] {"network1", "network2"});
+ }
+
+ public void testParseThrowsExceptionIfBothHostnameAndNetworkSpecified()
+ {
+ _aclRulePredicates.parse(FROM_NETWORK.name(), "network1,network2");
+ try
+ {
+ _aclRulePredicates.parse(FROM_HOSTNAME.name(), "hostname1,hostname2");
+ fail("Exception not thrown");
+ }
+ catch(IllegalStateException e)
+ {
+ // pass
+ }
+ }
+}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/ClientActionTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/ClientActionTest.java
new file mode 100644
index 0000000000..ae5d3fda74
--- /dev/null
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/ClientActionTest.java
@@ -0,0 +1,79 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.server.security.access.config;
+
+import static org.mockito.Mockito.*;
+
+import java.net.InetAddress;
+
+import org.apache.qpid.server.security.access.firewall.FirewallRule;
+
+import junit.framework.TestCase;
+
+public class ClientActionTest extends TestCase
+{
+ private Action _action = mock(Action.class);
+ private AclAction _ruleAction = mock(AclAction.class);
+ private InetAddress _addressOfClient = mock(InetAddress.class);
+
+ private ClientAction _clientAction = new ClientAction(_action);
+
+ public void testMatches_returnsTrueWhenActionsMatchAndNoFirewallRule()
+ {
+ when(_action.matches(any(Action.class))).thenReturn(true);
+ when(_ruleAction.getFirewallRule()).thenReturn(null);
+
+ assertTrue(_clientAction.matches(_ruleAction, _addressOfClient));
+ }
+
+ public void testMatches_returnsFalseWhenActionsDontMatch()
+ {
+ FirewallRule firewallRule = mock(FirewallRule.class);
+ when(firewallRule.matches(_addressOfClient)).thenReturn(true);
+
+ when(_action.matches(any(Action.class))).thenReturn(false);
+ when(_ruleAction.getFirewallRule()).thenReturn(firewallRule);
+
+ assertFalse(_clientAction.matches(_ruleAction, _addressOfClient));
+ }
+
+ public void testMatches_returnsTrueWhenActionsAndFirewallRuleMatch()
+ {
+ FirewallRule firewallRule = mock(FirewallRule.class);
+ when(firewallRule.matches(_addressOfClient)).thenReturn(true);
+
+ when(_action.matches(any(Action.class))).thenReturn(true);
+ when(_ruleAction.getFirewallRule()).thenReturn(firewallRule);
+
+ assertTrue(_clientAction.matches(_ruleAction, _addressOfClient));
+ }
+
+ public void testMatches_ignoresFirewallRuleIfClientAddressIsNull()
+ {
+ FirewallRule firewallRule = mock(FirewallRule.class);
+
+ when(_action.matches(any(Action.class))).thenReturn(true);
+ when(_ruleAction.getFirewallRule()).thenReturn(firewallRule);
+
+ assertTrue(_clientAction.matches(_ruleAction, null));
+
+ verifyZeroInteractions(firewallRule);
+ }
+
+}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/RuleTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/RuleTest.java
new file mode 100644
index 0000000000..2ae7759679
--- /dev/null
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/config/RuleTest.java
@@ -0,0 +1,53 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.server.security.access.config;
+
+import static org.mockito.Mockito.*;
+
+import org.apache.qpid.server.security.access.Permission;
+
+import junit.framework.TestCase;
+
+public class RuleTest extends TestCase
+{
+ public void testEqualsAndHashCode()
+ {
+ AclAction aclAction = mock(AclAction.class);
+ String identity = "identity";
+ Permission allow = Permission.ALLOW;
+
+ Rule rule = new Rule(identity, aclAction, allow);
+ Rule equalRule = new Rule(identity, aclAction, allow);
+
+ assertTrue(rule.equals(rule));
+ assertTrue(rule.equals(equalRule));
+ assertTrue(equalRule.equals(rule));
+
+ assertTrue(rule.hashCode() == equalRule.hashCode());
+
+ assertFalse("Different identity should cause rules to be unequal",
+ rule.equals(new Rule("identity2", aclAction, allow)));
+
+ assertFalse("Different action should cause rules to be unequal",
+ rule.equals(new Rule(identity, mock(AclAction.class), allow)));
+
+ assertFalse("Different permission should cause rules to be unequal",
+ rule.equals(new Rule(identity, aclAction, Permission.DENY)));
+ }
+}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/firewall/HostnameFirewallRuleTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/firewall/HostnameFirewallRuleTest.java
new file mode 100644
index 0000000000..be82cb294a
--- /dev/null
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/firewall/HostnameFirewallRuleTest.java
@@ -0,0 +1,99 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.server.security.access.firewall;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.net.InetAddress;
+
+import org.apache.qpid.server.security.access.firewall.HostnameFirewallRule;
+
+import junit.framework.TestCase;
+
+public class HostnameFirewallRuleTest extends TestCase
+{
+ private InetAddress _addressNotInRule;
+
+ private HostnameFirewallRule _HostnameFirewallRule;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ _addressNotInRule = InetAddress.getByName("127.0.0.1");
+ }
+
+ public void testSingleHostname() throws Exception
+ {
+ String hostnameInRule = "hostnameInRule";
+ InetAddress addressWithMatchingHostname = mock(InetAddress.class);
+ when(addressWithMatchingHostname.getCanonicalHostName()).thenReturn(hostnameInRule);
+
+ _HostnameFirewallRule = new HostnameFirewallRule(hostnameInRule);
+
+ assertFalse(_HostnameFirewallRule.matches(_addressNotInRule));
+ assertTrue(_HostnameFirewallRule.matches(addressWithMatchingHostname));
+ }
+
+ public void testSingleHostnameWilcard() throws Exception
+ {
+ String hostnameInRule = ".*FOO.*";
+ InetAddress addressWithMatchingHostname = mock(InetAddress.class);
+ when(addressWithMatchingHostname.getCanonicalHostName()).thenReturn("xxFOOxx");
+
+ _HostnameFirewallRule = new HostnameFirewallRule(hostnameInRule);
+
+ assertFalse(_HostnameFirewallRule.matches(_addressNotInRule));
+ assertTrue(_HostnameFirewallRule.matches(addressWithMatchingHostname));
+ }
+
+ public void testMultipleHostnames() throws Exception
+ {
+ String[] hostnamesInRule = new String[] {"hostnameInRule1", "hostnameInRule2"};
+
+ _HostnameFirewallRule = new HostnameFirewallRule(hostnamesInRule);
+
+ assertFalse(_HostnameFirewallRule.matches(_addressNotInRule));
+ for (String hostnameInRule : hostnamesInRule)
+ {
+ InetAddress addressWithMatchingHostname = mock(InetAddress.class);
+ when(addressWithMatchingHostname.getCanonicalHostName()).thenReturn(hostnameInRule);
+
+ assertTrue(_HostnameFirewallRule.matches(addressWithMatchingHostname));
+ }
+ }
+
+ public void testEqualsAndHashCode()
+ {
+ String hostname1 = "hostname1";
+ String hostname2 = "hostname2";
+
+ HostnameFirewallRule rule = new HostnameFirewallRule(hostname1, hostname2);
+ HostnameFirewallRule equalRule = new HostnameFirewallRule(hostname1, hostname2);
+
+ assertTrue(rule.equals(rule));
+ assertTrue(rule.equals(equalRule));
+ assertTrue(equalRule.equals(rule));
+
+ assertTrue(rule.hashCode() == equalRule.hashCode());
+
+ assertFalse("Different hostnames should cause rules to be unequal",
+ rule.equals(new HostnameFirewallRule(hostname1, "different-hostname")));
+ }
+}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/firewall/NetworkFirewallRuleTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/firewall/NetworkFirewallRuleTest.java
new file mode 100644
index 0000000000..e521039db2
--- /dev/null
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/firewall/NetworkFirewallRuleTest.java
@@ -0,0 +1,115 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.server.security.access.firewall;
+
+import java.net.InetAddress;
+
+import org.apache.qpid.server.security.access.firewall.NetworkFirewallRule;
+
+import junit.framework.TestCase;
+
+public class NetworkFirewallRuleTest extends TestCase
+{
+ private static final String LOCALHOST_IP = "127.0.0.1";
+ private static final String OTHER_IP_1 = "192.168.23.1";
+ private static final String OTHER_IP_2 = "192.168.23.2";
+
+ private InetAddress _addressNotInRule;
+
+ private NetworkFirewallRule _networkFirewallRule;
+
+ @Override
+ protected void setUp() throws Exception
+ {
+ _addressNotInRule = InetAddress.getByName(LOCALHOST_IP);
+ }
+
+ public void testIpRule() throws Exception
+ {
+ String ipAddressInRule = OTHER_IP_1;
+
+ _networkFirewallRule = new NetworkFirewallRule(ipAddressInRule);
+
+ assertFalse(_networkFirewallRule.matches(_addressNotInRule));
+ assertTrue(_networkFirewallRule.matches(InetAddress.getByName(ipAddressInRule)));
+ }
+
+ public void testNetMask() throws Exception
+ {
+ String ipAddressInRule = "192.168.23.0/24";
+ _networkFirewallRule = new NetworkFirewallRule(ipAddressInRule);
+
+ assertFalse(_networkFirewallRule.matches(InetAddress.getByName("192.168.24.1")));
+ assertTrue(_networkFirewallRule.matches(InetAddress.getByName("192.168.23.0")));
+ assertTrue(_networkFirewallRule.matches(InetAddress.getByName("192.168.23.255")));
+ }
+
+ public void testWildcard() throws Exception
+ {
+ // Test xxx.xxx.*
+
+ assertFalse(new NetworkFirewallRule("192.168.*")
+ .matches(InetAddress.getByName("192.169.1.0")));
+
+ assertTrue(new NetworkFirewallRule("192.168.*")
+ .matches(InetAddress.getByName("192.168.1.0")));
+
+ assertTrue(new NetworkFirewallRule("192.168.*")
+ .matches(InetAddress.getByName("192.168.255.255")));
+
+ // Test xxx.xxx.xxx.*
+
+ assertFalse(new NetworkFirewallRule("192.168.1.*")
+ .matches(InetAddress.getByName("192.169.2.0")));
+
+ assertTrue(new NetworkFirewallRule("192.168.1.*")
+ .matches(InetAddress.getByName("192.168.1.0")));
+
+ assertTrue(new NetworkFirewallRule("192.168.1.*")
+ .matches(InetAddress.getByName("192.168.1.255")));
+ }
+
+ public void testMultipleNetworks() throws Exception
+ {
+ String[] ipAddressesInRule = new String[] {OTHER_IP_1, OTHER_IP_2};
+
+ _networkFirewallRule = new NetworkFirewallRule(ipAddressesInRule);
+
+ assertFalse(_networkFirewallRule.matches(_addressNotInRule));
+ for (String ipAddressInRule : ipAddressesInRule)
+ {
+ assertTrue(_networkFirewallRule.matches(InetAddress.getByName(ipAddressInRule)));
+ }
+ }
+
+ public void testEqualsAndHashCode()
+ {
+ NetworkFirewallRule rule = new NetworkFirewallRule(LOCALHOST_IP, OTHER_IP_1);
+ NetworkFirewallRule equalRule = new NetworkFirewallRule(LOCALHOST_IP, OTHER_IP_1);
+
+ assertTrue(rule.equals(rule));
+ assertTrue(rule.equals(equalRule));
+ assertTrue(equalRule.equals(rule));
+
+ assertTrue(rule.hashCode() == equalRule.hashCode());
+
+ assertFalse("Different networks should cause rules to be unequal",
+ rule.equals(new NetworkFirewallRule(LOCALHOST_IP, OTHER_IP_2)));
+ }
+}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/AccessControlTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/AccessControlTest.java
index 2385bcc3dd..a65c442bcf 100644
--- a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/AccessControlTest.java
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/AccessControlTest.java
@@ -20,6 +20,13 @@
*/
package org.apache.qpid.server.security.access.plugins;
+import static org.mockito.Mockito.*;
+
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+
+import javax.security.auth.Subject;
+
import junit.framework.TestCase;
import org.apache.commons.configuration.ConfigurationException;
@@ -194,6 +201,49 @@ public class AccessControlTest extends TestCase
assertEquals(Result.DEFER, result);
}
+ public void testAccess() throws Exception
+ {
+ Subject subject = TestPrincipalUtils.createTestSubject("user1");
+ SecurityManager.setThreadSubject(subject);
+
+ RuleSet mockRuleSet = mock(RuleSet.class);
+ ConfigurationPlugin accessControlConfiguration = createConfiguration(mockRuleSet);
+
+ InetAddress inetAddress = InetAddress.getLocalHost();
+ InetSocketAddress inetSocketAddress = new InetSocketAddress(inetAddress, 1);
+
+ AccessControl accessControl = AccessControl.FACTORY.newInstance(accessControlConfiguration);
+
+ accessControl.access(ObjectType.VIRTUALHOST, inetSocketAddress);
+
+ verify(mockRuleSet).check(subject, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY, inetAddress);
+ }
+
+ public void testAccessIsDeniedIfRuleThrowsException() throws Exception
+ {
+ Subject subject = TestPrincipalUtils.createTestSubject("user1");
+ SecurityManager.setThreadSubject(subject);
+
+ InetAddress inetAddress = InetAddress.getLocalHost();
+ InetSocketAddress inetSocketAddress = new InetSocketAddress(inetAddress, 1);
+
+ RuleSet mockRuleSet = mock(RuleSet.class);
+ when(mockRuleSet.check(
+ subject,
+ Operation.ACCESS,
+ ObjectType.VIRTUALHOST,
+ ObjectProperties.EMPTY,
+ inetAddress)).thenThrow(new RuntimeException());
+
+ ConfigurationPlugin accessControlConfiguration = createConfiguration(mockRuleSet);
+
+ AccessControl accessControl = AccessControl.FACTORY.newInstance(accessControlConfiguration);
+ Result result = accessControl.access(ObjectType.VIRTUALHOST, inetSocketAddress);
+
+ assertEquals(Result.DENIED, result);
+ }
+
+
/**
* Tests that a grant access method rule allows any access operation to be performed on a specified component
*/
@@ -332,7 +382,7 @@ public class AccessControlTest extends TestCase
final ConfigurationPlugin cp = new ConfigurationPlugin()
{
@SuppressWarnings("unchecked")
- public AccessControlConfiguration getConfiguration(final String plugin)
+ public AccessControlConfiguration getConfiguration(final String plugin)
{
return new AccessControlConfiguration()
{
diff --git a/java/broker-plugins/firewall/MANIFEST.MF b/java/broker-plugins/firewall/MANIFEST.MF
deleted file mode 100644
index a302921d03..0000000000
--- a/java/broker-plugins/firewall/MANIFEST.MF
+++ /dev/null
@@ -1,34 +0,0 @@
-Manifest-Version: 1.0
-Bundle-ManifestVersion: 2
-Bundle-Name: Qpid Broker-Plugins Firewall
-Bundle-SymbolicName: broker-plugins-firewall
-Bundle-Description: Firewall plugin for Qpid.
-Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt
-Bundle-DocURL: http://www.apache.org/
-Bundle-Version: 1.0.0
-Bundle-Activator: org.apache.qpid.server.security.access.plugins.FirewallActivator
-Bundle-RequiredExecutionEnvironment: JavaSE-1.6
-Bundle-ClassPath: .
-Bundle-ActivationPolicy: lazy
-Import-Package: org.apache.qpid,
- org.apache.qpid.framing,
- org.apache.qpid.protocol,
- org.apache.qpid.server.configuration,
- org.apache.qpid.server.configuration.plugins,
- org.apache.qpid.server.exchange,
- org.apache.qpid.server.plugins,
- org.apache.qpid.server.queue,
- org.apache.qpid.server.security,
- org.apache.qpid.server.security.access,
- org.apache.qpid.server.virtualhost,
- org.apache.qpid.util,
- org.apache.commons.configuration;version=1.0.0,
- org.apache.commons.lang;version=1.0.0,
- org.apache.commons.lang.builder;version=1.0.0,
- org.apache.log4j;version=1.0.0,
- javax.management;version=1.0.0,
- javax.management.openmbean;version=1.0.0,
- org.osgi.util.tracker;version=1.0.0,
- org.osgi.framework;version=1.3
-Private-Package: org.apache.qpid.server.security.access.config
-Export-Package: org.apache.qpid.server.security.access.plugins;uses:="org.osgi.framework"
diff --git a/java/broker-plugins/firewall/build.xml b/java/broker-plugins/firewall/build.xml
deleted file mode 100644
index 6ae6a35b89..0000000000
--- a/java/broker-plugins/firewall/build.xml
+++ /dev/null
@@ -1,34 +0,0 @@
-<!--
- - Licensed to the Apache Software Foundation (ASF) under one
- - or more contributor license agreements. See the NOTICE file
- - distributed with this work for additional information
- - regarding copyright ownership. The ASF licenses this file
- - to you under the Apache License, Version 2.0 (the
- - "License"); you may not use this file except in compliance
- - with the License. You may obtain a copy of the License at
- -
- - http://www.apache.org/licenses/LICENSE-2.0
- -
- - Unless required by applicable law or agreed to in writing,
- - software distributed under the License is distributed on an
- - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- - KIND, either express or implied. See the License for the
- - specific language governing permissions and limitations
- - under the License.
- -->
-<project name="Qpid Broker-Plugins Firewall" default="build">
- <property name="module.depends" value="common broker" />
- <property name="module.test.depends" value="test broker/test common/test management/common" />
-
- <property name="module.manifest" value="MANIFEST.MF" />
- <property name="module.plugin" value="true" />
- <property name="module.genpom" value="true"/>
- <property name="module.genpom.args" value="-Sqpid-common=provided -Sqpid-broker=provided"/>
-
- <property name="broker-plugins-firewall.libs" value=""/>
-
- <import file="../../module.xml" />
-
- <target name="bundle" depends="bundle-tasks" />
-
-</project>
diff --git a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/config/FirewallRule.java b/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/config/FirewallRule.java
deleted file mode 100644
index ecec4b0cec..0000000000
--- a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/config/FirewallRule.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.server.security.access.config;
-
-import org.apache.qpid.server.security.Result;
-import org.apache.qpid.util.NetMatcher;
-
-import java.net.InetAddress;
-import java.util.List;
-import java.util.concurrent.Callable;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.TimeUnit;
-import java.util.regex.Pattern;
-
-public class FirewallRule
-{
- public static final String ALLOW = "ALLOW";
- public static final String DENY = "DENY";
-
- private static final long DNS_TIMEOUT = 30000;
- private static final ExecutorService DNS_LOOKUP = Executors.newCachedThreadPool();
-
- private Result _access;
- private NetMatcher _network;
- private Pattern[] _hostnamePatterns;
-
- public FirewallRule(String access, List networks, List hostnames)
- {
- _access = (access.equalsIgnoreCase(ALLOW)) ? Result.ALLOWED : Result.DENIED;
-
- 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) throws FirewallException
- {
- if (_hostnamePatterns != null)
- {
- String hostname = getHostname(remote);
- if (hostname == null)
- {
- throw new FirewallException("DNS lookup failed");
- }
- for (Pattern pattern : _hostnamePatterns)
- {
- if (pattern.matcher(hostname).matches())
- {
- return true;
- }
- }
- return false;
- }
- else
- {
- return _network.matchInetNetwork(remote);
- }
- }
-
- /**
- * @param remote the InetAddress to look up
- * @return the hostname, null if not found, takes longer than 30s to find or otherwise fails
- */
- private String getHostname(final InetAddress remote) throws FirewallException
- {
- FutureTask<String> lookup = new FutureTask<String>(new Callable<String>()
- {
- public String call()
- {
- return remote.getCanonicalHostName();
- }
- });
- DNS_LOOKUP.execute(lookup);
-
- try
- {
- return lookup.get(DNS_TIMEOUT, TimeUnit.MILLISECONDS);
- }
- catch (Exception e)
- {
- return null;
- }
- finally
- {
- lookup.cancel(true);
- }
- }
-
- public Result getAccess()
- {
- return _access;
- }
-} \ No newline at end of file
diff --git a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/Firewall.java b/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/Firewall.java
deleted file mode 100644
index 40a65fddba..0000000000
--- a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/Firewall.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.server.security.access.plugins;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.security.AbstractPlugin;
-import org.apache.qpid.server.security.Result;
-import org.apache.qpid.server.security.SecurityPluginFactory;
-import org.apache.qpid.server.security.access.ObjectProperties;
-import org.apache.qpid.server.security.access.ObjectType;
-import org.apache.qpid.server.security.access.Operation;
-import org.apache.qpid.server.security.access.config.FirewallException;
-import org.apache.qpid.server.security.access.config.FirewallRule;
-
-import java.net.InetAddress;
-import java.net.InetSocketAddress;
-
-public class Firewall extends AbstractPlugin
-{
- public static final SecurityPluginFactory<Firewall> FACTORY = new SecurityPluginFactory<Firewall>()
- {
- public Firewall newInstance(ConfigurationPlugin config) throws ConfigurationException
- {
- FirewallConfiguration configuration = config.getConfiguration(FirewallConfiguration.class.getName());
-
- // If there is no configuration for this plugin then don't load it.
- if (configuration == null)
- {
- return null;
- }
-
- Firewall plugin = new Firewall();
- plugin.configure(configuration);
- return plugin;
- }
-
- public Class<Firewall> getPluginClass()
- {
- return Firewall.class;
- }
-
- public String getPluginName()
- {
- return Firewall.class.getName();
- }
- };
-
- private Result _default = Result.ABSTAIN;
- private FirewallRule[] _rules;
-
- public Result getDefault()
- {
- return _default;
- }
-
- public Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties)
- {
- return Result.ABSTAIN; // We only deal with access requests
- }
-
- public Result access(ObjectType objectType, Object instance)
- {
- if (objectType != ObjectType.VIRTUALHOST)
- {
- return Result.ABSTAIN; // We are only interested in access to virtualhosts
- }
-
- if (!(instance instanceof InetSocketAddress))
- {
- return Result.ABSTAIN; // We need an internet address
- }
-
- InetAddress address = ((InetSocketAddress) instance).getAddress();
-
- try
- {
- for (FirewallRule rule : _rules)
- {
- boolean match = rule.match(address);
- if (match)
- {
- return rule.getAccess();
- }
- }
- return getDefault();
- }
- catch (FirewallException fe)
- {
- return Result.DENIED;
- }
- }
-
-
- public void configure(ConfigurationPlugin config)
- {
- super.configure(config);
- FirewallConfiguration firewallConfiguration = (FirewallConfiguration) getConfig();
-
- // Get default action
- _default = firewallConfiguration.getDefaultAction();
-
- Configuration finalConfig = firewallConfiguration.getConfiguration();
-
- // all rules must have an access attribute
- int numRules = finalConfig.getList("rule[@access]").size();
- _rules = new FirewallRule[numRules];
- for (int i = 0; i < numRules; i++)
- {
- FirewallRule rule = new FirewallRule(finalConfig.getString("rule(" + i + ")[@access]"),
- finalConfig.getList("rule(" + i + ")[@network]"),
- finalConfig.getList("rule(" + i + ")[@hostname]"));
- _rules[i] = rule;
- }
-
- }
-}
diff --git a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/FirewallConfiguration.java b/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/FirewallConfiguration.java
deleted file mode 100644
index 010d1652f0..0000000000
--- a/java/broker-plugins/firewall/src/main/java/org/apache/qpid/server/security/access/plugins/FirewallConfiguration.java
+++ /dev/null
@@ -1,103 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.server.security.access.plugins;
-
-import org.apache.commons.configuration.CompositeConfiguration;
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.XMLConfiguration;
-
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
-import org.apache.qpid.server.security.Result;
-import org.apache.qpid.server.security.access.config.FirewallRule;
-
-import java.util.Arrays;
-import java.util.List;
-
-public class FirewallConfiguration extends ConfigurationPlugin
-{
- private CompositeConfiguration _finalConfig;
-
- public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory()
- {
- public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException
- {
- ConfigurationPlugin instance = new FirewallConfiguration();
- instance.setConfiguration(path, config);
- return instance;
- }
-
- public List<String> getParentPaths()
- {
- return Arrays.asList("security.firewall", "virtualhosts.virtualhost.security.firewall");
- }
- };
-
- public String[] getElementsProcessed()
- {
- return new String[] { "" };
- }
-
- public Configuration getConfiguration()
- {
- return _finalConfig;
- }
-
- public Result getDefaultAction()
- {
- String defaultAction = getConfig().getString("[@default-action]");
- if (defaultAction == null)
- {
- return Result.ABSTAIN;
- }
- else if (defaultAction.equalsIgnoreCase(FirewallRule.ALLOW))
- {
- return Result.ALLOWED;
- }
- else
- {
- return Result.DENIED;
- }
- }
-
-
-
- @Override
- public void validateConfiguration() throws ConfigurationException
- {
- // Valid Configuration either has xml links to new files
- _finalConfig = new CompositeConfiguration(getConfig());
- List subFiles = getConfig().getList("xml[@fileName]");
- for (Object subFile : subFiles)
- {
- _finalConfig.addConfiguration(new XMLConfiguration((String) subFile));
- }
-
- // all rules must have an access attribute or a default value
- if (_finalConfig.getList("rule[@access]").size() == 0 &&
- getConfig().getString("[@default-action]") == null)
- {
- throw new ConfigurationException("No rules or default-action found in firewall configuration.");
- }
- }
-
-}
diff --git a/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java b/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java
deleted file mode 100644
index 8969363979..0000000000
--- a/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallConfigurationTest.java
+++ /dev/null
@@ -1,322 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.server.security.access;
-
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-import org.apache.qpid.test.utils.QpidTestCase;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.io.RandomAccessFile;
-import java.net.InetSocketAddress;
-
-public class FirewallConfigurationTest extends QpidTestCase
-{
- @Override
- protected void tearDown() throws Exception
- {
- super.tearDown();
- ApplicationRegistry.remove();
- }
-
- public void testFirewallConfiguration() throws Exception
- {
- // Write out config
- File mainFile = File.createTempFile(getClass().getName(), null);
- mainFile.deleteOnExit();
- writeConfigFile(mainFile, false);
-
- // Load config
- ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
-
- // Test config
- assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
- assertTrue(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.1.2.3", 65535)));
- }
-
- public void testCombinedConfigurationFirewall() throws Exception
- {
- // Write out config
- File mainFile = File.createTempFile(getClass().getName(), null);
- File fileA = File.createTempFile(getClass().getName(), null);
- File fileB = File.createTempFile(getClass().getName(), null);
-
- mainFile.deleteOnExit();
- fileA.deleteOnExit();
- fileB.deleteOnExit();
-
- FileWriter out = new FileWriter(mainFile);
- out.write("<configuration><system/>");
- out.write("<xml fileName=\"" + fileA.getAbsolutePath() + "\"/>");
- out.write("</configuration>");
- out.close();
-
- out = new FileWriter(fileA);
- out.write("<broker>\n");
- out.write("\t<plugin-directory>${QPID_HOME}/lib/plugins</plugin-directory>\n");
- out.write("\t<cache-directory>${QPID_WORK}/cache</cache-directory>\n");
- out.write("\t<management><enabled>false</enabled></management>\n");
- out.write("\t<security>\n");
- out.write("\t\t<pd-auth-manager>\n");
- out.write("\t\t\t<principal-database>\n");
- out.write("\t\t\t\t<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>\n");
- out.write("\t\t\t\t<attributes>\n");
- out.write("\t\t\t\t\t<attribute>\n");
- out.write("\t\t\t\t\t\t<name>passwordFile</name>\n");
- out.write("\t\t\t\t\t\t<value>/dev/null</value>\n");
- out.write("\t\t\t\t\t</attribute>\n");
- out.write("\t\t\t\t</attributes>\n");
- out.write("\t\t\t</principal-database>\n");
- out.write("\t\t</pd-auth-manager>\n");
- out.write("\t\t<firewall>\n");
- out.write("\t\t\t<xml fileName=\"" + fileB.getAbsolutePath() + "\"/>");
- out.write("\t\t</firewall>\n");
- out.write("\t</security>\n");
- out.write("\t<virtualhosts>\n");
- out.write("\t\t<virtualhost>\n");
- out.write("\t\t\t<name>test</name>\n");
- out.write("\t\t</virtualhost>\n");
- out.write("\t</virtualhosts>\n");
- out.write("</broker>\n");
- out.close();
-
- out = new FileWriter(fileB);
- out.write("<firewall>\n");
- out.write("\t<rule access=\"deny\" network=\"127.0.0.1\"/>");
- out.write("</firewall>\n");
- out.close();
-
- // Load config
- ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
-
- // Test config
- assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
- }
-
- public void testConfigurationFirewallReload() throws Exception
- {
- // Write out config
- File mainFile = File.createTempFile(getClass().getName(), null);
-
- mainFile.deleteOnExit();
- writeConfigFile(mainFile, false);
-
- // Load config
- ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
-
- // Test config
- assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
-
- // Switch to deny the connection
- writeConfigFile(mainFile, true);
-
- reg.getConfiguration().reparseConfigFileSecuritySections();
-
- assertTrue(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
- }
-
- public void testCombinedConfigurationFirewallReload() throws Exception
- {
- // Write out config
- File mainFile = File.createTempFile(getClass().getName(), null);
- File fileA = File.createTempFile(getClass().getName(), null);
- File fileB = File.createTempFile(getClass().getName(), null);
-
- mainFile.deleteOnExit();
- fileA.deleteOnExit();
- fileB.deleteOnExit();
-
- FileWriter out = new FileWriter(mainFile);
- out.write("<configuration><system/>");
- out.write("<xml fileName=\"" + fileA.getAbsolutePath() + "\"/>");
- out.write("</configuration>");
- out.close();
-
- out = new FileWriter(fileA);
- out.write("<broker>\n");
- out.write("\t<plugin-directory>${QPID_HOME}/lib/plugins</plugin-directory>\n");
- out.write("\t<management><enabled>false</enabled></management>\n");
- out.write("\t<security>\n");
- out.write("\t\t<pd-auth-manager>\n");
- out.write("\t\t\t<principal-database>\n");
- out.write("\t\t\t\t<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>\n");
- out.write("\t\t\t\t<attributes>\n");
- out.write("\t\t\t\t\t<attribute>\n");
- out.write("\t\t\t\t\t\t<name>passwordFile</name>\n");
- out.write("\t\t\t\t\t\t<value>/dev/null</value>\n");
- out.write("\t\t\t\t\t</attribute>\n");
- out.write("\t\t\t\t</attributes>\n");
- out.write("\t\t\t</principal-database>\n");
- out.write("\t\t</pd-auth-manager>\n");
- out.write("\t\t<firewall>\n");
- out.write("\t\t\t<xml fileName=\"" + fileB.getAbsolutePath() + "\"/>");
- out.write("\t\t</firewall>\n");
- out.write("\t</security>\n");
- out.write("\t<virtualhosts>\n");
- out.write("\t\t<virtualhost>\n");
- out.write("\t\t\t<name>test</name>\n");
- out.write("\t\t</virtualhost>\n");
- out.write("\t</virtualhosts>\n");
- out.write("</broker>\n");
- out.close();
-
- out = new FileWriter(fileB);
- out.write("<firewall>\n");
- out.write("\t<rule access=\"deny\" network=\"127.0.0.1\"/>");
- out.write("</firewall>\n");
- out.close();
-
- // Load config
- ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
-
- // Test config
- assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
-
- RandomAccessFile fileBRandom = new RandomAccessFile(fileB, "rw");
- fileBRandom.setLength(0);
- fileBRandom.seek(0);
- fileBRandom.close();
-
- out = new FileWriter(fileB);
- out.write("<firewall>\n");
- out.write("\t<rule access=\"allow\" network=\"127.0.0.1\"/>");
- out.write("</firewall>\n");
- out.close();
-
- reg.getConfiguration().reparseConfigFileSecuritySections();
-
- assertTrue(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
-
- fileBRandom = new RandomAccessFile(fileB, "rw");
- fileBRandom.setLength(0);
- fileBRandom.seek(0);
- fileBRandom.close();
-
- out = new FileWriter(fileB);
- out.write("<firewall>\n");
- out.write("\t<rule access=\"deny\" network=\"127.0.0.1\"/>");
- out.write("</firewall>\n");
- out.close();
-
- reg.getConfiguration().reparseConfigFileSecuritySections();
-
- assertFalse(reg.getSecurityManager().accessVirtualhost("test", new InetSocketAddress("127.0.0.1", 65535)));
- }
-
- private void writeFirewallVhostsFile(File vhostsFile, boolean allow) throws IOException
- {
- FileWriter out = new FileWriter(vhostsFile);
- String ipAddr = "127.0.0.1"; // FIXME: get this from InetAddress.getLocalHost().getAddress() ?
- out.write("<virtualhosts><virtualhost>");
- out.write("<name>test</name>");
- out.write("<test>");
- out.write("<security><firewall>");
- out.write("<rule access=\""+((allow) ? "allow" : "deny")+"\" network=\""+ipAddr +"\"/>");
- out.write("</firewall></security>");
- out.write("</test>");
- out.write("</virtualhost></virtualhosts>");
- out.close();
- }
-
- private void writeConfigFile(File mainFile, boolean allow) throws IOException {
- writeConfigFile(mainFile, allow, true, null, "test");
- }
-
- /*
- XMLConfiguration config = new XMLConfiguration(mainFile);
- PluginManager pluginManager = new MockPluginManager("");
- SecurityManager manager = new SecurityManager(config, pluginManager, Firewall.FACTORY);
-
- */
- private void writeConfigFile(File mainFile, boolean allow, boolean includeVhosts, File vhostsFile, String name) throws IOException {
- FileWriter out = new FileWriter(mainFile);
- out.write("<broker>\n");
- out.write("\t<plugin-directory>${QPID_HOME}/lib/plugins</plugin-directory>\n");
- out.write("\t<management><enabled>false</enabled></management>\n");
- out.write("\t<security>\n");
- out.write("\t\t<pd-auth-manager>\n");
- out.write("\t\t\t<principal-database>\n");
- out.write("\t\t\t\t<class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>\n");
- out.write("\t\t\t\t<attributes>\n");
- out.write("\t\t\t\t\t<attribute>\n");
- out.write("\t\t\t\t\t\t<name>passwordFile</name>\n");
- out.write("\t\t\t\t\t\t<value>/dev/null</value>\n");
- out.write("\t\t\t\t\t</attribute>\n");
- out.write("\t\t\t\t</attributes>\n");
- out.write("\t\t\t</principal-database>\n");
- out.write("\t\t</pd-auth-manager>\n");
- out.write("\t\t<firewall>\n");
- out.write("\t\t\t<rule access=\""+ ((allow) ? "allow" : "deny") +"\" network=\"127.0.0.1\"/>");
- out.write("\t\t</firewall>\n");
- out.write("\t</security>\n");
- if (includeVhosts)
- {
- out.write("\t<virtualhosts>\n");
- out.write("\t\t<default>test</default>\n");
- out.write("\t\t<virtualhost>\n");
- out.write(String.format("\t\t\t<name>%s</name>\n", name));
- out.write("\t\t</virtualhost>\n");
- out.write("\t</virtualhosts>\n");
- }
- if (vhostsFile != null)
- {
- out.write("\t<virtualhosts>"+vhostsFile.getAbsolutePath()+"</virtualhosts>\n");
- }
- out.write("</broker>\n");
- out.close();
- }
-
- /**
- * Test that configuration loads correctly when virtual hosts are specified in an external
- * configuration file only.
- * <p>
- * Test for QPID-2360
- */
- public void testExternalFirewallVirtualhostXMLFile() throws Exception
- {
- // Write out config
- File mainFile = File.createTempFile(getClass().getName(), "config");
- mainFile.deleteOnExit();
- File vhostsFile = File.createTempFile(getClass().getName(), "vhosts");
- vhostsFile.deleteOnExit();
- writeConfigFile(mainFile, false, false, vhostsFile, null);
- writeFirewallVhostsFile(vhostsFile, false);
-
- // Load config
- ApplicationRegistry reg = new ConfigurationFileApplicationRegistry(mainFile);
- ApplicationRegistry.initialise(reg);
-
- // Test config
- VirtualHostRegistry virtualHostRegistry = reg.getVirtualHostRegistry();
- VirtualHost virtualHost = virtualHostRegistry.getVirtualHost("test");
-
- assertEquals("Incorrect virtualhost count", 1, virtualHostRegistry.getVirtualHosts().size());
- assertEquals("Incorrect virtualhost name", "test", virtualHost.getName());
- }
-}
diff --git a/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallPluginTest.java b/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallPluginTest.java
deleted file mode 100644
index 2004852c48..0000000000
--- a/java/broker-plugins/firewall/src/test/java/org/apache/qpid/server/security/access/FirewallPluginTest.java
+++ /dev/null
@@ -1,294 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.qpid.server.security.access;
-
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.commons.configuration.XMLConfiguration;
-
-import org.apache.qpid.server.configuration.ServerConfiguration;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.Result;
-import org.apache.qpid.server.security.access.plugins.Firewall;
-import org.apache.qpid.server.security.access.plugins.FirewallConfiguration;
-import org.apache.qpid.server.util.TestApplicationRegistry;
-import org.apache.qpid.test.utils.QpidTestCase;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-
-public class FirewallPluginTest extends QpidTestCase
-{
- public class RuleInfo
- {
- private String _access;
- private String _network;
- private String _hostname;
-
- public void setAccess(String _access)
- {
- this._access = _access;
- }
-
- public String getAccess()
- {
- return _access;
- }
-
- public void setNetwork(String _network)
- {
- this._network = _network;
- }
-
- public String getNetwork()
- {
- return _network;
- }
-
- public void setHostname(String _hostname)
- {
- this._hostname = _hostname;
- }
-
- public String getHostname()
- {
- return _hostname;
- }
- }
-
- // IP address
- private SocketAddress _address;
- private ServerConfiguration _serverConfig;
-
- @Override
- protected void setUp() throws Exception
- {
- super.setUp();
- _serverConfig = new ServerConfiguration(new XMLConfiguration());
- ApplicationRegistry.initialise(new TestApplicationRegistry(_serverConfig));
- _address = new InetSocketAddress("127.0.0.1", 65535);
- }
-
- @Override
- protected void tearDown() throws Exception
- {
- super.tearDown();
- ApplicationRegistry.remove();
- }
- private Firewall initialisePlugin(String defaultAction, RuleInfo[] rules) throws IOException, ConfigurationException
- {
- // Create sample config file
- File confFile = File.createTempFile(getClass().getSimpleName()+"conffile", null);
- confFile.deleteOnExit();
- BufferedWriter buf = new BufferedWriter(new FileWriter(confFile));
- buf.write("<firewall default-action=\""+defaultAction+"\">\n");
- if (rules != null)
- {
- for (RuleInfo rule : rules)
- {
- buf.write("<rule");
- buf.write(" access=\""+rule.getAccess()+"\"");
- if (rule.getHostname() != null)
- {
- buf.write(" hostname=\""+rule.getHostname()+"\"");
- }
- if (rule.getNetwork() != null)
- {
- buf.write(" network=\""+rule.getNetwork()+"\"");
- }
- buf.write("/>\n");
- }
- }
- buf.write("</firewall>");
- buf.close();
-
- // Configure plugin
- FirewallConfiguration config = new FirewallConfiguration();
- config.setConfiguration("", new XMLConfiguration(confFile));
- Firewall plugin = new Firewall();
- plugin.configure(config);
- return plugin;
- }
-
- private Firewall initialisePlugin(String string) throws ConfigurationException, IOException
- {
- return initialisePlugin(string, null);
- }
-
- public void testDefaultAction() throws Exception
- {
- // Test simple deny
- Firewall plugin = initialisePlugin("deny");
- assertEquals(Result.DENIED, plugin.access(ObjectType.VIRTUALHOST, _address));
-
- // Test simple allow
- plugin = initialisePlugin("allow");
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
-
- public void testSingleIPRule() throws Exception
- {
- RuleInfo rule = new RuleInfo();
- rule.setAccess("allow");
- rule.setNetwork("192.168.23.23");
-
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{rule});
-
- assertEquals(Result.DENIED, plugin.access(ObjectType.VIRTUALHOST, _address));
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("192.168.23.23", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
- public void testSingleNetworkRule() throws Exception
- {
- RuleInfo rule = new RuleInfo();
- rule.setAccess("allow");
- rule.setNetwork("192.168.23.0/24");
-
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{rule});
-
- assertEquals(Result.DENIED, plugin.access(ObjectType.VIRTUALHOST, _address));
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("192.168.23.23", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
- public void testSingleHostRule() throws Exception
- {
- RuleInfo rule = new RuleInfo();
- rule.setAccess("allow");
- rule.setHostname(new InetSocketAddress("127.0.0.1", 5672).getHostName());
-
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{rule});
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("127.0.0.1", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
- public void testSingleHostWilcardRule() throws Exception
- {
- RuleInfo rule = new RuleInfo();
- rule.setAccess("allow");
- String hostname = new InetSocketAddress("127.0.0.1", 0).getHostName();
- rule.setHostname(".*"+hostname.subSequence(hostname.length() - 1, hostname.length())+"*");
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{rule});
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("127.0.0.1", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
- public void testSeveralFirstAllowsAccess() throws Exception
- {
- RuleInfo firstRule = new RuleInfo();
- firstRule.setAccess("allow");
- firstRule.setNetwork("192.168.23.23");
-
- RuleInfo secondRule = new RuleInfo();
- secondRule.setAccess("deny");
- secondRule.setNetwork("192.168.42.42");
-
- RuleInfo thirdRule = new RuleInfo();
- thirdRule.setAccess("deny");
- thirdRule.setHostname("localhost");
-
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{firstRule, secondRule, thirdRule});
-
- assertEquals(Result.DENIED, plugin.access(ObjectType.VIRTUALHOST, _address));
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("192.168.23.23", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
- public void testSeveralLastAllowsAccess() throws Exception
- {
- RuleInfo firstRule = new RuleInfo();
- firstRule.setAccess("deny");
- firstRule.setHostname("localhost");
-
- RuleInfo secondRule = new RuleInfo();
- secondRule.setAccess("deny");
- secondRule.setNetwork("192.168.42.42");
-
- RuleInfo thirdRule = new RuleInfo();
- thirdRule.setAccess("allow");
- thirdRule.setNetwork("192.168.23.23");
-
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{firstRule, secondRule, thirdRule});
-
- assertEquals(Result.DENIED, plugin.access(ObjectType.VIRTUALHOST, _address));
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("192.168.23.23", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
- public void testNetmask() throws Exception
- {
- RuleInfo firstRule = new RuleInfo();
- firstRule.setAccess("allow");
- firstRule.setNetwork("192.168.23.0/24");
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{firstRule});
-
- assertEquals(Result.DENIED, plugin.access(ObjectType.VIRTUALHOST, _address));
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("192.168.23.23", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
- public void testCommaSeperatedNetmask() throws Exception
- {
- RuleInfo firstRule = new RuleInfo();
- firstRule.setAccess("allow");
- firstRule.setNetwork("10.1.1.1/8, 192.168.23.0/24");
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{firstRule});
-
- assertEquals(Result.DENIED, plugin.access(ObjectType.VIRTUALHOST, _address));
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("192.168.23.23", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-
- public void testCommaSeperatedHostnames() throws Exception
- {
- RuleInfo firstRule = new RuleInfo();
- firstRule.setAccess("allow");
- firstRule.setHostname("foo, bar, "+new InetSocketAddress("127.0.0.1", 5672).getHostName());
- Firewall plugin = initialisePlugin("deny", new RuleInfo[]{firstRule});
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("10.0.0.1", 65535);
- assertEquals(Result.DENIED, plugin.access(ObjectType.VIRTUALHOST, _address));
-
- // Set IP so that we're connected from the right address
- _address = new InetSocketAddress("127.0.0.1", 65535);
- assertEquals(Result.ALLOWED, plugin.access(ObjectType.VIRTUALHOST, _address));
- }
-}
diff --git a/java/broker/etc/broker_example.acl b/java/broker/etc/broker_example.acl
index fee1192371..fc650801c8 100644
--- a/java/broker/etc/broker_example.acl
+++ b/java/broker/etc/broker_example.acl
@@ -78,11 +78,24 @@ ACL ALLOW-LOG webadmins UPDATE METHOD
#ACL ALLOW-LOG webadmins UPDATE METHOD component="VirtualHost.Queue" name="deleteMessages"
### MESSAGING ###
+# The 'ACCESS VIRTUALHOST' rules below apply to messaging operations (as opposed to management operations)
-#Example permissions for request-response based messaging.
+# Firewall examples
-#Allow 'messaging-users' group to connect to all virtualhosts
+# Deny access to all users from *.example.company1.com and *.example.company2.com
+ACL DENY-LOG all ACCESS VIRTUALHOST from_hostname=".*\.example\.company1.com,.*\.example\.company2.com"
+
+# Deny access to all users in the IP ranges 192.168.1.0-192.168.1.255 and 192.168.2.0-192.168.2.255,
+# using the notation specified in RFC 4632, "Classless Inter-domain Routing (CIDR)"
+ACL DENY-LOG messaging-users ACCESS VIRTUALHOST from_network="192.168.1.0/24,192.168.2.0/24"
+
+# Deny access to all users in the IP ranges 192.169.1.0-192.169.1.255 and 192.169.2.0-192.169.2.255,
+# using wildcard notation.
+ACL DENY-LOG messaging-users ACCESS VIRTUALHOST from_network="192.169.1.*,192.169.2.*"
+
+# Allow 'messaging-users' group to connect to all virtualhosts
ACL ALLOW-LOG messaging-users ACCESS VIRTUALHOST
+
# Deny messaging-users management
ACL DENY-LOG messaging-users ACCESS MANAGEMENT
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java
index a9ec4d1647..8e38681e68 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java
@@ -18,33 +18,31 @@
*/
package org.apache.qpid.server.security.access;
-import org.apache.commons.lang.StringUtils;
-
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.queue.AMQQueue;
-
import java.util.ArrayList;
import java.util.EnumMap;
+import java.util.HashMap;
import java.util.List;
import java.util.Map;
+import org.apache.commons.lang.StringUtils;
+import org.apache.commons.lang.builder.EqualsBuilder;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.queue.AMQQueue;
+
/**
* An set of properties for an access control v2 rule {@link ObjectType}.
- *
+ *
* The {@link #matches(ObjectProperties)} method is intended to be used when determining precedence of rules, and
* {@link #equals(Object)} and {@link #hashCode()} are intended for use in maps. This is due to the wildcard matching
* described above.
*/
public class ObjectProperties
{
- /** serialVersionUID */
- private static final long serialVersionUID = -1356019341374170495L;
-
public static final String STAR= "*";
public static final ObjectProperties EMPTY = new ObjectProperties();
-
+
public enum Property
{
ROUTING_KEY,
@@ -65,81 +63,89 @@ public class ObjectProperties
AUTO_DELETE,
COMPONENT,
PACKAGE,
- CLASS;
-
- public static Property parse(String text)
+ CLASS,
+ FROM_NETWORK,
+ FROM_HOSTNAME;
+
+ private static final Map<String, Property> _canonicalNameToPropertyMap = new HashMap<String, ObjectProperties.Property>();
+
+ static
{
for (Property property : values())
{
- if (property.getName().equalsIgnoreCase(text))
- {
- return property;
- }
+ _canonicalNameToPropertyMap.put(getCanonicalName(property.name()), property);
+ }
+ }
+
+ /**
+ * Properties are parsed using their canonical name (see {@link #getCanonicalName(String)})
+ * so that, for the sake of user-friendliness, the ACL file parses is insensitive to
+ * case and underscores.
+ */
+ public static Property parse(String text)
+ {
+ String propertyName = getCanonicalName(text);
+ Property property = _canonicalNameToPropertyMap.get(propertyName);
+
+ if(property == null)
+ {
+ throw new IllegalArgumentException("Not a valid property: " + text
+ + " because " + propertyName
+ + " is not in " + _canonicalNameToPropertyMap.keySet());
+ }
+ else
+ {
+ return property;
}
- throw new IllegalArgumentException("Not a valid property: " + text);
}
-
- public String getName()
+
+ private static String getCanonicalName(String name)
{
- return StringUtils.remove(name(), '_').toLowerCase();
+ return StringUtils.remove(name, '_').toLowerCase();
}
-
- public static List<String> getPropertyNames()
- {
- List<String> properties = new ArrayList<String>();
- for (Property property : values())
- {
- properties.add(property.getName());
- }
- return properties;
- }
}
private final EnumMap<Property, String> _properties = new EnumMap<Property, String>(Property.class);
- public static List<String> getAllPropertyNames()
+ public static List<String> getAllPropertyNames()
{
- List<String> properties = new ArrayList<String>();
- for (Property property : Property.values())
- {
- properties.add(StringUtils.remove(property.name(), '_').toLowerCase());
- }
- return properties;
- }
-
+ List<String> properties = new ArrayList<String>();
+ for (Property property : Property.values())
+ {
+ properties.add(StringUtils.remove(property.name(), '_').toLowerCase());
+ }
+ return properties;
+ }
+
public ObjectProperties()
{
- super();
}
-
+
+ public ObjectProperties(Property property, String value)
+ {
+ _properties.put(property, value);
+ }
+
public ObjectProperties(ObjectProperties copy)
{
- super();
-
_properties.putAll(copy._properties);
}
-
+
public ObjectProperties(String name)
{
- super();
-
setName(name);
}
-
+
public ObjectProperties(AMQShortString name)
{
- super();
-
setName(name);
}
-
+
public ObjectProperties(AMQQueue queue)
{
- super();
-
setName(queue.getName());
-
+
put(Property.AUTO_DELETE, queue.isAutoDelete());
put(Property.TEMPORARY, queue.isAutoDelete());
put(Property.DURABLE, queue.isDurable());
@@ -157,45 +163,45 @@ public class ObjectProperties
put(Property.OWNER, queue.getAuthorizationHolder().getAuthorizedPrincipal().getName());
}
}
-
+
public ObjectProperties(Exchange exch, AMQQueue queue, AMQShortString routingKey)
{
this(queue);
-
- setName(exch.getName());
-
+
+ setName(exch.getName());
+
put(Property.QUEUE_NAME, queue.getName());
put(Property.ROUTING_KEY, routingKey);
}
-
+
public ObjectProperties(Exchange exch, AMQShortString routingKey)
{
this(exch.getName(), routingKey.asString());
}
-
+
public ObjectProperties(String exchangeName, String routingKey, Boolean immediate)
{
this(exchangeName, routingKey);
-
+
put(Property.IMMEDIATE, immediate);
}
-
+
public ObjectProperties(String exchangeName, String routingKey)
{
super();
-
+
setName(exchangeName);
-
+
put(Property.ROUTING_KEY, routingKey);
}
-
+
public ObjectProperties(Boolean autoDelete, Boolean durable, AMQShortString exchangeName,
Boolean internal, Boolean nowait, Boolean passive, AMQShortString exchangeType)
{
super();
-
+
setName(exchangeName);
-
+
put(Property.AUTO_DELETE, autoDelete);
put(Property.TEMPORARY, autoDelete);
put(Property.DURABLE, durable);
@@ -204,14 +210,14 @@ public class ObjectProperties
put(Property.PASSIVE, passive);
put(Property.TYPE, exchangeType);
}
-
+
public ObjectProperties(Boolean autoDelete, Boolean durable, Boolean exclusive, Boolean nowait, Boolean passive,
AMQShortString queueName, String owner)
{
super();
-
+
setName(queueName);
-
+
put(Property.AUTO_DELETE, autoDelete);
put(Property.TEMPORARY, autoDelete);
put(Property.DURABLE, durable);
@@ -220,7 +226,7 @@ public class ObjectProperties
put(Property.PASSIVE, passive);
put(Property.OWNER, owner);
}
-
+
public ObjectProperties(Boolean exclusive, Boolean noAck, Boolean noLocal, Boolean nowait, AMQQueue queue)
{
this(queue);
@@ -230,17 +236,7 @@ public class ObjectProperties
put(Property.EXCLUSIVE, exclusive);
put(Property.NO_WAIT, nowait);
}
-
- public List<String> getPropertyNames()
- {
- List<String> properties = new ArrayList<String>();
- for (Property property : _properties.keySet())
- {
- properties.add(property.getName());
- }
- return properties;
- }
-
+
public Boolean isSet(Property key)
{
return _properties.containsKey(key) && Boolean.valueOf(_properties.get(key));
@@ -255,17 +251,17 @@ public class ObjectProperties
{
return _properties.get(Property.NAME);
}
-
+
public void setName(String name)
{
_properties.put(Property.NAME, name);
}
-
+
public void setName(AMQShortString name)
{
put(Property.NAME, name);
}
-
+
public String put(Property key, AMQShortString value)
{
return put(key, value == null ? "" : value.asString());
@@ -275,7 +271,7 @@ public class ObjectProperties
{
return _properties.put(key, value == null ? "" : value.trim());
}
-
+
public void put(Property key, Boolean value)
{
if (value != null)
@@ -283,66 +279,64 @@ public class ObjectProperties
_properties.put(key, Boolean.toString(value));
}
}
-
+
public boolean matches(ObjectProperties properties)
{
if (properties._properties.keySet().isEmpty())
{
return true;
}
-
+
if (!_properties.keySet().containsAll(properties._properties.keySet()))
{
return false;
}
-
+
for (Map.Entry<Property,String> entry : properties._properties.entrySet())
{
Property key = entry.getKey();
String ruleValue = entry.getValue();
-
+
String thisValue = _properties.get(key);
- if (!valueMatches(thisValue, ruleValue))
+ if (!valueMatches(thisValue, ruleValue))
{
return false;
}
}
-
+
return true;
}
-
+
private boolean valueMatches(String thisValue, String ruleValue)
{
return (StringUtils.isEmpty(ruleValue)
|| StringUtils.equals(thisValue, ruleValue))
|| ruleValue.equals(STAR)
- || (ruleValue.endsWith(STAR)
+ || (ruleValue.endsWith(STAR)
&& thisValue != null
&& thisValue.length() >= ruleValue.length() - 1
&& thisValue.startsWith(ruleValue.substring(0, ruleValue.length() - 1)));
}
@Override
- public boolean equals(Object o)
+ public boolean equals(Object obj)
{
- if (this == o)
+ if (obj == null)
{
- return true;
+ return false;
}
- if (o == null || getClass() != o.getClass())
+ if (obj == this)
{
- return false;
+ return true;
}
-
- ObjectProperties that = (ObjectProperties) o;
-
- if (_properties != null ? !_properties.equals(that._properties) : that._properties != null)
+ if (obj.getClass() != getClass())
{
return false;
}
-
- return true;
+ ObjectProperties rhs = (ObjectProperties) obj;
+ return new EqualsBuilder()
+ .append(_properties, rhs._properties).isEquals();
}
@Override
diff --git a/java/ivy.nexus.xml b/java/ivy.nexus.xml
index 5d5bf304b6..c39f466da3 100644
--- a/java/ivy.nexus.xml
+++ b/java/ivy.nexus.xml
@@ -45,12 +45,6 @@
<artifact name="qpid-broker-plugins-access-control" type="jar.asc" ext="jar.asc"/>
<artifact name="qpid-broker-plugins-access-control" type="source" ext="jar" e:classifier="sources"/>
<artifact name="qpid-broker-plugins-access-control" type="source.asc" ext="jar.asc" e:classifier="sources"/>
- <artifact name="qpid-broker-plugins-firewall" type="pom" ext="pom"/>
- <artifact name="qpid-broker-plugins-firewall" type="pom.asc" ext="pom.asc"/>
- <artifact name="qpid-broker-plugins-firewall" type="jar" ext="jar"/>
- <artifact name="qpid-broker-plugins-firewall" type="jar.asc" ext="jar.asc"/>
- <artifact name="qpid-broker-plugins-firewall" type="source" ext="jar" e:classifier="sources"/>
- <artifact name="qpid-broker-plugins-firewall" type="source.asc" ext="jar.asc" e:classifier="sources"/>
<artifact name="qpid-broker-plugins-management-http" type="pom" ext="pom"/>
<artifact name="qpid-broker-plugins-management-http" type="pom.asc" ext="pom.asc"/>
<artifact name="qpid-broker-plugins-management-http" type="jar" ext="jar"/>
diff --git a/java/systests/etc/config-systests-firewall-2.xml b/java/systests/etc/config-systests-firewall-2.xml
deleted file mode 100644
index 5167d88f12..0000000000
--- a/java/systests/etc/config-systests-firewall-2.xml
+++ /dev/null
@@ -1,83 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- -
- - Licensed to the Apache Software Foundation (ASF) under one
- - or more contributor license agreements. See the NOTICE file
- - distributed with this work for additional information
- - regarding copyright ownership. The ASF licenses this file
- - to you under the Apache License, Version 2.0 (the
- - "License"); you may not use this file except in compliance
- - with the License. You may obtain a copy of the License at
- -
- - http://www.apache.org/licenses/LICENSE-2.0
- -
- - Unless required by applicable law or agreed to in writing,
- - software distributed under the License is distributed on an
- - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- - KIND, either express or implied. See the License for the
- - specific language governing permissions and limitations
- - under the License.
- -
- -->
-<broker>
- <prefix>${QPID_HOME}</prefix>
- <work>${QPID_WORK}</work>
- <conf>${prefix}/etc</conf>
- <plugin-directory>${QPID_HOME}/lib/plugins</plugin-directory>
- <cache-directory>${QPID_WORK}/cache</cache-directory>
- <connector>
- <!-- To enable SSL edit the keystorePath and keystorePassword
- and set enabled to true.
- To disasble Non-SSL port set sslOnly to true -->
- <ssl>
- <enabled>false</enabled>
- <port>8672</port>
- <sslOnly>false</sslOnly>
- <keyStorePath>/path/to/keystore.ks</keyStorePath>
- <keyStorePassword>keystorepass</keyStorePassword>
- </ssl>
- <port>5672</port>
- <socketReceiveBuffer>262144</socketReceiveBuffer>
- <socketSendBuffer>262144</socketSendBuffer>
- </connector>
- <management>
- <enabled>false</enabled>
- </management>
- <advanced>
- <framesize>65535</framesize>
- <locale>en_US</locale>
- </advanced>
-
- <security>
- <pd-auth-manager>
- <principal-database>
- <class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>
- <attributes>
- <attribute>
- <name>passwordFile</name>
- <value>${conf}/passwd</value>
- </attribute>
- </attributes>
- </principal-database>
- </pd-auth-manager>
-
- <msg-auth>false</msg-auth>
-
- <firewall default-action="deny"/>
- </security>
-
- <virtualhosts>${conf}/virtualhosts-systests-firewall-2.xml</virtualhosts>
-
- <heartbeat>
- <delay>0</delay>
- <timeoutFactor>2.0</timeoutFactor>
- </heartbeat>
- <queue>
- <auto_register>true</auto_register>
- </queue>
-
- <status-updates>ON</status-updates>
-
-</broker>
-
-
diff --git a/java/systests/etc/config-systests-firewall-3.xml b/java/systests/etc/config-systests-firewall-3.xml
deleted file mode 100644
index 2bcbf53a39..0000000000
--- a/java/systests/etc/config-systests-firewall-3.xml
+++ /dev/null
@@ -1,85 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- -
- - Licensed to the Apache Software Foundation (ASF) under one
- - or more contributor license agreements. See the NOTICE file
- - distributed with this work for additional information
- - regarding copyright ownership. The ASF licenses this file
- - to you under the Apache License, Version 2.0 (the
- - "License"); you may not use this file except in compliance
- - with the License. You may obtain a copy of the License at
- -
- - http://www.apache.org/licenses/LICENSE-2.0
- -
- - Unless required by applicable law or agreed to in writing,
- - software distributed under the License is distributed on an
- - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- - KIND, either express or implied. See the License for the
- - specific language governing permissions and limitations
- - under the License.
- -
- -->
-<broker>
- <prefix>${QPID_HOME}</prefix>
- <work>${QPID_WORK}</work>
- <conf>${prefix}/etc</conf>
- <plugin-directory>${QPID_HOME}/lib/plugins</plugin-directory>
- <cache-directory>${QPID_WORK}/cache</cache-directory>
- <connector>
- <!-- To enable SSL edit the keystorePath and keystorePassword
- and set enabled to true.
- To disable Non-SSL port set sslOnly to true -->
- <ssl>
- <enabled>false</enabled>
- <port>8672</port>
- <sslOnly>false</sslOnly>
- <keyStorePath>/path/to/keystore.ks</keyStorePath>
- <keyStorePassword>keystorepass</keyStorePassword>
- </ssl>
- <port>5672</port>
- <socketReceiveBuffer>262144</socketReceiveBuffer>
- <socketSendBuffer>262144</socketSendBuffer>
- </connector>
- <management>
- <enabled>false</enabled>
- </management>
- <advanced>
- <framesize>65535</framesize>
- <locale>en_US</locale>
- </advanced>
-
- <security>
- <pd-auth-manager>
- <principal-database>
- <class>org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase</class>
- <attributes>
- <attribute>
- <name>passwordFile</name>
- <value>${conf}/passwd</value>
- </attribute>
- </attributes>
- </principal-database>
- </pd-auth-manager>
-
- <msg-auth>false</msg-auth>
-
- <firewall default-action="deny">
- <rule access="allow" network="127.0.0.1"/>
- </firewall>
- </security>
-
- <virtualhosts>${conf}/virtualhosts-systests-firewall-3.xml</virtualhosts>
-
- <heartbeat>
- <delay>0</delay>
- <timeoutFactor>2.0</timeoutFactor>
- </heartbeat>
- <queue>
- <auto_register>true</auto_register>
- </queue>
-
- <status-updates>ON</status-updates>
-
-</broker>
-
-
diff --git a/java/systests/etc/config-systests-firewall-settings.xml b/java/systests/etc/config-systests-firewall-settings.xml
deleted file mode 100644
index aa73be0646..0000000000
--- a/java/systests/etc/config-systests-firewall-settings.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- -
- - Licensed to the Apache Software Foundation (ASF) under one
- - or more contributor license agreements. See the NOTICE file
- - distributed with this work for additional information
- - regarding copyright ownership. The ASF licenses this file
- - to you under the Apache License, Version 2.0 (the
- - "License"); you may not use this file except in compliance
- - with the License. You may obtain a copy of the License at
- -
- - http://www.apache.org/licenses/LICENSE-2.0
- -
- - Unless required by applicable law or agreed to in writing,
- - software distributed under the License is distributed on an
- - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- - KIND, either express or implied. See the License for the
- - specific language governing permissions and limitations
- - under the License.
- -
- -->
-<broker>
- <security>
- <firewall>
- <rule access="allow" network="127.0.0.1"/>
- </firewall>
- </security>
-
- <virtualhosts>${QPID_HOME}/etc/virtualhosts-systests-firewall.xml</virtualhosts>
-</broker>
diff --git a/java/systests/etc/config-systests-firewall.xml b/java/systests/etc/config-systests-firewall.xml
deleted file mode 100644
index a884a39614..0000000000
--- a/java/systests/etc/config-systests-firewall.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- -
- - Licensed to the Apache Software Foundation (ASF) under one
- - or more contributor license agreements. See the NOTICE file
- - distributed with this work for additional information
- - regarding copyright ownership. The ASF licenses this file
- - to you under the Apache License, Version 2.0 (the
- - "License"); you may not use this file except in compliance
- - with the License. You may obtain a copy of the License at
- -
- - http://www.apache.org/licenses/LICENSE-2.0
- -
- - Unless required by applicable law or agreed to in writing,
- - software distributed under the License is distributed on an
- - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- - KIND, either express or implied. See the License for the
- - specific language governing permissions and limitations
- - under the License.
- -
- -->
-<configuration>
- <system/>
- <override>
- <xml fileName="${QPID_HOME}/${test.config}" optional="true"/>
- <xml fileName="${QPID_FIREWALL_CONFIG_SETTINGS}" optional="true"/>
- <xml fileName="${QPID_HOME}/etc/config-systests-firewall-settings.xml"/>
- <xml fileName="${QPID_HOME}/etc/config-systests-settings.xml"/>
- </override>
-</configuration>
diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java
index 400464b4eb..8324ac74a5 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java
@@ -404,4 +404,33 @@ public class ExternalACLTest extends AbstractACLTestCase
sess.rollback();
conn.close();
}
+
+ public void setUpFirewallAllow() throws Exception
+ {
+ writeACLFile("test", "ACL ALLOW client ACCESS VIRTUALHOST from_network=\"127.0.0.1\"");
+ }
+
+ public void testFirewallAllow() throws Exception
+ {
+ getConnection("test", "client", "guest");
+ // test pass because we successfully connected
+ }
+
+ public void setUpFirewallDeny() throws Exception
+ {
+ writeACLFile("test", "ACL DENY client ACCESS VIRTUALHOST from_network=\"127.0.0.1\"");
+ }
+
+ public void testFirewallDeny() throws Exception
+ {
+ try
+ {
+ getConnection("test", "client", "guest");
+ fail("We expected the connection to fail");
+ }
+ catch(JMSException e)
+ {
+ // pass
+ }
+ }
}
diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/firewall/FirewallConfigTest.java b/java/systests/src/main/java/org/apache/qpid/server/security/firewall/FirewallConfigTest.java
deleted file mode 100644
index f5adf815aa..0000000000
--- a/java/systests/src/main/java/org/apache/qpid/server/security/firewall/FirewallConfigTest.java
+++ /dev/null
@@ -1,283 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.qpid.server.security.firewall;
-
-import org.apache.qpid.client.AMQConnectionURL;
-import org.apache.qpid.test.utils.QpidBrokerTestCase;
-
-import javax.jms.Connection;
-import javax.jms.JMSException;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.net.InetAddress;
-import java.net.UnknownHostException;
-
-public class FirewallConfigTest extends QpidBrokerTestCase
-{
- private File _tmpConfig, _tmpVirtualhosts;
- private String _ipAddressOfBrokerHost;
-
- @Override
- protected void setUp() throws Exception
- {
- // Setup initial config file.
- _configFile = new File("build/etc/config-systests-firewall.xml");
-
- // Setup temporary config file
- _tmpConfig = File.createTempFile("config-systests-firewall", ".xml");
- setSystemProperty("QPID_FIREWALL_CONFIG_SETTINGS", _tmpConfig.getAbsolutePath());
- _tmpConfig.deleteOnExit();
-
- // Setup temporary virtualhosts file
- _tmpVirtualhosts = File.createTempFile("virtualhosts-systests-firewall", ".xml");
- setSystemProperty("QPID_FIREWALL_VIRTUALHOSTS_SETTINGS", _tmpVirtualhosts.getAbsolutePath());
- _tmpVirtualhosts.deleteOnExit();
-
- _ipAddressOfBrokerHost = getIpAddressOfBrokerHost();
- }
-
- private void writeFirewallFile(boolean allow, boolean inVhost) throws IOException
- {
- FileWriter out = new FileWriter(inVhost ? _tmpVirtualhosts : _tmpConfig);
- if (inVhost)
- {
- out.write("<virtualhosts><virtualhost><test>");
- }
- else
- {
- out.write("<broker>");
- }
- out.write("<security><firewall>");
- out.write("<rule access=\""+((allow) ? "allow" : "deny")+"\" network=\"" + _ipAddressOfBrokerHost + "\"/>");
- out.write("</firewall></security>");
- if (inVhost)
- {
- out.write("</test></virtualhost></virtualhosts>");
- }
- else
- {
- out.write("</broker>");
- }
- out.close();
- }
-
- public void testVhostAllowBrokerDeny() throws Exception
- {
-
- _configFile = new File("build/etc/config-systests-firewall-2.xml");
-
- super.setUp();
- try
- {
- //Try to get a connection to the 'test2' vhost
- //This is expected to succeed as it is allowed at the vhost level
- getConnection(new AMQConnectionURL("amqp://guest:guest@clientid/test2?brokerlist='" + getBroker() + "'"));
- }
- catch (JMSException e)
- {
- e.getLinkedException().printStackTrace();
- fail("The connection was expected to succeed: " + e.getMessage());
- }
-
- try
- {
- //Try to get a connection to the 'test' vhost
- //This is expected to fail as it is denied at the broker level
- getConnection();
- fail("We expected the connection to fail");
- }
- catch (JMSException e)
- {
- //ignore
- }
- }
-
- public void testVhostDenyBrokerAllow() throws Exception
- {
- _configFile = new File("build/etc/config-systests-firewall-3.xml");
-
- super.setUp();
- try
- {
- //Try to get a connection to the 'test2' vhost
- //This is expected to fail as it is denied at the vhost level
- getConnection(new AMQConnectionURL("amqp://guest:guest@clientid/test2?brokerlist='" + getBroker() + "'"));
- fail("The connection was expected to fail");
- }
- catch (JMSException e)
- {
- //ignore
- }
-
- try
- {
- //Try to get a connection to the 'test' vhost
- //This is expected to succeed as it is allowed at the broker level
- getConnection();
- }
- catch (JMSException e)
- {
- e.getLinkedException().printStackTrace();
- fail("The connection was expected to succeed: " + e.getMessage());
- }
- }
-
- public void testDenyOnRestart() throws Exception
- {
- testDeny(false, new Runnable() {
-
- public void run()
- {
- try
- {
- restartBroker();
- } catch (Exception e)
- {
- fail(e.getMessage());
- }
- }
- });
- }
-
- public void testDenyOnRestartInVhost() throws Exception
- {
- testDeny(true, new Runnable() {
-
- public void run()
- {
- try
- {
- restartBroker();
- } catch (Exception e)
- {
- fail(e.getMessage());
- }
- }
- });
- }
-
- public void testAllowOnReloadInVhost() throws Exception
- {
- testFirewall(false, true, new Runnable() {
-
- public void run()
- {
- try
- {
- reloadBrokerSecurityConfig();
- } catch (Exception e)
- {
- fail(e.getMessage());
- }
- }
- });
- }
-
- public void testDenyOnReload() throws Exception
- {
- testDeny(false, new Runnable() {
-
- public void run()
- {
- try
- {
- reloadBrokerSecurityConfig();
- } catch (Exception e)
- {
- fail(e.getMessage());
- }
- }
- }
- );
- }
-
- public void testDenyOnReloadInVhost() throws Exception
- {
- testDeny(true, new Runnable() {
-
- public void run()
- {
- try
- {
- reloadBrokerSecurityConfig();
- } catch (Exception e)
- {
- fail(e.getMessage());
- }
- }
- }
- );
-
- }
-
- private void testDeny(boolean inVhost, Runnable restartOrReload) throws Exception
- {
- testFirewall(true, inVhost, restartOrReload);
- }
-
- /*
- * Check we can get a connection
- */
- private boolean checkConnection() throws Exception
- {
- Exception exception = null;
- Connection conn = null;
- try
- {
- conn = getConnection();
- }
- catch (JMSException e)
- {
- exception = e;
- }
-
- return conn != null;
- }
-
- private void testFirewall(boolean initial, boolean inVhost, Runnable restartOrReload) throws Exception
- {
-
- writeFirewallFile(initial, inVhost);
- setConfigurationProperty("management.enabled", String.valueOf(true));
- super.setUp();
-
- assertEquals("Initial connection check failed", initial, checkConnection());
-
- // Reload changed firewall file after restart or reload
- writeFirewallFile(!initial, inVhost);
- restartOrReload.run();
-
- assertEquals("Second connection check failed", !initial, checkConnection());
- }
-
- private String getIpAddressOfBrokerHost()
- {
- String brokerHost = getBroker().getHost();
- try
- {
- return InetAddress.getByName(brokerHost).getHostAddress();
- }
- catch (UnknownHostException e)
- {
- throw new RuntimeException("Could not determine IP address of host : " + brokerHost, e);
- }
-
- }
-}