Skip to content

Commit

Permalink
Merge pull request WebGoat#105 from nbaars/master
Browse files Browse the repository at this point in the history
Fixed classloading issues with Goathills lessons
  • Loading branch information
mayhew64 committed Oct 1, 2015
2 parents 49c7fb7 + 487bc71 commit 16b8eeb
Show file tree
Hide file tree
Showing 9 changed files with 44 additions and 129 deletions.
3 changes: 2 additions & 1 deletion webgoat-container/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ target/
/src/main/webapp/plugin_lessons/*.jar
/src/main/webapp/plugin_extracted/*
dependency-reduced-pom.xml
src/main/webapp/users/guest.org.owasp.webgoat.lessons.BackDoors.props
src/main/webapp/users/guest.org.owasp.webgoat.lessons.BackDoors.props
/src/main/webapp/WEB-INF/lib/*.jar
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

import com.google.common.base.Optional;
import com.google.common.collect.Lists;
import org.apache.catalina.loader.WebappClassLoader;
import org.owasp.webgoat.lessons.AbstractLesson;
import org.springframework.util.StringUtils;

import java.io.File;
import java.io.IOException;
import java.net.URLClassLoader;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.HashMap;
Expand Down Expand Up @@ -43,10 +43,10 @@ public void findLesson(List<String> classes) {
private void findLesson(String name) {
String realClassName = StringUtils.trimLeadingCharacter(name, '/').replaceAll("/", ".").replaceAll(".class", "");
//TODO should be passed in (refactor)
URLClassLoader cl = (URLClassLoader) Thread.currentThread().getContextClassLoader();
WebappClassLoader cl = (WebappClassLoader) Thread.currentThread().getContextClassLoader();

try {
Class clazz = cl.loadClass(realClassName);
Class clazz = cl.loadClass(realClassName, true);

if (AbstractLesson.class.isAssignableFrom(clazz)) {
this.lesson = clazz;
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
package org.owasp.webgoat.plugins;

import com.google.common.collect.Lists;
import org.apache.catalina.loader.WebappClassLoader;
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.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.ResourceUtils;

import java.io.IOException;
import java.net.URL;
import java.net.URLClassLoader;
import java.nio.file.FileVisitResult;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.SimpleFileVisitor;
import java.nio.file.attribute.BasicFileAttributes;
import java.util.List;
Expand All @@ -30,12 +29,12 @@
*
* @version $Id: $Id
*/
public class PluginsLoader implements Runnable {
public class PluginsLoader {

private static final String WEBGOAT_PLUGIN_EXTENSION = "jar";
private static boolean alreadyLoaded = false;
private final Logger logger = LoggerFactory.getLogger(this.getClass());
private final Path pluginSource;
private final PluginClassLoaderRepository repository;
private Path pluginTarget;

/**
Expand All @@ -44,39 +43,55 @@ public class PluginsLoader implements Runnable {
* @param pluginSource 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.pluginTarget = Objects.requireNonNull(pluginTarget, "plugin target cannot be null");
this.repository = Objects.requireNonNull(repository, "repository cannot be null");
}

/**
* Copy jars to the lib directory
*/
public void copyJars() {
try {
if (!alreadyLoaded) {
WebappClassLoader cl = (WebappClassLoader) Thread.currentThread().getContextClassLoader();
cl.setAntiJARLocking(true);

List<URL> jars = listJars();

Path webInfLib = pluginTarget.getParent().resolve(cl.getJarPath().replaceFirst("\\/", ""));
for (URL jar : jars) {
Path sourceJarFile = Paths.get(jar.toURI());
FileUtils.copyFileToDirectory(sourceJarFile.toFile(), webInfLib.toFile());
}
alreadyLoaded = true;
}
} catch (Exception e) {
logger.error("Copying plugins failed", e);
}
}

/**
* <p>loadPlugins.</p>
*
* @param reload a boolean.
* @return a {@link java.util.List} object.
*/
public List<Plugin> loadPlugins(final boolean reload) {
public List<Plugin> loadPlugins() {
copyJars();
List<Plugin> plugins = Lists.newArrayList();

try {
PluginFileUtils.createDirsIfNotExists(pluginTarget);
cleanupExtractedPluginsDirectory();
List<URL> jars = listJars();
initClassLoader(jars);

plugins = processPlugins(jars);
} catch (Exception e) {
logger.error("Loading plugins failed", e);
}
return plugins;
}

private void initClassLoader(List<URL> jars) {
URLClassLoader classLoader = PluginClassLoaderFactory.createClassLoader(jars);
this.repository.replaceClassLoader(classLoader);
Thread.currentThread().setContextClassLoader(classLoader);
}

private void cleanupExtractedPluginsDirectory() {
Path i18nDirectory = pluginTarget.resolve("plugin/i18n/");
FileUtils.deleteQuietly(i18nDirectory.toFile());
Expand Down Expand Up @@ -131,10 +146,4 @@ public Plugin call() throws Exception {
}
return extractorCallables;
}

/** {@inheritDoc} */
@Override
public void run() {
loadPlugins(true);
}
}

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
*/
package org.owasp.webgoat.service;

import org.owasp.webgoat.plugins.PluginsLoader;
import org.owasp.webgoat.session.WebSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
Expand All @@ -40,6 +41,7 @@
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpSession;
import java.nio.file.Paths;

/**
* <p>PluginReloadService class.</p>
Expand All @@ -61,6 +63,11 @@ public class PluginReloadService extends BaseService {
public @ResponseBody
ResponseEntity<String> reloadPlugins(HttpSession session) {
WebSession webSession = (WebSession) session.getAttribute(WebSession.SESSION);
logger.debug("Loading plugins into cache");
String pluginPath = session.getServletContext().getRealPath("plugin_lessons");
String targetPath = session.getServletContext().getRealPath("plugin_extracted");
new PluginsLoader(Paths.get(pluginPath), Paths.get(targetPath)).copyJars();

webSession.getCourse().loadLessonFromPlugin(session.getServletContext());
return new ResponseEntity("Plugins reload refresh the WebGoat page!",HttpStatus.OK);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import org.owasp.webgoat.lessons.Category;
import org.owasp.webgoat.plugins.Plugin;
import org.owasp.webgoat.plugins.PluginsLoader;
import org.owasp.webgoat.plugins.classloader.PluginClassLoaderRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

Expand Down Expand Up @@ -66,7 +65,6 @@ public class Course {

final Logger logger = LoggerFactory.getLogger(Course.class);

private final PluginClassLoaderRepository repository = new PluginClassLoaderRepository();
private final List<AbstractLesson> lessons = new LinkedList<AbstractLesson>();

private final static String PROPERTIES_FILENAME = HammerHead.propertiesPath;
Expand Down Expand Up @@ -337,7 +335,7 @@ public void loadLessonFromPlugin(ServletContext context) {
return;
}
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) {
try {
AbstractLesson lesson = plugin.getLesson().get();
Expand Down
Empty file.

0 comments on commit 16b8eeb

Please sign in to comment.