opends/src/ads/org/opends/admin/ads/util/ConnectionUtils.java
@@ -29,6 +29,7 @@ import java.io.IOException; import java.net.ConnectException; import java.security.GeneralSecurityException; import java.util.HashSet; import java.util.Hashtable; import java.util.Set; @@ -45,6 +46,7 @@ import javax.naming.ldap.StartTlsResponse; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.KeyManager; import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.TrustManager; /** @@ -495,6 +497,28 @@ } /** * Tells whether the provided Throwable was caused because of a problem with * a certificate while trying to establish a connection. * @param t the Throwable to analyze. * @return <CODE>true</CODE> if the provided Throwable was caused because of a * problem with a certificate while trying to establish a connection and * <CODE>false</CODE> otherwise. */ public static boolean isCertificateException(Throwable t) { boolean returnValue = false; while (!returnValue && (t != null)) { returnValue = (t instanceof SSLHandshakeException) || (t instanceof GeneralSecurityException); t = t.getCause(); } return returnValue; } /** * Returns the String representation of the first value of an attribute in a * LDAP entry. * @param entry the entry. opends/src/quicksetup/org/opends/quicksetup/Configuration.java
@@ -91,7 +91,7 @@ * the configuration file. */ public int getPort() throws IOException { return getPort("ds-cfg-listen-port"); return getLDAPPort("ds-cfg-listen-port"); } /** @@ -103,7 +103,54 @@ */ public int getSecurePort() throws IOException { // TODO find out which is the attribute for this port. return getPort("ds-cfg-listen-secure-port"); return getLDAPPort("ds-cfg-listen-secure-port"); } /** * Tells whether this server is configured as a replication server or not. * @return <CODE>true</CODE> if the server is configured as a Replication * Server and <CODE>false</CODE> otherwise. * @throws IOException if there were problems reading the information from * the configuration file. */ public boolean isReplicationServer() throws IOException { return getReplicationPort() != -1; } /** * Provides the Replication port as is specified in the config.ldif file. * Returns -1 if this server is not a Replication Server. * * @return the Replication port specified in the config.ldif file. * @throws IOException if there were problems reading the information from * the configuration file. */ public int getReplicationPort() throws IOException { int port = -1; String contents = getContents(); int index = contents.indexOf("cn=replication server"); if (index != -1) { String attrWithPoints = "ds-cfg-replication-server-port:"; int index1 = contents.indexOf(attrWithPoints, index); if (index1 != -1) { int index2 = contents.indexOf(Constants.LINE_SEPARATOR, index1); if (index2 != -1) { String sPort = contents.substring(attrWithPoints.length() + index1, index2).trim(); try { port = Integer.parseInt(sPort); } catch (NumberFormatException nfe) { // do nothing; } } } } return port; } /** @@ -119,7 +166,7 @@ return getConfigurationValues("ds-cfg-log-file"); } private int getPort(String portAttr) throws IOException { private int getLDAPPort(String portAttr) throws IOException { int port = -1; String contents = getContents(); int index = contents.indexOf("cn=ldap connection handler"); @@ -239,6 +286,15 @@ return getConfigurationValues("ds-cfg-backend-directory"); } /** * Returns the list of base dns as they appear in the configuration file. * * @return the list of base dns as they appear in the configuration file. * @throws IOException if there is a problem reading the config file. */ public Set<String> getBaseDNs() throws IOException { return getConfigurationValues("ds-cfg-backend-base-dn"); } /** * Loads the contents of the configuration file into memory. opends/src/quicksetup/org/opends/quicksetup/Constants.java
@@ -72,6 +72,8 @@ /** Default dynamic name of directory manager. */ public static final String DIRECTORY_MANAGER_DN = "cn=Directory Manager"; /** Default global admin UID. */ public static final String GLOBAL_ADMIN_UID = "admin"; /** These HTML tags cause a line break in formatted text. */ public static final String[] BREAKING_TAGS = { HTML_LINE_BREAK, opends/src/quicksetup/org/opends/quicksetup/UserData.java
@@ -115,7 +115,7 @@ DataReplicationOptions.Type.STANDALONE, data, getDefaultReplicationPort()); setReplicationOptions(repl); setGlobalAdministratorUID("admin"); setGlobalAdministratorUID(Constants.GLOBAL_ADMIN_UID); SuffixesToReplicateOptions suffixes = new SuffixesToReplicateOptions( opends/src/quicksetup/org/opends/quicksetup/resources/Resources.properties
@@ -144,6 +144,7 @@ finish-button-tooltip=Finish Setup close-button-label=Close close-button-tooltip=Close Setup Window close-progress-button-tooltip=Close Progress Dialog close-button-install-tooltip=Close Setup Window close-button-uninstall-tooltip=Close Uninstall Window quit-button-label=Quit @@ -189,6 +190,17 @@ uninstallation can continue. Do you want the uninstaller to stop \ the server for you and continue with the uninstall? If you click \ No, you will need to stop the server manually to continue. confirm-uninstall-replication-server-running-title=Confirmation Required confirm-uninstall-replication-server-running-msg=This server is configured to \ perform replication.\nIn order to remove references to this server in other \ servers you must provide administrator authentication.\n\nClick on 'Yes' to \ provide authentication to remove the remote references. confirm-uninstall-replication-server-not-running-title=Confirmation Required confirm-uninstall-replication-server-not-running-msg=This server is configured \ to perform replication.\nIn order to remove references to this server in other \ servers the server will be started and then you must provide administrator \ authentication.\n\nClick on 'Yes' to start the server and then provide \ authentication to remove the remote references. confirm-uninstall-server-running-title=Server is Running confirm-cancel-title=Confirmation Required confirm-cancel-prompt=Cancel the running operation? @@ -343,7 +355,7 @@ cannot-connect-to-shutdown-without-cause=Could not connect to the Directory \ Server with the provided credentials.\nCheck that the Administrative User DN \ and password are valid. server-not-running-msg=The Directory Server is not running. Click OK to \ server-not-running-msg=The Directory Server is not running. Click 'Yes' to \ continue the uninstall. server-not-running-title=Directory Server not Running @@ -983,6 +995,7 @@ ## # Progress messages # progress-title=Progress progress-downloading=Downloading progress-done=Done. progress-points=..... @@ -1351,6 +1364,22 @@ installandupgrader-rbupgrade-tooltip=Select to upgrade an existing server \ instance. # # Progress Dialog # progress-dialog-title=Progress summary-starting=Starting Server... summary-stopping=Stopping Server... summary-start-error=An error occurred Starting Server. Check 'Details' text \ area for more information. summary-stop-error=An error occurred Stopping Server. Check 'Details' text \ area for more information. error-starting-server-code=Error Starting Directory Server. Error code: {0}. summary-start-success=OpenDS Started Successfully. summary-stop-success=OpenDS Stopped Successfully. general-action-required=Action Required general-warning=Warning general-info=Information opends/src/quicksetup/org/opends/quicksetup/ui/CertificateDialog.java
@@ -101,7 +101,7 @@ pack(); if (getPreferredSize().width > parent.getWidth()) { setPreferredSize(new Dimension(parent.getWidth() - 20, setPreferredSize(new Dimension(Math.max(parent.getWidth() - 20, 400), getPreferredSize().height)); } pack(); @@ -204,9 +204,18 @@ topPanel.add(Box.createHorizontalStrut( certificateDetails.getPreferredSize().width), gbc); gbc.insets.top = 0; gbc.insets.bottom = UIFactory.TOP_INSET_INPUT_SUBPANEL; gbc.weighty = 1.0; topPanel.add(certificateDetails, gbc); JPanel auxPanel = new JPanel(new GridBagLayout()); gbc.weightx = 0.0; gbc.insets = UIFactory.getEmptyInsets(); gbc.gridwidth = GridBagConstraints.RELATIVE; auxPanel.add(Box.createVerticalStrut(100), gbc); gbc.weightx = 1.0; gbc.gridwidth = GridBagConstraints.REMAINDER; auxPanel.add(certificateDetails, gbc); gbc.insets = UIFactory.getCurrentStepPanelInsets(); gbc.insets.bottom = UIFactory.TOP_INSET_INPUT_SUBPANEL; topPanel.add(auxPanel, gbc); certificateDetails.setVisible(false); gbc.weighty = 0.2; gbc.insets = UIFactory.getEmptyInsets(); opends/src/quicksetup/org/opends/quicksetup/ui/ProgressDialog.java
File was renamed from opends/src/statuspanel/org/opends/statuspanel/ui/ProgressDialog.java @@ -25,7 +25,7 @@ * Portions Copyright 2007 Sun Microsystems, Inc. */ package org.opends.statuspanel.ui; package org.opends.quicksetup.ui; import java.awt.Dimension; import java.awt.GridBagConstraints; @@ -46,12 +46,10 @@ import javax.swing.event.HyperlinkListener; import org.opends.quicksetup.event.MinimumSizeComponentListener; import org.opends.quicksetup.ui.UIFactory; import org.opends.quicksetup.i18n.ResourceProvider; import org.opends.quicksetup.util.HtmlProgressMessageFormatter; import org.opends.quicksetup.util.ProgressMessageFormatter; import org.opends.statuspanel.i18n.ResourceProvider; /** * This panel is used to show the progress of the start/stop/restart operations. * @@ -87,7 +85,7 @@ { super(frame); this.parent = frame; setTitle(getMsg("statuspanel-dialog-title")); setTitle(getMsg("progress-dialog-title")); createLayout(); } opends/src/quicksetup/org/opends/quicksetup/ui/QuickSetup.java
@@ -184,7 +184,7 @@ /** * ProgressUpdateListener implementation. Here we take the * ProgressUpdateEvent and create an ProgressDescriptor that * ProgressUpdateEvent and create a ProgressDescriptor that * will be used to update the progress dialog. * * @param ev the ProgressUpdateEvent we receive. opends/src/quicksetup/org/opends/quicksetup/util/Utils.java
@@ -34,7 +34,6 @@ import java.io.InputStream; import java.io.PrintWriter; import java.io.RandomAccessFile; import java.security.GeneralSecurityException; import java.util.*; import java.util.logging.Level; import java.util.logging.Logger; @@ -44,7 +43,6 @@ import javax.naming.ldap.InitialLdapContext; import javax.naming.ldap.LdapName; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.SSLHandshakeException; import javax.net.ssl.TrustManager; import org.opends.admin.ads.util.ConnectionUtils; @@ -894,16 +892,7 @@ */ public static boolean isCertificateException(Throwable t) { boolean returnValue = false; while (!returnValue && (t != null)) { returnValue = (t instanceof SSLHandshakeException) || (t instanceof GeneralSecurityException); t = t.getCause(); } return returnValue; return ConnectionUtils.isCertificateException(t); } /** opends/src/server/org/opends/server/admin/client/cli/DsFrameworkCliParser.java
@@ -168,7 +168,7 @@ private FileBasedArgument keyStorePasswordFileArg = null; /** * The 'keyStorePasswordFile' global argument. * The 'certNicknameArg' global argument. */ private StringArgument certNicknameArg = null; opends/src/statuspanel/org/opends/statuspanel/ConfigException.java
New file @@ -0,0 +1,47 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Portions Copyright 2007 Sun Microsystems, Inc. */ package org.opends.statuspanel; /** * Exception thrown when there is an error with the configuration (for instance * a valid URL for the requested protocol could not be found). */ public class ConfigException extends Exception { private static final long serialVersionUID = 1266482779183126905L; /** * Constructor for the exception. * @param msg the localized message to be used. */ public ConfigException(String msg) { super(msg); } } opends/src/statuspanel/org/opends/statuspanel/ConfigFromFile.java
@@ -33,6 +33,8 @@ import java.util.List; import java.util.Set; import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; import org.opends.server.core.DirectoryServer; import org.opends.server.util.LDIFException; @@ -43,9 +45,9 @@ import org.opends.server.types.Entry; import org.opends.server.types.LDIFImportConfig; import org.opends.server.types.ObjectClass; import org.opends.statuspanel.i18n.ResourceProvider; import org.opends.quicksetup.util.Utils; import org.opends.quicksetup.Installation; import org.opends.statuspanel.i18n.ResourceProvider; /** * This class is used to retrieve configuration information directly from the @@ -72,6 +74,8 @@ private HashSet<ListenerDescriptor> listeners = new HashSet<ListenerDescriptor>(); private HashSet<ListenerDescriptor> startTLSListeners = new HashSet<ListenerDescriptor>(); private HashSet<DatabaseDescriptor> databases = new HashSet<DatabaseDescriptor>(); private HashSet<String> administrativeUsers = new HashSet<String>(); @@ -79,6 +83,9 @@ private boolean replicationConfigured = false; private HashSet<String> replicatedSuffixes = new HashSet<String>(); private static final Logger LOG = Logger.getLogger(ConfigFromFile.class.getName()); /** * Default constructor. * @@ -96,6 +103,7 @@ { errorMessage = null; listeners.clear(); startTLSListeners.clear(); databases.clear(); administrativeUsers.clear(); replicationConfigured = false; @@ -117,16 +125,19 @@ } catch (IOException ioe) { LOG.log(Level.SEVERE, "Error reading config file: "+ioe, ioe); errorMessage = Utils.getThrowableMsg(getI18n(), "error-reading-config-file", null, ioe); } catch (LDIFException le) { LOG.log(Level.SEVERE, "Error reading config file: "+le, le); errorMessage = Utils.getThrowableMsg(getI18n(), "error-reading-config-file", null, le); } catch (Throwable t) { LOG.log(Level.SEVERE, "Error reading config file: "+t, t); // Bug t.printStackTrace(); errorMessage = Utils.getThrowableMsg(getI18n(), @@ -199,6 +210,64 @@ */ public String getLDAPURL() { return getLDAPURL(false); } /** * Returns the ldaps URL that we can use to connect to the server based in * what we found in the config.ldif file. * @return the ldaps URL that we can use to connect to the server based in * what we found in the config.ldif file. */ public String getLDAPSURL() { return getLDAPURL(true); } /** * Returns the ldap URL that we can use to connect to the server using Start * TLS based in what we found in the config.ldif file. * @return the ldap URL that we can use to connect to the server using Start * TLS based in what we found in the config.ldif file. */ public String getStartTLSURL() { String url = null; for (ListenerDescriptor desc : startTLSListeners) { if (desc.getState() == ListenerDescriptor.State.ENABLED) { int port = -1; try { String addressPort = desc.getAddressPort(); int index = addressPort.indexOf(":"); if (index != -1) { port = Integer.parseInt(addressPort.substring(index+1)); } else { port = Integer.parseInt(addressPort); } } catch (Exception ex) { // Could not get the port } if (port != -1) { url = "ldap://localhost:"+port; break; } } } return url; } private String getLDAPURL(boolean secure) { String url = null; for (ListenerDescriptor desc : getListeners()) @@ -227,16 +296,17 @@ if (port != -1) { if (desc.getProtocol() == ListenerDescriptor.Protocol.LDAP) if (!secure && (desc.getProtocol() == ListenerDescriptor.Protocol.LDAP)) { url = "ldap://localhost:"+port; /* We prefer to test using the LDAP port: do not continue * searching */ break; } else if (desc.getProtocol() == ListenerDescriptor.Protocol.LDAPS) if (secure && (desc.getProtocol() == ListenerDescriptor.Protocol.LDAPS)) { url = "ldaps://localhost:"+port; break; } } } @@ -383,6 +453,18 @@ } listeners.add(new ListenerDescriptor(addressPort, protocol, protocolDescription, state)); if (protocol == ListenerDescriptor.Protocol.LDAP) { String allowStartTLS = getFirstValue(entry, "ds-cfg-allow-start-tls"); if (allowStartTLS != null) { if ("true".equalsIgnoreCase(allowStartTLS.trim())) { startTLSListeners.add(new ListenerDescriptor(addressPort, protocol, protocolDescription, state)); } } } } /** opends/src/statuspanel/org/opends/statuspanel/ConfigFromLDAP.java
@@ -43,6 +43,7 @@ import javax.naming.ldap.LdapName; import org.opends.statuspanel.i18n.ResourceProvider; import org.opends.admin.ads.util.ApplicationTrustManager; import org.opends.quicksetup.util.Utils; /** @@ -67,7 +68,10 @@ private String dn; private String pwd; private String ldapUrl; private String lastUrl; private ConnectionProtocolPolicy policy; private ConfigFromFile offlineConf; private ApplicationTrustManager trustManager; private InitialLdapContext ctx; private String javaVersion; @@ -83,15 +87,28 @@ /** * Sets the connection information required to contact the server using LDAP. * @param ldapUrl the LDAP URL of the server. * @param offlineConf the ConfigFromFile object used to retrieve the LDAP URL * that will be used to connect to the server. * @param policy the configuration policy to be used (whether we prefer the * most secure, the less secure, a specific method...). * @param dn the authentication Distinguished Name to bind. * @param pwd the authentication password to bind. * @param trustManager the trust manager to be used for the secure * connections. * @throws ConfigException if a valid URL could not be found with the provided * parameters. */ public void setConnectionInfo(String ldapUrl, String dn, String pwd) public void setConnectionInfo(ConfigFromFile offlineConf, ConnectionProtocolPolicy policy, String dn, String pwd, ApplicationTrustManager trustManager) throws ConfigException { if (ldapUrl == null) if (offlineConf == null) { throw new IllegalArgumentException("ldapUrl cannot be null."); throw new IllegalArgumentException("offlineConf cannot be null."); } if (policy == null) { throw new IllegalArgumentException("policy cannot be null."); } if (dn == null) { @@ -101,9 +118,15 @@ { throw new IllegalArgumentException("pwd cannot be null."); } this.trustManager = trustManager; this.offlineConf = offlineConf; this.policy = policy; String ldapUrl = getURL(offlineConf, policy); if (!Utils.areDnsEqual(dn, this.dn) || !pwd.equals(this.pwd) || !ldapUrl.equals(this.ldapUrl)) (policy != this.policy) || !ldapUrl.equals(lastUrl)) { if (ctx != null) { @@ -118,7 +141,7 @@ } } this.ldapUrl = ldapUrl; this.lastUrl = ldapUrl; this.dn = dn; this.pwd = pwd; } @@ -265,8 +288,11 @@ * @return the InitialLdapContext object to be used to retrieve configuration * and monitoring information. * @throws NamingException if we could not get an InitialLdapContext. * @throws ConfigException if we could not retrieve a valid LDAP URL in * the configuration. */ private InitialLdapContext getDirContext() throws NamingException private InitialLdapContext getDirContext() throws NamingException, ConfigException { if (ctx != null) { @@ -288,8 +314,86 @@ } if (ctx == null) { ctx = Utils.createLdapContext(ldapUrl, dn, pwd, Utils.getDefaultLDAPTimeout(), null); String ldapUrl = offlineConf.getLDAPURL(); String startTlsUrl = offlineConf.getStartTLSURL(); String ldapsUrl = offlineConf.getLDAPSURL(); switch (policy) { case USE_STARTTLS: if (startTlsUrl != null) { ctx = Utils.createStartTLSContext(startTlsUrl, dn, pwd, Utils.getDefaultLDAPTimeout(), null, trustManager, null); } else { throw new ConfigException(getMsg("could-not-find-valid-ldapurl")); } break; case USE_LDAPS: if (ldapsUrl != null) { ctx = Utils.createLdapsContext(ldapsUrl, dn, pwd, Utils.getDefaultLDAPTimeout(), null, trustManager); } else { throw new ConfigException(getMsg("could-not-find-valid-ldapurl")); } break; case USE_LDAP: if (ldapUrl != null) { ctx = Utils.createLdapContext(ldapUrl, dn, pwd, Utils.getDefaultLDAPTimeout(), null); } else { throw new ConfigException(getMsg("could-not-find-valid-ldapurl")); } break; case USE_MOST_SECURE_AVAILABLE: if (ldapsUrl != null) { ctx = Utils.createLdapsContext(ldapsUrl, dn, pwd, Utils.getDefaultLDAPTimeout(), null, trustManager); } else if (startTlsUrl != null) { ctx = Utils.createStartTLSContext(startTlsUrl, dn, pwd, Utils.getDefaultLDAPTimeout(), null, trustManager, null); } else if (ldapUrl != null) { ctx = Utils.createLdapContext(ldapUrl, dn, pwd, Utils.getDefaultLDAPTimeout(), null); } else { throw new ConfigException(getMsg("could-not-find-valid-ldapurl")); } break; case USE_LESS_SECURE_AVAILABLE: if (ldapUrl != null) { ctx = Utils.createLdapContext(ldapUrl, dn, pwd, Utils.getDefaultLDAPTimeout(), null); } else if (ldapsUrl != null) { ctx = Utils.createLdapsContext(ldapsUrl, dn, pwd, Utils.getDefaultLDAPTimeout(), null, trustManager); } else { throw new ConfigException(getMsg("could-not-find-valid-ldapurl")); } break; default: throw new IllegalStateException("Unknown connection policy: "+ policy); } } return ctx; } @@ -908,4 +1012,82 @@ { return ResourceProvider.getInstance(); } private String getURL(ConfigFromFile offlineConf, ConnectionProtocolPolicy policy) throws ConfigException { String url; String ldapUrl = offlineConf.getLDAPURL(); String startTlsUrl = offlineConf.getStartTLSURL(); String ldapsUrl = offlineConf.getLDAPSURL(); switch (policy) { case USE_STARTTLS: if (startTlsUrl != null) { url = startTlsUrl; } else { throw new ConfigException(getMsg("could-not-find-valid-ldapurl")); } break; case USE_LDAPS: if (ldapsUrl != null) { url = ldapsUrl; } else { throw new ConfigException(getMsg("could-not-find-valid-ldapurl")); } break; case USE_LDAP: if (ldapUrl != null) { url = ldapUrl; } else { throw new ConfigException(getMsg("could-not-find-valid-ldapurl")); } break; case USE_MOST_SECURE_AVAILABLE: if (ldapsUrl != null) { url = ldapsUrl; } else if (startTlsUrl != null) { url = startTlsUrl; } else if (ldapUrl != null) { url = ldapUrl; } else { throw new ConfigException(getMsg("could-not-find-valid-ldapurl")); } break; case USE_LESS_SECURE_AVAILABLE: if (ldapUrl != null) { url = ldapUrl; } else if (ldapsUrl != null) { url = ldapsUrl; } else { throw new ConfigException(getMsg("could-not-find-valid-ldapurl")); } break; default: throw new IllegalStateException("Unknown connection policy: "+ policy); } return url; } } opends/src/statuspanel/org/opends/statuspanel/ConnectionProtocolPolicy.java
New file @@ -0,0 +1,53 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Portions Copyright 2007 Sun Microsystems, Inc. */ package org.opends.statuspanel; /** Policy to follow to choose the protocol to be used. */ public enum ConnectionProtocolPolicy { /** * Force to use Start TLS. */ USE_STARTTLS, /** * Force to use LDAP. */ USE_LDAP, /** * Force to use LDAPs. */ USE_LDAPS, /** * Use the most secure available (LDAPs, StartTLS and finally LDAP). */ USE_MOST_SECURE_AVAILABLE, /** * Use the less secure available (LDAP, and then LDAPs). */ USE_LESS_SECURE_AVAILABLE, } opends/src/statuspanel/org/opends/statuspanel/ServerStatusPooler.java
@@ -29,7 +29,10 @@ import java.io.File; import java.util.HashSet; import java.util.logging.Level; import java.util.logging.Logger; import org.opends.admin.ads.util.ApplicationTrustManager; import org.opends.quicksetup.Installation; import org.opends.quicksetup.util.Utils; import org.opends.statuspanel.event.ServerStatusChangeEvent; @@ -47,6 +50,7 @@ { private String dn; private String pwd; private ApplicationTrustManager trustManager; private ServerStatusDescriptor lastDescriptor; private boolean stopPooling; private Thread poolingThread; @@ -56,23 +60,28 @@ private boolean stopping; private ConfigFromFile offLineConf = new ConfigFromFile(); private ConfigFromLDAP onLineConf = new ConfigFromLDAP(); private String ldapUrl; private int nTriesWithErrorOnline; private ConnectionProtocolPolicy policy; /* The pooling periods */ private static final int OFFLINE_POOLING_PERIOD = 6000; private static final int ONLINE_POOLING_PERIOD = 4000; private static final Logger LOG = Logger.getLogger(ServerStatusPooler.class.getName()); /** * Default constructor. * @param policy the configuration policy to be used (whether we prefer the * most secure, the less secure, a specific method...). */ public ServerStatusPooler() public ServerStatusPooler(ConnectionProtocolPolicy policy) { /* This is required to retrieve the ldap url to be used by the * ConfigFromLDAP class. */ offLineConf.readConfiguration(); ldapUrl = offLineConf.getLDAPURL(); this.policy = policy; } /** @@ -232,13 +241,18 @@ * information using LDAP. * @param dn the authentication Distinguished Name to bind. * @param pwd the authentication password to bind. * @param trustManager the trust manager to be used for the secure * connections. * @throws ConfigException if a valid URL could not be found with the provided * parameters. */ public void setAuthentication(String dn, String pwd) public void setAuthentication(String dn, String pwd, ApplicationTrustManager trustManager) throws ConfigException { this.dn = dn; this.pwd = pwd; if ((ldapUrl != null) && (poolingThread != null) && poolingThread.isAlive() && !stopPooling) this.trustManager = trustManager; if ((poolingThread != null) && poolingThread.isAlive() && !stopPooling) { /* If we are pooling, stop the pooling update the connection information * and restart the pooling. Set the stopPooling boolean to true to @@ -258,12 +272,12 @@ t.printStackTrace(); } poolingThread = null; onLineConf.setConnectionInfo(ldapUrl, dn, pwd); onLineConf.setConnectionInfo(offLineConf, policy, dn, pwd, trustManager); startPooling(); } else if (ldapUrl != null) else { onLineConf.setConnectionInfo(ldapUrl, dn, pwd); onLineConf.setConnectionInfo(offLineConf, policy, dn, pwd, trustManager); } } @@ -330,20 +344,9 @@ desc.setListeners(new HashSet<ListenerDescriptor>()); desc.setOpenConnections(-1); } else if (ldapUrl != null) { updateDescriptorWithOnLineInfo(desc); } else { /* We cannot retrieve an ldapurl from the config file. Display * what we got in the config file. */ updateDescriptorWithOffLineInfo(desc); if (desc.getErrorMessage() != null) { desc.setErrorMessage(getMsg("could-not-find-valid-ldapurl")); } updateDescriptorWithOnLineInfo(desc); } } catch (Exception ex) @@ -372,10 +375,17 @@ desc.setDatabases(offLineConf.getDatabases()); desc.setListeners(offLineConf.getListeners()); desc.setErrorMessage(offLineConf.getErrorMessage()); ldapUrl = offLineConf.getLDAPURL(); if ((ldapUrl != null) && (dn != null) && (pwd != null)) if ((dn != null) && (pwd != null)) { onLineConf.setConnectionInfo(ldapUrl, dn, pwd); try { onLineConf.setConnectionInfo(offLineConf, policy, dn, pwd, trustManager); } catch (ConfigException ce) { LOG.log(Level.WARNING, "Error retrieving LDAP URL: "+ce, ce); } } desc.setOpenConnections(-1); desc.setJavaVersion(null); @@ -406,8 +416,15 @@ if (nTriesWithErrorOnline >= 5) { offLineConf.readConfiguration(); ldapUrl = offLineConf.getLDAPURL(); onLineConf.setConnectionInfo(ldapUrl, dn, pwd); try { onLineConf.setConnectionInfo(offLineConf, policy, dn, pwd, trustManager); } catch (ConfigException ce) { desc.setErrorMessage(ce.getMessage()); } nTriesWithErrorOnline = 0; } } opends/src/statuspanel/org/opends/statuspanel/StatusCli.java
@@ -29,15 +29,26 @@ import java.io.BufferedReader; import java.io.File; import java.io.FileInputStream; import java.io.FileReader; import java.io.IOException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.Set; import java.util.TreeSet; import java.util.logging.Level; import java.util.logging.Logger; import javax.net.ssl.KeyManager; import javax.swing.table.TableModel; import org.opends.admin.ads.util.ApplicationKeyManager; import org.opends.admin.ads.util.ApplicationTrustManager; import org.opends.quicksetup.Installation; import org.opends.quicksetup.QuickSetupLog; import org.opends.quicksetup.util.Utils; @@ -48,11 +59,13 @@ import org.opends.statuspanel.ui.DatabasesTableModel; import org.opends.statuspanel.ui.ListenersTableModel; import static org.opends.server.messages.MessageHandler.getMessage; import static org.opends.server.messages.ToolMessages.*; import static org.opends.server.tools.ToolConstants.*; import org.opends.server.messages.MessageHandler; import org.opends.server.util.PasswordReader; import org.opends.server.util.SelectableCertificateKeyManager; import org.opends.server.util.ServerConstants; import org.opends.server.util.args.ArgumentException; import org.opends.server.util.args.ArgumentParser; @@ -77,6 +90,66 @@ private boolean displayMustStartLegend; /** * The 'binDN' global argument. */ private StringArgument bindDnArg = null; /** * The 'bindPasswordFile' global argument. */ private FileBasedArgument bindPasswordFileArg = null; /** * The 'bindPassword' global argument. */ private StringArgument bindPasswordArg = null; /** * The 'trustAllArg' global argument. */ private BooleanArgument trustAllArg = null; /** * The 'trustStore' global argument. */ private StringArgument trustStorePathArg = null; /** * The 'trustStorePassword' global argument. */ private StringArgument trustStorePasswordArg = null; /** * The 'trustStorePasswordFile' global argument. */ private FileBasedArgument trustStorePasswordFileArg = null; /** * The 'keyStore' global argument. */ private StringArgument keyStorePathArg = null; /** * The 'keyStorePassword' global argument. */ private StringArgument keyStorePasswordArg = null; /** * The 'keyStorePasswordFile' global argument. */ private FileBasedArgument keyStorePasswordFileArg = null; /** * The 'certNicknameArg' global argument. */ private StringArgument certNicknameArg = null; /** * The Logger. */ static private final Logger LOG = Logger.getLogger(StatusCli.class.getName()); /** * Return code: Uninstall successful. */ static int SUCCESSFUL = 0; @@ -142,9 +215,12 @@ new ArgumentParser(StatusPanelLauncher.class.getName(), getI18n().getMsg("status-cli-usage-description"), false); BooleanArgument showUsage; BooleanArgument useSSLArg; BooleanArgument startTLSArg; StringArgument bindDN; StringArgument bindPW; FileBasedArgument bindPWFile; String scriptName; if (Utils.isWindows()) { scriptName = Installation.WINDOWS_STATUSCLI_FILE_NAME; @@ -154,9 +230,18 @@ System.setProperty(ServerConstants.PROPERTY_SCRIPT_NAME, scriptName); try { useSSLArg = new BooleanArgument("useSSL", OPTION_SHORT_USE_SSL, OPTION_LONG_USE_SSL, MSGID_DESCRIPTION_USE_SSL); argParser.addArgument(useSSLArg); startTLSArg = new BooleanArgument("startTLS", OPTION_SHORT_START_TLS, OPTION_LONG_START_TLS, MSGID_DESCRIPTION_START_TLS); argParser.addArgument(startTLSArg); bindDN = new StringArgument("binddn", OPTION_SHORT_BINDDN, OPTION_LONG_BINDDN, false, false, true, OPTION_VALUE_BINDDN, null, null, OPTION_VALUE_BINDDN, "cn=Directory Manager", null, MSGID_STOPDS_DESCRIPTION_BINDDN); argParser.addArgument(bindDN); @@ -175,6 +260,53 @@ null, null, MSGID_STOPDS_DESCRIPTION_BINDPWFILE); argParser.addArgument(bindPWFile); trustAllArg = new BooleanArgument("trustAll", 'X', "trustAll", MSGID_DESCRIPTION_TRUSTALL); argParser.addArgument(trustAllArg); trustStorePathArg = new StringArgument("trustStorePath", OPTION_SHORT_TRUSTSTOREPATH, OPTION_LONG_TRUSTSTOREPATH, false, false, true, OPTION_VALUE_TRUSTSTOREPATH, null, null, MSGID_DESCRIPTION_TRUSTSTOREPATH); argParser.addArgument(trustStorePathArg); trustStorePasswordArg = new StringArgument("trustStorePassword", null, OPTION_LONG_TRUSTSTORE_PWD, false, false, true, OPTION_VALUE_TRUSTSTORE_PWD, null, null, MSGID_DESCRIPTION_TRUSTSTOREPASSWORD); argParser.addArgument(trustStorePasswordArg); trustStorePasswordFileArg = new FileBasedArgument("truststorepasswordfile", OPTION_SHORT_TRUSTSTORE_PWD_FILE, OPTION_LONG_TRUSTSTORE_PWD_FILE, false, false, OPTION_VALUE_TRUSTSTORE_PWD_FILE, null, null, MSGID_DESCRIPTION_TRUSTSTOREPASSWORD_FILE); argParser.addArgument(trustStorePasswordFileArg); keyStorePathArg = new StringArgument("keyStorePath", OPTION_SHORT_KEYSTOREPATH, OPTION_LONG_KEYSTOREPATH, false, false, true, OPTION_VALUE_KEYSTOREPATH, null, null, MSGID_DESCRIPTION_KEYSTOREPATH); argParser.addArgument(keyStorePathArg); keyStorePasswordArg = new StringArgument("keyStorePassword", null, OPTION_LONG_KEYSTORE_PWD, false, false, true, OPTION_VALUE_KEYSTORE_PWD, null, null, MSGID_DESCRIPTION_KEYSTOREPASSWORD); argParser.addArgument(keyStorePasswordArg); keyStorePasswordFileArg = new FileBasedArgument("keystorepasswordfile", OPTION_SHORT_KEYSTORE_PWD_FILE, OPTION_LONG_KEYSTORE_PWD_FILE, false, false, OPTION_VALUE_KEYSTORE_PWD_FILE, null, null, MSGID_DESCRIPTION_KEYSTOREPASSWORD_FILE); argParser.addArgument(keyStorePasswordFileArg); certNicknameArg = new StringArgument("certnickname", 'N', "certNickname", false, false, true, "{nickname}", null, null, MSGID_DESCRIPTION_CERT_NICKNAME); argParser.addArgument(certNicknameArg); showUsage = new BooleanArgument("showusage", OPTION_SHORT_HELP, OPTION_LONG_HELP, MSGID_DESCRIPTION_USAGE); @@ -244,6 +376,46 @@ } } // Couldn't have at the same time trustAll and // trustStore related arg if (trustAllArg.isPresent() && trustStorePathArg.isPresent()) { int msgID = MSGID_TOOL_CONFLICTING_ARGS; errors.add(getMessage(msgID, trustAllArg.getLongIdentifier(), trustStorePathArg.getLongIdentifier())); } if (trustAllArg.isPresent() && trustStorePasswordArg.isPresent()) { int msgID = MSGID_TOOL_CONFLICTING_ARGS; errors.add(getMessage(msgID, trustAllArg.getLongIdentifier(), trustStorePasswordArg.getLongIdentifier())); } if (trustAllArg.isPresent() && trustStorePasswordFileArg.isPresent()) { int msgID = MSGID_TOOL_CONFLICTING_ARGS; errors.add(getMessage(msgID, trustAllArg.getLongIdentifier(), trustStorePasswordFileArg.getLongIdentifier())); } // Couldn't have at the same time trustStorePasswordArg and // trustStorePasswordFileArg if (trustStorePasswordArg.isPresent() && trustStorePasswordFileArg.isPresent()) { int msgID = MSGID_TOOL_CONFLICTING_ARGS; errors.add(getMessage(msgID, trustStorePasswordArg .getLongIdentifier(), trustStorePasswordFileArg.getLongIdentifier())); } // Couldn't have at the same time startTLSArg and // useSSLArg if (startTLSArg.isPresent() && useSSLArg.isPresent()) { int msgID = MSGID_TOOL_CONFLICTING_ARGS; errors.add(getMessage(msgID, startTLSArg.getLongIdentifier(), useSSLArg.getLongIdentifier())); } if (errors.size() > 0) { System.err.println(Utils.getStringFromCollection(errors, @@ -264,29 +436,50 @@ ServerStatusDescriptor desc = createServerStatusDescriptor( directoryManagerDn, directoryManagerPwd); if (isServerRunning) { String ldapUrl = offLineConf.getLDAPURL(); if (directoryManagerDn == null) { directoryManagerDn = ""; } if (directoryManagerPwd == null) { directoryManagerPwd = ""; } ConfigFromLDAP onLineConf = new ConfigFromLDAP(); onLineConf.setConnectionInfo(ldapUrl, directoryManagerDn, directoryManagerPwd); onLineConf.readConfiguration(); updateDescriptorWithOnLineInfo(desc, onLineConf); } else { updateDescriptorWithOffLineInfo(desc, offLineConf); } writeStatus(desc); try { if (isServerRunning) { if (directoryManagerDn == null) { directoryManagerDn = ""; } if (directoryManagerPwd == null) { directoryManagerPwd = ""; } ConfigFromLDAP onLineConf = new ConfigFromLDAP(); ConnectionProtocolPolicy policy; if (startTLSArg.isPresent()) { policy = ConnectionProtocolPolicy.USE_STARTTLS; } if (useSSLArg.isPresent()) { policy = ConnectionProtocolPolicy.USE_LDAPS; } else { policy = ConnectionProtocolPolicy.USE_MOST_SECURE_AVAILABLE; } onLineConf.setConnectionInfo(offLineConf, policy, directoryManagerDn, directoryManagerPwd, getTrustManager()); onLineConf.readConfiguration(); // TO COMPLETE: check the certificates updateDescriptorWithOnLineInfo(desc, onLineConf); } else { updateDescriptorWithOffLineInfo(desc, offLineConf); } writeStatus(desc); } catch (ConfigException ce) { System.err.println(wrap(ce.getMessage())); } } return returnValue; @@ -1060,5 +1253,165 @@ } return centered; } /** * Handle TrustStore. * * @return The trustStore manager to be used for the command. */ public ApplicationTrustManager getTrustManager() { ApplicationTrustManager truststoreManager = null ; KeyStore truststore = null ; if (trustAllArg.isPresent()) { // Running a null TrustManager will force createLdapsContext and // createStartTLSContext to use a bindTrustManager. return null ; } else if (trustStorePathArg.isPresent()) { try { FileInputStream fos = new FileInputStream(trustStorePathArg.getValue()); String trustStorePasswordStringValue = null; char[] trustStorePasswordValue = null; if (trustStorePasswordArg.isPresent()) { trustStorePasswordStringValue = trustStorePasswordArg.getValue(); } else if (trustStorePasswordFileArg.isPresent()) { trustStorePasswordStringValue = trustStorePasswordFileArg.getValue(); } if (trustStorePasswordStringValue != null) { trustStorePasswordStringValue = System .getProperty("javax.net.ssl.trustStorePassword"); } if (trustStorePasswordStringValue != null) { trustStorePasswordValue = trustStorePasswordStringValue.toCharArray(); } truststore = KeyStore.getInstance(KeyStore.getDefaultType()); truststore.load(fos, trustStorePasswordValue); fos.close(); } catch (KeyStoreException e) { // Nothing to do: if this occurs we will systematically refuse the // certificates. Maybe we should avoid this and be strict, but we are // in a best effor mode. LOG.log(Level.WARNING, "Error with the truststore", e); } catch (NoSuchAlgorithmException e) { // Nothing to do: if this occurs we will systematically refuse the // certificates. Maybe we should avoid this and be strict, but we are // in a best effor mode. LOG.log(Level.WARNING, "Error with the truststore", e); } catch (CertificateException e) { // Nothing to do: if this occurs we will systematically refuse the // certificates. Maybe we should avoid this and be strict, but we are // in a best effor mode. LOG.log(Level.WARNING, "Error with the truststore", e); } catch (IOException e) { // Nothing to do: if this occurs we will systematically refuse the // certificates. Maybe we should avoid this and be strict, but we are // in a best effor mode. LOG.log(Level.WARNING, "Error with the truststore", e); } } truststoreManager = new ApplicationTrustManager(truststore); return truststoreManager; } /** * Handle KeyStore. * * @return The keyStore manager to be used for the command. */ public KeyManager getKeyManager() { KeyStore keyStore = null; String keyStorePasswordValue = null; if (keyStorePathArg.isPresent()) { try { FileInputStream fos = new FileInputStream(keyStorePathArg.getValue()); if (keyStorePasswordArg.isPresent()) { keyStorePasswordValue = keyStorePasswordArg.getValue(); } else if (keyStorePasswordFileArg.isPresent()) { keyStorePasswordValue = keyStorePasswordFileArg.getValue(); } keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(fos, keyStorePasswordValue.toCharArray()); } catch (KeyStoreException e) { // Nothing to do: if this occurs we will systematically refuse // the // certificates. Maybe we should avoid this and be strict, but // we are // in a best effor mode. LOG.log(Level.WARNING, "Error with the keystore", e); } catch (NoSuchAlgorithmException e) { // Nothing to do: if this occurs we will systematically refuse // the // certificates. Maybe we should avoid this and be strict, but // we are // in a best effor mode. LOG.log(Level.WARNING, "Error with the keystore", e); } catch (CertificateException e) { // Nothing to do: if this occurs we will systematically refuse // the // certificates. Maybe we should avoid this and be strict, but // we are // in a best effor mode. LOG.log(Level.WARNING, "Error with the keystore", e); } catch (IOException e) { // Nothing to do: if this occurs we will systematically refuse // the // certificates. Maybe we should avoid this and be strict, but // we are // in a best effor mode. LOG.log(Level.WARNING, "Error with the keystore", e); } ApplicationKeyManager akm = new ApplicationKeyManager(keyStore, keyStorePasswordValue.toCharArray()); if (certNicknameArg.isPresent()) { return new SelectableCertificateKeyManager(akm, certNicknameArg .getValue()); } else { return akm; } } else { return null; } } } opends/src/statuspanel/org/opends/statuspanel/StatusPanelController.java
@@ -39,7 +39,9 @@ import org.opends.server.core.DirectoryServer; import org.opends.admin.ads.util.ApplicationTrustManager; import org.opends.quicksetup.Installation; import org.opends.quicksetup.ui.ProgressDialog; import org.opends.quicksetup.ui.UIFactory; import org.opends.quicksetup.ui.Utilities; import org.opends.quicksetup.util.BackgroundTask; @@ -51,7 +53,6 @@ import org.opends.statuspanel.event.StatusPanelButtonListener; import org.opends.statuspanel.i18n.ResourceProvider; import org.opends.statuspanel.ui.LoginDialog; import org.opends.statuspanel.ui.ProgressDialog; import org.opends.statuspanel.ui.StatusPanelDialog; /** @@ -86,9 +87,14 @@ private Thread progressUpdater; private ApplicationTrustManager trustManager; //Update period of the progress dialog. private static final int UPDATE_PERIOD = 500; private static final ConnectionProtocolPolicy CONNECTION_POLICY = ConnectionProtocolPolicy.USE_MOST_SECURE_AVAILABLE; /** * This method creates the control panel dialogs and to check the current * install status. This method must be called outside the event thread because @@ -108,11 +114,12 @@ { DirectoryServer.bootstrapClient(); initLookAndFeel(); trustManager = new ApplicationTrustManager(null); /* Call this methods to create the dialogs (the control panel dialog * is generated when we call getLoginDialog()). */ getLoginDialog(); getProgressDialog(); serverStatusPooler = new ServerStatusPooler(); serverStatusPooler = new ServerStatusPooler(CONNECTION_POLICY); serverStatusPooler.addServerStatusChangeListener(this); serverStatusPooler.startPooling(); desc = serverStatusPooler.getLastDescriptor(); @@ -445,9 +452,19 @@ getLoginDialog().setVisible(true); if (!getLoginDialog().isCancelled()) { serverStatusPooler.setAuthentication( getLoginDialog().getDirectoryManagerDn(), getLoginDialog().getDirectoryManagerPwd()); try { serverStatusPooler.setAuthentication( getLoginDialog().getDirectoryManagerDn(), getLoginDialog().getDirectoryManagerPwd(), trustManager); } catch (ConfigException ce) { Utilities.displayError(getLoginDialog(), ce.getMessage(), getMsg("error-title")); getLoginDialog().toFront(); } } } @@ -468,7 +485,8 @@ { if (loginDialog == null) { loginDialog = new LoginDialog(getStatusPanelDialog()); loginDialog = new LoginDialog(getStatusPanelDialog(), trustManager, CONNECTION_POLICY); loginDialog.setModal(true); } return loginDialog; @@ -819,10 +837,10 @@ * This method is used to update the progress dialog. * * We are receiving notifications from the installer and uninstaller (this * class is a ProgressListener). However if we lots of notifications updating * the progress panel every time we get a progress update can result of a lot * of flickering. So the idea here is to have a minimal time between 2 updates * of the progress dialog (specified by UPDATE_PERIOD). * class is a ProgressListener). However if we send lots of notifications * updating the progress panel every time we get a progress update can result * of a lot of flickering. So the idea here is to have a minimal time between * 2 updates of the progress dialog (specified by UPDATE_PERIOD). */ private void runProgressUpdater() { opends/src/statuspanel/org/opends/statuspanel/resources/Resources.properties
@@ -101,33 +101,18 @@ undefined-protocol-label=-Unknown- error-reading-config-file=Error reading the configuration file. could-not-find-valid-ldapurl=Error reading the configuration file.\n\ This could be caused because there is not an enabled LDAP port to retrieve \ monitoring information or because you do not have read rights on the \ This could be caused because there is not an enabled LDAP port for the \ specified connection parameters or because you do not have read rights on the \ configuration file. number-entries-multiple-suffixes-in-db={0} (for all base DNs in {1}) error-reading-config-ldap=Error reading data from server. Try \ re-authenticating.\nDetails: {0} error-reading-config-ldap=Error reading data from server. Verify the \ authentication information provided.\nDetails: {0} no-dbs-found=-No LDAP Databases Found- no-listeners-found=-No Listener Ports Found- suffix-replicated-label=Enabled suffix-not-replicated-label=Disabled # # Progress Dialog # close-progress-button-tooltip=Close Progress Dialog progress-title=Progress summary-starting=Starting Server... summary-stopping=Stopping Server... summary-start-error=An error occurred Starting Server. Check 'Details' text \ area for more information. summary-stop-error=An error occurred Stopping Server. Check 'Details' text \ area for more information. error-starting-server-code=Error Starting Directory Server. Error code: {0}. summary-start-success=OpenDS Started Successfully. summary-stop-success=OpenDS Stopped Successfully. # # Confirmation messages # confirm-stop-message=Are you sure you want to Stop the Directory Server? 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)