/*
 * Copyright 2002 Sun Microsystems, Inc. All rights reserved.
 * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */

/*
 * @(#)secformClient.java	1.13 02/01/12
 */

package com.sun.cts.common.tests.jspServletClient;

import com.sun.cts.util.*;
import com.sun.cts.porting.*;
import com.sun.cts.harness.*;
import java.io.*;
import java.net.*;
import java.util.*;
import javasoft.sqe.javatest.Status;
import com.sun.cts.util.WebUtil.Response;


public class secformClient extends EETest
{
    // Configurable constants:
    private String protocol = "http";
    private String hostname = null;
    private int portnum  = 0;

    private String pageBase = null;
    private String pageSec = null;
    private String pageUnprotected = null;
    private String pageGuest = null;
    private String pageRoleReverse = null;
    private String pageOne=null;
    private String pageTwo=null;
    private String pageSample=null;
    private String pageallRoles=null;

    //common for JSP and Servlet
    private String pageLogin  = "/login.jsp";
    private String pageError  = "/error.jsp";
    private String pageSecurityCheck = "/j_security_check";

    private String pageJspBase = "/jsp_secform";
    private String pageJspSec = pageJspBase + "/jspSec.jsp";
    private String pageJspUnprotected = pageJspBase + "/unprotected.jsp";
    private String pageJspGuest = pageJspBase + "/guestPage.jsp";
    private String pageJspRoleReverse = pageJspBase + "/rolereverse.jsp";
    private String pageJspOne = pageJspBase + "/One.jsp";
    private String pageJspTwo = pageJspBase + "/Two.jsp";
    private String pageJspSample = pageJspBase + "/Sample.jsp";
    private String pageJspallRoles = pageJspBase + "/allRoles.jsp";


    private String pageServletBase = "/servlet_secform";
    private String pageServletSec = pageServletBase + "/ServletSecTest";
    private String pageServletUnprotected = pageServletBase+"/UnProtectedTest";
    private String pageServletGuest = pageServletBase + "/GuestPageTest";
    private String pageServletRoleReverse = pageServletBase+"/RoleReverseTest";
    private String pageServletOne = pageServletBase + "/OneTest";
    private String pageServletTwo = pageServletBase + "/TwoTest";
    private String pageServletSample = pageServletBase + "/SampleTest";
    private String pageServletallRoles = pageServletBase + "/allRolesTest";


    private String searchFor = "The user principal is: "; // (+username)
    private String searchForGetRemoteUser = "getRemoteUser(): "; // (+username)
    private String username = "";
    private String password = "";
    private String unauthUsername = "";
    private String unauthPassword = "";
    private String ctshome = "";

    // Constants:
    private final String WebHostProp = "webServerHost";
    private final String WebPortProp = "webServerPort";
    private final String UserNameProp = "user";
    private final String PasswordProp = "password";
    private final String unauthUserNameProp = "authuser";
    private final String unauthPasswordProp = "authpassword";
    private final String ctsHomeProp = "cts_home";

    // NOTE: This should be JSESSIONID.  However, the current reference
    // implementation would fail these tests because it uses SESSIONID
    // instead.  Tom Kincaid recommended we keep SESSIONID here until
    // the RI is fixed, and then fix this test (9/15/1999) - Mark Roth (mroth).
    // 
    // I changed this to JSESSIONID even though the RI still sends SESSIONID.
    // Therefore, this test will fail until the RI is fixed (10/5/1999)
    // Mark Roth (mroth)
    private final String cookieName = "JSESSIONID";

    private String testDir = System.getProperty("user.dir");

    // Shared test variables:
    private Properties props = null;
    private String request = null;
    private WebUtil.Response response = null;
    private WebUtil.Response loginPageRequestResponse= null;
    private WebUtil.Response errorPageRequestResponse= null;
    private Hashtable cookies = null;
    private String sessionid = null;

    private CTSURL ctsurl = new CTSURL();

   /*
    *   @class.setup_props: webServerHost;
    *                       webServerPort;
    *			    user;
    *			    password;
    *			    authuser;
    *			    authpassword;
    *               cts_home;
    */
  
    public void setup(String[] args, Properties p) throws Fault
    {
        props = p;

        try {
            hostname = p.getProperty(WebHostProp);
	    portnum = Integer.parseInt(p.getProperty(WebPortProp));
	    username = p.getProperty(UserNameProp);
	    password = p.getProperty(PasswordProp);
	    unauthUsername = p.getProperty(unauthUserNameProp);
	    unauthPassword = p.getProperty(unauthPasswordProp);
        ctshome = p.getProperty(ctsHomeProp);

            TestUtil.logMsg("username: "+username);
            TestUtil.logMsg("password: "+password);

            if (args[0].equals("jsp"))
            {
                pageBase = pageJspBase;
                pageSec  = pageJspSec;
                pageGuest = pageJspGuest;
                pageUnprotected = pageJspUnprotected;
                pageRoleReverse = pageJspRoleReverse;
		pageOne = pageJspOne;
		pageTwo = pageJspTwo;
		pageSample = pageJspSample;
		pageallRoles = pageJspallRoles;

                //prefix pageJspBase to pageLogin, pageError ,pageSecurityCheck 
                pageLogin = pageJspBase+pageLogin;
                pageError = pageJspBase+pageError;
                pageSecurityCheck = pageJspBase+pageSecurityCheck;

            }
            else
            {
                pageBase = pageServletBase;
                pageSec  = pageServletSec;
                pageGuest = pageServletGuest;
                pageUnprotected = pageServletUnprotected;
                pageRoleReverse = pageServletRoleReverse;
		pageOne = pageServletOne;
		pageTwo = pageServletTwo;
		pageSample = pageServletSample;
		pageallRoles = pageServletallRoles;


                //prefix pageServletBase to pageLogin, pageError, pageSecurityCheck 
                pageLogin = pageServletBase+pageLogin;
                pageError = pageServletBase+pageError;
                pageSecurityCheck = pageServletBase+pageSecurityCheck;


            }


	} catch ( Exception e ) {
	   logErr("Error: got exception: ", e);
	} 
    }
  
    /*
     * @testName:  test1
     *
     * @assertion: Test FORM-based authentication, specified in the Java 
     *             Servlet Specification v2.2, Sec 11.5.3.  Also tests an
     *             assertion in section 11.3.
     *
     *              1. If user has not been authenticated and user attempts
     *                 to access a protected web resource, the correct login
     *                 form is returned.
     *              2. If user has not been authenticated and user attempts
     *                 to access a protected web resource, and user enters
     *                 a valid username and password, the original web resource
     *                 is returned and user is authenticated.  A call
     *                 to getRemoteUser() must return the username.
     *              3. If user has been authenticated and user is authorized
     *                 to access a protected web resource, user gets web 
     *                 resource without the need to re-authenticate.  A call
     *                 to getRemoteUser() still returns the username.
     *
     * @test_Strategy: 
     *              1. Send request to access jspSec.jsp
     *              2. Receive login page(make sure it the expected login page) 
     *              3. Send form response with username and password
     *              4. Receive jspSec.jsp (ensure principal is correct, and
     *                 ensure getRemoteUser() returns the username, and
     *		       ensure isUserInRole() is working properly)
     *              5. Re-request jspSec.jsp
     *              6. Ensure principal is still correct and getRemoteUser() 
     *                 still returns the correct username.  Also ensure 
     *		       isUserInRole() is still working properly.
     */

