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 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2007-2008 Sun Microsystems, Inc. 026 */ 027 028 package org.opends.server.admin.client.cli; 029 030 import static org.opends.server.admin.client.cli.DsFrameworkCliReturnCode.*; 031 import static org.opends.server.loggers.debug.DebugLogger.debugEnabled; 032 import static org.opends.server.loggers.debug.DebugLogger.getTracer; 033 import static org.opends.messages.AdminToolMessages.*; 034 import static org.opends.messages.ToolMessages.*; 035 import org.opends.messages.Message; 036 import org.opends.messages.MessageBuilder; 037 import static org.opends.server.tools.ToolConstants.*; 038 import static org.opends.server.util.ServerConstants.MAX_LINE_WIDTH; 039 import static org.opends.server.util.StaticUtils.wrapText; 040 041 import java.io.File; 042 import java.io.FileInputStream; 043 import java.io.IOException; 044 import java.io.OutputStream; 045 import java.io.PrintStream; 046 import java.security.KeyStore; 047 import java.security.KeyStoreException; 048 import java.security.NoSuchAlgorithmException; 049 import java.security.cert.CertificateException; 050 import java.util.ArrayList; 051 import java.util.LinkedHashSet; 052 import java.util.logging.Level; 053 import java.util.logging.Logger; 054 055 import javax.net.ssl.KeyManager; 056 057 import org.opends.admin.ads.util.ApplicationKeyManager; 058 import org.opends.admin.ads.util.ApplicationTrustManager; 059 import org.opends.quicksetup.Constants; 060 import org.opends.server.loggers.debug.DebugTracer; 061 import org.opends.server.types.DebugLogLevel; 062 import org.opends.server.util.PasswordReader; 063 import org.opends.server.util.SelectableCertificateKeyManager; 064 import org.opends.server.util.args.Argument; 065 import org.opends.server.util.args.ArgumentException; 066 import org.opends.server.util.args.BooleanArgument; 067 import org.opends.server.util.args.FileBasedArgument; 068 import org.opends.server.util.args.IntegerArgument; 069 import org.opends.server.util.args.StringArgument; 070 071 /** 072 * This is a commodity class that can be used to check the arguments required 073 * to establish a secure connection in the command line. It can be used 074 * to generate an ApplicationTrustManager object based on the options provided 075 * by the user in the command line. 076 * 077 */ 078 public final class SecureConnectionCliArgs 079 { 080 /** 081 * The 'hostName' global argument. 082 */ 083 public StringArgument hostNameArg = null; 084 085 /** 086 * The 'port' global argument. 087 */ 088 public IntegerArgument portArg = null; 089 090 /** 091 * The 'bindDN' global argument. 092 */ 093 public StringArgument bindDnArg = null; 094 095 /** 096 * The 'adminUID' global argument. 097 */ 098 public StringArgument adminUidArg = null; 099 100 /** 101 * The 'bindPasswordFile' global argument. 102 */ 103 public FileBasedArgument bindPasswordFileArg = null; 104 105 /** 106 * The 'bindPassword' global argument. 107 */ 108 public StringArgument bindPasswordArg = null; 109 110 /** 111 * The 'trustAllArg' global argument. 112 */ 113 public BooleanArgument trustAllArg = null; 114 115 /** 116 * The 'trustStore' global argument. 117 */ 118 public StringArgument trustStorePathArg = null; 119 120 /** 121 * The 'trustStorePassword' global argument. 122 */ 123 public StringArgument trustStorePasswordArg = null; 124 125 /** 126 * The 'trustStorePasswordFile' global argument. 127 */ 128 public FileBasedArgument trustStorePasswordFileArg = null; 129 130 /** 131 * The 'keyStore' global argument. 132 */ 133 public StringArgument keyStorePathArg = null; 134 135 /** 136 * The 'keyStorePassword' global argument. 137 */ 138 public StringArgument keyStorePasswordArg = null; 139 140 /** 141 * The 'keyStorePasswordFile' global argument. 142 */ 143 public FileBasedArgument keyStorePasswordFileArg = null; 144 145 /** 146 * The 'certNicknameArg' global argument. 147 */ 148 public StringArgument certNicknameArg = null; 149 150 /** 151 * The 'useSSLArg' global argument. 152 */ 153 public BooleanArgument useSSLArg = null; 154 155 /** 156 * The 'useStartTLSArg' global argument. 157 */ 158 public BooleanArgument useStartTLSArg = null; 159 160 /** 161 * Argument indicating a SASL option. 162 */ 163 public StringArgument saslOptionArg = null; 164 165 /** 166 * Private container for global arguments. 167 */ 168 private LinkedHashSet<Argument> argList = null; 169 170 // the trust manager. 171 private ApplicationTrustManager trustManager; 172 173 /** 174 * The tracer object for the debug logger. 175 */ 176 private static final DebugTracer TRACER = getTracer(); 177 178 /** 179 * End Of Line. 180 */ 181 public static String EOL = System.getProperty("line.separator"); 182 183 /** 184 * The Logger. 185 */ 186 static private final Logger LOG = 187 Logger.getLogger(SecureConnectionCliArgs.class.getName()); 188 189 /** 190 * Creates a new instance of secure arguments. 191 */ 192 public SecureConnectionCliArgs() 193 { 194 } 195 196 /** 197 * Indicates whether or not any of the arguments are present. 198 * 199 * @return boolean where true indicates that at least one of the 200 * arguments is present 201 */ 202 public boolean argumentsPresent() { 203 boolean present = false; 204 if (argList != null) { 205 for (Argument arg : argList) { 206 if (arg.isPresent()) { 207 present = true; 208 break; 209 } 210 } 211 } 212 return present; 213 } 214 215 /** 216 * Get the admin UID which has to be used for the command. 217 * 218 * @return The admin UID specified by the command line argument, or the 219 * default value, if not specified. 220 */ 221 public String getAdministratorUID() 222 { 223 if (adminUidArg.isPresent()) 224 { 225 return adminUidArg.getValue(); 226 } 227 else 228 { 229 return adminUidArg.getDefaultValue(); 230 } 231 } 232 233 /** 234 * Tells whether this parser uses the Administrator UID (instead of the 235 * bind DN) or not. 236 * @return <CODE>true</CODE> if this parser uses the Administrator UID and 237 * <CODE>false</CODE> otherwise. 238 */ 239 public boolean useAdminUID() 240 { 241 return !adminUidArg.isHidden(); 242 } 243 244 /** 245 * Get the bindDN which has to be used for the command. 246 * 247 * @return The bindDN specified by the command line argument, or the 248 * default value, if not specified. 249 */ 250 public String getBindDN() 251 { 252 if (bindDnArg.isPresent()) 253 { 254 return bindDnArg.getValue(); 255 } 256 else 257 { 258 return bindDnArg.getDefaultValue(); 259 } 260 } 261 262 /** 263 * Get the password which has to be used for the command. 264 * 265 * @param dn 266 * The user DN for which to password could be asked. 267 * @param out 268 * The input stream to used if we have to prompt to the 269 * user. 270 * @param err 271 * The error stream to used if we have to prompt to the 272 * user. 273 * @param clearArg 274 * The password StringArgument argument. 275 * @param fileArg 276 * The password FileBased argument. 277 * @return The password stored into the specified file on by the 278 * command line argument, or prompts it if not specified. 279 */ 280 public String getBindPassword(String dn, 281 OutputStream out, OutputStream err, StringArgument clearArg, 282 FileBasedArgument fileArg) 283 { 284 if (clearArg.isPresent()) 285 { 286 String bindPasswordValue = clearArg.getValue(); 287 if(bindPasswordValue != null && bindPasswordValue.equals("-")) 288 { 289 // read the password from the stdin. 290 try 291 { 292 out.write(INFO_LDAPAUTH_PASSWORD_PROMPT.get(dn).getBytes()); 293 out.flush(); 294 char[] pwChars = PasswordReader.readPassword(); 295 bindPasswordValue = new String(pwChars); 296 } catch(Exception ex) 297 { 298 if (debugEnabled()) 299 { 300 TRACER.debugCaught(DebugLogLevel.ERROR, ex); 301 } 302 try 303 { 304 err.write(wrapText(ex.getMessage(), MAX_LINE_WIDTH).getBytes()); 305 err.write(EOL.getBytes()); 306 } 307 catch (IOException e) 308 { 309 } 310 return null; 311 } 312 } 313 return bindPasswordValue; 314 } 315 else 316 if (fileArg.isPresent()) 317 { 318 return fileArg.getValue(); 319 } 320 else 321 { 322 // read the password from the stdin. 323 try 324 { 325 out.write(INFO_LDAPAUTH_PASSWORD_PROMPT.get(dn).toString().getBytes()); 326 out.flush(); 327 char[] pwChars = PasswordReader.readPassword(); 328 return new String(pwChars); 329 } 330 catch (Exception ex) 331 { 332 if (debugEnabled()) 333 { 334 TRACER.debugCaught(DebugLogLevel.ERROR, ex); 335 } 336 try 337 { 338 err.write(wrapText(ex.getMessage(), MAX_LINE_WIDTH).getBytes()); 339 err.write(EOL.getBytes()); 340 } 341 catch (IOException e) 342 { 343 } 344 return null; 345 } 346 } 347 348 } 349 350 /** 351 * Get the password which has to be used for the command. 352 * 353 * @param dn 354 * The user DN for which to password could be asked. 355 * @param out 356 * The input stream to used if we have to prompt to the 357 * user. 358 * @param err 359 * The error stream to used if we have to prompt to the 360 * user. 361 * @return The password stored into the specified file on by the 362 * command line argument, or prompts it if not specified. 363 */ 364 public String getBindPassword(String dn, OutputStream out, OutputStream err) 365 { 366 return getBindPassword(dn, out, err, bindPasswordArg, bindPasswordFileArg); 367 } 368 369 /** 370 * Get the password which has to be used for the command without prompting 371 * the user. If no password was specified, return null. 372 * 373 * @param clearArg 374 * The password StringArgument argument. 375 * @param fileArg 376 * The password FileBased argument. 377 * @return The password stored into the specified file on by the 378 * command line argument, or null it if not specified. 379 */ 380 public String getBindPassword(StringArgument clearArg, 381 FileBasedArgument fileArg) 382 { 383 String pwd; 384 if (clearArg.isPresent()) 385 { 386 pwd = clearArg.getValue(); 387 } 388 else 389 if (fileArg.isPresent()) 390 { 391 pwd = fileArg.getValue(); 392 } 393 else 394 { 395 pwd = null; 396 } 397 return pwd; 398 } 399 400 /** 401 * Get the password which has to be used for the command without prompting 402 * the user. If no password was specified, return null. 403 * 404 * @return The password stored into the specified file on by the 405 * command line argument, or null it if not specified. 406 */ 407 public String getBindPassword() 408 { 409 return getBindPassword(bindPasswordArg, bindPasswordFileArg); 410 } 411 412 /** 413 * Initialize Global option. 414 * 415 * @throws ArgumentException 416 * If there is a problem with any of the parameters used 417 * to create this argument. 418 * @return a ArrayList with the options created. 419 */ 420 public LinkedHashSet<Argument> createGlobalArguments() 421 throws ArgumentException 422 { 423 argList = new LinkedHashSet<Argument>(); 424 425 useSSLArg = new BooleanArgument("useSSL", OPTION_SHORT_USE_SSL, 426 OPTION_LONG_USE_SSL, INFO_DESCRIPTION_USE_SSL.get()); 427 useSSLArg.setPropertyName(OPTION_LONG_USE_SSL); 428 argList.add(useSSLArg); 429 430 useStartTLSArg = new BooleanArgument("startTLS", OPTION_SHORT_START_TLS, 431 OPTION_LONG_START_TLS, 432 INFO_DESCRIPTION_START_TLS.get()); 433 useStartTLSArg.setPropertyName(OPTION_LONG_START_TLS); 434 argList.add(useStartTLSArg); 435 436 hostNameArg = new StringArgument("host", OPTION_SHORT_HOST, 437 OPTION_LONG_HOST, false, false, true, INFO_HOST_PLACEHOLDER.get(), 438 "localhost", 439 null, INFO_DESCRIPTION_HOST.get()); 440 hostNameArg.setPropertyName(OPTION_LONG_HOST); 441 argList.add(hostNameArg); 442 443 portArg = new IntegerArgument("port", OPTION_SHORT_PORT, OPTION_LONG_PORT, 444 false, false, true, INFO_PORT_PLACEHOLDER.get(), 389, null, 445 INFO_DESCRIPTION_PORT.get()); 446 portArg.setPropertyName(OPTION_LONG_PORT); 447 argList.add(portArg); 448 449 bindDnArg = new StringArgument("bindDN", OPTION_SHORT_BINDDN, 450 OPTION_LONG_BINDDN, false, false, true, INFO_BINDDN_PLACEHOLDER.get(), 451 "cn=Directory Manager", null, INFO_DESCRIPTION_BINDDN.get()); 452 bindDnArg.setPropertyName(OPTION_LONG_BINDDN); 453 argList.add(bindDnArg); 454 455 // It is up to the classes that required admin UID to make this argument 456 // visible and add it. 457 adminUidArg = new StringArgument("adminUID", 'I', 458 "adminUID", false, false, true, INFO_ADMINUID_PLACEHOLDER.get(), 459 Constants.GLOBAL_ADMIN_UID, null, 460 INFO_DESCRIPTION_ADMIN_UID.get()); 461 adminUidArg.setPropertyName("adminUID"); 462 adminUidArg.setHidden(true); 463 464 bindPasswordArg = new StringArgument("bindPassword", 465 OPTION_SHORT_BINDPWD, OPTION_LONG_BINDPWD, false, false, true, 466 INFO_BINDPWD_PLACEHOLDER.get(), null, null, 467 INFO_DESCRIPTION_BINDPASSWORD.get()); 468 bindPasswordArg.setPropertyName(OPTION_LONG_BINDPWD); 469 argList.add(bindPasswordArg); 470 471 bindPasswordFileArg = new FileBasedArgument("bindPasswordFile", 472 OPTION_SHORT_BINDPWD_FILE, OPTION_LONG_BINDPWD_FILE, false, false, 473 INFO_BINDPWD_FILE_PLACEHOLDER.get(), null, null, 474 INFO_DESCRIPTION_BINDPASSWORDFILE.get()); 475 bindPasswordFileArg.setPropertyName(OPTION_LONG_BINDPWD_FILE); 476 argList.add(bindPasswordFileArg); 477 478 saslOptionArg = new StringArgument( 479 "sasloption", OPTION_SHORT_SASLOPTION, 480 OPTION_LONG_SASLOPTION, false, 481 true, true, 482 INFO_SASL_OPTION_PLACEHOLDER.get(), null, null, 483 INFO_LDAP_CONN_DESCRIPTION_SASLOPTIONS.get()); 484 saslOptionArg.setPropertyName(OPTION_LONG_SASLOPTION); 485 argList.add(saslOptionArg); 486 487 trustAllArg = new BooleanArgument("trustAll", OPTION_SHORT_TRUSTALL, 488 OPTION_LONG_TRUSTALL, INFO_DESCRIPTION_TRUSTALL.get()); 489 trustAllArg.setPropertyName(OPTION_LONG_TRUSTALL); 490 argList.add(trustAllArg); 491 492 trustStorePathArg = new StringArgument("trustStorePath", 493 OPTION_SHORT_TRUSTSTOREPATH, OPTION_LONG_TRUSTSTOREPATH, false, 494 false, true, INFO_TRUSTSTOREPATH_PLACEHOLDER.get(), null, null, 495 INFO_DESCRIPTION_TRUSTSTOREPATH.get()); 496 trustStorePathArg.setPropertyName(OPTION_LONG_TRUSTSTOREPATH); 497 argList.add(trustStorePathArg); 498 499 trustStorePasswordArg = new StringArgument("trustStorePassword", 500 OPTION_SHORT_TRUSTSTORE_PWD, OPTION_LONG_TRUSTSTORE_PWD, false, false, 501 true, INFO_TRUSTSTORE_PWD_PLACEHOLDER.get(), null, null, 502 INFO_DESCRIPTION_TRUSTSTOREPASSWORD.get()); 503 trustStorePasswordArg.setPropertyName(OPTION_LONG_TRUSTSTORE_PWD); 504 argList.add(trustStorePasswordArg); 505 506 trustStorePasswordFileArg = new FileBasedArgument("trustStorePasswordFile", 507 OPTION_SHORT_TRUSTSTORE_PWD_FILE, OPTION_LONG_TRUSTSTORE_PWD_FILE, 508 false, false, INFO_TRUSTSTORE_PWD_FILE_PLACEHOLDER.get(), null, null, 509 INFO_DESCRIPTION_TRUSTSTOREPASSWORD_FILE.get()); 510 trustStorePasswordFileArg.setPropertyName(OPTION_LONG_TRUSTSTORE_PWD_FILE); 511 argList.add(trustStorePasswordFileArg); 512 513 keyStorePathArg = new StringArgument("keyStorePath", 514 OPTION_SHORT_KEYSTOREPATH, OPTION_LONG_KEYSTOREPATH, false, false, 515 true, INFO_KEYSTOREPATH_PLACEHOLDER.get(), null, null, 516 INFO_DESCRIPTION_KEYSTOREPATH.get()); 517 keyStorePathArg.setPropertyName(OPTION_LONG_KEYSTOREPATH); 518 argList.add(keyStorePathArg); 519 520 keyStorePasswordArg = new StringArgument("keyStorePassword", 521 OPTION_SHORT_KEYSTORE_PWD, 522 OPTION_LONG_KEYSTORE_PWD, false, false, true, 523 INFO_KEYSTORE_PWD_PLACEHOLDER.get(), null, null, 524 INFO_DESCRIPTION_KEYSTOREPASSWORD.get()); 525 keyStorePasswordArg.setPropertyName(OPTION_LONG_KEYSTORE_PWD); 526 argList.add(keyStorePasswordArg); 527 528 keyStorePasswordFileArg = new FileBasedArgument("keystorePasswordFile", 529 OPTION_SHORT_KEYSTORE_PWD_FILE, OPTION_LONG_KEYSTORE_PWD_FILE, false, 530 false, INFO_KEYSTORE_PWD_FILE_PLACEHOLDER.get(), null, null, 531 INFO_DESCRIPTION_KEYSTOREPASSWORD_FILE.get()); 532 keyStorePasswordFileArg.setPropertyName(OPTION_LONG_KEYSTORE_PWD_FILE); 533 argList.add(keyStorePasswordFileArg); 534 535 certNicknameArg = new StringArgument("certNickname", 536 OPTION_SHORT_CERT_NICKNAME, OPTION_LONG_CERT_NICKNAME, 537 false, false, true, INFO_NICKNAME_PLACEHOLDER.get(), null, null, 538 INFO_DESCRIPTION_CERT_NICKNAME.get()); 539 certNicknameArg.setPropertyName(OPTION_LONG_CERT_NICKNAME); 540 argList.add(certNicknameArg); 541 542 return argList; 543 } 544 545 /** 546 * Get the host name which has to be used for the command. 547 * 548 * @return The host name specified by the command line argument, or 549 * the default value, if not specified. 550 */ 551 public String getHostName() 552 { 553 if (hostNameArg.isPresent()) 554 { 555 return hostNameArg.getValue(); 556 } 557 else 558 { 559 return hostNameArg.getDefaultValue(); 560 } 561 } 562 563 /** 564 * Get the port which has to be used for the command. 565 * 566 * @return The port specified by the command line argument, or the 567 * default value, if not specified. 568 */ 569 public String getPort() 570 { 571 if (portArg.isPresent()) 572 { 573 return portArg.getValue(); 574 } 575 else 576 { 577 return portArg.getDefaultValue(); 578 } 579 } 580 581 /** 582 * Indication if provided global options are validate. 583 * 584 * @param buf the MessageBuilder to write the error messages. 585 * @return return code. 586 */ 587 public int validateGlobalOptions(MessageBuilder buf) 588 { 589 ArrayList<Message> errors = new ArrayList<Message>(); 590 // Couldn't have at the same time bindPassword and bindPasswordFile 591 if (bindPasswordArg.isPresent() && bindPasswordFileArg.isPresent()) { 592 Message message = ERR_TOOL_CONFLICTING_ARGS.get( 593 bindPasswordArg.getLongIdentifier(), 594 bindPasswordFileArg.getLongIdentifier()); 595 errors.add(message); 596 } 597 598 // Couldn't have at the same time trustAll and 599 // trustStore related arg 600 if (trustAllArg.isPresent() && trustStorePathArg.isPresent()) { 601 Message message = ERR_TOOL_CONFLICTING_ARGS.get( 602 trustAllArg.getLongIdentifier(), 603 trustStorePathArg.getLongIdentifier()); 604 errors.add(message); 605 } 606 if (trustAllArg.isPresent() && trustStorePasswordArg.isPresent()) { 607 Message message = ERR_TOOL_CONFLICTING_ARGS.get( 608 trustAllArg.getLongIdentifier(), 609 trustStorePasswordArg.getLongIdentifier()); 610 errors.add(message); 611 } 612 if (trustAllArg.isPresent() && trustStorePasswordFileArg.isPresent()) { 613 Message message = ERR_TOOL_CONFLICTING_ARGS.get( 614 trustAllArg.getLongIdentifier(), 615 trustStorePasswordFileArg.getLongIdentifier()); 616 errors.add(message); 617 } 618 619 // Couldn't have at the same time trustStorePasswordArg and 620 // trustStorePasswordFileArg 621 if (trustStorePasswordArg.isPresent() 622 && trustStorePasswordFileArg.isPresent()) { 623 Message message = ERR_TOOL_CONFLICTING_ARGS.get( 624 trustStorePasswordArg.getLongIdentifier(), 625 trustStorePasswordFileArg.getLongIdentifier()); 626 errors.add(message); 627 } 628 629 if (trustStorePathArg.isPresent()) 630 { 631 // Check that the path exists and is readable 632 String value = trustStorePathArg.getValue(); 633 if (!canRead(trustStorePathArg.getValue())) 634 { 635 Message message = ERR_CANNOT_READ_TRUSTSTORE.get( 636 value); 637 errors.add(message); 638 } 639 } 640 641 if (keyStorePathArg.isPresent()) 642 { 643 // Check that the path exists and is readable 644 String value = keyStorePathArg.getValue(); 645 if (!canRead(trustStorePathArg.getValue())) 646 { 647 Message message = ERR_CANNOT_READ_KEYSTORE.get( 648 value); 649 errors.add(message); 650 } 651 } 652 653 // Couldn't have at the same time startTLSArg and 654 // useSSLArg 655 if (useStartTLSArg.isPresent() 656 && useSSLArg.isPresent()) { 657 Message message = ERR_TOOL_CONFLICTING_ARGS.get( 658 useStartTLSArg 659 .getLongIdentifier(), useSSLArg.getLongIdentifier()); 660 errors.add(message); 661 } 662 if (errors.size() > 0) 663 { 664 for (Message error : errors) 665 { 666 if (buf.length() > 0) 667 { 668 buf.append(EOL); 669 } 670 buf.append(error); 671 } 672 return CONFLICTING_ARGS.getReturnCode(); 673 } 674 675 return SUCCESSFUL_NOP.getReturnCode(); 676 } 677 /** 678 * Indication if provided global options are validate. 679 * 680 * @param err the stream to be used to print error message. 681 * @return return code. 682 */ 683 public int validateGlobalOptions(PrintStream err) 684 { 685 MessageBuilder buf = new MessageBuilder(); 686 int returnValue = validateGlobalOptions(buf); 687 if (buf.length() > 0) 688 { 689 err.println(wrapText(buf.toString(), MAX_LINE_WIDTH)); 690 } 691 return returnValue; 692 } 693 694 695 /** 696 * Indicate if the SSL mode is required. 697 * 698 * @return True if SSL mode is required 699 */ 700 public boolean useSSL() 701 { 702 if (useSSLArg.isPresent()) 703 { 704 return true; 705 } 706 else 707 { 708 return false ; 709 } 710 } 711 712 /** 713 * Indicate if the startTLS mode is required. 714 * 715 * @return True if startTLS mode is required 716 */ 717 public boolean useStartTLS() 718 { 719 if (useStartTLSArg.isPresent()) 720 { 721 return true; 722 } 723 else 724 { 725 return false ; 726 } 727 } 728 729 /** 730 * Handle TrustStore. 731 * 732 * @return The trustStore manager to be used for the command. 733 */ 734 public ApplicationTrustManager getTrustManager() 735 { 736 if (trustManager == null) 737 { 738 KeyStore truststore = null ; 739 if (trustAllArg.isPresent()) 740 { 741 // Running a null TrustManager will force createLdapsContext and 742 // createStartTLSContext to use a bindTrustManager. 743 return null ; 744 } 745 else 746 if (trustStorePathArg.isPresent()) 747 { 748 try 749 { 750 FileInputStream fos = 751 new FileInputStream(trustStorePathArg.getValue()); 752 String trustStorePasswordStringValue = null; 753 char[] trustStorePasswordValue = null; 754 if (trustStorePasswordArg.isPresent()) 755 { 756 trustStorePasswordStringValue = trustStorePasswordArg.getValue(); 757 } 758 else if (trustStorePasswordFileArg.isPresent()) 759 { 760 trustStorePasswordStringValue = 761 trustStorePasswordFileArg.getValue(); 762 } 763 764 if (trustStorePasswordStringValue != null) 765 { 766 trustStorePasswordStringValue = System 767 .getProperty("javax.net.ssl.trustStorePassword"); 768 } 769 770 771 if (trustStorePasswordStringValue != null) 772 { 773 trustStorePasswordValue = 774 trustStorePasswordStringValue.toCharArray(); 775 } 776 777 truststore = KeyStore.getInstance(KeyStore.getDefaultType()); 778 truststore.load(fos, trustStorePasswordValue); 779 fos.close(); 780 } 781 catch (KeyStoreException e) 782 { 783 // Nothing to do: if this occurs we will systematically refuse the 784 // certificates. Maybe we should avoid this and be strict, but we 785 // are in a best effort mode. 786 LOG.log(Level.WARNING, "Error with the truststore", e); 787 } 788 catch (NoSuchAlgorithmException e) 789 { 790 // Nothing to do: if this occurs we will systematically refuse the 791 // certificates. Maybe we should avoid this and be strict, but we 792 // are in a best effort mode. 793 LOG.log(Level.WARNING, "Error with the truststore", e); 794 } 795 catch (CertificateException e) 796 { 797 // Nothing to do: if this occurs we will systematically refuse the 798 // certificates. Maybe we should avoid this and be strict, but we 799 // are in a best effort mode. 800 LOG.log(Level.WARNING, "Error with the truststore", e); 801 } 802 catch (IOException e) 803 { 804 // Nothing to do: if this occurs we will systematically refuse the 805 // certificates. Maybe we should avoid this and be strict, but we 806 // are in a best effort mode. 807 LOG.log(Level.WARNING, "Error with the truststore", e); 808 } 809 } 810 trustManager = new ApplicationTrustManager(truststore); 811 } 812 return trustManager; 813 } 814 815 /** 816 * Handle KeyStore. 817 * 818 * @return The keyStore manager to be used for the command. 819 */ 820 public KeyManager getKeyManager() 821 { 822 KeyStore keyStore = null; 823 String keyStorePasswordStringValue = null; 824 char[] keyStorePasswordValue = null; 825 if (keyStorePathArg.isPresent()) 826 { 827 try 828 { 829 FileInputStream fos = new FileInputStream(keyStorePathArg.getValue()); 830 if (keyStorePasswordArg.isPresent()) 831 { 832 keyStorePasswordStringValue = keyStorePasswordArg.getValue(); 833 } 834 else if (keyStorePasswordFileArg.isPresent()) 835 { 836 keyStorePasswordStringValue = keyStorePasswordFileArg.getValue(); 837 } 838 if (keyStorePasswordStringValue != null) 839 { 840 keyStorePasswordValue = keyStorePasswordStringValue.toCharArray(); 841 } 842 843 keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); 844 keyStore.load(fos,keyStorePasswordValue); 845 fos.close(); 846 } 847 catch (KeyStoreException e) 848 { 849 // Nothing to do: if this occurs we will systematically refuse 850 // the 851 // certificates. Maybe we should avoid this and be strict, but 852 // we are in a best effort mode. 853 LOG.log(Level.WARNING, "Error with the keystore", e); 854 } 855 catch (NoSuchAlgorithmException e) 856 { 857 // Nothing to do: if this occurs we will systematically refuse 858 // the 859 // certificates. Maybe we should avoid this and be strict, but 860 // we are 861 // in a best effort mode. 862 LOG.log(Level.WARNING, "Error with the keystore", e); 863 } 864 catch (CertificateException e) 865 { 866 // Nothing to do: if this occurs we will systematically refuse 867 // the 868 // certificates. Maybe we should avoid this and be strict, but 869 // we are 870 // in a best effort mode. 871 LOG.log(Level.WARNING, "Error with the keystore", e); 872 } 873 catch (IOException e) 874 { 875 // Nothing to do: if this occurs we will systematically refuse 876 // the 877 // certificates. Maybe we should avoid this and be strict, but 878 // we are 879 // in a best effort mode. 880 LOG.log(Level.WARNING, "Error with the keystore", e); 881 } 882 char[] password = null; 883 if (keyStorePasswordStringValue != null) 884 { 885 password = keyStorePasswordStringValue.toCharArray(); 886 } 887 ApplicationKeyManager akm = new ApplicationKeyManager(keyStore,password); 888 if (certNicknameArg.isPresent()) 889 { 890 return new SelectableCertificateKeyManager(akm, certNicknameArg 891 .getValue()); 892 } 893 else 894 { 895 return akm; 896 } 897 } 898 else 899 { 900 return null; 901 } 902 } 903 904 /** 905 * Returns <CODE>true</CODE> if we can read on the provided path and 906 * <CODE>false</CODE> otherwise. 907 * @param path the path. 908 * @return <CODE>true</CODE> if we can read on the provided path and 909 * <CODE>false</CODE> otherwise. 910 */ 911 private boolean canRead(String path) 912 { 913 boolean canRead; 914 File file = new File(path); 915 if (file.exists()) 916 { 917 canRead = file.canRead(); 918 } 919 else 920 { 921 canRead = false; 922 } 923 return canRead; 924 } 925 }