Package org.nimbustools.messaging.gt4_0_elastic.rpc

Source Code of org.nimbustools.messaging.gt4_0_elastic.rpc.RequestEngine

/*
* Copyright 1999-2008 University of Chicago
*
* 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.nimbustools.messaging.gt4_0_elastic.rpc;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.security.WSSConfig;
import org.apache.ws.security.message.token.Timestamp;
import org.globus.wsrf.Resource;
import org.globus.wsrf.ResourceContext;
import org.globus.wsrf.ResourceContextException;
import org.globus.wsrf.ResourceException;
import org.globus.wsrf.impl.security.authentication.wssec.ReplayAttackFilter;
import org.globus.wsrf.impl.security.authentication.wssec.WSSecurityEngine;
import org.globus.wsrf.impl.security.authentication.wssec.WSSecurityException;
import org.globus.wsrf.impl.security.authentication.wssec.WSSecurityRequestEngine;
import org.globus.wsrf.impl.security.descriptor.SecurityPropertiesHelper;
import org.globus.wsrf.utils.ContextUtils;
import org.w3c.dom.Element;
import org.w3c.dom.Node;

import javax.xml.rpc.handler.MessageContext;
import javax.xml.rpc.handler.soap.SOAPMessageContext;
import javax.xml.soap.SOAPHeaderElement;
import java.text.ParseException;
import java.text.SimpleDateFormat;

public class RequestEngine extends WSSecurityRequestEngine {

    // -------------------------------------------------------------------------
    // STATIC VARIABLES
    // -------------------------------------------------------------------------

    private static final Log logger =
            LogFactory.getLog(RequestEngine.class.getName());

    protected static final SimpleDateFormat problematicFormat =
                new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");

    private static WSSecurityEngine engine;
   
   
    // -------------------------------------------------------------------------
    // overrides WSSecurityRequestEngine
    // -------------------------------------------------------------------------

    public synchronized static WSSecurityEngine getEngine() {
        if (engine == null) {
            engine = new RequestEngine();
        }

        return engine;
    }


    // -------------------------------------------------------------------------
    // overrides WSSecurityEngine
    // -------------------------------------------------------------------------
   
    /**
     * Overrides processTimestampHeader in WSSecurityEngine
     *
     * The secmsg Timestamp constructor fails on timestamps with milliseconds
     * in them.
     *
     * Since this is handled after the envelope integrity check, it's OK to
     * replace the timestamp if necessary (this allows the the constructor to
     * succeed and attack window analysis to proceed).
     *
     * @param givenTimestampElem timestampElem from soap
     * @param msgCtx msgCtx
     * @param messageIDHeader messageIDHeader
     * @throws Exception problem
     * @see #perhapsChangeTimestampFormat(Element);
     */
    protected void processTimestampHeader(Element givenTimestampElem,
                                          MessageContext msgCtx,
                                          SOAPHeaderElement messageIDHeader)
        throws Exception {

        final String servicePath =
                ContextUtils.getTargetServicePath(
                        (org.apache.axis.MessageContext)msgCtx);
       
        if (servicePath == null) {
            throw new Exception(i18n.getMessage("serviceNull"));
        }

        Resource resource = null;
        try {
            final ResourceContext resCtx = ResourceContext
                .getResourceContext((SOAPMessageContext) msgCtx);
            resource = resCtx.getResource();
        } catch (ResourceContextException exp) {
            // Not an issue
        } catch (ResourceException exp) {
            // Not an issue
        }

        if (givenTimestampElem != null) {

            final Element timestampElem =
                this.perhapsChangeTimestampFormat(givenTimestampElem);

            final String propertyValue =
                SecurityPropertiesHelper.getReplayAttackWindow(servicePath,
                                                               resource);
            final ReplayAttackFilter replayFilter =
                ReplayAttackFilter.getInstance(propertyValue);

            if (messageIDHeader == null) {
                final Timestamp timestamp =
                    new Timestamp(WSSConfig.getDefaultWSConfig(),
                                  timestampElem);
                final boolean stampOk =
                    verifyTimestamp(timestamp,
                                    replayFilter.getMessageWindow());
                if (!stampOk) {
                    throw new WSSecurityException(WSSecurityException.FAILURE,
                                                  "timestampNotOk");
                }
            } else {
                checkMessageValidity(replayFilter, timestampElem,
                                     messageIDHeader);
            }
        } else {
            final String propertyValue =
                SecurityPropertiesHelper.getReplayAttackFilter(servicePath,
                                                               resource);
            if (rejectMsgSansTimestampHeader(msgCtx, propertyValue)) {
                logger.debug("Required time stamp header was not added.");
                throw new WSSecurityException(WSSecurityException.FAILURE,
                                              "timestampRequired");
            }
        }
    }


    // -------------------------------------------------------------------------
    // TIMESTAMP CHANGES
    // -------------------------------------------------------------------------
   
    protected Element perhapsChangeTimestampFormat(Element timestampElem)
            throws Exception {

        if (timestampElem == null) {
            throw new Exception("timestampElem may not be null");
        }

        final Node firstChild = timestampElem.getFirstChild();
        if (firstChild == null) {
            logger.warn("Timestamp but no data enclosed?");
            return timestampElem;
        }

        final String firstChildLocal = firstChild.getLocalName();
        if (firstChildLocal != null && firstChildLocal.equals("Created")) {

            if (firstChildLocal.equals("Created")) {
                this.handleCreatedOrExpires(firstChild, "Created");
            } else {
                logger.warn("Timestamp with something besides " +
                        "Created: '" + firstChildLocal + "'");
                return timestampElem;
            }

            final Node sibling = firstChild.getNextSibling();
            if (sibling == null) {
                logger.warn("Timestamp with Created but no Expires?");
                return timestampElem;
            }

            final String siblingLocal = sibling.getLocalName();
            if (siblingLocal != null && siblingLocal.equals("Expires")) {
                this.handleCreatedOrExpires(sibling, "Expires");
            } else {
                logger.warn("Timestamp with Created but no Expires?");
                logger.warn("Timestamp with Created and then something " +
                        "besides Expires: '" + siblingLocal + "'");
                return timestampElem;
            }
        }

        return timestampElem;
    }

    protected void handleCreatedOrExpires(Node node, String name) {

        final Node firstChild = node.getFirstChild();
        final String firstChildNodeValue = firstChild.getNodeValue();
       
        if (firstChildNodeValue == null) {
            logger.warn("Timestamp with null value for " + name);
        } else {
            final String newValue = this.chop(firstChildNodeValue);
            if (newValue != null) {
                firstChild.setNodeValue(newValue);
            }
        }
    }

    protected String chop(String stamp) {

        try {
            problematicFormat.parse(stamp);
        } catch (ParseException e) {
            // not in the problematic format
            return null; // *** EARLY RETURN ***
        }

        // remove milliseconds, Timestamp class wants "yyyy-MM-ddTHH:mm:ssZ"
        // and the problematic one looks like "yyyy-MM-ddTHH:mm:ss.SSSZ"

        // get first 19 characters then tack on Z
        final String prefix = stamp.substring(0, 19);
        return prefix + 'Z';
    }
}
TOP

Related Classes of org.nimbustools.messaging.gt4_0_elastic.rpc.RequestEngine

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.