[WSS4J] wss4j/test/wssec PrivilegedAccessor.java,NONE,1.1 TestWSSecurityHooks.java,NONE,1.1 PackageTests.java,1.7,1.8

[email protected] Wed, 11 Feb 2004 19:01:06 -0800
Newsgroups gmane.text.xml.wss4j
Message-ID <[email protected]>
Update of /cvsroot/wss4j/wss4j/test/wssec
In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv7097/test/wssec

Modified Files:
	PackageTests.java 
Added Files:
	PrivilegedAccessor.java TestWSSecurityHooks.java 
Log Message:
test case from "Jason Essington" <[email protected]> that checks 
the "Using wss4j from within a SecurityDomain" functionality. Uses 
PrivilegedAccessor file described in the junit faq
<http://junit.sourceforge.net/doc/faq/faq.htm#tests_11>

The TestWSSecurityHooks tests that the private (or package) fields from 
the super classes are being set by the hooks. It tests all the hooks, 
then tries to do an "Encrypt Signature" round trip. The round trip test 
may really be more complicated that what a unit test should be, and the 
other tests really should catch any problems.

--- NEW FILE: PrivilegedAccessor.java ---
/*
 * This class was taken nearly verbatim from http://junit.sourceforge.net/doc/faq/faq.htm#tests_11 
 * I did add the setValue(Object, String, Object)
 * Jason Essington <mailto:jasone-0ehoRKBSFavH/[email protected]>
 */
package wssec;
import java.lang.reflect.*;

/**
 * a.k.a. The "ObjectMolester"
 * <p>
 * This class is used to access a method or field of an object no
 * matter what the access modifier of the method or field.  The syntax
 * for accessing fields and methods is out of the ordinary because this
 * class uses reflection to peel away protection.
 * <p>
 * Here is an example of using this to access a private member.
 * <code>resolveName</code> is a private method of <code>Class</code>.
 *
 * <pre>
 * Class c = Class.class;
 * System.out.println(
 *      PrivilegedAccessor.invokeMethod( c,
 *                                       "resolveName",
 *                                       "/net/iss/common/PrivilegeAccessor" ) );
 * </pre>
 *
 * @author Charlie Hubbard ([email protected])
 * @author Prashant Dhokte ([email protected])
 */

public class PrivilegedAccessor {

    /**
     * Gets the value of the named field and returns it as an object.
     *
     * @param instance the object instance
     * @param fieldName the name of the field
     * @return an object representing the value of the field
     */
    public static Object getValue( Object instance, String fieldName ) 
          throws IllegalAccessException, NoSuchFieldException {
        Field field = getField(instance.getClass(), fieldName);
        field.setAccessible(true);
        return field.get(instance);
    }
    
    /**
     * Sets the value of the given field on the object instance supplied to the value supplied.
     * @param instance the object instance
     * @param fieldName the name of the field
     * @param value the value to assign to the field
     * @throws IllegalAccessException
     * @throws NoSuchFieldException
     */
    public static void setValue( Object instance, String fieldName, Object value ) 
          throws IllegalAccessException, NoSuchFieldException {
       Field field = getField(instance.getClass(), fieldName);
       field.setAccessible(true);
       field.set(instance, value);
    }
    
    /**
     * Calls a method on the given object instance with the given argument.
     *
     * @param instance the object instance
     * @param methodName the name of the method to invoke
     * @param arg the argument to pass to the method
     * @see PrivilegedAccessor#invokeMethod(Object,String,Object[])
     */
    public static Object invokeMethod( Object instance, String methodName, Object arg ) throws NoSuchMethodException,
                                                         IllegalAccessException, InvocationTargetException  {
        Object[] args = new Object[1];
        args[0] = arg;
        return invokeMethod(instance, methodName, args);
    }

    /**
     * Calls a method on the given object instance with the given arguments.
     *
     * @param instance the object instance
     * @param methodName the name of the method to invoke
     * @param args an array of objects to pass as arguments
     * @see PrivilegedAccessor#invokeMethod(Object,String,Object)
     */
    public static Object invokeMethod( Object instance, String methodName, Object[] args ) throws NoSuchMethodException,
                                                             IllegalAccessException, InvocationTargetException  {
        Class[] classTypes = null;
        if( args != null) {
            classTypes = new Class[args.length];
            for( int i = 0; i < args.length; i++ ) {
                if( args[i] != null )
                    classTypes[i] = args[i].getClass();
            }
        }
        return getMethod(instance,methodName,classTypes).invoke(instance,args);
    }