    public void test1() throws Fault {
        try {
	    // The first part of this test is used in test2 and test3 as 
	    // well, so the code has been moved to a helper method.
	    requestAndGetLoginPage( pageSec, 1 );

            // Send response to login form with session id cookie:
            request = pageSecurityCheck;
	    TestUtil.logMsg( "Sending request \"" + request + 
		"\" with login information." );
            Properties postData = new Properties();
            postData.setProperty( "j_username", username );
            postData.setProperty( "j_password", password );
            response = WebUtil.sendRequest( "POST",
                InetAddress.getByName( hostname ), portnum, ctsurl.getRequest(request), 
                postData, cookies );

            TestUtil.logMsg("response.statusToken:"+response.statusToken);
            TestUtil.logMsg("response.content:"+response.content);

	    // Check that the page was found (no error).
	    if( response.isError() ) {
		TestUtil.logErr( "Could not find " + request );
		throw new Fault( "test1 failed." );
	    }

            // Call followRedirect() to make sure we receive the required page
	    response = followRedirect(response,1); 

	   // Print jspSec.jsp
           TestUtil.logMsg("received response content  1: "+response.content);
            
	    // Check to make sure we are authenticated by checking the page
	    // content.  The jsp should output "The user principal is: j2ee"
	    String searchString = searchFor + username;
	    if( response.content.indexOf( searchString ) == -1 ) {
		TestUtil.logErr( "User Principal incorrect.  Page received:" );
		TestUtil.logErr( response.content );
		TestUtil.logErr( "(Should say: \"" + searchString + "\")" );
		throw new Fault( "test1 failed." );
	    }
	    TestUtil.logMsg( "User Principal correct." );

	    // Check to make sure getRemoteUser returns the user name.
	    searchString = searchForGetRemoteUser + username;
	    if( response.content.indexOf( searchString ) == -1 ) {
		TestUtil.logErr( "getRemoteUser() did not return " + 
		    username + ":" );
		TestUtil.logErr( response.content );
		TestUtil.logErr( "(Should say: \"" + searchString + "\")" );
		throw new Fault( "test1 failed." );
	    }
	    TestUtil.logMsg( "getRemoteUser() correct." );

	    // Check to make sure isUserInRole is working properly:
	    Hashtable roleCheck = new Hashtable();
	    roleCheck.put( "ADM", new Boolean( true ) );
	    roleCheck.put( "MGR", new Boolean( false ) );
	    roleCheck.put( "VP", new Boolean( false ) );
	    roleCheck.put( "EMP", new Boolean( true ) );
	    //roleCheck.put( "Administrator", new Boolean( false ) );
	    if( !checkRoles( response.content, roleCheck ) ) {
		TestUtil.logErr( "isUserInRole() does not work correctly." );
		TestUtil.logErr( "Page Received:" );
		TestUtil.logErr( response.content );
		throw new Fault( "test1 failed." );
	    }
	    TestUtil.logMsg( "isUserInRole() correct." );

	    // Now that we are authenticated, try accessing the resource again
	    // to ensure we need not go through the login page again.
	    request = pageSec;
            TestUtil.logMsg( "Re-sending request \"" + request + "\"" );
            response = WebUtil.sendRequest( "GET", 
                InetAddress.getByName( hostname ), portnum, ctsurl.getRequest(request), null,
		cookies );

	    // Check that the page was found (no error).
	    if( response.isError() ) {
		TestUtil.logErr( "Could not find " + pageSec );
		throw new Fault( "test1 failed." );
	    }

	    // Check to make sure we are still authenticated.
	    if( response.content.indexOf( searchString ) == -1 ) {
		TestUtil.logErr( "User Principal incorrect.  Page received:" );
		TestUtil.logErr( response.content );
		TestUtil.logErr( "(Should say: \"" + searchString + "\")" );
		throw new Fault( "test1 failed." );
	    }
	    TestUtil.logMsg( "User Principal still correct." );

	    // Check to make sure getRemoteUser still returns the user name.
	    searchString = searchForGetRemoteUser + username;
	    if( response.content.indexOf( searchString ) == -1 ) {
		TestUtil.logErr( "getRemoteUser() did not return " + 
		    username + " after lazy authentication:" );
		TestUtil.logErr( response.content );
		TestUtil.logErr( "(Should say: \"" + searchString + "\")" );
		throw new Fault( "test1 failed." );
	    }
	    TestUtil.logMsg( "getRemoteUser() still correct." );

	    // Check to make sure isUserInRole is still working properly:
	    if( !checkRoles( response.content, roleCheck ) ) {
		TestUtil.logErr( "isUserInRole() does not work correctly." );
		TestUtil.logErr( "Page Received:" );
		TestUtil.logErr( response.content );
		throw new Fault( "test1 failed." );
	    }
	    TestUtil.logMsg( "isUserInRole() still correct." ); 

	} catch (Exception e) {
	    TestUtil.logErr("Caught exception: " + e.getMessage());
	    e.printStackTrace();
	    throw new Fault("test1 failed: ", e);
	}
    }

    /*
     * @testName:  test2
     *
     * @assertion: Test FORM-based authentication, specified in the Java 
     *             Servlet Specification v2.2, Sec 11.5.3.
     *
     *             If user has not been authenticated and user attempts
     *             to access a protected web resource, and user enters
     *             incorrect username and password, the error page is
     *             returned.
     *
     * @test_Strategy: 
     *              1. Send request to access jspSec.jsp
     *              2. Receive login page 
     *              3. Send form response with username and incorrect password
     *              4. Receive error page 
     *                 (make sure it is the expected  error page)
     */

    public void test2() throws Fault {
	try {
	    // The first part of this test is used in test1 and test3 as 
	    // well, so the code has been moved to a helper method.
	    requestAndGetLoginPage( pageSec, 2 );

            // Send response to login form with session id cookie and username
	    // and incorrect password:
            request = pageSecurityCheck;
	    TestUtil.logMsg( "Sending request \"" + request + 
		"\" with incorrect login information." );
            Properties postData = new Properties();
            postData.setProperty( "j_username", username );
            postData.setProperty( "j_password", "incorrect" + password );
            response = WebUtil.sendRequest( "POST",
                InetAddress.getByName( hostname ), portnum, ctsurl.getRequest(request), 
                postData, cookies );
            TestUtil.logMsg("response.statusToken:"+response.statusToken);

	    // Check that the page was found (no error).
	    if( response.isError() ) {
		TestUtil.logErr( "Could not find " + request );
		throw new Fault( "test2 failed." );
	    }

            // Call followRedirect() to make sure we receive the required page
	    response = followRedirect(response,2); 
            

	    // Check to make sure the user principal is null:
	    String searchString = searchFor + "null";
	    if( response.content.indexOf( searchString ) == -1 ) {
		TestUtil.logErr( "User principal is not null in error page:" );
		TestUtil.logErr( response.content );
		throw new Fault( "test2 failed." );
	    }
	
            TestUtil.logMsg( "User Principal is null as expected." );
           

            // Request error page
	    request = pageError;
            TestUtil.logMsg( "Sending request \"" + request + "\"" );
            errorPageRequestResponse = WebUtil.sendRequest( "GET",
            InetAddress.getByName( hostname ), portnum, 
                                 ctsurl.getRequest(request), null, cookies );

            // Check that the page was found (no error).
            if( errorPageRequestResponse.isError() ) {
            	TestUtil.logErr( "Could not find " + request );
            	throw new Fault( "test2  failed." );
             }

	    //Compare the received error page with the expected error page
            // i.e Check whether 
	    //	    response.content ==errorPageRequestResponse.content
            if (response.content.equals(errorPageRequestResponse.content)){
             	TestUtil.logMsg("Received the expected error page");
	    }
            else
            {
            	TestUtil.logMsg("Received incorrect error page");
            	throw new Fault( "test2  failed." );
            }


        } catch (Exception e) {
	    TestUtil.logErr("Caught exception: " + e.getMessage());
	    e.printStackTrace();
	    throw new Fault("test2 failed: ", e);
	}
    }

    /*
     * @testName:  test3
     *
     * @assertion: Test FORM-based authentication, specified in the Java 
     *             Servlet Specification v2.2, Sec 11.5.3.
     *
     *             If user has not been authenticated and user attempts
     *             to access a protected web resource, and user enters
     *             correct username and password of a user that is 
     *             authorized to access the resource, the resource
     *             is returned (similar to test1, but uses user javajoe 
     *             instead of j2ee).  This test establishes that the javajoe
     *             user is set up properly.
     *
     * @test_Strategy: 
     *              1. Send request to access guestPage.jsp
     *              2. Receive login page
     *              3. Send form response with username(javajoe) and password
     *              4. Receive resource (check user principal)
     *  
     */
    public void test3() throws Fault {
	try {
	    // The first part of this test is used in test2 and test3 as 
	    // well, so the code has been moved to a helper method.
	    requestAndGetLoginPage( pageGuest, 3 );

            // Send response to login form with session id cookie:
            request = pageSecurityCheck;
	    TestUtil.logMsg( "Sending request \"" + request + 
		"\" with login information (as " + unauthUsername + ")." );
            Properties postData = new Properties();
            postData.setProperty( "j_username", unauthUsername );
            postData.setProperty( "j_password", unauthPassword );
            response = WebUtil.sendRequest( "POST",
                InetAddress.getByName( hostname ), portnum, ctsurl.getRequest(request), 
                postData, cookies );

	    // Check that the page was found (no error).
	    if( response.isError() ) {
		TestUtil.logErr( "Could not find " + request );
		throw new Fault( "test3 failed." );
	    }
            
            // Call followRedirect() to make sure we receive the required page
	    response = followRedirect(response,3); 

	    // Check to make sure we are authenticated by checking the page
	    // content.  The jsp should output "The user principal is: javajoe"
	    String searchString = searchFor + unauthUsername;
	    if( response.content.indexOf( searchString ) == -1 ) {
		TestUtil.logErr( "User Principal incorrect.  Page received:" );
		TestUtil.logErr( response.content );
		TestUtil.logErr( "(Should say: \"" + searchString + "\")" );
		throw new Fault( "test3 failed." );
	    }
	    TestUtil.logMsg( "User Principal correct." );
        } catch (Exception e) {
	    TestUtil.logErr("Caught exception: " + e.getMessage());
	    e.printStackTrace();
	    throw new Fault("test3 failed: ", e);
	}
    }

