📄 sslfilter.java
字号:
NextFilter nextFilter) throws SSLException { if (parent.contains(SslFilter.class)) { throw new IllegalStateException( "Only one " + SslFilter.class.getName() + " is permitted."); } IoSession session = parent.getSession(); session.setAttribute(NEXT_FILTER, nextFilter); // Create an SSL handler and start handshake. SslHandler handler = new SslHandler(this, sslContext, session); session.setAttribute(SSL_HANDLER, handler); } @Override public void onPostAdd(IoFilterChain parent, String name, NextFilter nextFilter) throws SSLException { if (autoStart) { initiateHandshake(nextFilter, parent.getSession()); } } @Override public void onPreRemove(IoFilterChain parent, String name, NextFilter nextFilter) throws SSLException { IoSession session = parent.getSession(); stopSsl(session); session.removeAttribute(NEXT_FILTER); session.removeAttribute(SSL_HANDLER); } // IoFilter impl. @Override public void sessionClosed(NextFilter nextFilter, IoSession session) throws SSLException { SslHandler handler = getSslSessionHandler(session); try { synchronized (handler) { // release resources handler.destroy(); } handler.flushScheduledEvents(); } finally { // notify closed session nextFilter.sessionClosed(session); } } @Override public void messageReceived(NextFilter nextFilter, IoSession session, Object message) throws SSLException { SslHandler handler = getSslSessionHandler(session); synchronized (handler) { if (!isSslStarted(session) && handler.isInboundDone()) { handler.scheduleMessageReceived(nextFilter, message); } else { IoBuffer buf = (IoBuffer) message; try { // forward read encrypted data to SSL handler handler.messageReceived(nextFilter, buf.buf()); // Handle data to be forwarded to application or written to net handleSslData(nextFilter, handler); if (handler.isInboundDone()) { if (handler.isOutboundDone()) { handler.destroy(); } else { initiateClosure(nextFilter, session); } if (buf.hasRemaining()) { // Forward the data received after closure. handler.scheduleMessageReceived(nextFilter, buf); } } } catch (SSLException ssle) { if (!handler.isHandshakeComplete()) { SSLException newSsle = new SSLHandshakeException( "SSL handshake failed."); newSsle.initCause(ssle); ssle = newSsle; } throw ssle; } } } handler.flushScheduledEvents(); } @Override public void messageSent(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) { if (writeRequest instanceof EncryptedWriteRequest) { EncryptedWriteRequest wrappedRequest = (EncryptedWriteRequest) writeRequest; nextFilter.messageSent(session, wrappedRequest.getParentRequest()); } else { // ignore extra buffers used for handshaking } } @Override public void exceptionCaught(NextFilter nextFilter, IoSession session, Throwable cause) throws Exception { if (cause instanceof WriteToClosedSessionException) { // Filter out SSL close notify, which is likely to fail to flush // due to disconnection. WriteToClosedSessionException e = (WriteToClosedSessionException) cause; List<WriteRequest> failedRequests = e.getRequests(); boolean containsCloseNotify = false; for (WriteRequest r: failedRequests) { if (isCloseNotify(r.getMessage())) { containsCloseNotify = true; break; } } if (containsCloseNotify) { if (failedRequests.size() == 1) { // close notify is the only failed request; bail out. return; } List<WriteRequest> newFailedRequests = new ArrayList<WriteRequest>(failedRequests.size() - 1); for (WriteRequest r: failedRequests) { if (!isCloseNotify(r.getMessage())) { newFailedRequests.add(r); } } if (newFailedRequests.isEmpty()) { // the failedRequests were full with close notify; bail out. return; } cause = new WriteToClosedSessionException( newFailedRequests, cause.getMessage(), cause.getCause()); } } nextFilter.exceptionCaught(session, cause); } private boolean isCloseNotify(Object message) { if (!(message instanceof IoBuffer)) { return false; } IoBuffer buf = (IoBuffer) message; int offset = buf.position(); return buf.remaining() == 23 && buf.get(offset + 0) == 0x15 && buf.get(offset + 1) == 0x03 && buf.get(offset + 2) == 0x01 && buf.get(offset + 3) == 0x00 && buf.get(offset + 4) == 0x12; } @Override public void filterWrite(NextFilter nextFilter, IoSession session, WriteRequest writeRequest) throws SSLException { boolean needsFlush = true; SslHandler handler = getSslSessionHandler(session); synchronized (handler) { if (!isSslStarted(session)) { handler.scheduleFilterWrite(nextFilter, writeRequest); } // Don't encrypt the data if encryption is disabled. else if (session.containsAttribute(DISABLE_ENCRYPTION_ONCE)) { // Remove the marker attribute because it is temporary. session.removeAttribute(DISABLE_ENCRYPTION_ONCE); handler.scheduleFilterWrite(nextFilter, writeRequest); } else { // Otherwise, encrypt the buffer. IoBuffer buf = (IoBuffer) writeRequest.getMessage(); if (handler.isWritingEncryptedData()) { // data already encrypted; simply return buffer handler.scheduleFilterWrite(nextFilter, writeRequest); } else if (handler.isHandshakeComplete()) { // SSL encrypt int pos = buf.position(); handler.encrypt(buf.buf()); buf.position(pos); IoBuffer encryptedBuffer = handler.fetchOutNetBuffer(); handler.scheduleFilterWrite( nextFilter, new EncryptedWriteRequest( writeRequest, encryptedBuffer)); } else { if (session.isConnected()) { // Handshake not complete yet. handler.schedulePreHandshakeWriteRequest(nextFilter, writeRequest); } needsFlush = false; } } } if (needsFlush) { handler.flushScheduledEvents(); } } @Override public void filterClose(final NextFilter nextFilter, final IoSession session) throws SSLException { SslHandler handler = (SslHandler) session.getAttribute(SSL_HANDLER); if (handler == null) { // The connection might already have closed, or // SSL might have not started yet. nextFilter.filterClose(session); return; } WriteFuture future = null; try { synchronized (handler) { if (isSslStarted(session)) { future = initiateClosure(nextFilter, session); future.addListener(new IoFutureListener<IoFuture>() { public void operationComplete(IoFuture future) { nextFilter.filterClose(session); } }); } } handler.flushScheduledEvents(); } finally { if (future == null) { nextFilter.filterClose(session); } } } private void initiateHandshake(NextFilter nextFilter, IoSession session) throws SSLException { SslHandler handler = getSslSessionHandler(session); synchronized (handler) { handler.handshake(nextFilter); } handler.flushScheduledEvents(); } private WriteFuture initiateClosure(NextFilter nextFilter, IoSession session) throws SSLException { SslHandler handler = getSslSessionHandler(session); // if already shut down if (!handler.closeOutbound()) { return DefaultWriteFuture.newNotWrittenFuture( session, new IllegalStateException("SSL session is shut down already.")); } // there might be data to write out here? WriteFuture future = handler.writeNetBuffer(nextFilter); if (future == null) { future = DefaultWriteFuture.newWrittenFuture(session); } if (handler.isInboundDone()) { handler.destroy(); } if (session.containsAttribute(USE_NOTIFICATION)) { handler.scheduleMessageReceived(nextFilter, SESSION_UNSECURED); } return future; } // Utiliities private void handleSslData(NextFilter nextFilter, SslHandler handler) throws SSLException { // Flush any buffered write requests occurred before handshaking. if (handler.isHandshakeComplete()) { handler.flushPreHandshakeEvents(); } // Write encrypted data to be written (if any) handler.writeNetBuffer(nextFilter); // handle app. data read (if any) handleAppDataRead(nextFilter, handler); } private void handleAppDataRead(NextFilter nextFilter, SslHandler handler) { // forward read app data IoBuffer readBuffer = handler.fetchAppBuffer(); if (readBuffer.hasRemaining()) { handler.scheduleMessageReceived(nextFilter, readBuffer); } } private SslHandler getSslSessionHandler(IoSession session) { SslHandler handler = (SslHandler) session.getAttribute(SSL_HANDLER); if (handler == null) { throw new IllegalStateException(); } if (handler.getParent() != this) { throw new IllegalArgumentException("Not managed by this filter."); } return handler; } /** * A message that is sent from {@link SslFilter} when the connection became * secure or is not secure anymore. * * @author The Apache MINA Project (dev@mina.apache.org) * @version $Rev: 713366 $, $Date: 2008-11-12 14:39:23 +0100 (Wed, 12 Nov 2008) $ */ public static class SslFilterMessage { private final String name; private SslFilterMessage(String name) { this.name = name; } @Override public String toString() { return name; } } private static class EncryptedWriteRequest extends WriteRequestWrapper { private final IoBuffer encryptedMessage; private EncryptedWriteRequest(WriteRequest writeRequest, IoBuffer encryptedMessage) { super(writeRequest); this.encryptedMessage = encryptedMessage; } @Override public Object getMessage() { return encryptedMessage; } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -