⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sslfilter.java

📁 mina是以Java实现的一个开源的网络程序框架
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
            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 + -