Author: markt Date: Thu Dec 14 13:41:03 2017 New Revision: 1818127 URL: http://svn.apache.org/viewvc?rev=1818127&view=rev Log: Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=61565 Add TLS config reload to Manager app
Modified: tomcat/trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java tomcat/trunk/java/org/apache/catalina/manager/LocalStrings.properties tomcat/trunk/java/org/apache/catalina/manager/ManagerServlet.java tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java tomcat/trunk/webapps/docs/changelog.xml tomcat/trunk/webapps/docs/manager-howto.xml Modified: tomcat/trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java?rev=1818127&r1=1818126&r2=1818127&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java (original) +++ tomcat/trunk/java/org/apache/catalina/manager/HTMLManagerServlet.java Thu Dec 14 13:41:03 2017 @@ -193,6 +193,7 @@ public final class HTMLManagerServlet ex } String deployConfig = request.getParameter("deployConfig"); String deployWar = request.getParameter("deployWar"); + String tlsHostName = request.getParameter("tlsHostName"); // Prepare our output writer to generate the response message response.setContentType("text/html; charset=" + Constants.CHARSET); @@ -219,6 +220,8 @@ public final class HTMLManagerServlet ex message = stop(cn, smClient); } else if (command.equals("/findleaks")) { message = findleaks(smClient); + } else if (command.equals("/sslReload")) { + message = sslReload(tlsHostName, smClient); } else { // Try GET doGet(request,response); @@ -228,6 +231,7 @@ public final class HTMLManagerServlet ex list(request, response, message, smClient); } + protected String upload(HttpServletRequest request, StringManager smClient) { String message = ""; @@ -540,6 +544,15 @@ public final class HTMLManagerServlet ex args[3] = smClient.getString("htmlManagerServlet.deployButton"); writer.print(MessageFormat.format(UPLOAD_SECTION, args)); + // Config section + args = new Object[5]; + args[0] = smClient.getString("htmlManagerServlet.configTitle"); + args[1] = smClient.getString("htmlManagerServlet.configSslReloadTitle"); + args[2] = response.encodeURL(request.getContextPath() + "/html/sslReload"); + args[3] = smClient.getString("htmlManagerServlet.configSslHostName"); + args[4] = smClient.getString("htmlManagerServlet.configReloadButton"); + writer.print(MessageFormat.format(CONFIG_SECTION, args)); + // Diagnostics section args = new Object[15]; args[0] = smClient.getString("htmlManagerServlet.diagnosticsTitle"); @@ -734,6 +747,16 @@ public final class HTMLManagerServlet ex } + protected String sslReload(String tlsHostName, StringManager smClient) { + StringWriter stringWriter = new StringWriter(); + PrintWriter printWriter = new PrintWriter(stringWriter); + + super.sslReload(printWriter, tlsHostName, smClient); + + return stringWriter.toString(); + } + + protected void sslConnectorCiphers(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setAttribute("cipherList", getConnectorCiphers()); @@ -1318,6 +1341,43 @@ public final class HTMLManagerServlet ex "<br>\n" + "\n"; + private static final String CONFIG_SECTION = + "<table border=\"1\" cellspacing=\"0\" cellpadding=\"3\">\n" + + "<tr>\n" + + " <td colspan=\"2\" class=\"title\">{0}</td>\n" + + "</tr>\n" + + + "<tr>\n" + + " <td colspan=\"2\" class=\"header-left\"><small>{1}</small></td>\n" + + "</tr>\n" + + "<tr>\n" + + " <td colspan=\"2\">\n" + + "<form method=\"post\" action=\"{2}\">\n" + + "<table cellspacing=\"0\" cellpadding=\"3\">\n" + + "<tr>\n" + + " <td class=\"row-right\">\n" + + " <small>{3}</small>\n" + + " </td>\n" + + " <td class=\"row-left\">\n" + + " <input type=\"text\" name=\"tlsHostName\" size=\"20\">\n" + + " </td>\n" + + "</tr>\n" + + "<tr>\n" + + " <td class=\"row-right\">\n" + + " \n" + + " </td>\n" + + " <td class=\"row-left\">\n" + + " <input type=\"submit\" value=\"{4}\">\n" + + " </td>\n" + + "</tr>\n" + + "</table>\n" + + "</form>\n" + + "</td>\n" + + "</tr>\n" + + + "</table>\n" + + "<br>"; + private static final String DIAGNOSTICS_SECTION = "<table border=\"1\" cellspacing=\"0\" cellpadding=\"3\">\n" + "<tr>\n" + Modified: tomcat/trunk/java/org/apache/catalina/manager/LocalStrings.properties URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/manager/LocalStrings.properties?rev=1818127&r1=1818126&r2=1818127&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/manager/LocalStrings.properties (original) +++ tomcat/trunk/java/org/apache/catalina/manager/LocalStrings.properties Thu Dec 14 13:41:03 2017 @@ -32,6 +32,10 @@ htmlManagerServlet.helpHtmlManager=HTML htmlManagerServlet.helpHtmlManagerFile=../docs/html-manager-howto.html htmlManagerServlet.helpManager=Manager Help htmlManagerServlet.helpManagerFile=../docs/manager-howto.html +htmlManagerServlet.configTitle=Configuration +htmlManagerServlet.configSslReloadTitle=Re-read TLS configuration files +htmlManagerServlet.configSslHostName=TLS host name (optional) +htmlManagerServlet.configReloadButton=Re-read htmlManagerServlet.deployButton=Deploy htmlManagerServlet.deployConfig=XML Configuration file URL: htmlManagerServlet.deployPath=Context Path (required): @@ -116,6 +120,9 @@ managerServlet.sessions=OK - Session inf managerServlet.sslConnectorCiphers=OK - Connector / SSL Cipher information managerServlet.sslConnectorCerts=OK - Connector / Certificate Chain information managerServlet.sslConnectorTrustedCerts=OK - Connector / Trusted Certificate information +managerServlet.sslReload=OK - Reloaded TLS configuration for [{0}] +managerServlet.sslReloadAll=OK - Reloaded TLS configuration for all TLS virtual hosts +managerServlet.sslReloadFail=FAIL - Failed to reload TLS configuration managerServlet.started=OK - Started application at context path [{0}] managerServlet.startFailed=FAIL - Application at context path [{0}] could not be started managerServlet.stopped=OK - Stopped application at context path [{0}] Modified: tomcat/trunk/java/org/apache/catalina/manager/ManagerServlet.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/catalina/manager/ManagerServlet.java?rev=1818127&r1=1818126&r2=1818127&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/catalina/manager/ManagerServlet.java (original) +++ tomcat/trunk/java/org/apache/catalina/manager/ManagerServlet.java Thu Dec 14 13:41:03 2017 @@ -62,6 +62,8 @@ import org.apache.catalina.core.Standard import org.apache.catalina.startup.ExpandWar; import org.apache.catalina.util.ContextName; import org.apache.catalina.util.ServerInfo; +import org.apache.coyote.ProtocolHandler; +import org.apache.coyote.http11.AbstractHttp11Protocol; import org.apache.tomcat.util.Diagnostics; import org.apache.tomcat.util.ExceptionUtils; import org.apache.tomcat.util.modeler.Registry; @@ -323,6 +325,7 @@ public class ManagerServlet extends Http && (request.getParameter("update").equals("true"))) { update = true; } + String tlsHostName = request.getParameter("tlsHostName"); boolean statusLine = false; if ("true".equals(request.getParameter("statusLine"))) { @@ -377,6 +380,8 @@ public class ManagerServlet extends Http sslConnectorCerts(writer, smClient); } else if (command.equals("/sslConnectorTrustedCerts")) { sslConnectorTrustedCerts(writer, smClient); + } else if (command.equals("/sslReload")) { + sslReload(writer, tlsHostName, smClient); } else { writer.println(smClient.getString("managerServlet.unknownCommand", command)); @@ -543,6 +548,41 @@ public class ManagerServlet extends Http } + protected void sslReload(PrintWriter writer, String tlsHostName, StringManager smClient) { + Connector connectors[] = getConnectors(); + boolean found = false; + for (Connector connector : connectors) { + if (Boolean.TRUE.equals(connector.getProperty("SSLEnabled"))) { + ProtocolHandler protocol = connector.getProtocolHandler(); + if (protocol instanceof AbstractHttp11Protocol<?>) { + AbstractHttp11Protocol<?> http11Protoocol = (AbstractHttp11Protocol<?>) protocol; + if (tlsHostName == null || tlsHostName.length() == 0) { + found = true; + http11Protoocol.reloadSsslHostConfigs(); + } else { + SSLHostConfig[] sslHostConfigs = http11Protoocol.findSslHostConfigs(); + for (SSLHostConfig sslHostConfig : sslHostConfigs) { + if (sslHostConfig.getHostName().equalsIgnoreCase(tlsHostName)) { + found = true; + http11Protoocol.reloadSsslHostConfig(tlsHostName); + } + } + } + } + } + } + if (found) { + if (tlsHostName == null || tlsHostName.length() == 0) { + writer.println(smClient.getString("managerServlet.sslReloadAll")); + } else { + writer.println(smClient.getString("managerServlet.sslReload", tlsHostName)); + } + } else { + writer.println(smClient.getString("managerServlet.sslReloadFail")); + } + } + + /** * Write some VM info. * @@ -1724,9 +1764,7 @@ public class ManagerServlet extends Http protected Map<String,List<String>> getConnectorCiphers() { Map<String,List<String>> result = new HashMap<>(); - Engine e = (Engine) host.getParent(); - Service s = e.getService(); - Connector connectors[] = s.findConnectors(); + Connector connectors[] = getConnectors(); for (Connector connector : connectors) { if (Boolean.TRUE.equals(connector.getProperty("SSLEnabled"))) { SSLHostConfig[] sslHostConfigs = connector.getProtocolHandler().findSslHostConfigs(); @@ -1749,9 +1787,7 @@ public class ManagerServlet extends Http protected Map<String,List<String>> getConnectorCerts() { Map<String,List<String>> result = new HashMap<>(); - Engine e = (Engine) host.getParent(); - Service s = e.getService(); - Connector connectors[] = s.findConnectors(); + Connector connectors[] = getConnectors(); for (Connector connector : connectors) { if (Boolean.TRUE.equals(connector.getProperty("SSLEnabled"))) { SSLHostConfig[] sslHostConfigs = connector.getProtocolHandler().findSslHostConfigs(); @@ -1792,9 +1828,7 @@ public class ManagerServlet extends Http protected Map<String,List<String>> getConnectorTrustedCerts() { Map<String,List<String>> result = new HashMap<>(); - Engine e = (Engine) host.getParent(); - Service s = e.getService(); - Connector connectors[] = s.findConnectors(); + Connector connectors[] = getConnectors(); for (Connector connector : connectors) { if (Boolean.TRUE.equals(connector.getProperty("SSLEnabled"))) { SSLHostConfig[] sslHostConfigs = connector.getProtocolHandler().findSslHostConfigs(); @@ -1824,4 +1858,11 @@ public class ManagerServlet extends Http return result; } + + + private Connector[] getConnectors() { + Engine e = (Engine) host.getParent(); + Service s = e.getService(); + return s.findConnectors(); + } } Modified: tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java?rev=1818127&r1=1818126&r2=1818127&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java (original) +++ tomcat/trunk/java/org/apache/coyote/http11/AbstractHttp11Protocol.java Thu Dec 14 13:41:03 2017 @@ -524,11 +524,23 @@ public abstract class AbstractHttp11Prot getEndpoint().addSslHostConfig(sslHostConfig); } + @Override public SSLHostConfig[] findSslHostConfigs() { return getEndpoint().findSslHostConfigs(); } + + public void reloadSsslHostConfigs() { + getEndpoint().reloadSslHostConfigs(); + } + + + public void reloadSsslHostConfig(String hostName) { + getEndpoint().reloadSslHostConfig(hostName); + } + + // ----------------------------------------------- HTTPS specific properties // -------------------------------------------- Handled via an SSLHostConfig Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1818127&r1=1818126&r2=1818127&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Thu Dec 14 13:41:03 2017 @@ -91,6 +91,11 @@ mbeans-descriptiors.xml files for custom components. (markt) </add> <add> + <bug>61565</bug>: Add the ability to trigger a reloading of TLS host + configuration (certificate and key files, server.xml is not re-parsed) + via the Manager web application. (markt) + </add> + <add> <bug>61566</bug>: Expose the currently in use certificate chain and list of trusted certificates for all virtual hosts configured using the JSSE style (keystore) TLS configuration via the Manager web application. Modified: tomcat/trunk/webapps/docs/manager-howto.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/manager-howto.xml?rev=1818127&r1=1818126&r2=1818127&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/manager-howto.xml (original) +++ tomcat/trunk/webapps/docs/manager-howto.xml Thu Dec 14 13:41:03 2017 @@ -915,6 +915,18 @@ Connector[HTTP/1.1-8443]-_default_ </subsection> +<subsection name="Reload TLS configuration"> + +<source>http://localhost:8080/manager/text/sslReload?tlsHostName=name</source> + +<p>Reload the TLS configuration files (the certificate and key files, this does +not trigger a re-parsing of server.xml). To reload the files for all hosts don't +specify the <code>tlsHostName</code> parameter.</p> + +<source><![CDATA[OK - Reloaded TLS configuration for [_default_]]]></source> + +</subsection> + <subsection name="Thread Dump"> <source>http://localhost:8080/manager/text/threaddump</source> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org