001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2009-2010 Sun Microsystems, Inc. 015 * Portions Copyright 2011-2016 ForgeRock AS. 016 */ 017package org.opends.guitools.controlpanel.ui; 018 019import java.awt.Component; 020import java.awt.GridBagConstraints; 021import java.awt.event.ActionEvent; 022import java.awt.event.ActionListener; 023import java.io.File; 024import java.io.IOException; 025import java.net.URI; 026import java.security.cert.X509Certificate; 027import java.util.ArrayList; 028import java.util.Iterator; 029import java.util.LinkedHashSet; 030 031import javax.naming.NamingEnumeration; 032import javax.naming.NamingException; 033import javax.naming.directory.SearchControls; 034import javax.naming.directory.SearchResult; 035import javax.naming.ldap.InitialLdapContext; 036import javax.swing.Box; 037import javax.swing.DefaultComboBoxModel; 038import javax.swing.JComboBox; 039import javax.swing.JEditorPane; 040import javax.swing.JLabel; 041import javax.swing.JPasswordField; 042import javax.swing.JTextField; 043import javax.swing.SwingUtilities; 044 045import org.forgerock.i18n.LocalizableMessage; 046import org.forgerock.i18n.slf4j.LocalizedLogger; 047import org.forgerock.opendj.ldap.DN; 048import org.opends.admin.ads.util.ApplicationTrustManager; 049import org.opends.admin.ads.util.ConnectionUtils; 050import org.opends.admin.ads.util.ConnectionWrapper; 051import org.opends.guitools.controlpanel.ControlPanelArgumentParser; 052import org.opends.guitools.controlpanel.datamodel.ConfigReadException; 053import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo; 054import org.opends.guitools.controlpanel.datamodel.CustomSearchResult; 055import org.opends.guitools.controlpanel.event.ConfigurationChangeEvent; 056import org.opends.guitools.controlpanel.task.OnlineUpdateException; 057import org.opends.guitools.controlpanel.util.BackgroundTask; 058import org.opends.guitools.controlpanel.util.Utilities; 059import org.opends.quicksetup.Installation; 060import org.opends.quicksetup.UserData; 061import org.opends.quicksetup.UserDataCertificateException; 062import org.opends.quicksetup.ui.CertificateDialog; 063import org.opends.quicksetup.util.UIKeyStore; 064import org.opends.quicksetup.util.Utils; 065import org.opends.server.monitors.VersionMonitorProvider; 066import org.opends.server.types.HostPort; 067import org.opends.server.types.OpenDsException; 068import org.opends.server.util.DynamicConstants; 069import org.opends.server.util.StaticUtils; 070 071import static com.forgerock.opendj.cli.Utils.*; 072 073import static org.opends.admin.ads.util.PreferredConnection.Type.*; 074import static org.opends.guitools.controlpanel.util.Utilities.*; 075import static org.opends.messages.AdminToolMessages.*; 076import static org.opends.messages.QuickSetupMessages.*; 077import static org.opends.server.monitors.VersionMonitorProvider.*; 078 079/** The panel that appears when the user is asked to provide authentication. */ 080public class LocalOrRemotePanel extends StatusGenericPanel 081{ 082 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 083 private static final long serialVersionUID = 5051556513294844797L; 084 085 private JComboBox<LocalizableMessage> combo; 086 private JLabel portLabel; 087 private JTextField hostName; 088 private JTextField port; 089 private JPasswordField pwd; 090 private JTextField dn; 091 private JLabel pwdLabel; 092 private JLabel dnLabel; 093 private String usedUrl; 094 private JLabel localInstallLabel; 095 private JEditorPane localInstall; 096 private JLabel localNotRunning; 097 private boolean isLocalServerRunning; 098 private boolean callOKWhenVisible; 099 100 /** Default constructor. */ 101 public LocalOrRemotePanel() 102 { 103 super(); 104 createLayout(); 105 } 106 107 @Override 108 public LocalizableMessage getTitle() 109 { 110 return INFO_CTRL_PANEL_LOCAL_OR_REMOTE_PANEL_TITLE.get(); 111 } 112 113 @Override 114 public GenericDialog.ButtonType getButtonType() 115 { 116 return GenericDialog.ButtonType.OK_CANCEL; 117 } 118 119 /** 120 * Returns the displayed host name. 121 * @return the displayed host name. 122 */ 123 public String getHostName() 124 { 125 return hostName.getText(); 126 } 127 128 /** 129 * Returns the displayed administration port. 130 * @return the displayed administration port. 131 */ 132 public int getPort() 133 { 134 try 135 { 136 return Integer.valueOf(this.port.getText().trim()); 137 } 138 catch (Exception ignored) 139 { 140 return -1; 141 } 142 } 143 144 /** 145 * Returns the displayed bind DN. 146 * @return the displayed bind DN. 147 */ 148 public String getBindDN() 149 { 150 return dn.getText(); 151 } 152 153 /** 154 * Returns the displayed password. 155 * @return the displayed password. 156 */ 157 public char[] getBindPassword() 158 { 159 return pwd.getPassword(); 160 } 161 162 /** 163 * Returns whether the panel displays the remote or the local server. 164 * @return whether the panel displays the remote or the local server. 165 */ 166 public boolean isRemote() 167 { 168 int index = combo.getSelectedIndex(); 169 return index == 1; 170 } 171 172 /** 173 * Sets the displayed host name. 174 * @param hostName the host name. 175 */ 176 public void setHostName(String hostName) 177 { 178 this.hostName.setText(hostName); 179 } 180 181 /** 182 * Sets the displayed administration port. 183 * @param port the displayed administration port. 184 */ 185 public void setPort(int port) 186 { 187 this.port.setText(String.valueOf(port)); 188 } 189 190 /** 191 * Sets the displayed bind DN. 192 * @param bindDN the displayed bind DN. 193 */ 194 public void setBindDN(String bindDN) 195 { 196 this.dn.setText(bindDN); 197 } 198 199 /** 200 * Sets the displayed password. 201 * @param pwd the password. 202 */ 203 public void setBindPassword(char[] pwd) 204 { 205 this.pwd.setText(new String(pwd)); 206 } 207 208 /** 209 * Sets whether the panel should display the remote or the local server. 210 * @param remote whether the panel should display the remote or the local 211 * server. 212 */ 213 public void setRemote(boolean remote) 214 { 215 int index = remote ? 1 : 0; 216 combo.setSelectedIndex(index); 217 updateComponentState(); 218 } 219 220 /** 221 * Method to be called when we want the panel to call automatically okClicked 222 * method when the panel is made visible. 223 * @param callOKWhenVisible whether okClicked must be called automatically 224 * when the panel is made visible or not. 225 */ 226 public void setCallOKWhenVisible(boolean callOKWhenVisible) 227 { 228 this.callOKWhenVisible = callOKWhenVisible; 229 } 230 231 /** 232 * Returns whether okClicked must be called automatically when the panel is 233 * made visible or not. 234 * @return whether okClicked must be called automatically when the panel is 235 * made visible or not. 236 */ 237 public boolean isCallOKWhenVisible() 238 { 239 return callOKWhenVisible; 240 } 241 242 /** Creates the layout of the panel (but the contents are not populated here). */ 243 private void createLayout() 244 { 245 GridBagConstraints gbc = new GridBagConstraints(); 246 247 gbc.anchor = GridBagConstraints.WEST; 248 gbc.gridx = 0; 249 gbc.gridy = 0; 250 251 gbc.weightx = 0.0; 252 gbc.weighty = 0.0; 253 String localServerInstallPath; 254 File instancePath = Installation.getLocal().getInstanceDirectory(); 255 try 256 { 257 localServerInstallPath = instancePath.getCanonicalPath(); 258 } 259 catch (IOException ioe) 260 { 261 localServerInstallPath = instancePath.getAbsolutePath(); 262 } 263 combo = Utilities.createComboBox(); 264 combo.setModel(new DefaultComboBoxModel<LocalizableMessage>( 265 new LocalizableMessage[] {INFO_CTRL_PANEL_LOCAL_SERVER.get(), 266 INFO_CTRL_PANEL_REMOTE_SERVER.get()})); 267 combo.setSelectedIndex(0); 268 gbc.gridwidth = 2; 269 JLabel l = Utilities.createDefaultLabel( 270 INFO_CTRL_PANEL_LOCAL_OR_REMOTE.get()); 271 add(l, gbc); 272 gbc.gridwidth = 1; 273 gbc.insets.top = 10; 274 gbc.gridy ++; 275 add(combo, gbc); 276 l.setLabelFor(combo); 277 gbc.gridx = 1; 278 279 localNotRunning = Utilities.createDefaultLabel(); 280 Utilities.setWarningLabel(localNotRunning, 281 INFO_CTRL_PANEL_LOCAL_SERVER_NOT_RUNNING.get()); 282 gbc.insets.left = 10; 283 add(localNotRunning, gbc); 284 localNotRunning.setFocusable(true); 285 hostName = Utilities.createMediumTextField(); 286 hostName.setText(UserData.getDefaultHostName()); 287 hostName.setToolTipText( 288 INFO_CTRL_PANEL_REMOTE_SERVER_TOOLTIP.get().toString()); 289 add(hostName, gbc); 290 gbc.insets.top = 10; 291 gbc.gridy ++; 292 gbc.insets.left = 0; 293 gbc.weightx = 0.0; 294 gbc.insets.right = 0; 295 gbc.gridx = 0; 296 297 ActionListener actionListener = new ActionListener() 298 { 299 @Override 300 public void actionPerformed(ActionEvent ev) 301 { 302 updateComponentState(); 303 } 304 }; 305 combo.addActionListener(actionListener); 306 307 gbc.gridx = 0; 308 gbc.gridwidth = 1; 309 310 localInstallLabel = Utilities.createPrimaryLabel( 311 INFO_CTRL_PANEL_INSTANCE_PATH_LABEL.get()); 312 gbc.insets.left = 0; 313 add(localInstallLabel, gbc); 314 gbc.gridx = 1; 315 gbc.insets.left = 10; 316 gbc.fill = GridBagConstraints.HORIZONTAL; 317 gbc.weightx = 0.1; 318 localInstall = Utilities.makeHtmlPane(localServerInstallPath, 319 ColorAndFontConstants.defaultFont); 320 add(localInstall, gbc); 321 localInstallLabel.setLabelFor(localInstall); 322 gbc.gridx ++; 323 gbc.weightx = 1.0; 324 gbc.insets.left = 0; 325 add(Box.createHorizontalGlue(), gbc); 326 327 gbc.gridy ++; 328 gbc.insets.top = 10; 329 gbc.insets.left = 0; 330 gbc.gridx = 0; 331 gbc.weightx = 0.0; 332 portLabel = Utilities.createPrimaryLabel( 333 INFO_CTRL_PANEL_ADMINISTRATION_PORT.get()); 334 add(portLabel, gbc); 335 gbc.gridx = 1; 336 gbc.insets.left = 10; 337 port = Utilities.createMediumTextField(); 338 port.setText(String.valueOf( 339 ControlPanelArgumentParser.getDefaultAdministrationPort())); 340 gbc.weightx = 1.0; 341 gbc.fill = GridBagConstraints.HORIZONTAL; 342 add(port, gbc); 343 portLabel.setLabelFor(port); 344 345 gbc.gridy ++; 346 gbc.gridx = 0; 347 gbc.weightx = 0.0; 348 gbc.fill = GridBagConstraints.NONE; 349 gbc.insets.left = 0; 350 dnLabel = Utilities.createPrimaryLabel(INFO_CTRL_PANEL_BIND_DN_LABEL.get()); 351 add(dnLabel, gbc); 352 gbc.insets.left = 10; 353 gbc.gridx = 1; 354 dn = Utilities.createTextField( 355 ControlPanelArgumentParser.getDefaultBindDN(), 20); 356 gbc.weightx = 1.0; 357 gbc.fill = GridBagConstraints.HORIZONTAL; 358 gbc.insets.left = 10; 359 add(dn, gbc); 360 dnLabel.setLabelFor(dn); 361 gbc.insets.top = 10; 362 gbc.insets.left = 0; 363 364 gbc.gridx = 0; 365 gbc.gridy ++; 366 gbc.weightx = 0.0; 367 gbc.fill = GridBagConstraints.NONE; 368 pwdLabel = Utilities.createPrimaryLabel( 369 INFO_CTRL_PANEL_BIND_PASSWORD_LABEL.get()); 370 gbc.insets.left = 0; 371 add(pwdLabel, gbc); 372 gbc.insets.left = 10; 373 gbc.gridx = 1; 374 pwd = Utilities.createPasswordField(); 375 gbc.weightx = 1.0; 376 gbc.fill = GridBagConstraints.HORIZONTAL; 377 add(pwd, gbc); 378 pwdLabel.setLabelFor(pwd); 379 380 addBottomGlue(gbc); 381 } 382 383 @Override 384 public Component getPreferredFocusComponent() 385 { 386 if (pwd.isVisible()) 387 { 388 return pwd; 389 } 390 return combo; 391 } 392 393 @Override 394 public void configurationChanged(ConfigurationChangeEvent ev) 395 { 396 } 397 398 @Override 399 public void toBeDisplayed(boolean visible) 400 { 401 super.toBeDisplayed(visible); 402 if (visible) 403 { 404 // Do it outside the event thread if the panel requires it. 405 BackgroundTask<Void> worker = new BackgroundTask<Void>() 406 { 407 @Override 408 public Void processBackgroundTask() throws Throwable 409 { 410 StaticUtils.sleep(200); 411 File instancePath = Installation.getLocal().getInstanceDirectory(); 412 isLocalServerRunning = Utilities.isServerRunning(instancePath); 413 return null; 414 } 415 416 @Override 417 public void backgroundTaskCompleted(Void returnValue, 418 Throwable t) 419 { 420 updateComponentState(); 421 displayMainPanel(); 422 Component comp = getPreferredFocusComponent(); 423 if (comp != null) 424 { 425 comp.requestFocusInWindow(); 426 } 427 if (isCallOKWhenVisible()) 428 { 429 okClicked(); 430 } 431 } 432 }; 433 displayMessage(INFO_CTRL_PANEL_LOADING_PANEL_SUMMARY.get()); 434 worker.startBackgroundTask(); 435 if (!isCallOKWhenVisible()) 436 { 437 pwd.setText(""); 438 } 439 } 440 } 441 442 @Override 443 public void okClicked() 444 { 445 setPrimaryValid(portLabel); 446 setPrimaryValid(dnLabel); 447 setPrimaryValid(pwdLabel); 448 final LinkedHashSet<LocalizableMessage> errors = new LinkedHashSet<>(); 449 450 boolean dnInvalid = false; 451 boolean pwdInvalid = false; 452 453 final boolean isLocal = combo.getSelectedIndex() == 0; 454 455 boolean doChecks = !isLocal || isLocalServerRunning; 456 if (doChecks) 457 { 458 if ("".equals(dn.getText().trim())) 459 { 460 dnInvalid = true; 461 errors.add(INFO_EMPTY_DIRECTORY_MANAGER_DN.get()); 462 } 463 else if (!isDN(dn.getText())) 464 { 465 dnInvalid = true; 466 errors.add(INFO_NOT_A_DIRECTORY_MANAGER_DN.get()); 467 } 468 469 if (pwd.getPassword().length == 0) 470 { 471 pwdInvalid = true; 472 errors.add(INFO_EMPTY_PWD.get()); 473 } 474 if (dnInvalid) 475 { 476 setPrimaryInvalid(dnLabel); 477 } 478 479 if (pwdInvalid) 480 { 481 setPrimaryInvalid(pwdLabel); 482 } 483 484 if (!isLocal) 485 { 486 if ("".equals(hostName.getText().trim())) 487 { 488 errors.add(INFO_EMPTY_REMOTE_HOST_NAME.get()); 489 } 490 491 try 492 { 493 int p = Integer.parseInt(port.getText()); 494 if (p <= 0 || p > 65535) 495 { 496 errors.add(INFO_INVALID_REMOTE_SERVER_PORT.get(0, 65535)); 497 } 498 } 499 catch (Throwable t) 500 { 501 errors.add(INFO_INVALID_REMOTE_SERVER_PORT.get(0, 65535)); 502 } 503 } 504 } 505 506 if (errors.isEmpty()) 507 { 508 setEnabledOK(false); 509 displayMessage(INFO_CTRL_PANEL_VERIFYING_AUTHENTICATION_SUMMARY.get()); 510 511 BackgroundTask<ConnectionWrapper> worker = new BackgroundTask<ConnectionWrapper>() 512 { 513 @Override 514 public ConnectionWrapper processBackgroundTask() throws Throwable 515 { 516 final ControlPanelInfo info = getInfo(); 517 info.stopPooling(); 518 if (isLocal) 519 { 520 // At least load the local information. 521 SwingUtilities.invokeLater(new Runnable() 522 { 523 @Override 524 public void run() 525 { 526 displayMessage( 527 INFO_CTRL_PANEL_READING_CONFIGURATION_SUMMARY.get()); 528 } 529 }); 530 if (info.isLocal() != isLocal) 531 { 532 closeInfoConnections(); 533 } 534 info.setIsLocal(isLocal); 535 info.regenerateDescriptor(); 536 if (!isLocalServerRunning) 537 { 538 return null; 539 } 540 } 541 ConnectionWrapper conn = null; 542 try 543 { 544 if (isLocal) 545 { 546 usedUrl = info.getAdminConnectorURL(); 547 conn = Utilities.getAdminDirContext(info, dn.getText(), String.valueOf(pwd.getPassword())); 548 } 549 else 550 { 551 HostPort hostPort = new HostPort(hostName.getText().trim(), Integer.valueOf(port.getText().trim())); 552 usedUrl = ConnectionUtils.getLDAPUrl(hostPort, true); 553 conn = new ConnectionWrapper(hostPort, LDAPS, dn.getText(), String.valueOf(pwd.getPassword()), 554 info.getConnectTimeout(), info.getTrustManager()); 555 checkVersion(conn.getLdapContext()); 556 } 557 558 StaticUtils.sleep(500); 559 SwingUtilities.invokeLater(new Runnable() 560 { 561 @Override 562 public void run() 563 { 564 displayMessage(INFO_CTRL_PANEL_READING_CONFIGURATION_SUMMARY.get()); 565 } 566 }); 567 closeInfoConnections(); 568 info.setIsLocal(isLocal); 569 info.setConnection(conn); 570 info.setUserDataDirContext(null); 571 info.regenerateDescriptor(); 572 return conn; 573 } catch (Throwable t) 574 { 575 StaticUtils.close(conn); 576 throw t; 577 } 578 } 579 580 @Override 581 public void backgroundTaskCompleted(ConnectionWrapper conn, Throwable throwable) 582 { 583 boolean handleCertificateException = false; 584 boolean localServerErrorConnecting = false; 585 586 if (throwable != null) 587 { 588 logger.info(LocalizableMessage.raw("Error connecting: " + throwable, throwable)); 589 590 final ControlPanelInfo info = getInfo(); 591 if (isVersionException(throwable)) 592 { 593 errors.add(((OpenDsException)throwable).getMessageObject()); 594 } 595 else if (isCertificateException(throwable)) 596 { 597 ApplicationTrustManager.Cause cause = 598 info.getTrustManager().getLastRefusedCause(); 599 600 logger.info(LocalizableMessage.raw("Certificate exception cause: "+cause)); 601 UserDataCertificateException.Type excType = null; 602 if (cause == ApplicationTrustManager.Cause.NOT_TRUSTED) 603 { 604 excType = UserDataCertificateException.Type.NOT_TRUSTED; 605 } 606 else if (cause == ApplicationTrustManager.Cause.HOST_NAME_MISMATCH) 607 { 608 excType = UserDataCertificateException.Type.HOST_NAME_MISMATCH; 609 } 610 else 611 { 612 errors.add(getThrowableMsg(INFO_ERROR_CONNECTING_TO_LOCAL.get(), throwable)); 613 } 614 615 if (excType != null) 616 { 617 String h; 618 int p; 619 try 620 { 621 URI uri = new URI(usedUrl); 622 h = uri.getHost(); 623 p = uri.getPort(); 624 } 625 catch (Throwable t) 626 { 627 logger.warn(LocalizableMessage.raw( 628 "Error parsing ldap url of ldap url.", t)); 629 h = INFO_NOT_AVAILABLE_LABEL.get().toString(); 630 p = -1; 631 } 632 ApplicationTrustManager trustMgr = info.getTrustManager(); 633 UserDataCertificateException udce = 634 new UserDataCertificateException(null, 635 INFO_CERTIFICATE_EXCEPTION.get(h, p), 636 throwable, h, p, 637 trustMgr.getLastRefusedChain(), 638 trustMgr.getLastRefusedAuthType(), 639 excType); 640 641 handleCertificateException(udce); 642 handleCertificateException = true; 643 } 644 } 645 else if (throwable instanceof NamingException) 646 { 647 boolean found = false; 648 String providedDn = dn.getText(); 649 if (isLocal) 650 { 651 Iterator<DN> it = info.getServerDescriptor(). 652 getAdministrativeUsers().iterator(); 653 while (it.hasNext() && !found) 654 { 655 found = Utils.areDnsEqual(providedDn, it.next().toString()); 656 } 657 if (!found) 658 { 659 errors.add(INFO_NOT_A_DIRECTORY_MANAGER_IN_CONFIG.get()); 660 } 661 else 662 { 663 errors.add(Utils.getMessageForException( 664 (NamingException)throwable)); 665 } 666 localServerErrorConnecting = true; 667 } 668 else 669 { 670 HostPort hostPort = new HostPort( 671 hostName.getText().trim(), 672 Integer.valueOf(port.getText().trim())); 673 NamingException ne = (NamingException)throwable; 674 errors.add(getMessageForException(ne, hostPort.toString())); 675 setPrimaryInvalid(portLabel); 676 } 677 setPrimaryInvalid(dnLabel); 678 setPrimaryInvalid(pwdLabel); 679 } 680 else if (throwable instanceof ConfigReadException) 681 { 682 logger.warn(LocalizableMessage.raw( 683 "Error reading configuration: "+throwable, throwable)); 684 errors.add(((ConfigReadException)throwable).getMessageObject()); 685 } 686 else 687 { 688 // This is a bug 689 logger.error(LocalizableMessage.raw( 690 "Unexpected error: "+throwable, throwable)); 691 errors.add(getThrowableMsg(INFO_BUG_MSG.get(), throwable)); 692 } 693 } 694 displayMainPanel(); 695 setEnabledOK(true); 696 if (!errors.isEmpty()) 697 { 698 if (!localServerErrorConnecting) 699 { 700 displayErrorDialog(errors); 701 } 702 else 703 { 704 ArrayList<String> stringErrors = new ArrayList<>(); 705 for (LocalizableMessage err : errors) 706 { 707 stringErrors.add(err.toString()); 708 } 709 String msg = Utilities.getStringFromCollection(stringErrors, 710 "<br>"); 711 if (displayConfirmationDialog( 712 INFO_CTRL_PANEL_CONFIRMATION_REQUIRED_SUMMARY.get(), 713 INFO_CTRL_PANEL_ERROR_CONNECTING_TO_LOCAL.get(msg))) 714 { 715 Utilities.getParentDialog( 716 LocalOrRemotePanel.this).setVisible(false); 717 } 718 } 719 pwd.setSelectionStart(0); 720 pwd.setSelectionEnd(pwd.getPassword().length); 721 pwd.requestFocusInWindow(); 722 } 723 else if (!handleCertificateException) 724 { 725 Utilities.getParentDialog( 726 LocalOrRemotePanel.this).setVisible(false); 727 } 728 729 if (!handleCertificateException) 730 { 731 startPooling(); 732 } 733 } 734 }; 735 worker.startBackgroundTask(); 736 } 737 else 738 { 739 displayErrorDialog(errors); 740 if (dnInvalid) 741 { 742 dn.setSelectionStart(0); 743 dn.setSelectionEnd(dn.getText().length()); 744 dn.requestFocusInWindow(); 745 } 746 if (pwdInvalid) 747 { 748 pwd.setSelectionStart(0); 749 pwd.setSelectionEnd(pwd.getPassword().length); 750 pwd.requestFocusInWindow(); 751 } 752 } 753 } 754 755 @Override 756 public void cancelClicked() 757 { 758 setPrimaryValid(dnLabel); 759 setPrimaryValid(pwdLabel); 760 setPrimaryValid(portLabel); 761 pwd.setText(null); 762 super.cancelClicked(); 763 } 764 765 /** 766 * Displays a dialog asking the user to accept a certificate if the user 767 * accepts it, we update the trust manager and simulate a click on "OK" to 768 * re-check the authentication. 769 * This method assumes that we are being called from the event thread. 770 */ 771 private void handleCertificateException(UserDataCertificateException ce) 772 { 773 CertificateDialog dlg = new CertificateDialog(null, ce); 774 dlg.pack(); 775 Utilities.centerGoldenMean(dlg, Utilities.getParentDialog(this)); 776 dlg.setVisible(true); 777 if (dlg.getUserAnswer() != 778 CertificateDialog.ReturnType.NOT_ACCEPTED) 779 { 780 X509Certificate[] chain = ce.getChain(); 781 String authType = ce.getAuthType(); 782 String host = ce.getHost(); 783 784 if (chain != null && authType != null && host != null) 785 { 786 logger.info(LocalizableMessage.raw("Accepting certificate presented by host "+host)); 787 getInfo().getTrustManager().acceptCertificate(chain, authType, host); 788 /* Simulate a click on the OK by calling in the okClicked method. */ 789 SwingUtilities.invokeLater(new Runnable() 790 { 791 @Override 792 public void run() 793 { 794 okClicked(); 795 } 796 }); 797 } 798 else 799 { 800 if (chain == null) 801 { 802 logger.warn(LocalizableMessage.raw( 803 "The chain is null for the UserDataCertificateException")); 804 } 805 if (authType == null) 806 { 807 logger.warn(LocalizableMessage.raw( 808 "The auth type is null for the UserDataCertificateException")); 809 } 810 if (host == null) 811 { 812 logger.warn(LocalizableMessage.raw( 813 "The host is null for the UserDataCertificateException")); 814 } 815 } 816 } 817 if (dlg.getUserAnswer() == 818 CertificateDialog.ReturnType.ACCEPTED_PERMANENTLY) 819 { 820 X509Certificate[] chain = ce.getChain(); 821 if (chain != null) 822 { 823 try 824 { 825 UIKeyStore.acceptCertificate(chain); 826 } 827 catch (Throwable t) 828 { 829 logger.warn(LocalizableMessage.raw("Error accepting certificate: "+t, t)); 830 } 831 } 832 } 833 } 834 835 private void updateComponentState() 836 { 837 boolean isLocal = combo.getSelectedIndex() == 0; 838 hostName.setVisible(!isLocal); 839 port.setVisible(!isLocal); 840 portLabel.setVisible(!isLocal); 841 localInstall.setVisible(isLocal); 842 localInstallLabel.setVisible(isLocal); 843 844 boolean displayAuthentication = !isLocal || isLocalServerRunning; 845 dn.setVisible(displayAuthentication); 846 dnLabel.setVisible(displayAuthentication); 847 pwd.setVisible(displayAuthentication); 848 pwdLabel.setVisible(displayAuthentication); 849 850 localNotRunning.setVisible(isLocal && !isLocalServerRunning); 851 } 852 853 private void startPooling() 854 { 855 // The server descriptor has been already retrieved. 856 // startPooling tries to retrieve immediately the server descriptor, so 857 // sleep the pooling period before calling it. 858 Thread t = new Thread(new Runnable() 859 { 860 @Override 861 public void run() 862 { 863 StaticUtils.sleep(getInfo().getPoolingPeriod()); 864 getInfo().startPooling(); 865 } 866 }); 867 t.start(); 868 } 869 870 private void checkVersion(InitialLdapContext ctx) throws OpenDsException 871 { 872 LocalizableMessage msg = null; 873 try 874 { 875 // Search for the version on the remote server. 876 SearchControls searchControls = new SearchControls(); 877 searchControls.setSearchScope( 878 SearchControls.OBJECT_SCOPE); 879 searchControls.setReturningAttributes( 880 new String[] { 881 VersionMonitorProvider.ATTR_PRODUCT_NAME, 882 VersionMonitorProvider.ATTR_MAJOR_VERSION, 883 VersionMonitorProvider.ATTR_POINT_VERSION, 884 VersionMonitorProvider.ATTR_MINOR_VERSION 885 }); 886 NamingEnumeration<SearchResult> en = 887 ctx.search("cn=Version,cn=monitor", "objectclass=*", searchControls); 888 SearchResult sr = null; 889 try 890 { 891 while (en.hasMore()) 892 { 893 sr = en.next(); 894 } 895 } 896 finally 897 { 898 en.close(); 899 } 900 901 CustomSearchResult csr = new CustomSearchResult(sr, "cn=Version,cn=monitor"); 902 903 String hostName = ConnectionUtils.getHostName(ctx); 904 905 String productName = getFirstValueAsString(csr, ATTR_PRODUCT_NAME); 906 String major = getFirstValueAsString(csr, ATTR_MAJOR_VERSION); 907 String point = getFirstValueAsString(csr, ATTR_POINT_VERSION); 908 String minor = getFirstValueAsString(csr, ATTR_MINOR_VERSION); 909 // Be strict, control panel is only compatible with exactly the same version 910 if (!productName.equalsIgnoreCase(DynamicConstants.PRODUCT_NAME)) 911 { 912 msg = ERR_NOT_SAME_PRODUCT_IN_REMOTE_SERVER_NOT_FOUND.get(hostName, 913 productName, DynamicConstants.PRODUCT_NAME); 914 } 915 else if (!String.valueOf(DynamicConstants.MAJOR_VERSION).equals(major) 916 || !String.valueOf(DynamicConstants.MINOR_VERSION).equals(minor) 917 || !String.valueOf(DynamicConstants.POINT_VERSION).equals(point)) 918 { 919 msg = ERR_INCOMPATIBLE_VERSION_IN_REMOTE_SERVER.get(hostName, 920 major, minor, point, DynamicConstants.MAJOR_VERSION, 921 DynamicConstants.MINOR_VERSION, DynamicConstants.POINT_VERSION); 922 } 923 } 924 catch (Throwable t) 925 { 926 msg = ERR_VERSION_IN_REMOTE_SERVER_NOT_FOUND.get(); 927 } 928 if (msg != null) 929 { 930 throw new OnlineUpdateException(msg, null); 931 } 932 } 933 934 private boolean isVersionException(Throwable t) 935 { 936 if (t instanceof OpenDsException) 937 { 938 OpenDsException oe = (OpenDsException)t; 939 if (oe.getMessageObject() != null) 940 { 941 LocalizableMessage msg = oe.getMessageObject(); 942 if (StaticUtils.hasDescriptor(msg, ERR_INCOMPATIBLE_VERSION_IN_REMOTE_SERVER) || 943 StaticUtils.hasDescriptor(msg, ERR_VERSION_IN_REMOTE_SERVER_NOT_FOUND) || 944 StaticUtils.hasDescriptor(msg, ERR_NOT_SAME_PRODUCT_IN_REMOTE_SERVER_NOT_FOUND)) 945 { 946 return true; 947 } 948 } 949 } 950 return false; 951 } 952 953 private void closeInfoConnections() 954 { 955 StaticUtils.close(getInfo().getConnection()); 956 StaticUtils.close(getInfo().getUserDataDirContext()); 957 } 958}