Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 22 additions & 14 deletions src/main/java/com/github/dockerjava/core/DockerClientConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,12 @@
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.net.URI;
import java.util.Map;
import java.util.Properties;

public class DockerClientConfig {
public class DockerClientConfig implements Serializable {
private static final String DOCKER_HOST_PROPERTY = "DOCKER_HOST";
private static final String DOCKER_CERT_PATH_PROPERTY = "DOCKER_CERT_PATH";
private static final String DOCKER_IO_URL_PROPERTY = "docker.io.url";
Expand Down Expand Up @@ -41,21 +42,22 @@ public class DockerClientConfig {
.build();
private static final String DOCKER_IO_PROPERTIES_PROPERTY = "docker.io.properties";
private final URI uri;
private final String version, username, password, email, serverAddress, dockerCertPath, dockerCfgPath;
private final String version, username, password, email, serverAddress, dockerCfgPath;
private final Integer readTimeout;
private final boolean loggingFilterEnabled;
private final SSLConfig sslConfig;

DockerClientConfig(URI uri, String version, String username, String password, String email, String serverAddress, String dockerCertPath, String dockerCfgPath, Integer readTimeout, boolean loggingFilterEnabled) {
DockerClientConfig(URI uri, String version, String username, String password, String email, String serverAddress, String dockerCfgPath, Integer readTimeout, boolean loggingFilterEnabled, SSLConfig sslConfig) {
this.uri = uri;
this.version = version;
this.username = username;
this.password = password;
this.email = email;
this.serverAddress = serverAddress;
this.dockerCertPath = dockerCertPath;
this.dockerCfgPath = dockerCfgPath;
this.readTimeout = readTimeout;
this.loggingFilterEnabled = loggingFilterEnabled;
this.sslConfig = sslConfig;
}

private static Properties loadIncludedDockerProperties(Properties systemProperties) {
Expand Down Expand Up @@ -212,23 +214,23 @@ public boolean isLoggingFilterEnabled() {
return loggingFilterEnabled;
}

public String getDockerCertPath() {
return dockerCertPath;
public SSLConfig getSslConfig() {
return sslConfig;
}

public String getDockerCfgPath() {
return dockerCfgPath;
}

@Override
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;

DockerClientConfig that = (DockerClientConfig) o;

if (loggingFilterEnabled != that.loggingFilterEnabled) return false;
if (dockerCertPath != null ? !dockerCertPath.equals(that.dockerCertPath) : that.dockerCertPath != null)
if (sslConfig != null ? !sslConfig.equals(that.sslConfig) : that.sslConfig != null)
return false;
if (dockerCfgPath != null ? !dockerCfgPath.equals(that.dockerCfgPath) : that.dockerCfgPath != null)
return false;
Expand All @@ -252,8 +254,8 @@ public int hashCode() {
result = 31 * result + (password != null ? password.hashCode() : 0);
result = 31 * result + (email != null ? email.hashCode() : 0);
result = 31 * result + (serverAddress != null ? serverAddress.hashCode() : 0);
result = 31 * result + (dockerCertPath != null ? dockerCertPath.hashCode() : 0);
result = 31 * result + (dockerCfgPath != null ? dockerCfgPath.hashCode() : 0);
result = 31 * result + (sslConfig != null ? sslConfig.hashCode() : 0);
result = 31 * result + (readTimeout != null ? readTimeout.hashCode() : 0);
result = 31 * result + (loggingFilterEnabled ? 1 : 0);
return result;
Expand All @@ -268,18 +270,19 @@ public String toString() {
", password='" + password + '\'' +
", email='" + email + '\'' +
", serverAddress='" + serverAddress + '\'' +
", dockerCertPath='" + dockerCertPath + '\'' +
", dockerCfgPath='" + dockerCfgPath + '\'' +
", sslConfig='" + sslConfig + '\'' +
", readTimeout=" + readTimeout +
", loggingFilterEnabled=" + loggingFilterEnabled +
'}';
}

public static class DockerClientConfigBuilder {
private URI uri;
private String version, username, password, email, serverAddress, dockerCertPath, dockerCfgPath;
private String version, username, password, email, serverAddress, dockerCfgPath;
private Integer readTimeout;
private boolean loggingFilterEnabled;
private SSLConfig sslConfig;

/**
* This will set all fields in the builder to those contained in the Properties object. The Properties object
Expand Down Expand Up @@ -342,7 +345,7 @@ public final DockerClientConfigBuilder withLoggingFilter(boolean loggingFilterEn
}

public final DockerClientConfigBuilder withDockerCertPath(String dockerCertPath) {
this.dockerCertPath = dockerCertPath;
this.sslConfig = new LocalDirectorySSLConfig(dockerCertPath);
return this;
}

Expand All @@ -352,6 +355,11 @@ public final DockerClientConfigBuilder withDockerCfgPath(String dockerCfgPath) {
}


public final DockerClientConfigBuilder withSSLConfig(SSLConfig config) {
this.sslConfig = config;
return this;
}

public DockerClientConfig build() {
return new DockerClientConfig(
uri,
Expand All @@ -360,10 +368,10 @@ public DockerClientConfig build() {
password,
email,
serverAddress,
dockerCertPath,
dockerCfgPath,
readTimeout,
loggingFilterEnabled
loggingFilterEnabled,
sslConfig
);
}
}
Expand Down
133 changes: 133 additions & 0 deletions src/main/java/com/github/dockerjava/core/KeystoreSSLConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
package com.github.dockerjava.core;

import com.google.common.base.Objects;
import com.google.common.base.Preconditions;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.Serializable;
import java.security.KeyManagementException;
import java.security.KeyStore;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.SecureRandom;
import java.security.UnrecoverableKeyException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

/**
* An SSL Config that is based on an pre-existing or pre-loaded KeyStore.
*/
public class KeystoreSSLConfig implements SSLConfig, Serializable {

private final KeyStore keystore;
private final String keystorePassword;

/**
* @param keystore a KeyStore
* @param keystorePassword key password
*/
public KeystoreSSLConfig(KeyStore keystore, String keystorePassword) {
this.keystorePassword = keystorePassword;
Preconditions.checkNotNull(keystore);
this.keystore = keystore;
}

/**
*
* @param pfxFile a PKCS12 file
* @param password Password for the keystore
* @throws KeyStoreException
* @throws IOException
* @throws CertificateException
* @throws NoSuchAlgorithmException
*/
public KeystoreSSLConfig(File pfxFile, String password)
throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException {
Preconditions.checkNotNull(pfxFile);
Preconditions.checkNotNull(password);
keystore = KeyStore.getInstance("pkcs12");
keystore.load(new FileInputStream(pfxFile), password.toCharArray());
keystorePassword = password;
}


/**
* Get the SSL Context out of the keystore.
* @return java SSLContext
* @throws KeyManagementException
* @throws UnrecoverableKeyException
* @throws NoSuchAlgorithmException
* @throws KeyStoreException
*/
@Override
public SSLContext getSSLContext()
throws KeyManagementException, UnrecoverableKeyException, NoSuchAlgorithmException,
KeyStoreException {

final SSLContext context = SSLContext.getInstance("TLS");

String httpProtocols = System.getProperty("https.protocols");
System.setProperty("https.protocols", "TLSv1");

if (httpProtocols != null)
System.setProperty("https.protocols", httpProtocols);

final KeyManagerFactory
keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
keyManagerFactory.init(keystore, keystorePassword.toCharArray());
context.init(keyManagerFactory.getKeyManagers(), new TrustManager[]{
new X509TrustManager() {
@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[]{};
}

@Override
public void checkClientTrusted(final X509Certificate[] arg0, final String arg1) {

}

@Override
public void checkServerTrusted(final X509Certificate[] arg0, final String arg1) {

}
}
}, new SecureRandom());

return context;
}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}

KeystoreSSLConfig that = (KeystoreSSLConfig) o;

return keystore.equals(that.keystore);

}

@Override
public int hashCode() {
return keystore.hashCode();
}

@Override
public String toString() {
return Objects.toStringHelper(this)
.add("keystore", keystore)
.toString();
}
}
101 changes: 101 additions & 0 deletions src/main/java/com/github/dockerjava/core/LocalDirectorySSLConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package com.github.dockerjava.core;

import com.google.common.base.Objects;
import com.google.common.base.Preconditions;

import com.github.dockerjava.api.DockerClientException;

import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.glassfish.jersey.SslConfigurator;

import java.io.Serializable;
import java.security.KeyStore;
import java.security.Security;

import javax.net.ssl.SSLContext;

/**
* SSL Config from local files.
*/
public class LocalDirectorySSLConfig implements SSLConfig, Serializable {

private final String dockerCertPath;

public LocalDirectorySSLConfig(String dockerCertPath) {
Preconditions.checkNotNull(dockerCertPath);
this.dockerCertPath = dockerCertPath;
}

public String getDockerCertPath() {
return dockerCertPath;
}

@Override
public SSLContext getSSLContext() {

boolean certificatesExist = CertificateUtils.verifyCertificatesExist(dockerCertPath);

if (certificatesExist) {

try {

Security.addProvider(new BouncyCastleProvider());

KeyStore keyStore = CertificateUtils.createKeyStore(dockerCertPath);
KeyStore trustStore = CertificateUtils.createTrustStore(dockerCertPath);

// properties acrobatics not needed for java > 1.6
String httpProtocols = System.getProperty("https.protocols");
System.setProperty("https.protocols", "TLSv1");
SslConfigurator sslConfig = SslConfigurator.newInstance(true);
if (httpProtocols != null) {
System.setProperty("https.protocols", httpProtocols);
}

sslConfig.keyStore(keyStore);
sslConfig.keyStorePassword("docker");
sslConfig.trustStore(trustStore);

return sslConfig.createSSLContext();


} catch (Exception e) {
throw new DockerClientException(e.getMessage(), e);
}

}

return null;

}

@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}

LocalDirectorySSLConfig that = (LocalDirectorySSLConfig) o;

if (!dockerCertPath.equals(that.dockerCertPath)) {
return false;
}

return true;
}

@Override
public int hashCode() {
return dockerCertPath.hashCode();
}

@Override
public String toString() {
return Objects.toStringHelper(this)
.add("dockerCertPath", dockerCertPath)
.toString();
}
}
22 changes: 22 additions & 0 deletions src/main/java/com/github/dockerjava/core/SSLConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.github.dockerjava.core;

import java.security.KeyManagementException;
import java.security.KeyStoreException;
import java.security.NoSuchAlgorithmException;
import java.security.UnrecoverableKeyException;

import javax.net.ssl.SSLContext;

/**
* Get an SSL Config. Allows for various different implementations.
*/
public interface SSLConfig {

/**
* Get the SSL Context, from wherever it comes (file, keystore).
* @return an SSL context.
*/
SSLContext getSSLContext()
throws KeyManagementException, UnrecoverableKeyException, NoSuchAlgorithmException,
KeyStoreException;
}
Loading