Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
   *
   * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
   *
   * The contents of this file are subject to the terms of either the GNU
   * General Public License Version 2 only ("GPL") or the Common Development
   * and Distribution License("CDDL") (collectively, the "License").  You
   * may not use this file except in compliance with the License.  You can
  * obtain a copy of the License at
  * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
  * or packager/legal/LICENSE.txt.  See the License for the specific
  * language governing permissions and limitations under the License.
  *
  * When distributing the software, include this License Header Notice in each
  * file and include the License file at packager/legal/LICENSE.txt.
  *
  * GPL Classpath Exception:
  * Oracle designates this particular file as subject to the "Classpath"
  * exception as provided by Oracle in the GPL Version 2 section of the License
  * file that accompanied this code.
  *
  * Modifications:
  * If applicable, add the following below the License Header, with the fields
  * enclosed by brackets [] replaced by your own identifying information:
  * "Portions Copyright [year] [name of copyright owner]"
  *
  * Contributor(s):
  * If you wish your version of this file to be governed by only the CDDL or
  * only the GPL Version 2, indicate your decision by adding "[Contributor]
  * elects to include this software in this distribution under the [CDDL or GPL
  * Version 2] license."  If you don't indicate a single choice of license, a
  * recipient has the option to distribute your version of this file under
  * either the CDDL, the GPL Version 2 or to extend the choice of license to
  * its licensees as provided above.  However, if you add GPL Version 2 code
  * and therefore, elected the GPL Version 2 license, then the option applies
  * only if the new code is made subject to such option by the copyright
  * holder.
  */
 
 package com.sun.enterprise.web.connector.grizzly.ssl;
 
 import java.util.Set;
SSL over NIO Selector implementation. Mainly, this class replace the clear text implementation by defining the SSL tasks counterpart: SSLReadTask, SSLProcessorTask and SSLByteBufferInputStream. The SSLPipeline is the default and must not be replace unless all its attribute properly implemented.

Author(s):
Jean-Francois Arcand
 
 public class SSLSelectorThread extends SelectorThread 
         implements SecureSelector<SSLImplementation>{
    
    
    
The SSLImplementation
 
     private SSLImplementation sslImplementation;
    
    
    
The SSLContext associated with the SSL implementation we are running on.
 
     protected SSLContext sslContext;
    
    
    
The list of cipher suite
 
     private String[] enabledCipherSuites = null;
    
    
    
the list of protocols
 
     private String[] enabledProtocols = null;
    
    
    
Client mode when handshaking.
    private boolean clientMode = false;
    
    
    
Require client Authentication.
    private boolean needClientAuth = false;
    
    
    
True when requesting authentication.
    private boolean wantClientAuth = false;    
    
    
    
Has the enabled protocol configured.
    private boolean isProtocolConfigured = false;
    
    
    
Has the enabled Cipher configured.
    private boolean isCipherConfigured = false;
    
    // ---------------------------------------------------------------------/.
    
    
    public SSLSelectorThread(){
        super();
                SSLPipeline.class.getName());
    }

    
    
