Index: activemq-jaas/src/main/java/org/apache/activemq/jaas/CertificateLoginModule.java
===================================================================
--- activemq-jaas/src/main/java/org/apache/activemq/jaas/CertificateLoginModule.java	(revision 453741)
+++ activemq-jaas/src/main/java/org/apache/activemq/jaas/CertificateLoginModule.java	(working copy)
@@ -18,28 +18,24 @@
 
 package org.apache.activemq.jaas;
 
-import java.io.File;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
 import java.io.IOException;
-import java.util.Enumeration;
+import java.security.cert.X509Certificate;
 import java.util.HashSet;
 import java.util.Iterator;
 import java.util.Map;
 import java.util.Set;
-import java.security.cert.X509Certificate;
 
 import javax.security.auth.Subject;
 import javax.security.auth.callback.Callback;
 import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
 import javax.security.auth.callback.UnsupportedCallbackException;
 import javax.security.auth.login.FailedLoginException;
 import javax.security.auth.login.LoginException;
 import javax.security.auth.spi.LoginModule;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-
 /**
  * A LoginModule that allows for authentication based on SSL certificates.
  * 
@@ -99,7 +95,8 @@
         
         username = getUserNameForCertificates(certificates);
         if ( username == null )
-            throw new FailedLoginException("Unable to verify client certificates.");
+            throw new FailedLoginException("No user for client certificate: "
+                + getDistinguishedName(certificates));
 
         groups = getUserGroups(username);
         
@@ -188,4 +185,12 @@
      */
     protected abstract Set getUserGroups(final String username) throws LoginException;
 
+    protected String getDistinguishedName(final X509Certificate[] certs) {
+        if (certs != null && certs.length > 0 && certs[0] != null) {
+            return certs[0].getSubjectDN().getName();
+        } else {
+            return null;
+        }
+    }
+
 }
Index: activemq-jaas/src/main/java/org/apache/activemq/jaas/TextFileCertificateLoginModule.java
===================================================================
--- activemq-jaas/src/main/java/org/apache/activemq/jaas/TextFileCertificateLoginModule.java	(revision 453741)
+++ activemq-jaas/src/main/java/org/apache/activemq/jaas/TextFileCertificateLoginModule.java	(working copy)
@@ -93,7 +93,7 @@
             throw new LoginException("Unable to load user properties file " + usersFile);
         }
         
