// Copyright 2010 Google Inc. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package com.google.enterprise.connector.encryptpassword; import com.google.enterprise.connector.common.AbstractCommandLineApp; import com.google.enterprise.connector.instantiator.EncryptedPropertyPlaceholderConfigurer; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Option; import org.apache.commons.cli.Options; import java.io.Console; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.logging.Level; import java.util.logging.Logger; /** * A utility to encrypt passwords from the command line. * * usage: EncryptPassword [-?] [-v] [-p password] * -?, --help Display this help. * -v, --version Display version. * -p, --password Encrypt the supplied password. */ public class EncryptPassword extends AbstractCommandLineApp { /** * Encrypt password static method suitable for calling by the Installer. * As a side effect, the supplied plain-text password character array * is cleared. * * @param password the plain-text password to encrypt * @return the encrypted password */ public static final String encrypt(char[] password) throws Exception { EncryptPassword app = new EncryptPassword(); app.initStandAloneContext(false); return app.encryptPassword(password); } @Override public String getName() { return "EncryptPassword"; } @Override public String getDescription() { return "Encrypts passwords using the Connector Manager keystore."; } @Override public String getCommandLineSyntax() { return super.getCommandLineSyntax() + "[-p password]"; } @Override public Options getOptions() { Options options = super.getOptions(); Option option = new Option("p", "password", true, "Encrypt the supplied password."); option.setArgName("password"); options.addOption(option); return options; } @Override public void run(CommandLine commandLine) throws Exception { initStandAloneContext(false); char[] password = getPassword(commandLine.getOptionValue("password")); if (password != null) { System.out.println(encryptPassword(password)); } } @Override protected void initStandAloneContext(boolean ignored) { // Turn down the logging output to the console. Logger.getLogger("com.google.enterprise.connector").setLevel(Level.WARNING); // Find the Connector Manager WEB-INF directory. File webInfDir = locateWebInf(); if (webInfDir == null) { System.err.println( "Unable to locate the connector-manager webapp directory."); System.err.println("Try changing to that directory, or use"); System.err.println("-Dmanager.dir=/path/to/webapps/connector-manager"); System.exit(-1); } // Establish the webapp keystore configuration before initializing // the Context. try { configureCryptor(webInfDir); } catch (IOException e) { System.err.println("Failed to read keystore configuration: " + e); System.exit(-1); } } /** * A command line utility to encrypt passwords. */ public static final void main(String[] args) throws Exception { EncryptPassword app = new EncryptPassword(); app.run(app.parseArgs(args)); System.exit(0); } /** * Returns the password to encrypt. If a password was not supplied on the * command line, prompt for it. * * @param password password option supplied on command line. * @return String password */ private char[] getPassword(String password) { if (password != null) { // If password was supplied on command line, return it. return password.toCharArray(); } // Since we will be prompting, might as well display the version. printVersion(); Console console = System.console(); if (console == null) { System.err.println("Error: No Console"); return null; } while (true) { char[] pw1 = console.readPassword(" Type Password: "); if ((pw1 == null) || (pw1.length == 0)) { System.exit(0); } char[] pw2 = console.readPassword("Retype Password: "); if (Arrays.equals(pw1, pw2)) { System.out.println("\nThe encrypted password is:"); Arrays.fill(pw2, '\0'); return pw1; } System.out.println("\007\nPasswords do not match. Please try again.\n"); } } /** * Encrypts the supplied password. As a side-effect, it clears the supplied * plain-text password after the conversion. * * @param password plain text password * @return encrypted password */ private String encryptPassword(char[] password) { try { return EncryptedPropertyPlaceholderConfigurer.encryptChars(password); } finally { Arrays.fill(password, '\0'); } } }