From 3120264067f72471e391f87eba07d71b259296ac Mon Sep 17 00:00:00 2001 From: Scott Cantor Date: Thu, 30 Mar 2006 05:00:53 +0000 Subject: [PATCH] Added some validation code. --- xmltooling/AbstractAttributeExtensibleXMLObject.h | 2 +- xmltooling/AbstractElementProxy.h | 2 +- xmltooling/XMLToolingConfig.cpp | 19 +++- xmltooling/base.h | 84 +++++++++++++-- xmltooling/io/AbstractXMLObjectMarshaller.h | 4 +- xmltooling/io/AbstractXMLObjectUnmarshaller.h | 6 +- xmltooling/signature/KeyInfo.h | 39 ++++++- xmltooling/signature/impl/KeyInfoImpl.cpp | 122 +++++++++++++++++++--- xmltooling/signature/impl/KeyInfoImpl.h | 20 +++- 9 files changed, 262 insertions(+), 36 deletions(-) diff --git a/xmltooling/AbstractAttributeExtensibleXMLObject.h b/xmltooling/AbstractAttributeExtensibleXMLObject.h index 09bfb7c..964a1be 100644 --- a/xmltooling/AbstractAttributeExtensibleXMLObject.h +++ b/xmltooling/AbstractAttributeExtensibleXMLObject.h @@ -24,7 +24,7 @@ #define __xmltooling_absattrextxmlobj_h__ #include -#include +#include #include #if defined (_MSC_VER) diff --git a/xmltooling/AbstractElementProxy.h b/xmltooling/AbstractElementProxy.h index 9829410..1bbd34e 100644 --- a/xmltooling/AbstractElementProxy.h +++ b/xmltooling/AbstractElementProxy.h @@ -23,7 +23,7 @@ #ifndef __xmltooling_abseleproxy_h__ #define __xmltooling_abseleproxy_h__ -#include +#include #include #if defined (_MSC_VER) diff --git a/xmltooling/XMLToolingConfig.cpp b/xmltooling/XMLToolingConfig.cpp index f4936ad..3cfbe79 100644 --- a/xmltooling/XMLToolingConfig.cpp +++ b/xmltooling/XMLToolingConfig.cpp @@ -32,6 +32,7 @@ #include "signature/impl/XMLSecSignatureImpl.h" #include "util/NDC.h" #include "util/XMLConstants.h" +#include "validation/Validator.h" #ifdef HAVE_DLFCN_H # include @@ -156,10 +157,26 @@ bool XMLToolingInternalConfig::init() // default registrations XMLObjectBuilder::registerDefaultBuilder(new UnknownElementBuilder()); - XMLObjectBuilder::registerBuilder(QName(XMLConstants::XMLSIG_NS,KeyInfo::LOCAL_NAME),new KeyInfoBuilderImpl()); + + QName q(XMLConstants::XMLSIG_NS,KeyInfo::LOCAL_NAME); + XMLObjectBuilder::registerBuilder(q,new KeyInfoBuilderImpl()); + Validator::registerValidator(q,new KeyInfoSchemaValidator()); + q=QName(XMLConstants::XMLSIG_NS,KeyInfo::TYPE_NAME); + XMLObjectBuilder::registerBuilder(q,new KeyInfoBuilderImpl()); + Validator::registerValidator(q,new KeyInfoSchemaValidator()); + + q=QName(XMLConstants::XMLSIG_NS,KeyName::LOCAL_NAME); + XMLObjectBuilder::registerBuilder(q,new KeyNameBuilderImpl()); + Validator::registerValidator(q,new KeyNameSchemaValidator()); + + q=QName(XMLConstants::XMLSIG_NS,MgmtData::LOCAL_NAME); + XMLObjectBuilder::registerBuilder(q,new MgmtDataBuilderImpl()); + Validator::registerValidator(q,new MgmtDataSchemaValidator()); + #ifndef XMLTOOLING_NO_XMLSEC XMLObjectBuilder::registerBuilder(QName(XMLConstants::XMLSIG_NS,Signature::LOCAL_NAME),new XMLSecSignatureBuilder()); #endif + REGISTER_EXCEPTION_FACTORY(XMLParserException); REGISTER_EXCEPTION_FACTORY(XMLObjectException); REGISTER_EXCEPTION_FACTORY(MarshallingException); diff --git a/xmltooling/base.h b/xmltooling/base.h index 093152e..de15fe1 100644 --- a/xmltooling/base.h +++ b/xmltooling/base.h @@ -104,8 +104,6 @@ virtual ~cname() {} \ XMLTOOLING_DOXYGEN(Type-specific clone method.) \ virtual cname* clone##cname() const=0; \ - XMLTOOLING_DOXYGEN(Element prefix) \ - static const XMLCh PREFIX[]; \ XMLTOOLING_DOXYGEN(Element local name) \ static const XMLCh LOCAL_NAME[] @@ -145,6 +143,43 @@ } /** + * Declares abstract get/set methods for named XML element content. + * + * @param proper the proper name to label the element's content + */ +#define DECL_XMLOBJECT_CONTENT(proper) \ + XMLTOOLING_DOXYGEN(Returns proper.) \ + virtual const XMLCh* get##proper() const=0; \ + XMLTOOLING_DOXYGEN(Sets proper.) \ + virtual void set##proper(const XMLCh* proper)=0 + +/** + * Implements get/set methods and a private member for named XML element content. + * + * @param proper the proper name to label the element's content + */ +#define IMPL_XMLOBJECT_CONTENT(proper) \ + private: \ + XMLCh* m_##proper; \ + public: \ + const XMLCh* get##proper() const { \ + return m_##proper; \ + } \ + void set##proper(const XMLCh* proper) { \ + m_##proper = prepareForAssignment(m_##proper,proper); \ + } \ + protected: \ + void marshallElementContent(DOMElement* domElement) const { \ + if(get##proper()) { \ + domElement->appendChild(domElement->getOwnerDocument()->createTextNode(get##proper())); \ + } \ + } \ + void processElementContent(const XMLCh* elementContent) { \ + set##proper(elementContent); \ + } + + +/** * Implements cloning methods for an XMLObject specialization implementation class. * * @param cname the name of the XMLObject specialization @@ -186,24 +221,59 @@ /** * Begins the declaration of an XMLObjectBuilder specialization implementation class. * - * @param cname the name of the XMLObject specialization - * @param namespaceURI the XML namespace of the default associated element + * @param cname the name of the XMLObject specialization + * @param namespaceURI the XML namespace of the default associated element + * @param namespacePrefix the XML namespace prefix of the default associated element */ -#define BEGIN_XMLOBJECTBUILDERIMPL(cname,namespaceURI) \ +#define BEGIN_XMLOBJECTBUILDERIMPL(cname,namespaceURI,namespacePrefix) \ class XMLTOOL_DLLLOCAL cname##BuilderImpl : public cname##Builder { \ public: \ cname* buildObject( \ - const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL, const QName* schemaType=NULL\ + const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix=NULL, const QName* schemaType=NULL \ ) const; \ cname* buildObject() const { \ - return buildObject(namespaceURI,cname::LOCAL_NAME,cname::PREFIX); \ + return buildObject(namespaceURI,cname::LOCAL_NAME,namespacePrefix); \ } /** + * Begins the declaration of an XMLObjectBuilder specialization implementation class. + * + * @param cname the name of the XMLObject specialization + */ +#define IMPL_XMLOBJECTBUILDER(cname) \ + cname* cname##BuilderImpl::buildObject( \ + const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType \ + ) const \ + { \ + return new cname##Impl(nsURI,localName,prefix,schemaType); \ + } + +/** * Ends the declaration of an XMLObjectBuilder specialization implementation class. */ #define END_XMLOBJECTBUILDERIMPL } +/** + * Begins the declaration of a Validator specialization. + * + * @param cname the base name of the Validator specialization + */ + #define BEGIN_XMLOBJECTVALIDATOR(cname) \ + class cname##Validator : public Validator \ + { \ + public: \ + virtual ~cname##Validator() {} \ + Validator* clone() const { \ + return new cname##Validator(); \ + } \ + void validate(const XMLObject* xmlObject) const + +/** + * Ends the declaration of a Validator specialization. + */ +#define END_XMLOBJECTVALIDATOR } + + #include namespace xmltooling { diff --git a/xmltooling/io/AbstractXMLObjectMarshaller.h b/xmltooling/io/AbstractXMLObjectMarshaller.h index 82d1621..f52ae1c 100644 --- a/xmltooling/io/AbstractXMLObjectMarshaller.h +++ b/xmltooling/io/AbstractXMLObjectMarshaller.h @@ -107,14 +107,14 @@ namespace xmltooling { * * @throws MarshallingException thrown if there is a problem marshalling an attribute */ - virtual void marshallAttributes(DOMElement* domElement) const=0; + virtual void marshallAttributes(DOMElement* domElement) const {} /** * Marshalls data from the XMLObject into content of the DOM Element. * * @param domElement the DOM element recieving the content */ - virtual void marshallElementContent(DOMElement* domElement) const=0; + virtual void marshallElementContent(DOMElement* domElement) const {} }; }; diff --git a/xmltooling/io/AbstractXMLObjectUnmarshaller.h b/xmltooling/io/AbstractXMLObjectUnmarshaller.h index 0853f15..be4e116 100644 --- a/xmltooling/io/AbstractXMLObjectUnmarshaller.h +++ b/xmltooling/io/AbstractXMLObjectUnmarshaller.h @@ -75,7 +75,7 @@ namespace xmltooling { * * @throws UnmarshallingException thrown if there is a problem adding the child to the parent */ - virtual void processChildElement(XMLObject* child, const DOMElement* childRoot)=0; + virtual void processChildElement(XMLObject* child, const DOMElement* childRoot) {} /** * Called after an attribute has been unmarshalled so that it can be added to the XMLObject. @@ -84,14 +84,14 @@ namespace xmltooling { * * @throws UnmarshallingException thrown if there is a problem adding the attribute to the XMLObject */ - virtual void processAttribute(const DOMAttr* attribute)=0; + virtual void processAttribute(const DOMAttr* attribute) {} /** * Called if the element being unmarshalled contained textual content so that it can be added to the XMLObject. * * @param elementContent the Element's text content */ - virtual void processElementContent(const XMLCh* elementContent)=0; + virtual void processElementContent(const XMLCh* elementContent) {} }; }; diff --git a/xmltooling/signature/KeyInfo.h b/xmltooling/signature/KeyInfo.h index a27ca97..83c9e4c 100644 --- a/xmltooling/signature/KeyInfo.h +++ b/xmltooling/signature/KeyInfo.h @@ -35,6 +35,7 @@ namespace xmltooling { */ BEGIN_XMLOBJECT(KeyInfo,ElementProxy); DECL_XMLOBJECT_ATTRIB(Id,ID); + static const XMLCh TYPE_NAME[]; END_XMLOBJECT; BEGIN_XMLOBJECTBUILDER(KeyInfo); @@ -44,14 +45,46 @@ namespace xmltooling { const XMLCh KeyInfo::LOCAL_NAME[] = { chLatin_K, chLatin_e, chLatin_y, chLatin_I, chLatin_n, chLatin_f, chLatin_o, chNull }; - const XMLCh KeyInfo::PREFIX[] = { - chLatin_d, chLatin_s, chNull - }; + const XMLCh KeyInfo::TYPE_NAME[] = { + chLatin_K, chLatin_e, chLatin_y, chLatin_I, chLatin_n, chLatin_f, chLatin_o, + chLatin_T, chLatin_y, chLatin_p, chLatin_e, chNull + }; const XMLCh KeyInfo::ID_ATTRIB_NAME[] = { chLatin_I, chLatin_d, chNull }; #endif + /** + * XMLObject representing XML Digital Signature, version 20020212, KeyName element. + */ + BEGIN_XMLOBJECT(KeyName,XMLObject); + DECL_XMLOBJECT_CONTENT(Name); + END_XMLOBJECT; + + BEGIN_XMLOBJECTBUILDER(KeyName); + END_XMLOBJECTBUILDER; + +#ifdef XMLTOOLING_DEFINE_CONSTANTS + const XMLCh KeyName::LOCAL_NAME[] = { + chLatin_K, chLatin_e, chLatin_y, chLatin_N, chLatin_a, chLatin_m, chLatin_e, chNull + }; +#endif + + /** + * XMLObject representing XML Digital Signature, version 20020212, MgmtData element. + */ + BEGIN_XMLOBJECT(MgmtData,XMLObject); + DECL_XMLOBJECT_CONTENT(Data); + END_XMLOBJECT; + + BEGIN_XMLOBJECTBUILDER(MgmtData); + END_XMLOBJECTBUILDER; + +#ifdef XMLTOOLING_DEFINE_CONSTANTS + const XMLCh MgmtData::LOCAL_NAME[] = { + chLatin_M, chLatin_g, chLatin_m, chLatin_t, chLatin_D, chLatin_a, chLatin_t, chLatin_a, chNull + }; +#endif }; #endif /* __xmltooling_keyinfo_h__ */ diff --git a/xmltooling/signature/impl/KeyInfoImpl.cpp b/xmltooling/signature/impl/KeyInfoImpl.cpp index 2d73ed8..44dc6ab 100644 --- a/xmltooling/signature/impl/KeyInfoImpl.cpp +++ b/xmltooling/signature/impl/KeyInfoImpl.cpp @@ -26,14 +26,12 @@ #include "io/AbstractXMLObjectMarshaller.h" #include "io/AbstractXMLObjectUnmarshaller.h" #include "signature/impl/KeyInfoImpl.h" -#include "util/NDC.h" #include "util/XMLHelper.h" #include "validation/AbstractValidatingXMLObject.h" -#include +#include using namespace xmltooling; -using namespace log4cpp; using namespace std; #if defined (_MSC_VER) @@ -43,24 +41,35 @@ using namespace std; namespace xmltooling { - class XMLTOOL_DLLLOCAL KeyInfoImpl : public KeyInfo, public AbstractDOMCachingXMLObject, public AbstractElementProxy, - public AbstractValidatingXMLObject, public AbstractXMLObjectMarshaller, public AbstractXMLObjectUnmarshaller + class XMLTOOL_DLLLOCAL KeyInfoImpl + : public KeyInfo, + public AbstractDOMCachingXMLObject, + public AbstractElementProxy, + public AbstractValidatingXMLObject, + public AbstractXMLObjectMarshaller, + public AbstractXMLObjectUnmarshaller { public: virtual ~KeyInfoImpl() {} KeyInfoImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) - : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_Id(NULL) {} + : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_Id(NULL) { + } - KeyInfoImpl(const KeyInfoImpl& src) : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), - AbstractElementProxy(src), AbstractValidatingXMLObject(src), m_Id(XMLString::replicate(src.m_Id)) { + KeyInfoImpl(const KeyInfoImpl& src) + : AbstractXMLObject(src), + AbstractDOMCachingXMLObject(src), + AbstractElementProxy(src), + AbstractValidatingXMLObject(src), + m_Id(XMLString::replicate(src.m_Id)) { + for (list::const_iterator i=src.m_children.begin(); i!=src.m_children.end(); i++) { getXMLObjects().push_back((*i) ? (*i)->clone() : NULL); } } - IMPL_XMLOBJECT_ATTRIB(Id); IMPL_XMLOBJECT_CLONE(KeyInfo); + IMPL_XMLOBJECT_ATTRIB(Id); protected: void marshallAttributes(DOMElement* domElement) const { @@ -76,29 +85,108 @@ namespace xmltooling { } } + void processElementContent(const XMLCh* elementContent) { + setTextContent(elementContent); + } + void processChildElement(XMLObject* childXMLObject, const DOMElement* root) { getXMLObjects().push_back(childXMLObject); } void processAttribute(const DOMAttr* attribute) { - if (XMLHelper::isNodeNamed(attribute, NULL, ID_ATTRIB_NAME)) + if (XMLHelper::isNodeNamed(attribute, NULL, ID_ATTRIB_NAME)) { setId(attribute->getValue()); + static_cast(attribute->getParentNode())->setIdAttributeNode(attribute); + } } + }; + + class XMLTOOL_DLLLOCAL KeyNameImpl + : public KeyName, + public AbstractDOMCachingXMLObject, + public AbstractValidatingXMLObject, + public AbstractXMLObjectMarshaller, + public AbstractXMLObjectUnmarshaller + { + public: + virtual ~KeyNameImpl() {} - void processElementContent(const XMLCh* elementContent) { - setTextContent(elementContent); + KeyNameImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_Name(NULL) { } + + KeyNameImpl(const KeyNameImpl& src) + : AbstractXMLObject(src), + AbstractDOMCachingXMLObject(src), + AbstractValidatingXMLObject(src), + m_Name(XMLString::replicate(src.m_Name)) { + } + + IMPL_XMLOBJECT_CLONE(KeyName); + IMPL_XMLOBJECT_CONTENT(Name); + }; + + class XMLTOOL_DLLLOCAL MgmtDataImpl + : public MgmtData, + public AbstractDOMCachingXMLObject, + public AbstractValidatingXMLObject, + public AbstractXMLObjectMarshaller, + public AbstractXMLObjectUnmarshaller + { + public: + virtual ~MgmtDataImpl() {} + + MgmtDataImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_Data(NULL) { + } + + MgmtDataImpl(const MgmtDataImpl& src) + : AbstractXMLObject(src), + AbstractDOMCachingXMLObject(src), + AbstractValidatingXMLObject(src), + m_Data(XMLString::replicate(src.m_Data)) { + } + + IMPL_XMLOBJECT_CLONE(MgmtData); + IMPL_XMLOBJECT_CONTENT(Data); }; - }; #if defined (_MSC_VER) #pragma warning( pop ) #endif -KeyInfo* KeyInfoBuilderImpl::buildObject( - const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType - ) const +// Builder Implementations + +IMPL_XMLOBJECTBUILDER(KeyInfo); +IMPL_XMLOBJECTBUILDER(KeyName); +IMPL_XMLOBJECTBUILDER(MgmtData); + +// Validators + +void KeyInfoSchemaValidator::validate(const XMLObject* xmlObject) const +{ + const KeyInfo* ptr=dynamic_cast(xmlObject); + if (!ptr) + throw ValidationException("KeyInfoSchemaValidator: unsupported object type ($1)",params(1,typeid(xmlObject).name())); + if (!ptr->hasChildren()) + throw ValidationException("KeyInfo is empty"); +} + +void KeyNameSchemaValidator::validate(const XMLObject* xmlObject) const +{ + const KeyName* ptr=dynamic_cast(xmlObject); + if (!ptr) + throw ValidationException("KeyNameSchemaValidator: unsupported object type ($1)",params(1,typeid(xmlObject).name())); + if (XMLString::stringLen(ptr->getName())==0) + throw ValidationException("KeyName is empty"); +} + +void MgmtDataSchemaValidator::validate(const XMLObject* xmlObject) const { - return new KeyInfoImpl(nsURI,localName,prefix,schemaType); + const MgmtData* ptr=dynamic_cast(xmlObject); + if (!ptr) + throw ValidationException("MgmtDataSchemaValidator: unsupported object type ($1)",params(1,typeid(xmlObject).name())); + if (XMLString::stringLen(ptr->getData())==0) + throw ValidationException("MgmtData is empty"); } diff --git a/xmltooling/signature/impl/KeyInfoImpl.h b/xmltooling/signature/impl/KeyInfoImpl.h index 98d0ac9..cb18679 100644 --- a/xmltooling/signature/impl/KeyInfoImpl.h +++ b/xmltooling/signature/impl/KeyInfoImpl.h @@ -25,12 +25,30 @@ #include #include +#include + +#define BEGIN_XMLSIGOBJECTBUILDERIMPL(cname) \ + BEGIN_XMLOBJECTBUILDERIMPL(cname,XMLConstants::XMLSIG_NS,XMLConstants::XMLSIG_PREFIX) namespace xmltooling { + + BEGIN_XMLSIGOBJECTBUILDERIMPL(KeyInfo); + END_XMLOBJECTBUILDERIMPL; - BEGIN_XMLOBJECTBUILDERIMPL(KeyInfo,XMLConstants::XMLSIG_NS); + BEGIN_XMLSIGOBJECTBUILDERIMPL(KeyName); END_XMLOBJECTBUILDERIMPL; + BEGIN_XMLSIGOBJECTBUILDERIMPL(MgmtData); + END_XMLOBJECTBUILDERIMPL; + + BEGIN_XMLOBJECTVALIDATOR(KeyInfoSchema); + END_XMLOBJECTVALIDATOR; + + BEGIN_XMLOBJECTVALIDATOR(KeyNameSchema); + END_XMLOBJECTVALIDATOR; + + BEGIN_XMLOBJECTVALIDATOR(MgmtDataSchema); + END_XMLOBJECTVALIDATOR; }; #endif /* __xmltooling_keyinfoimpl_h__ */ -- 2.1.4