001: /*
002: * SSHTools - Java SSH2 API
003: *
004: * Copyright (C) 2002-2003 Lee David Painter and Contributors.
005: *
006: * Contributions made by:
007: *
008: * Brett Smith
009: * Richard Pernavas
010: * Erwin Bolwidt
011: *
012: * This program is free software; you can redistribute it and/or
013: * modify it under the terms of the GNU General Public License
014: * as published by the Free Software Foundation; either version 2
015: * of the License, or (at your option) any later version.
016: *
017: * This program is distributed in the hope that it will be useful,
018: * but WITHOUT ANY WARRANTY; without even the implied warranty of
019: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
020: * GNU General Public License for more details.
021: *
022: * You should have received a copy of the GNU General Public License
023: * along with this program; if not, write to the Free Software
024: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
025: */
026: package com.sshtools.j2ssh.configuration;
027:
028: import com.sshtools.j2ssh.util.ExtensionClassLoader;
029:
030: import org.apache.commons.logging.Log;
031: import org.apache.commons.logging.LogFactory;
032:
033: import java.io.File;
034: import java.io.FileInputStream;
035: import java.io.FileNotFoundException;
036: import java.io.FileOutputStream;
037: import java.io.FilenameFilter;
038: import java.io.InputStream;
039: import java.io.OutputStream;
040:
041: import java.security.AccessControlException;
042: import java.security.AccessController;
043: import java.security.SecureRandom;
044: import java.security.Security;
045:
046: import java.util.Iterator;
047: import java.util.List;
048: import java.util.Properties;
049: import java.util.PropertyPermission;
050: import java.util.Vector;
051:
052: /**
053: *
054: *
055: * @author $author$
056: * @version $Revision: 1.67 $
057: */
058: public class ConfigurationLoader {
059: private static Vector contexts = new Vector();
060: private static SecureRandom rnd;
061: private static ExtensionClassLoader ext = null;
062: private static ClassLoader clsLoader = null;
063: private static Log log = LogFactory
064: .getLog(ConfigurationLoader.class);
065: private static String homedir;
066: private static boolean initialized = false;
067: private static Object initializationLock = new Object();
068:
069: static {
070: // Get the sshtools.home system property. If system properties can not be
071: // read then we are running in a sandbox
072: // try {
073: homedir = checkAndGetProperty("sshtools.home", System
074: .getProperty("java.home"));
075:
076: if ((homedir != null) && !homedir.endsWith(File.separator)) {
077: homedir += File.separator;
078: }
079:
080: rnd = new SecureRandom();
081: rnd.nextInt();
082: }
083:
084: /**
085: *
086: *
087: * @return
088: */
089: public static SecureRandom getRND() {
090: return rnd;
091: }
092:
093: /**
094: *
095: *
096: * @param projectname
097: * @param versionFile
098: *
099: * @return
100: */
101: public static String getVersionString(String projectname,
102: String versionFile) {
103: Properties properties = new Properties();
104: String version = projectname;
105:
106: try {
107: properties.load(loadFile(versionFile));
108:
109: String project = projectname.toLowerCase();
110: String major = properties.getProperty(project
111: + ".version.major");
112: String minor = properties.getProperty(project
113: + ".version.minor");
114: String build = properties.getProperty(project
115: + ".version.build");
116: String type = properties.getProperty(project
117: + ".project.type");
118:
119: if ((major != null) && (minor != null) && (build != null)) {
120: version += (" " + major + "." + minor + "." + build);
121: }
122:
123: if (type != null) {
124: version += (" " + type);
125: }
126: } catch (Exception e) {
127: }
128:
129: return version;
130: }
131:
132: /**
133: *
134: *
135: * @param property
136: * @param defaultValue
137: *
138: * @return
139: */
140: public static String checkAndGetProperty(String property,
141: String defaultValue) {
142: // Check for access to sshtools.platform
143: try {
144: if (System.getSecurityManager() != null) {
145: AccessController
146: .checkPermission(new PropertyPermission(
147: property, "read"));
148: }
149:
150: return System.getProperty(property, defaultValue);
151: } catch (AccessControlException ace) {
152: return defaultValue;
153: }
154: }
155:
156: /**
157: *
158: *
159: * @param force
160: *
161: * @throws ConfigurationException
162: */
163: public static void initialize(boolean force)
164: throws ConfigurationException {
165: initialize(force, new DefaultConfigurationContext());
166: }
167:
168: /**
169: * <p>
170: * Initializes the J2SSH api with a specified configuration context. This
171: * method will attempt to load the Bouncycastle JCE if it detects the java
172: * version is 1.3.1.
173: * </p>
174: *
175: * @param force force the configuration to load even if a configuration
176: * already exists
177: * @param context the configuration context to load
178: *
179: * @throws ConfigurationException if the configuration is invalid or if a
180: * security provider is not available
181: */
182: public static void initialize(boolean force,
183: ConfigurationContext context) throws ConfigurationException {
184: // }
185: try {
186: String javaversion = System.getProperty("java.version");
187: log.info("JAVA version is " + javaversion);
188:
189: if (javaversion.startsWith("1.3")) {
190: boolean provider = false;
191:
192: for (int i = 0; i < Security.getProviders().length; i++) {
193: log.info(Security.getProviders()[i].getName()
194: + " security provider found");
195:
196: if (Security.getProviders()[i]
197: .getClass()
198: .getName()
199: .equals(
200: "org.bouncycastle.jce.provider.BouncyCastleProvider")) {
201: provider = true;
202: }
203: }
204:
205: if (provider == false) {
206: log
207: .info("Attempting to load the bouncycastle jce provider");
208:
209: // Attempt to load a JCE Provider - replace or remove these statements
210: // depending upon how you want to initialize your JCE provider
211: Class cls;
212: cls = Class
213: .forName("org.bouncycastle.jce.provider.BouncyCastleProvider");
214: java.security.Security
215: .addProvider((java.security.Provider) cls
216: .newInstance());
217: }
218: }
219: } catch (Exception ex) {
220: log
221: .info(
222: "Failed to load the bouncycastle jce provider",
223: ex);
224:
225: if (java.security.Security.getProviders().length <= 0) {
226: throw new ConfigurationException(
227: "There are no security providers available; install jce-jdk13-119.jar available from http://www.bouncycastle.org");
228: } else {
229: log.info("An existing provider has been detected");
230: }
231: }
232:
233: synchronized (initializationLock) {
234: if (initialized && !force) {
235: return;
236: }
237:
238: // }
239: context.initialize();
240: contexts.add(context);
241:
242: if (ext == null) {
243: // We need to setup the dynamic class loading with the extension jars
244: ext = new ExtensionClassLoader(
245: ConfigurationLoader.class.getClassLoader());
246:
247: try {
248: // Jar files to add to the classpath
249: File dir = new File(homedir + "lib"
250: + File.separator + "ext");
251:
252: // Filter for .jar files
253: FilenameFilter filter = new FilenameFilter() {
254: public boolean accept(File dir, String name) {
255: return name.endsWith(".jar");
256: }
257: };
258:
259: // Get the list
260: File[] children = dir.listFiles(filter);
261: List classpath = new Vector();
262:
263: if (children != null) {
264: for (int i = 0; i < children.length; i++) {
265: // Get filename of file or directory
266: log.info("Extension "
267: + children[i].getAbsolutePath()
268: + " being added to classpath");
269: ext.add(children[i]);
270: }
271: }
272: } catch (AccessControlException ex) {
273: log
274: .info("Cannot access lib/ext directory, extension classes will not be loaded");
275: }
276: }
277:
278: initialized = true;
279: }
280: }
281:
282: /**
283: *
284: *
285: * @param cls
286: *
287: * @return
288: *
289: * @throws ConfigurationException
290: */
291: public static boolean isConfigurationAvailable(Class cls)
292: throws ConfigurationException {
293: if (!initialized) {
294: initialize(false);
295: }
296:
297: if (contexts.size() > 0) {
298: Iterator it = contexts.iterator();
299:
300: while (it.hasNext()) {
301: ConfigurationContext context = (ConfigurationContext) it
302: .next();
303:
304: if (context.isConfigurationAvailable(cls)) {
305: return true;
306: }
307: }
308:
309: return false;
310: } else {
311: return false;
312: }
313: }
314:
315: /**
316: *
317: *
318: * @param cls
319: *
320: * @return
321: *
322: * @throws ConfigurationException
323: */
324: public static Object getConfiguration(Class cls)
325: throws ConfigurationException {
326: if (contexts.size() > 0) {
327: Iterator it = contexts.iterator();
328:
329: while (it.hasNext()) {
330: ConfigurationContext context = (ConfigurationContext) it
331: .next();
332:
333: if (context.isConfigurationAvailable(cls)) {
334: return context.getConfiguration(cls);
335: }
336: }
337: }
338:
339: throw new ConfigurationException("No " + cls.getName()
340: + " configuration is available in this context");
341: }
342:
343: /**
344: *
345: *
346: * @return
347: */
348: public static String getConfigurationDirectory() {
349: return homedir + "conf/";
350: }
351:
352: /**
353: *
354: *
355: * @param name
356: *
357: * @return
358: *
359: * @throws ClassNotFoundException
360: * @throws ConfigurationException
361: */
362: public static Class getExtensionClass(String name)
363: throws ClassNotFoundException, ConfigurationException {
364: if (!initialized) {
365: initialize(false);
366: }
367:
368: if (ext == null) {
369: throw new ClassNotFoundException(
370: "Configuration not initialized");
371: }
372:
373: return ext.loadClass(name);
374: }
375:
376: /**
377: *
378: *
379: * @return
380: */
381: public static String getHomeDirectory() {
382: return homedir;
383: }
384:
385: /**
386: *
387: *
388: * @param clsLoader
389: */
390: public static void setContextClassLoader(ClassLoader clsLoader) {
391: ConfigurationLoader.clsLoader = clsLoader;
392: }
393:
394: public static ExtensionClassLoader getExtensionClassLoader() {
395: return ext;
396: }
397:
398: public static String getExtensionPath() {
399: return homedir + "/lib/ext";
400: }
401:
402: /**
403: *
404: *
405: * @return
406: */
407: public static ClassLoader getContextClassLoader() {
408: return ConfigurationLoader.clsLoader;
409: }
410:
411: /**
412: *
413: *
414: * @return
415: */
416: public static boolean isContextClassLoader() {
417: return (clsLoader != null);
418: }
419:
420: /**
421: *
422: *
423: * @param homedir
424: */
425: public static void setHomeDirectory(String homedir) {
426: ConfigurationLoader.homedir = homedir.replace('\\', '/');
427:
428: if (!ConfigurationLoader.homedir.endsWith("/")) {
429: ConfigurationLoader.homedir += "/";
430: }
431: }
432:
433: /**
434: *
435: *
436: * @param filename
437: *
438: * @return
439: *
440: * @throws FileNotFoundException
441: */
442: public static InputStream loadFile(String filename)
443: throws FileNotFoundException {
444: FileInputStream in;
445:
446: try {
447: in = new FileInputStream(getConfigurationDirectory()
448: + filename);
449:
450: return in;
451: } catch (FileNotFoundException fnfe) {
452: }
453:
454: try {
455: in = new FileInputStream(homedir + filename);
456:
457: return in;
458: } catch (FileNotFoundException fnfe) {
459: }
460:
461: in = new FileInputStream(filename);
462:
463: return in;
464: }
465:
466: /**
467: *
468: *
469: * @param filename
470: *
471: * @return
472: *
473: * @throws FileNotFoundException
474: */
475: public static OutputStream saveFile(String filename)
476: throws FileNotFoundException {
477: // Look for the file in the config directory
478: File f = new File(getConfigurationDirectory() + filename);
479:
480: if (f.exists()) {
481: // Yes its there so create an outputstream to it
482: return new FileOutputStream(f);
483: } else {
484: // Look for it absolute
485: f = new File(filename);
486:
487: if (f.exists()) {
488: return new FileOutputStream(filename); // yes so do absolute
489: } else {
490: // Determine whether the filename is absolute or not with a primitive check
491: return new FileOutputStream((filename
492: .indexOf(File.pathSeparator) >= 0) ? filename
493: : (getConfigurationDirectory() + filename));
494: }
495: }
496: }
497:
498: static class DefaultConfigurationContext implements
499: ConfigurationContext {
500: public void initialize() throws ConfigurationException {
501: // Do nothing
502: }
503:
504: public boolean isConfigurationAvailable(Class cls) {
505: return false;
506: }
507:
508: public Object getConfiguration(Class cls)
509: throws ConfigurationException {
510: throw new ConfigurationException(
511: "Default configuration does not contain "
512: + cls.getName());
513: }
514: }
515: }
|