Author: rgodfrey
Date: Mon Jan 13 16:57:08 2014
New Revision: 1557770

URL: http://svn.apache.org/r1557770
Log:
QPID-5475 : [Java Broker] add ability to use ssl client auth to REST api and 
HTTP management

Modified:
    
qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/SubjectCreator.java
    
qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
    
qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java
    
qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java
    
qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addPort.js
    
qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/Asserts.java
    
qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/QpidRestTestCase.java
    
qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/RestTestHelper.java
    
qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/SaslRestTest.java

Modified: 
qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/SubjectCreator.java
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/SubjectCreator.java?rev=1557770&r1=1557769&r2=1557770&view=diff
==============================================================================
--- 
qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/SubjectCreator.java
 (original)
+++ 
qpid/trunk/qpid/java/broker-core/src/main/java/org/apache/qpid/server/security/SubjectCreator.java
 Mon Jan 13 16:57:08 2014
@@ -37,6 +37,7 @@ import org.apache.qpid.server.security.a
 import org.apache.qpid.server.security.auth.SubjectAuthenticationResult;
 import 
org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManager;
 import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import 
org.apache.qpid.server.security.auth.manager.ExternalAuthenticationManager;
 
 /**
  * Creates a {@link Subject} formed by the {@link Principal}'s returned from:
@@ -129,6 +130,17 @@ public class SubjectCreator
         }
     }
 
+    public Subject createSubjectWithGroups(Principal principal)
+    {
+        Subject authenticationSubject = new Subject();
+
+        authenticationSubject.getPrincipals().add(principal);
+        
authenticationSubject.getPrincipals().addAll(getGroupPrincipals(principal.getName()));
+        authenticationSubject.setReadOnly();
+
+        return authenticationSubject;
+    }
+
     public Subject createSubjectWithGroups(String username)
     {
         Subject authenticationSubject = new Subject();
@@ -159,4 +171,9 @@ public class SubjectCreator
     {
         return _authenticationManager instanceof 
AnonymousAuthenticationManager;
     }
+
+    public boolean isExternalAuthenticationAllowed()
+    {
+        return _authenticationManager instanceof ExternalAuthenticationManager;
+    }
 }

Modified: 
qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java?rev=1557770&r1=1557769&r2=1557770&view=diff
==============================================================================
--- 
qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
 (original)
+++ 
qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagement.java
 Mon Jan 13 16:57:08 2014
@@ -23,15 +23,13 @@ package org.apache.qpid.server.managemen
 import java.lang.reflect.Type;
 import java.net.SocketAddress;
 import java.security.GeneralSecurityException;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.EnumSet;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Map;
-import java.util.UUID;
+import java.util.*;
 
+import javax.net.ssl.KeyManager;
 import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
 import org.apache.log4j.Logger;
 import org.apache.qpid.server.configuration.IllegalConfigurationException;
 import org.apache.qpid.server.logging.actors.CurrentActor;
@@ -77,6 +75,7 @@ import org.apache.qpid.server.model.Virt
 import org.apache.qpid.server.model.adapter.AbstractPluginAdapter;
 import org.apache.qpid.server.plugin.PluginFactory;
 import org.apache.qpid.server.util.MapValueConverter;
+import org.apache.qpid.transport.network.security.ssl.QpidMultipleTrustManager;
 import org.eclipse.jetty.server.Connector;
 import org.eclipse.jetty.server.DispatcherType;
 import org.eclipse.jetty.server.Server;
@@ -239,22 +238,82 @@ public class HttpManagement extends Abst
             else if (transports.contains(Transport.SSL))
             {
                 KeyStore keyStore = port.getKeyStore();
+                Collection<TrustStore> trustStores = port.getTrustStores();
                 if (keyStore == null)
                 {
                     throw new IllegalConfigurationException("Key store is not 
configured. Cannot start management on HTTPS port without keystore");
                 }
                 SslContextFactory factory = new SslContextFactory();
+                final boolean needClientAuth = 
Boolean.valueOf(String.valueOf(port.getAttribute(Port.NEED_CLIENT_AUTH)));
+                final boolean wantClientAuth = 
Boolean.valueOf(String.valueOf(port.getAttribute(Port.WANT_CLIENT_AUTH)));
+                boolean needClientCert = needClientAuth || wantClientAuth;
+                if (needClientCert && trustStores.isEmpty())
+                {
+                    throw new IllegalConfigurationException("Client 
certificate authentication is enabled on AMQP port '"
+                                                            + this.getName() + 
"' but no trust store defined");
+                }
+
                 try
                 {
                     SSLContext sslContext = SSLContext.getInstance("TLS");
-                    sslContext.init(keyStore.getKeyManagers(), null, null);
+                    KeyManager[] keyManagers = keyStore.getKeyManagers();
+
+                    TrustManager[] trustManagers;
+                    if(trustStores == null || trustStores.isEmpty())
+                    {
+                        trustManagers = null;
+                    }
+                    else if(trustStores.size() == 1)
+                    {
+                        trustManagers = 
trustStores.iterator().next().getTrustManagers();
+                    }
+                    else
+                    {
+                        Collection<TrustManager> trustManagerList = new 
ArrayList<TrustManager>();
+                        final QpidMultipleTrustManager mulTrustManager = new 
QpidMultipleTrustManager();
+
+                        for(TrustStore ts : trustStores)
+                        {
+                            TrustManager[] managers = ts.getTrustManagers();
+                            if(managers != null)
+                            {
+                                for(TrustManager manager : managers)
+                                {
+                                    if(manager instanceof X509TrustManager)
+                                    {
+                                        
mulTrustManager.addTrustManager((X509TrustManager)manager);
+                                    }
+                                    else
+                                    {
+                                        trustManagerList.add(manager);
+                                    }
+                                }
+                            }
+                        }
+                        if(!mulTrustManager.isEmpty())
+                        {
+                            trustManagerList.add(mulTrustManager);
+                        }
+                        trustManagers = trustManagerList.toArray(new 
TrustManager[trustManagerList.size()]);
+                    }
+                    sslContext.init(keyManagers, trustManagers, null);
+
                     factory.setSslContext(sslContext);
+                    if(needClientAuth)
+                    {
+                        factory.setNeedClientAuth(true);
+                    }
+                    else if(wantClientAuth)
+                    {
+                        factory.setWantClientAuth(true);
+                    }
                 }
                 catch (GeneralSecurityException e)
                 {
                     throw new RuntimeException("Cannot configure port " + 
port.getName() + " for transport " + Transport.SSL, e);
                 }
                 connector = new SslSocketConnector(factory);
+
             }
             else
             {

Modified: 
qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java?rev=1557770&r1=1557769&r2=1557770&view=diff
==============================================================================
--- 
qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java
 (original)
+++ 
qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java
 Mon Jan 13 16:57:08 2014
@@ -23,10 +23,14 @@ package org.apache.qpid.server.managemen
 import java.net.InetSocketAddress;
 import java.net.SocketAddress;
 import java.security.AccessControlException;
+import java.security.Principal;
 import java.security.PrivilegedActionException;
 import java.security.PrivilegedExceptionAction;
+import java.security.cert.X509Certificate;
+import java.util.Collections;
 
 import javax.security.auth.Subject;
+import javax.security.auth.x500.X500Principal;
 import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpSession;
@@ -36,11 +40,17 @@ import org.apache.qpid.server.logging.Lo
 import org.apache.qpid.server.logging.actors.CurrentActor;
 import org.apache.qpid.server.logging.actors.HttpManagementActor;
 import org.apache.qpid.server.management.plugin.session.LoginLogoutReporter;
+import org.apache.qpid.server.model.AuthenticationProvider;
 import org.apache.qpid.server.model.Broker;
 import org.apache.qpid.server.security.SecurityManager;
 import org.apache.qpid.server.security.SubjectCreator;
+import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
 import 
org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
 import org.apache.qpid.server.security.auth.SubjectAuthenticationResult;
+import org.apache.qpid.server.security.auth.UsernamePrincipal;
+import 
org.apache.qpid.server.security.auth.manager.ExternalAuthenticationManager;
+import 
org.apache.qpid.server.security.auth.manager.ExternalAuthenticationManagerFactory;
+import org.apache.qpid.transport.network.security.ssl.SSLUtil;
 
 public class HttpManagementUtil
 {
@@ -164,17 +174,41 @@ public class HttpManagementUtil
         session.setAttribute(ATTR_LOGIN_LOGOUT_REPORTER, new 
LoginLogoutReporter(logActor, subject));
     }
 
-    private static Subject tryToAuthenticate(HttpServletRequest request, 
HttpManagementConfiguration managementConfig)
+    public static Subject tryToAuthenticate(HttpServletRequest request, 
HttpManagementConfiguration managementConfig)
     {
         Subject subject = null;
         SocketAddress localAddress = getSocketAddress(request);
-        SubjectCreator subjectCreator = 
managementConfig.getAuthenticationProvider(localAddress).getSubjectCreator();
+        final AuthenticationProvider authenticationProvider = 
managementConfig.getAuthenticationProvider(localAddress);
+        SubjectCreator subjectCreator = 
authenticationProvider.getSubjectCreator();
         String remoteUser = request.getRemoteUser();
 
         if (remoteUser != null || 
subjectCreator.isAnonymousAuthenticationAllowed())
         {
             subject = authenticateUser(subjectCreator, remoteUser, null);
         }
+        else if(subjectCreator.isExternalAuthenticationAllowed()
+                && 
Collections.list(request.getAttributeNames()).contains("javax.servlet.request.X509Certificate"))
+        {
+            Principal principal = null;
+            X509Certificate[] certificates =
+                    (X509Certificate[]) 
request.getAttribute("javax.servlet.request.X509Certificate");
+            if(certificates != null && certificates.length != 0)
+            {
+                principal = certificates[0].getSubjectX500Principal();
+
+                
if(!Boolean.valueOf(String.valueOf(authenticationProvider.getAttribute(ExternalAuthenticationManagerFactory.ATTRIBUTE_USE_FULL_DN))))
+                {
+                    String username;
+                    String dn = ((X500Principal) 
principal).getName(X500Principal.RFC2253);
+
+
+                    username = SSLUtil.getIdFromSubjectDN(dn);
+                    principal = new  UsernamePrincipal(username);
+                }
+
+                subject = subjectCreator.createSubjectWithGroups(new 
AuthenticatedPrincipal(principal));
+            }
+        }
         else
         {
             String header = request.getHeader("Authorization");

Modified: 
qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java?rev=1557770&r1=1557769&r2=1557770&view=diff
==============================================================================
--- 
qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java
 (original)
+++ 
qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java
 Mon Jan 13 16:57:08 2014
@@ -284,6 +284,11 @@ public class SaslServlet extends Abstrac
     @Override
     protected Subject getAuthorisedSubject(HttpServletRequest request)
     {
-        return HttpManagementUtil.getAuthorisedSubject(request.getSession());
+        Subject subject = 
HttpManagementUtil.getAuthorisedSubject(request.getSession());
+        if(subject == null)
+        {
+            subject = HttpManagementUtil.tryToAuthenticate(request, 
HttpManagementUtil.getManagementConfiguration(getServletContext()));
+        }
+        return subject;
     }
 }

Modified: 
qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addPort.js
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addPort.js?rev=1557770&r1=1557769&r2=1557770&view=diff
==============================================================================
--- 
qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addPort.js
 (original)
+++ 
qpid/trunk/qpid/java/broker-plugins/management-http/src/main/java/resources/js/qpid/management/addPort.js
 Mon Jan 13 16:57:08 2014
@@ -110,7 +110,7 @@ define(["dojo/_base/xhr",
                 }
 
                 var type = dijit.byId("formAddPort.type").value;
-                if (type == "AMQP")
+                if (type == "AMQP" || type == "HTTP")
                 {
                     var transportWidget = 
registry.byId("formAddPort.transports");
                     var needClientAuth = 
dijit.byId("formAddPort.needClientAuth");
@@ -154,7 +154,7 @@ define(["dojo/_base/xhr",
             {
                 var clientAuthPanel = 
dojo.byId("formAddPort:fieldsClientAuth");
                 var display = clientAuthPanel.style.display;
-                if (transportType == "SSL" && protocolType == "AMQP")
+                if (transportType == "SSL" && (protocolType == "AMQP" || 
protocolType == "HTTP"))
                 {
                     clientAuthPanel.style.display = "block";
                     
registry.byId("formAddPort.needClientAuth").set("disabled", false);
@@ -212,8 +212,11 @@ define(["dojo/_base/xhr",
                                 });
 
                                 var isAMQP = ("AMQP" == newValue);
-                                
registry.byId("formAddPort.needClientAuth").set("enabled", isAMQP);
-                                
registry.byId("formAddPort.wantClientAuth").set("enabled", isAMQP);
+
+                                var isHTTP = ("HTTP" == newValue);
+
+                                
registry.byId("formAddPort.needClientAuth").set("enabled", isAMQP || isHTTP);
+                                
registry.byId("formAddPort.wantClientAuth").set("enabled", isAMQP || isHTTP);
 
                                 registry.byId("formAddPort:fields" + 
newValue).domNode.style.display = "block";
                                 var defaultsAMQPProtocols = 
registry.byId("formAddPort.protocolsDefault");

Modified: 
qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/Asserts.java
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/Asserts.java?rev=1557770&r1=1557769&r2=1557770&view=diff
==============================================================================
--- 
qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/Asserts.java
 (original)
+++ 
qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/Asserts.java
 Mon Jan 13 16:57:08 2014
@@ -126,7 +126,7 @@ public class Asserts
                 Queue.DISCARDS_TTL_MESSAGES, Queue.STATE_CHANGED);
     }
 
-    public static void assertAttributesPresent(Map<String, Object> data, 
String[] attributes)
+    public static void assertAttributesPresent(Map<String, Object> data, 
String... attributes)
     {
         for (String name : attributes)
         {

Modified: 
qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/QpidRestTestCase.java
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/QpidRestTestCase.java?rev=1557770&r1=1557769&r2=1557770&view=diff
==============================================================================
--- 
qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/QpidRestTestCase.java
 (original)
+++ 
qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/QpidRestTestCase.java
 Mon Jan 13 16:57:08 2014
@@ -35,6 +35,8 @@ import org.apache.qpid.test.utils.QpidBr
 public class QpidRestTestCase extends QpidBrokerTestCase
 {
     public static final String ANONYMOUS_AUTHENTICATION_PROVIDER = 
"testAnonymous";
+    public static final String EXTERNAL_AUTHENTICATION_PROVIDER = 
"testExternal";
+
     public static final String TEST1_VIRTUALHOST = "test";
     public static final String TEST2_VIRTUALHOST = "test2";
     public static final String TEST3_VIRTUALHOST = "test3";

Modified: 
qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/RestTestHelper.java
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/RestTestHelper.java?rev=1557770&r1=1557769&r2=1557770&view=diff
==============================================================================
--- 
qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/RestTestHelper.java
 (original)
+++ 
qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/RestTestHelper.java
 Mon Jan 13 16:57:08 2014
@@ -18,6 +18,8 @@
  */
 package org.apache.qpid.systest.rest;
 
