Skip to content

Commit

Permalink
ISPN-5721 ISPN-6517 SNI support for Hotrod server
Browse files Browse the repository at this point in the history
ISPN-5721 ISPN-6517 Fixed list of ciphers in SNI

Fixed
  • Loading branch information
Sebastian Laskawiec authored and tristantarrant committed May 12, 2016
1 parent dd01e28 commit 43edda6
Show file tree
Hide file tree
Showing 27 changed files with 639 additions and 118 deletions.
2 changes: 1 addition & 1 deletion bom/pom.xml
Expand Up @@ -74,7 +74,7 @@
<version.jboss.logging>3.3.0.Final</version.jboss.logging> <version.jboss.logging>3.3.0.Final</version.jboss.logging>
<version.jgroups>3.6.9.Final</version.jgroups> <version.jgroups>3.6.9.Final</version.jgroups>
<version.jta>1.0.1.Final</version.jta> <version.jta>1.0.1.Final</version.jta>
<version.netty>4.0.36.Final</version.netty> <version.netty>4.1.0.CR7</version.netty>
<version.osgi>4.3.1</version.osgi> <version.osgi>4.3.1</version.osgi>
<version.scala.major>2.11</version.scala.major> <version.scala.major>2.11</version.scala.major>
<version.scala>${version.scala.major}.7</version.scala> <version.scala>${version.scala.major}.7</version.scala>
Expand Down
Expand Up @@ -25,7 +25,7 @@ public abstract class ProtocolServerConfigurationBuilder<T extends ProtocolServe


protected ProtocolServerConfigurationBuilder(int port) { protected ProtocolServerConfigurationBuilder(int port) {
this.port = port; this.port = port;
this.ssl = new SslConfigurationBuilder(); this.ssl = new SslConfigurationBuilder(this);
} }


@Override @Override
Expand Down
@@ -1,6 +1,7 @@
package org.infinispan.server.core.configuration; package org.infinispan.server.core.configuration;


import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
import java.util.Map;


