[jboss-cvs] JBoss Messaging SVN: r7934 - in branches/Branch_1_4: integration/EAP4/src/main/org/jboss/jms/server/endpoint and 10 other directories.
jboss-cvs-commits at lists.jboss.org
jboss-cvs-commits at lists.jboss.org
Tue Feb 2 09:27:41 EST 2010
Author: gaohoward
Date: 2010-02-02 09:27:40 -0500 (Tue, 02 Feb 2010)
New Revision: 7934
Added:
branches/Branch_1_4/integration/EAP4/src/main/org/jboss/jms/server/container/SecurityActions.java
branches/Branch_1_4/integration/EAP4/src/main/org/jboss/jms/server/container/SecurityAspect.java
branches/Branch_1_4/integration/EAP4/src/main/org/jboss/jms/server/endpoint/SecurityActions.java
branches/Branch_1_4/integration/EAP4/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java
branches/Branch_1_4/integration/EAP5/src/main/
branches/Branch_1_4/integration/EAP5/src/main/org/
branches/Branch_1_4/integration/EAP5/src/main/org/jboss/
branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/
branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/
branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/container/
branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/container/SecurityActions.java
branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/container/SecurityAspect.java
branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/endpoint/
branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/endpoint/SecurityActions.java
branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java
Removed:
branches/Branch_1_4/src/main/org/jboss/jms/server/container/SecurityActions.java
branches/Branch_1_4/src/main/org/jboss/jms/server/container/SecurityAspect.java
branches/Branch_1_4/src/main/org/jboss/jms/server/endpoint/SecurityActions.java
branches/Branch_1_4/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java
Log:
JBMESSAGING-1787
Moving version specific sources
Copied: branches/Branch_1_4/integration/EAP4/src/main/org/jboss/jms/server/container/SecurityActions.java (from rev 7932, branches/Branch_1_4/src/main/org/jboss/jms/server/container/SecurityActions.java)
===================================================================
--- branches/Branch_1_4/integration/EAP4/src/main/org/jboss/jms/server/container/SecurityActions.java (rev 0)
+++ branches/Branch_1_4/integration/EAP4/src/main/org/jboss/jms/server/container/SecurityActions.java 2010-02-02 14:27:40 UTC (rev 7934)
@@ -0,0 +1,133 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jms.server.container;
+
+import java.security.AccessController;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+
+import javax.security.auth.Subject;
+
+import org.jboss.security.SecurityAssociation;
+
+
+/** A collection of privileged actions for this package
+ * @author Scott.Stark at jboss.org
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:anil.saldhana at jboss.com">anil saldhana</a>
+ * @version $Revison: 1.0$
+ */
+class SecurityActions
+{
+ interface PrincipalInfoAction
+ {
+ PrincipalInfoAction PRIVILEGED = new PrincipalInfoAction()
+ {
+ public void push(final Principal principal, final Object credential,
+ final Subject subject)
+ {
+ AccessController.doPrivileged(
+ new PrivilegedAction()
+ {
+ public Object run()
+ {
+ SecurityAssociation.pushSubjectContext(subject, principal, credential);
+ return null;
+ }
+ }
+ );
+ }
+ public void dup()
+ {
+ AccessController.doPrivileged(
+ new PrivilegedAction()
+ {
+ public Object run()
+ {
+ SecurityAssociation.dupSubjectContext();
+ return null;
+ }
+ }
+ );
+ }
+ public void pop()
+ {
+ AccessController.doPrivileged(
+ new PrivilegedAction()
+ {
+ public Object run()
+ {
+ SecurityAssociation.popSubjectContext();
+ return null;
+ }
+ }
+ );
+ }
+ };
+
+ PrincipalInfoAction NON_PRIVILEGED = new PrincipalInfoAction()
+ {
+ public void push(Principal principal, Object credential, Subject subject)
+ {
+ SecurityAssociation.pushSubjectContext(subject, principal, credential);
+ }
+ public void dup()
+ {
+ SecurityAssociation.dupSubjectContext();
+ }
+ public void pop()
+ {
+ SecurityAssociation.popSubjectContext();
+ }
+ };
+
+ void push(Principal principal, Object credential, Subject subject);
+ void dup();
+ void pop();
+ }
+
+ static void pushSubjectContext(Principal principal, Object credential,
+ Subject subject)
+ {
+ if(System.getSecurityManager() == null)
+ {
+ PrincipalInfoAction.NON_PRIVILEGED.push(principal, credential, subject);
+ }
+ else
+ {
+ PrincipalInfoAction.PRIVILEGED.push(principal, credential, subject);
+ }
+ }
+
+ static void popSubjectContext()
+ {
+ if(System.getSecurityManager() == null)
+ {
+ PrincipalInfoAction.NON_PRIVILEGED.pop();
+ }
+ else
+ {
+ PrincipalInfoAction.PRIVILEGED.pop();
+ }
+ }
+ }
Copied: branches/Branch_1_4/integration/EAP4/src/main/org/jboss/jms/server/container/SecurityAspect.java (from rev 7932, branches/Branch_1_4/src/main/org/jboss/jms/server/container/SecurityAspect.java)
===================================================================
--- branches/Branch_1_4/integration/EAP4/src/main/org/jboss/jms/server/container/SecurityAspect.java (rev 0)
+++ branches/Branch_1_4/integration/EAP4/src/main/org/jboss/jms/server/container/SecurityAspect.java 2010-02-02 14:27:40 UTC (rev 7934)
@@ -0,0 +1,353 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jms.server.container;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.jms.Destination;
+import javax.jms.JMSSecurityException;
+import javax.jms.Message;
+
+import org.jboss.aop.joinpoint.Invocation;
+import org.jboss.aop.joinpoint.MethodInvocation;
+import org.jboss.jms.destination.JBossDestination;
+import org.jboss.jms.message.JBossMessage;
+import org.jboss.jms.server.SecurityStore;
+import org.jboss.jms.server.endpoint.ServerConnectionEndpoint;
+import org.jboss.jms.server.endpoint.ServerConsumerEndpoint;
+import org.jboss.jms.server.endpoint.ServerSessionEndpoint;
+import org.jboss.jms.server.endpoint.advised.ConnectionAdvised;
+import org.jboss.jms.server.endpoint.advised.ConsumerAdvised;
+import org.jboss.jms.server.endpoint.advised.SessionAdvised;
+import org.jboss.jms.server.security.CheckType;
+import org.jboss.jms.server.security.SecurityMetadata;
+import org.jboss.jms.tx.ClientTransaction;
+import org.jboss.jms.tx.TransactionRequest;
+import org.jboss.logging.Logger;
+
+/**
+ * This aspect enforces the JBossMessaging JMS security policy.
+ *
+ * This aspect is PER_INSTANCE
+ *
+ * For performance reasons we cache access rights in the interceptor for a maximum of
+ * INVALIDATION_INTERVAL milliseconds.
+ * This is because we don't want to do a full authentication and authorization on every send,
+ * for example, since this will drastically reduce performance.
+ * This means any changes to security data won't be reflected until INVALIDATION_INTERVAL
+ * milliseconds later.
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:ovidiu at feodorov.com">Ovidiu Feodorov</a>
+ * @version <tt>$Revision 1.1 $</tt>
+ *
+ * $Id$
+ */
+public class SecurityAspect
+{
+ // Constants -----------------------------------------------------
+
+ private static final Logger log = Logger.getLogger(SecurityAspect.class);
+
+ // Static --------------------------------------------------------
+
+ // Attributes ----------------------------------------------------
+
+ private boolean trace = log.isTraceEnabled();
+
+ private Set readCache;
+
+ private Set writeCache;
+
+ private Set createCache;
+
+ //TODO Make this configurable
+ private static final long INVALIDATION_INTERVAL = 15000;
+
+ private long lastCheck;
+
+ // Constructors --------------------------------------------------
+
+ // Public --------------------------------------------------------
+ public SecurityAspect()
+ {
+ readCache = new HashSet();
+
+ writeCache = new HashSet();
+
+ createCache = new HashSet();
+ }
+
+ public Object handleCreateConsumerDelegate(Invocation invocation) throws Throwable
+ {
+ MethodInvocation mi = (MethodInvocation)invocation;
+
+ // read permission required on the destination
+ Destination dest = (Destination)mi.getArguments()[0];
+
+ SessionAdvised del = (SessionAdvised)invocation.getTargetObject();
+ ServerSessionEndpoint sess = (ServerSessionEndpoint)del.getEndpoint();
+
+ check(dest, CheckType.READ, sess.getConnectionEndpoint());
+
+ // if creating a durable subscription then need create permission
+
+ String subscriptionName = (String)mi.getArguments()[3];
+ if (subscriptionName != null)
+ {
+ // durable
+ check(dest, CheckType.CREATE, sess.getConnectionEndpoint());
+ }
+
+ return invocation.invokeNext();
+ }
+
+ public Object handleCreateBrowserDelegate(Invocation invocation) throws Throwable
+ {
+ // read permission required on the destination
+
+ MethodInvocation mi = (MethodInvocation)invocation;
+
+ Destination dest = (Destination)mi.getArguments()[0];
+
+ SessionAdvised del = (SessionAdvised)invocation.getTargetObject();
+ ServerSessionEndpoint sess = (ServerSessionEndpoint)del.getEndpoint();
+
+ check(dest, CheckType.READ, sess.getConnectionEndpoint());
+
+ return invocation.invokeNext();
+ }
+
+ public Object handleSend(Invocation invocation) throws Throwable
+ {
+ // anonymous producer - if destination is not null then write permissions required
+
+ MethodInvocation mi = (MethodInvocation)invocation;
+
+ Message m = (Message)mi.getArguments()[0];
+ Destination dest = m.getJMSDestination();
+
+ SessionAdvised del = (SessionAdvised)invocation.getTargetObject();
+ ServerSessionEndpoint se = (ServerSessionEndpoint)del.getEndpoint();
+ ServerConnectionEndpoint ce = se.getConnectionEndpoint();
+
+ check(dest, CheckType.WRITE, ce);
+
+ return invocation.invokeNext();
+ }
+
+
+ // An aspect over ConnectionAdvised
+ public Object handleSendTransaction(Invocation invocation) throws Throwable
+ {
+ ConnectionAdvised del = (ConnectionAdvised)invocation.getTargetObject();
+ ServerConnectionEndpoint ce = (ServerConnectionEndpoint)del.getEndpoint();
+
+ MethodInvocation mi = (MethodInvocation)invocation;
+
+ TransactionRequest t = (TransactionRequest)mi.getArguments()[0];
+
+ ClientTransaction txState = t.getState();
+
+ if (txState != null)
+ {
+ // distinct list of destinations...
+ HashSet destinations = new HashSet();
+
+ for (Iterator i = txState.getSessionStates().iterator(); i.hasNext(); )
+ {
+ ClientTransaction.SessionTxState sessionState = (ClientTransaction.SessionTxState)i.next();
+ for (Iterator j = sessionState.getMsgs().iterator(); j.hasNext(); )
+ {
+ JBossMessage message = (JBossMessage)j.next();
+ destinations.add(message.getJMSDestination());
+ }
+ }
+ for (Iterator iterDestinations = destinations.iterator();iterDestinations.hasNext();)
+ {
+ Destination destination = (Destination) iterDestinations.next();
+ check(destination, CheckType.WRITE, ce);
+ }
+
+ }
+
+ return invocation.invokeNext();
+ }
+
+
+
+ protected void checkConsumerAccess(Invocation invocation) throws Throwable
+ {
+ ConsumerAdvised del = (ConsumerAdvised)invocation.getTargetObject();
+ ServerConsumerEndpoint cons = (ServerConsumerEndpoint)del.getEndpoint();
+ ServerConnectionEndpoint conn = cons.getSessionEndpoint().getConnectionEndpoint();
+ JBossDestination dest = cons.getDestination();
+
+ check(dest, CheckType.READ, conn);
+ }
+
+ // Package protected ---------------------------------------------
+
+ // Protected -----------------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ private boolean checkCached(Destination dest, CheckType checkType)
+ {
+ long now = System.currentTimeMillis();
+
+ boolean granted = false;
+
+ if (now - lastCheck > INVALIDATION_INTERVAL)
+ {
+ readCache.clear();
+
+ writeCache.clear();
+
+ createCache.clear();
+ }
+ else
+ {
+ switch (checkType.type)
+ {
+ case CheckType.TYPE_READ:
+ {
+ granted = readCache.contains(dest);
+ break;
+ }
+ case CheckType.TYPE_WRITE:
+ {
+ granted = writeCache.contains(dest);
+ break;
+ }
+ case CheckType.TYPE_CREATE:
+ {
+ granted = createCache.contains(dest);
+ break;
+ }
+ default:
+ {
+ throw new IllegalArgumentException("Invalid checkType:" + checkType);
+ }
+ }
+ }
+
+ lastCheck = now;
+
+ return granted;
+ }
+
+ private void check(Destination dest, CheckType checkType, ServerConnectionEndpoint conn)
+ throws JMSSecurityException
+ {
+ JBossDestination jbd = (JBossDestination)dest;
+
+ if (jbd.isTemporary())
+ {
+ if (trace) { log.trace("skipping permission check on temporary destination " + dest); }
+ return;
+ }
+
+ if (trace) { log.trace("checking access permissions to " + dest); }
+
+ if (checkCached(dest, checkType))
+ {
+ // OK
+ return;
+ }
+
+ boolean isQueue = jbd.isQueue();
+ String name = jbd.getName();
+
+ SecurityStore sm = conn.getSecurityManager();
+ SecurityMetadata securityMetadata = sm.getSecurityMetadata(isQueue, name);
+
+ if (securityMetadata == null)
+ {
+ throw new JMSSecurityException("No security configuration avaliable for " + name);
+ }
+
+ // Authenticate. Successful autentication will place a new SubjectContext on thread local,
+ // which will be used in the authorization process. However, we need to make sure we clean up
+ // thread local immediately after we used the information, otherwise some other people
+ // security my be screwed up, on account of thread local security stack being corrupted.
+
+ sm.authenticate(conn.getUsername(), conn.getPassword());
+
+ // Authorize
+ Set principals = checkType == CheckType.READ ? securityMetadata.getReadPrincipals() :
+ checkType == CheckType.WRITE ? securityMetadata.getWritePrincipals() :
+ securityMetadata.getCreatePrincipals();
+ try
+ {
+ if (!sm.authorize(conn.getUsername(), principals, checkType))
+ {
+ String msg = "User: " + conn.getUsername() +
+ " is not authorized to " +
+ (checkType == CheckType.READ ? "read from" :
+ checkType == CheckType.WRITE ? "write to" : "create durable sub on") +
+ " destination " + name;
+
+ throw new JMSSecurityException(msg);
+ }
+ }
+ finally
+ {
+ // pop the Messaging SecurityContext, it did its job
+ SecurityActions.popSubjectContext();
+ }
+
+ // if we get here we're granted, add to the cache
+
+ switch (checkType.type)
+ {
+ case CheckType.TYPE_READ:
+ {
+ readCache.add(dest);
+ break;
+ }
+ case CheckType.TYPE_WRITE:
+ {
+ writeCache.add(dest);
+ break;
+ }
+ case CheckType.TYPE_CREATE:
+ {
+ createCache.add(dest);
+ break;
+ }
+ default:
+ {
+ throw new IllegalArgumentException("Invalid checkType:" + checkType);
+ }
+ }
+ }
+
+ // Inner classes -------------------------------------------------
+
+}
+
+
+
+
Copied: branches/Branch_1_4/integration/EAP4/src/main/org/jboss/jms/server/endpoint/SecurityActions.java (from rev 7932, branches/Branch_1_4/src/main/org/jboss/jms/server/endpoint/SecurityActions.java)
===================================================================
--- branches/Branch_1_4/integration/EAP4/src/main/org/jboss/jms/server/endpoint/SecurityActions.java (rev 0)
+++ branches/Branch_1_4/integration/EAP4/src/main/org/jboss/jms/server/endpoint/SecurityActions.java 2010-02-02 14:27:40 UTC (rev 7934)
@@ -0,0 +1,187 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jms.server.endpoint;
+
+import java.security.AccessController;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+
+import javax.security.auth.Subject;
+
+import org.jboss.security.SecurityAssociation;
+
+/** A collection of privileged actions for this package
+ * @author Scott.Stark at jboss.org
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @author tim.fox at jboss.com
+ * @author anil.saldhana at jboss.com
+ * @version $Revison: 1.0$
+ */
+class SecurityActions
+{
+ interface PrincipalInfoAction
+ {
+ PrincipalInfoAction PRIVILEGED = new PrincipalInfoAction()
+ {
+ public void push(final Principal principal, final Object credential, final Subject subject)
+ {
+ AccessController.doPrivileged(new PrivilegedAction<Object>()
+ {
+ public Object run()
+ {
+ SecurityAssociation.pushSubjectContext(subject, principal, credential);
+ return null;
+ }
+ });
+ }
+
+ public void dup()
+ {
+ AccessController.doPrivileged(new PrivilegedAction<Object>()
+ {
+ public Object run()
+ {
+ SecurityAssociation.dupSubjectContext();
+ return null;
+ }
+ });
+ }
+
+ public void pop()
+ {
+ AccessController.doPrivileged(new PrivilegedAction<Object>()
+ {
+ public Object run()
+ {
+ SecurityAssociation.popSubjectContext();
+ return null;
+ }
+ });
+ }
+ };
+
+ PrincipalInfoAction NON_PRIVILEGED = new PrincipalInfoAction()
+ {
+ public void push(Principal principal, Object credential, Subject subject)
+ {
+ SecurityAssociation.pushSubjectContext(subject, principal, credential);
+ }
+
+ public void dup()
+ {
+ SecurityAssociation.dupSubjectContext();
+ }
+
+ public void pop()
+ {
+ SecurityAssociation.popSubjectContext();
+ }
+ };
+
+ void push(Principal principal, Object credential, Subject subject);
+
+ void dup();
+
+ void pop();
+ }
+
+ static void pushSubjectContext(Principal principal, Object credential, Subject subject)
+ {
+ if (System.getSecurityManager() == null)
+ {
+ PrincipalInfoAction.NON_PRIVILEGED.push(principal, credential, subject);
+ }
+ else
+ {
+ PrincipalInfoAction.PRIVILEGED.push(principal, credential, subject);
+ }
+ }
+
+ static void popSubjectContext()
+ {
+ if (System.getSecurityManager() == null)
+ {
+ PrincipalInfoAction.NON_PRIVILEGED.pop();
+ }
+ else
+ {
+ PrincipalInfoAction.PRIVILEGED.pop();
+ }
+ }
+
+ static ClassLoader getTCL()
+ {
+ if (System.getSecurityManager() == null)
+ {
+ return Thread.currentThread().getContextClassLoader();
+ }
+ else
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
+ {
+ public ClassLoader run()
+ {
+ return Thread.currentThread().getContextClassLoader();
+ }
+ });
+ }
+ }
+
+ static ClassLoader getClassLoader(final Class<?> clazz)
+ {
+ if (System.getSecurityManager() == null)
+ {
+ return clazz.getClassLoader();
+ }
+ else
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
+ {
+ public ClassLoader run()
+ {
+ return clazz.getClassLoader();
+ }
+ });
+ }
+
+ }
+
+ static void setTCL(final ClassLoader tcl)
+ {
+ if (System.getSecurityManager() == null)
+ {
+ Thread.currentThread().setContextClassLoader(tcl);
+ }
+ else
+ {
+ AccessController.doPrivileged(new PrivilegedAction<Object>()
+ {
+ public Object run()
+ {
+ Thread.currentThread().setContextClassLoader(tcl);
+ return null;
+ }
+ });
+ }
+ }
+
+}
Copied: branches/Branch_1_4/integration/EAP4/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java (from rev 7932, branches/Branch_1_4/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java)
===================================================================
--- branches/Branch_1_4/integration/EAP4/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java (rev 0)
+++ branches/Branch_1_4/integration/EAP4/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java 2010-02-02 14:27:40 UTC (rev 7934)
@@ -0,0 +1,421 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jms.server.endpoint;
+
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jms.JMSException;
+
+import org.jboss.aop.AspectManager;
+import org.jboss.jms.client.delegate.ClientConnectionDelegate;
+import org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate;
+import org.jboss.jms.delegate.ConnectionFactoryEndpoint;
+import org.jboss.jms.delegate.CreateConnectionResult;
+import org.jboss.jms.delegate.TopologyResult;
+import org.jboss.jms.server.ServerPeer;
+import org.jboss.jms.server.connectionfactory.JNDIBindings;
+import org.jboss.jms.server.endpoint.advised.ConnectionAdvised;
+import org.jboss.jms.wireformat.ConnectionFactoryUpdate;
+import org.jboss.jms.wireformat.Dispatcher;
+import org.jboss.logging.Logger;
+import org.jboss.messaging.util.ConcurrentHashSet;
+import org.jboss.messaging.util.ExceptionUtil;
+import org.jboss.remoting.callback.Callback;
+import org.jboss.remoting.callback.InvokerCallbackHandler;
+import org.jboss.remoting.callback.ServerInvokerCallbackHandler;
+import org.jboss.security.SecurityAssociation;
+
+/**
+ * Concrete implementation of ConnectionFactoryEndpoint
+ *
+ * @author <a href="mailto:ovidiu at feodorov.com">Ovidiu Feodorov</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision$</tt>
+ *
+ * $Id$
+ */
+public class ServerConnectionFactoryEndpoint implements ConnectionFactoryEndpoint
+{
+ // Constants ------------------------------------------------------------------------------------
+
+ private static final Logger log = Logger.getLogger(ServerConnectionFactoryEndpoint.class);
+
+ // Static ---------------------------------------------------------------------------------------
+
+ // Attributes -----------------------------------------------------------------------------------
+
+ private ServerPeer serverPeer;
+
+ private String clientID;
+
+ private String uniqueName;
+
+ private String id;
+
+ private JNDIBindings jndiBindings;
+
+ private int prefetchSize;
+
+ private int defaultTempQueueFullSize;
+
+ private int defaultTempQueuePageSize;
+
+ private int defaultTempQueueDownCacheSize;
+
+ private int dupsOKBatchSize;
+
+ private boolean supportsFailover;
+
+ private boolean slowConsumers;
+
+ /** Cluster Topology on ClusteredConnectionFactories
+ Information to failover to other connections on clients **/
+ private ClientConnectionFactoryDelegate[] delegates;
+
+ /** Cluster Topology on ClusteredConnectionFactories
+ Information to failover to other connections on clients **/
+ private Map failoverMap;
+
+ private Set<InvokerCallbackHandler> handlers = new ConcurrentHashSet<InvokerCallbackHandler>();
+
+
+ // Constructors ---------------------------------------------------------------------------------
+
+ /**
+ * @param jndiBindings - names under which the corresponding JBossConnectionFactory is bound in
+ * JNDI.
+ */
+ public ServerConnectionFactoryEndpoint(String uniqueName, String id, ServerPeer serverPeer,
+ String defaultClientID,
+ JNDIBindings jndiBindings,
+ int preFetchSize,
+ boolean slowConsumers,
+ int defaultTempQueueFullSize,
+ int defaultTempQueuePageSize,
+ int defaultTempQueueDownCacheSize,
+ int dupsOKBatchSize,
+ boolean supportsFailover)
+ {
+ this.uniqueName = uniqueName;
+ this.serverPeer = serverPeer;
+ this.clientID = defaultClientID;
+ this.id = id;
+ this.jndiBindings = jndiBindings;
+ this.prefetchSize = preFetchSize;
+ this.defaultTempQueueFullSize = defaultTempQueueFullSize;
+ this.defaultTempQueuePageSize = defaultTempQueuePageSize;
+ this.defaultTempQueueDownCacheSize = defaultTempQueueDownCacheSize;
+ this.dupsOKBatchSize = dupsOKBatchSize;
+ this.supportsFailover = supportsFailover;
+ this.slowConsumers = slowConsumers;
+ if (slowConsumers)
+ {
+ this.prefetchSize = 1;
+ }
+ }
+
+ // ConnectionFactoryDelegate implementation -----------------------------------------------------
+
+ public CreateConnectionResult createConnectionDelegate(String username,
+ String password,
+ int failedNodeID)
+
+ throws JMSException
+ {
+ //This is never called directly
+ throw new IllegalStateException("createConnectionDelegate should never be called directly");
+ }
+
+ /**
+ * @param failedNodeID - zero or positive values mean connection creation attempt is result of
+ * failover. -1 are ignored (mean regular connection creation attempt).
+ */
+ public CreateConnectionResult createConnectionDelegate(String username,
+ String password,
+ int failedNodeID,
+ String remotingSessionID,
+ String clientVMID,
+ byte versionToUse,
+ ServerInvokerCallbackHandler callbackHandler)
+ throws JMSException
+ {
+ try
+ {
+ if (failedNodeID == -1)
+ {
+ // Just a standard createConnection
+ ClientConnectionDelegate cd =
+ createConnectionDelegateInternal(username, password, failedNodeID,
+ remotingSessionID, clientVMID,
+ versionToUse,
+ callbackHandler);
+ return new CreateConnectionResult(cd);
+ }
+ else
+ {
+ log.trace(this + " received client-side failover request. Creating failover "+
+ "connection to replace connection to failed node " + failedNodeID);
+
+ // Wait for server side failover to complete
+ int failoverNodeID = serverPeer.getFailoverWaiter().waitForFailover(failedNodeID);
+
+ if (failoverNodeID == -1 || failoverNodeID != serverPeer.getServerPeerID())
+ {
+ log.trace(this + " realized that we are on the wrong node or no failover has occured");
+ return new CreateConnectionResult(failoverNodeID);
+ }
+ else
+ {
+ log.trace(this + " received notification that server-side failover completed, " +
+ "creating connection delegate ...");
+ ClientConnectionDelegate cd =
+ createConnectionDelegateInternal(username, password, failedNodeID,
+ remotingSessionID, clientVMID,
+ versionToUse,
+ callbackHandler);
+ return new CreateConnectionResult(cd);
+ }
+ }
+ }
+ catch (Throwable t)
+ {
+ throw ExceptionUtil.handleJMSInvocation(t, this + " createFailoverConnectionDelegate");
+ }
+
+ }
+
+ /**
+ * @param failedNodeID - zero or positive values mean connection creation attempt is result of
+ * failover. Negative values are ignored (mean regular connection creation attempt).
+ */
+ private ClientConnectionDelegate
+ createConnectionDelegateInternal(final String username,
+ final String password,
+ final int failedNodeID,
+ final String remotingSessionID, final String clientVMID,
+ final byte versionToUse,
+ final ServerInvokerCallbackHandler callbackHandler)
+ throws Exception
+ {
+ log.trace("creating a new connection for user " + username);
+
+ // Authenticate. Successful autentication will place a new SubjectContext on thread local,
+ // which will be used in the authorization process. However, we need to make sure we clean
+ // up thread local immediately after we used the information, otherwise some other people
+ // security my be screwed up, on account of thread local security stack being corrupted.
+
+ if (System.getSecurityManager() == null)
+ {
+ serverPeer.getSecurityManager().authenticate(username, password);
+ }
+ else
+ {
+ try
+ {
+ AccessController.doPrivileged(new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ serverPeer.getSecurityManager().authenticate(username, password);
+ return null;
+ }
+ });
+ }
+ catch (PrivilegedActionException pe)
+ {
+ throw pe.getException();
+ }
+ }
+
+ // We don't need the SubjectContext on thread local anymore, clean it up
+ SecurityActions.popSubjectContext();
+
+ String clientIDUsed = clientID;
+
+ // see if there is a preconfigured client id for the user
+ if (username != null)
+ {
+ String preconfClientID =
+ serverPeer.getJmsUserManagerInstance().getPreConfiguredClientID(username);
+
+ if (preconfClientID != null)
+ {
+ clientIDUsed = preconfClientID;
+ }
+ }
+
+ // create the corresponding "server-side" connection endpoint and register it with the
+ // server peer's ClientManager
+ ServerConnectionEndpoint endpoint =
+ new ServerConnectionEndpoint(serverPeer, clientIDUsed, username, password, prefetchSize,
+ defaultTempQueueFullSize, defaultTempQueuePageSize,
+ defaultTempQueueDownCacheSize, failedNodeID, this,
+ remotingSessionID, clientVMID, versionToUse,
+ callbackHandler, dupsOKBatchSize);
+
+ String connectionID = endpoint.getConnectionID();
+
+ ConnectionAdvised connAdvised;
+
+ // Need to synchronized to prevent a deadlock
+ // See http://jira.jboss.com/jira/browse/JBMESSAGING-797
+ synchronized (AspectManager.instance())
+ {
+ connAdvised = new ConnectionAdvised(endpoint);
+ }
+
+ Dispatcher.instance.registerTarget(connectionID, connAdvised);
+
+ log.trace("created and registered " + endpoint);
+
+ // Need to synchronized to prevent a deadlock
+ // See http://jira.jboss.com/jira/browse/JBMESSAGING-797
+ synchronized (AspectManager.instance())
+ {
+ return new ClientConnectionDelegate(connectionID, serverPeer.getServerPeerID());
+ }
+ }
+
+ public byte[] getClientAOPStack() throws JMSException
+ {
+ try
+ {
+ return serverPeer.getClientAOPStack();
+ }
+ catch (Throwable t)
+ {
+ throw ExceptionUtil.handleJMSInvocation(t, this + " getClientAOPStack");
+ }
+ }
+
+ public void addCallback(String VMID, String remotingSessionID,
+ InvokerCallbackHandler callbackHandler) throws JMSException
+ {
+ log.debug("Adding callbackHandler on ConnectionFactory");
+
+ handlers.add(callbackHandler);
+
+ serverPeer.getConnectionManager().registerConnectionFactoryCallback(VMID, remotingSessionID, callbackHandler);
+ }
+
+ public void removeCallback(String VMID, String remotingSessionID,
+ ServerInvokerCallbackHandler callbackHandler) throws JMSException
+ {
+ log.debug("Removing callbackHandler on ConnectionFactory");
+
+ handlers.remove(callbackHandler);
+
+ serverPeer.getConnectionManager().unregisterConnectionFactoryCallback(VMID, remotingSessionID);
+ }
+
+ public TopologyResult getTopology() throws JMSException
+ {
+ return new TopologyResult(uniqueName, delegates, failoverMap);
+ }
+
+ public void removeCallbackhandler(InvokerCallbackHandler handler)
+ {
+ handlers.remove(handler);
+ }
+
+ // Public ---------------------------------------------------------------------------------------
+
+ public String getID()
+ {
+ return id;
+ }
+
+ public JNDIBindings getJNDIBindings()
+ {
+ return jndiBindings;
+ }
+
+ public ServerPeer getServerPeer()
+ {
+ return serverPeer;
+ }
+
+ /**
+ * Sends a cluster view update message to its associated ClusteredConnectionFactories.
+ *
+ * Observation: It is placed here, because if we decide to lock the ServerEndpoint while we send
+ * updates, we would need the method here to perform WriteLocks on objects.
+ */
+ public void updateClusteredClients(ClientConnectionFactoryDelegate[] delegates, Map failoverMap)
+ throws Exception
+ {
+ updateTopology(delegates, failoverMap);
+
+ log.debug("updateClusteredClients being called!!! clientFactoriesToUpdate.size = " + handlers.size());
+
+ ConnectionFactoryUpdate message =
+ new ConnectionFactoryUpdate(uniqueName, delegates, failoverMap);
+
+ Callback callback = new Callback(message);
+
+ for (InvokerCallbackHandler o: handlers)
+ {
+ log.debug("Updating CF on callback " + o);
+ ((ServerInvokerCallbackHandler)o).handleCallbackOneway(callback);
+ }
+ }
+
+ public void updateTopology(ClientConnectionFactoryDelegate[] delegates, Map failoverMap)
+ {
+ this.delegates = delegates;
+ this.failoverMap = failoverMap;
+ }
+
+ public boolean isSlowConsumers()
+ {
+ return slowConsumers;
+ }
+
+ public String toString()
+ {
+ return "ConnectionFactoryEndpoint[" + id + "]";
+ }
+
+ /** Method used for tests and validations only */
+ public Set getCallbackHandlers()
+ {
+ return java.util.Collections.unmodifiableSet(handlers);
+ }
+
+ // Package protected ----------------------------------------------------------------------------
+
+ boolean isSupportsFailover()
+ {
+ return supportsFailover;
+ }
+
+ // Protected ------------------------------------------------------------------------------------
+
+ // Private --------------------------------------------------------------------------------------
+
+ // Inner classes --------------------------------------------------------------------------------
+}
Added: branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/container/SecurityActions.java
===================================================================
--- branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/container/SecurityActions.java (rev 0)
+++ branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/container/SecurityActions.java 2010-02-02 14:27:40 UTC (rev 7934)
@@ -0,0 +1,67 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jms.server.container;
+
+import java.security.AccessController;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+
+import javax.security.auth.Subject;
+
+import org.jboss.security.SecurityAssociation;
+import org.jboss.security.SecurityContext;
+import org.jboss.security.SecurityContextAssociation;
+
+
+/** A collection of privileged actions for this package
+ * @author Scott.Stark at jboss.org
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:anil.saldhana at jboss.com">anil saldhana</a>
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ * @version $Revison: 1.0$
+ */
+class SecurityActions
+{
+
+ static SecurityContext getSecurityContext()
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<SecurityContext>(){
+
+ public SecurityContext run()
+ {
+ return SecurityContextAssociation.getSecurityContext();
+ }});
+ }
+
+ static void setSecurityContext(final SecurityContext sc)
+ {
+ AccessController.doPrivileged(new PrivilegedAction<Object>(){
+
+ public Object run()
+ {
+ SecurityContextAssociation.setSecurityContext(sc);
+ return null;
+ }});
+ }
+
+}
Added: branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/container/SecurityAspect.java
===================================================================
--- branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/container/SecurityAspect.java (rev 0)
+++ branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/container/SecurityAspect.java 2010-02-02 14:27:40 UTC (rev 7934)
@@ -0,0 +1,352 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jms.server.container;
+
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Set;
+
+import javax.jms.Destination;
+import javax.jms.JMSSecurityException;
+import javax.jms.Message;
+
+import org.jboss.aop.joinpoint.Invocation;
+import org.jboss.aop.joinpoint.MethodInvocation;
+import org.jboss.jms.destination.JBossDestination;
+import org.jboss.jms.message.JBossMessage;
+import org.jboss.jms.server.SecurityStore;
+import org.jboss.jms.server.endpoint.ServerConnectionEndpoint;
+import org.jboss.jms.server.endpoint.ServerConsumerEndpoint;
+import org.jboss.jms.server.endpoint.ServerSessionEndpoint;
+import org.jboss.jms.server.endpoint.advised.ConnectionAdvised;
+import org.jboss.jms.server.endpoint.advised.ConsumerAdvised;
+import org.jboss.jms.server.endpoint.advised.SessionAdvised;
+import org.jboss.jms.server.security.CheckType;
+import org.jboss.jms.server.security.SecurityMetadata;
+import org.jboss.jms.tx.ClientTransaction;
+import org.jboss.jms.tx.TransactionRequest;
+import org.jboss.logging.Logger;
+import org.jboss.security.SecurityContext;
+
+/**
+ * This aspect enforces the JBossMessaging JMS security policy.
+ *
+ * This aspect is PER_INSTANCE
+ *
+ * For performance reasons we cache access rights in the interceptor for a maximum of
+ * INVALIDATION_INTERVAL milliseconds.
+ * This is because we don't want to do a full authentication and authorization on every send,
+ * for example, since this will drastically reduce performance.
+ * This means any changes to security data won't be reflected until INVALIDATION_INTERVAL
+ * milliseconds later.
+ *
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @author <a href="mailto:ovidiu at feodorov.com">Ovidiu Feodorov</a>
+ * @version <tt>$Revision 1.1 $</tt>
+ *
+ * $Id: SecurityAspect.java 3147 2007-09-27 19:12:12Z anil.saldhana at jboss.com $
+ */
+public class SecurityAspect
+{
+ // Constants -----------------------------------------------------
+
+ private static final Logger log = Logger.getLogger(SecurityAspect.class);
+
+ // Static --------------------------------------------------------
+
+ // Attributes ----------------------------------------------------
+
+ private boolean trace = log.isTraceEnabled();
+
+ private Set readCache;
+
+ private Set writeCache;
+
+ private Set createCache;
+
+ //TODO Make this configurable
+ private static final long INVALIDATION_INTERVAL = 15000;
+
+ private long lastCheck;
+
+ // Constructors --------------------------------------------------
+
+ // Public --------------------------------------------------------
+ public SecurityAspect()
+ {
+ readCache = new HashSet();
+
+ writeCache = new HashSet();
+
+ createCache = new HashSet();
+ }
+
+ public Object handleCreateConsumerDelegate(Invocation invocation) throws Throwable
+ {
+ MethodInvocation mi = (MethodInvocation)invocation;
+
+ // read permission required on the destination
+ Destination dest = (Destination)mi.getArguments()[0];
+
+ SessionAdvised del = (SessionAdvised)invocation.getTargetObject();
+ ServerSessionEndpoint sess = (ServerSessionEndpoint)del.getEndpoint();
+
+ check(dest, CheckType.READ, sess.getConnectionEndpoint());
+
+ // if creating a durable subscription then need create permission
+
+ String subscriptionName = (String)mi.getArguments()[3];
+ if (subscriptionName != null)
+ {
+ // durable
+ check(dest, CheckType.CREATE, sess.getConnectionEndpoint());
+ }
+
+ return invocation.invokeNext();
+ }
+
+ public Object handleCreateBrowserDelegate(Invocation invocation) throws Throwable
+ {
+ // read permission required on the destination
+
+ MethodInvocation mi = (MethodInvocation)invocation;
+
+ Destination dest = (Destination)mi.getArguments()[0];
+
+ SessionAdvised del = (SessionAdvised)invocation.getTargetObject();
+ ServerSessionEndpoint sess = (ServerSessionEndpoint)del.getEndpoint();
+
+ check(dest, CheckType.READ, sess.getConnectionEndpoint());
+
+ return invocation.invokeNext();
+ }
+
+ public Object handleSend(Invocation invocation) throws Throwable
+ {
+ // anonymous producer - if destination is not null then write permissions required
+
+ MethodInvocation mi = (MethodInvocation)invocation;
+
+ Message m = (Message)mi.getArguments()[0];
+ Destination dest = m.getJMSDestination();
+
+ SessionAdvised del = (SessionAdvised)invocation.getTargetObject();
+ ServerSessionEndpoint se = (ServerSessionEndpoint)del.getEndpoint();
+ ServerConnectionEndpoint ce = se.getConnectionEndpoint();
+
+ check(dest, CheckType.WRITE, ce);
+
+ return invocation.invokeNext();
+ }
+
+
+ // An aspect over ConnectionAdvised
+ public Object handleSendTransaction(Invocation invocation) throws Throwable
+ {
+ ConnectionAdvised del = (ConnectionAdvised)invocation.getTargetObject();
+ ServerConnectionEndpoint ce = (ServerConnectionEndpoint)del.getEndpoint();
+
+ MethodInvocation mi = (MethodInvocation)invocation;
+
+ TransactionRequest t = (TransactionRequest)mi.getArguments()[0];
+
+ ClientTransaction txState = t.getState();
+
+ if (txState != null)
+ {
+ // distinct list of destinations...
+ HashSet destinations = new HashSet();
+
+ for (Iterator i = txState.getSessionStates().iterator(); i.hasNext(); )
+ {
+ ClientTransaction.SessionTxState sessionState = (ClientTransaction.SessionTxState)i.next();
+ for (Iterator j = sessionState.getMsgs().iterator(); j.hasNext(); )
+ {
+ JBossMessage message = (JBossMessage)j.next();
+ destinations.add(message.getJMSDestination());
+ }
+ }
+ for (Iterator iterDestinations = destinations.iterator();iterDestinations.hasNext();)
+ {
+ Destination destination = (Destination) iterDestinations.next();
+ check(destination, CheckType.WRITE, ce);
+ }
+
+ }
+
+ return invocation.invokeNext();
+ }
+
+
+
+ protected void checkConsumerAccess(Invocation invocation) throws Throwable
+ {
+ ConsumerAdvised del = (ConsumerAdvised)invocation.getTargetObject();
+ ServerConsumerEndpoint cons = (ServerConsumerEndpoint)del.getEndpoint();
+ ServerConnectionEndpoint conn = cons.getSessionEndpoint().getConnectionEndpoint();
+ JBossDestination dest = cons.getDestination();
+
+ check(dest, CheckType.READ, conn);
+ }
+
+ // Package protected ---------------------------------------------
+
+ // Protected -----------------------------------------------------
+
+ // Private -------------------------------------------------------
+
+ private boolean checkCached(Destination dest, CheckType checkType)
+ {
+ long now = System.currentTimeMillis();
+
+ boolean granted = false;
+
+ if (now - lastCheck > INVALIDATION_INTERVAL)
+ {
+ readCache.clear();
+
+ writeCache.clear();
+
+ createCache.clear();
+ }
+ else
+ {
+ switch (checkType.type)
+ {
+ case CheckType.TYPE_READ:
+ {
+ granted = readCache.contains(dest);
+ break;
+ }
+ case CheckType.TYPE_WRITE:
+ {
+ granted = writeCache.contains(dest);
+ break;
+ }
+ case CheckType.TYPE_CREATE:
+ {
+ granted = createCache.contains(dest);
+ break;
+ }
+ default:
+ {
+ throw new IllegalArgumentException("Invalid checkType:" + checkType);
+ }
+ }
+ }
+
+ lastCheck = now;
+
+ return granted;
+ }
+
+ private void check(Destination dest, CheckType checkType, ServerConnectionEndpoint conn)
+ throws JMSSecurityException
+ {
+ JBossDestination jbd = (JBossDestination)dest;
+
+ if (jbd.isTemporary())
+ {
+ if (trace) { log.trace("skipping permission check on temporary destination " + dest); }
+ return;
+ }
+
+ if (trace) { log.trace("checking access permissions to " + dest); }
+
+ if (checkCached(dest, checkType))
+ {
+ // OK
+ return;
+ }
+
+ boolean isQueue = jbd.isQueue();
+ String name = jbd.getName();
+
+ SecurityStore sm = conn.getSecurityManager();
+ SecurityMetadata securityMetadata = sm.getSecurityMetadata(isQueue, name);
+
+ if (securityMetadata == null)
+ {
+ throw new JMSSecurityException("No security configuration avaliable for " + name);
+ }
+
+ // Authenticate. Need to save current SecurityContext
+ SecurityContext previousSCtx = SecurityActions.getSecurityContext();
+
+ sm.authenticate(conn.getUsername(), conn.getPassword());
+
+ // Authorize
+ Set principals = checkType == CheckType.READ ? securityMetadata.getReadPrincipals() :
+ checkType == CheckType.WRITE ? securityMetadata.getWritePrincipals() :
+ securityMetadata.getCreatePrincipals();
+ try
+ {
+ if (!sm.authorize(conn.getUsername(), principals, checkType))
+ {
+ String msg = "User: " + conn.getUsername() +
+ " is not authorized to " +
+ (checkType == CheckType.READ ? "read from" :
+ checkType == CheckType.WRITE ? "write to" : "create durable sub on") +
+ " destination " + name;
+
+ throw new JMSSecurityException(msg);
+ }
+ }
+ finally
+ {
+ // Restore previous SecurityContext
+ SecurityActions.setSecurityContext(previousSCtx);
+ }
+
+ // if we get here we're granted, add to the cache
+
+ switch (checkType.type)
+ {
+ case CheckType.TYPE_READ:
+ {
+ readCache.add(dest);
+ break;
+ }
+ case CheckType.TYPE_WRITE:
+ {
+ writeCache.add(dest);
+ break;
+ }
+ case CheckType.TYPE_CREATE:
+ {
+ createCache.add(dest);
+ break;
+ }
+ default:
+ {
+ throw new IllegalArgumentException("Invalid checkType:" + checkType);
+ }
+ }
+ }
+
+ // Inner classes -------------------------------------------------
+
+}
+
+
+
+
Added: branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/endpoint/SecurityActions.java
===================================================================
--- branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/endpoint/SecurityActions.java (rev 0)
+++ branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/endpoint/SecurityActions.java 2010-02-02 14:27:40 UTC (rev 7934)
@@ -0,0 +1,123 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jms.server.endpoint;
+
+import java.security.AccessController;
+import java.security.Principal;
+import java.security.PrivilegedAction;
+
+import javax.security.auth.Subject;
+
+import org.jboss.security.SecurityAssociation;
+import org.jboss.security.SecurityContext;
+import org.jboss.security.SecurityContextAssociation;
+
+/** A collection of privileged actions for this package
+ * @author Scott.Stark at jboss.org
+ * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
+ * @author tim.fox at jboss.com
+ * @author anil.saldhana at jboss.com
+ * @author <a href="mailto:hgao at redhat.com">Howard Gao</a>
+ * @version $Revison: 1.0$
+ */
+class SecurityActions
+{
+
+ static SecurityContext getSecurityContext()
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<SecurityContext>(){
+
+ public SecurityContext run()
+ {
+ return SecurityContextAssociation.getSecurityContext();
+ }});
+ }
+
+ static void setSecurityContext(final SecurityContext sc)
+ {
+ AccessController.doPrivileged(new PrivilegedAction<Object>(){
+
+ public Object run()
+ {
+ SecurityContextAssociation.setSecurityContext(sc);
+ return null;
+ }});
+ }
+
+
+ static ClassLoader getTCL()
+ {
+ if (System.getSecurityManager() == null)
+ {
+ return Thread.currentThread().getContextClassLoader();
+ }
+ else
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
+ {
+ public ClassLoader run()
+ {
+ return Thread.currentThread().getContextClassLoader();
+ }
+ });
+ }
+ }
+
+ static ClassLoader getClassLoader(final Class<?> clazz)
+ {
+ if (System.getSecurityManager() == null)
+ {
+ return clazz.getClassLoader();
+ }
+ else
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
+ {
+ public ClassLoader run()
+ {
+ return clazz.getClassLoader();
+ }
+ });
+ }
+
+ }
+
+ static void setTCL(final ClassLoader tcl)
+ {
+ if (System.getSecurityManager() == null)
+ {
+ Thread.currentThread().setContextClassLoader(tcl);
+ }
+ else
+ {
+ AccessController.doPrivileged(new PrivilegedAction<Object>()
+ {
+ public Object run()
+ {
+ Thread.currentThread().setContextClassLoader(tcl);
+ return null;
+ }
+ });
+ }
+ }
+
+}
Added: branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java
===================================================================
--- branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java (rev 0)
+++ branches/Branch_1_4/integration/EAP5/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java 2010-02-02 14:27:40 UTC (rev 7934)
@@ -0,0 +1,418 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2005, JBoss Inc., and individual contributors as indicated
+ * by the @authors tag. See the copyright.txt in the distribution for a
+ * full listing of individual contributors.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ */
+package org.jboss.jms.server.endpoint;
+
+import java.security.AccessController;
+import java.security.PrivilegedActionException;
+import java.security.PrivilegedExceptionAction;
+import java.util.Map;
+import java.util.Set;
+
+import javax.jms.JMSException;
+
+import org.jboss.aop.AspectManager;
+import org.jboss.jms.client.delegate.ClientConnectionDelegate;
+import org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate;
+import org.jboss.jms.delegate.ConnectionFactoryEndpoint;
+import org.jboss.jms.delegate.CreateConnectionResult;
+import org.jboss.jms.delegate.TopologyResult;
+import org.jboss.jms.server.ServerPeer;
+import org.jboss.jms.server.connectionfactory.JNDIBindings;
+import org.jboss.jms.server.endpoint.advised.ConnectionAdvised;
+import org.jboss.jms.wireformat.ConnectionFactoryUpdate;
+import org.jboss.jms.wireformat.Dispatcher;
+import org.jboss.logging.Logger;
+import org.jboss.messaging.util.ConcurrentHashSet;
+import org.jboss.messaging.util.ExceptionUtil;
+import org.jboss.remoting.callback.Callback;
+import org.jboss.remoting.callback.InvokerCallbackHandler;
+import org.jboss.remoting.callback.ServerInvokerCallbackHandler;
+import org.jboss.security.SecurityContext;
+
+/**
+ * Concrete implementation of ConnectionFactoryEndpoint
+ *
+ * @author <a href="mailto:ovidiu at feodorov.com">Ovidiu Feodorov</a>
+ * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
+ * @version <tt>$Revision: 5366 $</tt>
+ *
+ * $Id: ServerConnectionFactoryEndpoint.java 5366 2008-11-14 21:46:28Z clebert.suconic at jboss.com $
+ */
+public class ServerConnectionFactoryEndpoint implements ConnectionFactoryEndpoint
+{
+ // Constants ------------------------------------------------------------------------------------
+
+ private static final Logger log = Logger.getLogger(ServerConnectionFactoryEndpoint.class);
+
+ // Static ---------------------------------------------------------------------------------------
+
+ // Attributes -----------------------------------------------------------------------------------
+
+ private ServerPeer serverPeer;
+
+ private String clientID;
+
+ private String uniqueName;
+
+ private String id;
+
+ private JNDIBindings jndiBindings;
+
+ private int prefetchSize;
+
+ private int defaultTempQueueFullSize;
+
+ private int defaultTempQueuePageSize;
+
+ private int defaultTempQueueDownCacheSize;
+
+ private int dupsOKBatchSize;
+
+ private boolean supportsFailover;
+
+ private boolean slowConsumers;
+
+ /** Cluster Topology on ClusteredConnectionFactories
+ Information to failover to other connections on clients **/
+ private ClientConnectionFactoryDelegate[] delegates;
+
+ /** Cluster Topology on ClusteredConnectionFactories
+ Information to failover to other connections on clients **/
+ private Map failoverMap;
+
+ private Set<InvokerCallbackHandler> handlers = new ConcurrentHashSet<InvokerCallbackHandler>();
+
+
+ // Constructors ---------------------------------------------------------------------------------
+
+ /**
+ * @param jndiBindings - names under which the corresponding JBossConnectionFactory is bound in
+ * JNDI.
+ */
+ public ServerConnectionFactoryEndpoint(String uniqueName, String id, ServerPeer serverPeer,
+ String defaultClientID,
+ JNDIBindings jndiBindings,
+ int preFetchSize,
+ boolean slowConsumers,
+ int defaultTempQueueFullSize,
+ int defaultTempQueuePageSize,
+ int defaultTempQueueDownCacheSize,
+ int dupsOKBatchSize,
+ boolean supportsFailover)
+ {
+ this.uniqueName = uniqueName;
+ this.serverPeer = serverPeer;
+ this.clientID = defaultClientID;
+ this.id = id;
+ this.jndiBindings = jndiBindings;
+ this.prefetchSize = preFetchSize;
+ this.defaultTempQueueFullSize = defaultTempQueueFullSize;
+ this.defaultTempQueuePageSize = defaultTempQueuePageSize;
+ this.defaultTempQueueDownCacheSize = defaultTempQueueDownCacheSize;
+ this.dupsOKBatchSize = dupsOKBatchSize;
+ this.supportsFailover = supportsFailover;
+ this.slowConsumers = slowConsumers;
+ if (slowConsumers)
+ {
+ this.prefetchSize = 1;
+ }
+ }
+
+ // ConnectionFactoryDelegate implementation -----------------------------------------------------
+
+ public CreateConnectionResult createConnectionDelegate(String username,
+ String password,
+ int failedNodeID)
+
+ throws JMSException
+ {
+ //This is never called directly
+ throw new IllegalStateException("createConnectionDelegate should never be called directly");
+ }
+
+ /**
+ * @param failedNodeID - zero or positive values mean connection creation attempt is result of
+ * failover. -1 are ignored (mean regular connection creation attempt).
+ */
+ public CreateConnectionResult createConnectionDelegate(String username,
+ String password,
+ int failedNodeID,
+ String remotingSessionID,
+ String clientVMID,
+ byte versionToUse,
+ ServerInvokerCallbackHandler callbackHandler)
+ throws JMSException
+ {
+ try
+ {
+ if (failedNodeID == -1)
+ {
+ // Just a standard createConnection
+ ClientConnectionDelegate cd =
+ createConnectionDelegateInternal(username, password, failedNodeID,
+ remotingSessionID, clientVMID,
+ versionToUse,
+ callbackHandler);
+ return new CreateConnectionResult(cd);
+ }
+ else
+ {
+ log.trace(this + " received client-side failover request. Creating failover "+
+ "connection to replace connection to failed node " + failedNodeID);
+
+ // Wait for server side failover to complete
+ int failoverNodeID = serverPeer.getFailoverWaiter().waitForFailover(failedNodeID);
+
+ if (failoverNodeID == -1 || failoverNodeID != serverPeer.getServerPeerID())
+ {
+ log.trace(this + " realized that we are on the wrong node or no failover has occured");
+ return new CreateConnectionResult(failoverNodeID);
+ }
+ else
+ {
+ log.trace(this + " received notification that server-side failover completed, " +
+ "creating connection delegate ...");
+ ClientConnectionDelegate cd =
+ createConnectionDelegateInternal(username, password, failedNodeID,
+ remotingSessionID, clientVMID,
+ versionToUse,
+ callbackHandler);
+ return new CreateConnectionResult(cd);
+ }
+ }
+ }
+ catch (Throwable t)
+ {
+ throw ExceptionUtil.handleJMSInvocation(t, this + " createFailoverConnectionDelegate");
+ }
+
+ }
+
+ /**
+ * @param failedNodeID - zero or positive values mean connection creation attempt is result of
+ * failover. Negative values are ignored (mean regular connection creation attempt).
+ */
+ private ClientConnectionDelegate
+ createConnectionDelegateInternal(final String username,
+ final String password,
+ final int failedNodeID,
+ final String remotingSessionID, final String clientVMID,
+ final byte versionToUse,
+ final ServerInvokerCallbackHandler callbackHandler)
+ throws Exception
+ {
+ log.trace("creating a new connection for user " + username);
+
+ // Authenticate. Need to save current SecurityContext
+ SecurityContext previousSCtx = SecurityActions.getSecurityContext();
+
+ if (System.getSecurityManager() == null)
+ {
+ serverPeer.getSecurityManager().authenticate(username, password);
+ }
+ else
+ {
+ try
+ {
+ AccessController.doPrivileged(new PrivilegedExceptionAction<Object>()
+ {
+ public Object run() throws Exception
+ {
+ serverPeer.getSecurityManager().authenticate(username, password);
+ return null;
+ }
+ });
+ }
+ catch (PrivilegedActionException pe)
+ {
+ throw pe.getException();
+ }
+ }
+
+ // Restore previous SecurityContext
+ SecurityActions.setSecurityContext(previousSCtx);
+
+ String clientIDUsed = clientID;
+
+ // see if there is a preconfigured client id for the user
+ if (username != null)
+ {
+ String preconfClientID =
+ serverPeer.getJmsUserManagerInstance().getPreConfiguredClientID(username);
+
+ if (preconfClientID != null)
+ {
+ clientIDUsed = preconfClientID;
+ }
+ }
+
+ // create the corresponding "server-side" connection endpoint and register it with the
+ // server peer's ClientManager
+ ServerConnectionEndpoint endpoint =
+ new ServerConnectionEndpoint(serverPeer, clientIDUsed, username, password, prefetchSize,
+ defaultTempQueueFullSize, defaultTempQueuePageSize,
+ defaultTempQueueDownCacheSize, failedNodeID, this,
+ remotingSessionID, clientVMID, versionToUse,
+ callbackHandler, dupsOKBatchSize);
+
+ String connectionID = endpoint.getConnectionID();
+
+ ConnectionAdvised connAdvised;
+
+ // Need to synchronized to prevent a deadlock
+ // See http://jira.jboss.com/jira/browse/JBMESSAGING-797
+ synchronized (AspectManager.instance())
+ {
+ connAdvised = new ConnectionAdvised(endpoint);
+ }
+
+ Dispatcher.instance.registerTarget(connectionID, connAdvised);
+
+ log.trace("created and registered " + endpoint);
+
+ // Need to synchronized to prevent a deadlock
+ // See http://jira.jboss.com/jira/browse/JBMESSAGING-797
+ synchronized (AspectManager.instance())
+ {
+ return new ClientConnectionDelegate(connectionID, serverPeer.getServerPeerID());
+ }
+ }
+
+ public byte[] getClientAOPStack() throws JMSException
+ {
+ try
+ {
+ return serverPeer.getClientAOPStack();
+ }
+ catch (Throwable t)
+ {
+ throw ExceptionUtil.handleJMSInvocation(t, this + " getClientAOPStack");
+ }
+ }
+
+ public void addCallback(String VMID, String remotingSessionID,
+ InvokerCallbackHandler callbackHandler) throws JMSException
+ {
+ log.debug("Adding callbackHandler on ConnectionFactory");
+
+ handlers.add(callbackHandler);
+
+ serverPeer.getConnectionManager().registerConnectionFactoryCallback(VMID, remotingSessionID, callbackHandler);
+ }
+
+ public void removeCallback(String VMID, String remotingSessionID,
+ ServerInvokerCallbackHandler callbackHandler) throws JMSException
+ {
+ log.debug("Removing callbackHandler on ConnectionFactory");
+
+ handlers.remove(callbackHandler);
+
+ serverPeer.getConnectionManager().unregisterConnectionFactoryCallback(VMID, remotingSessionID);
+ }
+
+ public TopologyResult getTopology() throws JMSException
+ {
+ return new TopologyResult(uniqueName, delegates, failoverMap);
+ }
+
+ public void removeCallbackhandler(InvokerCallbackHandler handler)
+ {
+ handlers.remove(handler);
+ }
+
+ // Public ---------------------------------------------------------------------------------------
+
+ public String getID()
+ {
+ return id;
+ }
+
+ public JNDIBindings getJNDIBindings()
+ {
+ return jndiBindings;
+ }
+
+ public ServerPeer getServerPeer()
+ {
+ return serverPeer;
+ }
+
+ /**
+ * Sends a cluster view update message to its associated ClusteredConnectionFactories.
+ *
+ * Observation: It is placed here, because if we decide to lock the ServerEndpoint while we send
+ * updates, we would need the method here to perform WriteLocks on objects.
+ */
+ public void updateClusteredClients(ClientConnectionFactoryDelegate[] delegates, Map failoverMap)
+ throws Exception
+ {
+ updateTopology(delegates, failoverMap);
+
+ log.debug("updateClusteredClients being called!!! clientFactoriesToUpdate.size = " + handlers.size());
+
+ ConnectionFactoryUpdate message =
+ new ConnectionFactoryUpdate(uniqueName, delegates, failoverMap);
+
+ Callback callback = new Callback(message);
+
+ for (InvokerCallbackHandler o: handlers)
+ {
+ log.debug("Updating CF on callback " + o);
+ ((ServerInvokerCallbackHandler)o).handleCallbackOneway(callback);
+ }
+ }
+
+ public void updateTopology(ClientConnectionFactoryDelegate[] delegates, Map failoverMap)
+ {
+ this.delegates = delegates;
+ this.failoverMap = failoverMap;
+ }
+
+ public boolean isSlowConsumers()
+ {
+ return slowConsumers;
+ }
+
+ public String toString()
+ {
+ return "ConnectionFactoryEndpoint[" + id + "]";
+ }
+
+ /** Method used for tests and validations only */
+ public Set getCallbackHandlers()
+ {
+ return java.util.Collections.unmodifiableSet(handlers);
+ }
+
+ // Package protected ----------------------------------------------------------------------------
+
+ boolean isSupportsFailover()
+ {
+ return supportsFailover;
+ }
+
+ // Protected ------------------------------------------------------------------------------------
+
+ // Private --------------------------------------------------------------------------------------
+
+ // Inner classes --------------------------------------------------------------------------------
+}
Deleted: branches/Branch_1_4/src/main/org/jboss/jms/server/container/SecurityActions.java
===================================================================
--- branches/Branch_1_4/src/main/org/jboss/jms/server/container/SecurityActions.java 2010-02-02 13:38:37 UTC (rev 7933)
+++ branches/Branch_1_4/src/main/org/jboss/jms/server/container/SecurityActions.java 2010-02-02 14:27:40 UTC (rev 7934)
@@ -1,133 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.jms.server.container;
-
-import java.security.AccessController;
-import java.security.Principal;
-import java.security.PrivilegedAction;
-
-import javax.security.auth.Subject;
-
-import org.jboss.security.SecurityAssociation;
-
-
-/** A collection of privileged actions for this package
- * @author Scott.Stark at jboss.org
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @author <a href="mailto:anil.saldhana at jboss.com">anil saldhana</a>
- * @version $Revison: 1.0$
- */
-class SecurityActions
-{
- interface PrincipalInfoAction
- {
- PrincipalInfoAction PRIVILEGED = new PrincipalInfoAction()
- {
- public void push(final Principal principal, final Object credential,
- final Subject subject)
- {
- AccessController.doPrivileged(
- new PrivilegedAction()
- {
- public Object run()
- {
- SecurityAssociation.pushSubjectContext(subject, principal, credential);
- return null;
- }
- }
- );
- }
- public void dup()
- {
- AccessController.doPrivileged(
- new PrivilegedAction()
- {
- public Object run()
- {
- SecurityAssociation.dupSubjectContext();
- return null;
- }
- }
- );
- }
- public void pop()
- {
- AccessController.doPrivileged(
- new PrivilegedAction()
- {
- public Object run()
- {
- SecurityAssociation.popSubjectContext();
- return null;
- }
- }
- );
- }
- };
-
- PrincipalInfoAction NON_PRIVILEGED = new PrincipalInfoAction()
- {
- public void push(Principal principal, Object credential, Subject subject)
- {
- SecurityAssociation.pushSubjectContext(subject, principal, credential);
- }
- public void dup()
- {
- SecurityAssociation.dupSubjectContext();
- }
- public void pop()
- {
- SecurityAssociation.popSubjectContext();
- }
- };
-
- void push(Principal principal, Object credential, Subject subject);
- void dup();
- void pop();
- }
-
- static void pushSubjectContext(Principal principal, Object credential,
- Subject subject)
- {
- if(System.getSecurityManager() == null)
- {
- PrincipalInfoAction.NON_PRIVILEGED.push(principal, credential, subject);
- }
- else
- {
- PrincipalInfoAction.PRIVILEGED.push(principal, credential, subject);
- }
- }
-
- static void popSubjectContext()
- {
- if(System.getSecurityManager() == null)
- {
- PrincipalInfoAction.NON_PRIVILEGED.pop();
- }
- else
- {
- PrincipalInfoAction.PRIVILEGED.pop();
- }
- }
- }
Deleted: branches/Branch_1_4/src/main/org/jboss/jms/server/container/SecurityAspect.java
===================================================================
--- branches/Branch_1_4/src/main/org/jboss/jms/server/container/SecurityAspect.java 2010-02-02 13:38:37 UTC (rev 7933)
+++ branches/Branch_1_4/src/main/org/jboss/jms/server/container/SecurityAspect.java 2010-02-02 14:27:40 UTC (rev 7934)
@@ -1,353 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.jms.server.container;
-
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Set;
-
-import javax.jms.Destination;
-import javax.jms.JMSSecurityException;
-import javax.jms.Message;
-
-import org.jboss.aop.joinpoint.Invocation;
-import org.jboss.aop.joinpoint.MethodInvocation;
-import org.jboss.jms.destination.JBossDestination;
-import org.jboss.jms.message.JBossMessage;
-import org.jboss.jms.server.SecurityStore;
-import org.jboss.jms.server.endpoint.ServerConnectionEndpoint;
-import org.jboss.jms.server.endpoint.ServerConsumerEndpoint;
-import org.jboss.jms.server.endpoint.ServerSessionEndpoint;
-import org.jboss.jms.server.endpoint.advised.ConnectionAdvised;
-import org.jboss.jms.server.endpoint.advised.ConsumerAdvised;
-import org.jboss.jms.server.endpoint.advised.SessionAdvised;
-import org.jboss.jms.server.security.CheckType;
-import org.jboss.jms.server.security.SecurityMetadata;
-import org.jboss.jms.tx.ClientTransaction;
-import org.jboss.jms.tx.TransactionRequest;
-import org.jboss.logging.Logger;
-
-/**
- * This aspect enforces the JBossMessaging JMS security policy.
- *
- * This aspect is PER_INSTANCE
- *
- * For performance reasons we cache access rights in the interceptor for a maximum of
- * INVALIDATION_INTERVAL milliseconds.
- * This is because we don't want to do a full authentication and authorization on every send,
- * for example, since this will drastically reduce performance.
- * This means any changes to security data won't be reflected until INVALIDATION_INTERVAL
- * milliseconds later.
- *
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @author <a href="mailto:ovidiu at feodorov.com">Ovidiu Feodorov</a>
- * @version <tt>$Revision 1.1 $</tt>
- *
- * $Id$
- */
-public class SecurityAspect
-{
- // Constants -----------------------------------------------------
-
- private static final Logger log = Logger.getLogger(SecurityAspect.class);
-
- // Static --------------------------------------------------------
-
- // Attributes ----------------------------------------------------
-
- private boolean trace = log.isTraceEnabled();
-
- private Set readCache;
-
- private Set writeCache;
-
- private Set createCache;
-
- //TODO Make this configurable
- private static final long INVALIDATION_INTERVAL = 15000;
-
- private long lastCheck;
-
- // Constructors --------------------------------------------------
-
- // Public --------------------------------------------------------
- public SecurityAspect()
- {
- readCache = new HashSet();
-
- writeCache = new HashSet();
-
- createCache = new HashSet();
- }
-
- public Object handleCreateConsumerDelegate(Invocation invocation) throws Throwable
- {
- MethodInvocation mi = (MethodInvocation)invocation;
-
- // read permission required on the destination
- Destination dest = (Destination)mi.getArguments()[0];
-
- SessionAdvised del = (SessionAdvised)invocation.getTargetObject();
- ServerSessionEndpoint sess = (ServerSessionEndpoint)del.getEndpoint();
-
- check(dest, CheckType.READ, sess.getConnectionEndpoint());
-
- // if creating a durable subscription then need create permission
-
- String subscriptionName = (String)mi.getArguments()[3];
- if (subscriptionName != null)
- {
- // durable
- check(dest, CheckType.CREATE, sess.getConnectionEndpoint());
- }
-
- return invocation.invokeNext();
- }
-
- public Object handleCreateBrowserDelegate(Invocation invocation) throws Throwable
- {
- // read permission required on the destination
-
- MethodInvocation mi = (MethodInvocation)invocation;
-
- Destination dest = (Destination)mi.getArguments()[0];
-
- SessionAdvised del = (SessionAdvised)invocation.getTargetObject();
- ServerSessionEndpoint sess = (ServerSessionEndpoint)del.getEndpoint();
-
- check(dest, CheckType.READ, sess.getConnectionEndpoint());
-
- return invocation.invokeNext();
- }
-
- public Object handleSend(Invocation invocation) throws Throwable
- {
- // anonymous producer - if destination is not null then write permissions required
-
- MethodInvocation mi = (MethodInvocation)invocation;
-
- Message m = (Message)mi.getArguments()[0];
- Destination dest = m.getJMSDestination();
-
- SessionAdvised del = (SessionAdvised)invocation.getTargetObject();
- ServerSessionEndpoint se = (ServerSessionEndpoint)del.getEndpoint();
- ServerConnectionEndpoint ce = se.getConnectionEndpoint();
-
- check(dest, CheckType.WRITE, ce);
-
- return invocation.invokeNext();
- }
-
-
- // An aspect over ConnectionAdvised
- public Object handleSendTransaction(Invocation invocation) throws Throwable
- {
- ConnectionAdvised del = (ConnectionAdvised)invocation.getTargetObject();
- ServerConnectionEndpoint ce = (ServerConnectionEndpoint)del.getEndpoint();
-
- MethodInvocation mi = (MethodInvocation)invocation;
-
- TransactionRequest t = (TransactionRequest)mi.getArguments()[0];
-
- ClientTransaction txState = t.getState();
-
- if (txState != null)
- {
- // distinct list of destinations...
- HashSet destinations = new HashSet();
-
- for (Iterator i = txState.getSessionStates().iterator(); i.hasNext(); )
- {
- ClientTransaction.SessionTxState sessionState = (ClientTransaction.SessionTxState)i.next();
- for (Iterator j = sessionState.getMsgs().iterator(); j.hasNext(); )
- {
- JBossMessage message = (JBossMessage)j.next();
- destinations.add(message.getJMSDestination());
- }
- }
- for (Iterator iterDestinations = destinations.iterator();iterDestinations.hasNext();)
- {
- Destination destination = (Destination) iterDestinations.next();
- check(destination, CheckType.WRITE, ce);
- }
-
- }
-
- return invocation.invokeNext();
- }
-
-
-
- protected void checkConsumerAccess(Invocation invocation) throws Throwable
- {
- ConsumerAdvised del = (ConsumerAdvised)invocation.getTargetObject();
- ServerConsumerEndpoint cons = (ServerConsumerEndpoint)del.getEndpoint();
- ServerConnectionEndpoint conn = cons.getSessionEndpoint().getConnectionEndpoint();
- JBossDestination dest = cons.getDestination();
-
- check(dest, CheckType.READ, conn);
- }
-
- // Package protected ---------------------------------------------
-
- // Protected -----------------------------------------------------
-
- // Private -------------------------------------------------------
-
- private boolean checkCached(Destination dest, CheckType checkType)
- {
- long now = System.currentTimeMillis();
-
- boolean granted = false;
-
- if (now - lastCheck > INVALIDATION_INTERVAL)
- {
- readCache.clear();
-
- writeCache.clear();
-
- createCache.clear();
- }
- else
- {
- switch (checkType.type)
- {
- case CheckType.TYPE_READ:
- {
- granted = readCache.contains(dest);
- break;
- }
- case CheckType.TYPE_WRITE:
- {
- granted = writeCache.contains(dest);
- break;
- }
- case CheckType.TYPE_CREATE:
- {
- granted = createCache.contains(dest);
- break;
- }
- default:
- {
- throw new IllegalArgumentException("Invalid checkType:" + checkType);
- }
- }
- }
-
- lastCheck = now;
-
- return granted;
- }
-
- private void check(Destination dest, CheckType checkType, ServerConnectionEndpoint conn)
- throws JMSSecurityException
- {
- JBossDestination jbd = (JBossDestination)dest;
-
- if (jbd.isTemporary())
- {
- if (trace) { log.trace("skipping permission check on temporary destination " + dest); }
- return;
- }
-
- if (trace) { log.trace("checking access permissions to " + dest); }
-
- if (checkCached(dest, checkType))
- {
- // OK
- return;
- }
-
- boolean isQueue = jbd.isQueue();
- String name = jbd.getName();
-
- SecurityStore sm = conn.getSecurityManager();
- SecurityMetadata securityMetadata = sm.getSecurityMetadata(isQueue, name);
-
- if (securityMetadata == null)
- {
- throw new JMSSecurityException("No security configuration avaliable for " + name);
- }
-
- // Authenticate. Successful autentication will place a new SubjectContext on thread local,
- // which will be used in the authorization process. However, we need to make sure we clean up
- // thread local immediately after we used the information, otherwise some other people
- // security my be screwed up, on account of thread local security stack being corrupted.
-
- sm.authenticate(conn.getUsername(), conn.getPassword());
-
- // Authorize
- Set principals = checkType == CheckType.READ ? securityMetadata.getReadPrincipals() :
- checkType == CheckType.WRITE ? securityMetadata.getWritePrincipals() :
- securityMetadata.getCreatePrincipals();
- try
- {
- if (!sm.authorize(conn.getUsername(), principals, checkType))
- {
- String msg = "User: " + conn.getUsername() +
- " is not authorized to " +
- (checkType == CheckType.READ ? "read from" :
- checkType == CheckType.WRITE ? "write to" : "create durable sub on") +
- " destination " + name;
-
- throw new JMSSecurityException(msg);
- }
- }
- finally
- {
- // pop the Messaging SecurityContext, it did its job
- SecurityActions.popSubjectContext();
- }
-
- // if we get here we're granted, add to the cache
-
- switch (checkType.type)
- {
- case CheckType.TYPE_READ:
- {
- readCache.add(dest);
- break;
- }
- case CheckType.TYPE_WRITE:
- {
- writeCache.add(dest);
- break;
- }
- case CheckType.TYPE_CREATE:
- {
- createCache.add(dest);
- break;
- }
- default:
- {
- throw new IllegalArgumentException("Invalid checkType:" + checkType);
- }
- }
- }
-
- // Inner classes -------------------------------------------------
-
-}
-
-
-
-
Deleted: branches/Branch_1_4/src/main/org/jboss/jms/server/endpoint/SecurityActions.java
===================================================================
--- branches/Branch_1_4/src/main/org/jboss/jms/server/endpoint/SecurityActions.java 2010-02-02 13:38:37 UTC (rev 7933)
+++ branches/Branch_1_4/src/main/org/jboss/jms/server/endpoint/SecurityActions.java 2010-02-02 14:27:40 UTC (rev 7934)
@@ -1,187 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.jms.server.endpoint;
-
-import java.security.AccessController;
-import java.security.Principal;
-import java.security.PrivilegedAction;
-
-import javax.security.auth.Subject;
-
-import org.jboss.security.SecurityAssociation;
-
-/** A collection of privileged actions for this package
- * @author Scott.Stark at jboss.org
- * @author <a href="mailto:alex at jboss.org">Alexey Loubyansky</a>
- * @author tim.fox at jboss.com
- * @author anil.saldhana at jboss.com
- * @version $Revison: 1.0$
- */
-class SecurityActions
-{
- interface PrincipalInfoAction
- {
- PrincipalInfoAction PRIVILEGED = new PrincipalInfoAction()
- {
- public void push(final Principal principal, final Object credential, final Subject subject)
- {
- AccessController.doPrivileged(new PrivilegedAction<Object>()
- {
- public Object run()
- {
- SecurityAssociation.pushSubjectContext(subject, principal, credential);
- return null;
- }
- });
- }
-
- public void dup()
- {
- AccessController.doPrivileged(new PrivilegedAction<Object>()
- {
- public Object run()
- {
- SecurityAssociation.dupSubjectContext();
- return null;
- }
- });
- }
-
- public void pop()
- {
- AccessController.doPrivileged(new PrivilegedAction<Object>()
- {
- public Object run()
- {
- SecurityAssociation.popSubjectContext();
- return null;
- }
- });
- }
- };
-
- PrincipalInfoAction NON_PRIVILEGED = new PrincipalInfoAction()
- {
- public void push(Principal principal, Object credential, Subject subject)
- {
- SecurityAssociation.pushSubjectContext(subject, principal, credential);
- }
-
- public void dup()
- {
- SecurityAssociation.dupSubjectContext();
- }
-
- public void pop()
- {
- SecurityAssociation.popSubjectContext();
- }
- };
-
- void push(Principal principal, Object credential, Subject subject);
-
- void dup();
-
- void pop();
- }
-
- static void pushSubjectContext(Principal principal, Object credential, Subject subject)
- {
- if (System.getSecurityManager() == null)
- {
- PrincipalInfoAction.NON_PRIVILEGED.push(principal, credential, subject);
- }
- else
- {
- PrincipalInfoAction.PRIVILEGED.push(principal, credential, subject);
- }
- }
-
- static void popSubjectContext()
- {
- if (System.getSecurityManager() == null)
- {
- PrincipalInfoAction.NON_PRIVILEGED.pop();
- }
- else
- {
- PrincipalInfoAction.PRIVILEGED.pop();
- }
- }
-
- static ClassLoader getTCL()
- {
- if (System.getSecurityManager() == null)
- {
- return Thread.currentThread().getContextClassLoader();
- }
- else
- {
- return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
- {
- public ClassLoader run()
- {
- return Thread.currentThread().getContextClassLoader();
- }
- });
- }
- }
-
- static ClassLoader getClassLoader(final Class<?> clazz)
- {
- if (System.getSecurityManager() == null)
- {
- return clazz.getClassLoader();
- }
- else
- {
- return AccessController.doPrivileged(new PrivilegedAction<ClassLoader>()
- {
- public ClassLoader run()
- {
- return clazz.getClassLoader();
- }
- });
- }
-
- }
-
- static void setTCL(final ClassLoader tcl)
- {
- if (System.getSecurityManager() == null)
- {
- Thread.currentThread().setContextClassLoader(tcl);
- }
- else
- {
- AccessController.doPrivileged(new PrivilegedAction<Object>()
- {
- public Object run()
- {
- Thread.currentThread().setContextClassLoader(tcl);
- return null;
- }
- });
- }
- }
-
-}
Deleted: branches/Branch_1_4/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java
===================================================================
--- branches/Branch_1_4/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java 2010-02-02 13:38:37 UTC (rev 7933)
+++ branches/Branch_1_4/src/main/org/jboss/jms/server/endpoint/ServerConnectionFactoryEndpoint.java 2010-02-02 14:27:40 UTC (rev 7934)
@@ -1,421 +0,0 @@
-/*
- * JBoss, Home of Professional Open Source
- * Copyright 2005, JBoss Inc., and individual contributors as indicated
- * by the @authors tag. See the copyright.txt in the distribution for a
- * full listing of individual contributors.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- */
-package org.jboss.jms.server.endpoint;
-
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-import java.security.PrivilegedActionException;
-import java.security.PrivilegedExceptionAction;
-import java.util.Map;
-import java.util.Set;
-
-import javax.jms.JMSException;
-
-import org.jboss.aop.AspectManager;
-import org.jboss.jms.client.delegate.ClientConnectionDelegate;
-import org.jboss.jms.client.delegate.ClientConnectionFactoryDelegate;
-import org.jboss.jms.delegate.ConnectionFactoryEndpoint;
-import org.jboss.jms.delegate.CreateConnectionResult;
-import org.jboss.jms.delegate.TopologyResult;
-import org.jboss.jms.server.ServerPeer;
-import org.jboss.jms.server.connectionfactory.JNDIBindings;
-import org.jboss.jms.server.endpoint.advised.ConnectionAdvised;
-import org.jboss.jms.wireformat.ConnectionFactoryUpdate;
-import org.jboss.jms.wireformat.Dispatcher;
-import org.jboss.logging.Logger;
-import org.jboss.messaging.util.ConcurrentHashSet;
-import org.jboss.messaging.util.ExceptionUtil;
-import org.jboss.remoting.callback.Callback;
-import org.jboss.remoting.callback.InvokerCallbackHandler;
-import org.jboss.remoting.callback.ServerInvokerCallbackHandler;
-import org.jboss.security.SecurityAssociation;
-
-/**
- * Concrete implementation of ConnectionFactoryEndpoint
- *
- * @author <a href="mailto:ovidiu at feodorov.com">Ovidiu Feodorov</a>
- * @author <a href="mailto:tim.fox at jboss.com">Tim Fox</a>
- * @version <tt>$Revision$</tt>
- *
- * $Id$
- */
-public class ServerConnectionFactoryEndpoint implements ConnectionFactoryEndpoint
-{
- // Constants ------------------------------------------------------------------------------------
-
- private static final Logger log = Logger.getLogger(ServerConnectionFactoryEndpoint.class);
-
- // Static ---------------------------------------------------------------------------------------
-
- // Attributes -----------------------------------------------------------------------------------
-
- private ServerPeer serverPeer;
-
- private String clientID;
-
- private String uniqueName;
-
- private String id;
-
- private JNDIBindings jndiBindings;
-
- private int prefetchSize;
-
- private int defaultTempQueueFullSize;
-
- private int defaultTempQueuePageSize;
-
- private int defaultTempQueueDownCacheSize;
-
- private int dupsOKBatchSize;
-
- private boolean supportsFailover;
-
- private boolean slowConsumers;
-
- /** Cluster Topology on ClusteredConnectionFactories
- Information to failover to other connections on clients **/
- private ClientConnectionFactoryDelegate[] delegates;
-
- /** Cluster Topology on ClusteredConnectionFactories
- Information to failover to other connections on clients **/
- private Map failoverMap;
-
- private Set<InvokerCallbackHandler> handlers = new ConcurrentHashSet<InvokerCallbackHandler>();
-
-
- // Constructors ---------------------------------------------------------------------------------
-
- /**
- * @param jndiBindings - names under which the corresponding JBossConnectionFactory is bound in
- * JNDI.
- */
- public ServerConnectionFactoryEndpoint(String uniqueName, String id, ServerPeer serverPeer,
- String defaultClientID,
- JNDIBindings jndiBindings,
- int preFetchSize,
- boolean slowConsumers,
- int defaultTempQueueFullSize,
- int defaultTempQueuePageSize,
- int defaultTempQueueDownCacheSize,
- int dupsOKBatchSize,
- boolean supportsFailover)
- {
- this.uniqueName = uniqueName;
- this.serverPeer = serverPeer;
- this.clientID = defaultClientID;
- this.id = id;
- this.jndiBindings = jndiBindings;
- this.prefetchSize = preFetchSize;
- this.defaultTempQueueFullSize = defaultTempQueueFullSize;
- this.defaultTempQueuePageSize = defaultTempQueuePageSize;
- this.defaultTempQueueDownCacheSize = defaultTempQueueDownCacheSize;
- this.dupsOKBatchSize = dupsOKBatchSize;
- this.supportsFailover = supportsFailover;
- this.slowConsumers = slowConsumers;
- if (slowConsumers)
- {
- this.prefetchSize = 1;
- }
- }
-
- // ConnectionFactoryDelegate implementation -----------------------------------------------------
-
- public CreateConnectionResult createConnectionDelegate(String username,
- String password,
- int failedNodeID)
-
- throws JMSException
- {
- //This is never called directly
- throw new IllegalStateException("createConnectionDelegate should never be called directly");
- }
-
- /**
- * @param failedNodeID - zero or positive values mean connection creation attempt is result of
- * failover. -1 are ignored (mean regular connection creation attempt).
- */
- public CreateConnectionResult createConnectionDelegate(String username,
- String password,
- int failedNodeID,
- String remotingSessionID,
- String clientVMID,
- byte versionToUse,
- ServerInvokerCallbackHandler callbackHandler)
- throws JMSException
- {
- try
- {
- if (failedNodeID == -1)
- {
- // Just a standard createConnection
- ClientConnectionDelegate cd =
- createConnectionDelegateInternal(username, password, failedNodeID,
- remotingSessionID, clientVMID,
- versionToUse,
- callbackHandler);
- return new CreateConnectionResult(cd);
- }
- else
- {
- log.trace(this + " received client-side failover request. Creating failover "+
- "connection to replace connection to failed node " + failedNodeID);
-
- // Wait for server side failover to complete
- int failoverNodeID = serverPeer.getFailoverWaiter().waitForFailover(failedNodeID);
-
- if (failoverNodeID == -1 || failoverNodeID != serverPeer.getServerPeerID())
- {
- log.trace(this + " realized that we are on the wrong node or no failover has occured");
- return new CreateConnectionResult(failoverNodeID);
- }
- else
- {
- log.trace(this + " received notification that server-side failover completed, " +
- "creating connection delegate ...");
- ClientConnectionDelegate cd =
- createConnectionDelegateInternal(username, password, failedNodeID,
- remotingSessionID, clientVMID,
- versionToUse,
- callbackHandler);
- return new CreateConnectionResult(cd);
- }
- }
- }
- catch (Throwable t)
- {
- throw ExceptionUtil.handleJMSInvocation(t, this + " createFailoverConnectionDelegate");
- }
-
- }
-
- /**
- * @param failedNodeID - zero or positive values mean connection creation attempt is result of
- * failover. Negative values are ignored (mean regular connection creation attempt).
- */
- private ClientConnectionDelegate
- createConnectionDelegateInternal(final String username,
- final String password,
- final int failedNodeID,
- final String remotingSessionID, final String clientVMID,
- final byte versionToUse,
- final ServerInvokerCallbackHandler callbackHandler)
- throws Exception
- {
- log.trace("creating a new connection for user " + username);
-
- // Authenticate. Successful autentication will place a new SubjectContext on thread local,
- // which will be used in the authorization process. However, we need to make sure we clean
- // up thread local immediately after we used the information, otherwise some other people
- // security my be screwed up, on account of thread local security stack being corrupted.
-
- if (System.getSecurityManager() == null)
- {
- serverPeer.getSecurityManager().authenticate(username, password);
- }
- else
- {
- try
- {
- AccessController.doPrivileged(new PrivilegedExceptionAction<Object>()
- {
- public Object run() throws Exception
- {
- serverPeer.getSecurityManager().authenticate(username, password);
- return null;
- }
- });
- }
- catch (PrivilegedActionException pe)
- {
- throw pe.getException();
- }
- }
-
- // We don't need the SubjectContext on thread local anymore, clean it up
- SecurityActions.popSubjectContext();
-
- String clientIDUsed = clientID;
-
- // see if there is a preconfigured client id for the user
- if (username != null)
- {
- String preconfClientID =
- serverPeer.getJmsUserManagerInstance().getPreConfiguredClientID(username);
-
- if (preconfClientID != null)
- {
- clientIDUsed = preconfClientID;
- }
- }
-
- // create the corresponding "server-side" connection endpoint and register it with the
- // server peer's ClientManager
- ServerConnectionEndpoint endpoint =
- new ServerConnectionEndpoint(serverPeer, clientIDUsed, username, password, prefetchSize,
- defaultTempQueueFullSize, defaultTempQueuePageSize,
- defaultTempQueueDownCacheSize, failedNodeID, this,
- remotingSessionID, clientVMID, versionToUse,
- callbackHandler, dupsOKBatchSize);
-
- String connectionID = endpoint.getConnectionID();
-
- ConnectionAdvised connAdvised;
-
- // Need to synchronized to prevent a deadlock
- // See http://jira.jboss.com/jira/browse/JBMESSAGING-797
- synchronized (AspectManager.instance())
- {
- connAdvised = new ConnectionAdvised(endpoint);
- }
-
- Dispatcher.instance.registerTarget(connectionID, connAdvised);
-
- log.trace("created and registered " + endpoint);
-
- // Need to synchronized to prevent a deadlock
- // See http://jira.jboss.com/jira/browse/JBMESSAGING-797
- synchronized (AspectManager.instance())
- {
- return new ClientConnectionDelegate(connectionID, serverPeer.getServerPeerID());
- }
- }
-
- public byte[] getClientAOPStack() throws JMSException
- {
- try
- {
- return serverPeer.getClientAOPStack();
- }
- catch (Throwable t)
- {
- throw ExceptionUtil.handleJMSInvocation(t, this + " getClientAOPStack");
- }
- }
-
- public void addCallback(String VMID, String remotingSessionID,
- InvokerCallbackHandler callbackHandler) throws JMSException
- {
- log.debug("Adding callbackHandler on ConnectionFactory");
-
- handlers.add(callbackHandler);
-
- serverPeer.getConnectionManager().registerConnectionFactoryCallback(VMID, remotingSessionID, callbackHandler);
- }
-
- public void removeCallback(String VMID, String remotingSessionID,
- ServerInvokerCallbackHandler callbackHandler) throws JMSException
- {
- log.debug("Removing callbackHandler on ConnectionFactory");
-
- handlers.remove(callbackHandler);
-
- serverPeer.getConnectionManager().unregisterConnectionFactoryCallback(VMID, remotingSessionID);
- }
-
- public TopologyResult getTopology() throws JMSException
- {
- return new TopologyResult(uniqueName, delegates, failoverMap);
- }
-
- public void removeCallbackhandler(InvokerCallbackHandler handler)
- {
- handlers.remove(handler);
- }
-
- // Public ---------------------------------------------------------------------------------------
-
- public String getID()
- {
- return id;
- }
-
- public JNDIBindings getJNDIBindings()
- {
- return jndiBindings;
- }
-
- public ServerPeer getServerPeer()
- {
- return serverPeer;
- }
-
- /**
- * Sends a cluster view update message to its associated ClusteredConnectionFactories.
- *
- * Observation: It is placed here, because if we decide to lock the ServerEndpoint while we send
- * updates, we would need the method here to perform WriteLocks on objects.
- */
- public void updateClusteredClients(ClientConnectionFactoryDelegate[] delegates, Map failoverMap)
- throws Exception
- {
- updateTopology(delegates, failoverMap);
-
- log.debug("updateClusteredClients being called!!! clientFactoriesToUpdate.size = " + handlers.size());
-
- ConnectionFactoryUpdate message =
- new ConnectionFactoryUpdate(uniqueName, delegates, failoverMap);
-
- Callback callback = new Callback(message);
-
- for (InvokerCallbackHandler o: handlers)
- {
- log.debug("Updating CF on callback " + o);
- ((ServerInvokerCallbackHandler)o).handleCallbackOneway(callback);
- }
- }
-
- public void updateTopology(ClientConnectionFactoryDelegate[] delegates, Map failoverMap)
- {
- this.delegates = delegates;
- this.failoverMap = failoverMap;
- }
-
- public boolean isSlowConsumers()
- {
- return slowConsumers;
- }
-
- public String toString()
- {
- return "ConnectionFactoryEndpoint[" + id + "]";
- }
-
- /** Method used for tests and validations only */
- public Set getCallbackHandlers()
- {
- return java.util.Collections.unmodifiableSet(handlers);
- }
-
- // Package protected ----------------------------------------------------------------------------
-
- boolean isSupportsFailover()
- {
- return supportsFailover;
- }
-
- // Protected ------------------------------------------------------------------------------------
-
- // Private --------------------------------------------------------------------------------------
-
- // Inner classes --------------------------------------------------------------------------------
-}
More information about the jboss-cvs-commits
mailing list