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;
+		}
+	}
 }