001 package org.apache.geronimo.tomcat; 002 003 import java.util.Map; 004 import javax.net.ssl.KeyManagerFactory; 005 006 import org.apache.geronimo.management.geronimo.SecureConnector; 007 import org.apache.geronimo.management.geronimo.WebManager; 008 import org.apache.geronimo.system.serverinfo.ServerInfo; 009 import org.apache.geronimo.gbean.GBeanInfo; 010 import org.apache.geronimo.gbean.GBeanInfoBuilder; 011 012 /** 013 * A wrapper around a connector for the HTTPS protocol for Tomcat. The 014 * functionality is not different than the standard ConnectorGBean, but 015 * there's an additional set of HTTPS attributes exposed. 016 * 017 * @version $Revision: 1.0$ 018 */ 019 public class HttpsConnectorGBean extends ConnectorGBean implements TomcatSecureConnector { 020 private final ServerInfo serverInfo; 021 private String keystoreFileName; 022 private String truststoreFileName; 023 private String algorithm; 024 025 public HttpsConnectorGBean(String name, String protocol, String host, int port, TomcatContainer container, ServerInfo serverInfo) throws Exception { 026 super(name, protocol, host, port, container); 027 028 if (serverInfo == null){ 029 throw new IllegalArgumentException("serverInfo cannot be null."); 030 } 031 032 this.serverInfo = serverInfo; 033 } 034 035 /** 036 * Adds any special parameters before constructing the connector. 037 * 038 * @param protocol Should be one of the constants from WebContainer. 039 * @param params The map of parameters that will be used to initialize the connector. 040 */ 041 protected void initializeParams(String protocol, Map params) { 042 super.initializeParams(protocol, params); 043 params.put("scheme", "https"); 044 params.put("secure", "true"); 045 } 046 047 /** 048 * Ensures that this implementation can handle the requested protocol. 049 * 050 * @param protocol 051 */ 052 protected void validateProtocol(String protocol) { 053 if(protocol != null && !protocol.equals(WebManager.PROTOCOL_HTTPS)) { 054 throw new IllegalStateException("HttpsConnectorGBean only supports "+WebManager.PROTOCOL_HTTPS); 055 } 056 } 057 058 /** 059 * Gets the name of the keystore file that holds the server certificate 060 * (and by default, the trusted CA certificates used for client certificate 061 * authentication). This is relative to the Geronimo home directory. 062 */ 063 public String getKeystoreFileName() { 064 return keystoreFileName; // don't look it up as we need it to be relative 065 } 066 067 /** 068 * Sets the name of the keystore file that holds the server certificate 069 * (and by default, the trusted CA certificates used for client certificate 070 * authentication). This is relative to the Geronimo home directory. 071 */ 072 public void setKeystoreFileName(String name) { 073 keystoreFileName = name; 074 connector.setAttribute("keystoreFile", serverInfo.resolveServerPath(keystoreFileName)); 075 } 076 077 public String getTruststoreFileName() { 078 return truststoreFileName; // don't look it up as we need it to be relative 079 } 080 081 public void setTruststoreFileName(String name) { 082 truststoreFileName = name; 083 connector.setAttribute("truststoreFile", serverInfo.resolveServerPath(truststoreFileName)); 084 } 085 086 /** 087 * Sets the password used to access the keystore, and by default, used to 088 * access the server private key inside the keystore. Not all connectors 089 * support configuring different passwords for those two features; if so, 090 * a separate PrivateKeyPassword should be defined in an 091 * implementation-specific connector interface. 092 */ 093 public void setKeystorePassword(String password) { 094 connector.setAttribute("keystorePass", password); 095 } 096 097 public void setTruststorePassword(String password) { 098 connector.setAttribute("truststorePass", password); 099 } 100 101 /** 102 * Gets the format of the entries in the keystore. The default format for 103 * Java keystores is JKS, though some connector implementations support 104 * PCKS12 (and possibly other formats). 105 */ 106 public String getKeystoreType() { 107 return (String)connector.getAttribute("keystoreType"); 108 } 109 110 /** 111 * Sets the format of the entries in the keystore. The default format for 112 * Java keystores is JKS, though some connector implementations support 113 * PCKS12 (and possibly other formats). 114 */ 115 public void setKeystoreType(String type) { 116 connector.setAttribute("keystoreType", type); 117 } 118 119 public String getTruststoreType() { 120 return (String)connector.getAttribute("truststoreType"); 121 } 122 123 public void setTruststoreType(String type) { 124 connector.setAttribute("truststoreType", type); 125 } 126 127 /** 128 * Gets the certificate algorithm used to access the keystore. This may 129 * be different for different JVM vendors, but should not usually be 130 * changed otherwise. 131 */ 132 public String getAlgorithm() { 133 return algorithm; 134 } 135 136 /** 137 * Sets the certificate algorithm used to access the keystore. This may 138 * be different for different JVM vendors, but should not usually be 139 * changed otherwise. 140 */ 141 public void setAlgorithm(String algorithm) { 142 this.algorithm = algorithm; 143 if ("default".equalsIgnoreCase(algorithm)) { 144 algorithm = KeyManagerFactory.getDefaultAlgorithm(); 145 } 146 connector.setAttribute("algorithm", algorithm); 147 } 148 149 /** 150 * Gets the protocol used for secure communication. This should usually 151 * be TLS, though some JVM implementations (particularly some of IBM's) 152 * may not be compatible with popular browsers unless this is changed to 153 * SSL. 154 */ 155 public String getSecureProtocol() { 156 return (String)connector.getAttribute("sslProtocol"); 157 } 158 159 /** 160 * Gets the protocol used for secure communication. This should usually 161 * be TLS, though some JVM implementations (particularly some of IBM's) 162 * may not be compatible with popular browsers unless this is changed to 163 * SSL. Don't change it if you're not having problems. 164 */ 165 public void setSecureProtocol(String protocol) { 166 connector.setAttribute("sslProtocol", protocol); 167 } 168 169 /** 170 * Checks whether clients are required to authenticate using client 171 * certificates in order to connect using this connector. If enabled, 172 * client certificates are validated using the trust store, which defaults 173 * to the same keystore file, keystore type, and keystore password as the 174 * regular keystore. Some connector implementations may allow you to 175 * configure those 3 values separately to use a different trust store. 176 */ 177 public boolean isClientAuthRequired() { 178 Object value = connector.getAttribute("clientAuth"); 179 return value == null ? false : new Boolean(value.toString()).booleanValue(); 180 } 181 182 /** 183 * Checks whether clients are required to authenticate using client 184 * certificates in order to connect using this connector. If enabled, 185 * client certificates are validated using the trust store, which defaults 186 * to the same keystore file, keystore type, and keystore password as the 187 * regular keystore. Some connector implementations may allow you to 188 * configure those 3 values separately to use a different trust store. 189 */ 190 public void setClientAuthRequired(boolean clientCert) { 191 connector.setAttribute("clientAuth", new Boolean(clientCert)); 192 } 193 194 /** 195 * Gets a comma seperated list of the encryption ciphers that may be used. If not 196 * specified, then any available cipher may be used. 197 */ 198 public String getCiphers() { 199 return (String)connector.getAttribute("ciphers"); 200 } 201 202 /** 203 * Sets a comma seperated list of the encryption ciphers that may be used. If not 204 * specified, then any available cipher may be used. 205 */ 206 public void setCiphers(String ciphers) { 207 connector.setAttribute("ciphers", ciphers); 208 } 209 210 public static final GBeanInfo GBEAN_INFO; 211 212 static { 213 GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic("Tomcat Connector", HttpsConnectorGBean.class, ConnectorGBean.GBEAN_INFO); 214 infoFactory.addAttribute("keystoreFileName", String.class, true, true); 215 infoFactory.addAttribute("truststoreFileName", String.class, true, true); 216 infoFactory.addAttribute("algorithm", String.class, true, true); 217 infoFactory.addAttribute("keystorePassword", String.class, true, true); 218 infoFactory.addAttribute("truststorePassword", String.class, true, true); 219 // todo should we support this? 220 // infoFactory.addAttribute("keyPassword", String.class, true, true); 221 infoFactory.addAttribute("secureProtocol", String.class, true, true); 222 infoFactory.addAttribute("keystoreType", String.class, true, true); 223 infoFactory.addAttribute("truststoreType", String.class, true, true); 224 infoFactory.addAttribute("clientAuthRequired", boolean.class, true, true); 225 infoFactory.addAttribute("ciphers", String.class, true, true); 226 infoFactory.addInterface(TomcatSecureConnector.class); 227 228 infoFactory.addReference("ServerInfo", ServerInfo.class, "GBean"); 229 infoFactory.setConstructor(new String[] { "name", "protocol", "host", "port", "TomcatContainer", "ServerInfo"}); 230 GBEAN_INFO = infoFactory.getBeanInfo(); 231 } 232 233 public static GBeanInfo getGBeanInfo() { 234 return GBEAN_INFO; 235 } 236 }