2 * Licensed to the University Corporation for Advanced Internet
3 * Development, Inc. (UCAID) under one or more contributor license
4 * agreements. See the NOTICE file distributed with this work for
5 * additional information regarding copyright ownership.
7 * UCAID licenses this file to you under the Apache License,
8 * Version 2.0 (the "License"); you may not use this file except
9 * in compliance with the License. You may obtain a copy of the
12 * http://www.apache.org/licenses/LICENSE-2.0
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
17 * either express or implied. See the License for the specific
18 * language governing permissions and limitations under the License.
24 * Implementation classes for SAML 1.x Protocols schema.
28 #include "exceptions.h"
29 #include "saml1/core/Assertions.h"
30 #include "saml1/core/Protocols.h"
31 #include "signature/ContentReference.h"
33 #include <xmltooling/AbstractComplexElement.h>
34 #include <xmltooling/AbstractSimpleElement.h>
35 #include <xmltooling/impl/AnyElement.h>
36 #include <xmltooling/io/AbstractXMLObjectMarshaller.h>
37 #include <xmltooling/io/AbstractXMLObjectUnmarshaller.h>
38 #include <xmltooling/signature/Signature.h>
39 #include <xmltooling/util/DateTime.h>
40 #include <xmltooling/util/XMLHelper.h>
43 #include <xercesc/util/XMLUniDefs.hpp>
45 using namespace opensaml::saml1p;
46 using namespace opensaml::saml1;
47 using namespace xmlsignature;
48 using namespace xmltooling;
50 using xmlconstants::XMLSIG_NS;
51 using xmlconstants::XML_ONE;
52 using samlconstants::SAML1P_NS;
53 using samlconstants::SAML1_NS;
54 using samlconstants::SAML1P_PREFIX;
56 #if defined (_MSC_VER)
57 #pragma warning( push )
58 #pragma warning( disable : 4250 4251 )
64 DECL_XMLOBJECTIMPL_SIMPLE(SAML_DLLLOCAL,AssertionArtifact);
65 DECL_XMLOBJECTIMPL_SIMPLE(SAML_DLLLOCAL,StatusMessage);
67 class SAML_DLLLOCAL RespondWithImpl : public virtual RespondWith,
68 public AbstractSimpleElement,
69 public AbstractDOMCachingXMLObject,
70 public AbstractXMLObjectMarshaller,
71 public AbstractXMLObjectUnmarshaller
73 mutable xmltooling::QName* m_qname;
75 virtual ~RespondWithImpl() {
79 RespondWithImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
80 : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_qname(nullptr) {
83 RespondWithImpl(const RespondWithImpl& src)
84 : AbstractXMLObject(src), AbstractSimpleElement(src), AbstractDOMCachingXMLObject(src), m_qname(nullptr) {
85 setQName(src.getQName());
88 xmltooling::QName* getQName() const {
89 if (!m_qname && getDOM() && getDOM()->getTextContent()) {
90 m_qname = XMLHelper::getNodeValueAsQName(getDOM());
95 void setQName(const xmltooling::QName* qname) {
96 m_qname=prepareForAssignment(m_qname,qname);
98 auto_ptr_XMLCh temp(m_qname->toString().c_str());
99 setTextContent(temp.get());
102 setTextContent(nullptr);
106 IMPL_XMLOBJECT_CLONE(RespondWith);
109 class SAML_DLLLOCAL QueryImpl : public virtual Query, public AnyElementImpl
112 virtual ~QueryImpl() {}
114 QueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
115 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
118 QueryImpl(const QueryImpl& src) : AbstractXMLObject(src), AnyElementImpl(src) {}
120 IMPL_XMLOBJECT_CLONE_EX(Query);
123 class SAML_DLLLOCAL SubjectQueryImpl : public virtual SubjectQuery,
124 public AbstractComplexElement,
125 public AbstractDOMCachingXMLObject,
126 public AbstractXMLObjectMarshaller,
127 public AbstractXMLObjectUnmarshaller
131 m_children.push_back(nullptr);
132 m_pos_Subject=m_children.begin();
141 virtual ~SubjectQueryImpl() {}
143 SubjectQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
144 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
148 SubjectQueryImpl(const SubjectQueryImpl& src)
149 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
153 void _clone(const SubjectQueryImpl& src) {
154 if (src.getSubject())
155 setSubject(src.getSubject()->cloneSubject());
158 SubjectQuery* cloneSubjectQuery() const {
159 return dynamic_cast<SubjectQuery*>(clone());
162 Query* cloneQuery() const {
163 return dynamic_cast<Query*>(clone());
166 IMPL_TYPED_CHILD(Subject);
169 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
170 PROC_TYPED_CHILD(Subject,SAML1_NS,true);
171 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
175 class SAML_DLLLOCAL AuthenticationQueryImpl : public virtual AuthenticationQuery, public SubjectQueryImpl
178 m_AuthenticationMethod=nullptr;
182 virtual ~AuthenticationQueryImpl() {
183 XMLString::release(&m_AuthenticationMethod);
186 AuthenticationQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
187 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
191 AuthenticationQueryImpl(const AuthenticationQueryImpl& src) : AbstractXMLObject(src), SubjectQueryImpl(src) {
195 void _clone(const AuthenticationQueryImpl& src) {
196 SubjectQueryImpl::_clone(src);
197 setAuthenticationMethod(src.getAuthenticationMethod());
200 IMPL_XMLOBJECT_CLONE_EX(AuthenticationQuery);
201 IMPL_STRING_ATTRIB(AuthenticationMethod);
204 void marshallAttributes(DOMElement* domElement) const {
205 MARSHALL_STRING_ATTRIB(AuthenticationMethod,AUTHENTICATIONMETHOD,nullptr);
206 SubjectQueryImpl::marshallAttributes(domElement);
209 void processAttribute(const DOMAttr* attribute) {
210 PROC_STRING_ATTRIB(AuthenticationMethod,AUTHENTICATIONMETHOD,nullptr);
211 SubjectQueryImpl::processAttribute(attribute);
215 class SAML_DLLLOCAL AttributeQueryImpl : public virtual AttributeQuery, public SubjectQueryImpl
222 virtual ~AttributeQueryImpl() {
223 XMLString::release(&m_Resource);
226 AttributeQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
227 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
231 AttributeQueryImpl(const AttributeQueryImpl& src) : AbstractXMLObject(src), SubjectQueryImpl(src) {
235 void _clone(const AttributeQueryImpl& src) {
236 SubjectQueryImpl::_clone(src);
237 setResource(src.getResource());
238 VectorOf(AttributeDesignator) v=getAttributeDesignators();
239 for (vector<AttributeDesignator*>::const_iterator i=src.m_AttributeDesignators.begin(); i!=src.m_AttributeDesignators.end(); i++) {
241 v.push_back((*i)->cloneAttributeDesignator());
246 IMPL_XMLOBJECT_CLONE_EX(AttributeQuery);
247 IMPL_STRING_ATTRIB(Resource);
248 IMPL_TYPED_CHILDREN(AttributeDesignator,m_children.end());
251 void marshallAttributes(DOMElement* domElement) const {
252 MARSHALL_STRING_ATTRIB(Resource,RESOURCE,nullptr);
253 SubjectQueryImpl::marshallAttributes(domElement);
256 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
257 PROC_TYPED_CHILDREN(AttributeDesignator,SAML1_NS,true);
258 SubjectQueryImpl::processChildElement(childXMLObject,root);
261 void processAttribute(const DOMAttr* attribute) {
262 PROC_STRING_ATTRIB(Resource,RESOURCE,nullptr);
263 SubjectQueryImpl::processAttribute(attribute);
267 class SAML_DLLLOCAL AuthorizationDecisionQueryImpl : public virtual AuthorizationDecisionQuery, public SubjectQueryImpl
272 m_children.push_back(nullptr);
273 m_pos_Evidence=m_pos_Subject;
278 virtual ~AuthorizationDecisionQueryImpl() {
279 XMLString::release(&m_Resource);
282 AuthorizationDecisionQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
283 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
287 AuthorizationDecisionQueryImpl(const AuthorizationDecisionQueryImpl& src) : AbstractXMLObject(src), SubjectQueryImpl(src) {
291 void _clone(const AuthorizationDecisionQueryImpl& src) {
292 SubjectQueryImpl::_clone(src);
293 setResource(src.getResource());
294 if (src.getEvidence())
295 setEvidence(src.getEvidence()->cloneEvidence());
296 VectorOf(Action) v=getActions();
297 for (vector<Action*>::const_iterator i=src.m_Actions.begin(); i!=src.m_Actions.end(); i++) {
299 v.push_back((*i)->cloneAction());
304 IMPL_XMLOBJECT_CLONE_EX(AuthorizationDecisionQuery);
305 IMPL_STRING_ATTRIB(Resource);
306 IMPL_TYPED_CHILD(Evidence);
307 IMPL_TYPED_CHILDREN(Action, m_pos_Evidence);
310 void marshallAttributes(DOMElement* domElement) const {
311 MARSHALL_STRING_ATTRIB(Resource,RESOURCE,nullptr);
312 SubjectQueryImpl::marshallAttributes(domElement);
315 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
316 PROC_TYPED_CHILD(Evidence,SAML1_NS,false);
317 PROC_TYPED_CHILDREN(Action,SAML1_NS,false);
318 SubjectQueryImpl::processChildElement(childXMLObject,root);
321 void processAttribute(const DOMAttr* attribute) {
322 PROC_STRING_ATTRIB(Resource,RESOURCE,nullptr);
323 SubjectQueryImpl::processAttribute(attribute);
327 class SAML_DLLLOCAL RequestAbstractTypeImpl : public virtual RequestAbstractType,
328 public AbstractComplexElement,
329 public AbstractDOMCachingXMLObject,
330 public AbstractXMLObjectMarshaller,
331 public AbstractXMLObjectUnmarshaller
334 m_MinorVersion=nullptr;
336 m_IssueInstant=nullptr;
337 m_children.push_back(nullptr);
339 m_pos_Signature=m_children.begin();
343 RequestAbstractTypeImpl() {
347 virtual ~RequestAbstractTypeImpl() {
348 XMLString::release(&m_MinorVersion);
349 XMLString::release(&m_RequestID);
350 delete m_IssueInstant;
353 RequestAbstractTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
354 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
358 RequestAbstractTypeImpl(const RequestAbstractTypeImpl& src)
359 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
363 //IMPL_TYPED_CHILD(Signature);
364 // Need customized setter.
367 void _clone(const RequestAbstractTypeImpl& src) {
368 setMinorVersion(src.m_MinorVersion);
369 setRequestID(src.getRequestID());
370 setIssueInstant(src.getIssueInstant());
371 if (src.getSignature())
372 setSignature(src.getSignature()->cloneSignature());
373 VectorOf(RespondWith) v=getRespondWiths();
374 for (vector<RespondWith*>::const_iterator i=src.m_RespondWiths.begin(); i!=src.m_RespondWiths.end(); i++) {
376 v.push_back((*i)->cloneRespondWith());
381 Signature* m_Signature;
382 list<XMLObject*>::iterator m_pos_Signature;
385 Signature* getSignature() const {
389 void setSignature(Signature* sig) {
390 prepareForAssignment(m_Signature,sig);
391 *m_pos_Signature=m_Signature=sig;
392 // Sync content reference back up.
394 m_Signature->setContentReference(new opensaml::ContentReference(*this));
397 RequestAbstractType* cloneRequestAbstractType() const {
398 return dynamic_cast<RequestAbstractType*>(clone());
401 IMPL_INTEGER_ATTRIB(MinorVersion);
402 IMPL_STRING_ATTRIB(RequestID); // have to special-case getXMLID
403 const XMLCh* getXMLID() const {
404 pair<bool,int> v = getMinorVersion();
405 return (!v.first || v.second > 0) ? m_RequestID : nullptr;
407 const XMLCh* getID() const {
408 return getRequestID();
410 void releaseDOM() const {
412 getDOM()->removeAttributeNS(nullptr, REQUESTID_ATTRIB_NAME);
413 AbstractDOMCachingXMLObject::releaseDOM();
415 IMPL_DATETIME_ATTRIB(IssueInstant,0);
416 IMPL_TYPED_CHILDREN(RespondWith,m_pos_Signature);
419 void prepareForMarshalling() const {
421 declareNonVisibleNamespaces();
424 void marshallAttributes(DOMElement* domElement) const {
425 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
426 domElement->setAttributeNS(nullptr,MAJORVERSION,XML_ONE);
428 const_cast<RequestAbstractTypeImpl*>(this)->m_MinorVersion=XMLString::replicate(XML_ONE);
429 MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,nullptr);
431 const_cast<RequestAbstractTypeImpl*>(this)->m_RequestID=SAMLConfig::getConfig().generateIdentifier();
432 domElement->setAttributeNS(nullptr, REQUESTID_ATTRIB_NAME, m_RequestID);
433 if (*m_MinorVersion!=chDigit_0) {
434 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
435 domElement->setIdAttributeNS(nullptr, REQUESTID_ATTRIB_NAME, true);
437 domElement->setIdAttributeNS(nullptr, REQUESTID_ATTRIB_NAME);
440 if (!m_IssueInstant) {
441 const_cast<RequestAbstractTypeImpl*>(this)->m_IssueInstantEpoch=time(nullptr);
442 const_cast<RequestAbstractTypeImpl*>(this)->m_IssueInstant=new DateTime(m_IssueInstantEpoch);
444 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,nullptr);
447 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
448 PROC_TYPED_CHILDREN(RespondWith,SAML1P_NS,false);
449 PROC_TYPED_CHILD(Signature,XMLSIG_NS,false);
450 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
453 void unmarshallAttributes(const DOMElement* domElement) {
454 // Standard processing, but then we check IDness.
455 AbstractXMLObjectUnmarshaller::unmarshallAttributes(domElement);
456 if (m_RequestID && (!m_MinorVersion || *m_MinorVersion!=chDigit_0)) {
457 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
458 const_cast<DOMElement*>(domElement)->setIdAttributeNS(nullptr, REQUESTID_ATTRIB_NAME, true);
460 const_cast<DOMElement*>(domElement)->setIdAttributeNS(nullptr, REQUESTID_ATTRIB_NAME);
465 void processAttribute(const DOMAttr* attribute) {
466 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
467 if (XMLHelper::isNodeNamed(attribute,nullptr,MAJORVERSION)) {
468 if (!XMLString::equals(attribute->getValue(),XML_ONE))
469 throw UnmarshallingException("Request has invalid major version.");
471 PROC_INTEGER_ATTRIB(MinorVersion,MINORVERSION,nullptr);
472 PROC_STRING_ATTRIB(RequestID,REQUESTID,nullptr);
473 PROC_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,nullptr);
477 class SAML_DLLLOCAL RequestImpl : public virtual Request, public RequestAbstractTypeImpl
480 m_children.push_back(nullptr);
482 m_pos_Query=m_pos_Signature;
487 virtual ~RequestImpl() {}
489 RequestImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
490 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
494 RequestImpl(const RequestImpl& src) : AbstractXMLObject(src), RequestAbstractTypeImpl(src) {
498 void _clone(const RequestImpl& src) {
499 RequestAbstractTypeImpl::_clone(src);
501 setQuery(src.getQuery()->cloneQuery());
502 VectorOf(AssertionIDReference) v=getAssertionIDReferences();
503 for (vector<AssertionIDReference*>::const_iterator i=src.m_AssertionIDReferences.begin(); i!=src.m_AssertionIDReferences.end(); i++) {
505 v.push_back((*i)->cloneAssertionIDReference());
508 VectorOf(AssertionArtifact) v2=getAssertionArtifacts();
509 for (vector<AssertionArtifact*>::const_iterator i=src.m_AssertionArtifacts.begin(); i!=src.m_AssertionArtifacts.end(); i++) {
511 v2.push_back((*i)->cloneAssertionArtifact());
516 IMPL_XMLOBJECT_CLONE_EX(Request);
517 IMPL_TYPED_CHILD(Query);
519 SubjectQuery* getSubjectQuery() const {
520 return dynamic_cast<SubjectQuery*>(getQuery());
522 AuthenticationQuery* getAuthenticationQuery() const {
523 return dynamic_cast<AuthenticationQuery*>(getQuery());
525 AttributeQuery* getAttributeQuery() const {
526 return dynamic_cast<AttributeQuery*>(getQuery());
528 AuthorizationDecisionQuery* getAuthorizationDecisionQuery() const {
529 return dynamic_cast<AuthorizationDecisionQuery*>(getQuery());
532 void setSubjectQuery(SubjectQuery* q) {
535 void setAuthenticationQuery(AuthenticationQuery* q) {
538 void setAttributeQuery(AttributeQuery* q) {
541 void setAuthorizationDecisionQuery(AuthorizationDecisionQuery* q) {
545 IMPL_TYPED_CHILDREN(AssertionIDReference, m_children.end());
546 IMPL_TYPED_CHILDREN(AssertionArtifact, m_children.end());
549 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
550 PROC_TYPED_CHILD(Query,SAML1P_NS,true);
551 PROC_TYPED_CHILDREN(AssertionIDReference,SAML1_NS,false);
552 PROC_TYPED_CHILDREN(AssertionArtifact,SAML1P_NS,false);
553 RequestAbstractTypeImpl::processChildElement(childXMLObject,root);
557 class SAML_DLLLOCAL StatusCodeImpl : public virtual StatusCode,
558 public AbstractComplexElement,
559 public AbstractDOMCachingXMLObject,
560 public AbstractXMLObjectMarshaller,
561 public AbstractXMLObjectUnmarshaller
565 m_children.push_back(nullptr);
566 m_StatusCode=nullptr;
567 m_pos_StatusCode=m_children.begin();
570 virtual ~StatusCodeImpl() {
574 StatusCodeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
575 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
579 StatusCodeImpl(const StatusCodeImpl& src)
580 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
582 setValue(src.getValue());
583 if (src.getStatusCode())
584 setStatusCode(src.getStatusCode()->cloneStatusCode());
587 IMPL_XMLOBJECT_CLONE(StatusCode);
588 IMPL_XMLOBJECT_ATTRIB(Value,xmltooling::QName);
589 IMPL_TYPED_CHILD(StatusCode);
592 void marshallAttributes(DOMElement* domElement) const {
593 MARSHALL_QNAME_ATTRIB(Value,VALUE,nullptr);
596 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
597 PROC_TYPED_CHILD(StatusCode,SAML1P_NS,true);
598 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
601 void processAttribute(const DOMAttr* attribute) {
602 PROC_QNAME_ATTRIB(Value,VALUE,nullptr);
606 class SAML_DLLLOCAL StatusDetailImpl : public virtual StatusDetail,
607 public AbstractComplexElement,
608 public AbstractDOMCachingXMLObject,
609 public AbstractXMLObjectMarshaller,
610 public AbstractXMLObjectUnmarshaller
613 virtual ~StatusDetailImpl() {}
615 StatusDetailImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
616 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
619 StatusDetailImpl(const StatusDetailImpl& src)
620 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
621 VectorOf(XMLObject) v=getUnknownXMLObjects();
622 for (vector<XMLObject*>::const_iterator i=src.m_UnknownXMLObjects.begin(); i!=src.m_UnknownXMLObjects.end(); ++i)
623 v.push_back((*i)->clone());
626 IMPL_XMLOBJECT_CLONE(StatusDetail);
627 IMPL_XMLOBJECT_CHILDREN(UnknownXMLObject,m_children.end());
630 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
631 getUnknownXMLObjects().push_back(childXMLObject);
635 class SAML_DLLLOCAL StatusImpl : public virtual Status,
636 public AbstractComplexElement,
637 public AbstractDOMCachingXMLObject,
638 public AbstractXMLObjectMarshaller,
639 public AbstractXMLObjectUnmarshaller
642 m_children.push_back(nullptr);
643 m_children.push_back(nullptr);
644 m_children.push_back(nullptr);
645 m_StatusCode=nullptr;
646 m_pos_StatusCode=m_children.begin();
647 m_StatusMessage=nullptr;
648 m_pos_StatusMessage=m_pos_StatusCode;
649 ++m_pos_StatusMessage;
650 m_StatusDetail=nullptr;
651 m_pos_StatusDetail=m_pos_StatusMessage;
652 ++m_pos_StatusDetail;
655 virtual ~StatusImpl() {}
657 StatusImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
658 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
662 StatusImpl(const StatusImpl& src)
663 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
665 if (src.getStatusCode())
666 setStatusCode(src.getStatusCode()->cloneStatusCode());
667 if (src.getStatusMessage())
668 setStatusMessage(src.getStatusMessage()->cloneStatusMessage());
669 if (src.getStatusDetail())
670 setStatusDetail(src.getStatusDetail()->cloneStatusDetail());
673 IMPL_XMLOBJECT_CLONE(Status);
674 IMPL_TYPED_CHILD(StatusCode);
675 IMPL_TYPED_CHILD(StatusMessage);
676 IMPL_TYPED_CHILD(StatusDetail);
679 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
680 PROC_TYPED_CHILD(StatusCode,SAML1P_NS,false);
681 PROC_TYPED_CHILD(StatusMessage,SAML1P_NS,false);
682 PROC_TYPED_CHILD(StatusDetail,SAML1P_NS,false);
683 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
687 class SAML_DLLLOCAL ResponseAbstractTypeImpl : public virtual ResponseAbstractType,
688 public AbstractComplexElement,
689 public AbstractDOMCachingXMLObject,
690 public AbstractXMLObjectMarshaller,
691 public AbstractXMLObjectUnmarshaller
694 m_MinorVersion=nullptr;
695 m_ResponseID=nullptr;
696 m_InResponseTo=nullptr;
697 m_IssueInstant=nullptr;
699 m_children.push_back(nullptr);
701 m_pos_Signature=m_children.begin();
705 ResponseAbstractTypeImpl() {
710 virtual ~ResponseAbstractTypeImpl() {
711 XMLString::release(&m_MinorVersion);
712 XMLString::release(&m_ResponseID);
713 XMLString::release(&m_InResponseTo);
714 XMLString::release(&m_Recipient);
715 delete m_IssueInstant;
718 ResponseAbstractTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
719 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
723 ResponseAbstractTypeImpl(const ResponseAbstractTypeImpl& src)
724 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
728 //IMPL_TYPED_CHILD(Signature);
729 // Need customized setter.
731 void _clone(const ResponseAbstractTypeImpl& src) {
732 setMinorVersion(src.m_MinorVersion);
733 setResponseID(src.getResponseID());
734 setInResponseTo(src.getInResponseTo());
735 setIssueInstant(src.getIssueInstant());
736 setRecipient(src.getRecipient());
737 if (src.getSignature())
738 setSignature(src.getSignature()->cloneSignature());
741 Signature* m_Signature;
742 list<XMLObject*>::iterator m_pos_Signature;
744 Signature* getSignature() const {
748 void setSignature(Signature* sig) {
749 prepareForAssignment(m_Signature,sig);
750 *m_pos_Signature=m_Signature=sig;
751 // Sync content reference back up.
753 m_Signature->setContentReference(new opensaml::ContentReference(*this));
756 ResponseAbstractType* cloneResponseAbstractType() const {
757 return dynamic_cast<ResponseAbstractType*>(clone());
760 IMPL_INTEGER_ATTRIB(MinorVersion);
761 IMPL_STRING_ATTRIB(ResponseID); // have to special-case getXMLID
762 const XMLCh* getXMLID() const {
763 pair<bool,int> v = getMinorVersion();
764 return (!v.first || v.second > 0) ? m_ResponseID : nullptr;
766 const XMLCh* getID() const {
767 return getResponseID();
769 void releaseDOM() const {
771 getDOM()->removeAttributeNS(nullptr, RESPONSEID_ATTRIB_NAME);
772 AbstractDOMCachingXMLObject::releaseDOM();
774 IMPL_STRING_ATTRIB(InResponseTo);
775 IMPL_DATETIME_ATTRIB(IssueInstant,0);
776 IMPL_STRING_ATTRIB(Recipient);
779 void prepareForMarshalling() const {
781 declareNonVisibleNamespaces();
784 void marshallAttributes(DOMElement* domElement) const {
785 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
786 domElement->setAttributeNS(nullptr,MAJORVERSION,XML_ONE);
788 const_cast<ResponseAbstractTypeImpl*>(this)->m_MinorVersion=XMLString::replicate(XML_ONE);
789 MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,nullptr);
791 const_cast<ResponseAbstractTypeImpl*>(this)->m_ResponseID=SAMLConfig::getConfig().generateIdentifier();
792 domElement->setAttributeNS(nullptr, RESPONSEID_ATTRIB_NAME, m_ResponseID);
793 if (*m_MinorVersion!=chDigit_0) {
794 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
795 domElement->setIdAttributeNS(nullptr, RESPONSEID_ATTRIB_NAME, true);
797 domElement->setIdAttributeNS(nullptr, RESPONSEID_ATTRIB_NAME);
800 MARSHALL_STRING_ATTRIB(InResponseTo,INRESPONSETO,nullptr);
801 if (!m_IssueInstant) {
802 const_cast<ResponseAbstractTypeImpl*>(this)->m_IssueInstantEpoch=time(nullptr);
803 const_cast<ResponseAbstractTypeImpl*>(this)->m_IssueInstant=new DateTime(m_IssueInstantEpoch);
805 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,nullptr);
806 MARSHALL_STRING_ATTRIB(Recipient,RECIPIENT,nullptr);
809 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
810 PROC_TYPED_CHILD(Signature,XMLSIG_NS,false);
811 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
814 void unmarshallAttributes(const DOMElement* domElement) {
815 // Standard processing, but then we check IDness.
816 AbstractXMLObjectUnmarshaller::unmarshallAttributes(domElement);
817 if (m_ResponseID && (!m_MinorVersion || *m_MinorVersion!=chDigit_0)) {
818 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
819 const_cast<DOMElement*>(domElement)->setIdAttributeNS(nullptr, RESPONSEID_ATTRIB_NAME, true);
821 const_cast<DOMElement*>(domElement)->setIdAttributeNS(nullptr, RESPONSEID_ATTRIB_NAME);
826 void processAttribute(const DOMAttr* attribute) {
827 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
828 if (XMLHelper::isNodeNamed(attribute,nullptr,MAJORVERSION)) {
829 if (!XMLString::equals(attribute->getValue(),XML_ONE))
830 throw UnmarshallingException("Response has invalid major version.");
832 PROC_INTEGER_ATTRIB(MinorVersion,MINORVERSION,nullptr);
833 PROC_STRING_ATTRIB(ResponseID,RESPONSEID,nullptr);
834 PROC_STRING_ATTRIB(InResponseTo,INRESPONSETO,nullptr);
835 PROC_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,nullptr);
836 PROC_STRING_ATTRIB(Recipient,RECIPIENT,nullptr);
840 class SAML_DLLLOCAL ResponseImpl : public virtual Response, public ResponseAbstractTypeImpl
843 m_children.push_back(nullptr);
845 m_pos_Status=m_pos_Signature;
850 virtual ~ResponseImpl() {}
852 ResponseImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
853 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
857 ResponseImpl(const ResponseImpl& src) : AbstractXMLObject(src), ResponseAbstractTypeImpl(src) {
861 void _clone(const ResponseImpl& src) {
862 ResponseAbstractTypeImpl::_clone(src);
864 setStatus(src.getStatus()->cloneStatus());
865 VectorOf(saml1::Assertion) v=getAssertions();
866 for (vector<saml1::Assertion*>::const_iterator i=src.m_Assertions.begin(); i!=src.m_Assertions.end(); i++) {
868 v.push_back((*i)->cloneAssertion());
873 IMPL_XMLOBJECT_CLONE_EX(Response);
874 IMPL_TYPED_CHILD(Status);
875 IMPL_TYPED_FOREIGN_CHILDREN(Assertion,saml1,m_children.end());
878 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
879 PROC_TYPED_CHILD(Status,SAML1P_NS,false);
880 PROC_TYPED_FOREIGN_CHILDREN(Assertion,saml1,SAML1_NS,true);
881 ResponseAbstractTypeImpl::processChildElement(childXMLObject,root);
888 #if defined (_MSC_VER)
889 #pragma warning( pop )
892 // Builder Implementations
894 IMPL_XMLOBJECTBUILDER(AssertionArtifact);
895 IMPL_XMLOBJECTBUILDER(AttributeQuery);
896 IMPL_XMLOBJECTBUILDER(AuthenticationQuery);
897 IMPL_XMLOBJECTBUILDER(AuthorizationDecisionQuery);
898 IMPL_XMLOBJECTBUILDER(Query);
899 IMPL_XMLOBJECTBUILDER(Request);
900 IMPL_XMLOBJECTBUILDER(RespondWith);
901 IMPL_XMLOBJECTBUILDER(Response);
902 IMPL_XMLOBJECTBUILDER(Status);
903 IMPL_XMLOBJECTBUILDER(StatusCode);
904 IMPL_XMLOBJECTBUILDER(StatusDetail);
905 IMPL_XMLOBJECTBUILDER(StatusMessage);
908 const XMLCh RequestAbstractType::LOCAL_NAME[] = {chNull};
909 const XMLCh RequestAbstractType::TYPE_NAME[] = UNICODE_LITERAL_19(R,e,q,u,e,s,t,A,b,s,t,r,a,c,t,T,y,p,e);
910 const XMLCh RequestAbstractType::MINORVERSION_ATTRIB_NAME[] = UNICODE_LITERAL_12(M,i,n,o,r,V,e,r,s,i,o,n);
911 const XMLCh RequestAbstractType::REQUESTID_ATTRIB_NAME[] = UNICODE_LITERAL_9(R,e,q,u,e,s,t,I,D);
912 const XMLCh RequestAbstractType::ISSUEINSTANT_ATTRIB_NAME[] = UNICODE_LITERAL_12(I,s,s,u,e,I,n,s,t,a,n,t);
913 const XMLCh ResponseAbstractType::LOCAL_NAME[] = {chNull};
914 const XMLCh ResponseAbstractType::TYPE_NAME[] = UNICODE_LITERAL_20(R,e,s,p,o,n,s,e,A,b,s,t,r,a,c,t,T,y,p,e);
915 const XMLCh ResponseAbstractType::MINORVERSION_ATTRIB_NAME[] = UNICODE_LITERAL_12(M,i,n,o,r,V,e,r,s,i,o,n);
916 const XMLCh ResponseAbstractType::RESPONSEID_ATTRIB_NAME[] = UNICODE_LITERAL_10(R,e,s,p,o,n,s,e,I,D);
917 const XMLCh ResponseAbstractType::ISSUEINSTANT_ATTRIB_NAME[] = UNICODE_LITERAL_12(I,s,s,u,e,I,n,s,t,a,n,t);
918 const XMLCh ResponseAbstractType::INRESPONSETO_ATTRIB_NAME[] = UNICODE_LITERAL_12(I,n,R,e,s,p,o,n,s,e,T,o);
919 const XMLCh ResponseAbstractType::RECIPIENT_ATTRIB_NAME[] = UNICODE_LITERAL_9(R,e,c,i,p,i,e,n,t);
920 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);
921 const XMLCh AttributeQuery::LOCAL_NAME[] = UNICODE_LITERAL_14(A,t,t,r,i,b,u,t,e,Q,u,e,r,y);
922 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);
923 const XMLCh AttributeQuery::RESOURCE_ATTRIB_NAME[] = UNICODE_LITERAL_8(R,e,s,o,u,r,c,e);
924 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);
925 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);
926 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);
927 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);
928 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);
929 const XMLCh AuthorizationDecisionQuery::RESOURCE_ATTRIB_NAME[] = UNICODE_LITERAL_8(R,e,s,o,u,r,c,e);
930 const XMLCh Query::LOCAL_NAME[] = UNICODE_LITERAL_5(Q,u,e,r,y);
931 const XMLCh Request::LOCAL_NAME[] = UNICODE_LITERAL_7(R,e,q,u,e,s,t);
932 const XMLCh Request::TYPE_NAME[] = UNICODE_LITERAL_11(R,e,q,u,e,s,t,T,y,p,e);
933 const XMLCh RespondWith::LOCAL_NAME[] = UNICODE_LITERAL_11(R,e,s,p,o,n,d,W,i,t,h);
934 const XMLCh Response::LOCAL_NAME[] = UNICODE_LITERAL_8(R,e,s,p,o,n,s,e);
935 const XMLCh Response::TYPE_NAME[] = UNICODE_LITERAL_12(R,e,s,p,o,n,s,e,T,y,p,e);
936 const XMLCh Status::LOCAL_NAME[] = UNICODE_LITERAL_6(S,t,a,t,u,s);
937 const XMLCh Status::TYPE_NAME[] = UNICODE_LITERAL_10(S,t,a,t,u,s,T,y,p,e);
938 const XMLCh StatusCode::LOCAL_NAME[] = UNICODE_LITERAL_10(S,t,a,t,u,s,C,o,d,e);
939 const XMLCh StatusCode::TYPE_NAME[] = UNICODE_LITERAL_14(S,t,a,t,u,s,C,o,d,e,T,y,p,e);
940 const XMLCh StatusCode::VALUE_ATTRIB_NAME[] = UNICODE_LITERAL_5(V,a,l,u,e);
941 const XMLCh StatusDetail::LOCAL_NAME[] = UNICODE_LITERAL_12(S,t,a,t,u,s,D,e,t,a,i,l);
942 const XMLCh StatusDetail::TYPE_NAME[] = UNICODE_LITERAL_16(S,t,a,t,u,s,D,e,t,a,i,l,T,y,p,e);
943 const XMLCh StatusMessage::LOCAL_NAME[] = UNICODE_LITERAL_13(S,t,a,t,u,s,M,e,s,s,a,g,e);
944 const XMLCh SubjectQuery::LOCAL_NAME[] = UNICODE_LITERAL_12(S,u,b,j,e,c,t,Q,u,e,r,y);
946 #define XCH(ch) chLatin_##ch
947 #define XNUM(d) chDigit_##d
949 const XMLCh _SUCCESS[] = UNICODE_LITERAL_7(S,u,c,c,e,s,s);
950 const XMLCh _REQUESTER[] = UNICODE_LITERAL_9(R,e,q,u,e,s,t,e,r);
951 const XMLCh _RESPONDER[] = UNICODE_LITERAL_9(R,e,s,p,o,n,d,e,r);
952 const XMLCh _VERSIONMISMATCH[] = UNICODE_LITERAL_15(V,e,r,s,i,o,n,M,i,s,m,a,t,c,h);
954 xmltooling::QName StatusCode::SUCCESS(SAML1P_NS,_SUCCESS,SAML1P_PREFIX);
955 xmltooling::QName StatusCode::REQUESTER(SAML1P_NS,_REQUESTER,SAML1P_PREFIX);
956 xmltooling::QName StatusCode::RESPONDER(SAML1P_NS,_RESPONDER,SAML1P_PREFIX);
957 xmltooling::QName StatusCode::VERSIONMISMATCH(SAML1P_NS,_VERSIONMISMATCH,SAML1P_PREFIX);