| /* |
| * 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.util; |
| |
| import org.apache.axiom.om.OMElement; |
| import org.apache.axis2.AxisFault; |
| import org.apache.axis2.context.MessageContext; |
| import org.apache.axis2.description.Parameter; |
| import org.apache.rampart.handler.WSSHandlerConstants; |
| import org.apache.rampart.handler.config.InflowConfiguration; |
| import org.apache.rampart.handler.config.OutflowConfiguration; |
| import org.apache.ws.security.WSSecurityException; |
| import org.apache.ws.security.handler.WSHandlerConstants; |
| |
| import javax.xml.namespace.QName; |
| |
| import java.util.Iterator; |
| |
| /** |
| * This is used to process the security parameters from the configuration files |
| * |
| * Example: <code> |
| <br> |
| |
| </code> |
| * |
| */ |
| public class HandlerParameterDecoder { |
| |
| /** |
| * |
| * @param msgCtx |
| * @param inflow |
| * @throws WSSecurityException |
| */ |
| public static void processParameters(MessageContext msgCtx, boolean inflow) |
| throws Exception { |
| Parameter inFlowSecParam; |
| Parameter outFlowSecParam; |
| |
| if(msgCtx.isServerSide()){ |
| inFlowSecParam = msgCtx.getParameter(WSSHandlerConstants.INFLOW_SECURITY_SERVER); |
| outFlowSecParam = msgCtx.getParameter(WSSHandlerConstants.OUTFLOW_SECURITY_SERVER); |
| }else{ |
| inFlowSecParam = msgCtx.getParameter(WSSHandlerConstants.INFLOW_SECURITY_CLIENT); |
| outFlowSecParam = msgCtx.getParameter(WSSHandlerConstants.OUTFLOW_SECURITY_CLIENT); |
| } |
| |
| //TODO: check whether policy is available |
| if(inFlowSecParam == null){ |
| inFlowSecParam = (Parameter)msgCtx.getProperty(WSSHandlerConstants.INFLOW_SECURITY); |
| } |
| |
| if(outFlowSecParam == null){ |
| outFlowSecParam = (Parameter)msgCtx.getProperty(WSSHandlerConstants.OUTFLOW_SECURITY); |
| } |
| |
| //If the configs are not available in the file |
| if(inFlowSecParam == null) { |
| inFlowSecParam = msgCtx.getParameter(WSSHandlerConstants.INFLOW_SECURITY); |
| } |
| if(outFlowSecParam == null) { |
| outFlowSecParam = msgCtx.getParameter(WSSHandlerConstants.OUTFLOW_SECURITY); |
| } |
| |
| int repetitionCount = -1; |
| |
| /* |
| * Populate the inflow parameters |
| */ |
| if (inFlowSecParam != null && inflow) { |
| OMElement inFlowParamElem = inFlowSecParam.getParameterElement(); |
| |
| OMElement actionElem = inFlowParamElem |
| .getFirstChildWithName(new QName(WSSHandlerConstants.ACTION)); |
| if (actionElem == null) { |
| throw new Exception( |
| "Inflow configuration must contain an 'action' " |
| + "elements the child of 'InflowSecurity' element"); |
| } |
| |
| Iterator childElements = actionElem.getChildElements(); |
| while (childElements.hasNext()) { |
| OMElement element = (OMElement) childElements.next(); |
| msgCtx.setProperty(element.getLocalName(), element.getText().trim()); |
| } |
| |
| } |
| |
| /* |
| * Populate the outflow parameters |
| */ |
| if (outFlowSecParam != null && !inflow) { |
| OMElement outFlowParamElem = outFlowSecParam.getParameterElement(); |
| |
| Iterator childElements = outFlowParamElem.getChildElements(); |
| while (childElements.hasNext()) { |
| OMElement element = (OMElement) childElements.next(); |
| |
| if(!element.getLocalName().equals(WSSHandlerConstants.ACTION)) { |
| throw new Exception( |
| "Alian element '" |
| + element.getLocalName() |
| + "' in the 'OutFlowSecurity' element, " |
| + "only 'action' elements can be present"); |
| } |
| |
| boolean signAllHeaders = false; |
| boolean signBody = false; |
| boolean encryptBody = false; |
| |
| repetitionCount++; |
| Iterator paramElements = element.getChildElements(); |
| while (paramElements.hasNext()) { |
| OMElement elem = (OMElement) paramElements.next(); |
| String localName = elem.getLocalName(); |
| String text = elem.getText().trim(); |
| if(localName.equals(WSSHandlerConstants.SIGN_ALL_HEADERS)) { |
| signAllHeaders = true; |
| } else if(localName.equals(WSSHandlerConstants.SIGN_BODY)) { |
| signBody = true; |
| } else if(localName.equals(WSSHandlerConstants.ENCRYPT_BODY)) { |
| encryptBody = true; |
| } else { |
| msgCtx.setProperty(Axis2Util.getKey(localName, |
| inflow,repetitionCount), text); |
| } |
| } |
| |
| if(signAllHeaders || signBody || encryptBody) { |
| handleSignEncrParts(signAllHeaders, signBody, encryptBody, |
| msgCtx, repetitionCount); |
| } |
| |
| |
| } |
| |
| msgCtx.setProperty(WSSHandlerConstants.SENDER_REPEAT_COUNT, |
| new Integer(repetitionCount)); |
| } |
| } |
| |
| public static OutflowConfiguration getOutflowConfiguration(Parameter outflowConfigParam) throws AxisFault { |
| if (outflowConfigParam != null) { |
| OMElement outflowParamElem = outflowConfigParam.getParameterElement(); |
| |
| OMElement actionElem = outflowParamElem |
| .getFirstChildWithName(new QName(WSSHandlerConstants.ACTION)); |
| if (actionElem == null) { |
| throw new AxisFault( |
| "Inflow configuration must contain an 'action' " |
| + "elements the child of 'InflowSecurity' element"); |
| } |
| |
| OutflowConfiguration outflowConfiguration = new OutflowConfiguration(); |
| |
| Iterator childElements = actionElem.getChildElements(); |
| while (childElements.hasNext()) { |
| OMElement element = (OMElement) childElements.next(); |
| |
| String localName = element.getLocalName(); |
| String text = element.getText().trim(); |
| if(localName.equals(WSHandlerConstants.PW_CALLBACK_CLASS)) { |
| outflowConfiguration.setPasswordCallbackClass(text); |
| } else if(localName.equals(WSHandlerConstants.SIG_PROP_FILE)) { |
| outflowConfiguration.setSignaturePropFile(text); |
| } else if(localName.equals(WSHandlerConstants.ENC_PROP_FILE)) { |
| outflowConfiguration.setEncryptionPropFile(text); |
| } else if(localName.equals(WSHandlerConstants.ENC_CALLBACK_CLASS)) { |
| outflowConfiguration.setEmbeddedKeyCallbackClass(text); |
| } else if(localName.equals(WSHandlerConstants.USER)) { |
| outflowConfiguration.setUser(text); |
| } else if(localName.equals(WSHandlerConstants.ENCRYPTION_USER)) { |
| outflowConfiguration.setEncryptionUser(text); |
| } |
| } |
| return outflowConfiguration; |
| } |
| return null; |
| } |
| |
| public static InflowConfiguration getInflowConfiguration(Parameter inflowConfigParam) throws AxisFault { |
| |
| if (inflowConfigParam != null) { |
| OMElement inFlowParamElem = inflowConfigParam.getParameterElement(); |
| |
| OMElement actionElem = inFlowParamElem |
| .getFirstChildWithName(new QName(WSSHandlerConstants.ACTION)); |
| if (actionElem == null) { |
| throw new AxisFault( |
| "Inflow configuration must contain an 'action' " |
| + "elements the child of 'InflowSecurity' element"); |
| } |
| |
| InflowConfiguration inflowConfiguration = new InflowConfiguration(); |
| |
| Iterator childElements = actionElem.getChildElements(); |
| while (childElements.hasNext()) { |
| OMElement element = (OMElement) childElements.next(); |
| |
| String localName = element.getLocalName(); |
| String text = element.getText().trim(); |
| |
| if(localName.equals(WSHandlerConstants.PW_CALLBACK_CLASS)) { |
| inflowConfiguration.setPasswordCallbackClass(text); |
| } else if(localName.equals(WSHandlerConstants.SIG_PROP_FILE)) { |
| inflowConfiguration.setSignaturePropFile(text); |
| } else if(localName.equals(WSHandlerConstants.DEC_PROP_FILE)) { |
| inflowConfiguration.setDecryptionPropFile(text); |
| } else if (WSHandlerConstants.ENABLE_SIGNATURE_CONFIRMATION |
| .equals(localName)) { |
| if ("false".equals(text) |
| || "0".equals(text)) { |
| inflowConfiguration |
| .setEnableSignatureConfirmation(false); |
| } |
| } |
| } |
| return inflowConfiguration; |
| } |
| return null; |
| } |
| |
| private static void handleSignEncrParts(boolean signAllHeaders, |
| boolean signBody, boolean encrBody, MessageContext msgCtx, |
| int repetition) { |
| String soapNs = msgCtx.getEnvelope().getNamespace().getNamespaceURI(); |
| if(signBody) { |
| //Add body signPart |
| String sigBodySigPart = "{Element}{" + soapNs + "}Body"; |
| addSigPart(sigBodySigPart, msgCtx, repetition); |
| } |
| if(encrBody) { |
| //Encrypt body content |
| String encrBodyEncrPart = "{}{" + soapNs + "}Body"; |
| addEncrPart(encrBodyEncrPart, msgCtx, repetition); |
| } |
| if(signAllHeaders) { |
| Iterator children = msgCtx.getEnvelope().getHeader().getChildElements(); |
| while (children.hasNext()) { |
| OMElement element = (OMElement) children.next(); |
| //Sign only the qualified headers |
| //TODO check whether we can sign the unqualified header elements |
| String ns = element.getNamespace().getNamespaceURI(); |
| if(ns != null && ns.length() > 0) { |
| addSigPart("{Element}{" + ns + "}" + element.getLocalName(),msgCtx, repetition); |
| } |
| } |
| } |
| |
| } |
| |
| private static void addSigPart(String sigPart, MessageContext msgCtx, int repetition) { |
| String key = Axis2Util.getKey(WSHandlerConstants.SIGNATURE_PARTS, false, repetition); |
| String existingSignParts = (String) msgCtx.getProperty(key); |
| if (existingSignParts != null && existingSignParts.length() > 0) { |
| // If the part is not already there as a sign part |
| if (existingSignParts.indexOf(sigPart) != -1) { |
| msgCtx.setProperty(key, existingSignParts + ";" + sigPart); |
| } |
| } else { |
| // If there are no signed parts |
| msgCtx.setProperty(key, sigPart); |
| } |
| } |
| |
| private static void addEncrPart(String encrPart, MessageContext msgCtx, int repetition) { |
| String key = Axis2Util.getKey(WSHandlerConstants.ENCRYPTION_PARTS, false, repetition); |
| String existingEncrParts = (String) msgCtx.getProperty(key); |
| if (existingEncrParts != null && existingEncrParts.length() > 0) { |
| if (existingEncrParts.indexOf(encrPart) != -1) { |
| msgCtx.setProperty(key, existingEncrParts + ";" + encrPart); |
| } |
| } else { |
| msgCtx.setProperty(key, encrPart); |
| } |
| } |
| |
| } |