From e290fc8fe50c2cf6e97e0e7b782101da5b5a94dc Mon Sep 17 00:00:00 2001
From: jvergara <jvergara@localhost>
Date: Wed, 05 Nov 2008 00:04:33 +0000
Subject: [PATCH] Fix for issue 3536 ( LDAP entry browser is broken in control panel when SSL or Start TLS are enabled on the server).
---
opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java | 8 +
opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/AbstractBrowseEntriesPanel.java | 201 +++++++++++++++++++++++++++++++++++++++++++++++++
opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/util/BackgroundTask.java | 12 +--
3 files changed, 209 insertions(+), 12 deletions(-)
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/AbstractBrowseEntriesPanel.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/AbstractBrowseEntriesPanel.java
index 6e8bbdc..149bce4 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/AbstractBrowseEntriesPanel.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/AbstractBrowseEntriesPanel.java
@@ -28,6 +28,8 @@
package org.opends.guitools.controlpanel.ui;
import static org.opends.messages.AdminToolMessages.*;
+import static org.opends.messages.QuickSetupMessages.INFO_CERTIFICATE_EXCEPTION;
+import static org.opends.messages.QuickSetupMessages.INFO_NOT_AVAILABLE_LABEL;
import java.awt.Component;
import java.awt.GridBagConstraints;
@@ -39,12 +41,16 @@
import java.awt.event.ItemListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
+import java.net.URI;
+import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.SortedSet;
import java.util.TreeSet;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import javax.naming.NamingException;
import javax.naming.ldap.InitialLdapContext;
@@ -68,6 +74,7 @@
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
+import org.opends.admin.ads.util.ApplicationTrustManager;
import org.opends.admin.ads.util.ConnectionUtils;
import org.opends.guitools.controlpanel.browser.BrowserController;
import org.opends.guitools.controlpanel.datamodel.BackendDescriptor;
@@ -87,6 +94,10 @@
import org.opends.guitools.controlpanel.util.Utilities;
import org.opends.messages.Message;
import org.opends.messages.MessageBuilder;
+import org.opends.quicksetup.UserDataCertificateException;
+import org.opends.quicksetup.ui.CertificateDialog;
+import org.opends.quicksetup.util.UIKeyStore;
+import org.opends.quicksetup.util.Utils;
import org.opends.server.protocols.ldap.LDAPFilter;
import org.opends.server.types.AttributeType;
import org.opends.server.types.AttributeValue;
@@ -129,6 +140,8 @@
private JLabel lNoMatchFound;
+ private InitialLdapContext createdUserDataCtx;
+
/**
* The tree pane contained in this panel.
*/
@@ -183,6 +196,9 @@
"organizationalUnit"
};
+ private static final Logger LOG =
+ Logger.getLogger(AbstractBrowseEntriesPanel.class.getName());
+
/**
* Default constructor.
*
@@ -1188,8 +1204,7 @@
if (getInfo().getUserDataDirContext() == null)
{
InitialLdapContext ctxUserData =
- Utilities.getUserDataDirContext(getInfo(),
- ConnectionUtils.getBindDN(ctx),
+ createUserDataDirContext(ConnectionUtils.getBindDN(ctx),
ConnectionUtils.getBindPassword(ctx));
getInfo().setUserDataDirContext(ctxUserData);
}
@@ -1395,6 +1410,188 @@
}
/**
+ * Creates the context to be used to retrieve user data for some given
+ * credentials.
+ * @param bindDN the bind DN.
+ * @param bindPassword the bind password.
+ * @return the context to be used to retrieve user data for some given
+ * credentials.
+ * @throws NamingException if an error occurs connecting to the server.
+ * @throws ConfigReadException if an error occurs reading the configuration.
+ */
+ private InitialLdapContext createUserDataDirContext(
+ final String bindDN, final String bindPassword)
+ throws NamingException, ConfigReadException
+ {
+ createdUserDataCtx = null;
+ try
+ {
+ createdUserDataCtx = Utilities.getUserDataDirContext(getInfo(),
+ bindDN, bindPassword);
+ }
+ catch (NamingException ne)
+ {
+ if (Utils.isCertificateException(ne))
+ {
+ ApplicationTrustManager.Cause cause =
+ getInfo().getTrustManager().getLastRefusedCause();
+
+ LOG.log(Level.INFO, "Certificate exception cause: "+cause);
+ UserDataCertificateException.Type excType = null;
+ if (cause == ApplicationTrustManager.Cause.NOT_TRUSTED)
+ {
+ excType = UserDataCertificateException.Type.NOT_TRUSTED;
+ }
+ else if (cause ==
+ ApplicationTrustManager.Cause.HOST_NAME_MISMATCH)
+ {
+ excType = UserDataCertificateException.Type.HOST_NAME_MISMATCH;
+ }
+
+ if (excType != null)
+ {
+ String h;
+ int p;
+ try
+ {
+ URI uri = new URI(getInfo().getAdminConnectorURL());
+ h = uri.getHost();
+ p = uri.getPort();
+ }
+ catch (Throwable t)
+ {
+ LOG.log(Level.WARNING,
+ "Error parsing ldap url of ldap url.", t);
+ h = INFO_NOT_AVAILABLE_LABEL.get().toString();
+ p = -1;
+ }
+ final UserDataCertificateException udce =
+ new UserDataCertificateException(null,
+ INFO_CERTIFICATE_EXCEPTION.get(h, String.valueOf(p)),
+ ne, h, p,
+ getInfo().getTrustManager().getLastRefusedChain(),
+ getInfo().getTrustManager().getLastRefusedAuthType(),
+ excType);
+
+ if (SwingUtilities.isEventDispatchThread())
+ {
+ handleCertificateException(udce, bindDN, bindPassword);
+ }
+ else
+ {
+ final ConfigReadException[] fcre = {null};
+ final NamingException[] fne = {null};
+ try
+ {
+ SwingUtilities.invokeAndWait(new Runnable()
+ {
+ public void run()
+ {
+ try
+ {
+ handleCertificateException(udce, bindDN, bindPassword);
+ }
+ catch (ConfigReadException cre)
+ {
+ fcre[0] = cre;
+ }
+ catch (NamingException ne)
+ {
+ fne[0] = ne;
+ }
+ }
+ });
+ }
+ catch (Throwable t)
+ {
+ throw new IllegalArgumentException("Unexpected error: "+t, t);
+ }
+ if (fcre[0] != null)
+ {
+ throw fcre[0];
+ }
+ if (fne[0] != null)
+ {
+ throw fne[0];
+ }
+ }
+ }
+ }
+ else
+ {
+ throw ne;
+ }
+ }
+ return createdUserDataCtx;
+ }
+
+ /**
+ * Displays a dialog asking the user to accept a certificate if the user
+ * accepts it, we update the trust manager and simulate a click on "OK" to
+ * re-check the authentication.
+ * This method assumes that we are being called from the event thread.
+ * @param bindDN the bind DN.
+ * @param bindPassword the bind password.
+ */
+ private void handleCertificateException(UserDataCertificateException ce,
+ String bindDN, String bindPassword)
+ throws NamingException, ConfigReadException
+ {
+ CertificateDialog dlg = new CertificateDialog(null, ce);
+ dlg.pack();
+ Utilities.centerGoldenMean(dlg, Utilities.getParentDialog(this));
+ dlg.setVisible(true);
+ if (dlg.getUserAnswer() !=
+ CertificateDialog.ReturnType.NOT_ACCEPTED)
+ {
+ X509Certificate[] chain = ce.getChain();
+ String authType = ce.getAuthType();
+ String host = ce.getHost();
+
+ if ((chain != null) && (authType != null) && (host != null))
+ {
+ LOG.log(Level.INFO, "Accepting certificate presented by host "+host);
+ getInfo().getTrustManager().acceptCertificate(chain, authType, host);
+ createdUserDataCtx = createUserDataDirContext(bindDN, bindPassword);
+ }
+ else
+ {
+ if (chain == null)
+ {
+ LOG.log(Level.WARNING,
+ "The chain is null for the UserDataCertificateException");
+ }
+ if (authType == null)
+ {
+ LOG.log(Level.WARNING,
+ "The auth type is null for the UserDataCertificateException");
+ }
+ if (host == null)
+ {
+ LOG.log(Level.WARNING,
+ "The host is null for the UserDataCertificateException");
+ }
+ }
+ }
+ if (dlg.getUserAnswer() ==
+ CertificateDialog.ReturnType.ACCEPTED_PERMANENTLY)
+ {
+ X509Certificate[] chain = ce.getChain();
+ if (chain != null)
+ {
+ try
+ {
+ UIKeyStore.acceptCertificate(chain);
+ }
+ catch (Throwable t)
+ {
+ LOG.log(Level.WARNING, "Error accepting certificate: "+t, t);
+ }
+ }
+ }
+ }
+
+ /**
* This class is used simply to avoid an inset on the left for the
* 'All Base DNs' item.
* Since this item is a CategorizedComboBoxElement of type
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java
index 935bf73..647e5af 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/ui/BrowseEntriesPanel.java
@@ -52,6 +52,7 @@
import java.util.ArrayList;
import java.util.LinkedHashSet;
+import javax.naming.InterruptedNamingException;
import javax.naming.ldap.InitialLdapContext;
import javax.swing.ButtonGroup;
import javax.swing.JComponent;
@@ -522,8 +523,11 @@
}
catch (Throwable t)
{
- EntryReadErrorEvent ev = new EntryReadErrorEvent(this, dn, t);
- entryPane.entryReadError(ev);
+ if (!(t instanceof InterruptedNamingException))
+ {
+ EntryReadErrorEvent ev = new EntryReadErrorEvent(this, dn, t);
+ entryPane.entryReadError(ev);
+ }
}
}
else
diff --git a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/util/BackgroundTask.java b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/util/BackgroundTask.java
index bb019f5..acb4a79 100644
--- a/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/util/BackgroundTask.java
+++ b/opendj-sdk/opends/src/guitools/org/opends/guitools/controlpanel/util/BackgroundTask.java
@@ -36,6 +36,7 @@
public abstract class BackgroundTask<T>
{
private BackgroundTaskThread<T> taskThread;
+ private boolean interrupted;
/**
* Creates a new thread and begins running the task in the background. When
* the task has completed, the {@code backgroundTaskCompleted} method will be
@@ -43,6 +44,7 @@
*/
public final void startBackgroundTask()
{
+ interrupted = false;
taskThread = new BackgroundTaskThread<T>(this);
taskThread.start();
}
@@ -53,6 +55,7 @@
*/
public final void interrupt()
{
+ interrupted = true;
if (taskThread != null)
{
taskThread.interrupt();
@@ -67,14 +70,7 @@
*/
public boolean isInterrupted()
{
- if (taskThread != null)
- {
- return taskThread.isInterrupted();
- }
- else
- {
- return false;
- }
+ return interrupted;
}
/**
--
Gitblit v1.10.0