Merge remote-tracking branch 'upstream/master'
This commit is contained in:
		
							
								
								
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										5
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							| @ -24,5 +24,10 @@ src/main/main.iml | ||||
| *.LOCAL.*.jsp | ||||
| *.REMOTE.*.jsp | ||||
| src/main/webapp/plugin_extracted/* | ||||
| src/main/webapp/users/*.jar | ||||
| src/main/webapp/plugin_lessons/*.jar | ||||
| src/main/webapp/users/*.props | ||||
| classes/* | ||||
|  | ||||
| /*.iml | ||||
| .extract/* | ||||
|  | ||||
| @ -96,9 +96,14 @@ Follow These instructions if you wish to run Webgoat and modify the source code | ||||
| Building the project (Developers) | ||||
| --------------------------------- | ||||
|  | ||||
| > cd webgoat | ||||
| Using a command shell/window: | ||||
|  | ||||
| > cd webgoat-classloader | ||||
| > mvn clean install | ||||
| > cd .. | ||||
| > mvn clean package | ||||
|  | ||||
| Building the webgoat-classloader is only necessary once, the classloader needs to be present in your local repository. | ||||
| After opening the project in Netbeans or Eclipse, you can easily run the project using:  | ||||
|  | ||||
| 1. Maven-Tomcat Plugin | ||||
|  | ||||
							
								
								
									
										3
									
								
								catalina.policy
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										3
									
								
								catalina.policy
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,3 @@ | ||||
| grant { | ||||
|   permission java.security.AllPermission; | ||||
| }; | ||||
							
								
								
									
										67
									
								
								pom.xml
									
									
									
									
									
								
							
							
						
						
									
										67
									
								
								pom.xml
									
									
									
									
									
								
							| @ -44,6 +44,19 @@ | ||||
|                     <encoding>ISO-8859-1</encoding> | ||||
|                 </configuration> | ||||
|             </plugin> | ||||
|             <plugin> | ||||
|                 <groupId>org.apache.maven.plugins</groupId> | ||||
|                 <artifactId>maven-jar-plugin</artifactId> | ||||
|                 <executions> | ||||
|                     <execution> | ||||
|                         <id>create-jar</id> | ||||
|                         <phase>compile</phase> | ||||
|                         <goals> | ||||
|                             <goal>jar</goal> | ||||
|                         </goals> | ||||
|                     </execution> | ||||
|                 </executions> | ||||
|             </plugin> | ||||
|             <plugin> | ||||
|                 <groupId>org.apache.maven.plugins</groupId> | ||||
|                 <artifactId>maven-war-plugin</artifactId> | ||||
| @ -64,38 +77,6 @@ | ||||
|                     </archive> | ||||
|                 </configuration> | ||||
|             </plugin> | ||||
|             <plugin> | ||||
|                 <artifactId>maven-war-plugin</artifactId> | ||||
|                 <version>2.6</version> | ||||
|                 <configuration> | ||||
|                     <attachClasses>true</attachClasses> | ||||
|                 </configuration> | ||||
|             </plugin> | ||||
|             <plugin> | ||||
|                 <groupId>org.apache.maven.plugins</groupId> | ||||
|                 <artifactId>maven-dependency-plugin</artifactId> | ||||
|                 <executions> | ||||
|                     <execution> | ||||
|                         <goals> | ||||
|                             <goal>copy</goal> | ||||
|                         </goals> | ||||
|                         <phase>package</phase> | ||||
|                         <configuration> | ||||
|                             <artifactItems> | ||||
|                                 <artifactItem> | ||||
|                                     <groupId>${project.groupId}</groupId> | ||||
|                                     <artifactId>${project.artifactId}</artifactId> | ||||
|                                     <version>${project.version}</version> | ||||
|                                     <type>jar</type> | ||||
|                                     <classifier>classes</classifier> | ||||
|                                     <outputDirectory>${project.build.directory}</outputDirectory> | ||||
|                                     <destFileName>webgoat-container-${project.version}.jar</destFileName> | ||||
|                                 </artifactItem> | ||||
|                             </artifactItems> | ||||
|                         </configuration> | ||||
|                     </execution> | ||||
|                 </executions> | ||||
|             </plugin> | ||||
|             <plugin> | ||||
|                 <groupId>org.codehaus.mojo</groupId> | ||||
|                 <artifactId>build-helper-maven-plugin</artifactId> | ||||
| @ -125,7 +106,24 @@ | ||||
|                     <url>http://localhost:8080/manager</url> | ||||
|                     <path>/WebGoat</path> | ||||
|                     <attachArtifactClassifier>exec</attachArtifactClassifier> | ||||
|                     <contextReloadable>true</contextReloadable> | ||||
|                     <useSeparateTomcatClassLoader>true</useSeparateTomcatClassLoader> | ||||
|                     <contextFile>${project.basedir}/src/main/webapp/WEB-INF/context.xml</contextFile> | ||||
|                     <extraDependencies> | ||||
|                         <extraDependency> | ||||
|                             <groupId>org.owasp.webgoat</groupId> | ||||
|                             <artifactId>webgoat-classloader</artifactId> | ||||
|                             <version>${project.version}</version> | ||||
|                         </extraDependency> | ||||
|                     </extraDependencies> | ||||
|                 </configuration> | ||||
|                 <dependencies> | ||||
|                     <dependency> | ||||
|                         <groupId>org.owasp.webgoat</groupId> | ||||
|                         <artifactId>webgoat-container</artifactId> | ||||
|                         <version>${project.version}</version> | ||||
|                     </dependency> | ||||
|                 </dependencies> | ||||
|                 <executions> | ||||
|                     <execution> | ||||
|                         <id>tomcat-run</id> | ||||
| @ -140,6 +138,11 @@ | ||||
|     </build> | ||||
|  | ||||
|     <dependencies> | ||||
|         <dependency> | ||||
|             <groupId>org.owasp.webgoat</groupId> | ||||
|             <artifactId>webgoat-classloader</artifactId> | ||||
|             <version>${project.version}</version> | ||||
|         </dependency> | ||||
|         <dependency> | ||||
|             <groupId>javax.activation</groupId> | ||||
|             <artifactId>activation</artifactId> | ||||
|  | ||||
| @ -1,17 +1,5 @@ | ||||
| package org.owasp.webgoat; | ||||
|  | ||||
| import java.io.IOException; | ||||
| import java.io.PrintWriter; | ||||
| import java.text.SimpleDateFormat; | ||||
| import java.util.Date; | ||||
| import java.util.Locale; | ||||
| import java.util.TimeZone; | ||||
| import javax.servlet.ServletContext; | ||||
| import javax.servlet.ServletException; | ||||
| import javax.servlet.http.HttpServlet; | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
| import javax.servlet.http.HttpServletResponse; | ||||
| import javax.servlet.http.HttpSession; | ||||
| import org.owasp.webgoat.lessons.AbstractLesson; | ||||
| import org.owasp.webgoat.lessons.WelcomeScreen; | ||||
| import org.owasp.webgoat.lessons.admin.WelcomeAdminScreen; | ||||
| @ -24,6 +12,19 @@ import org.owasp.webgoat.session.WebgoatContext; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
|  | ||||
| import javax.servlet.ServletContext; | ||||
| import javax.servlet.ServletException; | ||||
| import javax.servlet.http.HttpServlet; | ||||
| import javax.servlet.http.HttpServletRequest; | ||||
| import javax.servlet.http.HttpServletResponse; | ||||
| import javax.servlet.http.HttpSession; | ||||
| import java.io.IOException; | ||||
| import java.io.PrintWriter; | ||||
| import java.text.SimpleDateFormat; | ||||
| import java.util.Date; | ||||
| import java.util.Locale; | ||||
| import java.util.TimeZone; | ||||
|  | ||||
| /** | ||||
|  * ************************************************************************************************* | ||||
|  * | ||||
| @ -192,8 +193,7 @@ public class HammerHead extends HttpServlet { | ||||
|             logger.debug("Screen: " + screen); | ||||
|             request.getRequestDispatcher(viewPage).forward(request, response); | ||||
|         } catch (Throwable t) { | ||||
|             logger.error("Error handling request", t); | ||||
|             screen = new ErrorScreen(mySession, t); | ||||
|             logger.error("Error handling request", t); screen = new ErrorScreen(mySession, t); | ||||
|         } finally { | ||||
|             try { | ||||
|                 if (screen instanceof ErrorScreen) { | ||||
|  | ||||
| @ -5,13 +5,13 @@ | ||||
|  */ | ||||
| package org.owasp.webgoat.application; | ||||
|  | ||||
| import javax.servlet.ServletContext; | ||||
| import javax.servlet.ServletContextEvent; | ||||
| import javax.servlet.ServletContextListener; | ||||
| import java.io.IOException; | ||||
| import java.io.InputStream; | ||||
| import java.util.jar.Attributes; | ||||
| import java.util.jar.Manifest; | ||||
| import javax.servlet.ServletContext; | ||||
| import javax.servlet.ServletContextEvent; | ||||
| import javax.servlet.ServletContextListener; | ||||
|  | ||||
| /** | ||||
|  * Web application lifecycle listener. | ||||
|  | ||||
| @ -355,8 +355,7 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object | ||||
|      * @return The lessonPlan value | ||||
|      */ | ||||
|     protected String getLessonName() { | ||||
|         int index = this.getClass().getName().indexOf("lessons."); | ||||
|         return this.getClass().getName().substring(index + "lessons.".length()); | ||||
|         return this.getClass().getSimpleName(); | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @ -734,6 +733,7 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object | ||||
|         Form form = new Form(getFormAction(), Form.POST).setName("form").setEncType(""); | ||||
|         form.addElement(createContent(s)); | ||||
|         setContent(form); | ||||
|         s.getRequest().getRequestURL(); | ||||
|     } | ||||
|  | ||||
|     public String getFormAction() { | ||||
| @ -802,4 +802,17 @@ public abstract class AbstractLesson extends Screen implements Comparable<Object | ||||
|     	} | ||||
|     	return labelManager; | ||||
|     } | ||||
|  | ||||
|     protected final String buildImagePath(WebSession w, String imgResourceName) { | ||||
|         return w.getRequest().getContextPath() + "/plugin_extracted/plugin/" + getLessonName() + "/images/" + imgResourceName; | ||||
|     } | ||||
|  | ||||
|     protected final String buildJspPath(WebSession w, String jspResourceName) { | ||||
|         return w.getRequest().getContextPath() + "/plugin_extracted/plugin/" + getLessonName() + "/jsp/" + jspResourceName; | ||||
|     } | ||||
|  | ||||
|     protected final String buildJsPath(WebSession w, String jsResourceName) { | ||||
|         return w.getRequest().getContextPath() + "/plugin_extracted/plugin/" + getLessonName() + "/js/" +  jsResourceName; | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -1,21 +1,18 @@ | ||||
| package org.owasp.webgoat.plugins; | ||||
|  | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.util.Iterator; | ||||
| import java.util.LinkedList; | ||||
| import java.util.List; | ||||
| import java.util.Set; | ||||
|  | ||||
| import javax.servlet.ServletContext; | ||||
|  | ||||
| import org.owasp.webgoat.HammerHead; | ||||
| import org.owasp.webgoat.lessons.AbstractLesson; | ||||
| import org.owasp.webgoat.session.WebgoatContext; | ||||
| import org.owasp.webgoat.session.WebgoatProperties; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
|  | ||||
| import javax.servlet.ServletContext; | ||||
| import java.io.File; | ||||
| import java.util.Iterator; | ||||
| import java.util.LinkedList; | ||||
| import java.util.List; | ||||
| import java.util.Set; | ||||
|  | ||||
| /** | ||||
|  * ************************************************************************************************* | ||||
|  * <p/> | ||||
| @ -178,7 +175,7 @@ public class LegacyLoader { | ||||
|         for (String file : files) { | ||||
|             String className = getClassFile(file, path); | ||||
|  | ||||
|             if (className != null && !className.endsWith("_i")) { | ||||
|             if (className != null && !className.endsWith("_i") && className.startsWith("org.owasp.webgoat.lessons.admin")) { | ||||
|                 try { | ||||
|                 	Class c = Class.forName(className); | ||||
|                     Object o = c.newInstance(); | ||||
|  | ||||
| @ -1,16 +1,16 @@ | ||||
| package org.owasp.webgoat.plugins; | ||||
|  | ||||
| import com.google.common.base.Optional; | ||||
| import com.google.common.collect.Lists; | ||||
| import org.owasp.webgoat.classloader.PluginClassLoader; | ||||
| import org.owasp.webgoat.lessons.AbstractLesson; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
| import org.springframework.util.StringUtils; | ||||
|  | ||||
| import java.io.ByteArrayOutputStream; | ||||
| import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.util.Arrays; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
| @ -20,54 +20,48 @@ import static java.nio.file.StandardOpenOption.CREATE; | ||||
| import static java.nio.file.StandardOpenOption.TRUNCATE_EXISTING; | ||||
| import static org.owasp.webgoat.plugins.PluginFileUtils.fileEndsWith; | ||||
| import static org.owasp.webgoat.plugins.PluginFileUtils.hasParentDirectoryWithName; | ||||
| import static org.owasp.webgoat.plugins.PluginFileUtils.replaceInFiles; | ||||
|  | ||||
| public class Plugin { | ||||
|  | ||||
|     private static final String NAME_LESSON_SOLUTION_DIRECTORY = "lessonSolutions"; | ||||
|     private static final String NAME_LESSON_PLANS_DIRECTORY = "lessonPlans"; | ||||
|     private static final String NAME_LESSON_I18N_DIRECTORY = "i18n"; | ||||
|     private final Logger logger = LoggerFactory.getLogger(Plugin.class); | ||||
|     private final Path pluginDirectory; | ||||
|  | ||||
|     private Class<AbstractLesson> lesson; | ||||
|     private Map<String, File> solutionLanguageFiles = new HashMap<>(); | ||||
|     private Map<String, File> lessonPlansLanguageFiles = new HashMap<>(); | ||||
|     private List<File> pluginFiles = Lists.newArrayList(); | ||||
|     private File lessonSourceFile; | ||||
|  | ||||
|     public static class PluginLoadingFailure extends RuntimeException { | ||||
|  | ||||
|         public PluginLoadingFailure(String message) { | ||||
|             super(message); | ||||
|         } | ||||
|  | ||||
|         public PluginLoadingFailure(String message, Exception e) { | ||||
|             super(message, e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public Plugin(Path pluginDirectory) { | ||||
|         this.pluginDirectory = pluginDirectory; | ||||
|     } | ||||
|  | ||||
|     public void loadClasses(Map<String, byte[]> classes) { | ||||
|         ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader(); | ||||
|         PluginClassLoader pluginClassLoader = new PluginClassLoader(contextClassLoader); | ||||
|         for (Map.Entry<String, byte[]> clazz : classes.entrySet()) { | ||||
|             loadClass(pluginClassLoader, clazz.getKey(), clazz.getValue()); | ||||
|         } | ||||
|         if (lesson == null) { | ||||
|             throw new PluginLoadingFailure(String | ||||
|                     .format("Lesson class not found, following classes were detected in the plugin: %s", | ||||
|                             StringUtils.collectionToCommaDelimitedString(classes.keySet()))); | ||||
|     public Plugin(Path pluginDirectory, List<String> classes) { | ||||
|         this.pluginDirectory = pluginDirectory; | ||||
|         findLesson(classes); | ||||
|     } | ||||
|  | ||||
|     private void findLesson(List<String> classes) { | ||||
|         for (String clazzName : classes) { | ||||
|             findLesson(clazzName); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private void loadClass(PluginClassLoader pluginClassLoader, String name, byte[] classFile) { | ||||
|     private void findLesson(String name) { | ||||
|         String realClassName = name.replaceFirst("/", "").replaceAll("/", ".").replaceAll(".class", ""); | ||||
|         PluginClassLoader cl = (PluginClassLoader) Thread.currentThread().getContextClassLoader(); | ||||
|  | ||||
|         Class clazz = pluginClassLoader.loadClass(realClassName, classFile); | ||||
|         if (AbstractLesson.class.isAssignableFrom(clazz)) { | ||||
|             this.lesson = clazz; | ||||
|         try { | ||||
|             Class clazz = cl.loadClass(realClassName, true); | ||||
|  | ||||
|             if (AbstractLesson.class.isAssignableFrom(clazz)) { | ||||
|                 this.lesson = clazz; | ||||
|             } | ||||
|         } catch (ClassNotFoundException ce) { | ||||
|             throw new PluginLoadingFailure("Class " + realClassName + " listed in jar but unable to load the class.", ce); | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -85,6 +79,9 @@ public class Plugin { | ||||
|             if (fileEndsWith(file, ".properties") && hasParentDirectoryWithName(file, NAME_LESSON_I18N_DIRECTORY)) { | ||||
|                 copyProperties(reload, file); | ||||
|             } | ||||
|             if (fileEndsWith(file, ".css", ".jsp", ".js")) { | ||||
|                 pluginFiles.add(file.toFile()); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @ -94,6 +91,7 @@ public class Plugin { | ||||
|             Files.copy(file, bos); | ||||
|             Path propertiesPath = createPropertiesDirectory(); | ||||
|             ResourceBundleClassLoader.setPropertiesPath(propertiesPath); | ||||
|             PluginFileUtils.createDirsIfNotExists(file.getParent()); | ||||
|             if (reload) { | ||||
|                 Files.write(propertiesPath.resolve(file.getFileName()), bos.toByteArray(), CREATE, APPEND); | ||||
|             } else { | ||||
| @ -114,25 +112,48 @@ public class Plugin { | ||||
|  | ||||
|     public void rewritePaths(Path pluginTarget) { | ||||
|         try { | ||||
|             PluginFileUtils.replaceInFiles(this.lesson.getSimpleName() + "_files", | ||||
|             replaceInFiles(this.lesson.getSimpleName() + "_files", | ||||
|                     pluginTarget.getFileName().toString() + "/plugin/" + this.lesson | ||||
|                             .getSimpleName() + "/lessonSolutions/en/" + this.lesson.getSimpleName() + "_files", | ||||
|                     solutionLanguageFiles.values()); | ||||
|             PluginFileUtils.replaceInFiles(this.lesson.getSimpleName() + "_files", | ||||
|             replaceInFiles(this.lesson.getSimpleName() + "_files", | ||||
|                     pluginTarget.getFileName().toString() + "/plugin/" + this.lesson | ||||
|                             .getSimpleName() + "/lessonPlans/en/" + this.lesson.getSimpleName() + "_files", | ||||
|                     lessonPlansLanguageFiles.values()); | ||||
|  | ||||
|             String[] replacements = {"jsp", "js"}; | ||||
|             for ( String replacement : replacements ) { | ||||
|                 String s = String.format("plugin/%s/%s/", this.lesson.getSimpleName(), replacement); | ||||
|                 String r = String.format("%s/plugin/%s/%s/", pluginTarget.getFileName().toString(), | ||||
|                         this.lesson.getSimpleName(), replacement); | ||||
|                 replaceInFiles(s,r, pluginFiles); | ||||
|                 replaceInFiles(s,r, Arrays.asList(lessonSourceFile)); | ||||
|             } | ||||
|  | ||||
|             //CSS with url('/plugin/images') should not begin with / otherwise image cannot be found | ||||
|             String s = String.format("/plugin/%s/images/", this.lesson.getSimpleName()); | ||||
|             String r = String.format("%s/plugin/%s/images/", pluginTarget.getFileName().toString(), this.lesson.getSimpleName()); | ||||
|             replaceInFiles(s,r, pluginFiles); | ||||
|             replaceInFiles(s,r, Arrays.asList(lessonSourceFile)); | ||||
|  | ||||
|  | ||||
|         } catch (IOException e) { | ||||
|             throw new PluginLoadingFailure("Unable to rewrite the paths in the solutions", e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public AbstractLesson getLesson() { | ||||
|     /** | ||||
|      * Lesson is optional, it is also possible that the supplied jar contains only helper classes. | ||||
|      */ | ||||
|     public Optional<AbstractLesson> getLesson() { | ||||
|         try { | ||||
|             return lesson.newInstance(); | ||||
|             if (lesson != null) { | ||||
|                 return Optional.of(lesson.newInstance()); | ||||
|             } | ||||
|         } catch (IllegalAccessException | InstantiationException e) { | ||||
|             throw new PluginLoadingFailure("Unable to instantiate the lesson " + lesson.getName(), e); | ||||
|         } | ||||
|         return Optional.absent(); | ||||
|     } | ||||
|  | ||||
|     public Optional<File> getLessonSolution(String language) { | ||||
|  | ||||
| @ -17,6 +17,7 @@ public class PluginBackgroundLoader implements ServletContextListener { | ||||
|     public void contextInitialized(ServletContextEvent event) { | ||||
|         String pluginPath = event.getServletContext().getRealPath("plugin_lessons"); | ||||
|         String targetPath = event.getServletContext().getRealPath("plugin_extracted"); | ||||
|  | ||||
|         scheduler = Executors.newSingleThreadScheduledExecutor(); | ||||
|         scheduler.scheduleAtFixedRate(new PluginsLoader(Paths.get(pluginPath), Paths.get(targetPath)), 0, 5, TimeUnit.MINUTES); | ||||
|     } | ||||
|  | ||||
| @ -1,43 +0,0 @@ | ||||
| package org.owasp.webgoat.plugins; | ||||
|  | ||||
| import com.google.common.base.Optional; | ||||
| import com.google.common.base.Predicate; | ||||
| import com.google.common.collect.FluentIterable; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
|  | ||||
| import java.util.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| public class PluginClassLoader extends ClassLoader { | ||||
|  | ||||
|     private final List<Class<?>> classes = new ArrayList<>(); | ||||
|     private final Logger logger = LoggerFactory.getLogger(Plugin.class); | ||||
|  | ||||
|     public Class<?> loadClass(String nameOfClass, byte[] classFile) { | ||||
|         Class<?> clazz = defineClass(nameOfClass, classFile, 0, classFile.length); | ||||
|         classes.add(clazz); | ||||
|         return clazz; | ||||
|     } | ||||
|  | ||||
|     public PluginClassLoader(ClassLoader contextClassLoader) { | ||||
|         super(contextClassLoader); | ||||
|     } | ||||
|  | ||||
|     public Class findClass(final String name) throws ClassNotFoundException { | ||||
|         logger.debug("Finding class " + name); | ||||
|         Optional<Class<?>> foundClass = FluentIterable.from(classes) | ||||
|                 .firstMatch(new Predicate<Class<?>>() { | ||||
|                     @Override | ||||
|                     public boolean apply(Class<?> clazz) { | ||||
|                         return clazz.getName().equals(name); | ||||
|                     } | ||||
|                 }); | ||||
|         if (foundClass.isPresent()) { | ||||
|             return foundClass.get(); | ||||
|         } | ||||
|         throw new ClassNotFoundException("Class " + name + " not found"); | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| package org.owasp.webgoat.plugins; | ||||
|  | ||||
| import java.io.ByteArrayOutputStream; | ||||
| import com.google.common.collect.Lists; | ||||
|  | ||||
| import java.io.IOException; | ||||
| import java.net.URI; | ||||
| import java.nio.file.FileSystem; | ||||
| @ -14,20 +15,19 @@ import java.nio.file.attribute.BasicFileAttributes; | ||||
| import java.util.ArrayList; | ||||
| import java.util.HashMap; | ||||
| import java.util.List; | ||||
| import java.util.Map; | ||||
|  | ||||
| import static java.lang.String.format; | ||||
| import static java.nio.file.StandardCopyOption.REPLACE_EXISTING; | ||||
| import static org.owasp.webgoat.plugins.PluginFileUtils.createDirsIfNotExists; | ||||
|  | ||||
| /** | ||||
|  * Extract the wpf file and place them in the system temp directory in the folder webgoat and collect the files | ||||
|  * Extract the jar file and place them in the system temp directory in the folder webgoat and collect the files | ||||
|  * and classes. | ||||
|  */ | ||||
| public class PluginExtractor { | ||||
|  | ||||
|     private final Path pluginArchive; | ||||
|     private final Map<String, byte[]> classes = new HashMap<>(); | ||||
|     private final List<String> classes = Lists.newArrayList(); | ||||
|     private final List<Path> files = new ArrayList<>(); | ||||
|  | ||||
|     public PluginExtractor(Path pluginArchive) { | ||||
| @ -41,20 +41,18 @@ public class PluginExtractor { | ||||
|                 @Override | ||||
|                 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { | ||||
|                     if (file.toString().endsWith(".class")) { | ||||
|                         ByteArrayOutputStream bos = new ByteArrayOutputStream(); | ||||
|                         Files.copy(file, bos); | ||||
|                         classes.put(file.toString(), bos.toByteArray()); | ||||
|                         classes.add(file.toString()); | ||||
|                     } | ||||
|                     files.add(Files.copy(file, createDirsIfNotExists(Paths.get(target.toString(), file.toString())), REPLACE_EXISTING)); | ||||
|                     return FileVisitResult.CONTINUE; | ||||
|                 } | ||||
|             }); | ||||
|         } catch (Exception e) { | ||||
|             new Plugin.PluginLoadingFailure(format("Unable to extract: %s", pluginArchive.getFileName()), e); | ||||
|             new PluginLoadingFailure(format("Unable to extract: %s", pluginArchive.getFileName()), e); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     public Map<String, byte[]> getClasses() { | ||||
|     public List<String> getClasses() { | ||||
|         return this.classes; | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -7,6 +7,7 @@ import java.io.File; | ||||
| import java.io.IOException; | ||||
| import java.nio.file.DirectoryStream; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.OpenOption; | ||||
| import java.nio.file.Path; | ||||
| import java.nio.file.Paths; | ||||
| import java.nio.file.StandardOpenOption; | ||||
| @ -20,6 +21,15 @@ public class PluginFileUtils { | ||||
|         return p.getFileName().toString().endsWith(s); | ||||
|     } | ||||
|  | ||||
|     public static boolean fileEndsWith(Path p, String... suffixes) { | ||||
|         for (String suffix : suffixes) { | ||||
|             if (fileEndsWith(p, suffix)) { | ||||
|                 return true; | ||||
|             } | ||||
|         } | ||||
|         return false; | ||||
|     } | ||||
|  | ||||
|     public static boolean hasParentDirectoryWithName(Path p, String s) { | ||||
|         if (p == null || p.getParent() == null || p.getParent().equals(p.getRoot())) { | ||||
|             return false; | ||||
| @ -69,4 +79,12 @@ public class PluginFileUtils { | ||||
|         Files.write(file, fileAsString.getBytes(), StandardOpenOption.TRUNCATE_EXISTING); | ||||
|     } | ||||
|  | ||||
|     public static void writeFile(Path targetFile, byte[] bytes, OpenOption... options) throws IOException { | ||||
|         createDirsIfNotExists(targetFile.getParent()); | ||||
|         if (!Files.exists(targetFile)) { | ||||
|             Files.createFile(targetFile); | ||||
|         } | ||||
|         Files.write(targetFile, bytes, options); | ||||
|     } | ||||
|  | ||||
| } | ||||
|  | ||||
| @ -0,0 +1,8 @@ | ||||
| package org.owasp.webgoat.plugins; | ||||
|  | ||||
| public class PluginLoadingFailure extends RuntimeException { | ||||
|  | ||||
|     public PluginLoadingFailure(String message, Exception e) { | ||||
|         super(message, e); | ||||
|     } | ||||
| } | ||||
| @ -1,60 +1,84 @@ | ||||
| package org.owasp.webgoat.plugins; | ||||
|  | ||||
| import com.google.common.base.Preconditions; | ||||
| import com.google.common.collect.Lists; | ||||
| import org.owasp.webgoat.classloader.PluginClassLoader; | ||||
| import org.slf4j.Logger; | ||||
| import org.slf4j.LoggerFactory; | ||||
|  | ||||
| import java.io.IOException; | ||||
| import java.net.URISyntaxException; | ||||
| import java.net.URL; | ||||
| 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.ArrayList; | ||||
| import java.util.List; | ||||
|  | ||||
| public class PluginsLoader implements Runnable { | ||||
|  | ||||
|     protected 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 Path pluginTarget; | ||||
|  | ||||
|  | ||||
|     public PluginsLoader(Path pluginSource, Path pluginTarget) { | ||||
|         Preconditions.checkNotNull(pluginSource, "plugin source cannot be null"); | ||||
|         Preconditions.checkNotNull(pluginTarget, "plugin target cannot be null"); | ||||
|  | ||||
|         this.pluginSource = pluginSource; | ||||
|         this.pluginTarget = pluginTarget; | ||||
|     } | ||||
|  | ||||
|     public List<Plugin> loadPlugins(final boolean reload) { | ||||
|         final List<Plugin> plugins = new ArrayList<Plugin>(); | ||||
|         final PluginClassLoader cl = (PluginClassLoader)Thread.currentThread().getContextClassLoader(); | ||||
|         List<Plugin> plugins = Lists.newArrayList(); | ||||
|  | ||||
|         try { | ||||
|             Files.walkFileTree(pluginSource, new SimpleFileVisitor<Path>() { | ||||
|  | ||||
|                 @Override | ||||
|                 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { | ||||
|                     try { | ||||
|                     	if (PluginFileUtils.fileEndsWith(file, WEBGOAT_PLUGIN_EXTENSION)) { | ||||
|                             PluginFileUtils.createDirsIfNotExists(pluginTarget); | ||||
|                             PluginExtractor extractor = new PluginExtractor(file); | ||||
|                             extractor.extract(pluginTarget); | ||||
|                             Plugin plugin = new Plugin(pluginTarget); | ||||
|                             plugin.loadClasses(extractor.getClasses()); | ||||
|                             plugin.loadFiles(extractor.getFiles(), reload); | ||||
|                             plugin.rewritePaths(pluginTarget); | ||||
|                             plugins.add(plugin);                 		 | ||||
|                     	} | ||||
|                     } catch (Plugin.PluginLoadingFailure e) { | ||||
|                        logger.error("Unable to load plugin, continue loading others...", e); | ||||
|                     } | ||||
|                     return FileVisitResult.CONTINUE; | ||||
|                 } | ||||
|  | ||||
|             }); | ||||
|         } catch (IOException e) { | ||||
|             List<URL> jars = listJars(); | ||||
|             cl.addURL(jars); | ||||
|             plugins = processPlugins(jars, reload); | ||||
|         } catch (IOException | URISyntaxException e) { | ||||
|             logger.error("Loading plugins failed", e); | ||||
|         } | ||||
|         return plugins; | ||||
|     } | ||||
|  | ||||
|     private List<URL> listJars() throws IOException { | ||||
|         final List<URL> jars = Lists.newArrayList(); | ||||
|         Files.walkFileTree(pluginSource, new SimpleFileVisitor<Path>() { | ||||
|  | ||||
|             @Override | ||||
|             public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) throws IOException { | ||||
|                 if (PluginFileUtils.fileEndsWith(file, WEBGOAT_PLUGIN_EXTENSION)) { | ||||
|                     jars.add(file.toUri().toURL()); | ||||
|                 } | ||||
|                 return FileVisitResult.CONTINUE; | ||||
|             } | ||||
|         }); | ||||
|         return jars; | ||||
|     } | ||||
|  | ||||
|     private List<Plugin> processPlugins(List<URL> jars, boolean reload) throws URISyntaxException, IOException { | ||||
|         final List<Plugin> plugins = Lists.newArrayList(); | ||||
|         for (URL jar : jars) { | ||||
|  | ||||
|             PluginExtractor extractor = new PluginExtractor(Paths.get(jar.toURI())); | ||||
|             extractor.extract(pluginTarget); | ||||
|  | ||||
|             Plugin plugin = new Plugin(pluginTarget, extractor.getClasses()); | ||||
|             if (plugin.getLesson().isPresent()) { | ||||
|                 PluginFileUtils.createDirsIfNotExists(pluginTarget); | ||||
|                 plugin.loadFiles(extractor.getFiles(), reload); | ||||
|                 plugin.rewritePaths(pluginTarget); | ||||
|                 plugins.add(plugin); | ||||
|             } | ||||
|         } | ||||
|         return plugins; | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|     public void run() { | ||||
|  | ||||
| @ -19,13 +19,13 @@ public class ResourceBundleClassLoader { | ||||
|         classLoader.propertiesPath = path; | ||||
|     } | ||||
|  | ||||
|     public static ClassLoader createPropertyFilesClassLoader(ClassLoader parentClassLoader) { | ||||
|     public static ClassLoader createPropertyFilesClassLoader() { | ||||
|         final List<URL> urls = new ArrayList<>(); | ||||
|  | ||||
|         try { | ||||
|             urls.add(classLoader.propertiesPath.toUri().toURL()); | ||||
|         } catch (IOException e) { | ||||
|             throw new Plugin.PluginLoadingFailure("Unable to load the properties for the classloader", e); | ||||
|             throw new PluginLoadingFailure("Unable to load the properties for the classloader", e); | ||||
|         } | ||||
|         return new URLClassLoader(urls.toArray(new URL[urls.size()]), Thread.currentThread().getContextClassLoader()); | ||||
|     } | ||||
|  | ||||
| @ -265,7 +265,6 @@ public class Course { | ||||
|         } | ||||
|  | ||||
|         Collections.sort(lessonList); | ||||
|         // System.out.println(java.util.Arrays.asList(lessonList)); | ||||
|         return lessonList; | ||||
|     } | ||||
|  | ||||
| @ -295,6 +294,7 @@ public class Course { | ||||
|         logger.debug("Loading plugins into cache"); | ||||
|         String pluginPath = context.getRealPath("plugin_lessons"); | ||||
|         String targetPath = context.getRealPath("plugin_extracted"); | ||||
|  | ||||
|         if (pluginPath == null) { | ||||
|             logger.error("Plugins directory {} not found", pluginPath); | ||||
|             return; | ||||
| @ -304,7 +304,7 @@ public class Course { | ||||
|         List<Plugin> plugins = new PluginsLoader(Paths.get(pluginPath), Paths.get(targetPath)).loadPlugins(true); | ||||
|         for (Plugin plugin : plugins) { | ||||
|             try { | ||||
|                 AbstractLesson lesson = plugin.getLesson(); | ||||
|                 AbstractLesson lesson = plugin.getLesson().get(); | ||||
|                 lesson.setWebgoatContext(webgoatContext); | ||||
|                 lesson.update(properties); | ||||
|  | ||||
|  | ||||
| @ -48,7 +48,7 @@ public class LabelProvider | ||||
| 	{ | ||||
| 		if (!labels.containsKey(locale)) | ||||
| 		{ | ||||
| 			ClassLoader classLoader = ResourceBundleClassLoader.createPropertyFilesClassLoader(ResourceBundle.class.getClassLoader()); | ||||
| 			ClassLoader classLoader = ResourceBundleClassLoader.createPropertyFilesClassLoader(); | ||||
| 			ResourceBundle resBundle = ResourceBundle.getBundle("WebGoatLabels", locale, classLoader, localeController); | ||||
| 			labels.put(locale, resBundle); | ||||
| 		} | ||||
|  | ||||
| @ -1,2 +1,4 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <Context antiJARLocking="true" path="/WebGoat"/> | ||||
| <Context antiJARLocking="true" path="/WebGoat"> | ||||
|     <Loader delegate="true" loaderClass="org.owasp.webgoat.classloader.PluginClassLoader" searchExternalFirst="true"/> | ||||
| </Context> | ||||
|  | ||||
							
								
								
									
										4
									
								
								src/main/webapp/WEB-INF/context.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/main/webapp/WEB-INF/context.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <Context antiJARLocking="true" path="/WebGoat"> | ||||
|     <Loader delegate="true" loaderClass="org.owasp.webgoat.classloader.PluginClassLoader" searchExternalFirst="true"/> | ||||
| </Context> | ||||
| @ -23,7 +23,7 @@ public class GlobalPropertiesTest { | ||||
|         new GlobalProperties(pluginDirectory).loadProperties(directory); | ||||
|  | ||||
|         ClassLoader propertyFilesClassLoader = | ||||
|             ResourceBundleClassLoader.createPropertyFilesClassLoader(this.getClass().getClassLoader()); | ||||
|             ResourceBundleClassLoader.createPropertyFilesClassLoader(); | ||||
|         assertNotNull(propertyFilesClassLoader.getResourceAsStream("global.properties")); | ||||
|     } | ||||
|  | ||||
|  | ||||
| @ -1,45 +1,32 @@ | ||||
| package org.owasp.webgoat.plugins; | ||||
|  | ||||
| import org.junit.Test; | ||||
|  | ||||
| import java.nio.charset.StandardCharsets; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.nio.file.Paths; | ||||
| import java.util.Arrays; | ||||
| import java.util.List; | ||||
|  | ||||
| import static org.junit.Assert.assertThat; | ||||
| import static org.junit.matchers.JUnitMatchers.containsString; | ||||
| import static org.junit.matchers.JUnitMatchers.hasItem; | ||||
|  | ||||
| public class PluginTest { | ||||
|  | ||||
|     @Test | ||||
|     public void pathShouldBeRewrittenInHtmlFile() throws Exception { | ||||
|         Path tmpDir = PluginTestHelper.createTmpDir(); | ||||
|         Path pluginSourcePath = PluginTestHelper.pathForLoading(); | ||||
|         Plugin plugin = PluginTestHelper.createPluginFor(TestPlugin.class); | ||||
|         Path htmlFile = Paths.get(pluginSourcePath.toString(), "lessonSolutions", "rewrite_test.html"); | ||||
|         plugin.loadFiles(Arrays.asList(htmlFile), true); | ||||
|         plugin.rewritePaths(tmpDir); | ||||
|         List<String> allLines = Files.readAllLines(htmlFile, StandardCharsets.UTF_8); | ||||
|  | ||||
|         assertThat(allLines, | ||||
|             hasItem(containsString("plugin/TestPlugin/lessonSolutions/en/TestPlugin_files/image001.png"))); | ||||
|     } | ||||
|  | ||||
|     @Test | ||||
|     public void shouldNotRewriteOtherLinks() throws Exception { | ||||
|         Path tmpDir = PluginTestHelper.createTmpDir(); | ||||
|         Path pluginSourcePath = PluginTestHelper.pathForLoading(); | ||||
|         Plugin plugin = PluginTestHelper.createPluginFor(TestPlugin.class); | ||||
|         Path htmlFile = Paths.get(pluginSourcePath.toString(), "lessonSolutions", "rewrite_test.html"); | ||||
|         plugin.loadFiles(Arrays.asList(htmlFile), true); | ||||
|         plugin.rewritePaths(tmpDir); | ||||
|         List<String> allLines = Files.readAllLines(htmlFile, StandardCharsets.UTF_8); | ||||
|  | ||||
|         assertThat(allLines, | ||||
|             hasItem(containsString("Unknown_files/image001.png"))); | ||||
|     } | ||||
| //    @Test | ||||
| //    public void pathShouldBeRewrittenInHtmlFile() throws Exception { | ||||
| //        Path tmpDir = PluginTestHelper.createTmpDir(); | ||||
| //        Path pluginSourcePath = PluginTestHelper.pathForLoading(); | ||||
| //        Plugin plugin = PluginTestHelper.createPluginFor(TestPlugin.class); | ||||
| //        Path htmlFile = Paths.get(pluginSourcePath.toString(), "lessonSolutions", "rewrite_test.html"); | ||||
| //        plugin.loadFiles(Arrays.asList(htmlFile), true); | ||||
| //        plugin.rewritePaths(tmpDir); | ||||
| //        List<String> allLines = Files.readAllLines(htmlFile, StandardCharsets.UTF_8); | ||||
| // | ||||
| //        assertThat(allLines, | ||||
| //            hasItem(containsString("plugin/TestPlugin/lessonSolutions/en/TestPlugin_files/image001.png"))); | ||||
| //    } | ||||
| // | ||||
| //    @Test | ||||
| //    public void shouldNotRewriteOtherLinks() throws Exception { | ||||
| //        Path tmpDir = PluginTestHelper.createTmpDir(); | ||||
| //        Path pluginSourcePath = PluginTestHelper.pathForLoading(); | ||||
| //        Plugin plugin = PluginTestHelper.createPluginFor(TestPlugin.class); | ||||
| //        Path htmlFile = Paths.get(pluginSourcePath.toString(), "lessonSolutions", "rewrite_test.html"); | ||||
| //        plugin.loadFiles(Arrays.asList(htmlFile), true); | ||||
| //        plugin.rewritePaths(tmpDir); | ||||
| //        List<String> allLines = Files.readAllLines(htmlFile, StandardCharsets.UTF_8); | ||||
| // | ||||
| //        assertThat(allLines, | ||||
| //            hasItem(containsString("Unknown_files/image001.png"))); | ||||
| //    } | ||||
| } | ||||
| @ -5,8 +5,6 @@ import java.net.URISyntaxException; | ||||
| import java.nio.file.Files; | ||||
| import java.nio.file.Path; | ||||
| import java.nio.file.Paths; | ||||
| import java.util.HashMap; | ||||
| import java.util.Map; | ||||
|  | ||||
| public class PluginTestHelper { | ||||
|  | ||||
| @ -23,12 +21,11 @@ public class PluginTestHelper { | ||||
|         return Paths.get(path.toString(), "org/owasp/webgoat/plugins"); | ||||
|     } | ||||
|  | ||||
|     public static Plugin createPluginFor(Class pluginClass) throws Exception { | ||||
|         Path pluginTargetPath = Files.createDirectory(Paths.get(tempDirectory.toString(), "pluginTargetPath")); | ||||
|         Plugin plugin = new Plugin(pluginTargetPath); | ||||
|         Map<String, byte[]> classes = new HashMap<>(); | ||||
|         classes.put(pluginClass.getName(), Files.readAllBytes(Paths.get(pathForLoading().toString(), pluginClass.getSimpleName() + ".class"))); | ||||
|         plugin.loadClasses(classes); | ||||
|         return plugin; | ||||
|     } | ||||
| //    public static Plugin createPluginFor(Class pluginClass) throws Exception { | ||||
| //        Path pluginTargetPath = Files.createDirectory(Paths.get(tempDirectory.toString(), "pluginTargetPath")); | ||||
| //        Map<String, byte[]> classes = new HashMap<>(); | ||||
| //        classes.put(pluginClass.getName(), Files.readAllBytes(Paths.get(pathForLoading().toString(), pluginClass.getSimpleName() + ".class"))); | ||||
| //        Plugin plugin = new Plugin(pluginTargetPath, classes); | ||||
| //        return plugin; | ||||
| //    } | ||||
| } | ||||
|  | ||||
							
								
								
									
										4
									
								
								webgoat-classloader/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								webgoat-classloader/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | ||||
| target/ | ||||
| .idea/ | ||||
| *.iml | ||||
| dependency-reduced-pom.xml | ||||
							
								
								
									
										18
									
								
								webgoat-classloader/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								webgoat-classloader/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||||
|     <name>WebGoat</name> | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|     <groupId>org.owasp.webgoat</groupId> | ||||
|     <artifactId>webgoat-classloader</artifactId> | ||||
|     <packaging>jar</packaging> | ||||
|     <version>6.1.0</version> | ||||
|  | ||||
|     <dependencies> | ||||
|         <dependency> | ||||
|             <groupId>org.apache.tomcat</groupId> | ||||
|             <artifactId>tomcat-catalina</artifactId> | ||||
|             <version>7.0.47</version> | ||||
|         </dependency> | ||||
|     </dependencies> | ||||
|  | ||||
| </project> | ||||
| @ -0,0 +1,31 @@ | ||||
| package org.owasp.webgoat.classloader; | ||||
|  | ||||
| import org.apache.catalina.loader.WebappClassLoader; | ||||
|  | ||||
| import java.net.URL; | ||||
| import java.util.List; | ||||
|  | ||||
| /** | ||||
|  * Classloader for Tomcat. | ||||
|  * | ||||
|  * We need to provide this classloader otherwise jsp files cannot be compiled. JspContextWrapper uses | ||||
|  * Thread.currentThread().getContextClassLoader() but during initialisation it loads the classloader which means | ||||
|  * this classloader will never pickup the plugin classes. | ||||
|  * | ||||
|  * With this loader we can add jars we load during the plugin loading and the jsp will pick it up because this is | ||||
|  * the same classloader. | ||||
|  */ | ||||
| public class PluginClassLoader extends WebappClassLoader { | ||||
|     public PluginClassLoader() { | ||||
|     } | ||||
|  | ||||
|     public PluginClassLoader(ClassLoader parent) { | ||||
|         super(parent); | ||||
|     } | ||||
|  | ||||
|     public void addURL(List<URL> urls) { | ||||
|         for (URL url : urls) { | ||||
|             super.addURL(url); | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										4
									
								
								webgoat-release/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								webgoat-release/.gitignore
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -0,0 +1,4 @@ | ||||
| target/ | ||||
| .idea/ | ||||
| *.iml | ||||
| dependency-reduced-pom.xml | ||||
							
								
								
									
										18
									
								
								webgoat-release/README.md
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								webgoat-release/README.md
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| # Releasing WebGoat | ||||
|  | ||||
| ## Introduction | ||||
|  | ||||
| This project will create a release for WebGoat ready for distribution. | ||||
| This project creates a war with all the lessons included. | ||||
|  | ||||
| ## Details | ||||
|  | ||||
| The following steps happen during the release: | ||||
|  | ||||
| * Download the webgoat-container.war from the repository | ||||
| * Unpack the war | ||||
| * Download the dist-plugin.zip from the repository | ||||
| * Unpack the lessons | ||||
| * Build the war again (webgoat-release-${version}.war) | ||||
| * Create the executable jar (webgoat-release-${version}-war-exec.jar) | ||||
|  | ||||
							
								
								
									
										124
									
								
								webgoat-release/pom.xml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								webgoat-release/pom.xml
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,124 @@ | ||||
| <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||||
|          xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||||
|     <name>WebGoat</name> | ||||
|     <modelVersion>4.0.0</modelVersion> | ||||
|     <groupId>org.owasp.webgoat</groupId> | ||||
|     <artifactId>webgoat-release</artifactId> | ||||
|     <packaging>war</packaging> | ||||
|     <version>6.1.0</version> | ||||
|  | ||||
|     <repositories> | ||||
|         <repository> | ||||
|             <id>maven2-repository.dev.java.net</id> | ||||
|             <name>Java.net Maven 2 Repository</name> | ||||
|             <url>http://download.java.net/maven/2</url> | ||||
|         </repository> | ||||
|     </repositories> | ||||
|  | ||||
|     <!-- Shared version number properties --> | ||||
|     <properties> | ||||
|         <tiles.version>2.2.2</tiles.version> | ||||
|         <!-- If run from Bamboo this will be replaced with the bamboo build number --> | ||||
|         <build.number>local</build.number> | ||||
|         <lessons.version>1.0</lessons.version> | ||||
|         <war.output.dir>${project.build.directory}/war/</war.output.dir> | ||||
|         <lessons.output.dir>${war.output.dir}/plugin_lessons</lessons.output.dir> | ||||
|     </properties> | ||||
|  | ||||
|     <!-- | ||||
|         Step 1: Unpack the container WAR file | ||||
|         Step 2: Use the zip file and unpack it | ||||
|         Step 3: Build a new WAR file and install it in the repository | ||||
|     --> | ||||
|  | ||||
|     <build> | ||||
|         <plugins> | ||||
|             <!-- Unpack the container.war and dist-plugins.jar --> | ||||
|             <plugin> | ||||
|                 <groupId>org.apache.maven.plugins</groupId> | ||||
|                 <artifactId>maven-dependency-plugin</artifactId> | ||||
|                 <version>2.10</version> | ||||
|                 <executions> | ||||
|                     <execution> | ||||
|                         <id>unpack-war</id> | ||||
|                         <phase>generate-resources</phase> | ||||
|                         <goals> | ||||
|                             <goal>unpack</goal> | ||||
|                         </goals> | ||||
|                         <configuration> | ||||
|                             <artifactItems> | ||||
|                                 <artifactItem> | ||||
|                                     <groupId>org.owasp.webgoat</groupId> | ||||
|                                     <artifactId>webgoat-container</artifactId> | ||||
|                                     <version>${project.version}</version> | ||||
|                                     <type>war</type> | ||||
|                                 </artifactItem> | ||||
|                             </artifactItems> | ||||
|                             <outputDirectory>${war.output.dir}</outputDirectory> | ||||
|                         </configuration> | ||||
|                     </execution> | ||||
|                     <execution> | ||||
|                         <id>unpack-lessons-zip</id> | ||||
|                         <phase>generate-resources</phase> | ||||
|                         <goals> | ||||
|                             <goal>unpack</goal> | ||||
|                         </goals> | ||||
|                         <configuration> | ||||
|                             <skip>false</skip> | ||||
|                             <artifactItems> | ||||
|                                 <artifactItem> | ||||
|                                     <includes>**/*.jar</includes> | ||||
|                                     <groupId>org.owasp.webgoat.lesson</groupId> | ||||
|                                     <artifactId>dist</artifactId> | ||||
|                                     <version>${lessons.version}</version> | ||||
|                                     <type>zip</type> | ||||
|                                     <classifier>plugins</classifier> | ||||
|                                 </artifactItem> | ||||
|                             </artifactItems> | ||||
|                             <outputDirectory>${lessons.output.dir}</outputDirectory> | ||||
|                         </configuration> | ||||
|                     </execution> | ||||
|                 </executions> | ||||
|             </plugin> | ||||
|             <!-- Create the war --> | ||||
|             <plugin> | ||||
|                 <groupId>org.apache.maven.plugins</groupId> | ||||
|                 <artifactId>maven-war-plugin</artifactId> | ||||
|                 <version>2.4</version> | ||||
|                 <configuration> | ||||
|                     <warSourceDirectory>${war.output.dir}</warSourceDirectory> | ||||
|                     <archive> | ||||
|                         <manifest> | ||||
|                             <addDefaultImplementationEntries>true</addDefaultImplementationEntries> | ||||
|                         </manifest> | ||||
|                         <manifestEntries> | ||||
|                             <Specification-Title>${project.name}</Specification-Title> | ||||
|                             <Specification-Version>${project.version}</Specification-Version> | ||||
|                             <Implementation-Version>${build.number}</Implementation-Version> | ||||
|                         </manifestEntries> | ||||
|                     </archive> | ||||
|                 </configuration> | ||||
|             </plugin> | ||||
|             <!-- Create the executable jar --> | ||||
|             <plugin> | ||||
|                 <groupId>org.apache.tomcat.maven</groupId> | ||||
|                 <artifactId>tomcat7-maven-plugin</artifactId> | ||||
|                 <version>2.1</version> | ||||
|                 <configuration> | ||||
|                     <url>http://localhost:8080/manager</url> | ||||
|                     <path>/WebGoat</path> | ||||
|                     <attachArtifactClassifier>exec</attachArtifactClassifier> | ||||
|                 </configuration> | ||||
|                 <executions> | ||||
|                     <execution> | ||||
|                         <id>tomcat-run</id> | ||||
|                         <goals> | ||||
|                             <goal>exec-war-only</goal> | ||||
|                         </goals> | ||||
|                         <phase>package</phase> | ||||
|                     </execution> | ||||
|                 </executions> | ||||
|             </plugin> | ||||
|         </plugins> | ||||
|     </build> | ||||
| </project> | ||||
		Reference in New Issue
	
	Block a user