    /**
     *
     * @param instance the object instance
     * @param methodName the
     */
    public static Method getMethod( Object instance, String methodName, Class[] classTypes ) throws NoSuchMethodException {
        Method accessMethod = getMethod(instance.getClass(), methodName, classTypes);
        accessMethod.setAccessible(true);
        return accessMethod;
    }

    /**
     * Return the named field from the given class.
     */
    private static Field getField(Class thisClass, String fieldName) throws NoSuchFieldException {
        if (thisClass == null)
            throw new NoSuchFieldException("Invalid field : " + fieldName);
        try {
            return thisClass.getDeclaredField( fieldName );
        }
        catch(NoSuchFieldException e) {
            return getField(thisClass.getSuperclass(), fieldName);
        }
    }

    /**
     * Return the named method with a method signature matching classTypes
     * from the given class.
     */
    private static Method getMethod(Class thisClass, String methodName, Class[] classTypes) throws NoSuchMethodException {
        if (thisClass == null)
            throw new NoSuchMethodException("Invalid method : " + methodName);
        try {
            return thisClass.getDeclaredMethod( methodName, classTypes );
        }
        catch(NoSuchMethodException e) {
            return getMethod(thisClass.getSuperclass(), methodName, classTypes);
        }
    }
}
--- NEW FILE: TestWSSecurityHooks.java ---
/*
 * Created on Feb 10, 2004
 */
package wssec;

import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;

import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.UnsupportedCallbackException;

import org.apache.axis.AxisFault;
import org.apache.axis.Message;
import org.apache.axis.MessageContext;
import org.apache.axis.client.AxisClient;
import org.apache.axis.configuration.NullProvider;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.axis.security.WSDoAllConstants;
import org.apache.ws.axis.security.WSDoAllReceiver;
import org.apache.ws.axis.security.WSDoAllSender;
import org.apache.ws.security.WSPasswordCallback;
import org.apache.ws.security.components.crypto.Crypto;
import org.apache.ws.security.components.crypto.Merlin;

import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;

/**
 * <dl>
 * <dt><b>Title: </b><dd>WS Security Hooks Test Case</dd>
 * <p>
 * <dt><b>Description: </b><dd>Test Case to verify the load...Crypto hooks work properly. 
 * Also tests the setKeyStore method of Merlin </dd>
 * </dl>
 * 
 * @see org.apache.ws.security.components.crypto.Merlin#setKeyStore
 * @see org.apache.ws.axis.security.WSDoAllReceiver#loadSignatureCrypto
 * @see org.apache.ws.axis.security.WSDoAllReceiver#loadDecryptionCrypto
 * @see org.apache.ws.axis.security.WSDoAllSender#loadSignatureCrypto
 * @see org.apache.ws.axis.security.WSDoAllSender#loadEncryptionCrypto
 * 
 * @author <a href="mailto:jasone-0ehoRKBSFavH/[email protected]>Jason Essington</a>
 * @version $Revision: 1.1 $
 */
public class TestWSSecurityHooks extends TestCase implements CallbackHandler
{
   private static Log log = LogFactory.getLog(TestWSSecurityHooks.class);
   private static final String soapMessage = "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"+
         "<soapenv:Envelope " +
               "xmlns:soapenv=\"http://www.w3.org/2003/05/soap-envelope\" " +
               "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
               "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">" +
            "<soapenv:Header>" +
            "</soapenv:Header>" +
            "<soapenv:Body>" +
               "<ns1:echo " +
                     "xmlns:ns1=\"http://org.apache.wss4j.wssec/TESTCASE\" " +
                     "soapenv:encodingStyle=\"http://www.w3.org/2003/05/soap-encoding\">" +
                  "<inStr xsi:type=\"xsd:string\">ECHO ECHo ECho Echo echo echO ecHO eCHO ECHO</inStr>" +
               "</ns1:echo>" +
            "</soapenv:Body>" +
         "</soapenv:Envelope>";

   KeyStore keystore = null;
   MessageContext mc = null;
   