    /*
     * @testName:  test4
     *
     * @assertion: Test FORM-based authentication, specified in the Java 
     *             Servlet Specification v2.2, Sec 11.5.3.
     *
     *             If user has not been authenticated and user attempts
     *             to access a protected web resource, and user enters
     *             correct username and password of a user that is 
     *             not authorized to access the resource, the resource
     *             is not returned.  The authenticated user is not
     *             denied access to an unprotected page.
     *
     * @test_Strategy: 
     *              1. Send request to access jspSec.jsp
     *              2. Receive login page
     *              3. Send form response with username and password
     *              4. Receive an error (expected unauthorized error)
     *              5. Send request to access unprotected.jsp
     *              6. Receive unprotected.jsp.
     */
    public void test4() throws Fault {
	try {
	    // The first part of this test is used in test1 and test2 as 
	    // well, so the code has been moved to a helper method.
	    requestAndGetLoginPage( pageSec, 4 );

            // Send response to login form with session id cookie and username
	    // and password:
            request = pageSecurityCheck;
	    TestUtil.logMsg( "Sending request \"" + request + 
		"\" with correct login information (" + unauthUsername + ")" +
		", but incorrect authorization for this resource." );
            Properties postData = new Properties();
            postData.setProperty( "j_username", unauthUsername );
            postData.setProperty( "j_password", unauthPassword );
            response = WebUtil.sendRequest( "POST",
                InetAddress.getByName( hostname ), portnum, ctsurl.getRequest(request), 
                postData, cookies );

            if (response.statusToken.equals("302"))
            {
                // We should receive a redirection page
                if( response.location == null )
                {
                        TestUtil.logErr( "No redirection to login page received." );
                        throw new Fault( "test4 failed." );
                }

                 // Extract location from redirection and format new request:
                request = WebUtil.getRequestFromURL( response.location );
                TestUtil.logMsg("Redirect to: " + response.location );

                // Request redirected page (login page):
                TestUtil.logMsg( "Sending request \"" + request + "\"" );
                response = WebUtil.sendRequest( "GET",
                        InetAddress.getByName( hostname ), portnum, request, null,
                        cookies );
           }

           // Receive "403" or "404" error code for unauthorized access (forbidden).
           if( (response.statusToken.equals("403"))||(response.statusToken.equals("404"))) {
		TestUtil.logMsg( "Status Token "+response.statusToken);
	    	TestUtil.logMsg( "Received expected unauthorized access error" );
            }else{
              	TestUtil.logErr(
                    "Did not receive error for unauthorized access: " +
                    request );
		TestUtil.logMsg( "Status Token "+response.statusToken);
                TestUtil.logErr( "Page content:" );
                TestUtil.logErr( response.content );
                throw new Fault( "test4 failed." );
            }

	    // Request unprotected page (unprotected.jsp page):
	    request = pageUnprotected;
	    TestUtil.logMsg( "Sending request \"" + request + "\"" );
	    response = WebUtil.sendRequest( "GET",
		InetAddress.getByName( hostname ), portnum, ctsurl.getRequest(request), null, null);

	    // Check that we did not receive an error and that we did not
	    // receive a redirection:
	    if( response.isError() ) {
		TestUtil.logErr( "Error retrieving " + request );
		throw new Fault( "test4 failed." );
	    }


	    // Check that the page returned is the correct one.  The principal
	    // is not checked.
	    String searchString = searchFor;
	    if( response.content.indexOf( searchString ) == -1 ) {
		TestUtil.logErr( "Incorrect page received:" );
		TestUtil.logErr( response.content );
		TestUtil.logErr( "(Should contain: \"" + searchString + "\")" );
		throw new Fault( "test4 failed." );
	    }
	    TestUtil.logMsg( "Access to unprotected page granted." );

        } catch (Exception e) {
	    TestUtil.logErr("Caught exception: " + e.getMessage());
	    e.printStackTrace();
	    throw new Fault("test4 failed: ", e);
	}
    }

    /*
     * @testName:  test5
     *
     * @assertion: Test FORM-based authentication, specified in the Java 
     *             Servlet Specification v2.2, Sec 11.5.3.  Also tests
     *             assertions from section 11.3.
     *
     *             If user has not been authenticated and user attempts
     *             to access an unprotected web resource, the resource
     *             is returned, and the user is not forced to authenticate.
     *             Also, isUserInRole() must return false for any valid or
     *             invalid role reference.  A call to getRemoteUser() must
     *             return null.
     *
     * @test_Strategy: 
     *              1. Send request to access unprotected.jsp
     *              2. Receive unprotected.jsp
     *              3. Search the returned page for "!true!", which would
     *                 indicate that at least one call to isUserInRole 
     *                 attempted by unprotected.jsp returned true.
     *              4. Check that the call to getRemoteUser() returned null.
     */
    public void test5() throws Fault {
	try {
	    // Request restricted jsp page.
	    String request = pageUnprotected;
	    TestUtil.logMsg( "Sending request \"" + request + "\"" );
	    response = WebUtil.sendRequest( "GET", 
		InetAddress.getByName( hostname ), portnum, ctsurl.getRequest(request), null,
		null );

	    // Check that the page was found (no error).
	    if( response.isError() ) {
		TestUtil.logErr( "Could not find " + pageUnprotected );
		throw new Fault( "test5 failed." );
	    }

	    // Check that we did not receive an error and that we did not
	    // receive a redirection:
	    if( response.isError() ) {
		TestUtil.logErr( "Error retrieving " + request );
		throw new Fault( "test5 failed." );
	    }

	    // Check that the page returned is the correct one.  The principal
	    // is not checked.
	    String searchString = searchFor;
	    if( response.content.indexOf( searchString ) == -1 ) {
		TestUtil.logErr( "Incorrect page received:" );
		TestUtil.logErr( response.content );
		TestUtil.logErr( "(Should contain: \"" + searchString + "\")" );
		throw new Fault( "test5 failed." );
	    }

	    TestUtil.logMsg( "Access to unprotected page granted." );

	    // Check to see if any of the calls to isUserInRole returned true:
	    TestUtil.logMsg( "Checking isUserInRole..." );
	    searchString = "!true!";
	    if( response.content.indexOf( searchString ) != -1 ) {
		TestUtil.logErr( 
		    "At least one call to isUserInRole returned true." );
		TestUtil.logErr( "Page received:" );
		TestUtil.logErr( response.content );
		throw new Fault( "test5 failed." );
	    }

	    TestUtil.logMsg( "isUserInRole test passed." );

            // Check to make sure the call to getRemoteUser() returned null.
	    TestUtil.logMsg( "Checking getRemoteUser()..." );
	    searchString = searchForGetRemoteUser + "null";
	    if( response.content.indexOf( searchString ) == -1 ) {
		TestUtil.logErr( 
		    "A call to getRemoteUser() did not return null." );
		TestUtil.logErr( "Page received:" );
		TestUtil.logErr( response.content );
		throw new Fault( "test5 failed." );
	    }
	    TestUtil.logMsg( "getRemoteUser() test passed." );

        } catch (Exception e) {
	    TestUtil.logErr("Caught exception: " + e.getMessage());
	    e.printStackTrace();
	    throw new Fault("test5 failed: ", e);
	}
    }

    /*
     * @testName:  test6
     *
     * @assertion: Test FORM-based authentication, specified in the Java 
     *             Servlet Specification v2.2, Sec 11.5.3.  Also tests
     *             assertions from section 11.3.
     *
     *		   Given two servlets in the same application, each of
     *		   which calls isUserInRole(X), and where X is linked to
     *		   different roles in the scope of each of the servlets
     *		   (i.e. R1 for servlet 1 and R2 for servlet 2), then a user
     *		   whose identity is mapped to R1 but not R2, shall get a true 
     *		   return value from isUserInRole( X ) in servlet 1, and
     *		   a false return value from servlet 2 (a user whose
     *		   identity is mapped to R2 but not R1 should get the
     *		   inverse set of return values).
     *
     * @test_Strategy: 
     *		    Since test1 already verifies the functionality for 
     *		    isUserInRole returning true, this test needs only verify
     *		    that it should return false for the other jsp.  For this
     *		    test, MGR and ADM are swapped, so isUserInRole() should
     *		    return opposite values from test1.
     *
     *              1. Send request to access rolereverse.jsp
     *              2. Receive login page
     *              3. Send form response with username and password
     *              4. Receive resource (check isUserInRole for all known 
     *                 roles)
     */
    public void test6() throws Fault {
	try {
	    // The first part of this test is used in test2 and test3 as 
	    // well, so the code has been moved to a helper method.
	    requestAndGetLoginPage( pageRoleReverse, 6 );

            // Send response to login form with session id cookie:
            request = pageSecurityCheck;
	    TestUtil.logMsg( "Sending request \"" + request + 
		"\" with login information (as " + username + ")." );
            Properties postData = new Properties();
            postData.setProperty( "j_username", username );
            postData.setProperty( "j_password", password );
            response = WebUtil.sendRequest( "POST",
                InetAddress.getByName( hostname ), portnum, ctsurl.getRequest(request), 
                postData, cookies );

	    // Check that the page was found (no error).
	    if( response.isError() ) {
		TestUtil.logErr( "Could not find " + request );
		throw new Fault( "test6 failed." );
	    }

            // Call followRedirect() to make sure we receive the required page
	    response = followRedirect(response,6); 
            
	    // Check to make sure we are authenticated by checking the page
	    // content.  The jsp should output "The user principal is: j2ee"
	    String searchString = searchFor + username;
	    if( response.content.indexOf( searchString ) == -1 ) {
		TestUtil.logErr( "User Principal incorrect.  Page received:" );
		TestUtil.logErr( response.content );
		TestUtil.logErr( "(Should say: \"" + searchString + "\")" );
		throw new Fault( "test6 failed." );
	    }
	    TestUtil.logMsg( "User Principal correct." );

	    // Check to make sure isUserInRole is working properly:
	    Hashtable roleCheck = new Hashtable();
	    roleCheck.put( "ADM", new Boolean( false ) );
	    roleCheck.put( "MGR", new Boolean( true ) );
	    roleCheck.put( "VP", new Boolean( false ) );
	    roleCheck.put( "EMP", new Boolean( true ) );
	    //roleCheck.put( "Manager", new Boolean( false ) );
	    if( !checkRoles( response.content, roleCheck ) ) {
		TestUtil.logErr( "isUserInRole() does not work correctly." );
		TestUtil.logErr( "Page Received:" );
		TestUtil.logErr( response.content );
		throw new Fault( "test6 failed." );
	    }
	    TestUtil.logMsg( "isUserInRole() correct." );

        } catch (Exception e) {
	    TestUtil.logErr("Caught exception: " + e.getMessage());
	    e.printStackTrace();
	    throw new Fault("test6 failed: ", e);
	}
    }

