Author: coheigea
Date: Fri Feb  4 17:26:31 2011
New Revision: 1067229

URL: http://svn.apache.org/viewvc?rev=1067229&view=rev
Log:
[WSS-256] - Throw an exception on processing multiple security headers with the 
same actor.

Added:
    
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/misc/SecurityHeaderTest.java
Modified:
    
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/handler/WSHandler.java
    
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecHeader.java
    
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/util/WSSecurityUtil.java

Modified: 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/handler/WSHandler.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/handler/WSHandler.java?rev=1067229&r1=1067228&r2=1067229&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/handler/WSHandler.java
 (original)
+++ 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/handler/WSHandler.java
 Fri Feb  4 17:26:31 2011
@@ -1103,7 +1103,7 @@ public abstract class WSHandler {
      * @param timeToLive
      *            the limit on the receivers' side, that the timestamp is 
validated against
      * @return true if the timestamp is before (now-timeToLive), false 
otherwise
-     * @Deprecated TTL validation is now done by default in the 
TimestampProcessor
+     * @deprecated TTL validation is now done by default in the 
TimestampProcessor
      * @throws WSSecurityException
      */
     protected boolean verifyTimestamp(Timestamp timestamp, int timeToLive) 
throws WSSecurityException {

Modified: 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecHeader.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecHeader.java?rev=1067229&r1=1067228&r2=1067229&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecHeader.java
 (original)
+++ 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/message/WSSecHeader.java
 Fri Feb  4 17:26:31 2011
@@ -19,6 +19,7 @@
 package org.apache.ws.security.message;
 
 import org.apache.ws.security.WSConstants;
+import org.apache.ws.security.WSSecurityException;
 import org.apache.ws.security.util.WSSecurityUtil;
 import org.w3c.dom.Document;
 import org.w3c.dom.Element;
@@ -103,7 +104,7 @@ public class WSSecHeader {
      * @return true if empty or if there is no security header
      *         false if non empty security header
      */
-    public boolean isEmpty(Document doc) {
+    public boolean isEmpty(Document doc) throws WSSecurityException {
         if (securityHeader == null) {            
             securityHeader = 
                 WSSecurityUtil.findWsseSecurityHeaderBlock(
@@ -127,7 +128,7 @@ public class WSSecHeader {
      * @param doc A SOAP envelope as <code>Document</code>
      * @return A <code>wsse:Security</code> element
      */
-    public Element insertSecurityHeader(Document doc) {
+    public Element insertSecurityHeader(Document doc) throws 
WSSecurityException {
         //
         // If there is already a security header in this instance just return 
it
         //
@@ -172,7 +173,7 @@ public class WSSecHeader {
         return securityHeader;
     }
     
-    public void removeSecurityHeader(Document doc) {
+    public void removeSecurityHeader(Document doc) throws WSSecurityException {
         if (securityHeader == null) {            
             securityHeader = 
                 WSSecurityUtil.findWsseSecurityHeaderBlock(

Modified: 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/util/WSSecurityUtil.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/main/java/org/apache/ws/security/util/WSSecurityUtil.java?rev=1067229&r1=1067228&r2=1067229&view=diff
==============================================================================
--- 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/util/WSSecurityUtil.java
 (original)
+++ 
webservices/wss4j/trunk/src/main/java/org/apache/ws/security/util/WSSecurityUtil.java
 Fri Feb  4 17:26:31 2011
@@ -82,7 +82,7 @@ public class WSSecurityUtil {
      * @return the <code>wsse:Security</code> element or <code>null</code>
      *         if not such element found
      */
-    public static Element getSecurityHeader(Document doc, String actor) {
+    public static Element getSecurityHeader(Document doc, String actor) throws 
WSSecurityException {
         String soapNamespace = 
WSSecurityUtil.getSOAPNamespace(doc.getDocumentElement());
         Element soapHeaderElement = 
             getDirectChildElement(
@@ -98,27 +98,38 @@ public class WSSecurityUtil {
         if (WSConstants.URI_SOAP12_ENV.equals(soapNamespace)) {
             actorLocal = WSConstants.ATTR_ROLE;
         }
+        
         //
-        // get all wsse:Security nodes
+        // Iterate through the security headers
         //
-        List<Node> securityHeaderList = 
-            getDirectChildElements(
-                soapHeaderElement, 
-                WSConstants.WSSE_LN, 
-                WSConstants.WSSE_NS
-            );
-        if (securityHeaderList == null) {
-            return null;
-        }
-        for (int i = 0; i < securityHeaderList.size(); i++) {
-            Element elem = (Element) securityHeaderList.get(i);
-            Attr attr = elem.getAttributeNodeNS(soapNamespace, actorLocal);
-            String hActor = (attr != null) ? attr.getValue() : null;
-            if (WSSecurityUtil.isActorEqual(actor, hActor)) {
-                return elem;
+        Element foundSecurityHeader = null;
+        for (
+            Node currentChild = soapHeaderElement.getFirstChild(); 
+            currentChild != null; 
+            currentChild = currentChild.getNextSibling()
+        ) {
+            if (Node.ELEMENT_NODE == currentChild.getNodeType()
+                && WSConstants.WSSE_LN.equals(currentChild.getLocalName())
+                && WSConstants.WSSE_NS.equals(currentChild.getNamespaceURI())) 
{
+                
+                Element elem = (Element)currentChild;
+                Attr attr = elem.getAttributeNodeNS(soapNamespace, actorLocal);
+                String hActor = (attr != null) ? attr.getValue() : null;
+
+                if (WSSecurityUtil.isActorEqual(actor, hActor)) {
+                    if (foundSecurityHeader != null) {
+                        if (log.isDebugEnabled()) {
+                            log.debug(
+                                "Two or more security headers have the same 
actor name: " + actor
+                            );
+                        }
+                        throw new 
WSSecurityException(WSSecurityException.INVALID_SECURITY);
+                    }
+                    foundSecurityHeader = elem;
+                }
             }
         }
-        return null;
+        return foundSecurityHeader;
     }
 
 
@@ -642,7 +653,7 @@ public class WSSecurityUtil {
         Document doc,
         Element envelope, 
         boolean doCreate
-    ) {
+    ) throws WSSecurityException {
         return findWsseSecurityHeaderBlock(doc, envelope, null, doCreate);
     }
 
@@ -660,7 +671,7 @@ public class WSSecurityUtil {
         Element envelope,
         String actor, 
         boolean doCreate
-    ) {
+    ) throws WSSecurityException {
         Element wsseSecurity = getSecurityHeader(doc, actor);
         if (wsseSecurity != null) {
             return wsseSecurity;

Added: 
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/misc/SecurityHeaderTest.java
URL: 
http://svn.apache.org/viewvc/webservices/wss4j/trunk/src/test/java/org/apache/ws/security/misc/SecurityHeaderTest.java?rev=1067229&view=auto
==============================================================================
--- 
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/misc/SecurityHeaderTest.java
 (added)
+++ 
webservices/wss4j/trunk/src/test/java/org/apache/ws/security/misc/SecurityHeaderTest.java
 Fri Feb  4 17:26:31 2011
@@ -0,0 +1,127 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.ws.security.misc;
+
+import org.apache.ws.security.WSSecurityEngine;
+import org.apache.ws.security.WSSecurityException;
+import org.apache.ws.security.common.SOAPUtil;
+import org.w3c.dom.Document;
+
+/**
+ * This tests how security headers are parsed and processed.
+ */
+public class SecurityHeaderTest extends org.junit.Assert {
+    private static final String DUPLICATE_NULL_ACTOR_MSG = 
+        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" 
+        + "<SOAP-ENV:Envelope 
xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"; "
+        + "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"; "
+        + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\";>"
+        + "<SOAP-ENV:Header>"
+        + "<wsse:Security SOAP-ENV:mustUnderstand=\"1\" "
+        + 
"xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\";>"
+        + "</wsse:Security>"
+        + "<wsse:Security SOAP-ENV:mustUnderstand=\"1\" "
+        + 
"xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\";>"
+        + "</wsse:Security>"
+        + "</SOAP-ENV:Header>"
+        + "<SOAP-ENV:Body>" 
+        + "<add xmlns=\"http://ws.apache.org/counter/counter_port_type\";>" 
+        + "<value xmlns=\"\">15</value>" + "</add>" 
+        + "</SOAP-ENV:Body>\r\n       \r\n" + "</SOAP-ENV:Envelope>";
+    private static final String DUPLICATE_ACTOR_MSG = 
+        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" 
+        + "<SOAP-ENV:Envelope 
xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"; "
+        + "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"; "
+        + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\";>"
+        + "<SOAP-ENV:Header>"
+        + "<wsse:Security SOAP-ENV:actor=\"user\" 
SOAP-ENV:mustUnderstand=\"1\" "
+        + 
"xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\";>"
+        + "</wsse:Security>"
+        + "<wsse:Security SOAP-ENV:actor=\"user\" 
SOAP-ENV:mustUnderstand=\"1\" "
+        + 
"xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\";>"
+        + "</wsse:Security>"
+        + "</SOAP-ENV:Header>"
+        + "<SOAP-ENV:Body>" 
+        + "<add xmlns=\"http://ws.apache.org/counter/counter_port_type\";>" 
+        + "<value xmlns=\"\">15</value>" + "</add>" 
+        + "</SOAP-ENV:Body>\r\n       \r\n" + "</SOAP-ENV:Envelope>";
+    private static final String TWO_ACTOR_MSG = 
+        "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" 
+        + "<SOAP-ENV:Envelope 
xmlns:SOAP-ENV=\"http://schemas.xmlsoap.org/soap/envelope/\"; "
+        + "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\"; "
+        + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\";>"
+        + "<SOAP-ENV:Header>"
+        + "<wsse:Security SOAP-ENV:mustUnderstand=\"1\" "
+        + 
"xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\";>"
+        + "</wsse:Security>"
+        + "<wsse:Security SOAP-ENV:actor=\"user\" 
SOAP-ENV:mustUnderstand=\"1\" "
+        + 
"xmlns:wsse=\"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd\";>"
+        + "</wsse:Security>"
+        + "</SOAP-ENV:Header>"
+        + "<SOAP-ENV:Body>" 
+        + "<add xmlns=\"http://ws.apache.org/counter/counter_port_type\";>" 
+        + "<value xmlns=\"\">15</value>" + "</add>" 
+        + "</SOAP-ENV:Body>\r\n       \r\n" + "</SOAP-ENV:Envelope>";
+    
+    private WSSecurityEngine secEngine = new WSSecurityEngine();
+
+    /**
+     * Test for processing multiple security headers with the same (null) actor
+     */
+    @org.junit.Test
+    public void testDuplicateNullActor() throws Exception {
+        Document doc = SOAPUtil.toSOAPPart(DUPLICATE_NULL_ACTOR_MSG);
+        try {
+            secEngine.processSecurityHeader(doc, null, null, null);
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+    }
+    
+    /**
+     * Test for processing multiple security headers with the same actor
+     */
+    @org.junit.Test
+    public void testDuplicateActor() throws Exception {
+        Document doc = SOAPUtil.toSOAPPart(DUPLICATE_ACTOR_MSG);
+        try {
+            secEngine.processSecurityHeader(doc, "user", null, null);
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+        
+        try {
+            secEngine.processSecurityHeader(doc, "otheruser", null, null);
+        } catch (WSSecurityException ex) {
+            // expected
+        }
+    }
+    
+    /**
+     * Test for processing multiple security headers with different actors
+     */
+    @org.junit.Test
+    public void testTwoActors() throws Exception {
+        Document doc = SOAPUtil.toSOAPPart(TWO_ACTOR_MSG);
+        secEngine.processSecurityHeader(doc, null, null, null);
+        
+        secEngine.processSecurityHeader(doc, "user", null, null);
+    }
+}


Reply via email to