/** /**
* SslConfiguration. * SslConfiguration.
Expand All @@ -9,30 +10,17 @@
* @since 5.3 * @since 5.3
*/ */
public class SslConfiguration { public class SslConfiguration {

public static final String DEFAULT_SNI_DOMAIN = "*";

private final boolean enabled; private final boolean enabled;
private final boolean requireClientAuth; private final boolean requireClientAuth;
private final String keyStoreFileName; private final Map<String, SslEngineConfiguration> sniDomainsConfiguration;
private final char[] keyStorePassword;
private final char[] keyStoreCertificatePassword;
private final SSLContext sslContext;
private final String trustStoreFileName;
private final char[] trustStorePassword;

SslConfiguration(boolean enabled, boolean requireClientAuth, String keyStoreFileName, char[] keyStorePassword, SSLContext sslContext, String trustStoreFileName,
char[] trustStorePassword) {
this(enabled, requireClientAuth, keyStoreFileName, keyStorePassword, null, sslContext, trustStoreFileName, trustStorePassword);
}


SslConfiguration(boolean enabled, boolean requireClientAuth, String keyStoreFileName, char[] keyStorePassword, char[] keyStoreCertificatePassword, SSLContext sslContext, String trustStoreFileName, SslConfiguration(boolean enabled, boolean requireClientAuth, Map<String, SslEngineConfiguration> sniDomainsConfiguration) {
char[] trustStorePassword) {
this.enabled = enabled; this.enabled = enabled;
this.requireClientAuth = requireClientAuth; this.requireClientAuth = requireClientAuth;
this.keyStoreFileName = keyStoreFileName; this.sniDomainsConfiguration = sniDomainsConfiguration;
this.keyStorePassword = keyStorePassword;
this.keyStoreCertificatePassword = keyStoreCertificatePassword;
this.sslContext = sslContext;
this.trustStoreFileName = trustStoreFileName;
this.trustStorePassword = trustStorePassword;
} }


public boolean enabled() { public boolean enabled() {
Expand All @@ -44,32 +32,39 @@ public boolean requireClientAuth() {
} }


public String keyStoreFileName() { public String keyStoreFileName() {
return keyStoreFileName; return sniDomainsConfiguration.get(DEFAULT_SNI_DOMAIN).keyStoreFileName();
} }


public char[] keyStorePassword() { public char[] keyStorePassword() {
return keyStorePassword; return sniDomainsConfiguration.get(DEFAULT_SNI_DOMAIN).keyStorePassword();
} }


public char[] keyStoreCertificatePassword() { public char[] keyStoreCertificatePassword() {
return keyStoreCertificatePassword; return sniDomainsConfiguration.get(DEFAULT_SNI_DOMAIN).keyStoreCertificatePassword();
} }


public SSLContext sslContext() { public SSLContext sslContext() {
return sslContext; return sniDomainsConfiguration.get(DEFAULT_SNI_DOMAIN).sslContext();
} }


public String trustStoreFileName() { public String trustStoreFileName() {
return trustStoreFileName; return sniDomainsConfiguration.get(DEFAULT_SNI_DOMAIN).trustStoreFileName();
} }


public char[] trustStorePassword() { public char[] trustStorePassword() {
return trustStorePassword; return sniDomainsConfiguration.get(DEFAULT_SNI_DOMAIN).trustStorePassword();
}

public Map<String, SslEngineConfiguration> sniDomainsConfiguration() {
return sniDomainsConfiguration;
} }


@Override @Override
public String toString() { public String toString() {
return "SslConfiguration [enabled=" + enabled + ", requireClientAuth=" + requireClientAuth + ", keyStoreFileName=" + keyStoreFileName + ", sslContext=" + sslContext return "SslConfiguration [" +
+ ", trustStoreFileName=" + trustStoreFileName + "]"; "enabled=" + enabled +
", requireClientAuth=" + requireClientAuth +
", sniDomainsConfiguration=" + sniDomainsConfiguration +
']';
} }
} }
@@ -1,32 +1,39 @@
package org.infinispan.server.core.configuration; package org.infinispan.server.core.configuration;


import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;

import org.infinispan.commons.configuration.Builder; import org.infinispan.commons.configuration.Builder;
import org.infinispan.server.core.logging.JavaLog; import org.infinispan.server.core.logging.JavaLog;
import org.infinispan.util.logging.LogFactory; import org.infinispan.util.logging.LogFactory;


import javax.net.ssl.KeyManager;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/** /**
* *
* SSLConfigurationBuilder. * SSLConfigurationBuilder.
* *
* @author Tristan Tarrant * @author Tristan Tarrant
* @author Sebastian Łaskawiec
* @since 5.3 * @since 5.3
*/ */
public class SslConfigurationBuilder implements Builder<SslConfiguration> { public class SslConfigurationBuilder<T extends ProtocolServerConfiguration, S extends ProtocolServerConfigurationChildBuilder<T, S>> implements Builder<SslConfiguration>, ProtocolServerConfigurationChildBuilder<T, S> {
private static final JavaLog log = LogFactory.getLog(SslConfigurationBuilder.class, JavaLog.class); private static final JavaLog log = LogFactory.getLog(SslConfigurationBuilder.class, JavaLog.class);
private final ProtocolServerConfigurationChildBuilder<T, S> parentConfigurationBuilder;
private boolean enabled = false; private boolean enabled = false;
private boolean requireClientAuth = false; private boolean requireClientAuth = false;
private String keyStoreFileName; private SslEngineConfigurationBuilder defaultDomainConfigurationBuilder = new SslEngineConfigurationBuilder(this);
private char[] keyStorePassword; private Map<String, SslEngineConfigurationBuilder> sniDomains;
private char[] keyStoreCertificatePassword;
private SSLContext sslContext; SslConfigurationBuilder(ProtocolServerConfigurationChildBuilder<T, S> parentConfigurationBuilder) {
private String trustStoreFileName; this.parentConfigurationBuilder = parentConfigurationBuilder;
private char[] trustStorePassword; sniDomains = new HashMap<>();

defaultDomainConfigurationBuilder = new SslEngineConfigurationBuilder(this);
SslConfigurationBuilder() {} sniDomains.put(SslConfiguration.DEFAULT_SNI_DOMAIN, defaultDomainConfigurationBuilder);
}


/** /**
* Disables the SSL support * Disables the SSL support
Expand Down Expand Up @@ -60,11 +67,22 @@ public SslConfigurationBuilder requireClientAuth(boolean requireClientAuth) {
return this; return this;
} }


/**
* Returns SNI domain configuration.
*
* @param domain A domain which will hold configuration details. It is also possible to specify <code>*</code>
* for all domains.
* @return {@link SslConfigurationBuilder} instance associated with specified domain.
*/
public SslEngineConfigurationBuilder sniHostName(String domain) {
return sniDomains.computeIfAbsent(domain, (v) -> new SslEngineConfigurationBuilder(this));
}

/** /**
* Sets the {@link SSLContext} to use for setting up SSL connections. * Sets the {@link SSLContext} to use for setting up SSL connections.
*/ */
public SslConfigurationBuilder sslContext(SSLContext sslContext) { public SslConfigurationBuilder sslContext(SSLContext sslContext) {
this.sslContext = sslContext; defaultDomainConfigurationBuilder.sslContext(sslContext);
return this; return this;
} }


Expand All @@ -74,7 +92,7 @@ public SslConfigurationBuilder sslContext(SSLContext sslContext) {
* {@link #keyManagers(KeyManager[])} * {@link #keyManagers(KeyManager[])}
*/ */
public SslConfigurationBuilder keyStoreFileName(String keyStoreFileName) { public SslConfigurationBuilder keyStoreFileName(String keyStoreFileName) {
this.keyStoreFileName = keyStoreFileName; defaultDomainConfigurationBuilder.keyStoreFileName(keyStoreFileName);
return this; return this;
} }


Expand All @@ -84,7 +102,7 @@ public SslConfigurationBuilder keyStoreFileName(String keyStoreFileName) {
* {@link #keyManagers(KeyManager[])} * {@link #keyManagers(KeyManager[])}
*/ */
public SslConfigurationBuilder keyStorePassword(char[] keyStorePassword) { public SslConfigurationBuilder keyStorePassword(char[] keyStorePassword) {
this.keyStorePassword = keyStorePassword; defaultDomainConfigurationBuilder.keyStorePassword(keyStorePassword);
return this; return this;
} }


Expand All @@ -94,7 +112,7 @@ public SslConfigurationBuilder keyStorePassword(char[] keyStorePassword) {
* {@link #keyStorePassword(String)} will be used. * {@link #keyStorePassword(String)} will be used.
*/ */
public SslConfigurationBuilder keyStoreCertificatePassword(char[] keyStoreCertificatePassword) { public SslConfigurationBuilder keyStoreCertificatePassword(char[] keyStoreCertificatePassword) {
this.keyStoreCertificatePassword = keyStoreCertificatePassword; defaultDomainConfigurationBuilder.keyStoreCertificatePassword(keyStoreCertificatePassword);
return this; return this;
} }


Expand All @@ -104,7 +122,7 @@ public SslConfigurationBuilder keyStoreCertificatePassword(char[] keyStoreCertif
* {@link #trustManagers(TrustManager[])} * {@link #trustManagers(TrustManager[])}
*/ */
public SslConfigurationBuilder trustStoreFileName(String trustStoreFileName) { public SslConfigurationBuilder trustStoreFileName(String trustStoreFileName) {
this.trustStoreFileName = trustStoreFileName; defaultDomainConfigurationBuilder.trustStoreFileName(trustStoreFileName);
return this; return this;
} }


Expand All @@ -114,50 +132,102 @@ public SslConfigurationBuilder trustStoreFileName(String trustStoreFileName) {
* {@link #trustManagers(TrustManager[])} * {@link #trustManagers(TrustManager[])}
*/ */
public SslConfigurationBuilder trustStorePassword(char[] trustStorePassword) { public SslConfigurationBuilder trustStorePassword(char[] trustStorePassword) {
this.trustStorePassword = trustStorePassword; defaultDomainConfigurationBuilder.trustStorePassword(trustStorePassword);
return this; return this;
} }


@Override @Override
public void validate() { public void validate() {
if (enabled) { if (enabled) {
if (sslContext == null) { sniDomains.forEach((domainName, config) -> config.validate());
if (keyStoreFileName == null) {
throw log.noSSLKeyManagerConfiguration();
}
if (keyStoreFileName != null && keyStorePassword == null) {
throw log.missingKeyStorePassword(keyStoreFileName);
}
if (trustStoreFileName == null) {
throw log.noSSLTrustManagerConfiguration();
}
if (trustStoreFileName != null && trustStorePassword == null) {
throw log.missingTrustStorePassword(trustStoreFileName);
}
} else {
if (keyStoreFileName != null || trustStoreFileName != null) {
throw log.xorSSLContext();
}
}
} }
} }


@Override @Override
public SslConfiguration create() { public SslConfiguration create() {
return new SslConfiguration(enabled, requireClientAuth, keyStoreFileName, keyStorePassword, keyStoreCertificatePassword, sslContext, trustStoreFileName, trustStorePassword); Map<String, SslEngineConfiguration> producedSniConfigurations = sniDomains.entrySet()
.stream()
.collect(Collectors.toMap(Map.Entry::getKey,
e -> e.getValue().create()));
return new SslConfiguration(enabled, requireClientAuth, producedSniConfigurations);
} }


@Override @Override
public SslConfigurationBuilder read(SslConfiguration template) { public SslConfigurationBuilder read(SslConfiguration template) {
this.enabled = template.enabled(); this.enabled = template.enabled();
this.requireClientAuth = template.requireClientAuth(); this.requireClientAuth = template.requireClientAuth();
this.keyStoreFileName = template.keyStoreFileName();
this.keyStorePassword = template.keyStorePassword(); this.sniDomains = new HashMap<>();
this.keyStoreCertificatePassword = template.keyStoreCertificatePassword(); template.sniDomainsConfiguration().entrySet()
this.sslContext = template.sslContext(); .forEach(e -> sniDomains.put(e.getKey(), new SslEngineConfigurationBuilder(this).read(e.getValue())));
this.trustStoreFileName = template.trustStoreFileName();
this.trustStorePassword = template.trustStorePassword(); this.defaultDomainConfigurationBuilder = sniDomains
.computeIfAbsent(SslConfiguration.DEFAULT_SNI_DOMAIN, (v) -> new SslEngineConfigurationBuilder(this));
return this; return this;
} }


@Override
public S defaultCacheName(String defaultCacheName) {
return parentConfigurationBuilder.defaultCacheName(defaultCacheName);
}

@Override
public S name(String name) {
return parentConfigurationBuilder.name(name);
}

@Override
public S host(String host) {
return parentConfigurationBuilder.host(host);
}

@Override
public S port(int port) {
return parentConfigurationBuilder.port(port);
}

@Override
public S idleTimeout(int idleTimeout) {
return parentConfigurationBuilder.idleTimeout(idleTimeout);
}

@Override
public S tcpNoDelay(boolean tcpNoDelay) {
return parentConfigurationBuilder.tcpNoDelay(tcpNoDelay);
}

@Override
public S recvBufSize(int recvBufSize) {
return parentConfigurationBuilder.recvBufSize(recvBufSize);
}

@Override
public S sendBufSize(int sendBufSize) {
return parentConfigurationBuilder.sendBufSize(sendBufSize);
}

@Override
public SslConfigurationBuilder ssl() {
return parentConfigurationBuilder.ssl();
}

@Override
public S workerThreads(int workerThreads) {
return parentConfigurationBuilder.workerThreads(workerThreads);
}

@Override
public S ignoredCaches(Set<String> ignoredCaches) {
return parentConfigurationBuilder.ignoredCaches(ignoredCaches);
}

@Override
public T build() {
return parentConfigurationBuilder.build();
}

@Override
public S self() {
return parentConfigurationBuilder.self();
}
} }
@@ -0,0 +1,15 @@
package org.infinispan.server.core.configuration;

import org.infinispan.commons.configuration.Builder;

/**
* ProtocolServerConfigurationChildBuilder.
*
* @author Tristan Tarrant
* @since 5.3
*/
public interface SslConfigurationChildBuilder extends Builder<SslEngineConfiguration> {

SslEngineConfigurationBuilder sniHostName(String domain);

}

0 comments on commit 43edda6

Please sign in to comment.