Package org.apache.rampart.handler

Source Code of org.apache.rampart.handler.WSDoAllReceiver

/*
* 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.handler;

import org.apache.axiom.om.OMElement;
import org.apache.axiom.om.OMException;
import org.apache.axiom.soap.SOAPEnvelope;
import org.apache.axiom.soap.SOAPHeader;
import org.apache.axiom.soap.SOAPHeaderBlock;
import org.apache.axis2.AxisFault;
import org.apache.axis2.Constants;
import org.apache.axis2.addressing.AddressingConstants;
import org.apache.axis2.context.MessageContext;
import org.apache.axis2.context.OperationContext;
import org.apache.axis2.wsdl.WSDLConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.rampart.RampartConstants;
import org.apache.rampart.util.Axis2Util;
import org.apache.rampart.util.HandlerParameterDecoder;
import org.apache.rampart.util.RampartUtil;
import org.apache.ws.security.*;
import org.apache.ws.security.handler.RequestData;
import org.apache.ws.security.handler.WSHandlerConstants;
import org.apache.ws.security.handler.WSHandlerResult;
import org.apache.ws.security.message.token.Timestamp;
import org.apache.ws.security.util.WSSecurityUtil;
import org.w3c.dom.Document;

import javax.security.auth.callback.CallbackHandler;
import javax.xml.namespace.QName;

import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
* @deprecated
*/
public class WSDoAllReceiver extends WSDoAllHandler {

    private static final Log log = LogFactory.getLog(WSDoAllReceiver.class);
    private static Log mlog = LogFactory.getLog(RampartConstants.MESSAGE_LOG);

    public WSDoAllReceiver() {
        super();
        inHandler = true;
    }

    public void processMessage(MessageContext msgContext) throws AxisFault {
     
      if(mlog.isDebugEnabled()){
          mlog.debug("*********************** WSDoAllReceiver recieved \n"+msgContext.getEnvelope());
        }
     
        boolean doDebug = log.isDebugEnabled();

        if (doDebug) {
            log.debug("WSDoAllReceiver: enter invoke() ");
        }

        String useDoomValue = (String) getProperty(msgContext,
                WSSHandlerConstants.USE_DOOM);
        boolean useDoom = useDoomValue != null
                && Constants.VALUE_TRUE.equalsIgnoreCase(useDoomValue);

        RequestData reqData = new RequestData();
        try {

            this.processBasic(msgContext, useDoom, reqData);
        } catch (AxisFault axisFault) {
            setAddressingInformationOnFault(msgContext);
            throw axisFault;
        } catch (Exception e) {
            setAddressingInformationOnFault(msgContext);
            throw new AxisFault(e.getMessage(), e);
        } finally {

            if (reqData != null) {
                reqData.clear();
                reqData = null;
            }

            if (doDebug) {
                log.debug("WSDoAllReceiver: exit invoke()");
            }
        }

    }

