Package org.apache.ws.sandbox.axis.security.conversation

Source Code of org.apache.ws.sandbox.axis.security.conversation.ConversationServerHandler

/*
* Copyright  2003-2004 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.ws.sandbox.axis.security.conversation;

import org.apache.axis.AxisFault;
import org.apache.axis.Message;
import org.apache.axis.MessageContext;
import org.apache.axis.SOAPPart;
import org.apache.axis.handlers.BasicHandler;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ws.security.SOAPConstants;
import org.apache.ws.security.WSConstants;
import org.apache.ws.security.WSEncryptionPart;
import org.apache.ws.security.WSSConfig;
import org.apache.ws.sandbox.security.conversation.*;
import org.apache.ws.sandbox.security.conversation.message.info.DerivedKeyInfo;
import org.apache.ws.sandbox.security.conversation.message.token.SecurityContextToken;
import org.apache.ws.security.handler.WSHandlerConstants;
import org.apache.ws.security.message.token.Reference;
import org.apache.ws.security.message.token.SecurityTokenReference;
import org.apache.ws.security.transform.STRTransform;
import org.apache.ws.security.util.StringUtil;
import org.apache.ws.security.util.WSSecurityUtil;
import org.apache.xml.security.transforms.Transform;
import org.apache.xml.security.utils.XMLUtils;
import org.w3c.dom.Document;
import org.w3c.dom.Element;

import javax.xml.soap.SOAPHeader;
import javax.xml.soap.SOAPHeaderElement;
import java.io.ByteArrayOutputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Stack;
import java.util.Vector;

/**
* Serverside handler that implements WS-Secure Conversation for Axis.
*
*
* @author Dimuthu Leealarthne. (muthulee@yahoo.com)
*
*/
public class ConversationServerHandler extends BasicHandler {
    private static Log log =
            LogFactory.getLog(ConversationServerHandler.class.getName());
    private boolean doDebug = false;

    private static DerivedKeyCallbackHandler dkcbHandler =
            new DerivedKeyCallbackHandler();

    private static boolean isConfigured = false;
    private SOAPConstants soapConstants = null;

    private HashMap configurator = new HashMap();

    private int[] actionsInt = null;

    private boolean isSessionInfoConfigured = false;

    private boolean isInitTrustVerified = false;

    private Vector sigParts=null;
    private Vector encParts=null;

    private int keyLen =-1;

    public ConversationServerHandler() {
        log.debug("ConversationServerHandler :: created");
    }

    /**
     * Method inherited from the BasicHandler.
     * If in the request flow calls the doRequestMetod()
     * else calls the doResponse() method.
     *
     */
    public void invoke(MessageContext msg) throws AxisFault {
        log.debug("ConversationServerHandler :: invoked");

        if (msg.getPastPivot())
            doResponse(msg);
        else
            doRequest(msg);
    }