    /*
     * @testName:  test7 
     *
     * @assertion: Servlet Specification v2.3, sec 9.4
     *      A special directory exists within the application hierarchy named  
     *      WEB-INF. This directory contains all things related to the 
     *      application that aren't in the document root of the application. 
     *      It is important to note that the WEB-INF node is not part of the 
     *      public document tree of the application. No file contained in the 
     *      WEB-INF directory may be served directly to a client.
     *
     * @test_Strategy:
     *              1) send a http request to WEB-INF directory
     *              2) expect 404
     *              3) repeat step 1 and 2 for the following
     *                     a) web-inf (for case insensitive platforms)
     *                     b) WEB-INF/web.xml
     *                     c) web-inf/web.xml
     *              4) based on the http return code report test status
     */
     public void test7() throws Fault {
        try {

            //Try accessing WEB-INF
	    request= pageBase+"/WEB-INF";
            TestUtil.logMsg( "Sending request \"" + request + "\"" );
            response = WebUtil.sendRequest( "GET",
                InetAddress.getByName( hostname ), portnum, 
                ctsurl.getRequest(request), null, null );

           // Receive "404" error code.
           if( response.statusToken.equals("404")) {
                TestUtil.logMsg( "Status Token "+response.statusToken);
                TestUtil.logMsg( "Received expected error code" );
            }else{
                TestUtil.logErr(
                    "Did not receive expected error code" +
                    request );
                TestUtil.logMsg( "Status Token "+response.statusToken);
                TestUtil.logErr( "Page content:" );
                TestUtil.logErr( response.content );
                throw new Fault( "test7 failed." );
            }

            //Try accessing /web-inf (for case insensitive platforms)
	    request= pageBase+"/web-inf";
            TestUtil.logMsg( "Sending request \"" + request + "\"" );
            response = WebUtil.sendRequest( "GET",
                InetAddress.getByName( hostname ), portnum, 
                ctsurl.getRequest(request), null, null );

           // Receive "404" error code.
           if( response.statusToken.equals("404")) {
                TestUtil.logMsg( "Status Token "+response.statusToken);
                TestUtil.logMsg( "Received expected error code" );
            }else{
                TestUtil.logErr(
                    "Did not receive expected error code" +
                    request );
                TestUtil.logMsg( "Status Token "+response.statusToken);
                TestUtil.logErr( "Page content:" );
                TestUtil.logErr( response.content );
                throw new Fault( "test7 failed." );
            }

            //Try accessing WEB-INF/web.xml
	    request= pageBase+"/WEB-INF/web.xml";
            TestUtil.logMsg( "Sending request \"" + request + "\"" );
            response = WebUtil.sendRequest( "GET",
                InetAddress.getByName( hostname ), portnum, 
                ctsurl.getRequest(request), null, null );

           // Receive "404" error code.
           if( response.statusToken.equals("404")) {
                TestUtil.logMsg( "Status Token "+response.statusToken);
                TestUtil.logMsg( "Received expected error code" );
            }else{
                TestUtil.logErr(
                    "Did not receive expected error code" +
                    request );
                TestUtil.logMsg( "Status Token "+response.statusToken);
                TestUtil.logErr( "Page content:" );
                TestUtil.logErr( response.content );
                throw new Fault( "test7 failed." );
            }

            //Try accessing web-inf/web.xml (for case insensitive platforms)
	    request= pageBase+"/web-inf/web.xml";
            TestUtil.logMsg( "Sending request \"" + request + "\"" );
            response = WebUtil.sendRequest( "GET",
                InetAddress.getByName( hostname ), portnum, 
                ctsurl.getRequest(request), null, null );

           // Receive "404" error code.
           if( response.statusToken.equals("404")) {
                TestUtil.logMsg( "Status Token "+response.statusToken);
                TestUtil.logMsg( "Received expected error code" );
            }else{
                TestUtil.logErr(
                    "Did not receive expected error code" +
                    request );
                TestUtil.logMsg( "Status Token "+response.statusToken);
                TestUtil.logErr( "Page content:" );
                TestUtil.logErr( response.content );
                throw new Fault( "test7 failed." );
            }

        } catch (Exception e) {
            TestUtil.logErr("Caught exception: " + e.getMessage());
            e.printStackTrace();
            throw new Fault("test7 failed: ", e);
        }
    }

    /*
     * @testName:  test8 
     *
     * @assertion: Servlet Specification v2.3, sec 9.5
     *      Web applications can be packaged and signed, using the standard 
     *      Java Archive tools, into a Web ARchive format (war) file. 
     *      When packaged into such a form, a META-INF directory will be 
     *      present which contains information useful to the Java Archive 
     *      tools. If this directory is present, the servlet container 
     *      must not allow it be served as content to a web client's request.
     *
     * @test_Strategy:
     *              1) send a http request to META-INF directory
     *              2) expect 404
     *              3) repeat step 1 and 2 for the following
     *                     a) meta-inf (for case insensitive platforms)
     *                     b) META-INF/MANIFEST.MF
     *                     c) meta-inf/manifest.mf
     *              4) based on the http return code, report test status
     */
     public void test8() throws Fault {
        try {

            //Try accessing META-INF
	    request= pageBase+"/META-INF";
            TestUtil.logMsg( "Sending request \"" + request + "\"" );
            response = WebUtil.sendRequest( "GET",
                InetAddress.getByName( hostname ), portnum, 
                ctsurl.getRequest(request), null, null );

           // Receive "404" error code.
           if( response.statusToken.equals("404")) {
                TestUtil.logMsg( "Status Token "+response.statusToken);
                TestUtil.logMsg( "Received expected error code" );
            }else{
                TestUtil.logErr(
                    "Did not receive expected error code" +
                    request );
                TestUtil.logMsg( "Status Token "+response.statusToken);
                TestUtil.logErr( "Page content:" );
                TestUtil.logErr( response.content );
                throw new Fault( "test8 failed." );
            }

            //Try accessing /meta-inf (for case insensitive platforms)
	    request= pageBase+"/meta-inf";
            TestUtil.logMsg( "Sending request \"" + request + "\"" );
            response = WebUtil.sendRequest( "GET",
                InetAddress.getByName( hostname ), portnum, 
                ctsurl.getRequest(request), null, null );

           // Receive "404" error code.
           if( response.statusToken.equals("404")) {
                TestUtil.logMsg( "Status Token "+response.statusToken);
                TestUtil.logMsg( "Received expected error code" );
            }else{
                TestUtil.logErr(
                    "Did not receive expected error code" +
                    request );
                TestUtil.logMsg( "Status Token "+response.statusToken);
                TestUtil.logErr( "Page content:" );
                TestUtil.logErr( response.content );
                throw new Fault( "test8 failed." );
            }

            //Try accessing META-INF/MANIFEST.MF
	    request= pageBase+"/META-INF/MANIFEST.MF";
            TestUtil.logMsg( "Sending request \"" + request + "\"" );
            response = WebUtil.sendRequest( "GET",
                InetAddress.getByName( hostname ), portnum, 
                ctsurl.getRequest(request), null, null );

           // Receive "404" error code.
           if( response.statusToken.equals("404")) {
                TestUtil.logMsg( "Status Token "+response.statusToken);
                TestUtil.logMsg( "Received expected error code" );
            }else{
                TestUtil.logErr(
                    "Did not receive expected error code" +
                    request );
                TestUtil.logMsg( "Status Token "+response.statusToken);
                TestUtil.logErr( "Page content:" );
                TestUtil.logErr( response.content );
                throw new Fault( "test8 failed." );
            }

            //Try accessing meta-inf/manifest.mf(for case insensitive platforms)
	    request= pageBase+"/meta-inf/manifest.mf";
            TestUtil.logMsg( "Sending request \"" + request + "\"" );
            response = WebUtil.sendRequest( "GET",
                InetAddress.getByName( hostname ), portnum, 
                ctsurl.getRequest(request), null, null );

           // Receive "404" error code.
           if( response.statusToken.equals("404")) {
                TestUtil.logMsg( "Status Token "+response.statusToken);
                TestUtil.logMsg( "Received expected error code" );
            }else{
                TestUtil.logErr(
                    "Did not receive expected error code" +
                    request );
                TestUtil.logMsg( "Status Token "+response.statusToken);
                TestUtil.logErr( "Page content:" );
                TestUtil.logErr( response.content );
                throw new Fault( "test8 failed." );
            }

        } catch (Exception e) {
            TestUtil.logErr("Caught exception: " + e.getMessage());
            e.printStackTrace();
            throw new Fault("test8 failed: ", e);
        }
    }


