/* * Copyright 2015 ThoughtWorks, Inc. * * Licensed 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 com.thoughtworks.go.server.util; import com.thoughtworks.go.security.X509CertificateGenerator; import com.thoughtworks.go.server.Jetty9Server; import com.thoughtworks.go.server.config.GoSSLConfig; import com.thoughtworks.go.util.ArrayUtil; import com.thoughtworks.go.util.ExceptionUtils; import com.thoughtworks.go.util.SystemEnvironment; import org.eclipse.jetty.http.HttpVersion; import org.eclipse.jetty.server.*; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.slf4j.LoggerFactory; import java.io.File; import java.net.InetAddress; import java.net.UnknownHostException; public class GoSslSocketConnector implements GoSocketConnector { private static final org.slf4j.Logger LOGGER = LoggerFactory.getLogger(GoSslSocketConnector.class.getName()); private final String password; private final SystemEnvironment systemEnvironment; private final GoSSLConfig goSSLConfig; private final File keystore; private final File truststore; private final File agentKeystore; private final Connector connector; public GoSslSocketConnector(Jetty9Server server, String password, SystemEnvironment systemEnvironment, GoSSLConfig goSSLConfig) { this.password = password; this.systemEnvironment = systemEnvironment; this.goSSLConfig = goSSLConfig; this.keystore = systemEnvironment.keystore(); this.truststore = systemEnvironment.truststore(); this.agentKeystore = systemEnvironment.agentkeystore(); connector = sslConnector(server.getServer()); } private Connector sslConnector(Server server) { ensureX509Certificates(); HttpConfiguration httpsConfig = new HttpConfiguration(); httpsConfig.setOutputBufferSize(systemEnvironment.get(SystemEnvironment.RESPONSE_BUFFER_SIZE)); httpsConfig.addCustomizer(new SecureRequestCustomizer()); httpsConfig.setSendServerVersion(false); httpsConfig.addCustomizer(new ForwardedRequestCustomizer()); SslContextFactory sslContextFactory = new SslContextFactory(); sslContextFactory.setKeyStorePath(keystore.getPath()); sslContextFactory.setKeyStorePassword(password); sslContextFactory.setKeyManagerPassword(password); sslContextFactory.setTrustStorePath(truststore.getPath()); sslContextFactory.setTrustStorePassword(password); sslContextFactory.setWantClientAuth(true); if(!ArrayUtil.isEmpty(goSSLConfig.getCipherSuitesToBeIncluded())) sslContextFactory.setIncludeCipherSuites(goSSLConfig.getCipherSuitesToBeIncluded()); if(!ArrayUtil.isEmpty(goSSLConfig.getCipherSuitesToBeExcluded())) sslContextFactory.setExcludeCipherSuites(goSSLConfig.getCipherSuitesToBeExcluded()); if(!ArrayUtil.isEmpty(goSSLConfig.getProtocolsToBeExcluded())) sslContextFactory.setExcludeProtocols(goSSLConfig.getProtocolsToBeExcluded()); if(!ArrayUtil.isEmpty(goSSLConfig.getProtocolsToBeIncluded())) sslContextFactory.setIncludeProtocols(goSSLConfig.getProtocolsToBeIncluded()); sslContextFactory.setRenegotiationAllowed(goSSLConfig.isRenegotiationAllowed()); LOGGER.info("Included ciphers: {}", ArrayUtil.join(goSSLConfig.getCipherSuitesToBeIncluded())); LOGGER.info("Excluded ciphers: {}", ArrayUtil.join(goSSLConfig.getCipherSuitesToBeExcluded())); LOGGER.info("Included protocols: {}", ArrayUtil.join(goSSLConfig.getProtocolsToBeIncluded())); LOGGER.info("Excluded protocols: {}", ArrayUtil.join(goSSLConfig.getProtocolsToBeExcluded())); LOGGER.info("Renegotiation Allowed: {}", goSSLConfig.isRenegotiationAllowed()); ServerConnector https = new ServerConnector(server, new SslConnectionFactory(sslContextFactory, HttpVersion.HTTP_1_1.asString()), new HttpConnectionFactory(httpsConfig)); https.setHost(systemEnvironment.getListenHost()); https.setPort(systemEnvironment.getSslServerPort()); https.setIdleTimeout(systemEnvironment.get(SystemEnvironment.IDLE_TIMEOUT)); return https; } private void ensureX509Certificates() { String principalDn = "ou=Cruise server webserver certificate, cn=" + getHostname(); X509CertificateGenerator generator = new X509CertificateGenerator(); generator.createAndStoreX509Certificates(keystore, truststore, agentKeystore, password, principalDn); } private String getHostname() { try { return InetAddress.getLocalHost().getHostName(); } catch (UnknownHostException e) { throw ExceptionUtils.bomb(e); } } @Override public Connector getConnector() { return connector; } }