/* * 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 legal-notices/CDDLv1_0.txt * or http://forgerock.org/license/CDDLv1.0.html. * 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 legal-notices/CDDLv1_0.txt. * 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 * * * Copyright 2008-2009 Sun Microsystems, Inc. * Portions Copyright 2011-2015 ForgeRock AS */ package org.opends.guitools.controlpanel.ui; import java.awt.Component; import java.awt.GridBagConstraints; import java.net.URI; import java.security.cert.X509Certificate; import java.util.Iterator; import java.util.LinkedHashSet; import javax.naming.NamingException; import javax.naming.ldap.InitialLdapContext; import javax.swing.JLabel; import javax.swing.JPasswordField; import javax.swing.JTextField; import javax.swing.SwingUtilities; import org.forgerock.i18n.LocalizableMessage; import org.forgerock.i18n.slf4j.LocalizedLogger; import org.opends.admin.ads.util.ApplicationTrustManager; import org.opends.guitools.controlpanel.datamodel.ConfigReadException; import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent; import org.opends.guitools.controlpanel.util.BackgroundTask; import org.opends.guitools.controlpanel.util.Utilities; 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.types.DN; import org.opends.server.util.StaticUtils; import static com.forgerock.opendj.cli.Utils.*; import static org.opends.messages.AdminToolMessages.*; import static org.opends.messages.QuickSetupMessages.*; /** * The panel that appears when the user is asked to provide authentication. */ public class LoginPanel extends StatusGenericPanel { private static final long serialVersionUID = 5051556513294844797L; private JPasswordField pwd; private JTextField dn; private JLabel pwdLabel; private JLabel dnLabel; private String usedUrl; private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); /** * Default constructor. * */ public LoginPanel() { super(); createLayout(); } /** {@inheritDoc} */ @Override public LocalizableMessage getTitle() { return INFO_CTRL_PANEL_LOGIN_PANEL_TITLE.get(); } /** * Creates the layout of the panel (but the contents are not populated here). */ private void createLayout() { GridBagConstraints gbc = new GridBagConstraints(); gbc.anchor = GridBagConstraints.WEST; gbc.gridx = 0; gbc.gridy = 0; gbc.weightx = 0.0; gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; dnLabel = Utilities.createPrimaryLabel(INFO_CTRL_PANEL_BIND_DN_LABEL.get()); add(dnLabel, gbc); gbc.insets.left = 10; gbc.gridx = 1; dn = Utilities.createTextField("cn=Directory Manager", 20); gbc.weightx = 1.0; gbc.fill = GridBagConstraints.HORIZONTAL; add(dn, gbc); gbc.insets.top = 10; gbc.insets.left = 0; gbc.gridx = 0; gbc.gridy ++; gbc.weightx = 0.0; gbc.gridwidth = 1; gbc.fill = GridBagConstraints.NONE; pwdLabel = Utilities.createPrimaryLabel( INFO_CTRL_PANEL_BIND_PASSWORD_LABEL.get()); add(pwdLabel, gbc); gbc.insets.left = 10; gbc.gridx = 1; pwd = Utilities.createPasswordField(); gbc.weightx = 1.0; gbc.fill = GridBagConstraints.HORIZONTAL; add(pwd, gbc); addBottomGlue(gbc); } /** {@inheritDoc} */ @Override public Component getPreferredFocusComponent() { return pwd; } /** {@inheritDoc} */ @Override public void configurationChanged(ConfigurationChangeEvent ev) { } /** {@inheritDoc} */ @Override public void toBeDisplayed(boolean visible) { super.toBeDisplayed(visible); if (visible) { pwd.setText(""); } } /** {@inheritDoc} */ @Override public void okClicked() { setPrimaryValid(dnLabel); setPrimaryValid(pwdLabel); final LinkedHashSet errors = new LinkedHashSet<>(); boolean dnInvalid = false; boolean pwdInvalid = false; if ("".equals(dn.getText().trim())) { dnInvalid = true; errors.add(INFO_EMPTY_DIRECTORY_MANAGER_DN.get()); } else if (!isDN(dn.getText())) { dnInvalid = true; errors.add(INFO_NOT_A_DIRECTORY_MANAGER_DN.get()); } if (pwd.getPassword().length == 0) { pwdInvalid = true; errors.add(INFO_EMPTY_PWD.get()); } if (dnInvalid) { setPrimaryInvalid(dnLabel); } if (pwdInvalid) { setPrimaryInvalid(pwdLabel); } if (errors.isEmpty()) { setEnabledOK(false); setEnabledCancel(false); displayMessage(INFO_CTRL_PANEL_VERIFYING_AUTHENTICATION_SUMMARY.get()); BackgroundTask worker = new BackgroundTask() { /** {@inheritDoc} */ @Override public InitialLdapContext processBackgroundTask() throws Throwable { InitialLdapContext ctx = null; try { usedUrl = getInfo().getAdminConnectorURL(); ctx = Utilities.getAdminDirContext(getInfo(), dn.getText(), String.valueOf(pwd.getPassword())); if (getInfo().getDirContext() != null) { try { getInfo().getDirContext().close(); } catch (Throwable t) { } } if (getInfo().getUserDataDirContext() != null) { try { getInfo().getUserDataDirContext().close(); } catch (Throwable t) { } } try { Thread.sleep(500); } catch (Throwable t) { } SwingUtilities.invokeLater(new Runnable() { @Override public void run() { displayMessage( INFO_CTRL_PANEL_READING_CONFIGURATION_SUMMARY.get()); } }); getInfo().setDirContext(ctx); getInfo().setUserDataDirContext(null); getInfo().regenerateDescriptor(); return ctx; } catch (Throwable t) { StaticUtils.close(ctx); throw t; } } /** {@inheritDoc} */ @Override public void backgroundTaskCompleted(InitialLdapContext ctx, Throwable throwable) { boolean handleCertificateException = false; if (throwable != null) { logger.info(LocalizableMessage.raw("Error connecting: " + throwable, throwable)); if (isCertificateException(throwable)) { ApplicationTrustManager.Cause cause = getInfo().getTrustManager().getLastRefusedCause(); logger.info(LocalizableMessage.raw("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 { LocalizableMessage msg = getThrowableMsg( INFO_ERROR_CONNECTING_TO_LOCAL.get(), throwable); errors.add(msg); } if (excType != null) { String h; int p; try { URI uri = new URI(usedUrl); h = uri.getHost(); p = uri.getPort(); } catch (Throwable t) { logger.warn(LocalizableMessage.raw( "Error parsing ldap url of ldap url.", t)); h = INFO_NOT_AVAILABLE_LABEL.get().toString(); p = -1; } UserDataCertificateException udce = new UserDataCertificateException(null, INFO_CERTIFICATE_EXCEPTION.get(h, p), throwable, h, p, getInfo().getTrustManager().getLastRefusedChain(), getInfo().getTrustManager().getLastRefusedAuthType(), excType); handleCertificateException(udce); handleCertificateException = true; } } else if (throwable instanceof NamingException) { boolean found = false; String providedDn = dn.getText(); Iterator it = getInfo().getServerDescriptor(). getAdministrativeUsers().iterator(); while (it.hasNext() && !found) { found = Utils.areDnsEqual(providedDn, it.next().toString()); } if (!found) { errors.add(INFO_NOT_A_DIRECTORY_MANAGER_IN_CONFIG.get()); } else { errors.add(Utils.getMessageForException( (NamingException)throwable)); } setPrimaryInvalid(dnLabel); setPrimaryInvalid(pwdLabel); } else if (throwable instanceof ConfigReadException) { errors.add(((ConfigReadException)throwable).getMessageObject()); } else { // This is a bug throwable.printStackTrace(); errors.add(getThrowableMsg(INFO_BUG_MSG.get(), throwable)); } } displayMainPanel(); setEnabledCancel(true); setEnabledOK(true); if (!errors.isEmpty()) { displayErrorDialog(errors); pwd.setSelectionStart(0); pwd.setSelectionEnd(pwd.getPassword().length); pwd.requestFocusInWindow(); } else if (!handleCertificateException) { Utilities.getParentDialog(LoginPanel.this).setVisible(false); } } }; worker.startBackgroundTask(); } else { displayErrorDialog(errors); if (dnInvalid) { dn.setSelectionStart(0); dn.setSelectionEnd(dn.getText().length()); dn.requestFocusInWindow(); } if (pwdInvalid) { pwd.setSelectionStart(0); pwd.setSelectionEnd(pwd.getPassword().length); pwd.requestFocusInWindow(); } } } /** {@inheritDoc} */ @Override public void cancelClicked() { setPrimaryValid(dnLabel); setPrimaryValid(pwdLabel); pwd.setText(null); super.cancelClicked(); } /** * 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(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) { logger.info(LocalizableMessage.raw("Accepting certificate presented by host "+host)); getInfo().getTrustManager().acceptCertificate(chain, authType, host); /* Simulate a click on the OK by calling in the okClicked method. */ SwingUtilities.invokeLater(new Runnable() { @Override public void run() { okClicked(); } }); } else { if (chain == null) { logger.warn(LocalizableMessage.raw( "The chain is null for the UserDataCertificateException")); } if (authType == null) { logger.warn(LocalizableMessage.raw( "The auth type is null for the UserDataCertificateException")); } if (host == null) { logger.warn(LocalizableMessage.raw( "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) { logger.warn(LocalizableMessage.raw("Error accepting certificate: "+t, t)); } } } } }