Hi Alexey,
Thanks for taking time to respond. I spent some time on it today but
couldn't get it through. I am a newbie to Grizzly so I'm pasting the
relevant code for easier explanation of what I'm trying to achieve. Needless
to say this works well without SSL with no SSLFilter or handshaker in the
picture. However, I do need the client auth using SSL.
Custom protocol class that reads the stream and converts into the protocol.
public abstract class AbstractProtocol
{
private class DefaultFilterChainFactory implements
PatternFilterChainFactory
{
private FilterChain defaultFilterChain;
private DefaultFilterChainFactory()
{
this.defaultFilterChain = new DefaultFilterChain(this);
this.defaultFilterChain.add(new MonitorFilter());
this.defaultFilterChain.add(new TransportFilter());
this.defaultFilterChain.add(new ProtocolFilter());
}
public FilterChain create()
{
FilterChain filterChain = new DefaultFilterChain(this);
filterChain.addAll(defaultFilterChain);
return filterChain;
}
public FilterChain getFilterChainPattern()
{
return defaultFilterChain;
}
}
private class ProtocolFilter extends FilterAdapter
{
@Override
public NextAction handleRead(FilterChainContext ctx,
NextAction nextAction) throws IOException
{
Connection<?> connection = ctx.getConnection();
StreamReader streamReader = ctx.getStreamReader();
//Read the stream and build the protocol information of different
kinds.
//protocolReader decodes the stream and informs the registered
handler.
return nextAction;
}
}
private class MonitorFilter extends FilterAdapter
{
@Override
public void exceptionOccurred(FilterChainContext ctx,
Throwable error)
{
//
}
}
@Override
public NextAction handleClose(FilterChainContext ctx,
NextAction nextAction) throws IOException
{
//
}
}
protected AbstractProtocol()
{
this.defaultFilterChainFactory = new DefaultFilterChainFactory();
this.protocolReader = //
this.protocolWriter = //
}
public PatternFilterChainFactory getDefaultFilterChainFactory()
{
return defaultFilterChainFactory;
}
protected abstract MessageHandler getMessageHandler(
Connection<?> connection);
protected abstract void removeMessageHandler(Connection<?> connection);
}
Concrete implementation of the above
------------------------------------
//Implementation of the abstract ldap transport.
private final class ConcreteProtocol extends AbstractProtocol
{
//Returns the Message handler.
protected MessageHandler getMessageHandler(Connection<?>
connection)
{
return (MessageHandler)clientConnections.get(connection);
}
//Removes the message handler.
protected void removeMessageHandler(Connection<?> connection)
{
clientConnections.remove(connection);
}
}
Adapter Filter that accepts the client connections
------------------------------------------------
private class AdaptConnectionFilter extends FilterAdapter
{
private AbstractProtocol protocol = new COncreteProtocol(..)
//Accepts a client connection.
@Override
public NextAction handleAccept(
FilterChainContext ctx, NextAction nextAction) throws IOException
{
com.sun.grizzly.Connection connection = ctx.getConnection();
connection.configureBlocking(true);
connection.getStreamReader().setBlocking(true);
connection.getStreamWriter().setBlocking(true);
connection.setProcessor(ldapTransport
.getDefaultFilterChainFactory().getFilterChainPattern());
//
//..
return nextAction;
}
}
Finally, I am setting the filters and enabling the client auth.
public GrizzlyServer() throws Exception
{
//Create the SSL Filter.
final String keystore = "c:\\temp\\serverkeys";
final String truststore = "C:\\temp\\clientkeys";
final char keystorepass[] = "hellothere".toCharArray();
final char keypassword[] = "hiagain".toCharArray();
KeyStore ks = KeyStore.getInstance("JKS");
KeyStore ts = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(keystore),keystorepass);
ts.load(new FileInputStream(truststore),keystorepass);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks,keypassword);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ts);
SSLContext sslCtx = SSLContext.getInstance("TLS");
sslCtx.init(kmf.getKeyManagers(),tmf.getTrustManagers(),null);
SSLEngineConfigurator sslEngineConfigurator = new SSLEngineConfigurator(
sslCtx, false, true, true);
SSLFilter filter = new SSLFilter(sslEngineConfigurator);
tcpNIOTransport.getFilterChain().add(new TransportFilter());
tcpNIOTransport.getFilterChain().add(filter);
tcpNIOTransport.getFilterChain().add(new AdaptConnectionFilter());
//Register the filter to handle reads and exceptions.
}
Unfortunately the handshake doesn't start and I get the following stacktrace
at the server after executing the handleAccept:
java.io.EOFException
at
com.sun.grizzly.nio.transport.TCPNIOStreamReader.read0(TCPNIOStreamReader.java:184)
at
com.sun.grizzly.nio.transport.TCPNIOTransportFilter.handleRead(TCPNIOTransportFilter.java:72)
at
com.sun.grizzly.filterchain.TransportFilter.handleRead(TransportFilter.java:160)
at
com.sun.grizzly.filterchain.DefaultFilterChain$3.execute(DefaultFilterChain.java:92)
at
com.sun.grizzly.filterchain.DefaultFilterChain.executeChain(DefaultFilterChain.java:254)
at
com.sun.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:190)
at
com.sun.grizzly.filterchain.AbstractFilterChain.process(AbstractFilterChain.java:139)
at com.sun.grizzly.ProcessorRunnable.run(ProcessorRunnable.java:217)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:441)
I also tried using the forced handshaking without setting the SSLFilter in
the ctor. I'm forcing the handshake while accepting the connection in
handleAccept but I get a timeout exception there. Here is what I tried:
public NextAction handleAccept(FilterChainContext ctx,
NextAction nextAction) throws java.io.IOException
{
SSLHandshaker sslHandshaker = new BlockingSSLHandshaker();
SSLEngineConfigurator sslEngineConfigurator = null;
SSLFilter sslFilter = null;
String[] suites = {"SSL_RSA_WITH_RC4_128_MD5",
"SSL_RSA_WITH_RC4_128_SHA",
"TLS_RSA_WITH_AES_128_CBC_SHA",
"TLS_DHE_RSA_WITH_AES_128_CBC_SHA",
"TLS_DHE_DSS_WITH_AES_128_CBC_SHA",
"SSL_RSA_WITH_3DES_EDE_CBC_SHA",
"SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA",
"SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA",
"SSL_RSA_WITH_DES_CBC_SHA",
"SSL_DHE_RSA_WITH_DES_CBC_SHA",
"SSL_DHE_DSS_WITH_DES_CBC_SHA",
"SSL_RSA_EXPORT_WITH_RC4_40_MD5",
"SSL_RSA_EXPORT_WITH_DES40_CBC_SHA",
"SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA",
"SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA"};
Connection connection = ctx.getConnection();
connection.configureBlocking(true);
connection.getStreamReader().setBlocking(true);
connection.getStreamWriter().setBlocking(true);
try
{
final String keystore = "c:\\temp\\serverkeys";
final String truststore = "C:\\temp\\clientkeys";
final char keystorepass[] = "hellothere".toCharArray();
final char keypassword[] = "hiagain".toCharArray();
KeyStore ks = KeyStore.getInstance("JKS");
KeyStore ts = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(keystore),keystorepass);
ts.load(new FileInputStream(truststore),keystorepass);
KeyManagerFactory kmf = KeyManagerFactory.getInstance("SunX509");
kmf.init(ks,keypassword);
TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509");
tmf.init(ts);
SSLContext sslCtx = SSLContext.getInstance("TLS");
sslCtx.init(kmf.getKeyManagers(),tmf.getTrustManagers(),null);
sslEngineConfigurator = new SSLEngineConfigurator(
sslCtx, false, true, true);
String[] cipherSuites = sslEngineConfigurator.getEnabledCipherSuites();
if(cipherSuites == null)
{
System.out.println("suites is null ");
sslEngineConfigurator.setEnabledCipherSuites(suites);
}
sslFilter = new SSLFilter(sslEngineConfigurator,
sslHandshaker);
SSLStreamReader reader = new SSLStreamReader(connection
.getStreamReader());
SSLStreamWriter writer = new SSLStreamWriter(connection
.getStreamWriter());
sslHandshaker.handshake(reader, writer, sslEngineConfigurator)
.get();
The server throws the following exception in that case:
java.util.concurrent.ExecutionException:
java.util.concurrent.TimeoutException
at com.sun.grizzly.impl.ReadyFutureImpl.get(ReadyFutureImpl.java:138)
at
GrizzlyServerImpl$AdaptConnectionFilter.handleAccept(GrizzlyServer.java:394)
at
com.sun.grizzly.filterchain.DefaultFilterChain$1.execute(DefaultFilterChain.java:78)
at
com.sun.grizzly.filterchain.DefaultFilterChain.executeChain(DefaultFilterChain.java:254)
at
com.sun.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:190)
at
com.sun.grizzly.filterchain.AbstractFilterChain.process(AbstractFilterChain.java:139)
at com.sun.grizzly.ProcessorRunnable.run(ProcessorRunnable.java:217)
at
com.sun.grizzly.utils.CurrentThreadExecutor.execute(CurrentThreadExecutor.java:52)
at
com.sun.grizzly.strategies.WorkerThreadStrategy.executeProcessor(WorkerThreadStrategy.java:101)
at
com.sun.grizzly.nio.transport.TCPNIOTransport.executeProcessor(TCPNIOTransport.java:709)
at
com.sun.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:679)
at
com.sun.grizzly.AbstractTransport.fireIOEvent(AbstractTransport.java:352)
at
com.sun.grizzly.nio.transport.TCPNIOServerConnection$RegisterAcceptedChannelCompletionHandler.completed(TCPNIOServerConnection.java:269)
at
com.sun.grizzly.nio.transport.TCPNIOServerConnection$RegisterAcceptedChannelCompletionHandler.completed(TCPNIOServerConnection.java:236)
at
com.sun.grizzly.nio.DefaultSelectorHandler.registerChannel0(DefaultSelectorHandler.java:252)
at
com.sun.grizzly.nio.DefaultSelectorHandler.processPendingOperation(DefaultSelectorHandler.java:194)
at
com.sun.grizzly.nio.DefaultSelectorHandler.processPendingOperations(DefaultSelectorHandler.java:183)
at
com.sun.grizzly.nio.DefaultSelectorHandler.preSelect(DefaultSelectorHandler.java:77)
at com.sun.grizzly.nio.SelectorRunner.doSelect(SelectorRunner.java:250)
at com.sun.grizzly.nio.SelectorRunner.run(SelectorRunner.java:191)
at
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.util.concurrent.TimeoutException
at com.sun.grizzly.impl.FutureImpl.get(FutureImpl.java:170)
at
com.sun.grizzly.ssl.BlockingSSLHandshaker.handshake(BlockingSSLHandshaker.java:119)
... 22 more
Jan 22, 2010 5:14:44 PM com.sun.grizzly.filterchain.DefaultFilterChain
execute
WARNING: Exception during FilterChain execution
java.lang.NullPointerException
at
com.sun.grizzly.filterchain.DefaultFilterChain.executeChain(DefaultFilterChain.java:263)
at
com.sun.grizzly.filterchain.DefaultFilterChain.execute(DefaultFilterChain.java:190)
at
com.sun.grizzly.filterchain.AbstractFilterChain.process(AbstractFilterChain.java:139)
at com.sun.grizzly.ProcessorRunnable.run(ProcessorRunnable.java:217)
at
com.sun.grizzly.utils.CurrentThreadExecutor.execute(CurrentThreadExecutor.java:52)
at
com.sun.grizzly.strategies.WorkerThreadStrategy.executeProcessor(WorkerThreadStrategy.java:101)
at
com.sun.grizzly.nio.transport.TCPNIOTransport.executeProcessor(TCPNIOTransport.java:709)
at
com.sun.grizzly.nio.transport.TCPNIOTransport.fireIOEvent(TCPNIOTransport.java:679)
at
com.sun.grizzly.AbstractTransport.fireIOEvent(AbstractTransport.java:352)
at
com.sun.grizzly.nio.transport.TCPNIOServerConnection$RegisterAcceptedChannelCompletionHandler.completed(TCPNIOServerConnection.java:269)
at
com.sun.grizzly.nio.transport.TCPNIOServerConnection$RegisterAcceptedChannelCompletionHandler.completed(TCPNIOServerConnection.java:236)
at
com.sun.grizzly.nio.DefaultSelectorHandler.registerChannel0(DefaultSelectorHandler.java:252)
at
com.sun.grizzly.nio.DefaultSelectorHandler.processPendingOperation(DefaultSelectorHandler.java:194)
at
com.sun.grizzly.nio.DefaultSelectorHandler.processPendingOperations(DefaultSelectorHandler.java:183)
at
com.sun.grizzly.nio.DefaultSelectorHandler.preSelect(DefaultSelectorHandler.java:77)
at com.sun.grizzly.nio.SelectorRunner.doSelect(SelectorRunner.java:250)
at com.sun.grizzly.nio.SelectorRunner.run(SelectorRunner.java:191)
at
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:619)
Oleksiy Stashok wrote:
>
> Hi,
>
> can you pls. share the exception?
> SSLFilter shouldn't pass control to subsequent filters until handshake
> wasn't completed.
>
> WBR,
> Alexey.
>
> On Jan 21, 2010, at 23:41 , mambo123 wrote:
>
>>
>> I have a custom protocol filter adapter that accepts the SSL
>> connections. I
>> have chained this with the SSLFilter to perform the handshake prior to
>> reading any application data. I'm kinda confused how does the
>> SSLFilter let
>> the subsequent filters know that the handshake is done. I mean, my
>> custom
>> adapter also has a handleRead method and it is being called during
>> handshake
>> process and it throws an exception. My code looks like
>>
>> main()
>> {
>> nioTransport.getFilterChain().add(new TransportFilter());
>> nioTransport.getFilterChain().add(new SSLFilter());
>> nioTransport.getFilterChain().add(new MyFilterAdapter());
>> }
>> MyFilterAdapter extends FilterAdapter
>> {
>> handleAccept(..)
>> {
>> //Accept this connection.
>> }
>> handleRead(...)
>> {
>> //Find the message type and create different messages.
>> }
>>
>> }
>>
>>
>> --
>> View this message in context:
>> http://old.nabble.com/Chaining-with-the-SSLfilter-tp27265905p27265905.html
>> Sent from the Grizzly - Users mailing list archive at Nabble.com.
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
>> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>>
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: users-unsubscribe_at_grizzly.dev.java.net
> For additional commands, e-mail: users-help_at_grizzly.dev.java.net
>
>
>
--
View this message in context: http://old.nabble.com/Chaining-with-the-SSLfilter-tp27265905p27281441.html
Sent from the Grizzly - Users mailing list archive at Nabble.com.