    /**
     * Called in the request flow of the request.
     * Method looks for a SecurityToken in the SOAP envelope.
     * Process the header.
     *
     *  @param msg
     * @throws AxisFault
     */
    private void doRequest(MessageContext msg) throws AxisFault {
        if(!isSessionInfoConfigured){
            initSessionInfo();
            isSessionInfoConfigured = true;
        }


        Document doc = null;
        Message message = msg.getCurrentMessage();

        // Get the soap message as a Docuemnt
        SOAPPart sPart = (org.apache.axis.SOAPPart) message.getSOAPPart();
        try {
            doc =
                    ((org.apache.axis.message.SOAPEnvelope) sPart.getEnvelope())
                    .getAsDocument();
        } catch (Exception e) {
            e.printStackTrace();
        }

//    if((this.configurator = (HashMap)msg.getProperty("PolicyObject"))==null){
//      log.debug("ConversationServerHandler :: I am configuring");
//           initSessionInfo(); // load values to this.configurator from wsdd
//    }

        soapConstants = WSSecurityUtil.getSOAPConstants(doc.getDocumentElement());
        ConversationEngine eng = new ConversationEngine(this.configurator);

//    try {
//            boolean trustEngineResult = false;
//                if(!isInitTrustVerified){
//                String tmpStr = null;
//                  if ((tmpStr = (String) getOption(ConvHandlerConstants.TOKEN_TRUST_VERIFY))
//                        != null) {
//                  if(Boolean.getBoolean(tmpStr)){
//                    String trustPropFile = (String) getOption(ConvHandlerConstants.TRUST_ENGINE_PROP);
//                    TrustEngine trstEngine = new TrustEngine(trustPropFile);
//                    System.out.println("call the engine here ...");
//                    trustEngineResult=true;
//                  }
//                  isInitTrustVerified = true;
//                        }
//                }
//            if(trustEngineResult){
//                 //getUUID and proof of possession
//                 //add it to the derived key token
//            }
//        } catch (WSTrustException e2) {
//            // TODO Auto-generated catch block
//            e2.printStackTrace();
//        }



        try {
            Vector results = eng.processSecConvHeader(doc, "", dkcbHandler, (String)this.configurator.get(WSHandlerConstants.PW_CALLBACK_CLASS));
            ConvEngineResult convResult  = null;
            String uuid = "";

            /*put the actions into a stack to obtain LIFO behavior
            * Rational for using the stack;
            *
            * Consider "Signature Encrypt"
            * Then the ConvEngine Results will be in the order "Encrypt Signature"
            * i.e. ConvEngine reusult containing ConvEngineResult.ENCRYPT_DERIVED_KEY
            * will be before ConvEngineResult.SIGN_DERIVED_KEY
            *
            * Hense I need to read actions in the order of Last in First out - the stack
            *
            * This is same for "Encrypt Signature" visa versa.
            */
            Stack stk = new Stack();
            for(int i=0; i<actionsInt.length ; i++){
                stk.push(new Integer(actionsInt[i]));
            }
            int act = -1;
            boolean rstr = false;
            for(int i=0; i<results.size(); i++){
                convResult=(ConvEngineResult)results.get(i);

                switch(convResult.getAction()){

                    case ConvEngineResult.SECURITY_TOKEN_RESPONSE :
                        log.debug("ConversationServerHandler :: Found RSTR result");
                        uuid = convResult.getUuid();
                        rstr = true;
                        break;

                    case ConvEngineResult.ENCRYPT_DERIVED_KEY :
                        log.debug("ConversationServerHandler :: Found dk_encrypt result");
//            if(stk.isEmpty()){
//              throw new AxisFault("Action mismatch");
//            }
//
//            act =((Integer)stk.pop()).intValue();
//            if(act == ConversationConstants.DK_ENCRYPT){
//              //fine do nothing
//            }else{
//              throw new AxisFault("Mismatch action order");
//            }
                        break;

                    case ConvEngineResult.SIGN_DERIVED_KEY :
                        log.debug("ConversationServerHandler :: Found dk_sign result");
//          if(stk.isEmpty()){
//            throw new AxisFault("Action mismatch");
//          }
//          act =((Integer)stk.pop()).intValue();
//          if(act == ConversationConstants.DK_SIGN){
//              //fine do nothing
//          }else{
//            throw new AxisFault("Mismatch action order");
//          }
                        break;

                    case ConvEngineResult.SCT :
                        log.debug("ConversationServerHandler :: Found SCT result");
                        uuid = convResult.getUuid();
                        break;

                }
            }

            if(uuid.equals("")||(uuid==null)){
                //throw new AxisFault("ConversationServerHandler :: Cannot find Session.");
            }else{
                msg.setProperty(ConversationConstants.IDENTIFIER,uuid);
            }

//
//        if(!rstr){
//        if(!stk.isEmpty()){
//        throw new AxisFault("Action mismatch. Required action missing");
//      }
//            }


        } catch (ConversationException e1) {
            e1.printStackTrace();
            throw new AxisFault("CovnersationServerHandler :: "+e1.getMessage());
        }



        // Replace sPart with the new sPart.
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        XMLUtils.outputDOM(doc, os, true);
        String osStr = os.toString();
        sPart.setCurrentMessage(osStr, SOAPPart.FORM_STRING);

        //Following sets the headers as processed.
        SOAPHeader sHeader = null;
        try {
            sHeader = message.getSOAPEnvelope().getHeader();
        } catch (Exception ex) {
            throw new AxisFault(
                    "ConversatonServerHandler: cannot get SOAP header after security processing",
                    ex);
        }
        String actor = null;
        Iterator headers = sHeader.examineHeaderElements(actor);

        SOAPHeaderElement headerElement = null;
        while (headers.hasNext()) {
            SOAPHeaderElement hE = (SOAPHeaderElement) headers.next();
            if (hE.getLocalName().equals(WSConstants.WSSE_LN)
                    && hE.getNamespaceURI().equals(WSConstants.WSSE_NS)) {
                headerElement = hE;
                break;
            }
        }
        (
                (
                org
                .apache
                .axis
                .message
                .SOAPHeaderElement) headerElement)
                .setProcessed(
                        true);

        msg.setProperty(ConvHandlerConstants.DK_CB_HANDLER,dkcbHandler);
    } //do request

