package org.apache.geronimo.tomcat; import java.util.Map; import javax.net.ssl.KeyManagerFactory; import org.apache.geronimo.management.geronimo.SecureConnector; import org.apache.geronimo.management.geronimo.WebManager; import org.apache.geronimo.system.serverinfo.ServerInfo; import org.apache.geronimo.gbean.GBeanInfo; import org.apache.geronimo.gbean.GBeanInfoBuilder; /** * A wrapper around a connector for the HTTPS protocol for Tomcat. The * functionality is not different than the standard ConnectorGBean, but * there's an additional set of HTTPS attributes exposed. * * @version $Revision: 1.0$ */ public class HttpsConnectorGBean extends ConnectorGBean implements TomcatSecureConnector { private final ServerInfo serverInfo; private String keystoreFileName; private String truststoreFileName; private String algorithm; public HttpsConnectorGBean(String name, String protocol, String host, int port, TomcatContainer container, ServerInfo serverInfo) throws Exception { super(name, protocol, host, port, container); if (serverInfo == null){ throw new IllegalArgumentException("serverInfo cannot be null."); } this.serverInfo = serverInfo; } /** * Adds any special parameters before constructing the connector. * * @param protocol Should be one of the constants from WebContainer. * @param params The map of parameters that will be used to initialize the connector. */ protected void initializeParams(String protocol, Map params) { super.initializeParams(protocol, params); params.put("scheme", "https"); params.put("secure", "true"); } /** * Ensures that this implementation can handle the requested protocol. * * @param protocol */ protected void validateProtocol(String protocol) { if(protocol != null && !protocol.equals(WebManager.PROTOCOL_HTTPS)) { throw new IllegalStateException("HttpsConnectorGBean only supports "+WebManager.PROTOCOL_HTTPS); } } /** * Gets the name of the keystore file that holds the server certificate * (and by default, the trusted CA certificates used for client certificate * authentication). This is relative to the Geronimo home directory. */ public String getKeystoreFileName() { return keystoreFileName; // don't look it up as we need it to be relative } /** * Sets the name of the keystore file that holds the server certificate * (and by default, the trusted CA certificates used for client certificate * authentication). This is relative to the Geronimo home directory. */ public void setKeystoreFileName(String name) { keystoreFileName = name; connector.setAttribute("keystoreFile", serverInfo.resolvePath(keystoreFileName)); } public String getTruststoreFileName() { return truststoreFileName; // don't look it up as we need it to be relative } public void setTruststoreFileName(String name) { truststoreFileName = name; connector.setAttribute("truststoreFile", serverInfo.resolvePath(truststoreFileName)); } /** * Sets the password used to access the keystore, and by default, used to * access the server private key inside the keystore. Not all connectors * support configuring different passwords for those two features; if so, * a separate PrivateKeyPassword should be defined in an * implementation-specific connector interface. */ public void setKeystorePassword(String password) { connector.setAttribute("keystorePass", password); } public void setTruststorePassword(String password) { connector.setAttribute("truststorePass", password); } /** * Gets the format of the entries in the keystore. The default format for * Java keystores is JKS, though some connector implementations support * PCKS12 (and possibly other formats). */ public String getKeystoreType() { return (String)connector.getAttribute("keystoreType"); } /** * Sets the format of the entries in the keystore. The default format for * Java keystores is JKS, though some connector implementations support * PCKS12 (and possibly other formats). */ public void setKeystoreType(String type) { connector.setAttribute("keystoreType", type); } public String getTruststoreType() { return (String)connector.getAttribute("truststoreType"); } public void setTruststoreType(String type) { connector.setAttribute("truststoreType", type); } /** * Gets the certificate algorithm used to access the keystore. This may * be different for different JVM vendors, but should not usually be * changed otherwise. */ public String getAlgorithm() { return algorithm; } /** * Sets the certificate algorithm used to access the keystore. This may * be different for different JVM vendors, but should not usually be * changed otherwise. */ public void setAlgorithm(String algorithm) { this.algorithm = algorithm; if ("default".equalsIgnoreCase(algorithm)) { algorithm = KeyManagerFactory.getDefaultAlgorithm(); } connector.setAttribute("algorithm", algorithm); } /** * Gets the protocol used for secure communication. This should usually * be TLS, though some JVM implementations (particularly some of IBM's) * may not be compatible with popular browsers unless this is changed to * SSL. */ public String getSecureProtocol() { return (String)connector.getAttribute("sslProtocol"); } /** * Gets the protocol used for secure communication. This should usually * be TLS, though some JVM implementations (particularly some of IBM's) * may not be compatible with popular browsers unless this is changed to * SSL. Don't change it if you're not having problems. */ public void setSecureProtocol(String protocol) { connector.setAttribute("sslProtocol", protocol); } /** * Checks whether clients are required to authenticate using client * certificates in order to connect using this connector. If enabled, * client certificates are validated using the trust store, which defaults * to the same keystore file, keystore type, and keystore password as the * regular keystore. Some connector implementations may allow you to * configure those 3 values separately to use a different trust store. */ public boolean isClientAuthRequired() { Object value = connector.getAttribute("clientAuth"); return value == null ? false : new Boolean(value.toString()).booleanValue(); } /** * Checks whether clients are required to authenticate using client * certificates in order to connect using this connector. If enabled, * client certificates are validated using the trust store, which defaults * to the same keystore file, keystore type, and keystore password as the * regular keystore. Some connector implementations may allow you to * configure those 3 values separately to use a different trust store. */ public void setClientAuthRequired(boolean clientCert) { connector.setAttribute("clientAuth", new Boolean(clientCert)); } public static final GBeanInfo GBEAN_INFO; static { GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic("Tomcat Connector", HttpsConnectorGBean.class, ConnectorGBean.GBEAN_INFO); infoFactory.addAttribute("keystoreFileName", String.class, true, true); infoFactory.addAttribute("truststoreFileName", String.class, true, true); infoFactory.addAttribute("algorithm", String.class, true, true); infoFactory.addAttribute("keystorePassword", String.class, true, true); infoFactory.addAttribute("truststorePassword", String.class, true, true); // todo should we support this? // infoFactory.addAttribute("keyPassword", String.class, true, true); infoFactory.addAttribute("secureProtocol", String.class, true, true); infoFactory.addAttribute("keystoreType", String.class, true, true); infoFactory.addAttribute("truststoreType", String.class, true, true); infoFactory.addAttribute("clientAuthRequired", boolean.class, true, true); infoFactory.addInterface(TomcatSecureConnector.class); infoFactory.addReference("ServerInfo", ServerInfo.class, "GBean"); infoFactory.setConstructor(new String[] { "name", "protocol", "host", "port", "TomcatContainer", "ServerInfo"}); GBEAN_INFO = infoFactory.getBeanInfo(); } public static GBeanInfo getGBeanInfo() { return GBEAN_INFO; } }