Initial revision
authormaxcooper <maxcooper>
Thu, 8 Aug 2002 13:20:46 +0000 (13:20 +0000)
committermaxcooper <maxcooper>
Thu, 8 Aug 2002 13:20:46 +0000 (13:20 +0000)
36 files changed:
.cvsignore [new file with mode: 0644]
LICENSE [new file with mode: 0644]
README [new file with mode: 0644]
build-webapp.xml [new file with mode: 0644]
build-webapps.xml [new file with mode: 0644]
build.properties.sample [new file with mode: 0644]
build.xml [new file with mode: 0644]
conf/share/MANIFEST.MF [new file with mode: 0644]
conf/share/securityfilter-config_1_0.dtd [new file with mode: 0644]
conf/share/securityfilter-config_1_0.xsd [new file with mode: 0644]
conf/share/web-app_2_3.dtd [new file with mode: 0644]
src/catalina-example/org/securityfilter/catalina/TrivialCatalinaRealm.java [new file with mode: 0644]
src/example/org/securityfilter/example/TrivialSecurityRealm.java [new file with mode: 0644]
src/share/org/securityfilter/config/SecurityConfig.java [new file with mode: 0644]
src/share/org/securityfilter/config/SecurityConstraint.java [new file with mode: 0644]
src/share/org/securityfilter/config/WebResourceCollection.java [new file with mode: 0644]
src/share/org/securityfilter/filter/MatchableURLPattern.java [new file with mode: 0644]
src/share/org/securityfilter/filter/MatchableURLPatternFactory.java [new file with mode: 0644]
src/share/org/securityfilter/filter/SecurityFilter.java [new file with mode: 0644]
src/share/org/securityfilter/filter/SecurityRequestWrapper.java [new file with mode: 0644]
src/share/org/securityfilter/realm/SecurityRealmBase.java [new file with mode: 0644]
src/share/org/securityfilter/realm/SecurityRealmInterface.java [new file with mode: 0644]
src/share/org/securityfilter/realm/adapter/CatalinaRealmAdapter.java [new file with mode: 0644]
web/blank/WEB-INF/securityfilter-config.xml [new file with mode: 0644]
web/blank/WEB-INF/web.xml [new file with mode: 0644]
web/catalina-example/WEB-INF/securityfilter-config.xml [new file with mode: 0644]
web/example/WEB-INF/securityfilter-config.xml [new file with mode: 0644]
web/share/WEB-INF/web.xml [new file with mode: 0644]
web/share/error/403.jsp [new file with mode: 0644]
web/share/forbiddenPage.jsp [new file with mode: 0644]
web/share/index.jsp [new file with mode: 0644]
web/share/loginError.jsp [new file with mode: 0644]
web/share/loginForm.jsp [new file with mode: 0644]
web/share/logout.jsp [new file with mode: 0644]
web/share/menu.jsp [new file with mode: 0644]
web/share/securePage.jsp [new file with mode: 0644]