    /**
     * This method is called in the response.
     * This method should
     * 1) Add derived keys to the message as required.
     * 2) Sign/encrypt as required.
     *
     * @param msg
     * @throws AxisFault
     */
    private void doResponse(MessageContext msg) throws AxisFault {

        if(!isSessionInfoConfigured){
            initSessionInfo();
            isSessionInfoConfigured = true;
        }

        //System.out.println("Doing response .... ");
        Document doc = null;
        Message message = msg.getCurrentMessage();
        String uuid, identifier;
        //  Code to get the soap message as a Docuemnt
        SOAPPart sPart = (org.apache.axis.SOAPPart) message.getSOAPPart();

        try {
            if ((doc = (Document) msg.getProperty(WSHandlerConstants.SND_SECURITY))
                    == null) {
                doc =
                        ((org.apache.axis.message.SOAPEnvelope) sPart.getEnvelope())
                        .getAsDocument();
            }
        } catch (Exception e) {
            e.printStackTrace();
            throw new AxisFault("CovnersationServerHandler :: "+e.getMessage());
        }

        //get the uuid
        uuid = (String) msg.getProperty(ConversationConstants.IDENTIFIER);

        if (uuid == null) {
            //TODO :: throw exception
            System.out.println("UUID NULl line :: 346");
        }


        try {
            ConversationSession session = dkcbHandler.getSession(uuid);

            if(session.isAddBase2Message()){
                //add the relavent SCT
                Element securityHeader =
                        WSSecurityUtil.findWsseSecurityHeaderBlock(
                                doc,
                                doc.getDocumentElement(),
                                true);
                WSSecurityUtil.appendChildElement(
                        doc,
                        securityHeader,
                        (new SecurityContextToken(doc, uuid)).getElement());
            }

            ConversationManager manager = new ConversationManager();

            for (int i = 0; i < this.actionsInt.length; i++) {

                // Derrive the token
                SecurityTokenReference stRef2Base = null;
                if(session.getRef2Base()==null){
                    //do nothing
                }else{
                    stRef2Base = new SecurityTokenReference(doc);
                    Reference ref = new Reference(doc);
                    Reference oldRef = session.getRef2Base();

                    ref.setURI(oldRef.getURI());
                    ref.setValueType(oldRef.getValueType());
                    stRef2Base.setReference(ref);
                }
                DerivedKeyInfo dkInfo =
                        manager.createDerivedKeyToken(doc, uuid, dkcbHandler,stRef2Base, keyLen);

                String genID = dkInfo.getId();
                SecurityTokenReference stRef =
                        dkInfo.getSecTokRef2DkToken();

                if (actionsInt[i] == ConversationConstants.DK_ENCRYPT) {
                    manager.performDK_ENCR(
                            ConversationUtil.generateIdentifier(uuid, genID),
                            "",
                            true,
                            doc,
                            stRef,
                            dkcbHandler, this.encParts, (String)this.configurator.get(ConvHandlerConstants.DK_ENC_ALGO));

                } else if(actionsInt[i]==ConversationConstants.DK_SIGN){
                    //TODO
                    manager.performDK_Sign(doc, dkcbHandler, uuid, dkInfo,this.sigParts);
                }

                manager.addDkToken(doc,dkInfo);

            }
        } catch (ConversationException e1) {
            e1.printStackTrace();
            throw new AxisFault(
                    "ConversationClientHandler ::" + e1.getMessage());
        }

        //set it as current message
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        XMLUtils.outputDOM(doc, os, true);
        String osStr = os.toString();
        sPart.setCurrentMessage(osStr, SOAPPart.FORM_STRING);


    } //doResponse