    /*
     * @testName:  test9
     * 
     * @assertion: URLMapping from Servlet Specification v2.3, sec 11.2
     * 
     *  1) A string beginning with a  /  character and ending with a  
     *     /*  postfix is used as a path mapping. 
     *  2) A string beginning with a  *.  prefix is used as an extension 
     *     mapping. 
     *  3) All other strings are used as exact matches onlyˇ
     *  4) A string containing only the  /  character indicates that 
     *     servlet specified by the mapping becomes the "default" servlet 
     *     of the application. In this case the servlet path is the 
     *     request URI minus the context path and the path info is null.
     *
     *
     * @test_Strategy:
     *         1) Deploy a two webcomponents One.jsp and Two.jsp
     *            exercising various mapping rules 
     *         2) Make a http request with a URL(based on the above 
     *            mapping rules)
     *         3) Make a http request with a absolute match URL.
     *         4) compare the results obtained through step 2 and 3 
     *            and declare test result
     *
     */
     public void test9() throws Fault {
        try {
            String testURL=null;
            String exactMatchURL=null;

            //This tests exercises the URL mapping rules
            //See compareURLContents() method description for more info 

            //Note: pageOne can be a JSP or Servlet 
            //   1) for JSP 
            //          pageOne = pageBase + "/One.jsp";
            //   2) for servlet 
            //          pageOne = pageBase + "/OneTest";

            //Try accessing pageOne using "/On*"
	    testURL=pageBase + "/On*";
	    exactMatchURL=pageOne; 
            compareURLContents(testURL, 9, exactMatchURL);

            //Try accessing pageOne using "/One/index.html"
	    testURL=pageBase + "/One/index.html";
	    exactMatchURL=pageOne;
            compareURLContents(testURL, 9, exactMatchURL);

            //Try accessing pageOne using "/One/*"
	    testURL=pageBase + "/One/*";
	    exactMatchURL=pageOne;
            compareURLContents(testURL, 9, exactMatchURL);

            //Note: pageTwo can be a JSP or Servlet 
            //   1) for JSP 
            //          pageTwo = pageBase + "/Two.jsp";
            //   2) for servlet 
            //          pageTwo = pageBase + "/TwoTest";

            //Try accessing pageTwo using "*.jsp"
	    testURL=pageBase + "/*.jsp";
	    exactMatchURL=pageTwo;
            compareURLContents(testURL, 9, exactMatchURL);

            //Try accessing pageTwo using "*.two"
	    testURL=pageBase + "/*.two";
	    exactMatchURL=pageTwo;
            compareURLContents(testURL, 9, exactMatchURL);


        } catch (Exception e) {
            TestUtil.logErr("Caught exception: " + e.getMessage());
            e.printStackTrace();
            throw new Fault("test9 failed: ", e);
        }
    }

    /*
     * @testName:  test10
     *
     * @assertion: Test isUserInRole(), specified in the Java
     *             Servlet Specification v2.3, Sec 12.3. 
     *
     *     The isUserInRole method expects a String rolename. In order that 
     *     this rolename can be adjusted by the application assembler, or 
     *     the deployer without having to recompile the Servlet making the call 
     *     a <security-role-ref> element should be declared in the deployment 
     *     descriptor with the <role-name> sub-element containing the rolename 
     *     passed into this call. The value of the <role-link> sub-element 
     *     is the <role-name> of the <security-role> that the programmer is 
     *     testing that the caller is mapped to or not. The container is 
     *     required to respect this mapping of <security-role-ref> to 
     *     <security-role> in this manner when determining the return value 
     *     of the call. 
     *
     *     If, however, no <security-role-ref> has been declared with 
     *     <role-name> that matches the argument to isUserInRole, the 
     *     container must default to checking the argument against the list 
     *     of <security-role>s for this web application to determine 
     *     whether the caller is mapped to the rolename passed in.
     *
     * @test_Strategy:
     *     Note: test5 and test6 verifies the first part of the assertion.
     *           This test verifies only the second part of this assertion
     *
     *     1. Send request to access Sample.jsp
     *     2. Receive login page(make sure it is the expected login page)
     *     3. Send form response with username and password
     *     4. Receive Sample.jsp (ensure principal is correct, and
     *        ensure getRemoteUser() returns the username, and
     *        ensure isUserInRole() is working properly)
     */

     public void test10() throws Fault {
        try {
            requestAndGetLoginPage( pageSample, 10 );

            // Send response to login form with session id cookie:
            request = pageSecurityCheck;
            TestUtil.logMsg( "Sending request \"" + request +
                "\" with login information." );
            Properties postData = new Properties();
            postData.setProperty( "j_username", username );
            postData.setProperty( "j_password", password );
            response = WebUtil.sendRequest( "POST",
                InetAddress.getByName( hostname ), portnum, ctsurl.getRequest(request),
                postData, cookies );

            // Check that the page was found (no error).
            if( response.isError() ) {
                TestUtil.logErr( "Could not find " + request );
                throw new Fault( "test10 failed." );
            }

            // Call followRedirect() to make sure we receive the required page
            response = followRedirect(response,10);

            // Check to make sure we are authenticated by checking the page
            // content.  The jsp should output "The user principal is: j2ee"
            String searchString = searchFor + username;
            if( response.content.indexOf( searchString ) == -1 ) {
                TestUtil.logErr( "User Principal incorrect.  Page received:" );
                TestUtil.logErr( response.content );
                TestUtil.logErr( "(Should say: \"" + searchString + "\")" );
                throw new Fault( "test10 failed." );
            }
            TestUtil.logMsg( "User Principal correct." );

            // Check to make sure getRemoteUser returns the user name.
            searchString = searchForGetRemoteUser + username;
            if( response.content.indexOf( searchString ) == -1 ) {
                TestUtil.logErr( "getRemoteUser() did not return " +
                    username + ":" );
                TestUtil.logErr( response.content );
                TestUtil.logErr( "(Should say: \"" + searchString + "\")" );
                throw new Fault( "test10 failed." );
            }
            TestUtil.logMsg( "getRemoteUser() correct." );

            // Check to make sure isUserInRole is working properly:
            Hashtable roleCheck = new Hashtable();
            roleCheck.put( "Administrator", new Boolean( true ) );
            if( !checkRoles( response.content, roleCheck ) ) {
                TestUtil.logErr( "isUserInRole() does not work correctly." );
                TestUtil.logErr( "Page Received:" );
                TestUtil.logErr( response.content );
                throw new Fault( "test10 failed." );
            }
            TestUtil.logMsg( "isUserInRole() correct." );

        } catch (Exception e) {
            TestUtil.logErr("Caught exception: " + e.getMessage());
            e.printStackTrace();
            throw new Fault("test10 failed: ", e);
        }
    }

    /*
     * @testName:  test11
     *
     * @assertion: Servlet Specification v2.3, sec 13.2 DTD
     *      The auth-constraint element indicates the user roles that 
     *      should be permitted access to this resource collection. The role 
     *      used here must either in a security-role-ref element, 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.
     *
     * @test_Strategy:
     *      Configure allRoles.jsp to be accessible by allRoles (*)
     *
     *      1) Try accesing allRoles.jsp as the following user
     *           a) j2ee
     *           b) javajoe
     *      2) Based on the http reply, report test status 
     * 
     *
     */

     public void test11() throws Fault {
        try {

            // Access allRoles.jsp as user "j2ee" 
            TestUtil.logMsg( "\nAccessing allRoles.jsp as user j2ee");
            requestAndGetLoginPage( pageallRoles, 11 );
            request = pageSecurityCheck;
            TestUtil.logMsg( "Sending request \"" + request +
                "\" with login information." );
            Properties postData = new Properties();
            postData.setProperty( "j_username", username );
            postData.setProperty( "j_password", password );
            response = WebUtil.sendRequest( "POST",
                InetAddress.getByName( hostname ), portnum, 
                ctsurl.getRequest(request), postData, cookies );

            // Check that the page was found (no error).
            if( response.isError() ) {
                TestUtil.logErr( "Could not find " + request );
                throw new Fault( "test11 failed." );
            }

            // Call followRedirect() to make sure we receive the required page
            response = followRedirect(response,11);
            TestUtil.logMsg( "Successfully accessed allRoles.jsp as user j2ee");

            // Access allRoles.jsp as user "javajoe" 
            TestUtil.logMsg( "\nAccessing allRoles.jsp as user javajoe");
            requestAndGetLoginPage( pageallRoles, 11 );
            request = pageSecurityCheck;
            TestUtil.logMsg( "Sending request \"" + request +
                "\" with login information." );
            postData = new Properties();
            postData.setProperty( "j_username", unauthUsername );
            postData.setProperty( "j_password", unauthPassword );
            response = WebUtil.sendRequest( "POST",
                InetAddress.getByName( hostname ), portnum, 
                ctsurl.getRequest(request), postData, cookies );

            // Check that the page was found (no error).
            if( response.isError() ) {
                TestUtil.logErr( "Could not find " + request );
                throw new Fault( "test11 failed." );
            }

            // Call followRedirect() to make sure we receive the required page
            response = followRedirect(response,11);

            TestUtil.logMsg( "Successfully accessed allRoles.jsp as user javajoe");

        } catch (Exception e) {
            TestUtil.logErr("Caught exception: " + e.getMessage());
            e.printStackTrace();
            throw new Fault("test11 failed: ", e);
        }
    }