   public TestWSSecurityHooks(String name) {
      super(name);
   }
   
   protected void setUp() throws Exception {
      AxisClient tmpEngine = new AxisClient(new NullProvider());
      mc = new MessageContext(tmpEngine);
      mc.setCurrentMessage(getSOAPMessage(soapMessage));
      mc.setProperty(WSDoAllConstants.PW_CALLBACK_REF, this);
      keystore = loadKeyStore();
   }

   public static Test suite() {
      return new TestSuite(TestWSSecurityHooks.class);
   }

   public static void main(String[] args) {
      junit.textui.TestRunner.run(suite());
   }
   
   //
   //
   // Tests
   //
   //
   
   public void testCryptoHook() throws Exception {
      assertNotNull("", keystore);
      Crypto crypto = new TestCryptoImpl(keystore);
      assertNotNull(PrivilegedAccessor.getValue(crypto, "keystore"));
   }
   public void testSenderLoadSignatureHook() throws Exception {
      TestSenderImpl sender = new TestSenderImpl();
      // we have to coerce a value into this field or we'll get a bunch of NPEs when calling decodeSignatureParameter
      PrivilegedAccessor.setValue(sender, "msgContext", mc);
      PrivilegedAccessor.invokeMethod(sender, "decodeSignatureParameter", new Object[] {});
      assertNotNull(PrivilegedAccessor.getValue(sender, "sigCrypto"));
   }
   public void testSenderLoadEncryptionHook() throws Exception {
      TestSenderImpl sender = new TestSenderImpl();
      // decodeEcnryptionParameter() is rather insistant on having a user (anyUser)
      sender.setOption(WSDoAllConstants.ENCRYPTION_USER, "anyUserWillDo");
      // we have to coerce a value into this field or we'll get a bunch of NPEs when calling decodeSignatureParameter
      PrivilegedAccessor.setValue(sender, "msgContext", mc);
      PrivilegedAccessor.invokeMethod(sender, "decodeEncryptionParameter", new Object[] {});
      assertNotNull(PrivilegedAccessor.getValue(sender, "encCrypto"));
   }
   public void testReceiverLoadSignatureHook() throws Exception {
      TestReceiverImpl receiver = new TestReceiverImpl();
      PrivilegedAccessor.invokeMethod(receiver, "decodeSignatureParameter", new Object[] {});
      assertNotNull(PrivilegedAccessor.getValue(receiver, "sigCrypto"));
   }
   public void testReceiverLoadDecryptionHook() throws Exception {
      TestReceiverImpl receiver = new TestReceiverImpl();
      PrivilegedAccessor.invokeMethod(receiver, "decodeDecryptionParameter", new Object[] {});
      assertNotNull(PrivilegedAccessor.getValue(receiver, "decCrypto"));
   }
   
   public void testRoundTripWithHooks() throws Exception {
      // Setup our sender to Encrypt and Sign a soap message
      TestSenderImpl sender = new TestSenderImpl();
      sender.setOption(WSDoAllConstants.ACTOR, "test");
      sender.setOption(WSDoAllConstants.USER, "16c73ab6-b892-458f-abf5-2f875f74882e");
      sender.setOption(WSDoAllConstants.ACTION, "Encrypt Signature");
      sender.setOption(WSDoAllConstants.SIG_KEY_ID, "DirectReference");
      sender.setOption(WSDoAllConstants.ENC_KEY_ID, "X509KeyIdentifier");
      sender.invoke(mc);
      
      // Make sure that at least SOMETHING happened
      String soapPart = mc.getCurrentMessage().getSOAPPartAsString();
      assertNotSame("The message has not been Encrypted or Signed", soapPart, soapMessage);
      
      // Prepare the message context for the response
      Message message = getSOAPMessage(soapPart);
      mc.setPastPivot(true);
      mc.setCurrentMessage(message);
      
      // Setup our receiver for the decryption / signature validation
      TestReceiverImpl receiver = new TestReceiverImpl();
      receiver.setOption(WSDoAllConstants.ACTOR, "test");
      receiver.setOption(WSDoAllConstants.ACTION, "Encrypt Signature");
      receiver.invoke(mc);
   }
   
   //
   //
   // Test Utility Classes
   //
   //
      
