You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@directory.apache.org by Niklas Gustavsson <ni...@protocol7.com> on 2007/01/11 00:42:58 UTC

Adding SSLFilter on the fly

Hi

I'm trying to integrate MINA with Apache FtpServer, basically base 
FtpServer's socket handling on MINA. So far it's been a great 
experience. However, I just got stuck. It might very likely be an error 
on my side but I need some pointers :-)

The FTP AUTH command is sent by a client to tell the server that it 
wants to secure the FTP control socket with SSL. The flow is like this:

1. Client sends "AUTH TLS"
2. Server sends "234 Command AUTH okay; starting TLS connection."
3. Server secures the socket
4. Next client call is over the secure socket

Now, to implement this I add a SSLFilter at step 3. However, I seem to 
run into a condition where the response sent at step 2 sometimes end up 
in the, not yet initialized, SSLFilter. This results in:
java.lang.IllegalStateException
	at 
org.apache.mina.filter.SSLFilter.getSSLSessionHandler(SSLFilter.java:634)
	at org.apache.mina.filter.SSLFilter.messageReceived(SSLFilter.java:371)
	at 
org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362)
	at 
org.apache.mina.common.support.AbstractIoFilterChain.access$1200(AbstractIoFilterChain.java:54)
	at 
org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:800)
	at 
org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.messageReceived(AbstractIoFilterChain.java:617)
	at 
org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain..java:362)
	at 
org.apache.mina.common.support.AbstractIoFilterChain.fireMessageReceived(AbstractIoFilterChain.java:353)
	at 
org.apache.mina.transport.socket.nio.SocketIoProcessor.read(SocketIoProcessor.java:281)
	at 
org.apache.mina.transport.socket.nio.SocketIoProcessor.process(SocketIoProcessor.java:241)
	at 
org.apache.mina.transport.socket.nio.SocketIoProcessor.access$500(SocketIoProcessor.java:44)
	at 
org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:559)
	at 
org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:43)
	at java.lang.Thread.run(Thread.java:595)


 From my understanding, the response should already has been sent to the 
client but that seems not to be the case. The response (step 2) is sent as:
session.write(response).join();

Shouldn't the join() make that call wait until the write is completely 
done? If not, how would I otherwise ensure that the response has been 
sent before I add the SSL filter?

The full trace is attached.

Thanks!
/niklas

Fwd: Adding SSLFilter on the fly

Posted by Ersin Er <er...@gmail.com>.
---------- Forwarded message ----------
From: Niklas Gustavsson <ni...@protocol7.com>
Date: Jan 11, 2007 1:42 AM
Subject: Adding SSLFilter on the fly
To: dev@directory.apache.org


Hi

I'm trying to integrate MINA with Apache FtpServer, basically base
FtpServer's socket handling on MINA. So far it's been a great
experience. However, I just got stuck. It might very likely be an error
on my side but I need some pointers :-)

The FTP AUTH command is sent by a client to tell the server that it
wants to secure the FTP control socket with SSL. The flow is like this:

1. Client sends "AUTH TLS"
2. Server sends "234 Command AUTH okay; starting TLS connection."
3. Server secures the socket
4. Next client call is over the secure socket

Now, to implement this I add a SSLFilter at step 3. However, I seem to
run into a condition where the response sent at step 2 sometimes end up
in the, not yet initialized, SSLFilter. This results in:
java.lang.IllegalStateException
        at
org.apache.mina.filter.SSLFilter.getSSLSessionHandler(SSLFilter.java:634)
        at org.apache.mina.filter.SSLFilter.messageReceived(SSLFilter.java:371)
        at
org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362)
        at
org.apache.mina.common.support.AbstractIoFilterChain.access$1200(AbstractIoFilterChain.java:54)
        at
org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:800)
        at
org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.messageReceived(AbstractIoFilterChain.java:617)
        at
org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain..java:362)
        at
org.apache.mina.common.support.AbstractIoFilterChain.fireMessageReceived(AbstractIoFilterChain.java:353)
        at
org.apache.mina.transport.socket.nio.SocketIoProcessor.read(SocketIoProcessor.java:281)
        at
org.apache.mina.transport.socket.nio.SocketIoProcessor.process(SocketIoProcessor.java:241)
        at
org.apache.mina.transport.socket.nio.SocketIoProcessor.access$500(SocketIoProcessor.java:44)
        at
org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:559)
        at
org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:43)
        at java.lang.Thread.run(Thread.java:595)


 From my understanding, the response should already has been sent to the
client but that seems not to be the case. The response (step 2) is sent as:
session.write(response).join();

Shouldn't the join() make that call wait until the write is completely
done? If not, how would I otherwise ensure that the response has been
sent before I add the SSL filter?

The full trace is attached.

Thanks!
/niklas


Server ready :: Apache FTP Server
------- Apache FTP Server started ------
[/127.0.0.1:2291] CREATED
Launching thread for /127.0.0.1:2291
[/127.0.0.1:2291] OPENED
[/127.0.0.1:2291] WRITE: 220 Service ready for new user.

< 220 Service ready for new user.
> AUTH TLS
AUTH TLS

AUTH TLS

[/127.0.0.1:2291] RECEIVED: AUTH TLS
[/127.0.0.1:2291] WRITE: 234 Command AUTH okay; starting TLS connection.

< 220 Service ready for new user.
234 Command AUTH okay; starting TLS connection.
[/127.0.0.1:2291]  doHandshake()
[/127.0.0.1:2291]   initialHandshakeStatus=NEED_UNWRAP
[/127.0.0.1:2291]  unwrapHandshake()
[/127.0.0.1:2291]    inNetBuffer: java.nio.DirectByteBuffer[pos=0
lim=0 cap=16665]
[/127.0.0.1:2291]    appBuffer: java.nio.DirectByteBuffer[pos=0
lim=33330 cap=33330]
[/127.0.0.1:2291]  Unwrap res:Status = BUFFER_UNDERFLOW
HandshakeStatus = NEED_UNWRAP
bytesConsumed = 0 bytesProduced = 0
org.apache.ftpserver.listener.mina.MinaConnection@1cb52ae
[/127.0.0.1:2291] SENT: 220 Service ready for new user.

[/127.0.0.1:2291] SENT: 234 Command AUTH okay; starting TLS connection.

