| <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en"><head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"/><link rel="stylesheet" href="../.resources/report.css" type="text/css"/><link rel="shortcut icon" href="../.resources/report.gif" type="image/gif"/><title>RampartEngine.java</title><link rel="stylesheet" href="../.resources/prettify.css" type="text/css"/><script type="text/javascript" src="../.resources/prettify.js"></script></head><body onload="window['PR_TAB_WIDTH']=4;prettyPrint()"><div class="breadcrumb" id="breadcrumb"><span class="right"><a href="../.sessions.html" class="el_session">Sessions</a></span><a href="../index.html" class="el_report">Coverage Report</a> > <a href="index.html" class="el_package">org.apache.rampart</a> > <span class="el_source">RampartEngine.java</span></div><h1>RampartEngine.java</h1><pre class="source lang-java linenums">/* |
| * Copyright 2004,2005 The Apache Software Foundation. |
| * |
| * Licensed 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.rampart; |
| |
| import org.apache.axiom.soap.SOAPEnvelope; |
| import org.apache.axiom.soap.SOAPFault; |
| import org.apache.axiom.soap.SOAPHeader; |
| import org.apache.axiom.soap.SOAPHeaderBlock; |
| import org.apache.axis2.AxisFault; |
| import org.apache.axis2.context.MessageContext; |
| import org.apache.commons.logging.Log; |
| import org.apache.commons.logging.LogFactory; |
| import org.apache.rahas.Token; |
| import org.apache.rahas.TokenStorage; |
| import org.apache.rampart.policy.RampartPolicyData; |
| import org.apache.rampart.saml.SAMLAssertionHandler; |
| import org.apache.rampart.saml.SAMLAssertionHandlerFactory; |
| import org.apache.rampart.util.Axis2Util; |
| import org.apache.rampart.util.RampartUtil; |
| import org.apache.ws.secpolicy.WSSPolicyException; |
| import org.apache.ws.secpolicy.model.UsernameToken; |
| import org.apache.ws.security.*; |
| import org.apache.ws.security.components.crypto.Crypto; |
| |
| import javax.xml.namespace.QName; |
| import java.security.cert.X509Certificate; |
| import java.util.*; |
| |
| <span class="fc" id="L43">public class RampartEngine {</span> |
| |
| <span class="fc" id="L45"> private static Log log = LogFactory.getLog(RampartEngine.class);</span> |
| <span class="fc" id="L46"> private static Log tlog = LogFactory.getLog(RampartConstants.TIME_LOG);</span> |
| <span class="fc" id="L47"> private static ServiceNonceCache serviceNonceCache = new ServiceNonceCache();</span> |
| |
| public List<WSSecurityEngineResult> process(MessageContext msgCtx) throws WSSPolicyException, |
| RampartException, WSSecurityException, AxisFault { |
| |
| <span class="fc" id="L52"> boolean dotDebug = tlog.isDebugEnabled();</span> |
| |
| <span class="fc" id="L54"> log.debug("Enter process(MessageContext msgCtx)");</span> |
| |
| <span class="fc" id="L56"> RampartMessageData rmd = new RampartMessageData(msgCtx, false);</span> |
| |
| <span class="fc" id="L58"> RampartPolicyData rpd = rmd.getPolicyData();</span> |
| |
| <span class="fc" id="L60"> msgCtx.setProperty(RampartMessageData.RAMPART_POLICY_DATA, rpd);</span> |
| |
| <span class="fc" id="L62"> RampartUtil.validateTransport(rmd);</span> |
| |
| // If there is no policy information return immediately |
| <span class="fc bfc" id="L65" title="All 2 branches covered."> if (rpd == null) {</span> |
| <span class="fc" id="L66"> return null;</span> |
| } |
| |
| |
| //TODO these checks have to be done before the convertion to avoid unnecessary convertion to LLOM -> DOOM |
| // If the message is a security fault or no security |
| // header required by the policy |
| <span class="pc bpc" id="L73" title="1 of 4 branches missed."> if(isSecurityFault(rmd) || !RampartUtil.isSecHeaderRequired(rpd,rmd.isInitiator(),true)) {</span> |
| <span class="fc" id="L74"> SOAPEnvelope env = Axis2Util.getSOAPEnvelopeFromDOMDocument(rmd.getDocument(), true);</span> |
| |
| //Convert back to llom since the inflow cannot use llom |
| <span class="fc" id="L77"> msgCtx.setEnvelope(env);</span> |
| <span class="fc" id="L78"> Axis2Util.useDOOM(false);</span> |
| <span class="fc" id="L79"> log.debug("Return process MessageContext msgCtx)");</span> |
| <span class="fc" id="L80"> return null;</span> |
| } |
| |
| |
| List<WSSecurityEngineResult> results; |
| |
| <span class="fc" id="L86"> WSSecurityEngine engine = new WSSecurityEngine();</span> |
| |
| <span class="fc" id="L88"> ValidatorData data = new ValidatorData(rmd);</span> |
| |
| <span class="fc" id="L90"> SOAPHeader header = rmd.getMsgContext().getEnvelope().getHeader();</span> |
| <span class="pc bpc" id="L91" title="1 of 2 branches missed."> if(header == null) {</span> |
| <span class="nc" id="L92"> throw new RampartException("missingSOAPHeader");</span> |
| } |
| |
| <span class="fc" id="L95"> ArrayList headerBlocks = header.getHeaderBlocksWithNSURI(WSConstants.WSSE_NS);</span> |
| <span class="fc" id="L96"> SOAPHeaderBlock secHeader = null;</span> |
| //Issue is axiom - a returned collection must not be null |
| <span class="pc bpc" id="L98" title="1 of 2 branches missed."> if(headerBlocks != null) {</span> |
| <span class="fc" id="L99"> Iterator headerBlocksIterator = headerBlocks.iterator();</span> |
| <span class="fc bfc" id="L100" title="All 2 branches covered."> while (headerBlocksIterator.hasNext()) {</span> |
| <span class="fc" id="L101"> SOAPHeaderBlock elem = (SOAPHeaderBlock) headerBlocksIterator.next();</span> |
| <span class="pc bpc" id="L102" title="1 of 2 branches missed."> if(elem.getLocalName().equals(WSConstants.WSSE_LN)) {</span> |
| <span class="fc" id="L103"> secHeader = elem;</span> |
| <span class="fc" id="L104"> break;</span> |
| } |
| <span class="nc" id="L106"> }</span> |
| } |
| |
| <span class="fc bfc" id="L109" title="All 2 branches covered."> if(secHeader == null) {</span> |
| <span class="fc" id="L110"> throw new RampartException("missingSecurityHeader");</span> |
| } |
| |
| <span class="fc" id="L113"> long t0=0, t1=0, t2=0, t3=0;</span> |
| <span class="pc bpc" id="L114" title="1 of 2 branches missed."> if(dotDebug){</span> |
| <span class="nc" id="L115"> t0 = System.currentTimeMillis();</span> |
| } |
| |
| //wss4j does not allow username tokens with no password per default, see https://issues.apache.org/jira/browse/WSS-420 |
| //configure it to allow them explicitly if at least one username token assertion with no password requirement is found |
| <span class="fc bfc" id="L120" title="All 2 branches covered."> if (!rmd.isInitiator()) {</span> |
| <span class="fc" id="L121"> Collection<UsernameToken> usernameTokens = RampartUtil.getUsernameTokens(rpd);</span> |
| <span class="fc bfc" id="L122" title="All 2 branches covered."> for (UsernameToken usernameTok : usernameTokens) {</span> |
| <span class="fc bfc" id="L123" title="All 2 branches covered."> if (usernameTok.isNoPassword()) {</span> |
| <span class="fc" id="L124"> log.debug("Found UsernameToken with no password assertion in policy, configuring ws security processing to allow username tokens without password." );</span> |
| <span class="fc" id="L125"> engine.getWssConfig().setAllowUsernameTokenNoPassword(true);</span> |
| <span class="fc" id="L126"> break;</span> |
| } |
| <span class="fc" id="L128"> }</span> |
| } |
| |
| <span class="fc" id="L131"> String actorValue = secHeader.getAttributeValue(new QName(rmd</span> |
| .getSoapConstants().getEnvelopeURI(), "actor")); |
| |
| <span class="fc" id="L134"> Crypto signatureCrypto = RampartUtil.getSignatureCrypto(rpd.getRampartConfig(), </span> |
| msgCtx.getAxisService().getClassLoader()); |
| <span class="fc" id="L136"> TokenCallbackHandler tokenCallbackHandler = new TokenCallbackHandler(rmd.getTokenStorage(), RampartUtil.getPasswordCB(rmd));</span> |
| <span class="fc bfc" id="L137" title="All 2 branches covered."> if(rpd.isSymmetricBinding()) {</span> |
| //Here we have to create the CB handler to get the tokens from the |
| //token storage |
| <span class="fc" id="L140"> log.debug("Processing security header using SymetricBinding");</span> |
| <span class="fc" id="L141"> results = engine.processSecurityHeader(rmd.getDocument(),</span> |
| actorValue, |
| tokenCallbackHandler, |
| signatureCrypto, |
| RampartUtil.getEncryptionCrypto(rpd.getRampartConfig(), |
| msgCtx.getAxisService().getClassLoader())); |
| |
| // Remove encryption tokens if this is the initiator and if initiator is receiving a message |
| |
| <span class="pc bpc" id="L150" title="1 of 6 branches missed."> if (rmd.isInitiator() && (msgCtx.getFLOW() == MessageContext.IN_FLOW ||</span> |
| msgCtx.getFLOW() == MessageContext.IN_FAULT_FLOW)) { |
| <span class="fc" id="L152"> tokenCallbackHandler.removeEncryptedToken();</span> |
| } |
| |
| } else { |
| |
| <span class="fc" id="L157"> log.debug("Processing security header in normal path");</span> |
| <span class="fc" id="L158"> results = engine.processSecurityHeader(rmd.getDocument(),</span> |
| actorValue, |
| tokenCallbackHandler, |
| signatureCrypto, |
| RampartUtil.getEncryptionCrypto(rpd.getRampartConfig(), |
| msgCtx.getAxisService().getClassLoader())); |
| } |
| |
| <span class="pc bpc" id="L166" title="1 of 2 branches missed."> if(dotDebug){</span> |
| <span class="nc" id="L167"> t1 = System.currentTimeMillis();</span> |
| } |
| |
| //Store symm tokens |
| //Pick the first SAML token |
| //TODO : This is a hack , MUST FIX |
| //get the sec context id from the req msg ctx |
| |
| //Store username in MessageContext property |
| |
| <span class="fc bfc" id="L177" title="All 2 branches covered."> for (int j = 0; j < results.size(); j++) {</span> |
| <span class="fc" id="L178"> WSSecurityEngineResult wser = (WSSecurityEngineResult) results.get(j);</span> |
| <span class="fc" id="L179"> final Integer actInt =</span> |
| (Integer) wser.get(WSSecurityEngineResult.TAG_ACTION); |
| <span class="pc bpc" id="L181" title="1 of 2 branches missed."> if (WSConstants.ST_UNSIGNED == actInt.intValue()) {</span> |
| |
| <span class="nc" id="L183"> Object samlAssertion = wser.get(WSSecurityEngineResult.TAG_SAML_ASSERTION);</span> |
| |
| <span class="nc" id="L185"> SAMLAssertionHandler samlAssertionHandler</span> |
| = SAMLAssertionHandlerFactory.createAssertionHandler(samlAssertion); |
| |
| <span class="nc bnc" id="L188" title="All 2 branches missed."> if (samlAssertionHandler.isBearerAssertion()) {</span> |
| <span class="nc" id="L189"> break;</span> |
| } |
| //Store the token |
| try { |
| <span class="nc" id="L193"> TokenStorage store = rmd.getTokenStorage();</span> |
| <span class="nc bnc" id="L194" title="All 2 branches missed."> if (store.getToken(samlAssertionHandler.getAssertionId()) == null) {</span> |
| <span class="nc" id="L195"> Token token = new Token(samlAssertionHandler.getAssertionId(),</span> |
| samlAssertionHandler.getAssertionElement(), |
| samlAssertionHandler.getDateNotBefore(), |
| samlAssertionHandler.getDateNotOnOrAfter()); |
| |
| <span class="nc" id="L200"> token.setSecret(samlAssertionHandler.</span> |
| getAssertionKeyInfoSecret(signatureCrypto, tokenCallbackHandler)); |
| <span class="nc" id="L202"> store.add(token);</span> |
| } |
| <span class="nc" id="L204"> } catch (Exception e) {</span> |
| <span class="nc" id="L205"> throw new RampartException(</span> |
| "errorInAddingTokenIntoStore", e); |
| <span class="nc" id="L207"> }</span> |
| <span class="pc bfc" id="L208" title="All 2 branches covered."> } else if (WSConstants.UT == actInt) {</span> |
| |
| <span class="fc" id="L210"> WSUsernameTokenPrincipal userNameTokenPrincipal = (WSUsernameTokenPrincipal)wser.get(WSSecurityEngineResult.TAG_PRINCIPAL);</span> |
| |
| <span class="fc" id="L212"> String username = userNameTokenPrincipal.getName();</span> |
| <span class="fc" id="L213"> msgCtx.setProperty(RampartMessageData.USERNAME, username);</span> |
| |
| <span class="pc bpc" id="L215" title="1 of 2 branches missed."> if (userNameTokenPrincipal.getNonce() != null) {</span> |
| // Check whether this is a replay attack. To verify that we need to check whether nonce value |
| // is a repeating one |
| <span class="nc" id="L218"> int nonceLifeTimeInSeconds = 0;</span> |
| |
| <span class="nc bnc" id="L220" title="All 2 branches missed."> if (rpd.getRampartConfig() != null) {</span> |
| |
| <span class="nc" id="L222"> String stringLifeTime = rpd.getRampartConfig().getNonceLifeTime();</span> |
| |
| try { |
| <span class="nc" id="L225"> nonceLifeTimeInSeconds = Integer.parseInt(stringLifeTime);</span> |
| |
| <span class="nc" id="L227"> } catch (NumberFormatException e) {</span> |
| <span class="nc" id="L228"> log.error("Invalid value for nonceLifeTime in rampart configuration file.", e);</span> |
| <span class="nc" id="L229"> throw new RampartException(</span> |
| "invalidNonceLifeTime", e); |
| |
| <span class="nc" id="L232"> }</span> |
| } |
| |
| <span class="nc" id="L235"> String serviceEndpointName = msgCtx.getAxisService().getEndpointName();</span> |
| |
| <span class="nc" id="L237"> boolean valueRepeating = serviceNonceCache.isNonceRepeatingForService(serviceEndpointName, username, userNameTokenPrincipal.getNonce());</span> |
| |
| <span class="nc bnc" id="L239" title="All 2 branches missed."> if (valueRepeating){</span> |
| <span class="nc" id="L240"> throw new RampartException("repeatingNonceValue", new Object[]{ userNameTokenPrincipal.getNonce(), username} );</span> |
| } |
| |
| <span class="nc" id="L243"> serviceNonceCache.addNonceForService(serviceEndpointName, username, userNameTokenPrincipal.getNonce(), nonceLifeTimeInSeconds);</span> |
| } |
| <span class="fc bfc" id="L245" title="All 2 branches covered."> } else if (WSConstants.SIGN == actInt) {</span> |
| <span class="fc" id="L246"> X509Certificate cert = (X509Certificate) wser.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE);</span> |
| |
| <span class="pc bpc" id="L248" title="1 of 8 branches missed."> if (rpd.isAsymmetricBinding() && cert == null && rpd.getInitiatorToken() != null</span> |
| && !rpd.getInitiatorToken().isDerivedKeys()) { |
| |
| // If symmetric binding is used, the certificate should be null. |
| // If certificate is not null then probably initiator and |
| // recipient are using 2 different bindings. |
| <span class="fc" id="L254"> throw new RampartException("invalidSignatureAlgo");</span> |
| } |
| |
| <span class="fc" id="L257"> msgCtx.setProperty(RampartMessageData.X509_CERT, cert);</span> |
| } |
| |
| } |
| |
| <span class="fc" id="L262"> SOAPEnvelope env = Axis2Util.getSOAPEnvelopeFromDOMDocument(rmd.getDocument(), true);</span> |
| |
| <span class="pc bpc" id="L264" title="1 of 2 branches missed."> if(dotDebug){</span> |
| <span class="nc" id="L265"> t2 = System.currentTimeMillis();</span> |
| } |
| |
| //Convert back to llom since the inflow cannot use DOOM |
| <span class="fc" id="L269"> msgCtx.setEnvelope(env);</span> |
| <span class="fc" id="L270"> Axis2Util.useDOOM(false);</span> |
| |
| <span class="fc" id="L272"> PolicyValidatorCallbackHandler validator = RampartUtil.getPolicyValidatorCB(msgCtx, rpd);</span> |
| |
| <span class="pc bpc" id="L274" title="1 of 2 branches missed."> if (validator instanceof ExtendedPolicyValidatorCallbackHandler) {</span> |
| <span class="fc" id="L275"> ExtendedPolicyValidatorCallbackHandler extendedPolicyValidatorCallbackHandler</span> |
| = (ExtendedPolicyValidatorCallbackHandler)validator; |
| <span class="fc" id="L277"> extendedPolicyValidatorCallbackHandler.validate(data,results);</span> |
| <span class="fc" id="L278"> } else {</span> |
| <span class="nc" id="L279"> Vector resultsVector = new Vector(results);</span> |
| <span class="nc" id="L280"> validator.validate(data, resultsVector);</span> |
| } |
| |
| |
| <span class="pc bpc" id="L284" title="1 of 2 branches missed."> if(dotDebug){</span> |
| <span class="nc" id="L285"> t3 = System.currentTimeMillis();</span> |
| <span class="nc" id="L286"> tlog.debug("processHeader by WSSecurityEngine took : " + (t1 - t0) +</span> |
| ", DOOM conversion took :" + (t2 - t1) + |
| ", PolicyBasedResultsValidattor took " + (t3 - t2)); |
| } |
| |
| <span class="fc" id="L291"> log.debug("Return process(MessageContext msgCtx)");</span> |
| <span class="fc" id="L292"> return results;</span> |
| } |
| |
| // Check whether this a soap fault because of failure in processing the security header |
| //and if so, we don't expect the security header |
| // |
| // |
| |
| |
| private boolean isSecurityFault(RampartMessageData rmd) { |
| <span class="fc" id="L302"> SOAPFault soapFault = rmd.getMsgContext().getEnvelope().getBody().getFault();</span> |
| <span class="fc bfc" id="L303" title="All 2 branches covered."> return soapFault == null ? false : RampartUtil.isSecurityFault(soapFault);</span> |
| } |
| } |
| </pre><div class="footer"><span class="right">Created with <a href="http://www.eclemma.org/jacoco">JaCoCo</a> 0.6.1.201212231917</span></div></body></html> |