From: Scott Cantor Date: Tue, 16 May 2006 22:37:05 +0000 (+0000) Subject: Cloning fixes, initial protocol check-in. X-Git-Tag: 2.0-alpha1~252 X-Git-Url: http://www.project-moonshot.org/gitweb/?p=shibboleth%2Fcpp-opensaml.git;a=commitdiff_plain;h=23a155260850eef12ba34223fad83d4969df95d0 Cloning fixes, initial protocol check-in. --- diff --git a/saml/Makefile.am b/saml/Makefile.am index 460c788..6171f9f 100644 --- a/saml/Makefile.am +++ b/saml/Makefile.am @@ -22,7 +22,8 @@ utilinclude_HEADERS = \ util/SAMLConstants.h saml1coreinclude_HEADERS = \ - saml1/core/Assertions.h + saml1/core/Assertions.h \ + saml1/core/Protocols.h noinst_HEADERS = \ internal.h @@ -31,6 +32,8 @@ libsaml_la_SOURCES = \ SAMLConfig.cpp \ saml1/core/impl/AssertionsImpl.cpp \ saml1/core/impl/AssertionsSchemaValidators.cpp \ + saml1/core/impl/ProtocolsImpl.cpp \ + saml1/core/impl/ProtocolsSchemaValidators.cpp \ signature/SigningContext.cpp \ signature/VerifyingContext.cpp \ util/SAMLConstants.cpp diff --git a/saml/SAMLConfig.cpp b/saml/SAMLConfig.cpp index 5695db8..ddbf3d5 100644 --- a/saml/SAMLConfig.cpp +++ b/saml/SAMLConfig.cpp @@ -26,6 +26,7 @@ #include "exceptions.h" #include "SAMLConfig.h" #include "saml1/core/Assertions.h" +#include "saml1/core/Protocols.h" #include "util/SAMLConstants.h" #include @@ -70,6 +71,7 @@ bool SAMLInternalConfig::init() log.debug("XMLTooling library initialized"); saml1::registerAssertionClasses(); + saml1::registerProtocolClasses(); log.info("library initialization complete"); return true; diff --git a/saml/saml.vcproj b/saml/saml.vcproj index a6e42e7..216d6a5 100644 --- a/saml/saml.vcproj +++ b/saml/saml.vcproj @@ -210,6 +210,14 @@ RelativePath=".\saml1\core\impl\AssertionsSchemaValidators.cpp" > + + + + @@ -269,6 +277,10 @@ RelativePath=".\saml1\core\Assertions.h" > + + #include @@ -263,4 +263,4 @@ namespace opensaml { }; }; -#endif /* __saml_assertions_h__ */ +#endif /* __saml1_assertions_h__ */ diff --git a/saml/saml1/core/Protocols.h b/saml/saml1/core/Protocols.h new file mode 100644 index 0000000..48413a8 --- /dev/null +++ b/saml/saml1/core/Protocols.h @@ -0,0 +1,131 @@ +/* + * Copyright 2001-2006 Internet2 + * + * 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. + */ + +/** + * @file Protocols.h + * + * XMLObjects representing the SAML 1.x Protocols schema + */ + +#ifndef __saml1_protocols_h__ +#define __saml1_protocols_h__ + +#include + +#define DECL_SAML1POBJECTBUILDER(cname) \ + DECL_XMLOBJECTBUILDER(SAML_API,cname,opensaml::SAMLConstants::SAML1P_NS,opensaml::SAMLConstants::SAML1P_PREFIX) + +namespace opensaml { + + namespace saml1 { + + DECL_XMLOBJECT_SIMPLE(SAML_API,AssertionArtifact,Artifact,SAML 1.x AssertionArtifact element); + DECL_XMLOBJECT_SIMPLE(SAML_API,StatusMessage,Message,SAML 1.x StatusMessage element); + + BEGIN_XMLOBJECT(SAML_API,RespondWith,xmltooling::XMLObject,SAML 1.x RespondWith element); + /** Gets the QName content of the element. */ + virtual xmltooling::QName* getQName() const=0; + /** Sets the QName content of the element. */ + virtual void setQName(const xmltooling::QName* qname)=0; + END_XMLOBJECT; + + BEGIN_XMLOBJECT(SAML_API,Query,xmltooling::XMLObject,SAML 1.x Query element); + END_XMLOBJECT; + + BEGIN_XMLOBJECT(SAML_API,SubjectQuery,Query,SAML 1.x SubjectQuery element); + DECL_TYPED_CHILD(Subject); + END_XMLOBJECT; + + BEGIN_XMLOBJECT(SAML_API,AuthenticationQuery,SubjectQuery,SAML 1.x AuthenticationQuery element); + DECL_STRING_ATTRIB(AuthenticationMethod,AUTHENTICATIONMETHOD); + /** AuthenticationQueryType local name */ + static const XMLCh TYPE_NAME[]; + END_XMLOBJECT; + + BEGIN_XMLOBJECT(SAML_API,AttributeQuery,SubjectQuery,SAML 1.x AttributeQuery element); + DECL_STRING_ATTRIB(Resource,RESOURCE); + DECL_TYPED_CHILDREN(AttributeDesignator); + /** AttributeQueryType local name */ + static const XMLCh TYPE_NAME[]; + END_XMLOBJECT; + + BEGIN_XMLOBJECT(SAML_API,AuthorizationDecisionQuery,SubjectQuery,SAML 1.x AuthorizationDecisionQuery element); + DECL_STRING_ATTRIB(Resource,RESOURCE); + DECL_TYPED_CHILDREN(Action); + DECL_TYPED_CHILD(Evidence); + /** AuthorizationDecisionQueryType local name */ + static const XMLCh TYPE_NAME[]; + END_XMLOBJECT; + + BEGIN_XMLOBJECT(SAML_API,AbstractRequest,xmltooling::XMLObject,SAML 1.x RequestAbstractType base type); + DECL_INTEGER_ATTRIB(MinorVersion,MINORVERSION); + DECL_STRING_ATTRIB(RequestID,REQUESTID); + DECL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT); + DECL_TYPED_CHILDREN(RespondWith); + DECL_TYPED_FOREIGN_CHILD(Signature,xmlsignature); + END_XMLOBJECT; + + BEGIN_XMLOBJECT(SAML_API,Request,AbstractRequest,SAML 1.x Request element); + DECL_TYPED_CHILD(Query); + DECL_TYPED_CHILD(SubjectQuery); + DECL_TYPED_CHILD(AuthenticationQuery); + DECL_TYPED_CHILD(AttributeQuery); + DECL_TYPED_CHILD(AuthorizationDecisionQuery); + DECL_TYPED_CHILDREN(AssertionIDReference); + DECL_TYPED_CHILDREN(AssertionArtifact); + /** RequestType local name */ + static const XMLCh TYPE_NAME[]; + END_XMLOBJECT; + + BEGIN_XMLOBJECT(SAML_API,StatusCode,xmltooling::XMLObject,SAML 1.x StatusCode element); + DECL_XMLOBJECT_ATTRIB(Value,VALUE,xmltooling::QName); + DECL_TYPED_CHILD(StatusCode); + /** StatusCodeType local name */ + static const XMLCh TYPE_NAME[]; + /** Success Status Code */ + static xmltooling::QName SUCCESS; + /** Requester Error Status Code */ + static xmltooling::QName REQUESTER; + /** Responder Error Status Code */ + static xmltooling::QName RESPONDER; + /** Version Mismatch Error Status Code */ + static xmltooling::QName VERSIONMISMATCH; + END_XMLOBJECT; + + BEGIN_XMLOBJECT(SAML_API,StatusDetail,xmltooling::XMLObject,SAML 1.x StatusDetail element); + DECL_XMLOBJECT_CHILDREN(Detail); + /** StatusDetailType local name */ + static const XMLCh TYPE_NAME[]; + END_XMLOBJECT; + + DECL_SAML1POBJECTBUILDER(AssertionArtifact); + DECL_SAML1POBJECTBUILDER(AttributeQuery); + DECL_SAML1POBJECTBUILDER(AuthenticationQuery); + DECL_SAML1POBJECTBUILDER(AuthorizationDecisionQuery); + DECL_SAML1POBJECTBUILDER(Request); + DECL_SAML1POBJECTBUILDER(RespondWith); + DECL_SAML1POBJECTBUILDER(StatusCode); + DECL_SAML1POBJECTBUILDER(StatusDetail); + DECL_SAML1POBJECTBUILDER(StatusMessage); + + /** + * Registers builders and validators for Protocol classes into the runtime. + */ + void SAML_API registerProtocolClasses(); + }; +}; + +#endif /* __saml1_protocols_h__ */ diff --git a/saml/saml1/core/impl/AssertionsImpl.cpp b/saml/saml1/core/impl/AssertionsImpl.cpp index 37f7656..8ada823 100644 --- a/saml/saml1/core/impl/AssertionsImpl.cpp +++ b/saml/saml1/core/impl/AssertionsImpl.cpp @@ -372,8 +372,15 @@ namespace opensaml { public AbstractXMLObjectMarshaller, public AbstractXMLObjectUnmarshaller { + void init() { + m_Subject=NULL; + m_children.push_back(NULL); + m_pos_Subject=m_children.begin(); + } protected: - SubjectStatementImpl() {} + SubjectStatementImpl() { + init(); + } public: virtual ~SubjectStatementImpl() {} @@ -391,12 +398,6 @@ namespace opensaml { setSubject(src.getSubject()->cloneSubject()); } - void init() { - m_Subject=NULL; - m_children.push_back(NULL); - m_pos_Subject=m_children.begin(); - } - IMPL_TYPED_CHILD(Subject); protected: @@ -515,7 +516,8 @@ namespace opensaml { init(); } - AuthenticationStatementImpl(const AuthenticationStatementImpl& src) : SubjectStatementImpl(src) { + AuthenticationStatementImpl(const AuthenticationStatementImpl& src) + : AbstractXMLObject(src), SubjectStatementImpl(src) { init(); setAuthenticationMethod(src.getAuthenticationMethod()); setAuthenticationInstant(src.getAuthenticationInstant()); @@ -530,7 +532,6 @@ namespace opensaml { } void init() { - SubjectStatementImpl::init(); m_AuthenticationMethod=NULL; m_AuthenticationInstant=NULL; m_SubjectLocality=NULL; @@ -670,7 +671,8 @@ namespace opensaml { init(); } - AuthorizationDecisionStatementImpl(const AuthorizationDecisionStatementImpl& src) : SubjectStatementImpl(src) { + AuthorizationDecisionStatementImpl(const AuthorizationDecisionStatementImpl& src) + : AbstractXMLObject(src), SubjectStatementImpl(src) { init(); setResource(src.getResource()); setDecision(src.getDecision()); @@ -685,7 +687,6 @@ namespace opensaml { } void init() { - SubjectStatementImpl::init(); m_Resource=NULL; m_Decision=NULL; m_Evidence=NULL; @@ -852,10 +853,10 @@ namespace opensaml { AttributeStatementImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) : AbstractXMLObject(nsURI, localName, prefix, schemaType) { - init(); } - AttributeStatementImpl(const AttributeStatementImpl& src) : SubjectStatementImpl(src) { + AttributeStatementImpl(const AttributeStatementImpl& src) + : AbstractXMLObject(src), SubjectStatementImpl(src) { VectorOf(Attribute) v=getAttributes(); for (vector::const_iterator i=src.m_Attributes.begin(); i!=src.m_Attributes.end(); i++) { if (*i) { @@ -1175,6 +1176,7 @@ const XMLCh SubjectLocality::LOCAL_NAME[] = UNICODE_LITERAL_15(S,u,b,j,e const XMLCh SubjectLocality::TYPE_NAME[] = UNICODE_LITERAL_19(S,u,b,j,e,c,t,L,o,c,a,l,i,t,y,T,y,p,e); const XMLCh SubjectLocality::IPADDRESS_ATTRIB_NAME[] = UNICODE_LITERAL_9(I,P,A,d,d,r,e,s,s); const XMLCh SubjectLocality::DNSADDRESS_ATTRIB_NAME[] = UNICODE_LITERAL_10(D,N,S,A,d,d,r,e,s,s); +const XMLCh SubjectStatement::LOCAL_NAME[] = UNICODE_LITERAL_16(S,u,b,j,e,c,t,S,t,a,t,e,m,e,n,t); #define XCH(ch) chLatin_##ch #define XNUM(d) chDigit_##d diff --git a/saml/saml1/core/impl/ProtocolsImpl.cpp b/saml/saml1/core/impl/ProtocolsImpl.cpp new file mode 100644 index 0000000..fbdd632 --- /dev/null +++ b/saml/saml1/core/impl/ProtocolsImpl.cpp @@ -0,0 +1,603 @@ +/* + * Copyright 2001-2006 Internet2 + * + * 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. + */ + +/** + * ProtocolsImpl.cpp + * + * Implementation classes for SAML 1.x Protocols schema + */ + +#include "internal.h" +#include "exceptions.h" +#include "saml1/core/Protocols.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +using namespace opensaml::saml1; +using namespace opensaml; +using namespace xmlsignature; +using namespace xmltooling; +using namespace std; + +#if defined (_MSC_VER) + #pragma warning( push ) + #pragma warning( disable : 4250 4251 ) +#endif + +namespace opensaml { + namespace saml1 { + + DECL_XMLOBJECTIMPL_SIMPLE(SAML_DLLLOCAL,AssertionArtifact); + DECL_XMLOBJECTIMPL_SIMPLE(SAML_DLLLOCAL,StatusMessage); + + class SAML_DLLLOCAL RespondWithImpl : public virtual RespondWith, + protected AbstractSimpleElement, + public AbstractChildlessElement, + public AbstractDOMCachingXMLObject, + public AbstractValidatingXMLObject, + public AbstractXMLObjectMarshaller, + public AbstractXMLObjectUnmarshaller + { + QName* m_qname; + public: + virtual ~RespondWithImpl() { + delete m_qname; + } + + RespondWithImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_qname(NULL) { + } + + RespondWithImpl(const RespondWithImpl& src) + : AbstractXMLObject(src), + AbstractSimpleElement(src), + AbstractDOMCachingXMLObject(src), + AbstractValidatingXMLObject(src), m_qname(NULL) { + setQName(src.getQName()); + } + + QName* getQName() const { + return m_qname; + } + + void setQName(const QName* qname) { + m_qname=prepareForAssignment(m_qname,qname); + if (m_qname) { + auto_ptr_XMLCh temp(m_qname->toString().c_str()); + setTextContent(temp.get()); + } + else + setTextContent(NULL); + } + + IMPL_XMLOBJECT_CLONE(RespondWith); + IMPL_XMLOBJECT_CONTENT(); + }; + + class SAML_DLLLOCAL SubjectQueryImpl : public virtual SubjectQuery, + public AbstractComplexElement, + public AbstractDOMCachingXMLObject, + public AbstractValidatingXMLObject, + public AbstractXMLObjectMarshaller, + public AbstractXMLObjectUnmarshaller + { + void init() { + m_Subject=NULL; + m_children.push_back(NULL); + m_pos_Subject=m_children.begin(); + } + protected: + SubjectQueryImpl() { + init(); + } + public: + virtual ~SubjectQueryImpl() {} + + SubjectQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType) { + init(); + } + + SubjectQueryImpl(const SubjectQueryImpl& src) + : AbstractXMLObject(src), + AbstractDOMCachingXMLObject(src), + AbstractValidatingXMLObject(src) { + init(); + if (src.getSubject()) + setSubject(src.getSubject()->cloneSubject()); + } + + IMPL_TYPED_CHILD(Subject); + + protected: + void processChildElement(XMLObject* childXMLObject, const DOMElement* root) { + PROC_TYPED_CHILD(Subject,SAMLConstants::SAML1_NS,true); + AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root); + } + }; + + class SAML_DLLLOCAL AuthenticationQueryImpl : public virtual AuthenticationQuery, public SubjectQueryImpl + { + void init() { + m_AuthenticationMethod=NULL; + } + public: + virtual ~AuthenticationQueryImpl() { + XMLString::release(&m_AuthenticationMethod); + } + + AuthenticationQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType) { + init(); + } + + AuthenticationQueryImpl(const AuthenticationQueryImpl& src) + : AbstractXMLObject(src), SubjectQueryImpl(src) { + init(); + setAuthenticationMethod(src.getAuthenticationMethod()); + } + + IMPL_XMLOBJECT_CLONE(AuthenticationQuery); + SubjectQuery* cloneSubjectQuery() const { + return cloneAuthenticationQuery(); + } + Query* cloneQuery() const { + return cloneAuthenticationQuery(); + } + IMPL_STRING_ATTRIB(AuthenticationMethod); + + protected: + void marshallAttributes(DOMElement* domElement) const { + MARSHALL_STRING_ATTRIB(AuthenticationMethod,AUTHENTICATIONMETHOD,NULL); + SubjectQueryImpl::marshallAttributes(domElement); + } + + void processAttribute(const DOMAttr* attribute) { + PROC_STRING_ATTRIB(AuthenticationMethod,AUTHENTICATIONMETHOD,NULL); + SubjectQueryImpl::processAttribute(attribute); + } + }; + + class SAML_DLLLOCAL AttributeQueryImpl : public virtual AttributeQuery, public SubjectQueryImpl + { + void init() { + m_Resource=NULL; + } + public: + virtual ~AttributeQueryImpl() { + XMLString::release(&m_Resource); + } + + AttributeQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType) { + init(); + } + + AttributeQueryImpl(const AttributeQueryImpl& src) + : AbstractXMLObject(src), SubjectQueryImpl(src) { + init(); + setResource(src.getResource()); + VectorOf(AttributeDesignator) v=getAttributeDesignators(); + for (vector::const_iterator i=src.m_AttributeDesignators.begin(); i!=src.m_AttributeDesignators.end(); i++) { + if (*i) { + v.push_back((*i)->cloneAttributeDesignator()); + } + } + } + + IMPL_XMLOBJECT_CLONE(AttributeQuery); + SubjectQuery* cloneSubjectQuery() const { + return cloneAttributeQuery(); + } + Query* cloneQuery() const { + return cloneAttributeQuery(); + } + IMPL_STRING_ATTRIB(Resource); + IMPL_TYPED_CHILDREN(AttributeDesignator,m_children.end()); + + protected: + void marshallAttributes(DOMElement* domElement) const { + MARSHALL_STRING_ATTRIB(Resource,RESOURCE,NULL); + SubjectQueryImpl::marshallAttributes(domElement); + } + + void processChildElement(XMLObject* childXMLObject, const DOMElement* root) { + PROC_TYPED_CHILDREN(AttributeDesignator,SAMLConstants::SAML1_NS,true); + SubjectQueryImpl::processChildElement(childXMLObject,root); + } + + void processAttribute(const DOMAttr* attribute) { + PROC_STRING_ATTRIB(Resource,RESOURCE,NULL); + SubjectQueryImpl::processAttribute(attribute); + } + }; + + class SAML_DLLLOCAL AuthorizationDecisionQueryImpl : public virtual AuthorizationDecisionQuery, public SubjectQueryImpl + { + void init() { + m_Resource=NULL; + m_Evidence=NULL; + m_children.push_back(NULL); + m_pos_Evidence=m_pos_Subject; + m_pos_Evidence++; + } + public: + virtual ~AuthorizationDecisionQueryImpl() { + XMLString::release(&m_Resource); + } + + AuthorizationDecisionQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType) { + init(); + } + + AuthorizationDecisionQueryImpl(const AuthorizationDecisionQueryImpl& src) + : AbstractXMLObject(src), SubjectQueryImpl(src) { + init(); + setResource(src.getResource()); + if (src.getEvidence()) + setEvidence(src.getEvidence()->cloneEvidence()); + VectorOf(Action) v=getActions(); + for (vector::const_iterator i=src.m_Actions.begin(); i!=src.m_Actions.end(); i++) { + if (*i) { + v.push_back((*i)->cloneAction()); + } + } + } + + IMPL_XMLOBJECT_CLONE(AuthorizationDecisionQuery); + SubjectQuery* cloneSubjectQuery() const { + return cloneAuthorizationDecisionQuery(); + } + Query* cloneQuery() const { + return cloneAuthorizationDecisionQuery(); + } + IMPL_STRING_ATTRIB(Resource); + IMPL_TYPED_CHILD(Evidence); + IMPL_TYPED_CHILDREN(Action, m_pos_Evidence); + + protected: + void marshallAttributes(DOMElement* domElement) const { + MARSHALL_STRING_ATTRIB(Resource,RESOURCE,NULL); + SubjectQueryImpl::marshallAttributes(domElement); + } + + void processChildElement(XMLObject* childXMLObject, const DOMElement* root) { + PROC_TYPED_CHILD(Evidence,SAMLConstants::SAML1_NS,false); + PROC_TYPED_CHILDREN(Action,SAMLConstants::SAML1_NS,false); + SubjectQueryImpl::processChildElement(childXMLObject,root); + } + + void processAttribute(const DOMAttr* attribute) { + PROC_STRING_ATTRIB(Resource,RESOURCE,NULL); + SubjectQueryImpl::processAttribute(attribute); + } + }; + + class SAML_DLLLOCAL AbstractRequestImpl : public virtual AbstractRequest, + public AbstractComplexElement, + public AbstractDOMCachingXMLObject, + public AbstractValidatingXMLObject, + public AbstractXMLObjectMarshaller, + public AbstractXMLObjectUnmarshaller + { + void init() { + m_MinorVersion=1; + m_RequestID=NULL; + m_IssueInstant=NULL; + m_children.push_back(NULL); + m_Signature=NULL; + m_pos_Signature=m_children.begin(); + } + protected: + AbstractRequestImpl() {} + public: + virtual ~AbstractRequestImpl() { + XMLString::release(&m_RequestID); + delete m_IssueInstant; + } + + AbstractRequestImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType) { + init(); + } + + AbstractRequestImpl(const AbstractRequestImpl& src) + : AbstractXMLObject(src), + AbstractDOMCachingXMLObject(src), + AbstractValidatingXMLObject(src) { + init(); + setMinorVersion(src.getMinorVersion()); + setRequestID(src.getRequestID()); + setIssueInstant(src.getIssueInstant()); + if (src.getSignature()) + setSignature(src.getSignature()->cloneSignature()); + VectorOf(RespondWith) v=getRespondWiths(); + for (vector::const_iterator i=src.m_RespondWiths.begin(); i!=src.m_RespondWiths.end(); i++) { + if (*i) { + v.push_back((*i)->cloneRespondWith()); + } + } + } + + IMPL_INTEGER_ATTRIB(MinorVersion); + IMPL_STRING_ATTRIB(RequestID); + IMPL_DATETIME_ATTRIB(IssueInstant); + IMPL_TYPED_CHILDREN(RespondWith,m_pos_Signature); + IMPL_TYPED_CHILD(Signature); + + protected: + void marshallAttributes(DOMElement* domElement) const { + static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n); + static const XMLCh ONE[] = { chDigit_1, chNull }; + domElement->setAttributeNS(NULL,MAJORVERSION,ONE); + MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL); + if (!m_RequestID) + const_cast(this)->m_RequestID=SAMLConfig::getConfig().generateIdentifier(); + MARSHALL_ID_ATTRIB(RequestID,REQUESTID,NULL); + if (!m_IssueInstant) + const_cast(this)->m_IssueInstant=new DateTime(time(NULL)); + MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL); + } + + void processChildElement(XMLObject* childXMLObject, const DOMElement* root) { + PROC_TYPED_CHILDREN(RespondWith,SAMLConstants::SAML1P_NS,false); + PROC_TYPED_CHILD(Signature,XMLConstants::XMLSIG_NS,false); + AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root); + } + + void processAttribute(const DOMAttr* attribute) { + static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n); + if (XMLHelper::isNodeNamed(attribute,NULL,MAJORVERSION)) { + if (XMLString::parseInt(attribute->getValue()) != 1) + throw UnmarshallingException("Request has invalid major version."); + } + PROC_INTEGER_ATTRIB(MinorVersion,MINORVERSION,NULL); + PROC_ID_ATTRIB(RequestID,REQUESTID,NULL); + PROC_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,NULL); + } + }; + + class SAML_DLLLOCAL RequestImpl : public virtual Request, public AbstractRequestImpl + { + void init() { + m_children.push_back(NULL); + m_Query=NULL; + m_pos_Query=m_pos_Signature; + m_pos_Query++; + } + public: + virtual ~RequestImpl() {} + + RequestImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType) { + init(); + } + + RequestImpl(const RequestImpl& src) + : AbstractXMLObject(src), AbstractRequestImpl(src) { + init(); + if (src.getQuery()) + setQuery(src.getQuery()->cloneQuery()); + VectorOf(AssertionIDReference) v=getAssertionIDReferences(); + for (vector::const_iterator i=src.m_AssertionIDReferences.begin(); i!=src.m_AssertionIDReferences.end(); i++) { + if (*i) { + v.push_back((*i)->cloneAssertionIDReference()); + } + } + VectorOf(AssertionArtifact) v2=getAssertionArtifacts(); + for (vector::const_iterator i=src.m_AssertionArtifacts.begin(); i!=src.m_AssertionArtifacts.end(); i++) { + if (*i) { + v2.push_back((*i)->cloneAssertionArtifact()); + } + } + } + + IMPL_XMLOBJECT_CLONE(Request); + AbstractRequest* cloneAbstractRequest() const { + return cloneRequest(); + } + IMPL_TYPED_CHILD(Query); + + SubjectQuery* getSubjectQuery() const { + return dynamic_cast(getQuery()); + } + AuthenticationQuery* getAuthenticationQuery() const { + return dynamic_cast(getQuery()); + } + AttributeQuery* getAttributeQuery() const { + return dynamic_cast(getQuery()); + } + AuthorizationDecisionQuery* getAuthorizationDecisionQuery() const { + return dynamic_cast(getQuery()); + } + + void setSubjectQuery(SubjectQuery* q) { + setQuery(q); + } + void setAuthenticationQuery(AuthenticationQuery* q) { + setQuery(q); + } + void setAttributeQuery(AttributeQuery* q) { + setQuery(q); + } + void setAuthorizationDecisionQuery(AuthorizationDecisionQuery* q) { + setQuery(q); + } + + IMPL_TYPED_CHILDREN(AssertionIDReference, m_children.end()); + IMPL_TYPED_CHILDREN(AssertionArtifact, m_children.end()); + + protected: + void processChildElement(XMLObject* childXMLObject, const DOMElement* root) { + PROC_TYPED_CHILD(Query,SAMLConstants::SAML1P_NS,true); + PROC_TYPED_CHILDREN(AssertionIDReference,SAMLConstants::SAML1_NS,false); + PROC_TYPED_CHILDREN(AssertionArtifact,SAMLConstants::SAML1P_NS,false); + AbstractRequestImpl::processChildElement(childXMLObject,root); + } + }; + + class SAML_DLLLOCAL StatusCodeImpl : public virtual StatusCode, + public AbstractComplexElement, + public AbstractDOMCachingXMLObject, + public AbstractValidatingXMLObject, + public AbstractXMLObjectMarshaller, + public AbstractXMLObjectUnmarshaller + { + void init() { + m_Value=NULL; + m_children.push_back(NULL); + m_StatusCode=NULL; + m_pos_StatusCode=m_children.begin(); + } + public: + virtual ~StatusCodeImpl() { + delete m_Value; + } + + StatusCodeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType) { + init(); + } + + StatusCodeImpl(const StatusCodeImpl& src) + : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) { + init(); + setValue(src.getValue()); + if (src.getStatusCode()) + setStatusCode(src.getStatusCode()->cloneStatusCode()); + } + + IMPL_XMLOBJECT_CLONE(StatusCode); + IMPL_XMLOBJECT_ATTRIB(Value,QName); + IMPL_TYPED_CHILD(StatusCode); + + protected: + void marshallAttributes(DOMElement* domElement) const { + MARSHALL_QNAME_ATTRIB(Value,VALUE,NULL); + } + + void processChildElement(XMLObject* childXMLObject, const DOMElement* root) { + PROC_TYPED_CHILD(StatusCode,SAMLConstants::SAML1P_NS,true); + AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root); + } + + void processAttribute(const DOMAttr* attribute) { + PROC_QNAME_ATTRIB(Value,VALUE,NULL); + } + }; + + class SAML_DLLLOCAL StatusDetailImpl : public virtual StatusDetail, + public AbstractComplexElement, + public AbstractDOMCachingXMLObject, + public AbstractValidatingXMLObject, + public AbstractXMLObjectMarshaller, + public AbstractXMLObjectUnmarshaller + { + public: + virtual ~StatusDetailImpl() {} + + StatusDetailImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const QName* schemaType) + : AbstractXMLObject(nsURI, localName, prefix, schemaType) { + } + + StatusDetailImpl(const StatusDetailImpl& src) + : AbstractXMLObject(src), AbstractDOMCachingXMLObject(src), AbstractValidatingXMLObject(src) { + VectorOf(XMLObject) v=getDetails(); + for (vector::const_iterator i=src.m_Details.begin(); i!=src.m_Details.end(); i++) { + if (*i) { + v.push_back((*i)->clone()); + } + } + } + + IMPL_XMLOBJECT_CLONE(StatusDetail); + IMPL_XMLOBJECT_CHILDREN(Detail,m_children.end()); + + protected: + void processChildElement(XMLObject* childXMLObject, const DOMElement* root) { + getDetails().push_back(childXMLObject); + } + }; + + }; +}; + +#if defined (_MSC_VER) + #pragma warning( pop ) +#endif + +// Builder Implementations + +IMPL_XMLOBJECTBUILDER(AssertionArtifact); +IMPL_XMLOBJECTBUILDER(AttributeQuery); +IMPL_XMLOBJECTBUILDER(AuthenticationQuery); +IMPL_XMLOBJECTBUILDER(AuthorizationDecisionQuery); +IMPL_XMLOBJECTBUILDER(Request); +IMPL_XMLOBJECTBUILDER(RespondWith); +IMPL_XMLOBJECTBUILDER(StatusCode); +IMPL_XMLOBJECTBUILDER(StatusDetail); +IMPL_XMLOBJECTBUILDER(StatusMessage); + +// Unicode literals +const XMLCh AbstractRequest::MINORVERSION_ATTRIB_NAME[] = UNICODE_LITERAL_12(M,i,n,o,r,V,e,r,s,i,o,n); +const XMLCh AbstractRequest::REQUESTID_ATTRIB_NAME[] = UNICODE_LITERAL_9(R,e,q,u,e,s,t,I,D); +const XMLCh AbstractRequest::ISSUEINSTANT_ATTRIB_NAME[] = UNICODE_LITERAL_12(I,s,s,u,e,I,n,s,t,a,n,t); +const XMLCh AssertionArtifact::LOCAL_NAME[] = UNICODE_LITERAL_17(A,s,s,e,r,t,i,o,n,A,r,t,i,f,a,c,t); +const XMLCh AttributeQuery::LOCAL_NAME[] = UNICODE_LITERAL_14(A,t,t,r,i,b,u,t,e,Q,u,e,r,y); +const XMLCh AttributeQuery::TYPE_NAME[] = UNICODE_LITERAL_18(A,t,t,r,i,b,u,t,e,Q,u,e,r,y,T,y,p,e); +const XMLCh AttributeQuery::RESOURCE_ATTRIB_NAME[] = UNICODE_LITERAL_8(R,e,s,o,u,r,c,e); +const XMLCh AuthenticationQuery::LOCAL_NAME[] = UNICODE_LITERAL_19(A,u,t,h,e,n,t,i,c,a,t,i,o,n,Q,u,e,r,y); +const XMLCh AuthenticationQuery::TYPE_NAME[] = UNICODE_LITERAL_23(A,u,t,h,e,n,t,i,c,a,t,i,o,n,Q,u,e,r,y,T,y,p,e); +const XMLCh AuthenticationQuery::AUTHENTICATIONMETHOD_ATTRIB_NAME[] = UNICODE_LITERAL_20(A,u,t,h,e,n,t,i,c,a,t,i,o,n,M,e,t,h,o,d); +const XMLCh AuthorizationDecisionQuery::LOCAL_NAME[] = UNICODE_LITERAL_26(A,u,t,h,o,r,i,z,a,t,i,o,n,D,e,c,i,s,i,o,n,Q,u,e,r,y); +const XMLCh AuthorizationDecisionQuery::TYPE_NAME[] = UNICODE_LITERAL_30(A,u,t,h,o,r,i,z,a,t,i,o,n,D,e,c,i,s,i,o,n,Q,u,e,r,y,T,y,p,e); +const XMLCh AuthorizationDecisionQuery::RESOURCE_ATTRIB_NAME[] = UNICODE_LITERAL_8(R,e,s,o,u,r,c,e); +const XMLCh Query::LOCAL_NAME[] = UNICODE_LITERAL_5(Q,u,e,r,y); +const XMLCh Request::LOCAL_NAME[] = UNICODE_LITERAL_7(R,e,q,u,e,s,t); +const XMLCh Request::TYPE_NAME[] = UNICODE_LITERAL_11(R,e,q,u,e,s,t,T,y,p,e); +const XMLCh RespondWith::LOCAL_NAME[] = UNICODE_LITERAL_11(R,e,s,p,o,n,d,W,i,t,h); +const XMLCh StatusCode::LOCAL_NAME[] = UNICODE_LITERAL_10(S,t,a,t,u,s,C,o,d,e); +const XMLCh StatusCode::TYPE_NAME[] = UNICODE_LITERAL_14(S,t,a,t,u,s,C,o,d,e,T,y,p,e); +const XMLCh StatusCode::VALUE_ATTRIB_NAME[] = UNICODE_LITERAL_5(V,a,l,u,e); +const XMLCh StatusDetail::LOCAL_NAME[] = UNICODE_LITERAL_12(S,t,a,t,u,s,D,e,t,a,i,l); +const XMLCh StatusDetail::TYPE_NAME[] = UNICODE_LITERAL_16(S,t,a,t,u,s,D,e,t,a,i,l,T,y,p,e); +const XMLCh StatusMessage::LOCAL_NAME[] = UNICODE_LITERAL_13(S,t,a,t,u,s,M,e,s,s,a,g,e); +const XMLCh SubjectQuery::LOCAL_NAME[] = UNICODE_LITERAL_12(S,u,b,j,e,c,t,Q,u,e,r,y); + +#define XCH(ch) chLatin_##ch +#define XNUM(d) chDigit_##d + +const XMLCh _SUCCESS[] = UNICODE_LITERAL_7(S,u,c,c,e,s,s); +const XMLCh _REQUESTER[] = UNICODE_LITERAL_9(R,e,q,u,e,s,t,e,r); +const XMLCh _RESPONDER[] = UNICODE_LITERAL_9(R,e,s,p,o,n,d,e,r); +const XMLCh _VERSIONMISMATCH[] = UNICODE_LITERAL_15(V,e,r,s,i,o,n,M,i,s,m,a,t,c,h); + +QName StatusCode::SUCCESS(SAMLConstants::SAML1P_NS,_SUCCESS,SAMLConstants::SAML1P_PREFIX); +QName StatusCode::REQUESTER(SAMLConstants::SAML1P_NS,_REQUESTER,SAMLConstants::SAML1P_PREFIX); +QName StatusCode::RESPONDER(SAMLConstants::SAML1P_NS,_RESPONDER,SAMLConstants::SAML1P_PREFIX); +QName StatusCode::VERSIONMISMATCH(SAMLConstants::SAML1P_NS,_VERSIONMISMATCH,SAMLConstants::SAML1P_PREFIX); diff --git a/saml/saml1/core/impl/ProtocolsSchemaValidators.cpp b/saml/saml1/core/impl/ProtocolsSchemaValidators.cpp new file mode 100644 index 0000000..d4b1bc2 --- /dev/null +++ b/saml/saml1/core/impl/ProtocolsSchemaValidators.cpp @@ -0,0 +1,112 @@ +/* +* Copyright 2001-2006 Internet2 + * +* 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. + */ + +/** + * ProtocolsSchemaValidators.cpp + * + * Schema-based validators for SAML 1.x Protocols classes + */ + +#include "internal.h" +#include "exceptions.h" +#include "saml1/core/Protocols.h" + +using namespace opensaml::saml1; +using namespace opensaml; +using namespace xmltooling; +using namespace std; + +namespace opensaml { + namespace saml1 { + + XMLOBJECTVALIDATOR_SIMPLE(SAML_DLLLOCAL,AssertionArtifact); + XMLOBJECTVALIDATOR_SIMPLE(SAML_DLLLOCAL,StatusMessage); + + BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,RespondWith); + XMLOBJECTVALIDATOR_REQUIRE(RespondWith,QName); + END_XMLOBJECTVALIDATOR; + + BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,AuthenticationQuery); + XMLOBJECTVALIDATOR_REQUIRE(AuthenticationQuery,AuthenticationMethod); + XMLOBJECTVALIDATOR_REQUIRE(AuthenticationQuery,Subject); + END_XMLOBJECTVALIDATOR; + + BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,AttributeQuery); + XMLOBJECTVALIDATOR_REQUIRE(AttributeQuery,Subject); + END_XMLOBJECTVALIDATOR; + + BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,AuthorizationDecisionQuery); + XMLOBJECTVALIDATOR_REQUIRE(AuthorizationDecisionQuery,Subject); + XMLOBJECTVALIDATOR_REQUIRE(AuthorizationDecisionQuery,Resource); + XMLOBJECTVALIDATOR_NONEMPTY(AuthorizationDecisionQuery,Action); + END_XMLOBJECTVALIDATOR; + + BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,Request); + XMLOBJECTVALIDATOR_REQUIRE(Request,RequestID); + XMLOBJECTVALIDATOR_REQUIRE(Request,IssueInstant); + int count=0; + if (ptr->getQuery()!=NULL) + count++; + if (!ptr->getAssertionIDReferences().empty()) + count++; + if (!ptr->getAssertionArtifacts().empty()) + count++; + if (count != 1) + throw ValidationException("Request must have either a query, >0 assertion references, or >0 artifacts."); + END_XMLOBJECTVALIDATOR; + + BEGIN_XMLOBJECTVALIDATOR(SAML_DLLLOCAL,StatusCode); + XMLOBJECTVALIDATOR_REQUIRE(StatusCode,Value); + END_XMLOBJECTVALIDATOR; + }; +}; + +#define REGISTER_ELEMENT(cname) \ + q=QName(SAMLConstants::SAML1P_NS,cname::LOCAL_NAME); \ + XMLObjectBuilder::registerBuilder(q,new cname##Builder()); \ + Validator::registerValidator(q,new cname##SchemaValidator()) + +#define REGISTER_TYPE(cname) \ + q=QName(SAMLConstants::SAML1P_NS,cname::TYPE_NAME); \ + XMLObjectBuilder::registerBuilder(q,new cname##Builder()); \ + Validator::registerValidator(q,new cname##SchemaValidator()) + +#define REGISTER_ELEMENT_NOVAL(cname) \ + q=QName(SAMLConstants::SAML1P_NS,cname::LOCAL_NAME); \ + XMLObjectBuilder::registerBuilder(q,new cname##Builder()); + +#define REGISTER_TYPE_NOVAL(cname) \ + q=QName(SAMLConstants::SAML1P_NS,cname::TYPE_NAME); \ + XMLObjectBuilder::registerBuilder(q,new cname##Builder()); + +void opensaml::saml1::registerProtocolClasses() { + QName q; + REGISTER_ELEMENT(AssertionArtifact); + REGISTER_ELEMENT(AttributeQuery); + REGISTER_ELEMENT(AuthenticationQuery); + REGISTER_ELEMENT(AuthorizationDecisionQuery); + REGISTER_ELEMENT(Request); + REGISTER_ELEMENT(RespondWith); + REGISTER_ELEMENT(StatusCode); + REGISTER_ELEMENT_NOVAL(StatusDetail); + REGISTER_ELEMENT(StatusMessage); + REGISTER_TYPE(AttributeQuery); + REGISTER_TYPE(AuthenticationQuery); + REGISTER_TYPE(AuthorizationDecisionQuery); + REGISTER_TYPE(Request); + REGISTER_TYPE(StatusCode); + REGISTER_TYPE_NOVAL(StatusDetail); +}