Commit 8e4db474 authored by Gaston Dombiak's avatar Gaston Dombiak Committed by gato

1) Added control over certification validation (including UI)

2) Improved CS setup to expose information about error preventing the connection

git-svn-id: http://svn.igniterealtime.org/svn/repos/openfire/trunk@10492 b35dd754-fafc-0310-a699-88a17e54d16e
parent e330966a
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
package org.jivesoftware.openfire.clearspace; package org.jivesoftware.openfire.clearspace;
import org.apache.commons.httpclient.*; import org.apache.commons.httpclient.*;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;
import org.apache.commons.httpclient.auth.AuthScope; import org.apache.commons.httpclient.auth.AuthScope;
import org.apache.commons.httpclient.methods.*; import org.apache.commons.httpclient.methods.*;
import org.dom4j.*; import org.dom4j.*;
...@@ -226,6 +228,10 @@ public class ClearspaceManager extends BasicModule implements ExternalComponentM ...@@ -226,6 +228,10 @@ public class ClearspaceManager extends BasicModule implements ExternalComponentM
} }
private void init() { private void init() {
// Register the trust manager to use when using HTTPS
Protocol easyhttps = new Protocol("https", (ProtocolSocketFactory) new SSLProtocolSocketFactory(this), 443);
Protocol.registerProtocol("https", easyhttps);
// Convert XML based provider setup to Database based // Convert XML based provider setup to Database based
JiveGlobals.migrateProperty("clearspace.uri"); JiveGlobals.migrateProperty("clearspace.uri");
JiveGlobals.migrateProperty("clearspace.sharedSecret"); JiveGlobals.migrateProperty("clearspace.sharedSecret");
...@@ -331,20 +337,19 @@ public class ClearspaceManager extends BasicModule implements ExternalComponentM ...@@ -331,20 +337,19 @@ public class ClearspaceManager extends BasicModule implements ExternalComponentM
* *
* @return True if connection test was successful. * @return True if connection test was successful.
*/ */
public Boolean testConnection() { public Throwable testConnection() {
// Test invoking a simple method // Test invoking a simple method
try { try {
// If there is a problem with the URL or the user/password this service throws an exception // If there is a problem with the URL or the user/password this service throws an exception
String path = IM_URL_PREFIX + "testCredentials"; String path = IM_URL_PREFIX + "testCredentials";
executeRequest(GET, path); executeRequest(GET, path);
return true; return null;
} catch (Exception e) { } catch (Exception e) {
// It is not ok, return false. // It is not ok, return false.
Log.warn("Failed testing communicating with Clearspace" , e); Log.warn("Failed testing communicating with Clearspace" , e);
return e.getCause();
} }
return false;
} }
/** /**
...@@ -355,7 +360,7 @@ public class ClearspaceManager extends BasicModule implements ExternalComponentM ...@@ -355,7 +360,7 @@ public class ClearspaceManager extends BasicModule implements ExternalComponentM
* @return true if Openfire is connected to Clearspace. * @return true if Openfire is connected to Clearspace.
*/ */
public Boolean isOpenfireConnected() { public Boolean isOpenfireConnected() {
return testConnection(); return testConnection() == null;
} }
/** /**
...@@ -378,6 +383,11 @@ public class ClearspaceManager extends BasicModule implements ExternalComponentM ...@@ -378,6 +383,11 @@ public class ClearspaceManager extends BasicModule implements ExternalComponentM
} }
return false; return false;
} }
public Map<String, String> getProperties() {
return properties;
}
/** /**
* Returns the Clearspace service URI; e.g. <tt>https://localhost:80/clearspace</tt>. * Returns the Clearspace service URI; e.g. <tt>https://localhost:80/clearspace</tt>.
* This value is stored as the Jive Property <tt>clearspace.uri</tt>. * This value is stored as the Jive Property <tt>clearspace.uri</tt>.
...@@ -816,7 +826,9 @@ public class ClearspaceManager extends BasicModule implements ExternalComponentM ...@@ -816,7 +826,9 @@ public class ClearspaceManager extends BasicModule implements ExternalComponentM
// Checks the http status // Checks the http status
if (method.getStatusCode() != 200) { if (method.getStatusCode() != 200) {
throw new ConnectException("Error connecting to Clearspace, http status code: " + method.getStatusCode()); throw new ConnectException(
"Error connecting to Clearspace, http status code: " + method.getStatusCode(),
new HTTPConnectionException(method.getStatusCode()));
} }
Element response = localParser.get().parseDocument(body).getRootElement(); Element response = localParser.get().parseDocument(body).getRootElement();
......
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2005-2008 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution, or a commercial license
* agreement with Jive.
*/
package org.jivesoftware.openfire.clearspace;
import java.security.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.List;
import java.util.Date;
import java.util.Enumeration;
import java.util.Map;
import javax.net.ssl.X509TrustManager;
import org.jivesoftware.util.JiveGlobals;
import org.jivesoftware.util.CertificateManager;
import org.jivesoftware.util.Log;
/**
* Trust manager that validates Clearspace certificates. Using system properties
* it is possible to disable or enabled certain validations. By default all validations
* are enabled and self-signed certificated are not accepted.
*
* @author Gaston Dombiak
*/
public class ClearspaceX509TrustManager implements X509TrustManager {
/**
* KeyStore that holds the trusted CA
*/
private KeyStore trustStore;
private String server;
private Map<String, String> properties;
public ClearspaceX509TrustManager(String server, Map<String, String> properties, KeyStore keystore) throws NoSuchAlgorithmException, KeyStoreException {
super();
this.server = server;
this.trustStore = keystore;
this.properties = properties;
}
/**
* @see javax.net.ssl.X509TrustManager#checkClientTrusted(X509Certificate[],String authType)
*/
public void checkClientTrusted(X509Certificate[] certificates, String authType) throws CertificateException {
// Do nothing. We are the client so we are not testing certificates from clients
}
/**
* @see javax.net.ssl.X509TrustManager#checkServerTrusted(X509Certificate[],String authType)
*/
public void checkServerTrusted(X509Certificate[] x509Certificates, String authType) throws CertificateException {
// Flag that indicates if certificates of the remote server should be validated. Disabling
// certificate validation is not recommended for production environments.
boolean verify = getBooleanProperty("clearspace.certificate.verify", true);
if (verify) {
int nSize = x509Certificates.length;
List<String> peerIdentities = CertificateManager.getPeerIdentities(x509Certificates[0]);
if (getBooleanProperty("clearspace.certificate.verify.chain", true)) {
// Working down the chain, for every certificate in the chain,
// verify that the subject of the certificate is the issuer of the
// next certificate in the chain.
Principal principalLast = null;
for (int i = nSize -1; i >= 0 ; i--) {
X509Certificate x509certificate = x509Certificates[i];
Principal principalIssuer = x509certificate.getIssuerDN();
Principal principalSubject = x509certificate.getSubjectDN();
if (principalLast != null) {
if (principalIssuer.equals(principalLast)) {
try {
PublicKey publickey =
x509Certificates[i + 1].getPublicKey();
x509Certificates[i].verify(publickey);
}
catch (GeneralSecurityException generalsecurityexception) {
throw new CertificateException(
"signature verification failed of " + peerIdentities);
}
}
else {
throw new CertificateException(
"subject/issuer verification failed of " + peerIdentities);
}
}
principalLast = principalSubject;
}
}
if (getBooleanProperty("clearspace.certificate.verify.root", true)) {
// Verify that the the last certificate in the chain was issued
// by a third-party that the client trusts.
boolean trusted = false;
try {
trusted = trustStore.getCertificateAlias(x509Certificates[nSize - 1]) != null;
if (!trusted && nSize == 1 && JiveGlobals
.getBooleanProperty("clearspace.certificate.accept-selfsigned", false))
{
Log.warn("Accepting self-signed certificate of remote server: " +
peerIdentities);
trusted = true;
}
}
catch (KeyStoreException e) {
Log.error(e);
}
if (!trusted) {
throw new CertificateException("root certificate not trusted of " + peerIdentities);
}
}
if (getBooleanProperty("clearspace.certificate.verify.identity", false)) {
// Verify that the first certificate in the chain corresponds to
// the server we desire to authenticate.
// Check if the certificate uses a wildcard indicating that subdomains are valid
if (peerIdentities.size() == 1 && peerIdentities.get(0).startsWith("*.")) {
// Remove the wildcard
String peerIdentity = peerIdentities.get(0).replace("*.", "");
// Check if the requested subdomain matches the certified domain
if (!server.endsWith(peerIdentity)) {
throw new CertificateException("target verification failed of " + peerIdentities);
}
}
else if (!peerIdentities.contains(server)) {
throw new CertificateException("target verification failed of " + peerIdentities);
}
}
if (getBooleanProperty("clearspace.certificate.verify.validity", true)) {
// For every certificate in the chain, verify that the certificate
// is valid at the current time.
Date date = new Date();
for (int i = 0; i < nSize; i++) {
try {
x509Certificates[i].checkValidity(date);
}
catch (GeneralSecurityException generalsecurityexception) {
throw new CertificateException("invalid date of " + peerIdentities);
}
}
}
}
}
private boolean getBooleanProperty(String key, boolean defaultValue) {
String value = properties.get(key);
return value != null ? Boolean.parseBoolean(value) : defaultValue;
}
/**
* @see javax.net.ssl.X509TrustManager#getAcceptedIssuers()
*/
public X509Certificate[] getAcceptedIssuers() {
if (getBooleanProperty("clearspace.certificate.accept-selfsigned", false)) {
// Answer an empty list since we accept any issuer
return new X509Certificate[0];
}
else {
X509Certificate[] X509Certs = null;
try {
// See how many certificates are in the keystore.
int numberOfEntry = trustStore.size();
// If there are any certificates in the keystore.
if (numberOfEntry > 0) {
// Create an array of X509Certificates
X509Certs = new X509Certificate[numberOfEntry];
// Get all of the certificate alias out of the keystore.
Enumeration aliases = trustStore.aliases();
// Retrieve all of the certificates out of the keystore
// via the alias name.
int i = 0;
while (aliases.hasMoreElements()) {
X509Certs[i] =
(X509Certificate) trustStore.
getCertificate((String) aliases.nextElement());
i++;
}
}
}
catch (Exception e) {
Log.error(e);
X509Certs = null;
}
return X509Certs;
}
}
}
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2005-2008 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution, or a commercial license
* agreement with Jive.
*/
package org.jivesoftware.openfire.clearspace;
import java.io.IOException;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.UnknownHostException;
import org.apache.commons.httpclient.ConnectTimeoutException;
import org.apache.commons.httpclient.HttpClientError;
import org.apache.commons.httpclient.params.HttpConnectionParams;
import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;
import org.jivesoftware.openfire.net.SSLConfig;
import org.jivesoftware.util.Log;
import javax.net.SocketFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
/**
* Implementation of SecureProtocolSocketFactory that will use a custom trust manager for
* certification validation.
*
* @author Gaston Dombiak
*/
public class SSLProtocolSocketFactory implements SecureProtocolSocketFactory {
private SSLContext sslcontext = null;
private ClearspaceManager manager;
/**
* Constructor for EasySSLProtocolSocketFactory.
*/
public SSLProtocolSocketFactory(ClearspaceManager manager) {
super();
this.manager = manager;
}
private SSLContext createSSLContext(String host) {
try {
SSLContext context = SSLContext.getInstance("SSL");
context.init(
null,
new TrustManager[]{new ClearspaceX509TrustManager(host, manager.getProperties(), SSLConfig.gets2sTrustStore())},
null);
return context;
} catch (Exception e) {
Log.error(e.getMessage(), e);
throw new HttpClientError(e.toString());
}
}
private SSLContext getSSLContext(String host) {
if (this.sslcontext == null) {
this.sslcontext = createSSLContext(host);
}
return this.sslcontext;
}
/**
* @see SecureProtocolSocketFactory#createSocket(java.lang.String,int,java.net.InetAddress,int)
*/
public Socket createSocket(
String host,
int port,
InetAddress clientHost,
int clientPort)
throws IOException, UnknownHostException {
return getSSLContext(host).getSocketFactory().createSocket(
host,
port,
clientHost,
clientPort
);
}
/**
* Attempts to get a new socket connection to the given host within the given time limit.
* <p>
* To circumvent the limitations of older JREs that do not support connect timeout a
* controller thread is executed. The controller thread attempts to create a new socket
* within the given limit of time. If socket constructor does not return until the
* timeout expires, the controller terminates and throws an {@link ConnectTimeoutException}
* </p>
*
* @param host the host name/IP
* @param port the port on the host
* @param localAddress the local host name/IP to bind the socket to
* @param localPort the port on the local machine
* @param params {@link HttpConnectionParams Http connection parameters}
* @return Socket a new socket
* @throws IOException if an I/O error occurs while creating the socket
* @throws UnknownHostException if the IP address of the host cannot be
* determined
*/
public Socket createSocket(
final String host,
final int port,
final InetAddress localAddress,
final int localPort,
final HttpConnectionParams params
) throws IOException, UnknownHostException, ConnectTimeoutException {
if (params == null) {
throw new IllegalArgumentException("Parameters may not be null");
}
int timeout = params.getConnectionTimeout();
SocketFactory socketfactory = getSSLContext(host).getSocketFactory();
if (timeout == 0) {
return socketfactory.createSocket(host, port, localAddress, localPort);
}
else {
Socket socket = socketfactory.createSocket();
SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);
SocketAddress remoteaddr = new InetSocketAddress(host, port);
socket.bind(localaddr);
socket.connect(remoteaddr, timeout);
return socket;
}
}
/**
* @see org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory#createSocket(java.lang.String,int)
*/
public Socket createSocket(String host, int port)
throws IOException, UnknownHostException {
return getSSLContext(host).getSocketFactory().createSocket(
host,
port
);
}
/**
* @see org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory#createSocket(java.net.Socket,java.lang.String,int,boolean)
*/
public Socket createSocket(
Socket socket,
String host,
int port,
boolean autoClose)
throws IOException, UnknownHostException {
return getSSLContext(host).getSocketFactory().createSocket(
socket,
host,
port,
autoClose
);
}
public boolean equals(Object obj) {
return ((obj != null) && obj.getClass().equals(SSLProtocolSocketFactory.class));
}
public int hashCode() {
return SSLProtocolSocketFactory.class.hashCode();
}
}
/**
* $RCSfile$
* $Revision$
* $Date$
*
* Copyright (C) 2005-2008 Jive Software. All rights reserved.
*
* This software is published under the terms of the GNU Public License (GPL),
* a copy of which is included in this distribution, or a commercial license
* agreement with Jive.
*/
package org.jivesoftware.util;
/**
* Exception class that wraps an HTTP error code.
*
* @author Gaston Dombiak
*/
public class HTTPConnectionException extends Exception {
private int errorCode;
public HTTPConnectionException(int errorCode) {
super();
this.errorCode = errorCode;
}
public int getErrorCode() {
return errorCode;
}
public String getMessage() {
if (errorCode == 400) {
return "400 Bad Request";
}
else if (errorCode == 401) {
return "401 Unauthorized";
}
else if (errorCode == 402) {
return "402 Payment Required";
}
else if (errorCode == 403) {
return "403 Forbidden";
}
else if (errorCode == 404) {
return "404 Not Found";
}
else if (errorCode == 405) {
return "405 Method Not Allowed";
}
else if (errorCode == 406) {
return "406 Not Acceptable";
}
else if (errorCode == 407) {
return "407 Proxy Authentication Required";
}
else if (errorCode == 408) {
return "408 Request Timeout";
}
else if (errorCode == 409) {
return "409 Conflict";
}
else if (errorCode == 410) {
return "410 Gone";
}
else if (errorCode == 411) {
return "411 Length Required";
}
else if (errorCode == 412) {
return "412 Precondition Failed";
}
else if (errorCode == 413) {
return "413 Request Entity Too Large";
}
else if (errorCode == 414) {
return "414 Request-URI Too Long";
}
else if (errorCode == 415) {
return "415 Unsupported Media Type";
}
else if (errorCode == 416) {
return "416 Requested Range Not Satisfiable";
}
else if (errorCode == 418) {
return "417 Expectation Failed";
}
return "Unknown HTTP error code: " + errorCode;
}
}
...@@ -10,13 +10,20 @@ ...@@ -10,13 +10,20 @@
String uri; String uri;
String sharedSecret; String sharedSecret;
boolean verifyChain = JiveGlobals.getBooleanProperty("clearspace.certificate.verify.chain", true);
boolean verifyRoot = JiveGlobals.getBooleanProperty("clearspace.certificate.verify.root", true);
boolean selfSigned = JiveGlobals.getBooleanProperty("clearspace.certificate.accept-selfsigned", false);
boolean verifyIdentity = JiveGlobals.getBooleanProperty("clearspace.certificate.verify.identity", false);
boolean verifyValidity = JiveGlobals.getBooleanProperty("clearspace.certificate.verify.validity", true);
// Get parameters // Get parameters
boolean save = request.getParameter("save") != null; boolean save = request.getParameter("save") != null;
boolean test = request.getParameter("test") != null; boolean test = request.getParameter("test") != null;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
Map<String,String> xmppSettings = (Map<String,String>)session.getAttribute("xmppSettings"); Map<String,String> xmppSettings = (Map<String,String>)session.getAttribute("xmppSettings");
ClearspaceManager manager = null; ClearspaceManager manager;
if (ClearspaceManager.getInstance() != null) { if (ClearspaceManager.getInstance() != null) {
// Use the existing manager. This will be the case after setup was completed // Use the existing manager. This will be the case after setup was completed
manager = ClearspaceManager.getInstance(); manager = ClearspaceManager.getInstance();
...@@ -36,11 +43,22 @@ ...@@ -36,11 +43,22 @@
errors.put("secret", LocaleUtils.getLocalizedString("setup.clearspace.service.secret_error")); errors.put("secret", LocaleUtils.getLocalizedString("setup.clearspace.service.secret_error"));
} }
verifyChain = ParamUtils.getBooleanParameter(request, "verifyChain", verifyChain);
verifyRoot = ParamUtils.getBooleanParameter(request, "verifyRoot", verifyRoot);
selfSigned = ParamUtils.getBooleanParameter(request, "selfSigned", selfSigned);
verifyIdentity = ParamUtils.getBooleanParameter(request, "verifyIdentity", verifyIdentity);
verifyValidity = ParamUtils.getBooleanParameter(request, "verifyValidity", verifyValidity);
if (errors.isEmpty()) { if (errors.isEmpty()) {
// Store settings in a map and keep it in the session // Store settings in a map and keep it in the session
Map<String, String> settings = new HashMap<String, String>(); Map<String, String> settings = new HashMap<String, String>();
settings.put("clearspace.uri", uri); settings.put("clearspace.uri", uri);
settings.put("clearspace.sharedSecret", sharedSecret); settings.put("clearspace.sharedSecret", sharedSecret);
settings.put("clearspace.certificate.verify.chain", Boolean.toString(verifyChain));
settings.put("clearspace.certificate.verify.root", Boolean.toString(verifyRoot));
settings.put("clearspace.certificate.accept-selfsigned", Boolean.toString(selfSigned));
settings.put("clearspace.certificate.verify.identity", Boolean.toString(verifyIdentity));
settings.put("clearspace.certificate.verify.validity", Boolean.toString(verifyValidity));
session.setAttribute("clearspaceSettings", settings); session.setAttribute("clearspaceSettings", settings);
if (save) { if (save) {
...@@ -64,6 +82,13 @@ ...@@ -64,6 +82,13 @@
JiveGlobals.setProperty("provider.admin.className", JiveGlobals.setProperty("provider.admin.className",
"org.jivesoftware.openfire.clearspace.ClearspaceAdminProvider"); "org.jivesoftware.openfire.clearspace.ClearspaceAdminProvider");
// Set configuration for certificate validation
JiveGlobals.setProperty("clearspace.certificate.verify.chain", Boolean.toString(verifyChain));
JiveGlobals.setProperty("clearspace.certificate.verify.root", Boolean.toString(verifyRoot));
JiveGlobals.setProperty("clearspace.certificate.accept-selfsigned", Boolean.toString(selfSigned));
JiveGlobals.setProperty("clearspace.certificate.verify.identity", Boolean.toString(verifyIdentity));
JiveGlobals.setProperty("clearspace.certificate.verify.validity", Boolean.toString(verifyValidity));
// Save the settings for later, if we're in setup // Save the settings for later, if we're in setup
if (xmppSettings != null) { if (xmppSettings != null) {
xmppSettings.put("provider.auth.className", xmppSettings.put("provider.auth.className",
...@@ -184,6 +209,101 @@ ...@@ -184,6 +209,101 @@
</div> </div>
<!-- END jive-contentBox_bluebox --> <!-- END jive-contentBox_bluebox -->
<!-- BEGIN jiveAdvancedButton -->
<div class="jiveAdvancedButton">
<a href="#" onclick="togglePanel(jiveAdvanced); return false;" id="jiveAdvancedLink"><fmt:message key="setup.clearspace.service.advanced" /></a>
</div>
<!-- END jiveAdvancedButton -->
<!-- BEGIN jiveAdvancedPanelcs (advanced connection settings) -->
<div class="jiveadvancedPanelcs" id="jiveAdvanced" style="display: none;">
<div>
<table border="0" cellpadding="0" cellspacing="1">
<thead>
<tr>
<th width="10%"></th>
<th></th>
<th width="50"><fmt:message key="global.yes" /></th>
<th width="50"><fmt:message key="global.no" /></th>
</tr>
</thead>
<tbody>
<tr>
<td class="jive-advancedLabel" nowrap>
<fmt:message key="setup.clearspace.service.certificate.verify.chain" />:
</td>
<td class="jive-advancedDesc jive-advancedBorderBottom jive-advancedBorderRight">
<fmt:message key="setup.clearspace.service.certificate.verify.chain_help" />
</td>
<td class="jive-advancedBorderBottom jive-advancedBorderRight" align="center">
<input type="radio" name="verifyChain" value="true" <% if (verifyChain) { %>checked <% } %>>
</td>
<td class="jive-advancedBorderBottom" align="center">
<input type="radio" name="verifyChain" value="false" <% if (!verifyChain) { %>checked <% } %>>
</td>
</tr>
<tr>
<td class="jive-advancedLabel" nowrap>
<fmt:message key="setup.clearspace.service.certificate.verify.root" />:
</td>
<td class="jive-advancedDesc jive-advancedBorderBottom jive-advancedBorderRight">
<fmt:message key="setup.clearspace.service.certificate.verify.root_help" />
</td>
<td class="jive-advancedBorderBottom jive-advancedBorderRight" align="center">
<input type="radio" name="verifyRoot" value="true" <% if (verifyRoot) { %>checked <% } %>>
</td>
<td class="jive-advancedBorderBottom" align="center">
<input type="radio" name="verifyRoot" value="false" <% if (!verifyRoot) { %>checked <% } %>>
</td>
</tr>
<tr>
<td class="jive-advancedLabel" nowrap>
<fmt:message key="setup.clearspace.service.certificate.accept-selfsigned" />:
</td>
<td class="jive-advancedDesc jive-advancedBorderBottom jive-advancedBorderRight">
<fmt:message key="setup.clearspace.service.certificate.accept-selfsigned_help" />
</td>
<td class="jive-advancedBorderBottom jive-advancedBorderRight" align="center">
<input type="radio" name="selfSigned" value="true" <% if (selfSigned) { %>checked <% } %>>
</td>
<td class="jive-advancedBorderBottom" align="center">
<input type="radio" name="selfSigned" value="false" <% if (!selfSigned) { %>checked <% } %>>
</td>
</tr>
<tr>
<td class="jive-advancedLabel" nowrap>
<fmt:message key="setup.clearspace.service.certificate.verify.identity" />:
</td>
<td class="jive-advancedDesc jive-advancedBorderBottom jive-advancedBorderRight">
<fmt:message key="setup.clearspace.service.certificate.verify.identity_help" />
</td>
<td class="jive-advancedBorderBottom jive-advancedBorderRight" align="center">
<input type="radio" name="verifyIdentity" value="true" <% if (verifyIdentity) { %>checked <% } %>>
</td>
<td class="jive-advancedBorderBottom" align="center">
<input type="radio" name="verifyIdentity" value="false" <% if (!verifyIdentity) { %>checked <% } %>>
</td>
</tr>
<tr>
<td class="jive-advancedLabel" nowrap>
<fmt:message key="setup.clearspace.service.certificate.verify.validity" />:
</td>
<td class="jive-advancedDesc jive-advancedBorderBottom jive-advancedBorderRight">
<fmt:message key="setup.clearspace.service.certificate.verify.validity_help" />
</td>
<td class="jive-advancedBorderBottom jive-advancedBorderRight" align="center">
<input type="radio" name="verifyValidity" value="true" <% if (verifyValidity) { %>checked <% } %>>
</td>
<td class="jive-advancedBorderBottom" align="center">
<input type="radio" name="verifyValidity" value="false" <% if (!verifyValidity) { %>checked <% } %>>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<!-- END jiveAdvancedPanelcs (advanced connection settings) -->
<!-- BEGIN jive-buttons --> <!-- BEGIN jive-buttons -->
<div class="jive-buttons"> <div class="jive-buttons">
......
<%@ page import="org.jivesoftware.util.LocaleUtils" %> <%@ page import="org.jivesoftware.util.LocaleUtils" %>
<%@ page import="java.util.Map" %> <%@ page import="java.util.Map" %>
<%@ page import="org.jivesoftware.openfire.clearspace.ClearspaceManager" %> <%@ page import="org.jivesoftware.openfire.clearspace.ClearspaceManager" %>
<%@ page import="java.net.UnknownHostException" %>
<%@ page import="javax.net.ssl.SSLException" %>
<%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %> <%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %>
<%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %> <%@ taglib uri="http://java.sun.com/jstl/fmt_rt" prefix="fmt" %>
<% <%
boolean success = false; boolean success = false;
Throwable exception = null;
String errorDetail = ""; String errorDetail = "";
String exceptionDetail = "";
Map<String, String> settings = (Map<String, String>) session.getAttribute("clearspaceSettings"); Map<String, String> settings = (Map<String, String>) session.getAttribute("clearspaceSettings");
if (settings != null) { if (settings != null) {
ClearspaceManager manager = new ClearspaceManager(settings); ClearspaceManager manager = new ClearspaceManager(settings);
if (manager.testConnection()) { exception = manager.testConnection();
if (exception == null) {
success = true; success = true;
} }
else { else {
errorDetail = LocaleUtils.getLocalizedString("setup.clearspace.service.test.error-connection"); errorDetail = LocaleUtils.getLocalizedString("setup.clearspace.service.test.error-connection");
if (exception instanceof UnknownHostException) {
exceptionDetail = exception.toString();
}
else {
exceptionDetail = exception.getMessage();
}
} }
} }
%> %>
...@@ -36,6 +47,8 @@ ...@@ -36,6 +47,8 @@
<% } else { %> <% } else { %>
<h4 class="jive-testError"><fmt:message key="setup.clearspace.service.test.status-error" /></h4> <h4 class="jive-testError"><fmt:message key="setup.clearspace.service.test.status-error" /></h4>
<p><%= errorDetail %></p> <p><%= errorDetail %></p>
<p><b><fmt:message key="setup.clearspace.service.test.error-detail" /></b></p>
<p><%= exceptionDetail %></p>
<% } %> <% } %>
</div> </div>
......
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