Coverage Report - org.mule.extras.wssecurity.handlers.MuleWSSInHandler
 
Classes in this File Line Coverage Branch Coverage Complexity
MuleWSSInHandler
64%
48/75
50%
23/46
11.667
 
 1  
 /*
 2  
  * $Id: MuleWSSInHandler.java 10165 2007-12-28 11:34:33Z marie.rizzo $
 3  
  * --------------------------------------------------------------------------------------
 4  
  * Copyright (c) MuleSource, Inc.  All rights reserved.  http://www.mulesource.com
 5  
  *
 6  
  * The software in this package is published under the terms of the CPAL v1.0
 7  
  * license, a copy of which has been included with this distribution in the
 8  
  * LICENSE.txt file.
 9  
  */
 10  
 
 11  
 package org.mule.extras.wssecurity.handlers;
 12  
 
 13  
 import org.mule.MuleManager;
 14  
 import org.mule.providers.soap.xfire.XFireConnector;
 15  
 import org.mule.umo.security.SecurityException;
 16  
 
 17  
 import java.security.cert.X509Certificate;
 18  
 import java.util.Map;
 19  
 import java.util.Properties;
 20  
 import java.util.Vector;
 21  
 
 22  
 import javax.security.auth.callback.CallbackHandler;
 23  
 
 24  
 import org.apache.commons.logging.Log;
 25  
 import org.apache.commons.logging.LogFactory;
 26  
 import org.apache.ws.security.WSConstants;
 27  
 import org.apache.ws.security.WSSecurityEngineResult;
 28  
 import org.apache.ws.security.WSSecurityException;
 29  
 import org.apache.ws.security.handler.RequestData;
 30  
 import org.apache.ws.security.handler.WSHandlerConstants;
 31  
 import org.apache.ws.security.handler.WSHandlerResult;
 32  
 import org.apache.ws.security.util.WSSecurityUtil;
 33  
 import org.codehaus.xfire.MessageContext;
 34  
 import org.codehaus.xfire.XFireRuntimeException;
 35  
 import org.codehaus.xfire.exchange.AbstractMessage;
 36  
 import org.codehaus.xfire.fault.XFireFault;
 37  
 import org.codehaus.xfire.handler.Handler;
 38  
 import org.codehaus.xfire.handler.Phase;
 39  
 import org.codehaus.xfire.security.wss4j.AbstractWSS4JHandler;
 40  
 import org.codehaus.xfire.soap.handler.ReadHeadersHandler;
 41  
 import org.codehaus.xfire.util.dom.DOMInHandler;
 42  
 import org.w3c.dom.Document;
 43  
 
 44  
 public class MuleWSSInHandler extends AbstractWSS4JHandler implements Handler
 45  
 {
 46  
     /**
 47  
      * logger used by this class
 48  
      */
 49  8
     protected static final Log log = LogFactory.getLog(MuleWSSInHandler.class);
 50  
 
 51  
     public MuleWSSInHandler()
 52  
     {
 53  16
         super();
 54  16
         setPhase(Phase.PARSE);
 55  16
         getBefore().add(ReadHeadersHandler.class.getName());
 56  16
         getAfter().add(DOMInHandler.class.getName());
 57  16
     }
 58  
 
 59  
     public MuleWSSInHandler(Properties properties)
 60  
     {
 61  0
         this();
 62  0
         setProperties(properties);
 63  0
     }
 64  
 
 65  
     /**
 66  
      * The method invoke performs the security checks on the soap headers for the
 67  
      * incoming message.
 68  
      */
 69  
     public void invoke(MessageContext msgContext)
 70  
         throws SecurityException, XFireFault, WSSecurityException
 71  
     {
 72  16
         boolean doDebug = log.isDebugEnabled();
 73  
 
 74  16
         if (doDebug)
 75  
         {
 76  0
             log.debug("MuleWSSInSecurityHandler: enter invoke()");
 77  
         }
 78  
 
 79  16
         RequestData reqData = new RequestData();
 80  
 
 81  
         try
 82  
         {
 83  16
             reqData.setMsgContext(msgContext);
 84  
 
 85  16
             Vector actions = new Vector();
 86  
             String action;
 87  
 
 88  
             // the action property in the security header is necessary to know which
 89  
             // type of security measure to adopt. It cannot be null.
 90  16
             if ((action = (String)getOption(WSHandlerConstants.ACTION)) == null)
 91  
             {
 92  16
                 action = getString(WSHandlerConstants.ACTION, msgContext);
 93  
             }
 94  
             // try getting the action from the Xfire Connector
 95  16
             if (action == null)
 96  
             {
 97  0
                 Map connectors = MuleManager.getInstance().getConnectors();
 98  0
                 Object[] arr = connectors.values().toArray();
 99  0
                 for (int i =0; i < arr.length; i++)
 100  
                 {
 101  0
                     Object c = arr[i];
 102  0
                     if (c instanceof XFireConnector)
 103  
                     {
 104  0
                         action = (String)((XFireConnector)c).getExtraProperties().get(WSHandlerConstants.ACTION);
 105  0
                         if (action != null)
 106  
                         {
 107  0
                             break;
 108  
                         }
 109  
                     }
 110  
                 }
 111  
             }
 112  16
             if (action == null)
 113  
             {
 114  0
                 throw new XFireRuntimeException("MuleWSSInHandler: No action defined");
 115  
             }
 116  
 
 117  16
             int doAction = WSSecurityUtil.decodeAction(action, actions);
 118  
 
 119  16
             String actor = (String)getOption(WSHandlerConstants.ACTOR);
 120  
 
 121  16
             AbstractMessage sm = msgContext.getCurrentMessage();
 122  16
             Document doc = (Document)sm.getProperty(DOMInHandler.DOM_MESSAGE);
 123  
 
 124  16
             if (doc == null)
 125  0
                 throw new XFireRuntimeException("DOMInHandler must be enabled for WS-Security!");
 126  
 
 127  
             // Check if it's a response and if its a fault it doesn't continue.
 128  16
             if (sm.getBody() instanceof XFireFault) return;
 129  
 
 130  
             // Get the password using a callback handler
 131  16
             CallbackHandler cbHandler = null;
 132  16
             if ((doAction & (WSConstants.ENCR | WSConstants.UT)) != 0)
 133  
             {
 134  12
                 cbHandler = getPasswordCB(reqData);
 135  
             }
 136  
 
 137  
             // Get and check the parameters pertaining to the signature and
 138  
             // encryption actions. Doesn't get SAML properties, though
 139  16
             doReceiverAction(doAction, reqData);
 140  
 
 141  
             // If we're using signed SAML, we need to get the signature file in order
 142  
             // to decrypt the SAML token
 143  16
             if (action.equals(WSHandlerConstants.SAML_TOKEN_SIGNED))
 144  
             {
 145  0
                 reqData.setSigCrypto(loadSignatureCrypto(reqData));
 146  
             }
 147  
             
 148  
             Vector wsResult;
 149  
 
 150  
             // process the security header
 151  
             try
 152  
             {
 153  16
                 wsResult = secEngine.processSecurityHeader(doc, actor, cbHandler, reqData
 154  
                     .getSigCrypto(), reqData.getDecCrypto());
 155  
             }
 156  0
             catch (WSSecurityException ex)
 157  
             {
 158  0
                 throw new XFireFault("MuleWSSInHandler: security processing failed: " + ex.toString(), ex,
 159  
                     XFireFault.SENDER);
 160  16
             }
 161  
 
 162  
             // no security header found we check whether the action was set to
 163  
             // "no_security" or else we throw an exception
 164  16
             if (wsResult == null)
 165  
             {
 166  0
                 if (doAction == WSConstants.NO_SECURITY)
 167  
                 {
 168  
                     return;
 169  
                 }
 170  
                 else
 171  
                 {
 172  0
                     throw new XFireFault(
 173  
                         "MuleWSSInHandler: Request does not contain required Security header",
 174  
                         XFireFault.SENDER);
 175  
                 }
 176  
             }
 177  
 
 178  
             // confim that the signature is valid
 179  16
             if (reqData.getWssConfig().isEnableSignatureConfirmation())
 180  
             {
 181  16
                 checkSignatureConfirmation(reqData, wsResult);
 182  
             }
 183  
 
 184  
             // Extract the signature action result from the action vector
 185  16
             WSSecurityEngineResult actionResult = WSSecurityUtil.fetchActionResult(wsResult,
 186  
                 WSConstants.SIGN);
 187  
 
 188  16
             if (actionResult != null)
 189  
             {
 190  4
                 X509Certificate returnCert = actionResult.getCertificate();
 191  
 
 192  4
                 if (returnCert != null)
 193  
                 {
 194  4
                     if (!verifyTrust(returnCert, reqData))
 195  
                     {
 196  0
                         throw new XFireFault(
 197  
                             "MuleWSSInHandler: The certificate used for the signature is not trusted",
 198  
                             XFireFault.SENDER);
 199  
                     }
 200  
                 }
 201  
             }
 202  
 
 203  16
             if (actions.elementAt(0).equals(new Integer(16)))
 204  
             {
 205  0
                 actions.clear();
 206  0
                 actions.add(new Integer(2));
 207  0
                 actions.add(new Integer(8));
 208  
             }
 209  
 
 210  
             // now check the security actions: do they match, in right order?
 211  16
             if (!checkReceiverResults(wsResult, actions))
 212  
             {
 213  0
                 throw new XFireFault(
 214  
                     "MuleWSSInHandler: security processing failed (actions mismatch)",
 215  
                     XFireFault.SENDER);
 216  
 
 217  
             }
 218  
             /*
 219  
              * Construct and setup the security result structure. The service may
 220  
              * fetch this and check it.
 221  
              */
 222  
             Vector results;
 223  16
             if ((results = (Vector)msgContext.getProperty(WSHandlerConstants.RECV_RESULTS)) == null)
 224  
             {
 225  16
                 results = new Vector();
 226  16
                 msgContext.setProperty(WSHandlerConstants.RECV_RESULTS, results);
 227  
             }
 228  16
             WSHandlerResult rResult = new WSHandlerResult(actor, wsResult);
 229  16
             results.add(0, rResult);
 230  
 
 231  16
             if (doDebug)
 232  
             {
 233  0
                 log.debug("MuleWSSInHandler: exit invoke()");
 234  
             }
 235  
         }
 236  0
         catch (WSSecurityException e)
 237  
         {
 238  0
             throw new WSSecurityException(e.getErrorCode());
 239  
         }
 240  
         finally
 241  
         {
 242  16
             reqData.clear();
 243  16
             reqData = null;
 244  16
         }
 245  16
     }
 246  
 }