    /*
     * @testName:  test12
     *
     * @assertion: Servlet Specification v2.3, sec 13.2 (DTD)
     *     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.
     *
     * @test_Strategy:
     *      1) Do not specify any HTTP methods in the security constraints of
     *         Sample.jsp 
     *
     *      2) Access Sample.jsp using HTTP methods GET, HEAD, POST, 
     *         DELETE and PUT.
     * 
     *      3) If Sample.jsp is accessible with all of the above HTTP methods
     *         then declare test successfull otherwise report test failure
     * 
     *      Note: test12 is ONLY for JSP Area
     *
     */
     public void test12() throws Fault {
        try {
            // Access Sample.jsp using HTTP method POST 
            TestUtil.logMsg("\nAccessing pageSample Using HTTP method POST");
            requestAndGetLoginPage( pageSample, 12 );
            request = pageSecurityCheck;
            TestUtil.logMsg( "Sending request \"" + request +
                "\" with login information." );
            Properties postData = new Properties();
            postData.setProperty( "j_username", username );
            postData.setProperty( "j_password", password ); 
            response = WebUtil.sendRequest( "POST",
                InetAddress.getByName( hostname ), portnum, 
                ctsurl.getRequest(request), postData, cookies );

            // Check that the page was found (no error).
            if( response.isError() ) {
                TestUtil.logErr( "Could not find " + request );
                throw new Fault( "test12 failed." );
            }

            // Call followRedirect() to make sure we receive the required page
            response = followRedirect(response,12);
            
            TestUtil.logMsg("response.content :"+response.content);
            TestUtil.logMsg( "Successfully accessed " +pageSample +" with \"POST\"" );

            // Access pageSample using HTTP method GET 
            TestUtil.logMsg( "\nAccessing pageSample Using HTTP method GET");
            response = WebUtil.sendRequest( "GET",
                InetAddress.getByName( hostname ), portnum, 
                ctsurl.getRequest(request), postData, cookies );

            // Check that the page was found (no error).
            if( response.isError() ) {
                TestUtil.logErr( "Could not find " + request );
                throw new Fault( "test12 failed." );
            }

            // Call followRedirect() to make sure we receive the required page
            response = followRedirect(response,12);

            TestUtil.logMsg("response.content :"+response.content);
            TestUtil.logMsg( "Successfully accessed " +pageSample +" with \"GET\"" );


            // Access pageSample using HTTP method HEAD 
            TestUtil.logMsg("\nAccessing pageSample Using HTTP method HEAD");
            response = WebUtil.sendRequest( "HEAD",
                InetAddress.getByName( hostname ), portnum, 
		ctsurl.getRequest(request), postData, cookies );

            // Check that the page was found (no error).
            if( response.isError() ) {
                TestUtil.logErr( "Could not find " + request );
                throw new Fault( "test12 failed." );
            }

            // Call followRedirect() to make sure we receive the required page
            response = followRedirect(response,12);

            TestUtil.logMsg("response.content :"+response.content);

            TestUtil.logMsg( "Successfully accessed " +pageSample +
                              " with \"HEAD\"" );

           // Read the contents of Sample.jsp and
            // upload it using HTTP method PUT
            FileInputStream fstream = new FileInputStream(ctshome + "/tests/jsp/sec/secform/Sample.jsp");
            int fileContentLength = fstream.available();
            byte[] byteArray = new byte[1024];
            int bytesRead = fstream.read(byteArray, 0, fileContentLength);

            //Now use HTTP method DELETE and later use http method PUT

            // Delete pageSample using HTTP method DELETE
            TestUtil.logMsg("\nDELETE "+pageSample +
                              " Using HTTP method DELETE ....");
            response = WebUtil.sendRequest( "DELETE",
                InetAddress.getByName( hostname ), portnum,
                ctsurl.getRequest(request), postData, cookies );

            addNewCookies(cookies, response.cookies);

            // Check that the page was found (no error).
            if( response.isError() ) {
                TestUtil.logErr( "Could not find " + request );
                throw new Fault( "test12 failed." );
            }
            TestUtil.logMsg("response.content :"+response.content);
            TestUtil.logMsg( "Successfully accessed " +pageSample +
                              " with \"DELETE\"" );

            // put pageSample using HTTP method PUT
            TestUtil.logMsg("\nPUT "+pageSample +" Using HTTP method PUT ....");

            response = uploadUsingHttpMethodPUT( "PUT",
                InetAddress.getByName( hostname ), portnum,
                ctsurl.getRequest(request), byteArray, cookies,
                username, password);

            // Check that the page was found (no error).
            if( response.isError() ) {
                TestUtil.logErr( "Could not find " + request );
                throw new Fault( "test12 failed." );
            }
            TestUtil.logMsg("response.content :"+response.content);
            TestUtil.logMsg("response.statusToken :"+response.statusToken);
            TestUtil.logMsg( "uploaded "+pageSample+ "using HTTP method PUT" );


       } catch (Exception e) {
            TestUtil.logErr("Caught exception: " + e.getMessage());
            e.printStackTrace();
            throw new Fault("test12 failed: ", e);
        }
    }


    /*
     * @testName:  test13
     *
     * @assertion: Servlet Specification v2.3, sec 12.2
     *     The security model does not apply when a servlet uses
     *     the RequestDispatcher to invoke a static resource or servlet
     *     using a forward or an include.
     *
     *
     * @test_Strategy:
     *  
     *      1) Configure two servlets (IncludedServlet and ForwardedServlet)
     *         to be accessible only by administrator.
     *     
     *      2) Configure ControlServlet to be accessible by everyone 
     *         (i.e no security constraints for ControlServlet)
     *
     *      3) Now as a unauthenticated user access ForwardedServlet
     *         and IncludedServlet from ControlServlet
     * 
     *         ControlServlet ===>ForwardedServlet===>IncludedServlet
     *
     *         i.e  3.1) From a ControlServlet access ForwardedServlet 
     *                   through dispatcher's forward  method.
     *
     *              3.2) From the ForwardedServlet access/include  
     *                   IncludedServlet through Request dispatcher's 
     *                   include method
     *
     *      4) If the servlets(ForwardedServlet and IncludedServlet) are
     *         accessible report the test success otherwise report  test
     *         failure
     *
     *      Note: test13 is ONLY for SERVLET Area
     *
     */
     public void test13() throws Fault {
        try {

            request = pageServletBase + "/ControlServlet";

            // Access ControlServlet"
            TestUtil.logMsg( "\nAccessing ControlServlet");
            TestUtil.logMsg( "Sending request " + request);
            response = WebUtil.sendRequest( "POST",
                InetAddress.getByName( hostname ), portnum,
                ctsurl.getRequest(request), null, null );
            TestUtil.logMsg("response.content 1:"+response.content);

            // Check that the page was found (no error).
            if( response.isError() ) {
                TestUtil.logErr( "Could not find " + request );
                throw new Fault( "test13 failed." );
            }

            // Call followRedirect() to make sure we receive the required page
            response = followRedirect(response,13);
            TestUtil.logMsg("response.content 2:"+response.content);
            TestUtil.logMsg( "Successfully accessed ControlServlet,"+
                               " ForwardedServlet and IncludedServlet");

        } catch (Exception e) {
            TestUtil.logErr("Caught exception: " + e.getMessage());
            e.printStackTrace();
            throw new Fault("test13 failed: ", e);
        }
    }

    /*
     * @testName:  test14
     *
     * @assertion: Test FORM-based authentication, specified in the Java
     *             Servlet Specification v2.3, Sec 12.6
     *
     *      Therefore, a servlet container is required to track
     *      authentication information at the container level (rather than
     *      at the web application level). This allows users authenticated
     *      for one web application to access other resources managed by the
     *      container permitted to the same security identity.
     *
     * @test_Strategy:
     *              1. Configure pageSec(jspSec.jsp or ServletSecTest)
     *                 and pageSample(Sample.jsp or SampleTest ) to be
     *                 accessible only by Administrator
     *              2. Send request to access jspSec.jsp
     *              3. Receive login page
     *              4. Send form response with username and password
     *              5. Receive jspSec.jsp (ensure principal is correct, and
     *                 ensure getRemoteUser() returns the username, and
     *                 ensure isUserInRole() is working properly)
     *              6. Try accessing pageSample(Sample.jsp or SampleTest) 
     *                 which is also configured to be accessible with the 
     *                 same security  identity, since we are already 
     *                 authenticated we should be able to access pageSample
     *                 without going through login page again.
     *              7. Ensure principal is still correct and getRemoteUser()
     *                 still returns the correct username.  Also ensure
     *                 isUserInRole() is still working properly.
     */

