You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by jo...@apache.org on 2021/08/02 03:40:54 UTC
[mina] 09/15: Adds support for IoEvent.SECURED and
IoSession#isSecured()
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
commit f711c2a73efc8346ca2646f6c6fcde2d864161de
Author: Jonathan Valliere <jo...@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;
+ }
+ }
}