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