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

📄 sslfilter.java

📁 mina是以Java实现的一个开源的网络程序框架
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* *  Licensed to the Apache Software Foundation (ASF) under one *  or more contributor license agreements.  See the NOTICE file *  distributed with this work for additional information *  regarding copyright ownership.  The ASF licenses this file *  to you under the Apache License, Version 2.0 (the *  "License"); you may not use this file except in compliance *  with the License.  You may obtain a copy of the License at * *    http://www.apache.org/licenses/LICENSE-2.0 * *  Unless required by applicable law or agreed to in writing, *  software distributed under the License is distributed on an *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *  KIND, either express or implied.  See the License for the *  specific language governing permissions and limitations *  under the License. * */package org.apache.mina.filter.ssl;import java.net.InetSocketAddress;import java.util.ArrayList;import java.util.List;import javax.net.ssl.SSLContext;import javax.net.ssl.SSLEngine;import javax.net.ssl.SSLException;import javax.net.ssl.SSLHandshakeException;import javax.net.ssl.SSLSession;import org.apache.mina.core.buffer.IoBuffer;import org.apache.mina.core.filterchain.IoFilterAdapter;import org.apache.mina.core.filterchain.IoFilterChain;import org.apache.mina.core.future.DefaultWriteFuture;import org.apache.mina.core.future.IoFuture;import org.apache.mina.core.future.IoFutureListener;import org.apache.mina.core.future.WriteFuture;import org.apache.mina.core.service.IoHandler;import org.apache.mina.core.session.AttributeKey;import org.apache.mina.core.session.IoSession;import org.apache.mina.core.write.WriteRequest;import org.apache.mina.core.write.WriteRequestWrapper;import org.apache.mina.core.write.WriteToClosedSessionException;/** * An SSL filter that encrypts and decrypts the data exchanged in the session. * Adding this filter triggers SSL handshake procedure immediately by sending * a SSL 'hello' message, so you don't need to call * {@link #startSsl(IoSession)} manually unless you are implementing StartTLS * (see below).  If you don't want the handshake procedure to start * immediately, please specify {@code false} as {@code autoStart} parameter in * the constructor. * <p> * This filter uses an {@link SSLEngine} which was introduced in Java 5, so * Java version 5 or above is mandatory to use this filter. And please note that * this filter only works for TCP/IP connections. * <p> * * <h2>Implementing StartTLS</h2> * <p> * You can use {@link #DISABLE_ENCRYPTION_ONCE} attribute to implement StartTLS: * <pre> * public void messageReceived(IoSession session, Object message) { *    if (message instanceof MyStartTLSRequest) { *        // Insert SSLFilter to get ready for handshaking *        session.getFilterChain().addFirst(sslFilter); * *        // Disable encryption temporarilly. *        // This attribute will be removed by SSLFilter *        // inside the Session.write() call below. *        session.setAttribute(SSLFilter.DISABLE_ENCRYPTION_ONCE, Boolean.TRUE); * *        // Write StartTLSResponse which won't be encrypted. *        session.write(new MyStartTLSResponse(OK)); * *        // Now DISABLE_ENCRYPTION_ONCE attribute is cleared. *        assert session.getAttribute(SSLFilter.DISABLE_ENCRYPTION_ONCE) == null; *    } * } * </pre> * * @author The Apache MINA Project (dev@mina.apache.org) * @version $Rev: 713366 $, $Date: 2008-11-12 14:39:23 +0100 (Wed, 12 Nov 2008) $ * @org.apache.xbean.XBean */public class SslFilter extends IoFilterAdapter {    /**     * A session attribute key that stores underlying {@link SSLSession}     * for each session.     */    public static final AttributeKey SSL_SESSION = new AttributeKey(SslFilter.class, "session");    /**     * A session attribute key that makes next one write request bypass     * this filter (not encrypting the data).  This is a marker attribute,     * which means that you can put whatever as its value. ({@link Boolean#TRUE}     * is preferred.)  The attribute is automatically removed from the session     * attribute map as soon as {@link IoSession#write(Object)} is invoked,     * and therefore should be put again if you want to make more messages     * bypass this filter.  This is especially useful when you implement     * StartTLS.     */    public static final AttributeKey DISABLE_ENCRYPTION_ONCE = new AttributeKey(SslFilter.class, "disableOnce");    /**     * A session attribute key that makes this filter to emit a     * {@link IoHandler#messageReceived(IoSession, Object)} event with a     * special message ({@link #SESSION_SECURED} or {@link #SESSION_UNSECURED}).     * This is a marker attribute, which means that you can put whatever as its     * value. ({@link Boolean#TRUE} is preferred.)  By default, this filter     * doesn't emit any events related with SSL session flow control.     */    public static final AttributeKey USE_NOTIFICATION = new AttributeKey(SslFilter.class, "useNotification");    /**     * A session attribute key that should be set to an {@link InetSocketAddress}.     * Setting this attribute causes     * {@link SSLContext#createSSLEngine(String, int)} to be called passing the     * hostname and port of the {@link InetSocketAddress} to get an     * {@link SSLEngine} instance. If not set {@link SSLContext#createSSLEngine()}     * will be called.<br/>     * Using this feature {@link SSLSession} objects may be cached and reused     * when in client mode.     *     * @see SSLContext#createSSLEngine(String, int)     */    public static final AttributeKey PEER_ADDRESS = new AttributeKey(SslFilter.class, "peerAddress");    /**     * A special message object which is emitted with a {@link IoHandler#messageReceived(IoSession, Object)}     * event when the session is secured and its {@link #USE_NOTIFICATION}     * attribute is set.     */    public static final SslFilterMessage SESSION_SECURED = new SslFilterMessage(            "SESSION_SECURED");    /**     * A special message object which is emitted with a {@link IoHandler#messageReceived(IoSession, Object)}     * event when the session is not secure anymore and its {@link #USE_NOTIFICATION}     * attribute is set.     */    public static final SslFilterMessage SESSION_UNSECURED = new SslFilterMessage(            "SESSION_UNSECURED");    private static final AttributeKey NEXT_FILTER = new AttributeKey(SslFilter.class, "nextFilter");    private static final AttributeKey SSL_HANDLER = new AttributeKey(SslFilter.class, "handler");    /** The SslContext used */    private final SSLContext sslContext;    /** A flag used to tell the filter to start the handshake immediately */    private final boolean autoStart;        /** A flag used to determinate if the handshake should start immediately */    private static final boolean START_HANDSHAKE = true;    private boolean client;    private boolean needClientAuth;    private boolean wantClientAuth;    private String[] enabledCipherSuites;    private String[] enabledProtocols;    /**     * Creates a new SSL filter using the specified {@link SSLContext}.     * The handshake will start immediately.     */    public SslFilter(SSLContext sslContext) {        this(sslContext, START_HANDSHAKE);    }    /**     * Creates a new SSL filter using the specified {@link SSLContext}.     * If the <code>autostart</code> flag is set to <code>true</code>, the     * handshake will start immediately.     */    public SslFilter(SSLContext sslContext, boolean autoStart) {        if (sslContext == null) {            throw new NullPointerException("sslContext");        }        this.sslContext = sslContext;        this.autoStart = autoStart;    }    /**     * Returns the underlying {@link SSLSession} for the specified session.     *     * @return <tt>null</tt> if no {@link SSLSession} is initialized yet.     */    public SSLSession getSslSession(IoSession session) {        return (SSLSession) session.getAttribute(SSL_SESSION);    }    /**     * (Re)starts SSL session for the specified <tt>session</tt> if not started yet.     * Please note that SSL session is automatically started by default, and therefore     * you don't need to call this method unless you've used TLS closure.     *     * @return <tt>true</tt> if the SSL session has been started, <tt>false</tt> if already started.     * @throws SSLException if failed to start the SSL session     */    public boolean startSsl(IoSession session) throws SSLException {        SslHandler handler = getSslSessionHandler(session);        boolean started;        synchronized (handler) {            if (handler.isOutboundDone()) {                NextFilter nextFilter = (NextFilter) session                        .getAttribute(NEXT_FILTER);                handler.destroy();                handler.init();                handler.handshake(nextFilter);                started = true;            } else {                started = false;            }        }        handler.flushScheduledEvents();        return started;    }    /**     * Returns <tt>true</tt> if and only if the specified <tt>session</tt> is     * encrypted/decrypted over SSL/TLS currently.  This method will start     * to retun <tt>false</tt> after TLS <tt>close_notify</tt> message     * is sent and any messages written after then is not goinf to get encrypted.     */    public boolean isSslStarted(IoSession session) {        SslHandler handler = (SslHandler) session.getAttribute(SSL_HANDLER);                if (handler == null) {            return false;        }        synchronized (handler) {            return !handler.isOutboundDone();        }    }    /**     * Stops the SSL session by sending TLS <tt>close_notify</tt> message to     * initiate TLS closure.     *     * @param session the {@link IoSession} to initiate TLS closure     * @throws SSLException if failed to initiate TLS closure     * @throws IllegalArgumentException if this filter is not managing the specified session     */    public WriteFuture stopSsl(IoSession session) throws SSLException {        SslHandler handler = getSslSessionHandler(session);        NextFilter nextFilter = (NextFilter) session.getAttribute(NEXT_FILTER);        WriteFuture future;        synchronized (handler) {            future = initiateClosure(nextFilter, session);        }        handler.flushScheduledEvents();        return future;    }    /**     * Returns <tt>true</tt> if the engine is set to use client mode     * when handshaking.     */    public boolean isUseClientMode() {        return client;    }    /**     * Configures the engine to use client (or server) mode when handshaking.     */    public void setUseClientMode(boolean clientMode) {        this.client = clientMode;    }    /**     * Returns <tt>true</tt> if the engine will <em>require</em> client authentication.     * This option is only useful to engines in the server mode.     */    public boolean isNeedClientAuth() {        return needClientAuth;    }    /**     * Configures the engine to <em>require</em> client authentication.     * This option is only useful for engines in the server mode.     */    public void setNeedClientAuth(boolean needClientAuth) {        this.needClientAuth = needClientAuth;    }    /**     * Returns <tt>true</tt> if the engine will <em>request</em> client authentication.     * This option is only useful to engines in the server mode.     */    public boolean isWantClientAuth() {        return wantClientAuth;    }    /**     * Configures the engine to <em>request</em> client authentication.     * This option is only useful for engines in the server mode.     */    public void setWantClientAuth(boolean wantClientAuth) {        this.wantClientAuth = wantClientAuth;    }    /**     * Returns the list of cipher suites to be enabled when {@link SSLEngine}     * is initialized.     *     * @return <tt>null</tt> means 'use {@link SSLEngine}'s default.'     */    public String[] getEnabledCipherSuites() {        return enabledCipherSuites;    }    /**     * Sets the list of cipher suites to be enabled when {@link SSLEngine}     * is initialized.     *     * @param cipherSuites <tt>null</tt> means 'use {@link SSLEngine}'s default.'     */    public void setEnabledCipherSuites(String[] cipherSuites) {        this.enabledCipherSuites = cipherSuites;    }    /**     * Returns the list of protocols to be enabled when {@link SSLEngine}     * is initialized.     *     * @return <tt>null</tt> means 'use {@link SSLEngine}'s default.'     */    public String[] getEnabledProtocols() {        return enabledProtocols;    }    /**     * Sets the list of protocols to be enabled when {@link SSLEngine}     * is initialized.     *     * @param protocols <tt>null</tt> means 'use {@link SSLEngine}'s default.'     */    public void setEnabledProtocols(String[] protocols) {        this.enabledProtocols = protocols;    }    @Override    public void onPreAdd(IoFilterChain parent, String name,

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -