package org.owasp.webgoat.session; import java.io.IOException; import java.util.ArrayList; import java.util.Collections; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.Vector; import javax.servlet.ServletContext; import org.owasp.webgoat.HammerHead; import org.owasp.webgoat.lessons.AbstractLesson; import org.owasp.webgoat.lessons.Category; /** * Copyright (c) 2002 Free Software Foundation developed under the custody of the Open Web * Application Security Project (http://www.owasp.org) This software package org.owasp.webgoat.is published by OWASP * under the GPL. You should read and accept the LICENSE before you use, modify and/or redistribute * this software. * * @author Jeff Williams Aspect Security * @created October 28, 2003 */ public class Course { private List lessons = new ArrayList(); private final static String PROPERTIES_FILENAME = HammerHead.propertiesPath; private WebgoatProperties properties = null; public Course() { try { properties = new WebgoatProperties(PROPERTIES_FILENAME); } catch (IOException e) { System.out.println("Error loading WebGoat properties"); e.printStackTrace(); } } /** * Description of the Method * * @param fileName Description of the Parameter * @param path Description of the Parameter * @param ext Description of the Parameter * @return Description of the Return Value */ private String clean( String fileName, String path, String ext ) { fileName = fileName.trim(); // check if file is a directory if ( fileName.endsWith( "/" ) ) { return fileName; } // check if file is a class or java file if ( !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; } /** * Description of the Method * @param lesson Description of the Parameter * @param context Description of the Parameter * @param path Description of the Parameter * @param courseName Description of the Parameter * @param extension TODO */ private void findSourceResource( AbstractLesson lesson, ServletContext context, String path, String className, String extension ) { //System.out.println("findSourceResource() looking for source files in: " + path); //System.out.println("findSourceResource() looking for source files for class: " + className); Set files = context.getResourcePaths( path ); Iterator fileIter = files.iterator(); String resource = null; while ( fileIter.hasNext() ) { resource = (String) fileIter.next(); //System.out.println("findSourceResource() inspecting resource: " + resource); String lessonName = clean( resource, path, extension ); //System.out.println("findSourceResource() cleaned resource name: " + lessonName); //if ( className != null ) //{ // System.out.println("Resource to check: " + resource); // System.out.println("Lesson name: " + lessonName); //} // Not a match if ( lessonName == null ) { continue; } // A subdirectory else if ( ( lessonName.length() != 1 ) && lessonName.endsWith( "/" ) ) { findSourceResource( lesson, context, lessonName, className, extension ); } // A source file else { // Course name will be the fully qualified name: // like lesson.admin.lessonName if ( className.endsWith( lessonName ) ) { int length = 0; int index = className.indexOf("admin."); if ( index == -1 ) { index = className.indexOf("lessons."); length = "lessons.".length(); } else { length = "admin.".length(); } className = className.substring(index + length); //System.out.println("Resource to check: " + resource); //System.out.println("Lesson name: " + lessonName); //store the web path of the source file in the lesson lesson.setSourceFileName(resource); } } } } /** * Description of the Method * @param lesson Description of the Parameter * @param context Description of the Parameter * @param path Description of the Parameter * @param courseName Description of the Parameter * @param extension TODO */ private void findLessonPlanResource( AbstractLesson lesson, ServletContext context, String path, String courseName, String extension ) { Set files = context.getResourcePaths( path ); Iterator fileIter = files.iterator(); String resource = null; while ( fileIter.hasNext() ) { resource = (String) fileIter.next(); String className = clean( resource, path, extension ); //if ( className != null ) //{ // System.out.println("ClassName: " + className); // System.out.println("ResourceToCheck: " + resourceToCheck); //} if ( className == null ) { continue; } else if ( ( className.length() != 1 ) && className.endsWith( "/" ) ) { findLessonPlanResource( lesson, context, className, courseName, extension ); } else { // Course name will be the fully qualified name: // like lesson.admin.lessonName if ( courseName.endsWith( className ) ) { int length = 0; int index = courseName.indexOf("admin."); if ( index == -1 ) { index = courseName.indexOf("lessons."); length = "lessons.".length(); } else { length = "admin.".length(); } courseName = courseName.substring(index + length); //System.out.println("ClassName: " + className); //System.out.println("ResourceToCheck: " + resource); //store the web path of the source file in the lesson lesson.setLessonPlanFileName(resource); } } } } /** * Gets the categories attribute of the Course object * * @return The categories value */ public List getCategories() { List categories = new ArrayList(); Iterator iter = lessons.iterator(); while ( iter.hasNext() ) { AbstractLesson lesson = (AbstractLesson) iter.next(); 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(1), roles).get(0)); } /** * Gets the lesson attribute of the Course object * * @param lessonId Description of the Parameter * @param role Description of the Parameter * @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 = (AbstractLesson) 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 Vector(); roles.add(role); return getLesson(s, lessonId, roles); } public List getLessons( WebSession s, String role ) { List roles = new Vector(); roles.add(role); return getLessons(s, roles); } /** * Gets the lessons attribute of the Course object * * @param role Description of the Parameter * @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(); Iterator iter = lessons.iterator(); while ( iter.hasNext() ) { AbstractLesson lesson = (AbstractLesson) iter.next(); 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 Vector(); 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); } /** * Description of the Method * * @param path Description of the Parameter * @param context Description of the Parameter */ public void loadCourses( boolean enterprise, ServletContext context, String path ) { Set files = context.getResourcePaths( path ); Iterator fileIter = files.iterator(); while ( fileIter.hasNext() ) { String file = (String) fileIter.next(); String className = clean( file, path, ".class" ); //if ( className != null ) //{ // System.out.println( "Checking file: " + file ); // System.out.println( " class: " + className ); //} if ( className == null ) { continue; } else if ( ( className.length() != 1 ) && className.endsWith( "/" ) ) { loadCourses( enterprise, context, className ); } else { Class lessonClass = null; try { lessonClass = Class.forName( className ); Object possibleLesson = lessonClass.newInstance(); if ( possibleLesson instanceof AbstractLesson ) { AbstractLesson lesson = (AbstractLesson) possibleLesson; // Determine if the screen is to be loaded. Look // to see if the session parameter has been initialized. // Look to see if the screen is an enterprise edition screen. if ( !enterprise ) { if ( lesson.isEnterprise() ) { continue; } } // Do not load instructor screens. Currently, they must be manually deployed. if (lesson.getClass().getName().indexOf("instructor") > -1) continue; // There are two methods instead of one because the developer was not // smart enough to figure out the recursive return value findSourceResource( lesson, context, "/", className, ".java" ); findLessonPlanResource( lesson, context, "/", className, ".html" ); // Override lesson attributes based on properties. lesson.update(properties); if(lesson.getHidden() == false) lessons.add( lesson ); //System.out.println( "Found lesson: " + lesson ); } } catch ( Exception e ) { //System.out.println("Could not load lesson: " + className); //e.printStackTrace(); } } } } }