   /**
    * This is a subclass of Merlin that uses the setKeyStore() method rather than the 
    * load(is) method to set the private keystore field.
    */
   public class TestCryptoImpl extends Merlin {
      TestCryptoImpl(KeyStore ks) throws Exception {
         super(null);
         assertNotNull(keystore);
         setKeyStore(ks);
      }
   }
   
   /**
    * Subclass of WSDoAllReceiver that creates the Crypto's directly
    */
   public class TestReceiverImpl extends WSDoAllReceiver
   {
      protected Crypto loadDecryptionCrypto() throws AxisFault {
         try {
            return new TestCryptoImpl(keystore);
         } catch(Exception e) {
            fail("Failed to create a Crypto instance.");
            throw new AxisFault("Failed to create a Crypto instance.", e);
         }
      }
      protected Crypto loadSignatureCrypto() throws AxisFault {
         try {
            return new TestCryptoImpl(keystore);
         } catch(Exception e) {
            fail("Failed to create a Crypto instance.");
            throw new AxisFault("Failed to create a Crypto instance.", e);
         }
      }
   }
   
   /**
    * Subclass of WSDoAllSender that creates the Crypto's directly
    */
   public class TestSenderImpl extends WSDoAllSender
   {
      protected Crypto loadEncryptionCrypto() throws AxisFault {
         try {
            return new TestCryptoImpl(keystore);
         } catch(Exception e) {
            fail("Failed to create a Crypto instance.");
            throw new AxisFault("Failed to create a Crypto instance.", e);
         }
      }
      protected Crypto loadSignatureCrypto() throws AxisFault {
         try {
            return new TestCryptoImpl(keystore);
         } catch(Exception e) {
            fail("Failed to create a Crypto instance.");
            throw new AxisFault("Failed to create a Crypto instance.", e);
         }
      }
   }
   
   
   //
   //
   // test utility methods
   //
   //
   
   protected Message getSOAPMessage(String message) throws Exception {
      InputStream in = new ByteArrayInputStream(message.getBytes());
      Message msg = new Message(in);
      msg.setMessageContext(mc);
      return msg;
   }
   
   protected KeyStore loadKeyStore() throws Exception {
      KeyStore ks = null;
      FileInputStream is = null;
      is = new FileInputStream("keys/x509.PFX.MSFT");
      ks = KeyStore.getInstance("pkcs12");
      String password = "security";
      ks.load(is, password.toCharArray());
      return ks;
   }
   
   public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException {
      for (int i = 0; i < callbacks.length; i++) {
         if (callbacks[i] instanceof WSPasswordCallback) {
            WSPasswordCallback pc = (WSPasswordCallback) callbacks[i];
            pc.setPassword("security");
            
         } else {
            throw new UnsupportedCallbackException(callbacks[i], "Unrecognized Callback");
         }
      }
   }
   
}

Index: PackageTests.java
===================================================================
RCS file: /cvsroot/wss4j/wss4j/test/wssec/PackageTests.java,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- PackageTests.java	21 Jan 2004 13:29:58 -0000	1.7
+++ PackageTests.java	12 Feb 2004 03:01:04 -0000	1.8
@@ -21,10 +21,11 @@
         suite.addTestSuite(TestWSSecurity3.class);
         suite.addTestSuite(TestWSSecurity5.class);
         suite.addTestSuite(TestWSSecurity6.class);
-		suite.addTestSuite(TestWSSecurity7.class);
-		suite.addTestSuite(TestWSSecurity8.class);
-		suite.addTestSuite(TestWSSecurity9.class);
-		suite.addTestSuite(TestWSSecuritySOAP12.class);
+        suite.addTestSuite(TestWSSecurity7.class);
+        suite.addTestSuite(TestWSSecurity8.class);
+        suite.addTestSuite(TestWSSecurity9.class);
+        suite.addTestSuite(TestWSSecuritySOAP12.class);
+        suite.addTestSuite(TestWSSecurityHooks.class);
         return suite;
     }
 



-------------------------------------------------------
SF.Net is sponsored by: Speed Start Your Linux Apps Now.
Build and deploy apps & Web services for Linux with
a free DVD software kit from IBM. Click Now!
http://ads.osdn.com/?ad_id=1356&alloc_id=3438&op=click