[/127.0.0.1:2291] EXCEPTION:
java.lang.IllegalStateException
        at org.apache.mina.filter.SSLFilter.getSSLSessionHandler(SSLFilter.java:634)
        at org.apache.mina.filter.SSLFilter.messageReceived(SSLFilter.java:371)
        at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362)
        at org.apache.mina.common.support.AbstractIoFilterChain.access$1200(AbstractIoFilterChain.java:54)
        at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:800)
        at org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.messageReceived(AbstractIoFilterChain.java:617)
        at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362)
        at org.apache.mina.common.support.AbstractIoFilterChain.fireMessageReceived(AbstractIoFilterChain.java:353)
        at org.apache.mina.transport.socket.nio.SocketIoProcessor.read(SocketIoProcessor.java:281)
        at org.apache.mina.transport.socket.nio.SocketIoProcessor.process(SocketIoProcessor.java:241)
        at org.apache.mina.transport.socket.nio.SocketIoProcessor.access$500(SocketIoProcessor.java:44)
        at org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:559)
        at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:43)
        at java.lang.Thread.run(Thread.java:595)
[/127.0.0.1:2291] CLOSE
[/127.0.0.1:2291]  write outNetBuffer: java.nio.DirectByteBuffer[pos=0
lim=7 cap=16665]
[/127.0.0.1:2291]  session write: DirectBuffer[pos=0 lim=7 cap=8: 15
03 01 00 02 01 00]
[/127.0.0.1:2291]  Data Read:
org.apache.mina.filter.support.SSLHandler@1addb59 (DirectBuffer[pos=0
lim=7 cap=8192: 15 03 01 00 02 02 0A])
[/127.0.0.1:2291]  doHandshake()
[/127.0.0.1:2291]   initialHandshakeStatus=NEED_UNWRAP
[/127.0.0.1:2291]  unwrapHandshake()
[/127.0.0.1:2291]    inNetBuffer: java.nio.DirectByteBuffer[pos=0
lim=7 cap=16665]
[/127.0.0.1:2291]    appBuffer: java.nio.DirectByteBuffer[pos=0
lim=33330 cap=33330]
[/127.0.0.1:2291] Unexpected exception from SSLEngine.closeInbound().
javax.net.ssl.SSLException: Inbound closed before receiving peer's
close_notify: possible truncation attack?
        at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:166)
        at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1352)
        at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1320)
        at com.sun.net.ssl.internal.ssl.SSLEngineImpl.closeInbound(SSLEngineImpl.java:1259)
        at org.apache.mina.filter.support.SSLHandler.destroy(SSLHandler.java:165)
        at org.apache.mina.filter.SSLFilter.sessionClosed(SSLFilter.java:358)
        at org.apache.mina.common.support.AbstractIoFilterChain.callNextSessionClosed(AbstractIoFilterChain.java:321)
        at org.apache.mina.common.support.AbstractIoFilterChain.access$900(AbstractIoFilterChain.java:54)
        at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.sessionClosed(AbstractIoFilterChain.java:781)
        at org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.sessionClosed(AbstractIoFilterChain.java:599)
        at org.apache.mina.common.support.AbstractIoFilterChain.callNextSessionClosed(AbstractIoFilterChain.java:321)
        at org.apache.mina.common.support.AbstractIoFilterChain.fireSessionClosed(AbstractIoFilterChain.java:313)
        at org.apache.mina.common.support.IoServiceListenerSupport.fireSessionDestroyed(IoServiceListenerSupport.java:271)
        at org.apache.mina.transport.socket.nio.SocketIoProcessor.doRemove(SocketIoProcessor.java:225)
        at org.apache.mina.transport.socket.nio.SocketIoProcessor.access$700(SocketIoProcessor.java:44)
        at org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:563)
        at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:43)
        at java.lang.Thread.run(Thread.java:595)
[/127.0.0.1:2291] EXCEPTION:
javax.net.ssl.SSLHandshakeException: Initial SSL handshake failed.
        at org.apache.mina.filter.SSLFilter.messageReceived(SSLFilter.java:424)
        at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362)
        at org.apache.mina.common.support.AbstractIoFilterChain.access$1200(AbstractIoFilterChain.java:54)
        at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:800)
        at org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.messageReceived(AbstractIoFilterChain.java:617)
        at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362)
        at org.apache.mina.common.support.AbstractIoFilterChain.fireMessageReceived(AbstractIoFilterChain.java:353)
        at org.apache.mina.transport.socket.nio.SocketIoProcessor.read(SocketIoProcessor.java:281)
        at org.apache.mina.transport.socket.nio.SocketIoProcessor.process(SocketIoProcessor.java:241)
        at org.apache.mina.transport.socket.nio.SocketIoProcessor.access$500(SocketIoProcessor.java:44)
        at org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:559)
        at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:43)
        at java.lang.Thread.run(Thread.java:595)
Caused by: javax.net.ssl.SSLException: Received fatal alert: unexpected_message
        at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:166)
        at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1352)
        at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1320)
        at com.sun.net.ssl.internal.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1482)
        at com.sun.net.ssl.internal.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:957)
        at com.sun.net.ssl.internal.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:782)
        at com.sun.net.ssl.internal.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:674)
        at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:566)
        at org.apache.mina.filter.support.SSLHandler.unwrapHandshake(SSLHandler.java:677)
        at org.apache.mina.filter.support.SSLHandler.handshake(SSLHandler.java:494)
        at org.apache.mina.filter.support.SSLHandler.messageReceived(SSLHandler.java:293)
        at org.apache.mina.filter.SSLFilter.messageReceived(SSLFilter.java:392)
        ... 12 more
[/127.0.0.1:2291] CLOSED
Exiting since queue is empty for /127.0.0.1:2291




-- 
Ersin

Re: Adding SSLFilter on the fly

Posted by Trustin Lee <tr...@gmail.com>.
On 1/16/07, Trustin Lee <tr...@gmail.com> wrote:
>
> In MINA (Corrected FtpServer implementation using traffic control)
>
> 1) Client sends AUTH SSL.
> 2) Server reads AUTH SSL.
> 3) Server suspends read operation. (IoSession.suspendRead())
> 4) Server sends a response.
> 3) Client sends negotiation request, but I/O processor doesn't read until
> read operations are resumed.
> 5) Server adds a SSLFilter.
> 6) Server resumes read operation. (IoSession.resumeRead())


Oops, the sequence numbers are messed up. :)  It's actually 1 to 7.

Anyway, this solution might not work as I expected because I didn't try it.
If you are a good adventurer, please let me know if this works.  Otherwise,
you'd better stick to the former.

Trustin
-- 
what we call human nature is actually human habit
--
http://gleamynode.net/
--
PGP key fingerprints:
* E167 E6AF E73A CBCE EE41  4A29 544D DE48 FE95 4E7E
* B693 628E 6047 4F8F CFA4  455E 1C62 A7DC 0255 ECA6

Re: Adding SSLFilter on the fly

Posted by Trustin Lee <tr...@gmail.com>.
Problem has been solved! ;)

The main cause of this problem is in that blocking I/O code and MINA work in
different ways.  In blocking I/O:

