From 1d39a4fa10f410c5d4fdcc64413b9e0f0372f9e1 Mon Sep 17 00:00:00 2001 From: gregor Date: Wed, 3 Dec 2003 08:54:36 +0000 Subject: Zwischenstand, compilierbar git-svn-id: https://joinup.ec.europa.eu/svn/moa-idspss/trunk@69 d688527b-c9ab-4aba-bd8d-4036d912da1d --- spss.slinterface/.classpath | 4 +- .../WEB-INF/lib/xerces-2.4.0/xercesImpl-2.4.0.jar | Bin 927669 -> 0 bytes .../lib/xerces-2.4.0/xmlParserAPIs-2.4.0.jar | Bin 123705 -> 0 bytes .../lib/xerces-2.6.0exBug24783/xercesImpl.jar | Bin 0 -> 957657 bytes .../lib/xerces-2.6.0exBug24783/xmlParserAPIs.jar | Bin 0 -> 124724 bytes .../moa/spss/slinterface/Constants.java | 4 + .../egovernment/moa/spss/slinterface/DOMUtils.java | 43 +++ .../moa/spss/slinterface/XPathUtils.java | 162 +++++++++ .../moa/spss/slinterface/beans/DataInfoBean.java | 366 ++++++++++++++++++++- .../spss/slinterface/beans/HashInputDataInfo.java | 55 ++++ .../moa/spss/slinterface/filters/SL2MOAFilter.java | 16 +- .../slinterface/listeners/ContextListener.java | 13 +- .../listeners/XMLParserErrorHandler.java | 65 ++++ spss.slinterface/constraints.txt | 4 +- .../res/resources/properties/init.properties | 1 + spss.slinterface/res/resources/schemas/xml.xsd | 2 +- 16 files changed, 715 insertions(+), 20 deletions(-) delete mode 100644 spss.slinterface/WEB-INF/lib/xerces-2.4.0/xercesImpl-2.4.0.jar delete mode 100644 spss.slinterface/WEB-INF/lib/xerces-2.4.0/xmlParserAPIs-2.4.0.jar create mode 100644 spss.slinterface/WEB-INF/lib/xerces-2.6.0exBug24783/xercesImpl.jar create mode 100644 spss.slinterface/WEB-INF/lib/xerces-2.6.0exBug24783/xmlParserAPIs.jar create mode 100644 spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/XPathUtils.java create mode 100644 spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/beans/HashInputDataInfo.java create mode 100644 spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/listeners/XMLParserErrorHandler.java diff --git a/spss.slinterface/.classpath b/spss.slinterface/.classpath index 8c14ea4ef..99f657d27 100644 --- a/spss.slinterface/.classpath +++ b/spss.slinterface/.classpath @@ -15,7 +15,7 @@ - - + + diff --git a/spss.slinterface/WEB-INF/lib/xerces-2.4.0/xercesImpl-2.4.0.jar b/spss.slinterface/WEB-INF/lib/xerces-2.4.0/xercesImpl-2.4.0.jar deleted file mode 100644 index 99cc23f2a..000000000 Binary files a/spss.slinterface/WEB-INF/lib/xerces-2.4.0/xercesImpl-2.4.0.jar and /dev/null differ diff --git a/spss.slinterface/WEB-INF/lib/xerces-2.4.0/xmlParserAPIs-2.4.0.jar b/spss.slinterface/WEB-INF/lib/xerces-2.4.0/xmlParserAPIs-2.4.0.jar deleted file mode 100644 index 6ba4ff805..000000000 Binary files a/spss.slinterface/WEB-INF/lib/xerces-2.4.0/xmlParserAPIs-2.4.0.jar and /dev/null differ diff --git a/spss.slinterface/WEB-INF/lib/xerces-2.6.0exBug24783/xercesImpl.jar b/spss.slinterface/WEB-INF/lib/xerces-2.6.0exBug24783/xercesImpl.jar new file mode 100644 index 000000000..02250b0af Binary files /dev/null and b/spss.slinterface/WEB-INF/lib/xerces-2.6.0exBug24783/xercesImpl.jar differ diff --git a/spss.slinterface/WEB-INF/lib/xerces-2.6.0exBug24783/xmlParserAPIs.jar b/spss.slinterface/WEB-INF/lib/xerces-2.6.0exBug24783/xmlParserAPIs.jar new file mode 100644 index 000000000..2dd837714 Binary files /dev/null and b/spss.slinterface/WEB-INF/lib/xerces-2.6.0exBug24783/xmlParserAPIs.jar differ diff --git a/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/Constants.java b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/Constants.java index 6dbba7f89..1529317fa 100644 --- a/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/Constants.java +++ b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/Constants.java @@ -19,6 +19,7 @@ public class Constants public static final String IP_MOA2SL_STYLESHEET_ = "location.stylesheet.moa2sl"; public static final String IP_SL_SCHEMA_ = "location.schema.sl"; public static final String IP_MOA_SCHEMA_ = "location.schema.moa"; + public static final String IP_SLXHTML_SCHEMA_ = "location.schema.slxhtml"; public static final String IP_TEMP_DIR_ = "location.tempdir"; public static final String IP_SP_ENDPOINT_ = "service.sp.endpoint"; public static final String IP_SP_TRUSTPROFILEID_ = "service.sp.trustProfileId"; @@ -56,12 +57,15 @@ public class Constants public static final String NSURI_NAMESPACES_ = "http://www.w3.org/2000/xmlns/"; public static final String NSURI_XML_ = "http://www.w3.org/XML/1998/namespace"; public static final String NSURI_DSIG_ = "http://www.w3.org/2000/09/xmldsig#"; + public static final String NSURI_XHTML_ = "http://www.w3.org/1999/xhtml"; // Namespace prefixes public static final String NSPRE_SL_10_ = "sl10"; public static final String NSPRE_SL_11_ = "sl11"; public static final String NSPRE_SL_12_ = "sl12"; public static final String NSPRE_MOA_12_ = "moa"; + public static final String NSPRE_DSIG_ = "dsig"; + public static final String NSPRE_XHTML_ = "xhtml"; // MOA invoker constants diff --git a/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/DOMUtils.java b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/DOMUtils.java index 8bc23efa9..814d7832e 100644 --- a/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/DOMUtils.java +++ b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/DOMUtils.java @@ -5,18 +5,31 @@ */ package at.gv.egovernment.moa.spss.slinterface; +import java.io.InputStream; import java.util.ArrayList; import java.util.List; +import org.apache.xerces.parsers.DOMParser; +import org.w3c.dom.Document; import org.w3c.dom.Element; import org.w3c.dom.Node; import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import org.xml.sax.SAXException; + +import at.gv.egovernment.moa.spss.slinterface.listeners.XMLParserErrorHandler; /** * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at) */ public class DOMUtils { + private static final String SAX_NAMESPACES_FEATURE = "http://xml.org/sax/features/namespaces"; + private static final String XERCES_CREATE_ENTITY_REF_NODES_FEATURE = + "http://apache.org/xml/features/dom/create-entity-ref-nodes"; + protected static final String XERCES_DEFER_NODE_EXPANSION_ = + "http://apache.org/xml/features/dom/defer-node-expansion"; + /* ---------------------------------------------------------------------------------------------------- */ /** @@ -123,4 +136,34 @@ public class DOMUtils } return (childElems.size() == 0) ? null : childElems; } + + /* ---------------------------------------------------------------------------------------------------- */ + + public static Document parseWellFormed(InputStream is) throws Exception + { + DOMParser xmlParser = new DOMParser(); + try + { + xmlParser.setFeature(SAX_NAMESPACES_FEATURE, true); + xmlParser.setFeature(XERCES_CREATE_ENTITY_REF_NODES_FEATURE, false); + xmlParser.setFeature(XERCES_DEFER_NODE_EXPANSION_, false); + xmlParser.setErrorHandler(new XMLParserErrorHandler(false, true, true)); + + } + catch (SAXException e) + { + String message = "Initialization of XML parser failed."; + throw new Exception(message, e); + } + try + { + xmlParser.parse(new InputSource(is)); + return xmlParser.getDocument(); + } + catch (Exception e) + { + String message = "Wellformed parsing failed."; + throw new Exception(message, e); + } + } } diff --git a/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/XPathUtils.java b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/XPathUtils.java new file mode 100644 index 000000000..16e4938ed --- /dev/null +++ b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/XPathUtils.java @@ -0,0 +1,162 @@ +/* + * Created on 02.12.2003 + * + * (c) Stabsstelle IKT-Strategie des Bundes + */ +package at.gv.egovernment.moa.spss.slinterface; + +import java.util.HashMap; +import java.util.StringTokenizer; + +import org.apache.xml.utils.PrefixResolverDefault; +import org.apache.xpath.XPath; +import org.apache.xpath.XPathContext; +import org.apache.xpath.objects.XObject; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +/** + * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at) + */ +public class XPathUtils +{ + /** + * The XPath context for the XPath engine. + */ + protected XPathContext xPathContext_; + + /** + * The prefix resolver for the XPath engine. + */ + protected PrefixResolver prefixResolver_; + + /** + * The XPath engine. + */ + protected XPath xPath_; + + /* ==================================================================================================== */ + + public void setupContext(String xPathExpr, Node namespaceNode, String additionalNSPrefixes) + throws Exception + { + + try + { + // Set up a new evaluation context + xPathContext_ = new XPathContext(); + + // Set up the namespace prefix resolver for the XPath engine + prefixResolver_ = new PrefixResolver(namespaceNode, additionalNSPrefixes); + + // Initialize XPath engine + xPath_ = new XPath(xPathExpr, null, prefixResolver_, XPath.SELECT, null); + } + catch (Exception e) + { + throw new Exception("Setting up XPath evaluation context failed.", e); + } + } + + /* ---------------------------------------------------------------------------------------------------- */ + + public NodeList selectNodeSet(Node contextNode) throws Exception + { + XObject xObject; + try + { + xObject = xPath_.execute(xPathContext_, contextNode, prefixResolver_); + return xObject.nodelist(); + } + catch (Exception e) + { + throw new Exception("Executing XPath expression failed.", e); + } + } + + /* ---------------------------------------------------------------------------------------------------- */ + + public boolean selectBoolean(Node contextNode) throws Exception + { + XObject xObject; + try + { + xObject = xPath_.execute(xPathContext_, contextNode, prefixResolver_); + return xObject.bool(); + } + catch (Exception e) + { + throw new Exception("Executing XPath expression failed.", e); + } + } + + /* ==================================================================================================== */ + + /** + * Special extension of the {@link org.apache.xml.utils.PrefixResolverDefault} interface. Used to + * configure the Apache Xalan XPath engine which is employed as the backbone of this class. + */ + protected class PrefixResolver extends PrefixResolverDefault + { + + /** + * Contains the additionally specified namespace prefix (key) to namespace URI (value) attributions. + */ + protected HashMap additionalNSPrefixesMap_; + + /* ================================================================================================== */ + + /** + * Basic constructor. + * + * @param xpathExpressionContext The namespace declarations in scope for this node will be used to get + * the namespace uri for a prefix specified in the XPath expression. + * + * @param additionalNSPrefixes Allows the specification of additional prefix to uri attributions apart + * from the declarations in scope for the parameter + * xpathExpressionContext. May be null. + */ + public PrefixResolver(Node xpathExpressionContext, String additionalNSPrefixes) throws Exception + { + super(xpathExpressionContext); + additionalNSPrefixesMap_ = new HashMap(); + + // Register the specified additional namespace prefix to namespace uri attributions + if (additionalNSPrefixes != null) + { + StringTokenizer tokenizer = new StringTokenizer(additionalNSPrefixes, " "); + while (tokenizer.hasMoreTokens()) + { + String prefix = tokenizer.nextToken(); + if (!tokenizer.hasMoreTokens()) + { + + // There must be an even number of tokens in the string + throw new Exception("Parameter \"additionalNSPrefixes\" must have an even number of tokens."); + } + String uri = tokenizer.nextToken(); + additionalNSPrefixesMap_.put(prefix, uri); + } + } + } + + /* -------------------------------------------------------------------------------------------------- */ + + /** + * Gets the namespace uri for the specified namespace prefix. The additionally specified prefixes + * overrule the prefixes found in the specified namespace node. + * + * @param prefix The namespace prefix for which a namespace uri should be found. + * + * @return the namespace uri for the specified namespace prefix. + */ + public String getNamespaceForPrefix(String prefix) + { + String additionalURI = (String) additionalNSPrefixesMap_.get(prefix); + return (additionalURI != null) + ? additionalURI + : super.getNamespaceForPrefix(prefix); + } + } +} + diff --git a/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/beans/DataInfoBean.java b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/beans/DataInfoBean.java index 3e23c9eb0..db67ac411 100644 --- a/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/beans/DataInfoBean.java +++ b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/beans/DataInfoBean.java @@ -7,13 +7,22 @@ package at.gv.egovernment.moa.spss.slinterface.beans; import iaik.utils.Util; +import java.io.ByteArrayInputStream; import java.io.File; +import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; +import java.io.InputStream; +import java.net.URL; import java.util.ArrayList; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Properties; import java.util.Random; +import java.util.Set; +import java.util.StringTokenizer; import javax.servlet.ServletContext; import javax.servlet.http.HttpSession; @@ -21,11 +30,18 @@ import javax.servlet.http.HttpSessionBindingEvent; import javax.servlet.http.HttpSessionBindingListener; import org.apache.log4j.Logger; +import org.apache.xerces.parsers.DOMParser; +import org.w3c.dom.Attr; import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; import at.gv.egovernment.moa.spss.slinterface.Constants; import at.gv.egovernment.moa.spss.slinterface.DOMUtils; +import at.gv.egovernment.moa.spss.slinterface.XPathUtils; +import at.gv.egovernment.moa.spss.slinterface.moainvoker.MOAInvoker; /** * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at) @@ -34,27 +50,56 @@ public class DataInfoBean implements HttpSessionBindingListener { private static Logger logger_ = Logger.getLogger(Constants.LH_BEANS_); + // MOA private static final String HID_ELEM_ = "HashInputData"; private static final String B64CONT_ELEM_ = "Base64Content"; private static final String XMLCONT_ELEM_ = "XMLContent"; + private static final String SIGLOC_ELEM_ = "VerifySignatureLocation"; + // XMLDSIG + private static final String TYPE_ATTR_ = "Type"; + private static final String URI_ATTR_ = "URI"; + + // XHTML + private static final String SRC_ATTR_ = "src"; + private static final String HTML_ELEM_ = "html"; + private static final String HID_URL_PREFIX_ = "/showdata?hidCount="; - List hashInputDataFilenames_; + private static final String XPATH_ALL_IMG_ = "//" + Constants.NSPRE_XHTML_ + ":img"; + private static final String XPATH_ALL_REF_ = "./" + Constants.NSPRE_DSIG_ + ":SignedInfo/" + + Constants.NSPRE_DSIG_ + ":Reference"; + private static final String XPATH_SIG_ENV_CONTENT_ = "/" + Constants.NSPRE_MOA_12_ + ":VerifyXMLSignatureRequest/" + + Constants.NSPRE_MOA_12_ + ":VerifySignatureInfo/" + Constants.NSPRE_MOA_12_ + ":VerifySignatureEnvironment/*"; + + + + private static final String SLXHTML_TYPE_PREFIX_ = "http://www.buergerkarte.at/specifications/" + + "Security-Layer/20031113?Name=SignedImage&InstanceDocRef="; + + ServletContext context_; + + /** + * Contains objects of type {@link HashInputDataInfo}. + */ + List hashInputDataInfos_; + int hashInputDataCount_; /* ---------------------------------------------------------------------------------------------------- */ - public DataInfoBean(Document moaResponseDoc, ServletContext context, HttpSession session) - throws IOException + public DataInfoBean(Document moaRequestDoc, Document moaResponseDoc, ServletContext context, + HttpSession session) throws Exception { - hashInputDataFilenames_ = new ArrayList(); + context_ = context; + + hashInputDataInfos_ = new ArrayList(); int hashInputDataCount_ = 0; Element moaResponseElem = moaResponseDoc.getDocumentElement(); List hidElems = DOMUtils.getChildElems(moaResponseElem, Constants.NSURI_MOA_12_, HID_ELEM_, false); - Properties initProps = (Properties) context.getAttribute(Constants.WSCP_INIT_PROPS_); + Properties initProps = (Properties) context_.getAttribute(Constants.WSCP_INIT_PROPS_); String tempDir = initProps.getProperty(Constants.IP_TEMP_DIR_); if (tempDir == null) { @@ -69,7 +114,7 @@ public class DataInfoBean implements HttpSessionBindingListener // Open file for current hash input data String currHidFileNameStr = tempDir + session.getId() + "_" + System.currentTimeMillis() + "_" + random.nextLong(); - currHidFileNameStr = context.getRealPath(currHidFileNameStr); + currHidFileNameStr = context_.getRealPath(currHidFileNameStr); FileOutputStream currHidFOS; try { @@ -111,7 +156,25 @@ public class DataInfoBean implements HttpSessionBindingListener throw new RuntimeException("XML content not support yet."); } - hashInputDataFilenames_.add(currHidFileNameStr); + hashInputDataInfos_.add(new HashInputDataInfo(currHidFileNameStr)); + } + + // Check if hids are slxhtml documents; mark them appropriately + try + { + Map signedImages = getSignedImages(moaRequestDoc, hashInputDataInfos_); + for (int i = 0; i < hashInputDataInfos_.size(); i++) + { + HashInputDataInfo currHid = (HashInputDataInfo) hashInputDataInfos_.get(i); + FileInputStream currHidIS = new FileInputStream(currHid.filename_); + checkImages(currHidIS, currHid, signedImages); + } + } + catch (Exception e) + { + String message = "Performing SLXHTML checks failed."; + logger_.error(message, e); + throw new Exception(message, e); } } @@ -127,9 +190,9 @@ public class DataInfoBean implements HttpSessionBindingListener public void valueUnbound(HttpSessionBindingEvent event) { // Delete all temporary hash input data files - for (int i = 0; i < hashInputDataFilenames_.size(); i++) + for (int i = 0; i < hashInputDataInfos_.size(); i++) { - String currFileStr = (String) hashInputDataFilenames_.get(i); + String currFileStr = ((HashInputDataInfo) hashInputDataInfos_.get(i)).filename_; File currFile = new File(currFileStr); currFile.delete(); } @@ -146,16 +209,295 @@ public class DataInfoBean implements HttpSessionBindingListener public String getHashInputDataFilename() { - return (String) hashInputDataFilenames_.get(hashInputDataCount_); + HashInputDataInfo currHid = (HashInputDataInfo) hashInputDataInfos_.get(hashInputDataCount_); + return (currHid == null) ? null : currHid.filename_; } /* ---------------------------------------------------------------------------------------------------- */ public String getHashInputDataURL() { - - return (hashInputDataFilenames_.size() > hashInputDataCount_) + return (hashInputDataInfos_.size() > hashInputDataCount_) ? HID_URL_PREFIX_ + hashInputDataCount_ : null; } + + /* ---------------------------------------------------------------------------------------------------- */ + + public boolean getShowHashInputData() + { + HashInputDataInfo currHid = (HashInputDataInfo) hashInputDataInfos_.get(hashInputDataCount_); + return (currHid == null) ? false : currHid.doShow_; + } + + /* ---------------------------------------------------------------------------------------------------- */ + + public boolean getIsSLXHTMLDocument() + { + HashInputDataInfo currHid = (HashInputDataInfo) hashInputDataInfos_.get(hashInputDataCount_); + return (currHid == null) ? false : currHid.isSLXHTMLDocument_; + } + + /* ---------------------------------------------------------------------------------------------------- */ + + private Document parseSLXHTMLDocument(InputStream docIS) + { + DOMParser xmlParser = (DOMParser) context_.getAttribute(Constants.WSCP_XMLPARSER_); + InputSource docInputSource = new InputSource(docIS); + Document parsedDoc = null; + try + { + xmlParser.parse(docInputSource); + parsedDoc = xmlParser.getDocument(); + } + catch (Exception e) + { + // Exception shows that document is not a valid SLXHTML document; return null in that case + logger_.debug("HashInputData is not a valid SLXHTML document.", e); + return null; + } + + Element docElem = parsedDoc.getDocumentElement(); + if (docElem.getNamespaceURI() != Constants.NSURI_XHTML_ || docElem.getLocalName() != HTML_ELEM_) + { + return null; + } + + return parsedDoc; + } + + /* ---------------------------------------------------------------------------------------------------- */ + + private void checkImages(InputStream hidIS, HashInputDataInfo hid, Map signedImages) throws Exception + { + // Parse hidIS + Document slxhtmlDoc = parseSLXHTMLDocument(hidIS); + if (slxhtmlDoc == null) return; + + // Get all img elements of slxhtml document + XPathUtils xpUtils = new XPathUtils(); + String additionalNSPrefixes = Constants.NSPRE_XHTML_ + " " + Constants.NSURI_XHTML_; + xpUtils.setupContext(XPATH_ALL_IMG_, slxhtmlDoc.getDocumentElement(), additionalNSPrefixes); + NodeList imgTags = xpUtils.selectNodeSet(slxhtmlDoc); + + // Check if all img elements have corresponding slxhtml signed images + boolean allImgsSigned = true; + for (int i = 0; i < imgTags.getLength(); i++) + { + Element currImgElem = (Element) imgTags.item(i); + String uri = currImgElem.getAttribute(SRC_ATTR_); + if (!signedImages.containsKey(uri)) + { + allImgsSigned = false; + break; + } + } + + // Mark all corresponding slxhtml signed images as not to be shown + if (allImgsSigned) + { + for (int i = 0; i < imgTags.getLength(); i++) + { + Element currImgElem = (Element) imgTags.item(i); + String uri = currImgElem.getAttribute(SRC_ATTR_); + HashInputDataInfo currHidi = (HashInputDataInfo) signedImages.get(uri); + currHidi.doShow_ = false; + } + } + + // Change the src attributes of all img tags so that they refer to the temporary names + if (allImgsSigned) + { + for (int i = 0; i < imgTags.getLength(); i++) + { + Element currImgElem = (Element) imgTags.item(i); + String uri = currImgElem.getAttribute(SRC_ATTR_); + HashInputDataInfo currHidi = (HashInputDataInfo) signedImages.get(uri); + + Attr srcAttr = currImgElem.getAttributeNode(SRC_ATTR_); + int slashPos = currHidi.filename_.lastIndexOf('/'); + if (slashPos == -1) slashPos = 0; + String newSrcAttrValue = currHidi.filename_.substring(slashPos + 1); + srcAttr.setNodeValue(newSrcAttrValue); + } + } + + // Mark hid slxhtml document + hid.isSLXHTMLDocument_ = true; + + // Serialize modified slxhtml document to temporary file location + if (allImgsSigned) + { + FileOutputStream slxhtmlFOS = new FileOutputStream(hid.filename_); + MOAInvoker.serializeDocument(slxhtmlDoc, slxhtmlFOS); + slxhtmlFOS.close(); + } + + } + + /* ---------------------------------------------------------------------------------------------------- */ + + private Map getSignedImages(Document moaRequestDoc, List hashInputDataInfos) throws Exception + { + // Get signature from MOA request + Element signatureElem = getSignature(moaRequestDoc); + + // Get all signature references from MOA request + XPathUtils xpUtils = new XPathUtils(); + String additionalNSPrefixes = Constants.NSPRE_DSIG_ + " " + Constants.NSURI_DSIG_; + xpUtils.setupContext(XPATH_ALL_REF_, signatureElem, additionalNSPrefixes); + NodeList dsigRefs = xpUtils.selectNodeSet(signatureElem); + + // Check signature references for slxhtml images + HashMap imgHids = new HashMap(dsigRefs.getLength()); + for (int i = 0; i < dsigRefs.getLength(); i++) + { + Element currRef = (Element) dsigRefs.item(i); + String type = currRef.getAttribute(TYPE_ATTR_); + if (type != null && type.startsWith(SLXHTML_TYPE_PREFIX_)) + { + String uri = currRef.getAttribute(URI_ATTR_); + Set referredHids = createReferredHidsSet(type); + HashInputDataInfo currHidi = (HashInputDataInfo)hashInputDataInfos.get(i); + currHidi.uri_ = uri; + currHidi.referredHids_ = referredHids; + currHidi.isSLXHTMLImage_ = true; + imgHids.put(uri, currHidi); + } + } + + return imgHids; + } + + /* ---------------------------------------------------------------------------------------------------- */ + + private Set createReferredHidsSet(String type) throws Exception + { + HashSet set = new HashSet(); + String typeSuffix = type.substring(SLXHTML_TYPE_PREFIX_.length()); + StringTokenizer tokenizer = new StringTokenizer(typeSuffix, ","); + while (tokenizer.hasMoreTokens()) + { + try + { + set.add(new Integer(tokenizer.nextToken())); + } + catch (NumberFormatException e) + { + String message = "Signed image type attribute \"" + type + "\" is malformed."; + logger_.error(message, e); + throw new Exception(message, e); + } + } + return set; + } + + /* ---------------------------------------------------------------------------------------------------- */ + + private Element getSignature(Document moaRequestDoc) throws Exception + { + // Get signature environment content + NodeList contentNL; + try + { + XPathUtils xpUtils = new XPathUtils(); + String addNSPrefixes = Constants.NSPRE_MOA_12_ + " " + Constants.NSURI_MOA_12_; + xpUtils.setupContext(XPATH_SIG_ENV_CONTENT_, moaRequestDoc, addNSPrefixes); + contentNL = xpUtils.selectNodeSet(moaRequestDoc); + } + catch (Exception e) + { + String message = "Cannot find signature environment content."; + logger_.error(message); + throw new Exception(message, e); + } + if (contentNL.getLength() == 0) + { + String message = "Cannot find signature environment content."; + logger_.error(message); + throw new Exception(message); + } + Element contentElem = (Element) contentNL.item(0); + + // Get signature environment document form siganture environment content + String contentElemLocName = contentElem.getLocalName(); + Element sigEnvElem = null; + if (XMLCONT_ELEM_.equals(contentElemLocName)) + { + // XML content + NodeList contentNodes = contentElem.getChildNodes(); + for (int i = 0; i < contentNodes.getLength(); i++) + { + Node currContNode = (Node) contentNodes.item(i); + if (currContNode.getNodeType() == Node.ELEMENT_NODE) + { + sigEnvElem = (Element) currContNode; + break; + } + } + } + else if (B64CONT_ELEM_.equals(contentElemLocName)) + { + // Base64 content + String base64ContStr = DOMUtils.getText(contentElem); + byte[] contBytes = Util.Base64Decode(base64ContStr.getBytes()); + ByteArrayInputStream contBIS = new ByteArrayInputStream(contBytes); + Document sigEnvDoc; + try + { + sigEnvDoc = DOMUtils.parseWellFormed(contBIS); + } + catch (Exception e) + { + String message = "Cannot parse signature environment from base64 content."; + logger_.error(message); + throw new Exception(message, e); + } + sigEnvElem = sigEnvDoc.getDocumentElement(); + } + else + { + // LocRef content + String locRef = DOMUtils.getText(contentElem); + URL locRefURL = new URL(locRef); + InputStream contentIS = locRefURL.openStream(); + Document sigEnvDoc; + try + { + sigEnvDoc = DOMUtils.parseWellFormed(contentIS); + } + catch (Exception e) + { + String message = "Cannot parse signature environment from location reference content."; + logger_.error(message); + throw new Exception(message, e); + } + sigEnvElem = sigEnvDoc.getDocumentElement(); + } + + // Get signature form signature environment document + Element sigInfoElem = (Element) contentElem.getParentNode().getParentNode(); + Element sigLocElem = DOMUtils.getChildElem(sigInfoElem, Constants.NSURI_MOA_12_, SIGLOC_ELEM_); + String sigLocXPath = DOMUtils.getText(sigLocElem); + NodeList sigElemNL; + try + { + XPathUtils xpUtils = new XPathUtils(); + xpUtils.setupContext(sigLocXPath, sigLocElem, null); + sigElemNL = xpUtils.selectNodeSet(sigEnvElem); + } + catch (Exception e) + { + String message = "Cannot get signature at location \"" + sigLocXPath + "\" from signature environment."; + logger_.error(message); + throw new Exception(message, e); + } + if (sigElemNL.getLength() != 1 || ((Node) sigElemNL.item(0)).getNodeType() != Node.ELEMENT_NODE) + { + String message = "Cannot get signature at location \"" + sigLocXPath + "\" from signature environment."; + logger_.error(message); + throw new Exception(message); + } + return (Element) sigElemNL.item(0); + } } diff --git a/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/beans/HashInputDataInfo.java b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/beans/HashInputDataInfo.java new file mode 100644 index 000000000..e2cb27ab3 --- /dev/null +++ b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/beans/HashInputDataInfo.java @@ -0,0 +1,55 @@ +/* + * Created on 02.12.2003 + * + * (c) Stabsstelle IKT-Strategie des Bundes + */ +package at.gv.egovernment.moa.spss.slinterface.beans; + +import java.util.Set; + +/** + * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at) + */ +public class HashInputDataInfo +{ + /** + * The name of the temporary file in which this data is stored. + */ + public String filename_; + + /** + * Is this HID a SLXHTML document? + */ + public boolean isSLXHTMLDocument_; + + /** + * Is this HID a SLXHTML signed image? + */ + public boolean isSLXHTMLImage_; + + /** + * Show HID in result presentation? + */ + public boolean doShow_; + + /** + * The URI attribute value of the dsig:Reference corresponding with this HID. + */ + public String uri_; + + /** + * In case that this ID is a SLXHTML signed image, this set contains objects of type Integer, + * indicating the SLXHTML HIDs where this image is referenced. + */ + public Set referredHids_; + + public HashInputDataInfo(String filename) + { + filename_ = filename; + isSLXHTMLDocument_ = false; + isSLXHTMLImage_ = false; + doShow_ = true; + uri_ = null; + referredHids_ = null; + } +} diff --git a/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/SL2MOAFilter.java b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/SL2MOAFilter.java index 9a4529565..b67d978ad 100644 --- a/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/SL2MOAFilter.java +++ b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/filters/SL2MOAFilter.java @@ -128,9 +128,19 @@ public class SL2MOAFilter implements Filter } // Create bean with info about signed data - DataInfoBean dataInfo = new DataInfoBean(moaResponseDoc, config_.getServletContext(), session); - session.setAttribute("dataInfo", dataInfo); - + try + { + DataInfoBean dataInfo = new DataInfoBean( + moaXMLRequestDoc, moaResponseDoc, config_.getServletContext(), session); + session.setAttribute("dataInfo", dataInfo); + } + catch (Exception e) + { + String message = "Creating DataInfobean failed."; + logger_.error(message, e); + throw new ServletException(message, e); + } + // Transform MOA response into a SL response Document slResponseDoc; slResponseDoc = MOA2SL.toSlVerifyXMLSignatureResponse(moaResponseDoc); diff --git a/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/listeners/ContextListener.java b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/listeners/ContextListener.java index 0b3980a50..83b6e96dd 100644 --- a/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/listeners/ContextListener.java +++ b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/listeners/ContextListener.java @@ -48,6 +48,8 @@ public class ContextListener implements ServletContextListener private static Logger logger_ = Logger.getLogger(Constants.LH_LISTENERS_); + /* ---------------------------------------------------------------------------------------------------- */ + /** * Initializes the web application. * @@ -90,12 +92,20 @@ public class ContextListener implements ServletContextListener preparser.setFeature(SAX_NAMESPACES_FEATURE, true); preparser.setFeature(SAX_VALIDATION_FEATURE, true); + // Schema for Security-Layer 1.2 alpha (including LocRefContent) Properties initProps = (Properties) context.getAttribute(Constants.WSCP_INIT_PROPS_); String slSchemaLoc = initProps.getProperty(Constants.IP_SL_SCHEMA_); preparseSchema(context, preparser, slSchemaLoc); + + // Schema for MOA 1.2 String moaSchemaLoc = initProps.getProperty(Constants.IP_MOA_SCHEMA_); preparseSchema(context, preparser, moaSchemaLoc); - + + // Schema for SLXHTML 1.0 + String slxhtmlSchemaLoc = initProps.getProperty(Constants.IP_SLXHTML_SCHEMA_); + preparseSchema(context, preparser, slxhtmlSchemaLoc); + + // TODO parser is not threadsafe DOMParser xmlParser = new DOMParser(symbolTable, grammarPool); try { @@ -106,6 +116,7 @@ public class ContextListener implements ServletContextListener xmlParser.setFeature(XERCES_INCLUDE_IGNORABLE_WHITESPACE_FEATURE, true); xmlParser.setFeature(XERCES_CREATE_ENTITY_REF_NODES_FEATURE, false); xmlParser.setFeature(XERCES_DEFER_NODE_EXPANSION_, false); + xmlParser.setErrorHandler(new XMLParserErrorHandler(false, true, true)); } catch (SAXException e) diff --git a/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/listeners/XMLParserErrorHandler.java b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/listeners/XMLParserErrorHandler.java new file mode 100644 index 000000000..b6fc770c0 --- /dev/null +++ b/spss.slinterface/WEB-INF/src/at/gv/egovernment/moa/spss/slinterface/listeners/XMLParserErrorHandler.java @@ -0,0 +1,65 @@ +/* + * Created on 02.12.2003 + * + * (c) Stabsstelle IKT-Strategie des Bundes + */ +package at.gv.egovernment.moa.spss.slinterface.listeners; + +import org.apache.log4j.Logger; +import org.xml.sax.ErrorHandler; +import org.xml.sax.SAXException; +import org.xml.sax.SAXParseException; + +import at.gv.egovernment.moa.spss.slinterface.Constants; + +/** + * @author Gregor Karlinger (mailto:gregor.karlinger@cio.gv.at) + */ +public class XMLParserErrorHandler implements ErrorHandler +{ + private static Logger logger_ = Logger.getLogger(Constants.LH_LISTENERS_); + + private boolean reportWarning_, reportError_, reportFatal_; + + /* ---------------------------------------------------------------------------------------------------- */ + + public XMLParserErrorHandler(boolean reportWarning, boolean reportError, boolean reportFatal) + { + reportWarning_ = reportWarning; + reportError_ = reportError; + reportFatal_ = reportFatal; + } + + /* ---------------------------------------------------------------------------------------------------- */ + + /** + * @see org.xml.sax.ErrorHandler#warning(org.xml.sax.SAXParseException) + */ + public void warning(SAXParseException exception) throws SAXException + { + logger_.warn("XML parser reported a warning.", exception); + if (reportWarning_) throw exception; + } + + /* ---------------------------------------------------------------------------------------------------- */ + + /** + * @see org.xml.sax.ErrorHandler#error(org.xml.sax.SAXParseException) + */ + public void error(SAXParseException exception) throws SAXException + { + logger_.error("XML parser reported an error.", exception); + if (reportError_) throw exception; + } + + /* ---------------------------------------------------------------------------------------------------- */ + + /** + * @see org.xml.sax.ErrorHandler#fatalError(org.xml.sax.SAXParseException) + */ + public void fatalError(SAXParseException exception) throws SAXException + { + logger_.error("XML parser reported a fatal error.", exception); + if (reportFatal_) throw exception; + } +} diff --git a/spss.slinterface/constraints.txt b/spss.slinterface/constraints.txt index 1333c2d6c..6cdb6ee8a 100644 --- a/spss.slinterface/constraints.txt +++ b/spss.slinterface/constraints.txt @@ -1,2 +1,4 @@ - Prüfung eines ggf. vorhandenen SL-Manifests wird nicht durchgeführt. - In der Antwort wird der Code 98 zurückgeliefert. \ No newline at end of file + In der Antwort wird der Code 98 zurückgeliefert. + +- Bei signiertem XHTML-Dokument wird list-style-image-URL nicht geprüft. \ No newline at end of file diff --git a/spss.slinterface/res/resources/properties/init.properties b/spss.slinterface/res/resources/properties/init.properties index e6f1cbb91..1f8f9b1ce 100644 --- a/spss.slinterface/res/resources/properties/init.properties +++ b/spss.slinterface/res/resources/properties/init.properties @@ -3,6 +3,7 @@ location.stylesheet.moa2sl = /WEB-INF/classes/resources/stylesheets/moa2sl.xsl location.schema.sl = /WEB-INF/classes/resources/schemas/Core.20031231.xsd location.schema.moa = /WEB-INF/classes/resources/schemas/MOA-SPSS-1.2.xsd +location.schema.slxhtml = /WEB-INF/classes/resources/schemas/slxhtml-1.0/slxhtml.xsd location.tempdir = /workDir/temp/ diff --git a/spss.slinterface/res/resources/schemas/xml.xsd b/spss.slinterface/res/resources/schemas/xml.xsd index 117670acd..ff784eb98 100644 --- a/spss.slinterface/res/resources/schemas/xml.xsd +++ b/spss.slinterface/res/resources/schemas/xml.xsd @@ -1,5 +1,5 @@ - + -- cgit v1.2.3