diff options
author | Robert Godfrey <rgodfrey@apache.org> | 2014-03-06 00:14:23 +0000 |
---|---|---|
committer | Robert Godfrey <rgodfrey@apache.org> | 2014-03-06 00:14:23 +0000 |
commit | c6164f7c6a0c605535592f280dd8ecbb82c4c5ec (patch) | |
tree | e370d6e5b35002c9800c0178d9579da3cfea4571 | |
parent | 03e86eb4e4e93e989b692193ed8f3116e07695f2 (diff) | |
download | qpid-python-c6164f7c6a0c605535592f280dd8ecbb82c4c5ec.tar.gz |
QPID-5606 : [Java Broker] add connection principal to HTTP and JMX management actions
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk@1574728 13f79535-47bb-0310-9956-ffa450edef68
7 files changed, 210 insertions, 4 deletions
diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/connection/ConnectionPrincipal.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/connection/ConnectionPrincipal.java index e459b5df80..82ae9f6454 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/connection/ConnectionPrincipal.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/connection/ConnectionPrincipal.java @@ -21,10 +21,11 @@ package org.apache.qpid.server.connection; import org.apache.qpid.server.protocol.AMQConnectionModel; +import org.apache.qpid.server.security.auth.SocketConnectionPrincipal; -import java.security.Principal; +import java.net.SocketAddress; -public class ConnectionPrincipal implements Principal +public class ConnectionPrincipal implements SocketConnectionPrincipal { private final AMQConnectionModel _connection; @@ -39,6 +40,12 @@ public class ConnectionPrincipal implements Principal return _connection.getRemoteAddressString(); } + @Override + public SocketAddress getRemoteAddress() + { + return _connection.getRemoteAddress(); + } + public AMQConnectionModel getConnection() { return _connection; diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/SocketConnectionPrincipal.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/SocketConnectionPrincipal.java new file mode 100644 index 0000000000..c3627d6274 --- /dev/null +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/SocketConnectionPrincipal.java @@ -0,0 +1,29 @@ +/* + * + * 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.auth; + +import java.net.SocketAddress; +import java.security.Principal; + +public interface SocketConnectionPrincipal extends Principal +{ + SocketAddress getRemoteAddress(); +} diff --git a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/jmx/JMXPasswordAuthenticator.java b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/jmx/JMXPasswordAuthenticator.java index 1a23de0821..94de7754f6 100644 --- a/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/jmx/JMXPasswordAuthenticator.java +++ b/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/jmx/JMXPasswordAuthenticator.java @@ -20,13 +20,18 @@ */ package org.apache.qpid.server.security.auth.jmx; +import java.net.InetSocketAddress; import java.net.SocketAddress; +import java.rmi.server.RemoteServer; +import java.rmi.server.ServerNotActiveException; +import java.security.Principal; import java.security.PrivilegedAction; import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.security.SecurityManager; import org.apache.qpid.server.security.SubjectCreator; import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; +import org.apache.qpid.server.security.auth.SocketConnectionPrincipal; import org.apache.qpid.server.security.auth.SubjectAuthenticationResult; import javax.management.remote.JMXAuthenticator; @@ -108,7 +113,24 @@ public class JMXPasswordAuthenticator implements JMXAuthenticator } else if (AuthenticationStatus.SUCCESS.equals(result.getStatus())) { - return result.getSubject(); + final Subject originalSubject = result.getSubject(); + Subject subject; + + try + { + String clientHost = RemoteServer.getClientHost(); + subject = new Subject(false, + originalSubject.getPrincipals(), + originalSubject.getPublicCredentials(), + originalSubject.getPrivateCredentials()); + subject.getPrincipals().add(new JMSConnectionPrincipal(clientHost)); + subject.setReadOnly(); + } + catch(ServerNotActiveException e) + { + subject = originalSubject; + } + return subject; } else { @@ -131,4 +153,53 @@ public class JMXPasswordAuthenticator implements JMXAuthenticator } + private static class JMSConnectionPrincipal implements SocketConnectionPrincipal + { + private final InetSocketAddress _address; + + public JMSConnectionPrincipal(final String host) + { + _address = new InetSocketAddress(host,0); + } + + @Override + public SocketAddress getRemoteAddress() + { + return _address; + } + + @Override + public String getName() + { + return _address.toString(); + } + + @Override + public boolean equals(final Object o) + { + if (this == o) + { + return true; + } + if (o == null || getClass() != o.getClass()) + { + return false; + } + + final JMSConnectionPrincipal that = (JMSConnectionPrincipal) o; + + if (!_address.equals(that._address)) + { + return false; + } + + return true; + } + + @Override + public int hashCode() + { + return _address.hashCode(); + } + } }
\ No newline at end of file diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java index fae2dafd82..5d39b3c0c1 100644 --- a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java +++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java @@ -40,6 +40,7 @@ import org.apache.commons.codec.binary.Base64; import org.apache.qpid.server.logging.LogActor; import org.apache.qpid.server.logging.actors.CurrentActor; import org.apache.qpid.server.logging.actors.HttpManagementActor; +import org.apache.qpid.server.management.plugin.servlet.ServletConnectionPrincipal; import org.apache.qpid.server.management.plugin.session.LoginLogoutReporter; import org.apache.qpid.server.model.AuthenticationProvider; import org.apache.qpid.server.model.Broker; @@ -107,6 +108,15 @@ public class HttpManagementUtil { throw new SecurityException("Only authenticated users can access the management interface"); } + + Subject original = subject; + subject = new Subject(false, + original.getPrincipals(), + original.getPublicCredentials(), + original.getPrivateCredentials()); + subject.getPrincipals().add(new ServletConnectionPrincipal(request)); + subject.setReadOnly(); + LogActor actor = createHttpManagementActor(broker, request); assertManagementAccess(broker.getSecurityManager(), subject, actor); diff --git a/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/ServletConnectionPrincipal.java b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/ServletConnectionPrincipal.java new file mode 100644 index 0000000000..0925e2b088 --- /dev/null +++ b/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/ServletConnectionPrincipal.java @@ -0,0 +1,77 @@ +/* + * + * 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.management.plugin.servlet; + +import org.apache.qpid.server.security.auth.SocketConnectionPrincipal; + +import javax.servlet.ServletRequest; +import java.net.InetSocketAddress; +import java.net.SocketAddress; + +public class ServletConnectionPrincipal implements SocketConnectionPrincipal +{ + private final InetSocketAddress _address; + + public ServletConnectionPrincipal(ServletRequest request) + { + _address = new InetSocketAddress(request.getRemoteHost(), request.getRemotePort()); + } + + @Override + public SocketAddress getRemoteAddress() + { + return _address; + } + + @Override + public String getName() + { + return _address.toString(); + } + + @Override + public boolean equals(final Object o) + { + if (this == o) + { + return true; + } + if (o == null || getClass() != o.getClass()) + { + return false; + } + + final ServletConnectionPrincipal that = (ServletConnectionPrincipal) o; + + if (!_address.equals(that._address)) + { + return false; + } + + return true; + } + + @Override + public int hashCode() + { + return _address.hashCode(); + } +} 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 5441dc95c4..b59e9bc04d 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 @@ -21,6 +21,7 @@ package org.apache.qpid.server.management.plugin.servlet.rest; import org.apache.commons.codec.binary.Base64; +import org.apache.qpid.server.management.plugin.servlet.ServletConnectionPrincipal; import org.apache.qpid.server.util.ConnectionScopedRuntimeException; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.SerializationConfig; @@ -237,7 +238,13 @@ public class SaslServlet extends AbstractServlet if(saslServer.isComplete()) { - Subject subject = subjectCreator.createSubjectWithGroups(saslServer.getAuthorizationID()); + Subject originalSubject = subjectCreator.createSubjectWithGroups(saslServer.getAuthorizationID()); + Subject subject = new Subject(false, + originalSubject.getPrincipals(), + originalSubject.getPublicCredentials(), + originalSubject.getPrivateCredentials()); + subject.getPrincipals().add(new ServletConnectionPrincipal(request)); + subject.setReadOnly(); Broker broker = getBroker(); LogActor actor = HttpManagementUtil.getOrCreateAndCacheLogActor(request, broker); @@ -296,4 +303,5 @@ public class SaslServlet extends AbstractServlet } return subject; } + } 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 f959977d1f..a38addae7b 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 @@ -39,11 +39,14 @@ import javax.management.MBeanServer; import javax.management.ObjectName; import javax.management.RuntimeErrorException; import javax.management.remote.MBeanServerForwarder; +import javax.management.remote.rmi.RMIServer; import javax.security.auth.Subject; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.lang.reflect.Proxy; +import java.rmi.server.RemoteServer; +import java.rmi.server.ServerNotActiveException; import java.security.AccessControlContext; import java.security.AccessController; import java.security.PrivilegedAction; @@ -236,6 +239,7 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler { try { + return Subject.doAs(SecurityManager.SYSTEM, new PrivilegedExceptionAction<Object>() { @Override |