    private void processBasic(MessageContext msgContext, boolean useDoom, RequestData reqData)
            throws Exception {

        // populate the properties
        try {
            HandlerParameterDecoder.processParameters(msgContext, true);
        } catch (Exception e) {
            throw new AxisFault("Configuration error", e);
        }

        // Retrieves signature crypto and set it to decryption crypto
        RampartUtil.setDecryptionCrypto(msgContext);

        reqData.setMsgContext(msgContext);

        if (((getOption(WSSHandlerConstants.INFLOW_SECURITY)) == null) &&
            ((getProperty(msgContext, WSSHandlerConstants.INFLOW_SECURITY)) == null)) {
           
            if (msgContext.isServerSide() &&
                ((getOption(WSSHandlerConstants.INFLOW_SECURITY_SERVER)) == null) &&
                ((getProperty(msgContext, WSSHandlerConstants.INFLOW_SECURITY_SERVER)) == null)) {
           
                return;
            } else if (((getOption(WSSHandlerConstants.INFLOW_SECURITY_CLIENT)) == null) &&
                    ((getProperty(msgContext, WSSHandlerConstants.INFLOW_SECURITY_CLIENT)) == null))  {
               
                return;
            }
        }
       
        List<java.lang.Integer> actions = new ArrayList<Integer>();
        String action = null;
        if ((action = (String) getOption(WSSHandlerConstants.ACTION_ITEMS)) == null) {
            action = (String) getProperty(msgContext,
                    WSSHandlerConstants.ACTION_ITEMS);
        }
        if (action == null) {
            throw new AxisFault("WSDoAllReceiver: No action items defined");
        }
        int doAction = WSSecurityUtil.decodeAction(action, actions);

        if (doAction == WSConstants.NO_SECURITY) {
            return;
        }

        String actor = (String) getOption(WSHandlerConstants.ACTOR);

        Document doc = null;

        try {
            doc = Axis2Util.getDocumentFromSOAPEnvelope(msgContext
                    .getEnvelope(), useDoom);
        } catch (WSSecurityException wssEx) {
            throw new AxisFault(
                    "WSDoAllReceiver: Error in converting to Document", wssEx);
        }

        // Do not process faults
        SOAPConstants soapConstants = WSSecurityUtil.getSOAPConstants(doc
                .getDocumentElement());
        if (WSSecurityUtil.findElement(doc.getDocumentElement(), "Fault",
                soapConstants.getEnvelopeURI()) != null) {
            return;
        }

        /*
         * To check a UsernameToken or to decrypt an encrypted message we need a
         * password.
         */
        CallbackHandler cbHandler = null;
        if ((doAction & (WSConstants.ENCR | WSConstants.UT)) != 0) {
            cbHandler = getPasswordCallbackHandler(reqData);
        }

        // Copy the WSHandlerConstants.SEND_SIGV over to the new message
        // context - if it exists, if signatureConfirmation in the response msg
        String sigConfEnabled = null;
        if ((sigConfEnabled = (String) getOption(WSHandlerConstants.ENABLE_SIGNATURE_CONFIRMATION)) == null) {
            sigConfEnabled = (String) getProperty(msgContext,
                    WSHandlerConstants.ENABLE_SIGNATURE_CONFIRMATION);
        }

        // To handle sign confirmation of a sync response
        // TODO Async response
        if (!msgContext.isServerSide()
                && !"false".equalsIgnoreCase(sigConfEnabled)) {
            OperationContext opCtx = msgContext.getOperationContext();
            MessageContext outMsgCtx = opCtx
                    .getMessageContext(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
            if (outMsgCtx != null) {
                msgContext.setProperty(WSHandlerConstants.SEND_SIGV, outMsgCtx
                        .getProperty(WSHandlerConstants.SEND_SIGV));
            } else {
                throw new WSSecurityException(
                        "Cannot obtain request message context");
            }
        }

        /*
         * Get and check the Signature specific parameters first because they
         * may be used for encryption too.
         */

        doReceiverAction(doAction, reqData);

        List<WSSecurityEngineResult> wsResult = null;
        try {
            wsResult = secEngine.processSecurityHeader(doc, actor, cbHandler,
                    reqData.getSigCrypto(), reqData.getDecCrypto());
        } catch (WSSecurityException ex) {
            throw new AxisFault("WSDoAllReceiver: security processing failed",
                    ex);
        }
        if (wsResult == null) { // no security header found
            if (doAction == WSConstants.NO_SECURITY) {
                return;
            } else {
                throw new AxisFault(
                        "WSDoAllReceiver: Incoming message does not contain required Security header");
            }
        }

        if (reqData.getWssConfig().isEnableSignatureConfirmation()
                && !msgContext.isServerSide()) {
            checkSignatureConfirmation(reqData, wsResult);
        }

        /**
         * Set the new SOAPEnvelope
         */

        msgContext.setEnvelope(Axis2Util.getSOAPEnvelopeFromDOMDocument(doc, useDoom));

        /*
         * After setting the new current message, probably modified because of
         * decryption, we need to locate the security header. That is, we force
         * Axis (with getSOAPEnvelope()) to parse the string, build the new
         * header. Then we examine, look up the security header and set the
         * header as processed.
         *
         * Please note: find all header elements that contain the same actor
         * that was given to processSecurityHeader(). Then check if there is a
         * security header with this actor.
         */
        SOAPHeader header = null;
        try {
            header = msgContext.getEnvelope().getHeader();
        } catch (OMException ex) {
            throw new AxisFault(
                    "WSDoAllReceiver: cannot get SOAP header after security processing",
                    ex);
        }

        Iterator headers = header.examineHeaderBlocks(actor);

        SOAPHeaderBlock headerBlock = null;

        while (headers.hasNext()) { // Find the wsse header
            SOAPHeaderBlock hb = (SOAPHeaderBlock) headers.next();
            if (hb.getLocalName().equals(WSConstants.WSSE_LN)
                    && hb.getNamespace().getNamespaceURI().equals(WSConstants.WSSE_NS)) {
                headerBlock = hb;
                break;
            }
        }

        if(headerBlock != null) {
            headerBlock.setProcessed();
        }

        /*
         * Now we can check the certificate used to sign the message. In the
         * following implementation the certificate is only trusted if either it
         * itself or the certificate of the issuer is installed in the keystore.
         *
         * Note: the method verifyTrust(X509Certificate) allows custom
         * implementations with other validation algorithms for subclasses.
         */

        // Extract the signature action result from the action list
        WSSecurityEngineResult actionResult = WSSecurityUtil.fetchActionResult(
                wsResult, WSConstants.SIGN);

        if (actionResult != null) {
            X509Certificate returnCert = (X509Certificate)actionResult.get(WSSecurityEngineResult.TAG_X509_CERTIFICATE);

            if (returnCert != null) {
                CertificateValidator certificateValidator = new CertificateValidator();

                if (!certificateValidator.validateCertificate(returnCert, reqData.getSigCrypto())) {
                    throw new AxisFault(
                            "WSDoAllReceiver: The certificate used for the signature is not trusted");
                }
            }
        }

        /*
         * Perform further checks on the timestamp that was transmitted in the
         * header. In the following implementation the timestamp is valid if it
         * was created after (now-ttl), where ttl is set on server side, not by
         * the client.
         *
         * Note: the method verifyTimestamp(Timestamp) allows custom
         * implementations with other validation algorithms for subclasses.
         */

        // Extract the timestamp action result from the action list
        actionResult = WSSecurityUtil.fetchActionResult(wsResult,
                WSConstants.TS);

        if (actionResult != null) {
            Timestamp timestamp = (Timestamp)actionResult.get(WSSecurityEngineResult.TAG_TIMESTAMP);

            if (timestamp != null) {
                String ttl = null;
                if ((ttl = (String) getOption(WSHandlerConstants.TTL_TIMESTAMP)) == null) {
                    ttl = (String) getProperty(msgContext,
                            WSHandlerConstants.TTL_TIMESTAMP);
                }
                int ttl_i = 0;
                if (ttl != null) {
                    try {
                        ttl_i = Integer.parseInt(ttl);
                    } catch (NumberFormatException e) {
                        ttl_i = reqData.getTimeToLive();
                    }
                }
                if (ttl_i <= 0) {
                    ttl_i = reqData.getTimeToLive();
                }

                // TODO configure future time to live
                if (!timestamp.verifyCreated(ttl_i, 60)) {
                    throw new AxisFault(
                            "WSDoAllReceiver: The timestamp could not be validated");
                }
            }
        }

        /*
         * now check the security actions: do they match, in right order?
         */
        if (!checkReceiverResults(wsResult, actions)) {
            throw new AxisFault(
                    "WSDoAllReceiver: security processing failed (actions mismatch)");

        }
        /*
         * All ok up to this point. Now construct and setup the security result
         * structure. The service may fetch this and check it. Also the
         * DoAllSender will use this in certain situations such as:
         * USE_REQ_SIG_CERT to encrypt
         */
        List<WSHandlerResult> results = null;
        if ((results = (List<WSHandlerResult>) getProperty(msgContext,
                WSHandlerConstants.RECV_RESULTS)) == null) {
            results = new ArrayList<WSHandlerResult>();
            msgContext.setProperty(WSHandlerConstants.RECV_RESULTS, results);
        }
        WSHandlerResult rResult = new WSHandlerResult(actor, wsResult);
        results.add(0, rResult);
    }

    private void setAddressingInformationOnFault(MessageContext msgContext) {
        SOAPEnvelope env = msgContext.getEnvelope();
        SOAPHeader header = env.getHeader();

        if (header != null) {
            OMElement msgIdElem = header.getFirstChildWithName(new QName(
                    AddressingConstants.Final.WSA_NAMESPACE,
                    AddressingConstants.WSA_MESSAGE_ID));
            if (msgIdElem == null) {
                msgIdElem = header.getFirstChildWithName(new QName(
                        AddressingConstants.Submission.WSA_NAMESPACE,
                        AddressingConstants.WSA_MESSAGE_ID));
            }
            if (msgIdElem != null && msgIdElem.getText() != null) {
                msgContext.getOptions().setMessageId(msgIdElem.getText());
            }
        }
    }

}
TOP

Related Classes of org.apache.rampart.handler.WSDoAllReceiver

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.