    public void test14() throws Fault {
        try {
            TestUtil.logMsg( "\nAccessing  pageSec: " + pageSec);
            requestAndGetLoginPage( pageSec, 14 );

            // Send response to login form with session id cookie:
            request = pageSecurityCheck;
            TestUtil.logMsg( "Sending request \"" + request +
                "\" with login information." );
            Properties postData = new Properties();
            postData.setProperty( "j_username", username );
            postData.setProperty( "j_password", password );
            response = WebUtil.sendRequest( "POST",
                InetAddress.getByName( hostname ), portnum, 
                ctsurl.getRequest(request), postData, cookies );

            // Check that the page was found (no error).
            if( response.isError() ) {
                TestUtil.logErr( "Could not find " + request );
                throw new Fault( "test14 failed." );
            }

            // Call followRedirect() to make sure we receive the required page
            response = followRedirect(response,14);

            // Check to make sure we are authenticated by checking the page
            // content.  The jsp should output "The user principal is: j2ee"
            String searchString = searchFor + username;
            if( response.content.indexOf( searchString ) == -1 ) {
                TestUtil.logErr( "User Principal incorrect.  Page received:" );
                TestUtil.logErr( response.content );
                TestUtil.logErr( "(Should say: \"" + searchString + "\")" );
                throw new Fault( "test14 failed." );
            }
            TestUtil.logMsg( "User Principal correct." );

            // Check to make sure getRemoteUser returns the user name.
            searchString = searchForGetRemoteUser + username;
            if( response.content.indexOf( searchString ) == -1 ) {
                TestUtil.logErr( "getRemoteUser() did not return " +
                    username + ":" );
                TestUtil.logErr( response.content );
                TestUtil.logErr( "(Should say: \"" + searchString + "\")" );
                throw new Fault( "test1 failed." );
            }
            TestUtil.logMsg( "getRemoteUser() correct." );

            // Check to make sure isUserInRole is working properly:
            Hashtable roleCheck = new Hashtable();
            roleCheck.put( "ADM", new Boolean( true ) );
            roleCheck.put( "MGR", new Boolean( false ) );
            roleCheck.put( "VP", new Boolean( false ) );
            roleCheck.put( "EMP", new Boolean( true ) );
            //roleCheck.put( "Administrator", new Boolean( false ) );
            if( !checkRoles( response.content, roleCheck ) ) {
                TestUtil.logErr( "isUserInRole() does not work correctly." );
                TestUtil.logErr( "Page Received:" );
                TestUtil.logErr( response.content );
                throw new Fault( "test14 failed." );
            }
            TestUtil.logMsg( "isUserInRole() correct." );

            // Now that we are authenticated, try accessing pageSample 
            // without going through the login page again.
            request = pageSample;
            TestUtil.logMsg( "\nAccessing pageSample :" + request );
            response = WebUtil.sendRequest( "GET",
                InetAddress.getByName( hostname ), portnum, 
                ctsurl.getRequest(request), null, cookies );

            // Check that the page was found (no error).
            if( response.isError() ) {
                TestUtil.logErr( "Could not find " + pageSec );
                throw new Fault( "test14 failed." );
            }

            // Check to make sure we are still authenticated.
            if( response.content.indexOf( searchString ) == -1 ) {
                TestUtil.logErr( "User Principal incorrect.  Page received:" );
                TestUtil.logErr( response.content );
                TestUtil.logErr( "(Should say: \"" + searchString + "\")" );
                throw new Fault( "test14 failed." );
            }
            TestUtil.logMsg( "User Principal still correct." );

            // Check to make sure getRemoteUser still returns the user name.
            searchString = searchForGetRemoteUser + username;
            if( response.content.indexOf( searchString ) == -1 ) {
                TestUtil.logErr( "getRemoteUser() did not return " +
                    username + " after lazy authentication:" );
                TestUtil.logErr( response.content );
                TestUtil.logErr( "(Should say: \"" + searchString + "\")" );
                throw new Fault( "test14 failed." );
            }
            TestUtil.logMsg( "getRemoteUser() still correct." );

        } catch (Exception e) {
            TestUtil.logErr("Caught exception: " + e.getMessage());
            e.printStackTrace();
            throw new Fault("test14 failed: ", e);
        }
    }

    /**
     * Uploads data from a byteArray to an URL.  A WebUtil.Response object 
     * is returned with the response information.
     *
     * @param method http method "PUT"
     * @param addr Address of web server
     * @param port Port of web server
     * @param req The file to request
     *     (e.g. /jsp_dep_secContextRoot/jspSec.jsp)
     * @param postData is a byteArray which contains the data to be posted
     * @param cookieList A list of cookies to send when requesting the page.
     *     null if no cookie list is to be sent.
     * @param username The username for authentication, null if no
     *     authentication required.
     * @param password The password for authentication, null if no
     *     authentication required.
     * @return WebUtil.Response object containing response information
     * @exception IOException Thrown if request could not be made
     */

    public static Response uploadUsingHttpMethodPUT( String method,
        InetAddress addr, int port, String req, byte[] postData,
        Hashtable cookieList, String username, String password )
        throws IOException
    {
        String protocol = "HTTP/1.0";
        URL requestURL;
        Socket socket = null;
        PrintWriter out = null;
        BufferedReader in = null;
        String line;
        Response response = new Response();

        try {
            requestURL = new URL( "http", addr.getHostName(), port,
                req );
            req = method + " " + req + " " + protocol;

            socket = new Socket( addr, port );

            in = new BufferedReader( new InputStreamReader(
                socket.getInputStream() ) );
            out = new PrintWriter( new OutputStreamWriter(
                socket.getOutputStream() ) );
            out.println(req);

            if( cookieList != null ) {
                // Send cookies:
                Enumeration keys = cookieList.keys();

                // Does at least one cookie exist?
                if( keys.hasMoreElements() ) {
                    String cookieString = "Cookie: ";

                    // Add each cookie to the string
                    boolean first = true;
                    while( keys.hasMoreElements() ) {
                        String key = (String)keys.nextElement();
                        String value = (String)cookieList.get( key );
                        cookieString += (first ? "" : "; ") +
                            key + "=" + value; // + "; $Path=/";
                        first = false;
                    }

                    // Write cookies:
                    out.println(cookieString);
                }
            }

            // Send authentication information if necessary:
            if( username != null ) {
                String code = WebUtil.encodeBase64( username + ":" + password );
                out.println("Authorization: Basic " + code.trim() );
            }

            // Send extra header information if we are posting.
            if( postData != null ) {
                out.println("Content-type: text/data" );
            }

            // Read the file contents from the byte array(postData)
            // and store it in a string(fileContents)
            StringBuffer content = new StringBuffer(1024);
            ByteArrayInputStream bais = new ByteArrayInputStream(postData);
            int c;
            while((c=bais.read())!=-1)
                content.append((char)c);
            String fileContents=content.toString();

            //TestUtil.logMsg("File Content: "+ fileContents);

            // If this is a post request, send post data:
            if( (postData != null) && method.toUpperCase().equals( "PUT" ) ) {
                String postString = WebUtil.encodeBase64(fileContents);

                // Skip a line:
                out.println("Content-length: " + postString.length() );
                out.println("");
                out.println(postString);
            }
            else {
                // Skip a line:
                out.println("");
            }

            out.flush();

            // Read first line and check for HTTP version and OK.
            line = in.readLine();
            if( line != null ) {

                StringTokenizer st = new StringTokenizer( line.trim() );
                response.versionToken = st.nextToken();
                response.statusToken = st.nextToken();
            }

            // Read each line of the header until we hit a blank line
            while( (line = in.readLine()) != null ) {

                // Blank line means we are done with the header:
                if( line.trim().equals( "" ) ) break;

                // Analyze special tags location and set cookie
                if( line.toLowerCase().startsWith( "location:" ) ) {
                    // This is a redirect.  Extract valuable infomration:
                    response.location = line.substring( 10 );
                }
                else if( line.toLowerCase().startsWith( "set-cookie:" ) ) {
                    // This is a cookie.  Add the cookie to the response
                    // object.
                    response.parseCookie( line );
                }
                else if( line.toLowerCase().startsWith( "www-authenticate:" )){
                    // Request to authenticate this page.
                    response.authenticationRequested = true;
                }
            }

            // The rest is content:
            while( (line = in.readLine()) != null ) {
                response.content += line + "\n";
            }

            in.close();
            out.close();
        }
       catch( MalformedURLException e ) {
            throw new IOException( "MalformedURLException: " + e.getMessage() );
        }
        catch( UnknownHostException e ) {
            throw new IOException( "UnknownHostException: " + e.getMessage() );
        }
        catch( ConnectException e ) {
            throw new IOException( "ConnectException: " + e.getMessage() );
        }

        return response;
    }

    /**
     * Outputs a single line of text to the given output stream.  Appends
     * a \r\n automatically.
     * By adding a System.out.println here, you can easily echo what is being
     * sent to the web server.
     */
    private static void send( PrintWriter out, String s ) {
        out.print( s + "\r\n" );
        //if( debugOutputRequests ) {
        //   System.out.println( "REQUEST: " + s );
        //}
    }