diff --git a/.cvsignore b/.cvsignore
new file mode 100644 (file)
index 0000000..7d78eef
--- /dev/null
@@ -0,0 +1,4 @@
+build.properties
+dist
+target
+release
diff --git a/LICENSE b/LICENSE
new file mode 100644 (file)
index 0000000..954f708
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,65 @@
+/*
+ * $Header: /cvsroot/securityfilter/securityfilter/LICENSE,v 1.1 2002/08/08 13:20:46 maxcooper Exp $
+ * $Revision: 1.1 $
+ * $Date: 2002/08/08 13:20:46 $
+ *
+ * ====================================================================
+ * 
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999-2001 The Apache Software Foundation.  All rights 
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer. 
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:  
+ *       "This product includes software developed by the 
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Struts", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written 
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ */ 
+
+
+
+
+
diff --git a/README b/README
new file mode 100644 (file)
index 0000000..1e3da13
--- /dev/null
+++ b/README
@@ -0,0 +1,80 @@
+$Header: /cvsroot/securityfilter/securityfilter/README,v 1.1 2002/08/08 13:20:46 maxcooper Exp $
+$Revision: 1.1 $
+$Date: 2002/08/08 13:20:46 $
+
+
+       Security Filter v1.0-b4
+======================================
+http://www.securityfilter.org/
+http://securityfilter.sourceforge.com/
+
+
+What is SecurityFilter?
+-----------------------
+SecurityFilter is a filter that mimics container-based security. It looks just
+like container-based security to your app, as you can call
+request.getRemoteUser(), request.isUserInRole(), and request.getUserPrincipal()
+and get valid responses. However, it can be deployed within your web app, so you
+do not need to set the realm in the server configuration, or put any classes in
+the server classpath. The realm interface for SecurityFilter is proprietary, but
+it is very simple (2 methods) and should be easy to implement for your project.
+The other main advantage is that you can submit the login form without being
+forced there by the security mechanism.
+
+Securityfilter is free software, available under the Apache Software License
+v1.1.
+
+
+What's in this package?
+-----------------------
+Two example apps demonstrate securityfilter in action:
+
+1. securityfilter-example.war - Basic securityfilter app using native
+securityfilter realm implementation.
+
+2. securityfilter-catalina-example.war - Same as securityfilter-example app with
+Tomcat (Catalina) realm implementation and realm adapter class.
+
+A securityfilter-blank.war example app is also provided as a skeleton to use to
+start a new securityfilter application.
+
+
+How to use SecurityFilter
+-------------------------
+To use the SecurityFilter, you need to do these things:
+
+- Have jakarta-regexp in your classpath (tested with v1.2)
+- Declare the SecurityFilter in your web.xml file, and map everything to it
+- Declare your security preferences in WEB-INF/securityfilter-config.xml
+- Provide an implementation of SecurityRealmInterface (or extend
+SecurityRealmBase) for your app (and give its classname in securityfilter-
+config.xml)
+
+The example apps include web.xml and securityfilter-config.xml file examples.
+
+
+Future Direction
+----------------
+This is the first release. It is ready for use and should support everything
+needed for most apps.
+
+
+Contributors
+------------
+1. Max Cooper maintains the project and wrote much of the code.
+2. Torgeir Veimo contributed the Digester-based security-config.xml reader and
+did some additional work on supporting the structures in the file (like multiple
+roles per constraint).
+3. Prakash Malani provided review and Ant help.
+
+
+Feedback
+--------
+Let me know what your priorities are, and if there is anything else you would
+like to see. Contact me via email (max@maxcooper.com) or use SourceForge to
+report bugs or make feature requests (http://securityfilter.sourceforge.com/).
+
+
+Thank you,
+Max Cooper
+
diff --git a/build-webapp.xml b/build-webapp.xml
new file mode 100644 (file)
index 0000000..2ddb103
--- /dev/null
@@ -0,0 +1,318 @@
+<project name="Generic Webapp" default="compile" basedir=".">
+
+<!--
+        This is a generic build.xml file for Ant that can be used to develop
+        any web application that conforms to the following requirements:
+
+        - Web sources appear in the directory specified by the "webapp.web"
+          property, in exactly the hierarchy to be present in the created
+          web application archive.
+
+        - Java sources (if any) appear in the directory specified by the
+          "webapp.src" property, which will be compiled into the
+          "WEB-INF/classes" directory of the resulting web application.
+
+        - You must specify a "servlet.jar" property that defines the path
+          of the servlet API classes you will compile against.
+
+        - If you want to copy Struts libraries and TLD files to your web
+          application, set the "struts.libs" property to the pathname of a
+          directory containing struts.jar and the associated *.tld files.
+
+        - If you want to copy additional JAR files into the WEB-INF/lib
+          directory of your web app, set the "webapp.libs" property to the
+          pathname of a directory containing the JAR files to be copied.
+
+-->
+
+
+<!-- ========== Prerequisite Properties =================================== -->
+
+<!--
+        These properties MUST be set on the "ant" command line, the "antrc"
+        properties file in your home directory, or from settings in a superior
+        build.xml script, if you wish to take advantage of the corresponding
+        functionality.
+
+        compile.classpath             The class path containing external
+                                      JAR files and directories required for
+                                      compiling this web application.  Note
+                                      that struts.jar will automatically be
+                                      added if "struts.lib" is defined, and
+                                      dependent JAR files will be added if
+                                      "webapp.libs" is defined.
+
+        build.home                    Base directory into which we are building
+                                      the Struts components.
+
+        commons-beanutils.jar         (required).  The path to the JAR file
+                                      of the Jakarta Commons Beanutils
+                                      package (version 1.0 or later).
+
+        commons-collections.jar       (required).  The path to the JAR file
+                                      of the Jakarta Commons Collections
+                                      package (version 1.0 or later).
+
+        commons-digester.jar          (required).  The path to the JAR file
+                                      of the Jakarta Commons Digester
+                                      package (version 1.0 or later).
+
+        commons-logging.jar           (required).  The path to the JAR file
+                                      of the Jakarta Commons Logging
+                                      package (version 1.0 or later).
+
+        servlet.jar                   MUST be set to the pathname of the
+                                      servlet API classes you wish to
+                                      compile against.
+
+        securityfilter.libs           If specified, must be the pathname of a
+                                      directory from which "securityfilter.jar" 
+                                      will be copied to your WEB-INF/lib 
+                                      directory.  Also, the securityfilter.jar 
+                                      file will automatically be added to your 
+                                      compile classpath.
+
+        webapp.libs                   If specified, must be the pathname of a
+                                      directory from which all available
+                                      "*.jar" files are copied to the web
+                                      application's WEB-INF/lib directory.
+                                      Also, any JAR files found here will
+                                      automatically be added to your compile
+                                      classpath.
+
+        webapp.name                   MUST be set to the base name of the web
+                                      application archive file that will be
+                                      created for this web application.
+
+        webapp.suppress               Set this property to an arbitrary value
+                                      (such as "true") if you do NOT want the
+                                      source code for your web application
+                                      copied to the WEB-INF/src directory.
+
+        webapp.war                    If specified, overrides the default name
+                                      of the web application archive file to be
+                                      created for this webapp.  Default value
+                                      is "${webapp.name}.war".
+
+-->
+
+<property name="build.home"            value="target" />
+<property name="servlet.jar"          value="../jakarta-servletapi/lib/servlet.jar"/>
+
+
+
+<!-- ========== Initialization Properties ================================= -->
+
+
+<!--
+        These property values may optionally be overridden with property
+        settings from an "ant" command line, the "antrc" properties file
+        in your home directory, or from settings in a superior build.xml
+        script.
+-->
+
+
+
+<!-- Should Java compilations set the debug compiler option? -->
+<property name="compile.debug"         value="true" />
+
+<!-- Should Java compilations set the deprecation compiler option? -->
+<property name="compile.deprecation"   value="false" />
+
+<!-- Should Java compilations set the optimize compiler option? -->
+<property name="compile.optimize"      value="true" />
+
+<!-- The base directory for distribution targets -->
+<property name="dist.home"             value="dist" />
+
+<!-- The source directory for Java compilations related to this webapp -->
+<property name="webapp.src"            value="src/${webapp.name}" />
+
+<!-- The version number of this particular web application -->
+<property name="webapp.version"        value="1.0" />
+
+<!-- The name of the web application archive file to be produced -->
+<property name="webapp.war"            value="${webapp.name}.war" />
+
+<!-- The source directory for copying static web resources and files -->
+<property name="webapp.web"            value="web/${webapp.name}" />
+
+
+<!-- ========== Derived Properties ======================================== -->
+
+
+<!--
+        These property values are derived from values defined above, and
+        generally should NOT be overridden by command line settings
+-->
+
+<!-- The target directory for building the packed web application -->
+<property name="webapp.dist"           value="${dist.home}/webapps" />
+
+<!-- The target directory for building the unpacked web application -->
+<property name="webapp.target"         value="${build.home}/${webapp.name}" />
+
+<!-- The class path used for compiling this library -->
+<path id="classpath">
+  <pathelement location="${catalina.jar}"/>
+  <pathelement location="${commons-beanutils.jar}"/>
+  <pathelement location="${commons-collections.jar}"/>
+  <pathelement location="${commons-digester.jar}"/>
+  <pathelement location="${commons-logging.jar}"/>
+  <pathelement location="${servlet.jar}"/>
+  <pathelement location="${securityfilter.libs}/securityfilter.jar"/>
+  <pathelement location="${webapp.libs}"/>
+  <pathelement path="${compile.classpath}"/>
+</path>
+
+
+<!-- ========== Executable Targets ======================================== -->
+
+
+<!--
+        The "init" target evaluates "available" expressions as necessary
+        to modify the behavior of this script.
+-->
+<target name="init">
+
+  <echo    message="Processing webapp ${webapp.name}"/>
+
+  <!-- Do we need to copy dependent libraries? -->
+  <available property="copy.libs"        file="${webapp.libs}" />
+
+  <!-- Do we need to compile the Java sources for this web application? -->
+  <available property="webapp.compile"   file="${webapp.src}" />
+
+  <!-- Should we copy Security Filter library files? -->
+  <available property="webapp.securityfilter"    file="${securityfilter.libs}" />
+
+</target>
+
+
+<!--
+        The "prepare" target creates a directory structure in the build target
+        area for the unpacked files associated with this web application
+-->
+<target name="prepare" depends="init"
+        description="Prepare target directory">
+  <echo    message="Processing webapp ${webapp.name}"/>
+  <mkdir   dir="${webapp.target}" />
+  <mkdir   dir="${webapp.target}/WEB-INF" />
+  <mkdir   dir="${webapp.target}/WEB-INF/classes" />
+  <!-- do we need this twice? -->
+  <mkdir   dir="${webapp.target}" />
+</target>
+
+
+<!--
+        The "libs" target copies specified library JAR files (if any) from the
+        "${webapp.libs} directory into the WEB-INF/lib directory of this app.
+-->
+
+<target name="libs" depends="prepare" if="copy.libs"
+        description="Copy dependent libraries">
+  <echo    message="Processing webapp ${webapp.name}"/>
+  <mkdir   dir="${webapp.target}/WEB-INF/lib" />
+  <copy  todir="${webapp.target}/WEB-INF/lib">
+    <fileset dir="${webapp.libs}" includes="*.jar"/>
+  </copy>
+</target>
+
+
+<!--
+        The "source" target copies the Java source code of your web application
+        into the build target area, IF AND ONLY IF the "webapp.source"
+        property has been set to an arbitrary value.
+-->
+
+<target name="source" depends="prepare" if="webapp.compile"
+        unless="webapp.suppress"
+        description="Copy Java sources">
+  <echo    message="Processing webapp ${webapp.name}"/>
+  <mkdir   dir="${webapp.target}/WEB-INF/src"/>
+  <copy  todir="${webapp.target}/WEB-INF/src">
+    <fileset dir="${webapp.src}"/>
+  </copy>
+</target>
+
+
+<!--
+        The "securityfilter" target copies the Security Filter library JAR file 
+        into the build target area.
+-->
+<target name="securityfilter" depends="prepare" if="webapp.securityfilter"
+        description="Copy Security Filter library files">
+  <echo    message="Processing webapp ${webapp.name}"/>
+  <mkdir   dir="${webapp.target}/WEB-INF/lib"/>
+  <copy  todir="${webapp.target}/WEB-INF/lib">
+    <fileset dir="${securityfilter.libs}" includes="commons-*.jar"/>
+    <fileset dir="${securityfilter.libs}" includes="jakarta-regexp.jar"/>
+    <fileset dir="${securityfilter.libs}" includes="securityfilter.jar"/>
+  </copy>
+</target>
+
+
+<!--
+        The "static" target copies the static web resources portion of your
+        web application source into the build target area.
+-->
+<target name="static" depends="prepare,source,libs,securityfilter"
+        description="Copy static files">
+  <echo    message="Processing webapp ${webapp.name}"/>
+  <copy  todir="${webapp.target}">
+    <fileset dir="${webapp.web}"/>
+  </copy>
+</target>
+
+
+<!--
+        The "compile" target compiles the Java source code of your web
+        application, if and only if the specified source directory
+        actually exists.
+-->
+<target name="compile" depends="static" if="webapp.compile"
+        description="Compile Java sources">
+  <echo    message="Processing webapp ${webapp.name}"/>
+  <javac  srcdir="${webapp.src}"
+         destdir="${webapp.target}/WEB-INF/classes"
+           debug="${compile.debug}"
+     deprecation="${compile.deprecation}"
+        optimize="${compile.optimize}">
+    <classpath refid="classpath"/>
+  </javac>
+  <copy    todir="${webapp.target}/WEB-INF/classes">
+    <fileset dir="${webapp.src}">
+      <exclude name="**/*.java"/>
+    </fileset>
+  </copy>
+</target>
+
+
+
+<!--
+        The "dist" target creates a web application archive containing
+        your completed web application, suitable for deployment on any
+        compatible servlet container.
+-->
+<target name="dist" depends="compile"
+        description="Create web application archive">
+  <echo    message="Processing webapp ${webapp.name}"/>
+  <jar  jarfile="${webapp.dist}/${webapp.war}"
+        basedir="${webapp.target}"/>
+</target>
+
+
+<!--
+        The "clean" task deletes any created directories that have resulted
+        from running any of the other targets in this script.
+-->
+
+<target name="clean"
+        description="Clean build and distribution directories">
+  <echo    message="Processing webapp ${webapp.name}"/>
+  <delete   dir="${webapp.target}" />
+  <delete  file="${webapp.dist}/${webapp.war}"/>
+</target>
+
+
+</project>
diff --git a/build-webapps.xml b/build-webapps.xml
new file mode 100644 (file)
index 0000000..107e06e
--- /dev/null
@@ -0,0 +1,181 @@
+<project name="Security Filter Web Applications" default="compile" basedir=".">
+
+
+<!--
+        This is a build file that creates all of the web applications included
+        in a Security Filter distribution, using the generic "build-webapp.xml" 
+        script for the details
+-->
+
+
+<!-- ========== Prerequisite Properties =================================== -->
+
+
+<!--
+        These properties MUST be set on the "ant" command line, the "antrc"
+        properties file in your home directory, or from settings in a superior
+        build.xml script.
+
+        build.home                    Base directory into which we are building
+                                      the Security Filter components.
+
+        compile.classpath             If specified, contains a set of JAR files
+                                      and/or directories to be added to the
+                                      compilation classpath.
+
+        servlet.jar                   The pathname of the servlet API classes
+                                      that you wish to compile against.
+
+        securityfilter.libs           The directory containing 
+                                      securityfilter.jar file.
+
+        webapp.libs                   If specified, must be the pathname of a
+                                      directory from which all available
+                                      "*.jar" files are copied to the web
+                                      application's WEB-INF/lib directory.
+-->
+
+<property name="build.home"           value="${basedir}/target"/>
+<property name="servlet.jar"          value="../jakarta-servletapi/lib/servlet.jar"/>
+<property name="securityfilter.libs"  value="${build.home}/library"/>
+
+
+
+<!-- ========== Initialization Properties ================================= -->
+
+
+<!--
+        These property values may optionally be overridden with property
+        settings from an "ant" command line, the "antrc" properties file
+        in your home directory, or from settings in a superior build.xml
+        script.
+-->
+
+
+<!-- Should Java compilations set the debug compiler option? -->
+<property name="compile.debug"         value="true" />
+
+<!-- Should Java compilations set the deprecation compiler option? -->
+<property name="compile.deprecation"   value="false" />
+
+<!-- Should Java compilations set the optimize compiler option? -->
+<property name="compile.optimize"      value="true" />
+
+<!-- The base directory for distribution targets -->
+<property name="dist.home"             value="${basedir}/dist" />
+
+<!-- The directory into which the Security Filter JAR files have been created -->
+<property name="securityfilter.home"   value="${build.home}/library" />
+
+<!-- Directory where core securityfilter library configurations files are stored -->
+<property name="conf.share.dir" value="${basedir}/conf/share"/>
+
+
+<!-- ========== Executable Targets ======================================== -->
+
+
+<!--
+        The "static.generic" target causes the "static" target of each
+        individual web application to be executed.
+-->
+<target name="static.generic">
+  <ant  antfile="build-webapp.xml"    target="static">
+    <property name="webapp.name"      value="blank"/>
+  </ant>
+  <ant  antfile="build-webapp.xml"    target="static">
+    <property name="webapp.name"      value="example"/>
+  </ant>
+  <ant  antfile="build-webapp.xml"    target="static">
+    <property name="webapp.name"      value="catalina-example"/>
+  </ant>
+</target>
+
+
+<!--
+        The "static" target causes non-generic static activity required
+        for specific tag libraries to be executed.
+-->
+<target name="static" depends="static.generic"
+        description="Copy static resources for individual web applications">
+    <!-- Copy shared web content for the Security Filter example application -->
+    <copy todir="${build.home}/example">
+        <fileset dir="${basedir}/web/share" includes="**/*.jsp"/>
+    </copy>
+    <copy tofile="${build.home}/example/WEB-INF/web.xml"
+            file="${basedir}/web/share/WEB-INF/web.xml"/>
+    <!-- Copy shared web content for the Security Filter catalina-example application -->
+    <copy todir="${build.home}/catalina-example">
+        <fileset dir="${basedir}/web/share" includes="**/*.jsp"/>
+    </copy>
+    <copy tofile="${build.home}/catalina-example/WEB-INF/web.xml"
+            file="${basedir}/web/share/WEB-INF/web.xml"/>
+    <!-- Copy catalina.jar the Security Filter catalina-example application -->
+    <copy tofile="${build.home}/catalina-example/WEB-INF/lib/catalina.jar"
+            file="${catalina.jar}"/>
+</target>
+
+
+<!--
+        The "compile" target causes the "compile" target of each
+        individual web application to be executed.
+-->
+<target name="compile">
+  <ant  antfile="build-webapp.xml"    target="compile">
+    <property name="webapp.name"      value="blank"/>
+  </ant>
+  <ant  antfile="build-webapp.xml"    target="compile">
+    <property name="webapp.name"      value="example"/>
+  </ant>
+  <ant  antfile="build-webapp.xml"    target="compile">
+    <property name="webapp.name"      value="catalina-example"/>
+  </ant>
+</target>
+
+
+<!--
+        The "dist" target causes the "dist" target of each
+        individual web application to be executed.
+-->
+<target name="dist">
+  <ant  antfile="build-webapp.xml"    target="dist">
+    <property name="webapp.name"      value="blank"/>
+    <property name="webapp.war"       value="securityfilter-blank.war"/>
+  </ant>
+  <ant  antfile="build-webapp.xml"    target="dist">
+    <property name="webapp.name"      value="example"/>
+    <property name="webapp.war"       value="securityfilter-example.war"/>
+  </ant>
+  <ant  antfile="build-webapp.xml"    target="dist">
+    <property name="webapp.name"      value="catalina-example"/>
+    <property name="webapp.war"       value="securityfilter-catalina-example.war"/>
+  </ant>
+</target>
+
+
+<!--
+        The "clean.generic" target causes the "clean" target of each
+        individual web application to be executed.
+-->
+<target name="clean.generic">
+  <ant  antfile="build-webapp.xml"    target="clean">
+    <property name="webapp.name"      value="blank"/>
+  </ant>
+  <ant  antfile="build-webapp.xml"    target="clean">
+    <property name="webapp.name"      value="example"/>
+  </ant>
+  <ant  antfile="build-webapp.xml"    target="clean">
+    <property name="webapp.name"      value="catalina-example"/>
+  </ant>
+</target>
+
+
+<!--
+        The "clean" target causes non-generic clean activity required
+        for specific tag libraries to be executed.
+-->
+<target name="clean" depends="clean.generic"
+        description="Clean output for individual web applications">
+</target>
+
+
+</project>
diff --git a/build.properties.sample b/build.properties.sample
new file mode 100644 (file)
index 0000000..068fe98
--- /dev/null
@@ -0,0 +1,39 @@
+# -----------------------------------------------------------------------------
+# build.properties.sample
+#
+# This is an example "build.properties" file, used to customize building 
+# Security Filter for your local environment.  Make any changes you need, and 
+# rename this file to "build.properties" in the same directory that contains 
+# the Security Filter "build.xml" file.
+#
+# $Id: build.properties.sample,v 1.1 2002/08/08 13:20:46 maxcooper Exp $
+# -----------------------------------------------------------------------------
+
+# The catalina JAR file from version 4.0 (or later) of the Jakarta Tomcat 
+# package.
+catalina.jar=/usr/local/jakarta-tomcat-4.0/server/lib/catalina.jar
+
+# The JAR file containing version 1.0 (or later) of the Beanutils package
+# from the Jakarta Commons project.
+commons-beanutils.jar=/usr/local/commons-beanutils-1.0/commons-beanutils.jar
+
+# The JAR file containing version 1.0 (or later) of the Collections package
+# from the Jakarta Commons project.
+commons-collections.jar=/usr/local/commons-collections-1.0/commons-collections.jar
+
+# The JAR file containing version 1.0 (or later) of the Digester package
+# from the Jakarta Commons project.
+commons-digester.jar=/usr/local/commons-digester-1.0/commons-digester.jar
+
+# The JAR file containing version 1.0 (or later) of the Logging package
+# from the Jakarta Commons project.
+commons-logging.jar=/usr/local/commons-logging-1.0/commons-logging.jar
+
+# The JAR file containing version 1.2 (or later) of 
+# the the Jakarta Regexp project.
+jakarta-regexp.jar=/usr/local/jakarta-regexp-1.2/jakarta-regexp-1.2.jar
+
+# The JAR file containing the Servlet API version 2.3 (or later) classes to 
+# compile against
+servlet.jar=/usr/local/jakarta-servletapi-4/lib/servlet.jar
+
diff --git a/build.xml b/build.xml
new file mode 100644 (file)
index 0000000..a62319f
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,349 @@
+<project name="Security Filter" default="compile.library" basedir=".">
+
+<!--
+        Security Filter main build.xml file for building everything related to Security Filter :
+        - core Security Filter library
+        - documentation
+        - Security Filter web apps
+        - ...
+
+        This script will delegate some of it's tasks to the other build*.xml
+        scripts (build-webapps.xml, ...)
+-->
+
+
+<!-- ========== Prerequisite Properties =================================== -->
+
+<!--
+        These properties MUST be set on the "ant" command line, a
+        "build.properties" file in the base directory, or a
+        "build.properties" file in your user home directory.
+      
+        catalina.jar                  (required).  The path to the JAR file
+                                      of the Tomcat 
+                                      package (version 4.0 or later).
+
+        commons-beanutils.jar         (required).  The path to the JAR file
+                                      of the Jakarta Commons Beanutils
+                                      package (version 1.0 or later).
+
+        commons-collections.jar       (required).  The path to the JAR file
+                                      of the Jakarta Commons Collections
+                                      package (version 1.0 or later).
+
+        commons-digester.jar          (required).  The path to the JAR file
+                                      of the Jakarta Commons Digester
+                                      package (version 1.0 or later).
+
+        commons-logging.jar           (required).  The path to the JAR file
+                                      of the Jakarta Commons Logging
+                                      package (version 1.0 or later).
+
+        jakarta-regexp.jar                   (required).  The path to the JAR file
+                                      of the Jakarta Regexp
+                                      package (version 1.2 or later).
+
+        servlet.jar                   (required).  The path to the Servlet API
+                                      classes to compile against 
+                                      (version 2.3 or later).
+
+-->
+
+    <!-- Load local and user build preferences -->
+    <property file="${user.home}/build.properties"/>
+    <property file="build.properties"/>
+
+
+<!-- ========== Initialization Properties ================================= -->
+
+
+<!--
+        These property values may optionally be overridden with property
+        settings from an "ant" command line, the "build.properties" file
+        in this directory, the "build.properties" file in your home
+        directory, or from settings in a superior build.xml script.
+-->
+
+    <!-- Output directory name for all files generated by the build process -->
+    <property name="build.home" value="${basedir}/target"/>
+
+    <!-- Should Java compilations set the debug compiler option? -->
+    <property name="compile.debug" value="true" />
+
+    <!-- Should Java compilations set the deprecation compiler option? -->
+    <property name="compile.deprecation" value="false" />
+
+    <!-- Should Java compilations set the optimize compiler option? -->
+    <property name="compile.optimize" value="true" />
+
+    <!-- Name of the core struts library -->
+    <property name="app.name" value="securityfilter"/>
+
+    <!-- Name of the project -->
+    <property name="project.name" value="securityfilter"/>
+
+    <!-- Version of the project -->
+    <property name="project.version" value="1.0-b4-dev"/>
+
+
+<!-- ========== Derived Properties ======================================== -->
+
+
+<!--
+        These property values are derived from values defined above, and
+        generally should NOT be overridden by command line settings
+-->
+
+    <!-- The base directory for distribution targets -->
+    <property name="dist.home" value="dist" />
+
+    <!-- The base directory for release targets -->
+    <property name="release.home" value="release" />
+
+    <!-- Source directory -->
+    <property name="src.dir" value="src"/>
+
+    <!-- Source directory for core securityfilter library -->
+    <property name="src.share.dir" value="${src.dir}/share"/>
+
+    <!-- Directory where core struts library configurations files are stored -->
+    <property name="conf.share.dir" value="conf/share"/>
+
+    <!-- Directory where binary release files are staged -->
+    <property name="stage.bin.dir" value="${release.home}/stage/bin"/>
+
+    <!-- Directory where library release files are staged -->
+    <property name="stage.lib.dir" value="${release.home}/stage/lib"/>
+
+    <!-- Directory where source release files are staged -->
+    <property name="stage.src.dir" value="${release.home}/stage/src"/>
+
+    <!-- Directory where release builds are prepared for upload -->
+    <property name="upload.dir" value="${release.home}/upload"/>
+
+    <!-- Base file name for upload files -->
+    <property name="upload.file.base" value="${project.name}-${project.version}"/>
+    
+    <!-- Web directory -->
+    <property name="web.dir" value="web"/>
+
+    <!-- Compilation Classpath -->
+    <path id="compile.classpath">
+      <pathelement location="${catalina.jar}"/>
+      <pathelement location="${commons-beanutils.jar}"/>
+      <pathelement location="${commons-collections.jar}"/>
+      <pathelement location="${commons-digester.jar}"/>
+      <pathelement location="${commons-logging.jar}"/>
+      <pathelement location="${jakarta-regexp.jar}"/>
+      <pathelement location="${servlet.jar}"/>
+    </path>
+
+
+<!-- ========== Executable Targets ======================================== -->
+
+
+<!--
+        The "init" target evaluates "available" expressions as necessary
+        to modify the behavior of this script and print some information on
+        screen
+-->
+    <target name="init">
+
+        <echo message="--------- ${project.name} ${project.version} ---------"/>
+        <echo message=""/>
+
+        <echo message="java.class.path = ${java.class.path}"/>
+        <echo message="java.home = ${java.home}"/>
+        <echo message="user.home = ${user.home}"/>
+
+    </target>
+
+<!-- 
+        Create directories and copy files for the core securityfilter library
+-->
+    <target name="prepare.library" depends="init">
+        <mkdir dir="${build.home}/library/classes/META-INF"/>
+        <copy file="LICENSE"
+            tofile="${build.home}/library/classes/META-INF/LICENSE"/>
+        <copy todir="${build.home}/library/classes/org/securityfilter/resources">
+            <fileset dir="${conf.share.dir}" includes="**/*.dtd"/>
+        </copy>
+        <copy file="${catalina.jar}"
+            tofile="${build.home}/library/catalina.jar"/>
+        <copy file="${commons-beanutils.jar}"
+            tofile="${build.home}/library/commons-beanutils.jar"/>
+        <copy file="${commons-collections.jar}"
+            tofile="${build.home}/library/commons-collections.jar"/>
+        <copy file="${commons-digester.jar}"
+            tofile="${build.home}/library/commons-digester.jar"/>
+        <copy file="${commons-logging.jar}"
+            tofile="${build.home}/library/commons-logging.jar"/>
+        <copy file="${jakarta-regexp.jar}"
+            tofile="${build.home}/library/jakarta-regexp.jar"/>
+    </target>
+
+<!-- 
+        Prepare static directories for web applications
+-->
+    <target name="static.webapps">
+        <ant antfile="build-webapps.xml" target="static"/>
+    </target>
+
+<!-- 
+        Compile core securityfilter library directory components
+-->
+    <target name="compile.library" depends="prepare.library"
+     description="Compile Security Filter library files">
+        <javac srcdir="${src.share.dir}"
+            destdir="${build.home}/library/classes"
+            debug="${compile.debug}"
+            optimize="${compile.optimize}"
+            deprecation="${compile.deprecation}">
+          <classpath refid="compile.classpath"/>
+        </javac>
+        <copy todir="${build.home}/library">
+            <fileset dir="${conf.share.dir}" includes="*.dtd"/>
+        </copy>
+        <jar jarfile="${build.home}/library/${app.name}.jar"
+            manifest="${conf.share.dir}/MANIFEST.MF"
+            basedir="${build.home}/library/classes"
+            includes="**"/>
+    </target>
+
+<!--
+        Compile code for web applications
+-->
+    <target name="compile.webapps" depends="compile.library,static.webapps"
+     description="Compile Struts web applications">
+        <ant antfile="build-webapps.xml" target="compile"/>
+    </target>
+
+<!--
+        Create Javadoc documentation
+-->
+    <target name="compile.javadoc"
+     description="Generate JavaDoc API docs">
+        <delete dir="${build.home}/documentation/api"/>
+        <mkdir dir="${build.home}/documentation/api"/>
+        <javadoc sourcepath="${src.share.dir}"
+            destdir="${build.home}/documentation/api"
+            classpath="${servlet.jar}"
+            packagenames="org.securityfilter.*"
+            author="true"
+            private="true"
+            version="true"
+            windowtitle="Security Filter API Documentation"
+            doctitle="&lt;h1&gt;Security Filter (Version ${project.version})&lt;/h1&gt;"
+            bottom="Copyright &#169; 2000-2002 - Apache Software Foundation">
+            <classpath refid="compile.classpath"/>
+        </javadoc>
+    </target>
+
+<!--
+        Create directories and copy files for distribution
+-->
+    <target name="prepare.dist" depends="init">
+        <mkdir dir="${dist.home}"/>
+        <mkdir dir="${dist.home}/lib"/>
+        <mkdir dir="${dist.home}/webapps"/>
+    </target>
+
+<!--
+        Construct library distributables
+-->
+    <target name="dist.library" depends="prepare.dist,compile.library">
+        <copy todir="${dist.home}/lib">
+            <fileset dir="${build.home}/library" includes="*.dtd"/>
+            <fileset dir="${build.home}/library" includes="*.jar"/>
+            <fileset dir="${build.home}/library" includes="*.xml"/>
+        </copy>
+    </target>
+
+<!--
+        Construct distributable web applications
+-->
+    <target name="dist.webapps" depends="compile.webapps,compile.javadoc">
+        <ant antfile="build-webapps.xml" target="dist"/>
+    </target>
+
+<!--
+        Copy sources for distribution
+-->
+    <target name="dist.source" depends="prepare.dist">
+        <!-- <copy file="INSTALL" tofile="${dist.home}/INSTALL"/> -->
+        <copy file="LICENSE" tofile="${dist.home}/LICENSE"/>
+        <copy file="README" tofile="${dist.home}/README"/>
+    </target>
+
+<!--
+        Construct complete binary distribution
+-->
+    <target name="dist" depends="dist.library,dist.webapps,dist.source"
+     description="Construct binary distribution"/>
+
+<!--
+        Construct complete release distributions
+-->
+    <target name="release" depends="clean,dist"
+    description="Construct release distribution">
+        <mkdir dir="${stage.bin.dir}/${upload.file.base}"/>
+        <mkdir dir="${stage.lib.dir}/${upload.file.base}-lib"/>
+        <mkdir dir="${stage.src.dir}/${upload.file.base}-src"/>
+        <copy todir="${stage.bin.dir}/${upload.file.base}">
+            <fileset dir="${dist.home}"/>
+        </copy>
+        <copy todir="${stage.lib.dir}/${upload.file.base}-lib">
+            <fileset dir="${dist.home}" includes="LICENSE"/>
+            <fileset dir="${dist.home}/lib"/>
+        </copy>
+        <copy todir="${stage.src.dir}/${upload.file.base}-src">
+            <fileset dir=".">
+                <exclude name="build.properties"/>
+                <exclude name="*.ipr"/>
+                <exclude name="target/**"/>
+                <exclude name="dist/**"/>
+                <exclude name="release/**"/>
+            </fileset>
+        </copy>
+        <mkdir dir="${upload.dir}"/>
+        <zip  zipfile="${upload.dir}/${upload.file.base}.zip"
+              basedir="${stage.bin.dir}"/>
+        <zip  zipfile="${upload.dir}/${upload.file.base}-lib.zip"
+              basedir="${stage.lib.dir}"/>
+        <zip  zipfile="${upload.dir}/${upload.file.base}-src.zip"
+              basedir="${stage.src.dir}"/>
+        <tar  tarfile="${upload.dir}/${upload.file.base}.tar"
+              basedir="${stage.bin.dir}"
+             longfile="gnu"/>
+        <tar  tarfile="${upload.dir}/${upload.file.base}-lib.tar"
+              basedir="${stage.lib.dir}"
+             longfile="gnu"/>
+        <tar  tarfile="${upload.dir}/${upload.file.base}-src.tar"
+              basedir="${stage.src.dir}"
+             longfile="gnu"/>
+        <gzip     src="${upload.dir}/${upload.file.base}.tar"
+              zipfile="${upload.dir}/${upload.file.base}.tar.gz"/>
+        <gzip     src="${upload.dir}/${upload.file.base}-lib.tar"
+              zipfile="${upload.dir}/${upload.file.base}-lib.tar.gz"/>
+        <gzip     src="${upload.dir}/${upload.file.base}-src.tar"
+              zipfile="${upload.dir}/${upload.file.base}-src.tar.gz"/>
+    </target>
+
+
+<!--
+        Clean up build and distribution directories
+-->
+    <target name="clean"
+     description="Clean build and distribution directories">
+        <delete dir="${build.home}"/>
+        <delete dir="${dist.home}"/>
+        <delete dir="${release.home}"/>
+    </target>
+
+<!--
+        All-in-one build target
+-->
+    <target name="all" depends="clean,compile.library,compile.webapps"
+     description="Clean and build library and web applications"/>
+
+</project>
diff --git a/conf/share/MANIFEST.MF b/conf/share/MANIFEST.MF
new file mode 100644 (file)
index 0000000..742a7f2
--- /dev/null
@@ -0,0 +1,11 @@
+Manifest-Version: 1.0
+Extension-Name: Security Filter
+Specification-Title: Security Filter
+Specification-Vendor: SecurityFilter.org
+Specification-Version: 1.0
+Implementation-Title: Security Filter
+Implementation-Vendor: SecurityFilter.org
+Implementation-Vendor-Id: org.securityfilter
+Implementation-Version: 1.0
+Class-Path: catalina.jar commons-beanutils.jar commons-collections.jar commons-digester.jar commons-logging.jar jakarta-regexp.jar
+
diff --git a/conf/share/securityfilter-config_1_0.dtd b/conf/share/securityfilter-config_1_0.dtd
new file mode 100644 (file)
index 0000000..4253d15
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!ELEMENT description (#PCDATA)>
+<!ELEMENT role-name (#PCDATA)>
+<!--Root element for securityfilter config-->
+<!ELEMENT securityfilter-config (security-constraint*, login-config, security-role*, realm+)>
+<!ELEMENT security-constraint (display-name?, web-resource-collection+, auth-constraint?, user-data-constraint?)>
+<!ELEMENT login-config (auth-method?, form-login-config)>
+<!ELEMENT security-role (description, role-name)>
+<!ELEMENT realm (realm-param*)>
+<!ATTLIST realm
+       className CDATA #REQUIRED
+>
+<!ELEMENT display-name (#PCDATA)>
+<!ELEMENT web-resource-collection (web-resource-name, description?, url-pattern*, http-method*)>
+<!ELEMENT auth-constraint (description?, role-name*)>
+<!ELEMENT user-data-constraint (description, transport-guarantee)>
+<!ELEMENT auth-method (#PCDATA)>
+<!ELEMENT form-login-config (form-login-page, form-error-page, form-default-page?)>
+<!ELEMENT realm-param EMPTY>
+<!ATTLIST realm-param
+       name CDATA #REQUIRED
+       value CDATA #REQUIRED
+>
+<!ELEMENT web-resource-name (#PCDATA)>
+<!ELEMENT url-pattern (#PCDATA)>
+<!ELEMENT http-method (#PCDATA)>
+<!ELEMENT transport-guarantee (#PCDATA)>
+<!ELEMENT form-login-page (#PCDATA)>
+<!ELEMENT form-error-page (#PCDATA)>
+<!ELEMENT form-default-page (#PCDATA)>
diff --git a/conf/share/securityfilter-config_1_0.xsd b/conf/share/securityfilter-config_1_0.xsd
new file mode 100644 (file)
index 0000000..eab6b39
--- /dev/null
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- edited with XML Spy v4.4 U (http://www.xmlspy.com) by Max Cooper ((none)) -->
+<xs:schema targetNamespace="http://www.securityfilter.org/namespace" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns="http://www.securityfilter.org/namespace" elementFormDefault="qualified" attributeFormDefault="unqualified">
+       <xs:element name="securityfilter-config">
+               <xs:annotation>
+                       <xs:documentation>Root element for securityfilter config</xs:documentation>
+               </xs:annotation>
+               <xs:complexType>
+                       <xs:sequence>
+                               <xs:element name="security-constraint" minOccurs="0" maxOccurs="unbounded">
+                                       <xs:complexType>
+                                               <xs:sequence>
+                                                       <xs:element name="display-name" type="xs:string" minOccurs="0"/>
+                                                       <xs:element name="web-resource-collection" maxOccurs="unbounded">
+                                                               <xs:complexType>
+                                                                       <xs:sequence>
+                                                                               <xs:element name="web-resource-name" type="xs:string"/>
+                                                                               <xs:element ref="description" minOccurs="0"/>
+                                                                               <xs:element name="url-pattern" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+                                                                               <xs:element name="http-method" type="xs:string" minOccurs="0" maxOccurs="unbounded"/>
+                                                                       </xs:sequence>
+                                                               </xs:complexType>
+                                                       </xs:element>
+                                                       <xs:element name="auth-constraint" minOccurs="0">
+                                                               <xs:complexType>
+                                                                       <xs:sequence>
+                                                                               <xs:element ref="description" minOccurs="0"/>
+                                                                               <xs:element ref="role-name" minOccurs="0" maxOccurs="unbounded"/>
+                                                                       </xs:sequence>
+                                                               </xs:complexType>
+                                                       </xs:element>
+                                                       <xs:element name="user-data-constraint" minOccurs="0">
+                                                               <xs:complexType>
+                                                                       <xs:sequence>
+                                                                               <xs:element ref="description"/>
+                                                                               <xs:element name="transport-guarantee">
+                                                                                       <xs:simpleType>
+                                                                                               <xs:restriction base="xs:string">
+                                                                                                       <xs:enumeration value="NONE"/>
+                                                                                                       <xs:enumeration value="INTEGRAL"/>
+                                                                                                       <xs:enumeration value="CONFIDENTIAL"/>
+                                                                                               </xs:restriction>
+                                                                                       </xs:simpleType>
+                                                                               </xs:element>
+                                                                       </xs:sequence>
+                                                               </xs:complexType>
+                                                       </xs:element>
+                                               </xs:sequence>
+                                       </xs:complexType>
+                               </xs:element>
+                               <xs:element name="login-config">
+                                       <xs:complexType>
+                                               <xs:sequence>
+                                                       <xs:element name="auth-method" minOccurs="0">
+                                                               <xs:simpleType>
+                                                                       <xs:restriction base="xs:string">
+                                                                               <xs:pattern value="FORM"/>
+                                                                       </xs:restriction>
+                                                               </xs:simpleType>
+                                                       </xs:element>
+                                                       <xs:element name="form-login-config">
+                                                               <xs:complexType>
+                                                                       <xs:sequence>
+                                                                               <xs:element name="form-login-page" type="xs:string"/>
+                                                                               <xs:element name="form-error-page" type="xs:string"/>
+                                                                               <xs:element name="form-default-page" type="xs:string" minOccurs="0"/>
+                                                                       </xs:sequence>
+                                                               </xs:complexType>
+                                                       </xs:element>
+                                               </xs:sequence>
+                                       </xs:complexType>
+                               </xs:element>
+                               <xs:element name="security-role" minOccurs="0" maxOccurs="unbounded">
+                                       <xs:complexType>
+                                               <xs:sequence>
+                                                       <xs:element ref="description"/>
+                                                       <xs:element ref="role-name"/>
+                                               </xs:sequence>
+                                       </xs:complexType>
+                               </xs:element>
+                               <xs:element name="realm" maxOccurs="unbounded">
+                                       <xs:complexType>
+                                               <xs:sequence>
+                                                       <xs:element name="realm-param" minOccurs="0" maxOccurs="unbounded">
+                                                               <xs:complexType>
+                                                                       <xs:attribute name="name" type="xs:string" use="required"/>
+                                                                       <xs:attribute name="value" type="xs:string" use="required"/>
+                                                               </xs:complexType>
+                                                       </xs:element>
+                                               </xs:sequence>
+                                               <xs:attribute name="className" type="xs:string" use="required"/>
+                                       </xs:complexType>
+                               </xs:element>
+                       </xs:sequence>
+               </xs:complexType>
+       </xs:element>
+       <xs:element name="description" type="xs:string"/>
+       <xs:element name="role-name" type="xs:string"/>
+</xs:schema>
diff --git a/conf/share/web-app_2_3.dtd b/conf/share/web-app_2_3.dtd
new file mode 100644 (file)
index 0000000..b110d76
--- /dev/null
@@ -0,0 +1,1059 @@
+<!--
+Copyright 2000-2001 Sun Microsystems, Inc. 901 San Antonio Road,
+Palo Alto, CA  94303, U.S.A.  All rights reserved.
+
+This product or document is protected by copyright and distributed
+under licenses restricting its use, copying, distribution, and
+decompilation.  No part of this product or documentation may be
+reproduced in any form by any means without prior written authorization
+of Sun and its licensors, if any.
+
+Third party software, including font technology, is copyrighted and
+licensed from Sun suppliers.
+
+Sun, Sun Microsystems, the Sun Logo, Solaris, Java, JavaServer Pages, Java
+Naming and Directory Interface, JDBC, JDK, JavaMail and Enterprise JavaBeans,
+are trademarks or registered trademarks of Sun Microsystems, Inc in the U.S.
+and other countries.
+
+All SPARC trademarks are used under license and are trademarks
+or registered trademarks of SPARC International, Inc.
+in the U.S. and other countries. Products bearing SPARC
+trademarks are based upon an architecture developed by Sun Microsystems, Inc.
+
+PostScript is a registered trademark of Adobe Systems, Inc.
+
+Federal Acquisitions: Commercial Software - Government Users Subject to
+Standard License Terms and Conditions.
+
+DOCUMENTATION IS PROVIDED "AS IS" AND ALL EXPRESS OR IMPLIED
+CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
+IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
+PURPOSE OR NON-INFRINGEMENT, ARE DISCLAIMED, EXCEPT
+TO THE EXTENT THAT SUCH DISCLAIMERS ARE HELD TO BE LEGALLY
+INVALID.
+
+_________________________________________________________________________
+
+Copyright 2000-2001 Sun Microsystems, Inc.,
+901 San Antonio Road, Palo Alto, CA  94303, Etats-Unis.
+Tous droits re'serve's.
+
+
+Ce produit ou document est prote'ge' par un copyright et distribue' avec
+des licences qui en restreignent l'utilisation, la copie, la distribution,
+et la de'compilation.  Aucune partie de ce produit ou de sa documentation
+associe'e ne peut e^tre reproduite sous aucune forme, par quelque moyen
+que ce soit, sans l'autorisation pre'alable et e'crite de Sun et de ses
+bailleurs de licence, s'il y en a.
+
+Le logiciel de'tenu par des tiers, et qui comprend la technologie
+relative aux polices de caracte`res, est prote'ge' par un copyright
+et licencie' par des fournisseurs de Sun.
+
+Sun, Sun Microsystems, le logo Sun, Solaris, Java, JavaServer Pages, Java
+Naming and Directory Interface, JDBC, JDK, JavaMail, et Enterprise JavaBeans,
+sont des marques de fabrique ou des marques de'pose'es de Sun
+Microsystems, Inc. aux Etats-Unis et dans d'autres pays.
+
+Toutes les marques SPARC sont utilise'es sous licence et sont
+des marques de fabrique ou des marques de'pose'es de SPARC
+International, Inc. aux Etats-Unis et  dans
+d'autres pays. Les produits portant les marques SPARC sont
+base's sur une architecture de'veloppe'e par Sun Microsystems, Inc.
+
+Postcript est une marque enregistre'e d'Adobe Systems Inc.
+
+LA DOCUMENTATION EST FOURNIE "EN L'ETAT" ET TOUTES AUTRES CONDITIONS,
+DECLARATIONS ET GARANTIES EXPRESSES OU TACITES SONT FORMELLEMENT EXCLUES,
+DANS LA MESURE AUTORISEE PAR LA LOI APPLICABLE, Y COMPRIS NOTAMMENT
+TOUTE GARANTIE IMPLICITE RELATIVE A LA QUALITE MARCHANDE, A L'APTITUDE
+A UNE UTILISATION PARTICULIERE OU A L'ABSENCE DE CONTREFACON.
+-->
+
+<!--
+This is the XML DTD for the Servlet 2.3 deployment descriptor.
+All Servlet 2.3 deployment descriptors must include a DOCTYPE
+of the following form:
+
+  <!DOCTYPE web-app PUBLIC
+       "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+       "http://java.sun.com/dtd/web-app_2_3.dtd">
+
+-->
+
+<!--
+The following conventions apply to all J2EE deployment descriptor
+elements unless indicated otherwise.
+
+- In elements that contain PCDATA, leading and trailing whitespace
+  in the data may be ignored.
+
+- In elements whose value is an "enumerated type", the value is
+  case sensitive.
+
+- In elements that specify a pathname to a file within the same
+  JAR file, relative filenames (i.e., those not starting with "/")
+  are considered relative to the root of the JAR file's namespace.
+  Absolute filenames (i.e., those starting with "/") also specify
+  names in the root of the JAR file's namespace.  In general, relative
+  names are preferred.  The exception is .war files where absolute
+  names are preferred for consistency with the servlet API.
+-->
+
+
+<!--
+The web-app element is the root of the deployment descriptor for
+a web application.
+-->
+<!ELEMENT web-app (icon?, display-name?, description?, distributable?,
+context-param*, filter*, filter-mapping*, listener*, servlet*,
+servlet-mapping*, session-config?, mime-mapping*, welcome-file-list?,
+error-page*, taglib*, resource-env-ref*, resource-ref*, security-constraint*,
+login-config?, security-role*, env-entry*, ejb-ref*,  ejb-local-ref*)>
+
+<!--
+The auth-constraint element indicates the user roles that should
+be permitted access to this resource collection. The role-name
+used here must either correspond to the role-name of one of the
+security-role elements defined for this web application, or be
+the specially reserved role-name "*" that is a compact syntax for
+indicating all roles in the web application. If both "*" and
+rolenames appear, the container interprets this as all roles.
+If no roles are defined, no user is allowed access to the portion of
+the web application described by the containing security-constraint.
+The container matches role names case sensitively when determining
+access.
+
+
+Used in: security-constraint
+-->
+<!ELEMENT auth-constraint (description?, role-name*)>
+
+<!--
+The auth-method element is used to configure the authentication
+mechanism for the web application. As a prerequisite to gaining access to any web resources which are protected by an authorization
+constraint, a user must have authenticated using the configured
+mechanism. Legal values for this element are "BASIC", "DIGEST",
+"FORM", or "CLIENT-CERT".
+
+Used in: login-config
+-->
+<!ELEMENT auth-method (#PCDATA)>
+
+<!--
+The context-param element contains the declaration of a web
+application's servlet context initialization parameters.
+
+Used in: web-app
+-->
+<!ELEMENT context-param (param-name, param-value, description?)>
+
+<!--
+The description element is used to provide text describing the parent
+element.  The description element should include any information that
+the web application war file producer wants to provide to the consumer of
+the web application war file (i.e., to the Deployer). Typically, the tools
+used by the web application war file consumer will display the description
+when processing the parent element that contains the description.
+
+Used in: auth-constraint, context-param, ejb-local-ref, ejb-ref,
+env-entry, filter, init-param, resource-env-ref, resource-ref, run-as,
+security-role, security-role-ref, servlet, user-data-constraint,
+web-app, web-resource-collection
+-->
+<!ELEMENT description (#PCDATA)>
+
+<!--
+The display-name element contains a short name that is intended to be
+displayed by tools.  The display name need not be unique.
+
+Used in: filter, security-constraint, servlet, web-app
+
+Example:
+
+<display-name>Employee Self Service</display-name>
+-->
+<!ELEMENT display-name (#PCDATA)>
+
+<!--
+The distributable element, by its presence in a web application
+deployment descriptor, indicates that this web application is
+programmed appropriately to be deployed into a distributed servlet
+container
+
+Used in: web-app
+-->
+<!ELEMENT distributable EMPTY>
+
+<!--
+The ejb-link element is used in the ejb-ref or ejb-local-ref
+elements to specify that an EJB reference is linked to an
+enterprise bean.
+
+The name in the ejb-link element is composed of a
+path name specifying the ejb-jar containing the referenced enterprise
+bean with the ejb-name of the target bean appended and separated from
+the path name by "#".  The path name is relative to the war file
+containing the web application that is referencing the enterprise bean.
+This allows multiple enterprise beans with the same ejb-name to be
+uniquely identified.
+
+Used in: ejb-local-ref, ejb-ref
+
+Examples:
+
+       <ejb-link>EmployeeRecord</ejb-link>
+
+       <ejb-link>../products/product.jar#ProductEJB</ejb-link>
+
+-->
+<!ELEMENT ejb-link (#PCDATA)>
+
+<!--
+The ejb-local-ref element is used for the declaration of a reference to
+an enterprise bean's local home. The declaration consists of:
+
+       - an optional description
+       - the EJB reference name used in the code of the web application
+         that's referencing the enterprise bean
+       - the expected type of the referenced enterprise bean
+       - the expected local home and local interfaces of the referenced
+         enterprise bean
+       - optional ejb-link information, used to specify the referenced
+         enterprise bean
+
+Used in: web-app
+-->
+<!ELEMENT ejb-local-ref (description?, ejb-ref-name, ejb-ref-type,
+               local-home, local, ejb-link?)>
+
+<!--
+The ejb-ref element is used for the declaration of a reference to
+an enterprise bean's home. The declaration consists of:
+
+       - an optional description
+       - the EJB reference name used in the code of
+         the web application that's referencing the enterprise bean
+       - the expected type of the referenced enterprise bean
+       - the expected home and remote interfaces of the referenced
+         enterprise bean
+       - optional ejb-link information, used to specify the referenced
+         enterprise bean
+
+Used in: web-app
+-->
+<!ELEMENT ejb-ref (description?, ejb-ref-name, ejb-ref-type,
+               home, remote, ejb-link?)>
+
+<!--
+The ejb-ref-name element contains the name of an EJB reference. The
+EJB reference is an entry in the web application's environment and is
+relative to the java:comp/env context.  The name must be unique
+within the web application.
+
+It is recommended that name is prefixed with "ejb/".
+
+Used in: ejb-local-ref, ejb-ref
+
+Example:
+
+<ejb-ref-name>ejb/Payroll</ejb-ref-name>
+-->
+<!ELEMENT ejb-ref-name (#PCDATA)>
+
+<!--
+The ejb-ref-type element contains the expected type of the
+referenced enterprise bean.
+
+The ejb-ref-type element must be one of the following:
+
+       <ejb-ref-type>Entity</ejb-ref-type>
+       <ejb-ref-type>Session</ejb-ref-type>
+
+Used in: ejb-local-ref, ejb-ref
+-->
+<!ELEMENT ejb-ref-type (#PCDATA)>
+
+<!--
+The env-entry element contains the declaration of a web application's
+environment entry. The declaration consists of an optional
+description, the name of the environment entry, and an optional
+value.  If a value is not specified, one must be supplied
+during deployment.
+-->
+<!ELEMENT env-entry (description?, env-entry-name, env-entry-value?,
+env-entry-type)>
+
+<!--
+The env-entry-name element contains the name of a web applications's
+environment entry.  The name is a JNDI name relative to the
+java:comp/env context.  The name must be unique within a web application.
+
+Example:
+
+<env-entry-name>minAmount</env-entry-name>
+
+Used in: env-entry
+-->
+<!ELEMENT env-entry-name (#PCDATA)>
+
+<!--
+The env-entry-type element contains the fully-qualified Java type of
+the environment entry value that is expected by the web application's
+code.
+
+The following are the legal values of env-entry-type:
+
+       java.lang.Boolean
+       java.lang.Byte
+       java.lang.Character
+       java.lang.String
+       java.lang.Short
+       java.lang.Integer
+       java.lang.Long
+       java.lang.Float
+       java.lang.Double
+
+Used in: env-entry
+-->
+<!ELEMENT env-entry-type (#PCDATA)>
+
+<!--
+The env-entry-value element contains the value of a web application's
+environment entry. The value must be a String that is valid for the
+constructor of the specified type that takes a single String
+parameter, or for java.lang.Character, a single character.
+
+Example:
+
+<env-entry-value>100.00</env-entry-value>
+
+Used in: env-entry
+-->
+<!ELEMENT env-entry-value (#PCDATA)>
+
+<!--
+The error-code contains an HTTP error code, ex: 404
+
+Used in: error-page
+-->
+<!ELEMENT error-code (#PCDATA)>
+
+<!--
+The error-page element contains a mapping between an error code
+or exception type to the path of a resource in the web application
+
+Used in: web-app
+-->
+<!ELEMENT error-page ((error-code | exception-type), location)>
+
+<!--
+The exception type contains a fully qualified class name of a
+Java exception type.
+
+Used in: error-page
+-->
+<!ELEMENT exception-type (#PCDATA)>
+
+<!--
+The extension element contains a string describing an
+extension. example: "txt"
+
+Used in: mime-mapping
+-->
+<!ELEMENT extension (#PCDATA)>
+
+<!--
+Declares a filter in the web application. The filter is mapped to
+either a servlet or a URL pattern in the filter-mapping element, using
+the filter-name value to reference. Filters can access the
+initialization parameters declared in the deployment descriptor at
+runtime via the FilterConfig interface.
+
+Used in: web-app
+-->
+<!ELEMENT filter (icon?, filter-name, display-name?, description?,
+filter-class, init-param*)>
+
+<!--
+The fully qualified classname of the filter.
+
+Used in: filter
+-->
+<!ELEMENT filter-class (#PCDATA)>
+
+<!--
+Declaration of the filter mappings in this web application. The
+container uses the filter-mapping declarations to decide which filters
+to apply to a request, and in what order. The container matches the
+request URI to a Servlet in the normal way. To determine which filters
+to apply it matches filter-mapping declarations either on servlet-name,
+or on url-pattern for each filter-mapping element, depending on which
+style is used. The order in which filters are invoked is the order in
+which filter-mapping declarations that match a request URI for a
+servlet appear in the list of filter-mapping elements.The filter-name
+value must be the value of the <filter-name> sub-elements of one of the
+<filter> declarations in the deployment descriptor.
+
+Used in: web-app
+-->
+<!ELEMENT filter-mapping (filter-name, (url-pattern | servlet-name))>
+
+<!--
+The logical name of the filter. This name is used to map the filter.
+Each filter name is unique within the web application.
+
+Used in: filter, filter-mapping
+-->
+<!ELEMENT filter-name (#PCDATA)>
+
+<!--
+The form-error-page element defines the location in the web app
+where the error page that is displayed when login is not successful
+can be found. The path begins with a leading / and is interpreted
+relative to the root of the WAR.
+
+Used in: form-login-config
+-->
+<!ELEMENT form-error-page (#PCDATA)>
+
+<!--
+The form-login-config element specifies the login and error pages
+that should be used in form based login. If form based authentication
+is not used, these elements are ignored.
+
+Used in: login-config
+-->
+<!ELEMENT form-login-config (form-login-page, form-error-page)>
+
+<!--
+The form-login-page element defines the location in the web app
+where the page that can be used for login can be found. The path
+begins with a leading / and is interpreted relative to the root of the WAR.
+
+Used in: form-login-config
+-->
+<!ELEMENT form-login-page (#PCDATA)>
+
+<!--
+The home element contains the fully-qualified name of the enterprise
+bean's home interface.
+
+Used in: ejb-ref
+
+Example:
+
+<home>com.aardvark.payroll.PayrollHome</home>
+-->
+<!ELEMENT home (#PCDATA)>
+
+<!--
+The http-method contains an HTTP method (GET | POST |...).
+
+Used in: web-resource-collection
+-->
+<!ELEMENT http-method (#PCDATA)>
+
+<!--
+The icon element contains small-icon and large-icon elements that
+specify the file names for small and a large GIF or JPEG icon images
+used to represent the parent element in a GUI tool.
+
+Used in: filter, servlet, web-app
+-->
+<!ELEMENT icon (small-icon?, large-icon?)>
+
+<!--
+The init-param element contains a name/value pair as an
+initialization param of the servlet
+
+Used in: filter, servlet
+-->
+<!ELEMENT init-param (param-name, param-value, description?)>
+
+<!--
+The jsp-file element contains the full path to a JSP file within
+the web application beginning with a `/'.
+
+Used in: servlet
+-->
+<!ELEMENT jsp-file (#PCDATA)>
+
+<!--
+The large-icon element contains the name of a file
+containing a large (32 x 32) icon image. The file
+name is a relative path within the web application's
+war file.
+
+The image may be either in the JPEG or GIF format.
+The icon can be used by tools.
+
+Used in: icon
+
+Example:
+
+<large-icon>employee-service-icon32x32.jpg</large-icon>
+-->
+<!ELEMENT large-icon (#PCDATA)>
+
+<!--
+The listener element indicates the deployment properties for a web
+application listener bean.
+
+Used in: web-app
+-->
+<!ELEMENT listener (listener-class)>
+
+<!--
+The listener-class element declares a class in the application must be
+registered as a web application listener bean. The value is the fully qualified classname of the listener class.
+
+
+Used in: listener
+-->
+<!ELEMENT listener-class (#PCDATA)>
+
+<!--
+The load-on-startup element indicates that this servlet should be
+loaded (instantiated and have its init() called) on the startup
+of the web application. The optional contents of
+these element must be an integer indicating the order in which
+the servlet should be loaded. If the value is a negative integer,
+or the element is not present, the container is free to load the
+servlet whenever it chooses. If the value is a positive integer
+or 0, the container must load and initialize the servlet as the
+application is deployed. The container must guarantee that
+servlets marked with lower integers are loaded before servlets
+marked with higher integers. The container may choose the order
+of loading of servlets with the same load-on-start-up value.
+
+Used in: servlet
+-->
+<!ELEMENT load-on-startup (#PCDATA)>
+
+<!--
+
+The local element contains the fully-qualified name of the
+enterprise bean's local interface.
+
+Used in: ejb-local-ref
+
+-->
+<!ELEMENT local (#PCDATA)>
+
+<!--
+
+The local-home element contains the fully-qualified name of the
+enterprise bean's local home interface.
+
+Used in: ejb-local-ref
+-->
+<!ELEMENT local-home (#PCDATA)>
+
+<!--
+The location element contains the location of the resource in the web
+application relative to the root of the web application. The value of
+the location must have a leading `/'.
+
+Used in: error-page
+-->
+<!ELEMENT location (#PCDATA)>
+
+<!--
+The login-config element is used to configure the authentication
+method that should be used, the realm name that should be used for
+this application, and the attributes that are needed by the form login
+mechanism.
+
+Used in: web-app
+-->
+<!ELEMENT login-config (auth-method?, realm-name?, form-login-config?)>
+
+<!--
+The mime-mapping element defines a mapping between an extension
+and a mime type.
+
+Used in: web-app
+-->
+<!ELEMENT mime-mapping (extension, mime-type)>
+
+<!--
+The mime-type element contains a defined mime type. example:
+"text/plain"
+
+Used in: mime-mapping
+-->
+<!ELEMENT mime-type (#PCDATA)>
+
+<!--
+The param-name element contains the name of a parameter. Each parameter
+name must be unique in the web application.
+
+
+Used in: context-param, init-param
+-->
+<!ELEMENT param-name (#PCDATA)>
+
+<!--
+The param-value element contains the value of a parameter.
+
+Used in: context-param, init-param
+-->
+<!ELEMENT param-value (#PCDATA)>
+
+<!--
+The realm name element specifies the realm name to use in HTTP
+Basic authorization.
+
+Used in: login-config
+-->
+<!ELEMENT realm-name (#PCDATA)>
+
+<!--
+The remote element contains the fully-qualified name of the enterprise
+bean's remote interface.
+
+Used in: ejb-ref
+
+Example:
+
+<remote>com.wombat.empl.EmployeeService</remote>
+-->
+<!ELEMENT remote (#PCDATA)>
+
+<!--
+The res-auth element specifies whether the web application code signs
+on programmatically to the resource manager, or whether the Container
+will sign on to the resource manager on behalf of the web application. In the
+latter case, the Container uses information that is supplied by the
+Deployer.
+
+The value of this element must be one of the two following:
+
+       <res-auth>Application</res-auth>
+       <res-auth>Container</res-auth>
+
+Used in: resource-ref
+-->
+<!ELEMENT res-auth (#PCDATA)>
+
+<!--
+The res-ref-name element specifies the name of a resource manager
+connection factory reference.  The name is a JNDI name relative to the
+java:comp/env context.  The name must be unique within a web application.
+
+Used in: resource-ref
+-->
+<!ELEMENT res-ref-name (#PCDATA)>
+
+<!--
+The res-sharing-scope element specifies whether connections obtained
+through the given resource manager connection factory reference can be
+shared. The value of this element, if specified, must be one of the
+two following:
+
+       <res-sharing-scope>Shareable</res-sharing-scope>
+       <res-sharing-scope>Unshareable</res-sharing-scope>
+
+The default value is Shareable.
+
+Used in: resource-ref
+-->
+<!ELEMENT res-sharing-scope (#PCDATA)>
+
+<!--
+The res-type element specifies the type of the data source. The type
+is specified by the fully qualified Java language class or interface
+expected to be implemented by the data source.
+
+Used in: resource-ref
+-->
+<!ELEMENT res-type (#PCDATA)>
+
+<!--
+The resource-env-ref element contains a declaration of a web application's
+reference to an administered object associated with a resource
+in the web application's environment.  It consists of an optional
+description, the resource environment reference name, and an
+indication of the resource environment reference type expected by
+the web application code.
+
+Used in: web-app
+
+Example:
+
+<resource-env-ref>
+    <resource-env-ref-name>jms/StockQueue</resource-env-ref-name>
+    <resource-env-ref-type>javax.jms.Queue</resource-env-ref-type>
+</resource-env-ref>
+-->
+<!ELEMENT resource-env-ref (description?, resource-env-ref-name,
+               resource-env-ref-type)>
+
+<!--
+The resource-env-ref-name element specifies the name of a resource
+environment reference; its value is the environment entry name used in
+the web application code.  The name is a JNDI name relative to the
+java:comp/env context and must be unique within a web application.
+
+Used in: resource-env-ref
+-->
+<!ELEMENT resource-env-ref-name (#PCDATA)>
+
+<!--
+The resource-env-ref-type element specifies the type of a resource
+environment reference.  It is the fully qualified name of a Java
+language class or interface.
+
+Used in: resource-env-ref
+-->
+<!ELEMENT resource-env-ref-type (#PCDATA)>
+
+<!--
+The resource-ref element contains a declaration of a web application's
+reference to an external resource. It consists of an optional
+description, the resource manager connection factory reference name,
+the indication of the resource manager connection factory type
+expected by the web application code, the type of authentication
+(Application or Container), and an optional specification of the
+shareability of connections obtained from the resource (Shareable or
+Unshareable).
+
+Used in: web-app
+
+Example:
+
+    <resource-ref>
+       <res-ref-name>jdbc/EmployeeAppDB</res-ref-name>
+       <res-type>javax.sql.DataSource</res-type>
+       <res-auth>Container</res-auth>
+       <res-sharing-scope>Shareable</res-sharing-scope>
+    </resource-ref>
+-->
+<!ELEMENT resource-ref (description?, res-ref-name, res-type, res-auth,
+               res-sharing-scope?)>
+
+<!--
+The role-link element is a reference to a defined security role. The
+role-link element must contain the name of one of the security roles
+defined in the security-role elements.
+
+Used in: security-role-ref
+-->
+<!ELEMENT role-link (#PCDATA)>
+
+<!--
+The role-name element contains the name of a security role.
+
+The name must conform to the lexical rules for an NMTOKEN.
+
+Used in: auth-constraint, run-as, security-role, security-role-ref
+-->
+<!ELEMENT role-name (#PCDATA)>
+
+<!--
+The run-as element specifies the run-as identity to be used for the
+execution of the web application. It contains an optional description, and
+the name of a security role.
+
+Used in: servlet
+-->
+<!ELEMENT run-as (description?, role-name)>
+
+<!--
+The security-constraint element is used to associate security
+constraints with one or more web resource collections
+
+Used in: web-app
+-->
+<!ELEMENT security-constraint (display-name?, web-resource-collection+,
+auth-constraint?, user-data-constraint?)>
+
+<!--
+The security-role element contains the definition of a security
+role. The definition consists of an optional description of the
+security role, and the security role name.
+
+Used in: web-app
+
+Example:
+
+    <security-role>
+       <description>
+           This role includes all employees who are authorized
+           to access the employee service application.
+       </description>
+       <role-name>employee</role-name>
+    </security-role>
+-->
+<!ELEMENT security-role (description?, role-name)>
+
+<!--
+The security-role-ref element contains the declaration of a security
+role reference in the web application's code. The declaration consists
+of an optional description, the security role name used in the code,
+and an optional link to a security role. If the security role is not
+specified, the Deployer must choose an appropriate security role.
+
+The value of the role-name element must be the String used as the
+parameter to the EJBContext.isCallerInRole(String roleName) method
+or the HttpServletRequest.isUserInRole(String role) method.
+
+Used in: servlet
+
+-->
+<!ELEMENT security-role-ref (description?, role-name, role-link?)>
+
+<!--
+The servlet element contains the declarative data of a
+servlet. If a jsp-file is specified and the load-on-startup element is
+present, then the JSP should be precompiled and loaded.
+
+Used in: web-app
+-->
+<!ELEMENT servlet (icon?, servlet-name, display-name?, description?,
+(servlet-class|jsp-file), init-param*, load-on-startup?, run-as?, security-role-ref*)>
+
+<!--
+The servlet-class element contains the fully qualified class name
+of the servlet.
+
+Used in: servlet
+-->
+<!ELEMENT servlet-class (#PCDATA)>
+
+<!--
+The servlet-mapping element defines a mapping between a servlet
+and a url pattern
+
+Used in: web-app
+-->
+<!ELEMENT servlet-mapping (servlet-name, url-pattern)>
+
+<!--
+The servlet-name element contains the canonical name of the
+servlet. Each servlet name is unique within the web application.
+
+Used in: filter-mapping, servlet, servlet-mapping
+-->
+<!ELEMENT servlet-name (#PCDATA)>
+
+<!--
+The session-config element defines the session parameters for
+this web application.
+
+Used in: web-app
+-->
+<!ELEMENT session-config (session-timeout?)>
+
+<!--
+The session-timeout element defines the default session timeout
+interval for all sessions created in this web application. The
+specified timeout must be expressed in a whole number of minutes.
+If the timeout is 0 or less, the container ensures the default
+behaviour of sessions is never to time out.
+
+Used in: session-config
+-->
+<!ELEMENT session-timeout (#PCDATA)>
+
+<!--
+The small-icon element contains the name of a file
+containing a small (16 x 16) icon image. The file
+name is a relative path within the web application's
+war file.
+
+The image may be either in the JPEG or GIF format.
+The icon can be used by tools.
+
+Used in: icon
+
+Example:
+
+<small-icon>employee-service-icon16x16.jpg</small-icon>
+-->
+<!ELEMENT small-icon (#PCDATA)>
+
+<!--
+The taglib element is used to describe a JSP tag library.
+
+Used in: web-app
+-->
+<!ELEMENT taglib (taglib-uri, taglib-location)>
+
+<!--
+the taglib-location element contains the location (as a resource
+relative to the root of the web application) where to find the Tag
+Libary Description file for the tag library.
+
+Used in: taglib
+-->
+<!ELEMENT taglib-location (#PCDATA)>
+
+<!--
+The taglib-uri element describes a URI, relative to the location
+of the web.xml document, identifying a Tag Library used in the Web
+Application.
+
+Used in: taglib
+-->
+<!ELEMENT taglib-uri (#PCDATA)>
+
+<!--
+The transport-guarantee element specifies that the communication
+between client and server should be NONE, INTEGRAL, or
+CONFIDENTIAL. NONE means that the application does not require any
+transport guarantees. A value of INTEGRAL means that the application
+requires that the data sent between the client and server be sent in
+such a way that it can't be changed in transit. CONFIDENTIAL means
+that the application requires that the data be transmitted in a
+fashion that prevents other entities from observing the contents of
+the transmission. In most cases, the presence of the INTEGRAL or
+CONFIDENTIAL flag will indicate that the use of SSL is required.
+
+Used in: user-data-constraint
+-->
+<!ELEMENT transport-guarantee (#PCDATA)>
+
+<!--
+The url-pattern element contains the url pattern of the mapping. Must
+follow the rules specified in Section 11.2 of the Servlet API
+Specification.
+
+Used in: filter-mapping, servlet-mapping, web-resource-collection
+-->
+<!ELEMENT url-pattern (#PCDATA)>
+
+<!--
+The user-data-constraint element is used to indicate how data
+communicated between the client and container should be protected.
+
+Used in: security-constraint
+-->
+<!ELEMENT user-data-constraint (description?, transport-guarantee)>
+
+<!--
+The web-resource-collection element is used to identify a subset
+of the resources and HTTP methods on those resources within a web
+application to which a security constraint applies. If no HTTP methods
+are specified, then the security constraint applies to all HTTP
+methods.
+
+Used in: security-constraint
+-->
+<!ELEMENT web-resource-collection (web-resource-name, description?,
+url-pattern*, http-method*)>
+
+<!--
+The web-resource-name contains the name of this web resource
+collection.
+
+Used in: web-resource-collection
+-->
+<!ELEMENT web-resource-name (#PCDATA)>
+
+<!--
+The welcome-file element contains file name to use as a default
+welcome file, such as index.html
+
+Used in: welcome-file-list
+-->
+<!ELEMENT welcome-file (#PCDATA)>
+
+<!--
+The welcome-file-list contains an ordered list of welcome files
+elements.
+
+Used in: web-app
+-->
+<!ELEMENT welcome-file-list (welcome-file+)>
+
+<!--
+The ID mechanism is to allow tools that produce additional deployment
+information (i.e., information beyond the standard deployment
+descriptor information) to store the non-standard information in a
+separate file, and easily refer from these tool-specific files to the
+information in the standard deployment descriptor.
+
+Tools are not allowed to add the non-standard information into the
+standard deployment descriptor.
+-->
+
+<!ATTLIST auth-constraint id ID #IMPLIED>
+<!ATTLIST auth-method id ID #IMPLIED>
+<!ATTLIST context-param id ID #IMPLIED>
+<!ATTLIST description id ID #IMPLIED>
+<!ATTLIST display-name id ID #IMPLIED>
+<!ATTLIST distributable id ID #IMPLIED>
+<!ATTLIST ejb-link id ID #IMPLIED>
+<!ATTLIST ejb-local-ref id ID #IMPLIED>
+<!ATTLIST ejb-ref id ID #IMPLIED>
+<!ATTLIST ejb-ref-name id ID #IMPLIED>
+<!ATTLIST ejb-ref-type id ID #IMPLIED>
+<!ATTLIST env-entry id ID #IMPLIED>
+<!ATTLIST env-entry-name id ID #IMPLIED>
+<!ATTLIST env-entry-type id ID #IMPLIED>
+<!ATTLIST env-entry-value id ID #IMPLIED>
+<!ATTLIST error-code id ID #IMPLIED>
+<!ATTLIST error-page id ID #IMPLIED>
+<!ATTLIST exception-type id ID #IMPLIED>
+<!ATTLIST extension id ID #IMPLIED>
+<!ATTLIST filter id ID #IMPLIED>
+<!ATTLIST filter-class id ID #IMPLIED>
+<!ATTLIST filter-mapping id ID #IMPLIED>
+<!ATTLIST filter-name id ID #IMPLIED>
+<!ATTLIST form-error-page id ID #IMPLIED>
+<!ATTLIST form-login-config id ID #IMPLIED>
+<!ATTLIST form-login-page id ID #IMPLIED>
+<!ATTLIST home id ID #IMPLIED>
+<!ATTLIST http-method id ID #IMPLIED>
+<!ATTLIST icon id ID #IMPLIED>
+<!ATTLIST init-param id ID #IMPLIED>
+<!ATTLIST jsp-file id ID #IMPLIED>
+<!ATTLIST large-icon id ID #IMPLIED>
+<!ATTLIST listener id ID #IMPLIED>
+<!ATTLIST listener-class id ID #IMPLIED>
+<!ATTLIST load-on-startup id ID #IMPLIED>
+<!ATTLIST local id ID #IMPLIED>
+<!ATTLIST local-home id ID #IMPLIED>
+<!ATTLIST location id ID #IMPLIED>
+<!ATTLIST login-config id ID #IMPLIED>
+<!ATTLIST mime-mapping id ID #IMPLIED>
+<!ATTLIST mime-type id ID #IMPLIED>
+<!ATTLIST param-name id ID #IMPLIED>
+<!ATTLIST param-value id ID #IMPLIED>
+<!ATTLIST realm-name id ID #IMPLIED>
+<!ATTLIST remote id ID #IMPLIED>
+<!ATTLIST res-auth id ID #IMPLIED>
+<!ATTLIST res-ref-name id ID #IMPLIED>
+<!ATTLIST res-sharing-scope id ID #IMPLIED>
+<!ATTLIST res-type id ID #IMPLIED>
+<!ATTLIST resource-env-ref id ID #IMPLIED>
+<!ATTLIST resource-env-ref-name id ID #IMPLIED>
+<!ATTLIST resource-env-ref-type id ID #IMPLIED>
+<!ATTLIST resource-ref id ID #IMPLIED>
+<!ATTLIST role-link id ID #IMPLIED>
+<!ATTLIST role-name id ID #IMPLIED>
+<!ATTLIST run-as id ID #IMPLIED>
+<!ATTLIST security-constraint id ID #IMPLIED>
+<!ATTLIST security-role id ID #IMPLIED>
+<!ATTLIST security-role-ref id ID #IMPLIED>
+<!ATTLIST servlet id ID #IMPLIED>
+<!ATTLIST servlet-class id ID #IMPLIED>
+<!ATTLIST servlet-mapping id ID #IMPLIED>
+<!ATTLIST servlet-name id ID #IMPLIED>
+<!ATTLIST session-config id ID #IMPLIED>
+<!ATTLIST session-timeout id ID #IMPLIED>
+<!ATTLIST small-icon id ID #IMPLIED>
+<!ATTLIST taglib id ID #IMPLIED>
+<!ATTLIST taglib-location id ID #IMPLIED>
+<!ATTLIST taglib-uri id ID #IMPLIED>
+<!ATTLIST transport-guarantee id ID #IMPLIED>
+<!ATTLIST url-pattern id ID #IMPLIED>
+<!ATTLIST user-data-constraint id ID #IMPLIED>
+<!ATTLIST web-app id ID #IMPLIED>
+<!ATTLIST web-resource-collection id ID #IMPLIED>
+<!ATTLIST web-resource-name id ID #IMPLIED>
+<!ATTLIST welcome-file id ID #IMPLIED>
+<!ATTLIST welcome-file-list id ID #IMPLIED>
diff --git a/src/catalina-example/org/securityfilter/catalina/TrivialCatalinaRealm.java b/src/catalina-example/org/securityfilter/catalina/TrivialCatalinaRealm.java
new file mode 100644 (file)
index 0000000..ec55b06
--- /dev/null
@@ -0,0 +1,123 @@
+/*
+ * $Header: /cvsroot/securityfilter/securityfilter/src/catalina-example/org/securityfilter/catalina/Attic/TrivialCatalinaRealm.java,v 1.1 2002/08/08 13:20:47 maxcooper Exp $
+ * $Revision: 1.1 $
+ * $Date: 2002/08/08 13:20:47 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+package org.securityfilter.catalina;
+
+import org.apache.catalina.realm.GenericPrincipal;
+import org.apache.catalina.realm.RealmBase;
+
+import java.security.Principal;
+import java.util.ArrayList;
+
+/**
+ * TrivialCatalinaRealm - Trivial Catalina Realm implementation to demonstrate
+ * org.securityfilter.realm.adapter.CatalinaRealmAdapter adapter class.
+ *
+ * @author Max Cooper (max@maxcooper.com)
+ */
+public class TrivialCatalinaRealm extends RealmBase {
+   private static final String THE_USERNAME = "username";
+   private static final String THE_PASSWORD = "password";
+   private static final String THE_ROLE = "inthisrole";
+
+   /**
+    * Return a short name for this Realm implementation.
+    */
+   protected String getName() {
+      return null;
+   }
+
+   /**
+    * Return the password associated with the given principal's user name.
+    */
+   protected String getPassword(String s) {
+      return (THE_USERNAME.equals(s) ? THE_PASSWORD : null);
+   }
+
+   /**
+    * Return the Principal associated with the given user name.
+    */
+   protected Principal getPrincipal(String s) {
+      if (THE_USERNAME.equals(s)) {
+         ArrayList roleList = new ArrayList();
+         roleList.add(THE_ROLE);
+         return new GenericPrincipal(this, THE_USERNAME, THE_PASSWORD, roleList);
+      } else {
+         return null;
+      }
+   }
+
+   /**
+    * Setter for exampleProperty to deomonstrate setting realm properties from config file.
+    *
+    * This has no effect other than printing a message when the property is set.
+    *
+    * @param value example property value
+    */
+   public void setExampleProperty(String value) {
+      System.out.println(this.getClass().getName() + ": exampleProperty set to \'" + value + "\'");
+   }
+}
+
+// ----------------------------------------------------------------------------
+// EOF
\ No newline at end of file
diff --git a/src/example/org/securityfilter/example/TrivialSecurityRealm.java b/src/example/org/securityfilter/example/TrivialSecurityRealm.java
new file mode 100644 (file)
index 0000000..3bf7bc9
--- /dev/null
@@ -0,0 +1,122 @@
+/*
+ * $Header: /cvsroot/securityfilter/securityfilter/src/example/org/securityfilter/example/Attic/TrivialSecurityRealm.java,v 1.1 2002/08/08 13:20:47 maxcooper Exp $
+ * $Revision: 1.1 $
+ * $Date: 2002/08/08 13:20:47 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+package org.securityfilter.example;
+
+import org.securityfilter.realm.SecurityRealmBase;
+
+/**
+ * Trivial implementation of the SecurityRealmInterface.
+ *
+ * There is one user: username is 'username', password is 'password'
+ * And this user is in one role: 'inthisrole'
+ *
+ * @author Max Cooper (max@maxcooper.com)
+ * @version $Revision: 1.1 $ $Date: 2002/08/08 13:20:47 $
+ */
+public class TrivialSecurityRealm extends SecurityRealmBase {
+   private static final String THE_USERNAME = "username";
+   private static final String THE_PASSWORD = "password";
+   private static final String THE_ROLE = "inthisrole";
+
+   /**
+    * Authenticate a user.
+    *
+    * Implement this method in a subclass to avoid dealing with Principal objects.
+    *
+    * @param username a username
+    * @param password a plain text password, as entered by the user
+    *
+    * @return null if the user cannot be authenticated, otherwise a Pricipal object is returned
+    */
+   public boolean booleanAuthenticate(String username, String password) {
+      return THE_USERNAME.equals(username) && THE_PASSWORD.equals(password);
+   }
+
+   /**
+    * Test for role membership.
+    *
+    * Implement this method in a subclass to avoid dealing with Principal objects.
+    *
+    * @param principal Principal object representing a user
+    * @param rolename name of a role to test for membership
+    * @return true if the user is in the role, false otherwise
+    */
+   public boolean isUserInRole(String username, String role) {
+      return THE_USERNAME.equals(username) && THE_ROLE.equals(role);
+   }
+
+   /**
+    * Setter for exampleProperty to deomonstrate setting realm properties from config file.
+    *
+    * This has no effect other than printing a message when the property is set.
+    *
+    * @param value example property value
+    */
+   public void setExampleProperty(String value) {
+      System.out.println(this.getClass().getName() + ": exampleProperty set to \'" + value + "\'");
+   }
+}
+
+// ----------------------------------------------------------------------------
+// EOF
\ No newline at end of file
diff --git a/src/share/org/securityfilter/config/SecurityConfig.java b/src/share/org/securityfilter/config/SecurityConfig.java
new file mode 100644 (file)
index 0000000..2c3a94e
--- /dev/null
@@ -0,0 +1,277 @@
+/*
+ * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/config/SecurityConfig.java,v 1.1 2002/08/08 13:20:47 maxcooper Exp $
+ * $Revision: 1.1 $
+ * $Date: 2002/08/08 13:20:47 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+package org.securityfilter.config;
+
+import org.apache.commons.digester.Digester;
+import org.securityfilter.realm.SecurityRealmInterface;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * SecurityConfig gathers information from the security-config.xml file to be used by the filter.
+ *
+ * @author Torgeir Veimo (torgeir@pobox.com)
+ * @author Max Cooper (max@maxcooper.com)
+ * @version $Revision: 1.1 $ $Date: 2002/08/08 13:20:47 $
+ */
+public class SecurityConfig {
+
+   private String loginPage = null;
+   private String errorPage = null;
+   private String defaultPage = null;
+   private ArrayList securityConstraints = null;
+   private SecurityRealmInterface realm = null;
+   private Object lastRealm = null;
+   private boolean validating;
+
+   /**
+    * Constructor that takes the validating flag and debug level to be used while parsing.
+    *
+    * @param validating validate the input file, true = validate, false = don't validate
+    * @param debugLevel set the debug level to use while parsing
+    */
+   public SecurityConfig(boolean validating) {
+      this.validating = validating;
+   }
+
+   /**
+    * Return the login page url.
+    */
+   public String getLoginPage() {
+      return loginPage;
+   }
+
+   /**
+    * Set the login page URL. This is the page the user will be sent to to login (i.e. the login form).
+    *
+    * @param loginPage The login page url (relative to site root)
+    */
+   public void setLoginPage(String loginPage) {
+      this.loginPage = loginPage;
+   }
+
+   /**
+    * Return the error page URL.
+    */
+   public String getErrorPage() {
+      return errorPage;
+   }
+
+   /**
+    * Set the error page URL. This is the page the user will be sent to if login request fails.
+    *
+    * @param errorPage The login page URL (relative to site root)
+    */
+   public void setErrorPage(String errorPage) {
+      this.errorPage = errorPage;
+   }
+
+   /**
+    * Return the default page URL.
+    */
+   public String getDefaultPage() {
+      return defaultPage;
+   }
+
+   /**
+    * Set the default page URL. This is the page the user will be sent to if they submit a login request without
+    * being forced to the login page by the filter.
+    *
+    * @param defaultPage The default page URL (relative to site root)
+    */
+   public void setDefaultPage(String defaultPage) {
+      this.defaultPage = defaultPage;
+   }
+
+   /**
+    * Return the realm to use for authentication. This is the outer-most realm if nested realms are used.
+    * The outer-most realm must be listed first in the configuration file.
+    */
+   public SecurityRealmInterface getRealm() {
+      return realm;
+   }
+
+   /**
+    * Adds a realm to use for authentication.
+    *
+    * The first time this method is called, the realm must implement SecurityRealmInterface.
+    * Subsequent calls can be any kind of object, and setRealm(realm) will be called on the
+    * last realm passed to this method. This allows nesting of realms for caching or when a
+    * realm adapter is used.
+    *
+    * @param realm The realm to use, or nest in deeper realm
+    */
+   public synchronized void addRealm(
+      Object realm
+   ) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+      if (this.realm == null) {
+         this.realm = (SecurityRealmInterface) realm;
+         lastRealm = realm;
+      } else {
+         // call lastRealm.setRealm(realm)
+         Method addMethod = lastRealm.getClass().getMethod("setRealm", new Class[] { Object.class });
+         addMethod.invoke(lastRealm, new Object[] { realm });
+         lastRealm = realm;
+      }
+   }
+
+   /**
+    * Return the configured SecurityConstraints.
+    */
+   public List getSecurityConstraints() {
+      return this.securityConstraints;
+   }
+
+   /**
+    * Adds a SecurityConstraint.
+    *
+    * @param constraint The SecurityConstraint to add
+    */
+   public void addSecurityConstraint(SecurityConstraint constraint) {
+      securityConstraints.add(constraint);
+   }
+
+   /**
+    * Loads configuration from the specifued configURL.
+    *
+    * @param configURL The url to load.
+    *
+    * @exception IOException if an input/output error occurs
+    * @exception SAXException if the file has invalid xml syntax
+    */
+   public void loadConfig(URL configURL) throws IOException, SAXException {
+
+      securityConstraints = new ArrayList();
+
+      Digester digester = new Digester();
+
+      digester.push(this);
+      digester.setValidating(validating);
+
+      // realms
+      digester.addObjectCreate("securityfilter-config/realm", null, "className");
+      digester.addSetProperty("securityfilter-config/realm/realm-param", "name", "value");
+      digester.addSetNext("securityfilter-config/realm", "addRealm", "java.lang.Object");
+
+      // login and error pages
+      digester.addCallMethod("securityfilter-config/login-config/form-login-config/form-login-page", "setLoginPage", 0);
+      digester.addCallMethod("securityfilter-config/login-config/form-login-config/form-error-page", "setErrorPage", 0);
+      digester.addCallMethod("securityfilter-config/login-config/form-login-config/form-default-page", "setDefaultPage", 0);
+
+      // security-constraint
+      digester.addObjectCreate(
+         "securityfilter-config/security-constraint",
+         "org.securityfilter.config.SecurityConstraint"
+      );
+      digester.addSetNext(
+         "securityfilter-config/security-constraint",
+         "addSecurityConstraint",
+         "org.securityfilter.config.SecurityConstraint"
+      );
+      digester.addCallMethod(
+         "securityfilter-config/security-constraint/auth-constraint/role-name",
+         "addRole",
+         0
+      );
+
+      // web-resource-collection
+      digester.addObjectCreate(
+         "securityfilter-config/security-constraint/web-resource-collection",
+         "org.securityfilter.config.WebResourceCollection"
+      );
+      digester.addSetNext(
+         "securityfilter-config/security-constraint/web-resource-collection",
+         "addWebResourceCollection",
+         "org.securityfilter.config.WebResourceCollection"
+      );
+      digester.addCallMethod(
+         "securityfilter-config/security-constraint/web-resource-collection/web-resource-name",
+         "setName",
+         0
+      );
+      digester.addCallMethod(
+         "securityfilter-config/security-constraint/web-resource-collection/url-pattern",
+         "addURLPattern",
+         0
+      );
+      digester.addCallMethod(
+         "securityfilter-config/security-constraint/web-resource-collection/http-method",
+         "addHttpMethod",
+         0
+      );
+
+      InputSource input = new InputSource(configURL.openStream());
+      digester.parse(input);
+   }
+}
+
+// ------------------------------------------------------------------------
+// EOF
\ No newline at end of file
diff --git a/src/share/org/securityfilter/config/SecurityConstraint.java b/src/share/org/securityfilter/config/SecurityConstraint.java
new file mode 100644 (file)
index 0000000..580476f
--- /dev/null
@@ -0,0 +1,141 @@
+/*
+ * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/config/SecurityConstraint.java,v 1.1 2002/08/08 13:20:47 maxcooper Exp $
+ * $Revision: 1.1 $
+ * $Date: 2002/08/08 13:20:47 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+package org.securityfilter.config;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * SecurityConstraint
+ *
+ * @author Max Cooper (max@maxcooper.com)
+ * @author Torgeir Veimo (torgeir@pobox.com)
+ * @version $Revision: 1.1 $ $Date: 2002/08/08 13:20:47 $
+ */
+public class SecurityConstraint {
+   protected String name;
+   protected List resourceCollections;
+   protected List roles;
+
+   /**
+    * Constructor
+    */
+   public SecurityConstraint() {
+      this.resourceCollections = new ArrayList();
+      this.roles = new ArrayList();
+   }
+
+   /**
+    * Set the security constraint name.
+    *
+    * @param name the name of this SecurityConstraint
+    */
+   public void setName(String name) {
+      this.name = name;
+   }
+
+   /**
+    * Return the name of this SecurityConstraint
+    */
+   public String getName() {
+      return this.name;
+   }
+
+   /**
+    * Add a WebResourceCollection to this SecurityConstraint.
+    *
+    * @param resourceCollection the WebResourceCollection to add
+    */
+   public void addWebResourceCollection(WebResourceCollection resourceCollection) {
+      resourceCollections.add(resourceCollection);
+   }
+
+   /**
+    * Get the WebResourceCollections for this SecurityConstraint. The order of the list is the order in which the
+    * WebResourceCollections appeared in the config file.
+    */
+   public List getWebResourceCollections() {
+      return this.resourceCollections;
+   }
+
+   /**
+    * Add a role to this SecurityConstraint.
+    *
+    * @param role role to add
+    */
+   public void addRole(String role) {
+      roles.add(role);
+   }
+
+   /**
+    * Get the roles that are authorized to access the WebResourceCollections in this SecurityConstraint.
+    * Returns an empty list if no roles were present in the config file.
+    */
+   public List getRoles() {
+      return this.roles;
+   }
+}
+
+// ------------------------------------------------------------------------
+// EOF
\ No newline at end of file
diff --git a/src/share/org/securityfilter/config/WebResourceCollection.java b/src/share/org/securityfilter/config/WebResourceCollection.java
new file mode 100644 (file)
index 0000000..3cfa88a
--- /dev/null
@@ -0,0 +1,138 @@
+/*
+ * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/config/WebResourceCollection.java,v 1.1 2002/08/08 13:20:48 maxcooper Exp $
+ * $Revision: 1.1 $
+ * $Date: 2002/08/08 13:20:48 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+package org.securityfilter.config;
+
+import java.util.*;
+
+/**
+ * WebResourceCollection represents a web-resource-collection from the security config file.
+ * It has a name, a list of url patterns, and a list of http methods.
+ *
+ * @author Max Cooper (max@maxcooper.com)
+ * @version $Revision: 1.1 $ $Date: 2002/08/08 13:20:48 $
+ */
+public class WebResourceCollection {
+   protected String name;
+   protected List patterns;
+   protected Collection methods;
+
+   /**
+    * Constructor
+    */
+   public WebResourceCollection() {
+      patterns = Collections.synchronizedList(new ArrayList());
+      methods = Collections.synchronizedSet(new HashSet());
+   }
+
+   /**
+    * Set the name of this WebResourceCollection.
+    *
+    * @param name name of this WebResourceCollection
+    */
+   public void setName(String name) {
+      this.name = name;
+   }
+
+   /**
+    * Get the name of this WebResourceCollection.
+    */
+   public String getName() {
+      return this.name;
+   }
+
+   /**
+    * Add a url pattern to this WebResourceCollection.
+    *
+    * @param pattern url pattern to add
+    */
+   public void addURLPattern(String pattern) {
+      patterns.add(pattern);
+   }
+
+   /**
+    * Get a list of url patterns in the order they were added to this WebResourceCollection.
+    */
+   public List getURLPatterns() {
+      return Collections.unmodifiableList(patterns);
+   }
+
+   /**
+    * Add an http method to this WebResourceCollection.
+    *
+    * @param method http method to add
+    */
+   public void addHttpMethod(String method) {
+      methods.add(method);
+   }
+
+   /**
+    * Get a collection of http methods for this WebResourceCollection.
+    */
+   public Collection getHttpMethods() {
+      return Collections.unmodifiableCollection(methods);
+   }
+}
+
+// ----------------------------------------------------------------------------
+// EOF
\ No newline at end of file
diff --git a/src/share/org/securityfilter/filter/MatchableURLPattern.java b/src/share/org/securityfilter/filter/MatchableURLPattern.java
new file mode 100644 (file)
index 0000000..0bd2252
--- /dev/null
@@ -0,0 +1,216 @@
+/*
+ * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/filter/Attic/MatchableURLPattern.java,v 1.1 2002/08/08 13:20:48 maxcooper Exp $
+ * $Revision: 1.1 $
+ * $Date: 2002/08/08 13:20:48 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+package org.securityfilter.filter;
+
+import org.apache.regexp.RE;
+import org.apache.regexp.RECompiler;
+import org.apache.regexp.RESyntaxException;
+import org.securityfilter.config.SecurityConstraint;
+import org.securityfilter.config.WebResourceCollection;
+
+/**
+ * MatchableURLPattern - Contains matchable URL pattern and the associated SecurityConstraint and WebResourceCollection
+ * objects for the pattern. Also supports sorting according to the Servlet Spec v2.3 (not yet implemented - just sorts
+ * by the order field).
+ *
+ * @author Max Cooper (max@maxcooper.com)
+ * @version $Revision: 1.1 $ $Date: 2002/08/08 13:20:48 $
+ */
+public class MatchableURLPattern implements Comparable {
+   private String pattern;
+   private RE patternRE;
+   private SecurityConstraint constraint;
+   private WebResourceCollection resourceCollection;
+   private int order;
+
+   /**
+    * Construct a new MatchableURLPattern object.
+    *
+    * @param pattern the url pattern to match
+    * @param constraint the SecurityConstraint associated with this pattern
+    * @param resourceCollection the WebResourceCollection associated with this pattern
+    * @param order the order in which this pattern occurred in the configuration file
+    * @param compiler an RECompiler to use to compile this url pattern
+    *
+    * @see MatchableURLPatternFactory
+    */
+   public MatchableURLPattern(
+      String pattern,
+      SecurityConstraint constraint,
+      WebResourceCollection resourceCollection,
+      int order,
+      RECompiler compiler
+   ) throws RESyntaxException {
+      this.pattern = pattern;
+      this.constraint = constraint;
+      this.resourceCollection = resourceCollection;
+      this.order = order;
+      this.patternRE = new RE(compiler.compile(getConvertedPattern()));
+   }
+
+   /**
+    * Return true if this pattern matches the passed URL.
+    *
+    * @param URL the URL to attempt to match
+    * @return true if this pattern matches the URL, false otherwise
+    */
+   public boolean match(String URL) {
+      return patternRE.match(URL);
+   }
+
+   /**
+    * Get the url pattern to match.
+    */
+   public String getPattern() {
+      return pattern;
+   }
+
+   /**
+    * Get the SecurityConstraint object associated with this pattern.
+    */
+   public SecurityConstraint getSecurityConstraint() {
+      return constraint;
+   }
+
+   /**
+    * Get the order value for this pattern (the order in which it appeared in the config file).
+    */
+   public int getOrder() {
+      return order;
+   }
+
+   /**
+    * Get the WebResourceCollection associated with this pattern.
+    */
+   public WebResourceCollection getWebResourceCollection() {
+      return resourceCollection;
+   }
+
+   /**
+    * Test if this pattern is equivalent to another pattern.
+    * This is implemented so that consistency with the compareTo method results can be maintained.
+    *
+    * @param obj the value to test equivalence with
+    * @return true if the passed object is an equivalent MatchableURLPattern, false if it is not a MatchableURLPattern
+    * or if it is not equivalent.
+    */
+   public boolean equals(Object obj) {
+      if (obj instanceof MatchableURLPattern) {
+         MatchableURLPattern otherPattern = (MatchableURLPattern) obj;
+         return (
+            constraint.equals(otherPattern.getSecurityConstraint())
+            && resourceCollection.equals(otherPattern.getWebResourceCollection())
+            && pattern.equals(otherPattern.getPattern())
+         );
+      }
+      return false;
+   }
+
+   /**
+    * Compares this MatchableURLPattern to another to support sorting.
+    * Ordering is currently implemented according to the order field value, which can exhibit behavior inconsistent
+    * with equals() if non-equivalent instances have the same order value.
+    *
+    * TO-DO: Update to support servlet spec compliant ordering.
+    *
+    * @param o object to compare to
+    *
+    * @exception ClassCastException thrown if o is not a MatchableURLPattern instance
+    */
+   public int compareTo(Object o) throws ClassCastException {
+      MatchableURLPattern otherPattern = (MatchableURLPattern) o;
+      if (this.equals(otherPattern)) {
+         return 0;
+      } else {
+         // TO-DO: update to reflect servlet spec pattern order
+         return (getOrder() - otherPattern.getOrder());
+      }
+   }
+
+   /**
+    * Return the pattern string in RE syntax form.
+    *
+    * TO-DO: validate that the conversion is proper for all pattern strings (probably needs some improvements).
+    */
+   private String getConvertedPattern() {
+      StringBuffer buf = new StringBuffer(pattern);
+      int pos;
+      // escape '.' characters
+      pos = buf.toString().indexOf('.');
+      while (pos != -1) {
+         buf.insert(pos, "\\");
+         pos = buf.toString().indexOf('.', pos + 2);
+      }
+      // replace '*' chars in the pattern with '.*'
+      pos = buf.toString().indexOf('*');
+      while (pos != -1) {
+         buf.replace(pos, pos + 1, ".*");
+         pos = buf.toString().indexOf('*', pos + 2);
+      }
+      return buf.toString();
+   }
+}
+
+// ----------------------------------------------------------------------------
+// EOF
\ No newline at end of file
diff --git a/src/share/org/securityfilter/filter/MatchableURLPatternFactory.java b/src/share/org/securityfilter/filter/MatchableURLPatternFactory.java
new file mode 100644 (file)
index 0000000..5db9bc4
--- /dev/null
@@ -0,0 +1,109 @@
+/*
+ * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/filter/Attic/MatchableURLPatternFactory.java,v 1.1 2002/08/08 13:20:48 maxcooper Exp $
+ * $Revision: 1.1 $
+ * $Date: 2002/08/08 13:20:48 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+package org.securityfilter.filter;
+
+import org.apache.regexp.RECompiler;
+import org.apache.regexp.RESyntaxException;
+import org.securityfilter.config.SecurityConstraint;
+import org.securityfilter.config.WebResourceCollection;
+
+/**
+ * MatchableURLPatternFactory creates MatchableURLPattern instances. It keeps an RECompiler to use for the creation
+ * of a set of instances.
+ *
+ * @author Max Cooper (max@maxcooper.com)
+ * @version $Revision: 1.1 $ $Date: 2002/08/08 13:20:48 $
+ */
+public class MatchableURLPatternFactory {
+   private RECompiler compiler;
+
+   /**
+    * Constructor
+    */
+   public MatchableURLPatternFactory() {
+      compiler = new RECompiler();
+   }
+
+   /**
+    * Create a MatchableURLPattern instance.
+    *
+    * @param pattern url pattern in config file syntax
+    * @param constraint SecurityConstraint object to associate with this pattern
+    * @param resourceCollection WebResourceCollection to associate with this pattern
+    * @param order order in which this pattern appeared in the config file
+    *
+    * @exception RESyntaxException throws exception if pattern cannot be compiled after conversion to RE syntax
+    */
+   public MatchableURLPattern createURLPatternMatcher(
+      String pattern,
+      SecurityConstraint constraint,
+      WebResourceCollection resourceCollection,
+      int order
+   ) throws RESyntaxException {
+      return new MatchableURLPattern(pattern, constraint, resourceCollection, order, compiler);
+   }
+}
+
+// ----------------------------------------------------------------------------
+// EOF
\ No newline at end of file
diff --git a/src/share/org/securityfilter/filter/SecurityFilter.java b/src/share/org/securityfilter/filter/SecurityFilter.java
new file mode 100644 (file)
index 0000000..77ef803
--- /dev/null
@@ -0,0 +1,416 @@
+/*
+ * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/filter/SecurityFilter.java,v 1.1 2002/08/08 13:20:48 maxcooper Exp $
+ * $Revision: 1.1 $
+ * $Date: 2002/08/08 13:20:48 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+package org.securityfilter.filter;
+
+import org.apache.regexp.RE;
+import org.apache.regexp.RECompiler;
+import org.apache.regexp.RESyntaxException;
+import org.securityfilter.config.SecurityConfig;
+import org.securityfilter.config.SecurityConstraint;
+import org.securityfilter.config.WebResourceCollection;
+import org.securityfilter.realm.SecurityRealmInterface;
+
+import javax.servlet.*;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import java.io.IOException;
+import java.net.URL;
+import java.security.Principal;
+import java.util.*;
+
+/**
+ * SecurityFilter provides authentication and authorization services.
+ *
+ * @author Max Cooper (max@maxcooper.com)
+ * @author Torgeir Veimo (torgeir@pobox.com)
+ * @version $Revision: 1.1 $ $Date: 2002/08/08 13:20:48 $
+ */
+public class SecurityFilter implements javax.servlet.Filter {
+   public static final String CONTINUE_TO_URL = SecurityFilter.class.getName() + ".CONTINUE_TO_URL";
+   public static final String POSTED_PARAM_URL = SecurityFilter.class.getName() + ".POSTED_PARAM_URL";
+   public static final String POSTED_PARAM_MAP = SecurityFilter.class.getName() + ".POSTED_PARAM_MAP";
+
+   public static final String CONFIG_FILE_KEY = "config";
+   public static final String DEFAULT_CONFIG_FILE = "/WEB-INF/securityfilter-config.xml";
+   public static final String VALIDATE_KEY = "validate";
+   public static final String TRUE = "true";
+
+   protected FilterConfig config;
+   protected ArrayList URLPatterns;
+   protected SecurityRealmInterface realm;
+   protected String loginPage;
+   protected String errorPage;
+   protected String defaultPage;
+   protected RE loginSubmitRE;
+   protected List patternList;
+
+   private static final String FORM_USERNAME = "j_username";
+   private static final String FORM_PASSWORD = "j_password";
+   private static final String FORM_SUBMIT_PATTERN = ".*/j_security_check";
+
+   /**
+    * Initialize the SecurityFilter.
+    *
+    * @param config filter configuration object
+    */
+   public void init(FilterConfig config) {
+      this.config = config;
+      try {
+         // login submit RE
+         loginSubmitRE = new RE(new RECompiler().compile(FORM_SUBMIT_PATTERN));
+
+         // parse config file
+         String configFile = config.getInitParameter(CONFIG_FILE_KEY);
+         if (configFile == null) {
+            configFile = DEFAULT_CONFIG_FILE;
+         }
+         URL configURL = config.getServletContext().getResource(configFile);
+         String validate = config.getInitParameter(VALIDATE_KEY);
+         SecurityConfig securityConfig = new SecurityConfig(TRUE.equalsIgnoreCase(validate));
+         securityConfig.loadConfig(configURL);
+
+         // get config values
+         realm = securityConfig.getRealm();
+         errorPage = securityConfig.getErrorPage();
+         loginPage = securityConfig.getLoginPage();
+         defaultPage = securityConfig.getDefaultPage();
+
+         // create pattern list
+         patternList = new ArrayList();
+         MatchableURLPatternFactory patternFactory = new MatchableURLPatternFactory();
+         int order = 1;
+         List constraints = securityConfig.getSecurityConstraints();
+         for (Iterator cIter = constraints.iterator(); cIter.hasNext();) {
+            SecurityConstraint constraint = (SecurityConstraint) cIter.next();
+            for (Iterator rIter = constraint.getWebResourceCollections().iterator(); rIter.hasNext();) {
+               WebResourceCollection resourceCollection = (WebResourceCollection) rIter.next();
+               for (Iterator pIter = resourceCollection.getURLPatterns().iterator(); pIter.hasNext();) {
+                  MatchableURLPattern pattern = patternFactory.createURLPatternMatcher(
+                     (String) pIter.next(),
+                     constraint,
+                     resourceCollection,
+                     order++
+                  );
+                  patternList.add(pattern);
+               }
+            }
+         }
+         Collections.sort(patternList);
+
+      } catch (RESyntaxException rese) {
+         System.err.println("invalid regular expression pattern: " + rese);
+      } catch (java.io.IOException ioe) {
+         System.err.println("unable to parse input: " + ioe);
+      } catch (org.xml.sax.SAXException se) {
+         System.err.println("unable to parse input: " + se);
+      }
+   }
+
+   /**
+    * Destroy the filter, releasing resources.
+    */
+   public void destroy() {
+   }
+
+   /**
+    * Set the filter configuration, included for WebLogic 6 compatibility.
+    *
+    * @param config filter configuration object
+    */
+   public void setFilterConfig(FilterConfig config) {
+      init(config);
+   }
+
+   /**
+    * Get the filter config object, included for WebLogic 6 compatibility.
+    */
+   public FilterConfig getFilterConfig() {
+      return config;
+   }
+
+   /**
+    * Perform filtering operation, and optionally pass the request down the chain.
+    *
+    * @param request the current request
+    * @param response the current response
+    * @param chain request handler chain
+    * @exception IOException
+    * @exception ServletException
+    */
+   public void doFilter(
+      ServletRequest request,
+      ServletResponse response,
+      FilterChain chain
+   ) throws IOException, ServletException {
+
+      HttpServletRequest hReq = (HttpServletRequest) request;
+      HttpServletResponse hRes = (HttpServletResponse) response;
+      SecurityRequestWrapper wrappedRequest;
+
+      // if the request has already been wrapped by the filter, pass it through unchecked
+      if (request instanceof SecurityRequestWrapper) {
+         wrappedRequest = (SecurityRequestWrapper) request;
+      } else {
+         // extract the request URL portion that needs to be checked
+         String requestURL = hReq.getRequestURI();
+         // remove the contextPath
+         requestURL = requestURL.substring(hReq.getContextPath().length());
+
+         String pathInfo = hReq.getPathInfo();
+         if ("/".equals(requestURL) && pathInfo != null) {
+            requestURL = pathInfo;
+         }
+
+         // get posted parameter map, if any (returns null if not applicable)
+         Map parameterMap = getPostedParameterMap(hReq);
+
+         // wrap request
+         wrappedRequest = new SecurityRequestWrapper(hReq, realm, parameterMap);
+
+         // check if this is a login form submittal
+         if (loginSubmitRE.match(requestURL)) {
+            processLogin(wrappedRequest, hRes);
+            return;
+         }
+
+         // check if request matches security constraint
+         MatchableURLPattern match = matchPattern(requestURL);
+
+         // check constraint, if any
+         if (match != null) {
+            // check roles
+            Collection roles = match.getSecurityConstraint().getRoles();
+            if (!roles.isEmpty()) {
+               Principal principal = wrappedRequest.getUserPrincipal();
+               if (principal == null) {
+                  // user needs to be authenticated
+                  showLogin(hReq, hRes);
+                  return;
+               } else {
+                  boolean authorized = false;
+                  for (Iterator i = roles.iterator(); i.hasNext() && !authorized;) {
+                     String role = (String) i.next();
+                     if ("*".equals(role) || realm.isUserInRole(principal, role)) {
+                        authorized = true;
+                     }
+                  }
+                  if (!authorized) {
+                     // user does not meet role constraint
+                     hRes.sendError(HttpServletResponse.SC_FORBIDDEN);
+                     return;
+                  }
+               }
+            }
+         }
+      }
+
+      // pass the request down the filter chain
+      chain.doFilter(wrappedRequest, hRes);
+   }
+
+   /**
+    * Find a match for the requested URL, if any.
+    *
+    * @param URL the URL to match
+    * @return the matching MatchableURLPattern object, or null if there is no match.
+    */
+   protected MatchableURLPattern matchPattern(String URL) {
+      // PERFORMANCE IMPROVEMENT OPPORTUNITY: cahce URL pattern matches
+      MatchableURLPattern pattern = null;
+      for (Iterator i = patternList.iterator(); i.hasNext() && (pattern == null);) {
+         MatchableURLPattern testPattern = (MatchableURLPattern) i.next();
+         if (testPattern.match(URL)) {
+            pattern = testPattern;
+         }
+      }
+      return pattern;
+   }
+
+   /**
+    * Show the login page.
+    *
+    * @param request the current request
+    * @param response the current response
+    * @exception IOException
+    * @exception ServletException
+    */
+   protected void showLogin(
+      HttpServletRequest request,
+      HttpServletResponse response
+   ) throws IOException, ServletException {
+      // save continue to URL
+      setContinueToURL(request);
+      // if this is a post, save request parameters
+      if (request.getMethod().equalsIgnoreCase("POST")) {
+         setIncludePostedParametersForThisURL(request);
+      }
+      // forward to login page
+      request.getRequestDispatcher(loginPage).forward(request, response);
+   }
+
+   /**
+    * Process a login form submittal.
+    *
+    * @param request the current request
+    * @param response the current response
+    * @exception IOException
+    * @exception ServletException
+    */
+   protected void processLogin(
+      SecurityRequestWrapper request,
+      HttpServletResponse response
+   ) throws IOException, ServletException {
+      String username = request.getParameter(FORM_USERNAME);
+      String password = request.getParameter(FORM_PASSWORD);
+      Principal principal = realm.authenticate(username, password);
+      if (principal != null) {
+         // login successful
+         request.setUserPrincipal(principal);
+         String continueToURL = getAndClearContinueToURL(request);
+         response.sendRedirect(continueToURL);
+      } else {
+         // login failed, set response status and forward to error page
+         response.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
+         request.getRequestDispatcher(errorPage).forward(request, response);
+      }
+   }
+
+   /**
+    * Get the URL to continue to after successful login from the session, and then remove it from the session.
+    *
+    * @param request the current request
+    */
+   protected String getAndClearContinueToURL(HttpServletRequest request) {
+      HttpSession session = request.getSession(true);
+      String continueToURL = (String) session.getAttribute(CONTINUE_TO_URL);
+      if (continueToURL == null) {
+         return request.getContextPath() + defaultPage;
+      } else {
+         session.removeAttribute(CONTINUE_TO_URL);
+         return continueToURL;
+      }
+   }
+
+   /**
+    * Save the current URL and POSTed parameters.
+    *
+    * @param request the current request
+    */
+   protected void setIncludePostedParametersForThisURL(HttpServletRequest request) {
+      HttpSession session = request.getSession(true);
+      session.setAttribute(SecurityFilter.POSTED_PARAM_URL, request.getRequestURL().toString());
+      session.setAttribute(SecurityFilter.POSTED_PARAM_MAP, request.getParameterMap());
+   }
+
+   /**
+    * If this request matches the one we saved POSTed parameters, return a map of those parameters and remove this
+    * associated information (URL + parameter map) from the session).
+    *
+    * @param request the current request
+    * @return usually null, but when the request matches the posted URL that initiated the login sequence a map
+    * of the request parameters from the original post is returned
+    */
+   protected Map getPostedParameterMap(HttpServletRequest request) {
+      HttpSession session = request.getSession(true);
+      String postedURL = (String) session.getAttribute(SecurityFilter.POSTED_PARAM_URL);
+      if (postedURL != null && postedURL.equals(request.getRequestURL().toString())) {
+         // this is a request for the post that caused the login,
+         // return the map of posted params and remove it from the session
+         Map map = (Map) session.getAttribute(SecurityFilter.POSTED_PARAM_MAP);
+         session.removeAttribute(SecurityFilter.POSTED_PARAM_URL);
+         session.removeAttribute(SecurityFilter.POSTED_PARAM_MAP);
+         return map;
+      } else {
+         return null;
+      }
+   }
+
+   /**
+    * Save the current URL in the session so that we can redirect to this URL upon successful login.
+    * This method will not save the URL if it matches the login page, login error page, or login submit URL.
+    *
+    * @param request the current HttpServletRequest
+    */
+   protected void setContinueToURL(HttpServletRequest request) {
+      // only save if it isn't the login page, login error page, or the login submit URL
+      String currentURL = request.getServletPath();
+      if (
+         !loginSubmitRE.match(currentURL)
+         && !loginPage.equals(currentURL)
+         && !errorPage.equals(currentURL)
+      ) {
+         StringBuffer continueToURL = new StringBuffer(request.getRequestURI());
+
+         String queryString = request.getQueryString();
+         if (queryString != null) {
+            continueToURL.append("?" + queryString);
+         }
+         request.getSession().setAttribute(CONTINUE_TO_URL, continueToURL.toString());
+      }
+   }
+}
+
+// ------------------------------------------------------------------------
+// EOF
\ No newline at end of file
diff --git a/src/share/org/securityfilter/filter/SecurityRequestWrapper.java b/src/share/org/securityfilter/filter/SecurityRequestWrapper.java
new file mode 100644 (file)
index 0000000..b4358a9
--- /dev/null
@@ -0,0 +1,235 @@
+/*
+ * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/filter/SecurityRequestWrapper.java,v 1.1 2002/08/08 13:20:48 maxcooper Exp $
+ * $Revision: 1.1 $
+ * $Date: 2002/08/08 13:20:48 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+package org.securityfilter.filter;
+
+import org.securityfilter.realm.SecurityRealmInterface;
+
+import javax.servlet.ServletInputStream;
+import javax.servlet.ServletRequest;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import java.io.IOException;
+import java.security.Principal;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * SecurityRequestWrapper
+ *
+ * @author Max Cooper (max@maxcooper.com)
+ * @author Torgeir Veimo (torgeir@pobox.com)
+ * @version $Revision: 1.1 $ $Date: 2002/08/08 13:20:48 $
+ */
+public class SecurityRequestWrapper extends HttpServletRequestWrapper {
+   public static final String PRINCIPAL_SESSION_KEY = SecurityRequestWrapper.class.getName() + ".PRINCIPAL";
+
+   private HttpServletRequest request;
+   private SecurityRealmInterface realm;
+   private Map postedParameterMap;
+
+   /**
+    * Construct a new SecurityRequestWrapper.
+    *
+    * @param request the request to wrap
+    * @param realm the SecurityRealmInterface implementation
+    * @param postedParameterMap map of name-value pairs to present as request parameters (POSTed params from a previous
+    * request)
+    */
+   public SecurityRequestWrapper(HttpServletRequest request, SecurityRealmInterface realm, Map postedParameterMap) {
+      super(request);
+      this.request = request;
+      this.realm = realm;
+      this.postedParameterMap = postedParameterMap;
+   }
+
+   /**
+    * Get a parameter value by name. If multiple values are available, the first value is returned.
+    *
+    * @param s parameter name
+    */
+   public String getParameter(String s) {
+      if (postedParameterMap == null) {
+         return request.getParameter(s);
+      } else {
+         String value = request.getParameter(s);
+         if (value == null) {
+            String[] valueArray = (String[]) postedParameterMap.get(s);
+            if (valueArray != null) {
+               value = valueArray[0];
+            }
+         }
+         return value;
+      }
+   }
+
+   /**
+    * Get a map of parameter values for this request.
+    */
+   public Map getParameterMap() {
+      if (postedParameterMap == null) {
+         return request.getParameterMap();
+      } else {
+         Map map = new HashMap(postedParameterMap);
+         map.putAll(request.getParameterMap());
+         return Collections.unmodifiableMap(map);
+      }
+   }
+
+   /**
+    * Get an enumeration of paramaeter names for this request.
+    */
+   public Enumeration getParameterNames() {
+      if (postedParameterMap == null) {
+         return request.getParameterNames();
+      } else {
+         return Collections.enumeration(getParameterMap().keySet());
+      }
+   }
+
+   /**
+    * Get an array of values for a parameter.
+    *
+    * @param s parameter name
+    */
+   public String[] getParameterValues(String s) {
+      if (postedParameterMap == null) {
+         return request.getParameterValues(s);
+      } else {
+         String[] values = request.getParameterValues(s);
+         if (values == null) {
+            values = (String[]) postedParameterMap.get(s);
+         }
+         return values;
+      }
+   }
+
+   /**
+    * Set the request that is to be wrapped.
+    *
+    * @param request wrap this request
+    */
+   public void setRequest(ServletRequest request) {
+      super.setRequest(request);
+      this.request = (HttpServletRequest) request;
+   }
+
+   /**
+    * Check if a user is in a role.
+    *
+    * @param role name of role to check
+    */
+   public boolean isUserInRole(String role) {
+      return realm.isUserInRole(getUserPrincipal(), role);
+   }
+
+   /**
+    * Get the remote user's login name
+    */
+   public String getRemoteUser() {
+      String username = null;
+      Principal principal = getUserPrincipal();
+      if (principal != null) {
+         username = principal.getName();
+      }
+      return username;
+   }
+
+   /**
+    * Get a Principal object for the current user.
+    */
+   public Principal getUserPrincipal() {
+      return (Principal) request.getSession().getAttribute(PRINCIPAL_SESSION_KEY);
+   }
+
+   /**
+    * This method is provided to restore functionality of this method in case the wrapper class we are extending
+    * has disabled it. This method is needed to process multi-part requests downstream, and it appears that some
+    * wrapper implementations just return null. WebLogic 6.1.2.0 is one such implementation.
+    *
+    * @exception IOException
+    */
+   public ServletInputStream getInputStream() throws IOException {
+      ServletInputStream stream = super.getInputStream();
+      if (stream == null) {
+         stream = request.getInputStream();
+      }
+      return stream;
+   }
+
+   /**
+    * Set the username of the current user.
+    * WARNING: Calling this method will set the user for this session -- authenticate the user before calling
+    * this method.
+    *
+    * @param username the login name of the remote user for this session
+    */
+   public void setUserPrincipal(Principal principal) {
+      request.getSession().setAttribute(PRINCIPAL_SESSION_KEY, principal);
+   }
+}
+
+// ------------------------------------------------------------------------
+// EOF
\ No newline at end of file
diff --git a/src/share/org/securityfilter/realm/SecurityRealmBase.java b/src/share/org/securityfilter/realm/SecurityRealmBase.java
new file mode 100644 (file)
index 0000000..81580e6
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/realm/Attic/SecurityRealmBase.java,v 1.1 2002/08/08 13:20:48 maxcooper Exp $
+ * $Revision: 1.1 $
+ * $Date: 2002/08/08 13:20:48 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+package org.securityfilter.realm;
+
+import java.security.Principal;
+
+/**
+ * SecurityRealmBase - abstract security realm base class. This class insulates you from having
+ * to create or process Principal objects. You can implement a realm by implementing the two methods
+ * that neither take or return a Principal object and this class does the conversions for you.
+ *
+ * @author Max Cooper (max@maxcooper.com)
+ */
+public abstract class SecurityRealmBase implements SecurityRealmInterface {
+
+   /**
+    * Authenticate a user.
+    *
+    * Implement this method in a subclass to avoid dealing with Principal objects.
+    *
+    * @param username a username
+    * @param password a plain text password, as entered by the user
+    *
+    * @return null if the user cannot be authenticated, otherwise a Pricipal object is returned
+    */
+   public abstract boolean booleanAuthenticate(String username, String password);
+
+   /**
+    * Test for role membership.
+    *
+    * Implement this method in a subclass to avoid dealing with Principal objects.
+    *
+    * @param principal Principal object representing a user
+    * @param rolename name of a role to test for membership
+    * @return true if the user is in the role, false otherwise
+    */
+   public abstract boolean isUserInRole(String username, String rolename);
+
+   /**
+    * Authenticate a user.
+    *
+    * @param username a username
+    * @param password a plain text password, as entered by the user
+    *
+    * @return a Principal object representing the user if successful, false otherwise
+    */
+   public Principal authenticate(final String username, String password) {
+      if (booleanAuthenticate(username, password)) {
+         return new Principal() {
+            public String getName() {
+               return username;
+            }
+         };
+      } else {
+         return null;
+      }
+   }
+
+   /**
+    * Test for role membership.
+    *
+    * Use Principal.getName() to get the username from the principal object.
+    *
+    * @param principal Principal object representing a user
+    * @param rolename name of a role to test for membership
+    * @return true if the user is in the role, false otherwise
+    */
+   public boolean isUserInRole(Principal principal, String rolename) {
+      return isUserInRole(principal.getName(), rolename);
+   }
+}
+
+// ----------------------------------------------------------------------------
+// EOF
\ No newline at end of file
diff --git a/src/share/org/securityfilter/realm/SecurityRealmInterface.java b/src/share/org/securityfilter/realm/SecurityRealmInterface.java
new file mode 100644 (file)
index 0000000..03bb791
--- /dev/null
@@ -0,0 +1,102 @@
+/*
+ * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/realm/SecurityRealmInterface.java,v 1.1 2002/08/08 13:20:48 maxcooper Exp $
+ * $Revision: 1.1 $
+ * $Date: 2002/08/08 13:20:48 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+package org.securityfilter.realm;
+
+import java.security.Principal;
+
+/**
+ * SecurityRealmInterface - realm interface for SecurityFilter. Implement this interface to provide
+ * a realm implementation against which SecurityFilter can authenticate and authortize users.
+ *
+ * Typically, a project will implement this interface or adapt an existing realm implementation to this interface.
+ *
+ * @author Max Cooper (max@maxcooper.com)
+ * @version $Revision: 1.1 $ $Date: 2002/08/08 13:20:48 $
+ */
+public interface SecurityRealmInterface {
+
+   /**
+    * Authenticate a user.
+    *
+    * @param username a username
+    * @param password a plain text password, as entered by the user
+    *
+    * @return a Principal object representing the user if successful, false otherwise
+    */
+   public Principal authenticate(String username, String password);
+
+   /**
+    * Test for role membership.
+    *
+    * Use Principal.getName() to get the username from the principal object.
+    *
+    * @param principal Principal object representing a user
+    * @param rolename name of a role to test for membership
+    * @return true if the user is in the role, false otherwise
+    */
+   public boolean isUserInRole(Principal principal, String rolename);
+}
+
+// ------------------------------------------------------------------------
+// EOF
\ No newline at end of file
diff --git a/src/share/org/securityfilter/realm/adapter/CatalinaRealmAdapter.java b/src/share/org/securityfilter/realm/adapter/CatalinaRealmAdapter.java
new file mode 100644 (file)
index 0000000..595108f
--- /dev/null
@@ -0,0 +1,113 @@
+/*
+ * $Header: /cvsroot/securityfilter/securityfilter/src/share/org/securityfilter/realm/adapter/Attic/CatalinaRealmAdapter.java,v 1.1 2002/08/08 13:20:48 maxcooper Exp $
+ * $Revision: 1.1 $
+ * $Date: 2002/08/08 13:20:48 $
+ *
+ * ====================================================================
+ *
+ * The Apache Software License, Version 1.1
+ *
+ * Copyright (c) 1999 The Apache Software Foundation.  All rights
+ * reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in
+ *    the documentation and/or other materials provided with the
+ *    distribution.
+ *
+ * 3. The end-user documentation included with the redistribution, if
+ *    any, must include the following acknowlegement:
+ *       "This product includes software developed by the
+ *        Apache Software Foundation (http://www.apache.org/)."
+ *    Alternately, this acknowlegement may appear in the software itself,
+ *    if and wherever such third-party acknowlegements normally appear.
+ *
+ * 4. The names "The Jakarta Project", "Tomcat", and "Apache Software
+ *    Foundation" must not be used to endorse or promote products derived
+ *    from this software without prior written permission. For written
+ *    permission, please contact apache@apache.org.
+ *
+ * 5. Products derived from this software may not be called "Apache"
+ *    nor may "Apache" appear in their names without prior written
+ *    permission of the Apache Group.
+ *
+ * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR
+ * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+ * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ * ====================================================================
+ *
+ * This software consists of voluntary contributions made by many
+ * individuals on behalf of the Apache Software Foundation.  For more
+ * information on the Apache Software Foundation, please see
+ * <http://www.apache.org/>.
+ *
+ * [Additional notices, if required by prior licensing conditions]
+ *
+ */
+
+package org.securityfilter.realm.adapter;
+
+import org.apache.catalina.Realm;
+import org.securityfilter.realm.SecurityRealmInterface;
+
+import java.security.Principal;
+
+/**
+ * CatalinaRealmAdapter - adapts a Catalina Realm for use with the securityfilter
+ *
+ * @author Max Cooper (max@maxcooper.com)
+ */
+public class CatalinaRealmAdapter implements SecurityRealmInterface {
+   private Realm realm;
+
+   /**
+    * Set the Catalina Realm that we are to adapt.
+    */
+   public void setRealm(Object realm) {
+      this.realm = (Realm) realm;
+   }
+
+   /**
+    * Authenticate a user.
+    *
+    * @param username a username
+    * @param password a plain text password, as entered by the user
+    *
+    * @return a Principal object representing the user if successful, false otherwise
+    */
+   public Principal authenticate(String username, String password) {
+      return realm.authenticate(username, password);
+   }
+
+   /**
+    * Test for role membership.
+    *
+    * Use Principal.getName() to get the username from the principal object.
+    *
+    * @param principal Principal object representing a user
+    * @param rolename name of a role to test for membership
+    * @return true if the user is in the role, false otherwise
+    */
+   public boolean isUserInRole(Principal principal, String rolename) {
+      return realm.hasRole(principal, rolename);
+   }
+}
+
+// ----------------------------------------------------------------------------
+// EOF
\ No newline at end of file
diff --git a/web/blank/WEB-INF/securityfilter-config.xml b/web/blank/WEB-INF/securityfilter-config.xml
new file mode 100644 (file)
index 0000000..e4ebe43
--- /dev/null
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<!DOCTYPE securityfilter-config PUBLIC
+    "-//SecurityFilter.org//DTD Security Filter Configuration//EN"
+    "http://www.securityfilter.org/dtd/securityfilter-config_1_0.dtd">
+
+<securityfilter-config>
+
+   <security-constraint>
+      <web-resource-collection>
+         <web-resource-name></web-resource-name>
+         <url-pattern></url-pattern>
+      </web-resource-collection>
+      <auth-constraint>
+         <role-name></role-name>
+      </auth-constraint>
+   </security-constraint>
+
+   <login-config>
+      <form-login-config>
+         <form-login-page></form-login-page>
+         <form-error-page></form-error-page>
+         <form-default-page></form-default-page>
+      </form-login-config>
+   </login-config>
+
+   <realm className="">
+      <realm-param name="" value="" />
+   </realm>
+
+</securityfilter-config>
\ No newline at end of file
diff --git a/web/blank/WEB-INF/web.xml b/web/blank/WEB-INF/web.xml
new file mode 100644 (file)
index 0000000..d181163
--- /dev/null
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+
+<!DOCTYPE web-app PUBLIC
+   "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+   "http://java.sun.com/dtd/web-app_2_3.dtd">
+
+<web-app>
+
+   <filter>
+      <filter-name>Security Filter</filter-name>
+      <filter-class>org.securityfilter.filter.SecurityFilter</filter-class>
+      <init-param>
+         <param-name>config</param-name>
+         <param-value>/WEB-INF/securityfilter-config.xml</param-value>
+         <description>Configuration file location (this is the default value)</description>
+      </init-param>
+      <init-param>
+         <param-name>validate</param-name>
+         <param-value>true</param-value>
+         <description>Validate config file if set to true</description>
+      </init-param>
+   </filter>
+
+   <!-- map all requests to the SecurityFilter, control what it does with configuration settings -->
+   <filter-mapping>
+      <filter-name>Security Filter</filter-name>
+      <url-pattern>/*</url-pattern>
+   </filter-mapping>
+
+</web-app>
diff --git a/web/catalina-example/WEB-INF/securityfilter-config.xml b/web/catalina-example/WEB-INF/securityfilter-config.xml
new file mode 100644 (file)
index 0000000..1dc48ad
--- /dev/null
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<!DOCTYPE securityfilter-config PUBLIC
+    "-//SecurityFilter.org//DTD Security Filter Configuration//EN"
+    "http://www.securityfilter.org/dtd/securityfilter-config_1_0.dtd">
+
+<securityfilter-config>
+
+   <security-constraint>
+      <web-resource-collection>
+         <web-resource-name>Secure Page</web-resource-name>
+         <url-pattern>/securePage.jsp</url-pattern>
+      </web-resource-collection>
+      <auth-constraint>
+         <role-name>inthisrole</role-name>
+      </auth-constraint>
+   </security-constraint>
+
+   <security-constraint>
+      <web-resource-collection>
+         <web-resource-name>Secure page that the example user is not authorized to view</web-resource-name>
+         <url-pattern>/forbiddenPage.jsp</url-pattern>
+      </web-resource-collection>
+      <auth-constraint>
+         <role-name>notinthisrole</role-name>
+      </auth-constraint>
+   </security-constraint>
+
+   <login-config>
+      <form-login-config>
+         <form-login-page>/loginForm.jsp</form-login-page>
+         <form-error-page>/loginError.jsp</form-error-page>
+         <form-default-page>/index.jsp</form-default-page>
+      </form-login-config>
+   </login-config>
+
+   <!-- start with a Catalina realm adapter to wrap the Catalina realm definied below -->
+   <realm className="org.securityfilter.realm.adapter.CatalinaRealmAdapter" />
+
+   <!-- this is a Catalina realm that will be adapted to the securityfilter by the realm defined above -->
+   <realm className="org.securityfilter.catalina.TrivialCatalinaRealm">
+      <realm-param name="exampleProperty" value="it works!" />
+   </realm>
+
+</securityfilter-config>
\ No newline at end of file
diff --git a/web/example/WEB-INF/securityfilter-config.xml b/web/example/WEB-INF/securityfilter-config.xml
new file mode 100644 (file)
index 0000000..b4f5a5b
--- /dev/null
@@ -0,0 +1,41 @@
+<?xml version="1.0" encoding="ISO-8859-1"?>
+
+<!DOCTYPE securityfilter-config PUBLIC
+    "-//SecurityFilter.org//DTD Security Filter Configuration//EN"
+    "http://www.securityfilter.org/dtd/securityfilter-config_1_0.dtd">
+
+<securityfilter-config>
+
+   <security-constraint>
+      <web-resource-collection>
+         <web-resource-name>Secure Page</web-resource-name>
+         <url-pattern>/securePage.jsp</url-pattern>
+      </web-resource-collection>
+      <auth-constraint>
+         <role-name>inthisrole</role-name>
+      </auth-constraint>
+   </security-constraint>
+
+   <security-constraint>
+      <web-resource-collection>
+         <web-resource-name>Secure page that the example user is not authorized to view</web-resource-name>
+         <url-pattern>/forbiddenPage.jsp</url-pattern>
+      </web-resource-collection>
+      <auth-constraint>
+         <role-name>notinthisrole</role-name>
+      </auth-constraint>
+   </security-constraint>
+
+   <login-config>
+      <form-login-config>
+         <form-login-page>/loginForm.jsp</form-login-page>
+         <form-error-page>/loginError.jsp</form-error-page>
+         <form-default-page>/index.jsp</form-default-page>
+      </form-login-config>
+   </login-config>
+
+   <realm className="org.securityfilter.example.TrivialSecurityRealm">
+      <realm-param name="exampleProperty" value="it works!" />
+   </realm>
+
+</securityfilter-config>
\ No newline at end of file
diff --git a/web/share/WEB-INF/web.xml b/web/share/WEB-INF/web.xml
new file mode 100644 (file)
index 0000000..a094913
--- /dev/null
@@ -0,0 +1,45 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+
+<!DOCTYPE web-app PUBLIC
+   "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
+   "http://java.sun.com/dtd/web-app_2_3.dtd">
+
+<web-app>
+
+   <filter>
+      <filter-name>Security Filter</filter-name>
+      <filter-class>org.securityfilter.filter.SecurityFilter</filter-class>
+      <init-param>
+         <param-name>config</param-name>
+         <param-value>/WEB-INF/securityfilter-config.xml</param-value>
+         <description>Configuration file location (this is the default value)</description>
+      </init-param>
+      <init-param>
+         <param-name>validate</param-name>
+         <param-value>true</param-value>
+         <description>Validate config file if set to true</description>
+      </init-param>
+   </filter>
+
+   <!-- map all requests to the SecurityFilter, control what it does with configuration settings -->
+   <filter-mapping>
+      <filter-name>Security Filter</filter-name>
+      <url-pattern>/*</url-pattern>
+   </filter-mapping>
+
+   <!-- make the session time-out after one minute -->
+   <session-config>
+      <session-timeout>1</session-timeout>
+   </session-config>
+
+   <welcome-file-list>
+      <welcome-file>/index.jsp</welcome-file>
+   </welcome-file-list>
+
+   <!-- SecurityFilter works with custom error pages -->
+   <error-page>
+      <error-code>403</error-code>
+      <location>/error/403.jsp</location>
+   </error-page>
+
+</web-app>
diff --git a/web/share/error/403.jsp b/web/share/error/403.jsp
new file mode 100644 (file)
index 0000000..12baf95
--- /dev/null
@@ -0,0 +1,10 @@
+<html>
+<head>
+<title>SecurityFilter Example Application: Forbidden</title>
+</head>
+<body>
+<h1>SecurityFilter Example Application: Forbidden</h1>
+<%@include file="/menu.jsp" %>
+Error 403: You are not authorized to view the requested resource.
+</body>
+</html>
\ No newline at end of file
diff --git a/web/share/forbiddenPage.jsp b/web/share/forbiddenPage.jsp
new file mode 100644 (file)
index 0000000..45cfd96
--- /dev/null
@@ -0,0 +1,9 @@
+<html>
+<head>
+<title>SecurityFilter Example Application: Forbidden Secure Page</title>
+</head>
+<body>
+<h1>SecurityFilter Example Application: Forbidden Secure Page</h1>
+<%@include file="/menu.jsp" %>
+Welcome <%=request.getRemoteUser()%>, you are viewing a secure page. But something went wrong because you aren't authorized to see it!</body>
+</html>
\ No newline at end of file
diff --git a/web/share/index.jsp b/web/share/index.jsp
new file mode 100644 (file)
index 0000000..35b27e8
--- /dev/null
@@ -0,0 +1,10 @@
+<html>
+<head>
+<title>SecurityFilter Example Application: Home</title>
+</head>
+<body>
+<h1>SecurityFilter Example Application: Home</h1>
+<%@include file="/menu.jsp" %>
+Welcome to the Security Filter example application. Use the menu above to navigate the site.
+</body>
+</html>
\ No newline at end of file
diff --git a/web/share/loginError.jsp b/web/share/loginError.jsp
new file mode 100644 (file)
index 0000000..7eecc0b
--- /dev/null
@@ -0,0 +1,10 @@
+<html>
+<head>
+<title>SecurityFilter Example Application: Login Error Page</title>
+</head>
+<body>
+<h1>SecurityFilter Example Application: Login Error Page</h1>
+<%@include file="/menu.jsp" %>
+Bad username/password combination, please <a href="loginForm.jsp">try again</a>.
+</body>
+</html>
\ No newline at end of file
diff --git a/web/share/loginForm.jsp b/web/share/loginForm.jsp
new file mode 100644 (file)
index 0000000..ec51c95
--- /dev/null
@@ -0,0 +1,15 @@
+<html>
+<head>
+<title>SecurityFilter Example Application: Login Form</title>
+</head>
+<body>
+<h1>SecurityFilter Example Application: Login Form</h1>
+<%@include file="/menu.jsp" %>
+Login with username=<i>username</i> and password=<i>password</i>.
+<form action="j_security_check" method="POST">
+Username: <input type="text" name="j_username" value="username"><p>
+Password: <input type="password" name="j_password" value="password"><p>
+<input type="Submit">
+</form>
+</body>
+</html>
\ No newline at end of file
diff --git a/web/share/logout.jsp b/web/share/logout.jsp
new file mode 100644 (file)
index 0000000..9709ec0
--- /dev/null
@@ -0,0 +1,12 @@
+<html>
+<head>
+<title>SecurityFilter Example Application: Logout</title>
+</head>
+<body>
+<h1>SecurityFilter Example Application: Logout</h1>
+<%@include file="/menu.jsp" %>
+<% session.invalidate(); %>
+You have been logged out of the SecurityFilter example application.<p>
+This operation was achieved with a simple call to <code>session.invalidate()</code>.
+</body>
+</html>
\ No newline at end of file
diff --git a/web/share/menu.jsp b/web/share/menu.jsp
new file mode 100644 (file)
index 0000000..3ec9a6f
--- /dev/null
@@ -0,0 +1,8 @@
+<p>
+Navigation Menu: [
+<a href="index.jsp">Home</a>
+| <a href="securePage.jsp">Secure Page</a>
+| <a href="forbiddenPage.jsp">Forbidden Secure Page</a>
+| <a href="loginForm.jsp">Direct Login</a>
+| <a href="logout.jsp">Logout</a>
+]<p>
diff --git a/web/share/securePage.jsp b/web/share/securePage.jsp
new file mode 100644 (file)
index 0000000..6a612d5
--- /dev/null
@@ -0,0 +1,9 @@
+<html>
+<head>
+<title>SecurityFilter Example Application: Secure Page</title>
+</head>
+<body>
+<h1>SecurityFilter Example Application: Secure Page</h1>
+<%@include file="/menu.jsp" %>
+Welcome <i><%=request.getRemoteUser()%></i>, you are viewing a secure page.</body>
+</html>
\ No newline at end of file