1) Client sends AUTH SSL
2) Server reads AUTH SSL, sends a response.
3) Client sends negotiation request.
4) Server creates SSLSocket and starts to read the negotiation request.

In MINA (Current FtpServer implementation):

1) Client sends AUTH SSL.
2) Server reads AUTH SSL, sends a response.
3) Client sends negotiation request.
4) MINA I/O processor reads the negotiation request, but SSLFilter is not
added yet!  So it's interpreted as non-SSL message and codec will throw an
exception.
5) Server adds SSLFilter, but it's too late.

To fix this behavior, you have to make sure SSLFilter is added before the
I/O processor reads the negotiation request.  There are two solutions:

In MINA (Corrected FtpServer implementation using
SSLFilter.DISABLE_ENCRYPTION_ONCE)

1) Client sends AUTH SSL.
2) Server reads AUTH SSL.
3) Server adds a SSLFilter and set SSLFilter.DISABLE_ENCRYPTION_ONCEattribute (
IoSession.setAttribute(SSLFilter.DISABLE_ENCRYPTION_ONCE))
4) Server sends a response.  This message is not encrypted at all thanks to
the DISABLE_ENCRYPTION_ONCE attribute.
5) Client sends negotiation request.
6) Server starts negotiation process.

In MINA (Corrected FtpServer implementation using traffic control)

1) Client sends AUTH SSL.
2) Server reads AUTH SSL.
3) Server suspends read operation. (IoSession.suspendRead())
4) Server sends a response.
3) Client sends negotiation request, but I/O processor doesn't read until
read operations are resumed.
5) Server adds a SSLFilter.
6) Server resumes read operation. (IoSession.resumeRead())

For now, FtpServer's Connection interface provides only one method to secure
a connection, but you will have to split it into two to make it work with
MINA or other asynchronous I/O framework.

HTH,
Trustin

On 1/15/07, Niklas Gustavsson <ni...@protocol7.com> wrote:
>
> Trustin Lee wrote:
> > Hi Niklas,
> >
> > On 1/12/07, Niklas Gustavsson <ni...@protocol7.com> wrote:
> >>
> >> Hi
> >>
> >> Anyone got any idea as to how I could solve the issue I describe
> >> below? The MINA integration into FtpServer is not full functional,
> >> except for the SSL support :-/
> >
> >
> > Can I reproduce the problem by myself?  FtpServer is still incubator, so
> if
> > you checked in your mina integration code, I could test it by myself
> with
> > proper instruction.
>
> Yes, of course. Check out FtpServer from:
> http://svn.apache.org/repos/asf/incubator/ftpserver/trunk/
>
> Change to using MINA as the listener implementation in the file:
> core/src/java/org/apache/ftpserver/FtpServer.java
>
> listeners.add(new IOListener(serverContext));
> should be changed to:
> listeners.add(new MinaListener(serverContext));
>
> (you'll need to change imports as well of course).
>
> After that, you'll need to compile ftplet-api and core and then run the
> tests in ssl-tests, most of which will fail due to this problem.
>
> I'm also working on a minimal test case for you so you might want to
> wait for that. I want to eliminate the (not unlikely) risk that I've
> done something wrong.
>
> /niklas
>
>
>
>


-- 
what we call human nature is actually human habit
--
http://gleamynode.net/
--
PGP key fingerprints:
* E167 E6AF E73A CBCE EE41  4A29 544D DE48 FE95 4E7E
* B693 628E 6047 4F8F CFA4  455E 1C62 A7DC 0255 ECA6

Re: Adding SSLFilter on the fly

Posted by Niklas Gustavsson <ni...@protocol7.com>.
Trustin Lee wrote:
> Problem has been solved! ;)

Thanks! You're first method worked like a charm :-)

The traffic control solution however did not work. The reason is, I 
think, that the SSL handshake fails (as expected) pretty miserably when 
reading is suspended.

(Posting through gmane.org again, the list should have been updated)

/niklas


Re: Adding SSLFilter on the fly

Posted by Niklas Gustavsson <ni...@protocol7.com>.
Trustin Lee wrote:
> Hi Niklas,
> 
> On 1/12/07, Niklas Gustavsson <ni...@protocol7.com> wrote:
>>
>> Hi
>>
>> Anyone got any idea as to how I could solve the issue I describe
>> below? The MINA integration into FtpServer is not full functional,
>> except for the SSL support :-/
> 
> 
> Can I reproduce the problem by myself?  FtpServer is still incubator, so if
> you checked in your mina integration code, I could test it by myself with
> proper instruction.

Yes, of course. Check out FtpServer from:
http://svn.apache.org/repos/asf/incubator/ftpserver/trunk/

Change to using MINA as the listener implementation in the file:
core/src/java/org/apache/ftpserver/FtpServer.java

listeners.add(new IOListener(serverContext));
should be changed to:
listeners.add(new MinaListener(serverContext));

