Author: david.lloyd(a)jboss.com
Date: 2010-02-28 10:51:38 -0500 (Sun, 28 Feb 2010)
New Revision: 5771
Added:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ClientAuthenticationHandler.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ClientGreetingHandler.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ClientOpenListener.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/GreetingUtils.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteConnection.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/SaslClientContext.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/SaslContext.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/SaslServerContext.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/SaslUnwrappingMessageHandler.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/SaslUtils.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ServerAuthenticationHandler.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ServerGreetingHandler.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ServerInitialAuthenticationHandler.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ServerOpenListener.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/security/ServerAuthenticationProvider.java
Removed:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteOpenListener.java
Modified:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/CloseHandler.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/EndpointImpl.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RemotingOptions.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/InboundReplyInputHandler.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/InboundRequestInputHandler.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundReplyBufferWriter.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundReplyHandler.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundRequestBufferWriter.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundRequestHandler.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteConnectionHandler.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteConnectionProvider.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteMessageHandler.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteProtocol.java
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ProtocolServiceType.java
remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/InvocationTestBase.java
remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/LocalTestCase.java
remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/RemoteTestCase.java
Log:
Add authentication layer
Modified:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/CloseHandler.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/CloseHandler.java 2010-02-28
00:58:32 UTC (rev 5770)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/CloseHandler.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -22,6 +22,8 @@
package org.jboss.remoting3;
+import java.util.EventListener;
+
/**
* A handler which is notified of a resource close.
*
@@ -30,7 +32,7 @@
* @apiviz.exclude
* @remoting.implement
*/
-public interface CloseHandler<T> {
+public interface CloseHandler<T> extends EventListener {
/**
* Receive a notification that the resource was closed.
Modified:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/EndpointImpl.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/EndpointImpl.java 2010-02-28
00:58:32 UTC (rev 5770)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/EndpointImpl.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -591,7 +591,8 @@
return expectedType.cast(provider.getProviderInterface());
}
- private <T> Registration addMarshallingRegistration(final String name, final T
target, final ConcurrentMap<String, T> map, final String descr) throws
DuplicateRegistrationException {
+ public <T> Registration addProtocolService(final ProtocolServiceType<T>
type, final String name, final T provider) throws DuplicateRegistrationException {
+ final ConcurrentMap<String, T> map = getMapFor(type);
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
sm.checkPermission(ADD_MARSHALLING_PROTOCOL_PERM);
@@ -599,16 +600,12 @@
if ("default".equals(name)) {
throw new IllegalArgumentException("'default' is not an allowed
name");
}
- if (map.putIfAbsent(name, target) != null) {
- throw new DuplicateRegistrationException(descr + " '" + name +
"' is already registered");
+ if (map.putIfAbsent(name, provider) != null) {
+ throw new DuplicateRegistrationException(type.getDescription() + "
'" + name + "' is already registered");
}
- return new MapRegistration<T>(map, name, target);
+ return new MapRegistration<T>(map, name, provider);
}
- public <T> Registration addProtocolService(final ProtocolServiceType<T>
type, final String name, final T provider) throws DuplicateRegistrationException {
- return addMarshallingRegistration(name, provider, getMapFor(type),
type.getDescription());
- }
-
public String toString() {
return "endpoint \"" + name + "\" <" +
Integer.toHexString(hashCode()) + ">";
}
Modified:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RemotingOptions.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RemotingOptions.java 2010-02-28
00:58:32 UTC (rev 5770)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/RemotingOptions.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -138,4 +138,14 @@
* Specify whether a local connection or client should call by reference (the usual
default) or value.
*/
public static final Option<Boolean> CALL_BY_VALUE =
Option.simple(RemotingOptions.class, "CALL_BY_VALUE", Boolean.class);
+
+ /**
+ * Specify the name of a preregistered server authentication provider to use.
+ */
+ public static final Option<String> AUTHENTICATION_PROVIDER =
Option.simple(RemotingOptions.class, "AUTHENTICATION_PROVIDER", String.class);
+
+ /**
+ * Specify a set of SASL server mechanisms to allow. If not specified, no mechanisms
will be excluded.
+ */
+ public static final Option<Sequence<String>> SASL_SERVER_MECHANISMS =
Option.sequence(RemotingOptions.class, "SASL_SERVER_MECHANISMS", String.class);
}
Added:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ClientAuthenticationHandler.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ClientAuthenticationHandler.java
(rev 0)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ClientAuthenticationHandler.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -0,0 +1,108 @@
+/*
+ * 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.remote;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import org.jboss.marshalling.MarshallerFactory;
+import org.jboss.marshalling.Marshalling;
+import org.jboss.marshalling.MarshallingConfiguration;
+import org.jboss.remoting3.CloseHandler;
+import org.jboss.remoting3.spi.ConnectionHandler;
+import org.jboss.remoting3.spi.ConnectionHandlerContext;
+import org.jboss.remoting3.spi.ConnectionHandlerFactory;
+import org.jboss.xnio.Buffers;
+import org.jboss.xnio.IoUtils;
+import org.jboss.xnio.Result;
+import org.jboss.xnio.channels.MessageHandler;
+
+import javax.security.sasl.SaslClient;
+import javax.security.sasl.SaslException;
+
+final class ClientAuthenticationHandler implements MessageHandler {
+
+ private final RemoteConnection remoteConnection;
+ private final SaslClient saslClient;
+ private final Result<ConnectionHandlerFactory> factoryResult;
+
+ public ClientAuthenticationHandler(final RemoteConnection remoteConnection, final
SaslClient saslClient, final Result<ConnectionHandlerFactory> factoryResult) {
+ this.remoteConnection = remoteConnection;
+ this.saslClient = saslClient;
+ this.factoryResult = factoryResult;
+ }
+
+ public void handleMessage(final ByteBuffer buffer) {
+ final byte msgType = buffer.get();
+ switch (msgType) {
+ case RemoteProtocol.AUTH_CHALLENGE:
+ case RemoteProtocol.AUTH_COMPLETE: {
+ final byte[] response;
+ try {
+ response = saslClient.evaluateChallenge(Buffers.take(buffer,
buffer.remaining()));
+ } catch (SaslException e) {
+ // todo log it
+ factoryResult.setException(e);
+ IoUtils.safeClose(remoteConnection);
+ return;
+ }
+ if (msgType == RemoteProtocol.AUTH_COMPLETE) {
+ if ((response != null || response.length > 0)) {
+ // todo log extraneous message
+ IoUtils.safeClose(remoteConnection);
+ return;
+ }
+ // auth complete.
+ factoryResult.setResult(new ConnectionHandlerFactory() {
+ public ConnectionHandler createInstance(final
ConnectionHandlerContext connectionContext) {
+ // this happens immediately.
+ final MarshallerFactory marshallerFactory =
Marshalling.getMarshallerFactory("river");
+ final MarshallingConfiguration marshallingConfiguration = new
MarshallingConfiguration();
+ final RemoteConnectionHandler connectionHandler = new
RemoteConnectionHandler(connectionContext, remoteConnection, marshallerFactory,
marshallingConfiguration);
+ remoteConnection.addCloseHandler(new
CloseHandler<Object>() {
+ public void handleClose(final Object closed) {
+ IoUtils.safeClose(connectionHandler);
+ }
+ });
+ remoteConnection.setMessageHandler(new
RemoteMessageHandler(connectionHandler, remoteConnection));
+ return connectionHandler;
+ }
+ });
+ return;
+ }
+ break;
+ }
+ }
+ }
+
+ public void handleEof() {
+ factoryResult.setException(new EOFException("End of file on input"));
+ IoUtils.safeClose(remoteConnection);
+ }
+
+ public void handleException(final IOException e) {
+ // todo log it
+ factoryResult.setException(e);
+ IoUtils.safeClose(remoteConnection);
+ }
+}
Added:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ClientGreetingHandler.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ClientGreetingHandler.java
(rev 0)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ClientGreetingHandler.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -0,0 +1,117 @@
+/*
+ * 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.remote;
+
+import java.io.EOFException;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import org.jboss.remoting3.RemotingOptions;
+import org.jboss.remoting3.spi.ConnectionHandlerFactory;
+import org.jboss.xnio.Buffers;
+import org.jboss.xnio.IoUtils;
+import org.jboss.xnio.Option;
+import org.jboss.xnio.OptionMap;
+import org.jboss.xnio.Result;
+import org.jboss.xnio.channels.MessageHandler;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslClient;
+import javax.security.sasl.SaslException;
+
+final class ClientGreetingHandler implements MessageHandler {
+ private final RemoteConnection connection;
+ private final Result<ConnectionHandlerFactory> factoryResult;
+ private final CallbackHandler callbackHandler;
+
+ public ClientGreetingHandler(final RemoteConnection connection, final
Result<ConnectionHandlerFactory> factoryResult, final CallbackHandler
callbackHandler) {
+ this.connection = connection;
+ this.factoryResult = factoryResult;
+ this.callbackHandler = callbackHandler;
+ }
+
+ public void handleMessage(final ByteBuffer buffer) {
+ List<String> saslMechs = new ArrayList<String>();
+ switch (buffer.get()) {
+ case RemoteProtocol.GREETING: {
+ while (buffer.hasRemaining()) {
+ final byte type = buffer.get();
+ final int len = buffer.get() & 0xff;
+ switch (type) {
+ case RemoteProtocol.GREETING_VERSION: {
+ // We only support version zero, so knowing the other
side's version is not useful presently
+ buffer.get();
+ if (len > 1) Buffers.skip(buffer, len - 1);
+ break;
+ }
+ case RemoteProtocol.GREETING_SASL_MECH: {
+ saslMechs.add(Buffers.getModifiedUtf8(Buffers.slice(buffer,
len)));
+ break;
+ }
+ default: {
+ // unknown, skip it for forward compatibility.
+ Buffers.skip(buffer, len);
+ break;
+ }
+ }
+ }
+ // OK now send our authentication request
+ final OptionMap optionMap = connection.getOptionMap();
+ final String userName = optionMap.get(RemotingOptions.AUTH_USER_NAME);
+ final String hostName =
connection.getChannel().getPeerAddress().getHostName();
+ final Map<String, ?> propertyMap =
SaslUtils.createPropertyMap(optionMap);
+ final SaslClient saslClient;
+ try {
+ saslClient = Sasl.createSaslClient(saslMechs.toArray(new
String[saslMechs.size()]), userName == null ? "anonymous" : userName,
"remote", hostName, propertyMap, callbackHandler);
+ } catch (SaslException e) {
+ factoryResult.setException(e);
+ // todo log exception @ error
+ // todo send "goodbye" & close
+ IoUtils.safeClose(connection);
+ return;
+ }
+ connection.setMessageHandler(new ClientAuthenticationHandler(connection,
saslClient, factoryResult));
+ return;
+ }
+ default: {
+ // todo log invalid greeting
+ IoUtils.safeClose(connection);
+ return;
+ }
+ }
+ }
+
+ public void handleEof() {
+ factoryResult.setException(new EOFException("End of file on input"));
+ IoUtils.safeClose(connection);
+ }
+
+ public void handleException(final IOException e) {
+ // todo log it
+ factoryResult.setException(e);
+ IoUtils.safeClose(connection);
+ }
+}
\ No newline at end of file
Added:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ClientOpenListener.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ClientOpenListener.java
(rev 0)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ClientOpenListener.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -0,0 +1,83 @@
+/*
+ * 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.remote;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import org.jboss.remoting3.spi.ConnectionHandlerFactory;
+import org.jboss.remoting3.spi.ConnectionProviderContext;
+import org.jboss.xnio.ChannelListener;
+import org.jboss.xnio.IoUtils;
+import org.jboss.xnio.OptionMap;
+import org.jboss.xnio.Options;
+import org.jboss.xnio.Result;
+import org.jboss.xnio.channels.ConnectedStreamChannel;
+
+import javax.security.auth.callback.CallbackHandler;
+
+final class ClientOpenListener implements
ChannelListener<ConnectedStreamChannel<InetSocketAddress>> {
+
+ private final OptionMap optionMap;
+ private final ConnectionProviderContext connectionProviderContext;
+ private final Result<ConnectionHandlerFactory> factoryResult;
+ private final CallbackHandler callbackHandler;
+
+ public ClientOpenListener(final OptionMap optionMap, final ConnectionProviderContext
connectionProviderContext, final Result<ConnectionHandlerFactory> factoryResult,
final CallbackHandler callbackHandler) {
+ this.optionMap = optionMap;
+ this.connectionProviderContext = connectionProviderContext;
+ this.factoryResult = factoryResult;
+ this.callbackHandler = callbackHandler;
+ }
+
+ public void handleEvent(final ConnectedStreamChannel<InetSocketAddress>
channel) {
+ try {
+ channel.setOption(Options.TCP_NODELAY, Boolean.TRUE);
+ } catch (IOException e) {
+ // ignore
+ }
+ final RemoteConnection connection = new
RemoteConnection(connectionProviderContext.getExecutor(), channel, optionMap);
+
+ // Send client greeting packet...
+ final ByteBuffer buffer = connection.allocate();
+ try {
+ // length placeholder
+ buffer.putInt(0);
+ // version ID
+ GreetingUtils.writeByte(buffer, RemoteProtocol.GREETING_VERSION,
RemoteProtocol.VERSION);
+ // that's it!
+ buffer.flip();
+ connection.sendBlocking(buffer);
+ } catch (IOException e1) {
+ // todo log it
+ factoryResult.setException(e1);
+ IoUtils.safeClose(connection);
+ } finally {
+ connection.free(buffer);
+ }
+
+ connection.setMessageHandler(new ClientGreetingHandler(connection, factoryResult,
callbackHandler));
+ // start up the read cycle
+ channel.resumeReads();
+ }
+}
\ No newline at end of file
Added:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/GreetingUtils.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/GreetingUtils.java
(rev 0)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/GreetingUtils.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -0,0 +1,53 @@
+/*
+ * 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.remote;
+
+import java.nio.ByteBuffer;
+import org.jboss.xnio.Buffers;
+
+final class GreetingUtils {
+
+ private GreetingUtils() {
+ }
+
+ static void writeString(ByteBuffer buffer, byte type, String data) {
+ buffer.put(type);
+ buffer.put((byte) 0); // length placeholder
+ int s = buffer.position();
+ Buffers.putModifiedUtf8(buffer, data);
+ final int len = buffer.position() - s;
+ if (len > 255) {
+ // truncate long name
+ buffer.position(s + 255);
+ buffer.put(s-1, (byte) 255);
+ } else {
+ buffer.put(s-1, (byte) len);
+ }
+ }
+
+ static void writeByte(ByteBuffer buffer, byte type, byte value) {
+ buffer.put(type);
+ buffer.put((byte) 1);
+ buffer.put(value);
+ }
+}
Modified:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/InboundReplyInputHandler.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/InboundReplyInputHandler.java 2010-02-28
00:58:32 UTC (rev 5770)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/InboundReplyInputHandler.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -43,8 +43,9 @@
buffer.put(RemoteProtocol.REQUEST_ACK_CHUNK);
buffer.putInt(rid);
buffer.flip();
- connectionHandler.sendBlocking(buffer);
- connectionHandler.flushBlocking();
+ final RemoteConnection connection = connectionHandler.getRemoteConnection();
+ connection.sendBlocking(buffer);
+ connection.flushBlocking();
} finally {
connectionHandler.getBufferPool().free(buffer);
}
Modified:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/InboundRequestInputHandler.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/InboundRequestInputHandler.java 2010-02-28
00:58:32 UTC (rev 5770)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/InboundRequestInputHandler.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -45,8 +45,9 @@
buffer.put(RemoteProtocol.REQUEST_ACK_CHUNK);
buffer.putInt(rid);
buffer.flip();
- connectionHandler.sendBlocking(buffer);
- connectionHandler.flushBlocking();
+ final RemoteConnection connection = connectionHandler.getRemoteConnection();
+ connection.sendBlocking(buffer);
+ connection.flushBlocking();
} catch (IOException e) {
RemoteConnectionHandler.log.trace(e, "Failed to acknowledge chunk for
%s", this);
} finally {
Modified:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundReplyBufferWriter.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundReplyBufferWriter.java 2010-02-28
00:58:32 UTC (rev 5770)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundReplyBufferWriter.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -73,14 +73,14 @@
buffer.put(7, (byte) (buffer.get(3) | RemoteProtocol.MSG_FLAG_LAST));
}
RemoteConnectionHandler.log.trace("Sending buffer %s for %s",
buffer, this);
- connectionHandler.sendBlocking(buffer);
+ connectionHandler.getRemoteConnection().sendBlocking(buffer);
} finally {
connectionHandler.getBufferPool().free(buffer);
}
}
public void flush() throws IOException {
- inboundRequest.getRemoteConnectionHandler().flushBlocking();
+
inboundRequest.getRemoteConnectionHandler().getRemoteConnection().flushBlocking();
}
public String toString() {
Modified:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundReplyHandler.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundReplyHandler.java 2010-02-28
00:58:32 UTC (rev 5770)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundReplyHandler.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -71,7 +71,7 @@
buffer.put(RemoteProtocol.REPLY_EXCEPTION_ABORT);
buffer.putInt(rid);
buffer.flip();
- connectionHandler.sendBlocking(buffer);
+ connectionHandler.getRemoteConnection().sendBlocking(buffer);
} finally {
bufferPool.free(buffer);
}
Modified:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundRequestBufferWriter.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundRequestBufferWriter.java 2010-02-28
00:58:32 UTC (rev 5770)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundRequestBufferWriter.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -73,13 +73,13 @@
}
}
RemoteConnectionHandler.log.trace("Sending buffer %s for %s",
buffer, this);
- remoteConnectionHandler.sendBlocking(buffer);
+ remoteConnectionHandler.getRemoteConnection().sendBlocking(buffer);
} finally {
remoteConnectionHandler.getBufferPool().free(buffer);
}
}
public void flush() throws IOException {
- outboundRequest.getRemoteConnectionHandler().flushBlocking();
+
outboundRequest.getRemoteConnectionHandler().getRemoteConnection().flushBlocking();
}
}
Modified:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundRequestHandler.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundRequestHandler.java 2010-02-28
00:58:32 UTC (rev 5770)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/OutboundRequestHandler.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -79,7 +79,7 @@
buf.putInt(rid);
buf.flip();
try {
- connectionHandler.sendBlocking(buf);
+ connectionHandler.getRemoteConnection().sendBlocking(buf);
} catch (IOException e1) {
// todo log it
}
@@ -100,7 +100,7 @@
buf.put(RemoteProtocol.CLIENT_CLOSED);
buf.putInt(outboundClient.getId());
buf.flip();
- connectionHandler.sendBlocking(buf);
+ connectionHandler.getRemoteConnection().sendBlocking(buf);
} finally {
bufferPool.free(buf);
}
Added:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteConnection.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteConnection.java
(rev 0)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteConnection.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -0,0 +1,178 @@
+/*
+ * 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.remote;
+
+import java.io.Closeable;
+import java.io.IOException;
+import java.io.InterruptedIOException;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.util.concurrent.Executor;
+import org.jboss.remoting3.spi.AbstractHandleableCloseable;
+import org.jboss.xnio.Buffers;
+import org.jboss.xnio.IoUtils;
+import org.jboss.xnio.OptionMap;
+import org.jboss.xnio.Pool;
+import org.jboss.xnio.channels.Channels;
+import org.jboss.xnio.channels.ConnectedChannel;
+import org.jboss.xnio.channels.ConnectedStreamChannel;
+import org.jboss.xnio.channels.MessageHandler;
+
+import javax.security.auth.callback.CallbackHandler;
+
+final class RemoteConnection extends AbstractHandleableCloseable<RemoteConnection>
implements Closeable {
+ private final ConnectedStreamChannel<InetSocketAddress> channel;
+ private final Pool<ByteBuffer> bufferPool =
Buffers.createHeapByteBufferAllocator(4096);
+ private final MessageHandler.Setter messageHandlerSetter;
+ private final OptionMap optionMap;
+
+ RemoteConnection(final Executor executor, final
ConnectedStreamChannel<InetSocketAddress> channel, final OptionMap optionMap) {
+ super(executor);
+ this.channel = channel;
+ messageHandlerSetter = Channels.createMessageReader(channel, optionMap);
+ this.optionMap = optionMap;
+ }
+
+ public void close() throws IOException {
+ channel.close();
+ }
+
+ OptionMap getOptionMap() {
+ return optionMap;
+ }
+
+ ConnectedChannel<InetSocketAddress> getChannel() {
+ return channel;
+ }
+
+ ByteBuffer allocate() {
+ return bufferPool.allocate();
+ }
+
+ void free(ByteBuffer buffer) {
+ bufferPool.free(buffer);
+ }
+
+ void setMessageHandler(MessageHandler handler) {
+ messageHandlerSetter.set(handler);
+ }
+
+ void sendBlocking(final ByteBuffer buffer) throws IOException {
+ try {
+ sendBlockingNoClose(buffer);
+ } catch (IOException e) {
+ IoUtils.safeClose(this);
+ throw e;
+ } catch (RuntimeException e) {
+ IoUtils.safeClose(this);
+ throw e;
+ } catch (Error e) {
+ IoUtils.safeClose(this);
+ throw e;
+ }
+ }
+
+ void sendBlockingNoClose(final ByteBuffer buffer) throws IOException {
+ buffer.putInt(0, buffer.remaining() - 4);
+ boolean intr = false;
+ try {
+ while (buffer.hasRemaining()) {
+ if (channel.write(buffer) == 0) {
+ try {
+ channel.awaitWritable();
+ } catch (InterruptedIOException e) {
+ intr = Thread.interrupted();
+ }
+ }
+ }
+ } finally {
+ if (intr) Thread.currentThread().interrupt();
+ }
+ }
+
+ void flushBlocking() throws IOException {
+ try {
+ while (! channel.flush()) {
+ channel.awaitWritable();
+ }
+ } catch (IOException e) {
+ IoUtils.safeClose(this);
+ throw e;
+ } catch (RuntimeException e) {
+ IoUtils.safeClose(this);
+ throw e;
+ } catch (Error e) {
+ IoUtils.safeClose(this);
+ throw e;
+ }
+ }
+
+ void shutdownWritesBlocking() throws IOException {
+ try {
+ while (! channel.shutdownWrites()) {
+ channel.awaitWritable();
+ }
+ } catch (IOException e) {
+ IoUtils.safeClose(this);
+ throw e;
+ } catch (RuntimeException e) {
+ IoUtils.safeClose(this);
+ throw e;
+ } catch (Error e) {
+ IoUtils.safeClose(this);
+ throw e;
+ }
+ }
+
+ void sendAuthReject(final String msg) throws IOException {
+ final ByteBuffer buf = allocate();
+ try {
+ buf.putInt(0);
+ buf.put(RemoteProtocol.AUTH_REJECTED);
+ Buffers.putModifiedUtf8(buf, msg);
+ buf.flip();
+ sendBlocking(buf);
+ flushBlocking();
+ } finally {
+ free(buf);
+ }
+ }
+
+ void sendAuthMessage(final byte msgType, final byte[] message) throws IOException {
+ final ByteBuffer buf = allocate();
+ try {
+ buf.putInt(0);
+ buf.put(msgType);
+ if (message != null) buf.put(message);
+ buf.flip();
+ sendBlocking(buf);
+ flushBlocking();
+ } finally {
+ free(buf);
+ }
+ }
+
+ void shutdownReads() throws IOException {
+ channel.shutdownReads();
+ }
+}
Modified:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteConnectionHandler.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteConnectionHandler.java 2010-02-28
00:58:32 UTC (rev 5770)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteConnectionHandler.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -23,7 +23,6 @@
package org.jboss.remoting3.remote;
import java.io.IOException;
-import java.io.InterruptedIOException;
import java.nio.ByteBuffer;
import java.util.Random;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -42,7 +41,7 @@
import org.jboss.xnio.IoUtils;
import org.jboss.xnio.Pool;
import org.jboss.xnio.Result;
-import org.jboss.xnio.channels.StreamChannel;
+import org.jboss.xnio.channels.Channels;
import org.jboss.xnio.log.Logger;
final class RemoteConnectionHandler implements ConnectionHandler {
@@ -56,7 +55,7 @@
private final MarshallingConfiguration marshallingConfiguration;
private final ConnectionHandlerContext connectionContext;
- private final StreamChannel channel;
+ private final RemoteConnection remoteConnection;
private final Random random = new Random();
private final IntKeyMap<OutboundClient> outboundClients = new
IntKeyMap<OutboundClient>();
@@ -67,63 +66,13 @@
private final AtomicBoolean closed = new AtomicBoolean();
- public RemoteConnectionHandler(final ConnectionHandlerContext connectionContext,
final StreamChannel channel, final MarshallerFactory marshallerFactory, final
MarshallingConfiguration marshallingConfiguration) {
+ public RemoteConnectionHandler(final ConnectionHandlerContext connectionContext,
final RemoteConnection remoteConnection, final MarshallerFactory marshallerFactory, final
MarshallingConfiguration marshallingConfiguration) {
this.connectionContext = connectionContext;
- this.channel = channel;
+ this.remoteConnection = remoteConnection;
this.marshallerFactory = marshallerFactory;
this.marshallingConfiguration = marshallingConfiguration;
}
- void sendBlocking(final ByteBuffer buffer) throws IOException {
- try {
- sendBlockingNoClose(buffer);
- } catch (IOException e) {
- IoUtils.safeClose(this);
- throw e;
- } catch (RuntimeException e) {
- IoUtils.safeClose(this);
- throw e;
- } catch (Error e) {
- IoUtils.safeClose(this);
- throw e;
- }
- }
-
- void sendBlockingNoClose(final ByteBuffer buffer) throws IOException {
- buffer.putInt(0, buffer.remaining() - 4);
- boolean intr = false;
- try {
- while (buffer.hasRemaining()) {
- if (channel.write(buffer) == 0) {
- try {
- channel.awaitWritable();
- } catch (InterruptedIOException e) {
- intr = Thread.interrupted();
- }
- }
- }
- } finally {
- if (intr) Thread.currentThread().interrupt();
- }
- }
-
- void flushBlocking() throws IOException {
- try {
- while (! channel.flush()) {
- channel.awaitWritable();
- }
- } catch (IOException e) {
- IoUtils.safeClose(this);
- throw e;
- } catch (RuntimeException e) {
- IoUtils.safeClose(this);
- throw e;
- } catch (Error e) {
- IoUtils.safeClose(this);
- throw e;
- }
- }
-
public Cancellable open(final String serviceType, final String groupName, final
Result<RequestHandler> result) {
final OutboundClient outboundClient;
int id;
@@ -143,7 +92,7 @@
Buffers.putModifiedUtf8(buffer, groupName);
buffer.put((byte) 0);
buffer.flip();
- sendBlocking(buffer);
+ remoteConnection.sendBlocking(buffer);
} catch (IOException e) {
result.setException(e);
} catch (Throwable e) {
@@ -161,7 +110,7 @@
public void close() throws IOException {
if (! closed.getAndSet(true)) {
try {
- channel.close();
+ remoteConnection.close();
} finally {
// other actions here
for (IntKeyMap.Entry<OutboundClient> entry : outboundClients) {
@@ -208,10 +157,6 @@
return connectionContext;
}
- StreamChannel getChannel() {
- return channel;
- }
-
Random getRandom() {
return random;
}
@@ -235,4 +180,8 @@
AtomicBoolean getClosed() {
return closed;
}
+
+ RemoteConnection getRemoteConnection() {
+ return remoteConnection;
+ }
}
Modified:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteConnectionProvider.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteConnectionProvider.java 2010-02-28
00:58:32 UTC (rev 5770)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteConnectionProvider.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -22,15 +22,17 @@
package org.jboss.remoting3.remote;
-import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.URI;
import java.net.UnknownHostException;
+import org.jboss.remoting3.RemotingOptions;
+import org.jboss.remoting3.security.ServerAuthenticationProvider;
import org.jboss.remoting3.spi.ConnectionHandlerFactory;
import org.jboss.remoting3.spi.ConnectionProvider;
import org.jboss.remoting3.spi.ConnectionProviderContext;
import org.jboss.remoting3.spi.NetworkServerProvider;
+import org.jboss.remoting3.spi.ProtocolServiceType;
import org.jboss.xnio.Cancellable;
import org.jboss.xnio.ChannelListener;
import org.jboss.xnio.Connector;
@@ -68,7 +70,7 @@
// Open a client channel
final IoFuture<? extends ConnectedStreamChannel<InetSocketAddress>>
futureChannel;
try {
- futureChannel = connector.connectTo(new
InetSocketAddress(InetAddress.getByName(host), port), new RemoteOpenListener(false,
connectOptions, connectionProviderContext, result), null);
+ futureChannel = connector.connectTo(new
InetSocketAddress(InetAddress.getByName(host), port), new
ClientOpenListener(connectOptions, connectionProviderContext, result, callbackHandler),
null);
} catch (UnknownHostException e) {
result.setException(e);
return IoUtils.nullCancellable();
@@ -82,20 +84,12 @@
private class ProviderInterface implements NetworkServerProvider {
public ChannelListener<ConnectedStreamChannel<InetSocketAddress>>
getServerListener(final OptionMap optionMap) {
- return new RemoteOpenListener(true, optionMap, connectionProviderContext, new
Result<ConnectionHandlerFactory>() {
- public boolean setResult(final ConnectionHandlerFactory result) {
- connectionProviderContext.accept(result);
- return true;
- }
-
- public boolean setException(final IOException exception) {
- return true;
- }
-
- public boolean setCancelled() {
- return true;
- }
- });
+ final String providerName =
optionMap.get(RemotingOptions.AUTHENTICATION_PROVIDER);
+ final ServerAuthenticationProvider authenticationProvider =
connectionProviderContext.getProtocolServiceProvider(ProtocolServiceType.SERVER_AUTHENTICATION_PROVIDER,
providerName == null ? "default" : providerName);
+ if (authenticationProvider == null) {
+ throw new IllegalArgumentException("Missing authentication provider:
" + (providerName == null ? "default" : providerName));
+ }
+ return new ServerOpenListener(optionMap, connectionProviderContext);
}
}
}
Modified:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteMessageHandler.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteMessageHandler.java 2010-02-28
00:58:32 UTC (rev 5770)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteMessageHandler.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -40,10 +40,12 @@
final class RemoteMessageHandler implements org.jboss.xnio.channels.MessageHandler {
- private RemoteConnectionHandler remoteConnectionHandler;
+ private final RemoteConnection connection;
+ private final RemoteConnectionHandler remoteConnectionHandler;
- public RemoteMessageHandler(final RemoteConnectionHandler remoteConnectionHandler) {
+ RemoteMessageHandler(final RemoteConnectionHandler remoteConnectionHandler, final
RemoteConnection connection) {
this.remoteConnectionHandler = remoteConnectionHandler;
+ this.connection = connection;
}
public void handleMessage(final ByteBuffer buffer) {
@@ -75,7 +77,7 @@
outBuf.putInt(id);
outBuf.flip();
try {
- connectionHandler.sendBlocking(outBuf);
+ connection.sendBlocking(outBuf);
} catch (IOException e) {
// the channel has suddenly failed
RemoteConnectionHandler.log.trace("Send failed: %s",
e);
@@ -302,7 +304,7 @@
return;
}
default: {
- RemoteConnectionHandler.log.error("Received invalid packet type on
%s, closing", connectionHandler.getChannel());
+ RemoteConnectionHandler.log.error("Received invalid packet type on
%s, closing", connectionHandler);
IoUtils.safeClose(connectionHandler);
}
}
Deleted:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteOpenListener.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteOpenListener.java 2010-02-28
00:58:32 UTC (rev 5770)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteOpenListener.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -1,73 +0,0 @@
-/*
- * 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.remote;
-
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import org.jboss.marshalling.MarshallerFactory;
-import org.jboss.marshalling.Marshalling;
-import org.jboss.marshalling.MarshallingConfiguration;
-import org.jboss.remoting3.spi.ConnectionHandler;
-import org.jboss.remoting3.spi.ConnectionHandlerContext;
-import org.jboss.remoting3.spi.ConnectionHandlerFactory;
-import org.jboss.remoting3.spi.ConnectionProviderContext;
-import org.jboss.xnio.ChannelListener;
-import org.jboss.xnio.OptionMap;
-import org.jboss.xnio.Options;
-import org.jboss.xnio.Result;
-import org.jboss.xnio.channels.Channels;
-import org.jboss.xnio.channels.ConnectedStreamChannel;
-
-final class RemoteOpenListener implements
ChannelListener<ConnectedStreamChannel<InetSocketAddress>> {
-
- private final boolean server;
- private final OptionMap optionMap;
- private final ConnectionProviderContext connectionProviderContext;
- private final Result<ConnectionHandlerFactory> factoryResult;
-
- public RemoteOpenListener(final boolean server, final OptionMap optionMap, final
ConnectionProviderContext connectionProviderContext, final
Result<ConnectionHandlerFactory> factoryResult) {
- this.server = server;
- this.optionMap = optionMap;
- this.connectionProviderContext = connectionProviderContext;
- this.factoryResult = factoryResult;
- }
-
- public void handleEvent(final ConnectedStreamChannel<InetSocketAddress>
channel) {
- try {
- channel.setOption(Options.TCP_NODELAY, Boolean.TRUE);
- } catch (IOException e) {
- // ignore
- }
- // TODO: For now, just build a pre-set-up connection without a negotiation phase
- factoryResult.setResult(new ConnectionHandlerFactory() {
- public ConnectionHandler createInstance(final ConnectionHandlerContext
connectionContext) {
- final MarshallerFactory marshallerFactory =
Marshalling.getMarshallerFactory("river");
- final MarshallingConfiguration marshallingConfiguration = new
MarshallingConfiguration();
- final RemoteConnectionHandler connectionHandler = new
RemoteConnectionHandler(connectionContext, channel, marshallerFactory,
marshallingConfiguration);
- Channels.createMessageReader(channel, optionMap).set(new
RemoteMessageHandler(connectionHandler));
- channel.resumeReads();
- return connectionHandler;
- }
- });
- }
-}
Modified:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteProtocol.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteProtocol.java 2010-02-28
00:58:32 UTC (rev 5770)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteProtocol.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -33,6 +33,11 @@
*/
public final class RemoteProtocol {
+ /**
+ * The highest-supported version of the remote protocol supported by this
implementation.
+ */
+ public static final byte VERSION = 0;
+
static final int MSG_FLAG_FIRST = 1;
static final int MSG_FLAG_LAST = 2;
@@ -49,6 +54,19 @@
static final byte REPLY_ACK_CHUNK = 10;
static final byte REPLY_EXCEPTION_ABORT = 11;
+ static final byte AUTH_REQUEST = 12;
+ static final byte AUTH_CHALLENGE = 13;
+ static final byte AUTH_RESPONSE = 14;
+ static final byte AUTH_COMPLETE = 15;
+ static final byte AUTH_REJECTED = 16;
+
+ static final byte ALIVE = 99;
+
+ // Greeting types
+
+ static final byte GREETING_VERSION = 0; // sent by client & server
+ static final byte GREETING_SASL_MECH = 1; // sent by server
+
/**
* Create an instance of the connection provider for the "remote"
protocol.
*
Added:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/SaslClientContext.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/SaslClientContext.java
(rev 0)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/SaslClientContext.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -0,0 +1,60 @@
+/*
+ * 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.remote;
+
+import java.nio.ByteBuffer;
+
+import javax.security.sasl.SaslClient;
+import javax.security.sasl.SaslException;
+
+final class SaslClientContext implements SaslContext {
+ private final SaslClient saslClient;
+
+ SaslClientContext(final SaslClient saslClient) {
+ this.saslClient = saslClient;
+ }
+
+ public String getMechanismName() {
+ return saslClient.getMechanismName();
+ }
+
+ public Object getNegotiatedProperty(final String name) {
+ return saslClient.getNegotiatedProperty(name);
+ }
+
+ public ByteBuffer unwrap(final ByteBuffer src) throws SaslException {
+ final byte[] unwrapped;
+ if (src.hasArray()) {
+ final byte[] orig = src.array();
+ final int start = src.arrayOffset() + src.position();
+ final int len = src.remaining();
+ unwrapped = saslClient.unwrap(orig, start, len);
+ } else {
+ final int len = src.remaining();
+ final byte[] orig = new byte[len];
+ src.get(orig);
+ unwrapped = saslClient.unwrap(orig, 0, len);
+ }
+ return ByteBuffer.wrap(unwrapped);
+ }
+}
Added:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/SaslContext.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/SaslContext.java
(rev 0)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/SaslContext.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -0,0 +1,35 @@
+/*
+ * 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.remote;
+
+import java.nio.ByteBuffer;
+
+import javax.security.sasl.SaslException;
+
+interface SaslContext {
+ String getMechanismName();
+
+ Object getNegotiatedProperty(String name);
+
+ ByteBuffer unwrap(ByteBuffer src) throws SaslException;
+}
Added:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/SaslServerContext.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/SaslServerContext.java
(rev 0)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/SaslServerContext.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -0,0 +1,60 @@
+/*
+ * 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.remote;
+
+import java.nio.ByteBuffer;
+
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
+
+final class SaslServerContext implements SaslContext {
+ private final SaslServer saslServer;
+
+ SaslServerContext(final SaslServer saslServer) {
+ this.saslServer = saslServer;
+ }
+
+ public String getMechanismName() {
+ return saslServer.getMechanismName();
+ }
+
+ public Object getNegotiatedProperty(final String name) {
+ return saslServer.getNegotiatedProperty(name);
+ }
+
+ public ByteBuffer unwrap(final ByteBuffer src) throws SaslException {
+ final byte[] unwrapped;
+ if (src.hasArray()) {
+ final byte[] orig = src.array();
+ final int start = src.arrayOffset() + src.position();
+ final int len = src.remaining();
+ unwrapped = saslServer.unwrap(orig, start, len);
+ } else {
+ final int len = src.remaining();
+ final byte[] orig = new byte[len];
+ src.get(orig);
+ unwrapped = saslServer.unwrap(orig, 0, len);
+ }
+ return ByteBuffer.wrap(unwrapped);
+ }
+}
Added:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/SaslUnwrappingMessageHandler.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/SaslUnwrappingMessageHandler.java
(rev 0)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/SaslUnwrappingMessageHandler.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -0,0 +1,59 @@
+/*
+ * 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.remote;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import org.jboss.xnio.channels.MessageHandler;
+
+import javax.security.sasl.SaslException;
+
+final class SaslUnwrappingMessageHandler implements MessageHandler, MessageHandler.Setter
{
+ private final SaslContext saslContext;
+ private volatile MessageHandler delegate;
+
+ SaslUnwrappingMessageHandler(final SaslContext saslContext, final MessageHandler
delegate) {
+ this.saslContext = saslContext;
+ this.delegate = delegate;
+ }
+
+ public void handleMessage(final ByteBuffer buffer) {
+ try {
+ delegate.handleMessage(saslContext.unwrap(buffer));
+ } catch (SaslException e) {
+ delegate.handleException(e);
+ }
+ }
+
+ public void handleEof() {
+ delegate.handleEof();
+ }
+
+ public void handleException(final IOException e) {
+ delegate.handleException(e);
+ }
+
+ public void set(final MessageHandler messageHandler) {
+ delegate = messageHandler;
+ }
+}
Added:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/SaslUtils.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/SaslUtils.java
(rev 0)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/SaslUtils.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -0,0 +1,108 @@
+/*
+ * 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.remote;
+
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.Map;
+import java.util.Set;
+import org.jboss.xnio.Buffers;
+import org.jboss.xnio.Option;
+import org.jboss.xnio.OptionMap;
+import org.jboss.xnio.Options;
+import org.jboss.xnio.SaslQop;
+import org.jboss.xnio.Sequence;
+
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslClient;
+import javax.security.sasl.SaslException;
+
+final class SaslUtils {
+
+ private SaslUtils() {
+ }
+
+ static final byte[] EMPTY = new byte[0];
+
+ static Map<String, Object> createPropertyMap(OptionMap optionMap) {
+ final Map<String,Object> propertyMap = new HashMap<String,
Object>();
+
+ add(optionMap, Options.SASL_POLICY_FORWARD_SECRECY, propertyMap,
Sasl.POLICY_FORWARD_SECRECY);
+ add(optionMap, Options.SASL_POLICY_NOACTIVE, propertyMap, Sasl.POLICY_NOACTIVE);
+ add(optionMap, Options.SASL_POLICY_NOANONYMOUS, propertyMap,
Sasl.POLICY_NOANONYMOUS);
+ add(optionMap, Options.SASL_POLICY_NODICTIONARY, propertyMap,
Sasl.POLICY_NODICTIONARY);
+ add(optionMap, Options.SASL_POLICY_NOPLAINTEXT, propertyMap,
Sasl.POLICY_NOPLAINTEXT);
+ add(optionMap, Options.SASL_POLICY_PASS_CREDENTIALS, propertyMap,
Sasl.POLICY_PASS_CREDENTIALS);
+ add(optionMap, Options.SASL_REUSE, propertyMap, Sasl.REUSE);
+ add(optionMap, Options.SASL_SERVER_AUTH, propertyMap, Sasl.SERVER_AUTH);
+ addQopList(optionMap, Options.SASL_QOP, propertyMap, Sasl.QOP);
+ add(optionMap, Options.SASL_STRENGTH, propertyMap, Sasl.STRENGTH);
+ return propertyMap;
+ }
+
+ private static void add(OptionMap optionMap, Option<?> option, Map<String,
Object> map, String propName) {
+ final Object value = optionMap.get(option);
+ if (value != null) map.put(propName, value.toString().toLowerCase());
+ }
+
+ private static void addQopList(OptionMap optionMap,
Option<Sequence<SaslQop>> option, Map<String, Object> map, String
propName) {
+ final Sequence<SaslQop> seq = optionMap.get(option);
+ final StringBuilder builder = new StringBuilder();
+ final Iterator<SaslQop> iterator = seq.iterator();
+ while (iterator.hasNext()) {
+ builder.append(iterator.next());
+ if (iterator.hasNext()) {
+ builder.append(',');
+ }
+ }
+ }
+
+ private static final Set<String> SECURE_QOP;
+
+ static {
+ final Set<String> set = new HashSet<String>();
+ set.add("auth-int");
+ set.add("auth-conf");
+ SECURE_QOP = set;
+ }
+
+ static boolean isSecureQop(Object qop) {
+ return SECURE_QOP.contains(qop);
+ }
+
+ static void wrapFramed(SaslClient saslClient, ByteBuffer message) throws
SaslException {
+ final byte[] result;
+ if (message.hasArray()) {
+ result = saslClient.wrap(message.array(), message.arrayOffset() + 4,
message.position());
+ } else {
+ final int end = message.position();
+ message.position(4);
+ final byte[] bytes = Buffers.take(message, end - 4);
+ result = saslClient.wrap(bytes, 0, bytes.length);
+ }
+ message.position(4);
+ message.put(result);
+ }
+}
Added:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ServerAuthenticationHandler.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ServerAuthenticationHandler.java
(rev 0)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ServerAuthenticationHandler.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -0,0 +1,104 @@
+/*
+ * 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.remote;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import org.jboss.marshalling.MarshallerFactory;
+import org.jboss.marshalling.Marshalling;
+import org.jboss.marshalling.MarshallingConfiguration;
+import org.jboss.remoting3.CloseHandler;
+import org.jboss.remoting3.spi.ConnectionHandler;
+import org.jboss.remoting3.spi.ConnectionHandlerContext;
+import org.jboss.remoting3.spi.ConnectionHandlerFactory;
+import org.jboss.remoting3.spi.ConnectionProviderContext;
+import org.jboss.xnio.Buffers;
+import org.jboss.xnio.IoUtils;
+import org.jboss.xnio.channels.MessageHandler;
+
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
+
+final class ServerAuthenticationHandler implements MessageHandler {
+ private final RemoteConnection remoteConnection;
+ private final SaslServer saslServer;
+ private final ConnectionProviderContext connectionProviderContext;
+
+ ServerAuthenticationHandler(final RemoteConnection remoteConnection, final SaslServer
saslServer, final ConnectionProviderContext connectionProviderContext) {
+ this.saslServer = saslServer;
+ this.remoteConnection = remoteConnection;
+ this.connectionProviderContext = connectionProviderContext;
+ }
+
+ public void handleMessage(final ByteBuffer buffer) {
+ switch (buffer.get()) {
+ case RemoteProtocol.AUTH_RESPONSE: {
+ final byte[] challenge;
+ try {
+ try {
+ challenge = saslServer.evaluateResponse(Buffers.take(buffer,
buffer.remaining()));
+ } catch (SaslException e) {
+ // todo log it
+ remoteConnection.sendAuthReject("Authentication
failed");
+ return;
+ }
+ final boolean complete = saslServer.isComplete();
+ if (complete) {
+ remoteConnection.sendAuthMessage(RemoteProtocol.AUTH_COMPLETE,
challenge);
+ connectionProviderContext.accept(new ConnectionHandlerFactory()
{
+ public ConnectionHandler createInstance(final
ConnectionHandlerContext connectionContext) {
+ final MarshallerFactory marshallerFactory =
Marshalling.getMarshallerFactory("river");
+ final MarshallingConfiguration marshallingConfiguration =
new MarshallingConfiguration();
+ final RemoteConnectionHandler connectionHandler = new
RemoteConnectionHandler(connectionContext, remoteConnection, marshallerFactory,
marshallingConfiguration);
+ remoteConnection.addCloseHandler(new
CloseHandler<Object>() {
+ public void handleClose(final Object closed) {
+ IoUtils.safeClose(connectionHandler);
+ }
+ });
+ remoteConnection.setMessageHandler(new
RemoteMessageHandler(connectionHandler, remoteConnection));
+ return connectionHandler;
+ }
+ });
+ } else {
+ remoteConnection.sendAuthMessage(RemoteProtocol.AUTH_CHALLENGE,
challenge);
+ }
+ } catch (IOException e) {
+ // todo log it; close channel
+ IoUtils.safeClose(remoteConnection);
+ }
+ }
+ default: {
+ // todo log invalid msg
+ IoUtils.safeClose(remoteConnection);
+ }
+ }
+ }
+
+ public void handleEof() {
+ IoUtils.safeClose(remoteConnection);
+ }
+
+ public void handleException(final IOException e) {
+ IoUtils.safeClose(remoteConnection);
+ }
+}
Added:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ServerGreetingHandler.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ServerGreetingHandler.java
(rev 0)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ServerGreetingHandler.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -0,0 +1,88 @@
+/*
+ * 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.remote;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Map;
+import java.util.Set;
+import org.jboss.remoting3.security.ServerAuthenticationProvider;
+import org.jboss.remoting3.spi.ConnectionProviderContext;
+import org.jboss.xnio.Buffers;
+import org.jboss.xnio.IoUtils;
+import org.jboss.xnio.channels.MessageHandler;
+
+final class ServerGreetingHandler implements MessageHandler {
+ private final RemoteConnection connection;
+ private final ConnectionProviderContext connectionProviderContext;
+ private final Set<String> saslMechs;
+ private final ServerAuthenticationProvider provider;
+ private final Map<String, Object> propertyMap;
+
+ public ServerGreetingHandler(final RemoteConnection connection, final
ConnectionProviderContext connectionProviderContext, final Set<String> saslMechs,
final ServerAuthenticationProvider provider, final Map<String, Object> propertyMap)
{
+ this.connection = connection;
+ this.connectionProviderContext = connectionProviderContext;
+ this.saslMechs = saslMechs;
+ this.provider = provider;
+ this.propertyMap = propertyMap;
+ }
+
+ public void handleMessage(final ByteBuffer buffer) {
+ switch (buffer.get()) {
+ case RemoteProtocol.GREETING: {
+ while (buffer.hasRemaining()) {
+ final byte type = buffer.get();
+ final int len = buffer.get() & 0xff;
+ switch (type) {
+ case RemoteProtocol.GREETING_VERSION: {
+ // We only support version zero, so knowing the other
side's version is not useful presently
+ buffer.get();
+ if (len > 1) Buffers.skip(buffer, len - 1);
+ break;
+ }
+ default: {
+ // unknown, skip it for forward compatibility.
+ Buffers.skip(buffer, len);
+ break;
+ }
+ }
+ }
+ connection.setMessageHandler(new
ServerInitialAuthenticationHandler(connection, propertyMap, saslMechs, provider,
connectionProviderContext));
+ return;
+ }
+ default: {
+ // todo log invalid greeting
+ IoUtils.safeClose(connection);
+ }
+ }
+ }
+
+ public void handleEof() {
+ IoUtils.safeClose(connection);
+ }
+
+ public void handleException(final IOException e) {
+ // todo log it
+ IoUtils.safeClose(connection);
+ }
+}
Added:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ServerInitialAuthenticationHandler.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ServerInitialAuthenticationHandler.java
(rev 0)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ServerInitialAuthenticationHandler.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -0,0 +1,92 @@
+/*
+ * 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.remote;
+
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.Map;
+import java.util.Set;
+import org.jboss.remoting3.security.ServerAuthenticationProvider;
+import org.jboss.remoting3.spi.ConnectionProviderContext;
+import org.jboss.xnio.Buffers;
+import org.jboss.xnio.IoUtils;
+import org.jboss.xnio.channels.MessageHandler;
+
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslServer;
+
+final class ServerInitialAuthenticationHandler implements MessageHandler {
+ private final RemoteConnection remoteConnection;
+ private final Map<String, ?> saslPropertyMap;
+ private final Set<String> allowedMechsMap;
+ private final ServerAuthenticationProvider authenticationProvider;
+ private final ConnectionProviderContext connectionProviderContext;
+
+ ServerInitialAuthenticationHandler(final RemoteConnection remoteConnection, final
Map<String, ?> saslPropertyMap, final Set<String> allowedMechsMap, final
ServerAuthenticationProvider authenticationProvider, final ConnectionProviderContext
connectionProviderContext) {
+ this.remoteConnection = remoteConnection;
+ this.saslPropertyMap = saslPropertyMap;
+ this.allowedMechsMap = allowedMechsMap;
+ this.authenticationProvider = authenticationProvider;
+ this.connectionProviderContext = connectionProviderContext;
+ }
+
+ public void handleMessage(final ByteBuffer buffer) {
+ switch (buffer.get()) {
+ case RemoteProtocol.AUTH_REQUEST: {
+ try {
+ // mech name
+ final String name = Buffers.getModifiedUtf8(buffer);
+ if (allowedMechsMap.contains(name)) {
+ final SaslServer server = Sasl.createSaslServer(name,
"remote", remoteConnection.getChannel().getLocalAddress().getHostName(),
saslPropertyMap, authenticationProvider.getCallbackHandler());
+ remoteConnection.setMessageHandler(new
ServerAuthenticationHandler(remoteConnection, server, connectionProviderContext));
+ remoteConnection.sendAuthMessage(RemoteProtocol.AUTH_CHALLENGE,
SaslUtils.EMPTY);
+ return;
+ } else {
+ remoteConnection.sendAuthReject("Invalid mechanism
name");
+ return;
+ }
+ } catch (IOException e) {
+ IoUtils.safeClose(remoteConnection);
+ // todo log it
+ return;
+ }
+ }
+ default: {
+ // todo log invalid msg
+ IoUtils.safeClose(remoteConnection);
+ }
+ }
+ }
+
+ public void handleEof() {
+ try {
+ remoteConnection.shutdownReads();
+ } catch (IOException e) {
+ // todo log it
+ }
+ }
+
+ public void handleException(final IOException e) {
+ // todo log it
+ }
+}
Copied:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ServerOpenListener.java
(from rev 5760,
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/RemoteOpenListener.java)
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ServerOpenListener.java
(rev 0)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/remote/ServerOpenListener.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -0,0 +1,114 @@
+/*
+ * 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.remote;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.nio.ByteBuffer;
+import java.util.Enumeration;
+import java.util.HashSet;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+import org.jboss.remoting3.RemotingOptions;
+import org.jboss.remoting3.security.ServerAuthenticationProvider;
+import org.jboss.remoting3.spi.ConnectionProviderContext;
+import org.jboss.remoting3.spi.ProtocolServiceType;
+import org.jboss.xnio.ChannelListener;
+import org.jboss.xnio.IoUtils;
+import org.jboss.xnio.OptionMap;
+import org.jboss.xnio.Options;
+import org.jboss.xnio.Sequence;
+import org.jboss.xnio.channels.ConnectedStreamChannel;
+
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslServerFactory;
+
+final class ServerOpenListener implements
ChannelListener<ConnectedStreamChannel<InetSocketAddress>> {
+
+ private final OptionMap optionMap;
+ private final ConnectionProviderContext connectionProviderContext;
+
+ ServerOpenListener(final OptionMap optionMap, final ConnectionProviderContext
connectionProviderContext) {
+ this.optionMap = optionMap;
+ this.connectionProviderContext = connectionProviderContext;
+ }
+
+ public void handleEvent(final ConnectedStreamChannel<InetSocketAddress>
channel) {
+ try {
+ channel.setOption(Options.TCP_NODELAY, Boolean.TRUE);
+ } catch (IOException e) {
+ // ignore
+ }
+ final RemoteConnection connection = new
RemoteConnection(connectionProviderContext.getExecutor(), channel, optionMap);
+
+ // Calculate available server mechanisms
+ final Sequence<String> mechs =
optionMap.get(RemotingOptions.SASL_SERVER_MECHANISMS);
+ final Set<String> includes = mechs != null ? new
HashSet<String>(mechs) : null;
+ final Set<String> serverMechanisms = new LinkedHashSet<String>();
+ final Map<String, Object> propertyMap =
SaslUtils.createPropertyMap(optionMap);
+ final Enumeration<SaslServerFactory> e = Sasl.getSaslServerFactories();
+ while (e.hasMoreElements()) {
+ final SaslServerFactory saslServerFactory = e.nextElement();
+ for (String name : saslServerFactory.getMechanismNames(propertyMap)) {
+ if (includes == null || includes.contains(name)) {
+ serverMechanisms.add(name);
+ }
+ }
+ }
+
+ // Send server greeting packet...
+ final ByteBuffer buffer = connection.allocate();
+ try {
+ // length placeholder
+ buffer.putInt(0);
+ // version ID
+ GreetingUtils.writeByte(buffer, RemoteProtocol.GREETING_VERSION,
RemoteProtocol.VERSION);
+ // SASL server mechs
+ for (String name : serverMechanisms) {
+ GreetingUtils.writeString(buffer, RemoteProtocol.GREETING_SASL_MECH,
name);
+ }
+ // that's it!
+ buffer.flip();
+ connection.sendBlocking(buffer);
+ } catch (Exception e1) {
+ // todo log it
+ IoUtils.safeClose(connection);
+ } finally {
+ connection.free(buffer);
+ }
+ final String authProvider =
optionMap.get(RemotingOptions.AUTHENTICATION_PROVIDER);
+ if (authProvider == null) {
+ // todo log no valid auth provider
+ IoUtils.safeClose(connection);
+ }
+ final ServerAuthenticationProvider provider =
connectionProviderContext.getProtocolServiceProvider(ProtocolServiceType.SERVER_AUTHENTICATION_PROVIDER,
authProvider);
+ if (provider == null) {
+ // todo log no valid auth provider
+ IoUtils.safeClose(connection);
+ }
+ connection.setMessageHandler(new ServerGreetingHandler(connection,
connectionProviderContext, serverMechanisms, provider, propertyMap));
+ // start up the read cycle
+ channel.resumeReads();
+ }
+}
Added:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/security/ServerAuthenticationProvider.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/security/ServerAuthenticationProvider.java
(rev 0)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/security/ServerAuthenticationProvider.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -0,0 +1,32 @@
+/*
+ * 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.security;
+
+import javax.security.auth.callback.CallbackHandler;
+
+/**
+ *
+ */
+public interface ServerAuthenticationProvider {
+ CallbackHandler getCallbackHandler();
+}
Modified:
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ProtocolServiceType.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ProtocolServiceType.java 2010-02-28
00:58:32 UTC (rev 5770)
+++
remoting3/trunk/jboss-remoting/src/main/java/org/jboss/remoting3/spi/ProtocolServiceType.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -29,6 +29,7 @@
import org.jboss.marshalling.ClassExternalizerFactory;
import org.jboss.marshalling.ProviderDescriptor;
import java.io.Serializable;
+import org.jboss.remoting3.security.ServerAuthenticationProvider;
public final class ProtocolServiceType<T> implements Serializable {
@@ -77,6 +78,8 @@
public static final ProtocolServiceType<ClassExternalizerFactory>
CLASS_EXTERNALIZER_FACTORY;
+ public static final ProtocolServiceType<ServerAuthenticationProvider>
SERVER_AUTHENTICATION_PROVIDER;
+
private static final ProtocolServiceType<?>[] SERVICE_TYPES;
public static ProtocolServiceType<?>[] getServiceTypes() {
@@ -96,6 +99,7 @@
CLASS_RESOLVER = new
ProtocolServiceType<ClassResolver>(ClassResolver.class, "CLASS_RESOLVER",
"Class resolver", index++),
OBJECT_RESOLVER = new
ProtocolServiceType<ObjectResolver>(ObjectResolver.class,
"OBJECT_RESOLVER", "Object resolver", index++),
CLASS_EXTERNALIZER_FACTORY = new
ProtocolServiceType<ClassExternalizerFactory>(ClassExternalizerFactory.class,
"CLASS_EXTERNALIZER_FACTORY", "Class externalizer factory", index++),
+ SERVER_AUTHENTICATION_PROVIDER = new
ProtocolServiceType<ServerAuthenticationProvider>(ServerAuthenticationProvider.class,
"SERVER_AUTHENTICATION_PROVIDER", "Server authentication provider",
index++)
};
}
Modified:
remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/InvocationTestBase.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/InvocationTestBase.java 2010-02-28
00:58:32 UTC (rev 5770)
+++
remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/InvocationTestBase.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -62,13 +62,15 @@
}
}
- private static void enter() {
- log.info("Entering: %s", new
Throwable().getStackTrace()[1].getMethodName());
+ static void enter() {
+ final StackTraceElement e = new Throwable().getStackTrace()[1];
+ log.info("Entering: %s#%s", e.getClassName(), e.getMethodName());
}
- private static void exit() {
- log.info("Exiting: %s", new
Throwable().getStackTrace()[1].getMethodName());
- log.info("-----------------------------------------");
+ static void exit() {
+ final StackTraceElement e = new Throwable().getStackTrace()[1];
+ log.info("Exiting: %s#%s", e.getClassName(), e.getMethodName());
+
log.info("-------------------------------------------------------------");
}
protected abstract Connection getConnection() throws IOException;
Modified:
remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/LocalTestCase.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/LocalTestCase.java 2010-02-28
00:58:32 UTC (rev 5770)
+++
remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/LocalTestCase.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -28,7 +28,7 @@
import org.jboss.xnio.OptionMap;
import org.testng.annotations.Test;
-@Test
+@Test(suiteName = "Local tests")
public final class LocalTestCase extends InvocationTestBase {
protected Connection getConnection() throws IOException {
Modified:
remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/RemoteTestCase.java
===================================================================
---
remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/RemoteTestCase.java 2010-02-28
00:58:32 UTC (rev 5770)
+++
remoting3/trunk/jboss-remoting/src/test/java/org/jboss/remoting3/test/RemoteTestCase.java 2010-02-28
15:51:38 UTC (rev 5771)
@@ -28,7 +28,10 @@
import java.net.URI;
import org.jboss.remoting3.CloseHandler;
import org.jboss.remoting3.Connection;
+import org.jboss.remoting3.RemotingOptions;
+import org.jboss.remoting3.security.ServerAuthenticationProvider;
import org.jboss.remoting3.spi.NetworkServerProvider;
+import org.jboss.remoting3.spi.ProtocolServiceType;
import org.jboss.xnio.AcceptingServer;
import org.jboss.xnio.ChannelListener;
import org.jboss.xnio.IoFuture;
@@ -37,21 +40,63 @@
import org.jboss.xnio.Xnio;
import org.jboss.xnio.channels.BoundChannel;
import org.jboss.xnio.channels.ConnectedStreamChannel;
+import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
-@Test
+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.sasl.AuthenticationException;
+import javax.security.sasl.RealmCallback;
+
+@Test(suiteName = "Remote tests")
public final class RemoteTestCase extends InvocationTestBase {
+ @BeforeTest
+ public void setUp() throws IOException {
+ enter();
+ try {
+ super.setUp();
+
endpoint.addProtocolService(ProtocolServiceType.SERVER_AUTHENTICATION_PROVIDER,
"test", new ServerAuthenticationProvider() {
+ public CallbackHandler getCallbackHandler() {
+ return new CallbackHandler() {
+ public void handle(final Callback[] callbacks) throws
IOException, UnsupportedCallbackException {
+ for (Callback callback : callbacks) {
+ if (callback instanceof NameCallback) {
+ final NameCallback nameCallback = (NameCallback)
callback;
+ if (!
nameCallback.getName().equals("user")) {
+ throw new AuthenticationException("Invalid
user name");
+ }
+ } else if (callback instanceof PasswordCallback) {
+ final PasswordCallback passwordCallback =
(PasswordCallback) callback;
+
passwordCallback.setPassword("password".toCharArray());
+ } else if (callback instanceof RealmCallback) {
+ // allow
+ } else {
+ throw new UnsupportedCallbackException(callback);
+ }
+ }
+ }
+ };
+ }
+ });
+ } finally {
+ exit();
+ }
+ }
+
protected Connection getConnection() throws IOException {
final NetworkServerProvider provider =
endpoint.getConnectionProviderInterface("remote", NetworkServerProvider.class);
- final ChannelListener<ConnectedStreamChannel<InetSocketAddress>>
listener = provider.getServerListener(OptionMap.EMPTY);
+ final ChannelListener<ConnectedStreamChannel<InetSocketAddress>>
listener =
provider.getServerListener(OptionMap.builder().set(RemotingOptions.AUTHENTICATION_PROVIDER,
"test").getMap());
final Xnio xnio = Xnio.getInstance();
try {
final AcceptingServer<InetSocketAddress, ?, ?> server =
xnio.createSslTcpServer(listener, OptionMap.EMPTY);
// final AcceptingServer<InetSocketAddress, ?, ?> server =
xnio.createTcpServer(listener, OptionMap.EMPTY);
final IoFuture<? extends BoundChannel<InetSocketAddress>> future
= server.bind(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), 0));
final InetSocketAddress localAddress = future.get().getLocalAddress();
- final Connection connection = endpoint.connect(new URI("remote",
null, localAddress.getAddress().getHostAddress(), localAddress.getPort(), null, null,
null), OptionMap.EMPTY).get();
+ final Connection connection = endpoint.connect(new URI("remote",
null, localAddress.getAddress().getHostAddress(), localAddress.getPort(), null, null,
null), OptionMap.EMPTY, "user", "realm",
"password".toCharArray()).get();
connection.addCloseHandler(new CloseHandler<Connection>() {
public void handleClose(final Connection closed) {
IoUtils.safeClose(server);