From 7e6a2d6cd3a9b95acb001a3f37437893067bca27 Mon Sep 17 00:00:00 2001
From: jvergara <jvergara@localhost>
Date: Mon, 30 Jul 2007 15:53:44 +0000
Subject: [PATCH] The following modifications are done in order to be able to handle properly secure connections in both the status command-line and the status panel. Some options to specify a keystore, a trustore, etc. have been added to the status command-line so that is consistent with the other command-lines that use LDAP. As for these command-lines if the user does not specify to use Start TLS or LDAPS, the command-line will try to use LDAP to connect. But if there is no LDAP port enabled, the command-line will try to connect to the LDAPS port.
---
opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ui/LoginDialog.java | 270 ++++++++++++++++++++++++++++++++++++++++++++++++-----
1 files changed, 244 insertions(+), 26 deletions(-)
diff --git a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ui/LoginDialog.java b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ui/LoginDialog.java
index 4388dd8..56ef2c9 100644
--- a/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ui/LoginDialog.java
+++ b/opendj-sdk/opends/src/statuspanel/org/opends/statuspanel/ui/LoginDialog.java
@@ -32,9 +32,13 @@
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
+import java.net.URI;
+import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
import javax.naming.NamingException;
import javax.naming.directory.SearchControls;
@@ -46,16 +50,23 @@
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
import javax.swing.text.JTextComponent;
+import org.opends.admin.ads.util.ApplicationTrustManager;
import org.opends.quicksetup.Installation;
+import org.opends.quicksetup.Step;
+import org.opends.quicksetup.UserDataCertificateException;
import org.opends.quicksetup.event.MinimumSizeComponentListener;
+import org.opends.quicksetup.ui.CertificateDialog;
import org.opends.quicksetup.ui.UIFactory;
import org.opends.quicksetup.ui.Utilities;
import org.opends.quicksetup.util.BackgroundTask;
import org.opends.quicksetup.util.Utils;
+import org.opends.statuspanel.ConfigException;
import org.opends.statuspanel.ConfigFromFile;
+import org.opends.statuspanel.ConnectionProtocolPolicy;
import org.opends.statuspanel.i18n.ResourceProvider;
/**
@@ -65,7 +76,7 @@
*/
public class LoginDialog extends JDialog
{
- private static final long serialVersionUID = 9049409381101152000L;
+ private static final long serialVersionUID = 9049606381601152500L;
private JFrame parent;
@@ -82,16 +93,35 @@
private ConfigFromFile conf;
+ private ApplicationTrustManager trustManager;
+ private ConnectionProtocolPolicy policy;
+
+ private String usedUrl;
+
+ private static final Logger LOG =
+ Logger.getLogger(LoginDialog.class.getName());
+
/**
* Constructor of the LoginDialog.
* @param parent the parent frame for this dialog.
+ * @param trustManager the trust manager to be used for the secure
+ * connections.
+ * @param policy the configuration policy to be used (whether we prefer the
+ * most secure, the less secure, a specific method...).
*/
- public LoginDialog(JFrame parent)
+ public LoginDialog(JFrame parent, ApplicationTrustManager trustManager,
+ ConnectionProtocolPolicy policy)
{
super(parent);
setTitle(getMsg("login-dialog-title"));
this.parent = parent;
getContentPane().add(createPanel());
+ if (trustManager == null)
+ {
+ throw new IllegalArgumentException("The trustmanager cannot be null.");
+ }
+ this.trustManager = trustManager;
+ this.policy = policy;
/*
* TODO: find a way to calculate this dynamically. This is done to avoid
* all the text in a single line.
@@ -331,16 +361,97 @@
InitialLdapContext ctx = null;
try
{
- String ldapUrl = getLDAPURL();
-
- if (ldapUrl != null)
+ String ldapUrl = getConfig().getLDAPURL();
+ String startTlsUrl = getConfig().getStartTLSURL();
+ String ldapsUrl = getConfig().getLDAPSURL();
+ switch (policy)
{
- ctx = Utils.createLdapContext(ldapUrl, tfDn.getText(),
- tfPwd.getText(), Utils.getDefaultLDAPTimeout(), null);
- }
- else
- {
- throw new Error("could-not-find-valid-ldapurl");
+ case USE_STARTTLS:
+ if (startTlsUrl != null)
+ {
+ usedUrl = startTlsUrl;
+ ctx = Utils.createStartTLSContext(startTlsUrl, tfDn.getText(),
+ tfPwd.getText(), Utils.getDefaultLDAPTimeout(), null,
+ getTrustManager(), null);
+ }
+ else
+ {
+ throw new ConfigException(getMsg("could-not-find-valid-ldapurl"));
+ }
+ break;
+ case USE_LDAPS:
+ if (ldapsUrl != null)
+ {
+ usedUrl = ldapsUrl;
+ ctx = Utils.createLdapsContext(ldapsUrl, tfDn.getText(),
+ tfPwd.getText(), Utils.getDefaultLDAPTimeout(), null,
+ getTrustManager());
+ }
+ else
+ {
+ throw new ConfigException(getMsg("could-not-find-valid-ldapurl"));
+ }
+ break;
+ case USE_LDAP:
+ if (ldapUrl != null)
+ {
+ usedUrl = ldapUrl;
+ ctx = Utils.createLdapContext(ldapUrl, tfDn.getText(),
+ tfPwd.getText(), Utils.getDefaultLDAPTimeout(), null);
+ }
+ else
+ {
+ throw new ConfigException(getMsg("could-not-find-valid-ldapurl"));
+ }
+ break;
+ case USE_MOST_SECURE_AVAILABLE:
+ if (ldapsUrl != null)
+ {
+ usedUrl = ldapsUrl;
+ ctx = Utils.createLdapsContext(ldapsUrl, tfDn.getText(),
+ tfPwd.getText(), Utils.getDefaultLDAPTimeout(), null,
+ getTrustManager());
+ }
+ else if (startTlsUrl != null)
+ {
+ usedUrl = startTlsUrl;
+ ctx = Utils.createStartTLSContext(startTlsUrl, tfDn.getText(),
+ tfPwd.getText(), Utils.getDefaultLDAPTimeout(), null,
+ getTrustManager(), null);
+ }
+ else if (ldapUrl != null)
+ {
+ usedUrl = ldapUrl;
+ ctx = Utils.createLdapContext(ldapUrl, tfDn.getText(),
+ tfPwd.getText(), Utils.getDefaultLDAPTimeout(), null);
+ }
+ else
+ {
+ throw new ConfigException(getMsg("could-not-find-valid-ldapurl"));
+ }
+ break;
+ case USE_LESS_SECURE_AVAILABLE:
+ if (ldapUrl != null)
+ {
+ usedUrl = ldapUrl;
+ ctx = Utils.createLdapContext(ldapUrl, tfDn.getText(),
+ tfPwd.getText(), Utils.getDefaultLDAPTimeout(), null);
+ }
+ else if (ldapsUrl != null)
+ {
+ usedUrl = ldapsUrl;
+ ctx = Utils.createLdapsContext(ldapsUrl, tfDn.getText(),
+ tfPwd.getText(), Utils.getDefaultLDAPTimeout(), null,
+ getTrustManager());
+ }
+ else
+ {
+ throw new ConfigException(getMsg("could-not-find-valid-ldapurl"));
+ }
+ break;
+ default:
+ throw new IllegalStateException("Unknown connection policy: "+
+ policy);
}
/*
@@ -361,6 +472,9 @@
throw ne;
}
isServerRunning = Boolean.FALSE;
+ } catch (Error e)
+ {
+ throw e;
} catch (IllegalStateException ise)
{
throw ise;
@@ -369,8 +483,9 @@
{
throw new IllegalStateException("Unexpected throwable.", t);
}
- if (ctx != null)
+ finally
{
+ if (ctx != null)
try
{
ctx.close();
@@ -387,7 +502,59 @@
{
if (throwable != null)
{
- if (throwable instanceof NamingException)
+ LOG.log(Level.INFO, "Error connecting: " + throwable, throwable);
+ if (Utils.isCertificateException(throwable))
+ {
+ ApplicationTrustManager.Cause cause =
+ trustManager.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;
+ }
+ else
+ {
+ String msg = Utils.getThrowableMsg(getI18n(),
+ "error-connecting-to-local", null, throwable);
+ displayError(msg, getMsg("error-title"));
+ }
+
+ if (excType != null)
+ {
+ String h;
+ int p;
+ try
+ {
+ URI uri = new URI(usedUrl);
+ h = uri.getHost();
+ p = uri.getPort();
+ }
+ catch (Throwable t)
+ {
+ LOG.log(Level.WARNING,
+ "Error parsing ldap url of ldap url.", t);
+ h = getMsg("not-available-label");
+ p = -1;
+ }
+ UserDataCertificateException udce =
+ new UserDataCertificateException(Step.REPLICATION_OPTIONS,
+ getMsg("certificate-exception",
+ new String[] {h, String.valueOf(p)}),
+ throwable, h, p,
+ getTrustManager().getLastRefusedChain(),
+ getTrustManager().getLastRefusedAuthType(), excType);
+
+ handleCertificateException(udce);
+ }
+ }
+ else if (throwable instanceof NamingException)
{
boolean dnInvalid = false;
boolean pwdInvalid = false;
@@ -463,7 +630,7 @@
getMsg("error-title"));
}
}
- else if (throwable instanceof Error)
+ else if (throwable instanceof ConfigException)
{
displayError(throwable.getMessage(), getMsg("error-title"));
}
@@ -550,17 +717,6 @@
}
/**
- * Returns the ldap URL used to log into the server based in the contents
- * of the config file.
- * @return the ldap URL used to log into the server based in the contents
- * of the config file.
- */
- private String getLDAPURL()
- {
- return getConfig().getLDAPURL();
- }
-
- /**
* Returns the ConfigFromFile object that contains the configuration read
* from the config file.
* @return the ConfigFromFile object that contains the configuration read
@@ -594,6 +750,66 @@
}
/**
+ * Returns the trust manager that can be used to establish secure connections.
+ * @return the trust manager that can be used to establish secure connections.
+ */
+ private ApplicationTrustManager getTrustManager()
+ {
+ return trustManager;
+ }
+
+ /**
+ * 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.
+ */
+ private void handleCertificateException(UserDataCertificateException ce)
+ {
+ CertificateDialog dlg = new CertificateDialog(parent, ce);
+ dlg.pack();
+ dlg.setVisible(true);
+ if (dlg.isAccepted())
+ {
+ 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);
+ getTrustManager().acceptCertificate(chain, authType, host);
+ /* Simulate a click on the OK */
+ SwingUtilities.invokeLater(new Runnable()
+ {
+ public void run()
+ {
+ okButton.doClick();
+ }
+ });
+ }
+ 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");
+ }
+ }
+ }
+ }
+
+ /**
* Method written for testing purposes.
* @param args the arguments to be passed to the test program.
*/
@@ -602,7 +818,9 @@
try
{
// UIFactory.initialize();
- LoginDialog dlg = new LoginDialog(new JFrame());
+ LoginDialog dlg = new LoginDialog(new JFrame(),
+ new ApplicationTrustManager(null),
+ ConnectionProtocolPolicy.USE_MOST_SECURE_AVAILABLE);
dlg.pack();
dlg.setVisible(true);
} catch (Exception ex)
--
Gitblit v1.10.0