(you'll need to change imports as well of course).

After that, you'll need to compile ftplet-api and core and then run the 
tests in ssl-tests, most of which will fail due to this problem.

I'm also working on a minimal test case for you so you might want to 
wait for that. I want to eliminate the (not unlikely) risk that I've 
done something wrong.

/niklas


Re: Adding SSLFilter on the fly

Posted by Trustin Lee <tr...@gmail.com>.
Hi Niklas,

On 1/12/07, Niklas Gustavsson <ni...@protocol7.com> wrote:
>
> Hi
>
> Anyone got any idea as to how I could solve the issue I describe
> below? The MINA integration into FtpServer is not full functional,
> except for the SSL support :-/


Can I reproduce the problem by myself?  FtpServer is still incubator, so if
you checked in your mina integration code, I could test it by myself with
proper instruction.

Trustin
-- 
what we call human nature is actually human habit
--
http://gleamynode.net/
--
PGP key fingerprints:
* E167 E6AF E73A CBCE EE41  4A29 544D DE48 FE95 4E7E
* B693 628E 6047 4F8F CFA4  455E 1C62 A7DC 0255 ECA6

Re: Adding SSLFilter on the fly

Posted by Niklas Gustavsson <ni...@protocol7.com>.
Hi

Anyone got any idea as to how I could solve the issue I describe
below? The MINA integration into FtpServer is not full functional,
except for the SSL support :-/

Thanks!

/niklas

> Niklas Gustavsson wrote:
>> Hi
>>
>> I'm trying to integrate MINA with Apache FtpServer, basically base
FtpServer's socket handling on MINA. So far it's been a great
experience. However, I just got stuck. It might very likely be an
error on my side but I need some pointers :-)
>>
>> The FTP AUTH command is sent by a client to tell the server that it
wants to secure the FTP control socket with SSL. The flow is like
this:
>>
>> 1. Client sends "AUTH TLS"
>> 2. Server sends "234 Command AUTH okay; starting TLS connection."
>> 3. Server secures the socket
>> 4. Next client call is over the secure socket
>>
>> Now, to implement this I add a SSLFilter at step 3. However, I seem
to run into a condition where the response sent at step 2 sometimes
end up in the, not yet initialized, SSLFilter. This results in:
>> java.lang.IllegalStateException
>>     at org.apache.mina.filter.SSLFilter.getSSLSessionHandler(SSLFilter.java:634)
>>     at org.apache.mina.filter.SSLFilter.messageReceived(SSLFilter.java:371)
>>     at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362)
>>     at org.apache.mina.common.support.AbstractIoFilterChain.access$1200(AbstractIoFilterChain.java:54)
>>     at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:800)
>>     at org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.messageReceived(AbstractIoFilterChain.java:617)
>>     at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain..java:362)
>>     at org.apache.mina.common.support.AbstractIoFilterChain.fireMessageReceived(AbstractIoFilterChain.java:353)
>>     at org.apache.mina.transport.socket.nio.SocketIoProcessor.read(SocketIoProcessor.java:281)
>>     at org.apache.mina.transport.socket.nio.SocketIoProcessor.process(SocketIoProcessor.java:241)
>>     at org.apache.mina.transport.socket.nio.SocketIoProcessor.access$500(SocketIoProcessor.java:44)
>>     at org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:559)
>>     at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:43)
>>     at java.lang.Thread.run(Thread.java:595)
>>
>>
>>  From my understanding, the response should already has been sent
to the client but that seems not to be the case. The response (step 2)
is sent as:
>> session.write(response).join();
>>
>> Shouldn't the join() make that call wait until the write is
completely done? If not, how would I otherwise ensure that the
response has been sent before I add the SSL filter?
>>
>> The full trace is attached.
>>
>> Thanks!
>> /niklas
>>
>>
>> ------------------------------------------------------------------------
>>
>> Server ready :: Apache FTP Server
>> ------- Apache FTP Server started ------
>> [/127.0.0.1:2291] CREATED
>> Launching thread for /127.0.0.1:2291
>> [/127.0.0.1:2291] OPENED
>> [/127.0.0.1:2291] WRITE: 220 Service ready for new user.
>>
>> < 220 Service ready for new user.
>>> AUTH TLS
>> AUTH TLS
>>
>> AUTH TLS
>>
>> [/127.0.0.1:2291] RECEIVED: AUTH TLS
>> [/127.0.0.1:2291] WRITE: 234 Command AUTH okay; starting TLS connection.
>>
>> < 220 Service ready for new user.
>> 234 Command AUTH okay; starting TLS connection.
>> [/127.0.0.1:2291]  doHandshake()
>> [/127.0.0.1:2291]   initialHandshakeStatus=NEED_UNWRAP
>> [/127.0.0.1:2291]  unwrapHandshake()
>> [/127.0.0.1:2291]    inNetBuffer: java.nio.DirectByteBuffer[pos=0
lim=0 cap=16665]
>> [/127.0.0.1:2291]    appBuffer: java.nio.DirectByteBuffer[pos=0
lim=33330 cap=33330]
>> [/127.0.0.1:2291]  Unwrap res:Status = BUFFER_UNDERFLOW
HandshakeStatus = NEED_UNWRAP
>> bytesConsumed = 0 bytesProduced = 0
>> org.apache.ftpserver.listener.mina.MinaConnection@1cb52ae
>> [/127.0.0.1:2291] SENT: 220 Service ready for new user.
>>
>> [/127.0.0.1:2291] SENT: 234 Command AUTH okay; starting TLS connection.
>>
>> [/127.0.0.1:2291] EXCEPTION:
>> java.lang.IllegalStateException
>>     at org.apache.mina.filter.SSLFilter.getSSLSessionHandler(SSLFilter.java:634)
>>     at org.apache.mina.filter.SSLFilter.messageReceived(SSLFilter.java:371)
>>     at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362)
>>     at org.apache.mina.common.support.AbstractIoFilterChain.access$1200(AbstractIoFilterChain.java:54)
>>     at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:800)
>>     at org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.messageReceived(AbstractIoFilterChain.java:617)
>>     at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362)
>>     at org.apache.mina.common.support.AbstractIoFilterChain.fireMessageReceived(AbstractIoFilterChain.java:353)
>>     at org.apache.mina.transport.socket.nio.SocketIoProcessor.read(SocketIoProcessor.java:281)
>>     at org.apache.mina.transport.socket.nio.SocketIoProcessor.process(SocketIoProcessor.java:241)
>>     at org.apache.mina.transport.socket.nio.SocketIoProcessor.access$500(SocketIoProcessor.java:44)
>>     at org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:559)
>>     at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:43)
>>     at java.lang.Thread.run(Thread.java:595)
>> [/127.0.0.1:2291] CLOSE
>> [/127.0.0.1:2291]  write outNetBuffer:
java.nio.DirectByteBuffer[pos=0 lim=7 cap=16665]
>> [/127.0.0.1:2291]  session write: DirectBuffer[pos=0 lim=7 cap=8:
15 03 01 00 02 01 00]
>> [/127.0.0.1:2291]  Data Read:
org.apache.mina.filter.support.SSLHandler@1addb59 (DirectBuffer[pos=0
lim=7 cap=8192: 15 03 01 00 02 02 0A])
>> [/127.0.0.1:2291]  doHandshake()
>> [/127.0.0.1:2291]   initialHandshakeStatus=NEED_UNWRAP
>> [/127.0.0.1:2291]  unwrapHandshake()
>> [/127.0.0.1:2291]    inNetBuffer: java.nio.DirectByteBuffer[pos=0
lim=7 cap=16665]
>> [/127.0.0.1:2291]    appBuffer: java.nio.DirectByteBuffer[pos=0
lim=33330 cap=33330]
>> [/127.0.0.1:2291] Unexpected exception from SSLEngine.closeInbound().
>> javax.net.ssl.SSLException: Inbound closed before receiving peer's
close_notify: possible truncation attack?
>>     at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:166)
>>     at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1352)
>>     at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1320)
>>     at com.sun.net.ssl.internal.ssl.SSLEngineImpl.closeInbound(SSLEngineImpl.java:1259)
>>     at org.apache.mina.filter.support.SSLHandler.destroy(SSLHandler.java:165)
>>     at org.apache.mina.filter.SSLFilter.sessionClosed(SSLFilter.java:358)
>>     at org.apache.mina.common.support.AbstractIoFilterChain.callNextSessionClosed(AbstractIoFilterChain.java:321)
>>     at org.apache.mina.common.support.AbstractIoFilterChain.access$900(AbstractIoFilterChain.java:54)
>>     at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.sessionClosed(AbstractIoFilterChain.java:781)
>>     at org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.sessionClosed(AbstractIoFilterChain.java:599)
>>     at org.apache.mina.common.support.AbstractIoFilterChain.callNextSessionClosed(AbstractIoFilterChain.java:321)
>>     at org.apache.mina.common.support.AbstractIoFilterChain.fireSessionClosed(AbstractIoFilterChain.java:313)
>>     at org.apache.mina.common.support.IoServiceListenerSupport.fireSessionDestroyed(IoServiceListenerSupport.java:271)
>>     at org.apache.mina.transport.socket.nio.SocketIoProcessor.doRemove(SocketIoProcessor.java:225)
>>     at org.apache.mina.transport.socket.nio.SocketIoProcessor.access$700(SocketIoProcessor.java:44)
>>     at org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:563)
>>     at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:43)
>>     at java.lang.Thread.run(Thread.java:595)
>> [/127.0.0.1:2291] EXCEPTION:
>> javax.net.ssl.SSLHandshakeException: Initial SSL handshake failed.
>>     at org.apache.mina.filter.SSLFilter.messageReceived(SSLFilter.java:424)
>>     at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362)
>>     at org.apache.mina.common.support.AbstractIoFilterChain.access$1200(AbstractIoFilterChain.java:54)
>>     at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:800)
>>     at org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.messageReceived(AbstractIoFilterChain.java:617)
>>     at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362)
>>     at org.apache.mina.common.support.AbstractIoFilterChain.fireMessageReceived(AbstractIoFilterChain.java:353)
>>     at org.apache.mina.transport.socket.nio.SocketIoProcessor.read(SocketIoProcessor.java:281)
>>     at org.apache.mina.transport.socket.nio.SocketIoProcessor.process(SocketIoProcessor.java:241)
>>     at org.apache.mina.transport.socket.nio.SocketIoProcessor.access$500(SocketIoProcessor.java:44)
>>     at org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:559)
>>     at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:43)
>>     at java.lang.Thread.run(Thread.java:595)
>> Caused by: javax.net.ssl.SSLException: Received fatal alert:
unexpected_message
>>     at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:166)
>>     at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1352)
>>     at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1320)
>>     at com.sun.net.ssl.internal.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1482)
>>     at com.sun.net.ssl.internal.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:957)
>>     at com.sun.net.ssl.internal.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:782)
>>     at com.sun.net.ssl.internal.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:674)
>>     at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:566)
>>     at org.apache.mina.filter.support.SSLHandler.unwrapHandshake(SSLHandler.java:677)
>>     at org.apache.mina.filter.support.SSLHandler.handshake(SSLHandler.java:494)
>>     at org.apache.mina.filter.support.SSLHandler.messageReceived(SSLHandler.java:293)
>>     at org.apache.mina.filter.SSLFilter.messageReceived(SSLFilter.java:392)
>>     ... 12 more
>> [/127.0.0.1:2291] CLOSED
>> Exiting since queue is empty for /127.0.0.1:2291
>

