[jboss-remoting-commits] JBoss Remoting SVN: r6120 - in remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test: security and 1 other directory.

jboss-remoting-commits at lists.jboss.org jboss-remoting-commits at lists.jboss.org
Wed Oct 20 00:17:44 EDT 2010


Author: ron.sigal at jboss.com
Date: 2010-10-20 00:17:43 -0400 (Wed, 20 Oct 2010)
New Revision: 6120

Added:
   remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/security/
   remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/security/AuthenticationTestCase.java
Log:
JBREM-1228: New unit test.

Added: remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/security/AuthenticationTestCase.java
===================================================================
--- remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/security/AuthenticationTestCase.java	                        (rev 0)
+++ remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/security/AuthenticationTestCase.java	2010-10-20 04:17:43 UTC (rev 6120)
@@ -0,0 +1,475 @@
+/*
+ * JBoss, Home of Professional Open Source
+ * Copyright 2010, 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.remoting3.test.security;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.fail;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.URI;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.Properties;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.ThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServerFactory;
+
+import org.jboss.marshalling.river.RiverProviderDescriptor;
+import org.jboss.remoting3.Client;
+import org.jboss.remoting3.ClientContext;
+import org.jboss.remoting3.ClientListener;
+import org.jboss.remoting3.CloseHandler;
+import org.jboss.remoting3.Connection;
+import org.jboss.remoting3.Endpoint;
+import org.jboss.remoting3.Registration;
+import org.jboss.remoting3.RemoteExecutionException;
+import org.jboss.remoting3.Remoting;
+import org.jboss.remoting3.RequestContext;
+import org.jboss.remoting3.RequestListener;
+import org.jboss.remoting3.Endpoint.ServiceBuilder;
+import org.jboss.remoting3.remote.RemoteProtocolDescriptor;
+import org.jboss.remoting3.security.ServerAuthenticationProvider;
+import org.jboss.remoting3.security.SimpleClientCallbackHandler;
+import org.jboss.remoting3.security.SimpleServerAuthenticationProvider;
+import org.jboss.remoting3.spi.ConnectionProviderFactory;
+import org.jboss.remoting3.spi.NetworkServerProvider;
+import org.jboss.remoting3.spi.ProtocolServiceType;
+import org.jboss.remoting3.spi.RemotingServiceDescriptor;
+import org.jboss.remoting3.test.RemotingTestBase;
+import org.jboss.xnio.ChannelListener;
+import org.jboss.xnio.IoFuture;
+import org.jboss.xnio.OptionMap;
+import org.jboss.xnio.Options;
+import org.jboss.xnio.TcpServer;
+import org.jboss.xnio.Xnio;
+import org.jboss.xnio.channels.BoundChannel;
+import org.jboss.xnio.channels.ConnectedStreamChannel;
+import org.jboss.xnio.log.Logger;
+import org.testng.annotations.AfterMethod;
+import org.testng.annotations.BeforeMethod;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+/**
+ * 
+ * @author <a href="ron.sigal at jboss.com">Ron Sigal</a>
+ * @version $Revision: 1.1 $
+ * <p>
+ * Copyright Jun 22, 2010
+ */
+ at Test(suiteName = "Authentication")
+public class AuthenticationTestCase extends RemotingTestBase {
+
+   private static final Logger log = Logger.getLogger(AuthenticationTestCase.class);
+   private static int counter;
+
+   protected static final String SERVICE = "service";
+   protected static final String INSTANCE = "instance";
+   
+   protected HashSet<String> mechanismSet = new HashSet<String>();
+   protected Endpoint serverEndpoint;
+   protected TestRequestListener requestListener;
+   protected int port;
+   
+   @BeforeTest
+   public void getSASLMechanisms() {
+      Enumeration<SaslServerFactory> e = Sasl.getSaslServerFactories();
+      while (e.hasMoreElements()) {
+         SaslServerFactory ssf = e.nextElement();
+         log.debug(ssf.toString());
+         String[] mechanisms = ssf.getMechanismNames(null);
+         for (int i = 0; i < mechanisms.length; i++) {
+            log.debug("mechanism: " + mechanisms[i]);
+            mechanismSet.add(mechanisms[i]);
+         }
+      }
+      log.debug("number of mechanims: " + mechanismSet.size());
+   }
+   
+   @BeforeMethod
+   public void setUp() {
+   }
+
+   @AfterMethod
+   public void tearDown() throws IOException {
+   }
+
+   @Test
+   public void testDIGEST_MD5() throws Exception {
+      enter();
+
+      try {
+         if (mechanismSet.contains("DIGEST-MD5")) {
+            log.debug("running DIGEST-MD5 test");
+            OptionMap clientOptionMap = OptionMap.EMPTY;
+            OptionMap serverOptionMap = OptionMap.builder().setSequence(Options.SASL_MECHANISMS, new String[]{"DIGEST-MD5"}).getMap();
+            doTest(clientOptionMap, serverOptionMap);            
+         } else {
+            log.info("DIGEST-MD5 mechanism is not supported. Unable to run test");
+         }
+         log.info(getName() + " PASSES");
+      } finally {
+         if (serverEndpoint != null) {
+            serverEndpoint.close();
+         }
+         exit();
+      }
+   }
+   
+   @Test
+   public void testCRAM_MD5() throws Exception {
+      enter();
+
+      try {
+         if (mechanismSet.contains("CRAM-MD5")) {
+            log.debug("running CRAM-MD5 test");
+            OptionMap clientOptionMap = OptionMap.EMPTY;
+            OptionMap serverOptionMap = OptionMap.builder().setSequence(Options.SASL_MECHANISMS, new String[]{"CRAM-MD5"}).getMap();
+            doTest(clientOptionMap, serverOptionMap);            
+         } else {
+            log.info("CRAM-MD5 mechanism is not supported. Unable to run test");
+         }
+         log.info(getName() + " PASSES");
+      } finally {
+         if (serverEndpoint != null) {
+            serverEndpoint.close();
+         }
+         exit();
+      }
+   }
+
+   @Test
+   public void testAnonymous() throws Exception {
+      enter();
+
+      try {
+         if (mechanismSet.contains("ANONYMOUS")) {
+            log.debug("running ANONYMOUS test");
+            OptionMap serverOptionMap = OptionMap.builder().setSequence(Options.SASL_MECHANISMS, new String[]{"ANONYMOUS"}).getMap();
+            
+            ServerAuthenticationProvider authenticationProvider = new ServerAuthenticationProvider() {
+               public CallbackHandler getCallbackHandler() {
+                  return null;
+               }
+            };
+            
+            int id = counter++;
+            setupServer(id, serverOptionMap, authenticationProvider);
+            Endpoint clientEndpoint = Remoting.getConfiguredEndpoint();
+            URI uri = null;
+            Connection connection = null;
+            Client<Object, Object> client = null;
+
+            try {
+               uri = new URI(getRemotingScheme() + "://localhost:" + port);
+               connection = getFutureResult(clientEndpoint.connect(uri), "cannot connect to " + uri);
+               log.debug("connected to " + uri);
+               client = getFutureResult(connection.openClient(SERVICE, INSTANCE, Object.class, Object.class), "cannot create client to " + SERVICE + ":" + INSTANCE);
+               assertNotNull(client.invoke("hello"));
+            } finally {
+               if (client != null) {
+                  client.close();
+               }
+               if (connection != null) {
+                  connection.close();
+               }
+            }
+            
+         } else {
+            log.info("ANONYMOUS mechanism is not supported. Unable to run test");
+         }
+         log.info(getName() + " PASSES");
+      } finally {
+         if (serverEndpoint != null) {
+            serverEndpoint.close();
+         }
+         exit();
+      }
+   }
+   
+   protected void doTest(OptionMap clientOptionMap, OptionMap serverOptionMap) throws Exception {
+      try {
+         int id = counter++;
+         String realm = "endpoint" + id;
+         SimpleServerAuthenticationProvider authenticationProvider = new SimpleServerAuthenticationProvider();
+         authenticationProvider.addUser("trustin", realm, "lee".toCharArray());
+         authenticationProvider.addUser("david", realm, "lloyd".toCharArray());
+         authenticationProvider.addUser("*", realm, "*".toCharArray());
+         setupServer(id, serverOptionMap, authenticationProvider);
+         Endpoint clientEndpoint = Remoting.getConfiguredEndpoint();
+         URI uri = null;
+         Connection connection = null;
+         Client<Object, Object> client = null;
+
+         try {
+            uri = new URI(getRemotingScheme() + "://localhost:" + port);
+            connection = getFutureResult(clientEndpoint.connect(uri, clientOptionMap, "trustin", realm, "lee".toCharArray()), "cannot connect to " + uri);
+            log.debug("connected to " + uri);
+            client = getFutureResult(connection.openClient(SERVICE, INSTANCE, Object.class, Object.class), "cannot create client to " + SERVICE + ":" + INSTANCE);
+            assertNotNull(client.invoke("hello"));
+         } finally {
+            if (client != null) {
+               client.close();
+            }
+            if (connection != null) {
+               connection.close();
+            }
+         }
+         
+         try {
+            uri = new URI(getRemotingScheme() + "://localhost:" + port);
+            connection = getFutureResult(clientEndpoint.connect(uri, clientOptionMap, "trustin", realm, "notlee".toCharArray()), "cannot connect to " + uri);
+         } catch (SaslException e) {
+            assertEquals("Authentication failed", e.getMessage());
+         } catch (Exception e) {
+            fail("expected SaslException");
+         } finally {
+            if (connection != null) {
+               connection.close();
+            }
+         }
+
+         try {
+            uri = new URI(getRemotingScheme() + "://localhost:" + port);
+            connection = getFutureResult(clientEndpoint.connect(uri, clientOptionMap, "nottrustin", realm, "lee".toCharArray()), "cannot connect to " + uri);
+         } catch (SaslException e) {
+            assertEquals("Authentication failed", e.getMessage());
+         } catch (Exception e) {
+            fail("expected SaslException");
+         } finally {
+            if (connection != null) {
+               connection.close();
+            }
+         }
+         
+         try {
+            uri = new URI(getRemotingScheme() + "://localhost:" + port);
+            CallbackHandler callbackHandler = new SimpleClientCallbackHandler("trustin", realm, "lee".toCharArray());
+            connection = getFutureResult(clientEndpoint.connect(uri, clientOptionMap, callbackHandler), "cannot connect to " + uri);
+            log.debug("connected to " + uri);
+            client = getFutureResult(connection.openClient(SERVICE, INSTANCE, Object.class, Object.class), "cannot create client to " + SERVICE + ":" + INSTANCE);
+            assertNotNull(client.invoke("hello"));
+         } finally {
+            if (client != null) {
+               client.close();
+            }
+            if (connection != null) {
+               connection.close();
+            }
+         }
+         
+         try {
+            uri = new URI(getRemotingScheme() + "://localhost:" + port);
+            CallbackHandler callbackHandler = new SimpleClientCallbackHandler("trustin", realm, "notlee".toCharArray());
+            connection = getFutureResult(clientEndpoint.connect(uri, clientOptionMap, callbackHandler), "cannot connect to " + uri);
+         } catch (SaslException e) {
+            assertEquals("Authentication failed", e.getMessage());
+         } catch (Exception e) {
+            fail("expected SaslException");
+         } finally {
+            if (connection != null) {
+               connection.close();
+            }
+         }
+         
+         try {
+            uri = new URI(getRemotingScheme() + "://localhost:" + port);
+            CallbackHandler callbackHandler = new SimpleClientCallbackHandler("nottrustin", realm, "lee".toCharArray());
+            connection = getFutureResult(clientEndpoint.connect(uri, clientOptionMap, callbackHandler), "cannot connect to " + uri);
+         } catch (SaslException e) {
+            assertEquals("Authentication failed", e.getMessage());
+         } catch (Exception e) {
+            fail("expected SaslException");
+         } finally {
+            if (connection != null) {
+               connection.close();
+            }
+         }
+         
+         // The following test fails because it doesn't specify a password.
+//         uri = new URI(getRemotingScheme() + "://trustin;" + realm + "@localhost:" + port);
+//         connection = getFutureResult(clientEndpoint.connect(uri), "cannot connect to " + uri);
+//         log.debug("connected to " + uri);
+//         client = getFutureResult(connection.openClient(SERVICE, INSTANCE, Object.class, Object.class), "cannot create client to " + SERVICE + ":" + INSTANCE);
+//         assertNotNull(client.invoke("hello"));
+         
+         try {
+            uri = new URI(getRemotingScheme() + "://localhost:" + port);
+            connection = getFutureResult(clientEndpoint.connect(uri, clientOptionMap, "*", realm, "*".toCharArray()), "cannot connect to " + uri);
+            log.debug("connected to " + uri);
+            client = getFutureResult(connection.openClient(SERVICE, INSTANCE, Object.class, Object.class), "cannot create client to " + SERVICE + ":" + INSTANCE);
+            assertNotNull(client.invoke("hello"));
+         } finally {
+            if (client != null) {
+               client.close();
+            }
+            if (connection != null) {
+               connection.close();
+            }
+         }
+      } finally {
+         if (serverEndpoint != null) {
+            serverEndpoint.close();
+         }
+      }
+   }
+   
+   protected String getRemotingScheme() {
+      return "remote";
+   }
+   
+   protected RemotingServiceDescriptor<ConnectionProviderFactory> getProtocolDescriptor() {
+      return new RemoteProtocolDescriptor();
+   }
+   
+   protected void setupServer(int id, OptionMap optionMap, ServerAuthenticationProvider authenticationProvider) throws IOException {
+
+      // Create and configure endpoint.
+      final ThreadPoolExecutor executor = new ThreadPoolExecutor(8, 64, 30, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(64));
+      serverEndpoint = Remoting.createEndpoint("endpoint" + id, executor, optionMap);
+      final Registration marshallerRegistration = serverEndpoint.addProtocolService(ProtocolServiceType.MARSHALLER_PROVIDER_DESCRIPTOR, "river", new RiverProviderDescriptor());
+      String xnioProviderId = "authentication-" + id;
+      Properties props = new Properties();
+      props.put("remote.xnio.provider", xnioProviderId);
+      final Registration transportRegistration = serverEndpoint.addConnectionProvider(getRemotingScheme(), getProtocolDescriptor().getService(props));
+      
+      // Register service with endpoint.
+      requestListener = new TestRequestListener(id);
+      ServiceBuilder<Object, Object> sb = serverEndpoint.serviceBuilder(Object.class, Object.class);
+      sb.setInstanceName("instance").setServiceType("service");
+      sb.setClientListener(new TestClientListener(requestListener));
+      final Registration serviceRegistration = sb.register();
+      
+      // Set up XNIO layer.
+      NetworkServerProvider provider = serverEndpoint.getConnectionProviderInterface(getRemotingScheme(), NetworkServerProvider.class);
+      ChannelListener<ConnectedStreamChannel<InetSocketAddress>> listener = provider.getServerListener(optionMap, authenticationProvider);
+      final Xnio xnio = Xnio.getInstance(xnioProviderId);
+      final TcpServer tcpServer = createTcpServer(xnio, optionMap, listener);
+      port = tcpServer.getChannels().iterator().next().getLocalAddress().getPort();
+
+      // Prepare to close everything.
+      serverEndpoint.addCloseHandler(new TestCloseHandler(serviceRegistration, transportRegistration, marshallerRegistration, tcpServer, xnio, executor));
+   }
+   
+   protected TcpServer createTcpServer(Xnio xnio, OptionMap optionMap, ChannelListener<ConnectedStreamChannel<InetSocketAddress>> listener) throws IOException {
+      log.debug(this + " creating TcpServer");
+      TcpServer tcpServer =  xnio.createTcpServer(listener, optionMap);
+      IoFuture<? extends BoundChannel<InetSocketAddress>> future = tcpServer.bind(new InetSocketAddress("localhost", 0));
+      getFutureResult(future, "unable to bind " + tcpServer);
+      return tcpServer;
+   }
+   
+   static class TestRequestListener implements RequestListener<Object, Object> {
+      public int counter = 0;
+      private int answer;
+
+      public TestRequestListener(int answer) {
+         this.answer = answer;
+      }
+
+      public void handleRequest(RequestContext<Object> context, Object request) throws RemoteExecutionException {
+         try {
+            counter++;
+            context.sendReply(answer);
+         } catch (IOException e) {
+            try {
+               context.sendFailure("error returning response", e);
+            } catch (IOException e1) {
+               e.printStackTrace();
+               throw new RemoteExecutionException("error returning exception", e1);
+            }
+         }
+      }
+   }
+   
+   static class TestClientListener implements ClientListener<Object, Object> {
+      private RequestListener<Object, Object> requestListener;
+
+      TestClientListener(RequestListener<Object, Object> requestListener) {
+         this.requestListener = requestListener;
+      }
+
+      public RequestListener<Object, Object> handleClientOpen(final ClientContext clientContext, final OptionMap optionMap) {
+         clientContext.addCloseHandler(new CloseHandler<ClientContext>() {
+            public void handleClose(final ClientContext closed) {
+               log.debug("Client closed");
+            }
+         });
+         return requestListener;
+      }
+   }
+   
+   static class TestCloseHandler implements CloseHandler<Endpoint> {
+      private Registration serviceRegistration;
+      private Registration transportRegistration;
+      private Registration marshallerRegistration;
+      private TcpServer tcpServer;
+      private Xnio xnio;
+      private ThreadPoolExecutor executor;
+      
+      public TestCloseHandler(Registration serviceRegistration, Registration transportRegistration, Registration marshallerRegistration, TcpServer tcpServer, Xnio xnio, ThreadPoolExecutor executor) {
+         this.marshallerRegistration = marshallerRegistration;
+         this.transportRegistration = transportRegistration;
+         this.serviceRegistration = serviceRegistration;
+         this.tcpServer = tcpServer;
+         this.xnio = xnio;
+         this.executor = executor;
+      }
+      
+      public void handleClose(Endpoint closed) {
+         if (serviceRegistration != null) {
+            serviceRegistration.close();
+         }
+         if (transportRegistration != null) {
+            transportRegistration.close();
+         }
+         if (marshallerRegistration != null) {
+            marshallerRegistration.close();
+         }
+         if (tcpServer != null) {
+            try {
+               tcpServer.close();
+            } catch (IOException e) {
+               log.error("unable to close " + tcpServer);
+            }
+         }
+         if (xnio != null) {
+            try {
+               xnio.close();
+            } catch (IOException e) {
+               log.error("unable to close " + xnio);
+            }
+         }
+         if (executor != null) {
+            executor.shutdown();
+         }
+      }
+   }
+}



More information about the jboss-remoting-commits mailing list