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 <boost/lexical_cast.hpp>
44 #include <boost/lambda/bind.hpp>
45 #include <boost/lambda/if.hpp>
46 #include <boost/lambda/lambda.hpp>
47 #include <xercesc/util/XMLUniDefs.hpp>
49 using namespace opensaml::saml1p;
50 using namespace xmltooling;
52 using xmlconstants::XMLSIG_NS;
53 using xmlconstants::XML_ONE;
54 using samlconstants::SAML1P_NS;
55 using samlconstants::SAML1_NS;
56 using samlconstants::SAML1P_PREFIX;
58 #if defined (_MSC_VER)
59 #pragma warning( push )
60 #pragma warning( disable : 4250 4251 )
66 DECL_XMLOBJECTIMPL_SIMPLE(SAML_DLLLOCAL,AssertionArtifact);
67 DECL_XMLOBJECTIMPL_SIMPLE(SAML_DLLLOCAL,StatusMessage);
69 class SAML_DLLLOCAL RespondWithImpl : public virtual RespondWith,
70 public AbstractSimpleElement,
71 public AbstractDOMCachingXMLObject,
72 public AbstractXMLObjectMarshaller,
73 public AbstractXMLObjectUnmarshaller
75 mutable xmltooling::QName* m_qname;
77 virtual ~RespondWithImpl() {
81 RespondWithImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
82 : AbstractXMLObject(nsURI, localName, prefix, schemaType), m_qname(nullptr) {}
84 RespondWithImpl(const RespondWithImpl& src)
85 : AbstractXMLObject(src), AbstractSimpleElement(src), AbstractDOMCachingXMLObject(src), m_qname(nullptr) {
86 IMPL_CLONE_ATTRIB(QName); // not really an attribute, but it gets the job done
89 xmltooling::QName* getQName() const {
90 if (!m_qname && getDOM() && getDOM()->getTextContent()) {
91 m_qname = XMLHelper::getNodeValueAsQName(getDOM());
96 void setQName(const xmltooling::QName* qname) {
97 m_qname=prepareForAssignment(m_qname,qname);
99 auto_ptr_XMLCh temp(m_qname->toString().c_str());
100 setTextContent(temp.get());
103 setTextContent(nullptr);
107 IMPL_XMLOBJECT_CLONE(RespondWith);
110 class SAML_DLLLOCAL QueryImpl : public virtual Query, public AnyElementImpl
113 virtual ~QueryImpl() {}
115 QueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
116 : 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 IMPL_CLONE_TYPED_CHILD(Subject);
157 SubjectQuery* cloneSubjectQuery() const {
158 return dynamic_cast<SubjectQuery*>(clone());
161 Query* cloneQuery() const {
162 return dynamic_cast<Query*>(clone());
165 IMPL_TYPED_FOREIGN_CHILD(Subject,saml1);
168 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
169 PROC_TYPED_FOREIGN_CHILD(Subject,saml1,SAML1_NS,true);
170 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
174 class SAML_DLLLOCAL AuthenticationQueryImpl : public virtual AuthenticationQuery, public SubjectQueryImpl
177 m_AuthenticationMethod=nullptr;
181 virtual ~AuthenticationQueryImpl() {
182 XMLString::release(&m_AuthenticationMethod);
185 AuthenticationQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
186 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
190 AuthenticationQueryImpl(const AuthenticationQueryImpl& src) : AbstractXMLObject(src), SubjectQueryImpl(src) {
194 void _clone(const AuthenticationQueryImpl& src) {
195 SubjectQueryImpl::_clone(src);
196 IMPL_CLONE_ATTRIB(AuthenticationMethod);
199 IMPL_XMLOBJECT_CLONE_EX(AuthenticationQuery);
200 IMPL_STRING_ATTRIB(AuthenticationMethod);
203 void marshallAttributes(DOMElement* domElement) const {
204 MARSHALL_STRING_ATTRIB(AuthenticationMethod,AUTHENTICATIONMETHOD,nullptr);
205 SubjectQueryImpl::marshallAttributes(domElement);
208 void processAttribute(const DOMAttr* attribute) {
209 PROC_STRING_ATTRIB(AuthenticationMethod,AUTHENTICATIONMETHOD,nullptr);
210 SubjectQueryImpl::processAttribute(attribute);
214 class SAML_DLLLOCAL AttributeQueryImpl : public virtual AttributeQuery, public SubjectQueryImpl
221 virtual ~AttributeQueryImpl() {
222 XMLString::release(&m_Resource);
225 AttributeQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
226 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
230 AttributeQueryImpl(const AttributeQueryImpl& src) : AbstractXMLObject(src), SubjectQueryImpl(src) {
234 void _clone(const AttributeQueryImpl& src) {
235 SubjectQueryImpl::_clone(src);
236 IMPL_CLONE_ATTRIB(Resource);
237 IMPL_CLONE_TYPED_FOREIGN_CHILDREN(AttributeDesignator,saml1);
240 IMPL_XMLOBJECT_CLONE_EX(AttributeQuery);
241 IMPL_STRING_ATTRIB(Resource);
242 IMPL_TYPED_FOREIGN_CHILDREN(AttributeDesignator,saml1,m_children.end());
245 void marshallAttributes(DOMElement* domElement) const {
246 MARSHALL_STRING_ATTRIB(Resource,RESOURCE,nullptr);
247 SubjectQueryImpl::marshallAttributes(domElement);
250 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
251 PROC_TYPED_FOREIGN_CHILDREN(AttributeDesignator,saml1,SAML1_NS,true);
252 SubjectQueryImpl::processChildElement(childXMLObject,root);
255 void processAttribute(const DOMAttr* attribute) {
256 PROC_STRING_ATTRIB(Resource,RESOURCE,nullptr);
257 SubjectQueryImpl::processAttribute(attribute);
261 class SAML_DLLLOCAL AuthorizationDecisionQueryImpl : public virtual AuthorizationDecisionQuery, public SubjectQueryImpl
266 m_children.push_back(nullptr);
267 m_pos_Evidence=m_pos_Subject;
272 virtual ~AuthorizationDecisionQueryImpl() {
273 XMLString::release(&m_Resource);
276 AuthorizationDecisionQueryImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
277 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
281 AuthorizationDecisionQueryImpl(const AuthorizationDecisionQueryImpl& src) : AbstractXMLObject(src), SubjectQueryImpl(src) {
285 void _clone(const AuthorizationDecisionQueryImpl& src) {
286 SubjectQueryImpl::_clone(src);
287 IMPL_CLONE_ATTRIB(Resource);
288 IMPL_CLONE_TYPED_FOREIGN_CHILDREN(Action,saml1);
289 IMPL_CLONE_TYPED_CHILD(Evidence);
292 IMPL_XMLOBJECT_CLONE_EX(AuthorizationDecisionQuery);
293 IMPL_STRING_ATTRIB(Resource);
294 IMPL_TYPED_FOREIGN_CHILDREN(Action,saml1,m_pos_Evidence);
295 IMPL_TYPED_FOREIGN_CHILD(Evidence,saml1);
298 void marshallAttributes(DOMElement* domElement) const {
299 MARSHALL_STRING_ATTRIB(Resource,RESOURCE,nullptr);
300 SubjectQueryImpl::marshallAttributes(domElement);
303 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
304 PROC_TYPED_FOREIGN_CHILD(Evidence,saml1,SAML1_NS,false);
305 PROC_TYPED_FOREIGN_CHILDREN(Action,saml1,SAML1_NS,false);
306 SubjectQueryImpl::processChildElement(childXMLObject,root);
309 void processAttribute(const DOMAttr* attribute) {
310 PROC_STRING_ATTRIB(Resource,RESOURCE,nullptr);
311 SubjectQueryImpl::processAttribute(attribute);
315 class SAML_DLLLOCAL RequestAbstractTypeImpl : public virtual RequestAbstractType,
316 public AbstractComplexElement,
317 public AbstractDOMCachingXMLObject,
318 public AbstractXMLObjectMarshaller,
319 public AbstractXMLObjectUnmarshaller
322 m_MinorVersion=nullptr;
324 m_IssueInstant=nullptr;
325 m_children.push_back(nullptr);
327 m_pos_Signature=m_children.begin();
331 RequestAbstractTypeImpl() {
335 virtual ~RequestAbstractTypeImpl() {
336 XMLString::release(&m_MinorVersion);
337 XMLString::release(&m_RequestID);
338 delete m_IssueInstant;
341 RequestAbstractTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
342 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
346 RequestAbstractTypeImpl(const RequestAbstractTypeImpl& src)
347 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
351 //IMPL_TYPED_CHILD(Signature);
352 // Need customized setter.
355 void _clone(const RequestAbstractTypeImpl& src) {
356 IMPL_CLONE_INTEGER_ATTRIB(MinorVersion);
357 IMPL_CLONE_ATTRIB(RequestID);
358 IMPL_CLONE_ATTRIB(IssueInstant);
359 IMPL_CLONE_TYPED_CHILD(Signature);
360 IMPL_CLONE_TYPED_CHILDREN(RespondWith);
363 xmlsignature::Signature* m_Signature;
364 list<XMLObject*>::iterator m_pos_Signature;
367 xmlsignature::Signature* getSignature() const {
371 void setSignature(xmlsignature::Signature* sig) {
372 prepareForAssignment(m_Signature,sig);
373 *m_pos_Signature=m_Signature=sig;
374 // Sync content reference back up.
376 m_Signature->setContentReference(new opensaml::ContentReference(*this));
379 RequestAbstractType* cloneRequestAbstractType() const {
380 return dynamic_cast<RequestAbstractType*>(clone());
383 IMPL_INTEGER_ATTRIB(MinorVersion);
384 IMPL_STRING_ATTRIB(RequestID); // have to special-case getXMLID
385 const XMLCh* getXMLID() const {
386 pair<bool,int> v = getMinorVersion();
387 return (!v.first || v.second > 0) ? m_RequestID : nullptr;
389 const XMLCh* getID() const {
390 return getRequestID();
392 void releaseDOM() const {
394 getDOM()->removeAttributeNS(nullptr, REQUESTID_ATTRIB_NAME);
395 AbstractDOMCachingXMLObject::releaseDOM();
397 IMPL_DATETIME_ATTRIB(IssueInstant,0);
398 IMPL_TYPED_CHILDREN(RespondWith,m_pos_Signature);
401 void prepareForMarshalling() const {
403 declareNonVisibleNamespaces();
406 void marshallAttributes(DOMElement* domElement) const {
407 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
408 domElement->setAttributeNS(nullptr,MAJORVERSION,XML_ONE);
410 const_cast<RequestAbstractTypeImpl*>(this)->m_MinorVersion=XMLString::replicate(XML_ONE);
411 MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,nullptr);
413 const_cast<RequestAbstractTypeImpl*>(this)->m_RequestID=SAMLConfig::getConfig().generateIdentifier();
414 domElement->setAttributeNS(nullptr, REQUESTID_ATTRIB_NAME, m_RequestID);
415 if (*m_MinorVersion!=chDigit_0) {
416 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
417 domElement->setIdAttributeNS(nullptr, REQUESTID_ATTRIB_NAME, true);
419 domElement->setIdAttributeNS(nullptr, REQUESTID_ATTRIB_NAME);
422 if (!m_IssueInstant) {
423 const_cast<RequestAbstractTypeImpl*>(this)->m_IssueInstantEpoch=time(nullptr);
424 const_cast<RequestAbstractTypeImpl*>(this)->m_IssueInstant=new DateTime(m_IssueInstantEpoch);
426 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,nullptr);
429 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
430 PROC_TYPED_CHILDREN(RespondWith,SAML1P_NS,false);
431 PROC_TYPED_FOREIGN_CHILD(Signature,xmlsignature,XMLSIG_NS,false);
432 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
435 void unmarshallAttributes(const DOMElement* domElement) {
436 // Standard processing, but then we check IDness.
437 AbstractXMLObjectUnmarshaller::unmarshallAttributes(domElement);
438 if (m_RequestID && (!m_MinorVersion || *m_MinorVersion!=chDigit_0)) {
439 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
440 const_cast<DOMElement*>(domElement)->setIdAttributeNS(nullptr, REQUESTID_ATTRIB_NAME, true);
442 const_cast<DOMElement*>(domElement)->setIdAttributeNS(nullptr, REQUESTID_ATTRIB_NAME);
447 void processAttribute(const DOMAttr* attribute) {
448 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
449 if (XMLHelper::isNodeNamed(attribute,nullptr,MAJORVERSION)) {
450 if (!XMLString::equals(attribute->getValue(),XML_ONE))
451 throw UnmarshallingException("Request has invalid major version.");
453 PROC_INTEGER_ATTRIB(MinorVersion,MINORVERSION,nullptr);
454 PROC_STRING_ATTRIB(RequestID,REQUESTID,nullptr);
455 PROC_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,nullptr);
459 class SAML_DLLLOCAL RequestImpl : public virtual Request, public RequestAbstractTypeImpl
462 m_children.push_back(nullptr);
464 m_pos_Query=m_pos_Signature;
469 virtual ~RequestImpl() {}
471 RequestImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
472 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
476 RequestImpl(const RequestImpl& src) : AbstractXMLObject(src), RequestAbstractTypeImpl(src) {
480 void _clone(const RequestImpl& src) {
481 RequestAbstractTypeImpl::_clone(src);
482 IMPL_CLONE_TYPED_CHILD(Query);
483 IMPL_CLONE_TYPED_FOREIGN_CHILDREN(AssertionIDReference,saml1);
484 IMPL_CLONE_TYPED_CHILDREN(AssertionArtifact);
487 IMPL_XMLOBJECT_CLONE_EX(Request);
488 IMPL_TYPED_CHILD(Query);
490 SubjectQuery* getSubjectQuery() const {
491 return dynamic_cast<SubjectQuery*>(getQuery());
493 AuthenticationQuery* getAuthenticationQuery() const {
494 return dynamic_cast<AuthenticationQuery*>(getQuery());
496 AttributeQuery* getAttributeQuery() const {
497 return dynamic_cast<AttributeQuery*>(getQuery());
499 AuthorizationDecisionQuery* getAuthorizationDecisionQuery() const {
500 return dynamic_cast<AuthorizationDecisionQuery*>(getQuery());
503 void setSubjectQuery(SubjectQuery* q) {
506 void setAuthenticationQuery(AuthenticationQuery* q) {
509 void setAttributeQuery(AttributeQuery* q) {
512 void setAuthorizationDecisionQuery(AuthorizationDecisionQuery* q) {
516 IMPL_TYPED_FOREIGN_CHILDREN(AssertionIDReference,saml1,m_children.end());
517 IMPL_TYPED_CHILDREN(AssertionArtifact,m_children.end());
520 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
521 PROC_TYPED_CHILD(Query,SAML1P_NS,true);
522 PROC_TYPED_FOREIGN_CHILDREN(AssertionIDReference,saml1,SAML1_NS,false);
523 PROC_TYPED_CHILDREN(AssertionArtifact,SAML1P_NS,false);
524 RequestAbstractTypeImpl::processChildElement(childXMLObject,root);
528 class SAML_DLLLOCAL StatusCodeImpl : public virtual StatusCode,
529 public AbstractComplexElement,
530 public AbstractDOMCachingXMLObject,
531 public AbstractXMLObjectMarshaller,
532 public AbstractXMLObjectUnmarshaller
536 m_children.push_back(nullptr);
537 m_StatusCode=nullptr;
538 m_pos_StatusCode=m_children.begin();
542 virtual ~StatusCodeImpl() {
546 StatusCodeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
547 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
551 StatusCodeImpl(const StatusCodeImpl& src)
552 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
554 IMPL_CLONE_ATTRIB(Value);
555 IMPL_CLONE_TYPED_CHILD(StatusCode);
558 IMPL_XMLOBJECT_CLONE(StatusCode);
559 IMPL_XMLOBJECT_ATTRIB(Value,xmltooling::QName);
560 IMPL_TYPED_CHILD(StatusCode);
563 void marshallAttributes(DOMElement* domElement) const {
564 MARSHALL_QNAME_ATTRIB(Value,VALUE,nullptr);
567 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
568 PROC_TYPED_CHILD(StatusCode,SAML1P_NS,true);
569 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
572 void processAttribute(const DOMAttr* attribute) {
573 PROC_QNAME_ATTRIB(Value,VALUE,nullptr);
577 class SAML_DLLLOCAL StatusDetailImpl : public virtual StatusDetail,
578 public AbstractComplexElement,
579 public AbstractDOMCachingXMLObject,
580 public AbstractXMLObjectMarshaller,
581 public AbstractXMLObjectUnmarshaller
584 virtual ~StatusDetailImpl() {}
586 StatusDetailImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
587 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {}
589 StatusDetailImpl(const StatusDetailImpl& src)
590 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
591 IMPL_CLONE_XMLOBJECT_CHILDREN(UnknownXMLObject);
594 IMPL_XMLOBJECT_CLONE(StatusDetail);
595 IMPL_XMLOBJECT_CHILDREN(UnknownXMLObject,m_children.end());
598 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
599 getUnknownXMLObjects().push_back(childXMLObject);
603 class SAML_DLLLOCAL StatusImpl : public virtual Status,
604 public AbstractComplexElement,
605 public AbstractDOMCachingXMLObject,
606 public AbstractXMLObjectMarshaller,
607 public AbstractXMLObjectUnmarshaller
610 m_children.push_back(nullptr);
611 m_children.push_back(nullptr);
612 m_children.push_back(nullptr);
613 m_StatusCode=nullptr;
614 m_pos_StatusCode=m_children.begin();
615 m_StatusMessage=nullptr;
616 m_pos_StatusMessage=m_pos_StatusCode;
617 ++m_pos_StatusMessage;
618 m_StatusDetail=nullptr;
619 m_pos_StatusDetail=m_pos_StatusMessage;
620 ++m_pos_StatusDetail;
624 virtual ~StatusImpl() {}
626 StatusImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
627 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
631 StatusImpl(const StatusImpl& src)
632 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
634 IMPL_CLONE_TYPED_CHILD(StatusCode);
635 IMPL_CLONE_TYPED_CHILD(StatusMessage);
636 IMPL_CLONE_TYPED_CHILD(StatusDetail);
639 IMPL_XMLOBJECT_CLONE(Status);
640 IMPL_TYPED_CHILD(StatusCode);
641 IMPL_TYPED_CHILD(StatusMessage);
642 IMPL_TYPED_CHILD(StatusDetail);
645 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
646 PROC_TYPED_CHILD(StatusCode,SAML1P_NS,false);
647 PROC_TYPED_CHILD(StatusMessage,SAML1P_NS,false);
648 PROC_TYPED_CHILD(StatusDetail,SAML1P_NS,false);
649 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
653 class SAML_DLLLOCAL ResponseAbstractTypeImpl : public virtual ResponseAbstractType,
654 public AbstractComplexElement,
655 public AbstractDOMCachingXMLObject,
656 public AbstractXMLObjectMarshaller,
657 public AbstractXMLObjectUnmarshaller
660 m_MinorVersion=nullptr;
661 m_ResponseID=nullptr;
662 m_InResponseTo=nullptr;
663 m_IssueInstant=nullptr;
665 m_children.push_back(nullptr);
667 m_pos_Signature=m_children.begin();
671 ResponseAbstractTypeImpl() {
676 virtual ~ResponseAbstractTypeImpl() {
677 XMLString::release(&m_MinorVersion);
678 XMLString::release(&m_ResponseID);
679 XMLString::release(&m_InResponseTo);
680 XMLString::release(&m_Recipient);
681 delete m_IssueInstant;
684 ResponseAbstractTypeImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
685 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
689 ResponseAbstractTypeImpl(const ResponseAbstractTypeImpl& src)
690 : AbstractXMLObject(src), AbstractComplexElement(src), AbstractDOMCachingXMLObject(src) {
694 //IMPL_TYPED_CHILD(Signature);
695 // Need customized setter.
697 void _clone(const ResponseAbstractTypeImpl& src) {
698 IMPL_CLONE_INTEGER_ATTRIB(MinorVersion);
699 IMPL_CLONE_ATTRIB(ResponseID);
700 IMPL_CLONE_ATTRIB(InResponseTo);
701 IMPL_CLONE_ATTRIB(IssueInstant);
702 IMPL_CLONE_ATTRIB(Recipient);
703 IMPL_CLONE_TYPED_CHILD(Signature);
706 xmlsignature::Signature* m_Signature;
707 list<XMLObject*>::iterator m_pos_Signature;
709 xmlsignature::Signature* getSignature() const {
713 void setSignature(xmlsignature::Signature* sig) {
714 prepareForAssignment(m_Signature,sig);
715 *m_pos_Signature=m_Signature=sig;
716 // Sync content reference back up.
718 m_Signature->setContentReference(new opensaml::ContentReference(*this));
721 ResponseAbstractType* cloneResponseAbstractType() const {
722 return dynamic_cast<ResponseAbstractType*>(clone());
725 IMPL_INTEGER_ATTRIB(MinorVersion);
726 IMPL_STRING_ATTRIB(ResponseID); // have to special-case getXMLID
727 const XMLCh* getXMLID() const {
728 pair<bool,int> v = getMinorVersion();
729 return (!v.first || v.second > 0) ? m_ResponseID : nullptr;
731 const XMLCh* getID() const {
732 return getResponseID();
734 void releaseDOM() const {
736 getDOM()->removeAttributeNS(nullptr, RESPONSEID_ATTRIB_NAME);
737 AbstractDOMCachingXMLObject::releaseDOM();
739 IMPL_STRING_ATTRIB(InResponseTo);
740 IMPL_DATETIME_ATTRIB(IssueInstant,0);
741 IMPL_STRING_ATTRIB(Recipient);
744 void prepareForMarshalling() const {
746 declareNonVisibleNamespaces();
749 void marshallAttributes(DOMElement* domElement) const {
750 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
751 domElement->setAttributeNS(nullptr,MAJORVERSION,XML_ONE);
753 const_cast<ResponseAbstractTypeImpl*>(this)->m_MinorVersion=XMLString::replicate(XML_ONE);
754 MARSHALL_INTEGER_ATTRIB(MinorVersion,MINORVERSION,nullptr);
756 const_cast<ResponseAbstractTypeImpl*>(this)->m_ResponseID=SAMLConfig::getConfig().generateIdentifier();
757 domElement->setAttributeNS(nullptr, RESPONSEID_ATTRIB_NAME, m_ResponseID);
758 if (*m_MinorVersion!=chDigit_0) {
759 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
760 domElement->setIdAttributeNS(nullptr, RESPONSEID_ATTRIB_NAME, true);
762 domElement->setIdAttributeNS(nullptr, RESPONSEID_ATTRIB_NAME);
765 MARSHALL_STRING_ATTRIB(InResponseTo,INRESPONSETO,nullptr);
766 if (!m_IssueInstant) {
767 const_cast<ResponseAbstractTypeImpl*>(this)->m_IssueInstantEpoch=time(nullptr);
768 const_cast<ResponseAbstractTypeImpl*>(this)->m_IssueInstant=new DateTime(m_IssueInstantEpoch);
770 MARSHALL_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,nullptr);
771 MARSHALL_STRING_ATTRIB(Recipient,RECIPIENT,nullptr);
774 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
775 PROC_TYPED_FOREIGN_CHILD(Signature,xmlsignature,XMLSIG_NS,false);
776 AbstractXMLObjectUnmarshaller::processChildElement(childXMLObject,root);
779 void unmarshallAttributes(const DOMElement* domElement) {
780 // Standard processing, but then we check IDness.
781 AbstractXMLObjectUnmarshaller::unmarshallAttributes(domElement);
782 if (m_ResponseID && (!m_MinorVersion || *m_MinorVersion!=chDigit_0)) {
783 #ifdef XMLTOOLING_XERCESC_BOOLSETIDATTRIBUTE
784 const_cast<DOMElement*>(domElement)->setIdAttributeNS(nullptr, RESPONSEID_ATTRIB_NAME, true);
786 const_cast<DOMElement*>(domElement)->setIdAttributeNS(nullptr, RESPONSEID_ATTRIB_NAME);
791 void processAttribute(const DOMAttr* attribute) {
792 static const XMLCh MAJORVERSION[] = UNICODE_LITERAL_12(M,a,j,o,r,V,e,r,s,i,o,n);
793 if (XMLHelper::isNodeNamed(attribute,nullptr,MAJORVERSION)) {
794 if (!XMLString::equals(attribute->getValue(),XML_ONE))
795 throw UnmarshallingException("Response has invalid major version.");
797 PROC_INTEGER_ATTRIB(MinorVersion,MINORVERSION,nullptr);
798 PROC_STRING_ATTRIB(ResponseID,RESPONSEID,nullptr);
799 PROC_STRING_ATTRIB(InResponseTo,INRESPONSETO,nullptr);
800 PROC_DATETIME_ATTRIB(IssueInstant,ISSUEINSTANT,nullptr);
801 PROC_STRING_ATTRIB(Recipient,RECIPIENT,nullptr);
805 class SAML_DLLLOCAL ResponseImpl : public virtual Response, public ResponseAbstractTypeImpl
808 m_children.push_back(nullptr);
810 m_pos_Status=m_pos_Signature;
815 virtual ~ResponseImpl() {}
817 ResponseImpl(const XMLCh* nsURI, const XMLCh* localName, const XMLCh* prefix, const xmltooling::QName* schemaType)
818 : AbstractXMLObject(nsURI, localName, prefix, schemaType) {
822 ResponseImpl(const ResponseImpl& src) : AbstractXMLObject(src), ResponseAbstractTypeImpl(src) {
826 void _clone(const ResponseImpl& src) {
827 ResponseAbstractTypeImpl::_clone(src);
828 IMPL_CLONE_TYPED_CHILD(Status);
829 IMPL_CLONE_TYPED_FOREIGN_CHILDREN(Assertion,saml1);
832 IMPL_XMLOBJECT_CLONE_EX(Response);
833 IMPL_TYPED_CHILD(Status);
834 IMPL_TYPED_FOREIGN_CHILDREN(Assertion,saml1,m_children.end());
837 void processChildElement(XMLObject* childXMLObject, const DOMElement* root) {
838 PROC_TYPED_CHILD(Status,SAML1P_NS,false);
839 PROC_TYPED_FOREIGN_CHILDREN(Assertion,saml1,SAML1_NS,true);
840 ResponseAbstractTypeImpl::processChildElement(childXMLObject,root);
847 #if defined (_MSC_VER)
848 #pragma warning( pop )
851 // Builder Implementations
853 IMPL_XMLOBJECTBUILDER(AssertionArtifact);
854 IMPL_XMLOBJECTBUILDER(AttributeQuery);
855 IMPL_XMLOBJECTBUILDER(AuthenticationQuery);
856 IMPL_XMLOBJECTBUILDER(AuthorizationDecisionQuery);
857 IMPL_XMLOBJECTBUILDER(Query);
858 IMPL_XMLOBJECTBUILDER(Request);
859 IMPL_XMLOBJECTBUILDER(RespondWith);
860 IMPL_XMLOBJECTBUILDER(Response);
861 IMPL_XMLOBJECTBUILDER(Status);
862 IMPL_XMLOBJECTBUILDER(StatusCode);
863 IMPL_XMLOBJECTBUILDER(StatusDetail);
864 IMPL_XMLOBJECTBUILDER(StatusMessage);
867 const XMLCh RequestAbstractType::LOCAL_NAME[] = {chNull};
868 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);
869 const XMLCh RequestAbstractType::MINORVERSION_ATTRIB_NAME[] = UNICODE_LITERAL_12(M,i,n,o,r,V,e,r,s,i,o,n);
870 const XMLCh RequestAbstractType::REQUESTID_ATTRIB_NAME[] = UNICODE_LITERAL_9(R,e,q,u,e,s,t,I,D);
871 const XMLCh RequestAbstractType::ISSUEINSTANT_ATTRIB_NAME[] = UNICODE_LITERAL_12(I,s,s,u,e,I,n,s,t,a,n,t);
872 const XMLCh ResponseAbstractType::LOCAL_NAME[] = {chNull};
873 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);
874 const XMLCh ResponseAbstractType::MINORVERSION_ATTRIB_NAME[] = UNICODE_LITERAL_12(M,i,n,o,r,V,e,r,s,i,o,n);
875 const XMLCh ResponseAbstractType::RESPONSEID_ATTRIB_NAME[] = UNICODE_LITERAL_10(R,e,s,p,o,n,s,e,I,D);
876 const XMLCh ResponseAbstractType::ISSUEINSTANT_ATTRIB_NAME[] = UNICODE_LITERAL_12(I,s,s,u,e,I,n,s,t,a,n,t);
877 const XMLCh ResponseAbstractType::INRESPONSETO_ATTRIB_NAME[] = UNICODE_LITERAL_12(I,n,R,e,s,p,o,n,s,e,T,o);
878 const XMLCh ResponseAbstractType::RECIPIENT_ATTRIB_NAME[] = UNICODE_LITERAL_9(R,e,c,i,p,i,e,n,t);
879 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);
880 const XMLCh AttributeQuery::LOCAL_NAME[] = UNICODE_LITERAL_14(A,t,t,r,i,b,u,t,e,Q,u,e,r,y);
881 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);
882 const XMLCh AttributeQuery::RESOURCE_ATTRIB_NAME[] = UNICODE_LITERAL_8(R,e,s,o,u,r,c,e);
883 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);
884 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);
885 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);
886 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);
887 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);
888 const XMLCh AuthorizationDecisionQuery::RESOURCE_ATTRIB_NAME[] = UNICODE_LITERAL_8(R,e,s,o,u,r,c,e);
889 const XMLCh Query::LOCAL_NAME[] = UNICODE_LITERAL_5(Q,u,e,r,y);
890 const XMLCh Request::LOCAL_NAME[] = UNICODE_LITERAL_7(R,e,q,u,e,s,t);
891 const XMLCh Request::TYPE_NAME[] = UNICODE_LITERAL_11(R,e,q,u,e,s,t,T,y,p,e);
892 const XMLCh RespondWith::LOCAL_NAME[] = UNICODE_LITERAL_11(R,e,s,p,o,n,d,W,i,t,h);
893 const XMLCh Response::LOCAL_NAME[] = UNICODE_LITERAL_8(R,e,s,p,o,n,s,e);
894 const XMLCh Response::TYPE_NAME[] = UNICODE_LITERAL_12(R,e,s,p,o,n,s,e,T,y,p,e);
895 const XMLCh Status::LOCAL_NAME[] = UNICODE_LITERAL_6(S,t,a,t,u,s);
896 const XMLCh Status::TYPE_NAME[] = UNICODE_LITERAL_10(S,t,a,t,u,s,T,y,p,e);
897 const XMLCh StatusCode::LOCAL_NAME[] = UNICODE_LITERAL_10(S,t,a,t,u,s,C,o,d,e);
898 const XMLCh StatusCode::TYPE_NAME[] = UNICODE_LITERAL_14(S,t,a,t,u,s,C,o,d,e,T,y,p,e);
899 const XMLCh StatusCode::VALUE_ATTRIB_NAME[] = UNICODE_LITERAL_5(V,a,l,u,e);
900 const XMLCh StatusDetail::LOCAL_NAME[] = UNICODE_LITERAL_12(S,t,a,t,u,s,D,e,t,a,i,l);
901 const XMLCh StatusDetail::TYPE_NAME[] = UNICODE_LITERAL_16(S,t,a,t,u,s,D,e,t,a,i,l,T,y,p,e);
902 const XMLCh StatusMessage::LOCAL_NAME[] = UNICODE_LITERAL_13(S,t,a,t,u,s,M,e,s,s,a,g,e);
903 const XMLCh SubjectQuery::LOCAL_NAME[] = UNICODE_LITERAL_12(S,u,b,j,e,c,t,Q,u,e,r,y);
905 #define XCH(ch) chLatin_##ch
906 #define XNUM(d) chDigit_##d
908 const XMLCh _SUCCESS[] = UNICODE_LITERAL_7(S,u,c,c,e,s,s);
909 const XMLCh _REQUESTER[] = UNICODE_LITERAL_9(R,e,q,u,e,s,t,e,r);
910 const XMLCh _RESPONDER[] = UNICODE_LITERAL_9(R,e,s,p,o,n,d,e,r);
911 const XMLCh _VERSIONMISMATCH[] = UNICODE_LITERAL_15(V,e,r,s,i,o,n,M,i,s,m,a,t,c,h);
913 xmltooling::QName StatusCode::SUCCESS(SAML1P_NS,_SUCCESS,SAML1P_PREFIX);
914 xmltooling::QName StatusCode::REQUESTER(SAML1P_NS,_REQUESTER,SAML1P_PREFIX);
915 xmltooling::QName StatusCode::RESPONDER(SAML1P_NS,_RESPONDER,SAML1P_PREFIX);
916 xmltooling::QName StatusCode::VERSIONMISMATCH(SAML1P_NS,_VERSIONMISMATCH,SAML1P_PREFIX);