    /**
     * Conversation parameters are read from the wsdd file.
     * When WS-Policy is implemented, these parameters should be
     * configurable using policy components.
     *
     * @throws AxisFault
     */
    /**
     * Reads configeration parameters from the wsdd file.
     * @throws AxisFault
     */
    private void initSessionInfo() throws AxisFault {
        /**
         * Default values for a session. These will be overriden by WSDD file parameters.
         */
        this.configurator = new HashMap();
        String tmpStr;
        if ((tmpStr = (String) getOption(ConvHandlerConstants.KEY_FREQ))
                != null) {
            log.debug("Key Frequency is set ::" + tmpStr);
            this.configurator.put(
                    ConvHandlerConstants.KEY_FREQ,
                    new Integer(tmpStr));
        }

        if ((tmpStr = (String) getOption(ConvHandlerConstants.DK_ACTION))
                != null) {
            log.debug("Derived Key Action is read ::" + tmpStr);
            String[] action = StringUtil.split(tmpStr, ' ');
            actionsInt = new int[action.length];

            for (int i = 0; i < action.length; i++) {
                if ((action[i]).equalsIgnoreCase("Signature")) {
                    actionsInt[i] = ConversationConstants.DK_SIGN;
                } else if ((action[i]).equalsIgnoreCase("Encrypt")) {
                    actionsInt[i] = ConversationConstants.DK_ENCRYPT;
                }
            }

        }

        if ((tmpStr =
                (String) getOption(ConvHandlerConstants.SEVER_PROP_FILE))
                != null) {
            this.configurator.put(ConvHandlerConstants.SEVER_PROP_FILE, tmpStr);
        }


        if ((tmpStr =
                (String) getOption(ConvHandlerConstants.KEY_LEGNTH))
                != null) {
            log.debug("Key Frequency is set ::" + tmpStr);
            this.keyLen=Integer.parseInt(tmpStr);
            this.configurator.put(ConvHandlerConstants.KEY_LEGNTH, new Long(tmpStr));
        }


        if ((tmpStr =
                (String) getOption(WSHandlerConstants.PW_CALLBACK_CLASS))
                != null) {
            this.configurator.put(WSHandlerConstants.PW_CALLBACK_CLASS, tmpStr);
        }else{
            log.debug("Set the pass word call back class.");
        }

        if ((tmpStr =
                (String) getOption(WSHandlerConstants.SIGNATURE_PARTS))
                != null) {
            this.sigParts = new Vector();
            this.splitEncParts(tmpStr,sigParts);
        }

        if ((tmpStr =(String) getOption(WSHandlerConstants.ENCRYPTION_PARTS))
                != null) {
            this.encParts = new Vector();
            this.splitEncParts(tmpStr,encParts);
        }



        if((tmpStr =(String) getOption(WSHandlerConstants.DEC_PROP_FILE))!= null) {
            this.configurator.put(WSHandlerConstants.DEC_PROP_FILE, tmpStr);
            System.out.println("Decryption properties read");
        }

        if((tmpStr =(String) getOption(ConvHandlerConstants.DK_ENC_ALGO))!= null) {
            this.configurator.put(ConvHandlerConstants.DK_ENC_ALGO, tmpStr);
        }





    }


    /**
     * Extracted from the class <code>org.apache.ws.axis.security.WSDoAllSender.java</code>.
     *
     * @param tmpS
     * @param encryptParts
     * @throws AxisFault
     */
    private void splitEncParts(String tmpS, Vector encryptParts)
            throws AxisFault {

        WSEncryptionPart encPart = null;
        String[] rawParts = StringUtil.split(tmpS, ';');

        for (int i = 0; i < rawParts.length; i++) {
            String[] partDef = StringUtil.split(rawParts[i], '}');

            if (partDef.length == 1) {
                if (doDebug) {
                    log.debug("single partDef: '" + partDef[0] + "'");
                }
                encPart =
                        new WSEncryptionPart(
                                partDef[0].trim(),
                                soapConstants.getEnvelopeURI(),
                                "Content");
            } else if (partDef.length == 3) {
                String mode = partDef[0].trim();
                if (mode.length() <= 1) {
                    mode = "Content";
                } else {
                    mode = mode.substring(1);
                }
                String nmSpace = partDef[1].trim();
                if (nmSpace.length() <= 1) {
                    nmSpace = soapConstants.getEnvelopeURI();
                } else {
                    nmSpace = nmSpace.substring(1);
                }
                String element = partDef[2].trim();
                if (doDebug) {
                    log.debug(
                            "partDefs: '"
                            + mode
                            + "' ,'"
                            + nmSpace
                            + "' ,'"
                            + element
                            + "'");
                }
                encPart = new WSEncryptionPart(element, nmSpace, mode);
            } else {
                throw new AxisFault(
                        "WSDoAllSender: wrong part definition: " + tmpS);
            }
            encryptParts.add(encPart);
        }
    }
}
TOP

Related Classes of org.apache.ws.sandbox.axis.security.conversation.ConversationServerHandler

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.