001/** 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018 019package org.apache.hadoop.security.ssl; 020 021import org.mortbay.jetty.security.SslSocketConnector; 022 023import javax.net.ssl.SSLServerSocket; 024import java.io.IOException; 025import java.net.ServerSocket; 026import java.util.ArrayList; 027import org.apache.hadoop.conf.Configuration; 028import org.apache.hadoop.fs.CommonConfigurationKeys; 029import java.util.List; 030import java.util.Arrays; 031import org.apache.commons.logging.Log; 032import org.apache.commons.logging.LogFactory; 033 034/** 035 * This subclass of the Jetty SslSocketConnector exists solely to control 036 * the TLS protocol versions allowed. This is fallout from the POODLE 037 * vulnerability (CVE-2014-3566), which requires that SSLv3 be disabled. 038 * Only TLS 1.0 and later protocols are allowed. 039 */ 040public class SslSocketConnectorSecure extends SslSocketConnector { 041 public static final Log LOG = LogFactory.getLog(SslSocketConnectorSecure.class); 042 public SslSocketConnectorSecure() { 043 super(); 044 } 045 046 /** 047 * Create a new ServerSocket that will not accept SSLv3 connections, 048 * but will accept TLSv1.x connections. 049 */ 050 protected ServerSocket newServerSocket(String host, int port,int backlog) 051 throws IOException { 052 SSLServerSocket socket = (SSLServerSocket) 053 super.newServerSocket(host, port, backlog); 054 ArrayList<String> nonSSLProtocols = new ArrayList<String>(); 055 // Get the list of excluded protocols from core-site.xml 056 Configuration conf = new Configuration(); 057 String excludeProtocols = conf.get(CommonConfigurationKeys.SSL_EXCLUDE_INSECURE_PROTOCOLS_KEY, 058 CommonConfigurationKeys.SSL_EXCLUDE_INSECURE_PROTOCOLS_DEFAULT); 059 LOG.info("Exclude protocols: "+excludeProtocols); 060 List<String> excludeProtocolsList = Arrays.asList(excludeProtocols.split(",")); 061 // For all enabled protocols, check if it is in excluded protocols 062 for (String p : socket.getEnabledProtocols()) { 063 if (!excludeProtocolsList.contains(p)) { 064 // If yes don't add the protocol 065 nonSSLProtocols.add(p); 066 } 067 } 068 LOG.info("Enabled protocols: "+Arrays.toString(nonSSLProtocols.toArray(new String[nonSSLProtocols.size()]))); 069 socket.setEnabledProtocols(nonSSLProtocols.toArray( 070 new String[nonSSLProtocols.size()])); 071 return socket; 072 } 073}