Re: Adding SSLFilter on the fly

Posted by Niklas Gustavsson <ni...@protocol7.com>.
Alex Karasulu wrote:
> Niklas,
> 
> You might want to direct your inquiries to the MINA mailing list from 
> now on.
> 
> MINA has become it's own TLP and is no longer a subproject of the 
> Directory TLP.

Oh, I was using the newsgroup over at gmane.org for posting, it seems 
they still point to the old list. I've requested them to move it.

Anyways, the question still stands :-)

/niklas

Re: Adding SSLFilter on the fly

Posted by Niklas Gustavsson <ni...@protocol7.com>.
Hi

Anyone got any idea as to how I could solve the issue I describe below? 
The MINA integration into FtpServer is not full functional, except for 
the SSL support :-/

Thanks!

/niklas

> Niklas Gustavsson wrote:
>> Hi
>>
>> I'm trying to integrate MINA with Apache FtpServer, basically base 
>> FtpServer's socket handling on MINA. So far it's been a great 
>> experience. However, I just got stuck. It might very likely be an 
>> error on my side but I need some pointers :-)
>>
>> The FTP AUTH command is sent by a client to tell the server that it 
>> wants to secure the FTP control socket with SSL. The flow is like this:
>>
>> 1. Client sends "AUTH TLS"
>> 2. Server sends "234 Command AUTH okay; starting TLS connection."
>> 3. Server secures the socket
>> 4. Next client call is over the secure socket
>>
>> Now, to implement this I add a SSLFilter at step 3. However, I seem to 
>> run into a condition where the response sent at step 2 sometimes end 
>> up in the, not yet initialized, SSLFilter. This results in:
>> java.lang.IllegalStateException
>>     at 
>> org.apache.mina.filter.SSLFilter.getSSLSessionHandler(SSLFilter.java:634)
>>     at 
>> org.apache.mina.filter.SSLFilter.messageReceived(SSLFilter.java:371)
>>     at 
>> org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362) 
>>
>>     at 
>> org.apache.mina.common.support.AbstractIoFilterChain.access$1200(AbstractIoFilterChain.java:54) 
>>
>>     at 
>> org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:800) 
>>
>>     at 
>> org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.messageReceived(AbstractIoFilterChain.java:617) 
>>
>>     at 
>> org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain..java:362) 
>>
>>     at 
>> org.apache.mina.common.support.AbstractIoFilterChain.fireMessageReceived(AbstractIoFilterChain.java:353) 
>>
>>     at 
>> org.apache.mina.transport.socket.nio.SocketIoProcessor.read(SocketIoProcessor.java:281) 
>>
>>     at 
>> org.apache.mina.transport.socket.nio.SocketIoProcessor.process(SocketIoProcessor.java:241) 
>>
>>     at 
>> org.apache.mina.transport.socket.nio.SocketIoProcessor.access$500(SocketIoProcessor.java:44) 
>>
>>     at 
>> org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:559) 
>>
>>     at 
>> org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:43) 
>>
>>     at java.lang.Thread.run(Thread.java:595)
>>
>>
>>  From my understanding, the response should already has been sent to 
>> the client but that seems not to be the case. The response (step 2) is 
>> sent as:
>> session.write(response).join();
>>
>> Shouldn't the join() make that call wait until the write is completely 
>> done? If not, how would I otherwise ensure that the response has been 
>> sent before I add the SSL filter?
>>
>> The full trace is attached.
>>
>> Thanks!
>> /niklas
>>
>>
>> ------------------------------------------------------------------------
>>
>> Server ready :: Apache FTP Server
>> ------- Apache FTP Server started ------
>> [/127.0.0.1:2291] CREATED
>> Launching thread for /127.0.0.1:2291
>> [/127.0.0.1:2291] OPENED
>> [/127.0.0.1:2291] WRITE: 220 Service ready for new user.
>>
>> < 220 Service ready for new user.
>>> AUTH TLS
>> AUTH TLS
>>
>> AUTH TLS
>>
>> [/127.0.0.1:2291] RECEIVED: AUTH TLS
>> [/127.0.0.1:2291] WRITE: 234 Command AUTH okay; starting TLS connection.
>>
>> < 220 Service ready for new user.
>> 234 Command AUTH okay; starting TLS connection.
>> [/127.0.0.1:2291]  doHandshake()
>> [/127.0.0.1:2291]   initialHandshakeStatus=NEED_UNWRAP
>> [/127.0.0.1:2291]  unwrapHandshake()
>> [/127.0.0.1:2291]    inNetBuffer: java.nio.DirectByteBuffer[pos=0 
>> lim=0 cap=16665]
>> [/127.0.0.1:2291]    appBuffer: java.nio.DirectByteBuffer[pos=0 
>> lim=33330 cap=33330]
>> [/127.0.0.1:2291]  Unwrap res:Status = BUFFER_UNDERFLOW 
>> HandshakeStatus = NEED_UNWRAP
>> bytesConsumed = 0 bytesProduced = 0
>> org.apache.ftpserver.listener.mina.MinaConnection@1cb52ae
>> [/127.0.0.1:2291] SENT: 220 Service ready for new user.
>>
>> [/127.0.0.1:2291] SENT: 234 Command AUTH okay; starting TLS connection.
>>
>> [/127.0.0.1:2291] EXCEPTION:
>> java.lang.IllegalStateException
>>     at 
>> org.apache.mina.filter.SSLFilter.getSSLSessionHandler(SSLFilter.java:634)
>>     at 
>> org.apache.mina.filter.SSLFilter.messageReceived(SSLFilter.java:371)
>>     at 
>> org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362) 
>>
>>     at 
>> org.apache.mina.common.support.AbstractIoFilterChain.access$1200(AbstractIoFilterChain.java:54) 
>>
>>     at 
>> org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:800) 
>>
>>     at 
>> org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.messageReceived(AbstractIoFilterChain.java:617) 
>>
>>     at 
>> org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362) 
>>
>>     at 
>> org.apache.mina.common.support.AbstractIoFilterChain.fireMessageReceived(AbstractIoFilterChain.java:353) 
>>
>>     at 
>> org.apache.mina.transport.socket.nio.SocketIoProcessor.read(SocketIoProcessor.java:281) 
>>
>>     at 
>> org.apache.mina.transport.socket.nio.SocketIoProcessor.process(SocketIoProcessor.java:241) 
>>
>>     at 
>> org.apache.mina.transport.socket.nio.SocketIoProcessor.access$500(SocketIoProcessor.java:44) 
>>
>>     at 
>> org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:559) 
>>
>>     at 
>> org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:43) 
>>
>>     at java.lang.Thread.run(Thread.java:595)
>> [/127.0.0.1:2291] CLOSE
>> [/127.0.0.1:2291]  write outNetBuffer: java.nio.DirectByteBuffer[pos=0 
>> lim=7 cap=16665]
>> [/127.0.0.1:2291]  session write: DirectBuffer[pos=0 lim=7 cap=8: 15 
>> 03 01 00 02 01 00]
>> [/127.0.0.1:2291]  Data Read: 
>> org.apache.mina.filter.support.SSLHandler@1addb59 (DirectBuffer[pos=0 
>> lim=7 cap=8192: 15 03 01 00 02 02 0A])
>> [/127.0.0.1:2291]  doHandshake()
>> [/127.0.0.1:2291]   initialHandshakeStatus=NEED_UNWRAP
>> [/127.0.0.1:2291]  unwrapHandshake()
>> [/127.0.0.1:2291]    inNetBuffer: java.nio.DirectByteBuffer[pos=0 
>> lim=7 cap=16665]
>> [/127.0.0.1:2291]    appBuffer: java.nio.DirectByteBuffer[pos=0 
>> lim=33330 cap=33330]
>> [/127.0.0.1:2291] Unexpected exception from SSLEngine.closeInbound().
>> javax.net.ssl.SSLException: Inbound closed before receiving peer's 
>> close_notify: possible truncation attack?
>>     at 
>> com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:166)
>>     at 
>> com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1352)
>>     at 
>> com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1320)
>>     at 
>> com.sun.net.ssl.internal.ssl.SSLEngineImpl.closeInbound(SSLEngineImpl.java:1259) 
>>
>>     at 
>> org.apache.mina.filter.support.SSLHandler.destroy(SSLHandler.java:165)
>>     at org.apache.mina.filter.SSLFilter.sessionClosed(SSLFilter.java:358)
>>     at 
>> org.apache.mina.common.support.AbstractIoFilterChain.callNextSessionClosed(AbstractIoFilterChain.java:321) 
>>
>>     at 
>> org.apache.mina.common.support.AbstractIoFilterChain.access$900(AbstractIoFilterChain.java:54) 
>>
>>     at 
>> org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.sessionClosed(AbstractIoFilterChain.java:781) 
>>
>>     at 
>> org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.sessionClosed(AbstractIoFilterChain.java:599) 
>>
>>     at 
>> org.apache.mina.common.support.AbstractIoFilterChain.callNextSessionClosed(AbstractIoFilterChain.java:321) 
>>
>>     at 
>> org.apache.mina.common.support.AbstractIoFilterChain.fireSessionClosed(AbstractIoFilterChain.java:313) 
>>
>>     at 
>> org.apache.mina.common.support.IoServiceListenerSupport.fireSessionDestroyed(IoServiceListenerSupport.java:271) 
>>
>>     at 
>> org.apache.mina.transport.socket.nio.SocketIoProcessor.doRemove(SocketIoProcessor.java:225) 
>>
>>     at 
>> org.apache.mina.transport.socket.nio.SocketIoProcessor.access$700(SocketIoProcessor.java:44) 
>>
>>     at 
>> org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:563) 
>>
>>     at 
>> org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:43) 
>>
>>     at java.lang.Thread.run(Thread.java:595)
>> [/127.0.0.1:2291] EXCEPTION:
>> javax.net.ssl.SSLHandshakeException: Initial SSL handshake failed.
>>     at 
>> org.apache.mina.filter.SSLFilter.messageReceived(SSLFilter.java:424)
>>     at 
>> org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362) 
>>
>>     at 
>> org.apache.mina.common.support.AbstractIoFilterChain.access$1200(AbstractIoFilterChain.java:54) 
>>
>>     at 
>> org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:800) 
>>
>>     at 
>> org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.messageReceived(AbstractIoFilterChain.java:617) 
>>
>>     at 
>> org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362) 
>>
>>     at 
>> org.apache.mina.common.support.AbstractIoFilterChain.fireMessageReceived(AbstractIoFilterChain.java:353) 
>>
>>     at 
>> org.apache.mina.transport.socket.nio.SocketIoProcessor.read(SocketIoProcessor.java:281) 
>>
>>     at 
>> org.apache.mina.transport.socket.nio.SocketIoProcessor.process(SocketIoProcessor.java:241) 
>>
>>     at 
>> org.apache.mina.transport.socket.nio.SocketIoProcessor.access$500(SocketIoProcessor.java:44) 
>>
>>     at 
>> org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:559) 
>>
>>     at 
>> org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:43) 
>>
>>     at java.lang.Thread.run(Thread.java:595)
>> Caused by: javax.net.ssl.SSLException: Received fatal alert: 
>> unexpected_message
>>     at 
>> com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:166)
>>     at 
>> com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1352)
>>     at 
>> com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1320)
>>     at 
>> com.sun.net.ssl.internal.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1482) 
>>
>>     at 
>> com.sun.net.ssl.internal.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:957) 
>>
>>     at 
>> com.sun.net.ssl.internal.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:782) 
>>
>>     at 
>> com.sun.net.ssl.internal.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:674)
>>     at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:566)
>>     at 
>> org.apache.mina.filter.support.SSLHandler.unwrapHandshake(SSLHandler.java:677) 
>>
>>     at 
>> org.apache.mina.filter.support.SSLHandler.handshake(SSLHandler.java:494)
>>     at 
>> org.apache.mina.filter.support.SSLHandler.messageReceived(SSLHandler.java:293) 
>>
>>     at 
>> org.apache.mina.filter.SSLFilter.messageReceived(SSLFilter.java:392)
>>     ... 12 more
>> [/127.0.0.1:2291] CLOSED
>> Exiting since queue is empty for /127.0.0.1:2291
> 