-        String dn = certs[0].getSubjectDN().getName();
+        String dn = getDistinguishedName(certs);
         
         for(Enumeration vals = users.elements(), keys = users.keys(); vals.hasMoreElements(); ) {
             if ( ((String)vals.nextElement()).equals(dn) ) {
Index: activemq-core/src/main/java/org/apache/activemq/transport/tcp/SslTransportServer.java
===================================================================
--- activemq-core/src/main/java/org/apache/activemq/transport/tcp/SslTransportServer.java	(revision 453741)
+++ activemq-core/src/main/java/org/apache/activemq/transport/tcp/SslTransportServer.java	(working copy)
@@ -48,12 +48,12 @@
     
     
     /**
-     * Constructor.
+     * Creates a ssl transport server for the specified url using the provided
+     * serverSocketFactory
      * 
      * @param transportFactory The factory used to create transports when connections arrive.
      * @param location The location of the broker to bind to.
      * @param serverSocketFactory The factory used to create this server.
-     * @param needClientAuth States if this server should needClientAuth.
      * @throws IOException passed up from TcpTransportFactory.
      * @throws URISyntaxException passed up from TcpTransportFactory.
      */
@@ -65,34 +65,34 @@
     }
     
     /**
-     * Setter for needClientAuth.
-     * 
-     * When set to true, needClientAuth will set SSLSockets' needClientAuth to true forcing clients to provide
-     *      client certificates.
+     * Sets whether client authentication should be required
+     * Must be called before {@link #bind()}
+     * Note: Calling this method clears the wantClientAuth flag
+     * in the underlying implementation.
      */
     public void setNeedClientAuth(boolean needAuth) {
         this.needClientAuth = needAuth;
     }
     
     /**
-     * Getter for needClientAuth.
+     * Returns whether client authentication should be required.
      */
     public boolean getNeedClientAuth() {
         return this.needClientAuth;
     }
     
     /**
-     * Getter for wantClientAuth.
+     * Returns whether client authentication should be requested.
      */
     public boolean getWantClientAuth() {
         return this.wantClientAuth;
     }
     
     /**
-     * Setter for wantClientAuth.
-     * 
-     * When set to true, wantClientAuth will set SSLSockets' wantClientAuth to true forcing clients to provide
-     *      client certificates.
+     * Sets whether client authentication should be requested.
+     * Must be called before {@link #bind()}
+     * Note: Calling this method clears the needClientAuth flag
+     * in the underlying implementation.
      */
     public void setWantClientAuth(boolean wantAuth) {
         this.wantClientAuth = wantAuth;
Index: activemq-core/src/main/java/org/apache/activemq/transport/tcp/SslTransport.java
===================================================================
--- activemq-core/src/main/java/org/apache/activemq/transport/tcp/SslTransport.java	(revision 453741)
+++ activemq-core/src/main/java/org/apache/activemq/transport/tcp/SslTransport.java	(working copy)
@@ -18,21 +18,19 @@
 
 package org.apache.activemq.transport.tcp;
 
-import org.apache.activemq.wireformat.WireFormat;
 import org.apache.activemq.command.Command;
 import org.apache.activemq.command.ConnectionInfo;
-import org.apache.activemq.util.IntrospectionSupport;
+import org.apache.activemq.wireformat.WireFormat;
 
 import java.io.IOException;
 import java.net.URI;
+import java.net.UnknownHostException;
 import java.security.cert.X509Certificate;
-import java.util.Map;
 
-import javax.net.SocketFactory;
+import javax.net.ssl.SSLPeerUnverifiedException;
+import javax.net.ssl.SSLSession;
+import javax.net.ssl.SSLSocket;
 import javax.net.ssl.SSLSocketFactory;
-import javax.net.ssl.SSLSocket;
-import javax.net.ssl.SSLSession;
-import javax.net.ssl.SSLPeerUnverifiedException;
 
 /**
  * A Transport class that uses SSL and client-side certificate authentication.
@@ -44,7 +42,7 @@
  *      set before the socket is connected. Otherwise, unexpected situations may occur.
  * 
  */
-class SslTransport extends TcpTransport {
+public class SslTransport extends TcpTransport {
     /**
      * Connect to a remote node such as a Broker.
      * 
@@ -60,7 +58,9 @@
      */
     public SslTransport(WireFormat wireFormat, SSLSocketFactory socketFactory, URI remoteLocation, URI localLocation, boolean needClientAuth) throws IOException {
         super(wireFormat, socketFactory, remoteLocation, localLocation);
-        ((SSLSocket)this.socket).setNeedClientAuth(needClientAuth);
+        if (this.socket != null) {
+            ((SSLSocket)this.socket).setNeedClientAuth(needClientAuth);
+        }
     }
     
     /**
@@ -106,5 +106,13 @@
 
         super.doConsume(command);
     }
+
+    /**
+     * @return pretty print of 'this'
+     */
+    public String toString() {
+        return "ssl://"+socket.getInetAddress()+":"+socket.getPort();
+    }
+
 }
 
Index: activemq-core/src/main/java/org/apache/activemq/security/JaasCertificateSecurityContext.java
===================================================================
--- activemq-core/src/main/java/org/apache/activemq/security/JaasCertificateSecurityContext.java	(revision 0)
+++ activemq-core/src/main/java/org/apache/activemq/security/JaasCertificateSecurityContext.java	(revision 0)
@@ -0,0 +1,53 @@
+/**
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.activemq.security;
+
+import java.security.cert.X509Certificate;
+import java.util.Set;
+
+import javax.security.auth.Subject;
+
+/**
+ * Extends the SecurityContext to provide a username which is the
+ * Distinguished Name from the certificate.
+ *
+ */
+public class JaasCertificateSecurityContext extends SecurityContext {
+
+    private Subject subject;
+    private X509Certificate[] certs;
+  
+    public JaasCertificateSecurityContext(String userName, Subject subject, X509Certificate[] certs) {
+        super(userName);
+        this.subject = subject;
+        this.certs = certs;
+    }
+
+    public Set getPrincipals() {
+        return subject.getPrincipals();
+    }
+  
+    public String getUserName() {
+        if (certs != null && certs.length > 0) {
+            return certs[0].getSubjectDN().getName();
+        }
+        return super.getUserName();
+    }
+
+}
Index: activemq-core/src/main/java/org/apache/activemq/security/JaasCertificateAuthenticationBroker.java
===================================================================
--- activemq-core/src/main/java/org/apache/activemq/security/JaasCertificateAuthenticationBroker.java	(revision 453741)
+++ activemq-core/src/main/java/org/apache/activemq/security/JaasCertificateAuthenticationBroker.java	(working copy)
@@ -96,11 +96,11 @@
                             break;
                         }
                     }
-                    
-                    SecurityContext s = new JaasSecurityContext(dnName, subject);
+                    SecurityContext s = new JaasCertificateSecurityContext(
+                        dnName, subject, (X509Certificate[])info.getTransportContext());
                     context.setSecurityContext(s);
                 } catch (Exception e) {
-                    throw new SecurityException("User name or password is invalid.", e);
+                    throw new SecurityException("User name or password is invalid: " + e.getMessage(), e);
                 }
             } finally {
                 Thread.currentThread().setContextClassLoader(original);
Index: activemq-core/src/main/java/org/apache/activemq/broker/TransportConnector.java
===================================================================
--- activemq-core/src/main/java/org/apache/activemq/broker/TransportConnector.java	(revision 453741)
+++ activemq-core/src/main/java/org/apache/activemq/broker/TransportConnector.java	(working copy)
@@ -147,14 +147,21 @@
                     connection.start();
                 }
                 catch (Exception e) {
+                    String remoteHost = transport.getRemoteAddress();
                 	ServiceSupport.dispose(transport);
-                    onAcceptError(e);
+                    onAcceptError(e, remoteHost);
                 }
             }
 
             public void onAcceptError(Exception error) {
-                log.error("Could not accept connection: " + error, error);
+                onAcceptError(error,null);
             }
+
+            private void onAcceptError(Exception error, String remoteHost) {
+                log.error("Could not accept connection "  +
+                    (remoteHost == null ? "" : "from " + remoteHost)
+                    + ": " + error, error);
+            }
         });
         this.server.setBrokerInfo(brokerInfo);
     }
