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
>
>

Reply via email to