Initialize SSLSelectorReadThread used to process OP_READ operations.
    @Override
    protected void initMultiSelectors() throws IOException
                                                 InstantiationException {
        for (int i = 0; i < .i++) {
            [i] = new SSLSelectorReadThread(){
                public ReadTask getReadTask(SelectionKey key
                    throws IOException{
                    ReadTask readTask = SSLSelectorThread.this.getReadTask(key);
                    readTask.setSelectorThread(this);
                    return readTask;
                }
            };
            ((SSLSelectorReadThread)[i]). = i;
        }
    }
 
    
    
Enable all registered interestOps. Due a a NIO bug, all interestOps invocation needs to occurs on the same thread as the selector thread.
    @Override
    public void enableSelectionKeys(){
        SelectionKey selectionKey;
        int size = getKeysToEnable().size();
        long currentTime = System.currentTimeMillis();
        for (int i=0; i < sizei++) {
            selectionKey = (SelectionKey)getKeysToEnable().poll();
            selectionKey.interestOps(
                    selectionKey.interestOps() | .);
            if ( selectionKey.attachment() != null){
                ((SSLEngine)selectionKey
                        .attachment()).getSession().putValue
                            (String.valueOf(selectionKey.hashCode()), System.currentTimeMillis());
            }
            .trap(selectionKey);   
        } 
    } 
    
    
    
Handle OP_READ
 
    @Override
    protected ReadTask handleRead(SelectionKey keythrows IOException{                   
        // disable OP_READ on key before doing anything else 
        key.interestOps(key.interestOps() & (~.));
        
        if (){
            .log(.,"Handling OP_READ on SocketChannel " + 
                    key.channel());
        }      
        
        return getReadTask(key);
    }    
    
    
    
Cancel keep-alive connections.
    @Override
    protected void expireIdleKeys() {
        if ( <= 0 || !.isOpen()) return;
        long current = System.currentTimeMillis();
        if (current < getNextKeysExpiration()) {
            return;
        }
        setNextKeysExpiration(current + getKaTimeout());
        
        Set<SelectionKeyreadyKeys = .keys();
        if (readyKeys.isEmpty()){
            return;
        }
        Iterator<SelectionKeyiterator = readyKeys.iterator();
        SelectionKey key;
        while (iterator.hasNext()) {
            key = (SelectionKey)iterator.next();
            if ( !key.isValid() ) {
                .untrap(key);
                continue;
            }
            
            // Keep-alive expired
            final Object attachment = key.attachment();
            if (attachment != null) {                
                SSLSession sslSession = null;
                long expire = -1L;
                if (attachment instanceof SSLEngine){
                    sslSession = ((SSLEngine)attachment).getSession();
                    String hashString = String.valueOf(key.hashCode());
                    if (sslSession != null 
                            && sslSession.getValue(hashString) != null){
                        expire = (Long)sslSession.getValue(hashString); 
                    }
                } else if (attachment instanceof Long){
                    expire = (Longattachment;
                }
                
                if (expire != -1L){
                    if (current - expire >= getKaTimeout()) {                   
                        cancelKey(key);
                    } else if (expire + getKaTimeout() < getNextKeysExpiration()){
                        setNextKeysExpiration(expire + getKaTimeout());
                    }
                }
            }
        }                    
    }
    
    
    
Register a SelectionKey to this Selector running of this thread.
    @Override
    public void registerKey(SelectionKey key){
        if (key == nullreturn;
        
        if (.dropConnection()) {
            cancelKey(key);
            return;
        }
        if (){
            .log(.,
                    "Registering SocketChannel for keep alive " +  
                    key.channel());
        }         
        getKeysToEnable().add(key);
        .wakeup();
    } 
    
    
Create a new Pipeline instance using the pipelineClassName value.
    @Override
    protected Pipeline newPipeline(int maxThreads,
                                   int minThreads,
                                   String name
                                   int port,
                                   int priority){
        
        Class className = null;                               
        Pipeline pipeline = null;                               
        try{                              
            className = Class.forName(getPipelineClassName());
            pipeline = (Pipeline)className.newInstance();
        } catch (ClassNotFoundException ex){
            getLogger().log(.,
                       "Unable to load Pipeline: " + getPipelineClassName());
            pipeline = new SSLPipeline();
        } catch (InstantiationException ex){
            getLogger().log(.,
                       "Unable to instantiate Pipeline: "
                       + getPipelineClassName());
            pipeline = new SSLPipeline();
        } catch (IllegalAccessException ex){
            getLogger().log(.,
                       "Unable to instantiate Pipeline: "
                       + getPipelineClassName());
            pipeline = new SSLPipeline();
        }
        
        if (getLogger().isLoggable(.)){
            getLogger().log(.,
                       "http-listener " + port + " uses pipeline: "
                       + pipeline.getClass().getName());
        }
        
        pipeline.setMaxThreads(maxThreads);
        pipeline.setMinThreads(minThreads);    
        pipeline.setName(name);
        pipeline.setPort(port);
        pipeline.setPriority(priority);
        pipeline.setQueueSizeInBytes(getMaxQueueSizeInBytes());
        pipeline.setThreadsIncrement(getThreadsIncrement());
        pipeline.setThreadsTimeout(getThreadsTimeout());
        
        return pipeline;
    
    }

    
    
Return a SSLReadTask from the pool. If the pool is empty, create a new instance. Make sure the SSLEngine is reused when the SelectionKey is part of a keep-alive transaction.
    @Override
    public ReadTask getReadTask(SelectionKey keythrows IOException{
        ReadTask task = super.getReadTask(key);
        
        SSLEngine sslEngine = null;
        Object attachment = key.attachment();
        if (attachment != null && attachment instanceof SSLEngine){
            sslEngine = (SSLEngine)attachment;
        } else {
            key.attach(null);
        }
        
        if (sslEngine != null) {
            ((SSLReadTask)task).setHandshake(false);
        } else {
            sslEngine = .createSSLEngine(); 
            if ( != null){                
                if (!) {
                     = configureEnabledCiphers(sslEngine,
                            );
                     = true;
                }                
                sslEngine.setEnabledCipherSuites();
            } 
            if ( != null){                
                if (!) {
                     = configureEnabledProtocols(sslEngine,
                                                                 );
                     = true;
                }                
                sslEngine.setEnabledProtocols();
            }       
            sslEngine.setUseClientMode(isClientMode()); 
        }
        sslEngine.getSession().removeValue(String.valueOf(key.hashCode()));
        // Carefully set need/want flags, because according to the SSLEngine javadoc, they reset each other.
        if (isNeedClientAuth()) {
            sslEngine.setNeedClientAuth(true);
        } else if (isWantClientAuth()) {
            sslEngine.setWantClientAuth(true);
        } else {
            sslEngine.setNeedClientAuth(false);
        }
        ((SSLReadTask)task).setSSLEngine(sslEngine);           
        return task;
    }           
    
    
    
Return a new SSLReadTask instance
    @Override
    protected DefaultReadTask newReadTask(){
        StreamAlgorithm streamAlgorithm = new NoParsingAlgorithm();    
        streamAlgorithm.setPort(getPort());
               
        SSLReadTask task;
        if (getMaxReadWorkerThreads() > 0 || ){
            task =  new SSLAsyncReadTask();  
        } else {
            task = new SSLReadTask();
        }
                     
        task.initialize(streamAlgorithmisUseDirectByteBuffer(), isUseByteBufferView());
        task.setPipeline(getReadPipeline());  
        task.setSelectorThread(this);
        task.setRecycle(isRecycleTasks());
        
        return task;
    }
    
    
    
Create SSLProcessorTask objects and configure it to be ready to proceed request.
    @Override
    protected ProcessorTask newProcessorTask(boolean initialize){                                                      
        SSLProcessorTask task = null;
        if (!) {
            task = new SSLProcessorTask(initializeisBufferResponse());
        } else {
            task = new SSLAsyncProcessorTask(initializeisBufferResponse());
        }      
        return configureProcessorTask(task);        
    }
    
    
    
Set the SSLContext required to support SSL over NIO.
    public void setSSLContext(SSLContext sslContext){
        this. = sslContext;
    }
 
    
    
Return the SSLContext required to support SSL over NIO.
    
    public SSLContext getSSLContext(){
        return ;
    }
    
    
    
Set the Coyote SSLImplementation.
    public void setSSLImplementation(SSLImplementation sslImplementation){
        this. = sslImplementation;
    }   

    
    
Return the current SSLImplementation this Thread
        return ;
    } 
    
    
Returns the list of cipher suites to be enabled when javax.net.ssl.SSLEngine is initialized.

Returns:
null means 'use javax.net.ssl.SSLEngine's default.'
    public String[] getEnabledCipherSuites() {
        return ;
    }

    
    
Sets the list of cipher suites to be enabled when javax.net.ssl.SSLEngine is initialized.

Parameters:
cipherSuites null means 'use javax.net.ssl.SSLEngine's default.'
    public void setEnabledCipherSuites(String[] enabledCipherSuites) {
        this. = enabledCipherSuites;
    }

   
    
Returns the list of protocols to be enabled when javax.net.ssl.SSLEngine is initialized.

Returns:
null means 'use javax.net.ssl.SSLEngine's default.'
  
    public String[] getEnabledProtocols() {
        return ;
    }

    
    
Sets the list of protocols to be enabled when javax.net.ssl.SSLEngine is initialized.

Parameters:
protocols null means 'use javax.net.ssl.SSLEngine's default.'
    
    public void setEnabledProtocols(String[] enabledProtocols) {
        this. = enabledProtocols;
    }

    
    
Returns true if the SSlEngine is set to use client mode when handshaking.
    public boolean isClientMode() {
        return ;
    }


    
Configures the engine to use client (or server) mode when handshaking.
    
    public void setClientMode(boolean clientMode) {
        this. = clientMode;
    }

    
    
Returns true if the SSLEngine will require client authentication.
   
    public boolean isNeedClientAuth() {
        return ;
    }

    
    
Configures the engine to require client authentication.
    
    public void setNeedClientAuth(boolean needClientAuth) {
        this. = needClientAuth;
    }

    
    
Returns true if the engine will request client authentication.
   
    public boolean isWantClientAuth() {
        return ;
    }

    
    
Configures the engine to request client authentication.
    
    public void setWantClientAuth(boolean wantClientAuth) {
        this. = wantClientAuth;
    }
    
    
    
Return the list of allowed protocol.

Returns:
String[] an array of supported protocols.
    private final static String[] configureEnabledProtocols(
            SSLEngine sslEngineString[] requestedProtocols){
        
        String[] supportedProtocols = sslEngine.getSupportedProtocols();
        String[] protocols = null;
        ArrayList<Stringlist = null;
        for(String supportedProtocolsupportedProtocols){        
            /*
             * Check to see if the requested protocol is among the
             * supported protocols, i.e., may be enabled
             */
            for(String protocolrequestedProtocols) {
                protocol = protocol.trim();
                if (supportedProtocol.equals(protocol)) {
                    if (list == null) {
                        list = new ArrayList<String>();
                    }
                    list.add(protocol);
                    break;
                }
            }
        } 
        if (list != null) {
            protocols = list.toArray(new String[list.size()]);                
        }
 
        return protocols;
    }
    
    
    /*
     * Determines the SSL cipher suites to be enabled.
     *
     * @return Array of SSL cipher suites to be enabled, or null if none of the
     * requested ciphers are supported
     */
    private final static String[] configureEnabledCiphers(SSLEngine sslEngine,
            String[] requestedCiphers) {
        String[] supportedCiphers = sslEngine.getSupportedCipherSuites();
        String[] ciphers = null;
        ArrayList<Stringlist = null;
        for(String supportedCiphersupportedCiphers){        
            /*
             * Check to see if the requested protocol is among the
             * supported protocols, i.e., may be enabled
             */
            for(String cipherrequestedCiphers) {
                cipher = cipher.trim();
                if (supportedCipher.equals(cipher)) {
                    if (list == null) {
                        list = new ArrayList<String>();
                    }
                    list.add(cipher);
                    break;
                }
            }
        } 
        if (list != null) {
            ciphers = list.toArray(new String[list.size()]);                
        }
 
        return ciphers;
    }
 
    
    
Initialize the fileCacheFactory associated with this instance
    @Override
    protected void initFileCacheFactory(){
         = SSLFileCacheFactory.getFactory();
    }
    
    // --------------------------------------------------- Not used/
    
    
Return the ServerSocketFactory used when a blocking IO is enabled.
       return null;
    }

    
    
Set the ServerSocketFactory used when a blocking IO is enabled.
   
    public void setServerSocketFactory(ServerSocketFactory factory){
       ;
    }
    
    
    
Enable gathering of monitoring datas.
    @Override
    public void enableMonitoring(){
         = true;
        enablePipelineStats();      
        if ( != null) {
            for (int i = 0; i < .i++) {
                ((SSLSelectorReadThread)[i]). = true;
            }
        }
    }
    
    
    
Disable gathering of monitoring datas.
    @Override
    public void disableMonitoring(){
        disablePipelineStats();  
        if ( != null) {
            for (int i = 0; i < .i++) {
                ((SSLSelectorReadThread)[i]). = false;
            }
        }
    }
    
New to GrepCode? Check out our FAQ X