Fixed goathills lesson with JSP now load correctly again

This commit is contained in:
Nanne Baars 2015-09-28 23:27:58 +02:00
parent c0d727d1f2
commit d4450da5d7
4 changed files with 11 additions and 84 deletions

View File

@ -1,9 +1,8 @@
package org.owasp.webgoat.plugins; package org.owasp.webgoat.plugins;
import com.google.common.collect.Lists; import com.google.common.collect.Lists;
import org.apache.catalina.loader.WebappClassLoader;
import org.apache.commons.io.FileUtils; import org.apache.commons.io.FileUtils;
import org.owasp.webgoat.plugins.classloader.PluginClassLoaderFactory;
import org.owasp.webgoat.plugins.classloader.PluginClassLoaderRepository;
import org.owasp.webgoat.util.LabelProvider; import org.owasp.webgoat.util.LabelProvider;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -11,7 +10,6 @@ import org.springframework.util.ResourceUtils;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.FileVisitResult; import java.nio.file.FileVisitResult;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
@ -35,7 +33,6 @@ public class PluginsLoader implements Runnable {
private static final String WEBGOAT_PLUGIN_EXTENSION = "jar"; private static final String WEBGOAT_PLUGIN_EXTENSION = "jar";
private final Logger logger = LoggerFactory.getLogger(this.getClass()); private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final Path pluginSource; private final Path pluginSource;
private final PluginClassLoaderRepository repository;
private Path pluginTarget; private Path pluginTarget;
/** /**
@ -44,26 +41,28 @@ public class PluginsLoader implements Runnable {
* @param pluginSource a {@link java.nio.file.Path} object. * @param pluginSource a {@link java.nio.file.Path} object.
* @param pluginTarget a {@link java.nio.file.Path} object. * @param pluginTarget a {@link java.nio.file.Path} object.
*/ */
public PluginsLoader(PluginClassLoaderRepository repository, Path pluginSource, Path pluginTarget) { public PluginsLoader(Path pluginSource, Path pluginTarget) {
this.pluginSource = Objects.requireNonNull(pluginSource, "plugin source cannot be null"); this.pluginSource = Objects.requireNonNull(pluginSource, "plugin source cannot be null");
this.pluginTarget = Objects.requireNonNull(pluginTarget, "plugin target cannot be null"); this.pluginTarget = Objects.requireNonNull(pluginTarget, "plugin target cannot be null");
this.repository = Objects.requireNonNull(repository, "repository cannot be null");
} }
/** /**
* <p>loadPlugins.</p> * <p>loadPlugins.</p>
* *
* @param reload a boolean.
* @return a {@link java.util.List} object. * @return a {@link java.util.List} object.
*/ */
public List<Plugin> loadPlugins(final boolean reload) { public List<Plugin> loadPlugins() {
List<Plugin> plugins = Lists.newArrayList(); List<Plugin> plugins = Lists.newArrayList();
WebappClassLoader cl = (WebappClassLoader) Thread.currentThread().getContextClassLoader();
try { try {
PluginFileUtils.createDirsIfNotExists(pluginTarget); PluginFileUtils.createDirsIfNotExists(pluginTarget);
cleanupExtractedPluginsDirectory(); cleanupExtractedPluginsDirectory();
List<URL> jars = listJars(); List<URL> jars = listJars();
initClassLoader(jars); for (URL url : jars) {
cl.addRepository(url.toString());
}
plugins = processPlugins(jars); plugins = processPlugins(jars);
} catch (Exception e) { } catch (Exception e) {
logger.error("Loading plugins failed", e); logger.error("Loading plugins failed", e);
@ -71,11 +70,7 @@ public class PluginsLoader implements Runnable {
return plugins; return plugins;
} }
private void initClassLoader(List<URL> jars) {
URLClassLoader classLoader = PluginClassLoaderFactory.createClassLoader(jars);
this.repository.replaceClassLoader(classLoader);
Thread.currentThread().setContextClassLoader(classLoader);
}
private void cleanupExtractedPluginsDirectory() { private void cleanupExtractedPluginsDirectory() {
Path i18nDirectory = pluginTarget.resolve("plugin/i18n/"); Path i18nDirectory = pluginTarget.resolve("plugin/i18n/");
@ -135,6 +130,6 @@ public class PluginsLoader implements Runnable {
/** {@inheritDoc} */ /** {@inheritDoc} */
@Override @Override
public void run() { public void run() {
loadPlugins(true); loadPlugins();
} }
} }

View File

@ -1,31 +0,0 @@
package org.owasp.webgoat.plugins.classloader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.List;
/**
* Create a classloader for the plugins
*/
public class PluginClassLoaderFactory {
private static final Logger logger = LoggerFactory.getLogger(PluginClassLoaderFactory.class);
public static URLClassLoader createClassLoader(List<URL> urls) {
return new URLClassLoader(urls.toArray(new URL[urls.size()]), determineParentClassLoader());
}
private static ClassLoader determineParentClassLoader() {
ClassLoader parent = Thread.currentThread().getContextClassLoader();
try {
parent = Thread.currentThread().getContextClassLoader().getParent()
.loadClass("org.apache.jasper.runtime.JspContextWrapper").getClassLoader();
} catch (ClassNotFoundException e) {
logger.info("Tomcat JspContextWrapper not found, probably not running on Tomcat...");
}
return parent;
}
}

View File

@ -1,35 +0,0 @@
package org.owasp.webgoat.plugins.classloader;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.URLClassLoader;
/**
* Holds the classloaders for the plugins. For now all the plugins are loaded by the same
* classloader. This class can be extended to contain a classloader per plugin.
*/
public class PluginClassLoaderRepository {
private static final Logger logger = LoggerFactory.getLogger(PluginClassLoaderRepository.class);
private URLClassLoader currentPluginLoader;
/**
* @return the plugin classloader
*/
public URLClassLoader get() {
return currentPluginLoader;
}
public void replaceClassLoader(URLClassLoader classLoader) {
if (this.currentPluginLoader != null) {
try {
this.currentPluginLoader.close();
} catch (IOException e) {
logger.warn("Unable to close the current classloader", e);
}
}
this.currentPluginLoader = classLoader;
}
}

View File

@ -5,7 +5,6 @@ import org.owasp.webgoat.lessons.AbstractLesson;
import org.owasp.webgoat.lessons.Category; import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.plugins.Plugin; import org.owasp.webgoat.plugins.Plugin;
import org.owasp.webgoat.plugins.PluginsLoader; import org.owasp.webgoat.plugins.PluginsLoader;
import org.owasp.webgoat.plugins.classloader.PluginClassLoaderRepository;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -66,7 +65,6 @@ public class Course {
final Logger logger = LoggerFactory.getLogger(Course.class); final Logger logger = LoggerFactory.getLogger(Course.class);
private final PluginClassLoaderRepository repository = new PluginClassLoaderRepository();
private final List<AbstractLesson> lessons = new LinkedList<AbstractLesson>(); private final List<AbstractLesson> lessons = new LinkedList<AbstractLesson>();
private final static String PROPERTIES_FILENAME = HammerHead.propertiesPath; private final static String PROPERTIES_FILENAME = HammerHead.propertiesPath;
@ -337,7 +335,7 @@ public class Course {
return; return;
} }
lessons.clear(); lessons.clear();
List<Plugin> plugins = new PluginsLoader(repository, Paths.get(pluginPath), Paths.get(targetPath)).loadPlugins(true); List<Plugin> plugins = new PluginsLoader(Paths.get(pluginPath), Paths.get(targetPath)).loadPlugins();
for (Plugin plugin : plugins) { for (Plugin plugin : plugins) {
try { try {
AbstractLesson lesson = plugin.getLesson().get(); AbstractLesson lesson = plugin.getLesson().get();