This is an automated email from the ASF dual-hosted git repository. johnnyv pushed a commit to branch bugfix/DIRMINA1132 in repository https://gitbox.apache.org/repos/asf/mina.git
The following commit(s) were added to refs/heads/bugfix/DIRMINA1132 by this push: new 2efbcbc Adds support for IoEvent.SECURED and IoSession#isSecured() 2efbcbc is described below commit 2efbcbc20e7950428ff79ab9fcfd44d07a307cc8 Author: Jonathan Valliere <john...@apache.org> AuthorDate: Sat Jul 24 18:00:09 2021 -0400 Adds support for IoEvent.SECURED and IoSession#isSecured() --- .../org/apache/mina/filter/ssl2/SSL2Filter.java | 8 +- .../org/apache/mina/filter/ssl2/SSL2Handler.java | 14 +- .../org/apache/mina/filter/ssl2/SSL2HandlerG0.java | 31 +- .../transport/socket/nio/NioSocketSession.java | 618 ++++++++++----------- 4 files changed, 353 insertions(+), 318 deletions(-) diff --git a/mina-core/src/main/java/org/apache/mina/filter/ssl2/SSL2Filter.java b/mina-core/src/main/java/org/apache/mina/filter/ssl2/SSL2Filter.java index 80e5688..803fde5 100644 --- a/mina-core/src/main/java/org/apache/mina/filter/ssl2/SSL2Filter.java +++ b/mina-core/src/main/java/org/apache/mina/filter/ssl2/SSL2Filter.java @@ -48,16 +48,14 @@ import org.slf4j.LoggerFactory; * @author <a href="http://mina.apache.org">Apache MINA Project</a> */ public class SSL2Filter extends IoFilterAdapter { - /** - * The logger - */ + + public static final AttributeKey SSL_HANDLER = new AttributeKey(SSL2Filter.class, "handler"); + protected static final Logger LOGGER = LoggerFactory.getLogger(SSL2Filter.class); protected static final Executor EXECUTOR = new ThreadPoolExecutor(2, 2, 100, TimeUnit.MILLISECONDS, new LinkedBlockingDeque<Runnable>(), new BasicThreadFactory("ssl-exec", true)); - protected static final AttributeKey SSL_HANDLER = new AttributeKey(SSL2Filter.class, "handler"); - protected final SSLContext mContext; protected boolean mNeedClientAuth; diff --git a/mina-core/src/main/java/org/apache/mina/filter/ssl2/SSL2Handler.java b/mina-core/src/main/java/org/apache/mina/filter/ssl2/SSL2Handler.java index d8eb1eb..3329b8e 100644 --- a/mina-core/src/main/java/org/apache/mina/filter/ssl2/SSL2Handler.java +++ b/mina-core/src/main/java/org/apache/mina/filter/ssl2/SSL2Handler.java @@ -74,6 +74,16 @@ public abstract class SSL2Handler { } /** + * {@code true} if the encryption session is open + */ + abstract public boolean isOpen(); + + /** + * {@code true} if the encryption session is connected and secure + */ + abstract public boolean isConnected(); + + /** * Opens the encryption session, this may include sending the initial handshake * message * @@ -153,8 +163,8 @@ public abstract class SSL2Handler { b.append("server"); } - b.append(", status="); - b.append(this.mEngine.getHandshakeStatus()); + b.append(", connected="); + b.append(this.isConnected()); b.append("]"); diff --git a/mina-core/src/main/java/org/apache/mina/filter/ssl2/SSL2HandlerG0.java b/mina-core/src/main/java/org/apache/mina/filter/ssl2/SSL2HandlerG0.java index 9961a32..2f8300d 100644 --- a/mina-core/src/main/java/org/apache/mina/filter/ssl2/SSL2HandlerG0.java +++ b/mina-core/src/main/java/org/apache/mina/filter/ssl2/SSL2HandlerG0.java @@ -10,6 +10,7 @@ import org.apache.mina.core.buffer.IoBuffer; import org.apache.mina.core.filterchain.IoFilter.NextFilter; import org.apache.mina.core.session.IoSession; import org.apache.mina.core.write.WriteRequest; +import org.apache.mina.filter.ssl.SslEvent; public class SSL2HandlerG0 extends SSL2Handler { @@ -18,6 +19,11 @@ public class SSL2HandlerG0 extends SSL2Handler { */ static protected final int MAX_UNACK_MESSAGES = 6; + /** + * Indicates whether the first handshake was completed + */ + protected boolean mHandshakeComplete = false; + public SSL2HandlerG0(SSLEngine p, Executor e, IoSession s) { super(p, e, s); } @@ -25,6 +31,22 @@ public class SSL2HandlerG0 extends SSL2Handler { /** * {@inheritDoc} */ + @Override + public boolean isOpen() { + return this.mEngine.isOutboundDone() == false; + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isConnected() { + return this.mHandshakeComplete && isOpen(); + } + + /** + * {@inheritDoc} + */ synchronized public void open(final NextFilter next) throws SSLException { if (this.mEngine.getUseClientMode()) { if (LOGGER.isDebugEnabled()) { @@ -105,6 +127,7 @@ public class SSL2HandlerG0 extends SSL2Handler { if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} lreceive() - handshake finished, flushing pending requests", toString()); } + this.lfinish(next); this.lflush(next); break; } @@ -163,7 +186,6 @@ public class SSL2HandlerG0 extends SSL2Handler { */ @SuppressWarnings("incomplete-switch") synchronized protected boolean lwrite(final NextFilter next, final WriteRequest request) throws SSLException { - if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} lwrite() - source {}", toString(), request); } @@ -230,6 +252,7 @@ public class SSL2HandlerG0 extends SSL2Handler { if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} lwrite() - handshake finished, flushing pending requests", toString()); } + this.lfinish(next); if (this.lwrite(next, request)) { this.lflush(next); return true; @@ -293,6 +316,7 @@ public class SSL2HandlerG0 extends SSL2Handler { if (LOGGER.isDebugEnabled()) { LOGGER.debug("{} lwrite() - handshake finished, flushing pending requests", toString()); } + this.lfinish(next); this.lflush(next); break; } @@ -300,6 +324,11 @@ public class SSL2HandlerG0 extends SSL2Handler { return result.bytesProduced() > 0; } + synchronized protected void lfinish(final NextFilter next) { + this.mHandshakeComplete = true; + next.event(this.mSession, SslEvent.SECURED); + } + /** * Flushes the encode queue * diff --git a/mina-core/src/main/java/org/apache/mina/transport/socket/nio/NioSocketSession.java b/mina-core/src/main/java/org/apache/mina/transport/socket/nio/NioSocketSession.java index 84e7e48..fb04fa4 100644 --- a/mina-core/src/main/java/org/apache/mina/transport/socket/nio/NioSocketSession.java +++ b/mina-core/src/main/java/org/apache/mina/transport/socket/nio/NioSocketSession.java @@ -35,6 +35,8 @@ import org.apache.mina.core.service.IoService; import org.apache.mina.core.service.TransportMetadata; import org.apache.mina.core.session.IoSession; import org.apache.mina.filter.ssl.SslFilter; +import org.apache.mina.filter.ssl2.SSL2Filter; +import org.apache.mina.filter.ssl2.SSL2Handler; import org.apache.mina.transport.socket.AbstractSocketSessionConfig; import org.apache.mina.transport.socket.SocketSessionConfig; @@ -44,314 +46,310 @@ import org.apache.mina.transport.socket.SocketSessionConfig; * @author <a href="http://mina.apache.org">Apache MINA Project</a> */ class NioSocketSession extends NioSession { - static final TransportMetadata METADATA = new DefaultTransportMetadata("nio", "socket", false, true, - InetSocketAddress.class, SocketSessionConfig.class, IoBuffer.class, FileRegion.class); - - /** - * - * Creates a new instance of NioSocketSession. - * - * @param service the associated IoService - * @param processor the associated IoProcessor - * @param channel the used channel - */ - public NioSocketSession(IoService service, IoProcessor<NioSession> processor, SocketChannel channel) { - super(processor, service, channel); - config = new SessionConfigImpl(); - config.setAll(service.getSessionConfig()); - } - - private Socket getSocket() { - return ((SocketChannel) channel).socket(); - } - - /** - * {@inheritDoc} - */ - @Override - public TransportMetadata getTransportMetadata() { - return METADATA; - } - - /** - * {@inheritDoc} - */ - @Override - public SocketSessionConfig getConfig() { - return (SocketSessionConfig) config; - } - - /** - * {@inheritDoc} - */ - @Override - SocketChannel getChannel() { - return (SocketChannel) channel; - } - - /** - * {@inheritDoc} - */ - @Override - public InetSocketAddress getRemoteAddress() { - if (channel == null) { - return null; - } - - Socket socket = getSocket(); - - if (socket == null) { - return null; - } - - return (InetSocketAddress) socket.getRemoteSocketAddress(); - } - - /** - * {@inheritDoc} - */ - @Override - public InetSocketAddress getLocalAddress() { - if (channel == null) { - return null; - } - - Socket socket = getSocket(); - - if (socket == null) { - return null; - } - - return (InetSocketAddress) socket.getLocalSocketAddress(); - } - - @Override - public InetSocketAddress getServiceAddress() { - return (InetSocketAddress) super.getServiceAddress(); - } - - /** - * A private class storing a copy of the IoService configuration when the IoSession - * is created. That allows the session to have its own configuration setting, over - * the IoService default one. - */ - private class SessionConfigImpl extends AbstractSocketSessionConfig { - /** - * {@inheritDoc} - */ - @Override - public boolean isKeepAlive() { - try { - return getSocket().getKeepAlive(); - } catch (SocketException e) { - throw new RuntimeIoException(e); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void setKeepAlive(boolean on) { - try { - getSocket().setKeepAlive(on); - } catch (SocketException e) { - throw new RuntimeIoException(e); - } - } - - /** - * {@inheritDoc} - */ - @Override - public boolean isOobInline() { - try { - return getSocket().getOOBInline(); - } catch (SocketException e) { - throw new RuntimeIoException(e); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void setOobInline(boolean on) { - try { - getSocket().setOOBInline(on); - } catch (SocketException e) { - throw new RuntimeIoException(e); - } - } - - /** - * {@inheritDoc} - */ - @Override - public boolean isReuseAddress() { - try { - return getSocket().getReuseAddress(); - } catch (SocketException e) { - throw new RuntimeIoException(e); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void setReuseAddress(boolean on) { - try { - getSocket().setReuseAddress(on); - } catch (SocketException e) { - throw new RuntimeIoException(e); - } - } - - /** - * {@inheritDoc} - */ - @Override - public int getSoLinger() { - try { - return getSocket().getSoLinger(); - } catch (SocketException e) { - throw new RuntimeIoException(e); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void setSoLinger(int linger) { - try { - if (linger < 0) { - getSocket().setSoLinger(false, 0); - } else { - getSocket().setSoLinger(true, linger); - } - } catch (SocketException e) { - throw new RuntimeIoException(e); - } - } - - /** - * {@inheritDoc} - */ - @Override - public boolean isTcpNoDelay() { - if (!isConnected()) { - return false; - } - - try { - return getSocket().getTcpNoDelay(); - } catch (SocketException e) { - throw new RuntimeIoException(e); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void setTcpNoDelay(boolean on) { - try { - getSocket().setTcpNoDelay(on); - } catch (SocketException e) { - throw new RuntimeIoException(e); - } - } - - /** - * {@inheritDoc} - */ - @Override - public int getTrafficClass() { - try { - return getSocket().getTrafficClass(); - } catch (SocketException e) { - throw new RuntimeIoException(e); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void setTrafficClass(int tc) { - try { - getSocket().setTrafficClass(tc); - } catch (SocketException e) { - throw new RuntimeIoException(e); - } - } - - /** - * {@inheritDoc} - */ - @Override - public int getSendBufferSize() { - try { - return getSocket().getSendBufferSize(); - } catch (SocketException e) { - throw new RuntimeIoException(e); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void setSendBufferSize(int size) { - try { - getSocket().setSendBufferSize(size); - } catch (SocketException e) { - throw new RuntimeIoException(e); - } - } - - /** - * {@inheritDoc} - */ - @Override - public int getReceiveBufferSize() { - try { - return getSocket().getReceiveBufferSize(); - } catch (SocketException e) { - throw new RuntimeIoException(e); - } - } - - /** - * {@inheritDoc} - */ - @Override - public void setReceiveBufferSize(int size) { - try { - getSocket().setReceiveBufferSize(size); - } catch (SocketException e) { - throw new RuntimeIoException(e); - } - } - } - - /** - * {@inheritDoc} - */ - @Override - public final boolean isSecured() { - // If the session does not have a SslFilter, we can return false - IoFilterChain chain = getFilterChain(); - - IoFilter sslFilter = chain.get(SslFilter.class); - - if (sslFilter != null) { - // Get the SslHandler from the SslFilter - return ((SslFilter)sslFilter).isSecured(this); - } else { - return false; - } - } + static final TransportMetadata METADATA = new DefaultTransportMetadata("nio", "socket", false, true, + InetSocketAddress.class, SocketSessionConfig.class, IoBuffer.class, FileRegion.class); + + /** + * + * Creates a new instance of NioSocketSession. + * + * @param service the associated IoService + * @param processor the associated IoProcessor + * @param channel the used channel + */ + public NioSocketSession(IoService service, IoProcessor<NioSession> processor, SocketChannel channel) { + super(processor, service, channel); + config = new SessionConfigImpl(); + config.setAll(service.getSessionConfig()); + } + + private Socket getSocket() { + return ((SocketChannel) channel).socket(); + } + + /** + * {@inheritDoc} + */ + @Override + public TransportMetadata getTransportMetadata() { + return METADATA; + } + + /** + * {@inheritDoc} + */ + @Override + public SocketSessionConfig getConfig() { + return (SocketSessionConfig) config; + } + + /** + * {@inheritDoc} + */ + @Override + SocketChannel getChannel() { + return (SocketChannel) channel; + } + + /** + * {@inheritDoc} + */ + @Override + public InetSocketAddress getRemoteAddress() { + if (channel == null) { + return null; + } + + Socket socket = getSocket(); + + if (socket == null) { + return null; + } + + return (InetSocketAddress) socket.getRemoteSocketAddress(); + } + + /** + * {@inheritDoc} + */ + @Override + public InetSocketAddress getLocalAddress() { + if (channel == null) { + return null; + } + + Socket socket = getSocket(); + + if (socket == null) { + return null; + } + + return (InetSocketAddress) socket.getLocalSocketAddress(); + } + + @Override + public InetSocketAddress getServiceAddress() { + return (InetSocketAddress) super.getServiceAddress(); + } + + /** + * A private class storing a copy of the IoService configuration when the + * IoSession is created. That allows the session to have its own configuration + * setting, over the IoService default one. + */ + private class SessionConfigImpl extends AbstractSocketSessionConfig { + /** + * {@inheritDoc} + */ + @Override + public boolean isKeepAlive() { + try { + return getSocket().getKeepAlive(); + } catch (SocketException e) { + throw new RuntimeIoException(e); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void setKeepAlive(boolean on) { + try { + getSocket().setKeepAlive(on); + } catch (SocketException e) { + throw new RuntimeIoException(e); + } + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isOobInline() { + try { + return getSocket().getOOBInline(); + } catch (SocketException e) { + throw new RuntimeIoException(e); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void setOobInline(boolean on) { + try { + getSocket().setOOBInline(on); + } catch (SocketException e) { + throw new RuntimeIoException(e); + } + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isReuseAddress() { + try { + return getSocket().getReuseAddress(); + } catch (SocketException e) { + throw new RuntimeIoException(e); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void setReuseAddress(boolean on) { + try { + getSocket().setReuseAddress(on); + } catch (SocketException e) { + throw new RuntimeIoException(e); + } + } + + /** + * {@inheritDoc} + */ + @Override + public int getSoLinger() { + try { + return getSocket().getSoLinger(); + } catch (SocketException e) { + throw new RuntimeIoException(e); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void setSoLinger(int linger) { + try { + if (linger < 0) { + getSocket().setSoLinger(false, 0); + } else { + getSocket().setSoLinger(true, linger); + } + } catch (SocketException e) { + throw new RuntimeIoException(e); + } + } + + /** + * {@inheritDoc} + */ + @Override + public boolean isTcpNoDelay() { + if (!isConnected()) { + return false; + } + + try { + return getSocket().getTcpNoDelay(); + } catch (SocketException e) { + throw new RuntimeIoException(e); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void setTcpNoDelay(boolean on) { + try { + getSocket().setTcpNoDelay(on); + } catch (SocketException e) { + throw new RuntimeIoException(e); + } + } + + /** + * {@inheritDoc} + */ + @Override + public int getTrafficClass() { + try { + return getSocket().getTrafficClass(); + } catch (SocketException e) { + throw new RuntimeIoException(e); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void setTrafficClass(int tc) { + try { + getSocket().setTrafficClass(tc); + } catch (SocketException e) { + throw new RuntimeIoException(e); + } + } + + /** + * {@inheritDoc} + */ + @Override + public int getSendBufferSize() { + try { + return getSocket().getSendBufferSize(); + } catch (SocketException e) { + throw new RuntimeIoException(e); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void setSendBufferSize(int size) { + try { + getSocket().setSendBufferSize(size); + } catch (SocketException e) { + throw new RuntimeIoException(e); + } + } + + /** + * {@inheritDoc} + */ + @Override + public int getReceiveBufferSize() { + try { + return getSocket().getReceiveBufferSize(); + } catch (SocketException e) { + throw new RuntimeIoException(e); + } + } + + /** + * {@inheritDoc} + */ + @Override + public void setReceiveBufferSize(int size) { + try { + getSocket().setReceiveBufferSize(size); + } catch (SocketException e) { + throw new RuntimeIoException(e); + } + } + } + + /** + * {@inheritDoc} + */ + @Override + public final boolean isSecured() { + SslFilter s = SslFilter.class.cast(getFilterChain().get(SslFilter.class)); + if (s != null) { + return s.isSecured(this); + } else { + SSL2Handler x = SSL2Handler.class.cast(this.getAttribute(SSL2Filter.SSL_HANDLER)); + return x != null ? x.isConnected() : false; + } + } }