+import static org.apache.qpid.test.utils.TestSSLConstants.KEYSTORE;
+import static org.apache.qpid.test.utils.TestSSLConstants.KEYSTORE_PASSWORD;
 import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE;
 import static org.apache.qpid.test.utils.TestSSLConstants.TRUSTSTORE_PASSWORD;
 
@@ -41,6 +43,7 @@ import java.util.List;
 import java.util.Map;
 
 import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.KeyManagerFactory;
 import javax.net.ssl.SSLContext;
 import javax.net.ssl.SSLSocketFactory;
 import javax.net.ssl.TrustManagerFactory;
@@ -65,16 +68,19 @@ import org.codehaus.jackson.type.TypeRef
 public class RestTestHelper
 {
     private static final Logger LOGGER = 
Logger.getLogger(RestTestHelper.class);
+    private static final String CERT_ALIAS_APP1 = "app1";
 
     private int _httpPort;
 
     private boolean _useSsl;
 
+
     private String _username;
 
     private String _password;
 
     private File _passwdFile;
+    private boolean _useSslAuth;
 
     public RestTestHelper(int httpPort)
     {
@@ -110,7 +116,30 @@ public class RestTestHelper
     {
         URL url = getManagementURL(path);
         HttpURLConnection httpCon = (HttpURLConnection) url.openConnection();
-        if(_useSsl)
+
+        if(_useSslAuth)
+        {
+            try
+            {
+                // We have to use a SSLSocketFactory from a new SSLContext so 
that we don't re-use
+                // the JVM's defaults that may have been initialised in 
previous tests.
+
+                SSLContext sslContext = SSLContextFactory.buildClientContext(
+                        TRUSTSTORE, TRUSTSTORE_PASSWORD,
+                        KeyStore.getDefaultType(),
+                        TrustManagerFactory.getDefaultAlgorithm(),
+                        KEYSTORE, KEYSTORE_PASSWORD, 
KeyStore.getDefaultType(), KeyManagerFactory.getDefaultAlgorithm(), 
CERT_ALIAS_APP1);
+
+                SSLSocketFactory sslSocketFactory = 
sslContext.getSocketFactory();
+
+                ((HttpsURLConnection) 
httpCon).setSSLSocketFactory(sslSocketFactory);
+            }
+            catch (GeneralSecurityException e)
+            {
+                throw new RuntimeException(e);
+            }
+        }
+        else if(_useSsl)
         {
             try
             {
@@ -475,4 +504,10 @@ public class RestTestHelper
         connection.connect();
         return readConnectionInputStream(connection);
     }
+
+    public void setUseSslAuth(final boolean useSslAuth)
+    {
+        _useSslAuth = useSslAuth;
+        _useSsl = true;
+    }
 }

Modified: 
qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/SaslRestTest.java
URL: 
http://svn.apache.org/viewvc/qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/SaslRestTest.java?rev=1557770&r1=1557769&r2=1557770&view=diff
==============================================================================
--- 
qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/SaslRestTest.java
 (original)
+++ 
qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/systest/rest/SaslRestTest.java
 Mon Jan 13 16:57:08 2014
@@ -55,6 +55,8 @@ public class SaslRestTest extends QpidRe
     public void startBrokerNow() throws Exception
     {
         super.startBroker();
+
+        getRestTestHelper().setUsernameAndPassword(null,null);
     }
 
     public void testGetMechanismsWithBrokerPlainPasswordPrincipalDatabase() 
throws Exception
@@ -71,7 +73,7 @@ public class SaslRestTest extends QpidRe
         {
             assertTrue("Mechanism " + mechanism + " is not found", 
mechanisms.contains(mechanism));
         }
-        assertNull("Unexpected user was returned", saslData.get("user"));
+        assertNull("Unexpected user was returned: " + saslData.get("user"), 
saslData.get("user"));
     }
 
     public void testGetMechanismsWithBrokerBase64MD5FilePrincipalDatabase() 
throws Exception
@@ -89,7 +91,8 @@ public class SaslRestTest extends QpidRe
         {
             assertTrue("Mechanism " + mechanism + " is not found", 
mechanisms.contains(mechanism));
         }
-        assertNull("Unexpected user was returned", saslData.get("user"));
+
+        assertNull("Unexpected user was returned: " + saslData.get("user"), 
saslData.get("user"));
     }
 
     public void testPlainSaslAuthenticationForValidCredentials() throws 
Exception



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to