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 2007-2010 Sun Microsystems, Inc. 015 * Portions Copyright 2011-2016 ForgeRock AS. 016 */ 017package org.opends.server.admin.client.cli; 018 019import static com.forgerock.opendj.cli.ReturnCode.*; 020import static com.forgerock.opendj.cli.Utils.*; 021import static com.forgerock.opendj.cli.CommonArguments.*; 022import static org.opends.messages.ToolMessages.*; 023import static org.opends.messages.AdminToolMessages.*; 024 025import java.io.File; 026import java.io.FileInputStream; 027import java.io.IOException; 028import java.net.InetAddress; 029import java.security.KeyStore; 030import java.security.KeyStoreException; 031import java.security.NoSuchAlgorithmException; 032import java.security.cert.CertificateException; 033import java.util.ArrayList; 034import java.util.LinkedHashSet; 035import java.util.List; 036import java.util.Set; 037 038import com.forgerock.opendj.cli.ArgumentParser; 039import org.forgerock.i18n.LocalizableMessage; 040import org.forgerock.i18n.LocalizableMessageBuilder; 041import org.forgerock.i18n.LocalizableMessageDescriptor.Arg1; 042import org.forgerock.i18n.slf4j.LocalizedLogger; 043import org.forgerock.opendj.config.server.ConfigException; 044import org.opends.admin.ads.util.ApplicationTrustManager; 045import org.opends.server.admin.AdministrationConnector; 046import org.opends.server.admin.server.ServerManagementContext; 047import org.opends.server.admin.std.server.AdministrationConnectorCfg; 048import org.opends.server.admin.std.server.FileBasedTrustManagerProviderCfg; 049import org.opends.server.admin.std.server.RootCfg; 050import org.opends.server.admin.std.server.TrustManagerProviderCfg; 051import org.opends.server.core.DirectoryServer; 052 053import com.forgerock.opendj.cli.Argument; 054import com.forgerock.opendj.cli.ArgumentException; 055import com.forgerock.opendj.cli.BooleanArgument; 056import com.forgerock.opendj.cli.CliConstants; 057import com.forgerock.opendj.cli.FileBasedArgument; 058import com.forgerock.opendj.cli.IntegerArgument; 059import com.forgerock.opendj.cli.StringArgument; 060 061/** 062 * This is a commodity class that can be used to check the arguments required to 063 * establish a secure connection in the command line. It can be used to generate 064 * an ApplicationTrustManager object based on the options provided by the user 065 * in the command line. 066 */ 067public final class SecureConnectionCliArgs 068{ 069 private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass(); 070 071 private StringArgument hostNameArg; 072 private IntegerArgument portArg; 073 private StringArgument bindDnArg; 074 private StringArgument adminUidArg; 075 private FileBasedArgument bindPasswordFileArg; 076 private StringArgument bindPasswordArg; 077 private BooleanArgument trustAllArg; 078 private StringArgument trustStorePathArg; 079 private StringArgument trustStorePasswordArg; 080 private FileBasedArgument trustStorePasswordFileArg; 081 private StringArgument keyStorePathArg; 082 private StringArgument keyStorePasswordArg; 083 private FileBasedArgument keyStorePasswordFileArg; 084 private StringArgument certNicknameArg; 085 private BooleanArgument useSSLArg; 086 private BooleanArgument useStartTLSArg; 087 private StringArgument saslOptionArg; 088 private IntegerArgument connectTimeoutArg; 089 090 /** Private container for global arguments. */ 091 private Set<Argument> argList; 092 093 /** The trust manager. */ 094 private ApplicationTrustManager trustManager; 095 096 private boolean configurationInitialized; 097 098 /** Defines if the CLI always use the SSL connection type. */ 099 private boolean alwaysSSL; 100 101 /** 102 * Creates a new instance of secure arguments. 103 * 104 * @param alwaysSSL 105 * If true, always use the SSL connection type. In this case, the 106 * arguments useSSL and startTLS are not present. 107 */ 108 public SecureConnectionCliArgs(boolean alwaysSSL) 109 { 110 this.alwaysSSL = alwaysSSL; 111 } 112 113 /** 114 * Indicates whether or not any of the arguments are present. 115 * 116 * @return boolean where true indicates that at least one of the arguments is 117 * present 118 */ 119 public boolean argumentsPresent() 120 { 121 if (argList != null) 122 { 123 for (Argument arg : argList) 124 { 125 if (arg.isPresent()) 126 { 127 return true; 128 } 129 } 130 } 131 return false; 132 } 133 134 /** 135 * Get the admin UID which has to be used for the command. 136 * 137 * @return The admin UID specified by the command line argument, or the 138 * default value, if not specified. 139 */ 140 public String getAdministratorUID() 141 { 142 if (adminUidArg.isPresent()) 143 { 144 return adminUidArg.getValue(); 145 } 146 return adminUidArg.getDefaultValue(); 147 } 148 149 /** 150 * Get the bindDN which has to be used for the command. 151 * 152 * @return The bindDN specified by the command line argument, or the default 153 * value, if not specified. 154 */ 155 public String getBindDN() 156 { 157 if (bindDnArg.isPresent()) 158 { 159 return bindDnArg.getValue(); 160 } 161 return bindDnArg.getDefaultValue(); 162 } 163 164 /** 165 * Initialize Global option. 166 * 167 * @throws ArgumentException 168 * If there is a problem with any of the parameters used to create 169 * this argument. 170 * @return a ArrayList with the options created. 171 */ 172 public Set<Argument> createGlobalArguments() throws ArgumentException 173 { 174 argList = new LinkedHashSet<>(); 175 176 useSSLArg = useSSLArgument(); 177 if (!alwaysSSL) 178 { 179 argList.add(useSSLArg); 180 } 181 else 182 { 183 // simulate that the useSSL arg has been given in the CLI 184 useSSLArg.setPresent(true); 185 } 186 187 useStartTLSArg = startTLSArgument(); 188 if (!alwaysSSL) 189 { 190 argList.add(useStartTLSArg); 191 } 192 193 hostNameArg = hostNameArgument(getDefaultHostName()); 194 argList.add(hostNameArg); 195 196 portArg = createPortArgument(AdministrationConnector.DEFAULT_ADMINISTRATION_CONNECTOR_PORT); 197 argList.add(portArg); 198 199 bindDnArg = bindDNArgument(CliConstants.DEFAULT_ROOT_USER_DN); 200 argList.add(bindDnArg); 201 202 // Classes that required admin UID to be not hidden must call createVisibleAdminUidArgument(localizedDescription) 203 adminUidArg = adminUidHiddenArgument(INFO_DESCRIPTION_ADMIN_UID.get()); 204 205 bindPasswordArg = bindPasswordArgument(); 206 argList.add(bindPasswordArg); 207 208 bindPasswordFileArg = bindPasswordFileArgument(); 209 argList.add(bindPasswordFileArg); 210 211 saslOptionArg = saslArgument(); 212 argList.add(saslOptionArg); 213 214 trustAllArg = trustAllArgument(); 215 argList.add(trustAllArg); 216 217 trustStorePathArg = trustStorePathArgument(); 218 argList.add(trustStorePathArg); 219 220 trustStorePasswordArg = trustStorePasswordArgument(); 221 argList.add(trustStorePasswordArg); 222 223 trustStorePasswordFileArg = trustStorePasswordFileArgument(); 224 argList.add(trustStorePasswordFileArg); 225 226 keyStorePathArg = keyStorePathArgument(); 227 argList.add(keyStorePathArg); 228 229 keyStorePasswordArg = keyStorePasswordArgument(); 230 argList.add(keyStorePasswordArg); 231 232 keyStorePasswordFileArg = keyStorePasswordFileArgument(); 233 argList.add(keyStorePasswordFileArg); 234 235 certNicknameArg = certNickNameArgument(); 236 argList.add(certNicknameArg); 237 238 connectTimeoutArg = connectTimeOutArgument(); 239 argList.add(connectTimeoutArg); 240 241 return argList; 242 } 243 244 /** 245 * Get the host name which has to be used for the command. 246 * 247 * @return The host name specified by the command line argument, or the 248 * default value, if not specified. 249 */ 250 public String getHostName() 251 { 252 if (hostNameArg.isPresent()) 253 { 254 return hostNameArg.getValue(); 255 } 256 return hostNameArg.getDefaultValue(); 257 } 258 259 /** 260 * Returns the current hostname. 261 * 262 * If the hostname resolution fails, this method returns {@literal "localhost"}. 263 * @return the current hostname 264 */ 265 public String getDefaultHostName() { 266 try 267 { 268 return InetAddress.getLocalHost().getHostName(); 269 } 270 catch (Exception e) 271 { 272 return "localhost"; 273 } 274 } 275 276 /** 277 * Get the port which has to be used for the command. 278 * 279 * @return The port specified by the command line argument, or the default 280 * value, if not specified. 281 */ 282 public String getPort() 283 { 284 if (portArg.isPresent()) 285 { 286 return portArg.getValue(); 287 } 288 return portArg.getDefaultValue(); 289 } 290 291 /** 292 * Indication if provided global options are validate. 293 * 294 * @param buf 295 * the LocalizableMessageBuilder to write the error messages. 296 * @return return code. 297 */ 298 public int validateGlobalOptions(LocalizableMessageBuilder buf) 299 { 300 final List<LocalizableMessage> errors = new ArrayList<>(); 301 addErrorMessageIfArgumentsConflict(errors, bindPasswordArg, bindPasswordFileArg); 302 addErrorMessageIfArgumentsConflict(errors, trustAllArg, trustStorePathArg); 303 addErrorMessageIfArgumentsConflict(errors, trustAllArg, trustStorePasswordArg); 304 addErrorMessageIfArgumentsConflict(errors, trustAllArg, trustStorePasswordFileArg); 305 addErrorMessageIfArgumentsConflict(errors, trustStorePasswordArg, trustStorePasswordFileArg); 306 addErrorMessageIfArgumentsConflict(errors, useStartTLSArg, useSSLArg); 307 308 checkIfPathArgumentIsReadable(errors, trustStorePathArg, ERR_CANNOT_READ_TRUSTSTORE); 309 checkIfPathArgumentIsReadable(errors, keyStorePathArg, ERR_CANNOT_READ_KEYSTORE); 310 311 if (!errors.isEmpty()) 312 { 313 for (LocalizableMessage error : errors) 314 { 315 if (buf.length() > 0) 316 { 317 buf.append(LINE_SEPARATOR); 318 } 319 buf.append(error); 320 } 321 return CONFLICTING_ARGS.get(); 322 } 323 324 return SUCCESS.get(); 325 } 326 327 private void checkIfPathArgumentIsReadable(List<LocalizableMessage> errors, StringArgument pathArg, Arg1<Object> msg) 328 { 329 if (pathArg.isPresent() && !canRead(pathArg.getValue())) 330 { 331 errors.add(msg.get(pathArg.getValue())); 332 } 333 } 334 335 /** 336 * Indicate if the SSL mode is always used. 337 * 338 * @return True if SSL mode is always used. 339 */ 340 public boolean alwaysSSL() 341 { 342 return alwaysSSL; 343 } 344 345 /** 346 * Handle TrustStore. 347 * 348 * @return The trustStore manager to be used for the command. 349 */ 350 public ApplicationTrustManager getTrustManager() 351 { 352 if (trustManager == null) 353 { 354 KeyStore truststore = null; 355 if (trustAllArg.isPresent()) 356 { 357 // Running a null TrustManager will force createLdapsContext and 358 // createStartTLSContext to use a bindTrustManager. 359 return null; 360 } 361 else if (trustStorePathArg.isPresent()) 362 { 363 try (final FileInputStream fos = new FileInputStream(trustStorePathArg.getValue())) 364 { 365 String trustStorePasswordStringValue = null; 366 if (trustStorePasswordArg.isPresent()) 367 { 368 trustStorePasswordStringValue = trustStorePasswordArg.getValue(); 369 } 370 else if (trustStorePasswordFileArg.isPresent()) 371 { 372 trustStorePasswordStringValue = trustStorePasswordFileArg.getValue(); 373 } 374 375 if (trustStorePasswordStringValue != null) 376 { 377 trustStorePasswordStringValue = System.getProperty("javax.net.ssl.trustStorePassword"); 378 } 379 380 char[] trustStorePasswordValue = null; 381 if (trustStorePasswordStringValue != null) 382 { 383 trustStorePasswordValue = trustStorePasswordStringValue.toCharArray(); 384 } 385 386 truststore = KeyStore.getInstance(KeyStore.getDefaultType()); 387 truststore.load(fos, trustStorePasswordValue); 388 } 389 catch (KeyStoreException | NoSuchAlgorithmException | CertificateException | IOException e) 390 { 391 // Nothing to do: if this occurs we will systematically refuse the 392 // certificates. Maybe we should avoid this and be strict, but we 393 // are in a best effort mode. 394 logger.warn(LocalizableMessage.raw("Error with the truststore"), e); 395 } 396 } 397 trustManager = new ApplicationTrustManager(truststore); 398 } 399 return trustManager; 400 } 401 402 /** 403 * Returns {@code true} if we can read on the provided path and {@code false} 404 * otherwise. 405 * 406 * @param path 407 * the path. 408 * @return {@code true} if we can read on the provided path and {@code false} 409 * otherwise. 410 */ 411 private boolean canRead(String path) 412 { 413 final File file = new File(path); 414 return file.exists() && file.canRead(); 415 } 416 417 /** 418 * Returns the absolute path of the trust store file that appears on the 419 * config. Returns {@code null} if the trust store is not defined or it does 420 * not exist. 421 * 422 * @return the absolute path of the trust store file that appears on the 423 * config. 424 * @throws ConfigException 425 * if there is an error reading the configuration. 426 */ 427 public String getTruststoreFileFromConfig() throws ConfigException 428 { 429 String truststoreFileAbsolute = null; 430 TrustManagerProviderCfg trustManagerCfg = null; 431 AdministrationConnectorCfg administrationConnectorCfg = null; 432 433 boolean couldInitializeConfig = configurationInitialized; 434 // Initialization for admin framework 435 if (!configurationInitialized) 436 { 437 couldInitializeConfig = initializeConfiguration(); 438 } 439 if (couldInitializeConfig) 440 { 441 // Get the Directory Server configuration handler and use it. 442 RootCfg root = ServerManagementContext.getInstance().getRootConfiguration(); 443 administrationConnectorCfg = root.getAdministrationConnector(); 444 445 String trustManagerStr = administrationConnectorCfg.getTrustManagerProvider(); 446 trustManagerCfg = root.getTrustManagerProvider(trustManagerStr); 447 if (trustManagerCfg instanceof FileBasedTrustManagerProviderCfg) 448 { 449 FileBasedTrustManagerProviderCfg fileBasedTrustManagerCfg = (FileBasedTrustManagerProviderCfg) trustManagerCfg; 450 String truststoreFile = fileBasedTrustManagerCfg.getTrustStoreFile(); 451 // Check the file 452 if (truststoreFile.startsWith(File.separator)) 453 { 454 truststoreFileAbsolute = truststoreFile; 455 } 456 else 457 { 458 truststoreFileAbsolute = DirectoryServer.getInstanceRoot() + File.separator + truststoreFile; 459 } 460 File f = new File(truststoreFileAbsolute); 461 if (!f.exists() || !f.canRead() || f.isDirectory()) 462 { 463 truststoreFileAbsolute = null; 464 } 465 else 466 { 467 // Try to get the canonical path. 468 try 469 { 470 truststoreFileAbsolute = f.getCanonicalPath(); 471 } 472 catch (Throwable t) 473 { 474 // We can ignore this error. 475 } 476 } 477 } 478 } 479 return truststoreFileAbsolute; 480 } 481 482 /** 483 * Returns the admin port from the configuration. 484 * 485 * @return the admin port from the configuration. 486 * @throws ConfigException 487 * if an error occurs reading the configuration. 488 */ 489 public int getAdminPortFromConfig() throws ConfigException 490 { 491 // Initialization for admin framework 492 boolean couldInitializeConfiguration = configurationInitialized; 493 if (!configurationInitialized) 494 { 495 couldInitializeConfiguration = initializeConfiguration(); 496 } 497 if (couldInitializeConfiguration) 498 { 499 RootCfg root = ServerManagementContext.getInstance().getRootConfiguration(); 500 return root.getAdministrationConnector().getListenPort(); 501 } 502 else 503 { 504 return AdministrationConnector.DEFAULT_ADMINISTRATION_CONNECTOR_PORT; 505 } 506 } 507 508 private boolean initializeConfiguration() 509 { 510 // check if the initialization is required 511 try 512 { 513 ServerManagementContext.getInstance().getRootConfiguration().getAdministrationConnector(); 514 } 515 catch (java.lang.Throwable th) 516 { 517 try 518 { 519 DirectoryServer.bootstrapClient(); 520 DirectoryServer.initializeJMX(); 521 DirectoryServer.getInstance().initializeConfiguration(); 522 } 523 catch (Exception ex) 524 { 525 // do nothing 526 return false; 527 } 528 } 529 configurationInitialized = true; 530 return true; 531 } 532 533 /** 534 * Returns the port to be used according to the configuration and the 535 * arguments provided by the user. This method should be called after the 536 * arguments have been parsed. 537 * 538 * @return the port to be used according to the configuration and the 539 * arguments provided by the user. 540 */ 541 public int getPortFromConfig() 542 { 543 int portNumber; 544 if (alwaysSSL()) 545 { 546 portNumber = AdministrationConnector.DEFAULT_ADMINISTRATION_CONNECTOR_PORT; 547 // Try to get the port from the config file 548 try 549 { 550 portNumber = getAdminPortFromConfig(); 551 } 552 catch (ConfigException ex) 553 { 554 // Nothing to do 555 } 556 } 557 else 558 { 559 portNumber = CliConstants.DEFAULT_SSL_PORT; 560 } 561 return portNumber; 562 } 563 564 /** 565 * Updates the default values of the port and the trust store with what is 566 * read in the configuration. 567 * 568 * @param parser 569 * The argument parser where the secure connection arguments were added. 570 */ 571 public void initArgumentsWithConfiguration(final ArgumentParser parser) { 572 try 573 { 574 portArg = createPortArgument(getPortFromConfig()); 575 trustStorePathArg = trustStorePathArgument(getTruststoreFileFromConfig()); 576 parser.replaceArgument(portArg); 577 parser.replaceArgument(trustStorePathArg); 578 } 579 catch (ConfigException | ArgumentException e) 580 { 581 logger.error(LocalizableMessage.raw( 582 "Internal error while reading arguments of this program from configuration"), e); 583 } 584 } 585 586 /** 587 * Replace the admin UID argument by a non hidden one. 588 * 589 * @param description 590 * The localized description for the non hidden admin UID argument. 591 */ 592 public void createVisibleAdminUidArgument(final LocalizableMessage description) 593 { 594 try 595 { 596 this.adminUidArg = adminUid(description); 597 } 598 catch (final ArgumentException unexpected) 599 { 600 throw new RuntimeException("Unexpected"); 601 } 602 } 603 604 private IntegerArgument createPortArgument(final int defaultValue) throws ArgumentException 605 { 606 return portArgument( 607 defaultValue, alwaysSSL ? INFO_DESCRIPTION_ADMIN_PORT.get() : INFO_DESCRIPTION_PORT.get()); 608 } 609 610 /** 611 * Return the 'keyStore' global argument. 612 * 613 * @return The 'keyStore' global argument. 614 */ 615 public StringArgument getKeyStorePathArg() { 616 return keyStorePathArg; 617 } 618 619 /** 620 * Return the 'hostName' global argument. 621 * 622 * @return The 'hostName' global argument. 623 */ 624 public StringArgument getHostNameArg() { 625 return hostNameArg; 626 } 627 628 /** 629 * Return the 'port' global argument. 630 * 631 * @return The 'port' global argument. 632 */ 633 public IntegerArgument getPortArg() { 634 return portArg; 635 } 636 637 /** 638 * Return the 'bindDN' global argument. 639 * 640 * @return The 'bindDN' global argument. 641 */ 642 public StringArgument getBindDnArg() { 643 return bindDnArg; 644 } 645 646 /** 647 * Return the 'adminUID' global argument. 648 * 649 * @return The 'adminUID' global argument. 650 */ 651 public StringArgument getAdminUidArg() { 652 return adminUidArg; 653 } 654 655 /** 656 * Return the 'bindPasswordFile' global argument. 657 * 658 * @return The 'bindPasswordFile' global argument. 659 */ 660 public FileBasedArgument getBindPasswordFileArg() { 661 return bindPasswordFileArg; 662 } 663 664 /** 665 * Return the 'bindPassword' global argument. 666 * 667 * @return The 'bindPassword' global argument. 668 */ 669 public StringArgument getBindPasswordArg() { 670 return bindPasswordArg; 671 } 672 673 /** 674 * Return the 'trustAllArg' global argument. 675 * 676 * @return The 'trustAllArg' global argument. 677 */ 678 public BooleanArgument getTrustAllArg() { 679 return trustAllArg; 680 } 681 682 /** 683 * Return the 'trustStore' global argument. 684 * 685 * @return The 'trustStore' global argument. 686 */ 687 public StringArgument getTrustStorePathArg() { 688 return trustStorePathArg; 689 } 690 691 /** 692 * Return the 'trustStorePassword' global argument. 693 * 694 * @return The 'trustStorePassword' global argument. 695 */ 696 public StringArgument getTrustStorePasswordArg() { 697 return trustStorePasswordArg; 698 } 699 700 /** 701 * Return the 'trustStorePasswordFile' global argument. 702 * 703 * @return The 'trustStorePasswordFile' global argument. 704 */ 705 public FileBasedArgument getTrustStorePasswordFileArg() { 706 return trustStorePasswordFileArg; 707 } 708 709 /** 710 * Return the 'keyStorePassword' global argument. 711 * 712 * @return The 'keyStorePassword' global argument. 713 */ 714 public StringArgument getKeyStorePasswordArg() { 715 return keyStorePasswordArg; 716 } 717 718 /** 719 * Return the 'keyStorePasswordFile' global argument. 720 * 721 * @return The 'keyStorePasswordFile' global argument. 722 */ 723 public FileBasedArgument getKeyStorePasswordFileArg() { 724 return keyStorePasswordFileArg; 725 } 726 727 /** 728 * Return the 'certNicknameArg' global argument. 729 * 730 * @return The 'certNicknameArg' global argument. 731 */ 732 public StringArgument getCertNicknameArg() { 733 return certNicknameArg; 734 } 735 736 /** 737 * Return the 'useSSLArg' global argument. 738 * 739 * @return The 'useSSLArg' global argument. 740 */ 741 public BooleanArgument getUseSSLArg() { 742 return useSSLArg; 743 } 744 745 /** 746 * Return the 'useStartTLSArg' global argument. 747 * 748 * @return The 'useStartTLSArg' global argument. 749 */ 750 public BooleanArgument getUseStartTLSArg() { 751 return useStartTLSArg; 752 } 753 754 /** 755 * Return the 'saslOption' argument. 756 * 757 * @return the 'saslOption' argument. 758 */ 759 public StringArgument getSaslOptionArg() { 760 return saslOptionArg; 761 } 762 763 /** 764 * Return the 'connectTimeout' argument. 765 * 766 * @return the 'connectTimeout' argument. 767 */ 768 public IntegerArgument getConnectTimeoutArg() { 769 return connectTimeoutArg; 770 } 771 772 /** 773 * Set the bind DN argument with the provided description. 774 * Note that this method will create a new {@link Argument} instance replacing the current one. 775 * 776 * @param description 777 * The localized description which will be used in help messages. 778 */ 779 public void setBindDnArgDescription(final LocalizableMessage description) 780 { 781 try 782 { 783 this.bindDnArg = bindDNArgument(CliConstants.DEFAULT_ROOT_USER_DN, description); 784 } 785 catch (final ArgumentException unexpected) 786 { 787 throw new RuntimeException("unexpected"); 788 } 789 } 790 791 /** 792 * Set the bind password argument. 793 * 794 * @param bindPasswordArg 795 * The argument which will replace the current one. 796 */ 797 public void setBindPasswordArgument(final StringArgument bindPasswordArg) 798 { 799 this.bindPasswordArg = bindPasswordArg; 800 } 801 802 /** 803 * Set the bind password file argument. 804 * 805 * @param bindPasswordFileArg 806 * The argument which will replace the current one. 807 */ 808 public void setBindPasswordFileArgument(final FileBasedArgument bindPasswordFileArg) 809 { 810 this.bindPasswordFileArg = bindPasswordFileArg; 811 } 812}