Commit c0f5026e authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

Restart Jetty when certificates are modified. JM-892

git-svn-id: http://svn.igniterealtime.org/svn/repos/wildfire/trunk@6098 b35dd754-fafc-0310-a699-88a17e54d16e
parent d2526d65
......@@ -1534,6 +1534,8 @@ ssl.certificates.error_importing-reply=An error occured while importing the Cert
the reply is correct and that it belongs to the correct certificate.
ssl.certificates.imported=Certificate Authority reply was imported successfully.
ssl.certificates.ca-reply=Certificate Authority Reply:
ssl.certificates.restart_server=Certificates were modified so HTTP server needs to be restarted. Click {0}here{1} to \
restart HTTP server.
ssl.certificates.no_installed=One or more certificates are not installed. Click {0}here{1} to generate self-signed \
certificates.
ssl.certificates.issuer-updated=Issuer information updated successfully.
......@@ -1574,6 +1576,12 @@ ssl.signing-request.requests_info=Below you will find the signing requests gener
ssl.signing-request.alias=Alias
ssl.signing-request.signing-request=Signing Request
# Restart HTTP server
server-restart.title=HTTP Server Restart
server-restart.info=The HTTP server will be restarted. In a few seconds you will be redirected to the login page. \
In case that redirection fails click {0}here{1} to go to the login page.
# Compression settings Page
compression.settings.title=Nastaven\u00ed komprese
......
......@@ -1312,6 +1312,8 @@ ssl.certificates.error_importing-reply=An error occured while importing the Cert
the reply is correct and that it belongs to the correct certificate.
ssl.certificates.imported=Certificate Authority reply was imported successfully.
ssl.certificates.ca-reply=Certificate Authority Reply:
ssl.certificates.restart_server=Certificates were modified so HTTP server needs to be restarted. Click {0}here{1} to \
restart HTTP server.
ssl.certificates.no_installed=One or more certificates are not installed. Click {0}here{1} to generate self-signed \
certificates.
ssl.certificates.issuer-updated=Issuer information updated successfully.
......@@ -1352,6 +1354,12 @@ ssl.signing-request.requests_info=Below you will find the signing requests gener
ssl.signing-request.alias=Alias
ssl.signing-request.signing-request=Signing Request
# Restart HTTP server
server-restart.title=HTTP Server Restart
server-restart.info=The HTTP server will be restarted. In a few seconds you will be redirected to the login page. \
In case that redirection fails click {0}here{1} to go to the login page.
# Compression settings Page
compression.settings.title=Komprimierungseinstellungen
......
......@@ -181,6 +181,7 @@
## Added key: 'global.save'
## Added section: 'ssl.certificates.*'
## Added section: 'ssl.signing-request.*'
## Added section: 'server-restart.*'
## Removed key: 'ssl.certificates.uninstalled'
## Removed key: 'ssl.certificates.error_certificate'
## Removed key: 'ssl.certificates.certificate'
......@@ -1738,6 +1739,8 @@ ssl.certificates.error_importing-reply=An error occured while importing the Cert
the reply is correct and that it belongs to the correct certificate.
ssl.certificates.imported=Certificate Authority reply was imported successfully.
ssl.certificates.ca-reply=Certificate Authority Reply:
ssl.certificates.restart_server=Certificates were modified so HTTP server needs to be restarted. Click {0}here{1} to \
restart HTTP server.
ssl.certificates.no_installed=One or more certificates are not installed. Click {0}here{1} to generate self-signed \
certificates.
ssl.certificates.issuer-updated=Issuer information updated successfully.
......@@ -1778,6 +1781,12 @@ ssl.signing-request.requests_info=Below you will find the signing requests gener
ssl.signing-request.alias=Alias
ssl.signing-request.signing-request=Signing Request
# Restart HTTP server
server-restart.title=HTTP Server Restart
server-restart.info=The HTTP server will be restarted. In a few seconds you will be redirected to the login page. \
In case that redirection fails click {0}here{1} to go to the login page.
# Compression settings Page
compression.settings.title=Compression Settings
......
......@@ -1426,6 +1426,8 @@ ssl.certificates.error_importing-reply=Un error ha occurido mientras se estaba i
Autoridad Certificadora. Verifique que la respuesta sea correcta y que pertenece al certificado.
ssl.certificates.imported=Respuesta de la Autoridad Certificadora ha sido importada exitosamente.
ssl.certificates.ca-reply=Respuesta de la Autoridad Certificadora:
ssl.certificates.restart_server=El servidor HTTP debe ser reiniciado ya que los certificados han sido modificados. Haga \
clic {0}aqu\u00ed{1} para reiniciar el servidor HTTP.
ssl.certificates.no_installed=Uno o m\u00e1s certificados no se han instalado. Haga clic {0}aqu\u00ed{1} para generar \
certificados auto-firmados.
ssl.certificates.issuer-updated=Informaci\u00f3n de la entidad emisora actualizada exitosamente.
......@@ -1467,6 +1469,12 @@ ssl.signing-request.requests_info=A continuaci\u00f3n se listan los pedidos de f
ssl.signing-request.alias=Alias
ssl.signing-request.signing-request=Pedido de Firma
# Restart HTTP server
server-restart.title=Reiniciar Servidor HTTP
server-restart.info=El servidor HTTP ser\u00e1 reiniciado. En unos segundos ser\u00e1 redirigido a la p\u00e1gina de ingreso. \
En caso que la redicci\u00f3n falle haga clic {0}aqu\u00ed{1} para ir a la p\u00e1gina de ingreso.
# Compression settings Page
compression.settings.title=Configuraci\u00f3n de compresi\u00f3n
......
......@@ -1223,6 +1223,8 @@ ssl.certificates.error_importing-reply=An error occured while importing the Cert
the reply is correct and that it belongs to the correct certificate.
ssl.certificates.imported=Certificate Authority reply was imported successfully.
ssl.certificates.ca-reply=Certificate Authority Reply:
ssl.certificates.restart_server=Certificates were modified so HTTP server needs to be restarted. Click {0}here{1} to \
restart HTTP server.
ssl.certificates.no_installed=One or more certificates are not installed. Click {0}here{1} to generate self-signed \
certificates.
ssl.certificates.issuer-updated=Issuer information updated successfully.
......@@ -1263,6 +1265,12 @@ ssl.signing-request.requests_info=Below you will find the signing requests gener
ssl.signing-request.alias=Alias
ssl.signing-request.signing-request=Signing Request
# Restart HTTP server
server-restart.title=HTTP Server Restart
server-restart.info=The HTTP server will be restarted. In a few seconds you will be redirected to the login page. \
In case that redirection fails click {0}here{1} to go to the login page.
# Compression settings Page
compression.settings.title = Param\u00E8tres de Compression
compression.settings.update = Param\u00E8tres mis \u00E0 jour avec succ\u00E8s.
......
......@@ -1313,6 +1313,8 @@ ssl.certificates.error_importing-reply=An error occured while importing the Cert
the reply is correct and that it belongs to the correct certificate.
ssl.certificates.imported=Certificate Authority reply was imported successfully.
ssl.certificates.ca-reply=Certificate Authority Reply:
ssl.certificates.restart_server=Certificates were modified so HTTP server needs to be restarted. Click {0}here{1} to \
restart HTTP server.
ssl.certificates.no_installed=One or more certificates are not installed. Click {0}here{1} to generate self-signed \
certificates.
ssl.certificates.issuer-updated=Issuer information updated successfully.
......@@ -1353,6 +1355,12 @@ ssl.signing-request.requests_info=Below you will find the signing requests gener
ssl.signing-request.alias=Alias
ssl.signing-request.signing-request=Signing Request
# Restart HTTP server
server-restart.title=HTTP Server Restart
server-restart.info=The HTTP server will be restarted. In a few seconds you will be redirected to the login page. \
In case that redirection fails click {0}here{1} to go to the login page.
# Compression settings Page
compression.settings.title=Compression Settings
......
......@@ -1293,6 +1293,8 @@ ssl.certificates.error_importing-reply=An error occured while importing the Cert
the reply is correct and that it belongs to the correct certificate.
ssl.certificates.imported=Certificate Authority reply was imported successfully.
ssl.certificates.ca-reply=Certificate Authority Reply:
ssl.certificates.restart_server=Certificates were modified so HTTP server needs to be restarted. Click {0}here{1} to \
restart HTTP server.
ssl.certificates.no_installed=One or more certificates are not installed. Click {0}here{1} to generate self-signed \
certificates.
ssl.certificates.issuer-updated=Issuer information updated successfully.
......@@ -1333,6 +1335,12 @@ ssl.signing-request.requests_info=Below you will find the signing requests gener
ssl.signing-request.alias=Alias
ssl.signing-request.signing-request=Signing Request
# Restart HTTP server
server-restart.title=HTTP Server Restart
server-restart.info=The HTTP server will be restarted. In a few seconds you will be redirected to the login page. \
In case that redirection fails click {0}here{1} to go to the login page.
# Compression settings Page
compression.settings.title=Ustawienia kompresji
......
......@@ -1310,6 +1310,8 @@ ssl.certificates.error_importing-reply=An error occured while importing the Cert
the reply is correct and that it belongs to the correct certificate.
ssl.certificates.imported=Certificate Authority reply was imported successfully.
ssl.certificates.ca-reply=Certificate Authority Reply:
ssl.certificates.restart_server=Certificates were modified so HTTP server needs to be restarted. Click {0}here{1} to \
restart HTTP server.
ssl.certificates.no_installed=One or more certificates are not installed. Click {0}here{1} to generate self-signed \
certificates.
ssl.certificates.issuer-updated=Issuer information updated successfully.
......@@ -1350,6 +1352,12 @@ ssl.signing-request.requests_info=Below you will find the signing requests gener
ssl.signing-request.alias=Alias
ssl.signing-request.signing-request=Signing Request
# Restart HTTP server
server-restart.title=HTTP Server Restart
server-restart.info=The HTTP server will be restarted. In a few seconds you will be redirected to the login page. \
In case that redirection fails click {0}here{1} to go to the login page.
# Compression settings Page
compression.settings.title=Configura\u00e7\u00f5es de Compress\u00e3o
......
......@@ -1380,6 +1380,8 @@ ssl.certificates.error_importing-reply=An error occured while importing the Cert
the reply is correct and that it belongs to the correct certificate.
ssl.certificates.imported=Certificate Authority reply was imported successfully.
ssl.certificates.ca-reply=Certificate Authority Reply:
ssl.certificates.restart_server=Certificates were modified so HTTP server needs to be restarted. Click {0}here{1} to \
restart HTTP server.
ssl.certificates.no_installed=One or more certificates are not installed. Click {0}here{1} to generate self-signed \
certificates.
ssl.certificates.issuer-updated=Issuer information updated successfully.
......@@ -1420,6 +1422,12 @@ ssl.signing-request.requests_info=Below you will find the signing requests gener
ssl.signing-request.alias=Alias
ssl.signing-request.signing-request=Signing Request
# Restart HTTP server
server-restart.title=HTTP Server Restart
server-restart.info=The HTTP server will be restarted. In a few seconds you will be redirected to the login page. \
In case that redirection fails click {0}here{1} to go to the login page.
# Compression settings Page
compression.settings.title=\u538b\u7f29\u8bbe\u7f6e
......
......@@ -11,24 +11,25 @@
package org.jivesoftware.wildfire;
import org.apache.commons.logging.LogConfigurationException;
import org.apache.commons.logging.LogFactory;
import org.jivesoftware.util.*;
import org.jivesoftware.wildfire.net.SSLConfig;
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.security.SslSocketConnector;
import org.mortbay.jetty.servlet.Context;
import org.mortbay.jetty.servlet.ServletHolder;
import org.mortbay.jetty.servlet.ServletHandler;
import org.mortbay.jetty.servlet.ServletHolder;
import org.mortbay.jetty.servlet.ServletMapping;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.security.SslSocketConnector;
import org.mortbay.log.Logger;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.LogConfigurationException;
import javax.net.ssl.SSLServerSocketFactory;
import java.util.Collection;
import java.util.List;
import java.security.KeyStore;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
/**
......@@ -79,6 +80,8 @@ public class HttpServerManager {
private Context adminConsoleContext;
private ServletHolder httpBindContext;
private String httpBindPath;
private CertificateEventListener certificateListener;
private boolean restartNeeded = false;
/**
* Constructs a new HTTP server manager.
......@@ -121,6 +124,11 @@ public class HttpServerManager {
* proper contexts are then added to the Jetty servers.
*/
public void startup() {
restartNeeded = false;
// Add listener for certificate events
certificateListener = new CertificateListener();
CertificateManager.addListener(certificateListener);
if (httpBindContext != null && isHttpBindServiceEnabled()) {
bindPort = JiveGlobals.getIntProperty(HTTP_BIND_PORT, ADMIN_CONSOLE_PORT_DEFAULT);
bindSecurePort = JiveGlobals.getIntProperty(HTTP_BIND_SECURE_PORT,
......@@ -155,25 +163,36 @@ public class HttpServerManager {
* Shuts down any Jetty servers that are running the admin console and HTTP binding service.
*/
public void shutdown() {
if (httpBindServer != null) {
try {
// Remove listener for certificate events
if (certificateListener != null) {
CertificateManager.removeListener(certificateListener);
}
try {
if (httpBindServer != null && httpBindServer.isRunning()) {
httpBindServer.stop();
}
catch (Exception e) {
Log.error("Error stopping HTTP bind server", e);
if (httpBindContext != null && httpBindContext.isRunning()) {
httpBindContext.stop();
}
httpBindServer = null;
}
catch (Exception e) {
Log.error("Error stopping HTTP bind server", e);
}
httpBindServer = null;
//noinspection ConstantConditions
if (adminServer != null && adminServer != httpBindServer) {
try {
try {
if (adminServer != null && adminServer.isRunning()) {
adminServer.stop();
}
catch (Exception e) {
Log.error("Error stopping admin console server", e);
if (adminConsoleContext != null && adminConsoleContext.isRunning()) {
adminConsoleContext.stop();
}
adminServer = null;
}
catch (Exception e) {
Log.error("Error stopping admin console server", e);
}
adminServer = null;
}
......@@ -186,6 +205,16 @@ public class HttpServerManager {
return httpBindServer != null && httpBindServer.isRunning();
}
/**
* Returns true if the Jetty server needs to be restarted. This is usually required when
* certificates are added, deleted or modified or when server ports were modified.
*
* @return true if the Jetty server needs to be restarted.
*/
public boolean isRestartNeeded() {
return restartNeeded;
}
/**
* Returns the HTTP binding port which does not use SSL.
*
......@@ -273,13 +302,17 @@ public class HttpServerManager {
*/
private void startHttpBindServer(int port, int securePort) {
httpBindServer = new Server();
Collection<Connector> connectors = createAdminConsoleConnectors(port, securePort);
if (connectors.size() == 0) {
Connector httpConnector = createConnector(port);
Connector httpsConnector = createSSLConnector(securePort);
if (httpConnector == null && httpsConnector == null) {
httpBindServer = null;
return;
}
for (Connector connector : connectors) {
httpBindServer.addConnector(connector);
if (httpConnector != null) {
httpBindServer.addConnector(httpConnector);
}
if (httpsConnector != null) {
httpBindServer.addConnector(httpsConnector);
}
}
......@@ -311,8 +344,9 @@ public class HttpServerManager {
}
if (loadConnectors) {
Collection<Connector> connectors = createAdminConsoleConnectors(adminPort, adminSecurePort);
if (connectors.size() == 0) {
Connector httpConnector = createConnector(adminPort);
Connector httpsConnector = createSSLConnector(adminSecurePort);
if (httpConnector == null && httpsConnector == null) {
adminServer = null;
// Log warning.
......@@ -322,9 +356,11 @@ public class HttpServerManager {
return;
}
for (Connector connector : connectors) {
adminServer.addConnector(connector);
if (httpConnector != null) {
adminServer.addConnector(httpConnector);
}
if (httpsConnector != null) {
adminServer.addConnector(httpsConnector);
}
}
......@@ -381,7 +417,7 @@ public class HttpServerManager {
private void addContexts() {
if (httpBindServer == adminServer && httpBindServer != null) {
adminConsoleContext.addServlet(httpBindContext, httpBindPath);
if (adminConsoleContext.getServer() == null) {
if (adminServer.getHandler() == null) {
adminServer.addHandler(adminConsoleContext);
}
return;
......@@ -425,17 +461,19 @@ public class HttpServerManager {
handler.setServlets(toAddServlets.toArray(new ServletHolder[toAddServlets.size()]));
}
private Collection<Connector> createAdminConsoleConnectors(int port, int securePort) {
List<Connector> connectorList = new ArrayList<Connector>();
private Connector createConnector(int port) {
if (port > 0) {
SelectChannelConnector connector = new SelectChannelConnector();
connector.setPort(port);
connectorList.add(connector);
return connector;
}
return null;
}
private Connector createSSLConnector(int securePort) {
try {
if (securePort > 0) {
if (securePort > 0 && CertificateManager.isRSACertificate(SSLConfig.getKeyStore(),
XMPPServer.getInstance().getServerInfo().getName())) {
SslSocketConnector sslConnector = new JiveSslConnector();
sslConnector.setPort(securePort);
......@@ -448,13 +486,13 @@ public class HttpServerManager {
sslConnector.setKeyPassword(SSLConfig.getKeyPassword());
sslConnector.setKeystoreType(SSLConfig.getStoreType());
sslConnector.setKeystore(SSLConfig.getKeystoreLocation());
connectorList.add(sslConnector);
return sslConnector;
}
}
catch (Exception e) {
Log.error(e);
}
return connectorList;
return null;
}
private void changeHttpBindPorts(int unsecurePort, int securePort) {
......@@ -560,6 +598,62 @@ public class HttpServerManager {
}
}
private class CertificateListener implements CertificateEventListener {
public void certificateCreated(KeyStore keyStore, String alias, X509Certificate cert) {
// If new certificate is RSA then (re)start the HTTPS service
if ("RSA".equals(cert.getPublicKey().getAlgorithm())) {
restartNeeded = true;
}
}
public void certificateDeleted(KeyStore keyStore, String alias) {
restartNeeded = true;
}
public void certificateSigned(KeyStore keyStore, String alias,
List<X509Certificate> certificates) {
// If new certificate is RSA then (re)start the HTTPS service
if ("RSA".equals(certificates.get(0).getPublicKey().getAlgorithm())) {
restartNeeded = true;
}
}
/*private void stopSSLService() throws Exception {
if (adminServer != null && adminSSLConnector != null) {
adminSSLConnector.stop();
adminServer.removeConnector(adminSSLConnector);
adminSSLConnector = null;
}
// HTTP binding SSL service
if (httpBindServer != null && httpBindServer != adminServer &&
bindSSLConnector != null) {
bindSSLConnector.stop();
httpBindServer.removeConnector(bindSSLConnector);
bindSSLConnector = null;
}
}
private void startSSLService() throws Exception {
if (adminServer != null && adminSecurePort > 0) {
adminSSLConnector = createSSLConnector(adminSecurePort);
adminServer.addConnector(adminSSLConnector);
adminServer.setHandlers(adminServer.getHandlers());
adminSSLConnector.start();
/*adminServer.stop();
adminServer.start();
}
// HTTP binding SSL service
if (httpBindServer != null && httpBindServer != adminServer && bindSecurePort > 0) {
bindSSLConnector = createSSLConnector(bindSecurePort);
httpBindServer.addConnector(bindSSLConnector);
adminServer.setHandlers(adminServer.getHandlers());
bindSSLConnector.start();
/*httpBindServer.stop();
httpBindServer.start(); }
}*/
}
/**
* Listens for changes to Jive properties that affect the HTTP server manager.
*/
......
......@@ -570,6 +570,34 @@ public class XMPPServer {
}
}
/**
* Restarts the HTTP server only when running in stand alone mode. The restart process will be done
* in another thread that will wait 1 second before doing the actual restart. The delay will give time
* to the page that requested the restart to fully render its content.
*/
public void restartHTTPServer() {
Thread restartThread = new Thread() {
public void run() {
if (isStandAlone()) {
// Restart the HTTP server manager. This covers the case
// of changing the ports, as well as generating self-signed certificates.
// Wait a short period before shutting down the admin console.
// Otherwise, this page won't render properly!
try {
Thread.sleep(1000);
httpServerManager.shutdown();
httpServerManager.startup();
} catch (Exception e) {
e.printStackTrace();
}
}
}
};
restartThread.setContextClassLoader(loader);
restartThread.start();
}
/**
* Stops the server only if running in standalone mode. Do nothing if the server is running
* inside of another server.
......
......@@ -13,6 +13,7 @@
<%@ page import="java.util.Enumeration" %>
<%@ page import="java.util.HashMap" %>
<%@ page import="java.util.Map" %>
<%@ page import="org.jivesoftware.wildfire.HttpServerManager" %>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
......@@ -92,7 +93,21 @@
</head>
<body>
<% if (keyStore.size() < 2 ) { %>
<% if (HttpServerManager.getInstance().isRestartNeeded()) { %>
<div class="warning">
<table cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr>
<td class="jive-icon-label">
<fmt:message key="ssl.certificates.restart_server">
<fmt:param value="<%= "<a href='server-restart.jsp?page=ssl-certificates.jsp'>" %>" />
<fmt:param value="<%= "</a>" %>" />
</fmt:message>
</td></tr>
</tbody>
</table>
</div><br>
<% } else if (keyStore.size() < 2 ) { %>
<div class="warning">
<table cellpadding="0" cellspacing="0" border="0">
<tbody>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment