blob: 6c7c5dfddd7ea31e9460cb9d0db70b26c4abdedc [file] [log] [blame]
package brooklyn.entity.java;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.security.KeyPair;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.List;
import brooklyn.config.ConfigKey;
import brooklyn.entity.basic.AbstractEntity;
import brooklyn.util.MutableMap.Builder;
import brooklyn.util.ResourceUtils;
import brooklyn.util.crypto.FluentKeySigner;
import brooklyn.util.crypto.SecureKeys;
import brooklyn.util.exceptions.Exceptions;
import brooklyn.util.jmx.jmxmp.JmxmpAgent;
public class JmxmpSslSupport {
final static String BROOKLYN_VERSION = "0.5.0"; // BROOKLYN_VERSION (updated by script)
protected final JavaSoftwareProcessSshDriver driver;
private KeyStore agentTrustStore;
private KeyStore agentKeyStore;
public JmxmpSslSupport(JavaSoftwareProcessSshDriver driver) {
this.driver = driver;
}
public String getJmxSslKeyStoreFilePath() {
return driver.getRunDir()+"/jmx-keystore";
}
public String getJmxSslTrustStoreFilePath() {
return driver.getRunDir()+"/jmx-truststore";
}
public String getJmxmpAgentJarBasename() {
return "brooklyn-jmxmp-agent-shaded-"+BROOKLYN_VERSION+".jar";
}
public String getJmxmpAgentJarUrl() {
return "classpath://"+getJmxmpAgentJarBasename();
}
public String getJmxmpAgentJarDestinationFilePath() {
return driver.getRunDir()+"/"+getJmxmpAgentJarBasename();
}
public void applyAgentJmxJavaSystemProperties(Builder<String, Object> result) {
result.
put(JmxmpAgent.JMXMP_PORT_PROPERTY, driver.getJmxPort()).
put(JmxmpAgent.USE_SSL_PROPERTY, true).
put(JmxmpAgent.AUTHENTICATE_CLIENTS_PROPERTY, true).
// the option below wants a jmxremote.password file; we use certs (above) to authenticate
put("com.sun.management.jmxremote.authenticate", false);
// TODO reference the properties below
result.
put(JmxmpAgent.JMXMP_KEYSTORE_FILE_PROPERTY, getJmxSslKeyStoreFilePath()).
put(JmxmpAgent.JMXMP_TRUSTSTORE_FILE_PROPERTY, getJmxSslTrustStoreFilePath());
}
public void applyAgentJmxJavaConfigOptions(List<String> result) {
result.add("-javaagent:"+getJmxmpAgentJarDestinationFilePath());
}
public FluentKeySigner getBrooklynRootSigner() {
// TODO use brooklyn root CA keys etc
return new FluentKeySigner("brooklyn-root");
}
/** builds remote keystores, stores config keys/certs, and copies necessary files across */
public void install() {
try {
// build truststore and keystore
FluentKeySigner signer = getBrooklynRootSigner();
KeyPair jmxAgentKey = SecureKeys.newKeyPair();
X509Certificate jmxAgentCert = signer.newCertificateFor("jmxmp-agent", jmxAgentKey);
agentKeyStore = SecureKeys.newKeyStore();
agentKeyStore.setKeyEntry("jmxmp-agent", jmxAgentKey.getPrivate(),
// TODO jmx.ssl.agent.keyPassword
"".toCharArray(),
new Certificate[] { jmxAgentCert });
ByteArrayOutputStream agentKeyStoreBytes = new ByteArrayOutputStream();
agentKeyStore.store(agentKeyStoreBytes,
// TODO jmx.ssl.agent.keyStorePassword
"".toCharArray());
agentTrustStore = SecureKeys.newKeyStore();
agentTrustStore.setCertificateEntry("brooklyn", getJmxAccessCert());
ByteArrayOutputStream agentTrustStoreBytes = new ByteArrayOutputStream();
agentTrustStore.store(agentTrustStoreBytes, "".toCharArray());
// install the truststore and keystore
driver.getMachine().copyTo(new ByteArrayInputStream(agentKeyStoreBytes.toByteArray()), getJmxSslKeyStoreFilePath());
driver.getMachine().copyTo(new ByteArrayInputStream(agentTrustStoreBytes.toByteArray()), getJmxSslTrustStoreFilePath());
// and install the agent
driver.getMachine().copyTo(new ResourceUtils(this).getResourceFromUrl(getJmxmpAgentJarUrl()), getJmxmpAgentJarDestinationFilePath());
} catch (Exception e) {
throw Exceptions.propagate(e);
}
}
protected <T> T getConfig(ConfigKey<T> key) {
return driver.getEntity().getConfig(key);
}
public synchronized Certificate getJmxAccessCert() {
Certificate cert = getConfig(UsesJmx.JMX_SSL_ACCESS_CERT);
if (cert!=null) return cert;
// TODO load from keyStoreUrl
KeyPair jmxAccessKey = SecureKeys.newKeyPair();
X509Certificate jmxAccessCert = getBrooklynRootSigner().newCertificateFor("brooklyn-jmx-access", jmxAccessKey);
((AbstractEntity)driver.getEntity()).setConfigEvenIfOwned(UsesJmx.JMX_SSL_ACCESS_CERT, jmxAccessCert);
((AbstractEntity)driver.getEntity()).setConfigEvenIfOwned(UsesJmx.JMX_SSL_ACCESS_KEY, jmxAccessKey.getPrivate());
return jmxAccessCert;
}
public synchronized PrivateKey getJmxAccessKey() {
PrivateKey key = getConfig(UsesJmx.JMX_SSL_ACCESS_KEY);
if (key!=null) return key;
getJmxAccessCert();
return getConfig(UsesJmx.JMX_SSL_ACCESS_KEY);
}
}