On Thu, Jan 5, 2017 at 9:48 PM Jesse Schulman <je...@dreamtsoft.com> wrote:
> On Thu, Jan 5, 2017 at 2:08 PM Mark Thomas <ma...@apache.org> wrote: > > On 05/01/2017 21:05, Jesse Schulman wrote: > > We are using tomcat-embed 8.5.9, java8 and running on Centos7. Given > > Tomcat's new support for SNI, we wish to support adding/removing/updating > > certificates via our application at runtime without restarting tomcat or > > binding/unbinding the port. > > > > Our configuration is very simple, we have a single servlet for all > > requests, so we have a single connector/endpoint to manage all > > SSLHostConfigs. > > > > It appears that by manipulating the list of SSLHostConfig objects in the > > AbstractEndpoint we can achieve what we want, there however don't appear > to > > be any public methods available that allow that kind of operation. > > It should be possible with the current API. What can't you do? > > > I don't think I can modify an existing/added SSLHostConfig (remove an old > expiring certificate and add a new certificate). I also don't think I can > remove the SSLHostConfig for a given SNI hostname once it has been added. > > > I was able to extend a few tomcat classes (Connector, > > AbstractHttp11JsseProtocol, NioEndpoint) to expose what I need and verify > > that I can change the SSLHostConfig at runtime, however I would prefer to > > use APIs fully supported by tomcat. > > > > Is there any way to do what I want with the currently available APIs, or > > are there any plans to expose this kind of functionality? > > It depends exactly what you want to do. > > AbstractEndpoint.addSslHostConfig() > AbstractEndpoint.findSslHostConfigs() > > should be enough. > > > It seems addSslHostConfig does a putIfAbsent, which means I can't replace > an existing SSLHostConfig to update the certificate for an SNI hostname (or > the default SSLHostConfig). I also can't remove an SSLHostConfig entirely, > which is something we'd like to support in our application. For me it > would be simplest to create a new SSLHostConfig and replace the old one > when there is a need to update a certificate. > > > > > If not, are there any risks or issues with taking the approach described > > above by extending classes to expose what I need? > > It depends what you want to do. Generally, there is a risk we'll change > an API you are depending on since a lot of those are treated as internal > APIs. Some sample code might help. > > > I would of course test when we upgrade tomcat, and leverage any new APIs > that would allow me to remove any of my custom code. > > I extended AbstractHttp11JsseProtocol just so I could control which > endpoint implementation was used and so I could get access to my endpoint > implementation. My protocol is basically a copy of Http11NioProtocol that > constructs my endpoint implementation and has a getter for the same. > > The endpoint is where I added functionality and looks like this: > > public class MyNioEndpoint extends NioEndpoint { > private static final MyLogger LOGGER = > MyLogger.getLogger(MyNioEndpoint.class.getName()); > > public void removeSSLHostConfig(String sniHostName) { > if (Strings.isNullOrEmpty(sniHostName)) { > LOGGER.error("Cannot remove host config for invalid hostname: > " + sniHostName); > return; > } > > if (sniHostName.equals(getDefaultSSLHostConfigName())) { > LOGGER.error("Cannot remove default SSLHostConfig"); > return; > } > > SSLHostConfig removed = sslHostConfigs.remove(sniHostName); > if (removed != null) > releaseSSLContext(removed); > } > > public void addOrUpdateSSLHostConfig(SSLHostConfig config) { > if (config == null) { > LOGGER.error("null SSLHostConfig provided"); > return; > } > > String hostName = config.getHostName(); > if (Strings.isNullOrEmpty(hostName)) { > LOGGER.error("Invalid SSLHostConfig provided, cannot > add/update, hostname was empty"); > return; > } > > for (SSLHostConfig loadedConfig : findSslHostConfigs()) { > if (hostName.equals(loadedConfig.getHostName())) { > sslHostConfigs.remove(hostName); > releaseSSLContext(loadedConfig); > addSslHostConfig(loadedConfig); > return; > } > } > > addSslHostConfig(config); > } > > } > > Thanks for the reply, your help/suggestions are much appreciated! > Jesse > > I am bumping this, I think I made it sound as if I had all my questions answered (since I didn't put any questions in my response). Here are my remaining questions: Is there an existing/supported way to remove/replace an existing SSLHostConfig in AbstractEndpoint that is exposed via the Connector similar to how addSslHostConfig and findSslHostConfigs are exposed? Such that I don't need the MyEndpoint class I shared above? If the answer to the first question is no, are there any concerns with the code I shared? By releasing the SSLContext is that ensuring that nothing will stick around from an SSLHostConfig that is removed/replaced, or is there more to do? Thanks! Jesse > Mark > > --------------------------------------------------------------------- > To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org > For additional commands, e-mail: users-h...@tomcat.apache.org > >