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 }