    /**
     * Helper method that is used in tests 1, 2 and 3.  Performs the following
     * actions:
     *
     * 1. Send request to access jspSec.jsp
     * 2. Receive redirect to login page, extract location and session id
     *    cookie
     * 3. Send request to access new location, send cookie
     * 4. Receive login page
     *
     * @param request The initial page to request
     * @param testNum The test number for correct display of
     *     error messages.
     */
    private void requestAndGetLoginPage( String request, int testNum ) 
	throws Exception 
    {
	// Request restricted jsp page.
	TestUtil.logMsg( "Sending request \"" + request + "\"" );
	response = WebUtil.sendRequest( "GET", 
	    InetAddress.getByName( hostname ), portnum, ctsurl.getRequest(request), null,
	    null );

	// Check that the page was found (no error).
	if( response.isError() ) {
	    TestUtil.logErr( "Could not find " + request );
	    throw new Fault( "test" + testNum + " failed." );
	}

        // if (response.statusToken=302)
        //    then follow redirect to get the login page

        if (response.statusToken.equals("302"))
        {
                // We should receive a redirection to the login page:
                if( response.location == null )
                {
                        TestUtil.logErr( "No redirection to login page received." );
                        throw new Fault( "test" + testNum + " failed." );
                }

                 // Extract location from redirection and format new request:
                request = WebUtil.getRequestFromURL( response.location );
                TestUtil.logMsg("Redirect to: " + response.location );

		// Extract cookies:
		cookies = response.cookies;
		sessionid = (String)response.cookies.get( cookieName );
		//TestUtil.logMsg("Session ID Cookie: " + sessionid );

		// Check to make the session id cookie is valid:
		if( (sessionid == null) || (sessionid.trim().equals( "" )) ) {
	    		TestUtil.logErr( "No sessionid cookie received." );
	    		TestUtil.logErr( "There must be a cookie named " + cookieName + 
			"." );
	    	throw new Fault( "test" + testNum + " failed." );
		}

                // Request redirected page (login page):
                TestUtil.logMsg( "Sending request \"" + request + "\"" );
                response = WebUtil.sendRequest( "GET",
                        InetAddress.getByName( hostname ), portnum, request, null,
                        cookies );

                // Check that the page was found (no error).
                if( response.isError() ) {
                        TestUtil.logErr( "Could not find " + request );
                        throw new Fault( "test" + testNum + " failed." );
                }
        }
	else
	{
		// Extract cookies:
		cookies = response.cookies;
		sessionid = (String)response.cookies.get( cookieName );
		TestUtil.logMsg("Session ID Cookie: " + sessionid );

		// Check to make the session id cookie is valid:
		if( (sessionid == null) || (sessionid.trim().equals( "" )) ) {
	    		TestUtil.logErr( "No sessionid cookie received." );
	    		TestUtil.logErr( "There must be a cookie named " + cookieName + 
			"." );
	    	throw new Fault( "test" + testNum + " failed." );
		}
	}

	request = pageLogin;

	// Request login page
	TestUtil.logMsg( "Sending request \"" + request + "\"" );
	loginPageRequestResponse = WebUtil.sendRequest( "GET",
	    InetAddress.getByName( hostname ), portnum, ctsurl.getRequest(request), null,
	    cookies );

	// Check that the page was found (no error).
	if( loginPageRequestResponse.isError() ) {
	    TestUtil.logErr( "Could not find " + request );
	    throw new Fault( "test" + testNum + " failed." );
	} 

        //Compare the received login page with the expected login page
        // i.e Check whether response.content ==loginPageRequestResponse.content 
       if (response.content.equals(loginPageRequestResponse.content))
             TestUtil.logMsg("Received the expected login form");
	else
	{
            TestUtil.logMsg("Received incorrect login form");
	    throw new Fault( "test" + testNum + " failed." );
	}


    
    }

   /**
     * Helper method that is used in test 9.  Performs the following
     * actions:
     *
     * 1. Send request to access a jsp using testURL 
     *    (for example testURL can be "/*.jsp") 
     * 2. Checks the status of the http reply  
     * 3. If the page is not accessible throw exception
     * 4. If the page is accessible, then compare the content
     *    from the testURL with the contents of exact match URL.
     *    i.e compare 
     *      1) TEST URL       : http://hostname:port/context_root/*.jsp 
     *      2) Exact match URL: http://hostname:port/context_root/foo.jsp 
     *
     *    Note: Here *.jsp is mapped to foo.jsp 
     *
     *    If the contents are same then the mapping is correct, otherwise
     *    throw exception
     *
     * @param testURL The test URL  (for example "/*.jsp")
     * @param testNum The test number for correct display of
     *     error messages.
     * @param exactMatchURL The exact match URL (for example "/foo.jsp")
     */
    private void compareURLContents( String testURL, int testNum, 
				String exactMatchURL ) throws Exception
    {
        // Request a jsp page using testURL.
        TestUtil.logMsg( "Sending request \"" + testURL + "\"" );
        response = WebUtil.sendRequest( "GET",
            InetAddress.getByName( hostname ), portnum, 
            ctsurl.getRequest(testURL), null, null );

        // Check that the page was found (no error).
        if( response.isError() ) {
            TestUtil.logErr( "Could not find " + testURL );
            throw new Fault( "test" + testNum + " failed." );
        }

        WebUtil.Response response2=null;

        // Request the jsp page using exactMatchURL.
        TestUtil.logMsg( "Sending request \"" + exactMatchURL + "\"" );
        response2 = WebUtil.sendRequest( "GET",
            InetAddress.getByName( hostname ), portnum, 
	    ctsurl.getRequest(exactMatchURL), null, null );

        // Check that the page was found (no error).
        if( response.isError() ) {
            TestUtil.logErr( "Could not find " + exactMatchURL );
            throw new Fault( "test" + testNum + " failed." );
        }

        TestUtil.logMsg( "Comparing contents of "+ testURL +
				" and " + exactMatchURL );

       //compare the contents of testURL and exactMatchURL
       if(!response.content.equals(response2.content)){
            TestUtil.logErr( "MISMATCH in contents of "+ testURL +
				" and " + exactMatchURL );
            TestUtil.logErr( "contents of "+ testURL) ;
            TestUtil.logErr( response.content) ;
            TestUtil.logErr( "contents of "+ exactMatchURL) ;
            TestUtil.logErr( response2.content) ;
            throw new Fault( "test" + testNum + " failed." );
        }else
       	    TestUtil.logMsg("Contents MATCH : correct URL mapping\n");

      
    }


    /** 
     * Helper method to check that isUserInRole is working correctly.
     * Searches the given page content for "isUserInRole( x ): !y!" for
     * each x = key in Hashtable and y = corresponding value in hashtable.
     * If all results are as expected, returns true, else returns false.
     */
    private boolean checkRoles( String content, Hashtable roleCheck ) {
	Enumeration keys = roleCheck.keys();
	boolean pass = true;

	while( pass && keys.hasMoreElements() ) {
	    String key = (String)keys.nextElement();
	    boolean expected = ((Boolean)roleCheck.get( key )).booleanValue();

	    String search = 
		"isUserInRole(\"" + key + "\"): !" + expected + "!";
	    String logMsg = "Searching for \"" + search + "\": ";

	    if( content.indexOf( search ) == -1 ) {
		pass = false;
		logMsg += "NOT FOUND!";
	    }
	    else {
		logMsg += "found.";
	    }

	    TestUtil.logMsg( logMsg );
	}

	return pass;
    }

    public void cleanup()  throws Fault {
        logMsg("cleanup");
    }

    /**
     * Helper method that is used in tests 1, 2, 3, 5 and 6.  
     * Performs the following actions:
     *
     * 1. Checks whether the response.statusToken==302
     *    if(response.statusToken==302)
     *     send request to redirected URL 
     * 2. Returns Response object 
     *
     * @param response The initial page response 
     * @param testNum The test number for correct display of
     *     error messages.
     */

    public WebUtil.Response followRedirect(WebUtil.Response response,int testNum) throws Exception {

        // if (response.statusToken=302)
	//    send request to redirected URL
        if (response.statusToken.equals("302"))
        {
                // We should receive a redirection page:
                if( response.location == null )
                {
                        TestUtil.logErr( "redirection URL : null"  );
                        throw new Fault( "test" + testNum + " failed." );
                }

                 // Extract location from redirection and format new request:
                request = WebUtil.getRequestFromURL( response.location );
                TestUtil.logMsg("Redirect to: " + response.location );

                // update cookies if the webserver choose to send cookies,
                // immediately after a successful http post request.
                addNewCookies(cookies, response.cookies);
              
                // Request redirected page 
                TestUtil.logMsg( "Sending request \"" + request + "\"" );
                response = WebUtil.sendRequest( "GET",
                        InetAddress.getByName( hostname ), portnum, request, null,
                        cookies );

                // After a succesful http post request,
                // Sun's Reference Implementation returns a redirected URL
                // (Note: No cookies are sent back to the client at this point)
                // Only when the client accesses the redirected URL,
                // Sun RI sends a cookie (single sign on cookie) back to
                // the client. So update cookies hashtable with new cookies
                addNewCookies(cookies, response.cookies);

                 // Check that the page was found (no error).
                if( response.isError() ) {
			TestUtil.logErr( "Status Token "+response.statusToken);
                        TestUtil.logErr( "Could not find " + request );
                        throw new Fault( "test" + testNum + " failed." );
                }
        }
        else
        { 
                // After a successful post request, if a webserver
                // returns the webresource without redirecting to new URL
                // then update any new cookies received during this process.
                addNewCookies(cookies, response.cookies);

        }

	return response;
    } 

    /**
     * Helper method that is used to update cookies 
     * 
     * This helper method retrieves  cookies from "newCookies" hashtable
     * and updates it to "oldCookies" hashtable
     *
     * @param oldCookies  Hashtable containing original cookies  
     * @param newCookies  Hashtable containing new cookies
     *     error messages.
     */
     public void addNewCookies(Hashtable oldCookies, Hashtable newCookies)
     {
        //Add  new cookie/cookies to the existing cookies Hashtable
        for (Enumeration e = newCookies.keys();
                                       e.hasMoreElements();)
        {
	       //get cookie name
               String name = (String)e.nextElement();

               //get value for this name 
               String value = (String)newCookies.get(name);

	       if(oldCookies==null)
		oldCookies = new Hashtable();

               //Add this name value pair (cookie) to old cookies
               oldCookies.put(name.trim(), value.trim());

         }
   }




}
