blob: 048e582b4c32d54e24d9909e439a09abc14531f9 [file] [log] [blame]
/*******************************************************************************
* Copyright (C) 2008-2010 The University of Manchester
*
* Modifications to the initial code base are copyright of their
* respective authors, or their employers as appropriate.
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
******************************************************************************/
package net.sf.taverna.t2.commandline;
import java.io.BufferedReader;
import java.io.Console;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import net.sf.taverna.t2.commandline.exceptions.CommandLineMasterPasswordException;
import net.sf.taverna.t2.commandline.options.CommandLineOptions;
import net.sf.taverna.t2.security.credentialmanager.MasterPasswordProvider;
import org.apache.log4j.Logger;
/**
* An implementation of {@link MasterPasswordProvider} that reads Credential Manager's
* master password from stdin (pipe or terminal) is -cmpassword option is present in command
* line arguments. Otherwise it tries to read it from a special file password.txt in a special
* directory specified by -cmdir option, if present.
*
* @author Alex Nenadic
*/
public class CommandLineMasterPasswordProvider implements MasterPasswordProvider {
private static final String CREDENTIAL_MANAGER_MASTER_PASSWORD_OPTION = "cmpassword";
private static final String CREDENTIAL_MANAGER_DIRECTORY_OPTION = "cmdir";
private static Logger logger = Logger.getLogger(CommandLineMasterPasswordProvider.class);
private String masterPassword = null;
private int priority = 200;
private boolean finishedReadingPassword = false;
private final CommandLineOptions commandLineOptions;
public CommandLineMasterPasswordProvider(CommandLineOptions commandLineOptions) {
this.commandLineOptions = commandLineOptions;
}
@Override
public String getMasterPassword(boolean firstTime) {
if (!finishedReadingPassword) {
// -cmpassword option was present in the command line arguments
if (commandLineOptions.hasOption(CREDENTIAL_MANAGER_MASTER_PASSWORD_OPTION)) {
// Try to read the password from stdin (terminal or pipe)
try {
masterPassword = getCredentialManagerPasswordFromStdin();
} catch (CommandLineMasterPasswordException e) {
masterPassword = null;
}
}
// -cmpassword option was not present in the command line arguments
// and -cmdir option was there - try to get the master password from
// the "special" password file password.txt inside the Cred. Manager directory.
else {
if (commandLineOptions.hasOption(CREDENTIAL_MANAGER_DIRECTORY_OPTION)) {
// Try to read the password from a special file located in
// Credential Manager directory (if the dir was not null)
try {
masterPassword = getCredentialManagerPasswordFromFile();
} catch (CommandLineMasterPasswordException ex) {
masterPassword = null;
}
}
}
finishedReadingPassword = true; // we do not want to attempt to read from stdin several
// times
}
return masterPassword;
}
public void setMasterPassword(String masterPassword) {
this.masterPassword = masterPassword;
finishedReadingPassword = true;
}
@Override
public int getProviderPriority() {
return priority;
}
private String getCredentialManagerPasswordFromStdin()
throws CommandLineMasterPasswordException {
String password = null;
Console console = System.console();
if (console == null) { // password is being piped in, not entered in the terminal by user
BufferedReader buffReader = null;
try {
buffReader = new BufferedReader(new InputStreamReader(System.in));
password = buffReader.readLine();
} catch (IOException ex) {
// For some reason the error of the exception thrown
// does not get printed from the Launcher so print it here as
// well as it gives more clue as to what is going wrong.
logger.error(
"An error occured while trying to read Credential Manager's password that was piped in: "
+ ex.getMessage(), ex);
throw new CommandLineMasterPasswordException(
"An error occured while trying to read Credential Manager's password that was piped in: "
+ ex.getMessage(), ex);
} finally {
try {
buffReader.close();
} catch (Exception ioe1) {
// Ignore
}
}
} else { // read the password from the terminal as entered by the user
try {
// Block until user enters password
char passwordArray[] = console.readPassword("Password for Credential Manager: ");
if (passwordArray != null) { // user did not abort input
password = new String(passwordArray);
} // else password will be null
} catch (Exception ex) {
// For some reason the error of the exception thrown
// does not get printed from the Launcher so print it here as
// well as it gives more clue as to what is going wrong.
logger.error(
"An error occured while trying to read Credential Manager's password from the terminal: "
+ ex.getMessage(), ex);
throw new CommandLineMasterPasswordException(
"An error occured while trying to read Credential Manager's password from the terminal: "
+ ex.getMessage(), ex);
}
}
return password;
}
private String getCredentialManagerPasswordFromFile() throws CommandLineMasterPasswordException {
String password = null;
if (commandLineOptions.hasOption(CREDENTIAL_MANAGER_DIRECTORY_OPTION)) {
String cmDir = commandLineOptions.getCredentialManagerDir();
File passwordFile = new File(cmDir, "password.txt");
BufferedReader buffReader = null;
try {
buffReader = new BufferedReader(new FileReader(passwordFile));
password = buffReader.readLine();
} catch (IOException ioe) {
// For some reason the error of the exception thrown
// does not get printed from the Launcher so print it here as
// well as it gives more clue as to what is going wrong.
logger.error("There was an error reading the Credential Manager password from "
+ passwordFile.toString() + ": " + ioe.getMessage(), ioe);
throw new CommandLineMasterPasswordException(
"There was an error reading the Credential Manager password from "
+ passwordFile.toString() + ": " + ioe.getMessage(), ioe);
} finally {
try {
buffReader.close();
} catch (Exception ioe1) {
// Ignore
}
}
}
return password;
}
}