summaryrefslogtreecommitdiff
path: root/qpid/java/broker-plugins
diff options
context:
space:
mode:
authorKeith Wall <kwall@apache.org>2014-03-25 17:54:10 +0000
committerKeith Wall <kwall@apache.org>2014-03-25 17:54:10 +0000
commitcd6130384dc5f27ad494eabf8a2b15ca79280aa1 (patch)
tree77d7b1f0ced2cea6b031327fcb5c8143d763cf9d /qpid/java/broker-plugins
parentfcc3f654b60b7dd2180afe73e8809545725b41af (diff)
parent809061e0024b74f89afdeff8ba83d6514589f417 (diff)
downloadqpid-python-cd6130384dc5f27ad494eabf8a2b15ca79280aa1.tar.gz
NO-JIRA: Merge changes from trunk.
Command was: svn merge https://svn.apache.org/repos/asf/qpid/trunk git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/java-broker-bdb-ha2@1581428 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'qpid/java/broker-plugins')
-rw-r--r--qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlTest.java16
-rw-r--r--qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java105
-rw-r--r--qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerSessionDelegate.java2
-rw-r--r--qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQChannel.java5
-rw-r--r--qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/handler/ConnectionOpenMethodHandler.java3
-rw-r--r--qpid/java/broker-plugins/jdbc-provider-bone/src/main/java/resources/virtualhost/store/pool/bonecp/add.html2
-rw-r--r--qpid/java/broker-plugins/management-http/pom.xml6
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/FileServlet.java4
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java6
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java12
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/sasl.js221
-rw-r--r--qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js2
-rw-r--r--qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java25
13 files changed, 329 insertions, 80 deletions
diff --git a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlTest.java b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlTest.java
index 3a36ddef2c..072bd6a87f 100644
--- a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlTest.java
+++ b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/DefaultAccessControlTest.java
@@ -20,7 +20,9 @@
*/
package org.apache.qpid.server.security.access.plugins;
-import static org.mockito.Mockito.*;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
import java.net.InetAddress;
import java.net.InetSocketAddress;
@@ -181,7 +183,7 @@ public class DefaultAccessControlTest extends TestCase
final RuleSet rs = new RuleSet(mock(EventLoggerProvider.class));
// grant user4 access right on any method in any component
- rs.grant(1, "user4", Permission.ALLOW, Operation.ACCESS, ObjectType.METHOD, new ObjectProperties(ObjectProperties.STAR));
+ rs.grant(1, "user4", Permission.ALLOW, Operation.ACCESS, ObjectType.METHOD, new ObjectProperties(ObjectProperties.WILD_CARD));
configureAccessControl(rs);
Subject.doAs(TestPrincipalUtils.createTestSubject("user4"), new PrivilegedAction<Object>()
{
@@ -207,7 +209,7 @@ public class DefaultAccessControlTest extends TestCase
final RuleSet rs = new RuleSet(mock(EventLoggerProvider.class));
// grant user5 access right on any methods in "Test" component
- ObjectProperties ruleProperties = new ObjectProperties(ObjectProperties.STAR);
+ ObjectProperties ruleProperties = new ObjectProperties(ObjectProperties.WILD_CARD);
ruleProperties.put(ObjectProperties.Property.COMPONENT, "Test");
rs.grant(1, "user5", Permission.ALLOW, Operation.ACCESS, ObjectType.METHOD, ruleProperties);
configureAccessControl(rs);
@@ -234,6 +236,7 @@ public class DefaultAccessControlTest extends TestCase
public void testAccess() throws Exception
{
final Subject subject = TestPrincipalUtils.createTestSubject("user1");
+ final String testVirtualHost = getName();
final InetAddress inetAddress = InetAddress.getLocalHost();
final InetSocketAddress inetSocketAddress = new InetSocketAddress(inetAddress, 1);
@@ -249,13 +252,12 @@ public class DefaultAccessControlTest extends TestCase
{
RuleSet mockRuleSet = mock(RuleSet.class);
-
-
DefaultAccessControl accessControl = new DefaultAccessControl(mockRuleSet);
- accessControl.authorise(Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
+ ObjectProperties properties = new ObjectProperties(testVirtualHost);
+ accessControl.authorise(Operation.ACCESS, ObjectType.VIRTUALHOST, properties);
- verify(mockRuleSet).check(subject, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY, inetAddress);
+ verify(mockRuleSet).check(subject, Operation.ACCESS, ObjectType.VIRTUALHOST, properties, inetAddress);
return null;
}
});
diff --git a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java
index caf9b2fb61..32037807cd 100644
--- a/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java
+++ b/qpid/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java
@@ -21,24 +21,26 @@
package org.apache.qpid.server.security.access.plugins;
-import java.security.Principal;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
import javax.security.auth.Subject;
-import org.apache.qpid.server.logging.EventLogger;
+import org.apache.qpid.server.exchange.ExchangeImpl;
import org.apache.qpid.server.logging.EventLoggerProvider;
+import org.apache.qpid.server.model.VirtualHost;
+import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.security.Result;
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.Permission;
+import org.apache.qpid.server.security.access.ObjectProperties.Property;
import org.apache.qpid.server.security.access.config.Rule;
import org.apache.qpid.server.security.access.config.RuleSet;
import org.apache.qpid.server.security.auth.TestPrincipalUtils;
import org.apache.qpid.test.utils.QpidTestCase;
-import static org.mockito.Mockito.mock;
-
/**
* This test checks that the {@link RuleSet} object which forms the core of the access control plugin performs correctly.
*
@@ -51,6 +53,9 @@ import static org.mockito.Mockito.mock;
*/
public class RuleSetTest extends QpidTestCase
{
+ private static final String DENIED_VH = "deniedVH";
+ private static final String ALLOWED_VH = "allowedVH";
+
private RuleSet _ruleSet; // Object under test
private static final String TEST_USER = "user";
@@ -60,6 +65,8 @@ public class RuleSetTest extends QpidTestCase
private String _exchangeName = "amq.direct";
private String _exchangeType = "direct";
private Subject _testSubject = TestPrincipalUtils.createTestSubject(TEST_USER);
+ private AMQQueue<?> _queue;
+ private VirtualHost<?> _virtualHost;
@Override
public void setUp() throws Exception
@@ -67,6 +74,11 @@ public class RuleSetTest extends QpidTestCase
super.setUp();
_ruleSet = new RuleSet(mock(EventLoggerProvider.class));
+
+ _virtualHost = mock(VirtualHost.class);
+ _queue = mock(AMQQueue.class);
+ when(_queue.getName()).thenReturn(_queueName);
+ when(_queue.getParent(VirtualHost.class)).thenReturn(_virtualHost);
}
@Override
@@ -83,10 +95,8 @@ public class RuleSetTest extends QpidTestCase
public void assertDenyGrantAllow(Subject subject, Operation operation, ObjectType objectType, ObjectProperties properties)
{
- final Principal identity = subject.getPrincipals().iterator().next();
-
assertEquals(Result.DENIED, _ruleSet.check(subject, operation, objectType, properties));
- _ruleSet.grant(0, identity.getName(), Permission.ALLOW, operation, objectType, properties);
+ _ruleSet.grant(0, TEST_USER, Permission.ALLOW, operation, objectType, properties);
assertEquals(1, _ruleSet.getRuleCount());
assertEquals(Result.ALLOWED, _ruleSet.check(subject, operation, objectType, properties));
}
@@ -98,17 +108,77 @@ public class RuleSetTest extends QpidTestCase
assertEquals(_ruleSet.getDefault(), _ruleSet.check(_testSubject, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY));
}
- public void testVirtualHostAccess() throws Exception
+ public void testVirtualHostAccessAllowPermissionWithVirtualHostName() throws Exception
{
- assertDenyGrantAllow(_testSubject, Operation.ACCESS, ObjectType.VIRTUALHOST);
+ _ruleSet.grant(0, TEST_USER, Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, new ObjectProperties(ALLOWED_VH));
+ assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.ACCESS, ObjectType.VIRTUALHOST, new ObjectProperties(ALLOWED_VH)));
+ assertEquals(Result.DEFER, _ruleSet.check(_testSubject, Operation.ACCESS, ObjectType.VIRTUALHOST, new ObjectProperties(DENIED_VH)));
}
+ public void testVirtualHostAccessAllowPermissionWithNameSetToWildCard() throws Exception
+ {
+ _ruleSet.grant(0, TEST_USER, Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, new ObjectProperties(ObjectProperties.WILD_CARD));
+ assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.ACCESS, ObjectType.VIRTUALHOST, new ObjectProperties(ALLOWED_VH)));
+ assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.ACCESS, ObjectType.VIRTUALHOST, new ObjectProperties(DENIED_VH)));
+ }
+
+ public void testVirtualHostAccessAllowPermissionWithNoName() throws Exception
+ {
+ _ruleSet.grant(0, TEST_USER, Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
+ assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.ACCESS, ObjectType.VIRTUALHOST, new ObjectProperties(ALLOWED_VH)));
+ assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.ACCESS, ObjectType.VIRTUALHOST, new ObjectProperties(DENIED_VH)));
+ }
+
+ public void testVirtualHostAccessDenyPermissionWithNoName() throws Exception
+ {
+ _ruleSet.grant(0, TEST_USER, Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, ObjectProperties.EMPTY);
+ assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.ACCESS, ObjectType.VIRTUALHOST, new ObjectProperties(ALLOWED_VH)));
+ assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.ACCESS, ObjectType.VIRTUALHOST, new ObjectProperties(DENIED_VH)));
+ }
+
+ public void testVirtualHostAccessDenyPermissionWithNameSetToWildCard() throws Exception
+ {
+ _ruleSet.grant(0, TEST_USER, Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, new ObjectProperties(ObjectProperties.WILD_CARD));
+ assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.ACCESS, ObjectType.VIRTUALHOST, new ObjectProperties(ALLOWED_VH)));
+ assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.ACCESS, ObjectType.VIRTUALHOST, new ObjectProperties(DENIED_VH)));
+ }
+
+ public void testVirtualHostAccessAllowDenyPermissions() throws Exception
+ {
+ _ruleSet.grant(0, TEST_USER, Permission.DENY, Operation.ACCESS, ObjectType.VIRTUALHOST, new ObjectProperties(DENIED_VH));
+ _ruleSet.grant(1, TEST_USER, Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, new ObjectProperties(ALLOWED_VH));
+ assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.ACCESS, ObjectType.VIRTUALHOST, new ObjectProperties(ALLOWED_VH)));
+ assertEquals(Result.DENIED, _ruleSet.check(_testSubject, Operation.ACCESS, ObjectType.VIRTUALHOST, new ObjectProperties(DENIED_VH)));
+ }
+
+ public void testVirtualHostAccessAllowPermissionWithVirtualHostNameOtherPredicate() throws Exception
+ {
+ ObjectProperties properties = new ObjectProperties();
+ properties.put(Property.VIRTUALHOST_NAME, ALLOWED_VH);
+
+ _ruleSet.grant(0, TEST_USER, Permission.ALLOW, Operation.ACCESS, ObjectType.VIRTUALHOST, properties);
+ assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.ACCESS, ObjectType.VIRTUALHOST, properties));
+ assertEquals(Result.DEFER, _ruleSet.check(_testSubject, Operation.ACCESS, ObjectType.VIRTUALHOST, new ObjectProperties(DENIED_VH)));
+ }
+
+
public void testQueueCreateNamed() throws Exception
{
assertDenyGrantAllow(_testSubject, Operation.CREATE, ObjectType.QUEUE, new ObjectProperties(_queueName));
}
- public void testQueueCreatenamedNullRoutingKey()
+ public void testQueueCreateNamedVirtualHost() throws Exception
+ {
+ _ruleSet.grant(0, TEST_USER, Permission.ALLOW, Operation.CREATE, ObjectType.QUEUE, new ObjectProperties(Property.VIRTUALHOST_NAME, ALLOWED_VH));
+
+ when(_virtualHost.getName()).thenReturn(ALLOWED_VH);
+ assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, new ObjectProperties(_queue)));
+
+ when(_virtualHost.getName()).thenReturn(DENIED_VH);
+ assertEquals(Result.DEFER, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.QUEUE, new ObjectProperties(_queue)));
+ }
+
+ public void testQueueCreateNamedNullRoutingKey()
{
ObjectProperties properties = new ObjectProperties(_queueName);
properties.put(ObjectProperties.Property.ROUTING_KEY, (String) null);
@@ -116,6 +186,21 @@ public class RuleSetTest extends QpidTestCase
assertDenyGrantAllow(_testSubject, Operation.CREATE, ObjectType.QUEUE, properties);
}
+ public void testExchangeCreateNamedVirtualHost()
+ {
+ _ruleSet.grant(0, TEST_USER, Permission.ALLOW, Operation.CREATE, ObjectType.EXCHANGE, new ObjectProperties(Property.VIRTUALHOST_NAME, ALLOWED_VH));
+
+ ExchangeImpl<?> exchange = mock(ExchangeImpl.class);
+ when(exchange.getParent(VirtualHost.class)).thenReturn(_virtualHost);
+ when(exchange.getTypeName()).thenReturn(_exchangeType);
+ when(_virtualHost.getName()).thenReturn(ALLOWED_VH);
+
+ assertEquals(Result.ALLOWED, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.EXCHANGE, new ObjectProperties(exchange)));
+
+ when(_virtualHost.getName()).thenReturn(DENIED_VH);
+ assertEquals(Result.DEFER, _ruleSet.check(_testSubject, Operation.CREATE, ObjectType.EXCHANGE, new ObjectProperties(exchange)));
+ }
+
public void testExchangeCreate()
{
ObjectProperties properties = new ObjectProperties(_exchangeName);
diff --git a/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerSessionDelegate.java b/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerSessionDelegate.java
index 040be92ceb..999da2da6c 100644
--- a/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerSessionDelegate.java
+++ b/qpid/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerSessionDelegate.java
@@ -291,7 +291,7 @@ public class ServerSessionDelegate extends SessionDelegate
final VirtualHost virtualHost = getVirtualHost(ssn);
try
{
- virtualHost.getSecurityManager().authorisePublish(messageMetaData.isImmediate(), messageMetaData.getRoutingKey(), exchange.getName());
+ virtualHost.getSecurityManager().authorisePublish(messageMetaData.isImmediate(), messageMetaData.getRoutingKey(), exchange.getName(), virtualHost.getName());
}
catch (AccessControlException e)
{
diff --git a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQChannel.java b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQChannel.java
index baf5eceef7..7bde83cc99 100644
--- a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQChannel.java
+++ b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQChannel.java
@@ -303,9 +303,10 @@ public class AMQChannel<T extends AMQProtocolSession<T>>
public void setPublishFrame(MessagePublishInfo info, final MessageDestination e)
{
String routingKey = info.getRoutingKey() == null ? null : info.getRoutingKey().asString();
- SecurityManager securityManager = getVirtualHost().getSecurityManager();
+ VirtualHost virtualHost = getVirtualHost();
+ SecurityManager securityManager = virtualHost.getSecurityManager();
- securityManager.authorisePublish(info.isImmediate(), routingKey, e.getName());
+ securityManager.authorisePublish(info.isImmediate(), routingKey, e.getName(), virtualHost.getName());
_currentMessage = new IncomingMessage(info);
_currentMessage.setMessageDestination(e);
diff --git a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/handler/ConnectionOpenMethodHandler.java b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/handler/ConnectionOpenMethodHandler.java
index a29d56605a..1a29806f62 100644
--- a/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/handler/ConnectionOpenMethodHandler.java
+++ b/qpid/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/handler/ConnectionOpenMethodHandler.java
@@ -80,6 +80,8 @@ public class ConnectionOpenMethodHandler implements StateAwareMethodListener<Con
}
else
{
+ session.setVirtualHost(virtualHost);
+
// Check virtualhost access
try
{
@@ -95,7 +97,6 @@ public class ConnectionOpenMethodHandler implements StateAwareMethodListener<Con
throw body.getConnectionException(AMQConstant.CONNECTION_FORCED, "Virtual host '" + virtualHost.getName() + "' is not active");
}
- session.setVirtualHost(virtualHost);
// See Spec (0.8.2). Section 3.1.2 Virtual Hosts
if (session.getContextKey() == null)
diff --git a/qpid/java/broker-plugins/jdbc-provider-bone/src/main/java/resources/virtualhost/store/pool/bonecp/add.html b/qpid/java/broker-plugins/jdbc-provider-bone/src/main/java/resources/virtualhost/store/pool/bonecp/add.html
index 0a83bd9f6f..5b053849a3 100644
--- a/qpid/java/broker-plugins/jdbc-provider-bone/src/main/java/resources/virtualhost/store/pool/bonecp/add.html
+++ b/qpid/java/broker-plugins/jdbc-provider-bone/src/main/java/resources/virtualhost/store/pool/bonecp/add.html
@@ -20,7 +20,7 @@
<td class="tableContainer-labelCell" style="width: 300px;"><strong>Partition Count: </strong></td>
<td class="tableContainer-valueCell">
<input data-dojo-type="dijit/form/NumberSpinner" id="formAddVirtualHost.specific.store.pool.parititions"
- name="minConnectionsPerPartition" value="4" smallDelta="1" constraints="{min:1,max:1000,places:0}"/>
+ name="partitionCount" value="4" smallDelta="1" constraints="{min:1,max:1000,places:0}"/>
</td>
</tr>
<tr>
diff --git a/qpid/java/broker-plugins/management-http/pom.xml b/qpid/java/broker-plugins/management-http/pom.xml
index 4bfaf5e5d2..afb295f7cd 100644
--- a/qpid/java/broker-plugins/management-http/pom.xml
+++ b/qpid/java/broker-plugins/management-http/pom.xml
@@ -69,6 +69,12 @@
<type>zip</type>
</dependency>
+ <dependency>
+ <groupId>org.webjars</groupId>
+ <artifactId>cryptojs</artifactId>
+ <version>3.1.2</version>
+ </dependency>
+
<!-- test dependencies -->
<dependency>
<groupId>org.apache.qpid</groupId>
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/FileServlet.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/FileServlet.java
index 618aaed319..72e9bac29b 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/FileServlet.java
+++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/FileServlet.java
@@ -89,6 +89,10 @@ public class FileServlet extends HttpServlet
}
URL resourceURL = getClass().getResource(_resourcePathPrefix + filename);
+ if(resourceURL == null)
+ {
+ resourceURL = getClass().getResource("/META-INF" + _resourcePathPrefix + filename);
+ }
if(resourceURL != null)
{
response.setStatus(HttpServletResponse.SC_OK);
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java
index 0947ae2a89..b23f0cb168 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java
+++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/MessageServlet.java
@@ -485,10 +485,10 @@ public class MessageServlet extends AbstractServlet
}
- private void authorizeMethod(String methodName, VirtualHost host)
+ private void authorizeMethod(String methodName, VirtualHost<?> vhost)
{
- SecurityManager securityManager = host.getSecurityManager();
- securityManager.authoriseMethod(Operation.UPDATE, "VirtualHost.Queue", methodName);
+ SecurityManager securityManager = getBroker().getSecurityManager();
+ securityManager.authoriseMethod(Operation.UPDATE, "VirtualHost.Queue", methodName, vhost.getName());
}
}
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java
index 2ca67fadc9..af3973c7b3 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java
+++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java
@@ -59,7 +59,7 @@ public class SaslServlet extends AbstractServlet
private static final String ATTR_ID = "SaslServlet.ID";
private static final String ATTR_SASL_SERVER = "SaslServlet.SaslServer";
private static final String ATTR_EXPIRY = "SaslServlet.Expiry";
- private static final long SASL_EXCHANGE_EXPIRY = 1000L;
+ private static final long SASL_EXCHANGE_EXPIRY = 3000L;
public SaslServlet()
{
@@ -260,7 +260,17 @@ public class SaslServlet extends AbstractServlet
session.removeAttribute(ATTR_ID);
session.removeAttribute(ATTR_SASL_SERVER);
session.removeAttribute(ATTR_EXPIRY);
+ if(challenge != null && challenge.length != 0)
+ {
+ Map<String, Object> outputObject = new LinkedHashMap<String, Object>();
+ outputObject.put("challenge", new String(Base64.encodeBase64(challenge)));
+
+ final PrintWriter writer = response.getWriter();
+ ObjectMapper mapper = new ObjectMapper();
+ mapper.configure(SerializationConfig.Feature.INDENT_OUTPUT, true);
+ mapper.writeValue(writer, outputObject);
+ }
response.setStatus(HttpServletResponse.SC_OK);
}
else
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/sasl.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/sasl.js
index 2d99f886ed..a25375a669 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/sasl.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/authorization/sasl.js
@@ -18,8 +18,8 @@
* under the License.
*
*/
-define(["dojo/_base/xhr", "dojox/encoding/base64", "dojox/encoding/digests/_base", "dojox/encoding/digests/MD5"],
- function (xhr, base64, digestsBase, MD5) {
+define(["dojo/_base/xhr", "dojox/encoding/base64", "dojox/encoding/digests/_base", "dojox/encoding/digests/MD5", "dojox/uuid/generateRandomUuid", "dojo/request/script"],
+ function (xhr, base64, digestsBase, MD5, uuid, script) {
var encodeUTF8 = function encodeUTF8(str) {
var byteArray = [];
@@ -83,34 +83,32 @@ var saslPlain = function saslPlain(user, password, callbackFunction)
var saslCramMD5 = function saslCramMD5(user, password, saslMechanism, callbackFunction)
{
-
- // Using dojo.xhrGet, as very little information is being sent
- dojo.xhrPost({
- // The URL of the request
- url: "rest/sasl",
- content: {
- mechanism: saslMechanism
- },
- handleAs: "json",
- failOk: true
- }).then(function(data)
- {
-
- var challengeBytes = base64.decode(data.challenge);
- var wa=[];
- var bitLength = challengeBytes.length*8;
- for(var i=0; i<bitLength; i+=8)
+ dojo.xhrPost({
+ // The URL of the request
+ url: "rest/sasl",
+ content: {
+ mechanism: saslMechanism
+ },
+ handleAs: "json",
+ failOk: true
+ }).then(function(data)
{
- wa[i>>5] |= (challengeBytes[i/8] & 0xFF)<<(i%32);
- }
- var challengeStr = digestsBase.wordToString(wa).substring(0,challengeBytes.length);
- var digest = user + " " + MD5._hmac(challengeStr, password, digestsBase.outputTypes.Hex);
- var id = data.id;
+ var challengeBytes = base64.decode(data.challenge);
+ var wa=[];
+ var bitLength = challengeBytes.length*8;
+ for(var i=0; i<bitLength; i+=8)
+ {
+ wa[i>>5] |= (challengeBytes[i/8] & 0xFF)<<(i%32);
+ }
+ var challengeStr = digestsBase.wordToString(wa).substring(0,challengeBytes.length);
+
+ var digest = user + " " + MD5._hmac(challengeStr, password, digestsBase.outputTypes.Hex);
+ var id = data.id;
- var response = base64.encode(encodeUTF8( digest ));
+ var response = base64.encode(encodeUTF8( digest ));
- dojo.xhrPost({
+ dojo.xhrPost({
// The URL of the request
url: "rest/sasl",
content: {
@@ -121,20 +119,163 @@ var saslCramMD5 = function saslCramMD5(user, password, saslMechanism, callbackFu
failOk: true
}).then(callbackFunction, errorHandler);
- },
- function(error)
- {
- if(error.status == 403)
+ },
+ function(error)
{
- alert("Authentication Failed");
- }
- else
- {
- alert(error);
- }
- });
+ if(error.status == 403)
+ {
+ alert("Authentication Failed");
+ }
+ else
+ {
+ alert(error);
+ }
+ });
+
+
+
};
+ var saslScramSha1 = function saslScramSha1(user, password, saslMechanism, callbackFunction)
+ {
+
+ script.get("webjars/cryptojs/3.1.2/rollups/hmac-sha1.js").then( function()
+ {
+ script.get("webjars/cryptojs/3.1.2/components/enc-base64-min.js").then ( function()
+ {
+
+ var toBase64 = function toBase64( input )
+ {
+ var result = [];
+ for(var i = 0; i < input.length; i++)
+ {
+ result[i] = input.charCodeAt(i);
+ }
+ return base64.encode( result )
+ };
+
+ var fromBase64 = function fromBase64( input )
+ {
+ var decoded = base64.decode( input );
+ var result = "";
+ for(var i = 0; i < decoded.length; i++)
+ {
+ result+= String.fromCharCode(decoded[i]);
+ }
+ return result;
+ };
+
+ var xor = function xor(lhs, rhs) {
+ var words = [];
+ for(var i = 0; i < lhs.words.length; i++)
+ {
+ words.push(lhs.words[i]^rhs.words[i]);
+ }
+ return CryptoJS.lib.WordArray.create(words);
+ };
+
+ var hasNonAscii = function hasNonAscii(name) {
+ for(var i = 0; i < name.length; i++) {
+ if(name.charCodeAt(i) > 127) {
+ return true;
+ }
+ }
+ return false;
+ };
+
+ var generateSaltedPassword = function generateSaltedPassword(salt, password, iterationCount)
+ {
+ var hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA1, password);
+
+ hmac.update(salt);
+ hmac.update(CryptoJS.enc.Hex.parse("00000001"));
+
+ var result = hmac.finalize();
+ var previous = null;
+ for(var i = 1 ;i < iterationCount; i++)
+ {
+ hmac = CryptoJS.algo.HMAC.create(CryptoJS.algo.SHA1, password);
+ hmac.update( previous != null ? previous : result );
+ previous = hmac.finalize();
+ result = xor(result, previous);
+ }
+ return result;
+
+ };
+
+ GS2_HEADER = "n,,";
+
+ if(!hasNonAscii(user)) {
+
+ user = user.replace(/=/g, "=3D");
+ user = user.replace(/,/g, "=2C");
+
+ clientNonce = uuid();
+ clientFirstMessageBare = "n=" + user + ",r=" + clientNonce;
+ dojo.xhrPost({
+ // The URL of the request
+ url: "rest/sasl",
+ content: {
+ mechanism: saslMechanism,
+ response: toBase64(GS2_HEADER + clientFirstMessageBare)
+ },
+ handleAs: "json",
+ failOk: true
+ }).then(function (data) {
+ var serverFirstMessage = fromBase64(data.challenge);
+ var id = data.id;
+
+ var parts = serverFirstMessage.split(",");
+ nonce = parts[0].substring(2);
+ if (!nonce.substr(0, clientNonce.length) == clientNonce) {
+ alert("Authentication error - server nonce does not start with client nonce")
+ }
+ else {
+ var salt = CryptoJS.enc.Base64.parse(parts[1].substring(2));
+ var iterationCount = parts[2].substring(2);
+ var saltedPassword = generateSaltedPassword(salt, password, iterationCount)
+ var clientFinalMessageWithoutProof = "c=" + toBase64(GS2_HEADER) + ",r=" + nonce;
+ var authMessage = clientFirstMessageBare + "," + serverFirstMessage + "," + clientFinalMessageWithoutProof;
+ var clientKey = CryptoJS.HmacSHA1("Client Key", saltedPassword);
+ var storedKey = CryptoJS.SHA1(clientKey);
+ var clientSignature = CryptoJS.HmacSHA1(authMessage, storedKey);
+ var clientProof = xor(clientKey, clientSignature);
+ var serverKey = CryptoJS.HmacSHA1("Server Key", saltedPassword);
+ serverSignature = CryptoJS.HmacSHA1(authMessage, serverKey);
+ dojo.xhrPost({
+ // The URL of the request
+ url: "rest/sasl",
+ content: {
+ id: id,
+ response: toBase64(clientFinalMessageWithoutProof
+ + ",p=" + clientProof.toString(CryptoJS.enc.Base64))
+ },
+ handleAs: "json",
+ failOk: true
+ }).then(function (data) {
+ var serverFinalMessage = fromBase64(data.challenge);
+ if (serverSignature.toString(CryptoJS.enc.Base64) == serverFinalMessage.substring(2)) {
+ callbackFunction();
+ }
+ else {
+ errorHandler("Server signature did not match");
+ }
+
+
+ }, errorHandler);
+ }
+
+ }, errorHandler);
+ }
+ else
+ {
+ alert("Username '"+name+"' is invalid");
+ }
+
+ }, errorHandler);
+ }, errorHandler);
+ };
+
var containsMechanism = function containsMechanism(mechanisms, mech)
{
for (var i = 0; i < mechanisms.length; i++) {
@@ -157,7 +298,11 @@ SaslClient.authenticate = function(username, password, callbackFunction)
}).then(function(data)
{
var mechMap = data.mechanisms;
- if (containsMechanism(mechMap, "CRAM-MD5"))
+ if(containsMechanism(mechMap, "SCRAM-SHA-1"))
+ {
+ saslScramSha1(username, password, "SCRAM-SHA-1", callbackFunction)
+ }
+ else if (containsMechanism(mechMap, "CRAM-MD5"))
{
saslCramMD5(username, password, "CRAM-MD5", callbackFunction);
}
diff --git a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js
index 3d349830ac..6d83a68fb4 100644
--- a/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js
+++ b/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/common/util.js
@@ -140,7 +140,7 @@ define(["dojo/_base/xhr",
util.isProviderManagingUsers = function(type)
{
- return (type === "PlainPasswordFile" || type === "Base64MD5PasswordFile");
+ return (type === "PlainPasswordFile" || type === "Base64MD5PasswordFile" || type === "SCRAM-SHA1");
};
util.showSetAttributesDialog = function(attributeWidgetFactories, data, putURL, dialogTitle, appendNameToUrl)
diff --git a/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java b/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java
index 7b0a48cac1..5a7674d4fd 100644
--- a/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java
+++ b/qpid/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/MBeanInvocationHandlerImpl.java
@@ -60,15 +60,15 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler
private MBeanServer _mbs;
private final boolean _managementRightsInferAllAccess;
- private final Broker _broker;
+ private final Broker<?> _broker;
- MBeanInvocationHandlerImpl(Broker broker)
+ MBeanInvocationHandlerImpl(Broker<?> broker)
{
_managementRightsInferAllAccess = Boolean.valueOf(System.getProperty(BrokerProperties.PROPERTY_MANAGEMENT_RIGHTS_INFER_ALL_ACCESS, "true"));
_broker = broker;
}
- public static MBeanServerForwarder newProxyInstance(Broker broker)
+ public static MBeanServerForwarder newProxyInstance(Broker<?> broker)
{
final InvocationHandler handler = new MBeanInvocationHandlerImpl(broker);
final Class<?>[] interfaces = new Class[] { MBeanServerForwarder.class };
@@ -195,28 +195,23 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler
String methodName;
// Get the component, type and impact, which may be null
String type = getType(method, args);
- String vhost = getVirtualHost(method, args);
+ String virtualHostName = getVirtualHost(method, args);
int impact = getImpact(method, args);
- // Get the security manager for the virtual host (if set)
- SecurityManager security;
- if (vhost == null)
+ if (virtualHostName != null)
{
- security = _broker.getSecurityManager();
- }
- else
- {
- VirtualHost virtualHost = _broker.findVirtualHostByName(vhost);
+ VirtualHost<?> virtualHost = _broker.findVirtualHostByName(virtualHostName);
if (virtualHost == null)
{
- throw new IllegalArgumentException("Virtual host with name '" + vhost + "' is not found.");
+ throw new IllegalArgumentException("Virtual host with name '" + virtualHostName + "' is not found.");
}
- security = virtualHost.getSecurityManager();
}
methodName = getMethodName(method, args);
Operation operation = (isAccessMethod(methodName) || impact == MBeanOperationInfo.INFO) ? Operation.ACCESS : Operation.UPDATE;
- security.authoriseMethod(operation, type, methodName);
+
+ SecurityManager security = _broker.getSecurityManager();
+ security.authoriseMethod(operation, type, methodName, virtualHostName);
if (_managementRightsInferAllAccess)
{