/*
* SSHTools - Java SSH2 API
*
* Copyright (C) 2002-2003 Lee David Painter and Contributors.
*
* Contributions made by:
*
* Brett Smith
* Richard Pernavas
* Erwin Bolwidt
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package com.sshtools.j2ssh.configuration;
import com.sshtools.j2ssh.util.ExtensionClassLoader;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.AccessControlException;
import java.security.AccessController;
import java.security.SecureRandom;
import java.security.Security;
import java.util.Iterator;
import java.util.List;
import java.util.Properties;
import java.util.PropertyPermission;
import java.util.Vector;
/**
*
*
* @author $author$
* @version $Revision: 1.67 $
*/
public class ConfigurationLoader {
private static Vector contexts = new Vector();
private static SecureRandom rnd;
private static ExtensionClassLoader ext = null;
private static ClassLoader clsLoader = null;
private static Log log = LogFactory.getLog(ConfigurationLoader.class);
private static String homedir;
private static boolean initialized = false;
private static Object initializationLock = new Object();
static {
// Get the sshtools.home system property. If system properties can not be
// read then we are running in a sandbox
// try {
homedir = checkAndGetProperty("sshtools.home",
System.getProperty("java.home"));
if ((homedir != null) && !homedir.endsWith(File.separator)) {
homedir += File.separator;
}
rnd = new SecureRandom();
rnd.nextInt();
}
/**
*
*
* @return
*/
public static SecureRandom getRND() {
return rnd;
}
/**
*
*
* @param projectname
* @param versionFile
*
* @return
*/
public static String getVersionString(String projectname, String versionFile) {
Properties properties = new Properties();
String version = projectname;
try {
properties.load(loadFile(versionFile));
String project = projectname.toLowerCase();
String major = properties.getProperty(project + ".version.major");
String minor = properties.getProperty(project + ".version.minor");
String build = properties.getProperty(project + ".version.build");
String type = properties.getProperty(project + ".project.type");
if ((major != null) && (minor != null) && (build != null)) {
version += (" " + major + "." + minor + "." + build);
}
if (type != null) {
version += (" " + type);
}
} catch (Exception e) {
}
return version;
}
/**
*
*
* @param property
* @param defaultValue
*
* @return
*/
public static String checkAndGetProperty(String property,
String defaultValue) {
// Check for access to sshtools.platform
try {
if (System.getSecurityManager() != null) {
AccessController.checkPermission(new PropertyPermission(
property, "read"));
}
return System.getProperty(property, defaultValue);
} catch (AccessControlException ace) {
return defaultValue;
}
}
/**
*
*
* @param force
*
* @throws ConfigurationException
*/
public static void initialize(boolean force) throws ConfigurationException {
initialize(force, new DefaultConfigurationContext());
}
/**
* <p>
* Initializes the J2SSH api with a specified configuration context. This
* method will attempt to load the Bouncycastle JCE if it detects the java
* version is 1.3.1.
* </p>
*
* @param force force the configuration to load even if a configuration
* already exists
* @param context the configuration context to load
*
* @throws ConfigurationException if the configuration is invalid or if a
* security provider is not available
*/
public static void initialize(boolean force, ConfigurationContext context)
throws ConfigurationException {
// }
try {
String javaversion = System.getProperty("java.version");
log.info("JAVA version is " + javaversion);
if (javaversion.startsWith("1.3")) {
boolean provider = false;
for (int i = 0; i < Security.getProviders().length; i++) {
log.info(Security.getProviders()[i].getName() +
" security provider found");
if (Security.getProviders()[i].getClass().getName().equals("org.bouncycastle.jce.provider.BouncyCastleProvider")) {
provider = true;
}
}
if (provider == false) {
log.info("Attempting to load the bouncycastle jce provider");
// Attempt to load a JCE Provider - replace or remove these statements
// depending upon how you want to initialize your JCE provider
Class cls;
cls = Class.forName(
"org.bouncycastle.jce.provider.BouncyCastleProvider");
java.security.Security.addProvider((java.security.Provider) cls.newInstance());
}
}
} catch (Exception ex) {
log.info("Failed to load the bouncycastle jce provider", ex);
if (java.security.Security.getProviders().length <= 0) {
throw new ConfigurationException(
"There are no security providers available; install jce-jdk13-119.jar available from http://www.bouncycastle.org");
} else {
log.info("An existing provider has been detected");
}
}
synchronized (initializationLock) {
if (initialized && !force) {
return;
}
// }
context.initialize();
contexts.add(context);
if (ext == null) {
// We need to setup the dynamic class loading with the extension jars
ext = new ExtensionClassLoader(ConfigurationLoader.class.getClassLoader());
try {
// Jar files to add to the classpath
File dir = new File(homedir + "lib" + File.separator +
"ext");
// Filter for .jar files
FilenameFilter filter = new FilenameFilter() {
public boolean accept(File dir, String name) {
return name.endsWith(".jar");
}
};
// Get the list
File[] children = dir.listFiles(filter);
List classpath = new Vector();
if (children != null) {
for (int i = 0; i < children.length; i++) {
// Get filename of file or directory
log.info("Extension " +
children[i].getAbsolutePath() +
" being added to classpath");
ext.add(children[i]);
}
}
} catch (AccessControlException ex) {
log.info(
"Cannot access lib/ext directory, extension classes will not be loaded");
}
}
initialized = true;
}
}
/**
*
*
* @param cls
*
* @return
*
* @throws ConfigurationException
*/
public static boolean isConfigurationAvailable(Class cls)
throws ConfigurationException {
if (!initialized) {
initialize(false);
}
if (contexts.size() > 0) {
Iterator it = contexts.iterator();
while (it.hasNext()) {
ConfigurationContext context = (ConfigurationContext) it.next();
if (context.isConfigurationAvailable(cls)) {
return true;
}
}
return false;
} else {
return false;
}
}
/**
*
*
* @param cls
*
* @return
*
* @throws ConfigurationException
*/
public static Object getConfiguration(Class cls)
throws ConfigurationException {
if (contexts.size() > 0) {
Iterator it = contexts.iterator();
while (it.hasNext()) {
ConfigurationContext context = (ConfigurationContext) it.next();
if (context.isConfigurationAvailable(cls)) {
return context.getConfiguration(cls);
}
}
}
throw new ConfigurationException("No " + cls.getName() +
" configuration is available in this context");
}
/**
*
*
* @return
*/
public static String getConfigurationDirectory() {
return homedir + "conf/";
}
/**
*
*
* @param name
*
* @return
*
* @throws ClassNotFoundException
* @throws ConfigurationException
*/
public static Class getExtensionClass(String name)
throws ClassNotFoundException, ConfigurationException {
if (!initialized) {
initialize(false);
}
if (ext == null) {
throw new ClassNotFoundException("Configuration not initialized");
}
return ext.loadClass(name);
}
/**
*
*
* @return
*/
public static String getHomeDirectory() {
return homedir;
}
/**
*
*
* @param clsLoader
*/
public static void setContextClassLoader(ClassLoader clsLoader) {
ConfigurationLoader.clsLoader = clsLoader;
}
public static ExtensionClassLoader getExtensionClassLoader() {
return ext;
}
public static String getExtensionPath() {
return homedir + "/lib/ext";
}
/**
*
*
* @return
*/
public static ClassLoader getContextClassLoader() {
return ConfigurationLoader.clsLoader;
}
/**
*
*
* @return
*/
public static boolean isContextClassLoader() {
return (clsLoader != null);
}
/**
*
*
* @param homedir
*/
public static void setHomeDirectory(String homedir) {
ConfigurationLoader.homedir = homedir.replace('\\', '/');
if (!ConfigurationLoader.homedir.endsWith("/")) {
ConfigurationLoader.homedir += "/";
}
}
/**
*
*
* @param filename
*
* @return
*
* @throws FileNotFoundException
*/
public static InputStream loadFile(String filename)
throws FileNotFoundException {
FileInputStream in;
try {
in = new FileInputStream(getConfigurationDirectory() + filename);
return in;
} catch (FileNotFoundException fnfe) {
}
try {
in = new FileInputStream(homedir + filename);
return in;
} catch (FileNotFoundException fnfe) {
}
in = new FileInputStream(filename);
return in;
}
/**
*
*
* @param filename
*
* @return
*
* @throws FileNotFoundException
*/
public static OutputStream saveFile(String filename)
throws FileNotFoundException {
// Look for the file in the config directory
File f = new File(getConfigurationDirectory() + filename);
if (f.exists()) {
// Yes its there so create an outputstream to it
return new FileOutputStream(f);
} else {
// Look for it absolute
f = new File(filename);
if (f.exists()) {
return new FileOutputStream(filename); // yes so do absolute
} else {
// Determine whether the filename is absolute or not with a primitive check
return new FileOutputStream((filename.indexOf(
File.pathSeparator) >= 0) ? filename
: (getConfigurationDirectory() +
filename));
}
}
}
static class DefaultConfigurationContext implements ConfigurationContext {
public void initialize() throws ConfigurationException {
// Do nothing
}
public boolean isConfigurationAvailable(Class cls) {
return false;
}
public Object getConfiguration(Class cls) throws ConfigurationException {
throw new ConfigurationException(
"Default configuration does not contain " + cls.getName());
}
}
}