package org.owasp.webgoat.session; import org.owasp.webgoat.HammerHead; import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Category; import org.owasp.webgoat.plugins.Plugin; import org.owasp.webgoat.plugins.PluginsLoader; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import javax.servlet.ServletContext; import java.io.File; import java.io.IOException; import java.nio.file.Path; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; /** * ************************************************************************************************* *

*

* This file is part of WebGoat, an Open Web Application Security Project * utility. For details, please see http://www.owasp.org/ *

* Copyright (c) 2002 - 20014 Bruce Mayhew *

* 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., 59 Temple * Place - Suite 330, Boston, MA 02111-1307, USA. *

* Getting Source ============== *

* Source for this application is maintained at https://github.com/WebGoat/WebGoat, a repository * for free software projects. *

* For details, please see http://webgoat.github.io * * @author Bruce Mayhew WebGoat * @created October 28, 2003 */ public class Course { final Logger logger = LoggerFactory.getLogger(Course.class); private final List lessons = new LinkedList(); private final static String PROPERTIES_FILENAME = HammerHead.propertiesPath; private WebgoatProperties properties = null; private final List files = new LinkedList(); private WebgoatContext webgoatContext; public Course() { try { properties = new WebgoatProperties(PROPERTIES_FILENAME); } catch (IOException e) { logger.error("Error loading webgoat properties", e); } } /** * Take an absolute file and return the filename. *

* Ex. /etc/password becomes password * * @param s * @return the file name */ private static String getFileName(String s) { String fileName = new File(s).getName(); if (fileName.contains("/")) { fileName = fileName.substring(fileName.lastIndexOf("/"), fileName.length()); } if (fileName.contains(".")) { fileName = fileName.substring(0, fileName.indexOf(".")); } return fileName; } /** * Take a class name and return the equivalent file name *

* Ex. org.owasp.webgoat becomes org/owasp/webgoat.java * * @param className * @return */ private static String getSourceFile(String className) { StringBuilder sb = new StringBuilder(); sb.append(className.replace(".", "/")); sb.append(".java"); return sb.toString(); } /** * Takes a file name and builds the class file name * * @param fileName Description of the Parameter * @param path Description of the Parameter * @return Description of the Return Value */ private static String getClassFile(String fileName, String path) { String ext = ".class"; fileName = fileName.trim(); /** * We do not handle directories. We do not handle files with different * extensions */ if (fileName.endsWith("/") || !fileName.endsWith(ext)) { return null; } // if the file is in /WEB-INF/classes strip the dir info off int index = fileName.indexOf("/WEB-INF/classes/"); if (index != -1) { fileName = fileName.substring(index + "/WEB-INF/classes/".length(), fileName.length() - ext.length()); fileName = fileName.replace('/', '.'); fileName = fileName.replace('\\', '.'); } else { // Strip off the leading path info fileName = fileName.substring(path.length(), fileName.length() - ext.length()); } return fileName; } /** * Gets the categories attribute of the Course object * * @return The categories value */ public List getCategories() { List categories = new ArrayList(); for (AbstractLesson lesson : lessons) { if (!categories.contains(lesson.getCategory())) { categories.add(lesson.getCategory()); } } Collections.sort(categories); return categories; } /** * Gets the firstLesson attribute of the Course object * * @return The firstLesson value */ public AbstractLesson getFirstLesson() { List roles = new ArrayList(); roles.add(AbstractLesson.USER_ROLE); // Category 0 is the admin function. We want the first real category // to be returned. This is noramally the General category and the Http Basics lesson return ((AbstractLesson) getLessons((Category) getCategories().get(0), roles).get(0)); } /** * Gets the lesson attribute of the Course object * * @param s * @param lessonId Description of the Parameter * @param roles * @return The lesson value */ public AbstractLesson getLesson(WebSession s, int lessonId, List roles) { if (s.isHackedAdmin()) { roles.add(AbstractLesson.HACKED_ADMIN_ROLE); } // System.out.println("getLesson() with roles: " + roles); Iterator iter = lessons.iterator(); while (iter.hasNext()) { AbstractLesson lesson = iter.next(); // System.out.println("getLesson() at role: " + lesson.getRole()); if (lesson.getScreenId() == lessonId && roles.contains(lesson.getRole())) { return lesson; } } return null; } public AbstractLesson getLesson(WebSession s, int lessonId, String role) { List roles = new ArrayList(); roles.add(role); return getLesson(s, lessonId, roles); } public List getLessons(WebSession s, String role) { List roles = new ArrayList(); roles.add(role); return getLessons(s, roles); } /** * Gets the lessons attribute of the Course object * * @param s * @param roles * @return The lessons value */ public List getLessons(WebSession s, List roles) { if (s.isHackedAdmin()) { roles.add(AbstractLesson.HACKED_ADMIN_ROLE); } List lessonList = new ArrayList(); Iterator categoryIter = getCategories().iterator(); while (categoryIter.hasNext()) { lessonList.addAll(getLessons(s, (Category) categoryIter.next(), roles)); } return lessonList; } /** * Gets the lessons attribute of the Course object * * @param category Description of the Parameter * @param role Description of the Parameter * @return The lessons value */ private List getLessons(Category category, List roles) { List lessonList = new ArrayList(); for (AbstractLesson lesson : lessons) { if (lesson.getCategory().equals(category) && roles.contains(lesson.getRole())) { lessonList.add(lesson); } } Collections.sort(lessonList); // System.out.println(java.util.Arrays.asList(lessonList)); return lessonList; } public List getLessons(WebSession s, Category category, String role) { List roles = new ArrayList(); roles.add(role); return getLessons(s, category, roles); } public List getLessons(WebSession s, Category category, List roles) { if (s.isHackedAdmin()) { roles.add(AbstractLesson.HACKED_ADMIN_ROLE); } return getLessons(category, roles); } public AbstractLesson getLesson(int lessonId) { for (AbstractLesson l : lessons) { if (l.getScreenId() == lessonId) { return l; } } return null; } private void loadLessionFromPlugin(ServletContext context) { context.getContextPath(); 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; } Path pluginDirectory = Paths.get(pluginPath); List plugins = new PluginsLoader(Paths.get(pluginPath), Paths.get(targetPath)).loadPlugins(false); for (Plugin plugin : plugins) { try { Class c = plugin.getLesson(); Object o = c.newInstance(); AbstractLesson lesson = (AbstractLesson) o; lesson.setWebgoatContext(webgoatContext); lesson.update(properties); if (lesson.getHidden() == false) { lessons.add(lesson); } for(Map.Entry lessonPlan : plugin.getLessonPlans().entrySet()) { lesson.setLessonPlanFileName(lessonPlan.getKey(), lessonPlan.getValue().toString()); } lesson.setLessonSolutionFileName(plugin.getLessonSolutions().get("en").toString()); lesson.setSourceFileName(plugin.getLessonSource().toString()); } catch (Exception e) { logger.error("Error in loadLessons: ", e); } } } /** * Description of the Method * * @param webgoatContext * @param path Description of the Parameter * @param context Description of the Parameter */ public void loadCourses(WebgoatContext webgoatContext, ServletContext context, String path) { logger.info("Loading courses: " + path); this.webgoatContext = webgoatContext; loadLessionFromPlugin(context); } }