Re: Adding SSLFilter on the fly

Posted by Alex Karasulu <ak...@apache.org>.
Niklas,

You might want to direct your inquiries to the MINA mailing list from 
now on.

MINA has become it's own TLP and is no longer a subproject of the 
Directory TLP.

Alex

Niklas Gustavsson wrote:
> Hi
> 
> I'm trying to integrate MINA with Apache FtpServer, basically base 
> FtpServer's socket handling on MINA. So far it's been a great 
> experience. However, I just got stuck. It might very likely be an error 
> on my side but I need some pointers :-)
> 
> The FTP AUTH command is sent by a client to tell the server that it 
> wants to secure the FTP control socket with SSL. The flow is like this:
> 
> 1. Client sends "AUTH TLS"
> 2. Server sends "234 Command AUTH okay; starting TLS connection."
> 3. Server secures the socket
> 4. Next client call is over the secure socket
> 
> Now, to implement this I add a SSLFilter at step 3. However, I seem to 
> run into a condition where the response sent at step 2 sometimes end up 
> in the, not yet initialized, SSLFilter. This results in:
> java.lang.IllegalStateException
>     at 
> org.apache.mina.filter.SSLFilter.getSSLSessionHandler(SSLFilter.java:634)
>     at org.apache.mina.filter.SSLFilter.messageReceived(SSLFilter.java:371)
>     at 
> org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362) 
> 
>     at 
> org.apache.mina.common.support.AbstractIoFilterChain.access$1200(AbstractIoFilterChain.java:54) 
> 
>     at 
> org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:800) 
> 
>     at 
> org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.messageReceived(AbstractIoFilterChain.java:617) 
> 
>     at 
> org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain..java:362) 
> 
>     at 
> org.apache.mina.common.support.AbstractIoFilterChain.fireMessageReceived(AbstractIoFilterChain.java:353) 
> 
>     at 
> org.apache.mina.transport.socket.nio.SocketIoProcessor.read(SocketIoProcessor.java:281) 
> 
>     at 
> org.apache.mina.transport.socket.nio.SocketIoProcessor.process(SocketIoProcessor.java:241) 
> 
>     at 
> org.apache.mina.transport.socket.nio.SocketIoProcessor.access$500(SocketIoProcessor.java:44) 
> 
>     at 
> org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:559) 
> 
>     at 
> org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:43) 
> 
>     at java.lang.Thread.run(Thread.java:595)
> 
> 
>  From my understanding, the response should already has been sent to the 
> client but that seems not to be the case. The response (step 2) is sent as:
> session.write(response).join();
> 
> Shouldn't the join() make that call wait until the write is completely 
> done? If not, how would I otherwise ensure that the response has been 
> sent before I add the SSL filter?
> 
> The full trace is attached.
> 
> Thanks!
> /niklas
> 
> 
> ------------------------------------------------------------------------
> 
> Server ready :: Apache FTP Server
> ------- Apache FTP Server started ------
> [/127.0.0.1:2291] CREATED
> Launching thread for /127.0.0.1:2291
> [/127.0.0.1:2291] OPENED
> [/127.0.0.1:2291] WRITE: 220 Service ready for new user.
> 
> < 220 Service ready for new user.
>> AUTH TLS
> AUTH TLS
> 
> AUTH TLS
> 
> [/127.0.0.1:2291] RECEIVED: AUTH TLS
> [/127.0.0.1:2291] WRITE: 234 Command AUTH okay; starting TLS connection.
> 
> < 220 Service ready for new user.
> 234 Command AUTH okay; starting TLS connection.
> [/127.0.0.1:2291]  doHandshake()
> [/127.0.0.1:2291]   initialHandshakeStatus=NEED_UNWRAP
> [/127.0.0.1:2291]  unwrapHandshake()
> [/127.0.0.1:2291]    inNetBuffer: java.nio.DirectByteBuffer[pos=0 lim=0 cap=16665]
> [/127.0.0.1:2291]    appBuffer: java.nio.DirectByteBuffer[pos=0 lim=33330 cap=33330]
> [/127.0.0.1:2291]  Unwrap res:Status = BUFFER_UNDERFLOW HandshakeStatus = NEED_UNWRAP
> bytesConsumed = 0 bytesProduced = 0
> org.apache.ftpserver.listener.mina.MinaConnection@1cb52ae
> [/127.0.0.1:2291] SENT: 220 Service ready for new user.
> 
> [/127.0.0.1:2291] SENT: 234 Command AUTH okay; starting TLS connection.
> 
> [/127.0.0.1:2291] EXCEPTION:
> java.lang.IllegalStateException
> 	at org.apache.mina.filter.SSLFilter.getSSLSessionHandler(SSLFilter.java:634)
> 	at org.apache.mina.filter.SSLFilter.messageReceived(SSLFilter.java:371)
> 	at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362)
> 	at org.apache.mina.common.support.AbstractIoFilterChain.access$1200(AbstractIoFilterChain.java:54)
> 	at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:800)
> 	at org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.messageReceived(AbstractIoFilterChain.java:617)
> 	at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362)
> 	at org.apache.mina.common.support.AbstractIoFilterChain.fireMessageReceived(AbstractIoFilterChain.java:353)
> 	at org.apache.mina.transport.socket.nio.SocketIoProcessor.read(SocketIoProcessor.java:281)
> 	at org.apache.mina.transport.socket.nio.SocketIoProcessor.process(SocketIoProcessor.java:241)
> 	at org.apache.mina.transport.socket.nio.SocketIoProcessor.access$500(SocketIoProcessor.java:44)
> 	at org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:559)
> 	at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:43)
> 	at java.lang.Thread.run(Thread.java:595)
> [/127.0.0.1:2291] CLOSE
> [/127.0.0.1:2291]  write outNetBuffer: java.nio.DirectByteBuffer[pos=0 lim=7 cap=16665]
> [/127.0.0.1:2291]  session write: DirectBuffer[pos=0 lim=7 cap=8: 15 03 01 00 02 01 00]
> [/127.0.0.1:2291]  Data Read: org.apache.mina.filter.support.SSLHandler@1addb59 (DirectBuffer[pos=0 lim=7 cap=8192: 15 03 01 00 02 02 0A])
> [/127.0.0.1:2291]  doHandshake()
> [/127.0.0.1:2291]   initialHandshakeStatus=NEED_UNWRAP
> [/127.0.0.1:2291]  unwrapHandshake()
> [/127.0.0.1:2291]    inNetBuffer: java.nio.DirectByteBuffer[pos=0 lim=7 cap=16665]
> [/127.0.0.1:2291]    appBuffer: java.nio.DirectByteBuffer[pos=0 lim=33330 cap=33330]
> [/127.0.0.1:2291] Unexpected exception from SSLEngine.closeInbound().
> javax.net.ssl.SSLException: Inbound closed before receiving peer's close_notify: possible truncation attack?
> 	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:166)
> 	at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1352)
> 	at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1320)
> 	at com.sun.net.ssl.internal.ssl.SSLEngineImpl.closeInbound(SSLEngineImpl.java:1259)
> 	at org.apache.mina.filter.support.SSLHandler.destroy(SSLHandler.java:165)
> 	at org.apache.mina.filter.SSLFilter.sessionClosed(SSLFilter.java:358)
> 	at org.apache.mina.common.support.AbstractIoFilterChain.callNextSessionClosed(AbstractIoFilterChain.java:321)
> 	at org.apache.mina.common.support.AbstractIoFilterChain.access$900(AbstractIoFilterChain.java:54)
> 	at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.sessionClosed(AbstractIoFilterChain.java:781)
> 	at org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.sessionClosed(AbstractIoFilterChain.java:599)
> 	at org.apache.mina.common.support.AbstractIoFilterChain.callNextSessionClosed(AbstractIoFilterChain.java:321)
> 	at org.apache.mina.common.support.AbstractIoFilterChain.fireSessionClosed(AbstractIoFilterChain.java:313)
> 	at org.apache.mina.common.support.IoServiceListenerSupport.fireSessionDestroyed(IoServiceListenerSupport.java:271)
> 	at org.apache.mina.transport.socket.nio.SocketIoProcessor.doRemove(SocketIoProcessor.java:225)
> 	at org.apache.mina.transport.socket.nio.SocketIoProcessor.access$700(SocketIoProcessor.java:44)
> 	at org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:563)
> 	at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:43)
> 	at java.lang.Thread.run(Thread.java:595)
> [/127.0.0.1:2291] EXCEPTION:
> javax.net.ssl.SSLHandshakeException: Initial SSL handshake failed.
> 	at org.apache.mina.filter.SSLFilter.messageReceived(SSLFilter.java:424)
> 	at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362)
> 	at org.apache.mina.common.support.AbstractIoFilterChain.access$1200(AbstractIoFilterChain.java:54)
> 	at org.apache.mina.common.support.AbstractIoFilterChain$EntryImpl$1.messageReceived(AbstractIoFilterChain.java:800)
> 	at org.apache.mina.common.support.AbstractIoFilterChain$HeadFilter.messageReceived(AbstractIoFilterChain.java:617)
> 	at org.apache.mina.common.support.AbstractIoFilterChain.callNextMessageReceived(AbstractIoFilterChain.java:362)
> 	at org.apache.mina.common.support.AbstractIoFilterChain.fireMessageReceived(AbstractIoFilterChain.java:353)
> 	at org.apache.mina.transport.socket.nio.SocketIoProcessor.read(SocketIoProcessor.java:281)
> 	at org.apache.mina.transport.socket.nio.SocketIoProcessor.process(SocketIoProcessor.java:241)
> 	at org.apache.mina.transport.socket.nio.SocketIoProcessor.access$500(SocketIoProcessor.java:44)
> 	at org.apache.mina.transport.socket.nio.SocketIoProcessor$Worker.run(SocketIoProcessor.java:559)
> 	at org.apache.mina.util.NamePreservingRunnable.run(NamePreservingRunnable.java:43)
> 	at java.lang.Thread.run(Thread.java:595)
> Caused by: javax.net.ssl.SSLException: Received fatal alert: unexpected_message
> 	at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Alerts.java:166)
> 	at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1352)
> 	at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(SSLEngineImpl.java:1320)
> 	at com.sun.net.ssl.internal.ssl.SSLEngineImpl.recvAlert(SSLEngineImpl.java:1482)
> 	at com.sun.net.ssl.internal.ssl.SSLEngineImpl.readRecord(SSLEngineImpl.java:957)
> 	at com.sun.net.ssl.internal.ssl.SSLEngineImpl.readNetRecord(SSLEngineImpl.java:782)
> 	at com.sun.net.ssl.internal.ssl.SSLEngineImpl.unwrap(SSLEngineImpl.java:674)
> 	at javax.net.ssl.SSLEngine.unwrap(SSLEngine.java:566)
> 	at org.apache.mina.filter.support.SSLHandler.unwrapHandshake(SSLHandler.java:677)
> 	at org.apache.mina.filter.support.SSLHandler.handshake(SSLHandler.java:494)
> 	at org.apache.mina.filter.support.SSLHandler.messageReceived(SSLHandler.java:293)
> 	at org.apache.mina.filter.SSLFilter.messageReceived(SSLFilter.java:392)
> 	... 12 more
> [/127.0.0.1:2291] CLOSED
> Exiting since queue is empty for /127.0.0.1:2291