| | |
| | | * Copyright 2008-2010 Sun Microsystems, Inc. |
| | | * Portions Copyright 2011-2014 ForgeRock AS |
| | | */ |
| | | |
| | | package org.opends.server.util.cli; |
| | | |
| | | import static org.opends.messages.QuickSetupMessages.*; |
| | | import static org.opends.messages.ToolMessages.*; |
| | | import static org.opends.messages.UtilityMessages.*; |
| | | |
| | | import java.io.File; |
| | | import java.io.FileInputStream; |
| | | import java.io.FileNotFoundException; |
| | |
| | | import org.opends.server.tools.dsconfig.ArgumentExceptionFactory; |
| | | import org.opends.server.util.SelectableCertificateKeyManager; |
| | | |
| | | import com.forgerock.opendj.cli.ArgumentException; |
| | | import com.forgerock.opendj.cli.ClientException; |
| | | import com.forgerock.opendj.cli.CommandBuilder; |
| | | import com.forgerock.opendj.cli.ConsoleApplication; |
| | | import com.forgerock.opendj.cli.Menu; |
| | | import com.forgerock.opendj.cli.MenuBuilder; |
| | | import com.forgerock.opendj.cli.MenuResult; |
| | | import com.forgerock.opendj.cli.ValidationCallback; |
| | | import com.forgerock.opendj.cli.*; |
| | | |
| | | import static org.opends.messages.QuickSetupMessages.*; |
| | | import static org.opends.messages.ToolMessages.*; |
| | | import static org.opends.messages.UtilityMessages.*; |
| | | |
| | | /** |
| | | * Supports interacting with a user through the command line to |
| | |
| | | private String providedBindDN; |
| | | private String adminUID; |
| | | private String providedAdminUID; |
| | | private char[] bindPassword; |
| | | private String bindPassword; |
| | | private KeyManager keyManager; |
| | | private ApplicationTrustManager trustManager; |
| | | |
| | |
| | | private boolean displayLdapIfSecureParameters = false; |
| | | |
| | | /** The SecureConnectionCliArgsList object. */ |
| | | private SecureConnectionCliArgs secureArgsList = null; |
| | | private SecureConnectionCliArgs secureArgsList; |
| | | |
| | | /** Indicate if we need to display the heading. */ |
| | | private boolean isHeadingDisplayed = false; |
| | |
| | | |
| | | private String keystorePath; |
| | | |
| | | private char[] keystorePassword; |
| | | private String keystorePassword; |
| | | |
| | | private String certifNickname; |
| | | |
| | | private String truststorePath; |
| | | |
| | | private char[] truststorePassword; |
| | | private String truststorePassword; |
| | | |
| | | /** The timeout to be used to connect. */ |
| | | private int connectTimeout; |
| | |
| | | private LocalizableMessage heading = INFO_LDAP_CONN_HEADING_CONNECTION_PARAMETERS.get(); |
| | | |
| | | /** A copy of the secureArgList for convenience. */ |
| | | private SecureConnectionCliArgs copySecureArgsList = null; |
| | | private SecureConnectionCliArgs copySecureArgsList; |
| | | |
| | | /** The command builder that we can return with the connection information. */ |
| | | private CommandBuilder commandBuilder; |
| | |
| | | ValidationCallback<String> callback = new ValidationCallback<String>() |
| | | { |
| | | |
| | | @Override |
| | | public String validate(ConsoleApplication app, String input) |
| | | throws ClientException |
| | | { |
| | |
| | | { |
| | | useSSL = true; |
| | | } |
| | | else if (result.getValue() |
| | | .equals(Protocols.START_TLS.getChoice())) |
| | | else if (result.getValue().equals(Protocols.START_TLS.getChoice())) |
| | | { |
| | | useStartTLS = true; |
| | | } |
| | |
| | | ValidationCallback<Integer> callback = new ValidationCallback<Integer>() |
| | | { |
| | | |
| | | @Override |
| | | public Integer validate(ConsoleApplication app, String input) |
| | | throws ClientException |
| | | { |
| | |
| | | ValidationCallback<String> callback = new ValidationCallback<String>() |
| | | { |
| | | |
| | | @Override |
| | | public String validate(ConsoleApplication app, String input) |
| | | throws ClientException |
| | | { |
| | |
| | | boolean addedPasswordFileArgument = false; |
| | | if (secureArgsList.bindPasswordArg.isPresent()) |
| | | { |
| | | bindPassword = secureArgsList.bindPasswordArg.getValue().toCharArray(); |
| | | bindPassword = secureArgsList.bindPasswordArg.getValue(); |
| | | } |
| | | if (keyManager == null) |
| | | { |
| | | if (secureArgsList.bindPasswordFileArg.isPresent()) |
| | | { |
| | | // Read from file if it exists. |
| | | bindPassword = secureArgsList.bindPasswordFileArg.getValue().toCharArray(); |
| | | bindPassword = secureArgsList.bindPasswordFileArg.getValue(); |
| | | |
| | | if (bindPassword == null) |
| | | { |
| | |
| | | { |
| | | prompt = INFO_LDAPAUTH_PASSWORD_PROMPT.get(adminUID); |
| | | } |
| | | bindPassword = app.readPassword(prompt); |
| | | bindPassword = readPassword(prompt); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | |
| | | } |
| | | } |
| | | copySecureArgsList.bindPasswordArg.clearValues(); |
| | | copySecureArgsList.bindPasswordArg.addValue(String.valueOf(bindPassword)); |
| | | copySecureArgsList.bindPasswordArg.addValue(bindPassword); |
| | | if (!addedPasswordFileArgument) |
| | | { |
| | | commandBuilder.addObfuscatedArgument( |
| | |
| | | connectTimeout = secureArgsList.connectTimeoutArg.getIntValue(); |
| | | } |
| | | |
| | | private String readPassword(LocalizableMessage prompt) throws ClientException |
| | | { |
| | | final char[] pwd = app.readPassword(prompt); |
| | | if (pwd != null) |
| | | { |
| | | return String.valueOf(pwd); |
| | | } |
| | | return null; |
| | | } |
| | | |
| | | /** |
| | | * Get the trust manager. |
| | | * |
| | |
| | | // just return null |
| | | return null; |
| | | } |
| | | else if (result.getValue().equals( |
| | | TrustMethod.TRUSTSTORE.getChoice())) |
| | | else if (result.getValue().equals(TrustMethod.TRUSTSTORE.getChoice())) |
| | | { |
| | | // We have to ask for trust store info |
| | | askForTrustStore = true; |
| | |
| | | |
| | | ValidationCallback<String> callback = new ValidationCallback<String>() |
| | | { |
| | | @Override |
| | | public String validate(ConsoleApplication app, String input) |
| | | throws ClientException |
| | | { |
| | |
| | | // we don't ask it in the interactive mode. |
| | | if (secureArgsList.trustStorePasswordArg.isPresent()) |
| | | { |
| | | truststorePassword = |
| | | secureArgsList.trustStorePasswordArg.getValue().toCharArray(); |
| | | truststorePassword = secureArgsList.trustStorePasswordArg.getValue(); |
| | | } |
| | | if (secureArgsList.trustStorePasswordFileArg.isPresent()) |
| | | { |
| | | // Read from file if it exists. |
| | | truststorePassword = secureArgsList.trustStorePasswordFileArg |
| | | .getValue().toCharArray(); |
| | | truststorePassword = secureArgsList.trustStorePasswordFileArg.getValue(); |
| | | } |
| | | if (truststorePassword != null && "-".equals(truststorePassword)) |
| | | if ("-".equals(truststorePassword)) |
| | | { |
| | | // Read the password from the stdin. |
| | | if (!app.isInteractive()) |
| | |
| | | app.println(); |
| | | LocalizableMessage prompt = INFO_LDAP_CONN_PROMPT_SECURITY_TRUSTSTORE_PASSWORD |
| | | .get(truststorePath); |
| | | truststorePassword = app.readPassword(prompt); |
| | | truststorePassword = readPassword(prompt); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | |
| | | FileInputStream fos = new FileInputStream(truststorePath); |
| | | if (truststorePassword != null) |
| | | { |
| | | truststore.load(fos, truststorePassword); |
| | | truststore.load(fos, truststorePassword.toCharArray()); |
| | | } |
| | | else |
| | | { |
| | |
| | | // Only add the trust store password if there is one AND if the user |
| | | // specified a trust store path. |
| | | copySecureArgsList.trustStorePasswordArg.clearValues(); |
| | | copySecureArgsList.trustStorePasswordArg.addValue(String.valueOf(truststorePassword)); |
| | | copySecureArgsList.trustStorePasswordArg.addValue(truststorePassword); |
| | | commandBuilder.addObfuscatedArgument( |
| | | copySecureArgsList.trustStorePasswordArg); |
| | | } |
| | |
| | | |
| | | ValidationCallback<String> callback = new ValidationCallback<String>() |
| | | { |
| | | @Override |
| | | public String validate(ConsoleApplication app, String input) |
| | | throws ClientException |
| | | { |
| | |
| | | } |
| | | |
| | | // Then the keystore password. |
| | | keystorePassword = secureArgsList.keyStorePasswordArg.getValue().toCharArray(); |
| | | keystorePassword = secureArgsList.keyStorePasswordArg.getValue(); |
| | | |
| | | if (secureArgsList.keyStorePasswordFileArg.isPresent()) |
| | | { |
| | | // Read from file if it exists. |
| | | keystorePassword = secureArgsList.keyStorePasswordFileArg.getValue().toCharArray(); |
| | | keystorePassword = secureArgsList.keyStorePasswordFileArg.getValue(); |
| | | |
| | | if (keystorePassword == null) |
| | | { |
| | |
| | | app.println(); |
| | | LocalizableMessage prompt = INFO_LDAP_CONN_PROMPT_SECURITY_KEYSTORE_PASSWORD |
| | | .get(keystorePath); |
| | | keystorePassword = app.readPassword(prompt); |
| | | keystorePassword = readPassword(prompt); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | |
| | | { |
| | | FileInputStream fos = new FileInputStream(keystorePath); |
| | | keystore = KeyStore.getInstance(KeyStore.getDefaultType()); |
| | | keystore.load(fos, keystorePassword); |
| | | keystore.load(fos, keystorePassword.toCharArray()); |
| | | fos.close(); |
| | | aliasesEnum = keystore.aliases(); |
| | | } |
| | |
| | | |
| | | // We'we got all the information to get the keys manager |
| | | ApplicationKeyManager akm = new ApplicationKeyManager(keystore, |
| | | keystorePassword); |
| | | keystorePassword.toCharArray()); |
| | | |
| | | |
| | | if (secureArgsList.keyStorePasswordFileArg.isPresent()) |
| | |
| | | else if (keystorePassword != null) |
| | | { |
| | | copySecureArgsList.keyStorePasswordArg.clearValues(); |
| | | copySecureArgsList.keyStorePasswordArg.addValue(String.valueOf(keystorePassword)); |
| | | copySecureArgsList.keyStorePasswordArg.addValue(keystorePassword); |
| | | commandBuilder.addObfuscatedArgument( |
| | | copySecureArgsList.keyStorePasswordArg); |
| | | } |
| | |
| | | { |
| | | return new SelectableCertificateKeyManager(akm, certifNickname); |
| | | } |
| | | else |
| | | { |
| | | return akm; |
| | | } |
| | | } |
| | | |
| | | /** |
| | | * Indicates whether or not a connection should use SSL based on |
| | |
| | | * @return bind password for connections |
| | | */ |
| | | public String getBindPassword() { |
| | | return String.valueOf(this.bindPassword); |
| | | return this.bindPassword; |
| | | } |
| | | |
| | | /** |
| | |
| | | |
| | | if (result.getValue().equals(TrustOption.CERTIFICATE_DETAILS.getChoice())) |
| | | { |
| | | for (int i = 0; i < chain.length; i++) |
| | | for (X509Certificate cert : chain) |
| | | { |
| | | app.println(); |
| | | app.println(INFO_LDAP_CONN_SECURITY_SERVER_CERTIFICATE.get(chain[i])); |
| | | app.println(INFO_LDAP_CONN_SECURITY_SERVER_CERTIFICATE.get(cert)); |
| | | } |
| | | continue; |
| | | } |
| | | |
| | | // We should add it in the memory truststore |
| | | for (int i = 0; i < chain.length; i++) |
| | | for (X509Certificate cert : chain) |
| | | { |
| | | String alias = chain[i].getSubjectDN().getName(); |
| | | String alias = cert.getSubjectDN().getName(); |
| | | try |
| | | { |
| | | truststore.setCertificateEntry(alias, chain[i]); |
| | | truststore.setCertificateEntry(alias, cert); |
| | | } |
| | | catch (KeyStoreException e1) |
| | | { |
| | |
| | | ValidationCallback<String> callback = |
| | | new ValidationCallback<String>() |
| | | { |
| | | @Override |
| | | public String validate(ConsoleApplication app, String input) |
| | | throws ClientException |
| | | { |
| | |
| | | } |
| | | |
| | | // Read the password from the stdin. |
| | | char[] truststorePassword; |
| | | String truststorePassword; |
| | | try |
| | | { |
| | | app.println(); |
| | | LocalizableMessage prompt = INFO_LDAP_CONN_PROMPT_SECURITY_KEYSTORE_PASSWORD |
| | | .get(truststorePath); |
| | | truststorePassword = app.readPassword(prompt); |
| | | truststorePassword = readPassword(prompt); |
| | | } |
| | | catch (Exception e) |
| | | { |
| | |
| | | { |
| | | fis = null; |
| | | } |
| | | ts.load(fis, truststorePassword); |
| | | ts.load(fis, truststorePassword.toCharArray()); |
| | | if (fis != null) |
| | | { |
| | | fis.close(); |
| | | } |
| | | for (int i = 0; i < chain.length; i++) |
| | | for (X509Certificate cert : chain) |
| | | { |
| | | String alias = chain[i].getSubjectDN().getName(); |
| | | ts.setCertificateEntry(alias, chain[i]); |
| | | String alias = cert.getSubjectDN().getName(); |
| | | ts.setCertificateEntry(alias, cert); |
| | | } |
| | | FileOutputStream fos = new FileOutputStream(truststorePath); |
| | | ts.store(fos, truststorePassword); |
| | | if (fos != null) |
| | | try |
| | | { |
| | | ts.store(fos, truststorePassword.toCharArray()); |
| | | } |
| | | finally |
| | | { |
| | | fos.close(); |
| | | } |
| | |
| | | if (this.useSSL) { |
| | | options.setUseSSL(true); |
| | | SSLConnectionFactory sslConnectionFactory = new SSLConnectionFactory(); |
| | | sslConnectionFactory.init(getTrustManager() == null, String |
| | | .valueOf(keystorePath), String.valueOf(keystorePassword), String |
| | | .valueOf(certifNickname), String.valueOf(truststorePath), String |
| | | .valueOf(truststorePassword)); |
| | | sslConnectionFactory.init(getTrustManager() == null, keystorePath, |
| | | keystorePassword, certifNickname, |
| | | truststorePath, truststorePassword); |
| | | options.setSSLConnectionFactory(sslConnectionFactory); |
| | | } else { |
| | | options.setUseSSL(false); |
| | |
| | | ApplicationTrustManager usedTrustManager, String usedUrl, |
| | | boolean displayErrorMessage, LocalizedLogger logger) |
| | | { |
| | | boolean returnValue = false; |
| | | ApplicationTrustManager.Cause cause; |
| | | if (usedTrustManager != null) |
| | | { |
| | |
| | | } |
| | | else |
| | | { |
| | | LocalizableMessage msg = Utils.getThrowableMsg(INFO_ERROR_CONNECTING_TO_LOCAL.get(), |
| | | t); |
| | | app.println(msg); |
| | | app.println(Utils.getThrowableMsg(INFO_ERROR_CONNECTING_TO_LOCAL.get(), t)); |
| | | } |
| | | |
| | | if (excType != null) |
| | |
| | | } |
| | | if (chain != null) |
| | | { |
| | | returnValue = checkServerCertificate(chain, authType, host); |
| | | return checkServerCertificate(chain, authType, host); |
| | | } |
| | | } |
| | | return returnValue; |
| | | return false; |
| | | } |
| | | |
| | | /** |