Commit cbfe7e43 authored by Guus der Kinderen's avatar Guus der Kinderen

OF-1049: Improve Certificate Management

The admin console should existing-but-invalid configuration.
Configuration should be modifiable through admin console.
parent 32a57837
...@@ -2262,6 +2262,10 @@ ssl.certificates.store-management.component-stores.info=These stores are used to ...@@ -2262,6 +2262,10 @@ ssl.certificates.store-management.component-stores.info=These stores are used to
ssl.certificates.store-management.connection-manager-stores.title=Connection Manager Stores ssl.certificates.store-management.connection-manager-stores.title=Connection Manager Stores
ssl.certificates.store-management.connection-manager-stores.info=These stores are used to establish connections with Openfire Connection Managers.ssl.certificates.store-management.socket-s2s-stores.title=Server Federation Stores ssl.certificates.store-management.connection-manager-stores.info=These stores are used to establish connections with Openfire Connection Managers.ssl.certificates.store-management.socket-s2s-stores.title=Server Federation Stores
ssl.certificates.store-management.manage=Manage Store Contents ssl.certificates.store-management.manage=Manage Store Contents
ssl.certificates.store-management.file_label=File
ssl.certificates.store-management.password_label=Password
ssl.certificates.store-management.error.cannot-access=Configuration problem: Unable to access the store.
ssl.certificates.store-management.saved_successfully=Settings updated successfully.
# Openfire Certificates Page # Openfire Certificates Page
......
...@@ -103,7 +103,7 @@ public class CertificateStoreManager extends BasicModule ...@@ -103,7 +103,7 @@ public class CertificateStoreManager extends BasicModule
return trustStores.get( configuration ); return trustStores.get( configuration );
} }
public void replaceIdentityStore( ConnectionType type, CertificateStoreConfiguration configuration ) throws CertificateStoreConfigException public void replaceIdentityStore( ConnectionType type, CertificateStoreConfiguration configuration, boolean createIfAbsent ) throws CertificateStoreConfigException
{ {
if ( type == null) if ( type == null)
{ {
...@@ -122,7 +122,7 @@ public class CertificateStoreManager extends BasicModule ...@@ -122,7 +122,7 @@ public class CertificateStoreManager extends BasicModule
if ( !identityStores.containsKey( configuration ) ) if ( !identityStores.containsKey( configuration ) )
{ {
// This constructor can throw an exception. If it does, the state of the manager should not have already changed. // This constructor can throw an exception. If it does, the state of the manager should not have already changed.
final IdentityStore store = new IdentityStore( configuration, true ); final IdentityStore store = new IdentityStore( configuration, createIfAbsent );
identityStores.put( configuration, store ); identityStores.put( configuration, store );
} }
...@@ -151,7 +151,7 @@ public class CertificateStoreManager extends BasicModule ...@@ -151,7 +151,7 @@ public class CertificateStoreManager extends BasicModule
JiveGlobals.setProperty( type.getPrefix() + "keypass", new String( configuration.getPassword() ) ); JiveGlobals.setProperty( type.getPrefix() + "keypass", new String( configuration.getPassword() ) );
} }
public void replaceTrustStore( ConnectionType type, CertificateStoreConfiguration configuration ) throws CertificateStoreConfigException public void replaceTrustStore( ConnectionType type, CertificateStoreConfiguration configuration, boolean createIfAbsent ) throws CertificateStoreConfigException
{ {
if ( type == null) if ( type == null)
{ {
...@@ -170,7 +170,7 @@ public class CertificateStoreManager extends BasicModule ...@@ -170,7 +170,7 @@ public class CertificateStoreManager extends BasicModule
if ( !trustStores.containsKey( configuration ) ) if ( !trustStores.containsKey( configuration ) )
{ {
// This constructor can throw an exception. If it does, the state of the manager should not have already changed. // This constructor can throw an exception. If it does, the state of the manager should not have already changed.
final TrustStore store = new TrustStore( configuration, true ); final TrustStore store = new TrustStore( configuration, createIfAbsent );
trustStores.put( configuration, store ); trustStores.put( configuration, store );
} }
......
...@@ -3,6 +3,10 @@ ...@@ -3,6 +3,10 @@
<%@ page import="java.util.HashMap" %> <%@ page import="java.util.HashMap" %>
<%@ page import="org.jivesoftware.openfire.spi.ConnectionType" %> <%@ page import="org.jivesoftware.openfire.spi.ConnectionType" %>
<%@ page import="org.jivesoftware.openfire.XMPPServer" %> <%@ page import="org.jivesoftware.openfire.XMPPServer" %>
<%@ page import="org.jivesoftware.openfire.keystore.CertificateStoreManager" %>
<%@ page import="org.jivesoftware.openfire.keystore.CertificateStoreConfiguration" %>
<%@ page import="java.io.File" %>
<%@ page import="org.jivesoftware.util.Log" %>
<%@ taglib uri="admin" prefix="admin" %> <%@ taglib uri="admin" prefix="admin" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %> <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt" %>
...@@ -12,10 +16,55 @@ ...@@ -12,10 +16,55 @@
<jsp:useBean id="now" class="java.util.Date"/> <jsp:useBean id="now" class="java.util.Date"/>
<% webManager.init(request, response, session, application, out ); <% webManager.init(request, response, session, application, out );
final CertificateStoreManager certificateStoreManager = XMPPServer.getInstance().getCertificateStoreManager();
final Map<String, String> errors = new HashMap<>(); final Map<String, String> errors = new HashMap<>();
pageContext.setAttribute( "errors", errors ); pageContext.setAttribute( "errors", errors );
pageContext.setAttribute( "connectionTypes", ConnectionType.values() ); pageContext.setAttribute( "connectionTypes", ConnectionType.values() );
pageContext.setAttribute( "certificateStoreManager", XMPPServer.getInstance().getCertificateStoreManager() ); pageContext.setAttribute( "certificateStoreManager", certificateStoreManager );
final boolean update = request.getParameter("update") != null;
if ( update ) {
ConnectionType connectionType = null;
try {
connectionType = ConnectionType.valueOf( request.getParameter( "connectionType" ) );
} catch ( IllegalArgumentException ex ) {
Log.warn( ex );
errors.put( "connectionType", ex.getMessage() );
}
final String locKey = request.getParameter( "loc-key" );
final String pwdKey = request.getParameter( "pwd-key" );
final String locTrust = request.getParameter( "loc-trust" );
final String pwdTrust = request.getParameter( "pwd-trust" );
if ( locKey == null || locKey.isEmpty() ) {
errors.put( "locKey", "Identity Store location must be defined." );
}
if ( pwdKey == null || pwdKey.isEmpty() ) {
errors.put( "pwdKey", "Identity Store password must be defined." );
}
if ( locTrust == null || locTrust.isEmpty() ) {
errors.put( "locTrust", "Trust Store location must be defined." );
}
if ( pwdTrust == null || pwdTrust.isEmpty() ) {
errors.put( "pwdTrust", "Trust Store password must be defined." );
}
if ( errors.isEmpty() ) {
try
{
final CertificateStoreConfiguration configKey = new CertificateStoreConfiguration( "jks", new File( locKey ), pwdKey.toCharArray() );
final CertificateStoreConfiguration configTrust = new CertificateStoreConfiguration( "jks", new File( locTrust ), pwdTrust.toCharArray() );
certificateStoreManager.replaceIdentityStore( connectionType, configKey, false );
certificateStoreManager.replaceTrustStore( connectionType, configTrust, false );
pageContext.setAttribute( "updated", true );
} catch ( Exception ex ) {
Log.warn( ex );
errors.put( "update", ex.getMessage() );
}
}
}
%> %>
<html> <html>
<head> <head>
...@@ -40,6 +89,13 @@ ...@@ -40,6 +89,13 @@
</admin:infobox> </admin:infobox>
</c:forEach> </c:forEach>
<!-- Display success report, but only if there were no errors. -->
<c:if test="${updated and empty errors}">
<admin:infoBox type="success">
<fmt:message key="ssl.certificates.store-management.saved_successfully"/>
</admin:infoBox>
</c:if>
<p> <p>
<fmt:message key="ssl.certificates.store-management.info-1"/> <fmt:message key="ssl.certificates.store-management.info-1"/>
</p> </p>
...@@ -73,27 +129,77 @@ ...@@ -73,27 +129,77 @@
</c:choose> </c:choose>
</c:set> </c:set>
<admin:contentBox title="${title}"> <form action="security-certificate-store-management.jsp" method="post">
<p> <input type="hidden" name="connectionType" value="${connectionType}"/>
<c:out value="${description}"/>
</p> <admin:contentBox title="${title}">
<p>
<table cellpadding="0" cellspacing="0" border="0"> <c:out value="${description}"/>
<tbody> </p>
<tr>
<td><label for="loc-key-socket"><fmt:message key="ssl.certificates.identity-store"/>:</label></td> <h4><fmt:message key="ssl.certificates.identity-store"/></h4>
<td><input id="loc-key-socket" name="loc-key-socket" type="text" size="80" readonly value="${certificateStoreManager.getIdentityStore(connectionType).configuration.file}"/></td>
<td><a href="security-keystore.jsp?connectionType=${connectionType}"><fmt:message key="ssl.certificates.store-management.manage"/></a></td> <c:if test="${empty certificateStoreManager.getIdentityStore(connectionType)}">
</tr> <admin:infobox type="warning"><fmt:message key="ssl.certificates.store-management.error.cannot-access"/></admin:infobox>
<tr> </c:if>
<td><label for="loc-trust-socket-c2s"><fmt:message key="ssl.certificates.trust-store"/>:</label></td>
<td><input id="loc-trust-socket-c2s" name="loc-trust-socket-c2s" type="text" size="80" readonly value="${certificateStoreManager.getTrustStore(connectionType).configuration.file}"/></td> <c:set var="pwdKey" value=""/>
<td><a href="security-truststore.jsp?connectionType=${connectionType}"><fmt:message key="ssl.certificates.store-management.manage"/></a></td> <c:forEach items="${certificateStoreManager.getIdentityStoreConfiguration(connectionType).password}" var="c">
</tr> <c:set var="pwdKey" value="${pwdKey}${c}"/>
</tbody> </c:forEach>
</table>
<table cellpadding="0" cellspacing="0" border="0">
</admin:contentBox> <tbody>
<tr>
<td><label for="loc-key"><fmt:message key="ssl.certificates.store-management.file_label"/>:</label></td>
<td><input id="loc-key" name="loc-key" type="text" size="80" value="${certificateStoreManager.getIdentityStoreConfiguration(connectionType).file}"/></td>
</tr>
<tr>
<td><label for="pwd-key"><fmt:message key="ssl.certificates.store-management.password_label"/>:</label></td>
<td><input id="pwd-key" name="pwd-key" type="password" size="30" value="${pwdKey}"/></td>
</tr>
<tr>
<td>&nbsp;</td>
<td><a href="security-keystore.jsp?connectionType=${connectionType}"><fmt:message key="ssl.certificates.store-management.manage"/></a></td>
</tr>
</tbody>
</table>
<br/>
<h4><fmt:message key="ssl.certificates.trust-store"/></h4>
<c:if test="${empty certificateStoreManager.getTrustStore(connectionType)}">
<admin:infobox type="warning"><fmt:message key="ssl.certificates.store-management.error.cannot-access"/></admin:infobox>
</c:if>
<c:set var="pwdTrust" value=""/>
<c:forEach items="${certificateStoreManager.getTrustStoreConfiguration(connectionType).password}" var="c">
<c:set var="pwdTrust" value="${pwdTrust}${c}"/>
</c:forEach>
<table cellpadding="0" cellspacing="0" border="0">
<tbody>
<tr>
<td><label for="loc-trust"><fmt:message key="ssl.certificates.store-management.file_label"/>:</label></td>
<td><input id="loc-trust" name="loc-trust" type="text" size="80" value="${certificateStoreManager.getTrustStoreConfiguration(connectionType).file}"/></td>
</tr>
<tr>
<td><label for="pwd-trust"><fmt:message key="ssl.certificates.store-management.password_label"/>:</label></td>
<td><input id="pwd-trust" name="pwd-trust" type="password" size="30" value="${pwdTrust}"/></td>
</tr>
<tr>
<td>&nbsp;</td>
<td><a href="security-truststore.jsp?connectionType=${connectionType}"><fmt:message key="ssl.certificates.store-management.manage"/></a></td>
</tr>
</tbody>
</table>
<br/>
<input type="submit" name="update" value="<fmt:message key="global.save_settings" />">
</admin:contentBox>
</form>
</c:forEach> </c:forEach>
......
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